From fd233778db8a2c900db9bd0e14672b2c2e482a78 Mon Sep 17 00:00:00 2001 From: Russ Butler Date: Thu, 11 May 2017 14:59:31 -0500 Subject: [PATCH 01/24] Remove RTOS and CMSIS files Remove the RTOS and CMSIS files in preperation for CMSIS 5. Note that the RTOS heap ad stack test is left since this is still applicable to RTX5. This file can be found here: rtos\rtx\TARGET_CORTEX_M\TESTS\memory\heap_and_stack\main.cpp --- cmsis/arm_math.h | 7556 ----------------- cmsis/core_cm0.h | 750 -- cmsis/core_cm0plus.h | 864 -- cmsis/core_cm3.h | 1732 ---- cmsis/core_cm4.h | 1898 ----- cmsis/core_cm4_simd.h | 673 -- cmsis/core_cm7.h | 2407 ------ cmsis/core_cmFunc.h | 664 -- cmsis/core_cmInstr.h | 916 -- cmsis/core_cmSimd.h | 697 -- cmsis/core_sc000.h | 866 -- cmsis/core_sc300.h | 1677 ---- rtos/rtx/TARGET_CORTEX_M/HAL_CM.c | 180 - rtos/rtx/TARGET_CORTEX_M/RTX_CM_lib.h | 698 -- rtos/rtx/TARGET_CORTEX_M/RTX_Conf_CM.c | 281 - rtos/rtx/TARGET_CORTEX_M/RTX_Config.h | 84 - .../TARGET_M0/TOOLCHAIN_ARM/HAL_CM0.c | 301 - .../TARGET_M0/TOOLCHAIN_ARM/SVC_Table.S | 57 - .../TARGET_M0/TOOLCHAIN_GCC/HAL_CM0.S | 370 - .../TARGET_M0/TOOLCHAIN_GCC/SVC_Table.S | 56 - .../TARGET_M0/TOOLCHAIN_IAR/HAL_CM0.S | 312 - .../TARGET_M0/TOOLCHAIN_IAR/SVC_Table.S | 58 - .../TARGET_M0P/TOOLCHAIN_ARM/HAL_CM0.c | 301 - .../TARGET_M0P/TOOLCHAIN_ARM/SVC_Table.S | 57 - .../TARGET_M0P/TOOLCHAIN_GCC/HAL_CM0.S | 370 - .../TARGET_M0P/TOOLCHAIN_GCC/SVC_Table.S | 56 - .../TARGET_M0P/TOOLCHAIN_IAR/HAL_CM0.S | 312 - .../TARGET_M0P/TOOLCHAIN_IAR/SVC_Table.S | 58 - .../TARGET_M3/TOOLCHAIN_ARM/HAL_CM3.c | 274 - .../TARGET_M3/TOOLCHAIN_ARM/SVC_Table.S | 57 - .../TARGET_M3/TOOLCHAIN_GCC/HAL_CM3.S | 345 - .../TARGET_M3/TOOLCHAIN_GCC/SVC_Table.S | 56 - .../TARGET_M3/TOOLCHAIN_IAR/HAL_CM3.S | 265 - .../TARGET_M3/TOOLCHAIN_IAR/SVC_Table.S | 58 - .../TARGET_RTOS_M4_M7/TOOLCHAIN_ARM/HAL_CM4.c | 327 - .../TOOLCHAIN_ARM/SVC_Table.S | 57 - .../TARGET_RTOS_M4_M7/TOOLCHAIN_GCC/HAL_CM4.S | 419 - .../TOOLCHAIN_GCC/SVC_Table.S | 56 - .../TARGET_RTOS_M4_M7/TOOLCHAIN_IAR/HAL_CM4.S | 363 - .../TOOLCHAIN_IAR/SVC_Table.S | 58 - rtos/rtx/TARGET_CORTEX_M/cmsis_os.h | 747 -- rtos/rtx/TARGET_CORTEX_M/rt_CMSIS.c | 2344 ----- rtos/rtx/TARGET_CORTEX_M/rt_Event.c | 190 - rtos/rtx/TARGET_CORTEX_M/rt_Event.h | 51 - rtos/rtx/TARGET_CORTEX_M/rt_HAL_CM.h | 344 - rtos/rtx/TARGET_CORTEX_M/rt_List.c | 318 - rtos/rtx/TARGET_CORTEX_M/rt_List.h | 72 - rtos/rtx/TARGET_CORTEX_M/rt_Mailbox.c | 293 - rtos/rtx/TARGET_CORTEX_M/rt_Mailbox.h | 53 - rtos/rtx/TARGET_CORTEX_M/rt_MemBox.c | 168 - rtos/rtx/TARGET_CORTEX_M/rt_MemBox.h | 50 - rtos/rtx/TARGET_CORTEX_M/rt_Memory.c | 140 - rtos/rtx/TARGET_CORTEX_M/rt_Memory.h | 49 - rtos/rtx/TARGET_CORTEX_M/rt_Mutex.c | 259 - rtos/rtx/TARGET_CORTEX_M/rt_Mutex.h | 49 - rtos/rtx/TARGET_CORTEX_M/rt_OsEventObserver.c | 61 - rtos/rtx/TARGET_CORTEX_M/rt_OsEventObserver.h | 63 - rtos/rtx/TARGET_CORTEX_M/rt_Robin.c | 83 - rtos/rtx/TARGET_CORTEX_M/rt_Robin.h | 50 - rtos/rtx/TARGET_CORTEX_M/rt_Semaphore.c | 182 - rtos/rtx/TARGET_CORTEX_M/rt_Semaphore.h | 51 - rtos/rtx/TARGET_CORTEX_M/rt_System.c | 325 - rtos/rtx/TARGET_CORTEX_M/rt_System.h | 57 - rtos/rtx/TARGET_CORTEX_M/rt_Task.c | 456 - rtos/rtx/TARGET_CORTEX_M/rt_Task.h | 88 - rtos/rtx/TARGET_CORTEX_M/rt_Time.c | 93 - rtos/rtx/TARGET_CORTEX_M/rt_Time.h | 52 - rtos/rtx/TARGET_CORTEX_M/rt_Timer.c | 135 - rtos/rtx/TARGET_CORTEX_M/rt_Timer.h | 50 - rtos/rtx/TARGET_CORTEX_M/rt_TypeDef.h | 175 - 70 files changed, 33634 deletions(-) delete mode 100644 cmsis/arm_math.h delete mode 100644 cmsis/core_cm0.h delete mode 100644 cmsis/core_cm0plus.h delete mode 100644 cmsis/core_cm3.h delete mode 100644 cmsis/core_cm4.h delete mode 100644 cmsis/core_cm4_simd.h delete mode 100644 cmsis/core_cm7.h delete mode 100644 cmsis/core_cmFunc.h delete mode 100644 cmsis/core_cmInstr.h delete mode 100644 cmsis/core_cmSimd.h delete mode 100644 cmsis/core_sc000.h delete mode 100644 cmsis/core_sc300.h delete mode 100644 rtos/rtx/TARGET_CORTEX_M/HAL_CM.c delete mode 100644 rtos/rtx/TARGET_CORTEX_M/RTX_CM_lib.h delete mode 100755 rtos/rtx/TARGET_CORTEX_M/RTX_Conf_CM.c delete mode 100644 rtos/rtx/TARGET_CORTEX_M/RTX_Config.h delete mode 100644 rtos/rtx/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_ARM/HAL_CM0.c delete mode 100644 rtos/rtx/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_ARM/SVC_Table.S delete mode 100644 rtos/rtx/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_GCC/HAL_CM0.S delete mode 100644 rtos/rtx/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_GCC/SVC_Table.S delete mode 100644 rtos/rtx/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_IAR/HAL_CM0.S delete mode 100644 rtos/rtx/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_IAR/SVC_Table.S delete mode 100644 rtos/rtx/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_ARM/HAL_CM0.c delete mode 100644 rtos/rtx/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_ARM/SVC_Table.S delete mode 100644 rtos/rtx/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_GCC/HAL_CM0.S delete mode 100644 rtos/rtx/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_GCC/SVC_Table.S delete mode 100644 rtos/rtx/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_IAR/HAL_CM0.S delete mode 100644 rtos/rtx/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_IAR/SVC_Table.S delete mode 100644 rtos/rtx/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_ARM/HAL_CM3.c delete mode 100644 rtos/rtx/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_ARM/SVC_Table.S delete mode 100644 rtos/rtx/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_GCC/HAL_CM3.S delete mode 100644 rtos/rtx/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_GCC/SVC_Table.S delete mode 100644 rtos/rtx/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_IAR/HAL_CM3.S delete mode 100644 rtos/rtx/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_IAR/SVC_Table.S delete mode 100644 rtos/rtx/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_ARM/HAL_CM4.c delete mode 100644 rtos/rtx/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_ARM/SVC_Table.S delete mode 100644 rtos/rtx/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_GCC/HAL_CM4.S delete mode 100644 rtos/rtx/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_GCC/SVC_Table.S delete mode 100644 rtos/rtx/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_IAR/HAL_CM4.S delete mode 100644 rtos/rtx/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_IAR/SVC_Table.S delete mode 100644 rtos/rtx/TARGET_CORTEX_M/cmsis_os.h delete mode 100644 rtos/rtx/TARGET_CORTEX_M/rt_CMSIS.c delete mode 100644 rtos/rtx/TARGET_CORTEX_M/rt_Event.c delete mode 100644 rtos/rtx/TARGET_CORTEX_M/rt_Event.h delete mode 100644 rtos/rtx/TARGET_CORTEX_M/rt_HAL_CM.h delete mode 100644 rtos/rtx/TARGET_CORTEX_M/rt_List.c delete mode 100644 rtos/rtx/TARGET_CORTEX_M/rt_List.h delete mode 100644 rtos/rtx/TARGET_CORTEX_M/rt_Mailbox.c delete mode 100644 rtos/rtx/TARGET_CORTEX_M/rt_Mailbox.h delete mode 100644 rtos/rtx/TARGET_CORTEX_M/rt_MemBox.c delete mode 100644 rtos/rtx/TARGET_CORTEX_M/rt_MemBox.h delete mode 100644 rtos/rtx/TARGET_CORTEX_M/rt_Memory.c delete mode 100644 rtos/rtx/TARGET_CORTEX_M/rt_Memory.h delete mode 100644 rtos/rtx/TARGET_CORTEX_M/rt_Mutex.c delete mode 100644 rtos/rtx/TARGET_CORTEX_M/rt_Mutex.h delete mode 100644 rtos/rtx/TARGET_CORTEX_M/rt_OsEventObserver.c delete mode 100644 rtos/rtx/TARGET_CORTEX_M/rt_OsEventObserver.h delete mode 100644 rtos/rtx/TARGET_CORTEX_M/rt_Robin.c delete mode 100644 rtos/rtx/TARGET_CORTEX_M/rt_Robin.h delete mode 100644 rtos/rtx/TARGET_CORTEX_M/rt_Semaphore.c delete mode 100644 rtos/rtx/TARGET_CORTEX_M/rt_Semaphore.h delete mode 100644 rtos/rtx/TARGET_CORTEX_M/rt_System.c delete mode 100644 rtos/rtx/TARGET_CORTEX_M/rt_System.h delete mode 100644 rtos/rtx/TARGET_CORTEX_M/rt_Task.c delete mode 100644 rtos/rtx/TARGET_CORTEX_M/rt_Task.h delete mode 100644 rtos/rtx/TARGET_CORTEX_M/rt_Time.c delete mode 100644 rtos/rtx/TARGET_CORTEX_M/rt_Time.h delete mode 100644 rtos/rtx/TARGET_CORTEX_M/rt_Timer.c delete mode 100644 rtos/rtx/TARGET_CORTEX_M/rt_Timer.h delete mode 100644 rtos/rtx/TARGET_CORTEX_M/rt_TypeDef.h diff --git a/cmsis/arm_math.h b/cmsis/arm_math.h deleted file mode 100644 index e4b2f62e809..00000000000 --- a/cmsis/arm_math.h +++ /dev/null @@ -1,7556 +0,0 @@ -/* ---------------------------------------------------------------------- -* Copyright (C) 2010-2015 ARM Limited. All rights reserved. -* -* $Date: 19. March 2015 -* $Revision: V.1.4.5 -* -* Project: CMSIS DSP Library -* Title: arm_math.h -* -* Description: Public header file for CMSIS DSP Library -* -* Target Processor: Cortex-M7/Cortex-M4/Cortex-M3/Cortex-M0 -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* - Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* - Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in -* the documentation and/or other materials provided with the -* distribution. -* - Neither the name of ARM LIMITED nor the names of its contributors -* may be used to endorse or promote products derived from this -* software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. - * -------------------------------------------------------------------- */ - -/** - \mainpage CMSIS DSP Software Library - * - * Introduction - * ------------ - * - * This user manual describes the CMSIS DSP software library, - * a suite of common signal processing functions for use on Cortex-M processor based devices. - * - * The library is divided into a number of functions each covering a specific category: - * - Basic math functions - * - Fast math functions - * - Complex math functions - * - Filters - * - Matrix functions - * - Transforms - * - Motor control functions - * - Statistical functions - * - Support functions - * - Interpolation functions - * - * The library has separate functions for operating on 8-bit integers, 16-bit integers, - * 32-bit integer and 32-bit floating-point values. - * - * Using the Library - * ------------ - * - * The library installer contains prebuilt versions of the libraries in the Lib folder. - * - arm_cortexM7lfdp_math.lib (Little endian and Double Precision Floating Point Unit on Cortex-M7) - * - arm_cortexM7bfdp_math.lib (Big endian and Double Precision Floating Point Unit on Cortex-M7) - * - arm_cortexM7lfsp_math.lib (Little endian and Single Precision Floating Point Unit on Cortex-M7) - * - arm_cortexM7bfsp_math.lib (Big endian and Single Precision Floating Point Unit on Cortex-M7) - * - arm_cortexM7l_math.lib (Little endian on Cortex-M7) - * - arm_cortexM7b_math.lib (Big endian on Cortex-M7) - * - 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 / CortexM0+) - * - arm_cortexM0b_math.lib (Big endian on Cortex-M0 / CortexM0+) - * - * 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-M7/M4/M3/M0/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_CM7 or ARM_MATH_CM4 or ARM_MATH_CM3 or - * ARM_MATH_CM0 or ARM_MATH_CM0PLUS depending on the target processor in the application. - * - * Examples - * -------- - * - * The library ships with a number of examples which demonstrate how to use the library functions. - * - * Toolchain Support - * ------------ - * - * The library has been developed and tested with MDK-ARM version 5.14.0.0 - * The library is being tested in GCC and IAR toolchains and updates on this activity will be made available shortly. - * - * Building the Library - * ------------ - * - * The library installer contains a project file to re build libraries on MDK-ARM Tool chain in the CMSIS\\DSP_Lib\\Source\\ARM folder. - * - arm_cortexM_math.uvprojx - * - * - * The libraries can be built by opening the arm_cortexM_math.uvprojx project in MDK-ARM, selecting a specific target, and defining the optional pre processor MACROs detailed above. - * - * Pre-processor Macros - * ------------ - * - * Each library project have differant pre-processor macros. - * - * - UNALIGNED_SUPPORT_DISABLE: - * - * Define macro UNALIGNED_SUPPORT_DISABLE, If the silicon does not support unaligned memory access - * - * - ARM_MATH_BIG_ENDIAN: - * - * Define macro ARM_MATH_BIG_ENDIAN to build the library for big endian targets. By default library builds for little endian targets. - * - * - ARM_MATH_MATRIX_CHECK: - * - * Define macro ARM_MATH_MATRIX_CHECK for checking on the input and output sizes of matrices - * - * - ARM_MATH_ROUNDING: - * - * Define macro ARM_MATH_ROUNDING for rounding on support functions - * - * - ARM_MATH_CMx: - * - * Define macro ARM_MATH_CM4 for building the library on Cortex-M4 target, ARM_MATH_CM3 for building library on Cortex-M3 target - * and ARM_MATH_CM0 for building library on Cortex-M0 target, ARM_MATH_CM0PLUS for building library on Cortex-M0+ target, and - * ARM_MATH_CM7 for building the library on cortex-M7. - * - * - __FPU_PRESENT: - * - * Initialize macro __FPU_PRESENT = 1 when building on FPU supported Targets. Enable this macro for M4bf and M4lf libraries - * - *
- * CMSIS-DSP in ARM::CMSIS Pack - * ----------------------------- - * - * The following files relevant to CMSIS-DSP are present in the ARM::CMSIS Pack directories: - * |File/Folder |Content | - * |------------------------------|------------------------------------------------------------------------| - * |\b CMSIS\\Documentation\\DSP | This documentation | - * |\b CMSIS\\DSP_Lib | Software license agreement (license.txt) | - * |\b CMSIS\\DSP_Lib\\Examples | Example projects demonstrating the usage of the library functions | - * |\b CMSIS\\DSP_Lib\\Source | Source files for rebuilding the library | - * - *
- * Revision History of CMSIS-DSP - * ------------ - * Please refer to \ref ChangeLog_pg. - * - * Copyright Notice - * ------------ - * - * Copyright (C) 2010-2015 ARM Limited. All rights reserved. - */ - - -/** - * @defgroup groupMath Basic Math Functions - */ - -/** - * @defgroup groupFastMath Fast Math Functions - * This set of functions provides a fast approximation to sine, cosine, and square root. - * As compared to most of the other functions in the CMSIS math library, the fast math functions - * operate on individual values and not arrays. - * There are separate functions for Q15, Q31, and floating-point data. - * - */ - -/** - * @defgroup groupCmplxMath Complex Math Functions - * This set of functions operates on complex data vectors. - * The data in the complex arrays is stored in an interleaved fashion - * (real, imag, real, imag, ...). - * In the API functions, the number of samples in a complex array refers - * to the number of complex values; the array contains twice this number of - * real values. - */ - -/** - * @defgroup groupFilters Filtering Functions - */ - -/** - * @defgroup groupMatrix Matrix Functions - * - * This set of functions provides basic matrix math operations. - * The functions operate on matrix data structures. For example, - * the type - * definition for the floating-point matrix structure is shown - * below: - *
- *     typedef struct
- *     {
- *       uint16_t numRows;     // number of rows of the matrix.
- *       uint16_t numCols;     // number of columns of the matrix.
- *       float32_t *pData;     // points to the data of the matrix.
- *     } arm_matrix_instance_f32;
- * 
- * There are similar definitions for Q15 and Q31 data types. - * - * The structure specifies the size of the matrix and then points to - * an array of data. The array is of size numRows X numCols - * and the values are arranged in row order. That is, the - * matrix element (i, j) is stored at: - *
- *     pData[i*numCols + j]
- * 
- * - * \par Init Functions - * There is an associated initialization function for each type of matrix - * data structure. - * The initialization function sets the values of the internal structure fields. - * Refer to the function arm_mat_init_f32(), arm_mat_init_q31() - * and arm_mat_init_q15() for floating-point, Q31 and Q15 types, respectively. - * - * \par - * Use of the initialization function is optional. However, if initialization function is used - * then the instance structure cannot be placed into a const data section. - * To place the instance structure in a const data - * section, manually initialize the data structure. For example: - *
- * arm_matrix_instance_f32 S = {nRows, nColumns, pData};
- * arm_matrix_instance_q31 S = {nRows, nColumns, pData};
- * arm_matrix_instance_q15 S = {nRows, nColumns, pData};
- * 
- * where nRows specifies the number of rows, nColumns - * specifies the number of columns, and pData points to the - * data array. - * - * \par Size Checking - * By default all of the matrix functions perform size checking on the input and - * output matrices. For example, the matrix addition function verifies that the - * two input matrices and the output matrix all have the same number of rows and - * columns. If the size check fails the functions return: - *
- *     ARM_MATH_SIZE_MISMATCH
- * 
- * Otherwise the functions return - *
- *     ARM_MATH_SUCCESS
- * 
- * There is some overhead associated with this matrix size checking. - * The matrix size checking is enabled via the \#define - *
- *     ARM_MATH_MATRIX_CHECK
- * 
- * within the library project settings. By default this macro is defined - * and size checking is enabled. By changing the project settings and - * undefining this macro size checking is eliminated and the functions - * run a bit faster. With size checking disabled the functions always - * return ARM_MATH_SUCCESS. - */ - -/** - * @defgroup groupTransforms Transform Functions - */ - -/** - * @defgroup groupController Controller Functions - */ - -/** - * @defgroup groupStats Statistics Functions - */ -/** - * @defgroup groupSupport Support Functions - */ - -/** - * @defgroup groupInterpolation Interpolation Functions - * These functions perform 1- and 2-dimensional interpolation of data. - * Linear interpolation is used for 1-dimensional data and - * bilinear interpolation is used for 2-dimensional data. - */ - -/** - * @defgroup groupExamples Examples - */ -#ifndef _ARM_MATH_H -#define _ARM_MATH_H - -#define __CMSIS_GENERIC /* disable NVIC and Systick functions */ - -#if defined(ARM_MATH_CM7) - #include "core_cm7.h" -#elif defined (ARM_MATH_CM4) - #include "core_cm4.h" -#elif defined (ARM_MATH_CM3) - #include "core_cm3.h" -#elif defined (ARM_MATH_CM0) - #include "core_cm0.h" -#define ARM_MATH_CM0_FAMILY - #elif defined (ARM_MATH_CM0PLUS) -#include "core_cm0plus.h" - #define ARM_MATH_CM0_FAMILY -#else - #error "Define according the used Cortex core ARM_MATH_CM7, ARM_MATH_CM4, ARM_MATH_CM3, ARM_MATH_CM0PLUS or ARM_MATH_CM0" -#endif - -#undef __CMSIS_GENERIC /* enable NVIC and Systick functions */ -#include "string.h" -#include "math.h" -#ifdef __cplusplus -extern "C" -{ -#endif - - - /** - * @brief Macros required for reciprocal calculation in Normalized LMS - */ - -#define DELTA_Q31 (0x100) -#define DELTA_Q15 0x5 -#define INDEX_MASK 0x0000003F -#ifndef PI -#define PI 3.14159265358979f -#endif - - /** - * @brief Macros required for SINE and COSINE Fast math approximations - */ - -#define FAST_MATH_TABLE_SIZE 512 -#define FAST_MATH_Q31_SHIFT (32 - 10) -#define FAST_MATH_Q15_SHIFT (16 - 10) -#define CONTROLLER_Q31_SHIFT (32 - 9) -#define TABLE_SIZE 256 -#define TABLE_SPACING_Q31 0x400000 -#define TABLE_SPACING_Q15 0x80 - - /** - * @brief Macros required for SINE and COSINE Controller functions - */ - /* 1.31(q31) Fixed value of 2/360 */ - /* -1 to +1 is divided into 360 values so total spacing is (2/360) */ -#define INPUT_SPACING 0xB60B61 - - /** - * @brief Macro for Unaligned Support - */ -#ifndef UNALIGNED_SUPPORT_DISABLE - #define ALIGN4 -#else - #if defined (__GNUC__) - #define ALIGN4 __attribute__((aligned(4))) - #else - #define ALIGN4 __align(4) - #endif -#endif /* #ifndef UNALIGNED_SUPPORT_DISABLE */ - - /** - * @brief Error status returned by some functions in the library. - */ - - typedef enum - { - ARM_MATH_SUCCESS = 0, /**< No error */ - ARM_MATH_ARGUMENT_ERROR = -1, /**< One or more arguments are incorrect */ - ARM_MATH_LENGTH_ERROR = -2, /**< Length of data buffer is incorrect */ - ARM_MATH_SIZE_MISMATCH = -3, /**< Size of matrices is not compatible with the operation. */ - ARM_MATH_NANINF = -4, /**< Not-a-number (NaN) or infinity is generated */ - ARM_MATH_SINGULAR = -5, /**< Generated by matrix inversion if the input matrix is singular and cannot be inverted. */ - ARM_MATH_TEST_FAILURE = -6 /**< Test Failed */ - } arm_status; - - /** - * @brief 8-bit fractional data type in 1.7 format. - */ - typedef int8_t q7_t; - - /** - * @brief 16-bit fractional data type in 1.15 format. - */ - typedef int16_t q15_t; - - /** - * @brief 32-bit fractional data type in 1.31 format. - */ - typedef int32_t q31_t; - - /** - * @brief 64-bit fractional data type in 1.63 format. - */ - typedef int64_t q63_t; - - /** - * @brief 32-bit floating-point type definition. - */ - typedef float float32_t; - - /** - * @brief 64-bit floating-point type definition. - */ - typedef double float64_t; - - /** - * @brief definition to read/write two 16 bit values. - */ -#if defined __CC_ARM - #define __SIMD32_TYPE int32_t __packed - #define CMSIS_UNUSED __attribute__((unused)) -#elif defined __ICCARM__ - #define __SIMD32_TYPE int32_t __packed - #define CMSIS_UNUSED -#elif defined __GNUC__ - #define __SIMD32_TYPE int32_t - #define CMSIS_UNUSED __attribute__((unused)) -#elif defined __CSMC__ /* Cosmic */ - #define __SIMD32_TYPE int32_t - #define CMSIS_UNUSED -#elif defined __TASKING__ - #define __SIMD32_TYPE __unaligned int32_t - #define CMSIS_UNUSED -#else - #error Unknown compiler -#endif - -#define __SIMD32(addr) (*(__SIMD32_TYPE **) & (addr)) -#define __SIMD32_CONST(addr) ((__SIMD32_TYPE *)(addr)) - -#define _SIMD32_OFFSET(addr) (*(__SIMD32_TYPE *) (addr)) - -#define __SIMD64(addr) (*(int64_t **) & (addr)) - -#if defined (ARM_MATH_CM3) || defined (ARM_MATH_CM0_FAMILY) - /** - * @brief definition to pack two 16 bit values. - */ -#define __PKHBT(ARG1, ARG2, ARG3) ( (((int32_t)(ARG1) << 0) & (int32_t)0x0000FFFF) | \ - (((int32_t)(ARG2) << ARG3) & (int32_t)0xFFFF0000) ) -#define __PKHTB(ARG1, ARG2, ARG3) ( (((int32_t)(ARG1) << 0) & (int32_t)0xFFFF0000) | \ - (((int32_t)(ARG2) >> ARG3) & (int32_t)0x0000FFFF) ) - -#endif - - - /** - * @brief definition to pack four 8 bit values. - */ -#ifndef ARM_MATH_BIG_ENDIAN - -#define __PACKq7(v0,v1,v2,v3) ( (((int32_t)(v0) << 0) & (int32_t)0x000000FF) | \ - (((int32_t)(v1) << 8) & (int32_t)0x0000FF00) | \ - (((int32_t)(v2) << 16) & (int32_t)0x00FF0000) | \ - (((int32_t)(v3) << 24) & (int32_t)0xFF000000) ) -#else - -#define __PACKq7(v0,v1,v2,v3) ( (((int32_t)(v3) << 0) & (int32_t)0x000000FF) | \ - (((int32_t)(v2) << 8) & (int32_t)0x0000FF00) | \ - (((int32_t)(v1) << 16) & (int32_t)0x00FF0000) | \ - (((int32_t)(v0) << 24) & (int32_t)0xFF000000) ) - -#endif - - - /** - * @brief Clips Q63 to Q31 values. - */ - static __INLINE q31_t clip_q63_to_q31( - q63_t x) - { - return ((q31_t) (x >> 32) != ((q31_t) x >> 31)) ? - ((0x7FFFFFFF ^ ((q31_t) (x >> 63)))) : (q31_t) x; - } - - /** - * @brief Clips Q63 to Q15 values. - */ - static __INLINE q15_t clip_q63_to_q15( - q63_t x) - { - return ((q31_t) (x >> 32) != ((q31_t) x >> 31)) ? - ((0x7FFF ^ ((q15_t) (x >> 63)))) : (q15_t) (x >> 15); - } - - /** - * @brief Clips Q31 to Q7 values. - */ - static __INLINE q7_t clip_q31_to_q7( - q31_t x) - { - return ((q31_t) (x >> 24) != ((q31_t) x >> 23)) ? - ((0x7F ^ ((q7_t) (x >> 31)))) : (q7_t) x; - } - - /** - * @brief Clips Q31 to Q15 values. - */ - static __INLINE q15_t clip_q31_to_q15( - q31_t x) - { - return ((q31_t) (x >> 16) != ((q31_t) x >> 15)) ? - ((0x7FFF ^ ((q15_t) (x >> 31)))) : (q15_t) x; - } - - /** - * @brief Multiplies 32 X 64 and returns 32 bit result in 2.30 format. - */ - - static __INLINE q63_t mult32x64( - q63_t x, - q31_t y) - { - return ((((q63_t) (x & 0x00000000FFFFFFFF) * y) >> 32) + - (((q63_t) (x >> 32) * y))); - } - - -//#if defined (ARM_MATH_CM0_FAMILY) && defined ( __CC_ARM ) -//#define __CLZ __clz -//#endif - -//note: function can be removed when all toolchain support __CLZ for Cortex-M0 -#if defined (ARM_MATH_CM0_FAMILY) && ((defined (__ICCARM__)) ) - - static __INLINE uint32_t __CLZ( - q31_t data); - - - static __INLINE uint32_t __CLZ( - q31_t data) - { - uint32_t count = 0; - uint32_t mask = 0x80000000; - - while((data & mask) == 0) - { - count += 1u; - mask = mask >> 1u; - } - - return (count); - - } - -#endif - - /** - * @brief Function to Calculates 1/in (reciprocal) value of Q31 Data type. - */ - - static __INLINE uint32_t arm_recip_q31( - q31_t in, - q31_t * dst, - q31_t * pRecipTable) - { - - uint32_t out, tempVal; - uint32_t index, i; - uint32_t signBits; - - if(in > 0) - { - signBits = __CLZ(in) - 1; - } - else - { - signBits = __CLZ(-in) - 1; - } - - /* Convert input sample to 1.31 format */ - in = in << signBits; - - /* calculation of index for initial approximated Val */ - index = (uint32_t) (in >> 24u); - index = (index & INDEX_MASK); - - /* 1.31 with exp 1 */ - out = pRecipTable[index]; - - /* calculation of reciprocal value */ - /* running approximation for two iterations */ - for (i = 0u; i < 2u; i++) - { - tempVal = (q31_t) (((q63_t) in * out) >> 31u); - tempVal = 0x7FFFFFFF - tempVal; - /* 1.31 with exp 1 */ - //out = (q31_t) (((q63_t) out * tempVal) >> 30u); - out = (q31_t) clip_q63_to_q31(((q63_t) out * tempVal) >> 30u); - } - - /* write output */ - *dst = out; - - /* return num of signbits of out = 1/in value */ - return (signBits + 1u); - - } - - /** - * @brief Function to Calculates 1/in (reciprocal) value of Q15 Data type. - */ - static __INLINE uint32_t arm_recip_q15( - q15_t in, - q15_t * dst, - q15_t * pRecipTable) - { - - uint32_t out = 0, tempVal = 0; - uint32_t index = 0, i = 0; - uint32_t signBits = 0; - - if(in > 0) - { - signBits = __CLZ(in) - 17; - } - else - { - signBits = __CLZ(-in) - 17; - } - - /* Convert input sample to 1.15 format */ - in = in << signBits; - - /* calculation of index for initial approximated Val */ - index = in >> 8; - index = (index & INDEX_MASK); - - /* 1.15 with exp 1 */ - out = pRecipTable[index]; - - /* calculation of reciprocal value */ - /* running approximation for two iterations */ - for (i = 0; i < 2; i++) - { - tempVal = (q15_t) (((q31_t) in * out) >> 15); - tempVal = 0x7FFF - tempVal; - /* 1.15 with exp 1 */ - out = (q15_t) (((q31_t) out * tempVal) >> 14); - } - - /* write output */ - *dst = out; - - /* return num of signbits of out = 1/in value */ - return (signBits + 1); - - } - - - /* - * @brief C custom defined intrinisic function for only M0 processors - */ -#if defined(ARM_MATH_CM0_FAMILY) - - static __INLINE q31_t __SSAT( - q31_t x, - uint32_t y) - { - int32_t posMax, negMin; - uint32_t i; - - posMax = 1; - for (i = 0; i < (y - 1); i++) - { - posMax = posMax * 2; - } - - if(x > 0) - { - posMax = (posMax - 1); - - if(x > posMax) - { - x = posMax; - } - } - else - { - negMin = -posMax; - - if(x < negMin) - { - x = negMin; - } - } - return (x); - - - } - -#endif /* end of ARM_MATH_CM0_FAMILY */ - - - - /* - * @brief C custom defined intrinsic function for M3 and M0 processors - */ -#if defined (ARM_MATH_CM3) || defined (ARM_MATH_CM0_FAMILY) - - /* - * @brief C custom defined QADD8 for M3 and M0 processors - */ - static __INLINE q31_t __QADD8( - q31_t x, - q31_t y) - { - - q31_t sum; - q7_t r, s, t, u; - - r = (q7_t) x; - s = (q7_t) y; - - r = __SSAT((q31_t) (r + s), 8); - s = __SSAT(((q31_t) (((x << 16) >> 24) + ((y << 16) >> 24))), 8); - t = __SSAT(((q31_t) (((x << 8) >> 24) + ((y << 8) >> 24))), 8); - u = __SSAT(((q31_t) ((x >> 24) + (y >> 24))), 8); - - sum = - (((q31_t) u << 24) & 0xFF000000) | (((q31_t) t << 16) & 0x00FF0000) | - (((q31_t) s << 8) & 0x0000FF00) | (r & 0x000000FF); - - return sum; - - } - - /* - * @brief C custom defined QSUB8 for M3 and M0 processors - */ - static __INLINE q31_t __QSUB8( - q31_t x, - q31_t y) - { - - q31_t sum; - q31_t r, s, t, u; - - r = (q7_t) x; - s = (q7_t) y; - - r = __SSAT((r - s), 8); - s = __SSAT(((q31_t) (((x << 16) >> 24) - ((y << 16) >> 24))), 8) << 8; - t = __SSAT(((q31_t) (((x << 8) >> 24) - ((y << 8) >> 24))), 8) << 16; - u = __SSAT(((q31_t) ((x >> 24) - (y >> 24))), 8) << 24; - - sum = - (u & 0xFF000000) | (t & 0x00FF0000) | (s & 0x0000FF00) | (r & - 0x000000FF); - - return sum; - } - - /* - * @brief C custom defined QADD16 for M3 and M0 processors - */ - - /* - * @brief C custom defined QADD16 for M3 and M0 processors - */ - static __INLINE q31_t __QADD16( - q31_t x, - q31_t y) - { - - q31_t sum; - q31_t r, s; - - r = (q15_t) x; - s = (q15_t) 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 = (q15_t) x; - s = (q15_t) 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 = (q15_t) x; - s = (q15_t) 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 = (q15_t) x; - s = (q15_t) 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) ((q15_t) (x >> 16) + (q15_t) y))) << 16) + - clip_q31_to_q15((q31_t) ((q15_t) x - (q15_t) (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 = (q15_t) x; - s = (q15_t) 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) ((q15_t) (x >> 16) - (q15_t) y))) << 16) + - clip_q31_to_q15((q31_t) ((q15_t) x + (q15_t) (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 = (q15_t) x; - s = (q15_t) 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) (((q15_t) x * (q15_t) (y >> 16)) - - ((q15_t) (x >> 16) * (q15_t) 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) (((q15_t) x * (q15_t) (y >> 16)) + - ((q15_t) (x >> 16) * (q15_t) 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 + ((q15_t) (x >> 16) * (q15_t) (y >> 16)) + - ((q15_t) x * (q15_t) 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 + ((q15_t) (x >> 16) * (q15_t) (y)) + - ((q15_t) x * (q15_t) (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 - ((q15_t) (x >> 16) * (q15_t) (y)) + - ((q15_t) x * (q15_t) (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 + ((q15_t) (x >> 16) * (q15_t) (y >> 16)) + - ((q15_t) x * (q15_t) 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 + ((q15_t) (x >> 16) * (q15_t) y)) + - ((q15_t) x * (q15_t) (y >> 16)); - } - - /* - * @brief C custom defined SMUAD for M3 and M0 processors - */ - static __INLINE q31_t __SMUAD( - q31_t x, - q31_t y) - { - - return (((x >> 16) * (y >> 16)) + - (((x << 16) >> 16) * ((y << 16) >> 16))); - } - - /* - * @brief C custom defined SMUSD for M3 and M0 processors - */ - static __INLINE q31_t __SMUSD( - q31_t x, - q31_t y) - { - - return (-((x >> 16) * (y >> 16)) + - (((x << 16) >> 16) * ((y << 16) >> 16))); - } - - - /* - * @brief C custom defined SXTB16 for M3 and M0 processors - */ - static __INLINE q31_t __SXTB16( - q31_t x) - { - - return ((((x << 24) >> 24) & 0x0000FFFF) | - (((x << 8) >> 8) & 0xFFFF0000)); - } - - -#endif /* defined (ARM_MATH_CM3) || defined (ARM_MATH_CM0_FAMILY) */ - - - /** - * @brief Instance structure for the Q7 FIR filter. - */ - typedef struct - { - uint16_t numTaps; /**< number of filter coefficients in the filter. */ - q7_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ - q7_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ - } arm_fir_instance_q7; - - /** - * @brief Instance structure for the Q15 FIR filter. - */ - typedef struct - { - uint16_t numTaps; /**< number of filter coefficients in the filter. */ - q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ - q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ - } arm_fir_instance_q15; - - /** - * @brief Instance structure for the Q31 FIR filter. - */ - typedef struct - { - uint16_t numTaps; /**< number of filter coefficients in the filter. */ - q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ - q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ - } arm_fir_instance_q31; - - /** - * @brief Instance structure for the floating-point FIR filter. - */ - typedef struct - { - uint16_t numTaps; /**< number of filter coefficients in the filter. */ - float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ - float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ - } arm_fir_instance_f32; - - - /** - * @brief Processing function for the Q7 FIR filter. - * @param[in] *S points to an instance of the Q7 FIR filter structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data. - * @param[in] blockSize number of samples to process. - * @return none. - */ - void arm_fir_q7( - const arm_fir_instance_q7 * S, - q7_t * pSrc, - q7_t * pDst, - uint32_t blockSize); - - - /** - * @brief Initialization function for the Q7 FIR filter. - * @param[in,out] *S points to an instance of the Q7 FIR structure. - * @param[in] numTaps Number of filter coefficients in the filter. - * @param[in] *pCoeffs points to the filter coefficients. - * @param[in] *pState points to the state buffer. - * @param[in] blockSize number of samples that are processed. - * @return none - */ - void arm_fir_init_q7( - arm_fir_instance_q7 * S, - uint16_t numTaps, - q7_t * pCoeffs, - q7_t * pState, - uint32_t blockSize); - - - /** - * @brief Processing function for the Q15 FIR filter. - * @param[in] *S points to an instance of the Q15 FIR structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data. - * @param[in] blockSize number of samples to process. - * @return none. - */ - void arm_fir_q15( - const arm_fir_instance_q15 * S, - q15_t * pSrc, - q15_t * pDst, - uint32_t blockSize); - - /** - * @brief Processing function for the fast Q15 FIR filter for Cortex-M3 and Cortex-M4. - * @param[in] *S points to an instance of the Q15 FIR filter structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data. - * @param[in] blockSize number of samples to process. - * @return none. - */ - void arm_fir_fast_q15( - const arm_fir_instance_q15 * S, - q15_t * pSrc, - q15_t * pDst, - uint32_t blockSize); - - /** - * @brief Initialization function for the Q15 FIR filter. - * @param[in,out] *S points to an instance of the Q15 FIR filter structure. - * @param[in] numTaps Number of filter coefficients in the filter. Must be even and greater than or equal to 4. - * @param[in] *pCoeffs points to the filter coefficients. - * @param[in] *pState points to the state buffer. - * @param[in] blockSize number of samples that are processed at a time. - * @return The function returns ARM_MATH_SUCCESS if initialization was successful or ARM_MATH_ARGUMENT_ERROR if - * numTaps is not a supported value. - */ - - arm_status arm_fir_init_q15( - arm_fir_instance_q15 * S, - uint16_t numTaps, - q15_t * pCoeffs, - q15_t * pState, - uint32_t blockSize); - - /** - * @brief Processing function for the Q31 FIR filter. - * @param[in] *S points to an instance of the Q31 FIR filter structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data. - * @param[in] blockSize number of samples to process. - * @return none. - */ - void arm_fir_q31( - const arm_fir_instance_q31 * S, - q31_t * pSrc, - q31_t * pDst, - uint32_t blockSize); - - /** - * @brief Processing function for the fast Q31 FIR filter for Cortex-M3 and Cortex-M4. - * @param[in] *S points to an instance of the Q31 FIR structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data. - * @param[in] blockSize number of samples to process. - * @return none. - */ - void arm_fir_fast_q31( - const arm_fir_instance_q31 * S, - q31_t * pSrc, - q31_t * pDst, - uint32_t blockSize); - - /** - * @brief Initialization function for the Q31 FIR filter. - * @param[in,out] *S points to an instance of the Q31 FIR structure. - * @param[in] numTaps Number of filter coefficients in the filter. - * @param[in] *pCoeffs points to the filter coefficients. - * @param[in] *pState points to the state buffer. - * @param[in] blockSize number of samples that are processed at a time. - * @return none. - */ - void arm_fir_init_q31( - arm_fir_instance_q31 * S, - uint16_t numTaps, - q31_t * pCoeffs, - q31_t * pState, - uint32_t blockSize); - - /** - * @brief Processing function for the floating-point FIR filter. - * @param[in] *S points to an instance of the floating-point FIR structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data. - * @param[in] blockSize number of samples to process. - * @return none. - */ - void arm_fir_f32( - const arm_fir_instance_f32 * S, - float32_t * pSrc, - float32_t * pDst, - uint32_t blockSize); - - /** - * @brief Initialization function for the floating-point FIR filter. - * @param[in,out] *S points to an instance of the floating-point FIR filter structure. - * @param[in] numTaps Number of filter coefficients in the filter. - * @param[in] *pCoeffs points to the filter coefficients. - * @param[in] *pState points to the state buffer. - * @param[in] blockSize number of samples that are processed at a time. - * @return none. - */ - void arm_fir_init_f32( - arm_fir_instance_f32 * S, - uint16_t numTaps, - float32_t * pCoeffs, - float32_t * pState, - uint32_t blockSize); - - - /** - * @brief Instance structure for the Q15 Biquad cascade filter. - */ - typedef struct - { - int8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ - q15_t *pState; /**< Points to the array of state coefficients. The array is of length 4*numStages. */ - q15_t *pCoeffs; /**< Points to the array of coefficients. The array is of length 5*numStages. */ - int8_t postShift; /**< Additional shift, in bits, applied to each output sample. */ - - } arm_biquad_casd_df1_inst_q15; - - - /** - * @brief Instance structure for the Q31 Biquad cascade filter. - */ - typedef struct - { - uint32_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ - q31_t *pState; /**< Points to the array of state coefficients. The array is of length 4*numStages. */ - q31_t *pCoeffs; /**< Points to the array of coefficients. The array is of length 5*numStages. */ - uint8_t postShift; /**< Additional shift, in bits, applied to each output sample. */ - - } arm_biquad_casd_df1_inst_q31; - - /** - * @brief Instance structure for the floating-point Biquad cascade filter. - */ - typedef struct - { - uint32_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ - float32_t *pState; /**< Points to the array of state coefficients. The array is of length 4*numStages. */ - float32_t *pCoeffs; /**< Points to the array of coefficients. The array is of length 5*numStages. */ - - - } arm_biquad_casd_df1_inst_f32; - - - - /** - * @brief Processing function for the Q15 Biquad cascade filter. - * @param[in] *S points to an instance of the Q15 Biquad cascade structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data. - * @param[in] blockSize number of samples to process. - * @return none. - */ - - void arm_biquad_cascade_df1_q15( - const arm_biquad_casd_df1_inst_q15 * S, - q15_t * pSrc, - q15_t * pDst, - uint32_t blockSize); - - /** - * @brief Initialization function for the Q15 Biquad cascade filter. - * @param[in,out] *S points to an instance of the Q15 Biquad cascade structure. - * @param[in] numStages number of 2nd order stages in the filter. - * @param[in] *pCoeffs points to the filter coefficients. - * @param[in] *pState points to the state buffer. - * @param[in] postShift Shift to be applied to the output. Varies according to the coefficients format - * @return none - */ - - void arm_biquad_cascade_df1_init_q15( - arm_biquad_casd_df1_inst_q15 * S, - uint8_t numStages, - q15_t * pCoeffs, - q15_t * pState, - int8_t postShift); - - - /** - * @brief Fast but less precise processing function for the Q15 Biquad cascade filter for Cortex-M3 and Cortex-M4. - * @param[in] *S points to an instance of the Q15 Biquad cascade structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data. - * @param[in] blockSize number of samples to process. - * @return none. - */ - - void arm_biquad_cascade_df1_fast_q15( - const arm_biquad_casd_df1_inst_q15 * S, - q15_t * pSrc, - q15_t * pDst, - uint32_t blockSize); - - - /** - * @brief Processing function for the Q31 Biquad cascade filter - * @param[in] *S points to an instance of the Q31 Biquad cascade structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data. - * @param[in] blockSize number of samples to process. - * @return none. - */ - - void arm_biquad_cascade_df1_q31( - const arm_biquad_casd_df1_inst_q31 * S, - q31_t * pSrc, - q31_t * pDst, - uint32_t blockSize); - - /** - * @brief Fast but less precise processing function for the Q31 Biquad cascade filter for Cortex-M3 and Cortex-M4. - * @param[in] *S points to an instance of the Q31 Biquad cascade structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data. - * @param[in] blockSize number of samples to process. - * @return none. - */ - - void arm_biquad_cascade_df1_fast_q31( - const arm_biquad_casd_df1_inst_q31 * S, - q31_t * pSrc, - q31_t * pDst, - uint32_t blockSize); - - /** - * @brief Initialization function for the Q31 Biquad cascade filter. - * @param[in,out] *S points to an instance of the Q31 Biquad cascade structure. - * @param[in] numStages number of 2nd order stages in the filter. - * @param[in] *pCoeffs points to the filter coefficients. - * @param[in] *pState points to the state buffer. - * @param[in] postShift Shift to be applied to the output. Varies according to the coefficients format - * @return none - */ - - void arm_biquad_cascade_df1_init_q31( - arm_biquad_casd_df1_inst_q31 * S, - uint8_t numStages, - q31_t * pCoeffs, - q31_t * pState, - int8_t postShift); - - /** - * @brief Processing function for the floating-point Biquad cascade filter. - * @param[in] *S points to an instance of the floating-point Biquad cascade structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data. - * @param[in] blockSize number of samples to process. - * @return none. - */ - - void arm_biquad_cascade_df1_f32( - const arm_biquad_casd_df1_inst_f32 * S, - float32_t * pSrc, - float32_t * pDst, - uint32_t blockSize); - - /** - * @brief Initialization function for the floating-point Biquad cascade filter. - * @param[in,out] *S points to an instance of the floating-point Biquad cascade structure. - * @param[in] numStages number of 2nd order stages in the filter. - * @param[in] *pCoeffs points to the filter coefficients. - * @param[in] *pState points to the state buffer. - * @return none - */ - - void arm_biquad_cascade_df1_init_f32( - arm_biquad_casd_df1_inst_f32 * S, - uint8_t numStages, - float32_t * pCoeffs, - float32_t * pState); - - - /** - * @brief Instance structure for the floating-point matrix structure. - */ - - typedef struct - { - uint16_t numRows; /**< number of rows of the matrix. */ - uint16_t numCols; /**< number of columns of the matrix. */ - float32_t *pData; /**< points to the data of the matrix. */ - } arm_matrix_instance_f32; - - - /** - * @brief Instance structure for the floating-point matrix structure. - */ - - typedef struct - { - uint16_t numRows; /**< number of rows of the matrix. */ - uint16_t numCols; /**< number of columns of the matrix. */ - float64_t *pData; /**< points to the data of the matrix. */ - } arm_matrix_instance_f64; - - /** - * @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, complex, 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_cmplx_mult_f32( - const arm_matrix_instance_f32 * pSrcA, - const arm_matrix_instance_f32 * pSrcB, - arm_matrix_instance_f32 * pDst); - - /** - * @brief Q15, complex, 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_cmplx_mult_q15( - const arm_matrix_instance_q15 * pSrcA, - const arm_matrix_instance_q15 * pSrcB, - arm_matrix_instance_q15 * pDst, - q15_t * pScratch); - - /** - * @brief Q31, complex, 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_cmplx_mult_q31( - const arm_matrix_instance_q31 * pSrcA, - const arm_matrix_instance_q31 * pSrcB, - arm_matrix_instance_q31 * pDst); - - - /** - * @brief Floating-point matrix transpose. - * @param[in] *pSrc points to the input matrix - * @param[out] *pDst points to the output matrix - * @return The function returns either ARM_MATH_SIZE_MISMATCH - * or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - - arm_status arm_mat_trans_f32( - const arm_matrix_instance_f32 * pSrc, - arm_matrix_instance_f32 * pDst); - - - /** - * @brief Q15 matrix transpose. - * @param[in] *pSrc points to the input matrix - * @param[out] *pDst points to the output matrix - * @return The function returns either ARM_MATH_SIZE_MISMATCH - * or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - - arm_status arm_mat_trans_q15( - const arm_matrix_instance_q15 * pSrc, - arm_matrix_instance_q15 * pDst); - - /** - * @brief Q31 matrix transpose. - * @param[in] *pSrc points to the input matrix - * @param[out] *pDst points to the output matrix - * @return The function returns either ARM_MATH_SIZE_MISMATCH - * or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - - arm_status arm_mat_trans_q31( - const arm_matrix_instance_q31 * pSrc, - arm_matrix_instance_q31 * pDst); - - - /** - * @brief Floating-point matrix multiplication - * @param[in] *pSrcA points to the first input matrix structure - * @param[in] *pSrcB points to the second input matrix structure - * @param[out] *pDst points to output matrix structure - * @return The function returns either - * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - - arm_status arm_mat_mult_f32( - const arm_matrix_instance_f32 * pSrcA, - const arm_matrix_instance_f32 * pSrcB, - arm_matrix_instance_f32 * pDst); - - /** - * @brief Q15 matrix multiplication - * @param[in] *pSrcA points to the first input matrix structure - * @param[in] *pSrcB points to the second input matrix structure - * @param[out] *pDst points to output matrix structure - * @param[in] *pState points to the array for storing intermediate results - * @return The function returns either - * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - - arm_status arm_mat_mult_q15( - const arm_matrix_instance_q15 * pSrcA, - const arm_matrix_instance_q15 * pSrcB, - arm_matrix_instance_q15 * pDst, - q15_t * pState); - - /** - * @brief Q15 matrix multiplication (fast variant) for Cortex-M3 and Cortex-M4 - * @param[in] *pSrcA points to the first input matrix structure - * @param[in] *pSrcB points to the second input matrix structure - * @param[out] *pDst points to output matrix structure - * @param[in] *pState points to the array for storing intermediate results - * @return The function returns either - * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - - arm_status arm_mat_mult_fast_q15( - const arm_matrix_instance_q15 * pSrcA, - const arm_matrix_instance_q15 * pSrcB, - arm_matrix_instance_q15 * pDst, - q15_t * pState); - - /** - * @brief Q31 matrix multiplication - * @param[in] *pSrcA points to the first input matrix structure - * @param[in] *pSrcB points to the second input matrix structure - * @param[out] *pDst points to output matrix structure - * @return The function returns either - * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - - arm_status arm_mat_mult_q31( - const arm_matrix_instance_q31 * pSrcA, - const arm_matrix_instance_q31 * pSrcB, - arm_matrix_instance_q31 * pDst); - - /** - * @brief Q31 matrix multiplication (fast variant) for Cortex-M3 and Cortex-M4 - * @param[in] *pSrcA points to the first input matrix structure - * @param[in] *pSrcB points to the second input matrix structure - * @param[out] *pDst points to output matrix structure - * @return The function returns either - * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - - arm_status arm_mat_mult_fast_q31( - const arm_matrix_instance_q31 * pSrcA, - const arm_matrix_instance_q31 * pSrcB, - arm_matrix_instance_q31 * pDst); - - - /** - * @brief Floating-point matrix subtraction - * @param[in] *pSrcA points to the first input matrix structure - * @param[in] *pSrcB points to the second input matrix structure - * @param[out] *pDst points to output matrix structure - * @return The function returns either - * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - - arm_status arm_mat_sub_f32( - const arm_matrix_instance_f32 * pSrcA, - const arm_matrix_instance_f32 * pSrcB, - arm_matrix_instance_f32 * pDst); - - /** - * @brief Q15 matrix subtraction - * @param[in] *pSrcA points to the first input matrix structure - * @param[in] *pSrcB points to the second input matrix structure - * @param[out] *pDst points to output matrix structure - * @return The function returns either - * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - - arm_status arm_mat_sub_q15( - const arm_matrix_instance_q15 * pSrcA, - const arm_matrix_instance_q15 * pSrcB, - arm_matrix_instance_q15 * pDst); - - /** - * @brief Q31 matrix subtraction - * @param[in] *pSrcA points to the first input matrix structure - * @param[in] *pSrcB points to the second input matrix structure - * @param[out] *pDst points to output matrix structure - * @return The function returns either - * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - - arm_status arm_mat_sub_q31( - const arm_matrix_instance_q31 * pSrcA, - const arm_matrix_instance_q31 * pSrcB, - arm_matrix_instance_q31 * pDst); - - /** - * @brief Floating-point matrix scaling. - * @param[in] *pSrc points to the input matrix - * @param[in] scale scale factor - * @param[out] *pDst points to the output matrix - * @return The function returns either - * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - - arm_status arm_mat_scale_f32( - const arm_matrix_instance_f32 * pSrc, - float32_t scale, - arm_matrix_instance_f32 * pDst); - - /** - * @brief Q15 matrix scaling. - * @param[in] *pSrc points to input matrix - * @param[in] scaleFract fractional portion of the scale factor - * @param[in] shift number of bits to shift the result by - * @param[out] *pDst points to output matrix - * @return The function returns either - * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - - arm_status arm_mat_scale_q15( - const arm_matrix_instance_q15 * pSrc, - q15_t scaleFract, - int32_t shift, - arm_matrix_instance_q15 * pDst); - - /** - * @brief Q31 matrix scaling. - * @param[in] *pSrc points to input matrix - * @param[in] scaleFract fractional portion of the scale factor - * @param[in] shift number of bits to shift the result by - * @param[out] *pDst points to output matrix structure - * @return The function returns either - * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - - arm_status arm_mat_scale_q31( - const arm_matrix_instance_q31 * pSrc, - q31_t scaleFract, - int32_t shift, - arm_matrix_instance_q31 * pDst); - - - /** - * @brief Q31 matrix initialization. - * @param[in,out] *S points to an instance of the floating-point matrix structure. - * @param[in] nRows number of rows in the matrix. - * @param[in] nColumns number of columns in the matrix. - * @param[in] *pData points to the matrix data array. - * @return none - */ - - void arm_mat_init_q31( - arm_matrix_instance_q31 * S, - uint16_t nRows, - uint16_t nColumns, - q31_t * pData); - - /** - * @brief Q15 matrix initialization. - * @param[in,out] *S points to an instance of the floating-point matrix structure. - * @param[in] nRows number of rows in the matrix. - * @param[in] nColumns number of columns in the matrix. - * @param[in] *pData points to the matrix data array. - * @return none - */ - - void arm_mat_init_q15( - arm_matrix_instance_q15 * S, - uint16_t nRows, - uint16_t nColumns, - q15_t * pData); - - /** - * @brief Floating-point matrix initialization. - * @param[in,out] *S points to an instance of the floating-point matrix structure. - * @param[in] nRows number of rows in the matrix. - * @param[in] nColumns number of columns in the matrix. - * @param[in] *pData points to the matrix data array. - * @return none - */ - - void arm_mat_init_f32( - arm_matrix_instance_f32 * S, - uint16_t nRows, - uint16_t nColumns, - float32_t * pData); - - - - /** - * @brief Instance structure for the Q15 PID Control. - */ - typedef struct - { - q15_t A0; /**< The derived gain, A0 = Kp + Ki + Kd . */ -#ifdef ARM_MATH_CM0_FAMILY - q15_t A1; - q15_t A2; -#else - q31_t A1; /**< The derived gain A1 = -Kp - 2Kd | Kd.*/ -#endif - q15_t state[3]; /**< The state array of length 3. */ - q15_t Kp; /**< The proportional gain. */ - q15_t Ki; /**< The integral gain. */ - q15_t Kd; /**< The derivative gain. */ - } arm_pid_instance_q15; - - /** - * @brief Instance structure for the Q31 PID Control. - */ - typedef struct - { - q31_t A0; /**< The derived gain, A0 = Kp + Ki + Kd . */ - q31_t A1; /**< The derived gain, A1 = -Kp - 2Kd. */ - q31_t A2; /**< The derived gain, A2 = Kd . */ - q31_t state[3]; /**< The state array of length 3. */ - q31_t Kp; /**< The proportional gain. */ - q31_t Ki; /**< The integral gain. */ - q31_t Kd; /**< The derivative gain. */ - - } arm_pid_instance_q31; - - /** - * @brief Instance structure for the floating-point PID Control. - */ - typedef struct - { - float32_t A0; /**< The derived gain, A0 = Kp + Ki + Kd . */ - float32_t A1; /**< The derived gain, A1 = -Kp - 2Kd. */ - float32_t A2; /**< The derived gain, A2 = Kd . */ - float32_t state[3]; /**< The state array of length 3. */ - float32_t Kp; /**< The proportional gain. */ - float32_t Ki; /**< The integral gain. */ - float32_t Kd; /**< The derivative gain. */ - } arm_pid_instance_f32; - - - - /** - * @brief Initialization function for the floating-point PID Control. - * @param[in,out] *S points to an instance of the PID structure. - * @param[in] resetStateFlag flag to reset the state. 0 = no change in state 1 = reset the state. - * @return none. - */ - void arm_pid_init_f32( - arm_pid_instance_f32 * S, - int32_t resetStateFlag); - - /** - * @brief Reset function for the floating-point PID Control. - * @param[in,out] *S is an instance of the floating-point PID Control structure - * @return none - */ - void arm_pid_reset_f32( - arm_pid_instance_f32 * S); - - - /** - * @brief Initialization function for the Q31 PID Control. - * @param[in,out] *S points to an instance of the Q15 PID structure. - * @param[in] resetStateFlag flag to reset the state. 0 = no change in state 1 = reset the state. - * @return none. - */ - void arm_pid_init_q31( - arm_pid_instance_q31 * S, - int32_t resetStateFlag); - - - /** - * @brief Reset function for the Q31 PID Control. - * @param[in,out] *S points to an instance of the Q31 PID Control structure - * @return none - */ - - void arm_pid_reset_q31( - arm_pid_instance_q31 * S); - - /** - * @brief Initialization function for the Q15 PID Control. - * @param[in,out] *S points to an instance of the Q15 PID structure. - * @param[in] resetStateFlag flag to reset the state. 0 = no change in state 1 = reset the state. - * @return none. - */ - void arm_pid_init_q15( - arm_pid_instance_q15 * S, - int32_t resetStateFlag); - - /** - * @brief Reset function for the Q15 PID Control. - * @param[in,out] *S points to an instance of the q15 PID Control structure - * @return none - */ - void arm_pid_reset_q15( - arm_pid_instance_q15 * S); - - - /** - * @brief Instance structure for the floating-point Linear Interpolate function. - */ - typedef struct - { - uint32_t nValues; /**< nValues */ - float32_t x1; /**< x1 */ - float32_t xSpacing; /**< xSpacing */ - float32_t *pYData; /**< pointer to the table of Y values */ - } arm_linear_interp_instance_f32; - - /** - * @brief Instance structure for the floating-point bilinear interpolation function. - */ - - typedef struct - { - uint16_t numRows; /**< number of rows in the data table. */ - uint16_t numCols; /**< number of columns in the data table. */ - float32_t *pData; /**< points to the data table. */ - } arm_bilinear_interp_instance_f32; - - /** - * @brief Instance structure for the Q31 bilinear interpolation function. - */ - - typedef struct - { - uint16_t numRows; /**< number of rows in the data table. */ - uint16_t numCols; /**< number of columns in the data table. */ - q31_t *pData; /**< points to the data table. */ - } arm_bilinear_interp_instance_q31; - - /** - * @brief Instance structure for the Q15 bilinear interpolation function. - */ - - typedef struct - { - uint16_t numRows; /**< number of rows in the data table. */ - uint16_t numCols; /**< number of columns in the data table. */ - q15_t *pData; /**< points to the data table. */ - } arm_bilinear_interp_instance_q15; - - /** - * @brief Instance structure for the Q15 bilinear interpolation function. - */ - - typedef struct - { - uint16_t numRows; /**< number of rows in the data table. */ - uint16_t numCols; /**< number of columns in the data table. */ - q7_t *pData; /**< points to the data table. */ - } arm_bilinear_interp_instance_q7; - - - /** - * @brief Q7 vector multiplication. - * @param[in] *pSrcA points to the first input vector - * @param[in] *pSrcB points to the second input vector - * @param[out] *pDst points to the output vector - * @param[in] blockSize number of samples in each vector - * @return none. - */ - - void arm_mult_q7( - q7_t * pSrcA, - q7_t * pSrcB, - q7_t * pDst, - uint32_t blockSize); - - /** - * @brief Q15 vector multiplication. - * @param[in] *pSrcA points to the first input vector - * @param[in] *pSrcB points to the second input vector - * @param[out] *pDst points to the output vector - * @param[in] blockSize number of samples in each vector - * @return none. - */ - - void arm_mult_q15( - q15_t * pSrcA, - q15_t * pSrcB, - q15_t * pDst, - uint32_t blockSize); - - /** - * @brief Q31 vector multiplication. - * @param[in] *pSrcA points to the first input vector - * @param[in] *pSrcB points to the second input vector - * @param[out] *pDst points to the output vector - * @param[in] blockSize number of samples in each vector - * @return none. - */ - - void arm_mult_q31( - q31_t * pSrcA, - q31_t * pSrcB, - q31_t * pDst, - uint32_t blockSize); - - /** - * @brief Floating-point vector multiplication. - * @param[in] *pSrcA points to the first input vector - * @param[in] *pSrcB points to the second input vector - * @param[out] *pDst points to the output vector - * @param[in] blockSize number of samples in each vector - * @return none. - */ - - void arm_mult_f32( - float32_t * pSrcA, - float32_t * pSrcB, - float32_t * pDst, - uint32_t blockSize); - - - - - - - /** - * @brief Instance structure for the Q15 CFFT/CIFFT function. - */ - - typedef struct - { - uint16_t fftLen; /**< length of the FFT. */ - uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ - uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ - q15_t *pTwiddle; /**< points to the Sin twiddle factor table. */ - uint16_t *pBitRevTable; /**< points to the bit reversal table. */ - uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ - uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ - } arm_cfft_radix2_instance_q15; - -/* Deprecated */ - arm_status arm_cfft_radix2_init_q15( - arm_cfft_radix2_instance_q15 * S, - uint16_t fftLen, - uint8_t ifftFlag, - uint8_t bitReverseFlag); - -/* Deprecated */ - void arm_cfft_radix2_q15( - const arm_cfft_radix2_instance_q15 * S, - q15_t * pSrc); - - - - /** - * @brief Instance structure for the Q15 CFFT/CIFFT function. - */ - - typedef struct - { - uint16_t fftLen; /**< length of the FFT. */ - uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ - uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ - q15_t *pTwiddle; /**< points to the twiddle factor table. */ - uint16_t *pBitRevTable; /**< points to the bit reversal table. */ - uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ - uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ - } arm_cfft_radix4_instance_q15; - -/* Deprecated */ - arm_status arm_cfft_radix4_init_q15( - arm_cfft_radix4_instance_q15 * S, - uint16_t fftLen, - uint8_t ifftFlag, - uint8_t bitReverseFlag); - -/* Deprecated */ - void arm_cfft_radix4_q15( - const arm_cfft_radix4_instance_q15 * S, - q15_t * pSrc); - - /** - * @brief Instance structure for the Radix-2 Q31 CFFT/CIFFT function. - */ - - typedef struct - { - uint16_t fftLen; /**< length of the FFT. */ - uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ - uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ - q31_t *pTwiddle; /**< points to the Twiddle factor table. */ - uint16_t *pBitRevTable; /**< points to the bit reversal table. */ - uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ - uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ - } arm_cfft_radix2_instance_q31; - -/* Deprecated */ - arm_status arm_cfft_radix2_init_q31( - arm_cfft_radix2_instance_q31 * S, - uint16_t fftLen, - uint8_t ifftFlag, - uint8_t bitReverseFlag); - -/* Deprecated */ - void arm_cfft_radix2_q31( - const arm_cfft_radix2_instance_q31 * S, - q31_t * pSrc); - - /** - * @brief Instance structure for the Q31 CFFT/CIFFT function. - */ - - typedef struct - { - uint16_t fftLen; /**< length of the FFT. */ - uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ - uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ - q31_t *pTwiddle; /**< points to the twiddle factor table. */ - uint16_t *pBitRevTable; /**< points to the bit reversal table. */ - uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ - uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ - } arm_cfft_radix4_instance_q31; - -/* Deprecated */ - void arm_cfft_radix4_q31( - const arm_cfft_radix4_instance_q31 * S, - q31_t * pSrc); - -/* Deprecated */ - arm_status arm_cfft_radix4_init_q31( - arm_cfft_radix4_instance_q31 * S, - uint16_t fftLen, - uint8_t ifftFlag, - uint8_t bitReverseFlag); - - /** - * @brief Instance structure for the floating-point CFFT/CIFFT function. - */ - - typedef struct - { - uint16_t fftLen; /**< length of the FFT. */ - uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ - uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ - float32_t *pTwiddle; /**< points to the Twiddle factor table. */ - uint16_t *pBitRevTable; /**< points to the bit reversal table. */ - uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ - uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ - float32_t onebyfftLen; /**< value of 1/fftLen. */ - } arm_cfft_radix2_instance_f32; - -/* Deprecated */ - arm_status arm_cfft_radix2_init_f32( - arm_cfft_radix2_instance_f32 * S, - uint16_t fftLen, - uint8_t ifftFlag, - uint8_t bitReverseFlag); - -/* Deprecated */ - void arm_cfft_radix2_f32( - const arm_cfft_radix2_instance_f32 * S, - float32_t * pSrc); - - /** - * @brief Instance structure for the floating-point CFFT/CIFFT function. - */ - - typedef struct - { - uint16_t fftLen; /**< length of the FFT. */ - uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ - uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ - float32_t *pTwiddle; /**< points to the Twiddle factor table. */ - uint16_t *pBitRevTable; /**< points to the bit reversal table. */ - uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ - uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ - float32_t onebyfftLen; /**< value of 1/fftLen. */ - } arm_cfft_radix4_instance_f32; - -/* Deprecated */ - arm_status arm_cfft_radix4_init_f32( - arm_cfft_radix4_instance_f32 * S, - uint16_t fftLen, - uint8_t ifftFlag, - uint8_t bitReverseFlag); - -/* Deprecated */ - void arm_cfft_radix4_f32( - const arm_cfft_radix4_instance_f32 * S, - float32_t * pSrc); - - /** - * @brief Instance structure for the fixed-point CFFT/CIFFT function. - */ - - typedef struct - { - uint16_t fftLen; /**< length of the FFT. */ - const q15_t *pTwiddle; /**< points to the Twiddle factor table. */ - const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ - uint16_t bitRevLength; /**< bit reversal table length. */ - } arm_cfft_instance_q15; - -void arm_cfft_q15( - const arm_cfft_instance_q15 * S, - q15_t * p1, - uint8_t ifftFlag, - uint8_t bitReverseFlag); - - /** - * @brief Instance structure for the fixed-point CFFT/CIFFT function. - */ - - typedef struct - { - uint16_t fftLen; /**< length of the FFT. */ - const q31_t *pTwiddle; /**< points to the Twiddle factor table. */ - const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ - uint16_t bitRevLength; /**< bit reversal table length. */ - } arm_cfft_instance_q31; - -void arm_cfft_q31( - const arm_cfft_instance_q31 * S, - q31_t * p1, - uint8_t ifftFlag, - uint8_t bitReverseFlag); - - /** - * @brief Instance structure for the floating-point CFFT/CIFFT function. - */ - - typedef struct - { - uint16_t fftLen; /**< length of the FFT. */ - const float32_t *pTwiddle; /**< points to the Twiddle factor table. */ - const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ - uint16_t bitRevLength; /**< bit reversal table length. */ - } arm_cfft_instance_f32; - - void arm_cfft_f32( - const arm_cfft_instance_f32 * S, - float32_t * p1, - uint8_t ifftFlag, - uint8_t bitReverseFlag); - - /** - * @brief Instance structure for the Q15 RFFT/RIFFT function. - */ - - typedef struct - { - uint32_t fftLenReal; /**< length of the real FFT. */ - 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. */ - const arm_cfft_instance_q15 *pCfft; /**< points to the complex FFT instance. */ - } arm_rfft_instance_q15; - - arm_status arm_rfft_init_q15( - arm_rfft_instance_q15 * S, - uint32_t fftLenReal, - uint32_t ifftFlagR, - uint32_t bitReverseFlag); - - void arm_rfft_q15( - const arm_rfft_instance_q15 * S, - q15_t * pSrc, - q15_t * pDst); - - /** - * @brief Instance structure for the Q31 RFFT/RIFFT function. - */ - - typedef struct - { - uint32_t fftLenReal; /**< length of the real FFT. */ - 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. */ - const arm_cfft_instance_q31 *pCfft; /**< points to the complex FFT instance. */ - } arm_rfft_instance_q31; - - arm_status arm_rfft_init_q31( - arm_rfft_instance_q31 * S, - uint32_t fftLenReal, - uint32_t ifftFlagR, - uint32_t bitReverseFlag); - - void arm_rfft_q31( - const arm_rfft_instance_q31 * S, - q31_t * pSrc, - q31_t * pDst); - - /** - * @brief Instance structure for the floating-point RFFT/RIFFT function. - */ - - typedef struct - { - uint32_t fftLenReal; /**< length of the real FFT. */ - uint16_t fftLenBy2; /**< length of the complex FFT. */ - uint8_t ifftFlagR; /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */ - uint8_t bitReverseFlagR; /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */ - uint32_t twidCoefRModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ - float32_t *pTwiddleAReal; /**< points to the real twiddle factor table. */ - float32_t *pTwiddleBReal; /**< points to the imag twiddle factor table. */ - arm_cfft_radix4_instance_f32 *pCfft; /**< points to the complex FFT instance. */ - } arm_rfft_instance_f32; - - arm_status arm_rfft_init_f32( - arm_rfft_instance_f32 * S, - arm_cfft_radix4_instance_f32 * S_CFFT, - uint32_t fftLenReal, - uint32_t ifftFlagR, - uint32_t bitReverseFlag); - - void arm_rfft_f32( - const arm_rfft_instance_f32 * S, - float32_t * pSrc, - float32_t * pDst); - - /** - * @brief Instance structure for the floating-point RFFT/RIFFT function. - */ - -typedef struct - { - arm_cfft_instance_f32 Sint; /**< Internal CFFT structure. */ - uint16_t fftLenRFFT; /**< length of the real sequence */ - float32_t * pTwiddleRFFT; /**< Twiddle factors real stage */ - } arm_rfft_fast_instance_f32 ; - -arm_status arm_rfft_fast_init_f32 ( - arm_rfft_fast_instance_f32 * S, - uint16_t fftLen); - -void arm_rfft_fast_f32( - arm_rfft_fast_instance_f32 * S, - float32_t * p, float32_t * pOut, - uint8_t ifftFlag); - - /** - * @brief Instance structure for the floating-point DCT4/IDCT4 function. - */ - - typedef struct - { - uint16_t N; /**< length of the DCT4. */ - uint16_t Nby2; /**< half of the length of the DCT4. */ - float32_t normalize; /**< normalizing factor. */ - float32_t *pTwiddle; /**< points to the twiddle factor table. */ - float32_t *pCosFactor; /**< points to the cosFactor table. */ - arm_rfft_instance_f32 *pRfft; /**< points to the real FFT instance. */ - arm_cfft_radix4_instance_f32 *pCfft; /**< points to the complex FFT instance. */ - } arm_dct4_instance_f32; - - /** - * @brief Initialization function for the floating-point DCT4/IDCT4. - * @param[in,out] *S points to an instance of floating-point DCT4/IDCT4 structure. - * @param[in] *S_RFFT points to an instance of floating-point RFFT/RIFFT structure. - * @param[in] *S_CFFT points to an instance of floating-point CFFT/CIFFT structure. - * @param[in] N length of the DCT4. - * @param[in] Nby2 half of the length of the DCT4. - * @param[in] normalize normalizing factor. - * @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if fftLenReal is not a supported transform length. - */ - - arm_status arm_dct4_init_f32( - arm_dct4_instance_f32 * S, - arm_rfft_instance_f32 * S_RFFT, - arm_cfft_radix4_instance_f32 * S_CFFT, - uint16_t N, - uint16_t Nby2, - float32_t normalize); - - /** - * @brief Processing function for the floating-point DCT4/IDCT4. - * @param[in] *S points to an instance of the floating-point DCT4/IDCT4 structure. - * @param[in] *pState points to state buffer. - * @param[in,out] *pInlineBuffer points to the in-place input and output buffer. - * @return none. - */ - - void arm_dct4_f32( - const arm_dct4_instance_f32 * S, - float32_t * pState, - float32_t * pInlineBuffer); - - /** - * @brief Instance structure for the Q31 DCT4/IDCT4 function. - */ - - typedef struct - { - uint16_t N; /**< length of the DCT4. */ - uint16_t Nby2; /**< half of the length of the DCT4. */ - q31_t normalize; /**< normalizing factor. */ - q31_t *pTwiddle; /**< points to the twiddle factor table. */ - q31_t *pCosFactor; /**< points to the cosFactor table. */ - arm_rfft_instance_q31 *pRfft; /**< points to the real FFT instance. */ - arm_cfft_radix4_instance_q31 *pCfft; /**< points to the complex FFT instance. */ - } arm_dct4_instance_q31; - - /** - * @brief Initialization function for the Q31 DCT4/IDCT4. - * @param[in,out] *S points to an instance of Q31 DCT4/IDCT4 structure. - * @param[in] *S_RFFT points to an instance of Q31 RFFT/RIFFT structure - * @param[in] *S_CFFT points to an instance of Q31 CFFT/CIFFT structure - * @param[in] N length of the DCT4. - * @param[in] Nby2 half of the length of the DCT4. - * @param[in] normalize normalizing factor. - * @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if N is not a supported transform length. - */ - - arm_status arm_dct4_init_q31( - arm_dct4_instance_q31 * S, - arm_rfft_instance_q31 * S_RFFT, - arm_cfft_radix4_instance_q31 * S_CFFT, - uint16_t N, - uint16_t Nby2, - q31_t normalize); - - /** - * @brief Processing function for the Q31 DCT4/IDCT4. - * @param[in] *S points to an instance of the Q31 DCT4 structure. - * @param[in] *pState points to state buffer. - * @param[in,out] *pInlineBuffer points to the in-place input and output buffer. - * @return none. - */ - - void arm_dct4_q31( - const arm_dct4_instance_q31 * S, - q31_t * pState, - q31_t * pInlineBuffer); - - /** - * @brief Instance structure for the Q15 DCT4/IDCT4 function. - */ - - typedef struct - { - uint16_t N; /**< length of the DCT4. */ - uint16_t Nby2; /**< half of the length of the DCT4. */ - q15_t normalize; /**< normalizing factor. */ - q15_t *pTwiddle; /**< points to the twiddle factor table. */ - q15_t *pCosFactor; /**< points to the cosFactor table. */ - arm_rfft_instance_q15 *pRfft; /**< points to the real FFT instance. */ - arm_cfft_radix4_instance_q15 *pCfft; /**< points to the complex FFT instance. */ - } arm_dct4_instance_q15; - - /** - * @brief Initialization function for the Q15 DCT4/IDCT4. - * @param[in,out] *S points to an instance of Q15 DCT4/IDCT4 structure. - * @param[in] *S_RFFT points to an instance of Q15 RFFT/RIFFT structure. - * @param[in] *S_CFFT points to an instance of Q15 CFFT/CIFFT structure. - * @param[in] N length of the DCT4. - * @param[in] Nby2 half of the length of the DCT4. - * @param[in] normalize normalizing factor. - * @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if N is not a supported transform length. - */ - - arm_status arm_dct4_init_q15( - arm_dct4_instance_q15 * S, - arm_rfft_instance_q15 * S_RFFT, - arm_cfft_radix4_instance_q15 * S_CFFT, - uint16_t N, - uint16_t Nby2, - q15_t normalize); - - /** - * @brief Processing function for the Q15 DCT4/IDCT4. - * @param[in] *S points to an instance of the Q15 DCT4 structure. - * @param[in] *pState points to state buffer. - * @param[in,out] *pInlineBuffer points to the in-place input and output buffer. - * @return none. - */ - - void arm_dct4_q15( - const arm_dct4_instance_q15 * S, - q15_t * pState, - q15_t * pInlineBuffer); - - /** - * @brief Floating-point vector addition. - * @param[in] *pSrcA points to the first input vector - * @param[in] *pSrcB points to the second input vector - * @param[out] *pDst points to the output vector - * @param[in] blockSize number of samples in each vector - * @return none. - */ - - void arm_add_f32( - float32_t * pSrcA, - float32_t * pSrcB, - float32_t * pDst, - uint32_t blockSize); - - /** - * @brief Q7 vector addition. - * @param[in] *pSrcA points to the first input vector - * @param[in] *pSrcB points to the second input vector - * @param[out] *pDst points to the output vector - * @param[in] blockSize number of samples in each vector - * @return none. - */ - - void arm_add_q7( - q7_t * pSrcA, - q7_t * pSrcB, - q7_t * pDst, - uint32_t blockSize); - - /** - * @brief Q15 vector addition. - * @param[in] *pSrcA points to the first input vector - * @param[in] *pSrcB points to the second input vector - * @param[out] *pDst points to the output vector - * @param[in] blockSize number of samples in each vector - * @return none. - */ - - void arm_add_q15( - q15_t * pSrcA, - q15_t * pSrcB, - q15_t * pDst, - uint32_t blockSize); - - /** - * @brief Q31 vector addition. - * @param[in] *pSrcA points to the first input vector - * @param[in] *pSrcB points to the second input vector - * @param[out] *pDst points to the output vector - * @param[in] blockSize number of samples in each vector - * @return none. - */ - - void arm_add_q31( - q31_t * pSrcA, - q31_t * pSrcB, - q31_t * pDst, - uint32_t blockSize); - - /** - * @brief Floating-point vector subtraction. - * @param[in] *pSrcA points to the first input vector - * @param[in] *pSrcB points to the second input vector - * @param[out] *pDst points to the output vector - * @param[in] blockSize number of samples in each vector - * @return none. - */ - - void arm_sub_f32( - float32_t * pSrcA, - float32_t * pSrcB, - float32_t * pDst, - uint32_t blockSize); - - /** - * @brief Q7 vector subtraction. - * @param[in] *pSrcA points to the first input vector - * @param[in] *pSrcB points to the second input vector - * @param[out] *pDst points to the output vector - * @param[in] blockSize number of samples in each vector - * @return none. - */ - - void arm_sub_q7( - q7_t * pSrcA, - q7_t * pSrcB, - q7_t * pDst, - uint32_t blockSize); - - /** - * @brief Q15 vector subtraction. - * @param[in] *pSrcA points to the first input vector - * @param[in] *pSrcB points to the second input vector - * @param[out] *pDst points to the output vector - * @param[in] blockSize number of samples in each vector - * @return none. - */ - - void arm_sub_q15( - q15_t * pSrcA, - q15_t * pSrcB, - q15_t * pDst, - uint32_t blockSize); - - /** - * @brief Q31 vector subtraction. - * @param[in] *pSrcA points to the first input vector - * @param[in] *pSrcB points to the second input vector - * @param[out] *pDst points to the output vector - * @param[in] blockSize number of samples in each vector - * @return none. - */ - - void arm_sub_q31( - q31_t * pSrcA, - q31_t * pSrcB, - q31_t * pDst, - uint32_t blockSize); - - /** - * @brief Multiplies a floating-point vector by a scalar. - * @param[in] *pSrc points to the input vector - * @param[in] scale scale factor to be applied - * @param[out] *pDst points to the output vector - * @param[in] blockSize number of samples in the vector - * @return none. - */ - - void arm_scale_f32( - float32_t * pSrc, - float32_t scale, - float32_t * pDst, - uint32_t blockSize); - - /** - * @brief Multiplies a Q7 vector by a scalar. - * @param[in] *pSrc points to the input vector - * @param[in] scaleFract fractional portion of the scale value - * @param[in] shift number of bits to shift the result by - * @param[out] *pDst points to the output vector - * @param[in] blockSize number of samples in the vector - * @return none. - */ - - void arm_scale_q7( - q7_t * pSrc, - q7_t scaleFract, - int8_t shift, - q7_t * pDst, - uint32_t blockSize); - - /** - * @brief Multiplies a Q15 vector by a scalar. - * @param[in] *pSrc points to the input vector - * @param[in] scaleFract fractional portion of the scale value - * @param[in] shift number of bits to shift the result by - * @param[out] *pDst points to the output vector - * @param[in] blockSize number of samples in the vector - * @return none. - */ - - void arm_scale_q15( - q15_t * pSrc, - q15_t scaleFract, - int8_t shift, - q15_t * pDst, - uint32_t blockSize); - - /** - * @brief Multiplies a Q31 vector by a scalar. - * @param[in] *pSrc points to the input vector - * @param[in] scaleFract fractional portion of the scale value - * @param[in] shift number of bits to shift the result by - * @param[out] *pDst points to the output vector - * @param[in] blockSize number of samples in the vector - * @return none. - */ - - void arm_scale_q31( - q31_t * pSrc, - q31_t scaleFract, - int8_t shift, - q31_t * pDst, - uint32_t blockSize); - - /** - * @brief Q7 vector absolute value. - * @param[in] *pSrc points to the input buffer - * @param[out] *pDst points to the output buffer - * @param[in] blockSize number of samples in each vector - * @return none. - */ - - void arm_abs_q7( - q7_t * pSrc, - q7_t * pDst, - uint32_t blockSize); - - /** - * @brief Floating-point vector absolute value. - * @param[in] *pSrc points to the input buffer - * @param[out] *pDst points to the output buffer - * @param[in] blockSize number of samples in each vector - * @return none. - */ - - void arm_abs_f32( - float32_t * pSrc, - float32_t * pDst, - uint32_t blockSize); - - /** - * @brief Q15 vector absolute value. - * @param[in] *pSrc points to the input buffer - * @param[out] *pDst points to the output buffer - * @param[in] blockSize number of samples in each vector - * @return none. - */ - - void arm_abs_q15( - q15_t * pSrc, - q15_t * pDst, - uint32_t blockSize); - - /** - * @brief Q31 vector absolute value. - * @param[in] *pSrc points to the input buffer - * @param[out] *pDst points to the output buffer - * @param[in] blockSize number of samples in each vector - * @return none. - */ - - void arm_abs_q31( - q31_t * pSrc, - q31_t * pDst, - uint32_t blockSize); - - /** - * @brief Dot product of floating-point vectors. - * @param[in] *pSrcA points to the first input vector - * @param[in] *pSrcB points to the second input vector - * @param[in] blockSize number of samples in each vector - * @param[out] *result output result returned here - * @return none. - */ - - void arm_dot_prod_f32( - float32_t * pSrcA, - float32_t * pSrcB, - uint32_t blockSize, - float32_t * result); - - /** - * @brief Dot product of Q7 vectors. - * @param[in] *pSrcA points to the first input vector - * @param[in] *pSrcB points to the second input vector - * @param[in] blockSize number of samples in each vector - * @param[out] *result output result returned here - * @return none. - */ - - void arm_dot_prod_q7( - q7_t * pSrcA, - q7_t * pSrcB, - uint32_t blockSize, - q31_t * result); - - /** - * @brief Dot product of Q15 vectors. - * @param[in] *pSrcA points to the first input vector - * @param[in] *pSrcB points to the second input vector - * @param[in] blockSize number of samples in each vector - * @param[out] *result output result returned here - * @return none. - */ - - void arm_dot_prod_q15( - q15_t * pSrcA, - q15_t * pSrcB, - uint32_t blockSize, - q63_t * result); - - /** - * @brief Dot product of Q31 vectors. - * @param[in] *pSrcA points to the first input vector - * @param[in] *pSrcB points to the second input vector - * @param[in] blockSize number of samples in each vector - * @param[out] *result output result returned here - * @return none. - */ - - void arm_dot_prod_q31( - q31_t * pSrcA, - q31_t * pSrcB, - uint32_t blockSize, - q63_t * result); - - /** - * @brief Shifts the elements of a Q7 vector a specified number of bits. - * @param[in] *pSrc points to the input vector - * @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right. - * @param[out] *pDst points to the output vector - * @param[in] blockSize number of samples in the vector - * @return none. - */ - - void arm_shift_q7( - q7_t * pSrc, - int8_t shiftBits, - q7_t * pDst, - uint32_t blockSize); - - /** - * @brief Shifts the elements of a Q15 vector a specified number of bits. - * @param[in] *pSrc points to the input vector - * @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right. - * @param[out] *pDst points to the output vector - * @param[in] blockSize number of samples in the vector - * @return none. - */ - - void arm_shift_q15( - q15_t * pSrc, - int8_t shiftBits, - q15_t * pDst, - uint32_t blockSize); - - /** - * @brief Shifts the elements of a Q31 vector a specified number of bits. - * @param[in] *pSrc points to the input vector - * @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right. - * @param[out] *pDst points to the output vector - * @param[in] blockSize number of samples in the vector - * @return none. - */ - - void arm_shift_q31( - q31_t * pSrc, - int8_t shiftBits, - q31_t * pDst, - uint32_t blockSize); - - /** - * @brief Adds a constant offset to a floating-point vector. - * @param[in] *pSrc points to the input vector - * @param[in] offset is the offset to be added - * @param[out] *pDst points to the output vector - * @param[in] blockSize number of samples in the vector - * @return none. - */ - - void arm_offset_f32( - float32_t * pSrc, - float32_t offset, - float32_t * pDst, - uint32_t blockSize); - - /** - * @brief Adds a constant offset to a Q7 vector. - * @param[in] *pSrc points to the input vector - * @param[in] offset is the offset to be added - * @param[out] *pDst points to the output vector - * @param[in] blockSize number of samples in the vector - * @return none. - */ - - void arm_offset_q7( - q7_t * pSrc, - q7_t offset, - q7_t * pDst, - uint32_t blockSize); - - /** - * @brief Adds a constant offset to a Q15 vector. - * @param[in] *pSrc points to the input vector - * @param[in] offset is the offset to be added - * @param[out] *pDst points to the output vector - * @param[in] blockSize number of samples in the vector - * @return none. - */ - - void arm_offset_q15( - q15_t * pSrc, - q15_t offset, - q15_t * pDst, - uint32_t blockSize); - - /** - * @brief Adds a constant offset to a Q31 vector. - * @param[in] *pSrc points to the input vector - * @param[in] offset is the offset to be added - * @param[out] *pDst points to the output vector - * @param[in] blockSize number of samples in the vector - * @return none. - */ - - void arm_offset_q31( - q31_t * pSrc, - q31_t offset, - q31_t * pDst, - uint32_t blockSize); - - /** - * @brief Negates the elements of a floating-point vector. - * @param[in] *pSrc points to the input vector - * @param[out] *pDst points to the output vector - * @param[in] blockSize number of samples in the vector - * @return none. - */ - - void arm_negate_f32( - float32_t * pSrc, - float32_t * pDst, - uint32_t blockSize); - - /** - * @brief Negates the elements of a Q7 vector. - * @param[in] *pSrc points to the input vector - * @param[out] *pDst points to the output vector - * @param[in] blockSize number of samples in the vector - * @return none. - */ - - void arm_negate_q7( - q7_t * pSrc, - q7_t * pDst, - uint32_t blockSize); - - /** - * @brief Negates the elements of a Q15 vector. - * @param[in] *pSrc points to the input vector - * @param[out] *pDst points to the output vector - * @param[in] blockSize number of samples in the vector - * @return none. - */ - - void arm_negate_q15( - q15_t * pSrc, - q15_t * pDst, - uint32_t blockSize); - - /** - * @brief Negates the elements of a Q31 vector. - * @param[in] *pSrc points to the input vector - * @param[out] *pDst points to the output vector - * @param[in] blockSize number of samples in the vector - * @return none. - */ - - void arm_negate_q31( - q31_t * pSrc, - q31_t * pDst, - uint32_t blockSize); - /** - * @brief Copies the elements of a floating-point vector. - * @param[in] *pSrc input pointer - * @param[out] *pDst output pointer - * @param[in] blockSize number of samples to process - * @return none. - */ - void arm_copy_f32( - float32_t * pSrc, - float32_t * pDst, - uint32_t blockSize); - - /** - * @brief Copies the elements of a Q7 vector. - * @param[in] *pSrc input pointer - * @param[out] *pDst output pointer - * @param[in] blockSize number of samples to process - * @return none. - */ - void arm_copy_q7( - q7_t * pSrc, - q7_t * pDst, - uint32_t blockSize); - - /** - * @brief Copies the elements of a Q15 vector. - * @param[in] *pSrc input pointer - * @param[out] *pDst output pointer - * @param[in] blockSize number of samples to process - * @return none. - */ - void arm_copy_q15( - q15_t * pSrc, - q15_t * pDst, - uint32_t blockSize); - - /** - * @brief Copies the elements of a Q31 vector. - * @param[in] *pSrc input pointer - * @param[out] *pDst output pointer - * @param[in] blockSize number of samples to process - * @return none. - */ - void arm_copy_q31( - q31_t * pSrc, - q31_t * pDst, - uint32_t blockSize); - /** - * @brief Fills a constant value into a floating-point vector. - * @param[in] value input value to be filled - * @param[out] *pDst output pointer - * @param[in] blockSize number of samples to process - * @return none. - */ - void arm_fill_f32( - float32_t value, - float32_t * pDst, - uint32_t blockSize); - - /** - * @brief Fills a constant value into a Q7 vector. - * @param[in] value input value to be filled - * @param[out] *pDst output pointer - * @param[in] blockSize number of samples to process - * @return none. - */ - void arm_fill_q7( - q7_t value, - q7_t * pDst, - uint32_t blockSize); - - /** - * @brief Fills a constant value into a Q15 vector. - * @param[in] value input value to be filled - * @param[out] *pDst output pointer - * @param[in] blockSize number of samples to process - * @return none. - */ - void arm_fill_q15( - q15_t value, - q15_t * pDst, - uint32_t blockSize); - - /** - * @brief Fills a constant value into a Q31 vector. - * @param[in] value input value to be filled - * @param[out] *pDst output pointer - * @param[in] blockSize number of samples to process - * @return none. - */ - void arm_fill_q31( - q31_t value, - q31_t * pDst, - uint32_t blockSize); - -/** - * @brief Convolution of floating-point sequences. - * @param[in] *pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] *pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] *pDst points to the location where the output result is written. Length srcALen+srcBLen-1. - * @return none. - */ - - void arm_conv_f32( - float32_t * pSrcA, - uint32_t srcALen, - float32_t * pSrcB, - uint32_t srcBLen, - float32_t * pDst); - - - /** - * @brief Convolution of Q15 sequences. - * @param[in] *pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] *pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] *pDst points to the block of output data Length srcALen+srcBLen-1. - * @param[in] *pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. - * @param[in] *pScratch2 points to scratch buffer of size min(srcALen, srcBLen). - * @return none. - */ - - - void arm_conv_opt_q15( - q15_t * pSrcA, - uint32_t srcALen, - q15_t * pSrcB, - uint32_t srcBLen, - q15_t * pDst, - q15_t * pScratch1, - q15_t * pScratch2); - - -/** - * @brief Convolution of Q15 sequences. - * @param[in] *pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] *pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] *pDst points to the location where the output result is written. Length srcALen+srcBLen-1. - * @return none. - */ - - void arm_conv_q15( - q15_t * pSrcA, - uint32_t srcALen, - q15_t * pSrcB, - uint32_t srcBLen, - q15_t * pDst); - - /** - * @brief Convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4 - * @param[in] *pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] *pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] *pDst points to the block of output data Length srcALen+srcBLen-1. - * @return none. - */ - - void arm_conv_fast_q15( - q15_t * pSrcA, - uint32_t srcALen, - q15_t * pSrcB, - uint32_t srcBLen, - q15_t * pDst); - - /** - * @brief Convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4 - * @param[in] *pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] *pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] *pDst points to the block of output data Length srcALen+srcBLen-1. - * @param[in] *pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. - * @param[in] *pScratch2 points to scratch buffer of size min(srcALen, srcBLen). - * @return none. - */ - - void arm_conv_fast_opt_q15( - q15_t * pSrcA, - uint32_t srcALen, - q15_t * pSrcB, - uint32_t srcBLen, - q15_t * pDst, - q15_t * pScratch1, - q15_t * pScratch2); - - - - /** - * @brief Convolution of Q31 sequences. - * @param[in] *pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] *pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] *pDst points to the block of output data Length srcALen+srcBLen-1. - * @return none. - */ - - void arm_conv_q31( - q31_t * pSrcA, - uint32_t srcALen, - q31_t * pSrcB, - uint32_t srcBLen, - q31_t * pDst); - - /** - * @brief Convolution of Q31 sequences (fast version) for Cortex-M3 and Cortex-M4 - * @param[in] *pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] *pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] *pDst points to the block of output data Length srcALen+srcBLen-1. - * @return none. - */ - - void arm_conv_fast_q31( - q31_t * pSrcA, - uint32_t srcALen, - q31_t * pSrcB, - uint32_t srcBLen, - q31_t * pDst); - - - /** - * @brief Convolution of Q7 sequences. - * @param[in] *pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] *pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] *pDst points to the block of output data Length srcALen+srcBLen-1. - * @param[in] *pScratch1 points to scratch buffer(of type q15_t) of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. - * @param[in] *pScratch2 points to scratch buffer (of type q15_t) of size min(srcALen, srcBLen). - * @return none. - */ - - void arm_conv_opt_q7( - q7_t * pSrcA, - uint32_t srcALen, - q7_t * pSrcB, - uint32_t srcBLen, - q7_t * pDst, - q15_t * pScratch1, - q15_t * pScratch2); - - - - /** - * @brief Convolution of Q7 sequences. - * @param[in] *pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] *pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] *pDst points to the block of output data Length srcALen+srcBLen-1. - * @return none. - */ - - void arm_conv_q7( - q7_t * pSrcA, - uint32_t srcALen, - q7_t * pSrcB, - uint32_t srcBLen, - q7_t * pDst); - - - /** - * @brief Partial convolution of floating-point sequences. - * @param[in] *pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] *pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] *pDst points to the block of output data - * @param[in] firstIndex is the first output sample to start with. - * @param[in] numPoints is the number of output points to be computed. - * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. - */ - - arm_status arm_conv_partial_f32( - float32_t * pSrcA, - uint32_t srcALen, - float32_t * pSrcB, - uint32_t srcBLen, - float32_t * pDst, - uint32_t firstIndex, - uint32_t numPoints); - - /** - * @brief Partial convolution of Q15 sequences. - * @param[in] *pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] *pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] *pDst points to the block of output data - * @param[in] firstIndex is the first output sample to start with. - * @param[in] numPoints is the number of output points to be computed. - * @param[in] * pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. - * @param[in] * pScratch2 points to scratch buffer of size min(srcALen, srcBLen). - * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. - */ - - arm_status arm_conv_partial_opt_q15( - q15_t * pSrcA, - uint32_t srcALen, - q15_t * pSrcB, - uint32_t srcBLen, - q15_t * pDst, - uint32_t firstIndex, - uint32_t numPoints, - q15_t * pScratch1, - q15_t * pScratch2); - - -/** - * @brief Partial convolution of Q15 sequences. - * @param[in] *pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] *pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] *pDst points to the block of output data - * @param[in] firstIndex is the first output sample to start with. - * @param[in] numPoints is the number of output points to be computed. - * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. - */ - - arm_status arm_conv_partial_q15( - q15_t * pSrcA, - uint32_t srcALen, - q15_t * pSrcB, - uint32_t srcBLen, - q15_t * pDst, - uint32_t firstIndex, - uint32_t numPoints); - - /** - * @brief Partial convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4 - * @param[in] *pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] *pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] *pDst points to the block of output data - * @param[in] firstIndex is the first output sample to start with. - * @param[in] numPoints is the number of output points to be computed. - * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. - */ - - arm_status arm_conv_partial_fast_q15( - q15_t * pSrcA, - uint32_t srcALen, - q15_t * pSrcB, - uint32_t srcBLen, - q15_t * pDst, - uint32_t firstIndex, - uint32_t numPoints); - - - /** - * @brief Partial convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4 - * @param[in] *pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] *pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] *pDst points to the block of output data - * @param[in] firstIndex is the first output sample to start with. - * @param[in] numPoints is the number of output points to be computed. - * @param[in] * pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. - * @param[in] * pScratch2 points to scratch buffer of size min(srcALen, srcBLen). - * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. - */ - - arm_status arm_conv_partial_fast_opt_q15( - q15_t * pSrcA, - uint32_t srcALen, - q15_t * pSrcB, - uint32_t srcBLen, - q15_t * pDst, - uint32_t firstIndex, - uint32_t numPoints, - q15_t * pScratch1, - q15_t * pScratch2); - - - /** - * @brief Partial convolution of Q31 sequences. - * @param[in] *pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] *pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] *pDst points to the block of output data - * @param[in] firstIndex is the first output sample to start with. - * @param[in] numPoints is the number of output points to be computed. - * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. - */ - - arm_status arm_conv_partial_q31( - q31_t * pSrcA, - uint32_t srcALen, - q31_t * pSrcB, - uint32_t srcBLen, - q31_t * pDst, - uint32_t firstIndex, - uint32_t numPoints); - - - /** - * @brief Partial convolution of Q31 sequences (fast version) for Cortex-M3 and Cortex-M4 - * @param[in] *pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] *pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] *pDst points to the block of output data - * @param[in] firstIndex is the first output sample to start with. - * @param[in] numPoints is the number of output points to be computed. - * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. - */ - - arm_status arm_conv_partial_fast_q31( - q31_t * pSrcA, - uint32_t srcALen, - q31_t * pSrcB, - uint32_t srcBLen, - q31_t * pDst, - uint32_t firstIndex, - uint32_t numPoints); - - - /** - * @brief Partial convolution of Q7 sequences - * @param[in] *pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] *pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] *pDst points to the block of output data - * @param[in] firstIndex is the first output sample to start with. - * @param[in] numPoints is the number of output points to be computed. - * @param[in] *pScratch1 points to scratch buffer(of type q15_t) of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. - * @param[in] *pScratch2 points to scratch buffer (of type q15_t) of size min(srcALen, srcBLen). - * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. - */ - - arm_status arm_conv_partial_opt_q7( - q7_t * pSrcA, - uint32_t srcALen, - q7_t * pSrcB, - uint32_t srcBLen, - q7_t * pDst, - uint32_t firstIndex, - uint32_t numPoints, - q15_t * pScratch1, - q15_t * pScratch2); - - -/** - * @brief Partial convolution of Q7 sequences. - * @param[in] *pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] *pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] *pDst points to the block of output data - * @param[in] firstIndex is the first output sample to start with. - * @param[in] numPoints is the number of output points to be computed. - * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. - */ - - arm_status arm_conv_partial_q7( - q7_t * pSrcA, - uint32_t srcALen, - q7_t * pSrcB, - uint32_t srcBLen, - q7_t * pDst, - uint32_t firstIndex, - uint32_t numPoints); - - - - /** - * @brief Instance structure for the Q15 FIR decimator. - */ - - typedef struct - { - uint8_t M; /**< decimation factor. */ - uint16_t numTaps; /**< number of coefficients in the filter. */ - q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ - q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ - } arm_fir_decimate_instance_q15; - - /** - * @brief Instance structure for the Q31 FIR decimator. - */ - - typedef struct - { - uint8_t M; /**< decimation factor. */ - uint16_t numTaps; /**< number of coefficients in the filter. */ - q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ - q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ - - } arm_fir_decimate_instance_q31; - - /** - * @brief Instance structure for the floating-point FIR decimator. - */ - - typedef struct - { - uint8_t M; /**< decimation factor. */ - uint16_t numTaps; /**< number of coefficients in the filter. */ - float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ - float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ - - } arm_fir_decimate_instance_f32; - - - - /** - * @brief Processing function for the floating-point FIR decimator. - * @param[in] *S points to an instance of the floating-point FIR decimator structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data - * @param[in] blockSize number of input samples to process per call. - * @return none - */ - - void arm_fir_decimate_f32( - const arm_fir_decimate_instance_f32 * S, - float32_t * pSrc, - float32_t * pDst, - uint32_t blockSize); - - - /** - * @brief Initialization function for the floating-point FIR decimator. - * @param[in,out] *S points to an instance of the floating-point FIR decimator structure. - * @param[in] numTaps number of coefficients in the filter. - * @param[in] M decimation factor. - * @param[in] *pCoeffs points to the filter coefficients. - * @param[in] *pState points to the state buffer. - * @param[in] blockSize number of input samples to process per call. - * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if - * blockSize is not a multiple of M. - */ - - arm_status arm_fir_decimate_init_f32( - arm_fir_decimate_instance_f32 * S, - uint16_t numTaps, - uint8_t M, - float32_t * pCoeffs, - float32_t * pState, - uint32_t blockSize); - - /** - * @brief Processing function for the Q15 FIR decimator. - * @param[in] *S points to an instance of the Q15 FIR decimator structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data - * @param[in] blockSize number of input samples to process per call. - * @return none - */ - - void arm_fir_decimate_q15( - const arm_fir_decimate_instance_q15 * S, - q15_t * pSrc, - q15_t * pDst, - uint32_t blockSize); - - /** - * @brief Processing function for the Q15 FIR decimator (fast variant) for Cortex-M3 and Cortex-M4. - * @param[in] *S points to an instance of the Q15 FIR decimator structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data - * @param[in] blockSize number of input samples to process per call. - * @return none - */ - - void arm_fir_decimate_fast_q15( - const arm_fir_decimate_instance_q15 * S, - q15_t * pSrc, - q15_t * pDst, - uint32_t blockSize); - - - - /** - * @brief Initialization function for the Q15 FIR decimator. - * @param[in,out] *S points to an instance of the Q15 FIR decimator structure. - * @param[in] numTaps number of coefficients in the filter. - * @param[in] M decimation factor. - * @param[in] *pCoeffs points to the filter coefficients. - * @param[in] *pState points to the state buffer. - * @param[in] blockSize number of input samples to process per call. - * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if - * blockSize is not a multiple of M. - */ - - arm_status arm_fir_decimate_init_q15( - arm_fir_decimate_instance_q15 * S, - uint16_t numTaps, - uint8_t M, - q15_t * pCoeffs, - q15_t * pState, - uint32_t blockSize); - - /** - * @brief Processing function for the Q31 FIR decimator. - * @param[in] *S points to an instance of the Q31 FIR decimator structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data - * @param[in] blockSize number of input samples to process per call. - * @return none - */ - - void arm_fir_decimate_q31( - const arm_fir_decimate_instance_q31 * S, - q31_t * pSrc, - q31_t * pDst, - uint32_t blockSize); - - /** - * @brief Processing function for the Q31 FIR decimator (fast variant) for Cortex-M3 and Cortex-M4. - * @param[in] *S points to an instance of the Q31 FIR decimator structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data - * @param[in] blockSize number of input samples to process per call. - * @return none - */ - - void arm_fir_decimate_fast_q31( - arm_fir_decimate_instance_q31 * S, - q31_t * pSrc, - q31_t * pDst, - uint32_t blockSize); - - - /** - * @brief Initialization function for the Q31 FIR decimator. - * @param[in,out] *S points to an instance of the Q31 FIR decimator structure. - * @param[in] numTaps number of coefficients in the filter. - * @param[in] M decimation factor. - * @param[in] *pCoeffs points to the filter coefficients. - * @param[in] *pState points to the state buffer. - * @param[in] blockSize number of input samples to process per call. - * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if - * blockSize is not a multiple of M. - */ - - arm_status arm_fir_decimate_init_q31( - arm_fir_decimate_instance_q31 * S, - uint16_t numTaps, - uint8_t M, - q31_t * pCoeffs, - q31_t * pState, - uint32_t blockSize); - - - - /** - * @brief Instance structure for the Q15 FIR interpolator. - */ - - typedef struct - { - uint8_t L; /**< upsample factor. */ - uint16_t phaseLength; /**< length of each polyphase filter component. */ - q15_t *pCoeffs; /**< points to the coefficient array. The array is of length L*phaseLength. */ - q15_t *pState; /**< points to the state variable array. The array is of length blockSize+phaseLength-1. */ - } arm_fir_interpolate_instance_q15; - - /** - * @brief Instance structure for the Q31 FIR interpolator. - */ - - typedef struct - { - uint8_t L; /**< upsample factor. */ - uint16_t phaseLength; /**< length of each polyphase filter component. */ - q31_t *pCoeffs; /**< points to the coefficient array. The array is of length L*phaseLength. */ - q31_t *pState; /**< points to the state variable array. The array is of length blockSize+phaseLength-1. */ - } arm_fir_interpolate_instance_q31; - - /** - * @brief Instance structure for the floating-point FIR interpolator. - */ - - typedef struct - { - uint8_t L; /**< upsample factor. */ - uint16_t phaseLength; /**< length of each polyphase filter component. */ - float32_t *pCoeffs; /**< points to the coefficient array. The array is of length L*phaseLength. */ - float32_t *pState; /**< points to the state variable array. The array is of length phaseLength+numTaps-1. */ - } arm_fir_interpolate_instance_f32; - - - /** - * @brief Processing function for the Q15 FIR interpolator. - * @param[in] *S points to an instance of the Q15 FIR interpolator structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data. - * @param[in] blockSize number of input samples to process per call. - * @return none. - */ - - void arm_fir_interpolate_q15( - const arm_fir_interpolate_instance_q15 * S, - q15_t * pSrc, - q15_t * pDst, - uint32_t blockSize); - - - /** - * @brief Initialization function for the Q15 FIR interpolator. - * @param[in,out] *S points to an instance of the Q15 FIR interpolator structure. - * @param[in] L upsample factor. - * @param[in] numTaps number of filter coefficients in the filter. - * @param[in] *pCoeffs points to the filter coefficient buffer. - * @param[in] *pState points to the state buffer. - * @param[in] blockSize number of input samples to process per call. - * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if - * the filter length numTaps is not a multiple of the interpolation factor L. - */ - - arm_status arm_fir_interpolate_init_q15( - arm_fir_interpolate_instance_q15 * S, - uint8_t L, - uint16_t numTaps, - q15_t * pCoeffs, - q15_t * pState, - uint32_t blockSize); - - /** - * @brief Processing function for the Q31 FIR interpolator. - * @param[in] *S points to an instance of the Q15 FIR interpolator structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data. - * @param[in] blockSize number of input samples to process per call. - * @return none. - */ - - void arm_fir_interpolate_q31( - const arm_fir_interpolate_instance_q31 * S, - q31_t * pSrc, - q31_t * pDst, - uint32_t blockSize); - - /** - * @brief Initialization function for the Q31 FIR interpolator. - * @param[in,out] *S points to an instance of the Q31 FIR interpolator structure. - * @param[in] L upsample factor. - * @param[in] numTaps number of filter coefficients in the filter. - * @param[in] *pCoeffs points to the filter coefficient buffer. - * @param[in] *pState points to the state buffer. - * @param[in] blockSize number of input samples to process per call. - * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if - * the filter length numTaps is not a multiple of the interpolation factor L. - */ - - arm_status arm_fir_interpolate_init_q31( - arm_fir_interpolate_instance_q31 * S, - uint8_t L, - uint16_t numTaps, - q31_t * pCoeffs, - q31_t * pState, - uint32_t blockSize); - - - /** - * @brief Processing function for the floating-point FIR interpolator. - * @param[in] *S points to an instance of the floating-point FIR interpolator structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data. - * @param[in] blockSize number of input samples to process per call. - * @return none. - */ - - void arm_fir_interpolate_f32( - const arm_fir_interpolate_instance_f32 * S, - float32_t * pSrc, - float32_t * pDst, - uint32_t blockSize); - - /** - * @brief Initialization function for the floating-point FIR interpolator. - * @param[in,out] *S points to an instance of the floating-point FIR interpolator structure. - * @param[in] L upsample factor. - * @param[in] numTaps number of filter coefficients in the filter. - * @param[in] *pCoeffs points to the filter coefficient buffer. - * @param[in] *pState points to the state buffer. - * @param[in] blockSize number of input samples to process per call. - * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if - * the filter length numTaps is not a multiple of the interpolation factor L. - */ - - arm_status arm_fir_interpolate_init_f32( - arm_fir_interpolate_instance_f32 * S, - uint8_t L, - uint16_t numTaps, - float32_t * pCoeffs, - float32_t * pState, - uint32_t blockSize); - - /** - * @brief Instance structure for the high precision Q31 Biquad cascade filter. - */ - - typedef struct - { - uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ - q63_t *pState; /**< points to the array of state coefficients. The array is of length 4*numStages. */ - q31_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */ - uint8_t postShift; /**< additional shift, in bits, applied to each output sample. */ - - } arm_biquad_cas_df1_32x64_ins_q31; - - - /** - * @param[in] *S points to an instance of the high precision Q31 Biquad cascade filter structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data - * @param[in] blockSize number of samples to process. - * @return none. - */ - - void arm_biquad_cas_df1_32x64_q31( - const arm_biquad_cas_df1_32x64_ins_q31 * S, - q31_t * pSrc, - q31_t * pDst, - uint32_t blockSize); - - - /** - * @param[in,out] *S points to an instance of the high precision Q31 Biquad cascade filter structure. - * @param[in] numStages number of 2nd order stages in the filter. - * @param[in] *pCoeffs points to the filter coefficients. - * @param[in] *pState points to the state buffer. - * @param[in] postShift shift to be applied to the output. Varies according to the coefficients format - * @return none - */ - - void arm_biquad_cas_df1_32x64_init_q31( - arm_biquad_cas_df1_32x64_ins_q31 * S, - uint8_t numStages, - q31_t * pCoeffs, - q63_t * pState, - uint8_t postShift); - - - - /** - * @brief Instance structure for the floating-point transposed direct form II Biquad cascade filter. - */ - - typedef struct - { - uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ - float32_t *pState; /**< points to the array of state coefficients. The array is of length 2*numStages. */ - float32_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */ - } arm_biquad_cascade_df2T_instance_f32; - - - - /** - * @brief 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 4*numStages. */ - float32_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */ - } arm_biquad_cascade_stereo_df2T_instance_f32; - - - - /** - * @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. */ - float64_t *pState; /**< points to the array of state coefficients. The array is of length 2*numStages. */ - float64_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */ - } arm_biquad_cascade_df2T_instance_f64; - - - /** - * @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 Processing function for the floating-point transposed direct form II Biquad cascade filter. 2 channels - * @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_stereo_df2T_f32( - const arm_biquad_cascade_stereo_df2T_instance_f32 * S, - float32_t * pSrc, - float32_t * pDst, - uint32_t blockSize); - - /** - * @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_f64( - const arm_biquad_cascade_df2T_instance_f64 * S, - float64_t * pSrc, - float64_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 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_stereo_df2T_init_f32( - arm_biquad_cascade_stereo_df2T_instance_f32 * S, - uint8_t numStages, - float32_t * pCoeffs, - float32_t * pState); - - - /** - * @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_f64( - arm_biquad_cascade_df2T_instance_f64 * S, - uint8_t numStages, - float64_t * pCoeffs, - float64_t * pState); - - - - /** - * @brief Instance structure for the Q15 FIR lattice filter. - */ - - typedef struct - { - uint16_t numStages; /**< number of filter stages. */ - q15_t *pState; /**< points to the state variable array. The array is of length numStages. */ - q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numStages. */ - } arm_fir_lattice_instance_q15; - - /** - * @brief Instance structure for the Q31 FIR lattice filter. - */ - - typedef struct - { - uint16_t numStages; /**< number of filter stages. */ - q31_t *pState; /**< points to the state variable array. The array is of length numStages. */ - q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numStages. */ - } arm_fir_lattice_instance_q31; - - /** - * @brief Instance structure for the floating-point FIR lattice filter. - */ - - typedef struct - { - uint16_t numStages; /**< number of filter stages. */ - float32_t *pState; /**< points to the state variable array. The array is of length numStages. */ - float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numStages. */ - } arm_fir_lattice_instance_f32; - - /** - * @brief Initialization function for the Q15 FIR lattice filter. - * @param[in] *S points to an instance of the Q15 FIR lattice structure. - * @param[in] numStages number of filter stages. - * @param[in] *pCoeffs points to the coefficient buffer. The array is of length numStages. - * @param[in] *pState points to the state buffer. The array is of length numStages. - * @return none. - */ - - void arm_fir_lattice_init_q15( - arm_fir_lattice_instance_q15 * S, - uint16_t numStages, - q15_t * pCoeffs, - q15_t * pState); - - - /** - * @brief Processing function for the Q15 FIR lattice filter. - * @param[in] *S points to an instance of the Q15 FIR lattice structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data. - * @param[in] blockSize number of samples to process. - * @return none. - */ - void arm_fir_lattice_q15( - const arm_fir_lattice_instance_q15 * S, - q15_t * pSrc, - q15_t * pDst, - uint32_t blockSize); - - /** - * @brief Initialization function for the Q31 FIR lattice filter. - * @param[in] *S points to an instance of the Q31 FIR lattice structure. - * @param[in] numStages number of filter stages. - * @param[in] *pCoeffs points to the coefficient buffer. The array is of length numStages. - * @param[in] *pState points to the state buffer. The array is of length numStages. - * @return none. - */ - - void arm_fir_lattice_init_q31( - arm_fir_lattice_instance_q31 * S, - uint16_t numStages, - q31_t * pCoeffs, - q31_t * pState); - - - /** - * @brief Processing function for the Q31 FIR lattice filter. - * @param[in] *S points to an instance of the Q31 FIR lattice structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data - * @param[in] blockSize number of samples to process. - * @return none. - */ - - void arm_fir_lattice_q31( - const arm_fir_lattice_instance_q31 * S, - q31_t * pSrc, - q31_t * pDst, - uint32_t blockSize); - -/** - * @brief Initialization function for the floating-point FIR lattice filter. - * @param[in] *S points to an instance of the floating-point FIR lattice structure. - * @param[in] numStages number of filter stages. - * @param[in] *pCoeffs points to the coefficient buffer. The array is of length numStages. - * @param[in] *pState points to the state buffer. The array is of length numStages. - * @return none. - */ - - void arm_fir_lattice_init_f32( - arm_fir_lattice_instance_f32 * S, - uint16_t numStages, - float32_t * pCoeffs, - float32_t * pState); - - /** - * @brief Processing function for the floating-point FIR lattice filter. - * @param[in] *S points to an instance of the floating-point FIR lattice structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data - * @param[in] blockSize number of samples to process. - * @return none. - */ - - void arm_fir_lattice_f32( - const arm_fir_lattice_instance_f32 * S, - float32_t * pSrc, - float32_t * pDst, - uint32_t blockSize); - - /** - * @brief Instance structure for the Q15 IIR lattice filter. - */ - typedef struct - { - uint16_t numStages; /**< number of stages in the filter. */ - q15_t *pState; /**< points to the state variable array. The array is of length numStages+blockSize. */ - q15_t *pkCoeffs; /**< points to the reflection coefficient array. The array is of length numStages. */ - q15_t *pvCoeffs; /**< points to the ladder coefficient array. The array is of length numStages+1. */ - } arm_iir_lattice_instance_q15; - - /** - * @brief Instance structure for the Q31 IIR lattice filter. - */ - typedef struct - { - uint16_t numStages; /**< number of stages in the filter. */ - q31_t *pState; /**< points to the state variable array. The array is of length numStages+blockSize. */ - q31_t *pkCoeffs; /**< points to the reflection coefficient array. The array is of length numStages. */ - q31_t *pvCoeffs; /**< points to the ladder coefficient array. The array is of length numStages+1. */ - } arm_iir_lattice_instance_q31; - - /** - * @brief Instance structure for the floating-point IIR lattice filter. - */ - typedef struct - { - uint16_t numStages; /**< number of stages in the filter. */ - float32_t *pState; /**< points to the state variable array. The array is of length numStages+blockSize. */ - float32_t *pkCoeffs; /**< points to the reflection coefficient array. The array is of length numStages. */ - float32_t *pvCoeffs; /**< points to the ladder coefficient array. The array is of length numStages+1. */ - } arm_iir_lattice_instance_f32; - - /** - * @brief Processing function for the floating-point IIR lattice filter. - * @param[in] *S points to an instance of the floating-point IIR lattice structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data. - * @param[in] blockSize number of samples to process. - * @return none. - */ - - void arm_iir_lattice_f32( - const arm_iir_lattice_instance_f32 * S, - float32_t * pSrc, - float32_t * pDst, - uint32_t blockSize); - - /** - * @brief Initialization function for the floating-point IIR lattice filter. - * @param[in] *S points to an instance of the floating-point IIR lattice structure. - * @param[in] numStages number of stages in the filter. - * @param[in] *pkCoeffs points to the reflection coefficient buffer. The array is of length numStages. - * @param[in] *pvCoeffs points to the ladder coefficient buffer. The array is of length numStages+1. - * @param[in] *pState points to the state buffer. The array is of length numStages+blockSize-1. - * @param[in] blockSize number of samples to process. - * @return none. - */ - - void arm_iir_lattice_init_f32( - arm_iir_lattice_instance_f32 * S, - uint16_t numStages, - float32_t * pkCoeffs, - float32_t * pvCoeffs, - float32_t * pState, - uint32_t blockSize); - - - /** - * @brief Processing function for the Q31 IIR lattice filter. - * @param[in] *S points to an instance of the Q31 IIR lattice structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data. - * @param[in] blockSize number of samples to process. - * @return none. - */ - - void arm_iir_lattice_q31( - const arm_iir_lattice_instance_q31 * S, - q31_t * pSrc, - q31_t * pDst, - uint32_t blockSize); - - - /** - * @brief Initialization function for the Q31 IIR lattice filter. - * @param[in] *S points to an instance of the Q31 IIR lattice structure. - * @param[in] numStages number of stages in the filter. - * @param[in] *pkCoeffs points to the reflection coefficient buffer. The array is of length numStages. - * @param[in] *pvCoeffs points to the ladder coefficient buffer. The array is of length numStages+1. - * @param[in] *pState points to the state buffer. The array is of length numStages+blockSize. - * @param[in] blockSize number of samples to process. - * @return none. - */ - - void arm_iir_lattice_init_q31( - arm_iir_lattice_instance_q31 * S, - uint16_t numStages, - q31_t * pkCoeffs, - q31_t * pvCoeffs, - q31_t * pState, - uint32_t blockSize); - - - /** - * @brief Processing function for the Q15 IIR lattice filter. - * @param[in] *S points to an instance of the Q15 IIR lattice structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data. - * @param[in] blockSize number of samples to process. - * @return none. - */ - - void arm_iir_lattice_q15( - const arm_iir_lattice_instance_q15 * S, - q15_t * pSrc, - q15_t * pDst, - uint32_t blockSize); - - -/** - * @brief Initialization function for the Q15 IIR lattice filter. - * @param[in] *S points to an instance of the fixed-point Q15 IIR lattice structure. - * @param[in] numStages number of stages in the filter. - * @param[in] *pkCoeffs points to reflection coefficient buffer. The array is of length numStages. - * @param[in] *pvCoeffs points to ladder coefficient buffer. The array is of length numStages+1. - * @param[in] *pState points to state buffer. The array is of length numStages+blockSize. - * @param[in] blockSize number of samples to process per call. - * @return none. - */ - - void arm_iir_lattice_init_q15( - arm_iir_lattice_instance_q15 * S, - uint16_t numStages, - q15_t * pkCoeffs, - q15_t * pvCoeffs, - q15_t * pState, - uint32_t blockSize); - - /** - * @brief Instance structure for the floating-point LMS filter. - */ - - typedef struct - { - uint16_t numTaps; /**< number of coefficients in the filter. */ - float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ - float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ - float32_t mu; /**< step size that controls filter coefficient updates. */ - } arm_lms_instance_f32; - - /** - * @brief Processing function for floating-point LMS filter. - * @param[in] *S points to an instance of the floating-point LMS filter structure. - * @param[in] *pSrc points to the block of input data. - * @param[in] *pRef points to the block of reference data. - * @param[out] *pOut points to the block of output data. - * @param[out] *pErr points to the block of error data. - * @param[in] blockSize number of samples to process. - * @return none. - */ - - void arm_lms_f32( - const arm_lms_instance_f32 * S, - float32_t * pSrc, - float32_t * pRef, - float32_t * pOut, - float32_t * pErr, - uint32_t blockSize); - - /** - * @brief Initialization function for floating-point LMS filter. - * @param[in] *S points to an instance of the floating-point LMS filter structure. - * @param[in] numTaps number of filter coefficients. - * @param[in] *pCoeffs points to the coefficient buffer. - * @param[in] *pState points to state buffer. - * @param[in] mu step size that controls filter coefficient updates. - * @param[in] blockSize number of samples to process. - * @return none. - */ - - void arm_lms_init_f32( - arm_lms_instance_f32 * S, - uint16_t numTaps, - float32_t * pCoeffs, - float32_t * pState, - float32_t mu, - uint32_t blockSize); - - /** - * @brief Instance structure for the Q15 LMS filter. - */ - - typedef struct - { - uint16_t numTaps; /**< number of coefficients in the filter. */ - q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ - q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ - q15_t mu; /**< step size that controls filter coefficient updates. */ - uint32_t postShift; /**< bit shift applied to coefficients. */ - } arm_lms_instance_q15; - - - /** - * @brief Initialization function for the Q15 LMS filter. - * @param[in] *S points to an instance of the Q15 LMS filter structure. - * @param[in] numTaps number of filter coefficients. - * @param[in] *pCoeffs points to the coefficient buffer. - * @param[in] *pState points to the state buffer. - * @param[in] mu step size that controls filter coefficient updates. - * @param[in] blockSize number of samples to process. - * @param[in] postShift bit shift applied to coefficients. - * @return none. - */ - - void arm_lms_init_q15( - arm_lms_instance_q15 * S, - uint16_t numTaps, - q15_t * pCoeffs, - q15_t * pState, - q15_t mu, - uint32_t blockSize, - uint32_t postShift); - - /** - * @brief Processing function for Q15 LMS filter. - * @param[in] *S points to an instance of the Q15 LMS filter structure. - * @param[in] *pSrc points to the block of input data. - * @param[in] *pRef points to the block of reference data. - * @param[out] *pOut points to the block of output data. - * @param[out] *pErr points to the block of error data. - * @param[in] blockSize number of samples to process. - * @return none. - */ - - void arm_lms_q15( - const arm_lms_instance_q15 * S, - q15_t * pSrc, - q15_t * pRef, - q15_t * pOut, - q15_t * pErr, - uint32_t blockSize); - - - /** - * @brief Instance structure for the Q31 LMS filter. - */ - - typedef struct - { - uint16_t numTaps; /**< number of coefficients in the filter. */ - q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ - q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ - q31_t mu; /**< step size that controls filter coefficient updates. */ - uint32_t postShift; /**< bit shift applied to coefficients. */ - - } arm_lms_instance_q31; - - /** - * @brief Processing function for Q31 LMS filter. - * @param[in] *S points to an instance of the Q15 LMS filter structure. - * @param[in] *pSrc points to the block of input data. - * @param[in] *pRef points to the block of reference data. - * @param[out] *pOut points to the block of output data. - * @param[out] *pErr points to the block of error data. - * @param[in] blockSize number of samples to process. - * @return none. - */ - - void arm_lms_q31( - const arm_lms_instance_q31 * S, - q31_t * pSrc, - q31_t * pRef, - q31_t * pOut, - q31_t * pErr, - uint32_t blockSize); - - /** - * @brief Initialization function for Q31 LMS filter. - * @param[in] *S points to an instance of the Q31 LMS filter structure. - * @param[in] numTaps number of filter coefficients. - * @param[in] *pCoeffs points to coefficient buffer. - * @param[in] *pState points to state buffer. - * @param[in] mu step size that controls filter coefficient updates. - * @param[in] blockSize number of samples to process. - * @param[in] postShift bit shift applied to coefficients. - * @return none. - */ - - void arm_lms_init_q31( - arm_lms_instance_q31 * S, - uint16_t numTaps, - q31_t * pCoeffs, - q31_t * pState, - q31_t mu, - uint32_t blockSize, - uint32_t postShift); - - /** - * @brief Instance structure for the floating-point normalized LMS filter. - */ - - typedef struct - { - uint16_t numTaps; /**< number of coefficients in the filter. */ - float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ - float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ - float32_t mu; /**< step size that control filter coefficient updates. */ - float32_t energy; /**< saves previous frame energy. */ - float32_t x0; /**< saves previous input sample. */ - } arm_lms_norm_instance_f32; - - /** - * @brief Processing function for floating-point normalized LMS filter. - * @param[in] *S points to an instance of the floating-point normalized LMS filter structure. - * @param[in] *pSrc points to the block of input data. - * @param[in] *pRef points to the block of reference data. - * @param[out] *pOut points to the block of output data. - * @param[out] *pErr points to the block of error data. - * @param[in] blockSize number of samples to process. - * @return none. - */ - - void arm_lms_norm_f32( - arm_lms_norm_instance_f32 * S, - float32_t * pSrc, - float32_t * pRef, - float32_t * pOut, - float32_t * pErr, - uint32_t blockSize); - - /** - * @brief Initialization function for floating-point normalized LMS filter. - * @param[in] *S points to an instance of the floating-point LMS filter structure. - * @param[in] numTaps number of filter coefficients. - * @param[in] *pCoeffs points to coefficient buffer. - * @param[in] *pState points to state buffer. - * @param[in] mu step size that controls filter coefficient updates. - * @param[in] blockSize number of samples to process. - * @return none. - */ - - void arm_lms_norm_init_f32( - arm_lms_norm_instance_f32 * S, - uint16_t numTaps, - float32_t * pCoeffs, - float32_t * pState, - float32_t mu, - uint32_t blockSize); - - - /** - * @brief Instance structure for the Q31 normalized LMS filter. - */ - typedef struct - { - uint16_t numTaps; /**< number of coefficients in the filter. */ - q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ - q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ - q31_t mu; /**< step size that controls filter coefficient updates. */ - uint8_t postShift; /**< bit shift applied to coefficients. */ - q31_t *recipTable; /**< points to the reciprocal initial value table. */ - q31_t energy; /**< saves previous frame energy. */ - q31_t x0; /**< saves previous input sample. */ - } arm_lms_norm_instance_q31; - - /** - * @brief Processing function for Q31 normalized LMS filter. - * @param[in] *S points to an instance of the Q31 normalized LMS filter structure. - * @param[in] *pSrc points to the block of input data. - * @param[in] *pRef points to the block of reference data. - * @param[out] *pOut points to the block of output data. - * @param[out] *pErr points to the block of error data. - * @param[in] blockSize number of samples to process. - * @return none. - */ - - void arm_lms_norm_q31( - arm_lms_norm_instance_q31 * S, - q31_t * pSrc, - q31_t * pRef, - q31_t * pOut, - q31_t * pErr, - uint32_t blockSize); - - /** - * @brief Initialization function for Q31 normalized LMS filter. - * @param[in] *S points to an instance of the Q31 normalized LMS filter structure. - * @param[in] numTaps number of filter coefficients. - * @param[in] *pCoeffs points to coefficient buffer. - * @param[in] *pState points to state buffer. - * @param[in] mu step size that controls filter coefficient updates. - * @param[in] blockSize number of samples to process. - * @param[in] postShift bit shift applied to coefficients. - * @return none. - */ - - void arm_lms_norm_init_q31( - arm_lms_norm_instance_q31 * S, - uint16_t numTaps, - q31_t * pCoeffs, - q31_t * pState, - q31_t mu, - uint32_t blockSize, - uint8_t postShift); - - /** - * @brief Instance structure for the Q15 normalized LMS filter. - */ - - typedef struct - { - uint16_t numTaps; /**< Number of coefficients in the filter. */ - q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ - q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ - q15_t mu; /**< step size that controls filter coefficient updates. */ - uint8_t postShift; /**< bit shift applied to coefficients. */ - q15_t *recipTable; /**< Points to the reciprocal initial value table. */ - q15_t energy; /**< saves previous frame energy. */ - q15_t x0; /**< saves previous input sample. */ - } arm_lms_norm_instance_q15; - - /** - * @brief Processing function for Q15 normalized LMS filter. - * @param[in] *S points to an instance of the Q15 normalized LMS filter structure. - * @param[in] *pSrc points to the block of input data. - * @param[in] *pRef points to the block of reference data. - * @param[out] *pOut points to the block of output data. - * @param[out] *pErr points to the block of error data. - * @param[in] blockSize number of samples to process. - * @return none. - */ - - void arm_lms_norm_q15( - arm_lms_norm_instance_q15 * S, - q15_t * pSrc, - q15_t * pRef, - q15_t * pOut, - q15_t * pErr, - uint32_t blockSize); - - - /** - * @brief Initialization function for Q15 normalized LMS filter. - * @param[in] *S points to an instance of the Q15 normalized LMS filter structure. - * @param[in] numTaps number of filter coefficients. - * @param[in] *pCoeffs points to coefficient buffer. - * @param[in] *pState points to state buffer. - * @param[in] mu step size that controls filter coefficient updates. - * @param[in] blockSize number of samples to process. - * @param[in] postShift bit shift applied to coefficients. - * @return none. - */ - - void arm_lms_norm_init_q15( - arm_lms_norm_instance_q15 * S, - uint16_t numTaps, - q15_t * pCoeffs, - q15_t * pState, - q15_t mu, - uint32_t blockSize, - uint8_t postShift); - - /** - * @brief Correlation of floating-point sequences. - * @param[in] *pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] *pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] *pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. - * @return none. - */ - - void arm_correlate_f32( - float32_t * pSrcA, - uint32_t srcALen, - float32_t * pSrcB, - uint32_t srcBLen, - float32_t * pDst); - - - /** - * @brief Correlation of Q15 sequences - * @param[in] *pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] *pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] *pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. - * @param[in] *pScratch points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. - * @return none. - */ - void arm_correlate_opt_q15( - q15_t * pSrcA, - uint32_t srcALen, - q15_t * pSrcB, - uint32_t srcBLen, - q15_t * pDst, - q15_t * pScratch); - - - /** - * @brief Correlation of Q15 sequences. - * @param[in] *pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] *pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] *pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. - * @return none. - */ - - void arm_correlate_q15( - q15_t * pSrcA, - uint32_t srcALen, - q15_t * pSrcB, - uint32_t srcBLen, - q15_t * pDst); - - /** - * @brief Correlation of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4. - * @param[in] *pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] *pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] *pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. - * @return none. - */ - - void arm_correlate_fast_q15( - q15_t * pSrcA, - uint32_t srcALen, - q15_t * pSrcB, - uint32_t srcBLen, - q15_t * pDst); - - - - /** - * @brief Correlation of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4. - * @param[in] *pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] *pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] *pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. - * @param[in] *pScratch points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. - * @return none. - */ - - void arm_correlate_fast_opt_q15( - q15_t * pSrcA, - uint32_t srcALen, - q15_t * pSrcB, - uint32_t srcBLen, - q15_t * pDst, - q15_t * pScratch); - - /** - * @brief Correlation of Q31 sequences. - * @param[in] *pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] *pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] *pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. - * @return none. - */ - - void arm_correlate_q31( - q31_t * pSrcA, - uint32_t srcALen, - q31_t * pSrcB, - uint32_t srcBLen, - q31_t * pDst); - - /** - * @brief Correlation of Q31 sequences (fast version) for Cortex-M3 and Cortex-M4 - * @param[in] *pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] *pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] *pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. - * @return none. - */ - - void arm_correlate_fast_q31( - q31_t * pSrcA, - uint32_t srcALen, - q31_t * pSrcB, - uint32_t srcBLen, - q31_t * pDst); - - - - /** - * @brief Correlation of Q7 sequences. - * @param[in] *pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] *pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] *pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. - * @param[in] *pScratch1 points to scratch buffer(of type q15_t) of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. - * @param[in] *pScratch2 points to scratch buffer (of type q15_t) of size min(srcALen, srcBLen). - * @return none. - */ - - void arm_correlate_opt_q7( - q7_t * pSrcA, - uint32_t srcALen, - q7_t * pSrcB, - uint32_t srcBLen, - q7_t * pDst, - q15_t * pScratch1, - q15_t * pScratch2); - - - /** - * @brief Correlation of Q7 sequences. - * @param[in] *pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] *pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] *pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. - * @return none. - */ - - void arm_correlate_q7( - q7_t * pSrcA, - uint32_t srcALen, - q7_t * pSrcB, - uint32_t srcBLen, - q7_t * pDst); - - - /** - * @brief Instance structure for the floating-point sparse FIR filter. - */ - typedef struct - { - uint16_t numTaps; /**< number of coefficients in the filter. */ - uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ - float32_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ - float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ - uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ - int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ - } arm_fir_sparse_instance_f32; - - /** - * @brief Instance structure for the Q31 sparse FIR filter. - */ - - typedef struct - { - uint16_t numTaps; /**< number of coefficients in the filter. */ - uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ - q31_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ - q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ - uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ - int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ - } arm_fir_sparse_instance_q31; - - /** - * @brief Instance structure for the Q15 sparse FIR filter. - */ - - typedef struct - { - uint16_t numTaps; /**< number of coefficients in the filter. */ - uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ - q15_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ - q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ - uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ - int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ - } arm_fir_sparse_instance_q15; - - /** - * @brief Instance structure for the Q7 sparse FIR filter. - */ - - typedef struct - { - uint16_t numTaps; /**< number of coefficients in the filter. */ - uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ - q7_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ - q7_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ - uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ - int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ - } arm_fir_sparse_instance_q7; - - /** - * @brief Processing function for the floating-point sparse FIR filter. - * @param[in] *S points to an instance of the floating-point sparse FIR structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data - * @param[in] *pScratchIn points to a temporary buffer of size blockSize. - * @param[in] blockSize number of input samples to process per call. - * @return none. - */ - - void arm_fir_sparse_f32( - arm_fir_sparse_instance_f32 * S, - float32_t * pSrc, - float32_t * pDst, - float32_t * pScratchIn, - uint32_t blockSize); - - /** - * @brief Initialization function for the floating-point sparse FIR filter. - * @param[in,out] *S points to an instance of the floating-point sparse FIR structure. - * @param[in] numTaps number of nonzero coefficients in the filter. - * @param[in] *pCoeffs points to the array of filter coefficients. - * @param[in] *pState points to the state buffer. - * @param[in] *pTapDelay points to the array of offset times. - * @param[in] maxDelay maximum offset time supported. - * @param[in] blockSize number of samples that will be processed per block. - * @return none - */ - - void arm_fir_sparse_init_f32( - arm_fir_sparse_instance_f32 * S, - uint16_t numTaps, - float32_t * pCoeffs, - float32_t * pState, - int32_t * pTapDelay, - uint16_t maxDelay, - uint32_t blockSize); - - /** - * @brief Processing function for the Q31 sparse FIR filter. - * @param[in] *S points to an instance of the Q31 sparse FIR structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data - * @param[in] *pScratchIn points to a temporary buffer of size blockSize. - * @param[in] blockSize number of input samples to process per call. - * @return none. - */ - - void arm_fir_sparse_q31( - arm_fir_sparse_instance_q31 * S, - q31_t * pSrc, - q31_t * pDst, - q31_t * pScratchIn, - uint32_t blockSize); - - /** - * @brief Initialization function for the Q31 sparse FIR filter. - * @param[in,out] *S points to an instance of the Q31 sparse FIR structure. - * @param[in] numTaps number of nonzero coefficients in the filter. - * @param[in] *pCoeffs points to the array of filter coefficients. - * @param[in] *pState points to the state buffer. - * @param[in] *pTapDelay points to the array of offset times. - * @param[in] maxDelay maximum offset time supported. - * @param[in] blockSize number of samples that will be processed per block. - * @return none - */ - - void arm_fir_sparse_init_q31( - arm_fir_sparse_instance_q31 * S, - uint16_t numTaps, - q31_t * pCoeffs, - q31_t * pState, - int32_t * pTapDelay, - uint16_t maxDelay, - uint32_t blockSize); - - /** - * @brief Processing function for the Q15 sparse FIR filter. - * @param[in] *S points to an instance of the Q15 sparse FIR structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data - * @param[in] *pScratchIn points to a temporary buffer of size blockSize. - * @param[in] *pScratchOut points to a temporary buffer of size blockSize. - * @param[in] blockSize number of input samples to process per call. - * @return none. - */ - - void arm_fir_sparse_q15( - arm_fir_sparse_instance_q15 * S, - q15_t * pSrc, - q15_t * pDst, - q15_t * pScratchIn, - q31_t * pScratchOut, - uint32_t blockSize); - - - /** - * @brief Initialization function for the Q15 sparse FIR filter. - * @param[in,out] *S points to an instance of the Q15 sparse FIR structure. - * @param[in] numTaps number of nonzero coefficients in the filter. - * @param[in] *pCoeffs points to the array of filter coefficients. - * @param[in] *pState points to the state buffer. - * @param[in] *pTapDelay points to the array of offset times. - * @param[in] maxDelay maximum offset time supported. - * @param[in] blockSize number of samples that will be processed per block. - * @return none - */ - - void arm_fir_sparse_init_q15( - arm_fir_sparse_instance_q15 * S, - uint16_t numTaps, - q15_t * pCoeffs, - q15_t * pState, - int32_t * pTapDelay, - uint16_t maxDelay, - uint32_t blockSize); - - /** - * @brief Processing function for the Q7 sparse FIR filter. - * @param[in] *S points to an instance of the Q7 sparse FIR structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data - * @param[in] *pScratchIn points to a temporary buffer of size blockSize. - * @param[in] *pScratchOut points to a temporary buffer of size blockSize. - * @param[in] blockSize number of input samples to process per call. - * @return none. - */ - - void arm_fir_sparse_q7( - arm_fir_sparse_instance_q7 * S, - q7_t * pSrc, - q7_t * pDst, - q7_t * pScratchIn, - q31_t * pScratchOut, - uint32_t blockSize); - - /** - * @brief Initialization function for the Q7 sparse FIR filter. - * @param[in,out] *S points to an instance of the Q7 sparse FIR structure. - * @param[in] numTaps number of nonzero coefficients in the filter. - * @param[in] *pCoeffs points to the array of filter coefficients. - * @param[in] *pState points to the state buffer. - * @param[in] *pTapDelay points to the array of offset times. - * @param[in] maxDelay maximum offset time supported. - * @param[in] blockSize number of samples that will be processed per block. - * @return none - */ - - void arm_fir_sparse_init_q7( - arm_fir_sparse_instance_q7 * S, - uint16_t numTaps, - q7_t * pCoeffs, - q7_t * pState, - int32_t * pTapDelay, - uint16_t maxDelay, - uint32_t blockSize); - - - /* - * @brief Floating-point sin_cos function. - * @param[in] theta input value in degrees - * @param[out] *pSinVal points to the processed sine output. - * @param[out] *pCosVal points to the processed cos output. - * @return none. - */ - - void arm_sin_cos_f32( - float32_t theta, - float32_t * pSinVal, - float32_t * pCcosVal); - - /* - * @brief Q31 sin_cos function. - * @param[in] theta scaled input value in degrees - * @param[out] *pSinVal points to the processed sine output. - * @param[out] *pCosVal points to the processed cosine output. - * @return none. - */ - - void arm_sin_cos_q31( - q31_t theta, - q31_t * pSinVal, - q31_t * pCosVal); - - - /** - * @brief Floating-point complex conjugate. - * @param[in] *pSrc points to the input vector - * @param[out] *pDst points to the output vector - * @param[in] numSamples number of complex samples in each vector - * @return none. - */ - - void arm_cmplx_conj_f32( - float32_t * pSrc, - float32_t * pDst, - uint32_t numSamples); - - /** - * @brief Q31 complex conjugate. - * @param[in] *pSrc points to the input vector - * @param[out] *pDst points to the output vector - * @param[in] numSamples number of complex samples in each vector - * @return none. - */ - - void arm_cmplx_conj_q31( - q31_t * pSrc, - q31_t * pDst, - uint32_t numSamples); - - /** - * @brief Q15 complex conjugate. - * @param[in] *pSrc points to the input vector - * @param[out] *pDst points to the output vector - * @param[in] numSamples number of complex samples in each vector - * @return none. - */ - - void arm_cmplx_conj_q15( - q15_t * pSrc, - q15_t * pDst, - uint32_t numSamples); - - - - /** - * @brief Floating-point complex magnitude squared - * @param[in] *pSrc points to the complex input vector - * @param[out] *pDst points to the real output vector - * @param[in] numSamples number of complex samples in the input vector - * @return none. - */ - - void arm_cmplx_mag_squared_f32( - float32_t * pSrc, - float32_t * pDst, - uint32_t numSamples); - - /** - * @brief Q31 complex magnitude squared - * @param[in] *pSrc points to the complex input vector - * @param[out] *pDst points to the real output vector - * @param[in] numSamples number of complex samples in the input vector - * @return none. - */ - - void arm_cmplx_mag_squared_q31( - q31_t * pSrc, - q31_t * pDst, - uint32_t numSamples); - - /** - * @brief Q15 complex magnitude squared - * @param[in] *pSrc points to the complex input vector - * @param[out] *pDst points to the real output vector - * @param[in] numSamples number of complex samples in the input vector - * @return none. - */ - - void arm_cmplx_mag_squared_q15( - q15_t * pSrc, - q15_t * pDst, - uint32_t numSamples); - - - /** - * @ingroup groupController - */ - - /** - * @defgroup PID PID Motor Control - * - * A Proportional Integral Derivative (PID) controller is a generic feedback control - * loop mechanism widely used in industrial control systems. - * A PID controller is the most commonly used type of feedback controller. - * - * This set of functions implements (PID) controllers - * for Q15, Q31, and floating-point data types. The functions operate on a single sample - * of data and each call to the function returns a single processed value. - * S points to an instance of the PID control data structure. in - * is the input sample value. The functions return the output value. - * - * \par Algorithm: - *
-   *    y[n] = y[n-1] + A0 * x[n] + A1 * x[n-1] + A2 * x[n-2]
-   *    A0 = Kp + Ki + Kd
-   *    A1 = (-Kp ) - (2 * Kd )
-   *    A2 = Kd  
- * - * \par - * where \c Kp is proportional constant, \c Ki is Integral constant and \c Kd is Derivative constant - * - * \par - * \image html PID.gif "Proportional Integral Derivative Controller" - * - * \par - * The PID controller calculates an "error" value as the difference between - * the measured output and the reference input. - * The controller attempts to minimize the error by adjusting the process control inputs. - * The proportional value determines the reaction to the current error, - * the integral value determines the reaction based on the sum of recent errors, - * and the derivative value determines the reaction based on the rate at which the error has been changing. - * - * \par Instance Structure - * The Gains A0, A1, A2 and state variables for a PID controller are stored together in an instance data structure. - * A separate instance structure must be defined for each PID Controller. - * There are separate instance structure declarations for each of the 3 supported data types. - * - * \par Reset Functions - * There is also an associated reset function for each data type which clears the state array. - * - * \par Initialization Functions - * There is also an associated initialization function for each data type. - * The initialization function performs the following operations: - * - Initializes the Gains A0, A1, A2 from Kp,Ki, Kd gains. - * - Zeros out the values in the state buffer. - * - * \par - * Instance structure cannot be placed into a const data section and it is recommended to use the initialization function. - * - * \par Fixed-Point Behavior - * Care must be taken when using the fixed-point versions of the PID Controller functions. - * In particular, the overflow and saturation behavior of the accumulator used in each function must be considered. - * Refer to the function specific documentation below for usage guidelines. - */ - - /** - * @addtogroup PID - * @{ - */ - - /** - * @brief Process function for the floating-point PID Control. - * @param[in,out] *S is an instance of the floating-point PID Control structure - * @param[in] in input sample to process - * @return out processed output sample. - */ - - - static __INLINE float32_t arm_pid_f32( - arm_pid_instance_f32 * S, - float32_t in) - { - float32_t out; - - /* y[n] = y[n-1] + A0 * x[n] + A1 * x[n-1] + A2 * x[n-2] */ - out = (S->A0 * in) + - (S->A1 * S->state[0]) + (S->A2 * S->state[1]) + (S->state[2]); - - /* Update state */ - S->state[1] = S->state[0]; - S->state[0] = in; - S->state[2] = out; - - /* return to application */ - return (out); - - } - - /** - * @brief Process function for the Q31 PID Control. - * @param[in,out] *S points to an instance of the Q31 PID Control structure - * @param[in] in input sample to process - * @return out processed output sample. - * - * Scaling and Overflow Behavior: - * \par - * The function is implemented using an internal 64-bit accumulator. - * The accumulator has a 2.62 format and maintains full precision of the intermediate multiplication results but provides only a single guard bit. - * Thus, if the accumulator result overflows it wraps around rather than clip. - * In order to avoid overflows completely the input signal must be scaled down by 2 bits as there are four additions. - * After all multiply-accumulates are performed, the 2.62 accumulator is truncated to 1.32 format and then saturated to 1.31 format. - */ - - static __INLINE q31_t arm_pid_q31( - arm_pid_instance_q31 * S, - q31_t in) - { - q63_t acc; - q31_t out; - - /* acc = A0 * x[n] */ - acc = (q63_t) S->A0 * in; - - /* acc += A1 * x[n-1] */ - acc += (q63_t) S->A1 * S->state[0]; - - /* acc += A2 * x[n-2] */ - acc += (q63_t) S->A2 * S->state[1]; - - /* convert output to 1.31 format to add y[n-1] */ - out = (q31_t) (acc >> 31u); - - /* out += y[n-1] */ - out += S->state[2]; - - /* Update state */ - S->state[1] = S->state[0]; - S->state[0] = in; - S->state[2] = out; - - /* return to application */ - return (out); - - } - - /** - * @brief Process function for the Q15 PID Control. - * @param[in,out] *S points to an instance of the Q15 PID Control structure - * @param[in] in input sample to process - * @return out processed output sample. - * - * Scaling and Overflow Behavior: - * \par - * The function is implemented using a 64-bit internal accumulator. - * Both Gains and state variables are represented in 1.15 format and multiplications yield a 2.30 result. - * The 2.30 intermediate results are accumulated in a 64-bit accumulator in 34.30 format. - * There is no risk of internal overflow with this approach and the full precision of intermediate multiplications is preserved. - * After all additions have been performed, the accumulator is truncated to 34.15 format by discarding low 15 bits. - * Lastly, the accumulator is saturated to yield a result in 1.15 format. - */ - - static __INLINE q15_t arm_pid_q15( - arm_pid_instance_q15 * S, - q15_t in) - { - q63_t acc; - q15_t out; - -#ifndef ARM_MATH_CM0_FAMILY - __SIMD32_TYPE *vstate; - - /* Implementation of PID controller */ - - /* acc = A0 * x[n] */ - acc = (q31_t) __SMUAD(S->A0, in); - - /* acc += A1 * x[n-1] + A2 * x[n-2] */ - vstate = __SIMD32_CONST(S->state); - acc = __SMLALD(S->A1, (q31_t) *vstate, acc); - -#else - /* acc = A0 * x[n] */ - acc = ((q31_t) S->A0) * in; - - /* acc += A1 * x[n-1] + A2 * x[n-2] */ - acc += (q31_t) S->A1 * S->state[0]; - acc += (q31_t) S->A2 * S->state[1]; - -#endif - - /* acc += y[n-1] */ - acc += (q31_t) S->state[2] << 15; - - /* saturate the output */ - out = (q15_t) (__SSAT((acc >> 15), 16)); - - /* Update state */ - S->state[1] = S->state[0]; - S->state[0] = in; - S->state[2] = out; - - /* return to application */ - return (out); - - } - - /** - * @} end of PID group - */ - - - /** - * @brief Floating-point matrix inverse. - * @param[in] *src points to the instance of the input floating-point matrix structure. - * @param[out] *dst points to the instance of the output floating-point matrix structure. - * @return The function returns ARM_MATH_SIZE_MISMATCH, if the dimensions do not match. - * If the input matrix is singular (does not have an inverse), then the algorithm terminates and returns error status ARM_MATH_SINGULAR. - */ - - arm_status arm_mat_inverse_f32( - const arm_matrix_instance_f32 * src, - arm_matrix_instance_f32 * dst); - - - /** - * @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_f64( - const arm_matrix_instance_f64 * src, - arm_matrix_instance_f64 * dst); - - - - /** - * @ingroup groupController - */ - - - /** - * @defgroup clarke Vector Clarke Transform - * Forward Clarke transform converts the instantaneous stator phases into a two-coordinate time invariant vector. - * Generally the Clarke transform uses three-phase currents Ia, Ib and Ic to calculate currents - * in the two-phase orthogonal stator axis Ialpha and Ibeta. - * When Ialpha is superposed with Ia as shown in the figure below - * \image html clarke.gif Stator current space vector and its components in (a,b). - * and Ia + Ib + Ic = 0, in this condition Ialpha and Ibeta - * can be calculated using only Ia and Ib. - * - * The function operates on a single sample of data and each call to the function returns the processed output. - * The library provides separate functions for Q31 and floating-point data types. - * \par Algorithm - * \image html clarkeFormula.gif - * where Ia and Ib are the instantaneous stator phases and - * pIalpha and pIbeta are the two coordinates of time invariant vector. - * \par Fixed-Point Behavior - * Care must be taken when using the Q31 version of the Clarke transform. - * In particular, the overflow and saturation behavior of the accumulator used must be considered. - * Refer to the function specific documentation below for usage guidelines. - */ - - /** - * @addtogroup clarke - * @{ - */ - - /** - * - * @brief Floating-point Clarke transform - * @param[in] Ia input three-phase coordinate a - * @param[in] Ib input three-phase coordinate b - * @param[out] *pIalpha points to output two-phase orthogonal vector axis alpha - * @param[out] *pIbeta points to output two-phase orthogonal vector axis beta - * @return none. - */ - - static __INLINE void arm_clarke_f32( - float32_t Ia, - float32_t Ib, - float32_t * pIalpha, - float32_t * pIbeta) - { - /* Calculate pIalpha using the equation, pIalpha = Ia */ - *pIalpha = Ia; - - /* Calculate pIbeta using the equation, pIbeta = (1/sqrt(3)) * Ia + (2/sqrt(3)) * Ib */ - *pIbeta = - ((float32_t) 0.57735026919 * Ia + (float32_t) 1.15470053838 * Ib); - - } - - /** - * @brief Clarke transform for Q31 version - * @param[in] Ia input three-phase coordinate a - * @param[in] Ib input three-phase coordinate b - * @param[out] *pIalpha points to output two-phase orthogonal vector axis alpha - * @param[out] *pIbeta points to output two-phase orthogonal vector axis beta - * @return none. - * - * Scaling and Overflow Behavior: - * \par - * The function is implemented using an internal 32-bit accumulator. - * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format. - * There is saturation on the addition, hence there is no risk of overflow. - */ - - static __INLINE void arm_clarke_q31( - q31_t Ia, - q31_t Ib, - q31_t * pIalpha, - q31_t * pIbeta) - { - q31_t product1, product2; /* Temporary variables used to store intermediate results */ - - /* Calculating pIalpha from Ia by equation pIalpha = Ia */ - *pIalpha = Ia; - - /* Intermediate product is calculated by (1/(sqrt(3)) * Ia) */ - product1 = (q31_t) (((q63_t) Ia * 0x24F34E8B) >> 30); - - /* Intermediate product is calculated by (2/sqrt(3) * Ib) */ - product2 = (q31_t) (((q63_t) Ib * 0x49E69D16) >> 30); - - /* pIbeta is calculated by adding the intermediate products */ - *pIbeta = __QADD(product1, product2); - } - - /** - * @} end of clarke group - */ - - /** - * @brief Converts the elements of the Q7 vector to Q31 vector. - * @param[in] *pSrc input pointer - * @param[out] *pDst output pointer - * @param[in] blockSize number of samples to process - * @return none. - */ - void arm_q7_to_q31( - q7_t * pSrc, - q31_t * pDst, - uint32_t blockSize); - - - - - /** - * @ingroup groupController - */ - - /** - * @defgroup inv_clarke Vector Inverse Clarke Transform - * Inverse Clarke transform converts the two-coordinate time invariant vector into instantaneous stator phases. - * - * The function operates on a single sample of data and each call to the function returns the processed output. - * The library provides separate functions for Q31 and floating-point data types. - * \par Algorithm - * \image html clarkeInvFormula.gif - * where pIa and pIb are the instantaneous stator phases and - * Ialpha and Ibeta are the two coordinates of time invariant vector. - * \par Fixed-Point Behavior - * Care must be taken when using the Q31 version of the Clarke transform. - * In particular, the overflow and saturation behavior of the accumulator used must be considered. - * Refer to the function specific documentation below for usage guidelines. - */ - - /** - * @addtogroup inv_clarke - * @{ - */ - - /** - * @brief Floating-point Inverse Clarke transform - * @param[in] Ialpha input two-phase orthogonal vector axis alpha - * @param[in] Ibeta input two-phase orthogonal vector axis beta - * @param[out] *pIa points to output three-phase coordinate a - * @param[out] *pIb points to output three-phase coordinate b - * @return none. - */ - - - static __INLINE void arm_inv_clarke_f32( - float32_t Ialpha, - float32_t Ibeta, - float32_t * pIa, - float32_t * pIb) - { - /* Calculating pIa from Ialpha by equation pIa = Ialpha */ - *pIa = Ialpha; - - /* Calculating pIb from Ialpha and Ibeta by equation pIb = -(1/2) * Ialpha + (sqrt(3)/2) * Ibeta */ - *pIb = -0.5 * Ialpha + (float32_t) 0.8660254039 *Ibeta; - - } - - /** - * @brief Inverse Clarke transform for Q31 version - * @param[in] Ialpha input two-phase orthogonal vector axis alpha - * @param[in] Ibeta input two-phase orthogonal vector axis beta - * @param[out] *pIa points to output three-phase coordinate a - * @param[out] *pIb points to output three-phase coordinate b - * @return none. - * - * Scaling and Overflow Behavior: - * \par - * The function is implemented using an internal 32-bit accumulator. - * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format. - * There is saturation on the subtraction, hence there is no risk of overflow. - */ - - static __INLINE void arm_inv_clarke_q31( - q31_t Ialpha, - q31_t Ibeta, - q31_t * pIa, - q31_t * pIb) - { - q31_t product1, product2; /* Temporary variables used to store intermediate results */ - - /* Calculating pIa from Ialpha by equation pIa = Ialpha */ - *pIa = Ialpha; - - /* Intermediate product is calculated by (1/(2*sqrt(3)) * Ia) */ - product1 = (q31_t) (((q63_t) (Ialpha) * (0x40000000)) >> 31); - - /* Intermediate product is calculated by (1/sqrt(3) * pIb) */ - product2 = (q31_t) (((q63_t) (Ibeta) * (0x6ED9EBA1)) >> 31); - - /* pIb is calculated by subtracting the products */ - *pIb = __QSUB(product2, product1); - - } - - /** - * @} end of inv_clarke group - */ - - /** - * @brief Converts the elements of the Q7 vector to Q15 vector. - * @param[in] *pSrc input pointer - * @param[out] *pDst output pointer - * @param[in] blockSize number of samples to process - * @return none. - */ - void arm_q7_to_q15( - q7_t * pSrc, - q15_t * pDst, - uint32_t blockSize); - - - - /** - * @ingroup groupController - */ - - /** - * @defgroup park Vector Park Transform - * - * Forward Park transform converts the input two-coordinate vector to flux and torque components. - * The Park transform can be used to realize the transformation of the Ialpha and the Ibeta currents - * from the stationary to the moving reference frame and control the spatial relationship between - * the stator vector current and rotor flux vector. - * If we consider the d axis aligned with the rotor flux, the diagram below shows the - * current vector and the relationship from the two reference frames: - * \image html park.gif "Stator current space vector and its component in (a,b) and in the d,q rotating reference frame" - * - * The function operates on a single sample of data and each call to the function returns the processed output. - * The library provides separate functions for Q31 and floating-point data types. - * \par Algorithm - * \image html parkFormula.gif - * where Ialpha and Ibeta are the stator vector components, - * pId and pIq are rotor vector components and cosVal and sinVal are the - * cosine and sine values of theta (rotor flux position). - * \par Fixed-Point Behavior - * Care must be taken when using the Q31 version of the Park transform. - * In particular, the overflow and saturation behavior of the accumulator used must be considered. - * Refer to the function specific documentation below for usage guidelines. - */ - - /** - * @addtogroup park - * @{ - */ - - /** - * @brief Floating-point Park transform - * @param[in] Ialpha input two-phase vector coordinate alpha - * @param[in] Ibeta input two-phase vector coordinate beta - * @param[out] *pId points to output rotor reference frame d - * @param[out] *pIq points to output rotor reference frame q - * @param[in] sinVal sine value of rotation angle theta - * @param[in] cosVal cosine value of rotation angle theta - * @return none. - * - * The function implements the forward Park transform. - * - */ - - static __INLINE void arm_park_f32( - float32_t Ialpha, - float32_t Ibeta, - float32_t * pId, - float32_t * pIq, - float32_t sinVal, - float32_t cosVal) - { - /* Calculate pId using the equation, pId = Ialpha * cosVal + Ibeta * sinVal */ - *pId = Ialpha * cosVal + Ibeta * sinVal; - - /* Calculate pIq using the equation, pIq = - Ialpha * sinVal + Ibeta * cosVal */ - *pIq = -Ialpha * sinVal + Ibeta * cosVal; - - } - - /** - * @brief Park transform for Q31 version - * @param[in] Ialpha input two-phase vector coordinate alpha - * @param[in] Ibeta input two-phase vector coordinate beta - * @param[out] *pId points to output rotor reference frame d - * @param[out] *pIq points to output rotor reference frame q - * @param[in] sinVal sine value of rotation angle theta - * @param[in] cosVal cosine value of rotation angle theta - * @return none. - * - * Scaling and Overflow Behavior: - * \par - * The function is implemented using an internal 32-bit accumulator. - * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format. - * There is saturation on the addition and subtraction, hence there is no risk of overflow. - */ - - - static __INLINE void arm_park_q31( - q31_t Ialpha, - q31_t Ibeta, - q31_t * pId, - q31_t * pIq, - q31_t sinVal, - q31_t cosVal) - { - q31_t product1, product2; /* Temporary variables used to store intermediate results */ - q31_t product3, product4; /* Temporary variables used to store intermediate results */ - - /* Intermediate product is calculated by (Ialpha * cosVal) */ - product1 = (q31_t) (((q63_t) (Ialpha) * (cosVal)) >> 31); - - /* Intermediate product is calculated by (Ibeta * sinVal) */ - product2 = (q31_t) (((q63_t) (Ibeta) * (sinVal)) >> 31); - - - /* Intermediate product is calculated by (Ialpha * sinVal) */ - product3 = (q31_t) (((q63_t) (Ialpha) * (sinVal)) >> 31); - - /* Intermediate product is calculated by (Ibeta * cosVal) */ - product4 = (q31_t) (((q63_t) (Ibeta) * (cosVal)) >> 31); - - /* Calculate pId by adding the two intermediate products 1 and 2 */ - *pId = __QADD(product1, product2); - - /* Calculate pIq by subtracting the two intermediate products 3 from 4 */ - *pIq = __QSUB(product4, product3); - } - - /** - * @} end of park group - */ - - /** - * @brief Converts the elements of the Q7 vector to floating-point vector. - * @param[in] *pSrc is input pointer - * @param[out] *pDst is output pointer - * @param[in] blockSize is the number of samples to process - * @return none. - */ - void arm_q7_to_float( - q7_t * pSrc, - float32_t * pDst, - uint32_t blockSize); - - - /** - * @ingroup groupController - */ - - /** - * @defgroup inv_park Vector Inverse Park transform - * Inverse Park transform converts the input flux and torque components to two-coordinate vector. - * - * The function operates on a single sample of data and each call to the function returns the processed output. - * The library provides separate functions for Q31 and floating-point data types. - * \par Algorithm - * \image html parkInvFormula.gif - * where pIalpha and pIbeta are the stator vector components, - * Id and Iq are rotor vector components and cosVal and sinVal are the - * cosine and sine values of theta (rotor flux position). - * \par Fixed-Point Behavior - * Care must be taken when using the Q31 version of the Park transform. - * In particular, the overflow and saturation behavior of the accumulator used must be considered. - * Refer to the function specific documentation below for usage guidelines. - */ - - /** - * @addtogroup inv_park - * @{ - */ - - /** - * @brief Floating-point Inverse Park transform - * @param[in] Id input coordinate of rotor reference frame d - * @param[in] Iq input coordinate of rotor reference frame q - * @param[out] *pIalpha points to output two-phase orthogonal vector axis alpha - * @param[out] *pIbeta points to output two-phase orthogonal vector axis beta - * @param[in] sinVal sine value of rotation angle theta - * @param[in] cosVal cosine value of rotation angle theta - * @return none. - */ - - static __INLINE void arm_inv_park_f32( - float32_t Id, - float32_t Iq, - float32_t * pIalpha, - float32_t * pIbeta, - float32_t sinVal, - float32_t cosVal) - { - /* Calculate pIalpha using the equation, pIalpha = Id * cosVal - Iq * sinVal */ - *pIalpha = Id * cosVal - Iq * sinVal; - - /* Calculate pIbeta using the equation, pIbeta = Id * sinVal + Iq * cosVal */ - *pIbeta = Id * sinVal + Iq * cosVal; - - } - - - /** - * @brief Inverse Park transform for Q31 version - * @param[in] Id input coordinate of rotor reference frame d - * @param[in] Iq input coordinate of rotor reference frame q - * @param[out] *pIalpha points to output two-phase orthogonal vector axis alpha - * @param[out] *pIbeta points to output two-phase orthogonal vector axis beta - * @param[in] sinVal sine value of rotation angle theta - * @param[in] cosVal cosine value of rotation angle theta - * @return none. - * - * Scaling and Overflow Behavior: - * \par - * The function is implemented using an internal 32-bit accumulator. - * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format. - * There is saturation on the addition, hence there is no risk of overflow. - */ - - - static __INLINE void arm_inv_park_q31( - q31_t Id, - q31_t Iq, - q31_t * pIalpha, - q31_t * pIbeta, - q31_t sinVal, - q31_t cosVal) - { - q31_t product1, product2; /* Temporary variables used to store intermediate results */ - q31_t product3, product4; /* Temporary variables used to store intermediate results */ - - /* Intermediate product is calculated by (Id * cosVal) */ - product1 = (q31_t) (((q63_t) (Id) * (cosVal)) >> 31); - - /* Intermediate product is calculated by (Iq * sinVal) */ - product2 = (q31_t) (((q63_t) (Iq) * (sinVal)) >> 31); - - - /* Intermediate product is calculated by (Id * sinVal) */ - product3 = (q31_t) (((q63_t) (Id) * (sinVal)) >> 31); - - /* Intermediate product is calculated by (Iq * cosVal) */ - product4 = (q31_t) (((q63_t) (Iq) * (cosVal)) >> 31); - - /* Calculate pIalpha by using the two intermediate products 1 and 2 */ - *pIalpha = __QSUB(product1, product2); - - /* Calculate pIbeta by using the two intermediate products 3 and 4 */ - *pIbeta = __QADD(product4, product3); - - } - - /** - * @} end of Inverse park group - */ - - - /** - * @brief Converts the elements of the Q31 vector to floating-point vector. - * @param[in] *pSrc is input pointer - * @param[out] *pDst is output pointer - * @param[in] blockSize is the number of samples to process - * @return none. - */ - void arm_q31_to_float( - q31_t * pSrc, - float32_t * pDst, - uint32_t blockSize); - - /** - * @ingroup groupInterpolation - */ - - /** - * @defgroup LinearInterpolate Linear Interpolation - * - * Linear interpolation is a method of curve fitting using linear polynomials. - * Linear interpolation works by effectively drawing a straight line between two neighboring samples and returning the appropriate point along that line - * - * \par - * \image html LinearInterp.gif "Linear interpolation" - * - * \par - * A Linear Interpolate function calculates an output value(y), for the input(x) - * using linear interpolation of the input values x0, x1( nearest input values) and the output values y0 and y1(nearest output values) - * - * \par Algorithm: - *
-   *       y = y0 + (x - x0) * ((y1 - y0)/(x1-x0))
-   *       where x0, x1 are nearest values of input x
-   *             y0, y1 are nearest values to output y
-   * 
- * - * \par - * This set of functions implements Linear interpolation process - * for Q7, Q15, Q31, and floating-point data types. The functions operate on a single - * sample of data and each call to the function returns a single processed value. - * S points to an instance of the Linear Interpolate function data structure. - * x is the input sample value. The functions returns the output value. - * - * \par - * if x is outside of the table boundary, Linear interpolation returns first value of the table - * if x is below input range and returns last value of table if x is above range. - */ - - /** - * @addtogroup LinearInterpolate - * @{ - */ - - /** - * @brief Process function for the floating-point Linear Interpolation Function. - * @param[in,out] *S is an instance of the floating-point Linear Interpolation structure - * @param[in] x input sample to process - * @return y processed output sample. - * - */ - - static __INLINE float32_t arm_linear_interp_f32( - arm_linear_interp_instance_f32 * S, - float32_t x) - { - - float32_t y; - float32_t x0, x1; /* Nearest input values */ - float32_t y0, y1; /* Nearest output values */ - float32_t xSpacing = S->xSpacing; /* spacing between input values */ - int32_t i; /* Index variable */ - float32_t *pYData = S->pYData; /* pointer to output table */ - - /* Calculation of index */ - i = (int32_t) ((x - S->x1) / xSpacing); - - if(i < 0) - { - /* Iniatilize output for below specified range as least output value of table */ - y = pYData[0]; - } - else if((uint32_t)i >= S->nValues) - { - /* Iniatilize output for above specified range as last output value of table */ - y = pYData[S->nValues - 1]; - } - else - { - /* Calculation of nearest input values */ - x0 = S->x1 + i * xSpacing; - x1 = S->x1 + (i + 1) * xSpacing; - - /* Read of nearest output values */ - y0 = pYData[i]; - y1 = pYData[i + 1]; - - /* Calculation of output */ - y = y0 + (x - x0) * ((y1 - y0) / (x1 - x0)); - - } - - /* returns output value */ - return (y); - } - - /** - * - * @brief Process function for the Q31 Linear Interpolation Function. - * @param[in] *pYData pointer to Q31 Linear Interpolation table - * @param[in] x input sample to process - * @param[in] nValues number of table values - * @return y processed output sample. - * - * \par - * Input sample x is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part. - * This function can support maximum of table size 2^12. - * - */ - - - static __INLINE q31_t arm_linear_interp_q31( - q31_t * pYData, - q31_t x, - uint32_t nValues) - { - q31_t y; /* output */ - q31_t y0, y1; /* Nearest output values */ - q31_t fract; /* fractional part */ - int32_t index; /* Index to read nearest output values */ - - /* Input is in 12.20 format */ - /* 12 bits for the table index */ - /* Index value calculation */ - index = ((x & 0xFFF00000) >> 20); - - if(index >= (int32_t)(nValues - 1)) - { - return (pYData[nValues - 1]); - } - else if(index < 0) - { - return (pYData[0]); - } - else - { - - /* 20 bits for the fractional part */ - /* shift left by 11 to keep fract in 1.31 format */ - fract = (x & 0x000FFFFF) << 11; - - /* Read two nearest output values from the index in 1.31(q31) format */ - y0 = pYData[index]; - y1 = pYData[index + 1u]; - - /* Calculation of y0 * (1-fract) and y is in 2.30 format */ - y = ((q31_t) ((q63_t) y0 * (0x7FFFFFFF - fract) >> 32)); - - /* Calculation of y0 * (1-fract) + y1 *fract and y is in 2.30 format */ - y += ((q31_t) (((q63_t) y1 * fract) >> 32)); - - /* Convert y to 1.31 format */ - return (y << 1u); - - } - - } - - /** - * - * @brief Process function for the Q15 Linear Interpolation Function. - * @param[in] *pYData pointer to Q15 Linear Interpolation table - * @param[in] x input sample to process - * @param[in] nValues number of table values - * @return y processed output sample. - * - * \par - * Input sample x is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part. - * This function can support maximum of table size 2^12. - * - */ - - - static __INLINE q15_t arm_linear_interp_q15( - q15_t * pYData, - q31_t x, - uint32_t nValues) - { - q63_t y; /* output */ - q15_t y0, y1; /* Nearest output values */ - q31_t fract; /* fractional part */ - int32_t index; /* Index to read nearest output values */ - - /* Input is in 12.20 format */ - /* 12 bits for the table index */ - /* Index value calculation */ - index = ((x & 0xFFF00000) >> 20u); - - if(index >= (int32_t)(nValues - 1)) - { - return (pYData[nValues - 1]); - } - else if(index < 0) - { - return (pYData[0]); - } - else - { - /* 20 bits for the fractional part */ - /* fract is in 12.20 format */ - fract = (x & 0x000FFFFF); - - /* Read two nearest output values from the index */ - y0 = pYData[index]; - y1 = pYData[index + 1u]; - - /* Calculation of y0 * (1-fract) and y is in 13.35 format */ - y = ((q63_t) y0 * (0xFFFFF - fract)); - - /* Calculation of (y0 * (1-fract) + y1 * fract) and y is in 13.35 format */ - y += ((q63_t) y1 * (fract)); - - /* convert y to 1.15 format */ - return (y >> 20); - } - - - } - - /** - * - * @brief Process function for the Q7 Linear Interpolation Function. - * @param[in] *pYData pointer to Q7 Linear Interpolation table - * @param[in] x input sample to process - * @param[in] nValues number of table values - * @return y processed output sample. - * - * \par - * Input sample x is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part. - * This function can support maximum of table size 2^12. - */ - - - static __INLINE q7_t arm_linear_interp_q7( - q7_t * pYData, - q31_t x, - uint32_t nValues) - { - q31_t y; /* output */ - q7_t y0, y1; /* Nearest output values */ - q31_t fract; /* fractional part */ - uint32_t index; /* Index to read nearest output values */ - - /* Input is in 12.20 format */ - /* 12 bits for the table index */ - /* Index value calculation */ - if (x < 0) - { - return (pYData[0]); - } - index = (x >> 20) & 0xfff; - - - if(index >= (nValues - 1)) - { - return (pYData[nValues - 1]); - } - else - { - - /* 20 bits for the fractional part */ - /* fract is in 12.20 format */ - fract = (x & 0x000FFFFF); - - /* Read two nearest output values from the index and are in 1.7(q7) format */ - y0 = pYData[index]; - y1 = pYData[index + 1u]; - - /* Calculation of y0 * (1-fract ) and y is in 13.27(q27) format */ - y = ((y0 * (0xFFFFF - fract))); - - /* Calculation of y1 * fract + y0 * (1-fract) and y is in 13.27(q27) format */ - y += (y1 * fract); - - /* convert y to 1.7(q7) format */ - return (y >> 20u); - - } - - } - /** - * @} end of LinearInterpolate group - */ - - /** - * @brief Fast approximation to the trigonometric sine function for floating-point data. - * @param[in] x input value in radians. - * @return sin(x). - */ - - float32_t arm_sin_f32( - float32_t x); - - /** - * @brief Fast approximation to the trigonometric sine function for Q31 data. - * @param[in] x Scaled input value in radians. - * @return sin(x). - */ - - q31_t arm_sin_q31( - q31_t x); - - /** - * @brief Fast approximation to the trigonometric sine function for Q15 data. - * @param[in] x Scaled input value in radians. - * @return sin(x). - */ - - q15_t arm_sin_q15( - q15_t x); - - /** - * @brief Fast approximation to the trigonometric cosine function for floating-point data. - * @param[in] x input value in radians. - * @return cos(x). - */ - - float32_t arm_cos_f32( - float32_t x); - - /** - * @brief Fast approximation to the trigonometric cosine function for Q31 data. - * @param[in] x Scaled input value in radians. - * @return cos(x). - */ - - q31_t arm_cos_q31( - q31_t x); - - /** - * @brief Fast approximation to the trigonometric cosine function for Q15 data. - * @param[in] x Scaled input value in radians. - * @return cos(x). - */ - - q15_t arm_cos_q15( - q15_t x); - - - /** - * @ingroup groupFastMath - */ - - - /** - * @defgroup SQRT Square Root - * - * Computes the square root of a number. - * There are separate functions for Q15, Q31, and floating-point data types. - * The square root function is computed using the Newton-Raphson algorithm. - * This is an iterative algorithm of the form: - *
-   *      x1 = x0 - f(x0)/f'(x0)
-   * 
- * where x1 is the current estimate, - * x0 is the previous estimate, and - * f'(x0) is the derivative of f() evaluated at x0. - * For the square root function, the algorithm reduces to: - *
-   *     x0 = in/2                         [initial guess]
-   *     x1 = 1/2 * ( x0 + in / x0)        [each iteration]
-   * 
- */ - - - /** - * @addtogroup SQRT - * @{ - */ - - /** - * @brief Floating-point square root function. - * @param[in] in input value. - * @param[out] *pOut square root of input value. - * @return The function returns ARM_MATH_SUCCESS if input value is positive value or ARM_MATH_ARGUMENT_ERROR if - * in is negative value and returns zero output for negative values. - */ - - static __INLINE arm_status arm_sqrt_f32( - float32_t in, - float32_t * pOut) - { - if(in >= 0.0f) - { - -// #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, - q31_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, - q15_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 - */ - - -//SMMLAR -#define multAcc_32x32_keep32_R(a, x, y) \ - a = (q31_t) (((((q63_t) a) << 32) + ((q63_t) x * y) + 0x80000000LL ) >> 32) - -//SMMLSR -#define multSub_32x32_keep32_R(a, x, y) \ - a = (q31_t) (((((q63_t) a) << 32) - ((q63_t) x * y) + 0x80000000LL ) >> 32) - -//SMMULR -#define mult_32x32_keep32_R(a, x, y) \ - a = (q31_t) (((q63_t) x * y + 0x80000000LL ) >> 32) - -//SMMLA -#define multAcc_32x32_keep32(a, x, y) \ - a += (q31_t) (((q63_t) x * y) >> 32) - -//SMMLS -#define multSub_32x32_keep32(a, x, y) \ - a -= (q31_t) (((q63_t) x * y) >> 32) - -//SMMUL -#define mult_32x32_keep32(a, x, y) \ - a = (q31_t) (((q63_t) x * y ) >> 32) - - -#if defined ( __CC_ARM ) //Keil - -//Enter low optimization region - place directly above function definition - #ifdef ARM_MATH_CM4 - #define LOW_OPTIMIZATION_ENTER \ - _Pragma ("push") \ - _Pragma ("O1") - #else - #define LOW_OPTIMIZATION_ENTER - #endif - -//Exit low optimization region - place directly after end of function definition - #ifdef ARM_MATH_CM4 - #define LOW_OPTIMIZATION_EXIT \ - _Pragma ("pop") - #else - #define LOW_OPTIMIZATION_EXIT - #endif - -//Enter low optimization region - place directly above function definition - #define IAR_ONLY_LOW_OPTIMIZATION_ENTER - -//Exit low optimization region - place directly after end of function definition - #define IAR_ONLY_LOW_OPTIMIZATION_EXIT - -#elif defined(__ICCARM__) //IAR - -//Enter low optimization region - place directly above function definition - #ifdef ARM_MATH_CM4 - #define LOW_OPTIMIZATION_ENTER \ - _Pragma ("optimize=low") - #else - #define LOW_OPTIMIZATION_ENTER - #endif - -//Exit low optimization region - place directly after end of function definition - #define LOW_OPTIMIZATION_EXIT - -//Enter low optimization region - place directly above function definition - #ifdef ARM_MATH_CM4 - #define IAR_ONLY_LOW_OPTIMIZATION_ENTER \ - _Pragma ("optimize=low") - #else - #define IAR_ONLY_LOW_OPTIMIZATION_ENTER - #endif - -//Exit low optimization region - place directly after end of function definition - #define IAR_ONLY_LOW_OPTIMIZATION_EXIT - -#elif defined(__GNUC__) - - #define LOW_OPTIMIZATION_ENTER __attribute__(( optimize("-O1") )) - - #define LOW_OPTIMIZATION_EXIT - - #define IAR_ONLY_LOW_OPTIMIZATION_ENTER - - #define IAR_ONLY_LOW_OPTIMIZATION_EXIT - -#elif defined(__CSMC__) // Cosmic - -#define LOW_OPTIMIZATION_ENTER -#define LOW_OPTIMIZATION_EXIT -#define IAR_ONLY_LOW_OPTIMIZATION_ENTER -#define IAR_ONLY_LOW_OPTIMIZATION_EXIT - -#elif defined(__TASKING__) // TASKING - -#define LOW_OPTIMIZATION_ENTER -#define LOW_OPTIMIZATION_EXIT -#define IAR_ONLY_LOW_OPTIMIZATION_ENTER -#define IAR_ONLY_LOW_OPTIMIZATION_EXIT - -#endif - - -#ifdef __cplusplus -} -#endif - - -#endif /* _ARM_MATH_H */ - -/** - * - * End of file. - */ diff --git a/cmsis/core_cm0.h b/cmsis/core_cm0.h deleted file mode 100644 index 978b013fd92..00000000000 --- a/cmsis/core_cm0.h +++ /dev/null @@ -1,750 +0,0 @@ -/**************************************************************************//** - * @file core_cm0.h - * @brief CMSIS Cortex-M0 Core Peripheral Access Layer Header File - * @version V4.10 - * @date 18. March 2015 - * - * @note - * - ******************************************************************************/ -/* Copyright (c) 2009 - 2015 ARM LIMITED - - All rights reserved. - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - Neither the name of ARM nor the names of its contributors may be used - to endorse or promote products derived from this software without - specific prior written permission. - * - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - ---------------------------------------------------------------------------*/ - - -#if defined ( __ICCARM__ ) - #pragma system_include /* treat file as system include file for MISRA check */ -#endif - -#ifndef __CORE_CM0_H_GENERIC -#define __CORE_CM0_H_GENERIC - -#ifdef __cplusplus - extern "C" { -#endif - -/** \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions - CMSIS violates the following MISRA-C:2004 rules: - - \li Required Rule 8.5, object/function definition in header file.
- Function definitions in header files are used to allow 'inlining'. - - \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
- Unions are used for effective representation of core registers. - - \li Advisory Rule 19.7, Function-like macro defined.
- Function-like macros are used to allow more efficient code. - */ - - -/******************************************************************************* - * CMSIS definitions - ******************************************************************************/ -/** \ingroup Cortex_M0 - @{ - */ - -/* CMSIS CM0 definitions */ -#define __CM0_CMSIS_VERSION_MAIN (0x04) /*!< [31:16] CMSIS HAL main version */ -#define __CM0_CMSIS_VERSION_SUB (0x00) /*!< [15:0] CMSIS HAL sub version */ -#define __CM0_CMSIS_VERSION ((__CM0_CMSIS_VERSION_MAIN << 16) | \ - __CM0_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */ - -#define __CORTEX_M (0x00) /*!< Cortex-M Core */ - - -#if defined ( __CC_ARM ) - #define __ASM __asm /*!< asm keyword for ARM Compiler */ - #define __INLINE __inline /*!< inline keyword for ARM Compiler */ - #define __STATIC_INLINE static __inline - -#elif defined ( __GNUC__ ) - #define __ASM __asm /*!< asm keyword for GNU Compiler */ - #define __INLINE inline /*!< inline keyword for GNU Compiler */ - #define __STATIC_INLINE static inline - -#elif defined ( __ICCARM__ ) - #define __ASM __asm /*!< asm keyword for IAR Compiler */ - #define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */ - #define __STATIC_INLINE static inline - -#elif defined ( __TMS470__ ) - #define __ASM __asm /*!< asm keyword for TI CCS Compiler */ - #define __STATIC_INLINE static inline - -#elif defined ( __TASKING__ ) - #define __ASM __asm /*!< asm keyword for TASKING Compiler */ - #define __INLINE inline /*!< inline keyword for TASKING Compiler */ - #define __STATIC_INLINE static inline - -#elif defined ( __CSMC__ ) - #define __packed - #define __ASM _asm /*!< asm keyword for COSMIC Compiler */ - #define __INLINE inline /*use -pc99 on compile line !< inline keyword for COSMIC Compiler */ - #define __STATIC_INLINE static inline - -#endif - -/** __FPU_USED indicates whether an FPU is used or not. - This core does not support an FPU at all -*/ -#define __FPU_USED 0 - -#if defined ( __CC_ARM ) - #if defined __TARGET_FPU_VFP - #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #endif - -#elif defined ( __GNUC__ ) - #if defined (__VFP_FP__) && !defined(__SOFTFP__) - #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #endif - -#elif defined ( __ICCARM__ ) - #if defined __ARMVFP__ - #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #endif - -#elif defined ( __TMS470__ ) - #if defined __TI__VFP_SUPPORT____ - #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #endif - -#elif defined ( __TASKING__ ) - #if defined __FPU_VFP__ - #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #endif - -#elif defined ( __CSMC__ ) /* Cosmic */ - #if ( __CSMC__ & 0x400) // FPU present for parser - #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #endif -#endif - -#include /* standard types definitions */ -#include /* Core Instruction Access */ -#include /* Core Function Access */ - -#ifdef __cplusplus -} -#endif - -#endif /* __CORE_CM0_H_GENERIC */ - -#ifndef __CMSIS_GENERIC - -#ifndef __CORE_CM0_H_DEPENDANT -#define __CORE_CM0_H_DEPENDANT - -#ifdef __cplusplus - extern "C" { -#endif - -/* check device defines and use defaults */ -#if defined __CHECK_DEVICE_DEFINES - #ifndef __CM0_REV - #define __CM0_REV 0x0000 - #warning "__CM0_REV not defined in device header file; using default!" - #endif - - #ifndef __NVIC_PRIO_BITS - #define __NVIC_PRIO_BITS 2 - #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" - #endif - - #ifndef __Vendor_SysTickConfig - #define __Vendor_SysTickConfig 0 - #warning "__Vendor_SysTickConfig not defined in device header file; using default!" - #endif -#endif - -/* IO definitions (access restrictions to peripheral registers) */ -/** - \defgroup CMSIS_glob_defs CMSIS Global Defines - - IO Type Qualifiers are used - \li to specify the access to peripheral variables. - \li for automatic generation of peripheral register debug information. -*/ -#ifdef __cplusplus - #define __I volatile /*!< Defines 'read only' permissions */ -#else - #define __I volatile const /*!< Defines 'read only' permissions */ -#endif -#define __O volatile /*!< Defines 'write only' permissions */ -#define __IO volatile /*!< Defines 'read / write' permissions */ - -#ifdef __cplusplus - #define __IM volatile /*!< Defines 'read only' permissions */ -#else - #define __IM volatile const /*!< Defines 'read only' permissions */ -#endif -#define __OM volatile /*!< Defines 'write only' permissions */ -#define __IOM volatile /*!< Defines 'read / write' permissions */ - -/*@} end of group Cortex_M0 */ - - - -/******************************************************************************* - * Register Abstraction - Core Register contain: - - Core Register - - Core NVIC Register - - Core SCB Register - - Core SysTick Register - ******************************************************************************/ -/** \defgroup CMSIS_core_register Defines and Type Definitions - \brief Type definitions and defines for Cortex-M processor based devices. -*/ - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_CORE Status and Control Registers - \brief Core Register type definitions. - @{ - */ - -/** \brief Union type to access the Application Program Status Register (APSR). - */ -typedef union -{ - struct - { - uint32_t _reserved0:28; /*!< bit: 0..27 Reserved */ - uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ - uint32_t C:1; /*!< bit: 29 Carry condition code flag */ - uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ - uint32_t N:1; /*!< bit: 31 Negative condition code flag */ - } b; /*!< Structure used for bit access */ - uint32_t w; /*!< Type used for word access */ -} APSR_Type; - -/* APSR Register Definitions */ -#define APSR_N_Pos 31 /*!< APSR: N Position */ -#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ - -#define APSR_Z_Pos 30 /*!< APSR: Z Position */ -#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ - -#define APSR_C_Pos 29 /*!< APSR: C Position */ -#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ - -#define APSR_V_Pos 28 /*!< APSR: V Position */ -#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ - - -/** \brief Union type to access the Interrupt Program Status Register (IPSR). - */ -typedef union -{ - struct - { - uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ - uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ - } b; /*!< Structure used for bit access */ - uint32_t w; /*!< Type used for word access */ -} IPSR_Type; - -/* IPSR Register Definitions */ -#define IPSR_ISR_Pos 0 /*!< IPSR: ISR Position */ -#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ - - -/** \brief Union type to access the Special-Purpose Program Status Registers (xPSR). - */ -typedef union -{ - struct - { - uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ - uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ - uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ - uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */ - uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ - uint32_t C:1; /*!< bit: 29 Carry condition code flag */ - uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ - uint32_t N:1; /*!< bit: 31 Negative condition code flag */ - } b; /*!< Structure used for bit access */ - uint32_t w; /*!< Type used for word access */ -} xPSR_Type; - -/* xPSR Register Definitions */ -#define xPSR_N_Pos 31 /*!< xPSR: N Position */ -#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ - -#define xPSR_Z_Pos 30 /*!< xPSR: Z Position */ -#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ - -#define xPSR_C_Pos 29 /*!< xPSR: C Position */ -#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ - -#define xPSR_V_Pos 28 /*!< xPSR: V Position */ -#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ - -#define xPSR_T_Pos 24 /*!< xPSR: T Position */ -#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ - -#define xPSR_ISR_Pos 0 /*!< xPSR: ISR Position */ -#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ - - -/** \brief Union type to access the Control Registers (CONTROL). - */ -typedef union -{ - struct - { - uint32_t _reserved0:1; /*!< bit: 0 Reserved */ - uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ - uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */ - } b; /*!< Structure used for bit access */ - uint32_t w; /*!< Type used for word access */ -} CONTROL_Type; - -/* CONTROL Register Definitions */ -#define CONTROL_SPSEL_Pos 1 /*!< CONTROL: SPSEL Position */ -#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ - -/*@} end of group CMSIS_CORE */ - - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) - \brief Type definitions for the NVIC Registers - @{ - */ - -/** \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). - */ -typedef struct -{ - __IO uint32_t ISER[1]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ - uint32_t RESERVED0[31]; - __IO uint32_t ICER[1]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ - uint32_t RSERVED1[31]; - __IO uint32_t ISPR[1]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ - uint32_t RESERVED2[31]; - __IO uint32_t ICPR[1]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ - uint32_t RESERVED3[31]; - uint32_t RESERVED4[64]; - __IO uint32_t IP[8]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */ -} NVIC_Type; - -/*@} end of group CMSIS_NVIC */ - - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_SCB System Control Block (SCB) - \brief Type definitions for the System Control Block Registers - @{ - */ - -/** \brief Structure type to access the System Control Block (SCB). - */ -typedef struct -{ - __I uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ - __IO uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ - uint32_t RESERVED0; - __IO uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ - __IO uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ - __IO uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ - uint32_t RESERVED1; - __IO uint32_t SHP[2]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */ - __IO uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ -} SCB_Type; - -/* SCB CPUID Register Definitions */ -#define SCB_CPUID_IMPLEMENTER_Pos 24 /*!< SCB CPUID: IMPLEMENTER Position */ -#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ - -#define SCB_CPUID_VARIANT_Pos 20 /*!< SCB CPUID: VARIANT Position */ -#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ - -#define SCB_CPUID_ARCHITECTURE_Pos 16 /*!< SCB CPUID: ARCHITECTURE Position */ -#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ - -#define SCB_CPUID_PARTNO_Pos 4 /*!< SCB CPUID: PARTNO Position */ -#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ - -#define SCB_CPUID_REVISION_Pos 0 /*!< SCB CPUID: REVISION Position */ -#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ - -/* SCB Interrupt Control State Register Definitions */ -#define SCB_ICSR_NMIPENDSET_Pos 31 /*!< SCB ICSR: NMIPENDSET Position */ -#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ - -#define SCB_ICSR_PENDSVSET_Pos 28 /*!< SCB ICSR: PENDSVSET Position */ -#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ - -#define SCB_ICSR_PENDSVCLR_Pos 27 /*!< SCB ICSR: PENDSVCLR Position */ -#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ - -#define SCB_ICSR_PENDSTSET_Pos 26 /*!< SCB ICSR: PENDSTSET Position */ -#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ - -#define SCB_ICSR_PENDSTCLR_Pos 25 /*!< SCB ICSR: PENDSTCLR Position */ -#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ - -#define SCB_ICSR_ISRPREEMPT_Pos 23 /*!< SCB ICSR: ISRPREEMPT Position */ -#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ - -#define SCB_ICSR_ISRPENDING_Pos 22 /*!< SCB ICSR: ISRPENDING Position */ -#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ - -#define SCB_ICSR_VECTPENDING_Pos 12 /*!< SCB ICSR: VECTPENDING Position */ -#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ - -#define SCB_ICSR_VECTACTIVE_Pos 0 /*!< SCB ICSR: VECTACTIVE Position */ -#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ - -/* SCB Application Interrupt and Reset Control Register Definitions */ -#define SCB_AIRCR_VECTKEY_Pos 16 /*!< SCB AIRCR: VECTKEY Position */ -#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ - -#define SCB_AIRCR_VECTKEYSTAT_Pos 16 /*!< SCB AIRCR: VECTKEYSTAT Position */ -#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ - -#define SCB_AIRCR_ENDIANESS_Pos 15 /*!< SCB AIRCR: ENDIANESS Position */ -#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ - -#define SCB_AIRCR_SYSRESETREQ_Pos 2 /*!< SCB AIRCR: SYSRESETREQ Position */ -#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ - -#define SCB_AIRCR_VECTCLRACTIVE_Pos 1 /*!< SCB AIRCR: VECTCLRACTIVE Position */ -#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ - -/* SCB System Control Register Definitions */ -#define SCB_SCR_SEVONPEND_Pos 4 /*!< SCB SCR: SEVONPEND Position */ -#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ - -#define SCB_SCR_SLEEPDEEP_Pos 2 /*!< SCB SCR: SLEEPDEEP Position */ -#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ - -#define SCB_SCR_SLEEPONEXIT_Pos 1 /*!< SCB SCR: SLEEPONEXIT Position */ -#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ - -/* SCB Configuration Control Register Definitions */ -#define SCB_CCR_STKALIGN_Pos 9 /*!< SCB CCR: STKALIGN Position */ -#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ - -#define SCB_CCR_UNALIGN_TRP_Pos 3 /*!< SCB CCR: UNALIGN_TRP Position */ -#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ - -/* SCB System Handler Control and State Register Definitions */ -#define SCB_SHCSR_SVCALLPENDED_Pos 15 /*!< SCB SHCSR: SVCALLPENDED Position */ -#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ - -/*@} end of group CMSIS_SCB */ - - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_SysTick System Tick Timer (SysTick) - \brief Type definitions for the System Timer Registers. - @{ - */ - -/** \brief Structure type to access the System Timer (SysTick). - */ -typedef struct -{ - __IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ - __IO uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ - __IO uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ - __I uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ -} SysTick_Type; - -/* SysTick Control / Status Register Definitions */ -#define SysTick_CTRL_COUNTFLAG_Pos 16 /*!< SysTick CTRL: COUNTFLAG Position */ -#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ - -#define SysTick_CTRL_CLKSOURCE_Pos 2 /*!< SysTick CTRL: CLKSOURCE Position */ -#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ - -#define SysTick_CTRL_TICKINT_Pos 1 /*!< SysTick CTRL: TICKINT Position */ -#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ - -#define SysTick_CTRL_ENABLE_Pos 0 /*!< SysTick CTRL: ENABLE Position */ -#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ - -/* SysTick Reload Register Definitions */ -#define SysTick_LOAD_RELOAD_Pos 0 /*!< SysTick LOAD: RELOAD Position */ -#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ - -/* SysTick Current Register Definitions */ -#define SysTick_VAL_CURRENT_Pos 0 /*!< SysTick VAL: CURRENT Position */ -#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ - -/* SysTick Calibration Register Definitions */ -#define SysTick_CALIB_NOREF_Pos 31 /*!< SysTick CALIB: NOREF Position */ -#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ - -#define SysTick_CALIB_SKEW_Pos 30 /*!< SysTick CALIB: SKEW Position */ -#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ - -#define SysTick_CALIB_TENMS_Pos 0 /*!< SysTick CALIB: TENMS Position */ -#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ - -/*@} end of group CMSIS_SysTick */ - - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) - \brief Cortex-M0 Core Debug Registers (DCB registers, SHCSR, and DFSR) - are only accessible over DAP and not via processor. Therefore - they are not covered by the Cortex-M0 header file. - @{ - */ -/*@} end of group CMSIS_CoreDebug */ - - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_core_base Core Definitions - \brief Definitions for base addresses, unions, and structures. - @{ - */ - -/* Memory mapping of Cortex-M0 Hardware */ -#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ -#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ -#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ -#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ - -#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ -#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ -#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ - - -/*@} */ - - - -/******************************************************************************* - * Hardware Abstraction Layer - Core Function Interface contains: - - Core NVIC Functions - - Core SysTick Functions - - Core Register Access Functions - ******************************************************************************/ -/** \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference -*/ - - - -/* ########################## NVIC functions #################################### */ -/** \ingroup CMSIS_Core_FunctionInterface - \defgroup CMSIS_Core_NVICFunctions NVIC Functions - \brief Functions that manage interrupts and exceptions via the NVIC. - @{ - */ - -/* Interrupt Priorities are WORD accessible only under ARMv6M */ -/* The following MACROS handle generation of the register offset and byte masks */ -#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL) -#define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) ) -#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) ) - - -/** \brief Enable External Interrupt - - The function enables a device-specific interrupt in the NVIC interrupt controller. - - \param [in] IRQn External interrupt number. Value cannot be negative. - */ -__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn) -{ - NVIC->ISER[0] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); -} - - -/** \brief Disable External Interrupt - - The function disables a device-specific interrupt in the NVIC interrupt controller. - - \param [in] IRQn External interrupt number. Value cannot be negative. - */ -__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn) -{ - NVIC->ICER[0] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); - __DSB(); - __ISB(); -} - - -/** \brief Get Pending Interrupt - - The function reads the pending register in the NVIC and returns the pending bit - for the specified interrupt. - - \param [in] IRQn Interrupt number. - - \return 0 Interrupt status is not pending. - \return 1 Interrupt status is pending. - */ -__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn) -{ - return((uint32_t)(((NVIC->ISPR[0] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); -} - - -/** \brief Set Pending Interrupt - - The function sets the pending bit of an external interrupt. - - \param [in] IRQn Interrupt number. Value cannot be negative. - */ -__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn) -{ - NVIC->ISPR[0] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); -} - - -/** \brief Clear Pending Interrupt - - The function clears the pending bit of an external interrupt. - - \param [in] IRQn External interrupt number. Value cannot be negative. - */ -__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn) -{ - NVIC->ICPR[0] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); -} - - -/** \brief Set Interrupt Priority - - The function sets the priority of an interrupt. - - \note The priority cannot be set for every core interrupt. - - \param [in] IRQn Interrupt number. - \param [in] priority Priority to set. - */ -__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) -{ - if((int32_t)(IRQn) < 0) { - SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | - (((priority << (8 - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); - } - else { - NVIC->IP[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | - (((priority << (8 - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); - } -} - - -/** \brief Get Interrupt Priority - - The function reads the priority of an interrupt. The interrupt - number can be positive to specify an external (device specific) - interrupt, or negative to specify an internal (core) interrupt. - - - \param [in] IRQn Interrupt number. - \return Interrupt Priority. Value is aligned automatically to the implemented - priority bits of the microcontroller. - */ -__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn) -{ - - if((int32_t)(IRQn) < 0) { - return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8 - __NVIC_PRIO_BITS))); - } - else { - return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8 - __NVIC_PRIO_BITS))); - } -} - - -/** \brief System Reset - - The function initiates a system reset request to reset the MCU. - */ -__STATIC_INLINE void NVIC_SystemReset(void) -{ - __DSB(); /* Ensure all outstanding memory accesses included - buffered write are completed before reset */ - SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | - SCB_AIRCR_SYSRESETREQ_Msk); - __DSB(); /* Ensure completion of memory access */ - while(1) { __NOP(); } /* wait until reset */ -} - -/*@} end of CMSIS_Core_NVICFunctions */ - - - -/* ################################## SysTick function ############################################ */ -/** \ingroup CMSIS_Core_FunctionInterface - \defgroup CMSIS_Core_SysTickFunctions SysTick Functions - \brief Functions that configure the System. - @{ - */ - -#if (__Vendor_SysTickConfig == 0) - -/** \brief System Tick Configuration - - The function initializes the System Timer and its interrupt, and starts the System Tick Timer. - Counter is in free running mode to generate periodic interrupts. - - \param [in] ticks Number of ticks between two interrupts. - - \return 0 Function succeeded. - \return 1 Function failed. - - \note When the variable __Vendor_SysTickConfig is set to 1, then the - function SysTick_Config is not included. In this case, the file device.h - must contain a vendor-specific implementation of this function. - - */ -__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) -{ - if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) { return (1UL); } /* Reload value impossible */ - - SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ - NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ - SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ - SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | - SysTick_CTRL_TICKINT_Msk | - SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ - return (0UL); /* Function successful */ -} - -#endif - -/*@} end of CMSIS_Core_SysTickFunctions */ - - - - -#ifdef __cplusplus -} -#endif - -#endif /* __CORE_CM0_H_DEPENDANT */ - -#endif /* __CMSIS_GENERIC */ diff --git a/cmsis/core_cm0plus.h b/cmsis/core_cm0plus.h deleted file mode 100644 index 65c7b628621..00000000000 --- a/cmsis/core_cm0plus.h +++ /dev/null @@ -1,864 +0,0 @@ -/**************************************************************************//** - * @file core_cm0plus.h - * @brief CMSIS Cortex-M0+ Core Peripheral Access Layer Header File - * @version V4.10 - * @date 18. March 2015 - * - * @note - * - ******************************************************************************/ -/* Copyright (c) 2009 - 2015 ARM LIMITED - - All rights reserved. - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - Neither the name of ARM nor the names of its contributors may be used - to endorse or promote products derived from this software without - specific prior written permission. - * - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - ---------------------------------------------------------------------------*/ - - -#if defined ( __ICCARM__ ) - #pragma system_include /* treat file as system include file for MISRA check */ -#endif - -#ifndef __CORE_CM0PLUS_H_GENERIC -#define __CORE_CM0PLUS_H_GENERIC - -#ifdef __cplusplus - extern "C" { -#endif - -/** \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions - CMSIS violates the following MISRA-C:2004 rules: - - \li Required Rule 8.5, object/function definition in header file.
- Function definitions in header files are used to allow 'inlining'. - - \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
- Unions are used for effective representation of core registers. - - \li Advisory Rule 19.7, Function-like macro defined.
- Function-like macros are used to allow more efficient code. - */ - - -/******************************************************************************* - * CMSIS definitions - ******************************************************************************/ -/** \ingroup Cortex-M0+ - @{ - */ - -/* CMSIS CM0P definitions */ -#define __CM0PLUS_CMSIS_VERSION_MAIN (0x04) /*!< [31:16] CMSIS HAL main version */ -#define __CM0PLUS_CMSIS_VERSION_SUB (0x00) /*!< [15:0] CMSIS HAL sub version */ -#define __CM0PLUS_CMSIS_VERSION ((__CM0PLUS_CMSIS_VERSION_MAIN << 16) | \ - __CM0PLUS_CMSIS_VERSION_SUB) /*!< CMSIS HAL version number */ - -#define __CORTEX_M (0x00) /*!< Cortex-M Core */ - - -#if defined ( __CC_ARM ) - #define __ASM __asm /*!< asm keyword for ARM Compiler */ - #define __INLINE __inline /*!< inline keyword for ARM Compiler */ - #define __STATIC_INLINE static __inline - -#elif defined ( __GNUC__ ) - #define __ASM __asm /*!< asm keyword for GNU Compiler */ - #define __INLINE inline /*!< inline keyword for GNU Compiler */ - #define __STATIC_INLINE static inline - -#elif defined ( __ICCARM__ ) - #define __ASM __asm /*!< asm keyword for IAR Compiler */ - #define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */ - #define __STATIC_INLINE static inline - -#elif defined ( __TMS470__ ) - #define __ASM __asm /*!< asm keyword for TI CCS Compiler */ - #define __STATIC_INLINE static inline - -#elif defined ( __TASKING__ ) - #define __ASM __asm /*!< asm keyword for TASKING Compiler */ - #define __INLINE inline /*!< inline keyword for TASKING Compiler */ - #define __STATIC_INLINE static inline - -#elif defined ( __CSMC__ ) - #define __packed - #define __ASM _asm /*!< asm keyword for COSMIC Compiler */ - #define __INLINE inline /*use -pc99 on compile line !< inline keyword for COSMIC Compiler */ - #define __STATIC_INLINE static inline - -#endif - -/** __FPU_USED indicates whether an FPU is used or not. - This core does not support an FPU at all -*/ -#define __FPU_USED 0 - -#if defined ( __CC_ARM ) - #if defined __TARGET_FPU_VFP - #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #endif - -#elif defined ( __GNUC__ ) - #if defined (__VFP_FP__) && !defined(__SOFTFP__) - #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #endif - -#elif defined ( __ICCARM__ ) - #if defined __ARMVFP__ - #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #endif - -#elif defined ( __TMS470__ ) - #if defined __TI__VFP_SUPPORT____ - #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #endif - -#elif defined ( __TASKING__ ) - #if defined __FPU_VFP__ - #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #endif - -#elif defined ( __CSMC__ ) /* Cosmic */ - #if ( __CSMC__ & 0x400) // FPU present for parser - #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #endif -#endif - -#include /* standard types definitions */ -#include /* Core Instruction Access */ -#include /* Core Function Access */ - -#ifdef __cplusplus -} -#endif - -#endif /* __CORE_CM0PLUS_H_GENERIC */ - -#ifndef __CMSIS_GENERIC - -#ifndef __CORE_CM0PLUS_H_DEPENDANT -#define __CORE_CM0PLUS_H_DEPENDANT - -#ifdef __cplusplus - extern "C" { -#endif - -/* check device defines and use defaults */ -#if defined __CHECK_DEVICE_DEFINES - #ifndef __CM0PLUS_REV - #define __CM0PLUS_REV 0x0000 - #warning "__CM0PLUS_REV not defined in device header file; using default!" - #endif - - #ifndef __MPU_PRESENT - #define __MPU_PRESENT 0 - #warning "__MPU_PRESENT not defined in device header file; using default!" - #endif - - #ifndef __VTOR_PRESENT - #define __VTOR_PRESENT 0 - #warning "__VTOR_PRESENT not defined in device header file; using default!" - #endif - - #ifndef __NVIC_PRIO_BITS - #define __NVIC_PRIO_BITS 2 - #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" - #endif - - #ifndef __Vendor_SysTickConfig - #define __Vendor_SysTickConfig 0 - #warning "__Vendor_SysTickConfig not defined in device header file; using default!" - #endif -#endif - -/* IO definitions (access restrictions to peripheral registers) */ -/** - \defgroup CMSIS_glob_defs CMSIS Global Defines - - IO Type Qualifiers are used - \li to specify the access to peripheral variables. - \li for automatic generation of peripheral register debug information. -*/ -#ifdef __cplusplus - #define __I volatile /*!< Defines 'read only' permissions */ -#else - #define __I volatile const /*!< Defines 'read only' permissions */ -#endif -#define __O volatile /*!< Defines 'write only' permissions */ -#define __IO volatile /*!< Defines 'read / write' permissions */ - -#ifdef __cplusplus - #define __IM volatile /*!< Defines 'read only' permissions */ -#else - #define __IM volatile const /*!< Defines 'read only' permissions */ -#endif -#define __OM volatile /*!< Defines 'write only' permissions */ -#define __IOM volatile /*!< Defines 'read / write' permissions */ - -/*@} end of group Cortex-M0+ */ - - - -/******************************************************************************* - * Register Abstraction - Core Register contain: - - Core Register - - Core NVIC Register - - Core SCB Register - - Core SysTick Register - - Core MPU Register - ******************************************************************************/ -/** \defgroup CMSIS_core_register Defines and Type Definitions - \brief Type definitions and defines for Cortex-M processor based devices. -*/ - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_CORE Status and Control Registers - \brief Core Register type definitions. - @{ - */ - -/** \brief Union type to access the Application Program Status Register (APSR). - */ -typedef union -{ - struct - { - uint32_t _reserved0:28; /*!< bit: 0..27 Reserved */ - uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ - uint32_t C:1; /*!< bit: 29 Carry condition code flag */ - uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ - uint32_t N:1; /*!< bit: 31 Negative condition code flag */ - } b; /*!< Structure used for bit access */ - uint32_t w; /*!< Type used for word access */ -} APSR_Type; - -/* APSR Register Definitions */ -#define APSR_N_Pos 31 /*!< APSR: N Position */ -#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ - -#define APSR_Z_Pos 30 /*!< APSR: Z Position */ -#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ - -#define APSR_C_Pos 29 /*!< APSR: C Position */ -#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ - -#define APSR_V_Pos 28 /*!< APSR: V Position */ -#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ - - -/** \brief Union type to access the Interrupt Program Status Register (IPSR). - */ -typedef union -{ - struct - { - uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ - uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ - } b; /*!< Structure used for bit access */ - uint32_t w; /*!< Type used for word access */ -} IPSR_Type; - -/* IPSR Register Definitions */ -#define IPSR_ISR_Pos 0 /*!< IPSR: ISR Position */ -#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ - - -/** \brief Union type to access the Special-Purpose Program Status Registers (xPSR). - */ -typedef union -{ - struct - { - uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ - uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ - uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ - uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */ - uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ - uint32_t C:1; /*!< bit: 29 Carry condition code flag */ - uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ - uint32_t N:1; /*!< bit: 31 Negative condition code flag */ - } b; /*!< Structure used for bit access */ - uint32_t w; /*!< Type used for word access */ -} xPSR_Type; - -/* xPSR Register Definitions */ -#define xPSR_N_Pos 31 /*!< xPSR: N Position */ -#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ - -#define xPSR_Z_Pos 30 /*!< xPSR: Z Position */ -#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ - -#define xPSR_C_Pos 29 /*!< xPSR: C Position */ -#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ - -#define xPSR_V_Pos 28 /*!< xPSR: V Position */ -#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ - -#define xPSR_T_Pos 24 /*!< xPSR: T Position */ -#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ - -#define xPSR_ISR_Pos 0 /*!< xPSR: ISR Position */ -#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ - - -/** \brief Union type to access the Control Registers (CONTROL). - */ -typedef union -{ - struct - { - uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ - uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ - uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */ - } b; /*!< Structure used for bit access */ - uint32_t w; /*!< Type used for word access */ -} CONTROL_Type; - -/* CONTROL Register Definitions */ -#define CONTROL_SPSEL_Pos 1 /*!< CONTROL: SPSEL Position */ -#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ - -#define CONTROL_nPRIV_Pos 0 /*!< CONTROL: nPRIV Position */ -#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ - -/*@} end of group CMSIS_CORE */ - - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) - \brief Type definitions for the NVIC Registers - @{ - */ - -/** \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). - */ -typedef struct -{ - __IO uint32_t ISER[1]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ - uint32_t RESERVED0[31]; - __IO uint32_t ICER[1]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ - uint32_t RSERVED1[31]; - __IO uint32_t ISPR[1]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ - uint32_t RESERVED2[31]; - __IO uint32_t ICPR[1]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ - uint32_t RESERVED3[31]; - uint32_t RESERVED4[64]; - __IO uint32_t IP[8]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */ -} NVIC_Type; - -/*@} end of group CMSIS_NVIC */ - - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_SCB System Control Block (SCB) - \brief Type definitions for the System Control Block Registers - @{ - */ - -/** \brief Structure type to access the System Control Block (SCB). - */ -typedef struct -{ - __I uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ - __IO uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ -#if (__VTOR_PRESENT == 1) - __IO uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ -#else - uint32_t RESERVED0; -#endif - __IO uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ - __IO uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ - __IO uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ - uint32_t RESERVED1; - __IO uint32_t SHP[2]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */ - __IO uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ -} SCB_Type; - -/* SCB CPUID Register Definitions */ -#define SCB_CPUID_IMPLEMENTER_Pos 24 /*!< SCB CPUID: IMPLEMENTER Position */ -#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ - -#define SCB_CPUID_VARIANT_Pos 20 /*!< SCB CPUID: VARIANT Position */ -#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ - -#define SCB_CPUID_ARCHITECTURE_Pos 16 /*!< SCB CPUID: ARCHITECTURE Position */ -#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ - -#define SCB_CPUID_PARTNO_Pos 4 /*!< SCB CPUID: PARTNO Position */ -#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ - -#define SCB_CPUID_REVISION_Pos 0 /*!< SCB CPUID: REVISION Position */ -#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ - -/* SCB Interrupt Control State Register Definitions */ -#define SCB_ICSR_NMIPENDSET_Pos 31 /*!< SCB ICSR: NMIPENDSET Position */ -#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ - -#define SCB_ICSR_PENDSVSET_Pos 28 /*!< SCB ICSR: PENDSVSET Position */ -#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ - -#define SCB_ICSR_PENDSVCLR_Pos 27 /*!< SCB ICSR: PENDSVCLR Position */ -#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ - -#define SCB_ICSR_PENDSTSET_Pos 26 /*!< SCB ICSR: PENDSTSET Position */ -#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ - -#define SCB_ICSR_PENDSTCLR_Pos 25 /*!< SCB ICSR: PENDSTCLR Position */ -#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ - -#define SCB_ICSR_ISRPREEMPT_Pos 23 /*!< SCB ICSR: ISRPREEMPT Position */ -#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ - -#define SCB_ICSR_ISRPENDING_Pos 22 /*!< SCB ICSR: ISRPENDING Position */ -#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ - -#define SCB_ICSR_VECTPENDING_Pos 12 /*!< SCB ICSR: VECTPENDING Position */ -#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ - -#define SCB_ICSR_VECTACTIVE_Pos 0 /*!< SCB ICSR: VECTACTIVE Position */ -#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ - -#if (__VTOR_PRESENT == 1) -/* SCB Interrupt Control State Register Definitions */ -#define SCB_VTOR_TBLOFF_Pos 8 /*!< SCB VTOR: TBLOFF Position */ -#define SCB_VTOR_TBLOFF_Msk (0xFFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ -#endif - -/* SCB Application Interrupt and Reset Control Register Definitions */ -#define SCB_AIRCR_VECTKEY_Pos 16 /*!< SCB AIRCR: VECTKEY Position */ -#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ - -#define SCB_AIRCR_VECTKEYSTAT_Pos 16 /*!< SCB AIRCR: VECTKEYSTAT Position */ -#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ - -#define SCB_AIRCR_ENDIANESS_Pos 15 /*!< SCB AIRCR: ENDIANESS Position */ -#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ - -#define SCB_AIRCR_SYSRESETREQ_Pos 2 /*!< SCB AIRCR: SYSRESETREQ Position */ -#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ - -#define SCB_AIRCR_VECTCLRACTIVE_Pos 1 /*!< SCB AIRCR: VECTCLRACTIVE Position */ -#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ - -/* SCB System Control Register Definitions */ -#define SCB_SCR_SEVONPEND_Pos 4 /*!< SCB SCR: SEVONPEND Position */ -#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ - -#define SCB_SCR_SLEEPDEEP_Pos 2 /*!< SCB SCR: SLEEPDEEP Position */ -#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ - -#define SCB_SCR_SLEEPONEXIT_Pos 1 /*!< SCB SCR: SLEEPONEXIT Position */ -#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ - -/* SCB Configuration Control Register Definitions */ -#define SCB_CCR_STKALIGN_Pos 9 /*!< SCB CCR: STKALIGN Position */ -#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ - -#define SCB_CCR_UNALIGN_TRP_Pos 3 /*!< SCB CCR: UNALIGN_TRP Position */ -#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ - -/* SCB System Handler Control and State Register Definitions */ -#define SCB_SHCSR_SVCALLPENDED_Pos 15 /*!< SCB SHCSR: SVCALLPENDED Position */ -#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ - -/*@} end of group CMSIS_SCB */ - - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_SysTick System Tick Timer (SysTick) - \brief Type definitions for the System Timer Registers. - @{ - */ - -/** \brief Structure type to access the System Timer (SysTick). - */ -typedef struct -{ - __IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ - __IO uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ - __IO uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ - __I uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ -} SysTick_Type; - -/* SysTick Control / Status Register Definitions */ -#define SysTick_CTRL_COUNTFLAG_Pos 16 /*!< SysTick CTRL: COUNTFLAG Position */ -#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ - -#define SysTick_CTRL_CLKSOURCE_Pos 2 /*!< SysTick CTRL: CLKSOURCE Position */ -#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ - -#define SysTick_CTRL_TICKINT_Pos 1 /*!< SysTick CTRL: TICKINT Position */ -#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ - -#define SysTick_CTRL_ENABLE_Pos 0 /*!< SysTick CTRL: ENABLE Position */ -#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ - -/* SysTick Reload Register Definitions */ -#define SysTick_LOAD_RELOAD_Pos 0 /*!< SysTick LOAD: RELOAD Position */ -#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ - -/* SysTick Current Register Definitions */ -#define SysTick_VAL_CURRENT_Pos 0 /*!< SysTick VAL: CURRENT Position */ -#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ - -/* SysTick Calibration Register Definitions */ -#define SysTick_CALIB_NOREF_Pos 31 /*!< SysTick CALIB: NOREF Position */ -#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ - -#define SysTick_CALIB_SKEW_Pos 30 /*!< SysTick CALIB: SKEW Position */ -#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ - -#define SysTick_CALIB_TENMS_Pos 0 /*!< SysTick CALIB: TENMS Position */ -#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ - -/*@} end of group CMSIS_SysTick */ - -#if (__MPU_PRESENT == 1) -/** \ingroup CMSIS_core_register - \defgroup CMSIS_MPU Memory Protection Unit (MPU) - \brief Type definitions for the Memory Protection Unit (MPU) - @{ - */ - -/** \brief Structure type to access the Memory Protection Unit (MPU). - */ -typedef struct -{ - __I uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ - __IO uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ - __IO uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ - __IO uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ - __IO uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ -} MPU_Type; - -/* MPU Type Register */ -#define MPU_TYPE_IREGION_Pos 16 /*!< MPU TYPE: IREGION Position */ -#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ - -#define MPU_TYPE_DREGION_Pos 8 /*!< MPU TYPE: DREGION Position */ -#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ - -#define MPU_TYPE_SEPARATE_Pos 0 /*!< MPU TYPE: SEPARATE Position */ -#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ - -/* MPU Control Register */ -#define MPU_CTRL_PRIVDEFENA_Pos 2 /*!< MPU CTRL: PRIVDEFENA Position */ -#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ - -#define MPU_CTRL_HFNMIENA_Pos 1 /*!< MPU CTRL: HFNMIENA Position */ -#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ - -#define MPU_CTRL_ENABLE_Pos 0 /*!< MPU CTRL: ENABLE Position */ -#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ - -/* MPU Region Number Register */ -#define MPU_RNR_REGION_Pos 0 /*!< MPU RNR: REGION Position */ -#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ - -/* MPU Region Base Address Register */ -#define MPU_RBAR_ADDR_Pos 8 /*!< MPU RBAR: ADDR Position */ -#define MPU_RBAR_ADDR_Msk (0xFFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ - -#define MPU_RBAR_VALID_Pos 4 /*!< MPU RBAR: VALID Position */ -#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ - -#define MPU_RBAR_REGION_Pos 0 /*!< MPU RBAR: REGION Position */ -#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */ - -/* MPU Region Attribute and Size Register */ -#define MPU_RASR_ATTRS_Pos 16 /*!< MPU RASR: MPU Region Attribute field Position */ -#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ - -#define MPU_RASR_XN_Pos 28 /*!< MPU RASR: ATTRS.XN Position */ -#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ - -#define MPU_RASR_AP_Pos 24 /*!< MPU RASR: ATTRS.AP Position */ -#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ - -#define MPU_RASR_TEX_Pos 19 /*!< MPU RASR: ATTRS.TEX Position */ -#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ - -#define MPU_RASR_S_Pos 18 /*!< MPU RASR: ATTRS.S Position */ -#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ - -#define MPU_RASR_C_Pos 17 /*!< MPU RASR: ATTRS.C Position */ -#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ - -#define MPU_RASR_B_Pos 16 /*!< MPU RASR: ATTRS.B Position */ -#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ - -#define MPU_RASR_SRD_Pos 8 /*!< MPU RASR: Sub-Region Disable Position */ -#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ - -#define MPU_RASR_SIZE_Pos 1 /*!< MPU RASR: Region Size Field Position */ -#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ - -#define MPU_RASR_ENABLE_Pos 0 /*!< MPU RASR: Region enable bit Position */ -#define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */ - -/*@} end of group CMSIS_MPU */ -#endif - - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) - \brief Cortex-M0+ Core Debug Registers (DCB registers, SHCSR, and DFSR) - are only accessible over DAP and not via processor. Therefore - they are not covered by the Cortex-M0 header file. - @{ - */ -/*@} end of group CMSIS_CoreDebug */ - - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_core_base Core Definitions - \brief Definitions for base addresses, unions, and structures. - @{ - */ - -/* Memory mapping of Cortex-M0+ Hardware */ -#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ -#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ -#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ -#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ - -#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ -#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ -#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ - -#if (__MPU_PRESENT == 1) - #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ - #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ -#endif - -/*@} */ - - - -/******************************************************************************* - * Hardware Abstraction Layer - Core Function Interface contains: - - Core NVIC Functions - - Core SysTick Functions - - Core Register Access Functions - ******************************************************************************/ -/** \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference -*/ - - - -/* ########################## NVIC functions #################################### */ -/** \ingroup CMSIS_Core_FunctionInterface - \defgroup CMSIS_Core_NVICFunctions NVIC Functions - \brief Functions that manage interrupts and exceptions via the NVIC. - @{ - */ - -/* Interrupt Priorities are WORD accessible only under ARMv6M */ -/* The following MACROS handle generation of the register offset and byte masks */ -#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL) -#define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) ) -#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) ) - - -/** \brief Enable External Interrupt - - The function enables a device-specific interrupt in the NVIC interrupt controller. - - \param [in] IRQn External interrupt number. Value cannot be negative. - */ -__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn) -{ - NVIC->ISER[0] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); -} - - -/** \brief Disable External Interrupt - - The function disables a device-specific interrupt in the NVIC interrupt controller. - - \param [in] IRQn External interrupt number. Value cannot be negative. - */ -__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn) -{ - NVIC->ICER[0] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); - __DSB(); - __ISB(); -} - - -/** \brief Get Pending Interrupt - - The function reads the pending register in the NVIC and returns the pending bit - for the specified interrupt. - - \param [in] IRQn Interrupt number. - - \return 0 Interrupt status is not pending. - \return 1 Interrupt status is pending. - */ -__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn) -{ - return((uint32_t)(((NVIC->ISPR[0] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); -} - - -/** \brief Set Pending Interrupt - - The function sets the pending bit of an external interrupt. - - \param [in] IRQn Interrupt number. Value cannot be negative. - */ -__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn) -{ - NVIC->ISPR[0] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); -} - - -/** \brief Clear Pending Interrupt - - The function clears the pending bit of an external interrupt. - - \param [in] IRQn External interrupt number. Value cannot be negative. - */ -__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn) -{ - NVIC->ICPR[0] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); -} - - -/** \brief Set Interrupt Priority - - The function sets the priority of an interrupt. - - \note The priority cannot be set for every core interrupt. - - \param [in] IRQn Interrupt number. - \param [in] priority Priority to set. - */ -__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) -{ - if((int32_t)(IRQn) < 0) { - SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | - (((priority << (8 - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); - } - else { - NVIC->IP[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | - (((priority << (8 - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); - } -} - - -/** \brief Get Interrupt Priority - - The function reads the priority of an interrupt. The interrupt - number can be positive to specify an external (device specific) - interrupt, or negative to specify an internal (core) interrupt. - - - \param [in] IRQn Interrupt number. - \return Interrupt Priority. Value is aligned automatically to the implemented - priority bits of the microcontroller. - */ -__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn) -{ - - if((int32_t)(IRQn) < 0) { - return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8 - __NVIC_PRIO_BITS))); - } - else { - return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8 - __NVIC_PRIO_BITS))); - } -} - - -/** \brief System Reset - - The function initiates a system reset request to reset the MCU. - */ -__STATIC_INLINE void NVIC_SystemReset(void) -{ - __DSB(); /* Ensure all outstanding memory accesses included - buffered write are completed before reset */ - SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | - SCB_AIRCR_SYSRESETREQ_Msk); - __DSB(); /* Ensure completion of memory access */ - while(1) { __NOP(); } /* wait until reset */ -} - -/*@} end of CMSIS_Core_NVICFunctions */ - - - -/* ################################## SysTick function ############################################ */ -/** \ingroup CMSIS_Core_FunctionInterface - \defgroup CMSIS_Core_SysTickFunctions SysTick Functions - \brief Functions that configure the System. - @{ - */ - -#if (__Vendor_SysTickConfig == 0) - -/** \brief System Tick Configuration - - The function initializes the System Timer and its interrupt, and starts the System Tick Timer. - Counter is in free running mode to generate periodic interrupts. - - \param [in] ticks Number of ticks between two interrupts. - - \return 0 Function succeeded. - \return 1 Function failed. - - \note When the variable __Vendor_SysTickConfig is set to 1, then the - function SysTick_Config is not included. In this case, the file device.h - must contain a vendor-specific implementation of this function. - - */ -__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) -{ - if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) {return (1UL);} /* Reload value impossible */ - - SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ - NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ - SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ - SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | - SysTick_CTRL_TICKINT_Msk | - SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ - return (0UL); /* Function successful */ -} - -#endif - -/*@} end of CMSIS_Core_SysTickFunctions */ - - - - -#ifdef __cplusplus -} -#endif - -#endif /* __CORE_CM0PLUS_H_DEPENDANT */ - -#endif /* __CMSIS_GENERIC */ diff --git a/cmsis/core_cm3.h b/cmsis/core_cm3.h deleted file mode 100644 index aa43c7e2d1a..00000000000 --- a/cmsis/core_cm3.h +++ /dev/null @@ -1,1732 +0,0 @@ -/**************************************************************************//** - * @file core_cm3.h - * @brief CMSIS Cortex-M3 Core Peripheral Access Layer Header File - * @version V4.10 - * @date 18. March 2015 - * - * @note - * - ******************************************************************************/ -/* Copyright (c) 2009 - 2015 ARM LIMITED - - All rights reserved. - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - Neither the name of ARM nor the names of its contributors may be used - to endorse or promote products derived from this software without - specific prior written permission. - * - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - ---------------------------------------------------------------------------*/ - - -#if defined ( __ICCARM__ ) - #pragma system_include /* treat file as system include file for MISRA check */ -#endif - -#ifndef __CORE_CM3_H_GENERIC -#define __CORE_CM3_H_GENERIC - -#ifdef __cplusplus - extern "C" { -#endif - -/** \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions - CMSIS violates the following MISRA-C:2004 rules: - - \li Required Rule 8.5, object/function definition in header file.
- Function definitions in header files are used to allow 'inlining'. - - \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
- Unions are used for effective representation of core registers. - - \li Advisory Rule 19.7, Function-like macro defined.
- Function-like macros are used to allow more efficient code. - */ - - -/******************************************************************************* - * CMSIS definitions - ******************************************************************************/ -/** \ingroup Cortex_M3 - @{ - */ - -/* CMSIS CM3 definitions */ -#define __CM3_CMSIS_VERSION_MAIN (0x04) /*!< [31:16] CMSIS HAL main version */ -#define __CM3_CMSIS_VERSION_SUB (0x00) /*!< [15:0] CMSIS HAL sub version */ -#define __CM3_CMSIS_VERSION ((__CM3_CMSIS_VERSION_MAIN << 16) | \ - __CM3_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */ - -#define __CORTEX_M (0x03) /*!< Cortex-M Core */ - - -#if defined ( __CC_ARM ) - #define __ASM __asm /*!< asm keyword for ARM Compiler */ - #define __INLINE __inline /*!< inline keyword for ARM Compiler */ - #define __STATIC_INLINE static __inline - -#elif defined ( __GNUC__ ) - #define __ASM __asm /*!< asm keyword for GNU Compiler */ - #define __INLINE inline /*!< inline keyword for GNU Compiler */ - #define __STATIC_INLINE static inline - -#elif defined ( __ICCARM__ ) - #define __ASM __asm /*!< asm keyword for IAR Compiler */ - #define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */ - #define __STATIC_INLINE static inline - -#elif defined ( __TMS470__ ) - #define __ASM __asm /*!< asm keyword for TI CCS Compiler */ - #define __STATIC_INLINE static inline - -#elif defined ( __TASKING__ ) - #define __ASM __asm /*!< asm keyword for TASKING Compiler */ - #define __INLINE inline /*!< inline keyword for TASKING Compiler */ - #define __STATIC_INLINE static inline - -#elif defined ( __CSMC__ ) - #define __packed - #define __ASM _asm /*!< asm keyword for COSMIC Compiler */ - #define __INLINE inline /*use -pc99 on compile line !< inline keyword for COSMIC Compiler */ - #define __STATIC_INLINE static inline - -#endif - -/** __FPU_USED indicates whether an FPU is used or not. - This core does not support an FPU at all -*/ -#define __FPU_USED 0 - -#if defined ( __CC_ARM ) - #if defined __TARGET_FPU_VFP - #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #endif - -#elif defined ( __GNUC__ ) - #if defined (__VFP_FP__) && !defined(__SOFTFP__) - #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #endif - -#elif defined ( __ICCARM__ ) - #if defined __ARMVFP__ - #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #endif - -#elif defined ( __TMS470__ ) - #if defined __TI__VFP_SUPPORT____ - #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #endif - -#elif defined ( __TASKING__ ) - #if defined __FPU_VFP__ - #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #endif - -#elif defined ( __CSMC__ ) /* Cosmic */ - #if ( __CSMC__ & 0x400) // FPU present for parser - #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #endif -#endif - -#include /* standard types definitions */ -#include /* Core Instruction Access */ -#include /* Core Function Access */ - -#ifdef __cplusplus -} -#endif - -#endif /* __CORE_CM3_H_GENERIC */ - -#ifndef __CMSIS_GENERIC - -#ifndef __CORE_CM3_H_DEPENDANT -#define __CORE_CM3_H_DEPENDANT - -#ifdef __cplusplus - extern "C" { -#endif - -/* check device defines and use defaults */ -#if defined __CHECK_DEVICE_DEFINES - #ifndef __CM3_REV - #define __CM3_REV 0x0200 - #warning "__CM3_REV not defined in device header file; using default!" - #endif - - #ifndef __MPU_PRESENT - #define __MPU_PRESENT 0 - #warning "__MPU_PRESENT not defined in device header file; using default!" - #endif - - #ifndef __NVIC_PRIO_BITS - #define __NVIC_PRIO_BITS 4 - #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" - #endif - - #ifndef __Vendor_SysTickConfig - #define __Vendor_SysTickConfig 0 - #warning "__Vendor_SysTickConfig not defined in device header file; using default!" - #endif -#endif - -/* IO definitions (access restrictions to peripheral registers) */ -/** - \defgroup CMSIS_glob_defs CMSIS Global Defines - - IO Type Qualifiers are used - \li to specify the access to peripheral variables. - \li for automatic generation of peripheral register debug information. -*/ -#ifdef __cplusplus - #define __I volatile /*!< Defines 'read only' permissions */ -#else - #define __I volatile const /*!< Defines 'read only' permissions */ -#endif -#define __O volatile /*!< Defines 'write only' permissions */ -#define __IO volatile /*!< Defines 'read / write' permissions */ - -#ifdef __cplusplus - #define __IM volatile /*!< Defines 'read only' permissions */ -#else - #define __IM volatile const /*!< Defines 'read only' permissions */ -#endif -#define __OM volatile /*!< Defines 'write only' permissions */ -#define __IOM volatile /*!< Defines 'read / write' permissions */ - -/*@} end of group Cortex_M3 */ - - - -/******************************************************************************* - * Register Abstraction - Core Register contain: - - Core Register - - Core NVIC Register - - Core SCB Register - - Core SysTick Register - - Core Debug Register - - Core MPU Register - ******************************************************************************/ -/** \defgroup CMSIS_core_register Defines and Type Definitions - \brief Type definitions and defines for Cortex-M processor based devices. -*/ - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_CORE Status and Control Registers - \brief Core Register type definitions. - @{ - */ - -/** \brief Union type to access the Application Program Status Register (APSR). - */ -typedef union -{ - struct - { - uint32_t _reserved0:27; /*!< bit: 0..26 Reserved */ - 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; - -/* APSR Register Definitions */ -#define APSR_N_Pos 31 /*!< APSR: N Position */ -#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ - -#define APSR_Z_Pos 30 /*!< APSR: Z Position */ -#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ - -#define APSR_C_Pos 29 /*!< APSR: C Position */ -#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ - -#define APSR_V_Pos 28 /*!< APSR: V Position */ -#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ - -#define APSR_Q_Pos 27 /*!< APSR: Q Position */ -#define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */ - - -/** \brief Union type to access the Interrupt Program Status Register (IPSR). - */ -typedef union -{ - struct - { - uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ - uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ - } b; /*!< Structure used for bit access */ - uint32_t w; /*!< Type used for word access */ -} IPSR_Type; - -/* IPSR Register Definitions */ -#define IPSR_ISR_Pos 0 /*!< IPSR: ISR Position */ -#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ - - -/** \brief Union type to access the Special-Purpose Program Status Registers (xPSR). - */ -typedef union -{ - struct - { - uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ - uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ - uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ - uint32_t 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; - -/* xPSR Register Definitions */ -#define xPSR_N_Pos 31 /*!< xPSR: N Position */ -#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ - -#define xPSR_Z_Pos 30 /*!< xPSR: Z Position */ -#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ - -#define xPSR_C_Pos 29 /*!< xPSR: C Position */ -#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ - -#define xPSR_V_Pos 28 /*!< xPSR: V Position */ -#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ - -#define xPSR_Q_Pos 27 /*!< xPSR: Q Position */ -#define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */ - -#define xPSR_IT_Pos 25 /*!< xPSR: IT Position */ -#define xPSR_IT_Msk (3UL << xPSR_IT_Pos) /*!< xPSR: IT Mask */ - -#define xPSR_T_Pos 24 /*!< xPSR: T Position */ -#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ - -#define xPSR_ISR_Pos 0 /*!< xPSR: ISR Position */ -#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ - - -/** \brief Union type to access the Control Registers (CONTROL). - */ -typedef union -{ - struct - { - uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ - uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ - uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */ - } b; /*!< Structure used for bit access */ - uint32_t w; /*!< Type used for word access */ -} CONTROL_Type; - -/* CONTROL Register Definitions */ -#define CONTROL_SPSEL_Pos 1 /*!< CONTROL: SPSEL Position */ -#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ - -#define CONTROL_nPRIV_Pos 0 /*!< CONTROL: nPRIV Position */ -#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ - -/*@} end of group CMSIS_CORE */ - - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) - \brief Type definitions for the NVIC Registers - @{ - */ - -/** \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). - */ -typedef struct -{ - __IO uint32_t ISER[8]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ - uint32_t RESERVED0[24]; - __IO uint32_t ICER[8]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ - uint32_t RSERVED1[24]; - __IO uint32_t ISPR[8]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ - uint32_t RESERVED2[24]; - __IO uint32_t ICPR[8]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ - uint32_t RESERVED3[24]; - __IO uint32_t IABR[8]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ - uint32_t RESERVED4[56]; - __IO uint8_t IP[240]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ - uint32_t RESERVED5[644]; - __O uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ -} NVIC_Type; - -/* Software Triggered Interrupt Register Definitions */ -#define NVIC_STIR_INTID_Pos 0 /*!< STIR: INTLINESNUM Position */ -#define NVIC_STIR_INTID_Msk (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/) /*!< STIR: INTLINESNUM Mask */ - -/*@} end of group CMSIS_NVIC */ - - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_SCB System Control Block (SCB) - \brief Type definitions for the System Control Block Registers - @{ - */ - -/** \brief Structure type to access the System Control Block (SCB). - */ -typedef struct -{ - __I uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ - __IO uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ - __IO uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ - __IO uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ - __IO uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ - __IO uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ - __IO uint8_t SHP[12]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ - __IO uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ - __IO uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ - __IO uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ - __IO uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ - __IO uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ - __IO uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ - __IO uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ - __I uint32_t PFR[2]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ - __I uint32_t DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ - __I uint32_t ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ - __I uint32_t MMFR[4]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ - __I uint32_t ISAR[5]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ - uint32_t RESERVED0[5]; - __IO uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ -} SCB_Type; - -/* SCB CPUID Register Definitions */ -#define SCB_CPUID_IMPLEMENTER_Pos 24 /*!< SCB CPUID: IMPLEMENTER Position */ -#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ - -#define SCB_CPUID_VARIANT_Pos 20 /*!< SCB CPUID: VARIANT Position */ -#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ - -#define SCB_CPUID_ARCHITECTURE_Pos 16 /*!< SCB CPUID: ARCHITECTURE Position */ -#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ - -#define SCB_CPUID_PARTNO_Pos 4 /*!< SCB CPUID: PARTNO Position */ -#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ - -#define SCB_CPUID_REVISION_Pos 0 /*!< SCB CPUID: REVISION Position */ -#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ - -/* SCB Interrupt Control State Register Definitions */ -#define SCB_ICSR_NMIPENDSET_Pos 31 /*!< SCB ICSR: NMIPENDSET Position */ -#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ - -#define SCB_ICSR_PENDSVSET_Pos 28 /*!< SCB ICSR: PENDSVSET Position */ -#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ - -#define SCB_ICSR_PENDSVCLR_Pos 27 /*!< SCB ICSR: PENDSVCLR Position */ -#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ - -#define SCB_ICSR_PENDSTSET_Pos 26 /*!< SCB ICSR: PENDSTSET Position */ -#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ - -#define SCB_ICSR_PENDSTCLR_Pos 25 /*!< SCB ICSR: PENDSTCLR Position */ -#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ - -#define SCB_ICSR_ISRPREEMPT_Pos 23 /*!< SCB ICSR: ISRPREEMPT Position */ -#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ - -#define SCB_ICSR_ISRPENDING_Pos 22 /*!< SCB ICSR: ISRPENDING Position */ -#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ - -#define SCB_ICSR_VECTPENDING_Pos 12 /*!< SCB ICSR: VECTPENDING Position */ -#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ - -#define SCB_ICSR_RETTOBASE_Pos 11 /*!< SCB ICSR: RETTOBASE Position */ -#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ - -#define SCB_ICSR_VECTACTIVE_Pos 0 /*!< SCB ICSR: VECTACTIVE Position */ -#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ - -/* SCB Vector Table Offset Register Definitions */ -#if (__CM3_REV < 0x0201) /* core r2p1 */ -#define SCB_VTOR_TBLBASE_Pos 29 /*!< SCB VTOR: TBLBASE Position */ -#define SCB_VTOR_TBLBASE_Msk (1UL << SCB_VTOR_TBLBASE_Pos) /*!< SCB VTOR: TBLBASE Mask */ - -#define SCB_VTOR_TBLOFF_Pos 7 /*!< SCB VTOR: TBLOFF Position */ -#define SCB_VTOR_TBLOFF_Msk (0x3FFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ -#else -#define SCB_VTOR_TBLOFF_Pos 7 /*!< SCB VTOR: TBLOFF Position */ -#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ -#endif - -/* SCB Application Interrupt and Reset Control Register Definitions */ -#define SCB_AIRCR_VECTKEY_Pos 16 /*!< SCB AIRCR: VECTKEY Position */ -#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ - -#define SCB_AIRCR_VECTKEYSTAT_Pos 16 /*!< SCB AIRCR: VECTKEYSTAT Position */ -#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ - -#define SCB_AIRCR_ENDIANESS_Pos 15 /*!< SCB AIRCR: ENDIANESS Position */ -#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ - -#define SCB_AIRCR_PRIGROUP_Pos 8 /*!< SCB AIRCR: PRIGROUP Position */ -#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ - -#define SCB_AIRCR_SYSRESETREQ_Pos 2 /*!< SCB AIRCR: SYSRESETREQ Position */ -#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ - -#define SCB_AIRCR_VECTCLRACTIVE_Pos 1 /*!< SCB AIRCR: VECTCLRACTIVE Position */ -#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ - -#define SCB_AIRCR_VECTRESET_Pos 0 /*!< SCB AIRCR: VECTRESET Position */ -#define SCB_AIRCR_VECTRESET_Msk (1UL /*<< SCB_AIRCR_VECTRESET_Pos*/) /*!< SCB AIRCR: VECTRESET Mask */ - -/* SCB System Control Register Definitions */ -#define SCB_SCR_SEVONPEND_Pos 4 /*!< SCB SCR: SEVONPEND Position */ -#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ - -#define SCB_SCR_SLEEPDEEP_Pos 2 /*!< SCB SCR: SLEEPDEEP Position */ -#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ - -#define SCB_SCR_SLEEPONEXIT_Pos 1 /*!< SCB SCR: SLEEPONEXIT Position */ -#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ - -/* SCB Configuration Control Register Definitions */ -#define SCB_CCR_STKALIGN_Pos 9 /*!< SCB CCR: STKALIGN Position */ -#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ - -#define SCB_CCR_BFHFNMIGN_Pos 8 /*!< SCB CCR: BFHFNMIGN Position */ -#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ - -#define SCB_CCR_DIV_0_TRP_Pos 4 /*!< SCB CCR: DIV_0_TRP Position */ -#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ - -#define SCB_CCR_UNALIGN_TRP_Pos 3 /*!< SCB CCR: UNALIGN_TRP Position */ -#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ - -#define SCB_CCR_USERSETMPEND_Pos 1 /*!< SCB CCR: USERSETMPEND Position */ -#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ - -#define SCB_CCR_NONBASETHRDENA_Pos 0 /*!< SCB CCR: NONBASETHRDENA Position */ -#define SCB_CCR_NONBASETHRDENA_Msk (1UL /*<< SCB_CCR_NONBASETHRDENA_Pos*/) /*!< SCB CCR: NONBASETHRDENA Mask */ - -/* SCB System Handler Control and State Register Definitions */ -#define SCB_SHCSR_USGFAULTENA_Pos 18 /*!< SCB SHCSR: USGFAULTENA Position */ -#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ - -#define SCB_SHCSR_BUSFAULTENA_Pos 17 /*!< SCB SHCSR: BUSFAULTENA Position */ -#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ - -#define SCB_SHCSR_MEMFAULTENA_Pos 16 /*!< SCB SHCSR: MEMFAULTENA Position */ -#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ - -#define SCB_SHCSR_SVCALLPENDED_Pos 15 /*!< SCB SHCSR: SVCALLPENDED Position */ -#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ - -#define SCB_SHCSR_BUSFAULTPENDED_Pos 14 /*!< SCB SHCSR: BUSFAULTPENDED Position */ -#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ - -#define SCB_SHCSR_MEMFAULTPENDED_Pos 13 /*!< SCB SHCSR: MEMFAULTPENDED Position */ -#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ - -#define SCB_SHCSR_USGFAULTPENDED_Pos 12 /*!< SCB SHCSR: USGFAULTPENDED Position */ -#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ - -#define SCB_SHCSR_SYSTICKACT_Pos 11 /*!< SCB SHCSR: SYSTICKACT Position */ -#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ - -#define SCB_SHCSR_PENDSVACT_Pos 10 /*!< SCB SHCSR: PENDSVACT Position */ -#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ - -#define SCB_SHCSR_MONITORACT_Pos 8 /*!< SCB SHCSR: MONITORACT Position */ -#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ - -#define SCB_SHCSR_SVCALLACT_Pos 7 /*!< SCB SHCSR: SVCALLACT Position */ -#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ - -#define SCB_SHCSR_USGFAULTACT_Pos 3 /*!< SCB SHCSR: USGFAULTACT Position */ -#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ - -#define SCB_SHCSR_BUSFAULTACT_Pos 1 /*!< SCB SHCSR: BUSFAULTACT Position */ -#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ - -#define SCB_SHCSR_MEMFAULTACT_Pos 0 /*!< SCB SHCSR: MEMFAULTACT Position */ -#define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */ - -/* SCB Configurable Fault Status Registers Definitions */ -#define SCB_CFSR_USGFAULTSR_Pos 16 /*!< SCB CFSR: Usage Fault Status Register Position */ -#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ - -#define SCB_CFSR_BUSFAULTSR_Pos 8 /*!< SCB CFSR: Bus Fault Status Register Position */ -#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ - -#define SCB_CFSR_MEMFAULTSR_Pos 0 /*!< SCB CFSR: Memory Manage Fault Status Register Position */ -#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ - -/* SCB Hard Fault Status Registers Definitions */ -#define SCB_HFSR_DEBUGEVT_Pos 31 /*!< SCB HFSR: DEBUGEVT Position */ -#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ - -#define SCB_HFSR_FORCED_Pos 30 /*!< SCB HFSR: FORCED Position */ -#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ - -#define SCB_HFSR_VECTTBL_Pos 1 /*!< SCB HFSR: VECTTBL Position */ -#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ - -/* SCB Debug Fault Status Register Definitions */ -#define SCB_DFSR_EXTERNAL_Pos 4 /*!< SCB DFSR: EXTERNAL Position */ -#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ - -#define SCB_DFSR_VCATCH_Pos 3 /*!< SCB DFSR: VCATCH Position */ -#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ - -#define SCB_DFSR_DWTTRAP_Pos 2 /*!< SCB DFSR: DWTTRAP Position */ -#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ - -#define SCB_DFSR_BKPT_Pos 1 /*!< SCB DFSR: BKPT Position */ -#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ - -#define SCB_DFSR_HALTED_Pos 0 /*!< SCB DFSR: HALTED Position */ -#define SCB_DFSR_HALTED_Msk (1UL /*<< SCB_DFSR_HALTED_Pos*/) /*!< SCB DFSR: HALTED Mask */ - -/*@} end of group CMSIS_SCB */ - - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) - \brief Type definitions for the System Control and ID Register not in the SCB - @{ - */ - -/** \brief Structure type to access the System Control and ID Register not in the SCB. - */ -typedef struct -{ - uint32_t RESERVED0[1]; - __I uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ -#if ((defined __CM3_REV) && (__CM3_REV >= 0x200)) - __IO uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ -#else - uint32_t RESERVED1[1]; -#endif -} SCnSCB_Type; - -/* Interrupt Controller Type Register Definitions */ -#define SCnSCB_ICTR_INTLINESNUM_Pos 0 /*!< ICTR: INTLINESNUM Position */ -#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/) /*!< ICTR: INTLINESNUM Mask */ - -/* Auxiliary Control Register Definitions */ - -#define SCnSCB_ACTLR_DISFOLD_Pos 2 /*!< ACTLR: DISFOLD Position */ -#define SCnSCB_ACTLR_DISFOLD_Msk (1UL << SCnSCB_ACTLR_DISFOLD_Pos) /*!< ACTLR: DISFOLD Mask */ - -#define SCnSCB_ACTLR_DISDEFWBUF_Pos 1 /*!< ACTLR: DISDEFWBUF Position */ -#define SCnSCB_ACTLR_DISDEFWBUF_Msk (1UL << SCnSCB_ACTLR_DISDEFWBUF_Pos) /*!< ACTLR: DISDEFWBUF Mask */ - -#define SCnSCB_ACTLR_DISMCYCINT_Pos 0 /*!< ACTLR: DISMCYCINT Position */ -#define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL /*<< SCnSCB_ACTLR_DISMCYCINT_Pos*/) /*!< ACTLR: DISMCYCINT Mask */ - -/*@} end of group CMSIS_SCnotSCB */ - - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_SysTick System Tick Timer (SysTick) - \brief Type definitions for the System Timer Registers. - @{ - */ - -/** \brief Structure type to access the System Timer (SysTick). - */ -typedef struct -{ - __IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ - __IO uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ - __IO uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ - __I uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ -} SysTick_Type; - -/* SysTick Control / Status Register Definitions */ -#define SysTick_CTRL_COUNTFLAG_Pos 16 /*!< SysTick CTRL: COUNTFLAG Position */ -#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ - -#define SysTick_CTRL_CLKSOURCE_Pos 2 /*!< SysTick CTRL: CLKSOURCE Position */ -#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ - -#define SysTick_CTRL_TICKINT_Pos 1 /*!< SysTick CTRL: TICKINT Position */ -#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ - -#define SysTick_CTRL_ENABLE_Pos 0 /*!< SysTick CTRL: ENABLE Position */ -#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ - -/* SysTick Reload Register Definitions */ -#define SysTick_LOAD_RELOAD_Pos 0 /*!< SysTick LOAD: RELOAD Position */ -#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ - -/* SysTick Current Register Definitions */ -#define SysTick_VAL_CURRENT_Pos 0 /*!< SysTick VAL: CURRENT Position */ -#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ - -/* SysTick Calibration Register Definitions */ -#define SysTick_CALIB_NOREF_Pos 31 /*!< SysTick CALIB: NOREF Position */ -#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ - -#define SysTick_CALIB_SKEW_Pos 30 /*!< SysTick CALIB: SKEW Position */ -#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ - -#define SysTick_CALIB_TENMS_Pos 0 /*!< SysTick CALIB: TENMS Position */ -#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ - -/*@} end of group CMSIS_SysTick */ - - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) - \brief Type definitions for the Instrumentation Trace Macrocell (ITM) - @{ - */ - -/** \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). - */ -typedef struct -{ - __O union - { - __O uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ - __O uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ - __O uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ - } PORT [32]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ - uint32_t RESERVED0[864]; - __IO uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ - uint32_t RESERVED1[15]; - __IO uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ - uint32_t RESERVED2[15]; - __IO uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ - uint32_t RESERVED3[29]; - __O uint32_t IWR; /*!< Offset: 0xEF8 ( /W) ITM Integration Write Register */ - __I uint32_t IRR; /*!< Offset: 0xEFC (R/ ) ITM Integration Read Register */ - __IO uint32_t IMCR; /*!< Offset: 0xF00 (R/W) ITM Integration Mode Control Register */ - uint32_t RESERVED4[43]; - __O uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ - __I uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ - uint32_t RESERVED5[6]; - __I uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ - __I uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ - __I uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ - __I uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ - __I uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ - __I uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ - __I uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ - __I uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ - __I uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ - __I uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ - __I uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ - __I uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ -} ITM_Type; - -/* ITM Trace Privilege Register Definitions */ -#define ITM_TPR_PRIVMASK_Pos 0 /*!< ITM TPR: PRIVMASK Position */ -#define ITM_TPR_PRIVMASK_Msk (0xFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ - -/* ITM Trace Control Register Definitions */ -#define ITM_TCR_BUSY_Pos 23 /*!< ITM TCR: BUSY Position */ -#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ - -#define ITM_TCR_TraceBusID_Pos 16 /*!< ITM TCR: ATBID Position */ -#define ITM_TCR_TraceBusID_Msk (0x7FUL << ITM_TCR_TraceBusID_Pos) /*!< ITM TCR: ATBID Mask */ - -#define ITM_TCR_GTSFREQ_Pos 10 /*!< ITM TCR: Global timestamp frequency Position */ -#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ - -#define ITM_TCR_TSPrescale_Pos 8 /*!< ITM TCR: TSPrescale Position */ -#define ITM_TCR_TSPrescale_Msk (3UL << ITM_TCR_TSPrescale_Pos) /*!< ITM TCR: TSPrescale Mask */ - -#define ITM_TCR_SWOENA_Pos 4 /*!< ITM TCR: SWOENA Position */ -#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ - -#define ITM_TCR_DWTENA_Pos 3 /*!< ITM TCR: DWTENA Position */ -#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ - -#define ITM_TCR_SYNCENA_Pos 2 /*!< ITM TCR: SYNCENA Position */ -#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ - -#define ITM_TCR_TSENA_Pos 1 /*!< ITM TCR: TSENA Position */ -#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ - -#define ITM_TCR_ITMENA_Pos 0 /*!< ITM TCR: ITM Enable bit Position */ -#define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */ - -/* ITM Integration Write Register Definitions */ -#define ITM_IWR_ATVALIDM_Pos 0 /*!< ITM IWR: ATVALIDM Position */ -#define ITM_IWR_ATVALIDM_Msk (1UL /*<< ITM_IWR_ATVALIDM_Pos*/) /*!< ITM IWR: ATVALIDM Mask */ - -/* ITM Integration Read Register Definitions */ -#define ITM_IRR_ATREADYM_Pos 0 /*!< ITM IRR: ATREADYM Position */ -#define ITM_IRR_ATREADYM_Msk (1UL /*<< ITM_IRR_ATREADYM_Pos*/) /*!< ITM IRR: ATREADYM Mask */ - -/* ITM Integration Mode Control Register Definitions */ -#define ITM_IMCR_INTEGRATION_Pos 0 /*!< ITM IMCR: INTEGRATION Position */ -#define ITM_IMCR_INTEGRATION_Msk (1UL /*<< ITM_IMCR_INTEGRATION_Pos*/) /*!< ITM IMCR: INTEGRATION Mask */ - -/* ITM Lock Status Register Definitions */ -#define ITM_LSR_ByteAcc_Pos 2 /*!< ITM LSR: ByteAcc Position */ -#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ - -#define ITM_LSR_Access_Pos 1 /*!< ITM LSR: Access Position */ -#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ - -#define ITM_LSR_Present_Pos 0 /*!< ITM LSR: Present Position */ -#define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */ - -/*@}*/ /* end of group CMSIS_ITM */ - - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) - \brief Type definitions for the Data Watchpoint and Trace (DWT) - @{ - */ - -/** \brief Structure type to access the Data Watchpoint and Trace Register (DWT). - */ -typedef struct -{ - __IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ - __IO uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ - __IO uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ - __IO uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ - __IO uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ - __IO uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ - __IO uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ - __I uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ - __IO uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ - __IO uint32_t MASK0; /*!< Offset: 0x024 (R/W) Mask Register 0 */ - __IO uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ - uint32_t RESERVED0[1]; - __IO uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ - __IO uint32_t MASK1; /*!< Offset: 0x034 (R/W) Mask Register 1 */ - __IO uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ - uint32_t RESERVED1[1]; - __IO uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ - __IO uint32_t MASK2; /*!< Offset: 0x044 (R/W) Mask Register 2 */ - __IO uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ - uint32_t RESERVED2[1]; - __IO uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ - __IO uint32_t MASK3; /*!< Offset: 0x054 (R/W) Mask Register 3 */ - __IO uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ -} DWT_Type; - -/* DWT Control Register Definitions */ -#define DWT_CTRL_NUMCOMP_Pos 28 /*!< DWT CTRL: NUMCOMP Position */ -#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ - -#define DWT_CTRL_NOTRCPKT_Pos 27 /*!< DWT CTRL: NOTRCPKT Position */ -#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ - -#define DWT_CTRL_NOEXTTRIG_Pos 26 /*!< DWT CTRL: NOEXTTRIG Position */ -#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ - -#define DWT_CTRL_NOCYCCNT_Pos 25 /*!< DWT CTRL: NOCYCCNT Position */ -#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ - -#define DWT_CTRL_NOPRFCNT_Pos 24 /*!< DWT CTRL: NOPRFCNT Position */ -#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ - -#define DWT_CTRL_CYCEVTENA_Pos 22 /*!< DWT CTRL: CYCEVTENA Position */ -#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ - -#define DWT_CTRL_FOLDEVTENA_Pos 21 /*!< DWT CTRL: FOLDEVTENA Position */ -#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ - -#define DWT_CTRL_LSUEVTENA_Pos 20 /*!< DWT CTRL: LSUEVTENA Position */ -#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ - -#define DWT_CTRL_SLEEPEVTENA_Pos 19 /*!< DWT CTRL: SLEEPEVTENA Position */ -#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ - -#define DWT_CTRL_EXCEVTENA_Pos 18 /*!< DWT CTRL: EXCEVTENA Position */ -#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ - -#define DWT_CTRL_CPIEVTENA_Pos 17 /*!< DWT CTRL: CPIEVTENA Position */ -#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ - -#define DWT_CTRL_EXCTRCENA_Pos 16 /*!< DWT CTRL: EXCTRCENA Position */ -#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ - -#define DWT_CTRL_PCSAMPLENA_Pos 12 /*!< DWT CTRL: PCSAMPLENA Position */ -#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ - -#define DWT_CTRL_SYNCTAP_Pos 10 /*!< DWT CTRL: SYNCTAP Position */ -#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ - -#define DWT_CTRL_CYCTAP_Pos 9 /*!< DWT CTRL: CYCTAP Position */ -#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ - -#define DWT_CTRL_POSTINIT_Pos 5 /*!< DWT CTRL: POSTINIT Position */ -#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ - -#define DWT_CTRL_POSTPRESET_Pos 1 /*!< DWT CTRL: POSTPRESET Position */ -#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ - -#define DWT_CTRL_CYCCNTENA_Pos 0 /*!< DWT CTRL: CYCCNTENA Position */ -#define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */ - -/* DWT CPI Count Register Definitions */ -#define DWT_CPICNT_CPICNT_Pos 0 /*!< DWT CPICNT: CPICNT Position */ -#define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */ - -/* DWT Exception Overhead Count Register Definitions */ -#define DWT_EXCCNT_EXCCNT_Pos 0 /*!< DWT EXCCNT: EXCCNT Position */ -#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */ - -/* DWT Sleep Count Register Definitions */ -#define DWT_SLEEPCNT_SLEEPCNT_Pos 0 /*!< DWT SLEEPCNT: SLEEPCNT Position */ -#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ - -/* DWT LSU Count Register Definitions */ -#define DWT_LSUCNT_LSUCNT_Pos 0 /*!< DWT LSUCNT: LSUCNT Position */ -#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */ - -/* DWT Folded-instruction Count Register Definitions */ -#define DWT_FOLDCNT_FOLDCNT_Pos 0 /*!< DWT FOLDCNT: FOLDCNT Position */ -#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */ - -/* DWT Comparator Mask Register Definitions */ -#define DWT_MASK_MASK_Pos 0 /*!< DWT MASK: MASK Position */ -#define DWT_MASK_MASK_Msk (0x1FUL /*<< DWT_MASK_MASK_Pos*/) /*!< DWT MASK: MASK Mask */ - -/* DWT Comparator Function Register Definitions */ -#define DWT_FUNCTION_MATCHED_Pos 24 /*!< DWT FUNCTION: MATCHED Position */ -#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ - -#define DWT_FUNCTION_DATAVADDR1_Pos 16 /*!< DWT FUNCTION: DATAVADDR1 Position */ -#define DWT_FUNCTION_DATAVADDR1_Msk (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos) /*!< DWT FUNCTION: DATAVADDR1 Mask */ - -#define DWT_FUNCTION_DATAVADDR0_Pos 12 /*!< DWT FUNCTION: DATAVADDR0 Position */ -#define DWT_FUNCTION_DATAVADDR0_Msk (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos) /*!< DWT FUNCTION: DATAVADDR0 Mask */ - -#define DWT_FUNCTION_DATAVSIZE_Pos 10 /*!< DWT FUNCTION: DATAVSIZE Position */ -#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ - -#define DWT_FUNCTION_LNK1ENA_Pos 9 /*!< DWT FUNCTION: LNK1ENA Position */ -#define DWT_FUNCTION_LNK1ENA_Msk (0x1UL << DWT_FUNCTION_LNK1ENA_Pos) /*!< DWT FUNCTION: LNK1ENA Mask */ - -#define DWT_FUNCTION_DATAVMATCH_Pos 8 /*!< DWT FUNCTION: DATAVMATCH Position */ -#define DWT_FUNCTION_DATAVMATCH_Msk (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos) /*!< DWT FUNCTION: DATAVMATCH Mask */ - -#define DWT_FUNCTION_CYCMATCH_Pos 7 /*!< DWT FUNCTION: CYCMATCH Position */ -#define DWT_FUNCTION_CYCMATCH_Msk (0x1UL << DWT_FUNCTION_CYCMATCH_Pos) /*!< DWT FUNCTION: CYCMATCH Mask */ - -#define DWT_FUNCTION_EMITRANGE_Pos 5 /*!< DWT FUNCTION: EMITRANGE Position */ -#define DWT_FUNCTION_EMITRANGE_Msk (0x1UL << DWT_FUNCTION_EMITRANGE_Pos) /*!< DWT FUNCTION: EMITRANGE Mask */ - -#define DWT_FUNCTION_FUNCTION_Pos 0 /*!< DWT FUNCTION: FUNCTION Position */ -#define DWT_FUNCTION_FUNCTION_Msk (0xFUL /*<< DWT_FUNCTION_FUNCTION_Pos*/) /*!< DWT FUNCTION: FUNCTION Mask */ - -/*@}*/ /* end of group CMSIS_DWT */ - - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_TPI Trace Port Interface (TPI) - \brief Type definitions for the Trace Port Interface (TPI) - @{ - */ - -/** \brief Structure type to access the Trace Port Interface Register (TPI). - */ -typedef struct -{ - __IO uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ - __IO uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ - uint32_t RESERVED0[2]; - __IO uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ - uint32_t RESERVED1[55]; - __IO uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ - uint32_t RESERVED2[131]; - __I uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ - __IO uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ - __I uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ - uint32_t RESERVED3[759]; - __I uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER */ - __I uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ - __I uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ - uint32_t RESERVED4[1]; - __I uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */ - __I uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */ - __IO uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ - uint32_t RESERVED5[39]; - __IO uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ - __IO uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ - uint32_t RESERVED7[8]; - __I uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */ - __I uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */ -} TPI_Type; - -/* TPI Asynchronous Clock Prescaler Register Definitions */ -#define TPI_ACPR_PRESCALER_Pos 0 /*!< TPI ACPR: PRESCALER Position */ -#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< TPI ACPR: PRESCALER Mask */ - -/* TPI Selected Pin Protocol Register Definitions */ -#define TPI_SPPR_TXMODE_Pos 0 /*!< TPI SPPR: TXMODE Position */ -#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ - -/* TPI Formatter and Flush Status Register Definitions */ -#define TPI_FFSR_FtNonStop_Pos 3 /*!< TPI FFSR: FtNonStop Position */ -#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ - -#define TPI_FFSR_TCPresent_Pos 2 /*!< TPI FFSR: TCPresent Position */ -#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ - -#define TPI_FFSR_FtStopped_Pos 1 /*!< TPI FFSR: FtStopped Position */ -#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ - -#define TPI_FFSR_FlInProg_Pos 0 /*!< TPI FFSR: FlInProg Position */ -#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ - -/* TPI Formatter and Flush Control Register Definitions */ -#define TPI_FFCR_TrigIn_Pos 8 /*!< TPI FFCR: TrigIn Position */ -#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ - -#define TPI_FFCR_EnFCont_Pos 1 /*!< TPI FFCR: EnFCont Position */ -#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ - -/* TPI TRIGGER Register Definitions */ -#define TPI_TRIGGER_TRIGGER_Pos 0 /*!< TPI TRIGGER: TRIGGER Position */ -#define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */ - -/* TPI Integration ETM Data Register Definitions (FIFO0) */ -#define TPI_FIFO0_ITM_ATVALID_Pos 29 /*!< TPI FIFO0: ITM_ATVALID Position */ -#define TPI_FIFO0_ITM_ATVALID_Msk (0x3UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ - -#define TPI_FIFO0_ITM_bytecount_Pos 27 /*!< TPI FIFO0: ITM_bytecount Position */ -#define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */ - -#define TPI_FIFO0_ETM_ATVALID_Pos 26 /*!< TPI FIFO0: ETM_ATVALID Position */ -#define TPI_FIFO0_ETM_ATVALID_Msk (0x3UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ - -#define TPI_FIFO0_ETM_bytecount_Pos 24 /*!< TPI FIFO0: ETM_bytecount Position */ -#define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */ - -#define TPI_FIFO0_ETM2_Pos 16 /*!< TPI FIFO0: ETM2 Position */ -#define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */ - -#define TPI_FIFO0_ETM1_Pos 8 /*!< TPI FIFO0: ETM1 Position */ -#define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */ - -#define TPI_FIFO0_ETM0_Pos 0 /*!< TPI FIFO0: ETM0 Position */ -#define TPI_FIFO0_ETM0_Msk (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/) /*!< TPI FIFO0: ETM0 Mask */ - -/* TPI ITATBCTR2 Register Definitions */ -#define TPI_ITATBCTR2_ATREADY_Pos 0 /*!< TPI ITATBCTR2: ATREADY Position */ -#define TPI_ITATBCTR2_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY_Pos*/) /*!< TPI ITATBCTR2: ATREADY Mask */ - -/* TPI Integration ITM Data Register Definitions (FIFO1) */ -#define TPI_FIFO1_ITM_ATVALID_Pos 29 /*!< TPI FIFO1: ITM_ATVALID Position */ -#define TPI_FIFO1_ITM_ATVALID_Msk (0x3UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ - -#define TPI_FIFO1_ITM_bytecount_Pos 27 /*!< TPI FIFO1: ITM_bytecount Position */ -#define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */ - -#define TPI_FIFO1_ETM_ATVALID_Pos 26 /*!< TPI FIFO1: ETM_ATVALID Position */ -#define TPI_FIFO1_ETM_ATVALID_Msk (0x3UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ - -#define TPI_FIFO1_ETM_bytecount_Pos 24 /*!< TPI FIFO1: ETM_bytecount Position */ -#define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */ - -#define TPI_FIFO1_ITM2_Pos 16 /*!< TPI FIFO1: ITM2 Position */ -#define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */ - -#define TPI_FIFO1_ITM1_Pos 8 /*!< TPI FIFO1: ITM1 Position */ -#define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */ - -#define TPI_FIFO1_ITM0_Pos 0 /*!< TPI FIFO1: ITM0 Position */ -#define TPI_FIFO1_ITM0_Msk (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/) /*!< TPI FIFO1: ITM0 Mask */ - -/* TPI ITATBCTR0 Register Definitions */ -#define TPI_ITATBCTR0_ATREADY_Pos 0 /*!< TPI ITATBCTR0: ATREADY Position */ -#define TPI_ITATBCTR0_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY_Pos*/) /*!< TPI ITATBCTR0: ATREADY Mask */ - -/* TPI Integration Mode Control Register Definitions */ -#define TPI_ITCTRL_Mode_Pos 0 /*!< TPI ITCTRL: Mode Position */ -#define TPI_ITCTRL_Mode_Msk (0x1UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ - -/* TPI DEVID Register Definitions */ -#define TPI_DEVID_NRZVALID_Pos 11 /*!< TPI DEVID: NRZVALID Position */ -#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ - -#define TPI_DEVID_MANCVALID_Pos 10 /*!< TPI DEVID: MANCVALID Position */ -#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ - -#define TPI_DEVID_PTINVALID_Pos 9 /*!< TPI DEVID: PTINVALID Position */ -#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ - -#define TPI_DEVID_MinBufSz_Pos 6 /*!< TPI DEVID: MinBufSz Position */ -#define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */ - -#define TPI_DEVID_AsynClkIn_Pos 5 /*!< TPI DEVID: AsynClkIn Position */ -#define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */ - -#define TPI_DEVID_NrTraceInput_Pos 0 /*!< TPI DEVID: NrTraceInput Position */ -#define TPI_DEVID_NrTraceInput_Msk (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ - -/* TPI DEVTYPE Register Definitions */ -#define TPI_DEVTYPE_MajorType_Pos 4 /*!< TPI DEVTYPE: MajorType Position */ -#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ - -#define TPI_DEVTYPE_SubType_Pos 0 /*!< TPI DEVTYPE: SubType Position */ -#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ - -/*@}*/ /* end of group CMSIS_TPI */ - - -#if (__MPU_PRESENT == 1) -/** \ingroup CMSIS_core_register - \defgroup CMSIS_MPU Memory Protection Unit (MPU) - \brief Type definitions for the Memory Protection Unit (MPU) - @{ - */ - -/** \brief Structure type to access the Memory Protection Unit (MPU). - */ -typedef struct -{ - __I uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ - __IO uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ - __IO uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ - __IO uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ - __IO uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ - __IO uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Alias 1 Region Base Address Register */ - __IO uint32_t RASR_A1; /*!< Offset: 0x018 (R/W) MPU Alias 1 Region Attribute and Size Register */ - __IO uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Alias 2 Region Base Address Register */ - __IO uint32_t RASR_A2; /*!< Offset: 0x020 (R/W) MPU Alias 2 Region Attribute and Size Register */ - __IO uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Alias 3 Region Base Address Register */ - __IO uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */ -} MPU_Type; - -/* MPU Type Register */ -#define MPU_TYPE_IREGION_Pos 16 /*!< MPU TYPE: IREGION Position */ -#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ - -#define MPU_TYPE_DREGION_Pos 8 /*!< MPU TYPE: DREGION Position */ -#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ - -#define MPU_TYPE_SEPARATE_Pos 0 /*!< MPU TYPE: SEPARATE Position */ -#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ - -/* MPU Control Register */ -#define MPU_CTRL_PRIVDEFENA_Pos 2 /*!< MPU CTRL: PRIVDEFENA Position */ -#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ - -#define MPU_CTRL_HFNMIENA_Pos 1 /*!< MPU CTRL: HFNMIENA Position */ -#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ - -#define MPU_CTRL_ENABLE_Pos 0 /*!< MPU CTRL: ENABLE Position */ -#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ - -/* MPU Region Number Register */ -#define MPU_RNR_REGION_Pos 0 /*!< MPU RNR: REGION Position */ -#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ - -/* MPU Region Base Address Register */ -#define MPU_RBAR_ADDR_Pos 5 /*!< MPU RBAR: ADDR Position */ -#define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ - -#define MPU_RBAR_VALID_Pos 4 /*!< MPU RBAR: VALID Position */ -#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ - -#define MPU_RBAR_REGION_Pos 0 /*!< MPU RBAR: REGION Position */ -#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */ - -/* MPU Region Attribute and Size Register */ -#define MPU_RASR_ATTRS_Pos 16 /*!< MPU RASR: MPU Region Attribute field Position */ -#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ - -#define MPU_RASR_XN_Pos 28 /*!< MPU RASR: ATTRS.XN Position */ -#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ - -#define MPU_RASR_AP_Pos 24 /*!< MPU RASR: ATTRS.AP Position */ -#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ - -#define MPU_RASR_TEX_Pos 19 /*!< MPU RASR: ATTRS.TEX Position */ -#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ - -#define MPU_RASR_S_Pos 18 /*!< MPU RASR: ATTRS.S Position */ -#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ - -#define MPU_RASR_C_Pos 17 /*!< MPU RASR: ATTRS.C Position */ -#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ - -#define MPU_RASR_B_Pos 16 /*!< MPU RASR: ATTRS.B Position */ -#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ - -#define MPU_RASR_SRD_Pos 8 /*!< MPU RASR: Sub-Region Disable Position */ -#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ - -#define MPU_RASR_SIZE_Pos 1 /*!< MPU RASR: Region Size Field Position */ -#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ - -#define MPU_RASR_ENABLE_Pos 0 /*!< MPU RASR: Region enable bit Position */ -#define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */ - -/*@} end of group CMSIS_MPU */ -#endif - - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) - \brief Type definitions for the Core Debug Registers - @{ - */ - -/** \brief Structure type to access the Core Debug Register (CoreDebug). - */ -typedef struct -{ - __IO uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ - __O uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ - __IO uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ - __IO uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ -} CoreDebug_Type; - -/* Debug Halting Control and Status Register */ -#define CoreDebug_DHCSR_DBGKEY_Pos 16 /*!< CoreDebug DHCSR: DBGKEY Position */ -#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ - -#define CoreDebug_DHCSR_S_RESET_ST_Pos 25 /*!< CoreDebug DHCSR: S_RESET_ST Position */ -#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ - -#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24 /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ -#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ - -#define CoreDebug_DHCSR_S_LOCKUP_Pos 19 /*!< CoreDebug DHCSR: S_LOCKUP Position */ -#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ - -#define CoreDebug_DHCSR_S_SLEEP_Pos 18 /*!< CoreDebug DHCSR: S_SLEEP Position */ -#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ - -#define CoreDebug_DHCSR_S_HALT_Pos 17 /*!< CoreDebug DHCSR: S_HALT Position */ -#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ - -#define CoreDebug_DHCSR_S_REGRDY_Pos 16 /*!< CoreDebug DHCSR: S_REGRDY Position */ -#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ - -#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5 /*!< CoreDebug DHCSR: C_SNAPSTALL Position */ -#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */ - -#define CoreDebug_DHCSR_C_MASKINTS_Pos 3 /*!< CoreDebug DHCSR: C_MASKINTS Position */ -#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ - -#define CoreDebug_DHCSR_C_STEP_Pos 2 /*!< CoreDebug DHCSR: C_STEP Position */ -#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ - -#define CoreDebug_DHCSR_C_HALT_Pos 1 /*!< CoreDebug DHCSR: C_HALT Position */ -#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ - -#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0 /*!< CoreDebug DHCSR: C_DEBUGEN Position */ -#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ - -/* Debug Core Register Selector Register */ -#define CoreDebug_DCRSR_REGWnR_Pos 16 /*!< CoreDebug DCRSR: REGWnR Position */ -#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ - -#define CoreDebug_DCRSR_REGSEL_Pos 0 /*!< CoreDebug DCRSR: REGSEL Position */ -#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< CoreDebug DCRSR: REGSEL Mask */ - -/* Debug Exception and Monitor Control Register */ -#define CoreDebug_DEMCR_TRCENA_Pos 24 /*!< CoreDebug DEMCR: TRCENA Position */ -#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ - -#define CoreDebug_DEMCR_MON_REQ_Pos 19 /*!< CoreDebug DEMCR: MON_REQ Position */ -#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */ - -#define CoreDebug_DEMCR_MON_STEP_Pos 18 /*!< CoreDebug DEMCR: MON_STEP Position */ -#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */ - -#define CoreDebug_DEMCR_MON_PEND_Pos 17 /*!< CoreDebug DEMCR: MON_PEND Position */ -#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */ - -#define CoreDebug_DEMCR_MON_EN_Pos 16 /*!< CoreDebug DEMCR: MON_EN Position */ -#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */ - -#define CoreDebug_DEMCR_VC_HARDERR_Pos 10 /*!< CoreDebug DEMCR: VC_HARDERR Position */ -#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ - -#define CoreDebug_DEMCR_VC_INTERR_Pos 9 /*!< CoreDebug DEMCR: VC_INTERR Position */ -#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */ - -#define CoreDebug_DEMCR_VC_BUSERR_Pos 8 /*!< CoreDebug DEMCR: VC_BUSERR Position */ -#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */ - -#define CoreDebug_DEMCR_VC_STATERR_Pos 7 /*!< CoreDebug DEMCR: VC_STATERR Position */ -#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */ - -#define CoreDebug_DEMCR_VC_CHKERR_Pos 6 /*!< CoreDebug DEMCR: VC_CHKERR Position */ -#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */ - -#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5 /*!< CoreDebug DEMCR: VC_NOCPERR Position */ -#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */ - -#define CoreDebug_DEMCR_VC_MMERR_Pos 4 /*!< CoreDebug DEMCR: VC_MMERR Position */ -#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */ - -#define CoreDebug_DEMCR_VC_CORERESET_Pos 0 /*!< CoreDebug DEMCR: VC_CORERESET Position */ -#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ - -/*@} end of group CMSIS_CoreDebug */ - - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_core_base Core Definitions - \brief Definitions for base addresses, unions, and structures. - @{ - */ - -/* Memory mapping of Cortex-M3 Hardware */ -#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ -#define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ -#define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ -#define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ -#define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ -#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ -#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ -#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ - -#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ -#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ -#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ -#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ -#define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ -#define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ -#define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ -#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */ - -#if (__MPU_PRESENT == 1) - #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ - #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ -#endif - -/*@} */ - - - -/******************************************************************************* - * Hardware Abstraction Layer - Core Function Interface contains: - - Core NVIC Functions - - Core SysTick Functions - - Core Debug Functions - - Core Register Access Functions - ******************************************************************************/ -/** \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference -*/ - - - -/* ########################## NVIC functions #################################### */ -/** \ingroup CMSIS_Core_FunctionInterface - \defgroup CMSIS_Core_NVICFunctions NVIC Functions - \brief Functions that manage interrupts and exceptions via the NVIC. - @{ - */ - -#ifdef CMSIS_NVIC_VIRTUAL - #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE - #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" - #endif - #include CMSIS_NVIC_VIRTUAL_HEADER_FILE -#else - #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping - #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping - #define NVIC_EnableIRQ __NVIC_EnableIRQ - #define NVIC_DisableIRQ __NVIC_DisableIRQ - #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ - #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ - #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ - #define NVIC_GetActive __NVIC_GetActive - #define NVIC_SetPriority __NVIC_SetPriority - #define NVIC_GetPriority __NVIC_GetPriority - #define NVIC_SystemReset __NVIC_SystemReset -#endif /* CMSIS_NVIC_VIRTUAL */ - -#ifdef CMSIS_VECTAB_VIRTUAL - #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE - #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" - #endif - #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE -#else - #define NVIC_SetVector __NVIC_SetVector - #define NVIC_GetVector __NVIC_GetVector -#endif /* CMSIS_VECTAB_VIRTUAL */ - -/** \brief Set Priority Grouping - - The function sets the priority grouping field using the required unlock sequence. - The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. - Only values from 0..7 are used. - In case of a conflict between priority grouping and available - priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. - - \param [in] PriorityGroup Priority grouping field. - */ -__STATIC_INLINE void __NVIC_SetPriorityGrouping(uint32_t PriorityGroup) -{ - uint32_t reg_value; - uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ - - reg_value = SCB->AIRCR; /* read old register configuration */ - reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ - reg_value = (reg_value | - ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | - (PriorityGroupTmp << 8) ); /* Insert write key and priorty group */ - SCB->AIRCR = reg_value; -} - - -/** \brief Get Priority Grouping - - The function reads the priority grouping field from the NVIC Interrupt Controller. - - \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). - */ -__STATIC_INLINE uint32_t __NVIC_GetPriorityGrouping(void) -{ - return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); -} - - -/** \brief Enable External Interrupt - - The function enables a device-specific interrupt in the NVIC interrupt controller. - - \param [in] IRQn External interrupt number. Value cannot be negative. - */ -__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) -{ - NVIC->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); -} - - -/** \brief Disable External Interrupt - - The function disables a device-specific interrupt in the NVIC interrupt controller. - - \param [in] IRQn External interrupt number. Value cannot be negative. - */ -__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) -{ - NVIC->ICER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); - __DSB(); - __ISB(); -} - - -/** \brief Get Pending Interrupt - - The function reads the pending register in the NVIC and returns the pending bit - for the specified interrupt. - - \param [in] IRQn Interrupt number. - - \return 0 Interrupt status is not pending. - \return 1 Interrupt status is pending. - */ -__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) -{ - return((uint32_t)(((NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); -} - - -/** \brief Set Pending Interrupt - - The function sets the pending bit of an external interrupt. - - \param [in] IRQn Interrupt number. Value cannot be negative. - */ -__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) -{ - NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); -} - - -/** \brief Clear Pending Interrupt - - The function clears the pending bit of an external interrupt. - - \param [in] IRQn External interrupt number. Value cannot be negative. - */ -__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) -{ - NVIC->ICPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); -} - - -/** \brief Get Active Interrupt - - The function reads the active register in NVIC and returns the active bit. - - \param [in] IRQn Interrupt number. - - \return 0 Interrupt status is not active. - \return 1 Interrupt status is active. - */ -__STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) -{ - return((uint32_t)(((NVIC->IABR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); -} - - -/** \brief Set Interrupt Priority - - The function sets the priority of an interrupt. - - \note The priority cannot be set for every core interrupt. - - \param [in] IRQn Interrupt number. - \param [in] priority Priority to set. - */ -__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) -{ - if((int32_t)IRQn < 0) { - SCB->SHP[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8 - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); - } - else { - NVIC->IP[((uint32_t)(int32_t)IRQn)] = (uint8_t)((priority << (8 - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); - } -} - - -/** \brief Get Interrupt Priority - - The function reads the priority of an interrupt. The interrupt - number can be positive to specify an external (device specific) - interrupt, or negative to specify an internal (core) interrupt. - - - \param [in] IRQn Interrupt number. - \return Interrupt Priority. Value is aligned automatically to the implemented - priority bits of the microcontroller. - */ -__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) -{ - - if((int32_t)IRQn < 0) { - return(((uint32_t)SCB->SHP[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] >> (8 - __NVIC_PRIO_BITS))); - } - else { - return(((uint32_t)NVIC->IP[((uint32_t)(int32_t)IRQn)] >> (8 - __NVIC_PRIO_BITS))); - } -} - - -/** \brief Encode Priority - - The function encodes the priority for an interrupt with the given priority group, - preemptive priority value, and subpriority value. - In case of a conflict between priority grouping and available - priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. - - \param [in] PriorityGroup Used priority group. - \param [in] PreemptPriority Preemptive priority value (starting from 0). - \param [in] SubPriority Subpriority value (starting from 0). - \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). - */ -__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) -{ - uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ - uint32_t PreemptPriorityBits; - uint32_t SubPriorityBits; - - PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); - SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); - - return ( - ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | - ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) - ); -} - - -/** \brief Decode Priority - - The function decodes an interrupt priority value with a given priority group to - preemptive priority value and subpriority value. - In case of a conflict between priority grouping and available - priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. - - \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). - \param [in] PriorityGroup Used priority group. - \param [out] pPreemptPriority Preemptive priority value (starting from 0). - \param [out] pSubPriority Subpriority value (starting from 0). - */ -__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* pPreemptPriority, uint32_t* pSubPriority) -{ - uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ - uint32_t PreemptPriorityBits; - uint32_t SubPriorityBits; - - PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); - SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); - - *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); - *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); -} - - -/** \brief System Reset - - The function initiates a system reset request to reset the MCU. - */ -__STATIC_INLINE void __NVIC_SystemReset(void) -{ - __DSB(); /* Ensure all outstanding memory accesses included - buffered write are completed before reset */ - SCB->AIRCR = (uint32_t)((0x5FAUL << 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) { __NOP(); } /* wait until reset */ -} - -/*@} end of CMSIS_Core_NVICFunctions */ - - - -/* ################################## SysTick function ############################################ */ -/** \ingroup CMSIS_Core_FunctionInterface - \defgroup CMSIS_Core_SysTickFunctions SysTick Functions - \brief Functions that configure the System. - @{ - */ - -#if (__Vendor_SysTickConfig == 0) - -/** \brief System Tick Configuration - - The function initializes the System Timer and its interrupt, and starts the System Tick Timer. - Counter is in free running mode to generate periodic interrupts. - - \param [in] ticks Number of ticks between two interrupts. - - \return 0 Function succeeded. - \return 1 Function failed. - - \note When the variable __Vendor_SysTickConfig is set to 1, then the - function SysTick_Config is not included. In this case, the file device.h - must contain a vendor-specific implementation of this function. - - */ -__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) -{ - if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) { return (1UL); } /* Reload value impossible */ - - SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ - NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ - SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ - SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | - SysTick_CTRL_TICKINT_Msk | - SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ - return (0UL); /* Function successful */ -} - -#endif - -/*@} end of CMSIS_Core_SysTickFunctions */ - - - -/* ##################################### Debug In/Output function ########################################### */ -/** \ingroup CMSIS_Core_FunctionInterface - \defgroup CMSIS_core_DebugFunctions ITM Functions - \brief Functions that access the ITM debug interface. - @{ - */ - -extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ -#define ITM_RXBUFFER_EMPTY 0x5AA55AA5 /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ - - -/** \brief ITM Send Character - - The function transmits a character via the ITM channel 0, and - \li Just returns when no debugger is connected that has booked the output. - \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. - - \param [in] ch Character to transmit. - - \returns Character to transmit. - */ -__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) -{ - if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ - ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */ - { - while (ITM->PORT[0].u32 == 0UL) { __NOP(); } - ITM->PORT[0].u8 = (uint8_t)ch; - } - return (ch); -} - - -/** \brief ITM Receive Character - - The function inputs a character via the external variable \ref ITM_RxBuffer. - - \return Received character. - \return -1 No character pending. - */ -__STATIC_INLINE int32_t ITM_ReceiveChar (void) { - int32_t ch = -1; /* no character available */ - - if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) { - ch = ITM_RxBuffer; - ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ - } - - return (ch); -} - - -/** \brief ITM Check Character - - The function checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. - - \return 0 No character available. - \return 1 Character available. - */ -__STATIC_INLINE int32_t ITM_CheckChar (void) { - - if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) { - return (0); /* no character available */ - } else { - return (1); /* character available */ - } -} - -/*@} end of CMSIS_core_DebugFunctions */ - - - - -#ifdef __cplusplus -} -#endif - -#endif /* __CORE_CM3_H_DEPENDANT */ - -#endif /* __CMSIS_GENERIC */ diff --git a/cmsis/core_cm4.h b/cmsis/core_cm4.h deleted file mode 100644 index 29e814496d5..00000000000 --- a/cmsis/core_cm4.h +++ /dev/null @@ -1,1898 +0,0 @@ -/**************************************************************************//** - * @file core_cm4.h - * @brief CMSIS Cortex-M4 Core Peripheral Access Layer Header File - * @version V4.10 - * @date 18. March 2015 - * - * @note - * - ******************************************************************************/ -/* Copyright (c) 2009 - 2015 ARM LIMITED - - All rights reserved. - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - Neither the name of ARM nor the names of its contributors may be used - to endorse or promote products derived from this software without - specific prior written permission. - * - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - ---------------------------------------------------------------------------*/ - - -#if defined ( __ICCARM__ ) - #pragma system_include /* treat file as system include file for MISRA check */ -#endif - -#ifndef __CORE_CM4_H_GENERIC -#define __CORE_CM4_H_GENERIC - -#ifdef __cplusplus - extern "C" { -#endif - -/** \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions - CMSIS violates the following MISRA-C:2004 rules: - - \li Required Rule 8.5, object/function definition in header file.
- Function definitions in header files are used to allow 'inlining'. - - \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
- Unions are used for effective representation of core registers. - - \li Advisory Rule 19.7, Function-like macro defined.
- Function-like macros are used to allow more efficient code. - */ - - -/******************************************************************************* - * CMSIS definitions - ******************************************************************************/ -/** \ingroup Cortex_M4 - @{ - */ - -/* CMSIS CM4 definitions */ -#define __CM4_CMSIS_VERSION_MAIN (0x04) /*!< [31:16] CMSIS HAL main version */ -#define __CM4_CMSIS_VERSION_SUB (0x00) /*!< [15:0] CMSIS HAL sub version */ -#define __CM4_CMSIS_VERSION ((__CM4_CMSIS_VERSION_MAIN << 16) | \ - __CM4_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */ - -#define __CORTEX_M (0x04) /*!< Cortex-M Core */ - - -#if defined ( __CC_ARM ) - #define __ASM __asm /*!< asm keyword for ARM Compiler */ - #define __INLINE __inline /*!< inline keyword for ARM Compiler */ - #define __STATIC_INLINE static __inline - -#elif defined ( __GNUC__ ) - #define __ASM __asm /*!< asm keyword for GNU Compiler */ - #define __INLINE inline /*!< inline keyword for GNU Compiler */ - #define __STATIC_INLINE static inline - -#elif defined ( __ICCARM__ ) - #define __ASM __asm /*!< asm keyword for IAR Compiler */ - #define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */ - #define __STATIC_INLINE static inline - -#elif defined ( __TMS470__ ) - #define __ASM __asm /*!< asm keyword for TI CCS Compiler */ - #define __STATIC_INLINE static inline - -#elif defined ( __TASKING__ ) - #define __ASM __asm /*!< asm keyword for TASKING Compiler */ - #define __INLINE inline /*!< inline keyword for TASKING Compiler */ - #define __STATIC_INLINE static inline - -#elif defined ( __CSMC__ ) - #define __packed - #define __ASM _asm /*!< asm keyword for COSMIC Compiler */ - #define __INLINE inline /*use -pc99 on compile line !< inline keyword for COSMIC Compiler */ - #define __STATIC_INLINE static inline - -#endif - -/** __FPU_USED indicates whether an FPU is used or not. - For this, __FPU_PRESENT has to be checked prior to making use of FPU specific registers and functions. -*/ -#if defined ( __CC_ARM ) - #if defined __TARGET_FPU_VFP - #if (__FPU_PRESENT == 1) - #define __FPU_USED 1 - #else - #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #define __FPU_USED 0 - #endif - #else - #define __FPU_USED 0 - #endif - -#elif defined ( __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 ( __ICCARM__ ) - #if defined __ARMVFP__ - #if (__FPU_PRESENT == 1) - #define __FPU_USED 1 - #else - #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #define __FPU_USED 0 - #endif - #else - #define __FPU_USED 0 - #endif - -#elif defined ( __TMS470__ ) - #if defined __TI_VFP_SUPPORT__ - #if (__FPU_PRESENT == 1) - #define __FPU_USED 1 - #else - #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #define __FPU_USED 0 - #endif - #else - #define __FPU_USED 0 - #endif - -#elif defined ( __TASKING__ ) - #if defined __FPU_VFP__ - #if (__FPU_PRESENT == 1) - #define __FPU_USED 1 - #else - #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #define __FPU_USED 0 - #endif - #else - #define __FPU_USED 0 - #endif - -#elif defined ( __CSMC__ ) /* Cosmic */ - #if ( __CSMC__ & 0x400) // FPU present for parser - #if (__FPU_PRESENT == 1) - #define __FPU_USED 1 - #else - #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #define __FPU_USED 0 - #endif - #else - #define __FPU_USED 0 - #endif -#endif - -#include /* standard types definitions */ -#include /* Core Instruction Access */ -#include /* Core Function Access */ -#include /* Compiler specific SIMD Intrinsics */ - -#ifdef __cplusplus -} -#endif - -#endif /* __CORE_CM4_H_GENERIC */ - -#ifndef __CMSIS_GENERIC - -#ifndef __CORE_CM4_H_DEPENDANT -#define __CORE_CM4_H_DEPENDANT - -#ifdef __cplusplus - extern "C" { -#endif - -/* check device defines and use defaults */ -#if defined __CHECK_DEVICE_DEFINES - #ifndef __CM4_REV - #define __CM4_REV 0x0000 - #warning "__CM4_REV not defined in device header file; using default!" - #endif - - #ifndef __FPU_PRESENT - #define __FPU_PRESENT 0 - #warning "__FPU_PRESENT not defined in device header file; using default!" - #endif - - #ifndef __MPU_PRESENT - #define __MPU_PRESENT 0 - #warning "__MPU_PRESENT not defined in device header file; using default!" - #endif - - #ifndef __NVIC_PRIO_BITS - #define __NVIC_PRIO_BITS 4 - #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" - #endif - - #ifndef __Vendor_SysTickConfig - #define __Vendor_SysTickConfig 0 - #warning "__Vendor_SysTickConfig not defined in device header file; using default!" - #endif -#endif - -/* IO definitions (access restrictions to peripheral registers) */ -/** - \defgroup CMSIS_glob_defs CMSIS Global Defines - - IO Type Qualifiers are used - \li to specify the access to peripheral variables. - \li for automatic generation of peripheral register debug information. -*/ -#ifdef __cplusplus - #define __I volatile /*!< Defines 'read only' permissions */ -#else - #define __I volatile const /*!< Defines 'read only' permissions */ -#endif -#define __O volatile /*!< Defines 'write only' permissions */ -#define __IO volatile /*!< Defines 'read / write' permissions */ - -#ifdef __cplusplus - #define __IM volatile /*!< Defines 'read only' permissions */ -#else - #define __IM volatile const /*!< Defines 'read only' permissions */ -#endif -#define __OM volatile /*!< Defines 'write only' permissions */ -#define __IOM volatile /*!< Defines 'read / write' permissions */ - -/*@} end of group Cortex_M4 */ - - - -/******************************************************************************* - * Register Abstraction - Core Register contain: - - Core Register - - Core NVIC Register - - Core SCB Register - - Core SysTick Register - - Core Debug Register - - Core MPU Register - - Core FPU Register - ******************************************************************************/ -/** \defgroup CMSIS_core_register Defines and Type Definitions - \brief Type definitions and defines for Cortex-M processor based devices. -*/ - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_CORE Status and Control Registers - \brief Core Register type definitions. - @{ - */ - -/** \brief Union type to access the Application Program Status Register (APSR). - */ -typedef union -{ - struct - { - 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 */ - 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; - -/* APSR Register Definitions */ -#define APSR_N_Pos 31 /*!< APSR: N Position */ -#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ - -#define APSR_Z_Pos 30 /*!< APSR: Z Position */ -#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ - -#define APSR_C_Pos 29 /*!< APSR: C Position */ -#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ - -#define APSR_V_Pos 28 /*!< APSR: V Position */ -#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ - -#define APSR_Q_Pos 27 /*!< APSR: Q Position */ -#define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */ - -#define APSR_GE_Pos 16 /*!< APSR: GE Position */ -#define APSR_GE_Msk (0xFUL << APSR_GE_Pos) /*!< APSR: GE Mask */ - - -/** \brief Union type to access the Interrupt Program Status Register (IPSR). - */ -typedef union -{ - struct - { - uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ - uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ - } b; /*!< Structure used for bit access */ - uint32_t w; /*!< Type used for word access */ -} IPSR_Type; - -/* IPSR Register Definitions */ -#define IPSR_ISR_Pos 0 /*!< IPSR: ISR Position */ -#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ - - -/** \brief Union type to access the Special-Purpose Program Status Registers (xPSR). - */ -typedef union -{ - struct - { - uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ - uint32_t _reserved0: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 */ - 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; - -/* xPSR Register Definitions */ -#define xPSR_N_Pos 31 /*!< xPSR: N Position */ -#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ - -#define xPSR_Z_Pos 30 /*!< xPSR: Z Position */ -#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ - -#define xPSR_C_Pos 29 /*!< xPSR: C Position */ -#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ - -#define xPSR_V_Pos 28 /*!< xPSR: V Position */ -#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ - -#define xPSR_Q_Pos 27 /*!< xPSR: Q Position */ -#define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */ - -#define xPSR_IT_Pos 25 /*!< xPSR: IT Position */ -#define xPSR_IT_Msk (3UL << xPSR_IT_Pos) /*!< xPSR: IT Mask */ - -#define xPSR_T_Pos 24 /*!< xPSR: T Position */ -#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ - -#define xPSR_GE_Pos 16 /*!< xPSR: GE Position */ -#define xPSR_GE_Msk (0xFUL << xPSR_GE_Pos) /*!< xPSR: GE Mask */ - -#define xPSR_ISR_Pos 0 /*!< xPSR: ISR Position */ -#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ - - -/** \brief Union type to access the Control Registers (CONTROL). - */ -typedef union -{ - struct - { - uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ - uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ - uint32_t 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; - -/* CONTROL Register Definitions */ -#define CONTROL_FPCA_Pos 2 /*!< CONTROL: FPCA Position */ -#define CONTROL_FPCA_Msk (1UL << CONTROL_FPCA_Pos) /*!< CONTROL: FPCA Mask */ - -#define CONTROL_SPSEL_Pos 1 /*!< CONTROL: SPSEL Position */ -#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ - -#define CONTROL_nPRIV_Pos 0 /*!< CONTROL: nPRIV Position */ -#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ - -/*@} end of group CMSIS_CORE */ - - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) - \brief Type definitions for the NVIC Registers - @{ - */ - -/** \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). - */ -typedef struct -{ - __IO uint32_t ISER[8]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ - uint32_t RESERVED0[24]; - __IO uint32_t ICER[8]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ - uint32_t RSERVED1[24]; - __IO uint32_t ISPR[8]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ - uint32_t RESERVED2[24]; - __IO uint32_t ICPR[8]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ - uint32_t RESERVED3[24]; - __IO uint32_t IABR[8]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ - uint32_t RESERVED4[56]; - __IO uint8_t IP[240]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ - uint32_t RESERVED5[644]; - __O uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ -} NVIC_Type; - -/* Software Triggered Interrupt Register Definitions */ -#define NVIC_STIR_INTID_Pos 0 /*!< STIR: INTLINESNUM Position */ -#define NVIC_STIR_INTID_Msk (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/) /*!< STIR: INTLINESNUM Mask */ - -/*@} end of group CMSIS_NVIC */ - - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_SCB System Control Block (SCB) - \brief Type definitions for the System Control Block Registers - @{ - */ - -/** \brief Structure type to access the System Control Block (SCB). - */ -typedef struct -{ - __I uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ - __IO uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ - __IO uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ - __IO uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ - __IO uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ - __IO uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ - __IO uint8_t SHP[12]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ - __IO uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ - __IO uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ - __IO uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ - __IO uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ - __IO uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ - __IO uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ - __IO uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ - __I uint32_t PFR[2]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ - __I uint32_t DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ - __I uint32_t ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ - __I uint32_t MMFR[4]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ - __I uint32_t ISAR[5]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ - uint32_t RESERVED0[5]; - __IO uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ -} SCB_Type; - -/* SCB CPUID Register Definitions */ -#define SCB_CPUID_IMPLEMENTER_Pos 24 /*!< SCB CPUID: IMPLEMENTER Position */ -#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ - -#define SCB_CPUID_VARIANT_Pos 20 /*!< SCB CPUID: VARIANT Position */ -#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ - -#define SCB_CPUID_ARCHITECTURE_Pos 16 /*!< SCB CPUID: ARCHITECTURE Position */ -#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ - -#define SCB_CPUID_PARTNO_Pos 4 /*!< SCB CPUID: PARTNO Position */ -#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ - -#define SCB_CPUID_REVISION_Pos 0 /*!< SCB CPUID: REVISION Position */ -#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ - -/* SCB Interrupt Control State Register Definitions */ -#define SCB_ICSR_NMIPENDSET_Pos 31 /*!< SCB ICSR: NMIPENDSET Position */ -#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ - -#define SCB_ICSR_PENDSVSET_Pos 28 /*!< SCB ICSR: PENDSVSET Position */ -#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ - -#define SCB_ICSR_PENDSVCLR_Pos 27 /*!< SCB ICSR: PENDSVCLR Position */ -#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ - -#define SCB_ICSR_PENDSTSET_Pos 26 /*!< SCB ICSR: PENDSTSET Position */ -#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ - -#define SCB_ICSR_PENDSTCLR_Pos 25 /*!< SCB ICSR: PENDSTCLR Position */ -#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ - -#define SCB_ICSR_ISRPREEMPT_Pos 23 /*!< SCB ICSR: ISRPREEMPT Position */ -#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ - -#define SCB_ICSR_ISRPENDING_Pos 22 /*!< SCB ICSR: ISRPENDING Position */ -#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ - -#define SCB_ICSR_VECTPENDING_Pos 12 /*!< SCB ICSR: VECTPENDING Position */ -#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ - -#define SCB_ICSR_RETTOBASE_Pos 11 /*!< SCB ICSR: RETTOBASE Position */ -#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ - -#define SCB_ICSR_VECTACTIVE_Pos 0 /*!< SCB ICSR: VECTACTIVE Position */ -#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ - -/* SCB Vector Table Offset Register Definitions */ -#define SCB_VTOR_TBLOFF_Pos 7 /*!< SCB VTOR: TBLOFF Position */ -#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ - -/* SCB Application Interrupt and Reset Control Register Definitions */ -#define SCB_AIRCR_VECTKEY_Pos 16 /*!< SCB AIRCR: VECTKEY Position */ -#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ - -#define SCB_AIRCR_VECTKEYSTAT_Pos 16 /*!< SCB AIRCR: VECTKEYSTAT Position */ -#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ - -#define SCB_AIRCR_ENDIANESS_Pos 15 /*!< SCB AIRCR: ENDIANESS Position */ -#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ - -#define SCB_AIRCR_PRIGROUP_Pos 8 /*!< SCB AIRCR: PRIGROUP Position */ -#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ - -#define SCB_AIRCR_SYSRESETREQ_Pos 2 /*!< SCB AIRCR: SYSRESETREQ Position */ -#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ - -#define SCB_AIRCR_VECTCLRACTIVE_Pos 1 /*!< SCB AIRCR: VECTCLRACTIVE Position */ -#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ - -#define SCB_AIRCR_VECTRESET_Pos 0 /*!< SCB AIRCR: VECTRESET Position */ -#define SCB_AIRCR_VECTRESET_Msk (1UL /*<< SCB_AIRCR_VECTRESET_Pos*/) /*!< SCB AIRCR: VECTRESET Mask */ - -/* SCB System Control Register Definitions */ -#define SCB_SCR_SEVONPEND_Pos 4 /*!< SCB SCR: SEVONPEND Position */ -#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ - -#define SCB_SCR_SLEEPDEEP_Pos 2 /*!< SCB SCR: SLEEPDEEP Position */ -#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ - -#define SCB_SCR_SLEEPONEXIT_Pos 1 /*!< SCB SCR: SLEEPONEXIT Position */ -#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ - -/* SCB Configuration Control Register Definitions */ -#define SCB_CCR_STKALIGN_Pos 9 /*!< SCB CCR: STKALIGN Position */ -#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ - -#define SCB_CCR_BFHFNMIGN_Pos 8 /*!< SCB CCR: BFHFNMIGN Position */ -#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ - -#define SCB_CCR_DIV_0_TRP_Pos 4 /*!< SCB CCR: DIV_0_TRP Position */ -#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ - -#define SCB_CCR_UNALIGN_TRP_Pos 3 /*!< SCB CCR: UNALIGN_TRP Position */ -#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ - -#define SCB_CCR_USERSETMPEND_Pos 1 /*!< SCB CCR: USERSETMPEND Position */ -#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ - -#define SCB_CCR_NONBASETHRDENA_Pos 0 /*!< SCB CCR: NONBASETHRDENA Position */ -#define SCB_CCR_NONBASETHRDENA_Msk (1UL /*<< SCB_CCR_NONBASETHRDENA_Pos*/) /*!< SCB CCR: NONBASETHRDENA Mask */ - -/* SCB System Handler Control and State Register Definitions */ -#define SCB_SHCSR_USGFAULTENA_Pos 18 /*!< SCB SHCSR: USGFAULTENA Position */ -#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ - -#define SCB_SHCSR_BUSFAULTENA_Pos 17 /*!< SCB SHCSR: BUSFAULTENA Position */ -#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ - -#define SCB_SHCSR_MEMFAULTENA_Pos 16 /*!< SCB SHCSR: MEMFAULTENA Position */ -#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ - -#define SCB_SHCSR_SVCALLPENDED_Pos 15 /*!< SCB SHCSR: SVCALLPENDED Position */ -#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ - -#define SCB_SHCSR_BUSFAULTPENDED_Pos 14 /*!< SCB SHCSR: BUSFAULTPENDED Position */ -#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ - -#define SCB_SHCSR_MEMFAULTPENDED_Pos 13 /*!< SCB SHCSR: MEMFAULTPENDED Position */ -#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ - -#define SCB_SHCSR_USGFAULTPENDED_Pos 12 /*!< SCB SHCSR: USGFAULTPENDED Position */ -#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ - -#define SCB_SHCSR_SYSTICKACT_Pos 11 /*!< SCB SHCSR: SYSTICKACT Position */ -#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ - -#define SCB_SHCSR_PENDSVACT_Pos 10 /*!< SCB SHCSR: PENDSVACT Position */ -#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ - -#define SCB_SHCSR_MONITORACT_Pos 8 /*!< SCB SHCSR: MONITORACT Position */ -#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ - -#define SCB_SHCSR_SVCALLACT_Pos 7 /*!< SCB SHCSR: SVCALLACT Position */ -#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ - -#define SCB_SHCSR_USGFAULTACT_Pos 3 /*!< SCB SHCSR: USGFAULTACT Position */ -#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ - -#define SCB_SHCSR_BUSFAULTACT_Pos 1 /*!< SCB SHCSR: BUSFAULTACT Position */ -#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ - -#define SCB_SHCSR_MEMFAULTACT_Pos 0 /*!< SCB SHCSR: MEMFAULTACT Position */ -#define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */ - -/* SCB Configurable Fault Status Registers Definitions */ -#define SCB_CFSR_USGFAULTSR_Pos 16 /*!< SCB CFSR: Usage Fault Status Register Position */ -#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ - -#define SCB_CFSR_BUSFAULTSR_Pos 8 /*!< SCB CFSR: Bus Fault Status Register Position */ -#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ - -#define SCB_CFSR_MEMFAULTSR_Pos 0 /*!< SCB CFSR: Memory Manage Fault Status Register Position */ -#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ - -/* SCB Hard Fault Status Registers Definitions */ -#define SCB_HFSR_DEBUGEVT_Pos 31 /*!< SCB HFSR: DEBUGEVT Position */ -#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ - -#define SCB_HFSR_FORCED_Pos 30 /*!< SCB HFSR: FORCED Position */ -#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ - -#define SCB_HFSR_VECTTBL_Pos 1 /*!< SCB HFSR: VECTTBL Position */ -#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ - -/* SCB Debug Fault Status Register Definitions */ -#define SCB_DFSR_EXTERNAL_Pos 4 /*!< SCB DFSR: EXTERNAL Position */ -#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ - -#define SCB_DFSR_VCATCH_Pos 3 /*!< SCB DFSR: VCATCH Position */ -#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ - -#define SCB_DFSR_DWTTRAP_Pos 2 /*!< SCB DFSR: DWTTRAP Position */ -#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ - -#define SCB_DFSR_BKPT_Pos 1 /*!< SCB DFSR: BKPT Position */ -#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ - -#define SCB_DFSR_HALTED_Pos 0 /*!< SCB DFSR: HALTED Position */ -#define SCB_DFSR_HALTED_Msk (1UL /*<< SCB_DFSR_HALTED_Pos*/) /*!< SCB DFSR: HALTED Mask */ - -/*@} end of group CMSIS_SCB */ - - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) - \brief Type definitions for the System Control and ID Register not in the SCB - @{ - */ - -/** \brief Structure type to access the System Control and ID Register not in the SCB. - */ -typedef struct -{ - uint32_t RESERVED0[1]; - __I uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ - __IO uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ -} SCnSCB_Type; - -/* Interrupt Controller Type Register Definitions */ -#define SCnSCB_ICTR_INTLINESNUM_Pos 0 /*!< ICTR: INTLINESNUM Position */ -#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/) /*!< ICTR: INTLINESNUM Mask */ - -/* Auxiliary Control Register Definitions */ -#define SCnSCB_ACTLR_DISOOFP_Pos 9 /*!< ACTLR: DISOOFP Position */ -#define SCnSCB_ACTLR_DISOOFP_Msk (1UL << SCnSCB_ACTLR_DISOOFP_Pos) /*!< ACTLR: DISOOFP Mask */ - -#define SCnSCB_ACTLR_DISFPCA_Pos 8 /*!< ACTLR: DISFPCA Position */ -#define SCnSCB_ACTLR_DISFPCA_Msk (1UL << SCnSCB_ACTLR_DISFPCA_Pos) /*!< ACTLR: DISFPCA Mask */ - -#define SCnSCB_ACTLR_DISFOLD_Pos 2 /*!< ACTLR: DISFOLD Position */ -#define SCnSCB_ACTLR_DISFOLD_Msk (1UL << SCnSCB_ACTLR_DISFOLD_Pos) /*!< ACTLR: DISFOLD Mask */ - -#define SCnSCB_ACTLR_DISDEFWBUF_Pos 1 /*!< ACTLR: DISDEFWBUF Position */ -#define SCnSCB_ACTLR_DISDEFWBUF_Msk (1UL << SCnSCB_ACTLR_DISDEFWBUF_Pos) /*!< ACTLR: DISDEFWBUF Mask */ - -#define SCnSCB_ACTLR_DISMCYCINT_Pos 0 /*!< ACTLR: DISMCYCINT Position */ -#define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL /*<< SCnSCB_ACTLR_DISMCYCINT_Pos*/) /*!< ACTLR: DISMCYCINT Mask */ - -/*@} end of group CMSIS_SCnotSCB */ - - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_SysTick System Tick Timer (SysTick) - \brief Type definitions for the System Timer Registers. - @{ - */ - -/** \brief Structure type to access the System Timer (SysTick). - */ -typedef struct -{ - __IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ - __IO uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ - __IO uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ - __I uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ -} SysTick_Type; - -/* SysTick Control / Status Register Definitions */ -#define SysTick_CTRL_COUNTFLAG_Pos 16 /*!< SysTick CTRL: COUNTFLAG Position */ -#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ - -#define SysTick_CTRL_CLKSOURCE_Pos 2 /*!< SysTick CTRL: CLKSOURCE Position */ -#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ - -#define SysTick_CTRL_TICKINT_Pos 1 /*!< SysTick CTRL: TICKINT Position */ -#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ - -#define SysTick_CTRL_ENABLE_Pos 0 /*!< SysTick CTRL: ENABLE Position */ -#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ - -/* SysTick Reload Register Definitions */ -#define SysTick_LOAD_RELOAD_Pos 0 /*!< SysTick LOAD: RELOAD Position */ -#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ - -/* SysTick Current Register Definitions */ -#define SysTick_VAL_CURRENT_Pos 0 /*!< SysTick VAL: CURRENT Position */ -#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ - -/* SysTick Calibration Register Definitions */ -#define SysTick_CALIB_NOREF_Pos 31 /*!< SysTick CALIB: NOREF Position */ -#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ - -#define SysTick_CALIB_SKEW_Pos 30 /*!< SysTick CALIB: SKEW Position */ -#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ - -#define SysTick_CALIB_TENMS_Pos 0 /*!< SysTick CALIB: TENMS Position */ -#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ - -/*@} end of group CMSIS_SysTick */ - - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) - \brief Type definitions for the Instrumentation Trace Macrocell (ITM) - @{ - */ - -/** \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). - */ -typedef struct -{ - __O union - { - __O uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ - __O uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ - __O uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ - } PORT [32]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ - uint32_t RESERVED0[864]; - __IO uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ - uint32_t RESERVED1[15]; - __IO uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ - uint32_t RESERVED2[15]; - __IO uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ - uint32_t RESERVED3[29]; - __O uint32_t IWR; /*!< Offset: 0xEF8 ( /W) ITM Integration Write Register */ - __I uint32_t IRR; /*!< Offset: 0xEFC (R/ ) ITM Integration Read Register */ - __IO uint32_t IMCR; /*!< Offset: 0xF00 (R/W) ITM Integration Mode Control Register */ - uint32_t RESERVED4[43]; - __O uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ - __I uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ - uint32_t RESERVED5[6]; - __I uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ - __I uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ - __I uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ - __I uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ - __I uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ - __I uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ - __I uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ - __I uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ - __I uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ - __I uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ - __I uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ - __I uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ -} ITM_Type; - -/* ITM Trace Privilege Register Definitions */ -#define ITM_TPR_PRIVMASK_Pos 0 /*!< ITM TPR: PRIVMASK Position */ -#define ITM_TPR_PRIVMASK_Msk (0xFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ - -/* ITM Trace Control Register Definitions */ -#define ITM_TCR_BUSY_Pos 23 /*!< ITM TCR: BUSY Position */ -#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ - -#define ITM_TCR_TraceBusID_Pos 16 /*!< ITM TCR: ATBID Position */ -#define ITM_TCR_TraceBusID_Msk (0x7FUL << ITM_TCR_TraceBusID_Pos) /*!< ITM TCR: ATBID Mask */ - -#define ITM_TCR_GTSFREQ_Pos 10 /*!< ITM TCR: Global timestamp frequency Position */ -#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ - -#define ITM_TCR_TSPrescale_Pos 8 /*!< ITM TCR: TSPrescale Position */ -#define ITM_TCR_TSPrescale_Msk (3UL << ITM_TCR_TSPrescale_Pos) /*!< ITM TCR: TSPrescale Mask */ - -#define ITM_TCR_SWOENA_Pos 4 /*!< ITM TCR: SWOENA Position */ -#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ - -#define ITM_TCR_DWTENA_Pos 3 /*!< ITM TCR: DWTENA Position */ -#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ - -#define ITM_TCR_SYNCENA_Pos 2 /*!< ITM TCR: SYNCENA Position */ -#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ - -#define ITM_TCR_TSENA_Pos 1 /*!< ITM TCR: TSENA Position */ -#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ - -#define ITM_TCR_ITMENA_Pos 0 /*!< ITM TCR: ITM Enable bit Position */ -#define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */ - -/* ITM Integration Write Register Definitions */ -#define ITM_IWR_ATVALIDM_Pos 0 /*!< ITM IWR: ATVALIDM Position */ -#define ITM_IWR_ATVALIDM_Msk (1UL /*<< ITM_IWR_ATVALIDM_Pos*/) /*!< ITM IWR: ATVALIDM Mask */ - -/* ITM Integration Read Register Definitions */ -#define ITM_IRR_ATREADYM_Pos 0 /*!< ITM IRR: ATREADYM Position */ -#define ITM_IRR_ATREADYM_Msk (1UL /*<< ITM_IRR_ATREADYM_Pos*/) /*!< ITM IRR: ATREADYM Mask */ - -/* ITM Integration Mode Control Register Definitions */ -#define ITM_IMCR_INTEGRATION_Pos 0 /*!< ITM IMCR: INTEGRATION Position */ -#define ITM_IMCR_INTEGRATION_Msk (1UL /*<< ITM_IMCR_INTEGRATION_Pos*/) /*!< ITM IMCR: INTEGRATION Mask */ - -/* ITM Lock Status Register Definitions */ -#define ITM_LSR_ByteAcc_Pos 2 /*!< ITM LSR: ByteAcc Position */ -#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ - -#define ITM_LSR_Access_Pos 1 /*!< ITM LSR: Access Position */ -#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ - -#define ITM_LSR_Present_Pos 0 /*!< ITM LSR: Present Position */ -#define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */ - -/*@}*/ /* end of group CMSIS_ITM */ - - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) - \brief Type definitions for the Data Watchpoint and Trace (DWT) - @{ - */ - -/** \brief Structure type to access the Data Watchpoint and Trace Register (DWT). - */ -typedef struct -{ - __IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ - __IO uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ - __IO uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ - __IO uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ - __IO uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ - __IO uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ - __IO uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ - __I uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ - __IO uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ - __IO uint32_t MASK0; /*!< Offset: 0x024 (R/W) Mask Register 0 */ - __IO uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ - uint32_t RESERVED0[1]; - __IO uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ - __IO uint32_t MASK1; /*!< Offset: 0x034 (R/W) Mask Register 1 */ - __IO uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ - uint32_t RESERVED1[1]; - __IO uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ - __IO uint32_t MASK2; /*!< Offset: 0x044 (R/W) Mask Register 2 */ - __IO uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ - uint32_t RESERVED2[1]; - __IO uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ - __IO uint32_t MASK3; /*!< Offset: 0x054 (R/W) Mask Register 3 */ - __IO uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ -} DWT_Type; - -/* DWT Control Register Definitions */ -#define DWT_CTRL_NUMCOMP_Pos 28 /*!< DWT CTRL: NUMCOMP Position */ -#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ - -#define DWT_CTRL_NOTRCPKT_Pos 27 /*!< DWT CTRL: NOTRCPKT Position */ -#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ - -#define DWT_CTRL_NOEXTTRIG_Pos 26 /*!< DWT CTRL: NOEXTTRIG Position */ -#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ - -#define DWT_CTRL_NOCYCCNT_Pos 25 /*!< DWT CTRL: NOCYCCNT Position */ -#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ - -#define DWT_CTRL_NOPRFCNT_Pos 24 /*!< DWT CTRL: NOPRFCNT Position */ -#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ - -#define DWT_CTRL_CYCEVTENA_Pos 22 /*!< DWT CTRL: CYCEVTENA Position */ -#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ - -#define DWT_CTRL_FOLDEVTENA_Pos 21 /*!< DWT CTRL: FOLDEVTENA Position */ -#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ - -#define DWT_CTRL_LSUEVTENA_Pos 20 /*!< DWT CTRL: LSUEVTENA Position */ -#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ - -#define DWT_CTRL_SLEEPEVTENA_Pos 19 /*!< DWT CTRL: SLEEPEVTENA Position */ -#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ - -#define DWT_CTRL_EXCEVTENA_Pos 18 /*!< DWT CTRL: EXCEVTENA Position */ -#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ - -#define DWT_CTRL_CPIEVTENA_Pos 17 /*!< DWT CTRL: CPIEVTENA Position */ -#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ - -#define DWT_CTRL_EXCTRCENA_Pos 16 /*!< DWT CTRL: EXCTRCENA Position */ -#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ - -#define DWT_CTRL_PCSAMPLENA_Pos 12 /*!< DWT CTRL: PCSAMPLENA Position */ -#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ - -#define DWT_CTRL_SYNCTAP_Pos 10 /*!< DWT CTRL: SYNCTAP Position */ -#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ - -#define DWT_CTRL_CYCTAP_Pos 9 /*!< DWT CTRL: CYCTAP Position */ -#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ - -#define DWT_CTRL_POSTINIT_Pos 5 /*!< DWT CTRL: POSTINIT Position */ -#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ - -#define DWT_CTRL_POSTPRESET_Pos 1 /*!< DWT CTRL: POSTPRESET Position */ -#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ - -#define DWT_CTRL_CYCCNTENA_Pos 0 /*!< DWT CTRL: CYCCNTENA Position */ -#define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */ - -/* DWT CPI Count Register Definitions */ -#define DWT_CPICNT_CPICNT_Pos 0 /*!< DWT CPICNT: CPICNT Position */ -#define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */ - -/* DWT Exception Overhead Count Register Definitions */ -#define DWT_EXCCNT_EXCCNT_Pos 0 /*!< DWT EXCCNT: EXCCNT Position */ -#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */ - -/* DWT Sleep Count Register Definitions */ -#define DWT_SLEEPCNT_SLEEPCNT_Pos 0 /*!< DWT SLEEPCNT: SLEEPCNT Position */ -#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ - -/* DWT LSU Count Register Definitions */ -#define DWT_LSUCNT_LSUCNT_Pos 0 /*!< DWT LSUCNT: LSUCNT Position */ -#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */ - -/* DWT Folded-instruction Count Register Definitions */ -#define DWT_FOLDCNT_FOLDCNT_Pos 0 /*!< DWT FOLDCNT: FOLDCNT Position */ -#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */ - -/* DWT Comparator Mask Register Definitions */ -#define DWT_MASK_MASK_Pos 0 /*!< DWT MASK: MASK Position */ -#define DWT_MASK_MASK_Msk (0x1FUL /*<< DWT_MASK_MASK_Pos*/) /*!< DWT MASK: MASK Mask */ - -/* DWT Comparator Function Register Definitions */ -#define DWT_FUNCTION_MATCHED_Pos 24 /*!< DWT FUNCTION: MATCHED Position */ -#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ - -#define DWT_FUNCTION_DATAVADDR1_Pos 16 /*!< DWT FUNCTION: DATAVADDR1 Position */ -#define DWT_FUNCTION_DATAVADDR1_Msk (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos) /*!< DWT FUNCTION: DATAVADDR1 Mask */ - -#define DWT_FUNCTION_DATAVADDR0_Pos 12 /*!< DWT FUNCTION: DATAVADDR0 Position */ -#define DWT_FUNCTION_DATAVADDR0_Msk (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos) /*!< DWT FUNCTION: DATAVADDR0 Mask */ - -#define DWT_FUNCTION_DATAVSIZE_Pos 10 /*!< DWT FUNCTION: DATAVSIZE Position */ -#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ - -#define DWT_FUNCTION_LNK1ENA_Pos 9 /*!< DWT FUNCTION: LNK1ENA Position */ -#define DWT_FUNCTION_LNK1ENA_Msk (0x1UL << DWT_FUNCTION_LNK1ENA_Pos) /*!< DWT FUNCTION: LNK1ENA Mask */ - -#define DWT_FUNCTION_DATAVMATCH_Pos 8 /*!< DWT FUNCTION: DATAVMATCH Position */ -#define DWT_FUNCTION_DATAVMATCH_Msk (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos) /*!< DWT FUNCTION: DATAVMATCH Mask */ - -#define DWT_FUNCTION_CYCMATCH_Pos 7 /*!< DWT FUNCTION: CYCMATCH Position */ -#define DWT_FUNCTION_CYCMATCH_Msk (0x1UL << DWT_FUNCTION_CYCMATCH_Pos) /*!< DWT FUNCTION: CYCMATCH Mask */ - -#define DWT_FUNCTION_EMITRANGE_Pos 5 /*!< DWT FUNCTION: EMITRANGE Position */ -#define DWT_FUNCTION_EMITRANGE_Msk (0x1UL << DWT_FUNCTION_EMITRANGE_Pos) /*!< DWT FUNCTION: EMITRANGE Mask */ - -#define DWT_FUNCTION_FUNCTION_Pos 0 /*!< DWT FUNCTION: FUNCTION Position */ -#define DWT_FUNCTION_FUNCTION_Msk (0xFUL /*<< DWT_FUNCTION_FUNCTION_Pos*/) /*!< DWT FUNCTION: FUNCTION Mask */ - -/*@}*/ /* end of group CMSIS_DWT */ - - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_TPI Trace Port Interface (TPI) - \brief Type definitions for the Trace Port Interface (TPI) - @{ - */ - -/** \brief Structure type to access the Trace Port Interface Register (TPI). - */ -typedef struct -{ - __IO uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ - __IO uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ - uint32_t RESERVED0[2]; - __IO uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ - uint32_t RESERVED1[55]; - __IO uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ - uint32_t RESERVED2[131]; - __I uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ - __IO uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ - __I uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ - uint32_t RESERVED3[759]; - __I uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER */ - __I uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ - __I uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ - uint32_t RESERVED4[1]; - __I uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */ - __I uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */ - __IO uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ - uint32_t RESERVED5[39]; - __IO uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ - __IO uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ - uint32_t RESERVED7[8]; - __I uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */ - __I uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */ -} TPI_Type; - -/* TPI Asynchronous Clock Prescaler Register Definitions */ -#define TPI_ACPR_PRESCALER_Pos 0 /*!< TPI ACPR: PRESCALER Position */ -#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< TPI ACPR: PRESCALER Mask */ - -/* TPI Selected Pin Protocol Register Definitions */ -#define TPI_SPPR_TXMODE_Pos 0 /*!< TPI SPPR: TXMODE Position */ -#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ - -/* TPI Formatter and Flush Status Register Definitions */ -#define TPI_FFSR_FtNonStop_Pos 3 /*!< TPI FFSR: FtNonStop Position */ -#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ - -#define TPI_FFSR_TCPresent_Pos 2 /*!< TPI FFSR: TCPresent Position */ -#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ - -#define TPI_FFSR_FtStopped_Pos 1 /*!< TPI FFSR: FtStopped Position */ -#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ - -#define TPI_FFSR_FlInProg_Pos 0 /*!< TPI FFSR: FlInProg Position */ -#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ - -/* TPI Formatter and Flush Control Register Definitions */ -#define TPI_FFCR_TrigIn_Pos 8 /*!< TPI FFCR: TrigIn Position */ -#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ - -#define TPI_FFCR_EnFCont_Pos 1 /*!< TPI FFCR: EnFCont Position */ -#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ - -/* TPI TRIGGER Register Definitions */ -#define TPI_TRIGGER_TRIGGER_Pos 0 /*!< TPI TRIGGER: TRIGGER Position */ -#define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */ - -/* TPI Integration ETM Data Register Definitions (FIFO0) */ -#define TPI_FIFO0_ITM_ATVALID_Pos 29 /*!< TPI FIFO0: ITM_ATVALID Position */ -#define TPI_FIFO0_ITM_ATVALID_Msk (0x3UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ - -#define TPI_FIFO0_ITM_bytecount_Pos 27 /*!< TPI FIFO0: ITM_bytecount Position */ -#define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */ - -#define TPI_FIFO0_ETM_ATVALID_Pos 26 /*!< TPI FIFO0: ETM_ATVALID Position */ -#define TPI_FIFO0_ETM_ATVALID_Msk (0x3UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ - -#define TPI_FIFO0_ETM_bytecount_Pos 24 /*!< TPI FIFO0: ETM_bytecount Position */ -#define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */ - -#define TPI_FIFO0_ETM2_Pos 16 /*!< TPI FIFO0: ETM2 Position */ -#define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */ - -#define TPI_FIFO0_ETM1_Pos 8 /*!< TPI FIFO0: ETM1 Position */ -#define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */ - -#define TPI_FIFO0_ETM0_Pos 0 /*!< TPI FIFO0: ETM0 Position */ -#define TPI_FIFO0_ETM0_Msk (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/) /*!< TPI FIFO0: ETM0 Mask */ - -/* TPI ITATBCTR2 Register Definitions */ -#define TPI_ITATBCTR2_ATREADY_Pos 0 /*!< TPI ITATBCTR2: ATREADY Position */ -#define TPI_ITATBCTR2_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY_Pos*/) /*!< TPI ITATBCTR2: ATREADY Mask */ - -/* TPI Integration ITM Data Register Definitions (FIFO1) */ -#define TPI_FIFO1_ITM_ATVALID_Pos 29 /*!< TPI FIFO1: ITM_ATVALID Position */ -#define TPI_FIFO1_ITM_ATVALID_Msk (0x3UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ - -#define TPI_FIFO1_ITM_bytecount_Pos 27 /*!< TPI FIFO1: ITM_bytecount Position */ -#define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */ - -#define TPI_FIFO1_ETM_ATVALID_Pos 26 /*!< TPI FIFO1: ETM_ATVALID Position */ -#define TPI_FIFO1_ETM_ATVALID_Msk (0x3UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ - -#define TPI_FIFO1_ETM_bytecount_Pos 24 /*!< TPI FIFO1: ETM_bytecount Position */ -#define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */ - -#define TPI_FIFO1_ITM2_Pos 16 /*!< TPI FIFO1: ITM2 Position */ -#define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */ - -#define TPI_FIFO1_ITM1_Pos 8 /*!< TPI FIFO1: ITM1 Position */ -#define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */ - -#define TPI_FIFO1_ITM0_Pos 0 /*!< TPI FIFO1: ITM0 Position */ -#define TPI_FIFO1_ITM0_Msk (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/) /*!< TPI FIFO1: ITM0 Mask */ - -/* TPI ITATBCTR0 Register Definitions */ -#define TPI_ITATBCTR0_ATREADY_Pos 0 /*!< TPI ITATBCTR0: ATREADY Position */ -#define TPI_ITATBCTR0_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY_Pos*/) /*!< TPI ITATBCTR0: ATREADY Mask */ - -/* TPI Integration Mode Control Register Definitions */ -#define TPI_ITCTRL_Mode_Pos 0 /*!< TPI ITCTRL: Mode Position */ -#define TPI_ITCTRL_Mode_Msk (0x1UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ - -/* TPI DEVID Register Definitions */ -#define TPI_DEVID_NRZVALID_Pos 11 /*!< TPI DEVID: NRZVALID Position */ -#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ - -#define TPI_DEVID_MANCVALID_Pos 10 /*!< TPI DEVID: MANCVALID Position */ -#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ - -#define TPI_DEVID_PTINVALID_Pos 9 /*!< TPI DEVID: PTINVALID Position */ -#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ - -#define TPI_DEVID_MinBufSz_Pos 6 /*!< TPI DEVID: MinBufSz Position */ -#define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */ - -#define TPI_DEVID_AsynClkIn_Pos 5 /*!< TPI DEVID: AsynClkIn Position */ -#define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */ - -#define TPI_DEVID_NrTraceInput_Pos 0 /*!< TPI DEVID: NrTraceInput Position */ -#define TPI_DEVID_NrTraceInput_Msk (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ - -/* TPI DEVTYPE Register Definitions */ -#define TPI_DEVTYPE_MajorType_Pos 4 /*!< TPI DEVTYPE: MajorType Position */ -#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ - -#define TPI_DEVTYPE_SubType_Pos 0 /*!< TPI DEVTYPE: SubType Position */ -#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ - -/*@}*/ /* end of group CMSIS_TPI */ - - -#if (__MPU_PRESENT == 1) -/** \ingroup CMSIS_core_register - \defgroup CMSIS_MPU Memory Protection Unit (MPU) - \brief Type definitions for the Memory Protection Unit (MPU) - @{ - */ - -/** \brief Structure type to access the Memory Protection Unit (MPU). - */ -typedef struct -{ - __I uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ - __IO uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ - __IO uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ - __IO uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ - __IO uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ - __IO uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Alias 1 Region Base Address Register */ - __IO uint32_t RASR_A1; /*!< Offset: 0x018 (R/W) MPU Alias 1 Region Attribute and Size Register */ - __IO uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Alias 2 Region Base Address Register */ - __IO uint32_t RASR_A2; /*!< Offset: 0x020 (R/W) MPU Alias 2 Region Attribute and Size Register */ - __IO uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Alias 3 Region Base Address Register */ - __IO uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */ -} MPU_Type; - -/* MPU Type Register */ -#define MPU_TYPE_IREGION_Pos 16 /*!< MPU TYPE: IREGION Position */ -#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ - -#define MPU_TYPE_DREGION_Pos 8 /*!< MPU TYPE: DREGION Position */ -#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ - -#define MPU_TYPE_SEPARATE_Pos 0 /*!< MPU TYPE: SEPARATE Position */ -#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ - -/* MPU Control Register */ -#define MPU_CTRL_PRIVDEFENA_Pos 2 /*!< MPU CTRL: PRIVDEFENA Position */ -#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ - -#define MPU_CTRL_HFNMIENA_Pos 1 /*!< MPU CTRL: HFNMIENA Position */ -#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ - -#define MPU_CTRL_ENABLE_Pos 0 /*!< MPU CTRL: ENABLE Position */ -#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ - -/* MPU Region Number Register */ -#define MPU_RNR_REGION_Pos 0 /*!< MPU RNR: REGION Position */ -#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ - -/* MPU Region Base Address Register */ -#define MPU_RBAR_ADDR_Pos 5 /*!< MPU RBAR: ADDR Position */ -#define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ - -#define MPU_RBAR_VALID_Pos 4 /*!< MPU RBAR: VALID Position */ -#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ - -#define MPU_RBAR_REGION_Pos 0 /*!< MPU RBAR: REGION Position */ -#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */ - -/* MPU Region Attribute and Size Register */ -#define MPU_RASR_ATTRS_Pos 16 /*!< MPU RASR: MPU Region Attribute field Position */ -#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ - -#define MPU_RASR_XN_Pos 28 /*!< MPU RASR: ATTRS.XN Position */ -#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ - -#define MPU_RASR_AP_Pos 24 /*!< MPU RASR: ATTRS.AP Position */ -#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ - -#define MPU_RASR_TEX_Pos 19 /*!< MPU RASR: ATTRS.TEX Position */ -#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ - -#define MPU_RASR_S_Pos 18 /*!< MPU RASR: ATTRS.S Position */ -#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ - -#define MPU_RASR_C_Pos 17 /*!< MPU RASR: ATTRS.C Position */ -#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ - -#define MPU_RASR_B_Pos 16 /*!< MPU RASR: ATTRS.B Position */ -#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ - -#define MPU_RASR_SRD_Pos 8 /*!< MPU RASR: Sub-Region Disable Position */ -#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ - -#define MPU_RASR_SIZE_Pos 1 /*!< MPU RASR: Region Size Field Position */ -#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ - -#define MPU_RASR_ENABLE_Pos 0 /*!< MPU RASR: Region enable bit Position */ -#define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */ - -/*@} end of group CMSIS_MPU */ -#endif - - -#if (__FPU_PRESENT == 1) -/** \ingroup CMSIS_core_register - \defgroup CMSIS_FPU Floating Point Unit (FPU) - \brief Type definitions for the Floating Point Unit (FPU) - @{ - */ - -/** \brief Structure type to access the Floating Point Unit (FPU). - */ -typedef struct -{ - uint32_t RESERVED0[1]; - __IO uint32_t FPCCR; /*!< Offset: 0x004 (R/W) Floating-Point Context Control Register */ - __IO uint32_t FPCAR; /*!< Offset: 0x008 (R/W) Floating-Point Context Address Register */ - __IO uint32_t FPDSCR; /*!< Offset: 0x00C (R/W) Floating-Point Default Status Control Register */ - __I uint32_t MVFR0; /*!< Offset: 0x010 (R/ ) Media and FP Feature Register 0 */ - __I uint32_t MVFR1; /*!< Offset: 0x014 (R/ ) Media and FP Feature Register 1 */ -} FPU_Type; - -/* Floating-Point Context Control Register */ -#define FPU_FPCCR_ASPEN_Pos 31 /*!< FPCCR: ASPEN bit Position */ -#define FPU_FPCCR_ASPEN_Msk (1UL << FPU_FPCCR_ASPEN_Pos) /*!< FPCCR: ASPEN bit Mask */ - -#define FPU_FPCCR_LSPEN_Pos 30 /*!< FPCCR: LSPEN Position */ -#define FPU_FPCCR_LSPEN_Msk (1UL << FPU_FPCCR_LSPEN_Pos) /*!< FPCCR: LSPEN bit Mask */ - -#define FPU_FPCCR_MONRDY_Pos 8 /*!< FPCCR: MONRDY Position */ -#define FPU_FPCCR_MONRDY_Msk (1UL << FPU_FPCCR_MONRDY_Pos) /*!< FPCCR: MONRDY bit Mask */ - -#define FPU_FPCCR_BFRDY_Pos 6 /*!< FPCCR: BFRDY Position */ -#define FPU_FPCCR_BFRDY_Msk (1UL << FPU_FPCCR_BFRDY_Pos) /*!< FPCCR: BFRDY bit Mask */ - -#define FPU_FPCCR_MMRDY_Pos 5 /*!< FPCCR: MMRDY Position */ -#define FPU_FPCCR_MMRDY_Msk (1UL << FPU_FPCCR_MMRDY_Pos) /*!< FPCCR: MMRDY bit Mask */ - -#define FPU_FPCCR_HFRDY_Pos 4 /*!< FPCCR: HFRDY Position */ -#define FPU_FPCCR_HFRDY_Msk (1UL << FPU_FPCCR_HFRDY_Pos) /*!< FPCCR: HFRDY bit Mask */ - -#define FPU_FPCCR_THREAD_Pos 3 /*!< FPCCR: processor mode bit Position */ -#define FPU_FPCCR_THREAD_Msk (1UL << FPU_FPCCR_THREAD_Pos) /*!< FPCCR: processor mode active bit Mask */ - -#define FPU_FPCCR_USER_Pos 1 /*!< FPCCR: privilege level bit Position */ -#define FPU_FPCCR_USER_Msk (1UL << FPU_FPCCR_USER_Pos) /*!< FPCCR: privilege level bit Mask */ - -#define FPU_FPCCR_LSPACT_Pos 0 /*!< FPCCR: Lazy state preservation active bit Position */ -#define FPU_FPCCR_LSPACT_Msk (1UL /*<< FPU_FPCCR_LSPACT_Pos*/) /*!< FPCCR: Lazy state preservation active bit Mask */ - -/* Floating-Point Context Address Register */ -#define FPU_FPCAR_ADDRESS_Pos 3 /*!< FPCAR: ADDRESS bit Position */ -#define FPU_FPCAR_ADDRESS_Msk (0x1FFFFFFFUL << FPU_FPCAR_ADDRESS_Pos) /*!< FPCAR: ADDRESS bit Mask */ - -/* Floating-Point Default Status Control Register */ -#define FPU_FPDSCR_AHP_Pos 26 /*!< FPDSCR: AHP bit Position */ -#define FPU_FPDSCR_AHP_Msk (1UL << FPU_FPDSCR_AHP_Pos) /*!< FPDSCR: AHP bit Mask */ - -#define FPU_FPDSCR_DN_Pos 25 /*!< FPDSCR: DN bit Position */ -#define FPU_FPDSCR_DN_Msk (1UL << FPU_FPDSCR_DN_Pos) /*!< FPDSCR: DN bit Mask */ - -#define FPU_FPDSCR_FZ_Pos 24 /*!< FPDSCR: FZ bit Position */ -#define FPU_FPDSCR_FZ_Msk (1UL << FPU_FPDSCR_FZ_Pos) /*!< FPDSCR: FZ bit Mask */ - -#define FPU_FPDSCR_RMode_Pos 22 /*!< FPDSCR: RMode bit Position */ -#define FPU_FPDSCR_RMode_Msk (3UL << FPU_FPDSCR_RMode_Pos) /*!< FPDSCR: RMode bit Mask */ - -/* Media and FP Feature Register 0 */ -#define FPU_MVFR0_FP_rounding_modes_Pos 28 /*!< MVFR0: FP rounding modes bits Position */ -#define FPU_MVFR0_FP_rounding_modes_Msk (0xFUL << FPU_MVFR0_FP_rounding_modes_Pos) /*!< MVFR0: FP rounding modes bits Mask */ - -#define FPU_MVFR0_Short_vectors_Pos 24 /*!< MVFR0: Short vectors bits Position */ -#define FPU_MVFR0_Short_vectors_Msk (0xFUL << FPU_MVFR0_Short_vectors_Pos) /*!< MVFR0: Short vectors bits Mask */ - -#define FPU_MVFR0_Square_root_Pos 20 /*!< MVFR0: Square root bits Position */ -#define FPU_MVFR0_Square_root_Msk (0xFUL << FPU_MVFR0_Square_root_Pos) /*!< MVFR0: Square root bits Mask */ - -#define FPU_MVFR0_Divide_Pos 16 /*!< MVFR0: Divide bits Position */ -#define FPU_MVFR0_Divide_Msk (0xFUL << FPU_MVFR0_Divide_Pos) /*!< MVFR0: Divide bits Mask */ - -#define FPU_MVFR0_FP_excep_trapping_Pos 12 /*!< MVFR0: FP exception trapping bits Position */ -#define FPU_MVFR0_FP_excep_trapping_Msk (0xFUL << FPU_MVFR0_FP_excep_trapping_Pos) /*!< MVFR0: FP exception trapping bits Mask */ - -#define FPU_MVFR0_Double_precision_Pos 8 /*!< MVFR0: Double-precision bits Position */ -#define FPU_MVFR0_Double_precision_Msk (0xFUL << FPU_MVFR0_Double_precision_Pos) /*!< MVFR0: Double-precision bits Mask */ - -#define FPU_MVFR0_Single_precision_Pos 4 /*!< MVFR0: Single-precision bits Position */ -#define FPU_MVFR0_Single_precision_Msk (0xFUL << FPU_MVFR0_Single_precision_Pos) /*!< MVFR0: Single-precision bits Mask */ - -#define FPU_MVFR0_A_SIMD_registers_Pos 0 /*!< MVFR0: A_SIMD registers bits Position */ -#define FPU_MVFR0_A_SIMD_registers_Msk (0xFUL /*<< FPU_MVFR0_A_SIMD_registers_Pos*/) /*!< MVFR0: A_SIMD registers bits Mask */ - -/* Media and FP Feature Register 1 */ -#define FPU_MVFR1_FP_fused_MAC_Pos 28 /*!< MVFR1: FP fused MAC bits Position */ -#define FPU_MVFR1_FP_fused_MAC_Msk (0xFUL << FPU_MVFR1_FP_fused_MAC_Pos) /*!< MVFR1: FP fused MAC bits Mask */ - -#define FPU_MVFR1_FP_HPFP_Pos 24 /*!< MVFR1: FP HPFP bits Position */ -#define FPU_MVFR1_FP_HPFP_Msk (0xFUL << FPU_MVFR1_FP_HPFP_Pos) /*!< MVFR1: FP HPFP bits Mask */ - -#define FPU_MVFR1_D_NaN_mode_Pos 4 /*!< MVFR1: D_NaN mode bits Position */ -#define FPU_MVFR1_D_NaN_mode_Msk (0xFUL << FPU_MVFR1_D_NaN_mode_Pos) /*!< MVFR1: D_NaN mode bits Mask */ - -#define FPU_MVFR1_FtZ_mode_Pos 0 /*!< MVFR1: FtZ mode bits Position */ -#define FPU_MVFR1_FtZ_mode_Msk (0xFUL /*<< FPU_MVFR1_FtZ_mode_Pos*/) /*!< MVFR1: FtZ mode bits Mask */ - -/*@} end of group CMSIS_FPU */ -#endif - - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) - \brief Type definitions for the Core Debug Registers - @{ - */ - -/** \brief Structure type to access the Core Debug Register (CoreDebug). - */ -typedef struct -{ - __IO uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ - __O uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ - __IO uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ - __IO uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ -} CoreDebug_Type; - -/* Debug Halting Control and Status Register */ -#define CoreDebug_DHCSR_DBGKEY_Pos 16 /*!< CoreDebug DHCSR: DBGKEY Position */ -#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ - -#define CoreDebug_DHCSR_S_RESET_ST_Pos 25 /*!< CoreDebug DHCSR: S_RESET_ST Position */ -#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ - -#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24 /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ -#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ - -#define CoreDebug_DHCSR_S_LOCKUP_Pos 19 /*!< CoreDebug DHCSR: S_LOCKUP Position */ -#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ - -#define CoreDebug_DHCSR_S_SLEEP_Pos 18 /*!< CoreDebug DHCSR: S_SLEEP Position */ -#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ - -#define CoreDebug_DHCSR_S_HALT_Pos 17 /*!< CoreDebug DHCSR: S_HALT Position */ -#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ - -#define CoreDebug_DHCSR_S_REGRDY_Pos 16 /*!< CoreDebug DHCSR: S_REGRDY Position */ -#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ - -#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5 /*!< CoreDebug DHCSR: C_SNAPSTALL Position */ -#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */ - -#define CoreDebug_DHCSR_C_MASKINTS_Pos 3 /*!< CoreDebug DHCSR: C_MASKINTS Position */ -#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ - -#define CoreDebug_DHCSR_C_STEP_Pos 2 /*!< CoreDebug DHCSR: C_STEP Position */ -#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ - -#define CoreDebug_DHCSR_C_HALT_Pos 1 /*!< CoreDebug DHCSR: C_HALT Position */ -#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ - -#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0 /*!< CoreDebug DHCSR: C_DEBUGEN Position */ -#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ - -/* Debug Core Register Selector Register */ -#define CoreDebug_DCRSR_REGWnR_Pos 16 /*!< CoreDebug DCRSR: REGWnR Position */ -#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ - -#define CoreDebug_DCRSR_REGSEL_Pos 0 /*!< CoreDebug DCRSR: REGSEL Position */ -#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< CoreDebug DCRSR: REGSEL Mask */ - -/* Debug Exception and Monitor Control Register */ -#define CoreDebug_DEMCR_TRCENA_Pos 24 /*!< CoreDebug DEMCR: TRCENA Position */ -#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ - -#define CoreDebug_DEMCR_MON_REQ_Pos 19 /*!< CoreDebug DEMCR: MON_REQ Position */ -#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */ - -#define CoreDebug_DEMCR_MON_STEP_Pos 18 /*!< CoreDebug DEMCR: MON_STEP Position */ -#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */ - -#define CoreDebug_DEMCR_MON_PEND_Pos 17 /*!< CoreDebug DEMCR: MON_PEND Position */ -#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */ - -#define CoreDebug_DEMCR_MON_EN_Pos 16 /*!< CoreDebug DEMCR: MON_EN Position */ -#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */ - -#define CoreDebug_DEMCR_VC_HARDERR_Pos 10 /*!< CoreDebug DEMCR: VC_HARDERR Position */ -#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ - -#define CoreDebug_DEMCR_VC_INTERR_Pos 9 /*!< CoreDebug DEMCR: VC_INTERR Position */ -#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */ - -#define CoreDebug_DEMCR_VC_BUSERR_Pos 8 /*!< CoreDebug DEMCR: VC_BUSERR Position */ -#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */ - -#define CoreDebug_DEMCR_VC_STATERR_Pos 7 /*!< CoreDebug DEMCR: VC_STATERR Position */ -#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */ - -#define CoreDebug_DEMCR_VC_CHKERR_Pos 6 /*!< CoreDebug DEMCR: VC_CHKERR Position */ -#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */ - -#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5 /*!< CoreDebug DEMCR: VC_NOCPERR Position */ -#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */ - -#define CoreDebug_DEMCR_VC_MMERR_Pos 4 /*!< CoreDebug DEMCR: VC_MMERR Position */ -#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */ - -#define CoreDebug_DEMCR_VC_CORERESET_Pos 0 /*!< CoreDebug DEMCR: VC_CORERESET Position */ -#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ - -/*@} end of group CMSIS_CoreDebug */ - - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_core_base Core Definitions - \brief Definitions for base addresses, unions, and structures. - @{ - */ - -/* Memory mapping of Cortex-M4 Hardware */ -#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ -#define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ -#define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ -#define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ -#define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ -#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ -#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ -#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ - -#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ -#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ -#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ -#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ -#define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ -#define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ -#define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ -#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */ - -#if (__MPU_PRESENT == 1) - #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ - #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ -#endif - -#if (__FPU_PRESENT == 1) - #define FPU_BASE (SCS_BASE + 0x0F30UL) /*!< Floating Point Unit */ - #define FPU ((FPU_Type *) FPU_BASE ) /*!< Floating Point Unit */ -#endif - -/*@} */ - - - -/******************************************************************************* - * Hardware Abstraction Layer - Core Function Interface contains: - - Core NVIC Functions - - Core SysTick Functions - - Core Debug Functions - - Core Register Access Functions - ******************************************************************************/ -/** \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference -*/ - - - -/* ########################## NVIC functions #################################### */ -/** \ingroup CMSIS_Core_FunctionInterface - \defgroup CMSIS_Core_NVICFunctions NVIC Functions - \brief Functions that manage interrupts and exceptions via the NVIC. - @{ - */ - -#ifdef CMSIS_NVIC_VIRTUAL - #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE - #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" - #endif - #include CMSIS_NVIC_VIRTUAL_HEADER_FILE -#else - #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping - #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping - #define NVIC_EnableIRQ __NVIC_EnableIRQ - #define NVIC_DisableIRQ __NVIC_DisableIRQ - #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ - #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ - #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ - #define NVIC_GetActive __NVIC_GetActive - #define NVIC_SetPriority __NVIC_SetPriority - #define NVIC_GetPriority __NVIC_GetPriority - #define NVIC_SystemReset __NVIC_SystemReset -#endif /* CMSIS_NVIC_VIRTUAL */ - -#ifdef CMSIS_VECTAB_VIRTUAL - #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE - #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" - #endif - #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE -#else - #define NVIC_SetVector __NVIC_SetVector - #define NVIC_GetVector __NVIC_GetVector -#endif /* CMSIS_VECTAB_VIRTUAL */ - - -/** \brief Set Priority Grouping - - The function sets the priority grouping field using the required unlock sequence. - The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. - Only values from 0..7 are used. - In case of a conflict between priority grouping and available - priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. - - \param [in] PriorityGroup Priority grouping field. - */ -__STATIC_INLINE void __NVIC_SetPriorityGrouping(uint32_t PriorityGroup) -{ - uint32_t reg_value; - uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ - - reg_value = SCB->AIRCR; /* read old register configuration */ - reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ - reg_value = (reg_value | - ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | - (PriorityGroupTmp << 8) ); /* Insert write key and priorty group */ - SCB->AIRCR = reg_value; -} - - -/** \brief Get Priority Grouping - - The function reads the priority grouping field from the NVIC Interrupt Controller. - - \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). - */ -__STATIC_INLINE uint32_t __NVIC_GetPriorityGrouping(void) -{ - return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); -} - - -/** \brief Enable External Interrupt - - The function enables a device-specific interrupt in the NVIC interrupt controller. - - \param [in] IRQn External interrupt number. Value cannot be negative. - */ -__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) -{ - NVIC->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); -} - - -/** \brief Disable External Interrupt - - The function disables a device-specific interrupt in the NVIC interrupt controller. - - \param [in] IRQn External interrupt number. Value cannot be negative. - */ -__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) -{ - NVIC->ICER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); - __DSB(); - __ISB(); -} - - -/** \brief Get Pending Interrupt - - The function reads the pending register in the NVIC and returns the pending bit - for the specified interrupt. - - \param [in] IRQn Interrupt number. - - \return 0 Interrupt status is not pending. - \return 1 Interrupt status is pending. - */ -__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) -{ - return((uint32_t)(((NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); -} - - -/** \brief Set Pending Interrupt - - The function sets the pending bit of an external interrupt. - - \param [in] IRQn Interrupt number. Value cannot be negative. - */ -__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) -{ - NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); -} - - -/** \brief Clear Pending Interrupt - - The function clears the pending bit of an external interrupt. - - \param [in] IRQn External interrupt number. Value cannot be negative. - */ -__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) -{ - NVIC->ICPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); -} - - -/** \brief Get Active Interrupt - - The function reads the active register in NVIC and returns the active bit. - - \param [in] IRQn Interrupt number. - - \return 0 Interrupt status is not active. - \return 1 Interrupt status is active. - */ -__STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) -{ - return((uint32_t)(((NVIC->IABR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); -} - - -/** \brief Set Interrupt Priority - - The function sets the priority of an interrupt. - - \note The priority cannot be set for every core interrupt. - - \param [in] IRQn Interrupt number. - \param [in] priority Priority to set. - */ -__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) -{ - if((int32_t)IRQn < 0) { - SCB->SHP[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8 - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); - } - else { - NVIC->IP[((uint32_t)(int32_t)IRQn)] = (uint8_t)((priority << (8 - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); - } -} - - -/** \brief Get Interrupt Priority - - The function reads the priority of an interrupt. The interrupt - number can be positive to specify an external (device specific) - interrupt, or negative to specify an internal (core) interrupt. - - - \param [in] IRQn Interrupt number. - \return Interrupt Priority. Value is aligned automatically to the implemented - priority bits of the microcontroller. - */ -__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) -{ - - if((int32_t)IRQn < 0) { - return(((uint32_t)SCB->SHP[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] >> (8 - __NVIC_PRIO_BITS))); - } - else { - return(((uint32_t)NVIC->IP[((uint32_t)(int32_t)IRQn)] >> (8 - __NVIC_PRIO_BITS))); - } -} - - -/** \brief Encode Priority - - The function encodes the priority for an interrupt with the given priority group, - preemptive priority value, and subpriority value. - In case of a conflict between priority grouping and available - priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. - - \param [in] PriorityGroup Used priority group. - \param [in] PreemptPriority Preemptive priority value (starting from 0). - \param [in] SubPriority Subpriority value (starting from 0). - \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). - */ -__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) -{ - uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ - uint32_t PreemptPriorityBits; - uint32_t SubPriorityBits; - - PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); - SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); - - return ( - ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | - ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) - ); -} - - -/** \brief Decode Priority - - The function decodes an interrupt priority value with a given priority group to - preemptive priority value and subpriority value. - In case of a conflict between priority grouping and available - priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. - - \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). - \param [in] PriorityGroup Used priority group. - \param [out] pPreemptPriority Preemptive priority value (starting from 0). - \param [out] pSubPriority Subpriority value (starting from 0). - */ -__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* pPreemptPriority, uint32_t* pSubPriority) -{ - uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ - uint32_t PreemptPriorityBits; - uint32_t SubPriorityBits; - - PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); - SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); - - *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); - *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); -} - - -/** \brief System Reset - - The function initiates a system reset request to reset the MCU. - */ -__STATIC_INLINE void __NVIC_SystemReset(void) -{ - __DSB(); /* Ensure all outstanding memory accesses included - buffered write are completed before reset */ - SCB->AIRCR = (uint32_t)((0x5FAUL << 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) { __NOP(); } /* wait until reset */ -} - -/*@} end of CMSIS_Core_NVICFunctions */ - - - -/* ################################## SysTick function ############################################ */ -/** \ingroup CMSIS_Core_FunctionInterface - \defgroup CMSIS_Core_SysTickFunctions SysTick Functions - \brief Functions that configure the System. - @{ - */ - -#if (__Vendor_SysTickConfig == 0) - -/** \brief System Tick Configuration - - The function initializes the System Timer and its interrupt, and starts the System Tick Timer. - Counter is in free running mode to generate periodic interrupts. - - \param [in] ticks Number of ticks between two interrupts. - - \return 0 Function succeeded. - \return 1 Function failed. - - \note When the variable __Vendor_SysTickConfig is set to 1, then the - function SysTick_Config is not included. In this case, the file device.h - must contain a vendor-specific implementation of this function. - - */ -__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) -{ - if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) { return (1UL); } /* Reload value impossible */ - - SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ - NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ - SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ - SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | - SysTick_CTRL_TICKINT_Msk | - SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ - return (0UL); /* Function successful */ -} - -#endif - -/*@} end of CMSIS_Core_SysTickFunctions */ - - - -/* ##################################### Debug In/Output function ########################################### */ -/** \ingroup CMSIS_Core_FunctionInterface - \defgroup CMSIS_core_DebugFunctions ITM Functions - \brief Functions that access the ITM debug interface. - @{ - */ - -extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ -#define ITM_RXBUFFER_EMPTY 0x5AA55AA5 /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ - - -/** \brief ITM Send Character - - The function transmits a character via the ITM channel 0, and - \li Just returns when no debugger is connected that has booked the output. - \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. - - \param [in] ch Character to transmit. - - \returns Character to transmit. - */ -__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) -{ - if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ - ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */ - { - while (ITM->PORT[0].u32 == 0UL) { __NOP(); } - ITM->PORT[0].u8 = (uint8_t)ch; - } - return (ch); -} - - -/** \brief ITM Receive Character - - The function inputs a character via the external variable \ref ITM_RxBuffer. - - \return Received character. - \return -1 No character pending. - */ -__STATIC_INLINE int32_t ITM_ReceiveChar (void) { - int32_t ch = -1; /* no character available */ - - if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) { - ch = ITM_RxBuffer; - ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ - } - - return (ch); -} - - -/** \brief ITM Check Character - - The function checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. - - \return 0 No character available. - \return 1 Character available. - */ -__STATIC_INLINE int32_t ITM_CheckChar (void) { - - if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) { - return (0); /* no character available */ - } else { - return (1); /* character available */ - } -} - -/*@} end of CMSIS_core_DebugFunctions */ - - - - -#ifdef __cplusplus -} -#endif - -#endif /* __CORE_CM4_H_DEPENDANT */ - -#endif /* __CMSIS_GENERIC */ diff --git a/cmsis/core_cm4_simd.h b/cmsis/core_cm4_simd.h deleted file mode 100644 index 83db95b5f11..00000000000 --- a/cmsis/core_cm4_simd.h +++ /dev/null @@ -1,673 +0,0 @@ -/**************************************************************************//** - * @file core_cm4_simd.h - * @brief CMSIS Cortex-M4 SIMD Header File - * @version V3.20 - * @date 25. February 2013 - * - * @note - * - ******************************************************************************/ -/* Copyright (c) 2009 - 2013 ARM LIMITED - - All rights reserved. - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - Neither the name of ARM nor the names of its contributors may be used - to endorse or promote products derived from this software without - specific prior written permission. - * - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - ---------------------------------------------------------------------------*/ - - -#ifdef __cplusplus - extern "C" { -#endif - -#ifndef __CORE_CM4_SIMD_H -#define __CORE_CM4_SIMD_H - - -/******************************************************************************* - * Hardware Abstraction Layer - ******************************************************************************/ - - -/* ################### Compiler specific Intrinsics ########################### */ -/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics - Access to dedicated SIMD instructions - @{ -*/ - -#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/ -/* ARM armcc specific functions */ - -/*------ CM4 SIMD Intrinsics -----------------------------------------------------*/ -#define __SADD8 __sadd8 -#define __QADD8 __qadd8 -#define __SHADD8 __shadd8 -#define __UADD8 __uadd8 -#define __UQADD8 __uqadd8 -#define __UHADD8 __uhadd8 -#define __SSUB8 __ssub8 -#define __QSUB8 __qsub8 -#define __SHSUB8 __shsub8 -#define __USUB8 __usub8 -#define __UQSUB8 __uqsub8 -#define __UHSUB8 __uhsub8 -#define __SADD16 __sadd16 -#define __QADD16 __qadd16 -#define __SHADD16 __shadd16 -#define __UADD16 __uadd16 -#define __UQADD16 __uqadd16 -#define __UHADD16 __uhadd16 -#define __SSUB16 __ssub16 -#define __QSUB16 __qsub16 -#define __SHSUB16 __shsub16 -#define __USUB16 __usub16 -#define __UQSUB16 __uqsub16 -#define __UHSUB16 __uhsub16 -#define __SASX __sasx -#define __QASX __qasx -#define __SHASX __shasx -#define __UASX __uasx -#define __UQASX __uqasx -#define __UHASX __uhasx -#define __SSAX __ssax -#define __QSAX __qsax -#define __SHSAX __shsax -#define __USAX __usax -#define __UQSAX __uqsax -#define __UHSAX __uhsax -#define __USAD8 __usad8 -#define __USADA8 __usada8 -#define __SSAT16 __ssat16 -#define __USAT16 __usat16 -#define __UXTB16 __uxtb16 -#define __UXTAB16 __uxtab16 -#define __SXTB16 __sxtb16 -#define __SXTAB16 __sxtab16 -#define __SMUAD __smuad -#define __SMUADX __smuadx -#define __SMLAD __smlad -#define __SMLADX __smladx -#define __SMLALD __smlald -#define __SMLALDX __smlaldx -#define __SMUSD __smusd -#define __SMUSDX __smusdx -#define __SMLSD __smlsd -#define __SMLSDX __smlsdx -#define __SMLSLD __smlsld -#define __SMLSLDX __smlsldx -#define __SEL __sel -#define __QADD __qadd -#define __QSUB __qsub - -#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \ - ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) ) - -#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \ - ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) ) - -#define __SMMLA(ARG1,ARG2,ARG3) ( (int32_t)((((int64_t)(ARG1) * (ARG2)) + \ - ((int64_t)(ARG3) << 32) ) >> 32)) - -/*-- End CM4 SIMD Intrinsics -----------------------------------------------------*/ - - - -#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/ -/* IAR iccarm specific functions */ - -/*------ CM4 SIMD Intrinsics -----------------------------------------------------*/ -#include - -/*-- End CM4 SIMD Intrinsics -----------------------------------------------------*/ - - - -#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/ -/* TI CCS specific functions */ - -/*------ CM4 SIMD Intrinsics -----------------------------------------------------*/ -#include - -/*-- End CM4 SIMD Intrinsics -----------------------------------------------------*/ - - - -#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/ -/* GNU gcc specific functions */ - -/*------ CM4 SIMD Intrinsics -----------------------------------------------------*/ -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SADD8(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("sadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD8(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("qadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHADD8(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("shadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UADD8(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("uadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQADD8(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("uqadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHADD8(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("uhadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSUB8(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("ssub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("qsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSUB8(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("shsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USUB8(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("usub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSUB8(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("uqsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSUB8(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("uhsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SADD16(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("sadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD16(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("qadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("shadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UADD16(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("uadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQADD16(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("uqadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHADD16(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("uhadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSUB16(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("ssub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("qsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("shsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USUB16(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("usub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSUB16(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("uqsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSUB16(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("uhsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SASX(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("sasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QASX(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("qasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHASX(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("shasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UASX(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("uasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQASX(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("uqasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHASX(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("uhasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSAX(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("ssax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSAX(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("qsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("shsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USAX(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("usax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSAX(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("uqsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSAX(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("uhsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USAD8(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("usad8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USADA8(uint32_t op1, uint32_t op2, uint32_t op3) -{ - uint32_t result; - - __ASM volatile ("usada8 %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); - return(result); -} - -#define __SSAT16(ARG1,ARG2) \ -({ \ - uint32_t __RES, __ARG1 = (ARG1); \ - __ASM ("ssat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ - __RES; \ - }) - -#define __USAT16(ARG1,ARG2) \ -({ \ - uint32_t __RES, __ARG1 = (ARG1); \ - __ASM ("usat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ - __RES; \ - }) - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UXTB16(uint32_t op1) -{ - uint32_t result; - - __ASM volatile ("uxtb16 %0, %1" : "=r" (result) : "r" (op1)); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("uxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SXTB16(uint32_t op1) -{ - uint32_t result; - - __ASM volatile ("sxtb16 %0, %1" : "=r" (result) : "r" (op1)); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("sxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUAD (uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("smuad %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("smuadx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3) -{ - uint32_t result; - - __ASM volatile ("smlad %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3) -{ - uint32_t result; - - __ASM volatile ("smladx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); - return(result); -} - -#define __SMLALD(ARG1,ARG2,ARG3) \ -({ \ - uint32_t __ARG1 = (ARG1), __ARG2 = (ARG2), __ARG3_H = (uint32_t)((uint64_t)(ARG3) >> 32), __ARG3_L = (uint32_t)((uint64_t)(ARG3) & 0xFFFFFFFFUL); \ - __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (__ARG3_L), "=r" (__ARG3_H) : "r" (__ARG1), "r" (__ARG2), "0" (__ARG3_L), "1" (__ARG3_H) ); \ - (uint64_t)(((uint64_t)__ARG3_H << 32) | __ARG3_L); \ - }) - -#define __SMLALDX(ARG1,ARG2,ARG3) \ -({ \ - uint32_t __ARG1 = (ARG1), __ARG2 = (ARG2), __ARG3_H = (uint32_t)((uint64_t)(ARG3) >> 32), __ARG3_L = (uint32_t)((uint64_t)(ARG3) & 0xFFFFFFFFUL); \ - __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (__ARG3_L), "=r" (__ARG3_H) : "r" (__ARG1), "r" (__ARG2), "0" (__ARG3_L), "1" (__ARG3_H) ); \ - (uint64_t)(((uint64_t)__ARG3_H << 32) | __ARG3_L); \ - }) - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUSD (uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("smusd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("smusdx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLSD (uint32_t op1, uint32_t op2, uint32_t op3) -{ - uint32_t result; - - __ASM volatile ("smlsd %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3) -{ - uint32_t result; - - __ASM volatile ("smlsdx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); - return(result); -} - -#define __SMLSLD(ARG1,ARG2,ARG3) \ -({ \ - uint32_t __ARG1 = (ARG1), __ARG2 = (ARG2), __ARG3_H = (uint32_t)((ARG3) >> 32), __ARG3_L = (uint32_t)((ARG3) & 0xFFFFFFFFUL); \ - __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (__ARG3_L), "=r" (__ARG3_H) : "r" (__ARG1), "r" (__ARG2), "0" (__ARG3_L), "1" (__ARG3_H) ); \ - (uint64_t)(((uint64_t)__ARG3_H << 32) | __ARG3_L); \ - }) - -#define __SMLSLDX(ARG1,ARG2,ARG3) \ -({ \ - uint32_t __ARG1 = (ARG1), __ARG2 = (ARG2), __ARG3_H = (uint32_t)((ARG3) >> 32), __ARG3_L = (uint32_t)((ARG3) & 0xFFFFFFFFUL); \ - __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (__ARG3_L), "=r" (__ARG3_H) : "r" (__ARG1), "r" (__ARG2), "0" (__ARG3_L), "1" (__ARG3_H) ); \ - (uint64_t)(((uint64_t)__ARG3_H << 32) | __ARG3_L); \ - }) - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SEL (uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("sel %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -#define __PKHBT(ARG1,ARG2,ARG3) \ -({ \ - uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \ - __ASM ("pkhbt %0, %1, %2, lsl %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \ - __RES; \ - }) - -#define __PKHTB(ARG1,ARG2,ARG3) \ -({ \ - uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \ - if (ARG3 == 0) \ - __ASM ("pkhtb %0, %1, %2" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2) ); \ - else \ - __ASM ("pkhtb %0, %1, %2, asr %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \ - __RES; \ - }) - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3) -{ - int32_t result; - - __ASM volatile ("smmla %0, %1, %2, %3" : "=r" (result): "r" (op1), "r" (op2), "r" (op3) ); - return(result); -} - -/*-- End CM4 SIMD Intrinsics -----------------------------------------------------*/ - - - -#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/ -/* TASKING carm specific functions */ - - -/*------ CM4 SIMD Intrinsics -----------------------------------------------------*/ -/* not yet supported */ -/*-- End CM4 SIMD Intrinsics -----------------------------------------------------*/ - - -#endif - -/*@} end of group CMSIS_SIMD_intrinsics */ - - -#endif /* __CORE_CM4_SIMD_H */ - -#ifdef __cplusplus -} -#endif diff --git a/cmsis/core_cm7.h b/cmsis/core_cm7.h deleted file mode 100644 index 54d78be3dbf..00000000000 --- a/cmsis/core_cm7.h +++ /dev/null @@ -1,2407 +0,0 @@ -/**************************************************************************//** - * @file core_cm7.h - * @brief CMSIS Cortex-M7 Core Peripheral Access Layer Header File - * @version V4.10 - * @date 18. March 2015 - * - * @note - * - ******************************************************************************/ -/* Copyright (c) 2009 - 2015 ARM LIMITED - - All rights reserved. - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - Neither the name of ARM nor the names of its contributors may be used - to endorse or promote products derived from this software without - specific prior written permission. - * - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - ---------------------------------------------------------------------------*/ - - -#if defined ( __ICCARM__ ) - #pragma system_include /* treat file as system include file for MISRA check */ -#endif - -#ifndef __CORE_CM7_H_GENERIC -#define __CORE_CM7_H_GENERIC - -#ifdef __cplusplus - extern "C" { -#endif - -/** \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions - CMSIS violates the following MISRA-C:2004 rules: - - \li Required Rule 8.5, object/function definition in header file.
- Function definitions in header files are used to allow 'inlining'. - - \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
- Unions are used for effective representation of core registers. - - \li Advisory Rule 19.7, Function-like macro defined.
- Function-like macros are used to allow more efficient code. - */ - - -/******************************************************************************* - * CMSIS definitions - ******************************************************************************/ -/** \ingroup Cortex_M7 - @{ - */ - -/* CMSIS CM7 definitions */ -#define __CM7_CMSIS_VERSION_MAIN (0x04) /*!< [31:16] CMSIS HAL main version */ -#define __CM7_CMSIS_VERSION_SUB (0x00) /*!< [15:0] CMSIS HAL sub version */ -#define __CM7_CMSIS_VERSION ((__CM7_CMSIS_VERSION_MAIN << 16) | \ - __CM7_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */ - -#define __CORTEX_M (0x07) /*!< Cortex-M Core */ - - -#if defined ( __CC_ARM ) - #define __ASM __asm /*!< asm keyword for ARM Compiler */ - #define __INLINE __inline /*!< inline keyword for ARM Compiler */ - #define __STATIC_INLINE static __inline - -#elif defined ( __GNUC__ ) - #define __ASM __asm /*!< asm keyword for GNU Compiler */ - #define __INLINE inline /*!< inline keyword for GNU Compiler */ - #define __STATIC_INLINE static inline - -#elif defined ( __ICCARM__ ) - #define __ASM __asm /*!< asm keyword for IAR Compiler */ - #define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */ - #define __STATIC_INLINE static inline - -#elif defined ( __TMS470__ ) - #define __ASM __asm /*!< asm keyword for TI CCS Compiler */ - #define __STATIC_INLINE static inline - -#elif defined ( __TASKING__ ) - #define __ASM __asm /*!< asm keyword for TASKING Compiler */ - #define __INLINE inline /*!< inline keyword for TASKING Compiler */ - #define __STATIC_INLINE static inline - -#elif defined ( __CSMC__ ) - #define __packed - #define __ASM _asm /*!< asm keyword for COSMIC Compiler */ - #define __INLINE inline /*use -pc99 on compile line !< inline keyword for COSMIC Compiler */ - #define __STATIC_INLINE static inline - -#endif - -/** __FPU_USED indicates whether an FPU is used or not. - For this, __FPU_PRESENT has to be checked prior to making use of FPU specific registers and functions. -*/ -#if defined ( __CC_ARM ) - #if defined __TARGET_FPU_VFP - #if (__FPU_PRESENT == 1) - #define __FPU_USED 1 - #else - #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #define __FPU_USED 0 - #endif - #else - #define __FPU_USED 0 - #endif - -#elif defined ( __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 ( __ICCARM__ ) - #if defined __ARMVFP__ - #if (__FPU_PRESENT == 1) - #define __FPU_USED 1 - #else - #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #define __FPU_USED 0 - #endif - #else - #define __FPU_USED 0 - #endif - -#elif defined ( __TMS470__ ) - #if defined __TI_VFP_SUPPORT__ - #if (__FPU_PRESENT == 1) - #define __FPU_USED 1 - #else - #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #define __FPU_USED 0 - #endif - #else - #define __FPU_USED 0 - #endif - -#elif defined ( __TASKING__ ) - #if defined __FPU_VFP__ - #if (__FPU_PRESENT == 1) - #define __FPU_USED 1 - #else - #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #define __FPU_USED 0 - #endif - #else - #define __FPU_USED 0 - #endif - -#elif defined ( __CSMC__ ) /* Cosmic */ - #if ( __CSMC__ & 0x400) // FPU present for parser - #if (__FPU_PRESENT == 1) - #define __FPU_USED 1 - #else - #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #define __FPU_USED 0 - #endif - #else - #define __FPU_USED 0 - #endif -#endif - -#include /* standard types definitions */ -#include /* Core Instruction Access */ -#include /* Core Function Access */ -#include /* Compiler specific SIMD Intrinsics */ - -#ifdef __cplusplus -} -#endif - -#endif /* __CORE_CM7_H_GENERIC */ - -#ifndef __CMSIS_GENERIC - -#ifndef __CORE_CM7_H_DEPENDANT -#define __CORE_CM7_H_DEPENDANT - -#ifdef __cplusplus - extern "C" { -#endif - -/* check device defines and use defaults */ -#if defined __CHECK_DEVICE_DEFINES - #ifndef __CM7_REV - #define __CM7_REV 0x0000 - #warning "__CM7_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 __ICACHE_PRESENT - #define __ICACHE_PRESENT 0 - #warning "__ICACHE_PRESENT not defined in device header file; using default!" - #endif - - #ifndef __DCACHE_PRESENT - #define __DCACHE_PRESENT 0 - #warning "__DCACHE_PRESENT not defined in device header file; using default!" - #endif - - #ifndef __DTCM_PRESENT - #define __DTCM_PRESENT 0 - #warning "__DTCM_PRESENT not defined in device header file; using default!" - #endif - - #ifndef __NVIC_PRIO_BITS - #define __NVIC_PRIO_BITS 3 - #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" - #endif - - #ifndef __Vendor_SysTickConfig - #define __Vendor_SysTickConfig 0 - #warning "__Vendor_SysTickConfig not defined in device header file; using default!" - #endif -#endif - -/* IO definitions (access restrictions to peripheral registers) */ -/** - \defgroup CMSIS_glob_defs CMSIS Global Defines - - IO Type Qualifiers are used - \li to specify the access to peripheral variables. - \li for automatic generation of peripheral register debug information. -*/ -#ifdef __cplusplus - #define __I volatile /*!< Defines 'read only' permissions */ -#else - #define __I volatile const /*!< Defines 'read only' permissions */ -#endif -#define __O volatile /*!< Defines 'write only' permissions */ -#define __IO volatile /*!< Defines 'read / write' permissions */ - -#ifdef __cplusplus - #define __IM volatile /*!< Defines 'read only' permissions */ -#else - #define __IM volatile const /*!< Defines 'read only' permissions */ -#endif -#define __OM volatile /*!< Defines 'write only' permissions */ -#define __IOM volatile /*!< Defines 'read / write' permissions */ - -/*@} end of group Cortex_M7 */ - - - -/******************************************************************************* - * Register Abstraction - Core Register contain: - - Core Register - - Core NVIC Register - - Core SCB Register - - Core SysTick Register - - Core Debug Register - - Core MPU Register - - Core FPU Register - ******************************************************************************/ -/** \defgroup CMSIS_core_register Defines and Type Definitions - \brief Type definitions and defines for Cortex-M processor based devices. -*/ - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_CORE Status and Control Registers - \brief Core Register type definitions. - @{ - */ - -/** \brief Union type to access the Application Program Status Register (APSR). - */ -typedef union -{ - struct - { - 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 */ - 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; - -/* APSR Register Definitions */ -#define APSR_N_Pos 31 /*!< APSR: N Position */ -#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ - -#define APSR_Z_Pos 30 /*!< APSR: Z Position */ -#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ - -#define APSR_C_Pos 29 /*!< APSR: C Position */ -#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ - -#define APSR_V_Pos 28 /*!< APSR: V Position */ -#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ - -#define APSR_Q_Pos 27 /*!< APSR: Q Position */ -#define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */ - -#define APSR_GE_Pos 16 /*!< APSR: GE Position */ -#define APSR_GE_Msk (0xFUL << APSR_GE_Pos) /*!< APSR: GE Mask */ - - -/** \brief Union type to access the Interrupt Program Status Register (IPSR). - */ -typedef union -{ - struct - { - uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ - uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ - } b; /*!< Structure used for bit access */ - uint32_t w; /*!< Type used for word access */ -} IPSR_Type; - -/* IPSR Register Definitions */ -#define IPSR_ISR_Pos 0 /*!< IPSR: ISR Position */ -#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ - - -/** \brief Union type to access the Special-Purpose Program Status Registers (xPSR). - */ -typedef union -{ - struct - { - uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ - uint32_t _reserved0: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 */ - 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; - -/* xPSR Register Definitions */ -#define xPSR_N_Pos 31 /*!< xPSR: N Position */ -#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ - -#define xPSR_Z_Pos 30 /*!< xPSR: Z Position */ -#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ - -#define xPSR_C_Pos 29 /*!< xPSR: C Position */ -#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ - -#define xPSR_V_Pos 28 /*!< xPSR: V Position */ -#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ - -#define xPSR_Q_Pos 27 /*!< xPSR: Q Position */ -#define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */ - -#define xPSR_IT_Pos 25 /*!< xPSR: IT Position */ -#define xPSR_IT_Msk (3UL << xPSR_IT_Pos) /*!< xPSR: IT Mask */ - -#define xPSR_T_Pos 24 /*!< xPSR: T Position */ -#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ - -#define xPSR_GE_Pos 16 /*!< xPSR: GE Position */ -#define xPSR_GE_Msk (0xFUL << xPSR_GE_Pos) /*!< xPSR: GE Mask */ - -#define xPSR_ISR_Pos 0 /*!< xPSR: ISR Position */ -#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ - - -/** \brief Union type to access the Control Registers (CONTROL). - */ -typedef union -{ - struct - { - uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ - uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ - uint32_t 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; - -/* CONTROL Register Definitions */ -#define CONTROL_FPCA_Pos 2 /*!< CONTROL: FPCA Position */ -#define CONTROL_FPCA_Msk (1UL << CONTROL_FPCA_Pos) /*!< CONTROL: FPCA Mask */ - -#define CONTROL_SPSEL_Pos 1 /*!< CONTROL: SPSEL Position */ -#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ - -#define CONTROL_nPRIV_Pos 0 /*!< CONTROL: nPRIV Position */ -#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ - -/*@} end of group CMSIS_CORE */ - - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) - \brief Type definitions for the NVIC Registers - @{ - */ - -/** \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). - */ -typedef struct -{ - __IO uint32_t ISER[8]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ - uint32_t RESERVED0[24]; - __IO uint32_t ICER[8]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ - uint32_t RSERVED1[24]; - __IO uint32_t ISPR[8]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ - uint32_t RESERVED2[24]; - __IO uint32_t ICPR[8]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ - uint32_t RESERVED3[24]; - __IO uint32_t IABR[8]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ - uint32_t RESERVED4[56]; - __IO uint8_t IP[240]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ - uint32_t RESERVED5[644]; - __O uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ -} NVIC_Type; - -/* Software Triggered Interrupt Register Definitions */ -#define NVIC_STIR_INTID_Pos 0 /*!< STIR: INTLINESNUM Position */ -#define NVIC_STIR_INTID_Msk (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/) /*!< STIR: INTLINESNUM Mask */ - -/*@} end of group CMSIS_NVIC */ - - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_SCB System Control Block (SCB) - \brief Type definitions for the System Control Block Registers - @{ - */ - -/** \brief Structure type to access the System Control Block (SCB). - */ -typedef struct -{ - __I uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ - __IO uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ - __IO uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ - __IO uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ - __IO uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ - __IO uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ - __IO uint8_t SHPR[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 ID_PFR[2]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ - __I uint32_t ID_DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ - __I uint32_t ID_AFR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ - __I uint32_t ID_MFR[4]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ - __I uint32_t ID_ISAR[5]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ - uint32_t RESERVED0[1]; - __I uint32_t CLIDR; /*!< Offset: 0x078 (R/ ) Cache Level ID register */ - __I uint32_t CTR; /*!< Offset: 0x07C (R/ ) Cache Type register */ - __I uint32_t CCSIDR; /*!< Offset: 0x080 (R/ ) Cache Size ID Register */ - __IO uint32_t CSSELR; /*!< Offset: 0x084 (R/W) Cache Size Selection Register */ - __IO uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ - uint32_t RESERVED3[93]; - __O uint32_t STIR; /*!< Offset: 0x200 ( /W) Software Triggered Interrupt Register */ - uint32_t RESERVED4[15]; - __I uint32_t MVFR0; /*!< Offset: 0x240 (R/ ) Media and VFP Feature Register 0 */ - __I uint32_t MVFR1; /*!< Offset: 0x244 (R/ ) Media and VFP Feature Register 1 */ - __I uint32_t MVFR2; /*!< Offset: 0x248 (R/ ) Media and VFP Feature Register 1 */ - uint32_t RESERVED5[1]; - __O uint32_t ICIALLU; /*!< Offset: 0x250 ( /W) I-Cache Invalidate All to PoU */ - uint32_t RESERVED6[1]; - __O uint32_t ICIMVAU; /*!< Offset: 0x258 ( /W) I-Cache Invalidate by MVA to PoU */ - __O uint32_t DCIMVAC; /*!< Offset: 0x25C ( /W) D-Cache Invalidate by MVA to PoC */ - __O uint32_t DCISW; /*!< Offset: 0x260 ( /W) D-Cache Invalidate by Set-way */ - __O uint32_t DCCMVAU; /*!< Offset: 0x264 ( /W) D-Cache Clean by MVA to PoU */ - __O uint32_t DCCMVAC; /*!< Offset: 0x268 ( /W) D-Cache Clean by MVA to PoC */ - __O uint32_t DCCSW; /*!< Offset: 0x26C ( /W) D-Cache Clean by Set-way */ - __O uint32_t DCCIMVAC; /*!< Offset: 0x270 ( /W) D-Cache Clean and Invalidate by MVA to PoC */ - __O uint32_t DCCISW; /*!< Offset: 0x274 ( /W) D-Cache Clean and Invalidate by Set-way */ - uint32_t RESERVED7[6]; - __IO uint32_t ITCMCR; /*!< Offset: 0x290 (R/W) Instruction Tightly-Coupled Memory Control Register */ - __IO uint32_t DTCMCR; /*!< Offset: 0x294 (R/W) Data Tightly-Coupled Memory Control Registers */ - __IO uint32_t AHBPCR; /*!< Offset: 0x298 (R/W) AHBP Control Register */ - __IO uint32_t CACR; /*!< Offset: 0x29C (R/W) L1 Cache Control Register */ - __IO uint32_t AHBSCR; /*!< Offset: 0x2A0 (R/W) AHB Slave Control Register */ - uint32_t RESERVED8[1]; - __IO uint32_t ABFSR; /*!< Offset: 0x2A8 (R/W) Auxiliary Bus Fault Status 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_BP_Pos 18 /*!< SCB CCR: Branch prediction enable bit Position */ -#define SCB_CCR_BP_Msk (1UL << SCB_CCR_BP_Pos) /*!< SCB CCR: Branch prediction enable bit Mask */ - -#define SCB_CCR_IC_Pos 17 /*!< SCB CCR: Instruction cache enable bit Position */ -#define SCB_CCR_IC_Msk (1UL << SCB_CCR_IC_Pos) /*!< SCB CCR: Instruction cache enable bit Mask */ - -#define SCB_CCR_DC_Pos 16 /*!< SCB CCR: Cache enable bit Position */ -#define SCB_CCR_DC_Msk (1UL << SCB_CCR_DC_Pos) /*!< SCB CCR: Cache enable bit Mask */ - -#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 */ - -/* Cache Level ID register */ -#define SCB_CLIDR_LOUU_Pos 27 /*!< SCB CLIDR: LoUU Position */ -#define SCB_CLIDR_LOUU_Msk (7UL << SCB_CLIDR_LOUU_Pos) /*!< SCB CLIDR: LoUU Mask */ - -#define SCB_CLIDR_LOC_Pos 24 /*!< SCB CLIDR: LoC Position */ -#define SCB_CLIDR_LOC_Msk (7UL << SCB_CLIDR_FORMAT_Pos) /*!< SCB CLIDR: LoC Mask */ - -/* Cache Type register */ -#define SCB_CTR_FORMAT_Pos 29 /*!< SCB CTR: Format Position */ -#define SCB_CTR_FORMAT_Msk (7UL << SCB_CTR_FORMAT_Pos) /*!< SCB CTR: Format Mask */ - -#define SCB_CTR_CWG_Pos 24 /*!< SCB CTR: CWG Position */ -#define SCB_CTR_CWG_Msk (0xFUL << SCB_CTR_CWG_Pos) /*!< SCB CTR: CWG Mask */ - -#define SCB_CTR_ERG_Pos 20 /*!< SCB CTR: ERG Position */ -#define SCB_CTR_ERG_Msk (0xFUL << SCB_CTR_ERG_Pos) /*!< SCB CTR: ERG Mask */ - -#define SCB_CTR_DMINLINE_Pos 16 /*!< SCB CTR: DminLine Position */ -#define SCB_CTR_DMINLINE_Msk (0xFUL << SCB_CTR_DMINLINE_Pos) /*!< SCB CTR: DminLine Mask */ - -#define SCB_CTR_IMINLINE_Pos 0 /*!< SCB CTR: ImInLine Position */ -#define SCB_CTR_IMINLINE_Msk (0xFUL /*<< SCB_CTR_IMINLINE_Pos*/) /*!< SCB CTR: ImInLine Mask */ - -/* Cache Size ID Register */ -#define SCB_CCSIDR_WT_Pos 31 /*!< SCB CCSIDR: WT Position */ -#define SCB_CCSIDR_WT_Msk (7UL << SCB_CCSIDR_WT_Pos) /*!< SCB CCSIDR: WT Mask */ - -#define SCB_CCSIDR_WB_Pos 30 /*!< SCB CCSIDR: WB Position */ -#define SCB_CCSIDR_WB_Msk (7UL << SCB_CCSIDR_WB_Pos) /*!< SCB CCSIDR: WB Mask */ - -#define SCB_CCSIDR_RA_Pos 29 /*!< SCB CCSIDR: RA Position */ -#define SCB_CCSIDR_RA_Msk (7UL << SCB_CCSIDR_RA_Pos) /*!< SCB CCSIDR: RA Mask */ - -#define SCB_CCSIDR_WA_Pos 28 /*!< SCB CCSIDR: WA Position */ -#define SCB_CCSIDR_WA_Msk (7UL << SCB_CCSIDR_WA_Pos) /*!< SCB CCSIDR: WA Mask */ - -#define SCB_CCSIDR_NUMSETS_Pos 13 /*!< SCB CCSIDR: NumSets Position */ -#define SCB_CCSIDR_NUMSETS_Msk (0x7FFFUL << SCB_CCSIDR_NUMSETS_Pos) /*!< SCB CCSIDR: NumSets Mask */ - -#define SCB_CCSIDR_ASSOCIATIVITY_Pos 3 /*!< SCB CCSIDR: Associativity Position */ -#define SCB_CCSIDR_ASSOCIATIVITY_Msk (0x3FFUL << SCB_CCSIDR_ASSOCIATIVITY_Pos) /*!< SCB CCSIDR: Associativity Mask */ - -#define SCB_CCSIDR_LINESIZE_Pos 0 /*!< SCB CCSIDR: LineSize Position */ -#define SCB_CCSIDR_LINESIZE_Msk (7UL /*<< SCB_CCSIDR_LINESIZE_Pos*/) /*!< SCB CCSIDR: LineSize Mask */ - -/* Cache Size Selection Register */ -#define SCB_CSSELR_LEVEL_Pos 1 /*!< SCB CSSELR: Level Position */ -#define SCB_CSSELR_LEVEL_Msk (7UL << SCB_CSSELR_LEVEL_Pos) /*!< SCB CSSELR: Level Mask */ - -#define SCB_CSSELR_IND_Pos 0 /*!< SCB CSSELR: InD Position */ -#define SCB_CSSELR_IND_Msk (1UL /*<< SCB_CSSELR_IND_Pos*/) /*!< SCB CSSELR: InD Mask */ - -/* SCB Software Triggered Interrupt Register */ -#define SCB_STIR_INTID_Pos 0 /*!< SCB STIR: INTID Position */ -#define SCB_STIR_INTID_Msk (0x1FFUL /*<< SCB_STIR_INTID_Pos*/) /*!< SCB STIR: INTID Mask */ - -/* Instruction Tightly-Coupled Memory Control Register*/ -#define SCB_ITCMCR_SZ_Pos 3 /*!< SCB ITCMCR: SZ Position */ -#define SCB_ITCMCR_SZ_Msk (0xFUL << SCB_ITCMCR_SZ_Pos) /*!< SCB ITCMCR: SZ Mask */ - -#define SCB_ITCMCR_RETEN_Pos 2 /*!< SCB ITCMCR: RETEN Position */ -#define SCB_ITCMCR_RETEN_Msk (1UL << SCB_ITCMCR_RETEN_Pos) /*!< SCB ITCMCR: RETEN Mask */ - -#define SCB_ITCMCR_RMW_Pos 1 /*!< SCB ITCMCR: RMW Position */ -#define SCB_ITCMCR_RMW_Msk (1UL << SCB_ITCMCR_RMW_Pos) /*!< SCB ITCMCR: RMW Mask */ - -#define SCB_ITCMCR_EN_Pos 0 /*!< SCB ITCMCR: EN Position */ -#define SCB_ITCMCR_EN_Msk (1UL /*<< SCB_ITCMCR_EN_Pos*/) /*!< SCB ITCMCR: EN Mask */ - -/* Data Tightly-Coupled Memory Control Registers */ -#define SCB_DTCMCR_SZ_Pos 3 /*!< SCB DTCMCR: SZ Position */ -#define SCB_DTCMCR_SZ_Msk (0xFUL << SCB_DTCMCR_SZ_Pos) /*!< SCB DTCMCR: SZ Mask */ - -#define SCB_DTCMCR_RETEN_Pos 2 /*!< SCB DTCMCR: RETEN Position */ -#define SCB_DTCMCR_RETEN_Msk (1UL << SCB_DTCMCR_RETEN_Pos) /*!< SCB DTCMCR: RETEN Mask */ - -#define SCB_DTCMCR_RMW_Pos 1 /*!< SCB DTCMCR: RMW Position */ -#define SCB_DTCMCR_RMW_Msk (1UL << SCB_DTCMCR_RMW_Pos) /*!< SCB DTCMCR: RMW Mask */ - -#define SCB_DTCMCR_EN_Pos 0 /*!< SCB DTCMCR: EN Position */ -#define SCB_DTCMCR_EN_Msk (1UL /*<< SCB_DTCMCR_EN_Pos*/) /*!< SCB DTCMCR: EN Mask */ - -/* AHBP Control Register */ -#define SCB_AHBPCR_SZ_Pos 1 /*!< SCB AHBPCR: SZ Position */ -#define SCB_AHBPCR_SZ_Msk (7UL << SCB_AHBPCR_SZ_Pos) /*!< SCB AHBPCR: SZ Mask */ - -#define SCB_AHBPCR_EN_Pos 0 /*!< SCB AHBPCR: EN Position */ -#define SCB_AHBPCR_EN_Msk (1UL /*<< SCB_AHBPCR_EN_Pos*/) /*!< SCB AHBPCR: EN Mask */ - -/* L1 Cache Control Register */ -#define SCB_CACR_FORCEWT_Pos 2 /*!< SCB CACR: FORCEWT Position */ -#define SCB_CACR_FORCEWT_Msk (1UL << SCB_CACR_FORCEWT_Pos) /*!< SCB CACR: FORCEWT Mask */ - -#define SCB_CACR_ECCEN_Pos 1 /*!< SCB CACR: ECCEN Position */ -#define SCB_CACR_ECCEN_Msk (1UL << SCB_CACR_ECCEN_Pos) /*!< SCB CACR: ECCEN Mask */ - -#define SCB_CACR_SIWT_Pos 0 /*!< SCB CACR: SIWT Position */ -#define SCB_CACR_SIWT_Msk (1UL /*<< SCB_CACR_SIWT_Pos*/) /*!< SCB CACR: SIWT Mask */ - -/* AHBS control register */ -#define SCB_AHBSCR_INITCOUNT_Pos 11 /*!< SCB AHBSCR: INITCOUNT Position */ -#define SCB_AHBSCR_INITCOUNT_Msk (0x1FUL << SCB_AHBPCR_INITCOUNT_Pos) /*!< SCB AHBSCR: INITCOUNT Mask */ - -#define SCB_AHBSCR_TPRI_Pos 2 /*!< SCB AHBSCR: TPRI Position */ -#define SCB_AHBSCR_TPRI_Msk (0x1FFUL << SCB_AHBPCR_TPRI_Pos) /*!< SCB AHBSCR: TPRI Mask */ - -#define SCB_AHBSCR_CTL_Pos 0 /*!< SCB AHBSCR: CTL Position*/ -#define SCB_AHBSCR_CTL_Msk (3UL /*<< SCB_AHBPCR_CTL_Pos*/) /*!< SCB AHBSCR: CTL Mask */ - -/* Auxiliary Bus Fault Status Register */ -#define SCB_ABFSR_AXIMTYPE_Pos 8 /*!< SCB ABFSR: AXIMTYPE Position*/ -#define SCB_ABFSR_AXIMTYPE_Msk (3UL << SCB_ABFSR_AXIMTYPE_Pos) /*!< SCB ABFSR: AXIMTYPE Mask */ - -#define SCB_ABFSR_EPPB_Pos 4 /*!< SCB ABFSR: EPPB Position*/ -#define SCB_ABFSR_EPPB_Msk (1UL << SCB_ABFSR_EPPB_Pos) /*!< SCB ABFSR: EPPB Mask */ - -#define SCB_ABFSR_AXIM_Pos 3 /*!< SCB ABFSR: AXIM Position*/ -#define SCB_ABFSR_AXIM_Msk (1UL << SCB_ABFSR_AXIM_Pos) /*!< SCB ABFSR: AXIM Mask */ - -#define SCB_ABFSR_AHBP_Pos 2 /*!< SCB ABFSR: AHBP Position*/ -#define SCB_ABFSR_AHBP_Msk (1UL << SCB_ABFSR_AHBP_Pos) /*!< SCB ABFSR: AHBP Mask */ - -#define SCB_ABFSR_DTCM_Pos 1 /*!< SCB ABFSR: DTCM Position*/ -#define SCB_ABFSR_DTCM_Msk (1UL << SCB_ABFSR_DTCM_Pos) /*!< SCB ABFSR: DTCM Mask */ - -#define SCB_ABFSR_ITCM_Pos 0 /*!< SCB ABFSR: ITCM Position*/ -#define SCB_ABFSR_ITCM_Msk (1UL /*<< SCB_ABFSR_ITCM_Pos*/) /*!< SCB ABFSR: ITCM Mask */ - -/*@} end of group CMSIS_SCB */ - - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) - \brief Type definitions for the System Control and ID Register not in the SCB - @{ - */ - -/** \brief Structure type to access the System Control and ID Register not in the SCB. - */ -typedef struct -{ - uint32_t RESERVED0[1]; - __I uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ - __IO uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ -} SCnSCB_Type; - -/* Interrupt Controller Type Register Definitions */ -#define SCnSCB_ICTR_INTLINESNUM_Pos 0 /*!< ICTR: INTLINESNUM Position */ -#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/) /*!< ICTR: INTLINESNUM Mask */ - -/* Auxiliary Control Register Definitions */ -#define SCnSCB_ACTLR_DISITMATBFLUSH_Pos 12 /*!< ACTLR: DISITMATBFLUSH Position */ -#define SCnSCB_ACTLR_DISITMATBFLUSH_Msk (1UL << SCnSCB_ACTLR_DISITMATBFLUSH_Pos) /*!< ACTLR: DISITMATBFLUSH Mask */ - -#define SCnSCB_ACTLR_DISRAMODE_Pos 11 /*!< ACTLR: DISRAMODE Position */ -#define SCnSCB_ACTLR_DISRAMODE_Msk (1UL << SCnSCB_ACTLR_DISRAMODE_Pos) /*!< ACTLR: DISRAMODE Mask */ - -#define SCnSCB_ACTLR_FPEXCODIS_Pos 10 /*!< ACTLR: FPEXCODIS Position */ -#define SCnSCB_ACTLR_FPEXCODIS_Msk (1UL << SCnSCB_ACTLR_FPEXCODIS_Pos) /*!< ACTLR: FPEXCODIS 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_DISMCYCINT_Pos 0 /*!< ACTLR: DISMCYCINT Position */ -#define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL /*<< SCnSCB_ACTLR_DISMCYCINT_Pos*/) /*!< ACTLR: DISMCYCINT Mask */ - -/*@} end of group CMSIS_SCnotSCB */ - - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_SysTick System Tick Timer (SysTick) - \brief Type definitions for the System Timer Registers. - @{ - */ - -/** \brief Structure type to access the System Timer (SysTick). - */ -typedef struct -{ - __IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ - __IO uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ - __IO uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ - __I uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ -} SysTick_Type; - -/* SysTick Control / Status Register Definitions */ -#define SysTick_CTRL_COUNTFLAG_Pos 16 /*!< SysTick CTRL: COUNTFLAG Position */ -#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ - -#define SysTick_CTRL_CLKSOURCE_Pos 2 /*!< SysTick CTRL: CLKSOURCE Position */ -#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ - -#define SysTick_CTRL_TICKINT_Pos 1 /*!< SysTick CTRL: TICKINT Position */ -#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ - -#define SysTick_CTRL_ENABLE_Pos 0 /*!< SysTick CTRL: ENABLE Position */ -#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ - -/* SysTick Reload Register Definitions */ -#define SysTick_LOAD_RELOAD_Pos 0 /*!< SysTick LOAD: RELOAD Position */ -#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ - -/* SysTick Current Register Definitions */ -#define SysTick_VAL_CURRENT_Pos 0 /*!< SysTick VAL: CURRENT Position */ -#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ - -/* SysTick Calibration Register Definitions */ -#define SysTick_CALIB_NOREF_Pos 31 /*!< SysTick CALIB: NOREF Position */ -#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ - -#define SysTick_CALIB_SKEW_Pos 30 /*!< SysTick CALIB: SKEW Position */ -#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ - -#define SysTick_CALIB_TENMS_Pos 0 /*!< SysTick CALIB: TENMS Position */ -#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ - -/*@} end of group CMSIS_SysTick */ - - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) - \brief Type definitions for the Instrumentation Trace Macrocell (ITM) - @{ - */ - -/** \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). - */ -typedef struct -{ - __O union - { - __O uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ - __O uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ - __O uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ - } PORT [32]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ - uint32_t RESERVED0[864]; - __IO uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ - uint32_t RESERVED1[15]; - __IO uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ - uint32_t RESERVED2[15]; - __IO uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ - uint32_t RESERVED3[29]; - __O uint32_t IWR; /*!< Offset: 0xEF8 ( /W) ITM Integration Write Register */ - __I uint32_t IRR; /*!< Offset: 0xEFC (R/ ) ITM Integration Read Register */ - __IO uint32_t IMCR; /*!< Offset: 0xF00 (R/W) ITM Integration Mode Control Register */ - uint32_t RESERVED4[43]; - __O uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ - __I uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ - uint32_t RESERVED5[6]; - __I uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ - __I uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ - __I uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ - __I uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ - __I uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ - __I uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ - __I uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ - __I uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ - __I uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ - __I uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ - __I uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ - __I uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ -} ITM_Type; - -/* ITM Trace Privilege Register Definitions */ -#define ITM_TPR_PRIVMASK_Pos 0 /*!< ITM TPR: PRIVMASK Position */ -#define ITM_TPR_PRIVMASK_Msk (0xFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ - -/* ITM Trace Control Register Definitions */ -#define ITM_TCR_BUSY_Pos 23 /*!< ITM TCR: BUSY Position */ -#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ - -#define ITM_TCR_TraceBusID_Pos 16 /*!< ITM TCR: ATBID Position */ -#define ITM_TCR_TraceBusID_Msk (0x7FUL << ITM_TCR_TraceBusID_Pos) /*!< ITM TCR: ATBID Mask */ - -#define ITM_TCR_GTSFREQ_Pos 10 /*!< ITM TCR: Global timestamp frequency Position */ -#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ - -#define ITM_TCR_TSPrescale_Pos 8 /*!< ITM TCR: TSPrescale Position */ -#define ITM_TCR_TSPrescale_Msk (3UL << ITM_TCR_TSPrescale_Pos) /*!< ITM TCR: TSPrescale Mask */ - -#define ITM_TCR_SWOENA_Pos 4 /*!< ITM TCR: SWOENA Position */ -#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ - -#define ITM_TCR_DWTENA_Pos 3 /*!< ITM TCR: DWTENA Position */ -#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ - -#define ITM_TCR_SYNCENA_Pos 2 /*!< ITM TCR: SYNCENA Position */ -#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ - -#define ITM_TCR_TSENA_Pos 1 /*!< ITM TCR: TSENA Position */ -#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ - -#define ITM_TCR_ITMENA_Pos 0 /*!< ITM TCR: ITM Enable bit Position */ -#define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */ - -/* ITM Integration Write Register Definitions */ -#define ITM_IWR_ATVALIDM_Pos 0 /*!< ITM IWR: ATVALIDM Position */ -#define ITM_IWR_ATVALIDM_Msk (1UL /*<< ITM_IWR_ATVALIDM_Pos*/) /*!< ITM IWR: ATVALIDM Mask */ - -/* ITM Integration Read Register Definitions */ -#define ITM_IRR_ATREADYM_Pos 0 /*!< ITM IRR: ATREADYM Position */ -#define ITM_IRR_ATREADYM_Msk (1UL /*<< ITM_IRR_ATREADYM_Pos*/) /*!< ITM IRR: ATREADYM Mask */ - -/* ITM Integration Mode Control Register Definitions */ -#define ITM_IMCR_INTEGRATION_Pos 0 /*!< ITM IMCR: INTEGRATION Position */ -#define ITM_IMCR_INTEGRATION_Msk (1UL /*<< ITM_IMCR_INTEGRATION_Pos*/) /*!< ITM IMCR: INTEGRATION Mask */ - -/* ITM Lock Status Register Definitions */ -#define ITM_LSR_ByteAcc_Pos 2 /*!< ITM LSR: ByteAcc Position */ -#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ - -#define ITM_LSR_Access_Pos 1 /*!< ITM LSR: Access Position */ -#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ - -#define ITM_LSR_Present_Pos 0 /*!< ITM LSR: Present Position */ -#define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */ - -/*@}*/ /* end of group CMSIS_ITM */ - - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) - \brief Type definitions for the Data Watchpoint and Trace (DWT) - @{ - */ - -/** \brief Structure type to access the Data Watchpoint and Trace Register (DWT). - */ -typedef struct -{ - __IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ - __IO uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ - __IO uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ - __IO uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ - __IO uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ - __IO uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ - __IO uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ - __I uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ - __IO uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ - __IO uint32_t MASK0; /*!< Offset: 0x024 (R/W) Mask Register 0 */ - __IO uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ - uint32_t RESERVED0[1]; - __IO uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ - __IO uint32_t MASK1; /*!< Offset: 0x034 (R/W) Mask Register 1 */ - __IO uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ - uint32_t RESERVED1[1]; - __IO uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ - __IO uint32_t MASK2; /*!< Offset: 0x044 (R/W) Mask Register 2 */ - __IO uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ - uint32_t RESERVED2[1]; - __IO uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ - __IO uint32_t MASK3; /*!< Offset: 0x054 (R/W) Mask Register 3 */ - __IO uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ - uint32_t RESERVED3[981]; - __O uint32_t LAR; /*!< Offset: 0xFB0 ( W) Lock Access Register */ - __I uint32_t LSR; /*!< Offset: 0xFB4 (R ) Lock Status Register */ -} DWT_Type; - -/* DWT Control Register Definitions */ -#define DWT_CTRL_NUMCOMP_Pos 28 /*!< DWT CTRL: NUMCOMP Position */ -#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ - -#define DWT_CTRL_NOTRCPKT_Pos 27 /*!< DWT CTRL: NOTRCPKT Position */ -#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ - -#define DWT_CTRL_NOEXTTRIG_Pos 26 /*!< DWT CTRL: NOEXTTRIG Position */ -#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ - -#define DWT_CTRL_NOCYCCNT_Pos 25 /*!< DWT CTRL: NOCYCCNT Position */ -#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ - -#define DWT_CTRL_NOPRFCNT_Pos 24 /*!< DWT CTRL: NOPRFCNT Position */ -#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ - -#define DWT_CTRL_CYCEVTENA_Pos 22 /*!< DWT CTRL: CYCEVTENA Position */ -#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ - -#define DWT_CTRL_FOLDEVTENA_Pos 21 /*!< DWT CTRL: FOLDEVTENA Position */ -#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ - -#define DWT_CTRL_LSUEVTENA_Pos 20 /*!< DWT CTRL: LSUEVTENA Position */ -#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ - -#define DWT_CTRL_SLEEPEVTENA_Pos 19 /*!< DWT CTRL: SLEEPEVTENA Position */ -#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ - -#define DWT_CTRL_EXCEVTENA_Pos 18 /*!< DWT CTRL: EXCEVTENA Position */ -#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ - -#define DWT_CTRL_CPIEVTENA_Pos 17 /*!< DWT CTRL: CPIEVTENA Position */ -#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ - -#define DWT_CTRL_EXCTRCENA_Pos 16 /*!< DWT CTRL: EXCTRCENA Position */ -#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ - -#define DWT_CTRL_PCSAMPLENA_Pos 12 /*!< DWT CTRL: PCSAMPLENA Position */ -#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ - -#define DWT_CTRL_SYNCTAP_Pos 10 /*!< DWT CTRL: SYNCTAP Position */ -#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ - -#define DWT_CTRL_CYCTAP_Pos 9 /*!< DWT CTRL: CYCTAP Position */ -#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ - -#define DWT_CTRL_POSTINIT_Pos 5 /*!< DWT CTRL: POSTINIT Position */ -#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ - -#define DWT_CTRL_POSTPRESET_Pos 1 /*!< DWT CTRL: POSTPRESET Position */ -#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ - -#define DWT_CTRL_CYCCNTENA_Pos 0 /*!< DWT CTRL: CYCCNTENA Position */ -#define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */ - -/* DWT CPI Count Register Definitions */ -#define DWT_CPICNT_CPICNT_Pos 0 /*!< DWT CPICNT: CPICNT Position */ -#define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */ - -/* DWT Exception Overhead Count Register Definitions */ -#define DWT_EXCCNT_EXCCNT_Pos 0 /*!< DWT EXCCNT: EXCCNT Position */ -#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */ - -/* DWT Sleep Count Register Definitions */ -#define DWT_SLEEPCNT_SLEEPCNT_Pos 0 /*!< DWT SLEEPCNT: SLEEPCNT Position */ -#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ - -/* DWT LSU Count Register Definitions */ -#define DWT_LSUCNT_LSUCNT_Pos 0 /*!< DWT LSUCNT: LSUCNT Position */ -#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */ - -/* DWT Folded-instruction Count Register Definitions */ -#define DWT_FOLDCNT_FOLDCNT_Pos 0 /*!< DWT FOLDCNT: FOLDCNT Position */ -#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */ - -/* DWT Comparator Mask Register Definitions */ -#define DWT_MASK_MASK_Pos 0 /*!< DWT MASK: MASK Position */ -#define DWT_MASK_MASK_Msk (0x1FUL /*<< DWT_MASK_MASK_Pos*/) /*!< DWT MASK: MASK Mask */ - -/* DWT Comparator Function Register Definitions */ -#define DWT_FUNCTION_MATCHED_Pos 24 /*!< DWT FUNCTION: MATCHED Position */ -#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ - -#define DWT_FUNCTION_DATAVADDR1_Pos 16 /*!< DWT FUNCTION: DATAVADDR1 Position */ -#define DWT_FUNCTION_DATAVADDR1_Msk (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos) /*!< DWT FUNCTION: DATAVADDR1 Mask */ - -#define DWT_FUNCTION_DATAVADDR0_Pos 12 /*!< DWT FUNCTION: DATAVADDR0 Position */ -#define DWT_FUNCTION_DATAVADDR0_Msk (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos) /*!< DWT FUNCTION: DATAVADDR0 Mask */ - -#define DWT_FUNCTION_DATAVSIZE_Pos 10 /*!< DWT FUNCTION: DATAVSIZE Position */ -#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ - -#define DWT_FUNCTION_LNK1ENA_Pos 9 /*!< DWT FUNCTION: LNK1ENA Position */ -#define DWT_FUNCTION_LNK1ENA_Msk (0x1UL << DWT_FUNCTION_LNK1ENA_Pos) /*!< DWT FUNCTION: LNK1ENA Mask */ - -#define DWT_FUNCTION_DATAVMATCH_Pos 8 /*!< DWT FUNCTION: DATAVMATCH Position */ -#define DWT_FUNCTION_DATAVMATCH_Msk (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos) /*!< DWT FUNCTION: DATAVMATCH Mask */ - -#define DWT_FUNCTION_CYCMATCH_Pos 7 /*!< DWT FUNCTION: CYCMATCH Position */ -#define DWT_FUNCTION_CYCMATCH_Msk (0x1UL << DWT_FUNCTION_CYCMATCH_Pos) /*!< DWT FUNCTION: CYCMATCH Mask */ - -#define DWT_FUNCTION_EMITRANGE_Pos 5 /*!< DWT FUNCTION: EMITRANGE Position */ -#define DWT_FUNCTION_EMITRANGE_Msk (0x1UL << DWT_FUNCTION_EMITRANGE_Pos) /*!< DWT FUNCTION: EMITRANGE Mask */ - -#define DWT_FUNCTION_FUNCTION_Pos 0 /*!< DWT FUNCTION: FUNCTION Position */ -#define DWT_FUNCTION_FUNCTION_Msk (0xFUL /*<< DWT_FUNCTION_FUNCTION_Pos*/) /*!< DWT FUNCTION: FUNCTION Mask */ - -/*@}*/ /* end of group CMSIS_DWT */ - - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_TPI Trace Port Interface (TPI) - \brief Type definitions for the Trace Port Interface (TPI) - @{ - */ - -/** \brief Structure type to access the Trace Port Interface Register (TPI). - */ -typedef struct -{ - __IO uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ - __IO uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ - uint32_t RESERVED0[2]; - __IO uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ - uint32_t RESERVED1[55]; - __IO uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ - uint32_t RESERVED2[131]; - __I uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ - __IO uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ - __I uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ - uint32_t RESERVED3[759]; - __I uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER */ - __I uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ - __I uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ - uint32_t RESERVED4[1]; - __I uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */ - __I uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */ - __IO uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ - uint32_t RESERVED5[39]; - __IO uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ - __IO uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ - uint32_t RESERVED7[8]; - __I uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */ - __I uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */ -} TPI_Type; - -/* TPI Asynchronous Clock Prescaler Register Definitions */ -#define TPI_ACPR_PRESCALER_Pos 0 /*!< TPI ACPR: PRESCALER Position */ -#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< TPI ACPR: PRESCALER Mask */ - -/* TPI Selected Pin Protocol Register Definitions */ -#define TPI_SPPR_TXMODE_Pos 0 /*!< TPI SPPR: TXMODE Position */ -#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ - -/* TPI Formatter and Flush Status Register Definitions */ -#define TPI_FFSR_FtNonStop_Pos 3 /*!< TPI FFSR: FtNonStop Position */ -#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ - -#define TPI_FFSR_TCPresent_Pos 2 /*!< TPI FFSR: TCPresent Position */ -#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ - -#define TPI_FFSR_FtStopped_Pos 1 /*!< TPI FFSR: FtStopped Position */ -#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ - -#define TPI_FFSR_FlInProg_Pos 0 /*!< TPI FFSR: FlInProg Position */ -#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ - -/* TPI Formatter and Flush Control Register Definitions */ -#define TPI_FFCR_TrigIn_Pos 8 /*!< TPI FFCR: TrigIn Position */ -#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ - -#define TPI_FFCR_EnFCont_Pos 1 /*!< TPI FFCR: EnFCont Position */ -#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ - -/* TPI TRIGGER Register Definitions */ -#define TPI_TRIGGER_TRIGGER_Pos 0 /*!< TPI TRIGGER: TRIGGER Position */ -#define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */ - -/* TPI Integration ETM Data Register Definitions (FIFO0) */ -#define TPI_FIFO0_ITM_ATVALID_Pos 29 /*!< TPI FIFO0: ITM_ATVALID Position */ -#define TPI_FIFO0_ITM_ATVALID_Msk (0x3UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ - -#define TPI_FIFO0_ITM_bytecount_Pos 27 /*!< TPI FIFO0: ITM_bytecount Position */ -#define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */ - -#define TPI_FIFO0_ETM_ATVALID_Pos 26 /*!< TPI FIFO0: ETM_ATVALID Position */ -#define TPI_FIFO0_ETM_ATVALID_Msk (0x3UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ - -#define TPI_FIFO0_ETM_bytecount_Pos 24 /*!< TPI FIFO0: ETM_bytecount Position */ -#define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */ - -#define TPI_FIFO0_ETM2_Pos 16 /*!< TPI FIFO0: ETM2 Position */ -#define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */ - -#define TPI_FIFO0_ETM1_Pos 8 /*!< TPI FIFO0: ETM1 Position */ -#define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */ - -#define TPI_FIFO0_ETM0_Pos 0 /*!< TPI FIFO0: ETM0 Position */ -#define TPI_FIFO0_ETM0_Msk (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/) /*!< TPI FIFO0: ETM0 Mask */ - -/* TPI ITATBCTR2 Register Definitions */ -#define TPI_ITATBCTR2_ATREADY_Pos 0 /*!< TPI ITATBCTR2: ATREADY Position */ -#define TPI_ITATBCTR2_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY_Pos*/) /*!< TPI ITATBCTR2: ATREADY Mask */ - -/* TPI Integration ITM Data Register Definitions (FIFO1) */ -#define TPI_FIFO1_ITM_ATVALID_Pos 29 /*!< TPI FIFO1: ITM_ATVALID Position */ -#define TPI_FIFO1_ITM_ATVALID_Msk (0x3UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ - -#define TPI_FIFO1_ITM_bytecount_Pos 27 /*!< TPI FIFO1: ITM_bytecount Position */ -#define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */ - -#define TPI_FIFO1_ETM_ATVALID_Pos 26 /*!< TPI FIFO1: ETM_ATVALID Position */ -#define TPI_FIFO1_ETM_ATVALID_Msk (0x3UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ - -#define TPI_FIFO1_ETM_bytecount_Pos 24 /*!< TPI FIFO1: ETM_bytecount Position */ -#define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */ - -#define TPI_FIFO1_ITM2_Pos 16 /*!< TPI FIFO1: ITM2 Position */ -#define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */ - -#define TPI_FIFO1_ITM1_Pos 8 /*!< TPI FIFO1: ITM1 Position */ -#define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */ - -#define TPI_FIFO1_ITM0_Pos 0 /*!< TPI FIFO1: ITM0 Position */ -#define TPI_FIFO1_ITM0_Msk (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/) /*!< TPI FIFO1: ITM0 Mask */ - -/* TPI ITATBCTR0 Register Definitions */ -#define TPI_ITATBCTR0_ATREADY_Pos 0 /*!< TPI ITATBCTR0: ATREADY Position */ -#define TPI_ITATBCTR0_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY_Pos*/) /*!< TPI ITATBCTR0: ATREADY Mask */ - -/* TPI Integration Mode Control Register Definitions */ -#define TPI_ITCTRL_Mode_Pos 0 /*!< TPI ITCTRL: Mode Position */ -#define TPI_ITCTRL_Mode_Msk (0x1UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ - -/* TPI DEVID Register Definitions */ -#define TPI_DEVID_NRZVALID_Pos 11 /*!< TPI DEVID: NRZVALID Position */ -#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ - -#define TPI_DEVID_MANCVALID_Pos 10 /*!< TPI DEVID: MANCVALID Position */ -#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ - -#define TPI_DEVID_PTINVALID_Pos 9 /*!< TPI DEVID: PTINVALID Position */ -#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ - -#define TPI_DEVID_MinBufSz_Pos 6 /*!< TPI DEVID: MinBufSz Position */ -#define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */ - -#define TPI_DEVID_AsynClkIn_Pos 5 /*!< TPI DEVID: AsynClkIn Position */ -#define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */ - -#define TPI_DEVID_NrTraceInput_Pos 0 /*!< TPI DEVID: NrTraceInput Position */ -#define TPI_DEVID_NrTraceInput_Msk (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ - -/* TPI DEVTYPE Register Definitions */ -#define TPI_DEVTYPE_MajorType_Pos 4 /*!< TPI DEVTYPE: MajorType Position */ -#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ - -#define TPI_DEVTYPE_SubType_Pos 0 /*!< TPI DEVTYPE: SubType Position */ -#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ - -/*@}*/ /* end of group CMSIS_TPI */ - - -#if (__MPU_PRESENT == 1) -/** \ingroup CMSIS_core_register - \defgroup CMSIS_MPU Memory Protection Unit (MPU) - \brief Type definitions for the Memory Protection Unit (MPU) - @{ - */ - -/** \brief Structure type to access the Memory Protection Unit (MPU). - */ -typedef struct -{ - __I uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ - __IO uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ - __IO uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ - __IO uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ - __IO uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ - __IO uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Alias 1 Region Base Address Register */ - __IO uint32_t RASR_A1; /*!< Offset: 0x018 (R/W) MPU Alias 1 Region Attribute and Size Register */ - __IO uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Alias 2 Region Base Address Register */ - __IO uint32_t RASR_A2; /*!< Offset: 0x020 (R/W) MPU Alias 2 Region Attribute and Size Register */ - __IO uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Alias 3 Region Base Address Register */ - __IO uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */ -} MPU_Type; - -/* MPU Type Register */ -#define MPU_TYPE_IREGION_Pos 16 /*!< MPU TYPE: IREGION Position */ -#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ - -#define MPU_TYPE_DREGION_Pos 8 /*!< MPU TYPE: DREGION Position */ -#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ - -#define MPU_TYPE_SEPARATE_Pos 0 /*!< MPU TYPE: SEPARATE Position */ -#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ - -/* MPU Control Register */ -#define MPU_CTRL_PRIVDEFENA_Pos 2 /*!< MPU CTRL: PRIVDEFENA Position */ -#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ - -#define MPU_CTRL_HFNMIENA_Pos 1 /*!< MPU CTRL: HFNMIENA Position */ -#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ - -#define MPU_CTRL_ENABLE_Pos 0 /*!< MPU CTRL: ENABLE Position */ -#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ - -/* MPU Region Number Register */ -#define MPU_RNR_REGION_Pos 0 /*!< MPU RNR: REGION Position */ -#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ - -/* MPU Region Base Address Register */ -#define MPU_RBAR_ADDR_Pos 5 /*!< MPU RBAR: ADDR Position */ -#define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ - -#define MPU_RBAR_VALID_Pos 4 /*!< MPU RBAR: VALID Position */ -#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ - -#define MPU_RBAR_REGION_Pos 0 /*!< MPU RBAR: REGION Position */ -#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */ - -/* MPU Region Attribute and Size Register */ -#define MPU_RASR_ATTRS_Pos 16 /*!< MPU RASR: MPU Region Attribute field Position */ -#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ - -#define MPU_RASR_XN_Pos 28 /*!< MPU RASR: ATTRS.XN Position */ -#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ - -#define MPU_RASR_AP_Pos 24 /*!< MPU RASR: ATTRS.AP Position */ -#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ - -#define MPU_RASR_TEX_Pos 19 /*!< MPU RASR: ATTRS.TEX Position */ -#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ - -#define MPU_RASR_S_Pos 18 /*!< MPU RASR: ATTRS.S Position */ -#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ - -#define MPU_RASR_C_Pos 17 /*!< MPU RASR: ATTRS.C Position */ -#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ - -#define MPU_RASR_B_Pos 16 /*!< MPU RASR: ATTRS.B Position */ -#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ - -#define MPU_RASR_SRD_Pos 8 /*!< MPU RASR: Sub-Region Disable Position */ -#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ - -#define MPU_RASR_SIZE_Pos 1 /*!< MPU RASR: Region Size Field Position */ -#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ - -#define MPU_RASR_ENABLE_Pos 0 /*!< MPU RASR: Region enable bit Position */ -#define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */ - -/*@} end of group CMSIS_MPU */ -#endif - - -#if (__FPU_PRESENT == 1) -/** \ingroup CMSIS_core_register - \defgroup CMSIS_FPU Floating Point Unit (FPU) - \brief Type definitions for the Floating Point Unit (FPU) - @{ - */ - -/** \brief Structure type to access the Floating Point Unit (FPU). - */ -typedef struct -{ - uint32_t RESERVED0[1]; - __IO uint32_t FPCCR; /*!< Offset: 0x004 (R/W) Floating-Point Context Control Register */ - __IO uint32_t FPCAR; /*!< Offset: 0x008 (R/W) Floating-Point Context Address Register */ - __IO uint32_t FPDSCR; /*!< Offset: 0x00C (R/W) Floating-Point Default Status Control Register */ - __I uint32_t MVFR0; /*!< Offset: 0x010 (R/ ) Media and FP Feature Register 0 */ - __I uint32_t MVFR1; /*!< Offset: 0x014 (R/ ) Media and FP Feature Register 1 */ - __I uint32_t MVFR2; /*!< Offset: 0x018 (R/ ) Media and FP Feature Register 2 */ -} 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 */ - -/* Media and FP Feature Register 2 */ - -/*@} end of group CMSIS_FPU */ -#endif - - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) - \brief Type definitions for the Core Debug Registers - @{ - */ - -/** \brief Structure type to access the Core Debug Register (CoreDebug). - */ -typedef struct -{ - __IO uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ - __O uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ - __IO uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ - __IO uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ -} CoreDebug_Type; - -/* Debug Halting Control and Status Register */ -#define CoreDebug_DHCSR_DBGKEY_Pos 16 /*!< CoreDebug DHCSR: DBGKEY Position */ -#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ - -#define CoreDebug_DHCSR_S_RESET_ST_Pos 25 /*!< CoreDebug DHCSR: S_RESET_ST Position */ -#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ - -#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24 /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ -#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ - -#define CoreDebug_DHCSR_S_LOCKUP_Pos 19 /*!< CoreDebug DHCSR: S_LOCKUP Position */ -#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ - -#define CoreDebug_DHCSR_S_SLEEP_Pos 18 /*!< CoreDebug DHCSR: S_SLEEP Position */ -#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ - -#define CoreDebug_DHCSR_S_HALT_Pos 17 /*!< CoreDebug DHCSR: S_HALT Position */ -#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ - -#define CoreDebug_DHCSR_S_REGRDY_Pos 16 /*!< CoreDebug DHCSR: S_REGRDY Position */ -#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ - -#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5 /*!< CoreDebug DHCSR: C_SNAPSTALL Position */ -#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */ - -#define CoreDebug_DHCSR_C_MASKINTS_Pos 3 /*!< CoreDebug DHCSR: C_MASKINTS Position */ -#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ - -#define CoreDebug_DHCSR_C_STEP_Pos 2 /*!< CoreDebug DHCSR: C_STEP Position */ -#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ - -#define CoreDebug_DHCSR_C_HALT_Pos 1 /*!< CoreDebug DHCSR: C_HALT Position */ -#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ - -#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0 /*!< CoreDebug DHCSR: C_DEBUGEN Position */ -#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ - -/* Debug Core Register Selector Register */ -#define CoreDebug_DCRSR_REGWnR_Pos 16 /*!< CoreDebug DCRSR: REGWnR Position */ -#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ - -#define CoreDebug_DCRSR_REGSEL_Pos 0 /*!< CoreDebug DCRSR: REGSEL Position */ -#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< CoreDebug DCRSR: REGSEL Mask */ - -/* Debug Exception and Monitor Control Register */ -#define CoreDebug_DEMCR_TRCENA_Pos 24 /*!< CoreDebug DEMCR: TRCENA Position */ -#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ - -#define CoreDebug_DEMCR_MON_REQ_Pos 19 /*!< CoreDebug DEMCR: MON_REQ Position */ -#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */ - -#define CoreDebug_DEMCR_MON_STEP_Pos 18 /*!< CoreDebug DEMCR: MON_STEP Position */ -#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */ - -#define CoreDebug_DEMCR_MON_PEND_Pos 17 /*!< CoreDebug DEMCR: MON_PEND Position */ -#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */ - -#define CoreDebug_DEMCR_MON_EN_Pos 16 /*!< CoreDebug DEMCR: MON_EN Position */ -#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */ - -#define CoreDebug_DEMCR_VC_HARDERR_Pos 10 /*!< CoreDebug DEMCR: VC_HARDERR Position */ -#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ - -#define CoreDebug_DEMCR_VC_INTERR_Pos 9 /*!< CoreDebug DEMCR: VC_INTERR Position */ -#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */ - -#define CoreDebug_DEMCR_VC_BUSERR_Pos 8 /*!< CoreDebug DEMCR: VC_BUSERR Position */ -#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */ - -#define CoreDebug_DEMCR_VC_STATERR_Pos 7 /*!< CoreDebug DEMCR: VC_STATERR Position */ -#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */ - -#define CoreDebug_DEMCR_VC_CHKERR_Pos 6 /*!< CoreDebug DEMCR: VC_CHKERR Position */ -#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */ - -#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5 /*!< CoreDebug DEMCR: VC_NOCPERR Position */ -#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */ - -#define CoreDebug_DEMCR_VC_MMERR_Pos 4 /*!< CoreDebug DEMCR: VC_MMERR Position */ -#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */ - -#define CoreDebug_DEMCR_VC_CORERESET_Pos 0 /*!< CoreDebug DEMCR: VC_CORERESET Position */ -#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ - -/*@} end of group CMSIS_CoreDebug */ - - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_core_base Core Definitions - \brief Definitions for base addresses, unions, and structures. - @{ - */ - -/* Memory mapping of Cortex-M4 Hardware */ -#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ -#define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ -#define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ -#define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ -#define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ -#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ -#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ -#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ - -#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ -#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ -#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ -#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ -#define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ -#define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ -#define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ -#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */ - -#if (__MPU_PRESENT == 1) - #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ - #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ -#endif - -#if (__FPU_PRESENT == 1) - #define FPU_BASE (SCS_BASE + 0x0F30UL) /*!< Floating Point Unit */ - #define FPU ((FPU_Type *) FPU_BASE ) /*!< Floating Point Unit */ -#endif - -/*@} */ - - - -/******************************************************************************* - * Hardware Abstraction Layer - Core Function Interface contains: - - Core NVIC Functions - - Core SysTick Functions - - Core Debug Functions - - Core Register Access Functions - ******************************************************************************/ -/** \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference -*/ - - - -/* ########################## NVIC functions #################################### */ -/** \ingroup CMSIS_Core_FunctionInterface - \defgroup CMSIS_Core_NVICFunctions NVIC Functions - \brief Functions that manage interrupts and exceptions via the NVIC. - @{ - */ - -/** \brief Set Priority Grouping - - The function sets the priority grouping field using the required unlock sequence. - The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. - Only values from 0..7 are used. - In case of a conflict between priority grouping and available - priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. - - \param [in] PriorityGroup Priority grouping field. - */ -__STATIC_INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup) -{ - uint32_t reg_value; - uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ - - reg_value = SCB->AIRCR; /* read old register configuration */ - reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ - reg_value = (reg_value | - ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | - (PriorityGroupTmp << 8) ); /* Insert write key and priorty group */ - SCB->AIRCR = reg_value; -} - - -/** \brief Get Priority Grouping - - The function reads the priority grouping field from the NVIC Interrupt Controller. - - \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). - */ -__STATIC_INLINE uint32_t NVIC_GetPriorityGrouping(void) -{ - return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); -} - - -/** \brief Enable External Interrupt - - The function enables a device-specific interrupt in the NVIC interrupt controller. - - \param [in] IRQn External interrupt number. Value cannot be negative. - */ -__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn) -{ - NVIC->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); -} - - -/** \brief Disable External Interrupt - - The function disables a device-specific interrupt in the NVIC interrupt controller. - - \param [in] IRQn External interrupt number. Value cannot be negative. - */ -__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn) -{ - NVIC->ICER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); - __DSB(); - __ISB(); -} - - -/** \brief Get Pending Interrupt - - The function reads the pending register in the NVIC and returns the pending bit - for the specified interrupt. - - \param [in] IRQn Interrupt number. - - \return 0 Interrupt status is not pending. - \return 1 Interrupt status is pending. - */ -__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn) -{ - return((uint32_t)(((NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); -} - - -/** \brief Set Pending Interrupt - - The function sets the pending bit of an external interrupt. - - \param [in] IRQn Interrupt number. Value cannot be negative. - */ -__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn) -{ - NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); -} - - -/** \brief Clear Pending Interrupt - - The function clears the pending bit of an external interrupt. - - \param [in] IRQn External interrupt number. Value cannot be negative. - */ -__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn) -{ - NVIC->ICPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); -} - - -/** \brief Get Active Interrupt - - The function reads the active register in NVIC and returns the active bit. - - \param [in] IRQn Interrupt number. - - \return 0 Interrupt status is not active. - \return 1 Interrupt status is active. - */ -__STATIC_INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn) -{ - return((uint32_t)(((NVIC->IABR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); -} - - -/** \brief Set Interrupt Priority - - The function sets the priority of an interrupt. - - \note The priority cannot be set for every core interrupt. - - \param [in] IRQn Interrupt number. - \param [in] priority Priority to set. - */ -__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) -{ - if((int32_t)IRQn < 0) { - SCB->SHPR[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8 - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); - } - else { - NVIC->IP[((uint32_t)(int32_t)IRQn)] = (uint8_t)((priority << (8 - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); - } -} - - -/** \brief Get Interrupt Priority - - The function reads the priority of an interrupt. The interrupt - number can be positive to specify an external (device specific) - interrupt, or negative to specify an internal (core) interrupt. - - - \param [in] IRQn Interrupt number. - \return Interrupt Priority. Value is aligned automatically to the implemented - priority bits of the microcontroller. - */ -__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn) -{ - - if((int32_t)IRQn < 0) { - return(((uint32_t)SCB->SHPR[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] >> (8 - __NVIC_PRIO_BITS))); - } - else { - return(((uint32_t)NVIC->IP[((uint32_t)(int32_t)IRQn)] >> (8 - __NVIC_PRIO_BITS))); - } -} - - -/** \brief Encode Priority - - The function encodes the priority for an interrupt with the given priority group, - preemptive priority value, and subpriority value. - In case of a conflict between priority grouping and available - priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. - - \param [in] PriorityGroup Used priority group. - \param [in] PreemptPriority Preemptive priority value (starting from 0). - \param [in] SubPriority Subpriority value (starting from 0). - \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). - */ -__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) -{ - uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ - uint32_t PreemptPriorityBits; - uint32_t SubPriorityBits; - - PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); - SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); - - return ( - ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | - ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) - ); -} - - -/** \brief Decode Priority - - The function decodes an interrupt priority value with a given priority group to - preemptive priority value and subpriority value. - In case of a conflict between priority grouping and available - priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. - - \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). - \param [in] PriorityGroup Used priority group. - \param [out] pPreemptPriority Preemptive priority value (starting from 0). - \param [out] pSubPriority Subpriority value (starting from 0). - */ -__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* pPreemptPriority, uint32_t* pSubPriority) -{ - uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ - uint32_t PreemptPriorityBits; - uint32_t SubPriorityBits; - - PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); - SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); - - *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); - *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); -} - - -/** \brief System Reset - - The function initiates a system reset request to reset the MCU. - */ -__STATIC_INLINE void NVIC_SystemReset(void) -{ - __DSB(); /* Ensure all outstanding memory accesses included - buffered write are completed before reset */ - SCB->AIRCR = (uint32_t)((0x5FAUL << 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) { __NOP(); } /* wait until reset */ -} - -/*@} end of CMSIS_Core_NVICFunctions */ - - -/* ########################## FPU functions #################################### */ -/** \ingroup CMSIS_Core_FunctionInterface - \defgroup CMSIS_Core_FpuFunctions FPU Functions - \brief Function that provides FPU type. - @{ - */ - -/** - \fn uint32_t SCB_GetFPUType(void) - \brief get FPU type - \returns - - \b 0: No FPU - - \b 1: Single precision FPU - - \b 2: Double + Single precision FPU - */ -__STATIC_INLINE uint32_t SCB_GetFPUType(void) -{ - uint32_t mvfr0; - - mvfr0 = SCB->MVFR0; - if ((mvfr0 & 0x00000FF0UL) == 0x220UL) { - return 2UL; // Double + Single precision FPU - } else if ((mvfr0 & 0x00000FF0UL) == 0x020UL) { - return 1UL; // Single precision FPU - } else { - return 0UL; // No FPU - } -} - - -/*@} end of CMSIS_Core_FpuFunctions */ - - - -/* ########################## Cache functions #################################### */ -/** \ingroup CMSIS_Core_FunctionInterface - \defgroup CMSIS_Core_CacheFunctions Cache Functions - \brief Functions that configure Instruction and Data cache. - @{ - */ - -/* Cache Size ID Register Macros */ -#define CCSIDR_WAYS(x) (((x) & SCB_CCSIDR_ASSOCIATIVITY_Msk) >> SCB_CCSIDR_ASSOCIATIVITY_Pos) -#define CCSIDR_SETS(x) (((x) & SCB_CCSIDR_NUMSETS_Msk ) >> SCB_CCSIDR_NUMSETS_Pos ) -#define CCSIDR_LSSHIFT(x) (((x) & SCB_CCSIDR_LINESIZE_Msk ) /*>> SCB_CCSIDR_LINESIZE_Pos*/ ) - - -/** \brief Enable I-Cache - - The function turns on I-Cache - */ -__STATIC_INLINE void SCB_EnableICache (void) -{ - #if (__ICACHE_PRESENT == 1) - __DSB(); - __ISB(); - SCB->ICIALLU = 0UL; // invalidate I-Cache - SCB->CCR |= (uint32_t)SCB_CCR_IC_Msk; // enable I-Cache - __DSB(); - __ISB(); - #endif -} - - -/** \brief Disable I-Cache - - The function turns off I-Cache - */ -__STATIC_INLINE void SCB_DisableICache (void) -{ - #if (__ICACHE_PRESENT == 1) - __DSB(); - __ISB(); - SCB->CCR &= ~(uint32_t)SCB_CCR_IC_Msk; // disable I-Cache - SCB->ICIALLU = 0UL; // invalidate I-Cache - __DSB(); - __ISB(); - #endif -} - - -/** \brief Invalidate I-Cache - - The function invalidates I-Cache - */ -__STATIC_INLINE void SCB_InvalidateICache (void) -{ - #if (__ICACHE_PRESENT == 1) - __DSB(); - __ISB(); - SCB->ICIALLU = 0UL; - __DSB(); - __ISB(); - #endif -} - - -/** \brief Enable D-Cache - - The function turns on D-Cache - */ -__STATIC_INLINE void SCB_EnableDCache (void) -{ - #if (__DCACHE_PRESENT == 1) - uint32_t ccsidr, sshift, wshift, sw; - uint32_t sets, ways; - - SCB->CSSELR = (0UL << 1) | 0UL; // Level 1 data cache - ccsidr = SCB->CCSIDR; - sets = (uint32_t)(CCSIDR_SETS(ccsidr)); - sshift = (uint32_t)(CCSIDR_LSSHIFT(ccsidr) + 4UL); - ways = (uint32_t)(CCSIDR_WAYS(ccsidr)); - wshift = (uint32_t)((uint32_t)__CLZ(ways) & 0x1FUL); - - __DSB(); - - do { // invalidate D-Cache - uint32_t tmpways = ways; - do { - sw = ((tmpways << wshift) | (sets << sshift)); - SCB->DCISW = sw; - } while(tmpways--); - } while(sets--); - __DSB(); - - SCB->CCR |= (uint32_t)SCB_CCR_DC_Msk; // enable D-Cache - - __DSB(); - __ISB(); - #endif -} - - -/** \brief Disable D-Cache - - The function turns off D-Cache - */ -__STATIC_INLINE void SCB_DisableDCache (void) -{ - #if (__DCACHE_PRESENT == 1) - uint32_t ccsidr, sshift, wshift, sw; - uint32_t sets, ways; - - SCB->CSSELR = (0UL << 1) | 0UL; // Level 1 data cache - ccsidr = SCB->CCSIDR; - sets = (uint32_t)(CCSIDR_SETS(ccsidr)); - sshift = (uint32_t)(CCSIDR_LSSHIFT(ccsidr) + 4UL); - ways = (uint32_t)(CCSIDR_WAYS(ccsidr)); - wshift = (uint32_t)((uint32_t)__CLZ(ways) & 0x1FUL); - - __DSB(); - - SCB->CCR &= ~(uint32_t)SCB_CCR_DC_Msk; // disable D-Cache - - do { // clean & invalidate D-Cache - uint32_t tmpways = ways; - do { - sw = ((tmpways << wshift) | (sets << sshift)); - SCB->DCCISW = sw; - } while(tmpways--); - } while(sets--); - - - __DSB(); - __ISB(); - #endif -} - - -/** \brief Invalidate D-Cache - - The function invalidates D-Cache - */ -__STATIC_INLINE void SCB_InvalidateDCache (void) -{ - #if (__DCACHE_PRESENT == 1) - uint32_t ccsidr, sshift, wshift, sw; - uint32_t sets, ways; - - SCB->CSSELR = (0UL << 1) | 0UL; // Level 1 data cache - ccsidr = SCB->CCSIDR; - sets = (uint32_t)(CCSIDR_SETS(ccsidr)); - sshift = (uint32_t)(CCSIDR_LSSHIFT(ccsidr) + 4UL); - ways = (uint32_t)(CCSIDR_WAYS(ccsidr)); - wshift = (uint32_t)((uint32_t)__CLZ(ways) & 0x1FUL); - - __DSB(); - - do { // invalidate D-Cache - uint32_t tmpways = ways; - do { - sw = ((tmpways << wshift) | (sets << sshift)); - SCB->DCISW = sw; - } while(tmpways--); - } while(sets--); - - __DSB(); - __ISB(); - #endif -} - - -/** \brief Clean D-Cache - - The function cleans D-Cache - */ -__STATIC_INLINE void SCB_CleanDCache (void) -{ - #if (__DCACHE_PRESENT == 1) - uint32_t ccsidr, sshift, wshift, sw; - uint32_t sets, ways; - - SCB->CSSELR = (0UL << 1) | 0UL; // Level 1 data cache - ccsidr = SCB->CCSIDR; - sets = (uint32_t)(CCSIDR_SETS(ccsidr)); - sshift = (uint32_t)(CCSIDR_LSSHIFT(ccsidr) + 4UL); - ways = (uint32_t)(CCSIDR_WAYS(ccsidr)); - wshift = (uint32_t)((uint32_t)__CLZ(ways) & 0x1FUL); - - __DSB(); - - do { // clean D-Cache - uint32_t tmpways = ways; - do { - sw = ((tmpways << wshift) | (sets << sshift)); - SCB->DCCSW = sw; - } while(tmpways--); - } while(sets--); - - __DSB(); - __ISB(); - #endif -} - - -/** \brief Clean & Invalidate D-Cache - - The function cleans and Invalidates D-Cache - */ -__STATIC_INLINE void SCB_CleanInvalidateDCache (void) -{ - #if (__DCACHE_PRESENT == 1) - uint32_t ccsidr, sshift, wshift, sw; - uint32_t sets, ways; - - SCB->CSSELR = (0UL << 1) | 0UL; // Level 1 data cache - ccsidr = SCB->CCSIDR; - sets = (uint32_t)(CCSIDR_SETS(ccsidr)); - sshift = (uint32_t)(CCSIDR_LSSHIFT(ccsidr) + 4UL); - ways = (uint32_t)(CCSIDR_WAYS(ccsidr)); - wshift = (uint32_t)((uint32_t)__CLZ(ways) & 0x1FUL); - - __DSB(); - - do { // clean & invalidate D-Cache - uint32_t tmpways = ways; - do { - sw = ((tmpways << wshift) | (sets << sshift)); - SCB->DCCISW = sw; - } while(tmpways--); - } while(sets--); - - __DSB(); - __ISB(); - #endif -} - - -/** - \fn void SCB_InvalidateDCache_by_Addr(volatile uint32_t *addr, int32_t dsize) - \brief D-Cache Invalidate by address - \param[in] addr address (aligned to 32-byte boundary) - \param[in] dsize size of memory block (in number of bytes) -*/ -__STATIC_INLINE void SCB_InvalidateDCache_by_Addr (uint32_t *addr, int32_t dsize) -{ - #if (__DCACHE_PRESENT == 1) - int32_t op_size = dsize; - uint32_t op_addr = (uint32_t)addr; - uint32_t linesize = 32UL; // in Cortex-M7 size of cache line is fixed to 8 words (32 bytes) - - __DSB(); - - while (op_size > 0) { - SCB->DCIMVAC = op_addr; - op_addr += linesize; - op_size -= (int32_t)linesize; - } - - __DSB(); - __ISB(); - #endif -} - - -/** - \fn void SCB_CleanDCache_by_Addr(volatile uint32_t *addr, int32_t dsize) - \brief D-Cache Clean by address - \param[in] addr address (aligned to 32-byte boundary) - \param[in] dsize size of memory block (in number of bytes) -*/ -__STATIC_INLINE void SCB_CleanDCache_by_Addr (uint32_t *addr, int32_t dsize) -{ - #if (__DCACHE_PRESENT == 1) - int32_t op_size = dsize; - uint32_t op_addr = (uint32_t) addr; - uint32_t linesize = 32UL; // in Cortex-M7 size of cache line is fixed to 8 words (32 bytes) - - __DSB(); - - while (op_size > 0) { - SCB->DCCMVAC = op_addr; - op_addr += linesize; - op_size -= (int32_t)linesize; - } - - __DSB(); - __ISB(); - #endif -} - - -/** - \fn void SCB_CleanInvalidateDCache_by_Addr(volatile uint32_t *addr, int32_t dsize) - \brief D-Cache Clean and Invalidate by address - \param[in] addr address (aligned to 32-byte boundary) - \param[in] dsize size of memory block (in number of bytes) -*/ -__STATIC_INLINE void SCB_CleanInvalidateDCache_by_Addr (uint32_t *addr, int32_t dsize) -{ - #if (__DCACHE_PRESENT == 1) - int32_t op_size = dsize; - uint32_t op_addr = (uint32_t) addr; - uint32_t linesize = 32UL; // in Cortex-M7 size of cache line is fixed to 8 words (32 bytes) - - __DSB(); - - while (op_size > 0) { - SCB->DCCIMVAC = op_addr; - op_addr += linesize; - op_size -= (int32_t)linesize; - } - - __DSB(); - __ISB(); - #endif -} - - -/*@} end of CMSIS_Core_CacheFunctions */ - - - -/* ################################## SysTick function ############################################ */ -/** \ingroup CMSIS_Core_FunctionInterface - \defgroup CMSIS_Core_SysTickFunctions SysTick Functions - \brief Functions that configure the System. - @{ - */ - -#if (__Vendor_SysTickConfig == 0) - -/** \brief System Tick Configuration - - The function initializes the System Timer and its interrupt, and starts the System Tick Timer. - Counter is in free running mode to generate periodic interrupts. - - \param [in] ticks Number of ticks between two interrupts. - - \return 0 Function succeeded. - \return 1 Function failed. - - \note When the variable __Vendor_SysTickConfig is set to 1, then the - function SysTick_Config is not included. In this case, the file device.h - must contain a vendor-specific implementation of this function. - - */ -__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) -{ - if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) { return (1UL); } /* Reload value impossible */ - - SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ - NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ - SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ - SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | - SysTick_CTRL_TICKINT_Msk | - SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ - return (0UL); /* Function successful */ -} - -#endif - -/*@} end of CMSIS_Core_SysTickFunctions */ - - - -/* ##################################### Debug In/Output function ########################################### */ -/** \ingroup CMSIS_Core_FunctionInterface - \defgroup CMSIS_core_DebugFunctions ITM Functions - \brief Functions that access the ITM debug interface. - @{ - */ - -extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ -#define ITM_RXBUFFER_EMPTY 0x5AA55AA5 /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ - - -/** \brief ITM Send Character - - The function transmits a character via the ITM channel 0, and - \li Just returns when no debugger is connected that has booked the output. - \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. - - \param [in] ch Character to transmit. - - \returns Character to transmit. - */ -__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) -{ - if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ - ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */ - { - while (ITM->PORT[0].u32 == 0UL) { __NOP(); } - ITM->PORT[0].u8 = (uint8_t)ch; - } - return (ch); -} - - -/** \brief ITM Receive Character - - The function inputs a character via the external variable \ref ITM_RxBuffer. - - \return Received character. - \return -1 No character pending. - */ -__STATIC_INLINE int32_t ITM_ReceiveChar (void) { - int32_t ch = -1; /* no character available */ - - if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) { - ch = ITM_RxBuffer; - ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ - } - - return (ch); -} - - -/** \brief ITM Check Character - - The function checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. - - \return 0 No character available. - \return 1 Character available. - */ -__STATIC_INLINE int32_t ITM_CheckChar (void) { - - if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) { - return (0); /* no character available */ - } else { - return (1); /* character available */ - } -} - -/*@} end of CMSIS_core_DebugFunctions */ - - - - -#ifdef __cplusplus -} -#endif - -#endif /* __CORE_CM7_H_DEPENDANT */ - -#endif /* __CMSIS_GENERIC */ diff --git a/cmsis/core_cmFunc.h b/cmsis/core_cmFunc.h deleted file mode 100644 index b6ad0a4c5f6..00000000000 --- a/cmsis/core_cmFunc.h +++ /dev/null @@ -1,664 +0,0 @@ -/**************************************************************************//** - * @file core_cmFunc.h - * @brief CMSIS Cortex-M Core Function Access Header File - * @version V4.10 - * @date 18. March 2015 - * - * @note - * - ******************************************************************************/ -/* Copyright (c) 2009 - 2015 ARM LIMITED - - All rights reserved. - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - Neither the name of ARM nor the names of its contributors may be used - to endorse or promote products derived from this software without - specific prior written permission. - * - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - ---------------------------------------------------------------------------*/ - - -#ifndef __CORE_CMFUNC_H -#define __CORE_CMFUNC_H - - -/* ########################### Core Function Access ########################### */ -/** \ingroup CMSIS_Core_FunctionInterface - \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions - @{ - */ - -#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/ -/* ARM armcc specific functions */ - -#if (__ARMCC_VERSION < 400677) - #error "Please use ARM Compiler Toolchain V4.0.677 or later!" -#endif - -/* intrinsic void __enable_irq(); */ -/* intrinsic void __disable_irq(); */ - -/** \brief Get Control Register - - This function returns the content of the Control Register. - - \return Control Register value - */ -__STATIC_INLINE uint32_t __get_CONTROL(void) -{ - register uint32_t __regControl __ASM("control"); - return(__regControl); -} - - -/** \brief Set Control Register - - This function writes the given value to the Control Register. - - \param [in] control Control Register value to set - */ -__STATIC_INLINE void __set_CONTROL(uint32_t control) -{ - register uint32_t __regControl __ASM("control"); - __regControl = control; -} - - -/** \brief Get IPSR Register - - This function returns the content of the IPSR Register. - - \return IPSR Register value - */ -__STATIC_INLINE uint32_t __get_IPSR(void) -{ - register uint32_t __regIPSR __ASM("ipsr"); - return(__regIPSR); -} - - -/** \brief Get APSR Register - - This function returns the content of the APSR Register. - - \return APSR Register value - */ -__STATIC_INLINE uint32_t __get_APSR(void) -{ - register uint32_t __regAPSR __ASM("apsr"); - return(__regAPSR); -} - - -/** \brief Get xPSR Register - - This function returns the content of the xPSR Register. - - \return xPSR Register value - */ -__STATIC_INLINE uint32_t __get_xPSR(void) -{ - register uint32_t __regXPSR __ASM("xpsr"); - return(__regXPSR); -} - - -/** \brief Get Process Stack Pointer - - This function returns the current value of the Process Stack Pointer (PSP). - - \return PSP Register value - */ -__STATIC_INLINE uint32_t __get_PSP(void) -{ - register uint32_t __regProcessStackPointer __ASM("psp"); - return(__regProcessStackPointer); -} - - -/** \brief Set Process Stack Pointer - - This function assigns the given value to the Process Stack Pointer (PSP). - - \param [in] topOfProcStack Process Stack Pointer value to set - */ -__STATIC_INLINE void __set_PSP(uint32_t topOfProcStack) -{ - register uint32_t __regProcessStackPointer __ASM("psp"); - __regProcessStackPointer = topOfProcStack; -} - - -/** \brief Get Main Stack Pointer - - This function returns the current value of the Main Stack Pointer (MSP). - - \return MSP Register value - */ -__STATIC_INLINE uint32_t __get_MSP(void) -{ - register uint32_t __regMainStackPointer __ASM("msp"); - return(__regMainStackPointer); -} - - -/** \brief Set Main Stack Pointer - - This function assigns the given value to the Main Stack Pointer (MSP). - - \param [in] topOfMainStack Main Stack Pointer value to set - */ -__STATIC_INLINE void __set_MSP(uint32_t topOfMainStack) -{ - register uint32_t __regMainStackPointer __ASM("msp"); - __regMainStackPointer = topOfMainStack; -} - - -/** \brief Get Priority Mask - - This function returns the current state of the priority mask bit from the Priority Mask Register. - - \return Priority Mask value - */ -__STATIC_INLINE uint32_t __get_PRIMASK(void) -{ - register uint32_t __regPriMask __ASM("primask"); - return(__regPriMask); -} - - -/** \brief Set Priority Mask - - This function assigns the given value to the Priority Mask Register. - - \param [in] priMask Priority Mask - */ -__STATIC_INLINE void __set_PRIMASK(uint32_t priMask) -{ - register uint32_t __regPriMask __ASM("primask"); - __regPriMask = (priMask); -} - - -#if (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300) - -/** \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 Set Base Priority with condition - - This function assigns the given value to the Base Priority register only if BASEPRI masking is disabled, - or the new value increases the BASEPRI priority level. - - \param [in] basePri Base Priority value to set - */ -__STATIC_INLINE void __set_BASEPRI_MAX(uint32_t basePri) -{ - register uint32_t __regBasePriMax __ASM("basepri_max"); - __regBasePriMax = (basePri & 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) || (__CORTEX_SC >= 300) */ - - -#if (__CORTEX_M == 0x04) || (__CORTEX_M == 0x07) - -/** \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) || (__CORTEX_M == 0x07) */ - - -#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/ -/* GNU gcc specific functions */ - -/** \brief Enable IRQ Interrupts - - This function enables IRQ interrupts by clearing the I-bit in the CPSR. - Can only be executed in Privileged modes. - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_irq(void) -{ - __ASM volatile ("cpsie i" : : : "memory"); -} - - -/** \brief Disable IRQ Interrupts - - This function disables IRQ interrupts by setting the I-bit in the CPSR. - Can only be executed in Privileged modes. - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_irq(void) -{ - __ASM volatile ("cpsid i" : : : "memory"); -} - - -/** \brief Get Control Register - - This function returns the content of the Control Register. - - \return Control Register value - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_CONTROL(void) -{ - uint32_t result; - - __ASM volatile ("MRS %0, control" : "=r" (result) ); - return(result); -} - - -/** \brief Set Control Register - - This function writes the given value to the Control Register. - - \param [in] control Control Register value to set - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_CONTROL(uint32_t control) -{ - __ASM volatile ("MSR control, %0" : : "r" (control) : "memory"); -} - - -/** \brief Get IPSR Register - - This function returns the content of the IPSR Register. - - \return IPSR Register value - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_IPSR(void) -{ - uint32_t result; - - __ASM volatile ("MRS %0, ipsr" : "=r" (result) ); - return(result); -} - - -/** \brief Get APSR Register - - This function returns the content of the APSR Register. - - \return APSR Register value - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_APSR(void) -{ - uint32_t result; - - __ASM volatile ("MRS %0, apsr" : "=r" (result) ); - return(result); -} - - -/** \brief Get xPSR Register - - This function returns the content of the xPSR Register. - - \return xPSR Register value - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_xPSR(void) -{ - uint32_t result; - - __ASM volatile ("MRS %0, xpsr" : "=r" (result) ); - return(result); -} - - -/** \brief Get Process Stack Pointer - - This function returns the current value of the Process Stack Pointer (PSP). - - \return PSP Register value - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PSP(void) -{ - register uint32_t result; - - __ASM volatile ("MRS %0, psp\n" : "=r" (result) ); - return(result); -} - - -/** \brief Set Process Stack Pointer - - This function assigns the given value to the Process Stack Pointer (PSP). - - \param [in] topOfProcStack Process Stack Pointer value to set - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PSP(uint32_t topOfProcStack) -{ - __ASM volatile ("MSR psp, %0\n" : : "r" (topOfProcStack) : "sp"); -} - - -/** \brief Get Main Stack Pointer - - This function returns the current value of the Main Stack Pointer (MSP). - - \return MSP Register value - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_MSP(void) -{ - register uint32_t result; - - __ASM volatile ("MRS %0, msp\n" : "=r" (result) ); - return(result); -} - - -/** \brief Set Main Stack Pointer - - This function assigns the given value to the Main Stack Pointer (MSP). - - \param [in] topOfMainStack Main Stack Pointer value to set - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_MSP(uint32_t topOfMainStack) -{ - __ASM volatile ("MSR msp, %0\n" : : "r" (topOfMainStack) : "sp"); -} - - -/** \brief Get Priority Mask - - This function returns the current state of the priority mask bit from the Priority Mask Register. - - \return Priority Mask value - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PRIMASK(void) -{ - uint32_t result; - - __ASM volatile ("MRS %0, primask" : "=r" (result) ); - return(result); -} - - -/** \brief Set Priority Mask - - This function assigns the given value to the Priority Mask Register. - - \param [in] priMask Priority Mask - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PRIMASK(uint32_t priMask) -{ - __ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory"); -} - - -#if (__CORTEX_M >= 0x03) - -/** \brief Enable FIQ - - This function enables FIQ interrupts by clearing the F-bit in the CPSR. - Can only be executed in Privileged modes. - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_fault_irq(void) -{ - __ASM volatile ("cpsie f" : : : "memory"); -} - - -/** \brief Disable FIQ - - This function disables FIQ interrupts by setting the F-bit in the CPSR. - Can only be executed in Privileged modes. - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_fault_irq(void) -{ - __ASM volatile ("cpsid f" : : : "memory"); -} - - -/** \brief Get Base Priority - - This function returns the current value of the Base Priority register. - - \return Base Priority register value - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_BASEPRI(void) -{ - uint32_t result; - - __ASM volatile ("MRS %0, basepri" : "=r" (result) ); - return(result); -} - - -/** \brief Set Base Priority - - This function assigns the given value to the Base Priority register. - - \param [in] basePri Base Priority value to set - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_BASEPRI(uint32_t value) -{ - __ASM volatile ("MSR basepri, %0" : : "r" (value) : "memory"); -} - - -/** \brief Set Base Priority with condition - - This function assigns the given value to the Base Priority register only if BASEPRI masking is disabled, - or the new value increases the BASEPRI priority level. - - \param [in] basePri Base Priority value to set - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_BASEPRI_MAX(uint32_t value) -{ - __ASM volatile ("MSR basepri_max, %0" : : "r" (value) : "memory"); -} - - -/** \brief Get Fault Mask - - This function returns the current value of the Fault Mask register. - - \return Fault Mask register value - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FAULTMASK(void) -{ - uint32_t result; - - __ASM volatile ("MRS %0, faultmask" : "=r" (result) ); - return(result); -} - - -/** \brief Set Fault Mask - - This function assigns the given value to the Fault Mask register. - - \param [in] faultMask Fault Mask value to set - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask) -{ - __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory"); -} - -#endif /* (__CORTEX_M >= 0x03) */ - - -#if (__CORTEX_M == 0x04) || (__CORTEX_M == 0x07) - -/** \brief Get FPSCR - - This function returns the current value of the Floating Point Status/Control register. - - \return Floating Point Status/Control register value - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FPSCR(void) -{ -#if (__FPU_PRESENT == 1) && (__FPU_USED == 1) - uint32_t result; - - /* Empty asm statement works as a scheduling barrier */ - __ASM volatile (""); - __ASM volatile ("VMRS %0, fpscr" : "=r" (result) ); - __ASM volatile (""); - return(result); -#else - return(0); -#endif -} - - -/** \brief Set FPSCR - - This function assigns the given value to the Floating Point Status/Control register. - - \param [in] fpscr Floating Point Status/Control value to set - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FPSCR(uint32_t fpscr) -{ -#if (__FPU_PRESENT == 1) && (__FPU_USED == 1) - /* Empty asm statement works as a scheduling barrier */ - __ASM volatile (""); - __ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) : "vfpcc"); - __ASM volatile (""); -#endif -} - -#endif /* (__CORTEX_M == 0x04) || (__CORTEX_M == 0x07) */ - - -#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/ -/* IAR iccarm specific functions */ -#include - - -#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/ -/* TI CCS specific functions */ -#include - - -#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. - */ - - -#elif defined ( __CSMC__ ) /*------------------ COSMIC Compiler -------------------*/ -/* Cosmic specific functions */ -#include - -#endif - -/*@} end of CMSIS_Core_RegAccFunctions */ - -#endif /* __CORE_CMFUNC_H */ diff --git a/cmsis/core_cmInstr.h b/cmsis/core_cmInstr.h deleted file mode 100644 index fca425c51db..00000000000 --- a/cmsis/core_cmInstr.h +++ /dev/null @@ -1,916 +0,0 @@ -/**************************************************************************//** - * @file core_cmInstr.h - * @brief CMSIS Cortex-M Core Instruction Access Header File - * @version V4.10 - * @date 18. March 2015 - * - * @note - * - ******************************************************************************/ -/* Copyright (c) 2009 - 2014 ARM LIMITED - - All rights reserved. - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - Neither the name of ARM nor the names of its contributors may be used - to endorse or promote products derived from this software without - specific prior written permission. - * - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - ---------------------------------------------------------------------------*/ - - -#ifndef __CORE_CMINSTR_H -#define __CORE_CMINSTR_H - - -/* ########################## Core Instruction Access ######################### */ -/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface - Access to dedicated instructions - @{ -*/ - -#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/ -/* ARM armcc specific functions */ - -#if (__ARMCC_VERSION < 400677) - #error "Please use ARM Compiler Toolchain V4.0.677 or later!" -#endif - - -/** \brief No Operation - - No Operation does nothing. This instruction can be used for code alignment purposes. - */ -#define __NOP __nop - - -/** \brief Wait For Interrupt - - Wait For Interrupt is a hint instruction that suspends execution - until one of a number of events occurs. - */ -#define __WFI __wfi - - -/** \brief Wait For Event - - Wait For Event is a hint instruction that permits the processor to enter - a low-power state until one of a number of events occurs. - */ -#define __WFE __wfe - - -/** \brief Send Event - - Send Event is a hint instruction. It causes an event to be signaled to the CPU. - */ -#define __SEV __sev - - -/** \brief Instruction Synchronization Barrier - - Instruction Synchronization Barrier flushes the pipeline in the processor, - so that all instructions following the ISB are fetched from cache or - memory, after the instruction has been completed. - */ -#define __ISB() do {\ - __schedule_barrier();\ - __isb(0xF);\ - __schedule_barrier();\ - } while (0) - -/** \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() do {\ - __schedule_barrier();\ - __dsb(0xF);\ - __schedule_barrier();\ - } while (0) - -/** \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() do {\ - __schedule_barrier();\ - __dmb(0xF);\ - __schedule_barrier();\ - } while (0) - -/** \brief Reverse byte order (32 bit) - - This function reverses the byte order in integer value. - - \param [in] value Value to reverse - \return Reversed value - */ -#define __REV __rev - - -/** \brief Reverse byte order (16 bit) - - This function reverses the byte order in two unsigned short values. - - \param [in] value Value to reverse - \return Reversed value - */ -#ifndef __NO_EMBEDDED_ASM -__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value) -{ - rev16 r0, r0 - bx lr -} -#endif - -/** \brief Reverse byte order in signed short value - - This function reverses the byte order in a signed short value with sign extension to integer. - - \param [in] value Value to reverse - \return Reversed value - */ -#ifndef __NO_EMBEDDED_ASM -__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int32_t __REVSH(int32_t value) -{ - revsh r0, r0 - bx lr -} -#endif - - -/** \brief Rotate Right in unsigned value (32 bit) - - This function Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. - - \param [in] value Value to rotate - \param [in] value Number of Bits to rotate - \return Rotated value - */ -#define __ROR __ror - - -/** \brief Breakpoint - - This function causes the processor to enter Debug state. - Debug tools can use this to investigate system state when the instruction at a particular address is reached. - - \param [in] value is ignored by the processor. - If required, a debugger can use it to store additional information about the breakpoint. - */ -#define __BKPT(value) __breakpoint(value) - - -/** \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 - */ -#if (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300) - #define __RBIT __rbit -#else -__attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value) -{ - uint32_t result; - int32_t s = 4 /*sizeof(v)*/ * 8 - 1; // extra shift needed at end - - result = value; // r will be reversed bits of v; first get LSB of v - for (value >>= 1; value; value >>= 1) - { - result <<= 1; - result |= value & 1; - s--; - } - result <<= s; // shift when v's highest bits are zero - return(result); -} -#endif - - -/** \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 - - -#if (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300) - -/** \brief LDR Exclusive (8 bit) - - This function executes a exclusive LDR instruction 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 executes a exclusive LDR instruction 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 executes a exclusive LDR instruction 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 executes a exclusive STR instruction for 8 bit values. - - \param [in] value Value to store - \param [in] ptr Pointer to location - \return 0 Function succeeded - \return 1 Function failed - */ -#define __STREXB(value, ptr) __strex(value, ptr) - - -/** \brief STR Exclusive (16 bit) - - This function executes a exclusive STR instruction for 16 bit values. - - \param [in] value Value to store - \param [in] ptr Pointer to location - \return 0 Function succeeded - \return 1 Function failed - */ -#define __STREXH(value, ptr) __strex(value, ptr) - - -/** \brief STR Exclusive (32 bit) - - This function executes a exclusive STR instruction for 32 bit values. - - \param [in] value Value to store - \param [in] ptr Pointer to location - \return 0 Function succeeded - \return 1 Function failed - */ -#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 Rotate Right with Extend (32 bit) - - This function moves each bit of a bitstring right by one bit. - The carry input is shifted in at the left end of the bitstring. - - \param [in] value Value to rotate - \return Rotated value - */ -#ifndef __NO_EMBEDDED_ASM -__attribute__((section(".rrx_text"))) __STATIC_INLINE __ASM uint32_t __RRX(uint32_t value) -{ - rrx r0, r0 - bx lr -} -#endif - - -/** \brief LDRT Unprivileged (8 bit) - - This function executes a Unprivileged LDRT instruction for 8 bit value. - - \param [in] ptr Pointer to data - \return value of type uint8_t at (*ptr) - */ -#define __LDRBT(ptr) ((uint8_t ) __ldrt(ptr)) - - -/** \brief LDRT Unprivileged (16 bit) - - This function executes a Unprivileged LDRT instruction for 16 bit values. - - \param [in] ptr Pointer to data - \return value of type uint16_t at (*ptr) - */ -#define __LDRHT(ptr) ((uint16_t) __ldrt(ptr)) - - -/** \brief LDRT Unprivileged (32 bit) - - This function executes a Unprivileged LDRT instruction for 32 bit values. - - \param [in] ptr Pointer to data - \return value of type uint32_t at (*ptr) - */ -#define __LDRT(ptr) ((uint32_t ) __ldrt(ptr)) - - -/** \brief STRT Unprivileged (8 bit) - - This function executes a Unprivileged STRT instruction for 8 bit values. - - \param [in] value Value to store - \param [in] ptr Pointer to location - */ -#define __STRBT(value, ptr) __strt(value, ptr) - - -/** \brief STRT Unprivileged (16 bit) - - This function executes a Unprivileged STRT instruction for 16 bit values. - - \param [in] value Value to store - \param [in] ptr Pointer to location - */ -#define __STRHT(value, ptr) __strt(value, ptr) - - -/** \brief STRT Unprivileged (32 bit) - - This function executes a Unprivileged STRT instruction for 32 bit values. - - \param [in] value Value to store - \param [in] ptr Pointer to location - */ -#define __STRT(value, ptr) __strt(value, ptr) - -#endif /* (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300) */ - - -#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/ -/* GNU gcc specific functions */ - -/* Define macros for porting to both thumb1 and thumb2. - * For thumb1, use low register (r0-r7), specified by constrant "l" - * Otherwise, use general registers, specified by constrant "r" */ -#if defined (__thumb__) && !defined (__thumb2__) -#define __CMSIS_GCC_OUT_REG(r) "=l" (r) -#define __CMSIS_GCC_USE_REG(r) "l" (r) -#else -#define __CMSIS_GCC_OUT_REG(r) "=r" (r) -#define __CMSIS_GCC_USE_REG(r) "r" (r) -#endif - -/** \brief No Operation - - No Operation does nothing. This instruction can be used for code alignment purposes. - */ -__attribute__((always_inline)) __STATIC_INLINE void __NOP(void) -{ - __ASM volatile ("nop"); -} - - -/** \brief Wait For Interrupt - - Wait For Interrupt is a hint instruction that suspends execution - until one of a number of events occurs. - */ -__attribute__((always_inline)) __STATIC_INLINE void __WFI(void) -{ - __ASM volatile ("wfi"); -} - - -/** \brief Wait For Event - - Wait For Event is a hint instruction that permits the processor to enter - a low-power state until one of a number of events occurs. - */ -__attribute__((always_inline)) __STATIC_INLINE void __WFE(void) -{ - __ASM volatile ("wfe"); -} - - -/** \brief Send Event - - Send Event is a hint instruction. It causes an event to be signaled to the CPU. - */ -__attribute__((always_inline)) __STATIC_INLINE void __SEV(void) -{ - __ASM volatile ("sev"); -} - - -/** \brief Instruction Synchronization Barrier - - Instruction Synchronization Barrier flushes the pipeline in the processor, - so that all instructions following the ISB are fetched from cache or - memory, after the instruction has been completed. - */ -__attribute__((always_inline)) __STATIC_INLINE void __ISB(void) -{ - __ASM volatile ("isb 0xF":::"memory"); -} - - -/** \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 0xF":::"memory"); -} - - -/** \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 0xF":::"memory"); -} - - -/** \brief Reverse byte order (32 bit) - - This function reverses the byte order in integer value. - - \param [in] value Value to reverse - \return Reversed value - */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __REV(uint32_t value) -{ -#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) - return __builtin_bswap32(value); -#else - uint32_t result; - - __ASM volatile ("rev %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); - return(result); -#endif -} - - -/** \brief Reverse byte order (16 bit) - - This function reverses the byte order in two unsigned short values. - - \param [in] value Value to reverse - \return Reversed value - */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __REV16(uint32_t value) -{ - uint32_t result; - - __ASM volatile ("rev16 %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); - return(result); -} - - -/** \brief Reverse byte order in signed short value - - This function reverses the byte order in a signed short value with sign extension to integer. - - \param [in] value Value to reverse - \return Reversed value - */ -__attribute__((always_inline)) __STATIC_INLINE int32_t __REVSH(int32_t value) -{ -#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) - return (short)__builtin_bswap16(value); -#else - uint32_t result; - - __ASM volatile ("revsh %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); - return(result); -#endif -} - - -/** \brief Rotate Right in unsigned value (32 bit) - - This function Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. - - \param [in] value Value to rotate - \param [in] value Number of Bits to rotate - \return Rotated value - */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __ROR(uint32_t op1, uint32_t op2) -{ - return (op1 >> op2) | (op1 << (32 - op2)); -} - - -/** \brief Breakpoint - - This function causes the processor to enter Debug state. - Debug tools can use this to investigate system state when the instruction at a particular address is reached. - - \param [in] value is ignored by the processor. - If required, a debugger can use it to store additional information about the breakpoint. - */ -#define __BKPT(value) __ASM volatile ("bkpt "#value) - - -/** \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; - -#if (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300) - __ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) ); -#else - int32_t s = 4 /*sizeof(v)*/ * 8 - 1; // extra shift needed at end - - result = value; // r will be reversed bits of v; first get LSB of v - for (value >>= 1; value; value >>= 1) - { - result <<= 1; - result |= value & 1; - s--; - } - result <<= s; // shift when v's highest bits are zero -#endif - return(result); -} - - -/** \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 __builtin_clz - - -#if (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300) - -/** \brief LDR Exclusive (8 bit) - - This function executes a exclusive LDR instruction for 8 bit value. - - \param [in] ptr Pointer to data - \return value of type uint8_t at (*ptr) - */ -__attribute__((always_inline)) __STATIC_INLINE uint8_t __LDREXB(volatile uint8_t *addr) -{ - uint32_t result; - -#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) - __ASM volatile ("ldrexb %0, %1" : "=r" (result) : "Q" (*addr) ); -#else - /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not - accepted by assembler. So has to use following less efficient pattern. - */ - __ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); -#endif - return ((uint8_t) result); /* Add explicit type cast here */ -} - - -/** \brief LDR Exclusive (16 bit) - - This function executes a exclusive LDR instruction for 16 bit values. - - \param [in] ptr Pointer to data - \return value of type uint16_t at (*ptr) - */ -__attribute__((always_inline)) __STATIC_INLINE uint16_t __LDREXH(volatile uint16_t *addr) -{ - uint32_t result; - -#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) - __ASM volatile ("ldrexh %0, %1" : "=r" (result) : "Q" (*addr) ); -#else - /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not - accepted by assembler. So has to use following less efficient pattern. - */ - __ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); -#endif - return ((uint16_t) result); /* Add explicit type cast here */ -} - - -/** \brief LDR Exclusive (32 bit) - - This function executes a exclusive LDR instruction for 32 bit values. - - \param [in] ptr Pointer to data - \return value of type uint32_t at (*ptr) - */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __LDREXW(volatile uint32_t *addr) -{ - uint32_t result; - - __ASM volatile ("ldrex %0, %1" : "=r" (result) : "Q" (*addr) ); - return(result); -} - - -/** \brief STR Exclusive (8 bit) - - This function executes a exclusive STR instruction for 8 bit values. - - \param [in] value Value to store - \param [in] ptr Pointer to location - \return 0 Function succeeded - \return 1 Function failed - */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr) -{ - uint32_t result; - - __ASM volatile ("strexb %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) ); - return(result); -} - - -/** \brief STR Exclusive (16 bit) - - This function executes a exclusive STR instruction for 16 bit values. - - \param [in] value Value to store - \param [in] ptr Pointer to location - \return 0 Function succeeded - \return 1 Function failed - */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr) -{ - uint32_t result; - - __ASM volatile ("strexh %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) ); - return(result); -} - - -/** \brief STR Exclusive (32 bit) - - This function executes a exclusive STR instruction for 32 bit values. - - \param [in] value Value to store - \param [in] ptr Pointer to location - \return 0 Function succeeded - \return 1 Function failed - */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr) -{ - uint32_t result; - - __ASM volatile ("strex %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" (value) ); - return(result); -} - - -/** \brief Remove the exclusive lock - - This function removes the exclusive lock which is created by LDREX. - - */ -__attribute__((always_inline)) __STATIC_INLINE void __CLREX(void) -{ - __ASM volatile ("clrex" ::: "memory"); -} - - -/** \brief Signed Saturate - - This function saturates a signed value. - - \param [in] value Value to be saturated - \param [in] sat Bit position to saturate to (1..32) - \return Saturated value - */ -#define __SSAT(ARG1,ARG2) \ -({ \ - uint32_t __RES, __ARG1 = (ARG1); \ - __ASM ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ - __RES; \ - }) - - -/** \brief Unsigned Saturate - - This function saturates an unsigned value. - - \param [in] value Value to be saturated - \param [in] sat Bit position to saturate to (0..31) - \return Saturated value - */ -#define __USAT(ARG1,ARG2) \ -({ \ - uint32_t __RES, __ARG1 = (ARG1); \ - __ASM ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ - __RES; \ - }) - - -/** \brief Rotate Right with Extend (32 bit) - - This function moves each bit of a bitstring right by one bit. - The carry input is shifted in at the left end of the bitstring. - - \param [in] value Value to rotate - \return Rotated value - */ -__attribute__((always_inline)) __STATIC_INLINE uint32_t __RRX(uint32_t value) -{ - uint32_t result; - - __ASM volatile ("rrx %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); - return(result); -} - - -/** \brief LDRT Unprivileged (8 bit) - - This function executes a Unprivileged LDRT instruction 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 __LDRBT(volatile uint8_t *addr) -{ - uint32_t result; - -#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) - __ASM volatile ("ldrbt %0, %1" : "=r" (result) : "Q" (*addr) ); -#else - /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not - accepted by assembler. So has to use following less efficient pattern. - */ - __ASM volatile ("ldrbt %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); -#endif - return ((uint8_t) result); /* Add explicit type cast here */ -} - - -/** \brief LDRT Unprivileged (16 bit) - - This function executes a Unprivileged LDRT instruction 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 __LDRHT(volatile uint16_t *addr) -{ - uint32_t result; - -#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) - __ASM volatile ("ldrht %0, %1" : "=r" (result) : "Q" (*addr) ); -#else - /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not - accepted by assembler. So has to use following less efficient pattern. - */ - __ASM volatile ("ldrht %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); -#endif - return ((uint16_t) result); /* Add explicit type cast here */ -} - - -/** \brief LDRT Unprivileged (32 bit) - - This function executes a Unprivileged LDRT instruction 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 __LDRT(volatile uint32_t *addr) -{ - uint32_t result; - - __ASM volatile ("ldrt %0, %1" : "=r" (result) : "Q" (*addr) ); - return(result); -} - - -/** \brief STRT Unprivileged (8 bit) - - This function executes a Unprivileged STRT instruction for 8 bit values. - - \param [in] value Value to store - \param [in] ptr Pointer to location - */ -__attribute__((always_inline)) __STATIC_INLINE void __STRBT(uint8_t value, volatile uint8_t *addr) -{ - __ASM volatile ("strbt %1, %0" : "=Q" (*addr) : "r" ((uint32_t)value) ); -} - - -/** \brief STRT Unprivileged (16 bit) - - This function executes a Unprivileged STRT instruction for 16 bit values. - - \param [in] value Value to store - \param [in] ptr Pointer to location - */ -__attribute__((always_inline)) __STATIC_INLINE void __STRHT(uint16_t value, volatile uint16_t *addr) -{ - __ASM volatile ("strht %1, %0" : "=Q" (*addr) : "r" ((uint32_t)value) ); -} - - -/** \brief STRT Unprivileged (32 bit) - - This function executes a Unprivileged STRT instruction for 32 bit values. - - \param [in] value Value to store - \param [in] ptr Pointer to location - */ -__attribute__((always_inline)) __STATIC_INLINE void __STRT(uint32_t value, volatile uint32_t *addr) -{ - __ASM volatile ("strt %1, %0" : "=Q" (*addr) : "r" (value) ); -} - -#endif /* (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300) */ - - -#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/ -/* IAR iccarm specific functions */ -#include - - -#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/ -/* TI CCS specific functions */ -#include - - -#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. - */ - - -#elif defined ( __CSMC__ ) /*------------------ COSMIC Compiler -------------------*/ -/* Cosmic specific functions */ -#include - -#endif - -/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ - -#endif /* __CORE_CMINSTR_H */ diff --git a/cmsis/core_cmSimd.h b/cmsis/core_cmSimd.h deleted file mode 100644 index 7b8e37fff60..00000000000 --- a/cmsis/core_cmSimd.h +++ /dev/null @@ -1,697 +0,0 @@ -/**************************************************************************//** - * @file core_cmSimd.h - * @brief CMSIS Cortex-M SIMD Header File - * @version V4.10 - * @date 18. March 2015 - * - * @note - * - ******************************************************************************/ -/* Copyright (c) 2009 - 2014 ARM LIMITED - - All rights reserved. - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - Neither the name of ARM nor the names of its contributors may be used - to endorse or promote products derived from this software without - specific prior written permission. - * - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - ---------------------------------------------------------------------------*/ - - -#if defined ( __ICCARM__ ) - #pragma system_include /* treat file as system include file for MISRA check */ -#endif - -#ifndef __CORE_CMSIMD_H -#define __CORE_CMSIMD_H - -#ifdef __cplusplus - extern "C" { -#endif - - -/******************************************************************************* - * 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 */ -#define __SADD8 __sadd8 -#define __QADD8 __qadd8 -#define __SHADD8 __shadd8 -#define __UADD8 __uadd8 -#define __UQADD8 __uqadd8 -#define __UHADD8 __uhadd8 -#define __SSUB8 __ssub8 -#define __QSUB8 __qsub8 -#define __SHSUB8 __shsub8 -#define __USUB8 __usub8 -#define __UQSUB8 __uqsub8 -#define __UHSUB8 __uhsub8 -#define __SADD16 __sadd16 -#define __QADD16 __qadd16 -#define __SHADD16 __shadd16 -#define __UADD16 __uadd16 -#define __UQADD16 __uqadd16 -#define __UHADD16 __uhadd16 -#define __SSUB16 __ssub16 -#define __QSUB16 __qsub16 -#define __SHSUB16 __shsub16 -#define __USUB16 __usub16 -#define __UQSUB16 __uqsub16 -#define __UHSUB16 __uhsub16 -#define __SASX __sasx -#define __QASX __qasx -#define __SHASX __shasx -#define __UASX __uasx -#define __UQASX __uqasx -#define __UHASX __uhasx -#define __SSAX __ssax -#define __QSAX __qsax -#define __SHSAX __shsax -#define __USAX __usax -#define __UQSAX __uqsax -#define __UHSAX __uhsax -#define __USAD8 __usad8 -#define __USADA8 __usada8 -#define __SSAT16 __ssat16 -#define __USAT16 __usat16 -#define __UXTB16 __uxtb16 -#define __UXTAB16 __uxtab16 -#define __SXTB16 __sxtb16 -#define __SXTAB16 __sxtab16 -#define __SMUAD __smuad -#define __SMUADX __smuadx -#define __SMLAD __smlad -#define __SMLADX __smladx -#define __SMLALD __smlald -#define __SMLALDX __smlaldx -#define __SMUSD __smusd -#define __SMUSDX __smusdx -#define __SMLSD __smlsd -#define __SMLSDX __smlsdx -#define __SMLSLD __smlsld -#define __SMLSLDX __smlsldx -#define __SEL __sel -#define __QADD __qadd -#define __QSUB __qsub - -#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \ - ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) ) - -#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \ - ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) ) - -#define __SMMLA(ARG1,ARG2,ARG3) ( (int32_t)((((int64_t)(ARG1) * (ARG2)) + \ - ((int64_t)(ARG3) << 32) ) >> 32)) - - -#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/ -/* GNU gcc specific functions */ -__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); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLALD (uint32_t op1, uint32_t op2, uint64_t acc) -{ - union llreg_u{ - uint32_t w32[2]; - uint64_t w64; - } llr; - llr.w64 = acc; - -#ifndef __ARMEB__ // Little endian - __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); -#else // Big endian - __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); -#endif - - return(llr.w64); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLALDX (uint32_t op1, uint32_t op2, uint64_t acc) -{ - union llreg_u{ - uint32_t w32[2]; - uint64_t w64; - } llr; - llr.w64 = acc; - -#ifndef __ARMEB__ // Little endian - __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); -#else // Big endian - __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); -#endif - - return(llr.w64); -} - -__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); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLSLD (uint32_t op1, uint32_t op2, uint64_t acc) -{ - union llreg_u{ - uint32_t w32[2]; - uint64_t w64; - } llr; - llr.w64 = acc; - -#ifndef __ARMEB__ // Little endian - __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); -#else // Big endian - __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); -#endif - - return(llr.w64); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLSLDX (uint32_t op1, uint32_t op2, uint64_t acc) -{ - union llreg_u{ - uint32_t w32[2]; - uint64_t w64; - } llr; - llr.w64 = acc; - -#ifndef __ARMEB__ // Little endian - __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); -#else // Big endian - __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); -#endif - - return(llr.w64); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SEL (uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("sel %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -#define __PKHBT(ARG1,ARG2,ARG3) \ -({ \ - uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \ - __ASM ("pkhbt %0, %1, %2, lsl %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \ - __RES; \ - }) - -#define __PKHTB(ARG1,ARG2,ARG3) \ -({ \ - uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \ - if (ARG3 == 0) \ - __ASM ("pkhtb %0, %1, %2" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2) ); \ - else \ - __ASM ("pkhtb %0, %1, %2, asr %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \ - __RES; \ - }) - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3) -{ - int32_t result; - - __ASM volatile ("smmla %0, %1, %2, %3" : "=r" (result): "r" (op1), "r" (op2), "r" (op3) ); - return(result); -} - - -#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/ -/* IAR iccarm specific functions */ -#include - - -#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/ -/* TI CCS specific functions */ -#include - - -#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/ -/* TASKING carm specific functions */ -/* not yet supported */ - - -#elif defined ( __CSMC__ ) /*------------------ COSMIC Compiler -------------------*/ -/* Cosmic specific functions */ -#include - -#endif - -/*@} end of group CMSIS_SIMD_intrinsics */ - - -#ifdef __cplusplus -} -#endif - -#endif /* __CORE_CMSIMD_H */ diff --git a/cmsis/core_sc000.h b/cmsis/core_sc000.h deleted file mode 100644 index 761f5d56641..00000000000 --- a/cmsis/core_sc000.h +++ /dev/null @@ -1,866 +0,0 @@ -/**************************************************************************//** - * @file core_sc000.h - * @brief CMSIS SC000 Core Peripheral Access Layer Header File - * @version V4.10 - * @date 18. March 2015 - * - * @note - * - ******************************************************************************/ -/* Copyright (c) 2009 - 2015 ARM LIMITED - - All rights reserved. - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - Neither the name of ARM nor the names of its contributors may be used - to endorse or promote products derived from this software without - specific prior written permission. - * - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - ---------------------------------------------------------------------------*/ - - -#if defined ( __ICCARM__ ) - #pragma system_include /* treat file as system include file for MISRA check */ -#endif - -#ifndef __CORE_SC000_H_GENERIC -#define __CORE_SC000_H_GENERIC - -#ifdef __cplusplus - extern "C" { -#endif - -/** \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions - CMSIS violates the following MISRA-C:2004 rules: - - \li Required Rule 8.5, object/function definition in header file.
- Function definitions in header files are used to allow 'inlining'. - - \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
- Unions are used for effective representation of core registers. - - \li Advisory Rule 19.7, Function-like macro defined.
- Function-like macros are used to allow more efficient code. - */ - - -/******************************************************************************* - * CMSIS definitions - ******************************************************************************/ -/** \ingroup SC000 - @{ - */ - -/* CMSIS SC000 definitions */ -#define __SC000_CMSIS_VERSION_MAIN (0x04) /*!< [31:16] CMSIS HAL main version */ -#define __SC000_CMSIS_VERSION_SUB (0x00) /*!< [15:0] CMSIS HAL sub version */ -#define __SC000_CMSIS_VERSION ((__SC000_CMSIS_VERSION_MAIN << 16) | \ - __SC000_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */ - -#define __CORTEX_SC (000) /*!< Cortex secure core */ - - -#if defined ( __CC_ARM ) - #define __ASM __asm /*!< asm keyword for ARM Compiler */ - #define __INLINE __inline /*!< inline keyword for ARM Compiler */ - #define __STATIC_INLINE static __inline - -#elif defined ( __GNUC__ ) - #define __ASM __asm /*!< asm keyword for GNU Compiler */ - #define __INLINE inline /*!< inline keyword for GNU Compiler */ - #define __STATIC_INLINE static inline - -#elif defined ( __ICCARM__ ) - #define __ASM __asm /*!< asm keyword for IAR Compiler */ - #define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */ - #define __STATIC_INLINE static inline - -#elif defined ( __TMS470__ ) - #define __ASM __asm /*!< asm keyword for TI CCS Compiler */ - #define __STATIC_INLINE static inline - -#elif defined ( __TASKING__ ) - #define __ASM __asm /*!< asm keyword for TASKING Compiler */ - #define __INLINE inline /*!< inline keyword for TASKING Compiler */ - #define __STATIC_INLINE static inline - -#elif defined ( __CSMC__ ) - #define __packed - #define __ASM _asm /*!< asm keyword for COSMIC Compiler */ - #define __INLINE inline /*use -pc99 on compile line !< inline keyword for COSMIC Compiler */ - #define __STATIC_INLINE static inline - -#endif - -/** __FPU_USED indicates whether an FPU is used or not. - This core does not support an FPU at all -*/ -#define __FPU_USED 0 - -#if defined ( __CC_ARM ) - #if defined __TARGET_FPU_VFP - #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #endif - -#elif defined ( __GNUC__ ) - #if defined (__VFP_FP__) && !defined(__SOFTFP__) - #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #endif - -#elif defined ( __ICCARM__ ) - #if defined __ARMVFP__ - #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #endif - -#elif defined ( __TMS470__ ) - #if defined __TI__VFP_SUPPORT____ - #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #endif - -#elif defined ( __TASKING__ ) - #if defined __FPU_VFP__ - #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #endif - -#elif defined ( __CSMC__ ) /* Cosmic */ - #if ( __CSMC__ & 0x400) // FPU present for parser - #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #endif -#endif - -#include /* standard types definitions */ -#include /* Core Instruction Access */ -#include /* Core Function Access */ - -#ifdef __cplusplus -} -#endif - -#endif /* __CORE_SC000_H_GENERIC */ - -#ifndef __CMSIS_GENERIC - -#ifndef __CORE_SC000_H_DEPENDANT -#define __CORE_SC000_H_DEPENDANT - -#ifdef __cplusplus - extern "C" { -#endif - -/* check device defines and use defaults */ -#if defined __CHECK_DEVICE_DEFINES - #ifndef __SC000_REV - #define __SC000_REV 0x0000 - #warning "__SC000_REV not defined in device header file; using default!" - #endif - - #ifndef __MPU_PRESENT - #define __MPU_PRESENT 0 - #warning "__MPU_PRESENT not defined in device header file; using default!" - #endif - - #ifndef __NVIC_PRIO_BITS - #define __NVIC_PRIO_BITS 2 - #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" - #endif - - #ifndef __Vendor_SysTickConfig - #define __Vendor_SysTickConfig 0 - #warning "__Vendor_SysTickConfig not defined in device header file; using default!" - #endif -#endif - -/* IO definitions (access restrictions to peripheral registers) */ -/** - \defgroup CMSIS_glob_defs CMSIS Global Defines - - IO Type Qualifiers are used - \li to specify the access to peripheral variables. - \li for automatic generation of peripheral register debug information. -*/ -#ifdef __cplusplus - #define __I volatile /*!< Defines 'read only' permissions */ -#else - #define __I volatile const /*!< Defines 'read only' permissions */ -#endif -#define __O volatile /*!< Defines 'write only' permissions */ -#define __IO volatile /*!< Defines 'read / write' permissions */ - -/*@} end of group SC000 */ - - - -/******************************************************************************* - * Register Abstraction - Core Register contain: - - Core Register - - Core NVIC Register - - Core SCB Register - - Core SysTick Register - - Core MPU Register - ******************************************************************************/ -/** \defgroup CMSIS_core_register Defines and Type Definitions - \brief Type definitions and defines for Cortex-M processor based devices. -*/ - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_CORE Status and Control Registers - \brief Core Register type definitions. - @{ - */ - -/** \brief Union type to access the Application Program Status Register (APSR). - */ -typedef union -{ - struct - { - uint32_t _reserved0:28; /*!< bit: 0..27 Reserved */ - uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ - uint32_t C:1; /*!< bit: 29 Carry condition code flag */ - uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ - uint32_t N:1; /*!< bit: 31 Negative condition code flag */ - } b; /*!< Structure used for bit access */ - uint32_t w; /*!< Type used for word access */ -} APSR_Type; - -/* APSR Register Definitions */ -#define APSR_N_Pos 31 /*!< APSR: N Position */ -#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ - -#define APSR_Z_Pos 30 /*!< APSR: Z Position */ -#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ - -#define APSR_C_Pos 29 /*!< APSR: C Position */ -#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ - -#define APSR_V_Pos 28 /*!< APSR: V Position */ -#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ - - -/** \brief Union type to access the Interrupt Program Status Register (IPSR). - */ -typedef union -{ - struct - { - uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ - uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ - } b; /*!< Structure used for bit access */ - uint32_t w; /*!< Type used for word access */ -} IPSR_Type; - -/* IPSR Register Definitions */ -#define IPSR_ISR_Pos 0 /*!< IPSR: ISR Position */ -#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ - - -/** \brief Union type to access the Special-Purpose Program Status Registers (xPSR). - */ -typedef union -{ - struct - { - uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ - uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ - uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ - uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */ - uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ - uint32_t C:1; /*!< bit: 29 Carry condition code flag */ - uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ - uint32_t N:1; /*!< bit: 31 Negative condition code flag */ - } b; /*!< Structure used for bit access */ - uint32_t w; /*!< Type used for word access */ -} xPSR_Type; - -/* xPSR Register Definitions */ -#define xPSR_N_Pos 31 /*!< xPSR: N Position */ -#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ - -#define xPSR_Z_Pos 30 /*!< xPSR: Z Position */ -#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ - -#define xPSR_C_Pos 29 /*!< xPSR: C Position */ -#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ - -#define xPSR_V_Pos 28 /*!< xPSR: V Position */ -#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ - -#define xPSR_T_Pos 24 /*!< xPSR: T Position */ -#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ - -#define xPSR_ISR_Pos 0 /*!< xPSR: ISR Position */ -#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ - - -/** \brief Union type to access the Control Registers (CONTROL). - */ -typedef union -{ - struct - { - uint32_t _reserved0:1; /*!< bit: 0 Reserved */ - uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ - uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */ - } b; /*!< Structure used for bit access */ - uint32_t w; /*!< Type used for word access */ -} CONTROL_Type; - -/* CONTROL Register Definitions */ -#define CONTROL_SPSEL_Pos 1 /*!< CONTROL: SPSEL Position */ -#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ - -/*@} end of group CMSIS_CORE */ - - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) - \brief Type definitions for the NVIC Registers - @{ - */ - -/** \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). - */ -typedef struct -{ - __IO uint32_t ISER[1]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ - uint32_t RESERVED0[31]; - __IO uint32_t ICER[1]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ - uint32_t RSERVED1[31]; - __IO uint32_t ISPR[1]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ - uint32_t RESERVED2[31]; - __IO uint32_t ICPR[1]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ - uint32_t RESERVED3[31]; - uint32_t RESERVED4[64]; - __IO uint32_t IP[8]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */ -} NVIC_Type; - -/*@} end of group CMSIS_NVIC */ - - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_SCB System Control Block (SCB) - \brief Type definitions for the System Control Block Registers - @{ - */ - -/** \brief Structure type to access the System Control Block (SCB). - */ -typedef struct -{ - __I uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ - __IO uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ - __IO uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ - __IO uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ - __IO uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ - __IO uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ - uint32_t RESERVED0[1]; - __IO uint32_t SHP[2]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */ - __IO uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ - uint32_t RESERVED1[154]; - __IO uint32_t SFCR; /*!< Offset: 0x290 (R/W) Security Features 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_VECTACTIVE_Pos 0 /*!< SCB ICSR: VECTACTIVE Position */ -#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ - -/* SCB Interrupt Control State Register Definitions */ -#define SCB_VTOR_TBLOFF_Pos 7 /*!< SCB VTOR: TBLOFF Position */ -#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ - -/* SCB Application Interrupt and Reset Control Register Definitions */ -#define SCB_AIRCR_VECTKEY_Pos 16 /*!< SCB AIRCR: VECTKEY Position */ -#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ - -#define SCB_AIRCR_VECTKEYSTAT_Pos 16 /*!< SCB AIRCR: VECTKEYSTAT Position */ -#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ - -#define SCB_AIRCR_ENDIANESS_Pos 15 /*!< SCB AIRCR: ENDIANESS Position */ -#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ - -#define SCB_AIRCR_SYSRESETREQ_Pos 2 /*!< SCB AIRCR: SYSRESETREQ Position */ -#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ - -#define SCB_AIRCR_VECTCLRACTIVE_Pos 1 /*!< SCB AIRCR: VECTCLRACTIVE Position */ -#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ - -/* SCB System Control Register Definitions */ -#define SCB_SCR_SEVONPEND_Pos 4 /*!< SCB SCR: SEVONPEND Position */ -#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ - -#define SCB_SCR_SLEEPDEEP_Pos 2 /*!< SCB SCR: SLEEPDEEP Position */ -#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ - -#define SCB_SCR_SLEEPONEXIT_Pos 1 /*!< SCB SCR: SLEEPONEXIT Position */ -#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ - -/* SCB Configuration Control Register Definitions */ -#define SCB_CCR_STKALIGN_Pos 9 /*!< SCB CCR: STKALIGN Position */ -#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ - -#define SCB_CCR_UNALIGN_TRP_Pos 3 /*!< SCB CCR: UNALIGN_TRP Position */ -#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ - -/* SCB System Handler Control and State Register Definitions */ -#define SCB_SHCSR_SVCALLPENDED_Pos 15 /*!< SCB SHCSR: SVCALLPENDED Position */ -#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ - -/*@} end of group CMSIS_SCB */ - - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) - \brief Type definitions for the System Control and ID Register not in the SCB - @{ - */ - -/** \brief Structure type to access the System Control and ID Register not in the SCB. - */ -typedef struct -{ - uint32_t RESERVED0[2]; - __IO uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ -} SCnSCB_Type; - -/* Auxiliary Control Register Definitions */ -#define SCnSCB_ACTLR_DISMCYCINT_Pos 0 /*!< ACTLR: DISMCYCINT Position */ -#define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL /*<< SCnSCB_ACTLR_DISMCYCINT_Pos*/) /*!< ACTLR: DISMCYCINT Mask */ - -/*@} end of group CMSIS_SCnotSCB */ - - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_SysTick System Tick Timer (SysTick) - \brief Type definitions for the System Timer Registers. - @{ - */ - -/** \brief Structure type to access the System Timer (SysTick). - */ -typedef struct -{ - __IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ - __IO uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ - __IO uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ - __I uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ -} SysTick_Type; - -/* SysTick Control / Status Register Definitions */ -#define SysTick_CTRL_COUNTFLAG_Pos 16 /*!< SysTick CTRL: COUNTFLAG Position */ -#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ - -#define SysTick_CTRL_CLKSOURCE_Pos 2 /*!< SysTick CTRL: CLKSOURCE Position */ -#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ - -#define SysTick_CTRL_TICKINT_Pos 1 /*!< SysTick CTRL: TICKINT Position */ -#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ - -#define SysTick_CTRL_ENABLE_Pos 0 /*!< SysTick CTRL: ENABLE Position */ -#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ - -/* SysTick Reload Register Definitions */ -#define SysTick_LOAD_RELOAD_Pos 0 /*!< SysTick LOAD: RELOAD Position */ -#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ - -/* SysTick Current Register Definitions */ -#define SysTick_VAL_CURRENT_Pos 0 /*!< SysTick VAL: CURRENT Position */ -#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ - -/* SysTick Calibration Register Definitions */ -#define SysTick_CALIB_NOREF_Pos 31 /*!< SysTick CALIB: NOREF Position */ -#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ - -#define SysTick_CALIB_SKEW_Pos 30 /*!< SysTick CALIB: SKEW Position */ -#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ - -#define SysTick_CALIB_TENMS_Pos 0 /*!< SysTick CALIB: TENMS Position */ -#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ - -/*@} end of group CMSIS_SysTick */ - -#if (__MPU_PRESENT == 1) -/** \ingroup CMSIS_core_register - \defgroup CMSIS_MPU Memory Protection Unit (MPU) - \brief Type definitions for the Memory Protection Unit (MPU) - @{ - */ - -/** \brief Structure type to access the Memory Protection Unit (MPU). - */ -typedef struct -{ - __I uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ - __IO uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ - __IO uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ - __IO uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ - __IO uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ -} MPU_Type; - -/* MPU Type Register */ -#define MPU_TYPE_IREGION_Pos 16 /*!< MPU TYPE: IREGION Position */ -#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ - -#define MPU_TYPE_DREGION_Pos 8 /*!< MPU TYPE: DREGION Position */ -#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ - -#define MPU_TYPE_SEPARATE_Pos 0 /*!< MPU TYPE: SEPARATE Position */ -#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ - -/* MPU Control Register */ -#define MPU_CTRL_PRIVDEFENA_Pos 2 /*!< MPU CTRL: PRIVDEFENA Position */ -#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ - -#define MPU_CTRL_HFNMIENA_Pos 1 /*!< MPU CTRL: HFNMIENA Position */ -#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ - -#define MPU_CTRL_ENABLE_Pos 0 /*!< MPU CTRL: ENABLE Position */ -#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ - -/* MPU Region Number Register */ -#define MPU_RNR_REGION_Pos 0 /*!< MPU RNR: REGION Position */ -#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ - -/* MPU Region Base Address Register */ -#define MPU_RBAR_ADDR_Pos 8 /*!< MPU RBAR: ADDR Position */ -#define MPU_RBAR_ADDR_Msk (0xFFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ - -#define MPU_RBAR_VALID_Pos 4 /*!< MPU RBAR: VALID Position */ -#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ - -#define MPU_RBAR_REGION_Pos 0 /*!< MPU RBAR: REGION Position */ -#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */ - -/* MPU Region Attribute and Size Register */ -#define MPU_RASR_ATTRS_Pos 16 /*!< MPU RASR: MPU Region Attribute field Position */ -#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ - -#define MPU_RASR_XN_Pos 28 /*!< MPU RASR: ATTRS.XN Position */ -#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ - -#define MPU_RASR_AP_Pos 24 /*!< MPU RASR: ATTRS.AP Position */ -#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ - -#define MPU_RASR_TEX_Pos 19 /*!< MPU RASR: ATTRS.TEX Position */ -#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ - -#define MPU_RASR_S_Pos 18 /*!< MPU RASR: ATTRS.S Position */ -#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ - -#define MPU_RASR_C_Pos 17 /*!< MPU RASR: ATTRS.C Position */ -#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ - -#define MPU_RASR_B_Pos 16 /*!< MPU RASR: ATTRS.B Position */ -#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ - -#define MPU_RASR_SRD_Pos 8 /*!< MPU RASR: Sub-Region Disable Position */ -#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ - -#define MPU_RASR_SIZE_Pos 1 /*!< MPU RASR: Region Size Field Position */ -#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ - -#define MPU_RASR_ENABLE_Pos 0 /*!< MPU RASR: Region enable bit Position */ -#define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */ - -/*@} end of group CMSIS_MPU */ -#endif - - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) - \brief SC000 Core Debug Registers (DCB registers, SHCSR, and DFSR) - are only accessible over DAP and not via processor. Therefore - they are not covered by the Cortex-M0 header file. - @{ - */ -/*@} end of group CMSIS_CoreDebug */ - - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_core_base Core Definitions - \brief Definitions for base addresses, unions, and structures. - @{ - */ - -/* Memory mapping of SC000 Hardware */ -#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ -#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ -#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ -#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ - -#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ -#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ -#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ -#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ - -#if (__MPU_PRESENT == 1) - #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ - #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ -#endif - -/*@} */ - - - -/******************************************************************************* - * Hardware Abstraction Layer - Core Function Interface contains: - - Core NVIC Functions - - Core SysTick Functions - - Core Register Access Functions - ******************************************************************************/ -/** \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference -*/ - - - -/* ########################## NVIC functions #################################### */ -/** \ingroup CMSIS_Core_FunctionInterface - \defgroup CMSIS_Core_NVICFunctions NVIC Functions - \brief Functions that manage interrupts and exceptions via the NVIC. - @{ - */ - -/* Interrupt Priorities are WORD accessible only under ARMv6M */ -/* The following MACROS handle generation of the register offset and byte masks */ -#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL) -#define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) ) -#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) ) - - -/** \brief Enable External Interrupt - - The function enables a device-specific interrupt in the NVIC interrupt controller. - - \param [in] IRQn External interrupt number. Value cannot be negative. - */ -__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn) -{ - NVIC->ISER[0] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); -} - - -/** \brief Disable External Interrupt - - The function disables a device-specific interrupt in the NVIC interrupt controller. - - \param [in] IRQn External interrupt number. Value cannot be negative. - */ -__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn) -{ - NVIC->ICER[0] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); - __DSB(); - __ISB(); -} - - -/** \brief Get Pending Interrupt - - The function reads the pending register in the NVIC and returns the pending bit - for the specified interrupt. - - \param [in] IRQn Interrupt number. - - \return 0 Interrupt status is not pending. - \return 1 Interrupt status is pending. - */ -__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn) -{ - return((uint32_t)(((NVIC->ISPR[0] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); -} - - -/** \brief Set Pending Interrupt - - The function sets the pending bit of an external interrupt. - - \param [in] IRQn Interrupt number. Value cannot be negative. - */ -__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn) -{ - NVIC->ISPR[0] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); -} - - -/** \brief Clear Pending Interrupt - - The function clears the pending bit of an external interrupt. - - \param [in] IRQn External interrupt number. Value cannot be negative. - */ -__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn) -{ - NVIC->ICPR[0] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); -} - - -/** \brief Set Interrupt Priority - - The function sets the priority of an interrupt. - - \note The priority cannot be set for every core interrupt. - - \param [in] IRQn Interrupt number. - \param [in] priority Priority to set. - */ -__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) -{ - if((int32_t)(IRQn) < 0) { - SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | - (((priority << (8 - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); - } - else { - NVIC->IP[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | - (((priority << (8 - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); - } -} - - -/** \brief Get Interrupt Priority - - The function reads the priority of an interrupt. The interrupt - number can be positive to specify an external (device specific) - interrupt, or negative to specify an internal (core) interrupt. - - - \param [in] IRQn Interrupt number. - \return Interrupt Priority. Value is aligned automatically to the implemented - priority bits of the microcontroller. - */ -__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn) -{ - - if((int32_t)(IRQn) < 0) { - return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8 - __NVIC_PRIO_BITS))); - } - else { - return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8 - __NVIC_PRIO_BITS))); - } -} - - -/** \brief System Reset - - The function initiates a system reset request to reset the MCU. - */ -__STATIC_INLINE void NVIC_SystemReset(void) -{ - __DSB(); /* Ensure all outstanding memory accesses included - buffered write are completed before reset */ - SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | - SCB_AIRCR_SYSRESETREQ_Msk); - __DSB(); /* Ensure completion of memory access */ - while(1) { __NOP(); } /* wait until reset */ -} - -/*@} end of CMSIS_Core_NVICFunctions */ - - - -/* ################################## SysTick function ############################################ */ -/** \ingroup CMSIS_Core_FunctionInterface - \defgroup CMSIS_Core_SysTickFunctions SysTick Functions - \brief Functions that configure the System. - @{ - */ - -#if (__Vendor_SysTickConfig == 0) - -/** \brief System Tick Configuration - - The function initializes the System Timer and its interrupt, and starts the System Tick Timer. - Counter is in free running mode to generate periodic interrupts. - - \param [in] ticks Number of ticks between two interrupts. - - \return 0 Function succeeded. - \return 1 Function failed. - - \note When the variable __Vendor_SysTickConfig is set to 1, then the - function SysTick_Config is not included. In this case, the file device.h - must contain a vendor-specific implementation of this function. - - */ -__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) -{ - if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) {return (1UL);} /* Reload value impossible */ - - SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ - NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ - SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ - SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | - SysTick_CTRL_TICKINT_Msk | - SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ - return (0UL); /* Function successful */ -} - -#endif - -/*@} end of CMSIS_Core_SysTickFunctions */ - - - - -#ifdef __cplusplus -} -#endif - -#endif /* __CORE_SC000_H_DEPENDANT */ - -#endif /* __CMSIS_GENERIC */ diff --git a/cmsis/core_sc300.h b/cmsis/core_sc300.h deleted file mode 100644 index d871fa84478..00000000000 --- a/cmsis/core_sc300.h +++ /dev/null @@ -1,1677 +0,0 @@ -/**************************************************************************//** - * @file core_sc300.h - * @brief CMSIS SC300 Core Peripheral Access Layer Header File - * @version V4.10 - * @date 18. March 2015 - * - * @note - * - ******************************************************************************/ -/* Copyright (c) 2009 - 2015 ARM LIMITED - - All rights reserved. - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - Neither the name of ARM nor the names of its contributors may be used - to endorse or promote products derived from this software without - specific prior written permission. - * - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - ---------------------------------------------------------------------------*/ - - -#if defined ( __ICCARM__ ) - #pragma system_include /* treat file as system include file for MISRA check */ -#endif - -#ifndef __CORE_SC300_H_GENERIC -#define __CORE_SC300_H_GENERIC - -#ifdef __cplusplus - extern "C" { -#endif - -/** \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions - CMSIS violates the following MISRA-C:2004 rules: - - \li Required Rule 8.5, object/function definition in header file.
- Function definitions in header files are used to allow 'inlining'. - - \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
- Unions are used for effective representation of core registers. - - \li Advisory Rule 19.7, Function-like macro defined.
- Function-like macros are used to allow more efficient code. - */ - - -/******************************************************************************* - * CMSIS definitions - ******************************************************************************/ -/** \ingroup SC3000 - @{ - */ - -/* CMSIS SC300 definitions */ -#define __SC300_CMSIS_VERSION_MAIN (0x04) /*!< [31:16] CMSIS HAL main version */ -#define __SC300_CMSIS_VERSION_SUB (0x00) /*!< [15:0] CMSIS HAL sub version */ -#define __SC300_CMSIS_VERSION ((__SC300_CMSIS_VERSION_MAIN << 16) | \ - __SC300_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */ - -#define __CORTEX_SC (300) /*!< Cortex secure core */ - - -#if defined ( __CC_ARM ) - #define __ASM __asm /*!< asm keyword for ARM Compiler */ - #define __INLINE __inline /*!< inline keyword for ARM Compiler */ - #define __STATIC_INLINE static __inline - -#elif defined ( __GNUC__ ) - #define __ASM __asm /*!< asm keyword for GNU Compiler */ - #define __INLINE inline /*!< inline keyword for GNU Compiler */ - #define __STATIC_INLINE static inline - -#elif defined ( __ICCARM__ ) - #define __ASM __asm /*!< asm keyword for IAR Compiler */ - #define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */ - #define __STATIC_INLINE static inline - -#elif defined ( __TMS470__ ) - #define __ASM __asm /*!< asm keyword for TI CCS Compiler */ - #define __STATIC_INLINE static inline - -#elif defined ( __TASKING__ ) - #define __ASM __asm /*!< asm keyword for TASKING Compiler */ - #define __INLINE inline /*!< inline keyword for TASKING Compiler */ - #define __STATIC_INLINE static inline - -#elif defined ( __CSMC__ ) - #define __packed - #define __ASM _asm /*!< asm keyword for COSMIC Compiler */ - #define __INLINE inline /*use -pc99 on compile line !< inline keyword for COSMIC Compiler */ - #define __STATIC_INLINE static inline - -#endif - -/** __FPU_USED indicates whether an FPU is used or not. - This core does not support an FPU at all -*/ -#define __FPU_USED 0 - -#if defined ( __CC_ARM ) - #if defined __TARGET_FPU_VFP - #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #endif - -#elif defined ( __GNUC__ ) - #if defined (__VFP_FP__) && !defined(__SOFTFP__) - #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #endif - -#elif defined ( __ICCARM__ ) - #if defined __ARMVFP__ - #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #endif - -#elif defined ( __TMS470__ ) - #if defined __TI__VFP_SUPPORT____ - #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #endif - -#elif defined ( __TASKING__ ) - #if defined __FPU_VFP__ - #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #endif - -#elif defined ( __CSMC__ ) /* Cosmic */ - #if ( __CSMC__ & 0x400) // FPU present for parser - #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #endif -#endif - -#include /* standard types definitions */ -#include /* Core Instruction Access */ -#include /* Core Function Access */ - -#ifdef __cplusplus -} -#endif - -#endif /* __CORE_SC300_H_GENERIC */ - -#ifndef __CMSIS_GENERIC - -#ifndef __CORE_SC300_H_DEPENDANT -#define __CORE_SC300_H_DEPENDANT - -#ifdef __cplusplus - extern "C" { -#endif - -/* check device defines and use defaults */ -#if defined __CHECK_DEVICE_DEFINES - #ifndef __SC300_REV - #define __SC300_REV 0x0000 - #warning "__SC300_REV not defined in device header file; using default!" - #endif - - #ifndef __MPU_PRESENT - #define __MPU_PRESENT 0 - #warning "__MPU_PRESENT not defined in device header file; using default!" - #endif - - #ifndef __NVIC_PRIO_BITS - #define __NVIC_PRIO_BITS 4 - #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" - #endif - - #ifndef __Vendor_SysTickConfig - #define __Vendor_SysTickConfig 0 - #warning "__Vendor_SysTickConfig not defined in device header file; using default!" - #endif -#endif - -/* IO definitions (access restrictions to peripheral registers) */ -/** - \defgroup CMSIS_glob_defs CMSIS Global Defines - - IO Type Qualifiers are used - \li to specify the access to peripheral variables. - \li for automatic generation of peripheral register debug information. -*/ -#ifdef __cplusplus - #define __I volatile /*!< Defines 'read only' permissions */ -#else - #define __I volatile const /*!< Defines 'read only' permissions */ -#endif -#define __O volatile /*!< Defines 'write only' permissions */ -#define __IO volatile /*!< Defines 'read / write' permissions */ - -/*@} end of group SC300 */ - - - -/******************************************************************************* - * Register Abstraction - Core Register contain: - - Core Register - - Core NVIC Register - - Core SCB Register - - Core SysTick Register - - Core Debug Register - - Core MPU Register - ******************************************************************************/ -/** \defgroup CMSIS_core_register Defines and Type Definitions - \brief Type definitions and defines for Cortex-M processor based devices. -*/ - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_CORE Status and Control Registers - \brief Core Register type definitions. - @{ - */ - -/** \brief Union type to access the Application Program Status Register (APSR). - */ -typedef union -{ - struct - { - uint32_t _reserved0:27; /*!< bit: 0..26 Reserved */ - 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; - -/* APSR Register Definitions */ -#define APSR_N_Pos 31 /*!< APSR: N Position */ -#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ - -#define APSR_Z_Pos 30 /*!< APSR: Z Position */ -#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ - -#define APSR_C_Pos 29 /*!< APSR: C Position */ -#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ - -#define APSR_V_Pos 28 /*!< APSR: V Position */ -#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ - -#define APSR_Q_Pos 27 /*!< APSR: Q Position */ -#define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */ - - -/** \brief Union type to access the Interrupt Program Status Register (IPSR). - */ -typedef union -{ - struct - { - uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ - uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ - } b; /*!< Structure used for bit access */ - uint32_t w; /*!< Type used for word access */ -} IPSR_Type; - -/* IPSR Register Definitions */ -#define IPSR_ISR_Pos 0 /*!< IPSR: ISR Position */ -#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ - - -/** \brief Union type to access the Special-Purpose Program Status Registers (xPSR). - */ -typedef union -{ - struct - { - uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ - uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ - uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ - uint32_t 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; - -/* xPSR Register Definitions */ -#define xPSR_N_Pos 31 /*!< xPSR: N Position */ -#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ - -#define xPSR_Z_Pos 30 /*!< xPSR: Z Position */ -#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ - -#define xPSR_C_Pos 29 /*!< xPSR: C Position */ -#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ - -#define xPSR_V_Pos 28 /*!< xPSR: V Position */ -#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ - -#define xPSR_Q_Pos 27 /*!< xPSR: Q Position */ -#define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */ - -#define xPSR_IT_Pos 25 /*!< xPSR: IT Position */ -#define xPSR_IT_Msk (3UL << xPSR_IT_Pos) /*!< xPSR: IT Mask */ - -#define xPSR_T_Pos 24 /*!< xPSR: T Position */ -#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ - -#define xPSR_ISR_Pos 0 /*!< xPSR: ISR Position */ -#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ - - -/** \brief Union type to access the Control Registers (CONTROL). - */ -typedef union -{ - struct - { - uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ - uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ - uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */ - } b; /*!< Structure used for bit access */ - uint32_t w; /*!< Type used for word access */ -} CONTROL_Type; - -/* CONTROL Register Definitions */ -#define CONTROL_SPSEL_Pos 1 /*!< CONTROL: SPSEL Position */ -#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ - -#define CONTROL_nPRIV_Pos 0 /*!< CONTROL: nPRIV Position */ -#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ - -/*@} end of group CMSIS_CORE */ - - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) - \brief Type definitions for the NVIC Registers - @{ - */ - -/** \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). - */ -typedef struct -{ - __IO uint32_t ISER[8]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ - uint32_t RESERVED0[24]; - __IO uint32_t ICER[8]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ - uint32_t RSERVED1[24]; - __IO uint32_t ISPR[8]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ - uint32_t RESERVED2[24]; - __IO uint32_t ICPR[8]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ - uint32_t RESERVED3[24]; - __IO uint32_t IABR[8]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ - uint32_t RESERVED4[56]; - __IO uint8_t IP[240]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ - uint32_t RESERVED5[644]; - __O uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ -} NVIC_Type; - -/* Software Triggered Interrupt Register Definitions */ -#define NVIC_STIR_INTID_Pos 0 /*!< STIR: INTLINESNUM Position */ -#define NVIC_STIR_INTID_Msk (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/) /*!< STIR: INTLINESNUM Mask */ - -/*@} end of group CMSIS_NVIC */ - - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_SCB System Control Block (SCB) - \brief Type definitions for the System Control Block Registers - @{ - */ - -/** \brief Structure type to access the System Control Block (SCB). - */ -typedef struct -{ - __I uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ - __IO uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ - __IO uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ - __IO uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ - __IO uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ - __IO uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ - __IO uint8_t SHP[12]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ - __IO uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ - __IO uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ - __IO uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ - __IO uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ - __IO uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ - __IO uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ - __IO uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ - __I uint32_t PFR[2]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ - __I uint32_t DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ - __I uint32_t ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ - __I uint32_t MMFR[4]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ - __I uint32_t ISAR[5]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ - uint32_t RESERVED0[5]; - __IO uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ - uint32_t RESERVED1[129]; - __IO uint32_t SFCR; /*!< Offset: 0x290 (R/W) Security Features Control Register */ -} SCB_Type; - -/* SCB CPUID Register Definitions */ -#define SCB_CPUID_IMPLEMENTER_Pos 24 /*!< SCB CPUID: IMPLEMENTER Position */ -#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ - -#define SCB_CPUID_VARIANT_Pos 20 /*!< SCB CPUID: VARIANT Position */ -#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ - -#define SCB_CPUID_ARCHITECTURE_Pos 16 /*!< SCB CPUID: ARCHITECTURE Position */ -#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ - -#define SCB_CPUID_PARTNO_Pos 4 /*!< SCB CPUID: PARTNO Position */ -#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ - -#define SCB_CPUID_REVISION_Pos 0 /*!< SCB CPUID: REVISION Position */ -#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ - -/* SCB Interrupt Control State Register Definitions */ -#define SCB_ICSR_NMIPENDSET_Pos 31 /*!< SCB ICSR: NMIPENDSET Position */ -#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ - -#define SCB_ICSR_PENDSVSET_Pos 28 /*!< SCB ICSR: PENDSVSET Position */ -#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ - -#define SCB_ICSR_PENDSVCLR_Pos 27 /*!< SCB ICSR: PENDSVCLR Position */ -#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ - -#define SCB_ICSR_PENDSTSET_Pos 26 /*!< SCB ICSR: PENDSTSET Position */ -#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ - -#define SCB_ICSR_PENDSTCLR_Pos 25 /*!< SCB ICSR: PENDSTCLR Position */ -#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ - -#define SCB_ICSR_ISRPREEMPT_Pos 23 /*!< SCB ICSR: ISRPREEMPT Position */ -#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ - -#define SCB_ICSR_ISRPENDING_Pos 22 /*!< SCB ICSR: ISRPENDING Position */ -#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ - -#define SCB_ICSR_VECTPENDING_Pos 12 /*!< SCB ICSR: VECTPENDING Position */ -#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ - -#define SCB_ICSR_RETTOBASE_Pos 11 /*!< SCB ICSR: RETTOBASE Position */ -#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ - -#define SCB_ICSR_VECTACTIVE_Pos 0 /*!< SCB ICSR: VECTACTIVE Position */ -#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ - -/* SCB Vector Table Offset Register Definitions */ -#define SCB_VTOR_TBLBASE_Pos 29 /*!< SCB VTOR: TBLBASE Position */ -#define SCB_VTOR_TBLBASE_Msk (1UL << SCB_VTOR_TBLBASE_Pos) /*!< SCB VTOR: TBLBASE Mask */ - -#define SCB_VTOR_TBLOFF_Pos 7 /*!< SCB VTOR: TBLOFF Position */ -#define SCB_VTOR_TBLOFF_Msk (0x3FFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ - -/* SCB Application Interrupt and Reset Control Register Definitions */ -#define SCB_AIRCR_VECTKEY_Pos 16 /*!< SCB AIRCR: VECTKEY Position */ -#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ - -#define SCB_AIRCR_VECTKEYSTAT_Pos 16 /*!< SCB AIRCR: VECTKEYSTAT Position */ -#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ - -#define SCB_AIRCR_ENDIANESS_Pos 15 /*!< SCB AIRCR: ENDIANESS Position */ -#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ - -#define SCB_AIRCR_PRIGROUP_Pos 8 /*!< SCB AIRCR: PRIGROUP Position */ -#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ - -#define SCB_AIRCR_SYSRESETREQ_Pos 2 /*!< SCB AIRCR: SYSRESETREQ Position */ -#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ - -#define SCB_AIRCR_VECTCLRACTIVE_Pos 1 /*!< SCB AIRCR: VECTCLRACTIVE Position */ -#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ - -#define SCB_AIRCR_VECTRESET_Pos 0 /*!< SCB AIRCR: VECTRESET Position */ -#define SCB_AIRCR_VECTRESET_Msk (1UL /*<< SCB_AIRCR_VECTRESET_Pos*/) /*!< SCB AIRCR: VECTRESET Mask */ - -/* SCB System Control Register Definitions */ -#define SCB_SCR_SEVONPEND_Pos 4 /*!< SCB SCR: SEVONPEND Position */ -#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ - -#define SCB_SCR_SLEEPDEEP_Pos 2 /*!< SCB SCR: SLEEPDEEP Position */ -#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ - -#define SCB_SCR_SLEEPONEXIT_Pos 1 /*!< SCB SCR: SLEEPONEXIT Position */ -#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ - -/* SCB Configuration Control Register Definitions */ -#define SCB_CCR_STKALIGN_Pos 9 /*!< SCB CCR: STKALIGN Position */ -#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ - -#define SCB_CCR_BFHFNMIGN_Pos 8 /*!< SCB CCR: BFHFNMIGN Position */ -#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ - -#define SCB_CCR_DIV_0_TRP_Pos 4 /*!< SCB CCR: DIV_0_TRP Position */ -#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ - -#define SCB_CCR_UNALIGN_TRP_Pos 3 /*!< SCB CCR: UNALIGN_TRP Position */ -#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ - -#define SCB_CCR_USERSETMPEND_Pos 1 /*!< SCB CCR: USERSETMPEND Position */ -#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ - -#define SCB_CCR_NONBASETHRDENA_Pos 0 /*!< SCB CCR: NONBASETHRDENA Position */ -#define SCB_CCR_NONBASETHRDENA_Msk (1UL /*<< SCB_CCR_NONBASETHRDENA_Pos*/) /*!< SCB CCR: NONBASETHRDENA Mask */ - -/* SCB System Handler Control and State Register Definitions */ -#define SCB_SHCSR_USGFAULTENA_Pos 18 /*!< SCB SHCSR: USGFAULTENA Position */ -#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ - -#define SCB_SHCSR_BUSFAULTENA_Pos 17 /*!< SCB SHCSR: BUSFAULTENA Position */ -#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ - -#define SCB_SHCSR_MEMFAULTENA_Pos 16 /*!< SCB SHCSR: MEMFAULTENA Position */ -#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ - -#define SCB_SHCSR_SVCALLPENDED_Pos 15 /*!< SCB SHCSR: SVCALLPENDED Position */ -#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ - -#define SCB_SHCSR_BUSFAULTPENDED_Pos 14 /*!< SCB SHCSR: BUSFAULTPENDED Position */ -#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ - -#define SCB_SHCSR_MEMFAULTPENDED_Pos 13 /*!< SCB SHCSR: MEMFAULTPENDED Position */ -#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ - -#define SCB_SHCSR_USGFAULTPENDED_Pos 12 /*!< SCB SHCSR: USGFAULTPENDED Position */ -#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ - -#define SCB_SHCSR_SYSTICKACT_Pos 11 /*!< SCB SHCSR: SYSTICKACT Position */ -#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ - -#define SCB_SHCSR_PENDSVACT_Pos 10 /*!< SCB SHCSR: PENDSVACT Position */ -#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ - -#define SCB_SHCSR_MONITORACT_Pos 8 /*!< SCB SHCSR: MONITORACT Position */ -#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ - -#define SCB_SHCSR_SVCALLACT_Pos 7 /*!< SCB SHCSR: SVCALLACT Position */ -#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ - -#define SCB_SHCSR_USGFAULTACT_Pos 3 /*!< SCB SHCSR: USGFAULTACT Position */ -#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ - -#define SCB_SHCSR_BUSFAULTACT_Pos 1 /*!< SCB SHCSR: BUSFAULTACT Position */ -#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ - -#define SCB_SHCSR_MEMFAULTACT_Pos 0 /*!< SCB SHCSR: MEMFAULTACT Position */ -#define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */ - -/* SCB Configurable Fault Status Registers Definitions */ -#define SCB_CFSR_USGFAULTSR_Pos 16 /*!< SCB CFSR: Usage Fault Status Register Position */ -#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ - -#define SCB_CFSR_BUSFAULTSR_Pos 8 /*!< SCB CFSR: Bus Fault Status Register Position */ -#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ - -#define SCB_CFSR_MEMFAULTSR_Pos 0 /*!< SCB CFSR: Memory Manage Fault Status Register Position */ -#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ - -/* SCB Hard Fault Status Registers Definitions */ -#define SCB_HFSR_DEBUGEVT_Pos 31 /*!< SCB HFSR: DEBUGEVT Position */ -#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ - -#define SCB_HFSR_FORCED_Pos 30 /*!< SCB HFSR: FORCED Position */ -#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ - -#define SCB_HFSR_VECTTBL_Pos 1 /*!< SCB HFSR: VECTTBL Position */ -#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ - -/* SCB Debug Fault Status Register Definitions */ -#define SCB_DFSR_EXTERNAL_Pos 4 /*!< SCB DFSR: EXTERNAL Position */ -#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ - -#define SCB_DFSR_VCATCH_Pos 3 /*!< SCB DFSR: VCATCH Position */ -#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ - -#define SCB_DFSR_DWTTRAP_Pos 2 /*!< SCB DFSR: DWTTRAP Position */ -#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ - -#define SCB_DFSR_BKPT_Pos 1 /*!< SCB DFSR: BKPT Position */ -#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ - -#define SCB_DFSR_HALTED_Pos 0 /*!< SCB DFSR: HALTED Position */ -#define SCB_DFSR_HALTED_Msk (1UL /*<< SCB_DFSR_HALTED_Pos*/) /*!< SCB DFSR: HALTED Mask */ - -/*@} end of group CMSIS_SCB */ - - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) - \brief Type definitions for the System Control and ID Register not in the SCB - @{ - */ - -/** \brief Structure type to access the System Control and ID Register not in the SCB. - */ -typedef struct -{ - uint32_t RESERVED0[1]; - __I uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ - uint32_t RESERVED1[1]; -} SCnSCB_Type; - -/* Interrupt Controller Type Register Definitions */ -#define SCnSCB_ICTR_INTLINESNUM_Pos 0 /*!< ICTR: INTLINESNUM Position */ -#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/) /*!< ICTR: INTLINESNUM Mask */ - -/*@} end of group CMSIS_SCnotSCB */ - - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_SysTick System Tick Timer (SysTick) - \brief Type definitions for the System Timer Registers. - @{ - */ - -/** \brief Structure type to access the System Timer (SysTick). - */ -typedef struct -{ - __IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ - __IO uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ - __IO uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ - __I uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ -} SysTick_Type; - -/* SysTick Control / Status Register Definitions */ -#define SysTick_CTRL_COUNTFLAG_Pos 16 /*!< SysTick CTRL: COUNTFLAG Position */ -#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ - -#define SysTick_CTRL_CLKSOURCE_Pos 2 /*!< SysTick CTRL: CLKSOURCE Position */ -#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ - -#define SysTick_CTRL_TICKINT_Pos 1 /*!< SysTick CTRL: TICKINT Position */ -#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ - -#define SysTick_CTRL_ENABLE_Pos 0 /*!< SysTick CTRL: ENABLE Position */ -#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ - -/* SysTick Reload Register Definitions */ -#define SysTick_LOAD_RELOAD_Pos 0 /*!< SysTick LOAD: RELOAD Position */ -#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ - -/* SysTick Current Register Definitions */ -#define SysTick_VAL_CURRENT_Pos 0 /*!< SysTick VAL: CURRENT Position */ -#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ - -/* SysTick Calibration Register Definitions */ -#define SysTick_CALIB_NOREF_Pos 31 /*!< SysTick CALIB: NOREF Position */ -#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ - -#define SysTick_CALIB_SKEW_Pos 30 /*!< SysTick CALIB: SKEW Position */ -#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ - -#define SysTick_CALIB_TENMS_Pos 0 /*!< SysTick CALIB: TENMS Position */ -#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ - -/*@} end of group CMSIS_SysTick */ - - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) - \brief Type definitions for the Instrumentation Trace Macrocell (ITM) - @{ - */ - -/** \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). - */ -typedef struct -{ - __O union - { - __O uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ - __O uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ - __O uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ - } PORT [32]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ - uint32_t RESERVED0[864]; - __IO uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ - uint32_t RESERVED1[15]; - __IO uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ - uint32_t RESERVED2[15]; - __IO uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ - uint32_t RESERVED3[29]; - __O uint32_t IWR; /*!< Offset: 0xEF8 ( /W) ITM Integration Write Register */ - __I uint32_t IRR; /*!< Offset: 0xEFC (R/ ) ITM Integration Read Register */ - __IO uint32_t IMCR; /*!< Offset: 0xF00 (R/W) ITM Integration Mode Control Register */ - uint32_t RESERVED4[43]; - __O uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ - __I uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ - uint32_t RESERVED5[6]; - __I uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ - __I uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ - __I uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ - __I uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ - __I uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ - __I uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ - __I uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ - __I uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ - __I uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ - __I uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ - __I uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ - __I uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ -} ITM_Type; - -/* ITM Trace Privilege Register Definitions */ -#define ITM_TPR_PRIVMASK_Pos 0 /*!< ITM TPR: PRIVMASK Position */ -#define ITM_TPR_PRIVMASK_Msk (0xFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ - -/* ITM Trace Control Register Definitions */ -#define ITM_TCR_BUSY_Pos 23 /*!< ITM TCR: BUSY Position */ -#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ - -#define ITM_TCR_TraceBusID_Pos 16 /*!< ITM TCR: ATBID Position */ -#define ITM_TCR_TraceBusID_Msk (0x7FUL << ITM_TCR_TraceBusID_Pos) /*!< ITM TCR: ATBID Mask */ - -#define ITM_TCR_GTSFREQ_Pos 10 /*!< ITM TCR: Global timestamp frequency Position */ -#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ - -#define ITM_TCR_TSPrescale_Pos 8 /*!< ITM TCR: TSPrescale Position */ -#define ITM_TCR_TSPrescale_Msk (3UL << ITM_TCR_TSPrescale_Pos) /*!< ITM TCR: TSPrescale Mask */ - -#define ITM_TCR_SWOENA_Pos 4 /*!< ITM TCR: SWOENA Position */ -#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ - -#define ITM_TCR_DWTENA_Pos 3 /*!< ITM TCR: DWTENA Position */ -#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ - -#define ITM_TCR_SYNCENA_Pos 2 /*!< ITM TCR: SYNCENA Position */ -#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ - -#define ITM_TCR_TSENA_Pos 1 /*!< ITM TCR: TSENA Position */ -#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ - -#define ITM_TCR_ITMENA_Pos 0 /*!< ITM TCR: ITM Enable bit Position */ -#define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */ - -/* ITM Integration Write Register Definitions */ -#define ITM_IWR_ATVALIDM_Pos 0 /*!< ITM IWR: ATVALIDM Position */ -#define ITM_IWR_ATVALIDM_Msk (1UL /*<< ITM_IWR_ATVALIDM_Pos*/) /*!< ITM IWR: ATVALIDM Mask */ - -/* ITM Integration Read Register Definitions */ -#define ITM_IRR_ATREADYM_Pos 0 /*!< ITM IRR: ATREADYM Position */ -#define ITM_IRR_ATREADYM_Msk (1UL /*<< ITM_IRR_ATREADYM_Pos*/) /*!< ITM IRR: ATREADYM Mask */ - -/* ITM Integration Mode Control Register Definitions */ -#define ITM_IMCR_INTEGRATION_Pos 0 /*!< ITM IMCR: INTEGRATION Position */ -#define ITM_IMCR_INTEGRATION_Msk (1UL /*<< ITM_IMCR_INTEGRATION_Pos*/) /*!< ITM IMCR: INTEGRATION Mask */ - -/* ITM Lock Status Register Definitions */ -#define ITM_LSR_ByteAcc_Pos 2 /*!< ITM LSR: ByteAcc Position */ -#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ - -#define ITM_LSR_Access_Pos 1 /*!< ITM LSR: Access Position */ -#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ - -#define ITM_LSR_Present_Pos 0 /*!< ITM LSR: Present Position */ -#define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */ - -/*@}*/ /* end of group CMSIS_ITM */ - - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) - \brief Type definitions for the Data Watchpoint and Trace (DWT) - @{ - */ - -/** \brief Structure type to access the Data Watchpoint and Trace Register (DWT). - */ -typedef struct -{ - __IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ - __IO uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ - __IO uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ - __IO uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ - __IO uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ - __IO uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ - __IO uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ - __I uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ - __IO uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ - __IO uint32_t MASK0; /*!< Offset: 0x024 (R/W) Mask Register 0 */ - __IO uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ - uint32_t RESERVED0[1]; - __IO uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ - __IO uint32_t MASK1; /*!< Offset: 0x034 (R/W) Mask Register 1 */ - __IO uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ - uint32_t RESERVED1[1]; - __IO uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ - __IO uint32_t MASK2; /*!< Offset: 0x044 (R/W) Mask Register 2 */ - __IO uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ - uint32_t RESERVED2[1]; - __IO uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ - __IO uint32_t MASK3; /*!< Offset: 0x054 (R/W) Mask Register 3 */ - __IO uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ -} DWT_Type; - -/* DWT Control Register Definitions */ -#define DWT_CTRL_NUMCOMP_Pos 28 /*!< DWT CTRL: NUMCOMP Position */ -#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ - -#define DWT_CTRL_NOTRCPKT_Pos 27 /*!< DWT CTRL: NOTRCPKT Position */ -#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ - -#define DWT_CTRL_NOEXTTRIG_Pos 26 /*!< DWT CTRL: NOEXTTRIG Position */ -#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ - -#define DWT_CTRL_NOCYCCNT_Pos 25 /*!< DWT CTRL: NOCYCCNT Position */ -#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ - -#define DWT_CTRL_NOPRFCNT_Pos 24 /*!< DWT CTRL: NOPRFCNT Position */ -#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ - -#define DWT_CTRL_CYCEVTENA_Pos 22 /*!< DWT CTRL: CYCEVTENA Position */ -#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ - -#define DWT_CTRL_FOLDEVTENA_Pos 21 /*!< DWT CTRL: FOLDEVTENA Position */ -#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ - -#define DWT_CTRL_LSUEVTENA_Pos 20 /*!< DWT CTRL: LSUEVTENA Position */ -#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ - -#define DWT_CTRL_SLEEPEVTENA_Pos 19 /*!< DWT CTRL: SLEEPEVTENA Position */ -#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ - -#define DWT_CTRL_EXCEVTENA_Pos 18 /*!< DWT CTRL: EXCEVTENA Position */ -#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ - -#define DWT_CTRL_CPIEVTENA_Pos 17 /*!< DWT CTRL: CPIEVTENA Position */ -#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ - -#define DWT_CTRL_EXCTRCENA_Pos 16 /*!< DWT CTRL: EXCTRCENA Position */ -#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ - -#define DWT_CTRL_PCSAMPLENA_Pos 12 /*!< DWT CTRL: PCSAMPLENA Position */ -#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ - -#define DWT_CTRL_SYNCTAP_Pos 10 /*!< DWT CTRL: SYNCTAP Position */ -#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ - -#define DWT_CTRL_CYCTAP_Pos 9 /*!< DWT CTRL: CYCTAP Position */ -#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ - -#define DWT_CTRL_POSTINIT_Pos 5 /*!< DWT CTRL: POSTINIT Position */ -#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ - -#define DWT_CTRL_POSTPRESET_Pos 1 /*!< DWT CTRL: POSTPRESET Position */ -#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ - -#define DWT_CTRL_CYCCNTENA_Pos 0 /*!< DWT CTRL: CYCCNTENA Position */ -#define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */ - -/* DWT CPI Count Register Definitions */ -#define DWT_CPICNT_CPICNT_Pos 0 /*!< DWT CPICNT: CPICNT Position */ -#define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */ - -/* DWT Exception Overhead Count Register Definitions */ -#define DWT_EXCCNT_EXCCNT_Pos 0 /*!< DWT EXCCNT: EXCCNT Position */ -#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */ - -/* DWT Sleep Count Register Definitions */ -#define DWT_SLEEPCNT_SLEEPCNT_Pos 0 /*!< DWT SLEEPCNT: SLEEPCNT Position */ -#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ - -/* DWT LSU Count Register Definitions */ -#define DWT_LSUCNT_LSUCNT_Pos 0 /*!< DWT LSUCNT: LSUCNT Position */ -#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */ - -/* DWT Folded-instruction Count Register Definitions */ -#define DWT_FOLDCNT_FOLDCNT_Pos 0 /*!< DWT FOLDCNT: FOLDCNT Position */ -#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */ - -/* DWT Comparator Mask Register Definitions */ -#define DWT_MASK_MASK_Pos 0 /*!< DWT MASK: MASK Position */ -#define DWT_MASK_MASK_Msk (0x1FUL /*<< DWT_MASK_MASK_Pos*/) /*!< DWT MASK: MASK Mask */ - -/* DWT Comparator Function Register Definitions */ -#define DWT_FUNCTION_MATCHED_Pos 24 /*!< DWT FUNCTION: MATCHED Position */ -#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ - -#define DWT_FUNCTION_DATAVADDR1_Pos 16 /*!< DWT FUNCTION: DATAVADDR1 Position */ -#define DWT_FUNCTION_DATAVADDR1_Msk (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos) /*!< DWT FUNCTION: DATAVADDR1 Mask */ - -#define DWT_FUNCTION_DATAVADDR0_Pos 12 /*!< DWT FUNCTION: DATAVADDR0 Position */ -#define DWT_FUNCTION_DATAVADDR0_Msk (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos) /*!< DWT FUNCTION: DATAVADDR0 Mask */ - -#define DWT_FUNCTION_DATAVSIZE_Pos 10 /*!< DWT FUNCTION: DATAVSIZE Position */ -#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ - -#define DWT_FUNCTION_LNK1ENA_Pos 9 /*!< DWT FUNCTION: LNK1ENA Position */ -#define DWT_FUNCTION_LNK1ENA_Msk (0x1UL << DWT_FUNCTION_LNK1ENA_Pos) /*!< DWT FUNCTION: LNK1ENA Mask */ - -#define DWT_FUNCTION_DATAVMATCH_Pos 8 /*!< DWT FUNCTION: DATAVMATCH Position */ -#define DWT_FUNCTION_DATAVMATCH_Msk (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos) /*!< DWT FUNCTION: DATAVMATCH Mask */ - -#define DWT_FUNCTION_CYCMATCH_Pos 7 /*!< DWT FUNCTION: CYCMATCH Position */ -#define DWT_FUNCTION_CYCMATCH_Msk (0x1UL << DWT_FUNCTION_CYCMATCH_Pos) /*!< DWT FUNCTION: CYCMATCH Mask */ - -#define DWT_FUNCTION_EMITRANGE_Pos 5 /*!< DWT FUNCTION: EMITRANGE Position */ -#define DWT_FUNCTION_EMITRANGE_Msk (0x1UL << DWT_FUNCTION_EMITRANGE_Pos) /*!< DWT FUNCTION: EMITRANGE Mask */ - -#define DWT_FUNCTION_FUNCTION_Pos 0 /*!< DWT FUNCTION: FUNCTION Position */ -#define DWT_FUNCTION_FUNCTION_Msk (0xFUL /*<< DWT_FUNCTION_FUNCTION_Pos*/) /*!< DWT FUNCTION: FUNCTION Mask */ - -/*@}*/ /* end of group CMSIS_DWT */ - - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_TPI Trace Port Interface (TPI) - \brief Type definitions for the Trace Port Interface (TPI) - @{ - */ - -/** \brief Structure type to access the Trace Port Interface Register (TPI). - */ -typedef struct -{ - __IO uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ - __IO uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ - uint32_t RESERVED0[2]; - __IO uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ - uint32_t RESERVED1[55]; - __IO uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ - uint32_t RESERVED2[131]; - __I uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ - __IO uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ - __I uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ - uint32_t RESERVED3[759]; - __I uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER */ - __I uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ - __I uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ - uint32_t RESERVED4[1]; - __I uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */ - __I uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */ - __IO uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ - uint32_t RESERVED5[39]; - __IO uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ - __IO uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ - uint32_t RESERVED7[8]; - __I uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */ - __I uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */ -} TPI_Type; - -/* TPI Asynchronous Clock Prescaler Register Definitions */ -#define TPI_ACPR_PRESCALER_Pos 0 /*!< TPI ACPR: PRESCALER Position */ -#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< TPI ACPR: PRESCALER Mask */ - -/* TPI Selected Pin Protocol Register Definitions */ -#define TPI_SPPR_TXMODE_Pos 0 /*!< TPI SPPR: TXMODE Position */ -#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ - -/* TPI Formatter and Flush Status Register Definitions */ -#define TPI_FFSR_FtNonStop_Pos 3 /*!< TPI FFSR: FtNonStop Position */ -#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ - -#define TPI_FFSR_TCPresent_Pos 2 /*!< TPI FFSR: TCPresent Position */ -#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ - -#define TPI_FFSR_FtStopped_Pos 1 /*!< TPI FFSR: FtStopped Position */ -#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ - -#define TPI_FFSR_FlInProg_Pos 0 /*!< TPI FFSR: FlInProg Position */ -#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ - -/* TPI Formatter and Flush Control Register Definitions */ -#define TPI_FFCR_TrigIn_Pos 8 /*!< TPI FFCR: TrigIn Position */ -#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ - -#define TPI_FFCR_EnFCont_Pos 1 /*!< TPI FFCR: EnFCont Position */ -#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ - -/* TPI TRIGGER Register Definitions */ -#define TPI_TRIGGER_TRIGGER_Pos 0 /*!< TPI TRIGGER: TRIGGER Position */ -#define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */ - -/* TPI Integration ETM Data Register Definitions (FIFO0) */ -#define TPI_FIFO0_ITM_ATVALID_Pos 29 /*!< TPI FIFO0: ITM_ATVALID Position */ -#define TPI_FIFO0_ITM_ATVALID_Msk (0x3UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ - -#define TPI_FIFO0_ITM_bytecount_Pos 27 /*!< TPI FIFO0: ITM_bytecount Position */ -#define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */ - -#define TPI_FIFO0_ETM_ATVALID_Pos 26 /*!< TPI FIFO0: ETM_ATVALID Position */ -#define TPI_FIFO0_ETM_ATVALID_Msk (0x3UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ - -#define TPI_FIFO0_ETM_bytecount_Pos 24 /*!< TPI FIFO0: ETM_bytecount Position */ -#define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */ - -#define TPI_FIFO0_ETM2_Pos 16 /*!< TPI FIFO0: ETM2 Position */ -#define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */ - -#define TPI_FIFO0_ETM1_Pos 8 /*!< TPI FIFO0: ETM1 Position */ -#define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */ - -#define TPI_FIFO0_ETM0_Pos 0 /*!< TPI FIFO0: ETM0 Position */ -#define TPI_FIFO0_ETM0_Msk (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/) /*!< TPI FIFO0: ETM0 Mask */ - -/* TPI ITATBCTR2 Register Definitions */ -#define TPI_ITATBCTR2_ATREADY_Pos 0 /*!< TPI ITATBCTR2: ATREADY Position */ -#define TPI_ITATBCTR2_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY_Pos*/) /*!< TPI ITATBCTR2: ATREADY Mask */ - -/* TPI Integration ITM Data Register Definitions (FIFO1) */ -#define TPI_FIFO1_ITM_ATVALID_Pos 29 /*!< TPI FIFO1: ITM_ATVALID Position */ -#define TPI_FIFO1_ITM_ATVALID_Msk (0x3UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ - -#define TPI_FIFO1_ITM_bytecount_Pos 27 /*!< TPI FIFO1: ITM_bytecount Position */ -#define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */ - -#define TPI_FIFO1_ETM_ATVALID_Pos 26 /*!< TPI FIFO1: ETM_ATVALID Position */ -#define TPI_FIFO1_ETM_ATVALID_Msk (0x3UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ - -#define TPI_FIFO1_ETM_bytecount_Pos 24 /*!< TPI FIFO1: ETM_bytecount Position */ -#define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */ - -#define TPI_FIFO1_ITM2_Pos 16 /*!< TPI FIFO1: ITM2 Position */ -#define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */ - -#define TPI_FIFO1_ITM1_Pos 8 /*!< TPI FIFO1: ITM1 Position */ -#define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */ - -#define TPI_FIFO1_ITM0_Pos 0 /*!< TPI FIFO1: ITM0 Position */ -#define TPI_FIFO1_ITM0_Msk (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/) /*!< TPI FIFO1: ITM0 Mask */ - -/* TPI ITATBCTR0 Register Definitions */ -#define TPI_ITATBCTR0_ATREADY_Pos 0 /*!< TPI ITATBCTR0: ATREADY Position */ -#define TPI_ITATBCTR0_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY_Pos*/) /*!< TPI ITATBCTR0: ATREADY Mask */ - -/* TPI Integration Mode Control Register Definitions */ -#define TPI_ITCTRL_Mode_Pos 0 /*!< TPI ITCTRL: Mode Position */ -#define TPI_ITCTRL_Mode_Msk (0x1UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ - -/* TPI DEVID Register Definitions */ -#define TPI_DEVID_NRZVALID_Pos 11 /*!< TPI DEVID: NRZVALID Position */ -#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ - -#define TPI_DEVID_MANCVALID_Pos 10 /*!< TPI DEVID: MANCVALID Position */ -#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ - -#define TPI_DEVID_PTINVALID_Pos 9 /*!< TPI DEVID: PTINVALID Position */ -#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ - -#define TPI_DEVID_MinBufSz_Pos 6 /*!< TPI DEVID: MinBufSz Position */ -#define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */ - -#define TPI_DEVID_AsynClkIn_Pos 5 /*!< TPI DEVID: AsynClkIn Position */ -#define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */ - -#define TPI_DEVID_NrTraceInput_Pos 0 /*!< TPI DEVID: NrTraceInput Position */ -#define TPI_DEVID_NrTraceInput_Msk (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ - -/* TPI DEVTYPE Register Definitions */ -#define TPI_DEVTYPE_MajorType_Pos 4 /*!< TPI DEVTYPE: MajorType Position */ -#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ - -#define TPI_DEVTYPE_SubType_Pos 0 /*!< TPI DEVTYPE: SubType Position */ -#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ - -/*@}*/ /* end of group CMSIS_TPI */ - - -#if (__MPU_PRESENT == 1) -/** \ingroup CMSIS_core_register - \defgroup CMSIS_MPU Memory Protection Unit (MPU) - \brief Type definitions for the Memory Protection Unit (MPU) - @{ - */ - -/** \brief Structure type to access the Memory Protection Unit (MPU). - */ -typedef struct -{ - __I uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ - __IO uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ - __IO uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ - __IO uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ - __IO uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ - __IO uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Alias 1 Region Base Address Register */ - __IO uint32_t RASR_A1; /*!< Offset: 0x018 (R/W) MPU Alias 1 Region Attribute and Size Register */ - __IO uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Alias 2 Region Base Address Register */ - __IO uint32_t RASR_A2; /*!< Offset: 0x020 (R/W) MPU Alias 2 Region Attribute and Size Register */ - __IO uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Alias 3 Region Base Address Register */ - __IO uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */ -} MPU_Type; - -/* MPU Type Register */ -#define MPU_TYPE_IREGION_Pos 16 /*!< MPU TYPE: IREGION Position */ -#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ - -#define MPU_TYPE_DREGION_Pos 8 /*!< MPU TYPE: DREGION Position */ -#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ - -#define MPU_TYPE_SEPARATE_Pos 0 /*!< MPU TYPE: SEPARATE Position */ -#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ - -/* MPU Control Register */ -#define MPU_CTRL_PRIVDEFENA_Pos 2 /*!< MPU CTRL: PRIVDEFENA Position */ -#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ - -#define MPU_CTRL_HFNMIENA_Pos 1 /*!< MPU CTRL: HFNMIENA Position */ -#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ - -#define MPU_CTRL_ENABLE_Pos 0 /*!< MPU CTRL: ENABLE Position */ -#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ - -/* MPU Region Number Register */ -#define MPU_RNR_REGION_Pos 0 /*!< MPU RNR: REGION Position */ -#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ - -/* MPU Region Base Address Register */ -#define MPU_RBAR_ADDR_Pos 5 /*!< MPU RBAR: ADDR Position */ -#define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ - -#define MPU_RBAR_VALID_Pos 4 /*!< MPU RBAR: VALID Position */ -#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ - -#define MPU_RBAR_REGION_Pos 0 /*!< MPU RBAR: REGION Position */ -#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */ - -/* MPU Region Attribute and Size Register */ -#define MPU_RASR_ATTRS_Pos 16 /*!< MPU RASR: MPU Region Attribute field Position */ -#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ - -#define MPU_RASR_XN_Pos 28 /*!< MPU RASR: ATTRS.XN Position */ -#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ - -#define MPU_RASR_AP_Pos 24 /*!< MPU RASR: ATTRS.AP Position */ -#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ - -#define MPU_RASR_TEX_Pos 19 /*!< MPU RASR: ATTRS.TEX Position */ -#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ - -#define MPU_RASR_S_Pos 18 /*!< MPU RASR: ATTRS.S Position */ -#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ - -#define MPU_RASR_C_Pos 17 /*!< MPU RASR: ATTRS.C Position */ -#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ - -#define MPU_RASR_B_Pos 16 /*!< MPU RASR: ATTRS.B Position */ -#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ - -#define MPU_RASR_SRD_Pos 8 /*!< MPU RASR: Sub-Region Disable Position */ -#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ - -#define MPU_RASR_SIZE_Pos 1 /*!< MPU RASR: Region Size Field Position */ -#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ - -#define MPU_RASR_ENABLE_Pos 0 /*!< MPU RASR: Region enable bit Position */ -#define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */ - -/*@} end of group CMSIS_MPU */ -#endif - - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) - \brief Type definitions for the Core Debug Registers - @{ - */ - -/** \brief Structure type to access the Core Debug Register (CoreDebug). - */ -typedef struct -{ - __IO uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ - __O uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ - __IO uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ - __IO uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ -} CoreDebug_Type; - -/* Debug Halting Control and Status Register */ -#define CoreDebug_DHCSR_DBGKEY_Pos 16 /*!< CoreDebug DHCSR: DBGKEY Position */ -#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ - -#define CoreDebug_DHCSR_S_RESET_ST_Pos 25 /*!< CoreDebug DHCSR: S_RESET_ST Position */ -#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ - -#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24 /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ -#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ - -#define CoreDebug_DHCSR_S_LOCKUP_Pos 19 /*!< CoreDebug DHCSR: S_LOCKUP Position */ -#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ - -#define CoreDebug_DHCSR_S_SLEEP_Pos 18 /*!< CoreDebug DHCSR: S_SLEEP Position */ -#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ - -#define CoreDebug_DHCSR_S_HALT_Pos 17 /*!< CoreDebug DHCSR: S_HALT Position */ -#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ - -#define CoreDebug_DHCSR_S_REGRDY_Pos 16 /*!< CoreDebug DHCSR: S_REGRDY Position */ -#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ - -#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5 /*!< CoreDebug DHCSR: C_SNAPSTALL Position */ -#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */ - -#define CoreDebug_DHCSR_C_MASKINTS_Pos 3 /*!< CoreDebug DHCSR: C_MASKINTS Position */ -#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ - -#define CoreDebug_DHCSR_C_STEP_Pos 2 /*!< CoreDebug DHCSR: C_STEP Position */ -#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ - -#define CoreDebug_DHCSR_C_HALT_Pos 1 /*!< CoreDebug DHCSR: C_HALT Position */ -#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ - -#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0 /*!< CoreDebug DHCSR: C_DEBUGEN Position */ -#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ - -/* Debug Core Register Selector Register */ -#define CoreDebug_DCRSR_REGWnR_Pos 16 /*!< CoreDebug DCRSR: REGWnR Position */ -#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ - -#define CoreDebug_DCRSR_REGSEL_Pos 0 /*!< CoreDebug DCRSR: REGSEL Position */ -#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< CoreDebug DCRSR: REGSEL Mask */ - -/* Debug Exception and Monitor Control Register */ -#define CoreDebug_DEMCR_TRCENA_Pos 24 /*!< CoreDebug DEMCR: TRCENA Position */ -#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ - -#define CoreDebug_DEMCR_MON_REQ_Pos 19 /*!< CoreDebug DEMCR: MON_REQ Position */ -#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */ - -#define CoreDebug_DEMCR_MON_STEP_Pos 18 /*!< CoreDebug DEMCR: MON_STEP Position */ -#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */ - -#define CoreDebug_DEMCR_MON_PEND_Pos 17 /*!< CoreDebug DEMCR: MON_PEND Position */ -#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */ - -#define CoreDebug_DEMCR_MON_EN_Pos 16 /*!< CoreDebug DEMCR: MON_EN Position */ -#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */ - -#define CoreDebug_DEMCR_VC_HARDERR_Pos 10 /*!< CoreDebug DEMCR: VC_HARDERR Position */ -#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ - -#define CoreDebug_DEMCR_VC_INTERR_Pos 9 /*!< CoreDebug DEMCR: VC_INTERR Position */ -#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */ - -#define CoreDebug_DEMCR_VC_BUSERR_Pos 8 /*!< CoreDebug DEMCR: VC_BUSERR Position */ -#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */ - -#define CoreDebug_DEMCR_VC_STATERR_Pos 7 /*!< CoreDebug DEMCR: VC_STATERR Position */ -#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */ - -#define CoreDebug_DEMCR_VC_CHKERR_Pos 6 /*!< CoreDebug DEMCR: VC_CHKERR Position */ -#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */ - -#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5 /*!< CoreDebug DEMCR: VC_NOCPERR Position */ -#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */ - -#define CoreDebug_DEMCR_VC_MMERR_Pos 4 /*!< CoreDebug DEMCR: VC_MMERR Position */ -#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */ - -#define CoreDebug_DEMCR_VC_CORERESET_Pos 0 /*!< CoreDebug DEMCR: VC_CORERESET Position */ -#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ - -/*@} end of group CMSIS_CoreDebug */ - - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_core_base Core Definitions - \brief Definitions for base addresses, unions, and structures. - @{ - */ - -/* Memory mapping of Cortex-M3 Hardware */ -#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ -#define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ -#define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ -#define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ -#define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ -#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ -#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ -#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ - -#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ -#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ -#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ -#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ -#define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ -#define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ -#define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ -#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */ - -#if (__MPU_PRESENT == 1) - #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ - #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ -#endif - -/*@} */ - - - -/******************************************************************************* - * Hardware Abstraction Layer - Core Function Interface contains: - - Core NVIC Functions - - Core SysTick Functions - - Core Debug Functions - - Core Register Access Functions - ******************************************************************************/ -/** \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference -*/ - - - -/* ########################## NVIC functions #################################### */ -/** \ingroup CMSIS_Core_FunctionInterface - \defgroup CMSIS_Core_NVICFunctions NVIC Functions - \brief Functions that manage interrupts and exceptions via the NVIC. - @{ - */ - -/** \brief Set Priority Grouping - - The function sets the priority grouping field using the required unlock sequence. - The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. - Only values from 0..7 are used. - In case of a conflict between priority grouping and available - priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. - - \param [in] PriorityGroup Priority grouping field. - */ -__STATIC_INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup) -{ - uint32_t reg_value; - uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ - - reg_value = SCB->AIRCR; /* read old register configuration */ - reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ - reg_value = (reg_value | - ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | - (PriorityGroupTmp << 8) ); /* Insert write key and priorty group */ - SCB->AIRCR = reg_value; -} - - -/** \brief Get Priority Grouping - - The function reads the priority grouping field from the NVIC Interrupt Controller. - - \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). - */ -__STATIC_INLINE uint32_t NVIC_GetPriorityGrouping(void) -{ - return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); -} - - -/** \brief Enable External Interrupt - - The function enables a device-specific interrupt in the NVIC interrupt controller. - - \param [in] IRQn External interrupt number. Value cannot be negative. - */ -__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn) -{ - NVIC->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); -} - - -/** \brief Disable External Interrupt - - The function disables a device-specific interrupt in the NVIC interrupt controller. - - \param [in] IRQn External interrupt number. Value cannot be negative. - */ -__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn) -{ - NVIC->ICER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); - __DSB(); - __ISB(); -} - - -/** \brief Get Pending Interrupt - - The function reads the pending register in the NVIC and returns the pending bit - for the specified interrupt. - - \param [in] IRQn Interrupt number. - - \return 0 Interrupt status is not pending. - \return 1 Interrupt status is pending. - */ -__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn) -{ - return((uint32_t)(((NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); -} - - -/** \brief Set Pending Interrupt - - The function sets the pending bit of an external interrupt. - - \param [in] IRQn Interrupt number. Value cannot be negative. - */ -__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn) -{ - NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); -} - - -/** \brief Clear Pending Interrupt - - The function clears the pending bit of an external interrupt. - - \param [in] IRQn External interrupt number. Value cannot be negative. - */ -__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn) -{ - NVIC->ICPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); -} - - -/** \brief Get Active Interrupt - - The function reads the active register in NVIC and returns the active bit. - - \param [in] IRQn Interrupt number. - - \return 0 Interrupt status is not active. - \return 1 Interrupt status is active. - */ -__STATIC_INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn) -{ - return((uint32_t)(((NVIC->IABR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); -} - - -/** \brief Set Interrupt Priority - - The function sets the priority of an interrupt. - - \note The priority cannot be set for every core interrupt. - - \param [in] IRQn Interrupt number. - \param [in] priority Priority to set. - */ -__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) -{ - if((int32_t)IRQn < 0) { - SCB->SHP[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8 - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); - } - else { - NVIC->IP[((uint32_t)(int32_t)IRQn)] = (uint8_t)((priority << (8 - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); - } -} - - -/** \brief Get Interrupt Priority - - The function reads the priority of an interrupt. The interrupt - number can be positive to specify an external (device specific) - interrupt, or negative to specify an internal (core) interrupt. - - - \param [in] IRQn Interrupt number. - \return Interrupt Priority. Value is aligned automatically to the implemented - priority bits of the microcontroller. - */ -__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn) -{ - - if((int32_t)IRQn < 0) { - return(((uint32_t)SCB->SHP[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] >> (8 - __NVIC_PRIO_BITS))); - } - else { - return(((uint32_t)NVIC->IP[((uint32_t)(int32_t)IRQn)] >> (8 - __NVIC_PRIO_BITS))); - } -} - - -/** \brief Encode Priority - - The function encodes the priority for an interrupt with the given priority group, - preemptive priority value, and subpriority value. - In case of a conflict between priority grouping and available - priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. - - \param [in] PriorityGroup Used priority group. - \param [in] PreemptPriority Preemptive priority value (starting from 0). - \param [in] SubPriority Subpriority value (starting from 0). - \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). - */ -__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) -{ - uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ - uint32_t PreemptPriorityBits; - uint32_t SubPriorityBits; - - PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); - SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); - - return ( - ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | - ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) - ); -} - - -/** \brief Decode Priority - - The function decodes an interrupt priority value with a given priority group to - preemptive priority value and subpriority value. - In case of a conflict between priority grouping and available - priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. - - \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). - \param [in] PriorityGroup Used priority group. - \param [out] pPreemptPriority Preemptive priority value (starting from 0). - \param [out] pSubPriority Subpriority value (starting from 0). - */ -__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* pPreemptPriority, uint32_t* pSubPriority) -{ - uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ - uint32_t PreemptPriorityBits; - uint32_t SubPriorityBits; - - PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); - SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); - - *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); - *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); -} - - -/** \brief System Reset - - The function initiates a system reset request to reset the MCU. - */ -__STATIC_INLINE void NVIC_SystemReset(void) -{ - __DSB(); /* Ensure all outstanding memory accesses included - buffered write are completed before reset */ - SCB->AIRCR = (uint32_t)((0x5FAUL << 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) { __NOP(); } /* wait until reset */ -} - -/*@} end of CMSIS_Core_NVICFunctions */ - - - -/* ################################## SysTick function ############################################ */ -/** \ingroup CMSIS_Core_FunctionInterface - \defgroup CMSIS_Core_SysTickFunctions SysTick Functions - \brief Functions that configure the System. - @{ - */ - -#if (__Vendor_SysTickConfig == 0) - -/** \brief System Tick Configuration - - The function initializes the System Timer and its interrupt, and starts the System Tick Timer. - Counter is in free running mode to generate periodic interrupts. - - \param [in] ticks Number of ticks between two interrupts. - - \return 0 Function succeeded. - \return 1 Function failed. - - \note When the variable __Vendor_SysTickConfig is set to 1, then the - function SysTick_Config is not included. In this case, the file device.h - must contain a vendor-specific implementation of this function. - - */ -__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) -{ - if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) { return (1UL); } /* Reload value impossible */ - - SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ - NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ - SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ - SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | - SysTick_CTRL_TICKINT_Msk | - SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ - return (0UL); /* Function successful */ -} - -#endif - -/*@} end of CMSIS_Core_SysTickFunctions */ - - - -/* ##################################### Debug In/Output function ########################################### */ -/** \ingroup CMSIS_Core_FunctionInterface - \defgroup CMSIS_core_DebugFunctions ITM Functions - \brief Functions that access the ITM debug interface. - @{ - */ - -extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ -#define ITM_RXBUFFER_EMPTY 0x5AA55AA5 /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ - - -/** \brief ITM Send Character - - The function transmits a character via the ITM channel 0, and - \li Just returns when no debugger is connected that has booked the output. - \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. - - \param [in] ch Character to transmit. - - \returns Character to transmit. - */ -__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) -{ - if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ - ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */ - { - while (ITM->PORT[0].u32 == 0UL) { __NOP(); } - ITM->PORT[0].u8 = (uint8_t)ch; - } - return (ch); -} - - -/** \brief ITM Receive Character - - The function inputs a character via the external variable \ref ITM_RxBuffer. - - \return Received character. - \return -1 No character pending. - */ -__STATIC_INLINE int32_t ITM_ReceiveChar (void) { - int32_t ch = -1; /* no character available */ - - if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) { - ch = ITM_RxBuffer; - ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ - } - - return (ch); -} - - -/** \brief ITM Check Character - - The function checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. - - \return 0 No character available. - \return 1 Character available. - */ -__STATIC_INLINE int32_t ITM_CheckChar (void) { - - if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) { - return (0); /* no character available */ - } else { - return (1); /* character available */ - } -} - -/*@} end of CMSIS_core_DebugFunctions */ - - - - -#ifdef __cplusplus -} -#endif - -#endif /* __CORE_SC300_H_DEPENDANT */ - -#endif /* __CMSIS_GENERIC */ diff --git a/rtos/rtx/TARGET_CORTEX_M/HAL_CM.c b/rtos/rtx/TARGET_CORTEX_M/HAL_CM.c deleted file mode 100644 index d423085e3d7..00000000000 --- a/rtos/rtx/TARGET_CORTEX_M/HAL_CM.c +++ /dev/null @@ -1,180 +0,0 @@ -/*---------------------------------------------------------------------------- - * CMSIS-RTOS - RTX - *---------------------------------------------------------------------------- - * Name: HAL_CM.C - * Purpose: Hardware Abstraction Layer for Cortex-M - * Rev.: V4.79 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -#include "rt_TypeDef.h" -#include "RTX_Config.h" -#include "rt_HAL_CM.h" -#include "cmsis_os.h" - -/*---------------------------------------------------------------------------- - * Global Variables - *---------------------------------------------------------------------------*/ - -#ifdef DBG_MSG -BIT dbg_msg; -#endif - -/*---------------------------------------------------------------------------- - * Functions - *---------------------------------------------------------------------------*/ - - -/*--------------------------- rt_init_stack ---------------------------------*/ - -void rt_init_stack (P_TCB p_TCB, FUNCP task_body) { - /* Prepare TCB and saved context for a first time start of a task. */ - U32 *stk,i,size; - - /* Prepare a complete interrupt frame for first task start */ - size = p_TCB->priv_stack >> 2; - if (size == 0U) { - size = (U16)os_stackinfo >> 2; - } - - /* Write to the top of stack. */ - stk = &p_TCB->stack[size]; - - /* Auto correct to 8-byte ARM stack alignment. */ - if ((U32)stk & 0x04U) { - stk--; - } - - stk -= 16; - - /* Default xPSR and initial PC */ - stk[15] = INITIAL_xPSR; - stk[14] = (U32)task_body; - - /* Clear R4-R11,R0-R3,R12,LR registers. */ - for (i = 0U; i < 14U; i++) { - stk[i] = 0U; - } - - /* Assign a void pointer to R0. */ - stk[8] = (U32)p_TCB->msg; - - /* Initial Task stack pointer. */ - p_TCB->tsk_stack = (U32)stk; - - /* Task entry point. */ - p_TCB->ptask = task_body; - - /* Initialize stack with magic pattern. */ - if (os_stackinfo & 0x10000000U) { - if (size > (16U+1U)) { - for (i = ((size - 16U)/2U) - 1U; i; i--) { - stk -= 2U; - stk[1] = MAGIC_PATTERN; - stk[0] = MAGIC_PATTERN; - } - if (--stk > p_TCB->stack) { - *stk = MAGIC_PATTERN; - } - } - } - - /* Set a magic word for checking of stack overflow. */ - p_TCB->stack[0] = MAGIC_WORD; -} - - -/*--------------------------- rt_ret_val ----------------------------------*/ - -static __inline U32 *rt_ret_regs (P_TCB p_TCB) { - /* Get pointer to task return value registers (R0..R3) in Stack */ -#if defined(__TARGET_FPU_VFP) - if (p_TCB->stack_frame) { - /* Extended Stack Frame: R4-R11,S16-S31,R0-R3,R12,LR,PC,xPSR,S0-S15,FPSCR */ - return (U32 *)(p_TCB->tsk_stack + (8U*4U) + (16U*4U)); - } else { - /* Basic Stack Frame: R4-R11,R0-R3,R12,LR,PC,xPSR */ - return (U32 *)(p_TCB->tsk_stack + (8U*4U)); - } -#else - /* Stack Frame: R4-R11,R0-R3,R12,LR,PC,xPSR */ - return (U32 *)(p_TCB->tsk_stack + (8U*4U)); -#endif -} - -void rt_ret_val (P_TCB p_TCB, U32 v0) { - U32 *ret; - - ret = rt_ret_regs(p_TCB); - ret[0] = v0; -} - -void rt_ret_val2(P_TCB p_TCB, U32 v0, U32 v1) { - U32 *ret; - - ret = rt_ret_regs(p_TCB); - ret[0] = v0; - ret[1] = v1; -} - - -/*--------------------------- dbg_init --------------------------------------*/ - -#ifdef DBG_MSG -void dbg_init (void) { - if (((DEMCR & DEMCR_TRCENA) != 0U) && - ((ITM_CONTROL & ITM_ITMENA) != 0U) && - ((ITM_ENABLE & (1UL << 31)) != 0U)) { - dbg_msg = __TRUE; - } -} -#endif - -/*--------------------------- dbg_task_notify -------------------------------*/ - -#ifdef DBG_MSG -void dbg_task_notify (P_TCB p_tcb, BOOL create) { - while (ITM_PORT31_U32 == 0U); - ITM_PORT31_U32 = (U32)p_tcb->ptask; - while (ITM_PORT31_U32 == 0U); - ITM_PORT31_U16 = (U16)((create << 8) | p_tcb->task_id); -} -#endif - -/*--------------------------- dbg_task_switch -------------------------------*/ - -#ifdef DBG_MSG -void dbg_task_switch (U32 task_id) { - while (ITM_PORT31_U32 == 0U); - ITM_PORT31_U8 = (U8)task_id; -} -#endif - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ diff --git a/rtos/rtx/TARGET_CORTEX_M/RTX_CM_lib.h b/rtos/rtx/TARGET_CORTEX_M/RTX_CM_lib.h deleted file mode 100644 index b96ef812c30..00000000000 --- a/rtos/rtx/TARGET_CORTEX_M/RTX_CM_lib.h +++ /dev/null @@ -1,698 +0,0 @@ - -/** \addtogroup rtos */ -/** @{*/ -/*---------------------------------------------------------------------------- - * CMSIS-RTOS - RTX - *---------------------------------------------------------------------------- - * Name: RTX_CM_LIB.H - * Purpose: RTX Kernel System Configuration - * Rev.: V4.79 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ -#include "mbed_error.h" - -#if defined (__CC_ARM) -#include -#pragma O3 -#define __USED __attribute__((used)) -#elif defined (__GNUC__) -#pragma GCC optimize ("O3") -#define __USED __attribute__((used)) -#elif defined (__ICCARM__) -#define __USED __root -#endif - - -/*---------------------------------------------------------------------------- - * Definitions - *---------------------------------------------------------------------------*/ - -#define _declare_box(pool,size,cnt) uint32_t pool[(((size)+3)/4)*(cnt) + 3] -#define _declare_box8(pool,size,cnt) uint64_t pool[(((size)+7)/8)*(cnt) + 2] - -#define OS_TCB_SIZE 64 -#define OS_TMR_SIZE 8 - -typedef void *OS_ID; -typedef uint32_t OS_TID; -typedef uint32_t OS_MUT[4]; -typedef uint32_t OS_RESULT; - -#if defined (__CC_ARM) && !defined (__MICROLIB) - -#define runtask_id() rt_tsk_self() -#define mutex_init(m) rt_mut_init(m) -#define mutex_wait(m) os_mut_wait(m,0xFFFFU) -#define mutex_rel(m) os_mut_release(m) - -extern uint8_t os_running; -extern OS_TID rt_tsk_self (void); -extern void rt_mut_init (OS_ID mutex); -extern OS_RESULT rt_mut_release (OS_ID mutex); -extern OS_RESULT rt_mut_wait (OS_ID mutex, uint16_t timeout); - -#define os_mut_wait(mutex,timeout) _os_mut_wait((uint32_t)rt_mut_wait,mutex,timeout) -#define os_mut_release(mutex) _os_mut_release((uint32_t)rt_mut_release,mutex) - -OS_RESULT _os_mut_release (uint32_t p, OS_ID mutex) __svc_indirect(0); -OS_RESULT _os_mut_wait (uint32_t p, OS_ID mutex, uint16_t timeout) __svc_indirect(0); - -#endif - - -/*---------------------------------------------------------------------------- - * Global Variables - *---------------------------------------------------------------------------*/ - -#if (OS_TASKCNT == 0) -#error "Invalid number of concurrent running threads!" -#endif - -#if (OS_PRIVCNT >= OS_TASKCNT) -#error "Too many threads with user-provided stack size!" -#endif - -#if (OS_TIMERS != 0) -#define OS_TASK_CNT (OS_TASKCNT + 1) -#ifndef __MBED_CMSIS_RTOS_CM -#define OS_PRIV_CNT (OS_PRIVCNT + 2) -#define OS_STACK_SZ (4*(OS_PRIVSTKSIZE+OS_MAINSTKSIZE+OS_TIMERSTKSZ)) -#endif -#else -#define OS_TASK_CNT OS_TASKCNT -#ifndef __MBED_CMSIS_RTOS_CM -#define OS_PRIV_CNT (OS_PRIVCNT + 1) -#define OS_STACK_SZ (4*(OS_PRIVSTKSIZE+OS_MAINSTKSIZE)) -#endif -#endif - -#ifndef OS_STKINIT -#define OS_STKINIT 0 -#endif - -uint16_t const os_maxtaskrun = OS_TASK_CNT; -#ifdef __MBED_CMSIS_RTOS_CM -uint32_t const os_stackinfo = (OS_STKINIT<<28) | (OS_STKCHECK<<24) | (OS_IDLESTKSIZE*4); -#else -uint32_t const os_stackinfo = (OS_STKINIT<<28) | (OS_STKCHECK<<24) | (OS_PRIV_CNT<<16) | (OS_STKSIZE*4); -#endif -uint32_t const os_rrobin = (OS_ROBIN << 16) | OS_ROBINTOUT; -uint32_t const os_tickfreq = OS_CLOCK; -uint16_t const os_tickus_i = OS_CLOCK/1000000; -uint16_t const os_tickus_f = (((uint64_t)(OS_CLOCK-1000000*(OS_CLOCK/1000000)))<<16)/1000000; -uint32_t const os_trv = OS_TRV; -#if defined(FEATURE_UVISOR) && defined(TARGET_UVISOR_SUPPORTED) -uint8_t const os_flags = 0; -#else /* defined(FEATURE_UVISOR) && defined(TARGET_UVISOR_SUPPORTED) */ -uint8_t const os_flags = OS_RUNPRIV; -#endif /* defined(FEATURE_UVISOR) && defined(TARGET_UVISOR_SUPPORTED) */ - -/* Export following defines to uVision debugger. */ -__USED uint32_t const CMSIS_RTOS_API_Version = osCMSIS; -__USED uint32_t const CMSIS_RTOS_RTX_Version = osCMSIS_RTX; -__USED uint32_t const os_clockrate = OS_TICK; -__USED uint32_t const os_timernum = 0U; - -/* Memory pool for TCB allocation */ -_declare_box (mp_tcb, OS_TCB_SIZE, OS_TASK_CNT); -uint16_t const mp_tcb_size = sizeof(mp_tcb); - -#ifdef __MBED_CMSIS_RTOS_CM -/* Memory pool for os_idle_demon stack allocation. */ -_declare_box8 (mp_stk, OS_IDLESTKSIZE*4, 1); -uint32_t const mp_stk_size = sizeof(mp_stk); -#else -/* Memory pool for System stack allocation (+os_idle_demon). */ -_declare_box8 (mp_stk, OS_STKSIZE*4, OS_TASK_CNT-OS_PRIV_CNT+1); -uint32_t const mp_stk_size = sizeof(mp_stk); - -/* Memory pool for user specified stack allocation (+main, +timer) */ -uint64_t os_stack_mem[2+OS_PRIV_CNT+(OS_STACK_SZ/8)]; -uint32_t const os_stack_sz = sizeof(os_stack_mem); -#endif - -#ifndef OS_FIFOSZ - #define OS_FIFOSZ 16 -#endif - -/* Fifo Queue buffer for ISR requests.*/ -uint32_t os_fifo[OS_FIFOSZ*2+1]; -uint8_t const os_fifo_size = OS_FIFOSZ; - -/* An array of Active task pointers. */ -void *os_active_TCB[OS_TASK_CNT]; - -/* User Timers Resources */ -#if (OS_TIMERS != 0) -extern void osTimerThread (void const *argument); -#ifdef __MBED_CMSIS_RTOS_CM -osThreadDef(osTimerThread, (osPriority)(OS_TIMERPRIO-3), 4*OS_TIMERSTKSZ); -#else -osThreadDef(osTimerThread, (osPriority)(OS_TIMERPRIO-3), 1, 4*OS_TIMERSTKSZ); -#endif -osThreadId osThreadId_osTimerThread; -osMessageQDef(osTimerMessageQ, OS_TIMERCBQS, void *); -osMessageQId osMessageQId_osTimerMessageQ; -#else -osThreadDef_t os_thread_def_osTimerThread = { NULL }; -osThreadId osThreadId_osTimerThread; -osMessageQDef(osTimerMessageQ, 0U, void *); -osMessageQId osMessageQId_osTimerMessageQ; -#endif - -/* Legacy RTX User Timers not used */ -uint32_t os_tmr = 0U; -uint32_t const *m_tmr = NULL; -uint16_t const mp_tmr_size = 0U; - -/* singleton mutex */ -osMutexId singleton_mutex_id; -osMutexDef(singleton_mutex); - -#if defined (__CC_ARM) && !defined (__MICROLIB) - /* A memory space for arm standard library. */ - static uint32_t std_libspace[OS_TASK_CNT][96/4]; - static OS_MUT std_libmutex[OS_MUTEXCNT]; - static uint32_t nr_mutex; - extern void *__libspace_start; -#endif - -#if defined (__ICCARM__) -static osMutexId std_mutex_id_sys[_MAX_LOCK] = {0}; -static OS_MUT std_mutex_sys[_MAX_LOCK] = {0}; -#define _FOPEN_MAX 10 -static osMutexId std_mutex_id_file[_FOPEN_MAX] = {0}; -static OS_MUT std_mutex_file[_FOPEN_MAX] = {0}; -void __iar_system_Mtxinit(__iar_Rmtx *mutex) /* Initialize a system lock */ -{ - osMutexDef_t def; - uint32_t index; - for (index = 0; index < _MAX_LOCK; index++) { - if (0 == std_mutex_id_sys[index]) { - def.mutex = &std_mutex_sys[index]; - std_mutex_id_sys[index] = osMutexCreate(&def); - *mutex = (__iar_Rmtx*)&std_mutex_id_sys[index]; - return; - } - } - // This should never happen - error("Not enough mutexes\n"); -} - -void __iar_system_Mtxdst(__iar_Rmtx *mutex)/*Destroy a system lock */ -{ - osMutexDelete(*(osMutexId*)*mutex); - *mutex = 0; -} - -void __iar_system_Mtxlock(__iar_Rmtx *mutex) /* Lock a system lock */ -{ - osMutexWait(*(osMutexId*)*mutex, osWaitForever); -} - -void __iar_system_Mtxunlock(__iar_Rmtx *mutex) /* Unlock a system lock */ -{ - osMutexRelease(*(osMutexId*)*mutex); -} - -void __iar_file_Mtxinit(__iar_Rmtx *mutex)/*Initialize a file lock */ -{ - osMutexDef_t def; - uint32_t index; - for (index = 0; index < _FOPEN_MAX; index++) { - if (0 == std_mutex_id_file[index]) { - def.mutex = &std_mutex_file[index]; - std_mutex_id_file[index] = osMutexCreate(&def); - *mutex = (__iar_Rmtx*)&std_mutex_id_file[index]; - return; - } - } - // The variable _FOPEN_MAX needs to be increased - error("Not enough mutexes\n"); -} - -void __iar_file_Mtxdst(__iar_Rmtx *mutex) /* Destroy a file lock */ -{ - osMutexDelete(*(osMutexId*)*mutex); - *mutex = 0; -} - -void __iar_file_Mtxlock(__iar_Rmtx *mutex) /* Lock a file lock */ -{ - osMutexWait(*(osMutexId*)*mutex, osWaitForever); -} - -void __iar_file_Mtxunlock(__iar_Rmtx *mutex) /* Unlock a file lock */ -{ - osMutexRelease(*(osMutexId*)*mutex); -} - -#endif - -/*---------------------------------------------------------------------------- - * RTX Optimizations (empty functions) - *---------------------------------------------------------------------------*/ - -#if OS_ROBIN == 0 - void rt_init_robin (void) {;} - void rt_chk_robin (void) {;} -#endif - -#if OS_STKCHECK == 0 - void rt_stk_check (void) {;} -#endif - - -/*---------------------------------------------------------------------------- - * Standard Library multithreading interface - *---------------------------------------------------------------------------*/ - -#if defined (__CC_ARM) && !defined (__MICROLIB) - -/*--------------------------- __user_perthread_libspace ---------------------*/ - -void *__user_perthread_libspace (void) { - /* Provide a separate libspace for each task. */ - uint32_t idx; - - idx = (os_running != 0U) ? runtask_id () : 0U; - if (idx == 0U) { - /* RTX not running yet. */ - return (&__libspace_start); - } - return ((void *)&std_libspace[idx-1]); -} - -/*--------------------------- _mutex_initialize -----------------------------*/ - -int _mutex_initialize (OS_ID *mutex) { - /* Allocate and initialize a system mutex. */ - - if (nr_mutex >= OS_MUTEXCNT) { - /* If you are here, you need to increase the number OS_MUTEXCNT. */ - error("Not enough stdlib mutexes\n"); - } - *mutex = &std_libmutex[nr_mutex++]; - mutex_init (*mutex); - return (1); -} - - -/*--------------------------- _mutex_acquire --------------------------------*/ - -__attribute__((used)) void _mutex_acquire (OS_ID *mutex) { - /* Acquire a system mutex, lock stdlib resources. */ - if (os_running) { - /* RTX running, acquire a mutex. */ - mutex_wait (*mutex); - } -} - - -/*--------------------------- _mutex_release --------------------------------*/ - -__attribute__((used)) void _mutex_release (OS_ID *mutex) { - /* Release a system mutex, unlock stdlib resources. */ - if (os_running) { - /* RTX running, release a mutex. */ - mutex_rel (*mutex); - } -} - -#endif - - -/*---------------------------------------------------------------------------- - * RTX Startup - *---------------------------------------------------------------------------*/ - -/* Main Thread definition */ -extern void pre_main (void); - -#if defined(TARGET_MCU_NRF51822) || defined(TARGET_MCU_NRF52832) || defined (TARGET_STM32F334R8) ||\ - defined(TARGET_STM32F070RB) || defined(TARGET_STM32F072RB) || \ - defined(TARGET_STM32F302R8) || defined(TARGET_STM32F303K8) || defined (TARGET_STM32F334C8) ||\ - defined(TARGET_STM32F103RB) -static uint32_t thread_stack_main[DEFAULT_STACK_SIZE / sizeof(uint32_t)]; -#elif defined(TARGET_XDOT_L151CC) -static uint32_t thread_stack_main[DEFAULT_STACK_SIZE * 6 / sizeof(uint32_t)]; -#else -static uint32_t thread_stack_main[DEFAULT_STACK_SIZE * 2 / sizeof(uint32_t)]; -#endif -osThreadDef_t os_thread_def_main = {(os_pthread)pre_main, osPriorityNormal, 1U, sizeof(thread_stack_main), thread_stack_main}; - -/* - * IAR Default Memory layout notes: - * -Heap defined by "HEAP" region in .icf file - * -Interrupt stack defined by "CSTACK" region in .icf file - * -Value INITIAL_SP is ignored - * - * IAR Custom Memory layout notes: - * -There is no custom layout available for IAR - everything must be defined in - * the .icf file and use the default layout - * - * - * GCC Default Memory layout notes: - * -Block of memory from symbol __end__ to define INITIAL_SP used to setup interrupt - * stack and heap in the function set_stack_heap() - * -ISR_STACK_SIZE can be overridden to be larger or smaller - * - * GCC Custom Memory layout notes: - * -Heap can be explicitly placed by defining both HEAP_START and HEAP_SIZE - * -Interrupt stack can be explicitly placed by defining both ISR_STACK_START and ISR_STACK_SIZE - * - * - * ARM Memory layout - * -Block of memory from end of region "RW_IRAM1" to define INITIAL_SP used to setup interrupt - * stack and heap in the function set_stack_heap() - * -ISR_STACK_SIZE can be overridden to be larger or smaller - * - * ARM Custom Memory layout notes: - * -Heap can be explicitly placed by defining both HEAP_START and HEAP_SIZE - * -Interrupt stack can be explicitly placed by defining both ISR_STACK_START and ISR_STACK_SIZE - * - */ - -extern unsigned char *mbed_heap_start; -extern uint32_t mbed_heap_size; - -unsigned char *mbed_stack_isr_start = 0; -uint32_t mbed_stack_isr_size = 0; - -/* - * Sanity check values - */ -#if defined(__ICCARM__) && \ - (defined(HEAP_START) || defined(HEAP_SIZE) || \ - defined(ISR_STACK_START) && defined(ISR_STACK_SIZE)) - #error "No custom layout allowed for IAR. Use .icf file instead" -#endif -#if defined(HEAP_START) && !defined(HEAP_SIZE) - #error "HEAP_SIZE must be defined if HEAP_START is defined" -#endif -#if defined(ISR_STACK_START) && !defined(ISR_STACK_SIZE) - #error "ISR_STACK_SIZE must be defined if ISR_STACK_START is defined" -#endif -#if defined(HEAP_SIZE) && !defined(HEAP_START) - #error "HEAP_START must be defined if HEAP_SIZE is defined" -#endif - -/* Interrupt stack and heap always defined for IAR - * Main thread defined here - */ -#if defined(__ICCARM__) - #pragma section="CSTACK" - #pragma section="HEAP" - #define HEAP_START ((unsigned char*)__section_begin("HEAP")) - #define HEAP_SIZE ((uint32_t)__section_size("HEAP")) - #define ISR_STACK_START ((unsigned char*)__section_begin("CSTACK")) - #define ISR_STACK_SIZE ((uint32_t)__section_size("CSTACK")) -#endif - -#if !defined(INITIAL_SP) && !defined(HEAP_START) - #error "no target defined" -#endif - -/* Define heap region if it has not been defined already */ -#if !defined(HEAP_START) - #if defined(__ICCARM__) - #error "Heap should already be defined for IAR" - #elif defined(__CC_ARM) - extern uint32_t Image$$RW_IRAM1$$ZI$$Limit[]; - #define HEAP_START ((unsigned char*)Image$$RW_IRAM1$$ZI$$Limit) - #define HEAP_SIZE ((uint32_t)((uint32_t)INITIAL_SP - (uint32_t)HEAP_START)) - #elif defined(__GNUC__) - extern uint32_t __end__[]; - #define HEAP_START ((unsigned char*)__end__) - #define HEAP_SIZE ((uint32_t)((uint32_t)INITIAL_SP - (uint32_t)HEAP_START)) - #endif -#endif - -/* Define stack sizes if they haven't been set already */ -#if !defined(ISR_STACK_SIZE) - #define ISR_STACK_SIZE ((uint32_t)OS_MAINSTKSIZE * 4) -#endif - -/* - * set_stack_heap purpose is to set the following variables: - * -mbed_heap_start - * -mbed_heap_size - * -mbed_stack_isr_start - * -mbed_stack_isr_size - * - * Along with setting up os_thread_def_main - */ -void set_stack_heap(void) { - - unsigned char *free_start = HEAP_START; - uint32_t free_size = HEAP_SIZE; - -#ifdef ISR_STACK_START - /* Interrupt stack explicitly specified */ - mbed_stack_isr_size = ISR_STACK_SIZE; - mbed_stack_isr_start = ISR_STACK_START; -#else - /* Interrupt stack - reserve space at the end of the free block */ - mbed_stack_isr_size = ISR_STACK_SIZE < free_size ? ISR_STACK_SIZE : free_size; - mbed_stack_isr_start = free_start + free_size - mbed_stack_isr_size; - free_size -= mbed_stack_isr_size; -#endif - - /* Heap - everything else */ - mbed_heap_size = free_size; - mbed_heap_start = free_start; -} - -#if defined (__CC_ARM) - -#ifdef __MICROLIB - -int main(void); -void _main_init (void) __attribute__((section(".ARM.Collect$$$$000000FF"))); -void $Super$$__cpp_initialize__aeabi_(void); - -void _main_init (void) { - osKernelInitialize(); -#ifdef __MBED_CMSIS_RTOS_CM - set_stack_heap(); -#endif - osThreadCreate(&os_thread_def_main, NULL); - osKernelStart(); - for (;;); -} - -void $Sub$$__cpp_initialize__aeabi_(void) -{ - // this should invoke C++ initializers prior _main_init, we keep this empty and - // invoke them after _main_init (=starts RTX kernel) -} - -void pre_main() -{ - singleton_mutex_id = osMutexCreate(osMutex(singleton_mutex)); - $Super$$__cpp_initialize__aeabi_(); - main(); -} - -#else - -int main(void); - -void pre_main (void) -{ - singleton_mutex_id = osMutexCreate(osMutex(singleton_mutex)); - __rt_lib_init((unsigned)mbed_heap_start, (unsigned)(mbed_heap_start + mbed_heap_size)); - main(); -} - -/* The single memory model is checking for stack collision at run time, verifing - that the heap pointer is underneath the stack pointer. - - With the RTOS there is not only one stack above the heap, there are multiple - stacks and some of them are underneath the heap pointer. -*/ -#pragma import(__use_two_region_memory) - -__asm void __rt_entry (void) { - - IMPORT __user_setup_stackheap - IMPORT _platform_post_stackheap_init - IMPORT os_thread_def_main - IMPORT osKernelInitialize -#ifdef __MBED_CMSIS_RTOS_CM - IMPORT set_stack_heap -#endif - IMPORT osKernelStart - IMPORT osThreadCreate - - /* __user_setup_stackheap returns: - * - Heap base in r0 (if the program uses the heap). - * - Stack base in sp. - * - Heap limit in r2 (if the program uses the heap and uses two-region memory). - * - * More info can be found in: - * ARM Compiler ARM C and C++ Libraries and Floating-Point Support User Guide - */ - BL __user_setup_stackheap - /* Ignore return value of __user_setup_stackheap since - * this will be setup by set_stack_heap - */ - BL _platform_post_stackheap_init - BL osKernelInitialize -#ifdef __MBED_CMSIS_RTOS_CM - BL set_stack_heap -#endif - LDR R0,=os_thread_def_main - MOVS R1,#0 - BL osThreadCreate - BL osKernelStart - /* osKernelStart should not return */ - B . - - ALIGN -} - -#endif - -#elif defined (__GNUC__) - -osMutexDef(malloc_mutex); -static osMutexId malloc_mutex_id; -osMutexDef(env_mutex); -static osMutexId env_mutex_id; - -extern int atexit(void (*func)(void)); -extern void __libc_fini_array(void); -extern void __libc_init_array (void); -extern int main(int argc, char **argv); - -void pre_main(void) { - singleton_mutex_id = osMutexCreate(osMutex(singleton_mutex)); - malloc_mutex_id = osMutexCreate(osMutex(malloc_mutex)); - env_mutex_id = osMutexCreate(osMutex(env_mutex)); - __libc_init_array(); - main(0, NULL); -} - -__attribute__((naked)) void software_init_hook_rtos (void) { - __asm ( - "bl osKernelInitialize\n" -#ifdef __MBED_CMSIS_RTOS_CM - "bl set_stack_heap\n" -#endif - "ldr r0,=os_thread_def_main\n" - "movs r1,#0\n" - "bl osThreadCreate\n" - "bl osKernelStart\n" - /* osKernelStart should not return */ - "B .\n" - ); -} - -// Opaque declaration of _reent structure -struct _reent; - -void __rtos_malloc_lock( struct _reent *_r ) -{ - osMutexWait(malloc_mutex_id, osWaitForever); -} - -void __rtos_malloc_unlock( struct _reent *_r ) -{ - osMutexRelease(malloc_mutex_id); -} - -void __rtos_env_lock( struct _reent *_r ) -{ - osMutexWait(env_mutex_id, osWaitForever); -} - -void __rtos_env_unlock( struct _reent *_r ) -{ - osMutexRelease(env_mutex_id); -} - -#elif defined (__ICCARM__) - -extern void* __vector_table; -extern int __low_level_init(void); -extern void __iar_data_init3(void); -extern __weak void __iar_init_core( void ); -extern __weak void __iar_init_vfp( void ); -extern void __iar_dynamic_initialization(void); -extern void mbed_sdk_init(void); -extern void mbed_main(void); -extern int main(void); -extern void exit(int arg); - -static uint8_t low_level_init_needed; - -void pre_main(void) { - singleton_mutex_id = osMutexCreate(osMutex(singleton_mutex)); - if (low_level_init_needed) { - __iar_dynamic_initialization(); - } - mbed_main(); - main(); -} - -#pragma required=__vector_table -void __iar_program_start( void ) -{ -#ifdef __MBED_CMSIS_RTOS_CM - __iar_init_core(); - __iar_init_vfp(); - - uint8_t low_level_init_needed_local; - - low_level_init_needed_local = __low_level_init(); - if (low_level_init_needed_local) { - __iar_data_init3(); - mbed_sdk_init(); - } - /* Store in a global variable after RAM has been initialized */ - low_level_init_needed = low_level_init_needed_local; -#endif - osKernelInitialize(); -#ifdef __MBED_CMSIS_RTOS_CM - set_stack_heap(); -#endif - osThreadCreate(&os_thread_def_main, NULL); - osKernelStart(); - /* osKernelStart should not return */ - while (1); -} - -#endif - - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ - -/** @}*/ diff --git a/rtos/rtx/TARGET_CORTEX_M/RTX_Conf_CM.c b/rtos/rtx/TARGET_CORTEX_M/RTX_Conf_CM.c deleted file mode 100755 index 206e6813c50..00000000000 --- a/rtos/rtx/TARGET_CORTEX_M/RTX_Conf_CM.c +++ /dev/null @@ -1,281 +0,0 @@ -/*---------------------------------------------------------------------------- - * CMSIS-RTOS - RTX - *---------------------------------------------------------------------------- - * Name: RTX_Conf_CM.C - * Purpose: Configuration of CMSIS RTX Kernel for Cortex-M - * Rev.: V4.70.1 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -#include "cmsis_os.h" -#include "mbed_error.h" - - -/*---------------------------------------------------------------------------- - * RTX User configuration part BEGIN - *---------------------------------------------------------------------------*/ - -// Include per-target RTX config file -#include "mbed_rtx.h" - -//-------- <<< Use Configuration Wizard in Context Menu >>> ----------------- -// -// Thread Configuration -// ======================= -// -// Number of concurrent running user threads <1-250> -// Defines max. number of user threads that will run at the same time. -// Default: 6 -#ifndef OS_TASKCNT - #error "no target defined" -#endif - -#ifdef __MBED_CMSIS_RTOS_CM -// Idle stack size [bytes] <64-4096:8><#/4> -// Defines default stack size for the Idle thread. -#ifndef OS_IDLESTKSIZE - #define OS_IDLESTKSIZE 128 -#endif -#else // __MBED_CMSIS_RTOS_CM -// Default Thread stack size [bytes] <64-4096:8><#/4> -// Defines default stack size for threads with osThreadDef stacksz = 0 -// Default: 200 -#ifndef OS_STKSIZE - #define OS_STKSIZE 200 -#endif -#endif // __MBED_CMSIS_RTOS_CM - -// Main Thread stack size [bytes] <64-32768:8><#/4> -#ifndef OS_MAINSTKSIZE - #error "no target defined" -#endif - -#ifndef __MBED_CMSIS_RTOS_CM -// Number of threads with user-provided stack size <0-250> -// Defines the number of threads with user-provided stack size. -// Default: 0 -#ifndef OS_PRIVCNT - #define OS_PRIVCNT 0 -#endif - -// Total stack size [bytes] for threads with user-provided stack size <0-1048576:8><#/4> -// Defines the combined stack size for threads with user-provided stack size. -// Default: 0 -#ifndef OS_PRIVSTKSIZE - #define OS_PRIVSTKSIZE 0 // this stack size value is in words -#endif -#endif // __MBED_CMSIS_RTOS_CM - -// Stack overflow checking -// Enable stack overflow checks at thread switch. -// Enabling this option increases slightly the execution time of a thread switch. -#ifndef OS_STKCHECK - #define OS_STKCHECK 1 -#endif - -// Stack usage watermark -// Initialize thread stack with watermark pattern for analyzing stack usage (current/maximum) in System and Thread Viewer. -// Enabling this option increases significantly the execution time of osThreadCreate. -#ifndef OS_STKINIT - #if (defined(MBED_STACK_STATS_ENABLED) && MBED_STACK_STATS_ENABLED) - #define OS_STKINIT 1 - #else - #define OS_STKINIT 0 - #endif -#endif - -// Processor mode for thread execution -// <0=> Unprivileged mode -// <1=> Privileged mode -// Default: Privileged mode -#ifndef OS_RUNPRIV - #define OS_RUNPRIV 1 -#endif - -// - -// RTX Kernel Timer Tick Configuration -// ====================================== -// Use Cortex-M SysTick timer as RTX Kernel Timer -// Cortex-M processors provide in most cases a SysTick timer that can be used as -// as time-base for RTX. -#ifndef OS_SYSTICK - #define OS_SYSTICK 1 -#endif -// -// RTOS Kernel Timer input clock frequency [Hz] <1-1000000000> -// Defines the input frequency of the RTOS Kernel Timer. -// When the Cortex-M SysTick timer is used, the input clock -// is on most systems identical with the core clock. -#ifndef OS_CLOCK - #error "no target defined" -#endif - -// RTX Timer tick interval value [us] <1-1000000> -// The RTX Timer tick interval value is used to calculate timeout values. -// When the Cortex-M SysTick timer is enabled, the value also configures the SysTick timer. -// Default: 1000 (1ms) -#ifndef OS_TICK - #define OS_TICK 1000 -#endif - -// - -// System Configuration -// ======================= -// -// Round-Robin Thread switching -// =============================== -// -// Enables Round-Robin Thread switching. -#ifndef OS_ROBIN - #define OS_ROBIN 1 -#endif - -// Round-Robin Timeout [ticks] <1-1000> -// Defines how long a thread will execute before a thread switch. -// Default: 5 -#ifndef OS_ROBINTOUT - #define OS_ROBINTOUT 5 -#endif - -// - -// User Timers -// ============== -// Enables user Timers -#ifndef OS_TIMERS - #define OS_TIMERS 1 -#endif - -// Timer Thread Priority -// <1=> Low -// <2=> Below Normal <3=> Normal <4=> Above Normal -// <5=> High -// <6=> Realtime (highest) -// Defines priority for Timer Thread -// Default: High -#ifndef OS_TIMERPRIO - #define OS_TIMERPRIO 5 -#endif - -// Timer Thread stack size [bytes] <64-4096:8><#/4> -// Defines stack size for Timer thread. -// Default: 200 -#ifndef OS_TIMERSTKSZ - #define OS_TIMERSTKSZ 200 -#endif - -// Timer Callback Queue size <1-32> -// Number of concurrent active timer callback functions. -// Default: 4 -#ifndef OS_TIMERCBQS - #define OS_TIMERCBQS 4 -#endif - -// - -// ISR FIFO Queue size<4=> 4 entries <8=> 8 entries -// <12=> 12 entries <16=> 16 entries -// <24=> 24 entries <32=> 32 entries -// <48=> 48 entries <64=> 64 entries -// <96=> 96 entries -// ISR functions store requests to this buffer, -// when they are called from the interrupt handler. -// Default: 16 entries -#ifndef OS_FIFOSZ - #define OS_FIFOSZ 16 -#endif - -// - -//------------- <<< end of configuration section >>> ----------------------- - -// Standard library system mutexes -// =============================== -// Define max. number system mutexes that are used to protect -// the arm standard runtime library. For microlib they are not used. -#ifndef OS_MUTEXCNT - #define OS_MUTEXCNT 12 -#endif - -/*---------------------------------------------------------------------------- - * RTX User configuration part END - *---------------------------------------------------------------------------*/ - -#define OS_TRV ((uint32_t)(((double)OS_CLOCK*(double)OS_TICK)/1E6)-1) - - -/*---------------------------------------------------------------------------- - * OS Idle daemon - *---------------------------------------------------------------------------*/ -extern void rtos_idle_loop(void); - -void os_idle_demon (void) { - /* The idle demon is a system thread, running when no other thread is */ - /* ready to run. */ - rtos_idle_loop(); -} - -/*---------------------------------------------------------------------------- - * RTX Errors - *---------------------------------------------------------------------------*/ -extern osThreadId svcThreadGetId (void); - -void os_error (uint32_t err_code) { - /* This function is called when a runtime error is detected. Parameter */ - /* 'err_code' holds the runtime error code (defined in RTX_Config.h). */ - osThreadId err_task = svcThreadGetId(); - error("RTX error code: 0x%08X, task ID: 0x%08X\n", err_code, err_task); -} - -void sysThreadError(osStatus status) { - if (status != osOK) { - osThreadId err_task = svcThreadGetId(); - error("CMSIS-RTOS error status: 0x%08X, task ID: 0x%08X\n", status, err_task); - } -} - -/*---------------------------------------------------------------------------- - * RTX Hooks - *---------------------------------------------------------------------------*/ -extern void thread_terminate_hook(osThreadId id); - -void sysThreadTerminate(osThreadId id) { - thread_terminate_hook(id); -} - -/*---------------------------------------------------------------------------- - * RTX Configuration Functions - *---------------------------------------------------------------------------*/ - -#include "RTX_CM_lib.h" - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ diff --git a/rtos/rtx/TARGET_CORTEX_M/RTX_Config.h b/rtos/rtx/TARGET_CORTEX_M/RTX_Config.h deleted file mode 100644 index 62a7b845485..00000000000 --- a/rtos/rtx/TARGET_CORTEX_M/RTX_Config.h +++ /dev/null @@ -1,84 +0,0 @@ - -/** \addtogroup rtos */ -/** @{*/ -/*---------------------------------------------------------------------------- - * CMSIS-RTOS - RTX - *---------------------------------------------------------------------------- - * Name: RTX_CONFIG.H - * Purpose: Exported functions of RTX_Config.c - * Rev.: V4.79 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - - -/* Error Codes */ -#define OS_ERR_STK_OVF 1U -#define OS_ERR_FIFO_OVF 2U -#define OS_ERR_MBX_OVF 3U -#define OS_ERR_TIMER_OVF 4U - -/* Definitions */ -#define BOX_ALIGN_8 0x80000000U -#define _declare_box(pool,size,cnt) U32 pool[(((size)+3)/4)*(cnt) + 3] -#define _declare_box8(pool,size,cnt) U64 pool[(((size)+7)/8)*(cnt) + 2] -#define _init_box8(pool,size,bsize) _init_box (pool,size,(bsize) | BOX_ALIGN_8) - -/* Variables */ -extern U32 mp_tcb[]; -extern U64 mp_stk[]; -extern U32 os_fifo[]; -extern void *os_active_TCB[]; - -/* Constants */ -extern U16 const os_maxtaskrun; -extern U32 const os_trv; -extern U8 const os_flags; -extern U32 const os_stackinfo; -extern U32 const os_rrobin; -extern U32 const os_clockrate; -extern U32 const os_timernum; -extern U16 const mp_tcb_size; -extern U32 const mp_stk_size; -extern U32 const *m_tmr; -extern U16 const mp_tmr_size; -extern U8 const os_fifo_size; - -/* Functions */ -extern void os_idle_demon (void); -extern S32 os_tick_init (void); -extern U32 os_tick_val (void); -extern U32 os_tick_ovf (void); -extern void os_tick_irqack (void); -extern void os_tmr_call (U16 info); -extern void os_error (U32 err_code); - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ - -/** @}*/ diff --git a/rtos/rtx/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_ARM/HAL_CM0.c b/rtos/rtx/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_ARM/HAL_CM0.c deleted file mode 100644 index 59351c2e23c..00000000000 --- a/rtos/rtx/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_ARM/HAL_CM0.c +++ /dev/null @@ -1,301 +0,0 @@ -/*---------------------------------------------------------------------------- - * CMSIS-RTOS - RTX - *---------------------------------------------------------------------------- - * Name: HAL_CM0.C - * Purpose: Hardware Abstraction Layer for Cortex-M0 - * Rev.: V4.70 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -#include "rt_TypeDef.h" -#include "RTX_Config.h" -#include "rt_System.h" -#include "rt_HAL_CM.h" -#include "rt_Task.h" -#include "rt_MemBox.h" - - -/*---------------------------------------------------------------------------- - * Functions - *---------------------------------------------------------------------------*/ - - -/*--------------------------- rt_set_PSP ------------------------------------*/ - -__asm void rt_set_PSP (U32 stack) { - MSR PSP,R0 - BX LR -} - - -/*--------------------------- rt_get_PSP ------------------------------------*/ - -__asm U32 rt_get_PSP (void) { - MRS R0,PSP - BX LR -} - - -/*--------------------------- os_set_env ------------------------------------*/ - -__asm void os_set_env (void) { - /* Switch to Unprivileged/Privileged Thread mode, use PSP. */ - MOV R0,SP ; PSP = MSP - MSR PSP,R0 - LDR R0,=__cpp(&os_flags) - LDRB R0,[R0] - LSLS R0,#31 - BNE PrivilegedE - MOVS R0,#0x03 ; Unprivileged Thread mode, use PSP - MSR CONTROL,R0 - BX LR -PrivilegedE - MOVS R0,#0x02 ; Privileged Thread mode, use PSP - MSR CONTROL,R0 - BX LR - - ALIGN -} - - -/*--------------------------- _alloc_box ------------------------------------*/ - -__asm void *_alloc_box (void *box_mem) { - /* Function wrapper for Unprivileged/Privileged mode. */ - LDR R3,=__cpp(rt_alloc_box) - MOV R12,R3 - MRS R3,IPSR - LSLS R3,#24 - BNE PrivilegedA - MRS R3,CONTROL - LSLS R3,#31 - BEQ PrivilegedA - SVC 0 - BX LR -PrivilegedA - BX R12 - - ALIGN -} - - -/*--------------------------- _free_box -------------------------------------*/ - -__asm U32 _free_box (void *box_mem, void *box) { - /* Function wrapper for Unprivileged/Privileged mode. */ - LDR R3,=__cpp(rt_free_box) - MOV R12,R3 - MRS R3,IPSR - LSLS R3,#24 - BNE PrivilegedF - MRS R3,CONTROL - LSLS R3,#31 - BEQ PrivilegedF - SVC 0 - BX LR -PrivilegedF - BX R12 - - ALIGN -} - - -/*-------------------------- SVC_Handler ------------------------------------*/ - -__asm void SVC_Handler (void) { - PRESERVE8 - - IMPORT SVC_Count - IMPORT SVC_Table - IMPORT rt_stk_check - - MRS R0,PSP ; Read PSP - LDR R1,[R0,#24] ; Read Saved PC from Stack - SUBS R1,R1,#2 ; Point to SVC Instruction - LDRB R1,[R1] ; Load SVC Number - CMP R1,#0 - BNE SVC_User ; User SVC Number > 0 - - MOV LR,R4 - LDMIA R0,{R0-R3,R4} ; Read R0-R3,R12 from stack - MOV R12,R4 - MOV R4,LR - BLX R12 ; Call SVC Function - - MRS R3,PSP ; Read PSP - STMIA R3!,{R0-R2} ; Store return values - - LDR R3,=__cpp(&os_tsk) - LDMIA R3!,{R1,R2} ; os_tsk.run, os_tsk.new - CMP R1,R2 - BEQ SVC_Exit ; no task switch - - SUBS R3,#8 - CMP R1,#0 ; Runtask deleted? - BEQ SVC_Next - - MRS R0,PSP ; Read PSP - SUBS R0,R0,#32 ; Adjust Start Address - STR R0,[R1,#TCB_TSTACK] ; Update os_tsk.run->tsk_stack - STMIA R0!,{R4-R7} ; Save old context (R4-R7) - MOV R4,R8 - MOV R5,R9 - MOV R6,R10 - MOV R7,R11 - STMIA R0!,{R4-R7} ; Save old context (R8-R11) - - PUSH {R2,R3} - BL rt_stk_check ; Check for Stack overflow - POP {R2,R3} - -SVC_Next - STR R2,[R3] ; os_tsk.run = os_tsk.new - - LDR R0,[R2,#TCB_TSTACK] ; os_tsk.new->tsk_stack - ADDS R0,R0,#16 ; Adjust Start Address - LDMIA R0!,{R4-R7} ; Restore new Context (R8-R11) - MOV R8,R4 - MOV R9,R5 - MOV R10,R6 - MOV R11,R7 - MSR PSP,R0 ; Write PSP - SUBS R0,R0,#32 ; Adjust Start Address - LDMIA R0!,{R4-R7} ; Restore new Context (R4-R7) - -SVC_Exit - MOVS R0,#:NOT:0xFFFFFFFD ; Set EXC_RETURN value - MVNS R0,R0 - BX R0 ; RETI to Thread Mode, use PSP - - /*------------------- User SVC ------------------------------*/ - -SVC_User - PUSH {R4,LR} ; Save Registers - LDR R2,=SVC_Count - LDR R2,[R2] - CMP R1,R2 - BHI SVC_Done ; Overflow - - LDR R4,=SVC_Table-4 - LSLS R1,R1,#2 - LDR R4,[R4,R1] ; Load SVC Function Address - MOV LR,R4 - - LDMIA R0,{R0-R3,R4} ; Read R0-R3,R12 from stack - MOV R12,R4 - BLX LR ; Call SVC Function - - MRS R4,PSP ; Read PSP - STMIA R4!,{R0-R3} ; Function return values -SVC_Done - POP {R4,PC} ; RETI - - ALIGN -} - - -/*-------------------------- PendSV_Handler ---------------------------------*/ - -__asm void PendSV_Handler (void) { - PRESERVE8 - - BL __cpp(rt_pop_req) - -Sys_Switch - LDR R3,=__cpp(&os_tsk) - LDMIA R3!,{R1,R2} ; os_tsk.run, os_tsk.new - CMP R1,R2 - BEQ Sys_Exit ; no task switch - - SUBS R3,#8 - - MRS R0,PSP ; Read PSP - SUBS R0,R0,#32 ; Adjust Start Address - STR R0,[R1,#TCB_TSTACK] ; Update os_tsk.run->tsk_stack - STMIA R0!,{R4-R7} ; Save old context (R4-R7) - MOV R4,R8 - MOV R5,R9 - MOV R6,R10 - MOV R7,R11 - STMIA R0!,{R4-R7} ; Save old context (R8-R11) - - PUSH {R2,R3} - BL rt_stk_check ; Check for Stack overflow - POP {R2,R3} - - STR R2,[R3] ; os_tsk.run = os_tsk.new - - LDR R0,[R2,#TCB_TSTACK] ; os_tsk.new->tsk_stack - ADDS R0,R0,#16 ; Adjust Start Address - LDMIA R0!,{R4-R7} ; Restore new Context (R8-R11) - MOV R8,R4 - MOV R9,R5 - MOV R10,R6 - MOV R11,R7 - MSR PSP,R0 ; Write PSP - SUBS R0,R0,#32 ; Adjust Start Address - LDMIA R0!,{R4-R7} ; Restore new Context (R4-R7) - -Sys_Exit - MOVS R0,#:NOT:0xFFFFFFFD ; Set EXC_RETURN value - MVNS R0,R0 - BX R0 ; RETI to Thread Mode, use PSP - - ALIGN -} - - -/*-------------------------- SysTick_Handler --------------------------------*/ - -__asm void SysTick_Handler (void) { - PRESERVE8 - - BL __cpp(rt_systick) - B Sys_Switch - - ALIGN -} - - -/*-------------------------- OS_Tick_Handler --------------------------------*/ - -__asm void OS_Tick_Handler (void) { - PRESERVE8 - - BL __cpp(os_tick_irqack) - BL __cpp(rt_systick) - B Sys_Switch - - ALIGN -} - - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ - diff --git a/rtos/rtx/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_ARM/SVC_Table.S b/rtos/rtx/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_ARM/SVC_Table.S deleted file mode 100644 index 3ba439bca83..00000000000 --- a/rtos/rtx/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_ARM/SVC_Table.S +++ /dev/null @@ -1,57 +0,0 @@ -;/*---------------------------------------------------------------------------- -; * CMSIS-RTOS - RTX -; *---------------------------------------------------------------------------- -; * Name: SVC_TABLE.S -; * Purpose: Pre-defined SVC Table for Cortex-M -; * Rev.: V4.70 -; *---------------------------------------------------------------------------- -; * -; * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH -; * All rights reserved. -; * Redistribution and use in source and binary forms, with or without -; * modification, are permitted provided that the following conditions are met: -; * - Redistributions of source code must retain the above copyright -; * notice, this list of conditions and the following disclaimer. -; * - Redistributions in binary form must reproduce the above copyright -; * notice, this list of conditions and the following disclaimer in the -; * documentation and/or other materials provided with the distribution. -; * - Neither the name of ARM nor the names of its contributors may be used -; * to endorse or promote products derived from this software without -; * specific prior written permission. -; * -; * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -; * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -; * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -; * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE -; * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -; * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -; * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -; * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -; * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -; * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -; * POSSIBILITY OF SUCH DAMAGE. -; *---------------------------------------------------------------------------*/ - - - AREA SVC_TABLE, CODE, READONLY - - EXPORT SVC_Count - -SVC_Cnt EQU (SVC_End-SVC_Table)/4 -SVC_Count DCD SVC_Cnt - -; Import user SVC functions here. -; IMPORT __SVC_1 - - EXPORT SVC_Table -SVC_Table -; Insert user SVC functions here. SVC 0 used by RTL Kernel. -; DCD __SVC_1 ; user SVC function - -SVC_End - - END - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ diff --git a/rtos/rtx/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_GCC/HAL_CM0.S b/rtos/rtx/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_GCC/HAL_CM0.S deleted file mode 100644 index a9f1ff17c09..00000000000 --- a/rtos/rtx/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_GCC/HAL_CM0.S +++ /dev/null @@ -1,370 +0,0 @@ -/*---------------------------------------------------------------------------- - * CMSIS-RTOS - RTX - *---------------------------------------------------------------------------- - * Name: HAL_CM0.S - * Purpose: Hardware Abstraction Layer for Cortex-M0 - * Rev.: V4.70 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - - .file "HAL_CM0.S" - .syntax unified - - .equ TCB_TSTACK, 44 - - -/*---------------------------------------------------------------------------- - * Functions - *---------------------------------------------------------------------------*/ - - .thumb - - .section ".text" - .align 2 - - -/*--------------------------- rt_set_PSP ------------------------------------*/ - -# void rt_set_PSP (U32 stack); - - .thumb_func - .type rt_set_PSP, %function - .global rt_set_PSP -rt_set_PSP: - .fnstart - .cantunwind - - MSR PSP,R0 - BX LR - - .fnend - .size rt_set_PSP, .-rt_set_PSP - - -/*--------------------------- rt_get_PSP ------------------------------------*/ - -# U32 rt_get_PSP (void); - - .thumb_func - .type rt_get_PSP, %function - .global rt_get_PSP -rt_get_PSP: - .fnstart - .cantunwind - - MRS R0,PSP - BX LR - - .fnend - .size rt_get_PSP, .-rt_get_PSP - - -/*--------------------------- os_set_env ------------------------------------*/ - -# void os_set_env (void); - /* Switch to Unprivileged/Privileged Thread mode, use PSP. */ - - .thumb_func - .type os_set_env, %function - .global os_set_env -os_set_env: - .fnstart - .cantunwind - - MOV R0,SP /* PSP = MSP */ - MSR PSP,R0 - LDR R0,=os_flags - LDRB R0,[R0] - LSLS R0,#31 - BNE PrivilegedE - MOVS R0,#0x03 /* Unprivileged Thread mode, use PSP */ - MSR CONTROL,R0 - BX LR -PrivilegedE: - MOVS R0,#0x02 /* Privileged Thread mode, use PSP */ - MSR CONTROL,R0 - BX LR - - .fnend - .size os_set_env, .-os_set_env - - -/*--------------------------- _alloc_box ------------------------------------*/ - -# void *_alloc_box (void *box_mem); - /* Function wrapper for Unprivileged/Privileged mode. */ - - .thumb_func - .type _alloc_box, %function - .global _alloc_box -_alloc_box: - .fnstart - .cantunwind - - LDR R3,=rt_alloc_box - MOV R12,R3 - MRS R3,IPSR - LSLS R3,#24 - BNE PrivilegedA - MRS R3,CONTROL - LSLS R3,#31 - BEQ PrivilegedA - SVC 0 - BX LR -PrivilegedA: - BX R12 - - .fnend - .size _alloc_box, .-_alloc_box - - -/*--------------------------- _free_box -------------------------------------*/ - -# U32 _free_box (void *box_mem, void *box); - /* Function wrapper for Unprivileged/Privileged mode. */ - - .thumb_func - .type _free_box, %function - .global _free_box -_free_box: - .fnstart - .cantunwind - - LDR R3,=rt_free_box - MOV R12,R3 - MRS R3,IPSR - LSLS R3,#24 - BNE PrivilegedF - MRS R3,CONTROL - LSLS R3,#31 - BEQ PrivilegedF - SVC 0 - BX LR -PrivilegedF: - BX R12 - - .fnend - .size _free_box, .-_free_box - - -/*-------------------------- SVC_Handler ------------------------------------*/ - -# void SVC_Handler (void); - - .thumb_func - .type SVC_Handler, %function - .global SVC_Handler -SVC_Handler: - .fnstart - .cantunwind - - MRS R0,PSP /* Read PSP */ - LDR R1,[R0,#24] /* Read Saved PC from Stack */ - SUBS R1,R1,#2 /* Point to SVC Instruction */ - LDRB R1,[R1] /* Load SVC Number */ - CMP R1,#0 - BNE SVC_User /* User SVC Number > 0 */ - - MOV LR,R4 - LDMIA R0,{R0-R3,R4} /* Read R0-R3,R12 from stack */ - MOV R12,R4 - MOV R4,LR - BLX R12 /* Call SVC Function */ - - MRS R3,PSP /* Read PSP */ - STMIA R3!,{R0-R2} /* Store return values */ - - LDR R3,=os_tsk - LDMIA R3!,{R1,R2} /* os_tsk.run, os_tsk.new */ - CMP R1,R2 - BEQ SVC_Exit /* no task switch */ - - SUBS R3,#8 - CMP R1,#0 /* Runtask deleted? */ - BEQ SVC_Next - - MRS R0,PSP /* Read PSP */ - SUBS R0,R0,#32 /* Adjust Start Address */ - STR R0,[R1,#TCB_TSTACK] /* Update os_tsk.run->tsk_stack */ - STMIA R0!,{R4-R7} /* Save old context (R4-R7) */ - MOV R4,R8 - MOV R5,R9 - MOV R6,R10 - MOV R7,R11 - STMIA R0!,{R4-R7} /* Save old context (R8-R11) */ - - PUSH {R2,R3} - BL rt_stk_check /* Check for Stack overflow */ - POP {R2,R3} - -SVC_Next: - STR R2,[R3] /* os_tsk.run = os_tsk.new */ - - LDR R0,[R2,#TCB_TSTACK] /* os_tsk.new->tsk_stack */ - ADDS R0,R0,#16 /* Adjust Start Address */ - LDMIA R0!,{R4-R7} /* Restore new Context (R8-R11) */ - MOV R8,R4 - MOV R9,R5 - MOV R10,R6 - MOV R11,R7 - MSR PSP,R0 /* Write PSP */ - SUBS R0,R0,#32 /* Adjust Start Address */ - LDMIA R0!,{R4-R7} /* Restore new Context (R4-R7) */ - -SVC_Exit: - MOVS R0,#~0xFFFFFFFD /* Set EXC_RETURN value */ - MVNS R0,R0 - BX R0 /* RETI to Thread Mode, use PSP */ - - /*------------------- User SVC ------------------------------*/ - -SVC_User: - PUSH {R4,LR} /* Save Registers */ - LDR R2,=SVC_Count - LDR R2,[R2] - CMP R1,R2 - BHI SVC_Done /* Overflow */ - - LDR R4,=SVC_Table-4 - LSLS R1,R1,#2 - LDR R4,[R4,R1] /* Load SVC Function Address */ - MOV LR,R4 - - LDMIA R0,{R0-R3,R4} /* Read R0-R3,R12 from stack */ - MOV R12,R4 - BLX LR /* Call SVC Function */ - - MRS R4,PSP /* Read PSP */ - STMIA R4!,{R0-R3} /* Function return values */ -SVC_Done: - POP {R4,PC} /* RETI */ - - .fnend - .size SVC_Handler, .-SVC_Handler - - -/*-------------------------- PendSV_Handler ---------------------------------*/ - -# void PendSV_Handler (void); - - .thumb_func - .type PendSV_Handler, %function - .global PendSV_Handler - .global Sys_Switch -PendSV_Handler: - .fnstart - .cantunwind - - BL rt_pop_req - -Sys_Switch: - LDR R3,=os_tsk - LDMIA R3!,{R1,R2} /* os_tsk.run, os_tsk.new */ - CMP R1,R2 - BEQ Sys_Exit /* no task switch */ - - SUBS R3,#8 - - MRS R0,PSP /* Read PSP */ - SUBS R0,R0,#32 /* Adjust Start Address */ - STR R0,[R1,#TCB_TSTACK] /* Update os_tsk.run->tsk_stack */ - STMIA R0!,{R4-R7} /* Save old context (R4-R7) */ - MOV R4,R8 - MOV R5,R9 - MOV R6,R10 - MOV R7,R11 - STMIA R0!,{R4-R7} /* Save old context (R8-R11) */ - - PUSH {R2,R3} - BL rt_stk_check /* Check for Stack overflow */ - POP {R2,R3} - - STR R2,[R3] /* os_tsk.run = os_tsk.new */ - - LDR R0,[R2,#TCB_TSTACK] /* os_tsk.new->tsk_stack */ - ADDS R0,R0,#16 /* Adjust Start Address */ - LDMIA R0!,{R4-R7} /* Restore new Context (R8-R11) */ - MOV R8,R4 - MOV R9,R5 - MOV R10,R6 - MOV R11,R7 - MSR PSP,R0 /* Write PSP */ - SUBS R0,R0,#32 /* Adjust Start Address */ - LDMIA R0!,{R4-R7} /* Restore new Context (R4-R7) */ - -Sys_Exit: - MOVS R0,#~0xFFFFFFFD /* Set EXC_RETURN value */ - MVNS R0,R0 - BX R0 /* RETI to Thread Mode, use PSP */ - - .fnend - .size PendSV_Handler, .-PendSV_Handler - - -/*-------------------------- SysTick_Handler --------------------------------*/ - -# void SysTick_Handler (void); - - .thumb_func - .type SysTick_Handler, %function - .global SysTick_Handler -SysTick_Handler: - .fnstart - .cantunwind - - BL rt_systick - B Sys_Switch - - .fnend - .size SysTick_Handler, .-SysTick_Handler - - -/*-------------------------- OS_Tick_Handler --------------------------------*/ - -# void OS_Tick_Handler (void); - - .thumb_func - .type OS_Tick_Handler, %function - .global OS_Tick_Handler -OS_Tick_Handler: - .fnstart - .cantunwind - - BL os_tick_irqack - BL rt_systick - B Sys_Switch - - .fnend - .size OS_Tick_Handler, .-OS_Tick_Handler - - - .end - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ diff --git a/rtos/rtx/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_GCC/SVC_Table.S b/rtos/rtx/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_GCC/SVC_Table.S deleted file mode 100644 index d583df13321..00000000000 --- a/rtos/rtx/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_GCC/SVC_Table.S +++ /dev/null @@ -1,56 +0,0 @@ -;/*---------------------------------------------------------------------------- -; * CMSIS-RTOS - RTX -; *---------------------------------------------------------------------------- -; * Name: SVC_TABLE.S -; * Purpose: Pre-defined SVC Table for Cortex-M -; * Rev.: V4.70 -; *---------------------------------------------------------------------------- -; * -; * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH -; * All rights reserved. -; * Redistribution and use in source and binary forms, with or without -; * modification, are permitted provided that the following conditions are met: -; * - Redistributions of source code must retain the above copyright -; * notice, this list of conditions and the following disclaimer. -; * - Redistributions in binary form must reproduce the above copyright -; * notice, this list of conditions and the following disclaimer in the -; * documentation and/or other materials provided with the distribution. -; * - Neither the name of ARM nor the names of its contributors may be used -; * to endorse or promote products derived from this software without -; * specific prior written permission. -; * -; * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -; * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -; * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -; * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE -; * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -; * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -; * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -; * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -; * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -; * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -; * POSSIBILITY OF SUCH DAMAGE. -; *---------------------------------------------------------------------------*/ - - - .file "SVC_Table.S" - - - .section ".svc_table" - - .global SVC_Table -SVC_Table: -/* Insert user SVC functions here. SVC 0 used by RTL Kernel. */ -# .long __SVC_1 /* user SVC function */ -SVC_End: - - .global SVC_Count -SVC_Count: - .long (SVC_End-SVC_Table)/4 - - - .end - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ diff --git a/rtos/rtx/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_IAR/HAL_CM0.S b/rtos/rtx/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_IAR/HAL_CM0.S deleted file mode 100644 index d0dc85374cd..00000000000 --- a/rtos/rtx/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_IAR/HAL_CM0.S +++ /dev/null @@ -1,312 +0,0 @@ -/*---------------------------------------------------------------------------- - * CMSIS-RTOS - RTX - *---------------------------------------------------------------------------- - * Name: HAL_CM0.S - * Purpose: Hardware Abstraction Layer for Cortex-M0 - * Rev.: V4.70 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - - NAME HAL_CM0.S - - #define TCB_TSTACK 44 - - EXTERN os_flags - EXTERN os_tsk - EXTERN rt_alloc_box - EXTERN rt_free_box - EXTERN rt_stk_check - EXTERN rt_pop_req - EXTERN rt_systick - EXTERN os_tick_irqack - EXTERN SVC_Table - EXTERN SVC_Count - -/*---------------------------------------------------------------------------- - * Functions - *---------------------------------------------------------------------------*/ - - SECTION .text:CODE:NOROOT(2) - THUMB - -/*--------------------------- rt_set_PSP ------------------------------------*/ - -; void rt_set_PSP (U32 stack); - - PUBLIC rt_set_PSP -rt_set_PSP: - - MSR PSP,R0 - BX LR - - -/*--------------------------- rt_get_PSP ------------------------------------*/ - -; U32 rt_get_PSP (void); - - PUBLIC rt_get_PSP -rt_get_PSP: - - MRS R0,PSP - BX LR - - -/*--------------------------- os_set_env ------------------------------------*/ - -; void os_set_env (void); - /* Switch to Unprivileged/Privileged Thread mode, use PSP. */ - - PUBLIC os_set_env -os_set_env: - - MOV R0,SP /* PSP = MSP */ - MSR PSP,R0 - LDR R0,=os_flags - LDRB R0,[R0] - LSLS R0,#31 - BNE PrivilegedE - MOVS R0,#0x03 /* Unprivileged Thread mode, use PSP */ - MSR CONTROL,R0 - BX LR -PrivilegedE: - MOVS R0,#0x02 /* Privileged Thread mode, use PSP */ - MSR CONTROL,R0 - BX LR - - -/*--------------------------- _alloc_box ------------------------------------*/ - -; void *_alloc_box (void *box_mem); - /* Function wrapper for Unprivileged/Privileged mode. */ - - PUBLIC _alloc_box -_alloc_box: - - LDR R3,=rt_alloc_box - MOV R12,R3 - MRS R3,IPSR - LSLS R3,#24 - BNE PrivilegedA - MRS R3,CONTROL - LSLS R3,#31 - BEQ PrivilegedA - SVC 0 - BX LR -PrivilegedA: - BX R12 - - -/*--------------------------- _free_box -------------------------------------*/ - -; U32 _free_box (void *box_mem, void *box); - /* Function wrapper for Unprivileged/Privileged mode. */ - - PUBLIC _free_box -_free_box: - - LDR R3,=rt_free_box - MOV R12,R3 - MRS R3,IPSR - LSLS R3,#24 - BNE PrivilegedF - MRS R3,CONTROL - LSLS R3,#31 - BEQ PrivilegedF - SVC 0 - BX LR -PrivilegedF: - BX R12 - - -/*-------------------------- SVC_Handler ------------------------------------*/ - -; void SVC_Handler (void); - - PUBLIC SVC_Handler -SVC_Handler: - - MRS R0,PSP /* Read PSP */ - LDR R1,[R0,#24] /* Read Saved PC from Stack */ - SUBS R1,R1,#2 /* Point to SVC Instruction */ - LDRB R1,[R1] /* Load SVC Number */ - CMP R1,#0 - BNE SVC_User /* User SVC Number > 0 */ - - MOV LR,R4 - LDMIA R0,{R0-R3,R4} /* Read R0-R3,R12 from stack */ - MOV R12,R4 - MOV R4,LR - BLX R12 /* Call SVC Function */ - - MRS R3,PSP /* Read PSP */ - STMIA R3!,{R0-R2} /* Store return values */ - - LDR R3,=os_tsk - LDMIA R3!,{R1,R2} /* os_tsk.run, os_tsk.new */ - CMP R1,R2 - BEQ SVC_Exit /* no task switch */ - - SUBS R3,#8 - CMP R1,#0 /* Runtask deleted? */ - BEQ SVC_Next - - MRS R0,PSP /* Read PSP */ - SUBS R0,R0,#32 /* Adjust Start Address */ - STR R0,[R1,#TCB_TSTACK] /* Update os_tsk.run->tsk_stack */ - STMIA R0!,{R4-R7} /* Save old context (R4-R7) */ - MOV R4,R8 - MOV R5,R9 - MOV R6,R10 - MOV R7,R11 - STMIA R0!,{R4-R7} /* Save old context (R8-R11) */ - - PUSH {R2,R3} - BL rt_stk_check /* Check for Stack overflow */ - POP {R2,R3} - -SVC_Next: - STR R2,[R3] /* os_tsk.run = os_tsk.new */ - - LDR R0,[R2,#TCB_TSTACK] /* os_tsk.new->tsk_stack */ - ADDS R0,R0,#16 /* Adjust Start Address */ - LDMIA R0!,{R4-R7} /* Restore new Context (R8-R11) */ - MOV R8,R4 - MOV R9,R5 - MOV R10,R6 - MOV R11,R7 - MSR PSP,R0 /* Write PSP */ - SUBS R0,R0,#32 /* Adjust Start Address */ - LDMIA R0!,{R4-R7} /* Restore new Context (R4-R7) */ - -SVC_Exit: - MOVS R0,#~0xFFFFFFFD /* Set EXC_RETURN value */ - MVNS R0,R0 - BX R0 /* RETI to Thread Mode, use PSP */ - - /*------------------- User SVC ------------------------------*/ - -SVC_User: - PUSH {R4,LR} /* Save Registers */ - LDR R2,=SVC_Count - LDR R2,[R2] - CMP R1,R2 - BHI SVC_Done /* Overflow */ - - LDR R4,=SVC_Table-4 - LSLS R1,R1,#2 - LDR R4,[R4,R1] /* Load SVC Function Address */ - MOV LR,R4 - - LDMIA R0,{R0-R3,R4} /* Read R0-R3,R12 from stack */ - MOV R12,R4 - BLX LR /* Call SVC Function */ - - MRS R4,PSP /* Read PSP */ - STMIA R4!,{R0-R3} /* Function return values */ -SVC_Done: - POP {R4,PC} /* RETI */ - - -/*-------------------------- PendSV_Handler ---------------------------------*/ - -; void PendSV_Handler (void); - - PUBLIC PendSV_Handler -PendSV_Handler: - - BL rt_pop_req - -Sys_Switch: - LDR R3,=os_tsk - LDMIA R3!,{R1,R2} /* os_tsk.run, os_tsk.new */ - CMP R1,R2 - BEQ Sys_Exit /* no task switch */ - - SUBS R3,#8 - - MRS R0,PSP /* Read PSP */ - SUBS R0,R0,#32 /* Adjust Start Address */ - STR R0,[R1,#TCB_TSTACK] /* Update os_tsk.run->tsk_stack */ - STMIA R0!,{R4-R7} /* Save old context (R4-R7) */ - MOV R4,R8 - MOV R5,R9 - MOV R6,R10 - MOV R7,R11 - STMIA R0!,{R4-R7} /* Save old context (R8-R11) */ - - PUSH {R2,R3} - BL rt_stk_check /* Check for Stack overflow */ - POP {R2,R3} - - STR R2,[R3] /* os_tsk.run = os_tsk.new */ - - LDR R0,[R2,#TCB_TSTACK] /* os_tsk.new->tsk_stack */ - ADDS R0,R0,#16 /* Adjust Start Address */ - LDMIA R0!,{R4-R7} /* Restore new Context (R8-R11) */ - MOV R8,R4 - MOV R9,R5 - MOV R10,R6 - MOV R11,R7 - MSR PSP,R0 /* Write PSP */ - SUBS R0,R0,#32 /* Adjust Start Address */ - LDMIA R0!,{R4-R7} /* Restore new Context (R4-R7) */ - -Sys_Exit: - MOVS R0,#~0xFFFFFFFD /* Set EXC_RETURN value */ - MVNS R0,R0 - BX R0 /* RETI to Thread Mode, use PSP */ - - -/*-------------------------- SysTick_Handler --------------------------------*/ - -; void SysTick_Handler (void); - - PUBLIC SysTick_Handler -SysTick_Handler: - - BL rt_systick - B Sys_Switch - - -/*-------------------------- OS_Tick_Handler --------------------------------*/ - -; void OS_Tick_Handler (void); - - PUBLIC OS_Tick_Handler -OS_Tick_Handler: - - BL os_tick_irqack - BL rt_systick - B Sys_Switch - - - END - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ diff --git a/rtos/rtx/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_IAR/SVC_Table.S b/rtos/rtx/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_IAR/SVC_Table.S deleted file mode 100644 index 18710cb2d11..00000000000 --- a/rtos/rtx/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_IAR/SVC_Table.S +++ /dev/null @@ -1,58 +0,0 @@ -;/*---------------------------------------------------------------------------- -; * CMSIS-RTOS - RTX -; *---------------------------------------------------------------------------- -; * Name: SVC_TABLE.S -; * Purpose: Pre-defined SVC Table for Cortex-M -; * Rev.: V4.70 -; *---------------------------------------------------------------------------- -; * -; * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH -; * All rights reserved. -; * Redistribution and use in source and binary forms, with or without -; * modification, are permitted provided that the following conditions are met: -; * - Redistributions of source code must retain the above copyright -; * notice, this list of conditions and the following disclaimer. -; * - Redistributions in binary form must reproduce the above copyright -; * notice, this list of conditions and the following disclaimer in the -; * documentation and/or other materials provided with the distribution. -; * - Neither the name of ARM nor the names of its contributors may be used -; * to endorse or promote products derived from this software without -; * specific prior written permission. -; * -; * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -; * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -; * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -; * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE -; * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -; * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -; * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -; * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -; * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -; * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -; * POSSIBILITY OF SUCH DAMAGE. -; *---------------------------------------------------------------------------*/ - - - NAME SVC_TABLE - SECTION .text:CONST (2) - - PUBLIC SVC_Count - -SVC_Cnt EQU (SVC_End-SVC_Table)/4 -SVC_Count DCD SVC_Cnt - -; Import user SVC functions here. -; IMPORT __SVC_1 - - PUBLIC SVC_Table -SVC_Table -; Insert user SVC functions here. SVC 0 used by RTL Kernel. -; DCD __SVC_1 ; user SVC function - -SVC_End - - END - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ diff --git a/rtos/rtx/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_ARM/HAL_CM0.c b/rtos/rtx/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_ARM/HAL_CM0.c deleted file mode 100644 index 59351c2e23c..00000000000 --- a/rtos/rtx/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_ARM/HAL_CM0.c +++ /dev/null @@ -1,301 +0,0 @@ -/*---------------------------------------------------------------------------- - * CMSIS-RTOS - RTX - *---------------------------------------------------------------------------- - * Name: HAL_CM0.C - * Purpose: Hardware Abstraction Layer for Cortex-M0 - * Rev.: V4.70 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -#include "rt_TypeDef.h" -#include "RTX_Config.h" -#include "rt_System.h" -#include "rt_HAL_CM.h" -#include "rt_Task.h" -#include "rt_MemBox.h" - - -/*---------------------------------------------------------------------------- - * Functions - *---------------------------------------------------------------------------*/ - - -/*--------------------------- rt_set_PSP ------------------------------------*/ - -__asm void rt_set_PSP (U32 stack) { - MSR PSP,R0 - BX LR -} - - -/*--------------------------- rt_get_PSP ------------------------------------*/ - -__asm U32 rt_get_PSP (void) { - MRS R0,PSP - BX LR -} - - -/*--------------------------- os_set_env ------------------------------------*/ - -__asm void os_set_env (void) { - /* Switch to Unprivileged/Privileged Thread mode, use PSP. */ - MOV R0,SP ; PSP = MSP - MSR PSP,R0 - LDR R0,=__cpp(&os_flags) - LDRB R0,[R0] - LSLS R0,#31 - BNE PrivilegedE - MOVS R0,#0x03 ; Unprivileged Thread mode, use PSP - MSR CONTROL,R0 - BX LR -PrivilegedE - MOVS R0,#0x02 ; Privileged Thread mode, use PSP - MSR CONTROL,R0 - BX LR - - ALIGN -} - - -/*--------------------------- _alloc_box ------------------------------------*/ - -__asm void *_alloc_box (void *box_mem) { - /* Function wrapper for Unprivileged/Privileged mode. */ - LDR R3,=__cpp(rt_alloc_box) - MOV R12,R3 - MRS R3,IPSR - LSLS R3,#24 - BNE PrivilegedA - MRS R3,CONTROL - LSLS R3,#31 - BEQ PrivilegedA - SVC 0 - BX LR -PrivilegedA - BX R12 - - ALIGN -} - - -/*--------------------------- _free_box -------------------------------------*/ - -__asm U32 _free_box (void *box_mem, void *box) { - /* Function wrapper for Unprivileged/Privileged mode. */ - LDR R3,=__cpp(rt_free_box) - MOV R12,R3 - MRS R3,IPSR - LSLS R3,#24 - BNE PrivilegedF - MRS R3,CONTROL - LSLS R3,#31 - BEQ PrivilegedF - SVC 0 - BX LR -PrivilegedF - BX R12 - - ALIGN -} - - -/*-------------------------- SVC_Handler ------------------------------------*/ - -__asm void SVC_Handler (void) { - PRESERVE8 - - IMPORT SVC_Count - IMPORT SVC_Table - IMPORT rt_stk_check - - MRS R0,PSP ; Read PSP - LDR R1,[R0,#24] ; Read Saved PC from Stack - SUBS R1,R1,#2 ; Point to SVC Instruction - LDRB R1,[R1] ; Load SVC Number - CMP R1,#0 - BNE SVC_User ; User SVC Number > 0 - - MOV LR,R4 - LDMIA R0,{R0-R3,R4} ; Read R0-R3,R12 from stack - MOV R12,R4 - MOV R4,LR - BLX R12 ; Call SVC Function - - MRS R3,PSP ; Read PSP - STMIA R3!,{R0-R2} ; Store return values - - LDR R3,=__cpp(&os_tsk) - LDMIA R3!,{R1,R2} ; os_tsk.run, os_tsk.new - CMP R1,R2 - BEQ SVC_Exit ; no task switch - - SUBS R3,#8 - CMP R1,#0 ; Runtask deleted? - BEQ SVC_Next - - MRS R0,PSP ; Read PSP - SUBS R0,R0,#32 ; Adjust Start Address - STR R0,[R1,#TCB_TSTACK] ; Update os_tsk.run->tsk_stack - STMIA R0!,{R4-R7} ; Save old context (R4-R7) - MOV R4,R8 - MOV R5,R9 - MOV R6,R10 - MOV R7,R11 - STMIA R0!,{R4-R7} ; Save old context (R8-R11) - - PUSH {R2,R3} - BL rt_stk_check ; Check for Stack overflow - POP {R2,R3} - -SVC_Next - STR R2,[R3] ; os_tsk.run = os_tsk.new - - LDR R0,[R2,#TCB_TSTACK] ; os_tsk.new->tsk_stack - ADDS R0,R0,#16 ; Adjust Start Address - LDMIA R0!,{R4-R7} ; Restore new Context (R8-R11) - MOV R8,R4 - MOV R9,R5 - MOV R10,R6 - MOV R11,R7 - MSR PSP,R0 ; Write PSP - SUBS R0,R0,#32 ; Adjust Start Address - LDMIA R0!,{R4-R7} ; Restore new Context (R4-R7) - -SVC_Exit - MOVS R0,#:NOT:0xFFFFFFFD ; Set EXC_RETURN value - MVNS R0,R0 - BX R0 ; RETI to Thread Mode, use PSP - - /*------------------- User SVC ------------------------------*/ - -SVC_User - PUSH {R4,LR} ; Save Registers - LDR R2,=SVC_Count - LDR R2,[R2] - CMP R1,R2 - BHI SVC_Done ; Overflow - - LDR R4,=SVC_Table-4 - LSLS R1,R1,#2 - LDR R4,[R4,R1] ; Load SVC Function Address - MOV LR,R4 - - LDMIA R0,{R0-R3,R4} ; Read R0-R3,R12 from stack - MOV R12,R4 - BLX LR ; Call SVC Function - - MRS R4,PSP ; Read PSP - STMIA R4!,{R0-R3} ; Function return values -SVC_Done - POP {R4,PC} ; RETI - - ALIGN -} - - -/*-------------------------- PendSV_Handler ---------------------------------*/ - -__asm void PendSV_Handler (void) { - PRESERVE8 - - BL __cpp(rt_pop_req) - -Sys_Switch - LDR R3,=__cpp(&os_tsk) - LDMIA R3!,{R1,R2} ; os_tsk.run, os_tsk.new - CMP R1,R2 - BEQ Sys_Exit ; no task switch - - SUBS R3,#8 - - MRS R0,PSP ; Read PSP - SUBS R0,R0,#32 ; Adjust Start Address - STR R0,[R1,#TCB_TSTACK] ; Update os_tsk.run->tsk_stack - STMIA R0!,{R4-R7} ; Save old context (R4-R7) - MOV R4,R8 - MOV R5,R9 - MOV R6,R10 - MOV R7,R11 - STMIA R0!,{R4-R7} ; Save old context (R8-R11) - - PUSH {R2,R3} - BL rt_stk_check ; Check for Stack overflow - POP {R2,R3} - - STR R2,[R3] ; os_tsk.run = os_tsk.new - - LDR R0,[R2,#TCB_TSTACK] ; os_tsk.new->tsk_stack - ADDS R0,R0,#16 ; Adjust Start Address - LDMIA R0!,{R4-R7} ; Restore new Context (R8-R11) - MOV R8,R4 - MOV R9,R5 - MOV R10,R6 - MOV R11,R7 - MSR PSP,R0 ; Write PSP - SUBS R0,R0,#32 ; Adjust Start Address - LDMIA R0!,{R4-R7} ; Restore new Context (R4-R7) - -Sys_Exit - MOVS R0,#:NOT:0xFFFFFFFD ; Set EXC_RETURN value - MVNS R0,R0 - BX R0 ; RETI to Thread Mode, use PSP - - ALIGN -} - - -/*-------------------------- SysTick_Handler --------------------------------*/ - -__asm void SysTick_Handler (void) { - PRESERVE8 - - BL __cpp(rt_systick) - B Sys_Switch - - ALIGN -} - - -/*-------------------------- OS_Tick_Handler --------------------------------*/ - -__asm void OS_Tick_Handler (void) { - PRESERVE8 - - BL __cpp(os_tick_irqack) - BL __cpp(rt_systick) - B Sys_Switch - - ALIGN -} - - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ - diff --git a/rtos/rtx/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_ARM/SVC_Table.S b/rtos/rtx/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_ARM/SVC_Table.S deleted file mode 100644 index 3ba439bca83..00000000000 --- a/rtos/rtx/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_ARM/SVC_Table.S +++ /dev/null @@ -1,57 +0,0 @@ -;/*---------------------------------------------------------------------------- -; * CMSIS-RTOS - RTX -; *---------------------------------------------------------------------------- -; * Name: SVC_TABLE.S -; * Purpose: Pre-defined SVC Table for Cortex-M -; * Rev.: V4.70 -; *---------------------------------------------------------------------------- -; * -; * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH -; * All rights reserved. -; * Redistribution and use in source and binary forms, with or without -; * modification, are permitted provided that the following conditions are met: -; * - Redistributions of source code must retain the above copyright -; * notice, this list of conditions and the following disclaimer. -; * - Redistributions in binary form must reproduce the above copyright -; * notice, this list of conditions and the following disclaimer in the -; * documentation and/or other materials provided with the distribution. -; * - Neither the name of ARM nor the names of its contributors may be used -; * to endorse or promote products derived from this software without -; * specific prior written permission. -; * -; * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -; * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -; * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -; * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE -; * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -; * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -; * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -; * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -; * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -; * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -; * POSSIBILITY OF SUCH DAMAGE. -; *---------------------------------------------------------------------------*/ - - - AREA SVC_TABLE, CODE, READONLY - - EXPORT SVC_Count - -SVC_Cnt EQU (SVC_End-SVC_Table)/4 -SVC_Count DCD SVC_Cnt - -; Import user SVC functions here. -; IMPORT __SVC_1 - - EXPORT SVC_Table -SVC_Table -; Insert user SVC functions here. SVC 0 used by RTL Kernel. -; DCD __SVC_1 ; user SVC function - -SVC_End - - END - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ diff --git a/rtos/rtx/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_GCC/HAL_CM0.S b/rtos/rtx/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_GCC/HAL_CM0.S deleted file mode 100644 index a9f1ff17c09..00000000000 --- a/rtos/rtx/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_GCC/HAL_CM0.S +++ /dev/null @@ -1,370 +0,0 @@ -/*---------------------------------------------------------------------------- - * CMSIS-RTOS - RTX - *---------------------------------------------------------------------------- - * Name: HAL_CM0.S - * Purpose: Hardware Abstraction Layer for Cortex-M0 - * Rev.: V4.70 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - - .file "HAL_CM0.S" - .syntax unified - - .equ TCB_TSTACK, 44 - - -/*---------------------------------------------------------------------------- - * Functions - *---------------------------------------------------------------------------*/ - - .thumb - - .section ".text" - .align 2 - - -/*--------------------------- rt_set_PSP ------------------------------------*/ - -# void rt_set_PSP (U32 stack); - - .thumb_func - .type rt_set_PSP, %function - .global rt_set_PSP -rt_set_PSP: - .fnstart - .cantunwind - - MSR PSP,R0 - BX LR - - .fnend - .size rt_set_PSP, .-rt_set_PSP - - -/*--------------------------- rt_get_PSP ------------------------------------*/ - -# U32 rt_get_PSP (void); - - .thumb_func - .type rt_get_PSP, %function - .global rt_get_PSP -rt_get_PSP: - .fnstart - .cantunwind - - MRS R0,PSP - BX LR - - .fnend - .size rt_get_PSP, .-rt_get_PSP - - -/*--------------------------- os_set_env ------------------------------------*/ - -# void os_set_env (void); - /* Switch to Unprivileged/Privileged Thread mode, use PSP. */ - - .thumb_func - .type os_set_env, %function - .global os_set_env -os_set_env: - .fnstart - .cantunwind - - MOV R0,SP /* PSP = MSP */ - MSR PSP,R0 - LDR R0,=os_flags - LDRB R0,[R0] - LSLS R0,#31 - BNE PrivilegedE - MOVS R0,#0x03 /* Unprivileged Thread mode, use PSP */ - MSR CONTROL,R0 - BX LR -PrivilegedE: - MOVS R0,#0x02 /* Privileged Thread mode, use PSP */ - MSR CONTROL,R0 - BX LR - - .fnend - .size os_set_env, .-os_set_env - - -/*--------------------------- _alloc_box ------------------------------------*/ - -# void *_alloc_box (void *box_mem); - /* Function wrapper for Unprivileged/Privileged mode. */ - - .thumb_func - .type _alloc_box, %function - .global _alloc_box -_alloc_box: - .fnstart - .cantunwind - - LDR R3,=rt_alloc_box - MOV R12,R3 - MRS R3,IPSR - LSLS R3,#24 - BNE PrivilegedA - MRS R3,CONTROL - LSLS R3,#31 - BEQ PrivilegedA - SVC 0 - BX LR -PrivilegedA: - BX R12 - - .fnend - .size _alloc_box, .-_alloc_box - - -/*--------------------------- _free_box -------------------------------------*/ - -# U32 _free_box (void *box_mem, void *box); - /* Function wrapper for Unprivileged/Privileged mode. */ - - .thumb_func - .type _free_box, %function - .global _free_box -_free_box: - .fnstart - .cantunwind - - LDR R3,=rt_free_box - MOV R12,R3 - MRS R3,IPSR - LSLS R3,#24 - BNE PrivilegedF - MRS R3,CONTROL - LSLS R3,#31 - BEQ PrivilegedF - SVC 0 - BX LR -PrivilegedF: - BX R12 - - .fnend - .size _free_box, .-_free_box - - -/*-------------------------- SVC_Handler ------------------------------------*/ - -# void SVC_Handler (void); - - .thumb_func - .type SVC_Handler, %function - .global SVC_Handler -SVC_Handler: - .fnstart - .cantunwind - - MRS R0,PSP /* Read PSP */ - LDR R1,[R0,#24] /* Read Saved PC from Stack */ - SUBS R1,R1,#2 /* Point to SVC Instruction */ - LDRB R1,[R1] /* Load SVC Number */ - CMP R1,#0 - BNE SVC_User /* User SVC Number > 0 */ - - MOV LR,R4 - LDMIA R0,{R0-R3,R4} /* Read R0-R3,R12 from stack */ - MOV R12,R4 - MOV R4,LR - BLX R12 /* Call SVC Function */ - - MRS R3,PSP /* Read PSP */ - STMIA R3!,{R0-R2} /* Store return values */ - - LDR R3,=os_tsk - LDMIA R3!,{R1,R2} /* os_tsk.run, os_tsk.new */ - CMP R1,R2 - BEQ SVC_Exit /* no task switch */ - - SUBS R3,#8 - CMP R1,#0 /* Runtask deleted? */ - BEQ SVC_Next - - MRS R0,PSP /* Read PSP */ - SUBS R0,R0,#32 /* Adjust Start Address */ - STR R0,[R1,#TCB_TSTACK] /* Update os_tsk.run->tsk_stack */ - STMIA R0!,{R4-R7} /* Save old context (R4-R7) */ - MOV R4,R8 - MOV R5,R9 - MOV R6,R10 - MOV R7,R11 - STMIA R0!,{R4-R7} /* Save old context (R8-R11) */ - - PUSH {R2,R3} - BL rt_stk_check /* Check for Stack overflow */ - POP {R2,R3} - -SVC_Next: - STR R2,[R3] /* os_tsk.run = os_tsk.new */ - - LDR R0,[R2,#TCB_TSTACK] /* os_tsk.new->tsk_stack */ - ADDS R0,R0,#16 /* Adjust Start Address */ - LDMIA R0!,{R4-R7} /* Restore new Context (R8-R11) */ - MOV R8,R4 - MOV R9,R5 - MOV R10,R6 - MOV R11,R7 - MSR PSP,R0 /* Write PSP */ - SUBS R0,R0,#32 /* Adjust Start Address */ - LDMIA R0!,{R4-R7} /* Restore new Context (R4-R7) */ - -SVC_Exit: - MOVS R0,#~0xFFFFFFFD /* Set EXC_RETURN value */ - MVNS R0,R0 - BX R0 /* RETI to Thread Mode, use PSP */ - - /*------------------- User SVC ------------------------------*/ - -SVC_User: - PUSH {R4,LR} /* Save Registers */ - LDR R2,=SVC_Count - LDR R2,[R2] - CMP R1,R2 - BHI SVC_Done /* Overflow */ - - LDR R4,=SVC_Table-4 - LSLS R1,R1,#2 - LDR R4,[R4,R1] /* Load SVC Function Address */ - MOV LR,R4 - - LDMIA R0,{R0-R3,R4} /* Read R0-R3,R12 from stack */ - MOV R12,R4 - BLX LR /* Call SVC Function */ - - MRS R4,PSP /* Read PSP */ - STMIA R4!,{R0-R3} /* Function return values */ -SVC_Done: - POP {R4,PC} /* RETI */ - - .fnend - .size SVC_Handler, .-SVC_Handler - - -/*-------------------------- PendSV_Handler ---------------------------------*/ - -# void PendSV_Handler (void); - - .thumb_func - .type PendSV_Handler, %function - .global PendSV_Handler - .global Sys_Switch -PendSV_Handler: - .fnstart - .cantunwind - - BL rt_pop_req - -Sys_Switch: - LDR R3,=os_tsk - LDMIA R3!,{R1,R2} /* os_tsk.run, os_tsk.new */ - CMP R1,R2 - BEQ Sys_Exit /* no task switch */ - - SUBS R3,#8 - - MRS R0,PSP /* Read PSP */ - SUBS R0,R0,#32 /* Adjust Start Address */ - STR R0,[R1,#TCB_TSTACK] /* Update os_tsk.run->tsk_stack */ - STMIA R0!,{R4-R7} /* Save old context (R4-R7) */ - MOV R4,R8 - MOV R5,R9 - MOV R6,R10 - MOV R7,R11 - STMIA R0!,{R4-R7} /* Save old context (R8-R11) */ - - PUSH {R2,R3} - BL rt_stk_check /* Check for Stack overflow */ - POP {R2,R3} - - STR R2,[R3] /* os_tsk.run = os_tsk.new */ - - LDR R0,[R2,#TCB_TSTACK] /* os_tsk.new->tsk_stack */ - ADDS R0,R0,#16 /* Adjust Start Address */ - LDMIA R0!,{R4-R7} /* Restore new Context (R8-R11) */ - MOV R8,R4 - MOV R9,R5 - MOV R10,R6 - MOV R11,R7 - MSR PSP,R0 /* Write PSP */ - SUBS R0,R0,#32 /* Adjust Start Address */ - LDMIA R0!,{R4-R7} /* Restore new Context (R4-R7) */ - -Sys_Exit: - MOVS R0,#~0xFFFFFFFD /* Set EXC_RETURN value */ - MVNS R0,R0 - BX R0 /* RETI to Thread Mode, use PSP */ - - .fnend - .size PendSV_Handler, .-PendSV_Handler - - -/*-------------------------- SysTick_Handler --------------------------------*/ - -# void SysTick_Handler (void); - - .thumb_func - .type SysTick_Handler, %function - .global SysTick_Handler -SysTick_Handler: - .fnstart - .cantunwind - - BL rt_systick - B Sys_Switch - - .fnend - .size SysTick_Handler, .-SysTick_Handler - - -/*-------------------------- OS_Tick_Handler --------------------------------*/ - -# void OS_Tick_Handler (void); - - .thumb_func - .type OS_Tick_Handler, %function - .global OS_Tick_Handler -OS_Tick_Handler: - .fnstart - .cantunwind - - BL os_tick_irqack - BL rt_systick - B Sys_Switch - - .fnend - .size OS_Tick_Handler, .-OS_Tick_Handler - - - .end - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ diff --git a/rtos/rtx/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_GCC/SVC_Table.S b/rtos/rtx/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_GCC/SVC_Table.S deleted file mode 100644 index d583df13321..00000000000 --- a/rtos/rtx/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_GCC/SVC_Table.S +++ /dev/null @@ -1,56 +0,0 @@ -;/*---------------------------------------------------------------------------- -; * CMSIS-RTOS - RTX -; *---------------------------------------------------------------------------- -; * Name: SVC_TABLE.S -; * Purpose: Pre-defined SVC Table for Cortex-M -; * Rev.: V4.70 -; *---------------------------------------------------------------------------- -; * -; * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH -; * All rights reserved. -; * Redistribution and use in source and binary forms, with or without -; * modification, are permitted provided that the following conditions are met: -; * - Redistributions of source code must retain the above copyright -; * notice, this list of conditions and the following disclaimer. -; * - Redistributions in binary form must reproduce the above copyright -; * notice, this list of conditions and the following disclaimer in the -; * documentation and/or other materials provided with the distribution. -; * - Neither the name of ARM nor the names of its contributors may be used -; * to endorse or promote products derived from this software without -; * specific prior written permission. -; * -; * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -; * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -; * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -; * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE -; * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -; * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -; * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -; * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -; * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -; * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -; * POSSIBILITY OF SUCH DAMAGE. -; *---------------------------------------------------------------------------*/ - - - .file "SVC_Table.S" - - - .section ".svc_table" - - .global SVC_Table -SVC_Table: -/* Insert user SVC functions here. SVC 0 used by RTL Kernel. */ -# .long __SVC_1 /* user SVC function */ -SVC_End: - - .global SVC_Count -SVC_Count: - .long (SVC_End-SVC_Table)/4 - - - .end - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ diff --git a/rtos/rtx/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_IAR/HAL_CM0.S b/rtos/rtx/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_IAR/HAL_CM0.S deleted file mode 100644 index d0dc85374cd..00000000000 --- a/rtos/rtx/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_IAR/HAL_CM0.S +++ /dev/null @@ -1,312 +0,0 @@ -/*---------------------------------------------------------------------------- - * CMSIS-RTOS - RTX - *---------------------------------------------------------------------------- - * Name: HAL_CM0.S - * Purpose: Hardware Abstraction Layer for Cortex-M0 - * Rev.: V4.70 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - - NAME HAL_CM0.S - - #define TCB_TSTACK 44 - - EXTERN os_flags - EXTERN os_tsk - EXTERN rt_alloc_box - EXTERN rt_free_box - EXTERN rt_stk_check - EXTERN rt_pop_req - EXTERN rt_systick - EXTERN os_tick_irqack - EXTERN SVC_Table - EXTERN SVC_Count - -/*---------------------------------------------------------------------------- - * Functions - *---------------------------------------------------------------------------*/ - - SECTION .text:CODE:NOROOT(2) - THUMB - -/*--------------------------- rt_set_PSP ------------------------------------*/ - -; void rt_set_PSP (U32 stack); - - PUBLIC rt_set_PSP -rt_set_PSP: - - MSR PSP,R0 - BX LR - - -/*--------------------------- rt_get_PSP ------------------------------------*/ - -; U32 rt_get_PSP (void); - - PUBLIC rt_get_PSP -rt_get_PSP: - - MRS R0,PSP - BX LR - - -/*--------------------------- os_set_env ------------------------------------*/ - -; void os_set_env (void); - /* Switch to Unprivileged/Privileged Thread mode, use PSP. */ - - PUBLIC os_set_env -os_set_env: - - MOV R0,SP /* PSP = MSP */ - MSR PSP,R0 - LDR R0,=os_flags - LDRB R0,[R0] - LSLS R0,#31 - BNE PrivilegedE - MOVS R0,#0x03 /* Unprivileged Thread mode, use PSP */ - MSR CONTROL,R0 - BX LR -PrivilegedE: - MOVS R0,#0x02 /* Privileged Thread mode, use PSP */ - MSR CONTROL,R0 - BX LR - - -/*--------------------------- _alloc_box ------------------------------------*/ - -; void *_alloc_box (void *box_mem); - /* Function wrapper for Unprivileged/Privileged mode. */ - - PUBLIC _alloc_box -_alloc_box: - - LDR R3,=rt_alloc_box - MOV R12,R3 - MRS R3,IPSR - LSLS R3,#24 - BNE PrivilegedA - MRS R3,CONTROL - LSLS R3,#31 - BEQ PrivilegedA - SVC 0 - BX LR -PrivilegedA: - BX R12 - - -/*--------------------------- _free_box -------------------------------------*/ - -; U32 _free_box (void *box_mem, void *box); - /* Function wrapper for Unprivileged/Privileged mode. */ - - PUBLIC _free_box -_free_box: - - LDR R3,=rt_free_box - MOV R12,R3 - MRS R3,IPSR - LSLS R3,#24 - BNE PrivilegedF - MRS R3,CONTROL - LSLS R3,#31 - BEQ PrivilegedF - SVC 0 - BX LR -PrivilegedF: - BX R12 - - -/*-------------------------- SVC_Handler ------------------------------------*/ - -; void SVC_Handler (void); - - PUBLIC SVC_Handler -SVC_Handler: - - MRS R0,PSP /* Read PSP */ - LDR R1,[R0,#24] /* Read Saved PC from Stack */ - SUBS R1,R1,#2 /* Point to SVC Instruction */ - LDRB R1,[R1] /* Load SVC Number */ - CMP R1,#0 - BNE SVC_User /* User SVC Number > 0 */ - - MOV LR,R4 - LDMIA R0,{R0-R3,R4} /* Read R0-R3,R12 from stack */ - MOV R12,R4 - MOV R4,LR - BLX R12 /* Call SVC Function */ - - MRS R3,PSP /* Read PSP */ - STMIA R3!,{R0-R2} /* Store return values */ - - LDR R3,=os_tsk - LDMIA R3!,{R1,R2} /* os_tsk.run, os_tsk.new */ - CMP R1,R2 - BEQ SVC_Exit /* no task switch */ - - SUBS R3,#8 - CMP R1,#0 /* Runtask deleted? */ - BEQ SVC_Next - - MRS R0,PSP /* Read PSP */ - SUBS R0,R0,#32 /* Adjust Start Address */ - STR R0,[R1,#TCB_TSTACK] /* Update os_tsk.run->tsk_stack */ - STMIA R0!,{R4-R7} /* Save old context (R4-R7) */ - MOV R4,R8 - MOV R5,R9 - MOV R6,R10 - MOV R7,R11 - STMIA R0!,{R4-R7} /* Save old context (R8-R11) */ - - PUSH {R2,R3} - BL rt_stk_check /* Check for Stack overflow */ - POP {R2,R3} - -SVC_Next: - STR R2,[R3] /* os_tsk.run = os_tsk.new */ - - LDR R0,[R2,#TCB_TSTACK] /* os_tsk.new->tsk_stack */ - ADDS R0,R0,#16 /* Adjust Start Address */ - LDMIA R0!,{R4-R7} /* Restore new Context (R8-R11) */ - MOV R8,R4 - MOV R9,R5 - MOV R10,R6 - MOV R11,R7 - MSR PSP,R0 /* Write PSP */ - SUBS R0,R0,#32 /* Adjust Start Address */ - LDMIA R0!,{R4-R7} /* Restore new Context (R4-R7) */ - -SVC_Exit: - MOVS R0,#~0xFFFFFFFD /* Set EXC_RETURN value */ - MVNS R0,R0 - BX R0 /* RETI to Thread Mode, use PSP */ - - /*------------------- User SVC ------------------------------*/ - -SVC_User: - PUSH {R4,LR} /* Save Registers */ - LDR R2,=SVC_Count - LDR R2,[R2] - CMP R1,R2 - BHI SVC_Done /* Overflow */ - - LDR R4,=SVC_Table-4 - LSLS R1,R1,#2 - LDR R4,[R4,R1] /* Load SVC Function Address */ - MOV LR,R4 - - LDMIA R0,{R0-R3,R4} /* Read R0-R3,R12 from stack */ - MOV R12,R4 - BLX LR /* Call SVC Function */ - - MRS R4,PSP /* Read PSP */ - STMIA R4!,{R0-R3} /* Function return values */ -SVC_Done: - POP {R4,PC} /* RETI */ - - -/*-------------------------- PendSV_Handler ---------------------------------*/ - -; void PendSV_Handler (void); - - PUBLIC PendSV_Handler -PendSV_Handler: - - BL rt_pop_req - -Sys_Switch: - LDR R3,=os_tsk - LDMIA R3!,{R1,R2} /* os_tsk.run, os_tsk.new */ - CMP R1,R2 - BEQ Sys_Exit /* no task switch */ - - SUBS R3,#8 - - MRS R0,PSP /* Read PSP */ - SUBS R0,R0,#32 /* Adjust Start Address */ - STR R0,[R1,#TCB_TSTACK] /* Update os_tsk.run->tsk_stack */ - STMIA R0!,{R4-R7} /* Save old context (R4-R7) */ - MOV R4,R8 - MOV R5,R9 - MOV R6,R10 - MOV R7,R11 - STMIA R0!,{R4-R7} /* Save old context (R8-R11) */ - - PUSH {R2,R3} - BL rt_stk_check /* Check for Stack overflow */ - POP {R2,R3} - - STR R2,[R3] /* os_tsk.run = os_tsk.new */ - - LDR R0,[R2,#TCB_TSTACK] /* os_tsk.new->tsk_stack */ - ADDS R0,R0,#16 /* Adjust Start Address */ - LDMIA R0!,{R4-R7} /* Restore new Context (R8-R11) */ - MOV R8,R4 - MOV R9,R5 - MOV R10,R6 - MOV R11,R7 - MSR PSP,R0 /* Write PSP */ - SUBS R0,R0,#32 /* Adjust Start Address */ - LDMIA R0!,{R4-R7} /* Restore new Context (R4-R7) */ - -Sys_Exit: - MOVS R0,#~0xFFFFFFFD /* Set EXC_RETURN value */ - MVNS R0,R0 - BX R0 /* RETI to Thread Mode, use PSP */ - - -/*-------------------------- SysTick_Handler --------------------------------*/ - -; void SysTick_Handler (void); - - PUBLIC SysTick_Handler -SysTick_Handler: - - BL rt_systick - B Sys_Switch - - -/*-------------------------- OS_Tick_Handler --------------------------------*/ - -; void OS_Tick_Handler (void); - - PUBLIC OS_Tick_Handler -OS_Tick_Handler: - - BL os_tick_irqack - BL rt_systick - B Sys_Switch - - - END - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ diff --git a/rtos/rtx/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_IAR/SVC_Table.S b/rtos/rtx/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_IAR/SVC_Table.S deleted file mode 100644 index 18710cb2d11..00000000000 --- a/rtos/rtx/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_IAR/SVC_Table.S +++ /dev/null @@ -1,58 +0,0 @@ -;/*---------------------------------------------------------------------------- -; * CMSIS-RTOS - RTX -; *---------------------------------------------------------------------------- -; * Name: SVC_TABLE.S -; * Purpose: Pre-defined SVC Table for Cortex-M -; * Rev.: V4.70 -; *---------------------------------------------------------------------------- -; * -; * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH -; * All rights reserved. -; * Redistribution and use in source and binary forms, with or without -; * modification, are permitted provided that the following conditions are met: -; * - Redistributions of source code must retain the above copyright -; * notice, this list of conditions and the following disclaimer. -; * - Redistributions in binary form must reproduce the above copyright -; * notice, this list of conditions and the following disclaimer in the -; * documentation and/or other materials provided with the distribution. -; * - Neither the name of ARM nor the names of its contributors may be used -; * to endorse or promote products derived from this software without -; * specific prior written permission. -; * -; * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -; * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -; * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -; * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE -; * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -; * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -; * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -; * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -; * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -; * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -; * POSSIBILITY OF SUCH DAMAGE. -; *---------------------------------------------------------------------------*/ - - - NAME SVC_TABLE - SECTION .text:CONST (2) - - PUBLIC SVC_Count - -SVC_Cnt EQU (SVC_End-SVC_Table)/4 -SVC_Count DCD SVC_Cnt - -; Import user SVC functions here. -; IMPORT __SVC_1 - - PUBLIC SVC_Table -SVC_Table -; Insert user SVC functions here. SVC 0 used by RTL Kernel. -; DCD __SVC_1 ; user SVC function - -SVC_End - - END - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ diff --git a/rtos/rtx/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_ARM/HAL_CM3.c b/rtos/rtx/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_ARM/HAL_CM3.c deleted file mode 100644 index 5c90f736083..00000000000 --- a/rtos/rtx/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_ARM/HAL_CM3.c +++ /dev/null @@ -1,274 +0,0 @@ -/*---------------------------------------------------------------------------- - * CMSIS-RTOS - RTX - *---------------------------------------------------------------------------- - * Name: HAL_CM3.C - * Purpose: Hardware Abstraction Layer for Cortex-M3 - * Rev.: V4.70 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -#include "rt_TypeDef.h" -#include "RTX_Config.h" -#include "rt_System.h" -#include "rt_HAL_CM.h" -#include "rt_Task.h" -#include "rt_MemBox.h" - - -/*---------------------------------------------------------------------------- - * Functions - *---------------------------------------------------------------------------*/ - - -/*--------------------------- rt_set_PSP ------------------------------------*/ - -__asm void rt_set_PSP (U32 stack) { - MSR PSP,R0 - BX LR -} - - -/*--------------------------- rt_get_PSP ------------------------------------*/ - -__asm U32 rt_get_PSP (void) { - MRS R0,PSP - BX LR -} - - -/*--------------------------- os_set_env ------------------------------------*/ - -__asm void os_set_env (void) { - /* Switch to Unprivileged/Privileged Thread mode, use PSP. */ - MOV R0,SP ; PSP = MSP - MSR PSP,R0 - LDR R0,=__cpp(&os_flags) - LDRB R0,[R0] - LSLS R0,#31 - MOVNE R0,#0x02 ; Privileged Thread mode, use PSP - MOVEQ R0,#0x03 ; Unprivileged Thread mode, use PSP - MSR CONTROL,R0 - BX LR - - ALIGN -} - - -/*--------------------------- _alloc_box ------------------------------------*/ - -__asm void *_alloc_box (void *box_mem) { - /* Function wrapper for Unprivileged/Privileged mode. */ - LDR R12,=__cpp(rt_alloc_box) - MRS R3,IPSR - LSLS R3,#24 - BXNE R12 - MRS R3,CONTROL - LSLS R3,#31 - BXEQ R12 - SVC 0 - BX LR - - ALIGN -} - - -/*--------------------------- _free_box -------------------------------------*/ - -__asm U32 _free_box (void *box_mem, void *box) { - /* Function wrapper for Unprivileged/Privileged mode. */ - LDR R12,=__cpp(rt_free_box) - MRS R3,IPSR - LSLS R3,#24 - BXNE R12 - MRS R3,CONTROL - LSLS R3,#31 - BXEQ R12 - SVC 0 - BX LR - - ALIGN -} - - -/*-------------------------- SVC_Handler ------------------------------------*/ - -__asm void SVC_Handler (void) { - PRESERVE8 - - IMPORT SVC_Count - IMPORT SVC_Table - IMPORT rt_stk_check - -#ifdef IFX_XMC4XXX - EXPORT SVC_Handler_Veneer -SVC_Handler_Veneer -#endif - - MRS R0,PSP ; Read PSP - LDR R1,[R0,#24] ; Read Saved PC from Stack - LDRB R1,[R1,#-2] ; Load SVC Number - CBNZ R1,SVC_User - - LDM R0,{R0-R3,R12} ; Read R0-R3,R12 from stack - BLX R12 ; Call SVC Function - - MRS R12,PSP ; Read PSP - STM R12,{R0-R2} ; Store return values - - LDR R3,=__cpp(&os_tsk) - LDM R3,{R1,R2} ; os_tsk.run, os_tsk.new - CMP R1,R2 - BEQ SVC_Exit ; no task switch - - CBZ R1,SVC_Next ; Runtask deleted? - STMDB R12!,{R4-R11} ; Save Old context - STR R12,[R1,#TCB_TSTACK] ; Update os_tsk.run->tsk_stack - - PUSH {R2,R3} - BL rt_stk_check ; Check for Stack overflow - POP {R2,R3} - -SVC_Next - STR R2,[R3] ; os_tsk.run = os_tsk.new - - LDR R12,[R2,#TCB_TSTACK] ; os_tsk.new->tsk_stack - LDMIA R12!,{R4-R11} ; Restore New Context - MSR PSP,R12 ; Write PSP - -SVC_Exit - MVN LR,#:NOT:0xFFFFFFFD ; set EXC_RETURN value -#ifdef IFX_XMC4XXX - PUSH {LR} - POP {PC} -#else - BX LR -#endif - - /*------------------- User SVC ------------------------------*/ - -SVC_User - PUSH {R4,LR} ; Save Registers - LDR R2,=SVC_Count - LDR R2,[R2] - CMP R1,R2 - BHI SVC_Done ; Overflow - - LDR R4,=SVC_Table-4 - LDR R4,[R4,R1,LSL #2] ; Load SVC Function Address - - LDM R0,{R0-R3,R12} ; Read R0-R3,R12 from stack - BLX R4 ; Call SVC Function - - MRS R12,PSP - STM R12,{R0-R3} ; Function return values -SVC_Done - POP {R4,PC} ; RETI - - ALIGN -} - - -/*-------------------------- PendSV_Handler ---------------------------------*/ - -__asm void PendSV_Handler (void) { - PRESERVE8 - -#ifdef IFX_XMC4XXX - EXPORT PendSV_Handler_Veneer -PendSV_Handler_Veneer -#endif - - BL __cpp(rt_pop_req) - -Sys_Switch - LDR R3,=__cpp(&os_tsk) - LDM R3,{R1,R2} ; os_tsk.run, os_tsk.new - CMP R1,R2 - BEQ Sys_Exit - - MRS R12,PSP ; Read PSP - STMDB R12!,{R4-R11} ; Save Old context - STR R12,[R1,#TCB_TSTACK] ; Update os_tsk.run->tsk_stack - - PUSH {R2,R3} - BL rt_stk_check ; Check for Stack overflow - POP {R2,R3} - - STR R2,[R3] ; os_tsk.run = os_tsk.new - - LDR R12,[R2,#TCB_TSTACK] ; os_tsk.new->tsk_stack - LDMIA R12!,{R4-R11} ; Restore New Context - MSR PSP,R12 ; Write PSP - -Sys_Exit - MVN LR,#:NOT:0xFFFFFFFD ; set EXC_RETURN value -#ifdef IFX_XMC4XXX - PUSH {LR} - POP {PC} -#else - BX LR ; Return to Thread Mode -#endif - - ALIGN -} - - -/*-------------------------- SysTick_Handler --------------------------------*/ - -__asm void SysTick_Handler (void) { - PRESERVE8 - -#ifdef IFX_XMC4XXX - EXPORT SysTick_Handler_Veneer -SysTick_Handler_Veneer -#endif - - BL __cpp(rt_systick) - B Sys_Switch - - ALIGN -} - - -/*-------------------------- OS_Tick_Handler --------------------------------*/ - -__asm void OS_Tick_Handler (void) { - PRESERVE8 - - BL __cpp(os_tick_irqack) - BL __cpp(rt_systick) - B Sys_Switch - - ALIGN -} - - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ - diff --git a/rtos/rtx/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_ARM/SVC_Table.S b/rtos/rtx/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_ARM/SVC_Table.S deleted file mode 100644 index e1289a53bc4..00000000000 --- a/rtos/rtx/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_ARM/SVC_Table.S +++ /dev/null @@ -1,57 +0,0 @@ -;/*---------------------------------------------------------------------------- -; * CMSIS-RTOS - RTX -; *---------------------------------------------------------------------------- -; * Name: SVC_TABLE.S -; * Purpose: Pre-defined SVC Table for Cortex-M -; * Rev.: V4.70 -; *---------------------------------------------------------------------------- -; * -; * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH -; * All rights reserved. -; * Redistribution and use in source and binary forms, with or without -; * modification, are permitted provided that the following conditions are met: -; * - Redistributions of source code must retain the above copyright -; * notice, this list of conditions and the following disclaimer. -; * - Redistributions in binary form must reproduce the above copyright -; * notice, this list of conditions and the following disclaimer in the -; * documentation and/or other materials provided with the distribution. -; * - Neither the name of ARM nor the names of its contributors may be used -; * to endorse or promote products derived from this software without -; * specific prior written permission. -; * -; * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -; * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -; * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -; * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE -; * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -; * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -; * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -; * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -; * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -; * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -; * POSSIBILITY OF SUCH DAMAGE. -; *---------------------------------------------------------------------------*/ - - - AREA SVC_TABLE, CODE, READONLY - - EXPORT SVC_Count - -SVC_Cnt EQU (SVC_End-SVC_Table)/4 -SVC_Count DCD SVC_Cnt - -; Import user SVC functions here. -; IMPORT __SVC_1 - - EXPORT SVC_Table -SVC_Table -; Insert user SVC functions here. SVC 0 used by RTL Kernel. -; DCD __SVC_1 ; user SVC function - -SVC_End - - END - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ diff --git a/rtos/rtx/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_GCC/HAL_CM3.S b/rtos/rtx/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_GCC/HAL_CM3.S deleted file mode 100644 index e218b0559db..00000000000 --- a/rtos/rtx/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_GCC/HAL_CM3.S +++ /dev/null @@ -1,345 +0,0 @@ -/*---------------------------------------------------------------------------- - * CMSIS-RTOS - RTX - *---------------------------------------------------------------------------- - * Name: HAL_CM3.S - * Purpose: Hardware Abstraction Layer for Cortex-M3 - * Rev.: V4.70 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - - .file "HAL_CM3.S" - .syntax unified - - .equ TCB_TSTACK, 44 - - -/*---------------------------------------------------------------------------- - * Functions - *---------------------------------------------------------------------------*/ - - .thumb - - .section ".text" - .align 2 - - -/*--------------------------- rt_set_PSP ------------------------------------*/ - -# void rt_set_PSP (U32 stack); - - .thumb_func - .type rt_set_PSP, %function - .global rt_set_PSP -rt_set_PSP: - .fnstart - .cantunwind - - MSR PSP,R0 - BX LR - - .fnend - .size rt_set_PSP, .-rt_set_PSP - - -/*--------------------------- rt_get_PSP ------------------------------------*/ - -# U32 rt_get_PSP (void); - - .thumb_func - .type rt_get_PSP, %function - .global rt_get_PSP -rt_get_PSP: - .fnstart - .cantunwind - - MRS R0,PSP - BX LR - - .fnend - .size rt_get_PSP, .-rt_get_PSP - - -/*--------------------------- os_set_env ------------------------------------*/ - -# void os_set_env (void); - /* Switch to Unprivileged/Privileged Thread mode, use PSP. */ - - .thumb_func - .type os_set_env, %function - .global os_set_env -os_set_env: - .fnstart - .cantunwind - - MOV R0,SP /* PSP = MSP */ - MSR PSP,R0 - LDR R0,=os_flags - LDRB R0,[R0] - LSLS R0,#31 - ITE NE - MOVNE R0,#0x02 /* Privileged Thread mode, use PSP */ - MOVEQ R0,#0x03 /* Unprivileged Thread mode, use PSP */ - MSR CONTROL,R0 - BX LR - - .fnend - .size os_set_env, .-os_set_env - - -/*--------------------------- _alloc_box ------------------------------------*/ - -# void *_alloc_box (void *box_mem); - /* Function wrapper for Unprivileged/Privileged mode. */ - - .thumb_func - .type _alloc_box, %function - .global _alloc_box -_alloc_box: - .fnstart - .cantunwind - - LDR R12,=rt_alloc_box - MRS R3,IPSR - LSLS R3,#24 - IT NE - BXNE R12 - MRS R3,CONTROL - LSLS R3,#31 - IT EQ - BXEQ R12 - SVC 0 - BX LR - - .fnend - .size _alloc_box, .-_alloc_box - - -/*--------------------------- _free_box -------------------------------------*/ - -# U32 _free_box (void *box_mem, void *box); - /* Function wrapper for Unprivileged/Privileged mode. */ - - .thumb_func - .type _free_box, %function - .global _free_box -_free_box: - .fnstart - .cantunwind - - LDR R12,=rt_free_box - MRS R3,IPSR - LSLS R3,#24 - IT NE - BXNE R12 - MRS R3,CONTROL - LSLS R3,#31 - IT EQ - BXEQ R12 - SVC 0 - BX LR - - .fnend - .size _free_box, .-_free_box - - -/*-------------------------- SVC_Handler ------------------------------------*/ - -# void SVC_Handler (void); - - .thumb_func - .type SVC_Handler, %function - .global SVC_Handler -SVC_Handler: - .ifdef IFX_XMC4XXX - .global SVC_Handler_Veneer -SVC_Handler_Veneer: - .endif - .fnstart - .cantunwind - - MRS R0,PSP /* Read PSP */ - LDR R1,[R0,#24] /* Read Saved PC from Stack */ - LDRB R1,[R1,#-2] /* Load SVC Number */ - CBNZ R1,SVC_User - - LDM R0,{R0-R3,R12} /* Read R0-R3,R12 from stack */ - BLX R12 /* Call SVC Function */ - - MRS R12,PSP /* Read PSP */ - STM R12,{R0-R2} /* Store return values */ - - LDR R3,=os_tsk - LDM R3,{R1,R2} /* os_tsk.run, os_tsk.new */ - CMP R1,R2 - BEQ SVC_Exit /* no task switch */ - - CBZ R1,SVC_Next /* Runtask deleted? */ - STMDB R12!,{R4-R11} /* Save Old context */ - STR R12,[R1,#TCB_TSTACK] /* Update os_tsk.run->tsk_stack */ - - PUSH {R2,R3} - BL rt_stk_check /* Check for Stack overflow */ - POP {R2,R3} - -SVC_Next: - STR R2,[R3] /* os_tsk.run = os_tsk.new */ - - LDR R12,[R2,#TCB_TSTACK] /* os_tsk.new->tsk_stack */ - LDMIA R12!,{R4-R11} /* Restore New Context */ - MSR PSP,R12 /* Write PSP */ - -SVC_Exit: - MVN LR,#~0xFFFFFFFD /* set EXC_RETURN value */ - .ifdef IFX_XMC4XXX - PUSH {LR} - POP {PC} - .else - BX LR - .endif - - /*------------------- User SVC ------------------------------*/ - -SVC_User: - PUSH {R4,LR} /* Save Registers */ - LDR R2,=SVC_Count - LDR R2,[R2] - CMP R1,R2 - BHI SVC_Done /* Overflow */ - - LDR R4,=SVC_Table-4 - LDR R4,[R4,R1,LSL #2] /* Load SVC Function Address */ - - LDM R0,{R0-R3,R12} /* Read R0-R3,R12 from stack */ - BLX R4 /* Call SVC Function */ - - MRS R12,PSP - STM R12,{R0-R3} /* Function return values */ -SVC_Done: - POP {R4,PC} /* RETI */ - - .fnend - .size SVC_Handler, .-SVC_Handler - - -/*-------------------------- PendSV_Handler ---------------------------------*/ - -# void PendSV_Handler (void); - - .thumb_func - .type PendSV_Handler, %function - .global PendSV_Handler - .global Sys_Switch -PendSV_Handler: - .ifdef IFX_XMC4XXX - .global PendSV_Handler_Veneer -PendSV_Handler_Veneer: - .endif - .fnstart - .cantunwind - - BL rt_pop_req - -Sys_Switch: - LDR R3,=os_tsk - LDM R3,{R1,R2} /* os_tsk.run, os_tsk.new */ - CMP R1,R2 - BEQ Sys_Exit - - MRS R12,PSP /* Read PSP */ - STMDB R12!,{R4-R11} /* Save Old context */ - STR R12,[R1,#TCB_TSTACK] /* Update os_tsk.run->tsk_stack */ - - PUSH {R2,R3} - BL rt_stk_check /* Check for Stack overflow */ - POP {R2,R3} - - STR R2,[R3] /* os_tsk.run = os_tsk.new */ - - LDR R12,[R2,#TCB_TSTACK] /* os_tsk.new->tsk_stack */ - LDMIA R12!,{R4-R11} /* Restore New Context */ - MSR PSP,R12 /* Write PSP */ - -Sys_Exit: - MVN LR,#~0xFFFFFFFD /* set EXC_RETURN value */ - .ifdef IFX_XMC4XXX - PUSH {LR} - POP {PC} - .else - BX LR /* Return to Thread Mode */ - .endif - - .fnend - .size PendSV_Handler, .-PendSV_Handler - - -/*-------------------------- SysTick_Handler --------------------------------*/ - -# void SysTick_Handler (void); - - .thumb_func - .type SysTick_Handler, %function - .global SysTick_Handler -SysTick_Handler: - .ifdef IFX_XMC4XXX - .global SysTick_Handler_Veneer -SysTick_Handler_Veneer: - .endif - .fnstart - .cantunwind - - BL rt_systick - B Sys_Switch - - .fnend - .size SysTick_Handler, .-SysTick_Handler - - -/*-------------------------- OS_Tick_Handler --------------------------------*/ - -# void OS_Tick_Handler (void); - - .thumb_func - .type OS_Tick_Handler, %function - .global OS_Tick_Handler -OS_Tick_Handler: - .fnstart - .cantunwind - - BL os_tick_irqack - BL rt_systick - B Sys_Switch - - .fnend - .size OS_Tick_Handler, .-OS_Tick_Handler - - - .end - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ diff --git a/rtos/rtx/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_GCC/SVC_Table.S b/rtos/rtx/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_GCC/SVC_Table.S deleted file mode 100644 index d583df13321..00000000000 --- a/rtos/rtx/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_GCC/SVC_Table.S +++ /dev/null @@ -1,56 +0,0 @@ -;/*---------------------------------------------------------------------------- -; * CMSIS-RTOS - RTX -; *---------------------------------------------------------------------------- -; * Name: SVC_TABLE.S -; * Purpose: Pre-defined SVC Table for Cortex-M -; * Rev.: V4.70 -; *---------------------------------------------------------------------------- -; * -; * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH -; * All rights reserved. -; * Redistribution and use in source and binary forms, with or without -; * modification, are permitted provided that the following conditions are met: -; * - Redistributions of source code must retain the above copyright -; * notice, this list of conditions and the following disclaimer. -; * - Redistributions in binary form must reproduce the above copyright -; * notice, this list of conditions and the following disclaimer in the -; * documentation and/or other materials provided with the distribution. -; * - Neither the name of ARM nor the names of its contributors may be used -; * to endorse or promote products derived from this software without -; * specific prior written permission. -; * -; * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -; * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -; * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -; * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE -; * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -; * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -; * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -; * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -; * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -; * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -; * POSSIBILITY OF SUCH DAMAGE. -; *---------------------------------------------------------------------------*/ - - - .file "SVC_Table.S" - - - .section ".svc_table" - - .global SVC_Table -SVC_Table: -/* Insert user SVC functions here. SVC 0 used by RTL Kernel. */ -# .long __SVC_1 /* user SVC function */ -SVC_End: - - .global SVC_Count -SVC_Count: - .long (SVC_End-SVC_Table)/4 - - - .end - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ diff --git a/rtos/rtx/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_IAR/HAL_CM3.S b/rtos/rtx/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_IAR/HAL_CM3.S deleted file mode 100644 index 587cc089f2a..00000000000 --- a/rtos/rtx/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_IAR/HAL_CM3.S +++ /dev/null @@ -1,265 +0,0 @@ -/*---------------------------------------------------------------------------- - * CMSIS-RTOS - RTX - *---------------------------------------------------------------------------- - * Name: HAL_CM3.S - * Purpose: Hardware Abstraction Layer for Cortex-M3 - * Rev.: V4.70 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - - NAME HAL_CM3.S - - #define TCB_TSTACK 44 - - EXTERN os_flags - EXTERN os_tsk - EXTERN rt_alloc_box - EXTERN rt_free_box - EXTERN rt_stk_check - EXTERN rt_pop_req - EXTERN rt_systick - EXTERN os_tick_irqack - EXTERN SVC_Table - EXTERN SVC_Count - -/*---------------------------------------------------------------------------- - * Functions - *---------------------------------------------------------------------------*/ - - SECTION .text:CODE:NOROOT(2) - THUMB - -/*--------------------------- rt_set_PSP ------------------------------------*/ - -; void rt_set_PSP (U32 stack); - - PUBLIC rt_set_PSP -rt_set_PSP: - - MSR PSP,R0 - BX LR - - -/*--------------------------- rt_get_PSP ------------------------------------*/ - -; U32 rt_get_PSP (void); - - PUBLIC rt_get_PSP -rt_get_PSP: - - MRS R0,PSP - BX LR - - -/*--------------------------- os_set_env ------------------------------------*/ - -; void os_set_env (void); - /* Switch to Unprivileged/Privileged Thread mode, use PSP. */ - - PUBLIC os_set_env -os_set_env: - - MOV R0,SP /* PSP = MSP */ - MSR PSP,R0 - LDR R0,=os_flags - LDRB R0,[R0] - LSLS R0,#31 - ITE NE - MOVNE R0,#0x02 /* Privileged Thread mode, use PSP */ - MOVEQ R0,#0x03 /* Unprivileged Thread mode, use PSP */ - MSR CONTROL,R0 - BX LR - - -/*--------------------------- _alloc_box ------------------------------------*/ - -; void *_alloc_box (void *box_mem); - /* Function wrapper for Unprivileged/Privileged mode. */ - - PUBLIC _alloc_box -_alloc_box: - - LDR R12,=rt_alloc_box - MRS R3,IPSR - LSLS R3,#24 - IT NE - BXNE R12 - MRS R3,CONTROL - LSLS R3,#31 - IT EQ - BXEQ R12 - SVC 0 - BX LR - - -/*--------------------------- _free_box -------------------------------------*/ - -; U32 _free_box (void *box_mem, void *box); - /* Function wrapper for Unprivileged/Privileged mode. */ - - PUBLIC _free_box -_free_box: - - LDR R12,=rt_free_box - MRS R3,IPSR - LSLS R3,#24 - IT NE - BXNE R12 - MRS R3,CONTROL - LSLS R3,#31 - IT EQ - BXEQ R12 - SVC 0 - BX LR - - -/*-------------------------- SVC_Handler ------------------------------------*/ - -; void SVC_Handler (void); - - PUBLIC SVC_Handler -SVC_Handler: - - MRS R0,PSP /* Read PSP */ - LDR R1,[R0,#24] /* Read Saved PC from Stack */ - LDRB R1,[R1,#-2] /* Load SVC Number */ - CBNZ R1,SVC_User - - LDM R0,{R0-R3,R12} /* Read R0-R3,R12 from stack */ - BLX R12 /* Call SVC Function */ - - MRS R12,PSP /* Read PSP */ - STM R12,{R0-R2} /* Store return values */ - - LDR R3,=os_tsk - LDM R3,{R1,R2} /* os_tsk.run, os_tsk.new */ - CMP R1,R2 - BEQ SVC_Exit /* no task switch */ - - CBZ R1,SVC_Next /* Runtask deleted? */ - STMDB R12!,{R4-R11} /* Save Old context */ - STR R12,[R1,#TCB_TSTACK] /* Update os_tsk.run->tsk_stack */ - - PUSH {R2,R3} - BL rt_stk_check /* Check for Stack overflow */ - POP {R2,R3} - -SVC_Next: - STR R2,[R3] /* os_tsk.run = os_tsk.new */ - - LDR R12,[R2,#TCB_TSTACK] /* os_tsk.new->tsk_stack */ - LDMIA R12!,{R4-R11} /* Restore New Context */ - MSR PSP,R12 /* Write PSP */ - -SVC_Exit: - MVN LR,#~0xFFFFFFFD /* set EXC_RETURN value */ - BX LR - - /*------------------- User SVC ------------------------------*/ - -SVC_User: - PUSH {R4,LR} /* Save Registers */ - LDR R2,=SVC_Count - LDR R2,[R2] - CMP R1,R2 - BHI SVC_Done /* Overflow */ - - LDR R4,=SVC_Table-4 - LDR R4,[R4,R1,LSL #2] /* Load SVC Function Address */ - - LDM R0,{R0-R3,R12} /* Read R0-R3,R12 from stack */ - BLX R4 /* Call SVC Function */ - - MRS R12,PSP - STM R12,{R0-R3} /* Function return values */ -SVC_Done: - POP {R4,PC} /* RETI */ - - -/*-------------------------- PendSV_Handler ---------------------------------*/ - -; void PendSV_Handler (void); - - PUBLIC PendSV_Handler -PendSV_Handler: - - BL rt_pop_req - -Sys_Switch: - LDR R3,=os_tsk - LDM R3,{R1,R2} /* os_tsk.run, os_tsk.new */ - CMP R1,R2 - BEQ Sys_Exit - - MRS R12,PSP /* Read PSP */ - STMDB R12!,{R4-R11} /* Save Old context */ - STR R12,[R1,#TCB_TSTACK] /* Update os_tsk.run->tsk_stack */ - - PUSH {R2,R3} - BL rt_stk_check /* Check for Stack overflow */ - POP {R2,R3} - - STR R2,[R3] /* os_tsk.run = os_tsk.new */ - - LDR R12,[R2,#TCB_TSTACK] /* os_tsk.new->tsk_stack */ - LDMIA R12!,{R4-R11} /* Restore New Context */ - MSR PSP,R12 /* Write PSP */ - -Sys_Exit: - MVN LR,#~0xFFFFFFFD /* set EXC_RETURN value */ - BX LR /* Return to Thread Mode */ - - -/*-------------------------- SysTick_Handler --------------------------------*/ - -; void SysTick_Handler (void); - - PUBLIC SysTick_Handler -SysTick_Handler: - - BL rt_systick - B Sys_Switch - - -/*-------------------------- OS_Tick_Handler --------------------------------*/ - -; void OS_Tick_Handler (void); - - PUBLIC OS_Tick_Handler -OS_Tick_Handler: - - BL os_tick_irqack - BL rt_systick - B Sys_Switch - - - END - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ diff --git a/rtos/rtx/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_IAR/SVC_Table.S b/rtos/rtx/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_IAR/SVC_Table.S deleted file mode 100644 index 18710cb2d11..00000000000 --- a/rtos/rtx/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_IAR/SVC_Table.S +++ /dev/null @@ -1,58 +0,0 @@ -;/*---------------------------------------------------------------------------- -; * CMSIS-RTOS - RTX -; *---------------------------------------------------------------------------- -; * Name: SVC_TABLE.S -; * Purpose: Pre-defined SVC Table for Cortex-M -; * Rev.: V4.70 -; *---------------------------------------------------------------------------- -; * -; * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH -; * All rights reserved. -; * Redistribution and use in source and binary forms, with or without -; * modification, are permitted provided that the following conditions are met: -; * - Redistributions of source code must retain the above copyright -; * notice, this list of conditions and the following disclaimer. -; * - Redistributions in binary form must reproduce the above copyright -; * notice, this list of conditions and the following disclaimer in the -; * documentation and/or other materials provided with the distribution. -; * - Neither the name of ARM nor the names of its contributors may be used -; * to endorse or promote products derived from this software without -; * specific prior written permission. -; * -; * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -; * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -; * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -; * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE -; * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -; * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -; * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -; * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -; * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -; * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -; * POSSIBILITY OF SUCH DAMAGE. -; *---------------------------------------------------------------------------*/ - - - NAME SVC_TABLE - SECTION .text:CONST (2) - - PUBLIC SVC_Count - -SVC_Cnt EQU (SVC_End-SVC_Table)/4 -SVC_Count DCD SVC_Cnt - -; Import user SVC functions here. -; IMPORT __SVC_1 - - PUBLIC SVC_Table -SVC_Table -; Insert user SVC functions here. SVC 0 used by RTL Kernel. -; DCD __SVC_1 ; user SVC function - -SVC_End - - END - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ diff --git a/rtos/rtx/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_ARM/HAL_CM4.c b/rtos/rtx/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_ARM/HAL_CM4.c deleted file mode 100644 index cfa5c1da3cd..00000000000 --- a/rtos/rtx/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_ARM/HAL_CM4.c +++ /dev/null @@ -1,327 +0,0 @@ -/*---------------------------------------------------------------------------- - * CMSIS-RTOS - RTX - *---------------------------------------------------------------------------- - * Name: HAL_CM4.C - * Purpose: Hardware Abstraction Layer for Cortex-M4 - * Rev.: V4.79 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -#include "rt_TypeDef.h" -#include "RTX_Config.h" -#include "rt_System.h" -#include "rt_HAL_CM.h" -#include "rt_Task.h" -#include "rt_MemBox.h" - - -/*---------------------------------------------------------------------------- - * Functions - *---------------------------------------------------------------------------*/ - - -/*--------------------------- rt_set_PSP ------------------------------------*/ - -__asm void rt_set_PSP (U32 stack) { - MSR PSP,R0 - BX LR -} - - -/*--------------------------- rt_get_PSP ------------------------------------*/ - -__asm U32 rt_get_PSP (void) { - MRS R0,PSP - BX LR -} - - -/*--------------------------- os_set_env ------------------------------------*/ - -__asm void os_set_env (void) { - /* Switch to Unprivileged/Privileged Thread mode, use PSP. */ - MOV R0,SP ; PSP = MSP - MSR PSP,R0 - LDR R0,=__cpp(&os_flags) - LDRB R0,[R0] - LSLS R0,#31 - MOVNE R0,#0x02 ; Privileged Thread mode, use PSP - MOVEQ R0,#0x03 ; Unprivileged Thread mode, use PSP - MSR CONTROL,R0 - BX LR - - ALIGN -} - - -/*--------------------------- _alloc_box ------------------------------------*/ - -__asm void *_alloc_box (void *box_mem) { - /* Function wrapper for Unprivileged/Privileged mode. */ - LDR R12,=__cpp(rt_alloc_box) - MRS R3,IPSR - LSLS R3,#24 - BXNE R12 - MRS R3,CONTROL - LSLS R3,#31 - BXEQ R12 - SVC 0 - BX LR - - ALIGN -} - - -/*--------------------------- _free_box -------------------------------------*/ - -__asm U32 _free_box (void *box_mem, void *box) { - /* Function wrapper for Unprivileged/Privileged mode. */ - LDR R12,=__cpp(rt_free_box) - MRS R3,IPSR - LSLS R3,#24 - BXNE R12 - MRS R3,CONTROL - LSLS R3,#31 - BXEQ R12 - SVC 0 - BX LR - - ALIGN -} - - -/*-------------------------- SVC_Handler ------------------------------------*/ - -__asm void SVC_Handler (void) { - PRESERVE8 - - IMPORT SVC_Count - IMPORT SVC_Table - IMPORT rt_stk_check - -#ifdef IFX_XMC4XXX - EXPORT SVC_Handler_Veneer -SVC_Handler_Veneer -#endif - - MRS R0,PSP ; Read PSP - LDR R1,[R0,#24] ; Read Saved PC from Stack - LDRB R1,[R1,#-2] ; Load SVC Number - CBNZ R1,SVC_User - - LDM R0,{R0-R3,R12} ; Read R0-R3,R12 from stack - PUSH {R4,LR} ; Save EXC_RETURN - BLX R12 ; Call SVC Function - POP {R4,LR} ; Restore EXC_RETURN - - MRS R12,PSP ; Read PSP - STM R12,{R0-R2} ; Store return values - - LDR R3,=__cpp(&os_tsk) - LDM R3,{R1,R2} ; os_tsk.run, os_tsk.new - CMP R1,R2 -#ifdef IFX_XMC4XXX - PUSHEQ {LR} - POPEQ {PC} -#else - BXEQ LR ; RETI, no task switch -#endif - - CBNZ R1,SVC_ContextSave ; Runtask not deleted? - - TST LR,#0x10 ; is it extended frame? - BNE SVC_ContextRestore - LDR R1,=0xE000EF34 - LDR R0,[R1] ; Load FPCCR - BIC R0,#1 ; Clear LSPACT (Lazy state) - STR R0,[R1] ; Store FPCCR - B SVC_ContextRestore - -SVC_ContextSave - TST LR,#0x10 ; is it extended frame? -#if (__FPU_PRESENT == 1) - VSTMDBEQ R12!,{S16-S31} ; yes, stack also VFP hi-regs -#endif - MOVEQ R0,#0x01 ; os_tsk->stack_frame val - MOVNE R0,#0x00 - STRB R0,[R1,#TCB_STACKF] ; os_tsk.run->stack_frame = val - STMDB R12!,{R4-R11} ; Save Old context - STR R12,[R1,#TCB_TSTACK] ; Update os_tsk.run->tsk_stack - - PUSH {R2,R3} - BL rt_stk_check ; Check for Stack overflow - POP {R2,R3} - -SVC_ContextRestore - STR R2,[R3] ; os_tsk.run = os_tsk.new - - LDR R12,[R2,#TCB_TSTACK] ; os_tsk.new->tsk_stack - LDMIA R12!,{R4-R11} ; Restore New Context - LDRB R0,[R2,#TCB_STACKF] ; Stack Frame - CMP R0,#0 ; Basic/Extended Stack Frame - MVNEQ LR,#:NOT:0xFFFFFFFD ; set EXC_RETURN value - MVNNE LR,#:NOT:0xFFFFFFED -#if (__FPU_PRESENT == 1) - VLDMIANE R12!,{S16-S31} ; restore VFP hi-registers -#endif - MSR PSP,R12 ; Write PSP - -SVC_Exit -#ifdef IFX_XMC4XXX - PUSH {LR} - POP {PC} -#else - BX LR -#endif - - /*------------------- User SVC ------------------------------*/ - -SVC_User - PUSH {R4,LR} ; Save Registers - LDR R2,=SVC_Count - LDR R2,[R2] - CMP R1,R2 - BHI SVC_Done ; Overflow - - LDR R4,=SVC_Table-4 - LDR R4,[R4,R1,LSL #2] ; Load SVC Function Address - - LDM R0,{R0-R3,R12} ; Read R0-R3,R12 from stack - BLX R4 ; Call SVC Function - - MRS R12,PSP - STM R12,{R0-R3} ; Function return values -SVC_Done - POP {R4,PC} ; RETI - - ALIGN -} - - -/*-------------------------- PendSV_Handler ---------------------------------*/ - -__asm void PendSV_Handler (void) { - PRESERVE8 - -#ifdef IFX_XMC4XXX - EXPORT PendSV_Handler_Veneer -PendSV_Handler_Veneer -#endif - - PUSH {R4,LR} ; Save EXC_RETURN - BL __cpp(rt_pop_req) - -Sys_Switch - POP {R4,LR} ; Restore EXC_RETURN - - LDR R3,=__cpp(&os_tsk) - LDM R3,{R1,R2} ; os_tsk.run, os_tsk.new - CMP R1,R2 -#ifdef IFX_XMC4XXX - PUSHEQ {LR} - POPEQ {PC} -#else - BXEQ LR ; RETI, no task switch -#endif - - MRS R12,PSP ; Read PSP - TST LR,#0x10 ; is it extended frame? -#if (__FPU_PRESENT == 1) - VSTMDBEQ R12!,{S16-S31} ; yes, stack also VFP hi-regs -#endif - MOVEQ R0,#0x01 ; os_tsk->stack_frame val - MOVNE R0,#0x00 - STRB R0,[R1,#TCB_STACKF] ; os_tsk.run->stack_frame = val - STMDB R12!,{R4-R11} ; Save Old context - STR R12,[R1,#TCB_TSTACK] ; Update os_tsk.run->tsk_stack - - PUSH {R2,R3} - BL rt_stk_check ; Check for Stack overflow - POP {R2,R3} - - STR R2,[R3] ; os_tsk.run = os_tsk.new - - LDR R12,[R2,#TCB_TSTACK] ; os_tsk.new->tsk_stack - LDMIA R12!,{R4-R11} ; Restore New Context - LDRB R0,[R2,#TCB_STACKF] ; Stack Frame - CMP R0,#0 ; Basic/Extended Stack Frame - MVNEQ LR,#:NOT:0xFFFFFFFD ; set EXC_RETURN value - MVNNE LR,#:NOT:0xFFFFFFED -#if (__FPU_PRESENT == 1) - VLDMIANE R12!,{S16-S31} ; restore VFP hi-regs -#endif - MSR PSP,R12 ; Write PSP - -Sys_Exit -#ifdef IFX_XMC4XXX - PUSH {LR} - POP {PC} -#else - BX LR ; Return to Thread Mode -#endif - - ALIGN -} - - -/*-------------------------- SysTick_Handler --------------------------------*/ - -__asm void SysTick_Handler (void) { - PRESERVE8 - -#ifdef IFX_XMC4XXX - EXPORT SysTick_Handler_Veneer -SysTick_Handler_Veneer -#endif - - PUSH {R4,LR} ; Save EXC_RETURN - BL __cpp(rt_systick) - B Sys_Switch - - ALIGN -} - - -/*-------------------------- OS_Tick_Handler --------------------------------*/ - -__asm void OS_Tick_Handler (void) { - PRESERVE8 - - PUSH {R4,LR} ; Save EXC_RETURN - BL __cpp(os_tick_irqack) - BL __cpp(rt_systick) - B Sys_Switch - - ALIGN -} - - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ - diff --git a/rtos/rtx/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_ARM/SVC_Table.S b/rtos/rtx/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_ARM/SVC_Table.S deleted file mode 100644 index e1289a53bc4..00000000000 --- a/rtos/rtx/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_ARM/SVC_Table.S +++ /dev/null @@ -1,57 +0,0 @@ -;/*---------------------------------------------------------------------------- -; * CMSIS-RTOS - RTX -; *---------------------------------------------------------------------------- -; * Name: SVC_TABLE.S -; * Purpose: Pre-defined SVC Table for Cortex-M -; * Rev.: V4.70 -; *---------------------------------------------------------------------------- -; * -; * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH -; * All rights reserved. -; * Redistribution and use in source and binary forms, with or without -; * modification, are permitted provided that the following conditions are met: -; * - Redistributions of source code must retain the above copyright -; * notice, this list of conditions and the following disclaimer. -; * - Redistributions in binary form must reproduce the above copyright -; * notice, this list of conditions and the following disclaimer in the -; * documentation and/or other materials provided with the distribution. -; * - Neither the name of ARM nor the names of its contributors may be used -; * to endorse or promote products derived from this software without -; * specific prior written permission. -; * -; * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -; * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -; * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -; * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE -; * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -; * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -; * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -; * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -; * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -; * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -; * POSSIBILITY OF SUCH DAMAGE. -; *---------------------------------------------------------------------------*/ - - - AREA SVC_TABLE, CODE, READONLY - - EXPORT SVC_Count - -SVC_Cnt EQU (SVC_End-SVC_Table)/4 -SVC_Count DCD SVC_Cnt - -; Import user SVC functions here. -; IMPORT __SVC_1 - - EXPORT SVC_Table -SVC_Table -; Insert user SVC functions here. SVC 0 used by RTL Kernel. -; DCD __SVC_1 ; user SVC function - -SVC_End - - END - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ diff --git a/rtos/rtx/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_GCC/HAL_CM4.S b/rtos/rtx/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_GCC/HAL_CM4.S deleted file mode 100644 index fc6e31f56aa..00000000000 --- a/rtos/rtx/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_GCC/HAL_CM4.S +++ /dev/null @@ -1,419 +0,0 @@ -/*---------------------------------------------------------------------------- - * CMSIS-RTOS - RTX - *---------------------------------------------------------------------------- - * Name: HAL_CM4.S - * Purpose: Hardware Abstraction Layer for Cortex-M4 - * Rev.: V4.79 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - - .file "HAL_CM4.S" - .syntax unified - - .equ TCB_STACKF, 37 - .equ TCB_TSTACK, 44 - - -/*---------------------------------------------------------------------------- - * Functions - *---------------------------------------------------------------------------*/ - - .thumb - - .section ".text" - .align 2 - - -/*--------------------------- rt_set_PSP ------------------------------------*/ - -# void rt_set_PSP (U32 stack); - - .thumb_func - .type rt_set_PSP, %function - .global rt_set_PSP -rt_set_PSP: - .fnstart - .cantunwind - - MSR PSP,R0 - BX LR - - .fnend - .size rt_set_PSP, .-rt_set_PSP - - -/*--------------------------- rt_get_PSP ------------------------------------*/ - -# U32 rt_get_PSP (void); - - .thumb_func - .type rt_get_PSP, %function - .global rt_get_PSP -rt_get_PSP: - .fnstart - .cantunwind - - MRS R0,PSP - BX LR - - .fnend - .size rt_get_PSP, .-rt_get_PSP - - -/*--------------------------- os_set_env ------------------------------------*/ - -# void os_set_env (void); - /* Switch to Unprivileged/Privileged Thread mode, use PSP. */ - - .thumb_func - .type os_set_env, %function - .global os_set_env -os_set_env: - .fnstart - .cantunwind - - MOV R0,SP /* PSP = MSP */ - MSR PSP,R0 - LDR R0,=os_flags - LDRB R0,[R0] - LSLS R0,#31 - ITE NE - MOVNE R0,#0x02 /* Privileged Thread mode, use PSP */ - MOVEQ R0,#0x03 /* Unprivileged Thread mode, use PSP */ - MSR CONTROL,R0 - BX LR - - .fnend - .size os_set_env, .-os_set_env - - -/*--------------------------- _alloc_box ------------------------------------*/ - -# void *_alloc_box (void *box_mem); - /* Function wrapper for Unprivileged/Privileged mode. */ - - .thumb_func - .type _alloc_box, %function - .global _alloc_box -_alloc_box: - .fnstart - .cantunwind - - LDR R12,=rt_alloc_box - MRS R3,IPSR - LSLS R3,#24 - IT NE - BXNE R12 - MRS R3,CONTROL - LSLS R3,#31 - IT EQ - BXEQ R12 - SVC 0 - BX LR - - .fnend - .size _alloc_box, .-_alloc_box - - -/*--------------------------- _free_box -------------------------------------*/ - -# U32 _free_box (void *box_mem, void *box); - /* Function wrapper for Unprivileged/Privileged mode. */ - - .thumb_func - .type _free_box, %function - .global _free_box -_free_box: - .fnstart - .cantunwind - - LDR R12,=rt_free_box - MRS R3,IPSR - LSLS R3,#24 - IT NE - BXNE R12 - MRS R3,CONTROL - LSLS R3,#31 - IT EQ - BXEQ R12 - SVC 0 - BX LR - - .fnend - .size _free_box, .-_free_box - - -/*-------------------------- SVC_Handler ------------------------------------*/ - -# void SVC_Handler (void); - - .thumb_func - .type SVC_Handler, %function - .global SVC_Handler -SVC_Handler: - .ifdef IFX_XMC4XXX - .global SVC_Handler_Veneer -SVC_Handler_Veneer: - .endif - .fnstart - .cantunwind - - MRS R0,PSP /* Read PSP */ - LDR R1,[R0,#24] /* Read Saved PC from Stack */ - LDRB R1,[R1,#-2] /* Load SVC Number */ - CBNZ R1,SVC_User - - LDM R0,{R0-R3,R12} /* Read R0-R3,R12 from stack */ - PUSH {R4,LR} /* Save EXC_RETURN */ - BLX R12 /* Call SVC Function */ - POP {R4,LR} /* Restore EXC_RETURN */ - - MRS R12,PSP /* Read PSP */ - STM R12,{R0-R2} /* Store return values */ - - LDR R3,=os_tsk - LDM R3,{R1,R2} /* os_tsk.run, os_tsk.new */ - CMP R1,R2 - .ifdef IFX_XMC4XXX - ITT EQ - PUSHEQ {LR} - POPEQ {PC} - .else - IT EQ - BXEQ LR /* RETI, no task switch */ - .endif - - CBNZ R1,SVC_ContextSave /* Runtask not deleted? */ - - TST LR,#0x10 /* is it extended frame? */ - BNE SVC_ContextRestore - LDR R1,=0xE000EF34 - LDR R0,[R1] /* Load FPCCR */ - BIC R0,#1 /* Clear LSPACT (Lazy state) */ - STR R0,[R1] /* Store FPCCR */ - B SVC_ContextRestore - -SVC_ContextSave: - TST LR,#0x10 /* is it extended frame? */ -#ifdef __FPU_PRESENT - ITTE EQ - VSTMDBEQ R12!,{S16-S31} /* yes, stack also VFP hi-regs */ -#else - ITE EQ -#endif - MOVEQ R0,#0x01 /* os_tsk->stack_frame val */ - MOVNE R0,#0x00 - STRB R0,[R1,#TCB_STACKF] /* os_tsk.run->stack_frame = val */ - STMDB R12!,{R4-R11} /* Save Old context */ - STR R12,[R1,#TCB_TSTACK] /* Update os_tsk.run->tsk_stack */ - - PUSH {R2,R3} - BL rt_stk_check /* Check for Stack overflow */ - POP {R2,R3} - -SVC_ContextRestore: - STR R2,[R3] /* os_tsk.run = os_tsk.new */ - - LDR R12,[R2,#TCB_TSTACK] /* os_tsk.new->tsk_stack */ - LDMIA R12!,{R4-R11} /* Restore New Context */ - LDRB R0,[R2,#TCB_STACKF] /* Stack Frame */ - CMP R0,#0 /* Basic/Extended Stack Frame */ -#ifdef __FPU_PRESENT - ITEE EQ -#else - ITE EQ -#endif - MVNEQ LR,#~0xFFFFFFFD /* set EXC_RETURN value */ - MVNNE LR,#~0xFFFFFFED -#ifdef __FPU_PRESENT - VLDMIANE R12!,{S16-S31} /* restore VFP hi-registers */ -#endif - MSR PSP,R12 /* Write PSP */ - -SVC_Exit: - .ifdef IFX_XMC4XXX - PUSH {LR} - POP {PC} - .else - BX LR - .endif - - /*------------------- User SVC ------------------------------*/ - -SVC_User: - PUSH {R4,LR} /* Save Registers */ - LDR R2,=SVC_Count - LDR R2,[R2] - CMP R1,R2 - BHI SVC_Done /* Overflow */ - - LDR R4,=SVC_Table-4 - LDR R4,[R4,R1,LSL #2] /* Load SVC Function Address */ - - LDM R0,{R0-R3,R12} /* Read R0-R3,R12 from stack */ - BLX R4 /* Call SVC Function */ - - MRS R12,PSP - STM R12,{R0-R3} /* Function return values */ -SVC_Done: - POP {R4,PC} /* RETI */ - - .fnend - .size SVC_Handler, .-SVC_Handler - - -/*-------------------------- PendSV_Handler ---------------------------------*/ - -# void PendSV_Handler (void); - - .thumb_func - .type PendSV_Handler, %function - .global PendSV_Handler - .global Sys_Switch -PendSV_Handler: - .ifdef IFX_XMC4XXX - .global PendSV_Handler_Veneer -PendSV_Handler_Veneer: - .endif - .fnstart - .cantunwind - - PUSH {R4,LR} /* Save EXC_RETURN */ - BL rt_pop_req - -Sys_Switch: - POP {R4,LR} /* Restore EXC_RETURN */ - - LDR R3,=os_tsk - LDM R3,{R1,R2} /* os_tsk.run, os_tsk.new */ - CMP R1,R2 - .ifdef IFX_XMC4XXX - ITT EQ - PUSHEQ {LR} - POPEQ {PC} - .else - IT EQ - BXEQ LR /* RETI, no task switch */ - .endif - - MRS R12,PSP /* Read PSP */ - TST LR,#0x10 /* is it extended frame? */ -#ifdef __FPU_PRESENT - ITTE EQ - VSTMDBEQ R12!,{S16-S31} /* yes, stack also VFP hi-regs */ -#else - ITE EQ -#endif - MOVEQ R0,#0x01 /* os_tsk->stack_frame val */ - MOVNE R0,#0x00 - STRB R0,[R1,#TCB_STACKF] /* os_tsk.run->stack_frame = val */ - STMDB R12!,{R4-R11} /* Save Old context */ - STR R12,[R1,#TCB_TSTACK] /* Update os_tsk.run->tsk_stack */ - - PUSH {R2,R3} - BL rt_stk_check /* Check for Stack overflow */ - POP {R2,R3} - - STR R2,[R3] /* os_tsk.run = os_tsk.new */ - - LDR R12,[R2,#TCB_TSTACK] /* os_tsk.new->tsk_stack */ - LDMIA R12!,{R4-R11} /* Restore New Context */ - LDRB R0,[R2,#TCB_STACKF] /* Stack Frame */ - CMP R0,#0 /* Basic/Extended Stack Frame */ -#ifdef __FPU_PRESENT - ITEE EQ -#else - ITE EQ -#endif - MVNEQ LR,#~0xFFFFFFFD /* set EXC_RETURN value */ - MVNNE LR,#~0xFFFFFFED -#ifdef __FPU_PRESENT - VLDMIANE R12!,{S16-S31} /* restore VFP hi-registers */ -#endif - MSR PSP,R12 /* Write PSP */ - -Sys_Exit: - .ifdef IFX_XMC4XXX - PUSH {LR} - POP {PC} - .else - BX LR /* Return to Thread Mode */ - .endif - - .fnend - .size PendSV_Handler, .-PendSV_Handler - - -/*-------------------------- SysTick_Handler --------------------------------*/ - -# void SysTick_Handler (void); - - .thumb_func - .type SysTick_Handler, %function - .global SysTick_Handler -SysTick_Handler: - .ifdef IFX_XMC4XXX - .global SysTick_Handler_Veneer -SysTick_Handler_Veneer: - .endif - .fnstart - .cantunwind - - PUSH {R4,LR} /* Save EXC_RETURN */ - BL rt_systick - B Sys_Switch - - .fnend - .size SysTick_Handler, .-SysTick_Handler - - -/*-------------------------- OS_Tick_Handler --------------------------------*/ - -# void OS_Tick_Handler (void); - - .thumb_func - .type OS_Tick_Handler, %function - .global OS_Tick_Handler -OS_Tick_Handler: - .fnstart - .cantunwind - - PUSH {R4,LR} /* Save EXC_RETURN */ - BL os_tick_irqack - BL rt_systick - B Sys_Switch - - .fnend - .size OS_Tick_Handler, .-OS_Tick_Handler - - - .end - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ diff --git a/rtos/rtx/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_GCC/SVC_Table.S b/rtos/rtx/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_GCC/SVC_Table.S deleted file mode 100644 index d583df13321..00000000000 --- a/rtos/rtx/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_GCC/SVC_Table.S +++ /dev/null @@ -1,56 +0,0 @@ -;/*---------------------------------------------------------------------------- -; * CMSIS-RTOS - RTX -; *---------------------------------------------------------------------------- -; * Name: SVC_TABLE.S -; * Purpose: Pre-defined SVC Table for Cortex-M -; * Rev.: V4.70 -; *---------------------------------------------------------------------------- -; * -; * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH -; * All rights reserved. -; * Redistribution and use in source and binary forms, with or without -; * modification, are permitted provided that the following conditions are met: -; * - Redistributions of source code must retain the above copyright -; * notice, this list of conditions and the following disclaimer. -; * - Redistributions in binary form must reproduce the above copyright -; * notice, this list of conditions and the following disclaimer in the -; * documentation and/or other materials provided with the distribution. -; * - Neither the name of ARM nor the names of its contributors may be used -; * to endorse or promote products derived from this software without -; * specific prior written permission. -; * -; * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -; * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -; * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -; * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE -; * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -; * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -; * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -; * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -; * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -; * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -; * POSSIBILITY OF SUCH DAMAGE. -; *---------------------------------------------------------------------------*/ - - - .file "SVC_Table.S" - - - .section ".svc_table" - - .global SVC_Table -SVC_Table: -/* Insert user SVC functions here. SVC 0 used by RTL Kernel. */ -# .long __SVC_1 /* user SVC function */ -SVC_End: - - .global SVC_Count -SVC_Count: - .long (SVC_End-SVC_Table)/4 - - - .end - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ diff --git a/rtos/rtx/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_IAR/HAL_CM4.S b/rtos/rtx/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_IAR/HAL_CM4.S deleted file mode 100644 index 3b3dc257081..00000000000 --- a/rtos/rtx/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_IAR/HAL_CM4.S +++ /dev/null @@ -1,363 +0,0 @@ -/*---------------------------------------------------------------------------- - * CMSIS-RTOS - RTX - *---------------------------------------------------------------------------- - * Name: HAL_CM4.S - * Purpose: Hardware Abstraction Layer for Cortex-M4 - * Rev.: V4.79 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - - NAME HAL_CM4.S - - #define TCB_STACKF 37 - #define TCB_TSTACK 44 - - EXTERN os_flags - EXTERN os_tsk - EXTERN rt_alloc_box - EXTERN rt_free_box - EXTERN rt_stk_check - EXTERN rt_pop_req - EXTERN rt_systick - EXTERN os_tick_irqack - EXTERN SVC_Table - EXTERN SVC_Count - -/*---------------------------------------------------------------------------- - * Functions - *---------------------------------------------------------------------------*/ - - SECTION .text:CODE:NOROOT(2) - THUMB - -/*--------------------------- rt_set_PSP ------------------------------------*/ - -; void rt_set_PSP (U32 stack); - - PUBLIC rt_set_PSP -rt_set_PSP: - - MSR PSP,R0 - BX LR - - -/*--------------------------- rt_get_PSP ------------------------------------*/ - -; U32 rt_get_PSP (void); - - PUBLIC rt_get_PSP -rt_get_PSP: - - MRS R0,PSP - BX LR - - -/*--------------------------- os_set_env ------------------------------------*/ - -; void os_set_env (void); - /* Switch to Unprivileged/Privileged Thread mode, use PSP. */ - - PUBLIC os_set_env -os_set_env: - - MOV R0,SP /* PSP = MSP */ - MSR PSP,R0 - LDR R0,=os_flags - LDRB R0,[R0] - LSLS R0,#31 - ITE NE - MOVNE R0,#0x02 /* Privileged Thread mode, use PSP */ - MOVEQ R0,#0x03 /* Unprivileged Thread mode, use PSP */ - MSR CONTROL,R0 - BX LR - - -/*--------------------------- _alloc_box ------------------------------------*/ - -; void *_alloc_box (void *box_mem); - /* Function wrapper for Unprivileged/Privileged mode. */ - - PUBLIC _alloc_box -_alloc_box: - - LDR R12,=rt_alloc_box - MRS R3,IPSR - LSLS R3,#24 - IT NE - BXNE R12 - MRS R3,CONTROL - LSLS R3,#31 - IT EQ - BXEQ R12 - SVC 0 - BX LR - - -/*--------------------------- _free_box -------------------------------------*/ - -; U32 _free_box (void *box_mem, void *box); - /* Function wrapper for Unprivileged/Privileged mode. */ - - PUBLIC _free_box -_free_box: - - LDR R12,=rt_free_box - MRS R3,IPSR - LSLS R3,#24 - IT NE - BXNE R12 - MRS R3,CONTROL - LSLS R3,#31 - IT EQ - BXEQ R12 - SVC 0 - BX LR - - -/*-------------------------- SVC_Handler ------------------------------------*/ - -; void SVC_Handler (void); - - PUBLIC SVC_Handler -SVC_Handler: - -#ifdef IFX_XMC4XXX - PUBLIC SVC_Handler_Veneer -SVC_Handler_Veneer: -#endif - - MRS R0,PSP /* Read PSP */ - LDR R1,[R0,#24] /* Read Saved PC from Stack */ - LDRB R1,[R1,#-2] /* Load SVC Number */ - CBNZ R1,SVC_User - - LDM R0,{R0-R3,R12} /* Read R0-R3,R12 from stack */ - PUSH {R4,LR} /* Save EXC_RETURN */ - BLX R12 /* Call SVC Function */ - POP {R4,LR} /* Restore EXC_RETURN */ - - MRS R12,PSP /* Read PSP */ - STM R12,{R0-R2} /* Store return values */ - - LDR R3,=os_tsk - LDM R3,{R1,R2} /* os_tsk.run, os_tsk.new */ - CMP R1,R2 -#ifdef IFX_XMC4XXX - ITT EQ - PUSHEQ {LR} - POPEQ {PC} -#else - IT EQ - BXEQ LR /* RETI, no task switch */ -#endif - - CBNZ R1,SVC_ContextSave /* Runtask not deleted? */ - - TST LR,#0x10 /* is it extended frame? */ - BNE SVC_ContextRestore - LDR R1,=0xE000EF34 - LDR R0,[R1] /* Load FPCCR */ - BIC R0,R0,#1 /* Clear LSPACT (Lazy state) */ - STR R0,[R1] /* Store FPCCR */ - B SVC_ContextRestore - -SVC_ContextSave: - TST LR,#0x10 /* is it extended frame? */ -#if (__FPU_PRESENT == 1) - ITTE EQ - VSTMDBEQ R12!,{S16-S31} /* yes, stack also VFP hi-regs */ -#else - ITE EQ -#endif - MOVEQ R0,#0x01 /* os_tsk->stack_frame val */ - MOVNE R0,#0x00 - STRB R0,[R1,#TCB_STACKF] /* os_tsk.run->stack_frame = val */ - STMDB R12!,{R4-R11} /* Save Old context */ - STR R12,[R1,#TCB_TSTACK] /* Update os_tsk.run->tsk_stack */ - - PUSH {R2,R3} - BL rt_stk_check /* Check for Stack overflow */ - POP {R2,R3} - -SVC_ContextRestore: - STR R2,[R3] /* os_tsk.run = os_tsk.new */ - - LDR R12,[R2,#TCB_TSTACK] /* os_tsk.new->tsk_stack */ - LDMIA R12!,{R4-R11} /* Restore New Context */ - LDRB R0,[R2,#TCB_STACKF] /* Stack Frame */ - CMP R0,#0 /* Basic/Extended Stack Frame */ -#if (__FPU_PRESENT == 1) - ITEE EQ -#else - ITE EQ -#endif - MVNEQ LR,#~0xFFFFFFFD /* set EXC_RETURN value */ - MVNNE LR,#~0xFFFFFFED -#if (__FPU_PRESENT == 1) - VLDMIANE R12!,{S16-S31} /* restore VFP hi-registers */ -#endif - MSR PSP,R12 /* Write PSP */ - -SVC_Exit: -#ifdef IFX_XMC4XXX - PUSH {LR} - POP {PC} -#else - BX LR -#endif - - /*------------------- User SVC ------------------------------*/ - -SVC_User: - PUSH {R4,LR} /* Save Registers */ - LDR R2,=SVC_Count - LDR R2,[R2] - CMP R1,R2 - BHI SVC_Done /* Overflow */ - - LDR R4,=SVC_Table-4 - LDR R4,[R4,R1,LSL #2] /* Load SVC Function Address */ - - LDM R0,{R0-R3,R12} /* Read R0-R3,R12 from stack */ - BLX R4 /* Call SVC Function */ - - MRS R12,PSP - STM R12,{R0-R3} /* Function return values */ -SVC_Done: - POP {R4,PC} /* RETI */ - - -/*-------------------------- PendSV_Handler ---------------------------------*/ - -; void PendSV_Handler (void); - - PUBLIC PendSV_Handler -PendSV_Handler: - -#ifdef IFX_XMC4XXX - PUBLIC PendSV_Handler_Veneer -PendSV_Handler_Veneer: -#endif - - PUSH {R4,LR} /* Save EXC_RETURN */ - BL rt_pop_req - -Sys_Switch: - POP {R4,LR} /* Restore EXC_RETURN */ - - LDR R3,=os_tsk - LDM R3,{R1,R2} /* os_tsk.run, os_tsk.new */ - CMP R1,R2 -#ifdef IFX_XMC4XXX - ITT EQ - PUSHEQ {LR} - POPEQ {PC} -#else - IT EQ - BXEQ LR /* RETI, no task switch */ -#endif - - MRS R12,PSP /* Read PSP */ - TST LR,#0x10 /* is it extended frame? */ -#if (__FPU_PRESENT == 1) - ITTE EQ - VSTMDBEQ R12!,{S16-S31} /* yes, stack also VFP hi-regs */ -#else - ITE EQ -#endif - MOVEQ R0,#0x01 /* os_tsk->stack_frame val */ - MOVNE R0,#0x00 - STRB R0,[R1,#TCB_STACKF] /* os_tsk.run->stack_frame = val */ - STMDB R12!,{R4-R11} /* Save Old context */ - STR R12,[R1,#TCB_TSTACK] /* Update os_tsk.run->tsk_stack */ - - PUSH {R2,R3} - BL rt_stk_check /* Check for Stack overflow */ - POP {R2,R3} - - STR R2,[R3] /* os_tsk.run = os_tsk.new */ - - LDR R12,[R2,#TCB_TSTACK] /* os_tsk.new->tsk_stack */ - LDMIA R12!,{R4-R11} /* Restore New Context */ - LDRB R0,[R2,#TCB_STACKF] /* Stack Frame */ - CMP R0,#0 /* Basic/Extended Stack Frame */ -#if (__FPU_PRESENT == 1) - ITEE EQ -#else - ITE EQ -#endif - MVNEQ LR,#~0xFFFFFFFD /* set EXC_RETURN value */ - MVNNE LR,#~0xFFFFFFED -#if (__FPU_PRESENT == 1) - VLDMIANE R12!,{S16-S31} /* restore VFP hi-registers */ -#endif - MSR PSP,R12 /* Write PSP */ - -Sys_Exit: -#ifdef IFX_XMC4XXX - PUSH {LR} - POP {PC} -#else - BX LR /* Return to Thread Mode */ -#endif - - -/*-------------------------- SysTick_Handler --------------------------------*/ - -; void SysTick_Handler (void); - - PUBLIC SysTick_Handler -SysTick_Handler: -#ifdef IFX_XMC4XXX - PUBLIC SysTick_Handler_Veneer -SysTick_Handler_Veneer: -#endif - - PUSH {R4,LR} /* Save EXC_RETURN */ - BL rt_systick - B Sys_Switch - - -/*-------------------------- OS_Tick_Handler --------------------------------*/ - -; void OS_Tick_Handler (void); - - PUBLIC OS_Tick_Handler -OS_Tick_Handler: - - PUSH {R4,LR} /* Save EXC_RETURN */ - BL os_tick_irqack - BL rt_systick - B Sys_Switch - - - END - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ diff --git a/rtos/rtx/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_IAR/SVC_Table.S b/rtos/rtx/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_IAR/SVC_Table.S deleted file mode 100644 index 18710cb2d11..00000000000 --- a/rtos/rtx/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_IAR/SVC_Table.S +++ /dev/null @@ -1,58 +0,0 @@ -;/*---------------------------------------------------------------------------- -; * CMSIS-RTOS - RTX -; *---------------------------------------------------------------------------- -; * Name: SVC_TABLE.S -; * Purpose: Pre-defined SVC Table for Cortex-M -; * Rev.: V4.70 -; *---------------------------------------------------------------------------- -; * -; * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH -; * All rights reserved. -; * Redistribution and use in source and binary forms, with or without -; * modification, are permitted provided that the following conditions are met: -; * - Redistributions of source code must retain the above copyright -; * notice, this list of conditions and the following disclaimer. -; * - Redistributions in binary form must reproduce the above copyright -; * notice, this list of conditions and the following disclaimer in the -; * documentation and/or other materials provided with the distribution. -; * - Neither the name of ARM nor the names of its contributors may be used -; * to endorse or promote products derived from this software without -; * specific prior written permission. -; * -; * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -; * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -; * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -; * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE -; * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -; * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -; * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -; * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -; * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -; * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -; * POSSIBILITY OF SUCH DAMAGE. -; *---------------------------------------------------------------------------*/ - - - NAME SVC_TABLE - SECTION .text:CONST (2) - - PUBLIC SVC_Count - -SVC_Cnt EQU (SVC_End-SVC_Table)/4 -SVC_Count DCD SVC_Cnt - -; Import user SVC functions here. -; IMPORT __SVC_1 - - PUBLIC SVC_Table -SVC_Table -; Insert user SVC functions here. SVC 0 used by RTL Kernel. -; DCD __SVC_1 ; user SVC function - -SVC_End - - END - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ diff --git a/rtos/rtx/TARGET_CORTEX_M/cmsis_os.h b/rtos/rtx/TARGET_CORTEX_M/cmsis_os.h deleted file mode 100644 index b1ab4b7ff9c..00000000000 --- a/rtos/rtx/TARGET_CORTEX_M/cmsis_os.h +++ /dev/null @@ -1,747 +0,0 @@ - -/** \addtogroup rtos */ -/** @{*/ -/* ---------------------------------------------------------------------- - * $Date: 5. February 2013 - * $Revision: V1.02 - * - * Project: CMSIS-RTOS API - * Title: cmsis_os.h RTX header file - * - * Version 0.02 - * Initial Proposal Phase - * Version 0.03 - * osKernelStart added, optional feature: main started as thread - * osSemaphores have standard behavior - * osTimerCreate does not start the timer, added osTimerStart - * osThreadPass is renamed to osThreadYield - * Version 1.01 - * Support for C++ interface - * - const attribute removed from the osXxxxDef_t typedef's - * - const attribute added to the osXxxxDef macros - * Added: osTimerDelete, osMutexDelete, osSemaphoreDelete - * Added: osKernelInitialize - * Version 1.02 - * Control functions for short timeouts in microsecond resolution: - * Added: osKernelSysTick, osKernelSysTickFrequency, osKernelSysTickMicroSec - * Removed: osSignalGet - *---------------------------------------------------------------------------- - * - * Copyright (c) 2013 ARM LIMITED - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - - -#ifndef _CMSIS_OS_H -#define _CMSIS_OS_H - -#define CMSIS_OS_RTX - -// __MBED_CMSIS_RTOS_CM captures our changes to the RTX kernel -#ifndef __MBED_CMSIS_RTOS_CM -#define __MBED_CMSIS_RTOS_CM -#endif -// we use __CMSIS_RTOS version, which changes some API in the kernel -#ifndef __CMSIS_RTOS -#define __CMSIS_RTOS -#endif - -// The stack space occupied is mainly dependent on the underling C standard library -#if defined(TOOLCHAIN_GCC) || defined(TOOLCHAIN_ARM_STD) || defined(TOOLCHAIN_IAR) -# define WORDS_STACK_SIZE 512 -#elif defined(TOOLCHAIN_ARM_MICRO) -# define WORDS_STACK_SIZE 128 -#endif - -#ifdef __MBED_CMSIS_RTOS_CM - -/* Single thread - disable timers and set task count to one */ -#if defined(MBED_RTOS_SINGLE_THREAD) -#define OS_TASKCNT 1 -#define OS_TIMERS 0 -#endif - -#endif - -#if defined(TARGET_XDOT_L151CC) -#define DEFAULT_STACK_SIZE (WORDS_STACK_SIZE/2) -#else -#define DEFAULT_STACK_SIZE (WORDS_STACK_SIZE*4) -#endif - -#define osCMSIS 0x10002U ///< CMSIS-RTOS API version (main [31:16] .sub [15:0]) - -#define osCMSIS_RTX ((4<<16)|80) ///< RTOS identification and version (main [31:16] .sub [15:0]) - -#define osKernelSystemId "RTX V4.80" ///< RTOS identification string - - -#define osFeature_MainThread 1 ///< main can be thread -#define osFeature_Pool 1 ///< Memory Pools available -#define osFeature_MailQ 1 ///< Mail Queues available -#define osFeature_MessageQ 1 ///< Message Queues available -#define osFeature_Signals 16 ///< 16 Signal Flags available per thread -#define osFeature_Semaphore 65535 ///< Maximum count for \ref osSemaphoreCreate function -#define osFeature_Wait 0 ///< osWait not available -#define osFeature_SysTick 1 ///< osKernelSysTick functions available -#define osFeature_ThreadEnum 1 ///< Thread enumeration available - -#if defined (__CC_ARM) -#define os_InRegs __value_in_regs // Compiler specific: force struct in registers -#elif defined (__ICCARM__) -#define os_InRegs __value_in_regs // Compiler specific: force struct in registers -#else -#define os_InRegs -#endif - -#include -#include - -#ifdef __cplusplus -extern "C" -{ -#endif - -// ==== Enumeration, structures, defines ==== - -/// Priority used for thread control. -typedef enum { - osPriorityIdle = -3, ///< priority: idle (lowest) - osPriorityLow = -2, ///< priority: low - osPriorityBelowNormal = -1, ///< priority: below normal - osPriorityNormal = 0, ///< priority: normal (default) - osPriorityAboveNormal = +1, ///< priority: above normal - osPriorityHigh = +2, ///< priority: high - osPriorityRealtime = +3, ///< priority: realtime (highest) - osPriorityError = 0x84 ///< system cannot determine priority or thread has illegal priority -} osPriority; - -/// Timeout value. -#define osWaitForever 0xFFFFFFFFU ///< wait forever timeout value - -/// Status code values returned by CMSIS-RTOS functions. -typedef enum { - osOK = 0, ///< function completed; no error or event occurred. - osEventSignal = 0x08, ///< function completed; signal event occurred. - osEventMessage = 0x10, ///< function completed; message event occurred. - osEventMail = 0x20, ///< function completed; mail event occurred. - osEventTimeout = 0x40, ///< function completed; timeout occurred. - osErrorParameter = 0x80, ///< parameter error: a mandatory parameter was missing or specified an incorrect object. - osErrorResource = 0x81, ///< resource not available: a specified resource was not available. - osErrorTimeoutResource = 0xC1, ///< resource not available within given time: a specified resource was not available within the timeout period. - osErrorISR = 0x82, ///< not allowed in ISR context: the function cannot be called from interrupt service routines. - osErrorISRRecursive = 0x83, ///< function called multiple times from ISR with same object. - osErrorPriority = 0x84, ///< system cannot determine priority or thread has illegal priority. - osErrorNoMemory = 0x85, ///< system is out of memory: it was impossible to allocate or reserve memory for the operation. - osErrorValue = 0x86, ///< value of a parameter is out of range. - osErrorOS = 0xFF, ///< unspecified RTOS error: run-time error but no other error message fits. - os_status_reserved = 0x7FFFFFFF ///< prevent from enum down-size compiler optimization. -} osStatus; - - -/// Timer type value for the timer definition. -typedef enum { - osTimerOnce = 0, ///< one-shot timer - osTimerPeriodic = 1 ///< repeating timer -} os_timer_type; - -typedef enum { - osThreadInfoState, - osThreadInfoStackSize, - osThreadInfoStackMax, - osThreadInfoEntry, - osThreadInfoArg, - - osThreadInfo_reserved = 0x7FFFFFFF ///< prevent from enum down-size compiler optimization. -} osThreadInfo; - -/// Entry point of a thread. -typedef void (*os_pthread) (void const *argument); - -/// Entry point of a timer call back function. -typedef void (*os_ptimer) (void const *argument); - -// >>> the following data type definitions may shall adapted towards a specific RTOS - -/// Thread ID identifies the thread (pointer to a thread control block). -typedef struct os_thread_cb *osThreadId; - -/// Timer ID identifies the timer (pointer to a timer control block). -typedef struct os_timer_cb *osTimerId; - -/// Mutex ID identifies the mutex (pointer to a mutex control block). -typedef struct os_mutex_cb *osMutexId; - -/// Semaphore ID identifies the semaphore (pointer to a semaphore control block). -typedef struct os_semaphore_cb *osSemaphoreId; - -/// Pool ID identifies the memory pool (pointer to a memory pool control block). -typedef struct os_pool_cb *osPoolId; - -/// Message ID identifies the message queue (pointer to a message queue control block). -typedef struct os_messageQ_cb *osMessageQId; - -/// Mail ID identifies the mail queue (pointer to a mail queue control block). -typedef struct os_mailQ_cb *osMailQId; - -/// Thread enumeration ID identifies the enumeration (pointer to a thread enumeration control block). -typedef uint32_t *osThreadEnumId; - -/// Thread Definition structure contains startup information of a thread. -typedef struct os_thread_def { - os_pthread pthread; ///< start address of thread function - osPriority tpriority; ///< initial thread priority - uint32_t instances; ///< maximum number of instances of that thread function - uint32_t stacksize; ///< stack size requirements in bytes; 0 is default stack size -#ifdef __MBED_CMSIS_RTOS_CM - uint32_t *stack_pointer; ///< pointer to the stack memory block -#endif -} osThreadDef_t; - -/// Timer Definition structure contains timer parameters. -typedef struct os_timer_def { - os_ptimer ptimer; ///< start address of a timer function - void *timer; ///< pointer to internal data -} osTimerDef_t; - -/// Mutex Definition structure contains setup information for a mutex. -typedef struct os_mutex_def { - void *mutex; ///< pointer to internal data -} osMutexDef_t; - -/// Semaphore Definition structure contains setup information for a semaphore. -typedef struct os_semaphore_def { - void *semaphore; ///< pointer to internal data -} osSemaphoreDef_t; - -/// Definition structure for memory block allocation. -typedef struct os_pool_def { - uint32_t pool_sz; ///< number of items (elements) in the pool - uint32_t item_sz; ///< size of an item - void *pool; ///< pointer to memory for pool -} osPoolDef_t; - -/// Definition structure for message queue. -typedef struct os_messageQ_def { - uint32_t queue_sz; ///< number of elements in the queue - void *pool; ///< memory array for messages -} osMessageQDef_t; - -/// Definition structure for mail queue. -typedef struct os_mailQ_def { - uint32_t queue_sz; ///< number of elements in the queue - uint32_t item_sz; ///< size of an item - void *pool; ///< memory array for mail -} osMailQDef_t; - -/// Event structure contains detailed information about an event. -typedef struct { - osStatus status; ///< status code: event or error information - union { - uint32_t v; ///< message as 32-bit value - void *p; ///< message or mail as void pointer - int32_t signals; ///< signal flags - } value; ///< event value - union { - osMailQId mail_id; ///< mail id obtained by \ref osMailCreate - osMessageQId message_id; ///< message id obtained by \ref osMessageCreate - } def; ///< event definition -} osEvent; - - -// ==== Kernel Control Functions ==== - -/// Initialize the RTOS Kernel for creating objects. -/// \return status code that indicates the execution status of the function. -osStatus osKernelInitialize (void); - -/// Start the RTOS Kernel. -/// \return status code that indicates the execution status of the function. -osStatus osKernelStart (void); - -/// Check if the RTOS kernel is already started. -/// \return 0 RTOS is not started, 1 RTOS is started. -int32_t osKernelRunning(void); - -#if (defined (osFeature_SysTick) && (osFeature_SysTick != 0)) // System Timer available - -/// \cond INTERNAL_VARIABLES -extern uint32_t const os_tickfreq; -extern uint16_t const os_tickus_i; -extern uint16_t const os_tickus_f; -/// \endcond - -/// Get the RTOS kernel system timer counter. -/// \return RTOS kernel system timer as 32-bit value -uint32_t osKernelSysTick (void); - -/// The RTOS kernel system timer frequency in Hz. -/// \note Reflects the system timer setting and is typically defined in a configuration file. -#define osKernelSysTickFrequency os_tickfreq - -/// Convert a microseconds value to a RTOS kernel system timer value. -/// \param microsec time value in microseconds. -/// \return time value normalized to the \ref osKernelSysTickFrequency -/* -#define osKernelSysTickMicroSec(microsec) (((uint64_t)microsec * (osKernelSysTickFrequency)) / 1000000) -*/ -#define osKernelSysTickMicroSec(microsec) ((microsec * os_tickus_i) + ((microsec * os_tickus_f) >> 16)) - -#endif // System Timer available - -// ==== Thread Management ==== - -/// Create a Thread Definition with function, priority, and stack requirements. -/// \param name name of the thread function. -/// \param priority initial priority of the thread function. -/// \param instances number of possible thread instances. -/// \param stacksz stack size (in bytes) requirements for the thread function. -/// macro body is implementation specific in every CMSIS-RTOS. -#if defined (osObjectsExternal) // object is external -#define osThreadDef(name, priority, instances, stacksz) \ -extern const osThreadDef_t os_thread_def_##name -#else // define the object -#ifdef __MBED_CMSIS_RTOS_CM -#define osThreadDef(name, priority, stacksz) \ -uint32_t os_thread_def_stack_##name [stacksz / sizeof(uint32_t)]; \ -const osThreadDef_t os_thread_def_##name = \ -{ (name), (priority), 1, (stacksz), (os_thread_def_stack_##name) } -#else -#define osThreadDef(name, priority, instances, stacksz) \ -const osThreadDef_t os_thread_def_##name = \ -{ (name), (priority), (instances), (stacksz) } -#endif -#endif - -/// Access a Thread definition. -/// \param name name of the thread definition object. -/// macro body is implementation specific in every CMSIS-RTOS. -#define osThread(name) \ -&os_thread_def_##name - -/// Create a thread and add it to Active Threads and set it to state READY. -/// \param[in] thread_def thread definition referenced with \ref osThread. -/// \param[in] argument pointer that is passed to the thread function as start argument. -/// \return thread ID for reference by other functions or NULL in case of error. -osThreadId osThreadCreate (const osThreadDef_t *thread_def, void *argument); - -osThreadId osThreadContextCreate (const osThreadDef_t *thread_def, void *argument, void *context); - -/// Return the thread ID of the current running thread. -/// \return thread ID for reference by other functions or NULL in case of error. -osThreadId osThreadGetId (void); - -/// Terminate execution of a thread and remove it from Active Threads. -/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. -/// \return status code that indicates the execution status of the function. -osStatus osThreadTerminate (osThreadId thread_id); - -/// Pass control to next thread that is in state \b READY. -/// \return status code that indicates the execution status of the function. -osStatus osThreadYield (void); - -/// Change priority of an active thread. -/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. -/// \param[in] priority new priority value for the thread function. -/// \return status code that indicates the execution status of the function. -osStatus osThreadSetPriority (osThreadId thread_id, osPriority priority); - -/// Get current priority of an active thread. -/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. -/// \return current priority value of the thread function. -osPriority osThreadGetPriority (osThreadId thread_id); - -#ifdef __MBED_CMSIS_RTOS_CM -/// Get current thread state. -uint8_t osThreadGetState (osThreadId thread_id); -#endif - -/// Get into from an active thread. -/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. -/// \param[in] info information to read. -/// \return current state of the thread function. -/// \return requested info that includes the status code. -os_InRegs osEvent _osThreadGetInfo(osThreadId thread_id, osThreadInfo info); - -// ==== Generic Wait Functions ==== - -/// Wait for Timeout (Time Delay). -/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue "Time delay" value -/// \return status code that indicates the execution status of the function. -osStatus osDelay (uint32_t millisec); - -#if (defined (osFeature_Wait) && (osFeature_Wait != 0)) // Generic Wait available - -/// Wait for Signal, Message, Mail, or Timeout. -/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out -/// \return event that contains signal, message, or mail information or error code. -os_InRegs osEvent osWait (uint32_t millisec); - -#endif // Generic Wait available - - -// ==== Timer Management Functions ==== -/// Define a Timer object. -/// \param name name of the timer object. -/// \param function name of the timer call back function. -#if defined (osObjectsExternal) // object is external -#define osTimerDef(name, function) \ -extern const osTimerDef_t os_timer_def_##name -#else // define the object -#define osTimerDef(name, function) \ -uint32_t os_timer_cb_##name[6]; \ -const osTimerDef_t os_timer_def_##name = \ -{ (function), (os_timer_cb_##name) } -#endif - -/// Access a Timer definition. -/// \param name name of the timer object. -#define osTimer(name) \ -&os_timer_def_##name - -/// Create a timer. -/// \param[in] timer_def timer object referenced with \ref osTimer. -/// \param[in] type osTimerOnce for one-shot or osTimerPeriodic for periodic behavior. -/// \param[in] argument argument to the timer call back function. -/// \return timer ID for reference by other functions or NULL in case of error. -osTimerId osTimerCreate (const osTimerDef_t *timer_def, os_timer_type type, void *argument); - -/// Start or restart a timer. -/// \param[in] timer_id timer ID obtained by \ref osTimerCreate. -/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue "Time delay" value of the timer. -/// \return status code that indicates the execution status of the function. -osStatus osTimerStart (osTimerId timer_id, uint32_t millisec); - -/// Stop the timer. -/// \param[in] timer_id timer ID obtained by \ref osTimerCreate. -/// \return status code that indicates the execution status of the function. -osStatus osTimerStop (osTimerId timer_id); - -/// Delete a timer that was created by \ref osTimerCreate. -/// \param[in] timer_id timer ID obtained by \ref osTimerCreate. -/// \return status code that indicates the execution status of the function. -osStatus osTimerDelete (osTimerId timer_id); - - -// ==== Signal Management ==== - -/// Set the specified Signal Flags of an active thread. -/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. -/// \param[in] signals specifies the signal flags of the thread that should be set. -/// \return previous signal flags of the specified thread or 0x80000000 in case of incorrect parameters. -int32_t osSignalSet (osThreadId thread_id, int32_t signals); - -/// Clear the specified Signal Flags of an active thread. -/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. -/// \param[in] signals specifies the signal flags of the thread that shall be cleared. -/// \return previous signal flags of the specified thread or 0x80000000 in case of incorrect parameters or call from ISR. -int32_t osSignalClear (osThreadId thread_id, int32_t signals); - -/// Wait for one or more Signal Flags to become signaled for the current \b RUNNING thread. -/// \param[in] signals wait until all specified signal flags set or 0 for any single signal flag. -/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. -/// \return event flag information or error code. -os_InRegs osEvent osSignalWait (int32_t signals, uint32_t millisec); - - -// ==== Mutex Management ==== - -/// Define a Mutex. -/// \param name name of the mutex object. -#if defined (osObjectsExternal) // object is external -#define osMutexDef(name) \ -extern const osMutexDef_t os_mutex_def_##name -#else // define the object -#define osMutexDef(name) \ -uint32_t os_mutex_cb_##name[4] = { 0 }; \ -const osMutexDef_t os_mutex_def_##name = { (os_mutex_cb_##name) } -#endif - -/// Access a Mutex definition. -/// \param name name of the mutex object. -#define osMutex(name) \ -&os_mutex_def_##name - -/// Create and Initialize a Mutex object. -/// \param[in] mutex_def mutex definition referenced with \ref osMutex. -/// \return mutex ID for reference by other functions or NULL in case of error. -osMutexId osMutexCreate (const osMutexDef_t *mutex_def); - -/// Wait until a Mutex becomes available. -/// \param[in] mutex_id mutex ID obtained by \ref osMutexCreate. -/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. -/// \return status code that indicates the execution status of the function. -osStatus osMutexWait (osMutexId mutex_id, uint32_t millisec); - -/// Release a Mutex that was obtained by \ref osMutexWait. -/// \param[in] mutex_id mutex ID obtained by \ref osMutexCreate. -/// \return status code that indicates the execution status of the function. -osStatus osMutexRelease (osMutexId mutex_id); - -/// Delete a Mutex that was created by \ref osMutexCreate. -/// \param[in] mutex_id mutex ID obtained by \ref osMutexCreate. -/// \return status code that indicates the execution status of the function. -osStatus osMutexDelete (osMutexId mutex_id); - - -// ==== Semaphore Management Functions ==== - -#if (defined (osFeature_Semaphore) && (osFeature_Semaphore != 0)) // Semaphore available - -/// Define a Semaphore object. -/// \param name name of the semaphore object. -#if defined (osObjectsExternal) // object is external -#define osSemaphoreDef(name) \ -extern const osSemaphoreDef_t os_semaphore_def_##name -#else // define the object -#define osSemaphoreDef(name) \ -uint32_t os_semaphore_cb_##name[2] = { 0 }; \ -const osSemaphoreDef_t os_semaphore_def_##name = { (os_semaphore_cb_##name) } -#endif - -/// Access a Semaphore definition. -/// \param name name of the semaphore object. -#define osSemaphore(name) \ -&os_semaphore_def_##name - -/// Create and Initialize a Semaphore object used for managing resources. -/// \param[in] semaphore_def semaphore definition referenced with \ref osSemaphore. -/// \param[in] count number of available resources. -/// \return semaphore ID for reference by other functions or NULL in case of error. -osSemaphoreId osSemaphoreCreate (const osSemaphoreDef_t *semaphore_def, int32_t count); - -/// Wait until a Semaphore token becomes available. -/// \param[in] semaphore_id semaphore object referenced with \ref osSemaphoreCreate. -/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. -/// \return number of available tokens, or -1 in case of incorrect parameters. -int32_t osSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec); - -/// Release a Semaphore token. -/// \param[in] semaphore_id semaphore object referenced with \ref osSemaphoreCreate. -/// \return status code that indicates the execution status of the function. -osStatus osSemaphoreRelease (osSemaphoreId semaphore_id); - -/// Delete a Semaphore that was created by \ref osSemaphoreCreate. -/// \param[in] semaphore_id semaphore object referenced with \ref osSemaphoreCreate. -/// \return status code that indicates the execution status of the function. -osStatus osSemaphoreDelete (osSemaphoreId semaphore_id); - -#endif // Semaphore available - - -// ==== Memory Pool Management Functions ==== - -#if (defined (osFeature_Pool) && (osFeature_Pool != 0)) // Memory Pool Management available - -/// \brief Define a Memory Pool. -/// \param name name of the memory pool. -/// \param no maximum number of blocks (objects) in the memory pool. -/// \param type data type of a single block (object). -#if defined (osObjectsExternal) // object is external -#define osPoolDef(name, no, type) \ -extern const osPoolDef_t os_pool_def_##name -#else // define the object -#define osPoolDef(name, no, type) \ -uint32_t os_pool_m_##name[3+((sizeof(type)+3)/4)*(no)]; \ -const osPoolDef_t os_pool_def_##name = \ -{ (no), sizeof(type), (os_pool_m_##name) } -#endif - -/// \brief Access a Memory Pool definition. -/// \param name name of the memory pool -#define osPool(name) \ -&os_pool_def_##name - -/// Create and Initialize a memory pool. -/// \param[in] pool_def memory pool definition referenced with \ref osPool. -/// \return memory pool ID for reference by other functions or NULL in case of error. -osPoolId osPoolCreate (const osPoolDef_t *pool_def); - -/// Allocate a memory block from a memory pool. -/// \param[in] pool_id memory pool ID obtain referenced with \ref osPoolCreate. -/// \return address of the allocated memory block or NULL in case of no memory available. -void *osPoolAlloc (osPoolId pool_id); - -/// Allocate a memory block from a memory pool and set memory block to zero. -/// \param[in] pool_id memory pool ID obtain referenced with \ref osPoolCreate. -/// \return address of the allocated memory block or NULL in case of no memory available. -void *osPoolCAlloc (osPoolId pool_id); - -/// Return an allocated memory block back to a specific memory pool. -/// \param[in] pool_id memory pool ID obtain referenced with \ref osPoolCreate. -/// \param[in] block address of the allocated memory block that is returned to the memory pool. -/// \return status code that indicates the execution status of the function. -osStatus osPoolFree (osPoolId pool_id, void *block); - -#endif // Memory Pool Management available - - -// ==== Message Queue Management Functions ==== - -#if (defined (osFeature_MessageQ) && (osFeature_MessageQ != 0)) // Message Queues available - -/// \brief Create a Message Queue Definition. -/// \param name name of the queue. -/// \param queue_sz maximum number of messages in the queue. -/// \param type data type of a single message element (for debugger). -#if defined (osObjectsExternal) // object is external -#define osMessageQDef(name, queue_sz, type) \ -extern const osMessageQDef_t os_messageQ_def_##name -#else // define the object -#define osMessageQDef(name, queue_sz, type) \ -uint32_t os_messageQ_q_##name[4+(queue_sz)] = { 0 }; \ -const osMessageQDef_t os_messageQ_def_##name = \ -{ (queue_sz), (os_messageQ_q_##name) } -#endif - -/// \brief Access a Message Queue Definition. -/// \param name name of the queue -#define osMessageQ(name) \ -&os_messageQ_def_##name - -/// Create and Initialize a Message Queue. -/// \param[in] queue_def queue definition referenced with \ref osMessageQ. -/// \param[in] thread_id thread ID (obtained by \ref osThreadCreate or \ref osThreadGetId) or NULL. -/// \return message queue ID for reference by other functions or NULL in case of error. -osMessageQId osMessageCreate (const osMessageQDef_t *queue_def, osThreadId thread_id); - -/// Put a Message to a Queue. -/// \param[in] queue_id message queue ID obtained with \ref osMessageCreate. -/// \param[in] info message information. -/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. -/// \return status code that indicates the execution status of the function. -osStatus osMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec); - -/// Get a Message or Wait for a Message from a Queue. -/// \param[in] queue_id message queue ID obtained with \ref osMessageCreate. -/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. -/// \return event information that includes status code. -os_InRegs osEvent osMessageGet (osMessageQId queue_id, uint32_t millisec); - -#endif // Message Queues available - - -// ==== Mail Queue Management Functions ==== - -#if (defined (osFeature_MailQ) && (osFeature_MailQ != 0)) // Mail Queues available - -/// \brief Create a Mail Queue Definition. -/// \param name name of the queue -/// \param queue_sz maximum number of messages in queue -/// \param type data type of a single message element -#if defined (osObjectsExternal) // object is external -#define osMailQDef(name, queue_sz, type) \ -extern const osMailQDef_t os_mailQ_def_##name -#else // define the object -#define osMailQDef(name, queue_sz, type) \ -uint32_t os_mailQ_q_##name[4+(queue_sz)] = { 0 }; \ -uint32_t os_mailQ_m_##name[3+((sizeof(type)+3)/4)*(queue_sz)]; \ -void * os_mailQ_p_##name[2] = { (os_mailQ_q_##name), os_mailQ_m_##name }; \ -const osMailQDef_t os_mailQ_def_##name = \ -{ (queue_sz), sizeof(type), (os_mailQ_p_##name) } -#endif - -/// \brief Access a Mail Queue Definition. -/// \param name name of the queue -#define osMailQ(name) \ -&os_mailQ_def_##name - -/// Create and Initialize mail queue. -/// \param[in] queue_def reference to the mail queue definition obtain with \ref osMailQ -/// \param[in] thread_id thread ID (obtained by \ref osThreadCreate or \ref osThreadGetId) or NULL. -/// \return mail queue ID for reference by other functions or NULL in case of error. -osMailQId osMailCreate (const osMailQDef_t *queue_def, osThreadId thread_id); - -/// Allocate a memory block from a mail. -/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. -/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out -/// \return pointer to memory block that can be filled with mail or NULL in case of error. -void *osMailAlloc (osMailQId queue_id, uint32_t millisec); - -/// Allocate a memory block from a mail and set memory block to zero. -/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. -/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out -/// \return pointer to memory block that can be filled with mail or NULL in case of error. -void *osMailCAlloc (osMailQId queue_id, uint32_t millisec); - -/// Put a mail to a queue. -/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. -/// \param[in] mail memory block previously allocated with \ref osMailAlloc or \ref osMailCAlloc. -/// \return status code that indicates the execution status of the function. -osStatus osMailPut (osMailQId queue_id, void *mail); - -/// Get a mail from a queue. -/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. -/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out -/// \return event that contains mail information or error code. -os_InRegs osEvent osMailGet (osMailQId queue_id, uint32_t millisec); - -/// Free a memory block from a mail. -/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. -/// \param[in] mail pointer to the memory block that was obtained with \ref osMailGet. -/// \return status code that indicates the execution status of the function. -osStatus osMailFree (osMailQId queue_id, void *mail); - -#endif // Mail Queues available - - -// ==== Thread Enumeration Functions ==== - -#if (defined (osFeature_ThreadEnum) && (osFeature_ThreadEnum != 0)) // Thread enumeration available - -/// Start a thread enumeration. -/// \return an enumeration ID or NULL on error. -osThreadEnumId _osThreadsEnumStart(void); - -/// Get the next task ID in the enumeration. -/// \return a thread ID or NULL on if the end of the enumeration has been reached. -osThreadId _osThreadEnumNext(osThreadEnumId enum_id); - -/// Free the enumeration structure. -/// \param[in] enum_id pointer to the enumeration ID that was obtained with \ref _osThreadsEnumStart. -/// \return status code that indicates the execution status of the function. -osStatus _osThreadEnumFree(osThreadEnumId enum_id); - -#endif // Thread Enumeration available - - -// ==== RTX Extensions ==== - -/// Suspend the RTX task scheduler. -/// \return number of ticks, for how long the system can sleep or power-down. -uint32_t os_suspend (void); - -/// Resume the RTX task scheduler -/// \param[in] sleep_time specifies how long the system was in sleep or power-down mode. -void os_resume (uint32_t sleep_time); - - -#ifdef __cplusplus -} -#endif - -#endif // _CMSIS_OS_H - -/** @}*/ diff --git a/rtos/rtx/TARGET_CORTEX_M/rt_CMSIS.c b/rtos/rtx/TARGET_CORTEX_M/rt_CMSIS.c deleted file mode 100644 index e5ebbbf2380..00000000000 --- a/rtos/rtx/TARGET_CORTEX_M/rt_CMSIS.c +++ /dev/null @@ -1,2344 +0,0 @@ -/*---------------------------------------------------------------------------- - * CMSIS-RTOS - RTX - *---------------------------------------------------------------------------- - * Name: rt_CMSIS.c - * Purpose: CMSIS RTOS API - * Rev.: V4.80 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -#define __CMSIS_GENERIC - -#if defined (__CORTEX_M4) || defined (__CORTEX_M4F) - #include "core_cm4.h" -#elif defined (__CORTEX_M7) || defined (__CORTEX_M7F) - #include "core_cm7.h" -#elif defined (__CORTEX_M3) - #include "core_cm3.h" -#elif defined (__CORTEX_M0) - #include "core_cm0.h" -#elif defined (__CORTEX_M0PLUS) - #include "core_cm0plus.h" -#else - #error "Missing __CORTEX_Mx definition" -#endif - -// This affects cmsis_os only, as it's not used anywhere else. This was left by kernel team -// to suppress the warning in rt_tid2ptcb about incompatible pointer assignment. -#define os_thread_cb OS_TCB - -#include "rt_TypeDef.h" -#include "RTX_Config.h" -#include "rt_System.h" -#include "rt_Task.h" -#include "rt_Event.h" -#include "rt_List.h" -#include "rt_Time.h" -#include "rt_Mutex.h" -#include "rt_Semaphore.h" -#include "rt_Mailbox.h" -#include "rt_MemBox.h" -#include "rt_Memory.h" -#include "rt_HAL_CM.h" -#include "rt_OsEventObserver.h" - -#include "cmsis_os.h" - -#if (osFeature_Signals != 16) -#error Invalid "osFeature_Signals" value! -#endif -#if (osFeature_Semaphore > 65535) -#error Invalid "osFeature_Semaphore" value! -#endif -#if (osFeature_Wait != 0) -#error osWait not supported! -#endif - - -// ==== Enumeration, structures, defines ==== - -// Service Calls defines - -#if defined (__CC_ARM) /* ARM Compiler */ - -#define __NO_RETURN __declspec(noreturn) - -#define osEvent_type osEvent -#define osEvent_ret_status ret -#define osEvent_ret_value ret -#define osEvent_ret_msg ret -#define osEvent_ret_mail ret - -#define osCallback_type osCallback -#define osCallback_ret ret - -#define SVC_0_1(f,t,...) \ -__svc_indirect(0) t _##f (t(*)()); \ - t f (void); \ -__attribute__((always_inline)) \ -static __inline t __##f (void) { \ - return _##f(f); \ -} - -#define SVC_1_0(f,t,t1,...) \ -__svc_indirect(0) t _##f (t(*)(t1),t1); \ - t f (t1 a1); \ -__attribute__((always_inline)) \ -static __inline t __##f (t1 a1) { \ - _##f(f,a1); \ -} - -#define SVC_1_1(f,t,t1,...) \ -__svc_indirect(0) t _##f (t(*)(t1),t1); \ - t f (t1 a1); \ -__attribute__((always_inline)) \ -static __inline t __##f (t1 a1) { \ - return _##f(f,a1); \ -} - -#define SVC_2_1(f,t,t1,t2,...) \ -__svc_indirect(0) t _##f (t(*)(t1,t2),t1,t2); \ - t f (t1 a1, t2 a2); \ -__attribute__((always_inline)) \ -static __inline t __##f (t1 a1, t2 a2) { \ - return _##f(f,a1,a2); \ -} - -#define SVC_3_1(f,t,t1,t2,t3,...) \ -__svc_indirect(0) t _##f (t(*)(t1,t2,t3),t1,t2,t3); \ - t f (t1 a1, t2 a2, t3 a3); \ -__attribute__((always_inline)) \ -static __inline t __##f (t1 a1, t2 a2, t3 a3) { \ - return _##f(f,a1,a2,a3); \ -} - -#define SVC_4_1(f,t,t1,t2,t3,t4,...) \ -__svc_indirect(0) t _##f (t(*)(t1,t2,t3,t4),t1,t2,t3,t4); \ - t f (t1 a1, t2 a2, t3 a3, t4 a4); \ -__attribute__((always_inline)) \ -static __inline t __##f (t1 a1, t2 a2, t3 a3, t4 a4) { \ - return _##f(f,a1,a2,a3,a4); \ -} - -#define SVC_1_2 SVC_1_1 -#define SVC_1_3 SVC_1_1 -#define SVC_2_3 SVC_2_1 - -#elif defined (__GNUC__) /* GNU Compiler */ - -#define __NO_RETURN __attribute__((noreturn)) - -typedef uint32_t __attribute__((vector_size(8))) ret64; -typedef uint32_t __attribute__((vector_size(16))) ret128; - -#define RET_pointer __r0 -#define RET_int32_t __r0 -#define RET_uint32_t __r0 -#define RET_osStatus __r0 -#define RET_osPriority __r0 -#define RET_osEvent {(osStatus)__r0, {(uint32_t)__r1}, {(void *)__r2}} -#define RET_osCallback {(void *)__r0, (void *)__r1} - -#define osEvent_type __attribute__((pcs("aapcs"))) ret128 -#define osEvent_ret_status (ret128){ret.status} -#define osEvent_ret_value (ret128){ret.status, ret.value.v} -#define osEvent_ret_msg (ret128){ret.status, ret.value.v, (uint32_t)ret.def.message_id} -#define osEvent_ret_mail (ret128){ret.status, ret.value.v, (uint32_t)ret.def.mail_id} - -#define osCallback_type __attribute__((pcs("aapcs"))) ret64 -#define osCallback_ret (ret64) {(uint32_t)ret.fp, (uint32_t)ret.arg} - -#define SVC_ArgN(n) \ - register int __r##n __asm("r"#n); - -#define SVC_ArgR(n,t,a) \ - register t __r##n __asm("r"#n) = a; - -#define SVC_Arg0() \ - SVC_ArgN(0) \ - SVC_ArgN(1) \ - SVC_ArgN(2) \ - SVC_ArgN(3) - -#define SVC_Arg1(t1) \ - SVC_ArgR(0,t1,a1) \ - SVC_ArgN(1) \ - SVC_ArgN(2) \ - SVC_ArgN(3) - -#define SVC_Arg2(t1,t2) \ - SVC_ArgR(0,t1,a1) \ - SVC_ArgR(1,t2,a2) \ - SVC_ArgN(2) \ - SVC_ArgN(3) - -#define SVC_Arg3(t1,t2,t3) \ - SVC_ArgR(0,t1,a1) \ - SVC_ArgR(1,t2,a2) \ - SVC_ArgR(2,t3,a3) \ - SVC_ArgN(3) - -#define SVC_Arg4(t1,t2,t3,t4) \ - SVC_ArgR(0,t1,a1) \ - SVC_ArgR(1,t2,a2) \ - SVC_ArgR(2,t3,a3) \ - SVC_ArgR(3,t4,a4) - -#if (defined (__CORTEX_M0)) || defined (__CORTEX_M0PLUS) -#define SVC_Call(f) \ - __asm volatile \ - ( \ - "ldr r7,="#f"\n\t" \ - "mov r12,r7\n\t" \ - "svc 0" \ - : "=r" (__r0), "=r" (__r1), "=r" (__r2), "=r" (__r3) \ - : "r" (__r0), "r" (__r1), "r" (__r2), "r" (__r3) \ - : "r7", "r12", "lr", "cc" \ - ); -#else -#define SVC_Call(f) \ - __asm volatile \ - ( \ - "ldr r12,="#f"\n\t" \ - "svc 0" \ - : "=r" (__r0), "=r" (__r1), "=r" (__r2), "=r" (__r3) \ - : "r" (__r0), "r" (__r1), "r" (__r2), "r" (__r3) \ - : "r12", "lr", "cc" \ - ); -#endif - -#define SVC_0_1(f,t,rv) \ -__attribute__((always_inline)) \ -static inline t __##f (void) { \ - SVC_Arg0(); \ - SVC_Call(f); \ - return (t) rv; \ -} - -#define SVC_1_0(f,t,t1) \ -__attribute__((always_inline)) \ -static inline t __##f (t1 a1) { \ - SVC_Arg1(t1); \ - SVC_Call(f); \ -} - -#define SVC_1_1(f,t,t1,rv) \ -__attribute__((always_inline)) \ -static inline t __##f (t1 a1) { \ - SVC_Arg1(t1); \ - SVC_Call(f); \ - return (t) rv; \ -} - -#define SVC_2_1(f,t,t1,t2,rv) \ -__attribute__((always_inline)) \ -static inline t __##f (t1 a1, t2 a2) { \ - SVC_Arg2(t1,t2); \ - SVC_Call(f); \ - return (t) rv; \ -} - -#define SVC_3_1(f,t,t1,t2,t3,rv) \ -__attribute__((always_inline)) \ -static inline t __##f (t1 a1, t2 a2, t3 a3) { \ - SVC_Arg3(t1,t2,t3); \ - SVC_Call(f); \ - return (t) rv; \ -} - -#define SVC_4_1(f,t,t1,t2,t3,t4,rv) \ -__attribute__((always_inline)) \ -static inline t __##f (t1 a1, t2 a2, t3 a3, t4 a4) { \ - SVC_Arg4(t1,t2,t3,t4); \ - SVC_Call(f); \ - return (t) rv; \ -} - -#define SVC_1_2 SVC_1_1 -#define SVC_1_3 SVC_1_1 -#define SVC_2_3 SVC_2_1 - -#elif defined (__ICCARM__) /* IAR Compiler */ - -#define __NO_RETURN __noreturn - -#define osEvent_type osEvent -#define osEvent_ret_status ret -#define osEvent_ret_value ret -#define osEvent_ret_msg ret -#define osEvent_ret_mail ret - -#define osCallback_type osCallback -#define osCallback_ret ret - -#define RET_osEvent osEvent -#define RET_osCallback osCallback - -#define SVC_Setup(f) \ - __asm( \ - "mov r12,%0\n" \ - :: "r"(&f): "r0", "r1", "r2", "r3", "r12" \ - ); - -#define SVC_Ret3() \ - __asm( \ - "ldr r0,[sp,#0]\n" \ - "ldr r1,[sp,#4]\n" \ - "ldr r2,[sp,#8]\n" \ - ); - -#define SVC_0_1(f,t,...) \ -t f (void); \ -_Pragma("swi_number=0") __swi t _##f (void); \ -static inline t __##f (void) { \ - SVC_Setup(f); \ - return _##f(); \ -} - -#define SVC_1_0(f,t,t1,...) \ -t f (t1 a1); \ -_Pragma("swi_number=0") __swi t _##f (t1 a1); \ -static inline t __##f (t1 a1) { \ - SVC_Setup(f); \ - _##f(a1); \ -} - -#define SVC_1_1(f,t,t1,...) \ -t f (t1 a1); \ -_Pragma("swi_number=0") __swi t _##f (t1 a1); \ -static inline t __##f (t1 a1) { \ - SVC_Setup(f); \ - return _##f(a1); \ -} - -#define SVC_2_1(f,t,t1,t2,...) \ -t f (t1 a1, t2 a2); \ -_Pragma("swi_number=0") __swi t _##f (t1 a1, t2 a2); \ -static inline t __##f (t1 a1, t2 a2) { \ - SVC_Setup(f); \ - return _##f(a1,a2); \ -} - -#define SVC_3_1(f,t,t1,t2,t3,...) \ -t f (t1 a1, t2 a2, t3 a3); \ -_Pragma("swi_number=0") __swi t _##f (t1 a1, t2 a2, t3 a3); \ -static inline t __##f (t1 a1, t2 a2, t3 a3) { \ - SVC_Setup(f); \ - return _##f(a1,a2,a3); \ -} - -#define SVC_4_1(f,t,t1,t2,t3,t4,...) \ -t f (t1 a1, t2 a2, t3 a3, t4 a4); \ -_Pragma("swi_number=0") __swi t _##f (t1 a1, t2 a2, t3 a3, t4 a4); \ -static inline t __##f (t1 a1, t2 a2, t3 a3, t4 a4) { \ - SVC_Setup(f); \ - return _##f(a1,a2,a3,a4); \ -} - -#define SVC_1_2 SVC_1_1 -#define SVC_1_3 SVC_1_1 -#define SVC_2_3 SVC_2_1 - -#endif - - -// Callback structure -typedef struct { - void *fp; // Function pointer - void *arg; // Function argument -} osCallback; - - -// OS Section definitions -#ifdef OS_SECTIONS_LINK_INFO -extern const uint32_t os_section_id$$Base; -extern const uint32_t os_section_id$$Limit; -#endif - -#ifndef __MBED_CMSIS_RTOS_CM -// OS Stack Memory for Threads definitions -extern uint64_t os_stack_mem[]; -extern const uint32_t os_stack_sz; -#endif - -// OS Timers external resources -extern const osThreadDef_t os_thread_def_osTimerThread; -extern osThreadId osThreadId_osTimerThread; -extern const osMessageQDef_t os_messageQ_def_osTimerMessageQ; -extern osMessageQId osMessageQId_osTimerMessageQ; - -// Thread creation and destruction -osMutexDef(osThreadMutex); -osMutexId osMutexId_osThreadMutex; -void sysThreadTerminate(osThreadId id); - -// ==== Helper Functions ==== - -/// Convert timeout in millisec to system ticks -static uint16_t rt_ms2tick (uint32_t millisec) { - uint32_t tick; - - if (millisec == 0U) { return 0x0U; } // No timeout - if (millisec == osWaitForever) { return 0xFFFFU; } // Indefinite timeout - if (millisec > 4000000U) { return 0xFFFEU; } // Max ticks supported - - tick = ((1000U * millisec) + os_clockrate - 1U) / os_clockrate; - if (tick > 0xFFFEU) { return 0xFFFEU; } - - return (uint16_t)tick; -} - -/// Convert Thread ID to TCB pointer -P_TCB rt_tid2ptcb (osThreadId thread_id) { - P_TCB ptcb; - - if (thread_id == NULL) { return NULL; } - - if ((uint32_t)thread_id & 3U) { return NULL; } - -#ifdef OS_SECTIONS_LINK_INFO - if ((os_section_id$$Base != 0U) && (os_section_id$$Limit != 0U)) { - if (thread_id < (osThreadId)os_section_id$$Base) { return NULL; } - if (thread_id >= (osThreadId)os_section_id$$Limit) { return NULL; } - } -#endif - - ptcb = thread_id; - - if (ptcb->cb_type != TCB) { return NULL; } - - return ptcb; -} - -/// Convert ID pointer to Object pointer -static void *rt_id2obj (void *id) { - - if ((uint32_t)id & 3U) { return NULL; } - -#ifdef OS_SECTIONS_LINK_INFO - if ((os_section_id$$Base != 0U) && (os_section_id$$Limit != 0U)) { - if (id < (void *)os_section_id$$Base) { return NULL; } - if (id >= (void *)os_section_id$$Limit) { return NULL; } - } -#endif - - return id; -} - - -// ==== Kernel Control ==== - -uint8_t os_initialized; // Kernel Initialized flag -uint8_t os_running; // Kernel Running flag - -// Kernel Control Service Calls declarations -SVC_0_1(svcKernelInitialize, osStatus, RET_osStatus) -SVC_0_1(svcKernelStart, osStatus, RET_osStatus) -SVC_0_1(svcKernelRunning, int32_t, RET_int32_t) -SVC_0_1(svcKernelSysTick, uint32_t, RET_uint32_t) - -static void sysThreadError (osStatus status); -osThreadId svcThreadCreate (const osThreadDef_t *thread_def, void *argument, void *context); -osMessageQId svcMessageCreate (const osMessageQDef_t *queue_def, osThreadId thread_id); - -// Kernel Control Service Calls - -/// Initialize the RTOS Kernel for creating objects -osStatus svcKernelInitialize (void) { -#ifdef __MBED_CMSIS_RTOS_CM - if (!os_initialized) { - rt_sys_init(); // RTX System Initialization - } -#else - uint32_t ret; - - if (os_initialized == 0U) { - - // Init Thread Stack Memory (must be 8-byte aligned) - if (((uint32_t)os_stack_mem & 7U) != 0U) { return osErrorNoMemory; } - ret = rt_init_mem(os_stack_mem, os_stack_sz); - if (ret != 0U) { return osErrorNoMemory; } - - rt_sys_init(); // RTX System Initialization - } -#endif - - os_tsk.run->prio = 255U; // Highest priority - - if (os_initialized == 0U) { - // Create OS Timers resources (Message Queue & Thread) - osMessageQId_osTimerMessageQ = svcMessageCreate (&os_messageQ_def_osTimerMessageQ, NULL); - osThreadId_osTimerThread = svcThreadCreate(&os_thread_def_osTimerThread, NULL, NULL); - // Initialize thread mutex - osMutexId_osThreadMutex = osMutexCreate(osMutex(osThreadMutex)); - } - - sysThreadError(osOK); - - os_initialized = 1U; - os_running = 0U; - - return osOK; -} - -/// Start the RTOS Kernel -osStatus svcKernelStart (void) { - - if (os_running) { return osOK; } - - rt_tsk_prio(0U, os_tsk.run->prio_base); // Restore priority - if (os_tsk.run->task_id == 0xFFU) { // Idle Thread - __set_PSP(os_tsk.run->tsk_stack + (8U*4U)); // Setup PSP - } - if (os_tsk.new_tsk == NULL) { // Force context switch - os_tsk.new_tsk = os_tsk.run; - os_tsk.run = NULL; - } - - rt_sys_start(); - - os_running = 1U; - - return osOK; -} - -/// Check if the RTOS kernel is already started -int32_t svcKernelRunning (void) { - return (int32_t)os_running; -} - -/// Get the RTOS kernel system timer counter -uint32_t svcKernelSysTick (void) { - uint32_t tick, tick0; - - tick = os_tick_val(); - if (os_tick_ovf()) { - tick0 = os_tick_val(); - if (tick0 < tick) { tick = tick0; } - tick += (os_trv + 1U) * (os_time + 1U); - } else { - tick += (os_trv + 1U) * os_time; - } - - return tick; -} - -// Kernel Control Public API - -/// Initialize the RTOS Kernel for creating objects -osStatus osKernelInitialize (void) { - if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) { - return osErrorISR; // Not allowed in ISR - } - if ((__get_CONTROL() & 1U) == 0U) { // Privileged mode - return svcKernelInitialize(); - } else { - return __svcKernelInitialize(); - } -} - -/// Start the RTOS Kernel -osStatus osKernelStart (void) { - uint32_t stack[8]; - - if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) { - return osErrorISR; // Not allowed in ISR - } - - /* Call the pre-start event (from unprivileged mode) if the handler exists - * and the kernel is not running. */ - /* FIXME osEventObs needs to be readable but not writable from unprivileged - * code. */ - if (!osKernelRunning() && osEventObs && osEventObs->pre_start) { - osEventObs->pre_start(); - } - - switch (__get_CONTROL() & 0x03U) { - case 0x00U: // Privileged Thread mode & MSP - __set_PSP((uint32_t)(stack + 8)); // Initial PSP - if (os_flags & 1U) { - __set_CONTROL(0x02U); // Set Privileged Thread mode & PSP - } else { - __set_CONTROL(0x03U); // Set Unprivileged Thread mode & PSP - } - __DSB(); - __ISB(); - break; - case 0x01U: // Unprivileged Thread mode & MSP - return osErrorOS; - case 0x02U: // Privileged Thread mode & PSP - if ((os_flags & 1U) == 0U) { // Unprivileged Thread mode requested - __set_CONTROL(0x03U); // Set Unprivileged Thread mode & PSP - __DSB(); - __ISB(); - } - break; - case 0x03U: // Unprivileged Thread mode & PSP - if (os_flags & 1U) { return osErrorOS; } // Privileged Thread mode requested - break; - } - return __svcKernelStart(); -} - -/// Check if the RTOS kernel is already started -int32_t osKernelRunning (void) { - if ((__get_PRIMASK() != 0U || __get_IPSR() != 0U) || ((__get_CONTROL() & 1U) == 0U)) { - // in ISR or Privileged - return (int32_t)os_running; - } else { - return __svcKernelRunning(); - } -} - -/// Get the RTOS kernel system timer counter -uint32_t osKernelSysTick (void) { - if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) { return 0U; } // Not allowed in ISR - return __svcKernelSysTick(); -} - - -// ==== Thread Management ==== - -/// Set Thread Error (for Create functions which return IDs) -static void sysThreadError (osStatus status) { - // To Do -} - -__NO_RETURN void osThreadExit (void); - -// Thread Service Calls declarations -SVC_3_1(svcThreadCreate, osThreadId, const osThreadDef_t *, void *, void *, RET_pointer) -SVC_0_1(svcThreadGetId, osThreadId, RET_pointer) -SVC_1_1(svcThreadTerminate, osStatus, osThreadId, RET_osStatus) -SVC_0_1(svcThreadYield, osStatus, RET_osStatus) -SVC_2_1(svcThreadSetPriority, osStatus, osThreadId, osPriority, RET_osStatus) -SVC_1_1(svcThreadGetPriority, osPriority, osThreadId, RET_osPriority) -SVC_2_3(svcThreadGetInfo, os_InRegs osEvent, osThreadId, osThreadInfo, RET_osEvent) - -// Thread Service Calls - -/// Create a thread and add it to Active Threads and set it to state READY -osThreadId svcThreadCreate (const osThreadDef_t *thread_def, void *argument, void *context) { - P_TCB ptcb; - OS_TID tsk; - void *stk; - - if ((thread_def == NULL) || - (thread_def->pthread == NULL) || - (thread_def->tpriority < osPriorityIdle) || - (thread_def->tpriority > osPriorityRealtime)) { - sysThreadError(osErrorParameter); - return NULL; - } - -#ifdef __MBED_CMSIS_RTOS_CM - if (thread_def->stacksize != 0) { // Custom stack size - stk = (void *)thread_def->stack_pointer; - } else { // Default stack size - stk = NULL; - } -#else - if (thread_def->stacksize != 0) { // Custom stack size - stk = rt_alloc_mem( // Allocate stack - os_stack_mem, - thread_def->stacksize - ); - if (stk == NULL) { - sysThreadError(osErrorNoMemory); // Out of memory - return NULL; - } - } else { // Default stack size - stk = NULL; - } -#endif - - tsk = rt_tsk_create( // Create task - (FUNCP)thread_def->pthread, // Task function pointer - (uint32_t) - (thread_def->tpriority-osPriorityIdle+1) | // Task priority - (thread_def->stacksize << 8), // Task stack size in bytes - stk, // Pointer to task's stack - argument // Argument to the task - ); - - if (tsk == 0U) { // Invalid task ID -#ifndef __MBED_CMSIS_RTOS_CM - if (stk != NULL) { - rt_free_mem(os_stack_mem, stk); // Free allocated stack - } -#endif - sysThreadError(osErrorNoMemory); // Create task failed (Out of memory) - return NULL; - } - - ptcb = (P_TCB)os_active_TCB[tsk - 1U]; // TCB pointer - - *((uint32_t *)ptcb->tsk_stack + 13) = (uint32_t)osThreadExit; - - if (osEventObs && osEventObs->thread_create) { - ptcb->context = osEventObs->thread_create(ptcb->task_id, context); - } else { - ptcb->context = context; - } - - return ptcb; -} - -/// Return the thread ID of the current running thread -osThreadId svcThreadGetId (void) { - OS_TID tsk; - - tsk = rt_tsk_self(); - if (tsk == 0U) { return NULL; } - return (P_TCB)os_active_TCB[tsk - 1U]; -} - -/// Terminate execution of a thread and remove it from ActiveThreads -osStatus svcThreadTerminate (osThreadId thread_id) { - OS_RESULT res; - P_TCB ptcb; -#ifndef __MBED_CMSIS_RTOS_CM - void *stk; -#endif - - ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer - if (ptcb == NULL) { - return osErrorParameter; - } - -#ifndef __MBED_CMSIS_RTOS_CM - stk = ptcb->priv_stack ? ptcb->stack : NULL; // Private stack -#endif - - if (osEventObs && osEventObs->thread_destroy) { - osEventObs->thread_destroy(ptcb->context); - } - - res = rt_tsk_delete(ptcb->task_id); // Delete task - - if (res == OS_R_NOK) { - return osErrorResource; // Delete task failed - } - -#ifndef __MBED_CMSIS_RTOS_CM - if (stk != NULL) { - rt_free_mem(os_stack_mem, stk); // Free private stack - } -#endif - - return osOK; -} - -/// Pass control to next thread that is in state READY -osStatus svcThreadYield (void) { - rt_tsk_pass(); // Pass control to next task - return osOK; -} - -/// Change priority of an active thread -osStatus svcThreadSetPriority (osThreadId thread_id, osPriority priority) { - OS_RESULT res; - P_TCB ptcb; - - ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer - if (ptcb == NULL) { - return osErrorParameter; - } - - if ((priority < osPriorityIdle) || (priority > osPriorityRealtime)) { - return osErrorValue; - } - - res = rt_tsk_prio( // Change task priority - ptcb->task_id, // Task ID - (uint8_t)(priority - osPriorityIdle + 1) // New task priority - ); - - if (res == OS_R_NOK) { - return osErrorResource; // Change task priority failed - } - - return osOK; -} - -/// Get current priority of an active thread -osPriority svcThreadGetPriority (osThreadId thread_id) { - P_TCB ptcb; - - ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer - if (ptcb == NULL) { - return osPriorityError; - } - - return (osPriority)(ptcb->prio - 1 + osPriorityIdle); -} - -/// Get info from an active thread -os_InRegs osEvent_type svcThreadGetInfo (osThreadId thread_id, osThreadInfo info) { - P_TCB ptcb; - osEvent ret; - ret.status = osOK; - - ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer - if (ptcb == NULL) { - ret.status = osErrorValue; - return osEvent_ret_status; - } - - if (osThreadInfoStackSize == info) { - uint32_t size; - size = ptcb->priv_stack; - if (0 == size) { - // This is an OS task - always a fixed size - size = os_stackinfo & 0x3FFFF; - } - ret.value.v = size; - return osEvent_ret_value; - } - - if (osThreadInfoStackMax == info) { - uint32_t i; - uint32_t *stack_ptr; - uint32_t stack_size; - if (!(os_stackinfo & (1 << 28))) { - // Stack init must be turned on for max stack usage - ret.status = osErrorResource; - return osEvent_ret_status; - } - stack_ptr = (uint32_t*)ptcb->stack; - stack_size = ptcb->priv_stack; - if (0 == stack_size) { - // This is an OS task - always a fixed size - stack_size = os_stackinfo & 0x3FFFF; - } - for (i = 1; i ptask; - return osEvent_ret_value; - } - - if (osThreadInfoArg == info) { - ret.value.p = (void*)ptcb->argv; - return osEvent_ret_value; - } - - // Unsupported option so return error - ret.status = osErrorParameter; - return osEvent_ret_status; -} - -// Thread Public API - -/// Create a thread and add it to Active Threads and set it to state READY -osThreadId osThreadCreate (const osThreadDef_t *thread_def, void *argument) { - return osThreadContextCreate(thread_def, argument, NULL); -} -osThreadId osThreadContextCreate (const osThreadDef_t *thread_def, void *argument, void *context) { - if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) { - return NULL; // Not allowed in ISR - } - if (((__get_CONTROL() & 1U) == 0U) && (os_running == 0U)) { - // Privileged and not running - return svcThreadCreate(thread_def, argument, context); - } else { - osThreadId id; - osMutexWait(osMutexId_osThreadMutex, osWaitForever); - // Thread mutex must be held when a thread is created or terminated - id = __svcThreadCreate(thread_def, argument, context); - osMutexRelease(osMutexId_osThreadMutex); - return id; - } -} - -/// Return the thread ID of the current running thread -osThreadId osThreadGetId (void) { - if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) { - return NULL; // Not allowed in ISR - } - return __svcThreadGetId(); -} - -/// Terminate execution of a thread and remove it from ActiveThreads -osStatus osThreadTerminate (osThreadId thread_id) { - osStatus status; - if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) { - return osErrorISR; // Not allowed in ISR - } - osMutexWait(osMutexId_osThreadMutex, osWaitForever); - sysThreadTerminate(thread_id); - // Thread mutex must be held when a thread is created or terminated - status = __svcThreadTerminate(thread_id); - osMutexRelease(osMutexId_osThreadMutex); - return status; -} - -/// Pass control to next thread that is in state READY -osStatus osThreadYield (void) { - if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) { - return osErrorISR; // Not allowed in ISR - } - return __svcThreadYield(); -} - -/// Change priority of an active thread -osStatus osThreadSetPriority (osThreadId thread_id, osPriority priority) { - if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) { - return osErrorISR; // Not allowed in ISR - } - return __svcThreadSetPriority(thread_id, priority); -} - -/// Get current priority of an active thread -osPriority osThreadGetPriority (osThreadId thread_id) { - if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) { - return osPriorityError; // Not allowed in ISR - } - return __svcThreadGetPriority(thread_id); -} - -/// INTERNAL - Not Public -/// Auto Terminate Thread on exit (used implicitly when thread exists) -__NO_RETURN void osThreadExit (void) { - osThreadId id; - // Thread mutex must be held when a thread is created or terminated - // Note - the mutex will be released automatically by the os when - // the thread is terminated - osMutexWait(osMutexId_osThreadMutex, osWaitForever); - id = __svcThreadGetId(); - sysThreadTerminate(id); - __svcThreadTerminate(id); - for (;;); // Should never come here -} - -#ifdef __MBED_CMSIS_RTOS_CM -/// Get current thread state -uint8_t osThreadGetState (osThreadId thread_id) { - P_TCB ptcb; - - if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) return osErrorISR; // Not allowed in ISR - - ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer - if (ptcb == NULL) return INACTIVE; - - return ptcb->state; -} -#endif - -/// Get the requested info from the specified active thread -os_InRegs osEvent _osThreadGetInfo(osThreadId thread_id, osThreadInfo info) { - osEvent ret; - - if (__get_IPSR() != 0U) { // Not allowed in ISR - ret.status = osErrorISR; - return ret; - } - return __svcThreadGetInfo(thread_id, info); -} - -osThreadEnumId _osThreadsEnumStart() { - static uint32_t thread_enum_index; - osMutexWait(osMutexId_osThreadMutex, osWaitForever); - thread_enum_index = 0; - return &thread_enum_index; -} - -osThreadId _osThreadEnumNext(osThreadEnumId enum_id) { - uint32_t i; - osThreadId id = NULL; - uint32_t *index = (uint32_t*)enum_id; - for (i = *index; i < os_maxtaskrun; i++) { - if (os_active_TCB[i] != NULL) { - id = (osThreadId)os_active_TCB[i]; - break; - } - } - if (i == os_maxtaskrun) { - // Include the idle task at the end of the enumeration - id = &os_idle_TCB; - } - *index = i + 1; - return id; -} - -osStatus _osThreadEnumFree(osThreadEnumId enum_id) { - uint32_t *index = (uint32_t*)enum_id; - *index = 0; - osMutexRelease(osMutexId_osThreadMutex); - return osOK; -} - -// ==== Generic Wait Functions ==== - -// Generic Wait Service Calls declarations -SVC_1_1(svcDelay, osStatus, uint32_t, RET_osStatus) -#if osFeature_Wait != 0 -SVC_1_3(svcWait, os_InRegs osEvent, uint32_t, RET_osEvent) -#endif - -// Generic Wait Service Calls - -/// Wait for Timeout (Time Delay) -osStatus svcDelay (uint32_t millisec) { - if (millisec == 0U) { return osOK; } - rt_dly_wait(rt_ms2tick(millisec)); - return osEventTimeout; -} - -/// Wait for Signal, Message, Mail, or Timeout -#if osFeature_Wait != 0 -os_InRegs osEvent_type svcWait (uint32_t millisec) { - osEvent ret; - - if (millisec == 0U) { - ret.status = osOK; - return osEvent_ret_status; - } - - /* To Do: osEventSignal, osEventMessage, osEventMail */ - rt_dly_wait(rt_ms2tick(millisec)); - ret.status = osEventTimeout; - - return osEvent_ret_status; -} -#endif - - -// Generic Wait API - -/// Wait for Timeout (Time Delay) -osStatus osDelay (uint32_t millisec) { - if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) { - return osErrorISR; // Not allowed in ISR - } - return __svcDelay(millisec); -} - -/// Wait for Signal, Message, Mail, or Timeout -os_InRegs osEvent osWait (uint32_t millisec) { - osEvent ret; - -#if osFeature_Wait == 0 - ret.status = osErrorOS; - return ret; -#else - if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) { // Not allowed in ISR - ret.status = osErrorISR; - return ret; - } - return __svcWait(millisec); -#endif -} - - -// ==== Timer Management ==== - -// Timer definitions -#define osTimerInvalid 0U -#define osTimerStopped 1U -#define osTimerRunning 2U - -// Timer structures - -typedef struct os_timer_cb_ { // Timer Control Block - struct os_timer_cb_ *next; // Pointer to next active Timer - uint8_t state; // Timer State - uint8_t type; // Timer Type (Periodic/One-shot) - uint16_t reserved; // Reserved - uint32_t tcnt; // Timer Delay Count - uint32_t icnt; // Timer Initial Count - void *arg; // Timer Function Argument - const osTimerDef_t *timer; // Pointer to Timer definition -} os_timer_cb; - -// Timer variables -os_timer_cb *os_timer_head; // Pointer to first active Timer - - -// Timer Helper Functions - -// Insert Timer into the list sorted by time -static void rt_timer_insert (os_timer_cb *pt, uint32_t tcnt) { - os_timer_cb *p, *prev; - - prev = NULL; - p = os_timer_head; - while (p != NULL) { - if (tcnt < p->tcnt) { break; } - tcnt -= p->tcnt; - prev = p; - p = p->next; - } - pt->next = p; - pt->tcnt = tcnt; - if (p != NULL) { - p->tcnt -= pt->tcnt; - } - if (prev != NULL) { - prev->next = pt; - } else { - os_timer_head = pt; - } -} - -// Remove Timer from the list -static int32_t rt_timer_remove (os_timer_cb *pt) { - os_timer_cb *p, *prev; - - prev = NULL; - p = os_timer_head; - while (p != NULL) { - if (p == pt) { break; } - prev = p; - p = p->next; - } - if (p == NULL) { return -1; } - if (prev != NULL) { - prev->next = pt->next; - } else { - os_timer_head = pt->next; - } - if (pt->next != NULL) { - pt->next->tcnt += pt->tcnt; - } - - return 0; -} - - -// Timer Service Calls declarations -SVC_3_1(svcTimerCreate, osTimerId, const osTimerDef_t *, os_timer_type, void *, RET_pointer) -SVC_2_1(svcTimerStart, osStatus, osTimerId, uint32_t, RET_osStatus) -SVC_1_1(svcTimerStop, osStatus, osTimerId, RET_osStatus) -SVC_1_1(svcTimerDelete, osStatus, osTimerId, RET_osStatus) -SVC_1_2(svcTimerCall, os_InRegs osCallback, osTimerId, RET_osCallback) - -// Timer Management Service Calls - -/// Create timer -osTimerId svcTimerCreate (const osTimerDef_t *timer_def, os_timer_type type, void *argument) { - os_timer_cb *pt; - - if ((timer_def == NULL) || (timer_def->ptimer == NULL)) { - sysThreadError(osErrorParameter); - return NULL; - } - - pt = timer_def->timer; - if (pt == NULL) { - sysThreadError(osErrorParameter); - return NULL; - } - - if ((type != osTimerOnce) && (type != osTimerPeriodic)) { - sysThreadError(osErrorValue); - return NULL; - } - - if (osThreadId_osTimerThread == NULL) { - sysThreadError(osErrorResource); - return NULL; - } - - if (pt->state != osTimerInvalid){ - sysThreadError(osErrorResource); - return NULL; - } - - pt->next = NULL; - pt->state = osTimerStopped; - pt->type = (uint8_t)type; - pt->arg = argument; - pt->timer = timer_def; - - return (osTimerId)pt; -} - -/// Start or restart timer -osStatus svcTimerStart (osTimerId timer_id, uint32_t millisec) { - os_timer_cb *pt; - uint32_t tcnt; - - pt = rt_id2obj(timer_id); - if (pt == NULL) { - return osErrorParameter; - } - - if (millisec == 0U) { return osErrorValue; } - - tcnt = (uint32_t)(((1000U * (uint64_t)millisec) + os_clockrate - 1U) / os_clockrate); - - switch (pt->state) { - case osTimerRunning: - if (rt_timer_remove(pt) != 0) { - return osErrorResource; - } - break; - case osTimerStopped: - pt->state = osTimerRunning; - pt->icnt = tcnt; - break; - default: - return osErrorResource; - } - - rt_timer_insert(pt, tcnt); - - return osOK; -} - -/// Stop timer -osStatus svcTimerStop (osTimerId timer_id) { - os_timer_cb *pt; - - pt = rt_id2obj(timer_id); - if (pt == NULL) { - return osErrorParameter; - } - - if (pt->state != osTimerRunning) { return osErrorResource; } - - pt->state = osTimerStopped; - - if (rt_timer_remove(pt) != 0) { - return osErrorResource; - } - - return osOK; -} - -/// Delete timer -osStatus svcTimerDelete (osTimerId timer_id) { - os_timer_cb *pt; - - pt = rt_id2obj(timer_id); - if (pt == NULL) { - return osErrorParameter; - } - - switch (pt->state) { - case osTimerRunning: - rt_timer_remove(pt); - break; - case osTimerStopped: - break; - default: - return osErrorResource; - } - - pt->state = osTimerInvalid; - - return osOK; -} - -/// Get timer callback parameters -os_InRegs osCallback_type svcTimerCall (osTimerId timer_id) { - os_timer_cb *pt; - osCallback ret; - - pt = rt_id2obj(timer_id); - if (pt == NULL) { - ret.fp = NULL; - ret.arg = NULL; - return osCallback_ret; - } - - ret.fp = (void *)pt->timer->ptimer; - ret.arg = pt->arg; - - return osCallback_ret; -} - -osStatus isrMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec); - -/// Timer Tick (called each SysTick) -void sysTimerTick (void) { - os_timer_cb *pt, *p; - osStatus status; - - p = os_timer_head; - if (p == NULL) { return; } - - p->tcnt--; - while ((p != NULL) && (p->tcnt == 0U)) { - pt = p; - p = p->next; - os_timer_head = p; - status = isrMessagePut(osMessageQId_osTimerMessageQ, (uint32_t)pt, 0U); - if (status != osOK) { - os_error(OS_ERR_TIMER_OVF); - } - if (pt->type == (uint8_t)osTimerPeriodic) { - rt_timer_insert(pt, pt->icnt); - } else { - pt->state = osTimerStopped; - } - } -} - -/// Get user timers wake-up time -uint32_t sysUserTimerWakeupTime (void) { - - if (os_timer_head) { - return os_timer_head->tcnt; - } - return 0xFFFFFFFFU; -} - -/// Update user timers on resume -void sysUserTimerUpdate (uint32_t sleep_time) { - - while ((os_timer_head != NULL) && (sleep_time != 0U)) { - if (sleep_time >= os_timer_head->tcnt) { - sleep_time -= os_timer_head->tcnt; - os_timer_head->tcnt = 1U; - sysTimerTick(); - } else { - os_timer_head->tcnt -= sleep_time; - break; - } - } -} - - -// Timer Management Public API - -/// Create timer -osTimerId osTimerCreate (const osTimerDef_t *timer_def, os_timer_type type, void *argument) { - if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) { - return NULL; // Not allowed in ISR - } - if (((__get_CONTROL() & 1U) == 0U) && (os_running == 0U)) { - // Privileged and not running - return svcTimerCreate(timer_def, type, argument); - } else { - return __svcTimerCreate(timer_def, type, argument); - } -} - -/// Start or restart timer -osStatus osTimerStart (osTimerId timer_id, uint32_t millisec) { - if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) { - return osErrorISR; // Not allowed in ISR - } - return __svcTimerStart(timer_id, millisec); -} - -/// Stop timer -osStatus osTimerStop (osTimerId timer_id) { - if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) { - return osErrorISR; // Not allowed in ISR - } - return __svcTimerStop(timer_id); -} - -/// Delete timer -osStatus osTimerDelete (osTimerId timer_id) { - if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) { - return osErrorISR; // Not allowed in ISR - } - return __svcTimerDelete(timer_id); -} - -/// INTERNAL - Not Public -/// Get timer callback parameters (used by OS Timer Thread) -os_InRegs osCallback osTimerCall (osTimerId timer_id) { - return __svcTimerCall(timer_id); -} - - -// Timer Thread -__NO_RETURN void osTimerThread (void const *argument) { - osCallback cb; - osEvent evt; - - for (;;) { - evt = osMessageGet(osMessageQId_osTimerMessageQ, osWaitForever); - if (evt.status == osEventMessage) { - cb = osTimerCall(evt.value.p); - if (cb.fp != NULL) { - (*(os_ptimer)cb.fp)(cb.arg); - } - } - } -} - - -// ==== Signal Management ==== - -// Signal Service Calls declarations -SVC_2_1(svcSignalSet, int32_t, osThreadId, int32_t, RET_int32_t) -SVC_2_1(svcSignalClear, int32_t, osThreadId, int32_t, RET_int32_t) -SVC_2_3(svcSignalWait, os_InRegs osEvent, int32_t, uint32_t, RET_osEvent) - -// Signal Service Calls - -/// Set the specified Signal Flags of an active thread -int32_t svcSignalSet (osThreadId thread_id, int32_t signals) { - P_TCB ptcb; - int32_t sig; - - ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer - if (ptcb == NULL) { - return (int32_t)0x80000000U; - } - - if ((uint32_t)signals & (0xFFFFFFFFU << osFeature_Signals)) { - return (int32_t)0x80000000U; - } - - sig = (int32_t)ptcb->events; // Previous signal flags - - rt_evt_set((uint16_t)signals, ptcb->task_id); // Set event flags - - return sig; -} - -/// Clear the specified Signal Flags of an active thread -int32_t svcSignalClear (osThreadId thread_id, int32_t signals) { - P_TCB ptcb; - int32_t sig; - - ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer - if (ptcb == NULL) { - return (int32_t)0x80000000U; - } - - if ((uint32_t)signals & (0xFFFFFFFFU << osFeature_Signals)) { - return (int32_t)0x80000000U; - } - - sig = (int32_t)ptcb->events; // Previous signal flags - - rt_evt_clr((uint16_t)signals, ptcb->task_id); // Clear event flags - - return sig; -} - -/// Wait for one or more Signal Flags to become signaled for the current RUNNING thread -os_InRegs osEvent_type svcSignalWait (int32_t signals, uint32_t millisec) { - OS_RESULT res; - osEvent ret; - - if ((uint32_t)signals & (0xFFFFFFFFU << osFeature_Signals)) { - ret.status = osErrorValue; - return osEvent_ret_status; - } - - if (signals != 0) { // Wait for all specified signals - res = rt_evt_wait((uint16_t)signals, rt_ms2tick(millisec), __TRUE); - } else { // Wait for any signal - res = rt_evt_wait(0xFFFFU, rt_ms2tick(millisec), __FALSE); - } - - if (res == OS_R_EVT) { - ret.status = osEventSignal; - ret.value.signals = (signals != 0) ? signals : (int32_t)os_tsk.run->waits; - } else { - ret.status = (millisec != 0U) ? osEventTimeout : osOK; - ret.value.signals = 0; - } - - return osEvent_ret_value; -} - - -// Signal ISR Calls - -/// Set the specified Signal Flags of an active thread -int32_t isrSignalSet (osThreadId thread_id, int32_t signals) { - P_TCB ptcb; - int32_t sig; - - ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer - if (ptcb == NULL) { - return (int32_t)0x80000000U; - } - - if ((uint32_t)signals & (0xFFFFFFFFU << osFeature_Signals)) { - return (int32_t)0x80000000U; - } - - sig = (int32_t)ptcb->events; // Previous signal flags - - isr_evt_set((uint16_t)signals, ptcb->task_id);// Set event flags - - return sig; -} - - -// Signal Public API - -/// Set the specified Signal Flags of an active thread -int32_t osSignalSet (osThreadId thread_id, int32_t signals) { - if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) { // in ISR - return isrSignalSet(thread_id, signals); - } else { // in Thread - return __svcSignalSet(thread_id, signals); - } -} - -/// Clear the specified Signal Flags of an active thread -int32_t osSignalClear (osThreadId thread_id, int32_t signals) { - if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) { - return (int32_t)0x80000000U; // Not allowed in ISR - } - return __svcSignalClear(thread_id, signals); -} - -/// Wait for one or more Signal Flags to become signaled for the current RUNNING thread -os_InRegs osEvent osSignalWait (int32_t signals, uint32_t millisec) { - osEvent ret; - - if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) { // Not allowed in ISR - ret.status = osErrorISR; - return ret; - } - return __svcSignalWait(signals, millisec); -} - - -// ==== Mutex Management ==== - -// Mutex Service Calls declarations -SVC_1_1(svcMutexCreate, osMutexId, const osMutexDef_t *, RET_pointer) -SVC_2_1(svcMutexWait, osStatus, osMutexId, uint32_t, RET_osStatus) -SVC_1_1(svcMutexRelease, osStatus, osMutexId, RET_osStatus) -SVC_1_1(svcMutexDelete, osStatus, osMutexId, RET_osStatus) - -// Mutex Service Calls - -/// Create and Initialize a Mutex object -osMutexId svcMutexCreate (const osMutexDef_t *mutex_def) { - OS_ID mut; - - if (mutex_def == NULL) { - sysThreadError(osErrorParameter); - return NULL; - } - - mut = mutex_def->mutex; - if (mut == NULL) { - sysThreadError(osErrorParameter); - return NULL; - } - - if (((P_MUCB)mut)->cb_type != 0U) { - sysThreadError(osErrorParameter); - return NULL; - } - - rt_mut_init(mut); // Initialize Mutex - - return mut; -} - -/// Wait until a Mutex becomes available -osStatus svcMutexWait (osMutexId mutex_id, uint32_t millisec) { - OS_ID mut; - OS_RESULT res; - - mut = rt_id2obj(mutex_id); - if (mut == NULL) { - return osErrorParameter; - } - - if (((P_MUCB)mut)->cb_type != MUCB) { - return osErrorParameter; - } - - res = rt_mut_wait(mut, rt_ms2tick(millisec)); // Wait for Mutex - - if (res == OS_R_TMO) { - return ((millisec != 0U) ? osErrorTimeoutResource : osErrorResource); - } - - return osOK; -} - -/// Release a Mutex that was obtained with osMutexWait -osStatus svcMutexRelease (osMutexId mutex_id) { - OS_ID mut; - OS_RESULT res; - - mut = rt_id2obj(mutex_id); - if (mut == NULL) { - return osErrorParameter; - } - - if (((P_MUCB)mut)->cb_type != MUCB) { - return osErrorParameter; - } - - res = rt_mut_release(mut); // Release Mutex - - if (res == OS_R_NOK) { - return osErrorResource; // Thread not owner or Zero Counter - } - - return osOK; -} - -/// Delete a Mutex that was created by osMutexCreate -osStatus svcMutexDelete (osMutexId mutex_id) { - OS_ID mut; - - mut = rt_id2obj(mutex_id); - if (mut == NULL) { - return osErrorParameter; - } - - if (((P_MUCB)mut)->cb_type != MUCB) { - return osErrorParameter; - } - - rt_mut_delete(mut); // Release Mutex - - return osOK; -} - - -// Mutex Public API - -/// Create and Initialize a Mutex object -osMutexId osMutexCreate (const osMutexDef_t *mutex_def) { - if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) { - return NULL; // Not allowed in ISR - } - if (((__get_CONTROL() & 1U) == 0U) && (os_running == 0U)) { - // Privileged and not running - return svcMutexCreate(mutex_def); - } else { - return __svcMutexCreate(mutex_def); - } -} - -/// Wait until a Mutex becomes available -osStatus osMutexWait (osMutexId mutex_id, uint32_t millisec) { - if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) { - return osErrorISR; // Not allowed in ISR - } - return __svcMutexWait(mutex_id, millisec); -} - -/// Release a Mutex that was obtained with osMutexWait -osStatus osMutexRelease (osMutexId mutex_id) { - if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) { - return osErrorISR; // Not allowed in ISR - } - return __svcMutexRelease(mutex_id); -} - -/// Delete a Mutex that was created by osMutexCreate -osStatus osMutexDelete (osMutexId mutex_id) { - if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) { - return osErrorISR; // Not allowed in ISR - } - return __svcMutexDelete(mutex_id); -} - - -// ==== Semaphore Management ==== - -// Semaphore Service Calls declarations -SVC_2_1(svcSemaphoreCreate, osSemaphoreId, const osSemaphoreDef_t *, int32_t, RET_pointer) -SVC_2_1(svcSemaphoreWait, int32_t, osSemaphoreId, uint32_t, RET_int32_t) -SVC_1_1(svcSemaphoreRelease, osStatus, osSemaphoreId, RET_osStatus) -SVC_1_1(svcSemaphoreDelete, osStatus, osSemaphoreId, RET_osStatus) - -// Semaphore Service Calls - -/// Create and Initialize a Semaphore object -osSemaphoreId svcSemaphoreCreate (const osSemaphoreDef_t *semaphore_def, int32_t count) { - OS_ID sem; - - if (semaphore_def == NULL) { - sysThreadError(osErrorParameter); - return NULL; - } - - sem = semaphore_def->semaphore; - if (sem == NULL) { - sysThreadError(osErrorParameter); - return NULL; - } - - if (((P_SCB)sem)->cb_type != 0U) { - sysThreadError(osErrorParameter); - return NULL; - } - - if (count > osFeature_Semaphore) { - sysThreadError(osErrorValue); - return NULL; - } - - rt_sem_init(sem, (uint16_t)count); // Initialize Semaphore - - return sem; -} - -/// Wait until a Semaphore becomes available -int32_t svcSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec) { - OS_ID sem; - OS_RESULT res; - - sem = rt_id2obj(semaphore_id); - if (sem == NULL) { - return -1; - } - - if (((P_SCB)sem)->cb_type != SCB) { - return -1; - } - - res = rt_sem_wait(sem, rt_ms2tick(millisec)); // Wait for Semaphore - - if (res == OS_R_TMO) { return 0; } // Timeout - - return (int32_t)(((P_SCB)sem)->tokens + 1U); -} - -/// Release a Semaphore -osStatus svcSemaphoreRelease (osSemaphoreId semaphore_id) { - OS_ID sem; - - sem = rt_id2obj(semaphore_id); - if (sem == NULL) { - return osErrorParameter; - } - - if (((P_SCB)sem)->cb_type != SCB) { - return osErrorParameter; - } - - if ((int32_t)((P_SCB)sem)->tokens == osFeature_Semaphore) { - return osErrorResource; - } - - rt_sem_send(sem); // Release Semaphore - - return osOK; -} - -/// Delete a Semaphore that was created by osSemaphoreCreate -osStatus svcSemaphoreDelete (osSemaphoreId semaphore_id) { - OS_ID sem; - - sem = rt_id2obj(semaphore_id); - if (sem == NULL) { - return osErrorParameter; - } - - if (((P_SCB)sem)->cb_type != SCB) { - return osErrorParameter; - } - - rt_sem_delete(sem); // Delete Semaphore - - return osOK; -} - - -// Semaphore ISR Calls - -/// Release a Semaphore -osStatus isrSemaphoreRelease (osSemaphoreId semaphore_id) { - OS_ID sem; - - sem = rt_id2obj(semaphore_id); - if (sem == NULL) { - return osErrorParameter; - } - - if (((P_SCB)sem)->cb_type != SCB) { - return osErrorParameter; - } - - if ((int32_t)((P_SCB)sem)->tokens == osFeature_Semaphore) { - return osErrorResource; - } - - isr_sem_send(sem); // Release Semaphore - - return osOK; -} - - -// Semaphore Public API - -/// Create and Initialize a Semaphore object -osSemaphoreId osSemaphoreCreate (const osSemaphoreDef_t *semaphore_def, int32_t count) { - if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) { - return NULL; // Not allowed in ISR - } - if (((__get_CONTROL() & 1U) == 0U) && (os_running == 0U)) { - // Privileged and not running - return svcSemaphoreCreate(semaphore_def, count); - } else { - return __svcSemaphoreCreate(semaphore_def, count); - } -} - -/// Wait until a Semaphore becomes available -int32_t osSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec) { - if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) { - return -1; // Not allowed in ISR - } - return __svcSemaphoreWait(semaphore_id, millisec); -} - -/// Release a Semaphore -osStatus osSemaphoreRelease (osSemaphoreId semaphore_id) { - if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) { // in ISR - return isrSemaphoreRelease(semaphore_id); - } else { // in Thread - return __svcSemaphoreRelease(semaphore_id); - } -} - -/// Delete a Semaphore that was created by osSemaphoreCreate -osStatus osSemaphoreDelete (osSemaphoreId semaphore_id) { - if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) { - return osErrorISR; // Not allowed in ISR - } - return __svcSemaphoreDelete(semaphore_id); -} - - -// ==== Memory Management Functions ==== - -// Memory Management Helper Functions - -// Clear Memory Box (Zero init) -static void rt_clr_box (void *box_mem, void *box) { - uint32_t *p, n; - - if ((box_mem != NULL) && (box != NULL)) { - p = box; - for (n = ((P_BM)box_mem)->blk_size; n; n -= 4U) { - *p++ = 0U; - } - } -} - -// Memory Management Service Calls declarations -SVC_1_1(svcPoolCreate, osPoolId, const osPoolDef_t *, RET_pointer) -SVC_1_1(sysPoolAlloc, void *, osPoolId, RET_pointer) -SVC_2_1(sysPoolFree, osStatus, osPoolId, void *, RET_osStatus) - -// Memory Management Service & ISR Calls - -/// Create and Initialize memory pool -osPoolId svcPoolCreate (const osPoolDef_t *pool_def) { - uint32_t blk_sz; - - if ((pool_def == NULL) || - (pool_def->pool_sz == 0U) || - (pool_def->item_sz == 0U) || - (pool_def->pool == NULL)) { - sysThreadError(osErrorParameter); - return NULL; - } - - blk_sz = (pool_def->item_sz + 3U) & (uint32_t)~3U; - - _init_box(pool_def->pool, sizeof(struct OS_BM) + (pool_def->pool_sz * blk_sz), blk_sz); - - return pool_def->pool; -} - -/// Allocate a memory block from a memory pool -void *sysPoolAlloc (osPoolId pool_id) { - void *mem; - - if (pool_id == NULL) { - return NULL; - } - - mem = rt_alloc_box(pool_id); - - return mem; -} - -/// Return an allocated memory block back to a specific memory pool -osStatus sysPoolFree (osPoolId pool_id, void *block) { - uint32_t res; - - if (pool_id == NULL) { - return osErrorParameter; - } - - res = rt_free_box(pool_id, block); - if (res != 0) { - return osErrorValue; - } - - return osOK; -} - - -// Memory Management Public API - -/// Create and Initialize memory pool -osPoolId osPoolCreate (const osPoolDef_t *pool_def) { - if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) { - return NULL; // Not allowed in ISR - } - if (((__get_CONTROL() & 1U) == 0U) && (os_running == 0U)) { - // Privileged and not running - return svcPoolCreate(pool_def); - } else { - return __svcPoolCreate(pool_def); - } -} - -/// Allocate a memory block from a memory pool -void *osPoolAlloc (osPoolId pool_id) { - if ((__get_PRIMASK() != 0U || __get_IPSR() != 0U) || ((__get_CONTROL() & 1U) == 0U)) { // in ISR or Privileged - return sysPoolAlloc(pool_id); - } else { // in Thread - return __sysPoolAlloc(pool_id); - } -} - -/// Allocate a memory block from a memory pool and set memory block to zero -void *osPoolCAlloc (osPoolId pool_id) { - void *mem; - - if ((__get_PRIMASK() != 0U || __get_IPSR() != 0U) || ((__get_CONTROL() & 1U) == 0U)) { // in ISR or Privileged - mem = sysPoolAlloc(pool_id); - } else { // in Thread - mem = __sysPoolAlloc(pool_id); - } - - rt_clr_box(pool_id, mem); - - return mem; -} - -/// Return an allocated memory block back to a specific memory pool -osStatus osPoolFree (osPoolId pool_id, void *block) { - if ((__get_PRIMASK() != 0U || __get_IPSR() != 0U) || ((__get_CONTROL() & 1U) == 0U)) { // in ISR or Privileged - return sysPoolFree(pool_id, block); - } else { // in Thread - return __sysPoolFree(pool_id, block); - } -} - - -// ==== Message Queue Management Functions ==== - -// Message Queue Management Service Calls declarations -SVC_2_1(svcMessageCreate, osMessageQId, const osMessageQDef_t *, osThreadId, RET_pointer) -SVC_3_1(svcMessagePut, osStatus, osMessageQId, uint32_t, uint32_t, RET_osStatus) -SVC_2_3(svcMessageGet, os_InRegs osEvent, osMessageQId, uint32_t, RET_osEvent) - -// Message Queue Service Calls - -/// Create and Initialize Message Queue -osMessageQId svcMessageCreate (const osMessageQDef_t *queue_def, osThreadId thread_id) { - - if ((queue_def == NULL) || - (queue_def->queue_sz == 0U) || - (queue_def->pool == NULL)) { - sysThreadError(osErrorParameter); - return NULL; - } - - if (((P_MCB)queue_def->pool)->cb_type != 0U) { - sysThreadError(osErrorParameter); - return NULL; - } - - rt_mbx_init(queue_def->pool, (uint16_t)(4U*(queue_def->queue_sz + 4U))); - - return queue_def->pool; -} - -/// Put a Message to a Queue -osStatus svcMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec) { - OS_RESULT res; - - if (queue_id == NULL) { - return osErrorParameter; - } - - if (((P_MCB)queue_id)->cb_type != MCB) { - return osErrorParameter; - } - - res = rt_mbx_send(queue_id, (void *)info, rt_ms2tick(millisec)); - - if (res == OS_R_TMO) { - return ((millisec != 0U) ? osErrorTimeoutResource : osErrorResource); - } - - return osOK; -} - -/// Get a Message or Wait for a Message from a Queue -os_InRegs osEvent_type svcMessageGet (osMessageQId queue_id, uint32_t millisec) { - OS_RESULT res; - osEvent ret; - - if (queue_id == NULL) { - ret.status = osErrorParameter; - return osEvent_ret_status; - } - - if (((P_MCB)queue_id)->cb_type != MCB) { - ret.status = osErrorParameter; - return osEvent_ret_status; - } - - res = rt_mbx_wait(queue_id, &ret.value.p, rt_ms2tick(millisec)); - - if (res == OS_R_TMO) { - ret.status = (millisec != 0U) ? osEventTimeout : osOK; - return osEvent_ret_value; - } - - ret.status = osEventMessage; - - return osEvent_ret_value; -} - - -// Message Queue ISR Calls - -/// Put a Message to a Queue -osStatus isrMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec) { - - if ((queue_id == NULL) || (millisec != 0U)) { - return osErrorParameter; - } - - if (((P_MCB)queue_id)->cb_type != MCB) { - return osErrorParameter; - } - - if (rt_mbx_check(queue_id) == 0U) { // Check if Queue is full - return osErrorResource; - } - - isr_mbx_send(queue_id, (void *)info); - - return osOK; -} - -/// Get a Message or Wait for a Message from a Queue -os_InRegs osEvent isrMessageGet (osMessageQId queue_id, uint32_t millisec) { - OS_RESULT res; - osEvent ret; - - if ((queue_id == NULL) || (millisec != 0U)) { - ret.status = osErrorParameter; - return ret; - } - - if (((P_MCB)queue_id)->cb_type != MCB) { - ret.status = osErrorParameter; - return ret; - } - - res = isr_mbx_receive(queue_id, &ret.value.p); - - if (res != OS_R_MBX) { - ret.status = osOK; - return ret; - } - - ret.status = osEventMessage; - - return ret; -} - - -// Message Queue Management Public API - -/// Create and Initialize Message Queue -osMessageQId osMessageCreate (const osMessageQDef_t *queue_def, osThreadId thread_id) { - if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) { - return NULL; // Not allowed in ISR - } - if (((__get_CONTROL() & 1U) == 0U) && (os_running == 0U)) { - // Privileged and not running - return svcMessageCreate(queue_def, thread_id); - } else { - return __svcMessageCreate(queue_def, thread_id); - } -} - -/// Put a Message to a Queue -osStatus osMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec) { - if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) { // in ISR - return isrMessagePut(queue_id, info, millisec); - } else { // in Thread - return __svcMessagePut(queue_id, info, millisec); - } -} - -/// Get a Message or Wait for a Message from a Queue -os_InRegs osEvent osMessageGet (osMessageQId queue_id, uint32_t millisec) { - if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) { // in ISR - return isrMessageGet(queue_id, millisec); - } else { // in Thread - return __svcMessageGet(queue_id, millisec); - } -} - - -// ==== Mail Queue Management Functions ==== - -// Mail Queue Management Service Calls declarations -SVC_2_1(svcMailCreate, osMailQId, const osMailQDef_t *, osThreadId, RET_pointer) -SVC_3_1(sysMailAlloc, void *, osMailQId, uint32_t, uint32_t, RET_pointer) -SVC_3_1(sysMailFree, osStatus, osMailQId, void *, uint32_t, RET_osStatus) - -// Mail Queue Management Service & ISR Calls - -/// Create and Initialize mail queue -osMailQId svcMailCreate (const osMailQDef_t *queue_def, osThreadId thread_id) { - uint32_t blk_sz; - P_MCB pmcb; - void *pool; - - if ((queue_def == NULL) || - (queue_def->queue_sz == 0U) || - (queue_def->item_sz == 0U) || - (queue_def->pool == NULL)) { - sysThreadError(osErrorParameter); - return NULL; - } - - pmcb = *(((void **)queue_def->pool) + 0); - pool = *(((void **)queue_def->pool) + 1); - - if ((pool == NULL) || (pmcb == NULL) || (pmcb->cb_type != 0U)) { - sysThreadError(osErrorParameter); - return NULL; - } - - blk_sz = (queue_def->item_sz + 3U) & (uint32_t)~3U; - - _init_box(pool, sizeof(struct OS_BM) + (queue_def->queue_sz * blk_sz), blk_sz); - - rt_mbx_init(pmcb, (uint16_t)(4U*(queue_def->queue_sz + 4U))); - - return queue_def->pool; -} - -/// Allocate a memory block from a mail -void *sysMailAlloc (osMailQId queue_id, uint32_t millisec, uint32_t isr) { - P_MCB pmcb; - void *pool; - void *mem; - - if (queue_id == NULL) { - return NULL; - } - - pmcb = *(((void **)queue_id) + 0); - pool = *(((void **)queue_id) + 1); - - if ((pool == NULL) || (pmcb == NULL)) { - return NULL; - } - - if ((isr != 0U) && (millisec != 0U)) { - return NULL; - } - - mem = rt_alloc_box(pool); - - if ((mem == NULL) && (millisec != 0U)) { - // Put Task to sleep when Memory not available - if (pmcb->p_lnk != NULL) { - rt_put_prio((P_XCB)pmcb, os_tsk.run); - } else { - pmcb->p_lnk = os_tsk.run; - os_tsk.run->p_lnk = NULL; - os_tsk.run->p_rlnk = (P_TCB)pmcb; - // Task is waiting to allocate a message - pmcb->state = 3U; - } - rt_block(rt_ms2tick(millisec), WAIT_MBX); - } - - return mem; -} - -/// Free a memory block from a mail -osStatus sysMailFree (osMailQId queue_id, void *mail, uint32_t isr) { - P_MCB pmcb; - P_TCB ptcb; - void *pool; - void *mem; - uint32_t res; - - if (queue_id == NULL) { - return osErrorParameter; - } - - pmcb = *(((void **)queue_id) + 0); - pool = *(((void **)queue_id) + 1); - - if ((pmcb == NULL) || (pool == NULL)) { - return osErrorParameter; - } - - res = rt_free_box(pool, mail); - - if (res != 0U) { - return osErrorValue; - } - - if ((pmcb->p_lnk != NULL) && (pmcb->state == 3U)) { - // Task is waiting to allocate a message - if (isr != 0U) { - rt_psq_enq (pmcb, (U32)pool); - rt_psh_req (); - } else { - mem = rt_alloc_box(pool); - if (mem != NULL) { - ptcb = rt_get_first((P_XCB)pmcb); - rt_ret_val(ptcb, (U32)mem); - rt_rmv_dly(ptcb); - rt_dispatch(ptcb); - } - } - } - - return osOK; -} - - -// Mail Queue Management Public API - -/// Create and Initialize mail queue -osMailQId osMailCreate (const osMailQDef_t *queue_def, osThreadId thread_id) { - if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) { - return NULL; // Not allowed in ISR - } - if (((__get_CONTROL() & 1U) == 0U) && (os_running == 0U)) { - // Privileged and not running - return svcMailCreate(queue_def, thread_id); - } else { - return __svcMailCreate(queue_def, thread_id); - } -} - -/// Allocate a memory block from a mail -void *osMailAlloc (osMailQId queue_id, uint32_t millisec) { - if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) { // in ISR - return sysMailAlloc(queue_id, millisec, 1U); - } else { // in Thread - return __sysMailAlloc(queue_id, millisec, 0U); - } -} - -/// Allocate a memory block from a mail and set memory block to zero -void *osMailCAlloc (osMailQId queue_id, uint32_t millisec) { - void *pool; - void *mem; - - if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) { // in ISR - mem = sysMailAlloc(queue_id, millisec, 1U); - } else { // in Thread - mem = __sysMailAlloc(queue_id, millisec, 0U); - } - - pool = *(((void **)queue_id) + 1); - - rt_clr_box(pool, mem); - - return mem; -} - -/// Free a memory block from a mail -osStatus osMailFree (osMailQId queue_id, void *mail) { - if (__get_PRIMASK() != 0U || __get_IPSR() != 0U) { // in ISR - return sysMailFree(queue_id, mail, 1U); - } else { // in Thread - return __sysMailFree(queue_id, mail, 0U); - } -} - -/// Put a mail to a queue -osStatus osMailPut (osMailQId queue_id, void *mail) { - if (queue_id == NULL) { - return osErrorParameter; - } - if (mail == NULL) { - return osErrorValue; - } - return osMessagePut(*((void **)queue_id), (uint32_t)mail, 0U); -} - -/// Get a mail from a queue -os_InRegs osEvent osMailGet (osMailQId queue_id, uint32_t millisec) { - osEvent ret; - - if (queue_id == NULL) { - ret.status = osErrorParameter; - return ret; - } - - ret = osMessageGet(*((void **)queue_id), millisec); - if (ret.status == osEventMessage) ret.status = osEventMail; - - return ret; -} - - -// ==== RTX Extensions ==== - -// Service Calls declarations -SVC_0_1(rt_suspend, uint32_t, RET_uint32_t) -SVC_1_0(rt_resume, void, uint32_t) - - -// Public API - -/// Suspends the OS task scheduler -uint32_t os_suspend (void) { - return __rt_suspend(); -} - -/// Resumes the OS task scheduler -void os_resume (uint32_t sleep_time) { - __rt_resume(sleep_time); -} diff --git a/rtos/rtx/TARGET_CORTEX_M/rt_Event.c b/rtos/rtx/TARGET_CORTEX_M/rt_Event.c deleted file mode 100644 index 8e9178b9559..00000000000 --- a/rtos/rtx/TARGET_CORTEX_M/rt_Event.c +++ /dev/null @@ -1,190 +0,0 @@ -/*---------------------------------------------------------------------------- - * CMSIS-RTOS - RTX - *---------------------------------------------------------------------------- - * Name: RT_EVENT.C - * Purpose: Implements waits and wake-ups for event flags - * Rev.: V4.79 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -#include "rt_TypeDef.h" -#include "RTX_Config.h" -#include "rt_System.h" -#include "rt_Event.h" -#include "rt_List.h" -#include "rt_Task.h" -#include "rt_HAL_CM.h" - - -/*---------------------------------------------------------------------------- - * Functions - *---------------------------------------------------------------------------*/ - - -/*--------------------------- rt_evt_wait -----------------------------------*/ - -OS_RESULT rt_evt_wait (U16 wait_flags, U16 timeout, BOOL and_wait) { - /* Wait for one or more event flags with optional time-out. */ - /* "wait_flags" identifies the flags to wait for. */ - /* "timeout" is the time-out limit in system ticks (0xffff if no time-out) */ - /* "and_wait" specifies the AND-ing of "wait_flags" as condition to be met */ - /* to complete the wait. (OR-ing if set to 0). */ - U32 block_state; - - if (and_wait) { - /* Check for AND-connected events */ - if ((os_tsk.run->events & wait_flags) == wait_flags) { - os_tsk.run->events &= ~wait_flags; - return (OS_R_EVT); - } - block_state = WAIT_AND; - } - else { - /* Check for OR-connected events */ - if (os_tsk.run->events & wait_flags) { - os_tsk.run->waits = os_tsk.run->events & wait_flags; - os_tsk.run->events &= ~wait_flags; - return (OS_R_EVT); - } - block_state = WAIT_OR; - } - /* Task has to wait */ - os_tsk.run->waits = wait_flags; - rt_block (timeout, (U8)block_state); - return (OS_R_TMO); -} - - -/*--------------------------- rt_evt_set ------------------------------------*/ - -void rt_evt_set (U16 event_flags, OS_TID task_id) { - /* Set one or more event flags of a selectable task. */ - P_TCB p_tcb; - - p_tcb = os_active_TCB[task_id-1U]; - if (p_tcb == NULL) { - return; - } - p_tcb->events |= event_flags; - event_flags = p_tcb->waits; - /* If the task is not waiting for an event, it should not be put */ - /* to ready state. */ - if (p_tcb->state == WAIT_AND) { - /* Check for AND-connected events */ - if ((p_tcb->events & event_flags) == event_flags) { - goto wkup; - } - } - if (p_tcb->state == WAIT_OR) { - /* Check for OR-connected events */ - if (p_tcb->events & event_flags) { - p_tcb->waits &= p_tcb->events; -wkup: p_tcb->events &= ~event_flags; - rt_rmv_dly (p_tcb); - p_tcb->state = READY; -#ifdef __CMSIS_RTOS - rt_ret_val2(p_tcb, 0x08U/*osEventSignal*/, p_tcb->waits); -#else - rt_ret_val (p_tcb, OS_R_EVT); -#endif - rt_dispatch (p_tcb); - } - } -} - - -/*--------------------------- rt_evt_clr ------------------------------------*/ - -void rt_evt_clr (U16 clear_flags, OS_TID task_id) { - /* Clear one or more event flags (identified by "clear_flags") of a */ - /* selectable task (identified by "task"). */ - P_TCB task = os_active_TCB[task_id-1U]; - - if (task == NULL) { - return; - } - task->events &= ~clear_flags; -} - - -/*--------------------------- isr_evt_set -----------------------------------*/ - -void isr_evt_set (U16 event_flags, OS_TID task_id) { - /* Same function as "os_evt_set", but to be called by ISRs. */ - P_TCB p_tcb = os_active_TCB[task_id-1U]; - - if (p_tcb == NULL) { - return; - } - rt_psq_enq (p_tcb, event_flags); - rt_psh_req (); -} - - -/*--------------------------- rt_evt_get ------------------------------------*/ - -U16 rt_evt_get (void) { - /* Get events of a running task after waiting for OR connected events. */ - return (os_tsk.run->waits); -} - - -/*--------------------------- rt_evt_psh ------------------------------------*/ - -void rt_evt_psh (P_TCB p_CB, U16 set_flags) { - /* Check if task has to be waken up */ - U16 event_flags; - - p_CB->events |= set_flags; - event_flags = p_CB->waits; - if (p_CB->state == WAIT_AND) { - /* Check for AND-connected events */ - if ((p_CB->events & event_flags) == event_flags) { - goto rdy; - } - } - if (p_CB->state == WAIT_OR) { - /* Check for OR-connected events */ - if (p_CB->events & event_flags) { - p_CB->waits &= p_CB->events; -rdy: p_CB->events &= ~event_flags; - rt_rmv_dly (p_CB); - p_CB->state = READY; -#ifdef __CMSIS_RTOS - rt_ret_val2(p_CB, 0x08U/*osEventSignal*/, p_CB->waits); -#else - rt_ret_val (p_CB, OS_R_EVT); -#endif - rt_put_prio (&os_rdy, p_CB); - } - } -} - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ diff --git a/rtos/rtx/TARGET_CORTEX_M/rt_Event.h b/rtos/rtx/TARGET_CORTEX_M/rt_Event.h deleted file mode 100644 index fe1b07217fd..00000000000 --- a/rtos/rtx/TARGET_CORTEX_M/rt_Event.h +++ /dev/null @@ -1,51 +0,0 @@ - -/** \addtogroup rtos */ -/** @{*/ -/*---------------------------------------------------------------------------- - * CMSIS-RTOS - RTX - *---------------------------------------------------------------------------- - * Name: RT_EVENT.H - * Purpose: Implements waits and wake-ups for event flags - * Rev.: V4.70 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -/* Functions */ -extern OS_RESULT rt_evt_wait (U16 wait_flags, U16 timeout, BOOL and_wait); -extern void rt_evt_set (U16 event_flags, OS_TID task_id); -extern void rt_evt_clr (U16 clear_flags, OS_TID task_id); -extern void isr_evt_set (U16 event_flags, OS_TID task_id); -extern U16 rt_evt_get (void); -extern void rt_evt_psh (P_TCB p_CB, U16 set_flags); - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ - - -/** @}*/ diff --git a/rtos/rtx/TARGET_CORTEX_M/rt_HAL_CM.h b/rtos/rtx/TARGET_CORTEX_M/rt_HAL_CM.h deleted file mode 100644 index f08d0fa1ebf..00000000000 --- a/rtos/rtx/TARGET_CORTEX_M/rt_HAL_CM.h +++ /dev/null @@ -1,344 +0,0 @@ - -/** \addtogroup rtos */ -/** @{*/ -/*---------------------------------------------------------------------------- - * CMSIS-RTOS - RTX - *---------------------------------------------------------------------------- - * Name: RT_HAL_CM.H - * Purpose: Hardware Abstraction Layer for Cortex-M definitions - * Rev.: V4.79 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -/* Definitions */ -#define INITIAL_xPSR 0x01000000U -#define DEMCR_TRCENA 0x01000000U -#define ITM_ITMENA 0x00000001U -#define MAGIC_WORD 0xE25A2EA5U -#define MAGIC_PATTERN 0xCCCCCCCCU - -#if defined (__CC_ARM) /* ARM Compiler */ - -#if ((defined(__TARGET_ARCH_7_M) || defined(__TARGET_ARCH_7E_M)) && !defined(NO_EXCLUSIVE_ACCESS)) - #define __USE_EXCLUSIVE_ACCESS -#else - #undef __USE_EXCLUSIVE_ACCESS -#endif - -/* Supress __ldrex and __strex deprecated warnings - "#3731-D: intrinsic is deprecated" */ -#ifdef __USE_EXCLUSIVE_ACCESS -#pragma diag_suppress 3731 -#endif - -#ifndef __CMSIS_GENERIC - -__attribute__((always_inline)) static inline U32 __get_PRIMASK(void) -{ - register U32 primask __asm("primask"); - return primask; -} - -#define __DMB() do {\ - __schedule_barrier();\ - __dmb(0xF);\ - __schedule_barrier();\ - } while (0) - -#endif - -#elif defined (__GNUC__) /* GNU Compiler */ - -#undef __USE_EXCLUSIVE_ACCESS - -#if defined (__CORTEX_M0) || defined (__CORTEX_M0PLUS) -#define __TARGET_ARCH_6S_M -#endif - -#if defined (__VFP_FP__) && !defined(__SOFTFP__) -#define __TARGET_FPU_VFP -#endif - -#define __inline inline -#define __weak __attribute__((weak)) - -#ifndef __CMSIS_GENERIC - -__attribute__((always_inline)) static inline U32 __get_PRIMASK(void) -{ - U32 result; - - __asm volatile ("mrs %0, primask" : "=r" (result)); - return result; -} - -__attribute__((always_inline)) static inline void __enable_irq(void) -{ - __asm volatile ("cpsie i"); -} - -__attribute__((always_inline)) static inline U32 __disable_irq(void) -{ - U32 result; - - __asm volatile ("mrs %0, primask" : "=r" (result)); - __asm volatile ("cpsid i"); - return(result & 1); -} - -__attribute__((always_inline)) static inline void __DMB(void) -{ - __asm volatile ("dmb 0xF":::"memory"); -} - -#endif - -__attribute__(( always_inline)) static inline U8 __clz(U32 value) -{ - U8 result; - - __asm volatile ("clz %0, %1" : "=r" (result) : "r" (value)); - return(result); -} - -#elif defined (__ICCARM__) /* IAR Compiler */ - -#undef __USE_EXCLUSIVE_ACCESS - -#if (__CORE__ == __ARM6M__) -#define __TARGET_ARCH_6S_M 1 -#endif - -#if defined __ARMVFP__ -#define __TARGET_FPU_VFP 1 -#endif - -#define __inline inline - -#ifndef __CMSIS_GENERIC - -static inline U32 __get_PRIMASK(void) -{ - U32 result; - - __asm volatile ("mrs %0, primask" : "=r" (result)); - return result; -} - -static inline void __enable_irq(void) -{ - __asm volatile ("cpsie i"); -} - -static inline U32 __disable_irq(void) -{ - U32 result; - - __asm volatile ("mrs %0, primask" : "=r" (result)); - __asm volatile ("cpsid i"); - return(result & 1); -} - -#endif - -static inline U8 __clz(U32 value) -{ - U8 result; - - __asm volatile ("clz %0, %1" : "=r" (result) : "r" (value)); - return(result); -} - -#endif - -/* NVIC registers */ -#define NVIC_ST_CTRL (*((volatile U32 *)0xE000E010U)) -#define NVIC_ST_RELOAD (*((volatile U32 *)0xE000E014U)) -#define NVIC_ST_CURRENT (*((volatile U32 *)0xE000E018U)) -#define NVIC_ISER ((volatile U32 *)0xE000E100U) -#define NVIC_ICER ((volatile U32 *)0xE000E180U) -#if defined(__TARGET_ARCH_6S_M) -#define NVIC_IP ((volatile U32 *)0xE000E400U) -#else -#define NVIC_IP ((volatile U8 *)0xE000E400U) -#endif -#define NVIC_INT_CTRL (*((volatile U32 *)0xE000ED04U)) -#define NVIC_AIR_CTRL (*((volatile U32 *)0xE000ED0CU)) -#define NVIC_SYS_PRI2 (*((volatile U32 *)0xE000ED1CU)) -#define NVIC_SYS_PRI3 (*((volatile U32 *)0xE000ED20U)) - -#define OS_PEND_IRQ() NVIC_INT_CTRL = (1UL<<28) -#define OS_PENDING ((NVIC_INT_CTRL >> 26) & 5U) -#define OS_UNPEND(fl) NVIC_INT_CTRL = (U32)(fl = (U8)OS_PENDING) << 25 -#define OS_PEND(fl,p) NVIC_INT_CTRL = (U32)(fl | (U8)(p<<2)) << 26 -#define OS_LOCK() NVIC_ST_CTRL = 0x0005U -#define OS_UNLOCK() NVIC_ST_CTRL = 0x0007U - -#define OS_X_PENDING ((NVIC_INT_CTRL >> 28) & 1U) -#define OS_X_UNPEND(fl) NVIC_INT_CTRL = (U32)(fl = (U8)OS_X_PENDING) << 27 -#define OS_X_PEND(fl,p) NVIC_INT_CTRL = (U32)(fl | p) << 28 -#if defined(__TARGET_ARCH_6S_M) -#define OS_X_INIT(n) NVIC_IP[n>>2] |= (U32)0xFFU << ((n & 0x03U) << 3); \ - NVIC_ISER[n>>5] = (U32)1U << (n & 0x1FU) -#else -#define OS_X_INIT(n) NVIC_IP[n] = 0xFFU; \ - NVIC_ISER[n>>5] = (U32)1U << (n & 0x1FU) -#endif -#define OS_X_LOCK(n) NVIC_ICER[n>>5] = (U32)1U << (n & 0x1FU) -#define OS_X_UNLOCK(n) NVIC_ISER[n>>5] = (U32)1U << (n & 0x1FU) - -/* Core Debug registers */ -#define DEMCR (*((volatile U32 *)0xE000EDFCU)) - -/* ITM registers */ -#define ITM_CONTROL (*((volatile U32 *)0xE0000E80U)) -#define ITM_ENABLE (*((volatile U32 *)0xE0000E00U)) -#define ITM_PORT30_U32 (*((volatile U32 *)0xE0000078U)) -#define ITM_PORT31_U32 (*((volatile U32 *)0xE000007CU)) -#define ITM_PORT31_U16 (*((volatile U16 *)0xE000007CU)) -#define ITM_PORT31_U8 (*((volatile U8 *)0xE000007CU)) - -/* Variables */ -extern BIT dbg_msg; - -/* Functions */ -#ifdef __USE_EXCLUSIVE_ACCESS - #define rt_inc(p) while(__strex((__ldrex(p)+1U),p)) - #define rt_dec(p) while(__strex((__ldrex(p)-1U),p)) -#else - #define rt_inc(p) do {\ - U32 primask = __get_PRIMASK();\ - __disable_irq();\ - (*p)++;\ - if (!primask) {\ - __enable_irq();\ - }\ - } while (0) - #define rt_dec(p) do {\ - U32 primask = __get_PRIMASK();\ - __disable_irq();\ - (*p)--;\ - if (!primask) {\ - __enable_irq();\ - }\ - } while (0) -#endif - -__inline static U32 rt_inc_qi (U32 size, U8 *count, U8 *first) { - U32 cnt,c2; -#ifdef __USE_EXCLUSIVE_ACCESS - do { - if ((cnt = __ldrex(count)) == size) { - __clrex(); - return (cnt); } - } while (__strex(cnt+1U, count)); - do { - c2 = (cnt = __ldrex(first)) + 1U; - if (c2 == size) { c2 = 0U; } - } while (__strex(c2, first)); -#else - U32 primask = __get_PRIMASK(); - __disable_irq(); - if ((cnt = *count) < size) { - *count = (U8)(cnt+1U); - c2 = (cnt = *first) + 1U; - if (c2 == size) { c2 = 0U; } - *first = (U8)c2; - } - if (!primask) { - __enable_irq (); - } -#endif - return (cnt); -} - -__inline static void rt_systick_init (void) { - NVIC_ST_RELOAD = os_trv; - NVIC_ST_CURRENT = 0U; - NVIC_ST_CTRL = 0x0007U; - NVIC_SYS_PRI3 |= 0xFF000000U; -} - -__inline static U32 rt_systick_val (void) { - return (os_trv - NVIC_ST_CURRENT); -} - -__inline static U32 rt_systick_ovf (void) { - return ((NVIC_INT_CTRL >> 26) & 1U); -} - -__inline static void rt_svc_init (void) { -#if !defined(__TARGET_ARCH_6S_M) - U32 sh,prigroup; -#endif - NVIC_SYS_PRI3 |= 0x00FF0000U; -#if defined(__TARGET_ARCH_6S_M) - NVIC_SYS_PRI2 |= (NVIC_SYS_PRI3<<(8+1)) & 0xFC000000U; -#else - sh = 8U - __clz(~((NVIC_SYS_PRI3 << 8) & 0xFF000000U)); - prigroup = ((NVIC_AIR_CTRL >> 8) & 0x07U); - if (prigroup >= sh) { - sh = prigroup + 1U; - } - -/* Only change the SVCall priority if uVisor is not present. */ -#if !(defined(FEATURE_UVISOR) && defined(TARGET_UVISOR_SUPPORTED)) - NVIC_SYS_PRI2 = ((0xFEFFFFFFU << sh) & 0xFF000000U) | (NVIC_SYS_PRI2 & 0x00FFFFFFU); -#endif /* !(defined(FEATURE_UVISOR) && defined(TARGET_UVISOR_SUPPORTED)) */ -#endif -} - -extern void rt_set_PSP (U32 stack); -extern U32 rt_get_PSP (void); -extern void os_set_env (void); -extern void *_alloc_box (void *box_mem); -extern U32 _free_box (void *box_mem, void *box); - -extern void rt_init_stack (P_TCB p_TCB, FUNCP task_body); -extern void rt_ret_val (P_TCB p_TCB, U32 v0); -extern void rt_ret_val2 (P_TCB p_TCB, U32 v0, U32 v1); - -extern void dbg_init (void); -extern void dbg_task_notify (P_TCB p_tcb, BOOL create); -extern void dbg_task_switch (U32 task_id); - -#ifdef DBG_MSG -#define DBG_INIT() dbg_init() -#define DBG_TASK_NOTIFY(p_tcb,create) if (dbg_msg) dbg_task_notify(p_tcb,create) -#define DBG_TASK_SWITCH(task_id) if (dbg_msg && (os_tsk.new_tsk!=os_tsk.run)) \ - dbg_task_switch(task_id) -#else -#define DBG_INIT() -#define DBG_TASK_NOTIFY(p_tcb,create) -#define DBG_TASK_SWITCH(task_id) -#endif - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ - -/** @}*/ diff --git a/rtos/rtx/TARGET_CORTEX_M/rt_List.c b/rtos/rtx/TARGET_CORTEX_M/rt_List.c deleted file mode 100644 index fbf4a35aef2..00000000000 --- a/rtos/rtx/TARGET_CORTEX_M/rt_List.c +++ /dev/null @@ -1,318 +0,0 @@ -/*---------------------------------------------------------------------------- - * CMSIS-RTOS - RTX - *---------------------------------------------------------------------------- - * Name: RT_LIST.C - * Purpose: Functions for the management of different lists - * Rev.: V4.79 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -#include "rt_TypeDef.h" -#include "RTX_Config.h" -#include "rt_System.h" -#include "rt_List.h" -#include "rt_Task.h" -#include "rt_Time.h" -#include "rt_HAL_CM.h" - -/*---------------------------------------------------------------------------- - * Global Variables - *---------------------------------------------------------------------------*/ - -/* List head of chained ready tasks */ -struct OS_XCB os_rdy; -/* List head of chained delay tasks */ -struct OS_XCB os_dly; - - -/*---------------------------------------------------------------------------- - * Functions - *---------------------------------------------------------------------------*/ - - -/*--------------------------- rt_put_prio -----------------------------------*/ - -void rt_put_prio (P_XCB p_CB, P_TCB p_task) { - /* Put task identified with "p_task" into list ordered by priority. */ - /* "p_CB" points to head of list; list has always an element at end with */ - /* a priority less than "p_task->prio". */ - P_TCB p_CB2; - U32 prio; - BOOL sem_mbx = __FALSE; - - if ((p_CB->cb_type == SCB) || (p_CB->cb_type == MCB) || (p_CB->cb_type == MUCB)) { - sem_mbx = __TRUE; - } - prio = p_task->prio; - p_CB2 = p_CB->p_lnk; - /* Search for an entry in the list */ - while ((p_CB2 != NULL) && (prio <= p_CB2->prio)) { - p_CB = (P_XCB)p_CB2; - p_CB2 = p_CB2->p_lnk; - } - /* Entry found, insert the task into the list */ - p_task->p_lnk = p_CB2; - p_CB->p_lnk = p_task; - if (sem_mbx) { - if (p_CB2 != NULL) { - p_CB2->p_rlnk = p_task; - } - p_task->p_rlnk = (P_TCB)p_CB; - } - else { - p_task->p_rlnk = NULL; - } -} - - -/*--------------------------- rt_get_first ----------------------------------*/ - -P_TCB rt_get_first (P_XCB p_CB) { - /* Get task at head of list: it is the task with highest priority. */ - /* "p_CB" points to head of list. */ - P_TCB p_first; - - p_first = p_CB->p_lnk; - p_CB->p_lnk = p_first->p_lnk; - if ((p_CB->cb_type == SCB) || (p_CB->cb_type == MCB) || (p_CB->cb_type == MUCB)) { - if (p_first->p_lnk != NULL) { - p_first->p_lnk->p_rlnk = (P_TCB)p_CB; - p_first->p_lnk = NULL; - } - p_first->p_rlnk = NULL; - } - else { - p_first->p_lnk = NULL; - } - return (p_first); -} - - -/*--------------------------- rt_put_rdy_first ------------------------------*/ - -void rt_put_rdy_first (P_TCB p_task) { - /* Put task identified with "p_task" at the head of the ready list. The */ - /* task must have at least a priority equal to highest priority in list. */ - p_task->p_lnk = os_rdy.p_lnk; - p_task->p_rlnk = NULL; - os_rdy.p_lnk = p_task; -} - - -/*--------------------------- rt_get_same_rdy_prio --------------------------*/ - -P_TCB rt_get_same_rdy_prio (void) { - /* Remove a task of same priority from ready list if any exists. Other- */ - /* wise return NULL. */ - P_TCB p_first; - - p_first = os_rdy.p_lnk; - if (p_first->prio == os_tsk.run->prio) { - os_rdy.p_lnk = os_rdy.p_lnk->p_lnk; - return (p_first); - } - return (NULL); -} - - -/*--------------------------- rt_resort_prio --------------------------------*/ - -void rt_resort_prio (P_TCB p_task) { - /* Re-sort ordered lists after the priority of 'p_task' has changed. */ - P_TCB p_CB; - - if (p_task->p_rlnk == NULL) { - if (p_task->state == READY) { - /* Task is chained into READY list. */ - p_CB = (P_TCB)&os_rdy; - goto res; - } - } - else { - p_CB = p_task->p_rlnk; - while (p_CB->cb_type == TCB) { - /* Find a header of this task chain list. */ - p_CB = p_CB->p_rlnk; - } -res:rt_rmv_list (p_task); - rt_put_prio ((P_XCB)p_CB, p_task); - } -} - - -/*--------------------------- rt_put_dly ------------------------------------*/ - -void rt_put_dly (P_TCB p_task, U16 delay) { - /* Put a task identified with "p_task" into chained delay wait list using */ - /* a delay value of "delay". */ - P_TCB p; - U32 delta,idelay = delay; - - p = (P_TCB)&os_dly; - if (p->p_dlnk == NULL) { - /* Delay list empty */ - delta = 0U; - goto last; - } - delta = os_dly.delta_time; - while (delta < idelay) { - if (p->p_dlnk == NULL) { - /* End of list found */ -last: p_task->p_dlnk = NULL; - p->p_dlnk = p_task; - p_task->p_blnk = p; - p->delta_time = (U16)(idelay - delta); - p_task->delta_time = 0U; - return; - } - p = p->p_dlnk; - delta += p->delta_time; - } - /* Right place found */ - p_task->p_dlnk = p->p_dlnk; - p->p_dlnk = p_task; - p_task->p_blnk = p; - if (p_task->p_dlnk != NULL) { - p_task->p_dlnk->p_blnk = p_task; - } - p_task->delta_time = (U16)(delta - idelay); - p->delta_time -= p_task->delta_time; -} - - -/*--------------------------- rt_dec_dly ------------------------------------*/ - -void rt_dec_dly (void) { - /* Decrement delta time of list head: remove tasks having a value of zero.*/ - P_TCB p_rdy; - - if (os_dly.p_dlnk == NULL) { - return; - } - os_dly.delta_time--; - while ((os_dly.delta_time == 0U) && (os_dly.p_dlnk != NULL)) { - p_rdy = os_dly.p_dlnk; - if (p_rdy->p_rlnk != NULL) { - /* Task is really enqueued, remove task from semaphore/mailbox */ - /* timeout waiting list. */ - p_rdy->p_rlnk->p_lnk = p_rdy->p_lnk; - if (p_rdy->p_lnk != NULL) { - p_rdy->p_lnk->p_rlnk = p_rdy->p_rlnk; - p_rdy->p_lnk = NULL; - } - p_rdy->p_rlnk = NULL; - } - rt_put_prio (&os_rdy, p_rdy); - os_dly.delta_time = p_rdy->delta_time; - if (p_rdy->state == WAIT_ITV) { - /* Calculate the next time for interval wait. */ - p_rdy->delta_time = p_rdy->interval_time + (U16)os_time; - } - p_rdy->state = READY; - os_dly.p_dlnk = p_rdy->p_dlnk; - if (p_rdy->p_dlnk != NULL) { - p_rdy->p_dlnk->p_blnk = (P_TCB)&os_dly; - p_rdy->p_dlnk = NULL; - } - p_rdy->p_blnk = NULL; - } -} - - -/*--------------------------- rt_rmv_list -----------------------------------*/ - -void rt_rmv_list (P_TCB p_task) { - /* Remove task identified with "p_task" from ready, semaphore or mailbox */ - /* waiting list if enqueued. */ - P_TCB p_b; - - if (p_task->p_rlnk != NULL) { - /* A task is enqueued in semaphore / mailbox waiting list. */ - p_task->p_rlnk->p_lnk = p_task->p_lnk; - if (p_task->p_lnk != NULL) { - p_task->p_lnk->p_rlnk = p_task->p_rlnk; - } - return; - } - - p_b = (P_TCB)&os_rdy; - while (p_b != NULL) { - /* Search the ready list for task "p_task" */ - if (p_b->p_lnk == p_task) { - p_b->p_lnk = p_task->p_lnk; - return; - } - p_b = p_b->p_lnk; - } -} - - -/*--------------------------- rt_rmv_dly ------------------------------------*/ - -void rt_rmv_dly (P_TCB p_task) { - /* Remove task identified with "p_task" from delay list if enqueued. */ - P_TCB p_b; - - p_b = p_task->p_blnk; - if (p_b != NULL) { - /* Task is really enqueued */ - p_b->p_dlnk = p_task->p_dlnk; - if (p_task->p_dlnk != NULL) { - /* 'p_task' is in the middle of list */ - p_b->delta_time += p_task->delta_time; - p_task->p_dlnk->p_blnk = p_b; - p_task->p_dlnk = NULL; - } - else { - /* 'p_task' is at the end of list */ - p_b->delta_time = 0U; - } - p_task->p_blnk = NULL; - } -} - - -/*--------------------------- rt_psq_enq ------------------------------------*/ - -void rt_psq_enq (OS_ID entry, U32 arg) { - /* Insert post service request "entry" into ps-queue. */ - U32 idx; - - idx = rt_inc_qi (os_psq->size, &os_psq->count, &os_psq->first); - if (idx < os_psq->size) { - os_psq->q[idx].id = entry; - os_psq->q[idx].arg = arg; - } - else { - os_error (OS_ERR_FIFO_OVF); - } -} - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ diff --git a/rtos/rtx/TARGET_CORTEX_M/rt_List.h b/rtos/rtx/TARGET_CORTEX_M/rt_List.h deleted file mode 100644 index e8da72420ed..00000000000 --- a/rtos/rtx/TARGET_CORTEX_M/rt_List.h +++ /dev/null @@ -1,72 +0,0 @@ - -/** \addtogroup rtos */ -/** @{*/ -/*---------------------------------------------------------------------------- - * CMSIS-RTOS - RTX - *---------------------------------------------------------------------------- - * Name: RT_LIST.H - * Purpose: Functions for the management of different lists - * Rev.: V4.79 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -/* Definitions */ - -/* Values for 'cb_type' */ -#define TCB 0U -#define MCB 1U -#define SCB 2U -#define MUCB 3U -#define HCB 4U - -/* Variables */ -extern struct OS_XCB os_rdy; -extern struct OS_XCB os_dly; - -/* Functions */ -extern void rt_put_prio (P_XCB p_CB, P_TCB p_task); -extern P_TCB rt_get_first (P_XCB p_CB); -extern void rt_put_rdy_first (P_TCB p_task); -extern P_TCB rt_get_same_rdy_prio (void); -extern void rt_resort_prio (P_TCB p_task); -extern void rt_put_dly (P_TCB p_task, U16 delay); -extern void rt_dec_dly (void); -extern void rt_rmv_list (P_TCB p_task); -extern void rt_rmv_dly (P_TCB p_task); -extern void rt_psq_enq (OS_ID entry, U32 arg); - -/* This is a fast macro generating in-line code */ -#define rt_rdy_prio(void) (os_rdy.p_lnk->prio) - - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ - - -/** @}*/ diff --git a/rtos/rtx/TARGET_CORTEX_M/rt_Mailbox.c b/rtos/rtx/TARGET_CORTEX_M/rt_Mailbox.c deleted file mode 100644 index 456b0ac6e27..00000000000 --- a/rtos/rtx/TARGET_CORTEX_M/rt_Mailbox.c +++ /dev/null @@ -1,293 +0,0 @@ -/*---------------------------------------------------------------------------- - * CMSIS-RTOS - RTX - *---------------------------------------------------------------------------- - * Name: RT_MAILBOX.C - * Purpose: Implements waits and wake-ups for mailbox messages - * Rev.: V4.79 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -#include "rt_TypeDef.h" -#include "RTX_Config.h" -#include "rt_System.h" -#include "rt_List.h" -#include "rt_Mailbox.h" -#include "rt_MemBox.h" -#include "rt_Task.h" -#include "rt_HAL_CM.h" - - -/*---------------------------------------------------------------------------- - * Functions - *---------------------------------------------------------------------------*/ - - -/*--------------------------- rt_mbx_init -----------------------------------*/ - -void rt_mbx_init (OS_ID mailbox, U16 mbx_size) { - /* Initialize a mailbox */ - P_MCB p_MCB = mailbox; - - p_MCB->cb_type = MCB; - p_MCB->state = 0U; - p_MCB->isr_st = 0U; - p_MCB->p_lnk = NULL; - p_MCB->first = 0U; - p_MCB->last = 0U; - p_MCB->count = 0U; - p_MCB->size = (U16)((mbx_size - (sizeof(struct OS_MCB) - (sizeof(void *)))) - / sizeof(void *)); -} - - -/*--------------------------- rt_mbx_send -----------------------------------*/ - -OS_RESULT rt_mbx_send (OS_ID mailbox, void *p_msg, U16 timeout) { - /* Send message to a mailbox */ - P_MCB p_MCB = mailbox; - P_TCB p_TCB; - - if ((p_MCB->p_lnk != NULL) && (p_MCB->state == 1U)) { - /* A task is waiting for message */ - p_TCB = rt_get_first ((P_XCB)p_MCB); -#ifdef __CMSIS_RTOS - rt_ret_val2(p_TCB, 0x10U/*osEventMessage*/, (U32)p_msg); -#else - *p_TCB->msg = p_msg; - rt_ret_val (p_TCB, OS_R_MBX); -#endif - rt_rmv_dly (p_TCB); - rt_dispatch (p_TCB); - } - else { - /* Store message in mailbox queue */ - if (p_MCB->count == p_MCB->size) { - /* No free message entry, wait for one. If message queue is full, */ - /* then no task is waiting for message. The 'p_MCB->p_lnk' list */ - /* pointer can now be reused for send message waits task list. */ - if (timeout == 0U) { - return (OS_R_TMO); - } - if (p_MCB->p_lnk != NULL) { - rt_put_prio ((P_XCB)p_MCB, os_tsk.run); - } - else { - p_MCB->p_lnk = os_tsk.run; - os_tsk.run->p_lnk = NULL; - os_tsk.run->p_rlnk = (P_TCB)p_MCB; - /* Task is waiting to send a message */ - p_MCB->state = 2U; - } - os_tsk.run->msg = p_msg; - rt_block (timeout, WAIT_MBX); - return (OS_R_TMO); - } - /* Yes, there is a free entry in a mailbox. */ - p_MCB->msg[p_MCB->first] = p_msg; - rt_inc (&p_MCB->count); - if (++p_MCB->first == p_MCB->size) { - p_MCB->first = 0U; - } - } - return (OS_R_OK); -} - - -/*--------------------------- rt_mbx_wait -----------------------------------*/ - -OS_RESULT rt_mbx_wait (OS_ID mailbox, void **message, U16 timeout) { - /* Receive a message; possibly wait for it */ - P_MCB p_MCB = mailbox; - P_TCB p_TCB; - - /* If a message is available in the fifo buffer */ - /* remove it from the fifo buffer and return. */ - if (p_MCB->count) { - *message = p_MCB->msg[p_MCB->last]; - if (++p_MCB->last == p_MCB->size) { - p_MCB->last = 0U; - } - if ((p_MCB->p_lnk != NULL) && (p_MCB->state == 2U)) { - /* A task is waiting to send message */ - p_TCB = rt_get_first ((P_XCB)p_MCB); -#ifdef __CMSIS_RTOS - rt_ret_val(p_TCB, 0U/*osOK*/); -#else - rt_ret_val(p_TCB, OS_R_OK); -#endif - p_MCB->msg[p_MCB->first] = p_TCB->msg; - if (++p_MCB->first == p_MCB->size) { - p_MCB->first = 0U; - } - rt_rmv_dly (p_TCB); - rt_dispatch (p_TCB); - } - else { - rt_dec (&p_MCB->count); - } - return (OS_R_OK); - } - /* No message available: wait for one */ - if (timeout == 0U) { - return (OS_R_TMO); - } - if (p_MCB->p_lnk != NULL) { - rt_put_prio ((P_XCB)p_MCB, os_tsk.run); - } - else { - p_MCB->p_lnk = os_tsk.run; - os_tsk.run->p_lnk = NULL; - os_tsk.run->p_rlnk = (P_TCB)p_MCB; - /* Task is waiting to receive a message */ - p_MCB->state = 1U; - } - rt_block(timeout, WAIT_MBX); -#ifndef __CMSIS_RTOS - os_tsk.run->msg = message; -#endif - return (OS_R_TMO); -} - - -/*--------------------------- rt_mbx_check ----------------------------------*/ - -OS_RESULT rt_mbx_check (OS_ID mailbox) { - /* Check for free space in a mailbox. Returns the number of messages */ - /* that can be stored to a mailbox. It returns 0 when mailbox is full. */ - P_MCB p_MCB = mailbox; - - return ((U32)(p_MCB->size - p_MCB->count)); -} - - -/*--------------------------- isr_mbx_send ----------------------------------*/ - -void isr_mbx_send (OS_ID mailbox, void *p_msg) { - /* Same function as "os_mbx_send", but to be called by ISRs. */ - P_MCB p_MCB = mailbox; - - rt_psq_enq (p_MCB, (U32)p_msg); - rt_psh_req (); -} - - -/*--------------------------- isr_mbx_receive -------------------------------*/ - -OS_RESULT isr_mbx_receive (OS_ID mailbox, void **message) { - /* Receive a message in the interrupt function. The interrupt function */ - /* should not wait for a message since this would block the rtx os. */ - P_MCB p_MCB = mailbox; - - if (p_MCB->count) { - /* A message is available in the fifo buffer. */ - *message = p_MCB->msg[p_MCB->last]; - if (p_MCB->state == 2U) { - /* A task is locked waiting to send message */ - rt_psq_enq (p_MCB, 0U); - rt_psh_req (); - } - rt_dec (&p_MCB->count); - if (++p_MCB->last == p_MCB->size) { - p_MCB->last = 0U; - } - return (OS_R_MBX); - } - return (OS_R_OK); -} - - -/*--------------------------- rt_mbx_psh ------------------------------------*/ - -void rt_mbx_psh (P_MCB p_CB, void *p_msg) { - /* Store the message to the mailbox queue or pass it to task directly. */ - P_TCB p_TCB; - void *mem; - - if (p_CB->p_lnk != NULL) switch (p_CB->state) { -#ifdef __CMSIS_RTOS - case 3: - /* Task is waiting to allocate memory, remove it from the waiting list */ - mem = rt_alloc_box(p_msg); - if (mem == NULL) { break; } - p_TCB = rt_get_first ((P_XCB)p_CB); - rt_ret_val(p_TCB, (U32)mem); - p_TCB->state = READY; - rt_rmv_dly (p_TCB); - rt_put_prio (&os_rdy, p_TCB); - break; -#endif - case 2: - /* Task is waiting to send a message, remove it from the waiting list */ - p_TCB = rt_get_first ((P_XCB)p_CB); -#ifdef __CMSIS_RTOS - rt_ret_val(p_TCB, 0U/*osOK*/); -#else - rt_ret_val(p_TCB, OS_R_OK); -#endif - p_CB->msg[p_CB->first] = p_TCB->msg; - rt_inc (&p_CB->count); - if (++p_CB->first == p_CB->size) { - p_CB->first = 0U; - } - p_TCB->state = READY; - rt_rmv_dly (p_TCB); - rt_put_prio (&os_rdy, p_TCB); - break; - case 1: - /* Task is waiting for a message, pass the message to the task directly */ - p_TCB = rt_get_first ((P_XCB)p_CB); -#ifdef __CMSIS_RTOS - rt_ret_val2(p_TCB, 0x10U/*osEventMessage*/, (U32)p_msg); -#else - *p_TCB->msg = p_msg; - rt_ret_val (p_TCB, OS_R_MBX); -#endif - p_TCB->state = READY; - rt_rmv_dly (p_TCB); - rt_put_prio (&os_rdy, p_TCB); - break; - default: - break; - } else { - /* No task is waiting for a message, store it to the mailbox queue */ - if (p_CB->count < p_CB->size) { - p_CB->msg[p_CB->first] = p_msg; - rt_inc (&p_CB->count); - if (++p_CB->first == p_CB->size) { - p_CB->first = 0U; - } - } - else { - os_error (OS_ERR_MBX_OVF); - } - } -} - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ diff --git a/rtos/rtx/TARGET_CORTEX_M/rt_Mailbox.h b/rtos/rtx/TARGET_CORTEX_M/rt_Mailbox.h deleted file mode 100644 index c63ba3aecef..00000000000 --- a/rtos/rtx/TARGET_CORTEX_M/rt_Mailbox.h +++ /dev/null @@ -1,53 +0,0 @@ - -/** \addtogroup rtos */ -/** @{*/ -/*---------------------------------------------------------------------------- - * CMSIS-RTOS - RTX - *---------------------------------------------------------------------------- - * Name: RT_MAILBOX.H - * Purpose: Implements waits and wake-ups for mailbox messages - * Rev.: V4.70 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -/* Functions */ -extern void rt_mbx_init (OS_ID mailbox, U16 mbx_size); -extern OS_RESULT rt_mbx_send (OS_ID mailbox, void *p_msg, U16 timeout); -extern OS_RESULT rt_mbx_wait (OS_ID mailbox, void **message, U16 timeout); -extern OS_RESULT rt_mbx_check (OS_ID mailbox); -extern void isr_mbx_send (OS_ID mailbox, void *p_msg); -extern OS_RESULT isr_mbx_receive (OS_ID mailbox, void **message); -extern void rt_mbx_psh (P_MCB p_CB, void *p_msg); - - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ - - -/** @}*/ diff --git a/rtos/rtx/TARGET_CORTEX_M/rt_MemBox.c b/rtos/rtx/TARGET_CORTEX_M/rt_MemBox.c deleted file mode 100644 index 8df30441f19..00000000000 --- a/rtos/rtx/TARGET_CORTEX_M/rt_MemBox.c +++ /dev/null @@ -1,168 +0,0 @@ -/*---------------------------------------------------------------------------- - * CMSIS-RTOS - RTX - *---------------------------------------------------------------------------- - * Name: RT_MEMBOX.C - * Purpose: Interface functions for fixed memory block management system - * Rev.: V4.79 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -#include "rt_TypeDef.h" -#include "RTX_Config.h" -#include "rt_System.h" -#include "rt_MemBox.h" -#include "rt_HAL_CM.h" - -/*---------------------------------------------------------------------------- - * Global Functions - *---------------------------------------------------------------------------*/ - - -/*--------------------------- _init_box -------------------------------------*/ - -U32 _init_box (void *box_mem, U32 box_size, U32 blk_size) { - /* Initialize memory block system, returns 0 if OK, 1 if fails. */ - void *end; - void *blk; - void *next; - U32 sizeof_bm; - - /* Create memory structure. */ - if (blk_size & BOX_ALIGN_8) { - /* Memory blocks 8-byte aligned. */ - blk_size = ((blk_size & ~BOX_ALIGN_8) + 7U) & ~(U32)7U; - sizeof_bm = (sizeof (struct OS_BM) + 7U) & ~(U32)7U; - } - else { - /* Memory blocks 4-byte aligned. */ - blk_size = (blk_size + 3U) & ~(U32)3U; - sizeof_bm = sizeof (struct OS_BM); - } - if (blk_size == 0U) { - return (1U); - } - if ((blk_size + sizeof_bm) > box_size) { - return (1U); - } - /* Create a Memory structure. */ - blk = ((U8 *) box_mem) + sizeof_bm; - ((P_BM) box_mem)->free = blk; - end = ((U8 *) box_mem) + box_size; - ((P_BM) box_mem)->end = end; - ((P_BM) box_mem)->blk_size = blk_size; - - /* Link all free blocks using offsets. */ - end = ((U8 *) end) - blk_size; - while (1) { - next = ((U8 *) blk) + blk_size; - if (next > end) { break; } - *((void **)blk) = next; - blk = next; - } - /* end marker */ - *((void **)blk) = 0U; - return (0U); -} - -/*--------------------------- rt_alloc_box ----------------------------------*/ - -void *rt_alloc_box (void *box_mem) { - /* Allocate a memory block and return start address. */ - void **free; -#ifndef __USE_EXCLUSIVE_ACCESS - U32 irq_mask; - - irq_mask = (U32)__disable_irq (); - free = ((P_BM) box_mem)->free; - if (free) { - ((P_BM) box_mem)->free = *free; - } - if (irq_mask == 0U) { __enable_irq (); } -#else - do { - if ((free = (void **)__ldrex(&((P_BM) box_mem)->free)) == 0U) { - __clrex(); - break; - } - } while (__strex((U32)*free, &((P_BM) box_mem)->free)); -#endif - return (free); -} - - -/*--------------------------- _calloc_box -----------------------------------*/ - -void *_calloc_box (void *box_mem) { - /* Allocate a 0-initialized memory block and return start address. */ - void *free; - U32 *p; - U32 i; - - free = _alloc_box (box_mem); - if (free) { - p = free; - for (i = ((P_BM) box_mem)->blk_size; i; i -= 4U) { - *p = 0U; - p++; - } - } - return (free); -} - - -/*--------------------------- rt_free_box -----------------------------------*/ - -U32 rt_free_box (void *box_mem, void *box) { - /* Free a memory block, returns 0 if OK, 1 if box does not belong to box_mem */ -#ifndef __USE_EXCLUSIVE_ACCESS - U32 irq_mask; -#endif - - if ((box < box_mem) || (box >= ((P_BM) box_mem)->end)) { - return (1U); - } - -#ifndef __USE_EXCLUSIVE_ACCESS - irq_mask = (U32)__disable_irq (); - *((void **)box) = ((P_BM) box_mem)->free; - ((P_BM) box_mem)->free = box; - if (irq_mask == 0U) { __enable_irq (); } -#else - do { - do { - *((void **)box) = ((P_BM) box_mem)->free; - __DMB(); - } while (*(void**)box != (void *)__ldrex(&((P_BM) box_mem)->free)); - } while (__strex ((U32)box, &((P_BM) box_mem)->free)); -#endif - return (0U); -} - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ diff --git a/rtos/rtx/TARGET_CORTEX_M/rt_MemBox.h b/rtos/rtx/TARGET_CORTEX_M/rt_MemBox.h deleted file mode 100644 index 693e1267106..00000000000 --- a/rtos/rtx/TARGET_CORTEX_M/rt_MemBox.h +++ /dev/null @@ -1,50 +0,0 @@ - -/** \addtogroup rtos */ -/** @{*/ -/*---------------------------------------------------------------------------- - * CMSIS-RTOS - RTX - *---------------------------------------------------------------------------- - * Name: RT_MEMBOX.H - * Purpose: Interface functions for fixed memory block management system - * Rev.: V4.79 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -/* Functions */ -#define rt_init_box _init_box -#define rt_calloc_box _calloc_box -extern U32 _init_box (void *box_mem, U32 box_size, U32 blk_size); -extern void *rt_alloc_box (void *box_mem); -extern void * _calloc_box (void *box_mem); -extern U32 rt_free_box (void *box_mem, void *box); - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ - -/** @}*/ diff --git a/rtos/rtx/TARGET_CORTEX_M/rt_Memory.c b/rtos/rtx/TARGET_CORTEX_M/rt_Memory.c deleted file mode 100644 index 7ade9e1c0e5..00000000000 --- a/rtos/rtx/TARGET_CORTEX_M/rt_Memory.c +++ /dev/null @@ -1,140 +0,0 @@ -/*---------------------------------------------------------------------------- - * CMSIS-RTOS - RTX - *---------------------------------------------------------------------------- - * Name: RT_MEMORY.C - * Purpose: Interface functions for Dynamic Memory Management System - * Rev.: V4.79 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -#include "rt_TypeDef.h" -#include "rt_Memory.h" - - -/* Functions */ - -// Initialize Dynamic Memory pool -// Parameters: -// pool: Pointer to memory pool -// size: Size of memory pool in bytes -// Return: 0 - OK, 1 - Error - -U32 rt_init_mem (void *pool, U32 size) { - MEMP *ptr; - - if ((pool == NULL) || (size < sizeof(MEMP))) { return (1U); } - - ptr = (MEMP *)pool; - ptr->next = (MEMP *)((U32)pool + size - sizeof(MEMP *)); - ptr->next->next = NULL; - ptr->len = 0U; - - return (0U); -} - -// Allocate Memory from Memory pool -// Parameters: -// pool: Pointer to memory pool -// size: Size of memory in bytes to allocate -// Return: Pointer to allocated memory - -void *rt_alloc_mem (void *pool, U32 size) { - MEMP *p, *p_search, *p_new; - U32 hole_size; - - if ((pool == NULL) || (size == 0U)) { return NULL; } - - /* Add header offset to 'size' */ - size += sizeof(MEMP); - /* Make sure that block is 4-byte aligned */ - size = (size + 3U) & ~(U32)3U; - - p_search = (MEMP *)pool; - while (1) { - hole_size = (U32)p_search->next - (U32)p_search; - hole_size -= p_search->len; - /* Check if hole size is big enough */ - if (hole_size >= size) { break; } - p_search = p_search->next; - if (p_search->next == NULL) { - /* Failed, we are at the end of the list */ - return NULL; - } - } - - if (p_search->len == 0U) { - /* No block is allocated, set the Length of the first element */ - p_search->len = size; - p = (MEMP *)(((U32)p_search) + sizeof(MEMP)); - } else { - /* Insert new list element into the memory list */ - p_new = (MEMP *)((U32)p_search + p_search->len); - p_new->next = p_search->next; - p_new->len = size; - p_search->next = p_new; - p = (MEMP *)(((U32)p_new) + sizeof(MEMP)); - } - - return (p); -} - -// Free Memory and return it to Memory pool -// Parameters: -// pool: Pointer to memory pool -// mem: Pointer to memory to free -// Return: 0 - OK, 1 - Error - -U32 rt_free_mem (void *pool, void *mem) { - MEMP *p_search, *p_prev, *p_return; - - if ((pool == NULL) || (mem == NULL)) { return (1U); } - - p_return = (MEMP *)((U32)mem - sizeof(MEMP)); - - /* Set list header */ - p_prev = NULL; - p_search = (MEMP *)pool; - while (p_search != p_return) { - p_prev = p_search; - p_search = p_search->next; - if (p_search == NULL) { - /* Valid Memory block not found */ - return (1U); - } - } - - if (p_prev == NULL) { - /* First block to be released, only set length to 0 */ - p_search->len = 0U; - } else { - /* Discard block from chain list */ - p_prev->next = p_search->next; - } - - return (0U); -} diff --git a/rtos/rtx/TARGET_CORTEX_M/rt_Memory.h b/rtos/rtx/TARGET_CORTEX_M/rt_Memory.h deleted file mode 100644 index 51b759d9742..00000000000 --- a/rtos/rtx/TARGET_CORTEX_M/rt_Memory.h +++ /dev/null @@ -1,49 +0,0 @@ - -/** \addtogroup rtos */ -/** @{*/ -/*---------------------------------------------------------------------------- - * CMSIS-RTOS - RTX - *---------------------------------------------------------------------------- - * Name: RT_MEMORY.H - * Purpose: Interface functions for Dynamic Memory Management System - * Rev.: V4.79 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -/* Types */ -typedef struct mem { /* << Memory Pool management struct >> */ - struct mem *next; /* Next Memory Block in the list */ - U32 len; /* Length of data block */ -} MEMP; - -/* Functions */ -extern U32 rt_init_mem (void *pool, U32 size); -extern void *rt_alloc_mem (void *pool, U32 size); -extern U32 rt_free_mem (void *pool, void *mem); - -/** @}*/ diff --git a/rtos/rtx/TARGET_CORTEX_M/rt_Mutex.c b/rtos/rtx/TARGET_CORTEX_M/rt_Mutex.c deleted file mode 100644 index 64afdd70493..00000000000 --- a/rtos/rtx/TARGET_CORTEX_M/rt_Mutex.c +++ /dev/null @@ -1,259 +0,0 @@ -/*---------------------------------------------------------------------------- - * CMSIS-RTOS - RTX - *---------------------------------------------------------------------------- - * Name: RT_MUTEX.C - * Purpose: Implements mutex synchronization objects - * Rev.: V4.79 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -#include "rt_TypeDef.h" -#include "RTX_Config.h" -#include "rt_List.h" -#include "rt_Task.h" -#include "rt_Mutex.h" -#include "rt_HAL_CM.h" - - -/*---------------------------------------------------------------------------- - * Functions - *---------------------------------------------------------------------------*/ - - -/*--------------------------- rt_mut_init -----------------------------------*/ - -void rt_mut_init (OS_ID mutex) { - /* Initialize a mutex object */ - P_MUCB p_MCB = mutex; - - p_MCB->cb_type = MUCB; - p_MCB->level = 0U; - p_MCB->p_lnk = NULL; - p_MCB->owner = NULL; - p_MCB->p_mlnk = NULL; -} - - -/*--------------------------- rt_mut_delete ---------------------------------*/ - -#ifdef __CMSIS_RTOS -OS_RESULT rt_mut_delete (OS_ID mutex) { - /* Delete a mutex object */ - P_MUCB p_MCB = mutex; - P_TCB p_TCB; - P_MUCB p_mlnk; - U8 prio; - - if (p_MCB->level != 0U) { - - p_TCB = p_MCB->owner; - - /* Remove mutex from task mutex owner list. */ - p_mlnk = p_TCB->p_mlnk; - if (p_mlnk == p_MCB) { - p_TCB->p_mlnk = p_MCB->p_mlnk; - } - else { - while (p_mlnk) { - if (p_mlnk->p_mlnk == p_MCB) { - p_mlnk->p_mlnk = p_MCB->p_mlnk; - break; - } - p_mlnk = p_mlnk->p_mlnk; - } - } - - /* Restore owner task's priority. */ - prio = p_TCB->prio_base; - p_mlnk = p_TCB->p_mlnk; - while (p_mlnk) { - if ((p_mlnk->p_lnk != NULL) && (p_mlnk->p_lnk->prio > prio)) { - /* A task with higher priority is waiting for mutex. */ - prio = p_mlnk->p_lnk->prio; - } - p_mlnk = p_mlnk->p_mlnk; - } - if (p_TCB->prio != prio) { - p_TCB->prio = prio; - if (p_TCB != os_tsk.run) { - rt_resort_prio (p_TCB); - } - } - - } - - while (p_MCB->p_lnk != NULL) { - /* A task is waiting for mutex. */ - p_TCB = rt_get_first ((P_XCB)p_MCB); - rt_ret_val(p_TCB, 0U/*osOK*/); - rt_rmv_dly(p_TCB); - p_TCB->state = READY; - rt_put_prio (&os_rdy, p_TCB); - } - - if ((os_rdy.p_lnk != NULL) && (os_rdy.p_lnk->prio > os_tsk.run->prio)) { - /* preempt running task */ - rt_put_prio (&os_rdy, os_tsk.run); - os_tsk.run->state = READY; - rt_dispatch (NULL); - } - - p_MCB->cb_type = 0U; - - return (OS_R_OK); -} -#endif - - -/*--------------------------- rt_mut_release --------------------------------*/ - -OS_RESULT rt_mut_release (OS_ID mutex) { - /* Release a mutex object */ - P_MUCB p_MCB = mutex; - P_TCB p_TCB; - P_MUCB p_mlnk; - U8 prio; - - if ((p_MCB->level == 0U) || (p_MCB->owner != os_tsk.run)) { - /* Unbalanced mutex release or task is not the owner */ - return (OS_R_NOK); - } - if (--p_MCB->level != 0U) { - return (OS_R_OK); - } - - /* Remove mutex from task mutex owner list. */ - p_mlnk = os_tsk.run->p_mlnk; - if (p_mlnk == p_MCB) { - os_tsk.run->p_mlnk = p_MCB->p_mlnk; - } - else { - while (p_mlnk) { - if (p_mlnk->p_mlnk == p_MCB) { - p_mlnk->p_mlnk = p_MCB->p_mlnk; - break; - } - p_mlnk = p_mlnk->p_mlnk; - } - } - - /* Restore owner task's priority. */ - prio = os_tsk.run->prio_base; - p_mlnk = os_tsk.run->p_mlnk; - while (p_mlnk) { - if ((p_mlnk->p_lnk != NULL) && (p_mlnk->p_lnk->prio > prio)) { - /* A task with higher priority is waiting for mutex. */ - prio = p_mlnk->p_lnk->prio; - } - p_mlnk = p_mlnk->p_mlnk; - } - os_tsk.run->prio = prio; - - if (p_MCB->p_lnk != NULL) { - /* A task is waiting for mutex. */ - p_TCB = rt_get_first ((P_XCB)p_MCB); -#ifdef __CMSIS_RTOS - rt_ret_val(p_TCB, 0U/*osOK*/); -#else - rt_ret_val(p_TCB, OS_R_MUT); -#endif - rt_rmv_dly (p_TCB); - /* A waiting task becomes the owner of this mutex. */ - p_MCB->level = 1U; - p_MCB->owner = p_TCB; - p_MCB->p_mlnk = p_TCB->p_mlnk; - p_TCB->p_mlnk = p_MCB; - /* Priority inversion, check which task continues. */ - if (os_tsk.run->prio >= rt_rdy_prio()) { - rt_dispatch (p_TCB); - } - else { - /* Ready task has higher priority than running task. */ - rt_put_prio (&os_rdy, os_tsk.run); - rt_put_prio (&os_rdy, p_TCB); - os_tsk.run->state = READY; - p_TCB->state = READY; - rt_dispatch (NULL); - } - } - else { - /* Check if own priority lowered by priority inversion. */ - if (rt_rdy_prio() > os_tsk.run->prio) { - rt_put_prio (&os_rdy, os_tsk.run); - os_tsk.run->state = READY; - rt_dispatch (NULL); - } - } - return (OS_R_OK); -} - - -/*--------------------------- rt_mut_wait -----------------------------------*/ - -OS_RESULT rt_mut_wait (OS_ID mutex, U16 timeout) { - /* Wait for a mutex, continue when mutex is free. */ - P_MUCB p_MCB = mutex; - - if (p_MCB->level == 0U) { - p_MCB->owner = os_tsk.run; - p_MCB->p_mlnk = os_tsk.run->p_mlnk; - os_tsk.run->p_mlnk = p_MCB; - goto inc; - } - if (p_MCB->owner == os_tsk.run) { - /* OK, running task is the owner of this mutex. */ -inc:p_MCB->level++; - return (OS_R_OK); - } - /* Mutex owned by another task, wait until released. */ - if (timeout == 0U) { - return (OS_R_TMO); - } - /* Raise the owner task priority if lower than current priority. */ - /* This priority inversion is called priority inheritance. */ - if (p_MCB->owner->prio < os_tsk.run->prio) { - p_MCB->owner->prio = os_tsk.run->prio; - rt_resort_prio (p_MCB->owner); - } - if (p_MCB->p_lnk != NULL) { - rt_put_prio ((P_XCB)p_MCB, os_tsk.run); - } - else { - p_MCB->p_lnk = os_tsk.run; - os_tsk.run->p_lnk = NULL; - os_tsk.run->p_rlnk = (P_TCB)p_MCB; - } - rt_block(timeout, WAIT_MUT); - return (OS_R_TMO); -} - - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ - diff --git a/rtos/rtx/TARGET_CORTEX_M/rt_Mutex.h b/rtos/rtx/TARGET_CORTEX_M/rt_Mutex.h deleted file mode 100644 index ac209d37e55..00000000000 --- a/rtos/rtx/TARGET_CORTEX_M/rt_Mutex.h +++ /dev/null @@ -1,49 +0,0 @@ - -/** \addtogroup rtos */ -/** @{*/ -/*---------------------------------------------------------------------------- - * CMSIS-RTOS - RTX - *---------------------------------------------------------------------------- - * Name: RT_MUTEX.H - * Purpose: Implements mutex synchronization objects - * Rev.: V4.70 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -/* Functions */ -extern void rt_mut_init (OS_ID mutex); -extern OS_RESULT rt_mut_delete (OS_ID mutex); -extern OS_RESULT rt_mut_release (OS_ID mutex); -extern OS_RESULT rt_mut_wait (OS_ID mutex, U16 timeout); - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ - - -/** @}*/ diff --git a/rtos/rtx/TARGET_CORTEX_M/rt_OsEventObserver.c b/rtos/rtx/TARGET_CORTEX_M/rt_OsEventObserver.c deleted file mode 100644 index 4335811d471..00000000000 --- a/rtos/rtx/TARGET_CORTEX_M/rt_OsEventObserver.c +++ /dev/null @@ -1,61 +0,0 @@ -/*---------------------------------------------------------------------------- - * CMSIS-RTOS - RTX - *---------------------------------------------------------------------------- - * Name: rt_OsEventObserver.c - * Purpose: OS Event Callbacks for CMSIS RTOS - * Rev.: VX.XX - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -#include "rt_OsEventObserver.h" - -/* - * _____ _____ ____ __ _____ - * | ___|_ _\ \/ / \/ | ____| - * | |_ | | \ /| |\/| | _| - * | _| | | / \| | | | |___ - * |_| |___/_/\_\_| |_|_____| - * - * FIXME: - * The osEventObs variable must be in protected memory. If not every box - * and box 0 can modify osEventObs to point to any handler to run code - * privileged. This issue is tracked at - * . - */ -const OsEventObserver *osEventObs; - -void osRegisterForOsEvents(const OsEventObserver *observer) -{ - static uint8_t has_been_called = 0; - if (has_been_called) { - return; - } - has_been_called = 1; - - osEventObs = observer; -} diff --git a/rtos/rtx/TARGET_CORTEX_M/rt_OsEventObserver.h b/rtos/rtx/TARGET_CORTEX_M/rt_OsEventObserver.h deleted file mode 100644 index 64aaa964ddf..00000000000 --- a/rtos/rtx/TARGET_CORTEX_M/rt_OsEventObserver.h +++ /dev/null @@ -1,63 +0,0 @@ - -/** \addtogroup rtos */ -/** @{*/ -/*---------------------------------------------------------------------------- - * CMSIS-RTOS - RTX - *---------------------------------------------------------------------------- - * Name: os_events.h - * Purpose: OS Event Callbacks for CMSIS RTOS - * Rev.: VX.XX - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2016 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ -#ifndef _RT_OS_EVENT_OBSERVER_H -#define _RT_OS_EVENT_OBSERVER_H - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct { - uint32_t version; - void (*pre_start)(void); - void *(*thread_create)(int thread_id, void *context); - void (*thread_destroy)(void *context); - void (*thread_switch)(void *context); -} OsEventObserver; -extern const OsEventObserver *osEventObs; - -void osRegisterForOsEvents(const OsEventObserver *observer); - -#ifdef __cplusplus -}; -#endif - -#endif - -/** @}*/ diff --git a/rtos/rtx/TARGET_CORTEX_M/rt_Robin.c b/rtos/rtx/TARGET_CORTEX_M/rt_Robin.c deleted file mode 100644 index dd2ca8adec9..00000000000 --- a/rtos/rtx/TARGET_CORTEX_M/rt_Robin.c +++ /dev/null @@ -1,83 +0,0 @@ -/*---------------------------------------------------------------------------- - * CMSIS-RTOS - RTX - *---------------------------------------------------------------------------- - * Name: RT_ROBIN.C - * Purpose: Round Robin Task switching - * Rev.: V4.79 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -#include "rt_TypeDef.h" -#include "RTX_Config.h" -#include "rt_List.h" -#include "rt_Task.h" -#include "rt_Time.h" -#include "rt_Robin.h" -#include "rt_HAL_CM.h" - -/*---------------------------------------------------------------------------- - * Global Variables - *---------------------------------------------------------------------------*/ - -struct OS_ROBIN os_robin; - - -/*---------------------------------------------------------------------------- - * Global Functions - *---------------------------------------------------------------------------*/ - -/*--------------------------- rt_init_robin ---------------------------------*/ - -__weak void rt_init_robin (void) { - /* Initialize Round Robin variables. */ - os_robin.task = NULL; - os_robin.tout = (U16)os_rrobin; -} - -/*--------------------------- rt_chk_robin ----------------------------------*/ - -__weak void rt_chk_robin (void) { - /* Check if Round Robin timeout expired and switch to the next ready task.*/ - P_TCB p_new; - - if (os_robin.task != os_rdy.p_lnk) { - /* New task was suspended, reset Round Robin timeout. */ - os_robin.task = os_rdy.p_lnk; - os_robin.time = (U16)os_time + os_robin.tout - 1U; - } - if (os_robin.time == (U16)os_time) { - /* Round Robin timeout has expired, swap Robin tasks. */ - os_robin.task = NULL; - p_new = rt_get_first (&os_rdy); - rt_put_prio ((P_XCB)&os_rdy, p_new); - } -} - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ diff --git a/rtos/rtx/TARGET_CORTEX_M/rt_Robin.h b/rtos/rtx/TARGET_CORTEX_M/rt_Robin.h deleted file mode 100644 index f4c42b88782..00000000000 --- a/rtos/rtx/TARGET_CORTEX_M/rt_Robin.h +++ /dev/null @@ -1,50 +0,0 @@ - -/** \addtogroup rtos */ -/** @{*/ -/*---------------------------------------------------------------------------- - * CMSIS-RTOS - RTX - *---------------------------------------------------------------------------- - * Name: RT_ROBIN.H - * Purpose: Round Robin Task switching definitions - * Rev.: V4.70 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -/* Variables */ -extern struct OS_ROBIN os_robin; - -/* Functions */ -extern void rt_init_robin (void); -extern void rt_chk_robin (void); - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ - - -/** @}*/ diff --git a/rtos/rtx/TARGET_CORTEX_M/rt_Semaphore.c b/rtos/rtx/TARGET_CORTEX_M/rt_Semaphore.c deleted file mode 100644 index db8d352e32d..00000000000 --- a/rtos/rtx/TARGET_CORTEX_M/rt_Semaphore.c +++ /dev/null @@ -1,182 +0,0 @@ -/*---------------------------------------------------------------------------- - * CMSIS-RTOS - RTX - *---------------------------------------------------------------------------- - * Name: RT_SEMAPHORE.C - * Purpose: Implements binary and counting semaphores - * Rev.: V4.79 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -#include "rt_TypeDef.h" -#include "RTX_Config.h" -#include "rt_System.h" -#include "rt_List.h" -#include "rt_Task.h" -#include "rt_Semaphore.h" -#include "rt_HAL_CM.h" - - -/*---------------------------------------------------------------------------- - * Functions - *---------------------------------------------------------------------------*/ - - -/*--------------------------- rt_sem_init -----------------------------------*/ - -void rt_sem_init (OS_ID semaphore, U16 token_count) { - /* Initialize a semaphore */ - P_SCB p_SCB = semaphore; - - p_SCB->cb_type = SCB; - p_SCB->p_lnk = NULL; - p_SCB->tokens = token_count; -} - - -/*--------------------------- rt_sem_delete ---------------------------------*/ - -#ifdef __CMSIS_RTOS -OS_RESULT rt_sem_delete (OS_ID semaphore) { - /* Delete semaphore */ - P_SCB p_SCB = semaphore; - P_TCB p_TCB; - - while (p_SCB->p_lnk != NULL) { - /* A task is waiting for token */ - p_TCB = rt_get_first ((P_XCB)p_SCB); - rt_ret_val(p_TCB, 0U); - rt_rmv_dly(p_TCB); - p_TCB->state = READY; - rt_put_prio (&os_rdy, p_TCB); - } - - if ((os_rdy.p_lnk != NULL) && (os_rdy.p_lnk->prio > os_tsk.run->prio)) { - /* preempt running task */ - rt_put_prio (&os_rdy, os_tsk.run); - os_tsk.run->state = READY; - rt_dispatch (NULL); - } - - p_SCB->cb_type = 0U; - - return (OS_R_OK); -} -#endif - - -/*--------------------------- rt_sem_send -----------------------------------*/ - -OS_RESULT rt_sem_send (OS_ID semaphore) { - /* Return a token to semaphore */ - P_SCB p_SCB = semaphore; - P_TCB p_TCB; - - if (p_SCB->p_lnk != NULL) { - /* A task is waiting for token */ - p_TCB = rt_get_first ((P_XCB)p_SCB); -#ifdef __CMSIS_RTOS - rt_ret_val(p_TCB, 1U); -#else - rt_ret_val(p_TCB, OS_R_SEM); -#endif - rt_rmv_dly (p_TCB); - rt_dispatch (p_TCB); - } - else { - /* Store token. */ - p_SCB->tokens++; - } - return (OS_R_OK); -} - - -/*--------------------------- rt_sem_wait -----------------------------------*/ - -OS_RESULT rt_sem_wait (OS_ID semaphore, U16 timeout) { - /* Obtain a token; possibly wait for it */ - P_SCB p_SCB = semaphore; - - if (p_SCB->tokens) { - p_SCB->tokens--; - return (OS_R_OK); - } - /* No token available: wait for one */ - if (timeout == 0U) { - return (OS_R_TMO); - } - if (p_SCB->p_lnk != NULL) { - rt_put_prio ((P_XCB)p_SCB, os_tsk.run); - } - else { - p_SCB->p_lnk = os_tsk.run; - os_tsk.run->p_lnk = NULL; - os_tsk.run->p_rlnk = (P_TCB)p_SCB; - } - rt_block(timeout, WAIT_SEM); - return (OS_R_TMO); -} - - -/*--------------------------- isr_sem_send ----------------------------------*/ - -void isr_sem_send (OS_ID semaphore) { - /* Same function as "os_sem_send", but to be called by ISRs */ - P_SCB p_SCB = semaphore; - - rt_psq_enq (p_SCB, 0U); - rt_psh_req (); -} - - -/*--------------------------- rt_sem_psh ------------------------------------*/ - -void rt_sem_psh (P_SCB p_CB) { - /* Check if task has to be waken up */ - P_TCB p_TCB; - - if (p_CB->p_lnk != NULL) { - /* A task is waiting for token */ - p_TCB = rt_get_first ((P_XCB)p_CB); - rt_rmv_dly (p_TCB); - p_TCB->state = READY; -#ifdef __CMSIS_RTOS - rt_ret_val(p_TCB, 1U); -#else - rt_ret_val(p_TCB, OS_R_SEM); -#endif - rt_put_prio (&os_rdy, p_TCB); - } - else { - /* Store token */ - p_CB->tokens++; - } -} - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ diff --git a/rtos/rtx/TARGET_CORTEX_M/rt_Semaphore.h b/rtos/rtx/TARGET_CORTEX_M/rt_Semaphore.h deleted file mode 100644 index 6aa6e930e79..00000000000 --- a/rtos/rtx/TARGET_CORTEX_M/rt_Semaphore.h +++ /dev/null @@ -1,51 +0,0 @@ - -/** \addtogroup rtos */ -/** @{*/ -/*---------------------------------------------------------------------------- - * CMSIS-RTOS - RTX - *---------------------------------------------------------------------------- - * Name: RT_SEMAPHORE.H - * Purpose: Implements binary and counting semaphores - * Rev.: V4.70 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -/* Functions */ -extern void rt_sem_init (OS_ID semaphore, U16 token_count); -extern OS_RESULT rt_sem_delete(OS_ID semaphore); -extern OS_RESULT rt_sem_send (OS_ID semaphore); -extern OS_RESULT rt_sem_wait (OS_ID semaphore, U16 timeout); -extern void isr_sem_send (OS_ID semaphore); -extern void rt_sem_psh (P_SCB p_CB); - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ - - -/** @}*/ diff --git a/rtos/rtx/TARGET_CORTEX_M/rt_System.c b/rtos/rtx/TARGET_CORTEX_M/rt_System.c deleted file mode 100644 index a04e6890f2d..00000000000 --- a/rtos/rtx/TARGET_CORTEX_M/rt_System.c +++ /dev/null @@ -1,325 +0,0 @@ -/*---------------------------------------------------------------------------- - * CMSIS-RTOS - RTX - *---------------------------------------------------------------------------- - * Name: RT_SYSTEM.C - * Purpose: System Task Manager - * Rev.: V4.80 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -#include "rt_TypeDef.h" -#include "RTX_Config.h" -#include "rt_Task.h" -#include "rt_System.h" -#include "rt_Event.h" -#include "rt_List.h" -#include "rt_Mailbox.h" -#include "rt_Semaphore.h" -#include "rt_Time.h" -#include "rt_Timer.h" -#include "rt_Robin.h" -#include "rt_HAL_CM.h" - -/*---------------------------------------------------------------------------- - * Global Variables - *---------------------------------------------------------------------------*/ - -S32 os_tick_irqn; - -/*---------------------------------------------------------------------------- - * Local Variables - *---------------------------------------------------------------------------*/ - -static volatile BIT os_lock; -static volatile BIT os_psh_flag; -static U8 pend_flags; - -/*---------------------------------------------------------------------------- - * Global Functions - *---------------------------------------------------------------------------*/ - -#define RL_RTX_VER 0x480 - -#if defined (__CC_ARM) -__asm void $$RTX$$version (void) { - /* Export a version number symbol for a version control. */ - - EXPORT __RL_RTX_VER - -__RL_RTX_VER EQU RL_RTX_VER -} -#endif - - -/*--------------------------- rt_suspend ------------------------------------*/ - -extern U32 sysUserTimerWakeupTime(void); - -U32 rt_suspend (void) { - /* Suspend OS scheduler */ - U32 delta = 0xFFFFU; -#ifdef __CMSIS_RTOS - U32 sleep; -#endif - - rt_tsk_lock(); - - if (os_dly.p_dlnk) { - delta = os_dly.delta_time; - } -#ifdef __CMSIS_RTOS - sleep = sysUserTimerWakeupTime(); - if (sleep < delta) { delta = sleep; } -#else - if (os_tmr.next) { - if (os_tmr.tcnt < delta) delta = os_tmr.tcnt; - } -#endif - - return (delta); -} - - -/*--------------------------- rt_resume -------------------------------------*/ - -extern void sysUserTimerUpdate (U32 sleep_time); - -void rt_resume (U32 sleep_time) { - /* Resume OS scheduler after suspend */ - P_TCB next; - U32 delta; - - os_tsk.run->state = READY; - rt_put_rdy_first (os_tsk.run); - - os_robin.task = NULL; - - /* Update delays. */ - if (os_dly.p_dlnk) { - delta = sleep_time; - if (delta >= os_dly.delta_time) { - delta -= os_dly.delta_time; - os_time += os_dly.delta_time; - os_dly.delta_time = 1U; - while (os_dly.p_dlnk) { - rt_dec_dly(); - if (delta == 0U) { break; } - delta--; - os_time++; - } - } else { - os_time += delta; - os_dly.delta_time -= (U16)delta; - } - } else { - os_time += sleep_time; - } - - /* Check the user timers. */ -#ifdef __CMSIS_RTOS - sysUserTimerUpdate(sleep_time); -#else - if (os_tmr.next) { - delta = sleep_time; - if (delta >= os_tmr.tcnt) { - delta -= os_tmr.tcnt; - os_tmr.tcnt = 1U; - while (os_tmr.next) { - rt_tmr_tick(); - if (delta == 0U) { break; } - delta--; - } - } else { - os_tmr.tcnt -= delta; - } - } -#endif - - /* Switch back to highest ready task */ - next = rt_get_first (&os_rdy); - rt_switch_req (next); - - rt_tsk_unlock(); -} - - -/*--------------------------- rt_tsk_lock -----------------------------------*/ - -void rt_tsk_lock (void) { - /* Prevent task switching by locking out scheduler */ - if (os_tick_irqn < 0) { - OS_LOCK(); - os_lock = __TRUE; - OS_UNPEND(pend_flags); - } else { - OS_X_LOCK((U32)os_tick_irqn); - os_lock = __TRUE; - OS_X_UNPEND(pend_flags); - } -} - - -/*--------------------------- rt_tsk_unlock ---------------------------------*/ - -void rt_tsk_unlock (void) { - /* Unlock scheduler and re-enable task switching */ - if (os_tick_irqn < 0) { - OS_UNLOCK(); - os_lock = __FALSE; - OS_PEND(pend_flags, os_psh_flag); - os_psh_flag = __FALSE; - } else { - OS_X_UNLOCK((U32)os_tick_irqn); - os_lock = __FALSE; - OS_X_PEND(pend_flags, os_psh_flag); - os_psh_flag = __FALSE; - } -} - - -/*--------------------------- rt_psh_req ------------------------------------*/ - -void rt_psh_req (void) { - /* Initiate a post service handling request if required. */ - if (os_lock == __FALSE) { - OS_PEND_IRQ(); - } - else { - os_psh_flag = __TRUE; - } -} - - -/*--------------------------- rt_pop_req ------------------------------------*/ - -void rt_pop_req (void) { - /* Process an ISR post service requests. */ - struct OS_XCB *p_CB; - P_TCB next; - U32 idx; - - os_tsk.run->state = READY; - rt_put_rdy_first (os_tsk.run); - - idx = os_psq->last; - while (os_psq->count) { - p_CB = os_psq->q[idx].id; - if (p_CB->cb_type == TCB) { - /* Is of TCB type */ - rt_evt_psh ((P_TCB)p_CB, (U16)os_psq->q[idx].arg); - } - else if (p_CB->cb_type == MCB) { - /* Is of MCB type */ - rt_mbx_psh ((P_MCB)p_CB, (void *)os_psq->q[idx].arg); - } - else { - /* Must be of SCB type */ - rt_sem_psh ((P_SCB)p_CB); - } - if (++idx == os_psq->size) { idx = 0U; } - rt_dec (&os_psq->count); - } - os_psq->last = (U8)idx; - - next = rt_get_first (&os_rdy); - rt_switch_req (next); -} - - -/*--------------------------- os_tick_init ----------------------------------*/ - -__weak S32 os_tick_init (void) { - /* Initialize SysTick timer as system tick timer. */ - rt_systick_init(); - return (-1); /* Return IRQ number of SysTick timer */ -} - -/*--------------------------- os_tick_val -----------------------------------*/ - -__weak U32 os_tick_val (void) { - /* Get SysTick timer current value (0 .. OS_TRV). */ - return rt_systick_val(); -} - -/*--------------------------- os_tick_ovf -----------------------------------*/ - -__weak U32 os_tick_ovf (void) { - /* Get SysTick timer overflow flag */ - return rt_systick_ovf(); -} - -/*--------------------------- os_tick_irqack --------------------------------*/ - -__weak void os_tick_irqack (void) { - /* Acknowledge timer interrupt. */ -} - - -/*--------------------------- rt_systick ------------------------------------*/ - -extern void sysTimerTick(void); - -void rt_systick (void) { - /* Check for system clock update, suspend running task. */ - P_TCB next; - - os_tsk.run->state = READY; - rt_put_rdy_first (os_tsk.run); - - /* Check Round Robin timeout. */ - rt_chk_robin (); - - /* Update delays. */ - os_time++; - rt_dec_dly (); - - /* Check the user timers. */ -#ifdef __CMSIS_RTOS - sysTimerTick(); -#else - rt_tmr_tick (); -#endif - - /* Switch back to highest ready task */ - next = rt_get_first (&os_rdy); - rt_switch_req (next); -} - -/*--------------------------- rt_stk_check ----------------------------------*/ - -__weak void rt_stk_check (void) { - if ((os_tsk.run->tsk_stack < (U32)os_tsk.run->stack) || - (os_tsk.run->stack[0] != MAGIC_WORD)) { - os_error (OS_ERR_STK_OVF); - } -} - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ - diff --git a/rtos/rtx/TARGET_CORTEX_M/rt_System.h b/rtos/rtx/TARGET_CORTEX_M/rt_System.h deleted file mode 100644 index b478ddbeb69..00000000000 --- a/rtos/rtx/TARGET_CORTEX_M/rt_System.h +++ /dev/null @@ -1,57 +0,0 @@ - -/** \addtogroup rtos */ -/** @{*/ -/*---------------------------------------------------------------------------- - * CMSIS-RTOS - RTX - *---------------------------------------------------------------------------- - * Name: RT_SYSTEM.H - * Purpose: System Task Manager definitions - * Rev.: V4.79 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -/* Variables */ -#define os_psq ((P_PSQ)&os_fifo) -extern S32 os_tick_irqn; - -/* Functions */ -extern U32 rt_suspend (void); -extern void rt_resume (U32 sleep_time); -extern void rt_tsk_lock (void); -extern void rt_tsk_unlock (void); -extern void rt_psh_req (void); -extern void rt_pop_req (void); -extern void rt_systick (void); -extern void rt_stk_check (void); - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ - - -/** @}*/ diff --git a/rtos/rtx/TARGET_CORTEX_M/rt_Task.c b/rtos/rtx/TARGET_CORTEX_M/rt_Task.c deleted file mode 100644 index 812978fdc67..00000000000 --- a/rtos/rtx/TARGET_CORTEX_M/rt_Task.c +++ /dev/null @@ -1,456 +0,0 @@ -/*---------------------------------------------------------------------------- - * CMSIS-RTOS - RTX - *---------------------------------------------------------------------------- - * Name: RT_TASK.C - * Purpose: Task functions and system start up. - * Rev.: V4.80 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -#include "rt_TypeDef.h" -#include "RTX_Config.h" -#include "rt_System.h" -#include "rt_Task.h" -#include "rt_List.h" -#include "rt_MemBox.h" -#include "rt_Robin.h" -#include "rt_HAL_CM.h" -#include "rt_OsEventObserver.h" - -/*---------------------------------------------------------------------------- - * Global Variables - *---------------------------------------------------------------------------*/ - -/* Running and next task info. */ -struct OS_TSK os_tsk; - -/* Task Control Blocks of idle demon */ -struct OS_TCB os_idle_TCB; - - -/*---------------------------------------------------------------------------- - * Local Functions - *---------------------------------------------------------------------------*/ - -static OS_TID rt_get_TID (void) { - U32 tid; - - for (tid = 1U; tid <= os_maxtaskrun; tid++) { - if (os_active_TCB[tid-1U] == NULL) { - return ((OS_TID)tid); - } - } - return (0U); -} - - -/*--------------------------- rt_init_context -------------------------------*/ - -static void rt_init_context (P_TCB p_TCB, U8 priority, FUNCP task_body) { - /* Initialize general part of the Task Control Block. */ - p_TCB->cb_type = TCB; - p_TCB->state = READY; - p_TCB->prio = priority; - p_TCB->prio_base = priority; - p_TCB->p_lnk = NULL; - p_TCB->p_rlnk = NULL; - p_TCB->p_dlnk = NULL; - p_TCB->p_blnk = NULL; - p_TCB->p_mlnk = NULL; - p_TCB->delta_time = 0U; - p_TCB->interval_time = 0U; - p_TCB->events = 0U; - p_TCB->waits = 0U; - p_TCB->stack_frame = 0U; - - if (p_TCB->priv_stack == 0U) { - /* Allocate the memory space for the stack. */ - p_TCB->stack = rt_alloc_box (mp_stk); - } - rt_init_stack (p_TCB, task_body); -} - - -/*--------------------------- rt_switch_req ---------------------------------*/ - -void rt_switch_req (P_TCB p_new) { - /* Switch to next task (identified by "p_new"). */ - os_tsk.new_tsk = p_new; - p_new->state = RUNNING; - if (osEventObs && osEventObs->thread_switch) { - osEventObs->thread_switch(p_new->context); - } - DBG_TASK_SWITCH(p_new->task_id); -} - - -/*--------------------------- rt_dispatch -----------------------------------*/ - -void rt_dispatch (P_TCB next_TCB) { - /* Dispatch next task if any identified or dispatch highest ready task */ - /* "next_TCB" identifies a task to run or has value NULL (=no next task) */ - if (next_TCB == NULL) { - /* Running task was blocked: continue with highest ready task */ - next_TCB = rt_get_first (&os_rdy); - rt_switch_req (next_TCB); - } - else { - /* Check which task continues */ - if (next_TCB->prio > os_tsk.run->prio) { - /* preempt running task */ - rt_put_rdy_first (os_tsk.run); - os_tsk.run->state = READY; - rt_switch_req (next_TCB); - } - else { - /* put next task into ready list, no task switch takes place */ - next_TCB->state = READY; - rt_put_prio (&os_rdy, next_TCB); - } - } -} - - -/*--------------------------- rt_block --------------------------------------*/ - -void rt_block (U16 timeout, U8 block_state) { - /* Block running task and choose next ready task. */ - /* "timeout" sets a time-out value or is 0xffff (=no time-out). */ - /* "block_state" defines the appropriate task state */ - P_TCB next_TCB; - - if (timeout) { - if (timeout < 0xFFFFU) { - rt_put_dly (os_tsk.run, timeout); - } - os_tsk.run->state = block_state; - next_TCB = rt_get_first (&os_rdy); - rt_switch_req (next_TCB); - } -} - - -/*--------------------------- rt_tsk_pass -----------------------------------*/ - -void rt_tsk_pass (void) { - /* Allow tasks of same priority level to run cooperatively.*/ - P_TCB p_new; - - p_new = rt_get_same_rdy_prio(); - if (p_new != NULL) { - rt_put_prio ((P_XCB)&os_rdy, os_tsk.run); - os_tsk.run->state = READY; - rt_switch_req (p_new); - } -} - - -/*--------------------------- rt_tsk_self -----------------------------------*/ - -OS_TID rt_tsk_self (void) { - /* Return own task identifier value. */ - if (os_tsk.run == NULL) { - return (0U); - } - return ((OS_TID)os_tsk.run->task_id); -} - - -/*--------------------------- rt_tsk_prio -----------------------------------*/ - -OS_RESULT rt_tsk_prio (OS_TID task_id, U8 new_prio) { - /* Change execution priority of a task to "new_prio". */ - P_TCB p_task; - - if (task_id == 0U) { - /* Change execution priority of calling task. */ - os_tsk.run->prio = new_prio; - os_tsk.run->prio_base = new_prio; -run:if (rt_rdy_prio() > new_prio) { - rt_put_prio (&os_rdy, os_tsk.run); - os_tsk.run->state = READY; - rt_dispatch (NULL); - } - return (OS_R_OK); - } - - /* Find the task in the "os_active_TCB" array. */ - if ((task_id > os_maxtaskrun) || (os_active_TCB[task_id-1U] == NULL)) { - /* Task with "task_id" not found or not started. */ - return (OS_R_NOK); - } - p_task = os_active_TCB[task_id-1U]; - p_task->prio = new_prio; - p_task->prio_base = new_prio; - if (p_task == os_tsk.run) { - goto run; - } - rt_resort_prio (p_task); - if (p_task->state == READY) { - /* Task enqueued in a ready list. */ - p_task = rt_get_first (&os_rdy); - rt_dispatch (p_task); - } - return (OS_R_OK); -} - - -/*--------------------------- rt_tsk_create ---------------------------------*/ - -OS_TID rt_tsk_create (FUNCP task, U32 prio_stksz, void *stk, void *argv) { - /* Start a new task declared with "task". */ - P_TCB task_context; - U32 i; - - /* Priority 0 is reserved for idle task! */ - if ((prio_stksz & 0xFFU) == 0U) { - prio_stksz += 1U; - } - task_context = rt_alloc_box (mp_tcb); - if (task_context == NULL) { - return (0U); - } - /* If "size != 0" use a private user provided stack. */ - task_context->stack = stk; - task_context->priv_stack = prio_stksz >> 8; - - /* Find a free entry in 'os_active_TCB' table. */ - i = rt_get_TID (); - if (i == 0U) { - return (0U); - } - task_context->task_id = (U8)i; - /* Pass parameter 'argv' to 'rt_init_context' */ - task_context->msg = argv; - task_context->argv = argv; - /* For 'size == 0' system allocates the user stack from the memory pool. */ - rt_init_context (task_context, (U8)(prio_stksz & 0xFFU), task); - - os_active_TCB[i-1U] = task_context; - DBG_TASK_NOTIFY(task_context, __TRUE); - rt_dispatch (task_context); - return ((OS_TID)i); -} - - -/*--------------------------- rt_tsk_delete ---------------------------------*/ - -OS_RESULT rt_tsk_delete (OS_TID task_id) { - /* Terminate the task identified with "task_id". */ - P_TCB task_context; - P_TCB p_TCB; - P_MUCB p_MCB, p_MCB0; - - if ((task_id == 0U) || (task_id == os_tsk.run->task_id)) { - /* Terminate itself. */ - os_tsk.run->state = INACTIVE; - os_tsk.run->tsk_stack = rt_get_PSP (); - rt_stk_check (); - p_MCB = os_tsk.run->p_mlnk; - while (p_MCB) { - /* Release mutexes owned by this task */ - if (p_MCB->p_lnk) { - /* A task is waiting for mutex. */ - p_TCB = rt_get_first ((P_XCB)p_MCB); -#ifdef __CMSIS_RTOS - rt_ret_val (p_TCB, 0U/*osOK*/); -#else - rt_ret_val (p_TCB, OS_R_MUT); -#endif - rt_rmv_dly (p_TCB); - p_TCB->state = READY; - rt_put_prio (&os_rdy, p_TCB); - /* A waiting task becomes the owner of this mutex. */ - p_MCB0 = p_MCB->p_mlnk; - p_MCB->level = 1U; - p_MCB->owner = p_TCB; - p_MCB->p_mlnk = p_TCB->p_mlnk; - p_TCB->p_mlnk = p_MCB; - p_MCB = p_MCB0; - } - else { - p_MCB0 = p_MCB->p_mlnk; - p_MCB->level = 0U; - p_MCB->owner = NULL; - p_MCB->p_mlnk = NULL; - p_MCB = p_MCB0; - } - } - os_active_TCB[os_tsk.run->task_id-1U] = NULL; - rt_free_box (mp_stk, os_tsk.run->stack); - os_tsk.run->stack = NULL; - DBG_TASK_NOTIFY(os_tsk.run, __FALSE); - rt_free_box (mp_tcb, os_tsk.run); - os_tsk.run = NULL; - rt_dispatch (NULL); - /* The program should never come to this point. */ - } - else { - /* Find the task in the "os_active_TCB" array. */ - if ((task_id > os_maxtaskrun) || (os_active_TCB[task_id-1U] == NULL)) { - /* Task with "task_id" not found or not started. */ - return (OS_R_NOK); - } - task_context = os_active_TCB[task_id-1U]; - rt_rmv_list (task_context); - rt_rmv_dly (task_context); - p_MCB = task_context->p_mlnk; - while (p_MCB) { - /* Release mutexes owned by this task */ - if (p_MCB->p_lnk) { - /* A task is waiting for mutex. */ - p_TCB = rt_get_first ((P_XCB)p_MCB); -#ifdef __CMSIS_RTOS - rt_ret_val (p_TCB, 0U/*osOK*/); -#else - rt_ret_val (p_TCB, OS_R_MUT); -#endif - rt_rmv_dly (p_TCB); - p_TCB->state = READY; - rt_put_prio (&os_rdy, p_TCB); - /* A waiting task becomes the owner of this mutex. */ - p_MCB0 = p_MCB->p_mlnk; - p_MCB->level = 1U; - p_MCB->owner = p_TCB; - p_MCB->p_mlnk = p_TCB->p_mlnk; - p_TCB->p_mlnk = p_MCB; - p_MCB = p_MCB0; - } - else { - p_MCB0 = p_MCB->p_mlnk; - p_MCB->level = 0U; - p_MCB->owner = NULL; - p_MCB->p_mlnk = NULL; - p_MCB = p_MCB0; - } - } - os_active_TCB[task_id-1U] = NULL; - rt_free_box (mp_stk, task_context->stack); - task_context->stack = NULL; - DBG_TASK_NOTIFY(task_context, __FALSE); - rt_free_box (mp_tcb, task_context); - if (rt_rdy_prio() > os_tsk.run->prio) { - /* Ready task has higher priority than running task. */ - os_tsk.run->state = READY; - rt_put_prio (&os_rdy, os_tsk.run); - rt_dispatch (NULL); - } - } - return (OS_R_OK); -} - - -/*--------------------------- rt_sys_init -----------------------------------*/ - -#ifdef __CMSIS_RTOS -void rt_sys_init (void) { -#else -void rt_sys_init (FUNCP first_task, U32 prio_stksz, void *stk) { -#endif - /* Initialize system and start up task declared with "first_task". */ - U32 i; - - DBG_INIT(); - - /* Initialize dynamic memory and task TCB pointers to NULL. */ - for (i = 0U; i < os_maxtaskrun; i++) { - os_active_TCB[i] = NULL; - } - rt_init_box (mp_tcb, (U32)mp_tcb_size, sizeof(struct OS_TCB)); - rt_init_box (mp_stk, mp_stk_size, BOX_ALIGN_8 | (U16)(os_stackinfo)); - rt_init_box ((U32 *)m_tmr, (U32)mp_tmr_size, sizeof(struct OS_TMR)); - - /* Set up TCB of idle demon */ - os_idle_TCB.task_id = 255U; - os_idle_TCB.priv_stack = 0U; - rt_init_context (&os_idle_TCB, 0U, os_idle_demon); - - /* Set up ready list: initially empty */ - os_rdy.cb_type = HCB; - os_rdy.p_lnk = NULL; - /* Set up delay list: initially empty */ - os_dly.cb_type = HCB; - os_dly.p_dlnk = NULL; - os_dly.p_blnk = NULL; - os_dly.delta_time = 0U; - - /* Fix SP and system variables to assume idle task is running */ - /* Transform main program into idle task by assuming idle TCB */ -#ifndef __CMSIS_RTOS - rt_set_PSP (os_idle_TCB.tsk_stack+32U); -#endif - os_tsk.run = &os_idle_TCB; - os_tsk.run->state = RUNNING; - - /* Set the current thread to idle, so that on exit from this SVCall we do not - * de-reference a NULL TCB. */ - rt_switch_req(&os_idle_TCB); - - /* Initialize ps queue */ - os_psq->first = 0U; - os_psq->last = 0U; - os_psq->size = os_fifo_size; - - rt_init_robin (); - -#ifndef __CMSIS_RTOS - /* Initialize SVC and PendSV */ - rt_svc_init (); - - /* Initialize and start system clock timer */ - os_tick_irqn = os_tick_init (); - if (os_tick_irqn >= 0) { - OS_X_INIT((U32)os_tick_irqn); - } - - /* Start up first user task before entering the endless loop */ - rt_tsk_create (first_task, prio_stksz, stk, NULL); -#endif -} - - -/*--------------------------- rt_sys_start ----------------------------------*/ - -#ifdef __CMSIS_RTOS -void rt_sys_start (void) { - /* Start system */ - - /* Initialize SVC and PendSV */ - rt_svc_init (); - - /* Initialize and start system clock timer */ - os_tick_irqn = os_tick_init (); - if (os_tick_irqn >= 0) { - OS_X_INIT((U32)os_tick_irqn); - } -} -#endif - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ diff --git a/rtos/rtx/TARGET_CORTEX_M/rt_Task.h b/rtos/rtx/TARGET_CORTEX_M/rt_Task.h deleted file mode 100644 index 092f8653568..00000000000 --- a/rtos/rtx/TARGET_CORTEX_M/rt_Task.h +++ /dev/null @@ -1,88 +0,0 @@ - -/** \addtogroup rtos */ -/** @{*/ -/*---------------------------------------------------------------------------- - * CMSIS-RTOS - RTX - *---------------------------------------------------------------------------- - * Name: RT_TASK.H - * Purpose: Task functions and system start up. - * Rev.: V4.79 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -/* Definitions */ - -#include "cmsis_os.h" - -/* Values for 'state' */ -#define INACTIVE 0U -#define READY 1U -#define RUNNING 2U -#define WAIT_DLY 3U -#define WAIT_ITV 4U -#define WAIT_OR 5U -#define WAIT_AND 6U -#define WAIT_SEM 7U -#define WAIT_MBX 8U -#define WAIT_MUT 9U - -/* Return codes */ -#define OS_R_TMO 0x01U -#define OS_R_EVT 0x02U -#define OS_R_SEM 0x03U -#define OS_R_MBX 0x04U -#define OS_R_MUT 0x05U - -#define OS_R_OK 0x00U -#define OS_R_NOK 0xFFU - -/* Variables */ -extern struct OS_TSK os_tsk; -extern struct OS_TCB os_idle_TCB; - -/* Functions */ -extern void rt_switch_req (P_TCB p_new); -extern void rt_dispatch (P_TCB next_TCB); -extern void rt_block (U16 timeout, U8 block_state); -extern void rt_tsk_pass (void); -extern OS_TID rt_tsk_self (void); -extern OS_RESULT rt_tsk_prio (OS_TID task_id, U8 new_prio); -extern OS_TID rt_tsk_create (FUNCP task, U32 prio_stksz, void *stk, void *argv); -extern OS_RESULT rt_tsk_delete (OS_TID task_id); -#ifdef __CMSIS_RTOS -extern void rt_sys_init (void); -extern void rt_sys_start (void); -#else -extern void rt_sys_init (FUNCP first_task, U32 prio_stksz, void *stk); -#endif - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ - -/** @}*/ diff --git a/rtos/rtx/TARGET_CORTEX_M/rt_Time.c b/rtos/rtx/TARGET_CORTEX_M/rt_Time.c deleted file mode 100644 index abbd4acf58e..00000000000 --- a/rtos/rtx/TARGET_CORTEX_M/rt_Time.c +++ /dev/null @@ -1,93 +0,0 @@ -/*---------------------------------------------------------------------------- - * CMSIS-RTOS - RTX - *---------------------------------------------------------------------------- - * Name: RT_TIME.C - * Purpose: Delay and interval wait functions - * Rev.: V4.79 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -#include "rt_TypeDef.h" -#include "RTX_Config.h" -#include "rt_Task.h" -#include "rt_Time.h" - -/*---------------------------------------------------------------------------- - * Global Variables - *---------------------------------------------------------------------------*/ - -/* Free running system tick counter */ -U32 os_time; - - -/*---------------------------------------------------------------------------- - * Functions - *---------------------------------------------------------------------------*/ - - -/*--------------------------- rt_time_get -----------------------------------*/ - -U32 rt_time_get (void) { - /* Get system time tick */ - return (os_time); -} - - -/*--------------------------- rt_dly_wait -----------------------------------*/ - -void rt_dly_wait (U16 delay_time) { - /* Delay task by "delay_time" */ - rt_block (delay_time, WAIT_DLY); -} - - -/*--------------------------- rt_itv_set ------------------------------------*/ - -void rt_itv_set (U16 interval_time) { - /* Set interval length and define start of first interval */ - os_tsk.run->interval_time = interval_time; - os_tsk.run->delta_time = interval_time + (U16)os_time; -} - - -/*--------------------------- rt_itv_wait -----------------------------------*/ - -void rt_itv_wait (void) { - /* Wait for interval end and define start of next one */ - U16 delta; - - delta = os_tsk.run->delta_time - (U16)os_time; - os_tsk.run->delta_time += os_tsk.run->interval_time; - if ((delta & 0x8000U) == 0U) { - rt_block (delta, WAIT_ITV); - } -} - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ diff --git a/rtos/rtx/TARGET_CORTEX_M/rt_Time.h b/rtos/rtx/TARGET_CORTEX_M/rt_Time.h deleted file mode 100644 index 0f28244b6eb..00000000000 --- a/rtos/rtx/TARGET_CORTEX_M/rt_Time.h +++ /dev/null @@ -1,52 +0,0 @@ - -/** \addtogroup rtos */ -/** @{*/ -/*---------------------------------------------------------------------------- - * CMSIS-RTOS - RTX - *---------------------------------------------------------------------------- - * Name: RT_TIME.H - * Purpose: Delay and interval wait functions definitions - * Rev.: V4.70 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -/* Variables */ -extern U32 os_time; - -/* Functions */ -extern U32 rt_time_get (void); -extern void rt_dly_wait (U16 delay_time); -extern void rt_itv_set (U16 interval_time); -extern void rt_itv_wait (void); - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ - - -/** @}*/ diff --git a/rtos/rtx/TARGET_CORTEX_M/rt_Timer.c b/rtos/rtx/TARGET_CORTEX_M/rt_Timer.c deleted file mode 100644 index fa4b84414a8..00000000000 --- a/rtos/rtx/TARGET_CORTEX_M/rt_Timer.c +++ /dev/null @@ -1,135 +0,0 @@ -/*---------------------------------------------------------------------------- - * CMSIS-RTOS - RTX - *---------------------------------------------------------------------------- - * Name: RT_TIMER.C - * Purpose: User timer functions - * Rev.: V4.70 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -#include "rt_TypeDef.h" -#include "RTX_Config.h" -#include "rt_Timer.h" -#include "rt_MemBox.h" -#include "cmsis_os.h" - -#ifndef __CMSIS_RTOS - - -/*---------------------------------------------------------------------------- - * Global Variables - *---------------------------------------------------------------------------*/ - -/* User Timer list pointer */ -struct OS_XTMR os_tmr; - -/*---------------------------------------------------------------------------- - * Functions - *---------------------------------------------------------------------------*/ - -/*--------------------------- rt_tmr_tick -----------------------------------*/ - -void rt_tmr_tick (void) { - /* Decrement delta count of timer list head. Timers having the value of */ - /* zero are removed from the list and the callback function is called. */ - P_TMR p; - - if (os_tmr.next == NULL) { - return; - } - os_tmr.tcnt--; - while ((os_tmr.tcnt == 0U) && ((p = os_tmr.next) != NULL)) { - /* Call a user provided function to handle an elapsed timer */ - os_tmr_call (p->info); - os_tmr.tcnt = p->tcnt; - os_tmr.next = p->next; - rt_free_box ((U32 *)m_tmr, p); - } -} - -/*--------------------------- rt_tmr_create ---------------------------------*/ - -OS_ID rt_tmr_create (U16 tcnt, U16 info) { - /* Create an user timer and put it into the chained timer list using */ - /* a timeout count value of "tcnt". User parameter "info" is used as a */ - /* parameter for the user provided callback function "os_tmr_call ()". */ - P_TMR p_tmr, p; - U32 delta,itcnt = tcnt; - - if ((tcnt == 0U) || (m_tmr == NULL)) { - return (NULL); - } - p_tmr = rt_alloc_box ((U32 *)m_tmr); - if (!p_tmr) { - return (NULL); - } - p_tmr->info = info; - p = (P_TMR)&os_tmr; - delta = p->tcnt; - while ((delta < itcnt) && (p->next != NULL)) { - p = p->next; - delta += p->tcnt; - } - /* Right place found, insert timer into the list */ - p_tmr->next = p->next; - p_tmr->tcnt = (U16)(delta - itcnt); - p->next = p_tmr; - p->tcnt -= p_tmr->tcnt; - return (p_tmr); -} - -/*--------------------------- rt_tmr_kill -----------------------------------*/ - -OS_ID rt_tmr_kill (OS_ID timer) { - /* Remove user timer from the chained timer list. */ - P_TMR p, p_tmr; - - p_tmr = (P_TMR)timer; - p = (P_TMR)&os_tmr; - /* Search timer list for requested timer */ - while (p->next != p_tmr) { - if (p->next == NULL) { - /* Failed, "timer" is not in the timer list */ - return (p_tmr); - } - p = p->next; - } - /* Timer was found, remove it from the list */ - p->next = p_tmr->next; - p->tcnt += p_tmr->tcnt; - rt_free_box ((U32 *)m_tmr, p_tmr); - /* Timer killed */ - return (NULL); -} - - -#endif - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ diff --git a/rtos/rtx/TARGET_CORTEX_M/rt_Timer.h b/rtos/rtx/TARGET_CORTEX_M/rt_Timer.h deleted file mode 100644 index abc58fed262..00000000000 --- a/rtos/rtx/TARGET_CORTEX_M/rt_Timer.h +++ /dev/null @@ -1,50 +0,0 @@ - -/** \addtogroup rtos */ -/** @{*/ -/*---------------------------------------------------------------------------- - * CMSIS-RTOS - RTX - *---------------------------------------------------------------------------- - * Name: RT_TIMER.H - * Purpose: User timer functions - * Rev.: V4.70 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - -/* Variables */ -extern struct OS_XTMR os_tmr; - -/* Functions */ -extern void rt_tmr_tick (void); -extern OS_ID rt_tmr_create (U16 tcnt, U16 info); -extern OS_ID rt_tmr_kill (OS_ID timer); - -/*---------------------------------------------------------------------------- - * end of file - *---------------------------------------------------------------------------*/ - -/** @}*/ diff --git a/rtos/rtx/TARGET_CORTEX_M/rt_TypeDef.h b/rtos/rtx/TARGET_CORTEX_M/rt_TypeDef.h deleted file mode 100644 index 272c813b0b4..00000000000 --- a/rtos/rtx/TARGET_CORTEX_M/rt_TypeDef.h +++ /dev/null @@ -1,175 +0,0 @@ - -/** \addtogroup rtos */ -/** @{*/ -/*---------------------------------------------------------------------------- - * CMSIS-RTOS - RTX - *---------------------------------------------------------------------------- - * Name: RT_TYPEDEF.H - * Purpose: Type Definitions - * Rev.: V4.79 - *---------------------------------------------------------------------------- - * - * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ -#ifndef RT_TYPE_DEF_H -#define RT_TYPE_DEF_H - -/* Types */ -typedef char S8; -typedef unsigned char U8; -typedef short S16; -typedef unsigned short U16; -typedef int S32; -typedef unsigned int U32; -typedef long long S64; -typedef unsigned long long U64; -typedef unsigned char BIT; -typedef unsigned int BOOL; -typedef void (*FUNCP)(void); - -typedef U32 OS_TID; -typedef void *OS_ID; -typedef U32 OS_RESULT; - -typedef struct OS_TCB { - /* General part: identical for all implementations. */ - U8 cb_type; /* Control Block Type */ - U8 state; /* Task state */ - U8 prio; /* Execution priority */ - U8 task_id; /* Task ID value for optimized TCB access */ - struct OS_TCB *p_lnk; /* Link pointer for ready/sem. wait list */ - struct OS_TCB *p_rlnk; /* Link pointer for sem./mbx lst backwards */ - struct OS_TCB *p_dlnk; /* Link pointer for delay list */ - struct OS_TCB *p_blnk; /* Link pointer for delay list backwards */ - U16 delta_time; /* Time until time out */ - U16 interval_time; /* Time interval for periodic waits */ - U16 events; /* Event flags */ - U16 waits; /* Wait flags */ - void **msg; /* Direct message passing when task waits */ - struct OS_MUCB *p_mlnk; /* Link pointer for mutex owner list */ - U8 prio_base; /* Base priority */ - - /* Hardware dependant part: specific for CM processor */ - U8 stack_frame; /* Stack frame: 0=Basic, 1=Extended, */ - U16 reserved; /* Two reserved bytes for alignment */ - /* (2=VFP/D16 stacked, 4=NEON/D32 stacked) */ - U32 priv_stack; /* Private stack size, 0= system assigned */ - U32 tsk_stack; /* Current task Stack pointer (R13) */ - U32 *stack; /* Pointer to Task Stack memory block */ - - /* Task entry point used for uVision debugger */ - FUNCP ptask; /* Task entry address */ - void *argv; /* Task argument */ - void *context; /* Pointer to thread context */ -} *P_TCB; -#define TCB_STACKF 37 /* 'stack_frame' offset */ -#define TCB_TSTACK 44 /* 'tsk_stack' offset */ - -typedef struct OS_PSFE { /* Post Service Fifo Entry */ - void *id; /* Object Identification */ - U32 arg; /* Object Argument */ -} *P_PSFE; - -typedef struct OS_PSQ { /* Post Service Queue */ - U8 first; /* FIFO Head Index */ - U8 last; /* FIFO Tail Index */ - U8 count; /* Number of stored items in FIFO */ - U8 size; /* FIFO Size */ - struct OS_PSFE q[1]; /* FIFO Content */ -} *P_PSQ; - -typedef struct OS_TSK { - P_TCB run; /* Current running task */ - P_TCB new_tsk; /* Scheduled task to run */ -} *P_TSK; - -typedef struct OS_ROBIN { /* Round Robin Control */ - P_TCB task; /* Round Robin task */ - U16 time; /* Round Robin switch time */ - U16 tout; /* Round Robin timeout */ -} *P_ROBIN; - -typedef struct OS_XCB { - U8 cb_type; /* Control Block Type */ - struct OS_TCB *p_lnk; /* Link pointer for ready/sem. wait list */ - struct OS_TCB *p_rlnk; /* Link pointer for sem./mbx lst backwards */ - struct OS_TCB *p_dlnk; /* Link pointer for delay list */ - struct OS_TCB *p_blnk; /* Link pointer for delay list backwards */ - U16 delta_time; /* Time until time out */ -} *P_XCB; - -typedef struct OS_MCB { - U8 cb_type; /* Control Block Type */ - U8 state; /* State flag variable */ - U8 isr_st; /* State flag variable for isr functions */ - struct OS_TCB *p_lnk; /* Chain of tasks waiting for message */ - U16 first; /* Index of the message list begin */ - U16 last; /* Index of the message list end */ - U16 count; /* Actual number of stored messages */ - U16 size; /* Maximum number of stored messages */ - void *msg[1]; /* FIFO for Message pointers 1st element */ -} *P_MCB; - -typedef struct OS_SCB { - U8 cb_type; /* Control Block Type */ - U8 mask; /* Semaphore token mask */ - U16 tokens; /* Semaphore tokens */ - struct OS_TCB *p_lnk; /* Chain of tasks waiting for tokens */ -} *P_SCB; - -typedef struct OS_MUCB { - U8 cb_type; /* Control Block Type */ - U16 level; /* Call nesting level */ - struct OS_TCB *p_lnk; /* Chain of tasks waiting for mutex */ - struct OS_TCB *owner; /* Mutex owner task */ - struct OS_MUCB *p_mlnk; /* Chain of mutexes by owner task */ -} *P_MUCB; - -typedef struct OS_XTMR { - struct OS_TMR *next; - U16 tcnt; -} *P_XTMR; - -typedef struct OS_TMR { - struct OS_TMR *next; /* Link pointer to Next timer */ - U16 tcnt; /* Timer delay count */ - U16 info; /* User defined call info */ -} *P_TMR; - -typedef struct OS_BM { - void *free; /* Pointer to first free memory block */ - void *end; /* Pointer to memory block end */ - U32 blk_size; /* Memory block size */ -} *P_BM; - -/* Definitions */ -#define __TRUE 1U -#define __FALSE 0U -#define NULL ((void *) 0) - -#endif - -/** @}*/ From a9a29a452906ae9b0680ceab7f280462515005fc Mon Sep 17 00:00:00 2001 From: Bartek Szatkowski Date: Mon, 15 May 2017 11:26:55 -0500 Subject: [PATCH 02/24] Pull in CMSIS 5 files Pull in unmodified CMSIS5 files from the repository https://github.com/ARM-software/CMSIS_5.git from the commit c1b4232f4a98275dd79ebc99cf9b5da5053def4d. The files were copied as shown below with source->dest_dir. CMSIS_5/CMSIS/Core/Include/core_*.h -> mbed-os/cmsis/ CMSIS_5/CMSIS/Core_A/Include/core_*.h -> mbed-os/cmsis/ CMSIS_5/CMSIS/DSP/Include/arm_math.h -> mbed-os/cmsis/ CMSIS_5/CMSIS/Core/Include/tz_context.h -> mbed-os/cmsis/ CMSIS_5/CMSIS/Core/Include/cmsis_compiler.h -> mbed-os/cmsis/TARGET_CORTEX_M/ CMSIS_5/CMSIS/Core/Include/cmsis_arm*.h -> mbed-os/cmsis/TARGET_CORTEX_M/TOOLCHAIN_ARM/ CMSIS_5/CMSIS/Core/Include/cmsis_gcc*.h -> mbed-os/cmsis/TARGET_CORTEX_M/TOOLCHAIN_GCC/ CMSIS_5/CMSIS/Core_A/Include/cmsis_compiler.h -> mbed-os/cmsis/TARGET_CORTEX_A/ CMSIS_5/CMSIS/Core_A/Include/cmsis_arm*.h -> mbed-os/cmsis/TARGET_CORTEX_A/TOOLCHAIN_ARM/ CMSIS_5/CMSIS/RTOS2/RTX/Library/cmsis_os1.c -> mbed-os/rtos/rtx/ CMSIS_5/CMSIS/RTOS2/Include/cmsis_os2.h -> mbed-os/rtos/rtx2/TARGET_CORTEX_M/ CMSIS_5/CMSIS/RTOS2/RTX/Config/* -> mbed-os/rtos/rtx2/TARGET_CORTEX_M/ CMSIS_5/CMSIS/RTOS2/RTX/Include1/* -> mbed-os/rtos/rtx/ CMSIS_5/CMSIS/RTOS2/RTX/Include/* -> mbed-os/rtos/rtx2/TARGET_CORTEX_M/ CMSIS_5/CMSIS/RTOS2/RTX/Source/rtx_* -> mbed-os/rtos/rtx2/TARGET_CORTEX_M/ CMSIS_5/CMSIS/RTOS2/RTX/Source/core_cm.h -> mbed-os/rtos/rtx2/TARGET_CORTEX_M/ CMSIS_5/CMSIS/RTOS2/RTX/Source/ARM/irq_cm0.s -> mbed-os/rtos/rtx2/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_ARM/ CMSIS_5/CMSIS/RTOS2/RTX/Source/GCC/irq_cm0.s -> mbed-os/rtos/rtx2/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_GCC/ CMSIS_5/CMSIS/RTOS2/RTX/Source/IAR/irq_cm0.s -> mbed-os/rtos/rtx2/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_IAR/ CMSIS_5/CMSIS/RTOS2/RTX/Source/ARM/irq_cm0.s -> mbed-os/rtos/rtx2/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_ARM/ CMSIS_5/CMSIS/RTOS2/RTX/Source/GCC/irq_cm0.s -> mbed-os/rtos/rtx2/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_GCC/ CMSIS_5/CMSIS/RTOS2/RTX/Source/IAR/irq_cm0.s -> mbed-os/rtos/rtx2/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_IAR/ CMSIS_5/CMSIS/RTOS2/RTX/Source/ARM/irq_cm3.s -> mbed-os/rtos/rtx2/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_ARM/ CMSIS_5/CMSIS/RTOS2/RTX/Source/GCC/irq_cm3.s -> mbed-os/rtos/rtx2/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_GCC/ CMSIS_5/CMSIS/RTOS2/RTX/Source/IAR/irq_cm3.s -> mbed-os/rtos/rtx2/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_IAR/ CMSIS_5/CMSIS/RTOS2/RTX/Source/ARM/irq_cm4f.s -> mbed-os/rtos/rtx2/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_ARM/ CMSIS_5/CMSIS/RTOS2/RTX/Source/GCC/irq_cm4f.s -> mbed-os/rtos/rtx2/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_GCC/ CMSIS_5/CMSIS/RTOS2/RTX/Source/IAR/irq_cm4f.s -> mbed-os/rtos/rtx2/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_IAR/ --- .../TOOLCHAIN_ARM/cmsis_armcc.h | 673 ++ .../TOOLCHAIN_ARM/cmsis_armclang.h | 646 ++ cmsis/TARGET_CORTEX_A/cmsis_compiler.h | 211 + .../TOOLCHAIN_ARM/cmsis_armcc.h | 809 ++ .../TOOLCHAIN_ARM/cmsis_armclang.h | 1795 ++++ .../TARGET_CORTEX_M/TOOLCHAIN_GCC/cmsis_gcc.h | 1958 +++++ cmsis/TARGET_CORTEX_M/cmsis_compiler.h | 287 + cmsis/arm_math.h | 7226 +++++++++++++++++ cmsis/core_armv8mbl.h | 1876 +++++ cmsis/core_armv8mml.h | 2900 +++++++ cmsis/core_ca.h | 2016 +++++ cmsis/core_cm0.h | 886 ++ cmsis/core_cm0plus.h | 1012 +++ cmsis/core_cm23.h | 1876 +++++ cmsis/core_cm3.h | 1919 +++++ cmsis/core_cm33.h | 2896 +++++++ cmsis/core_cm4.h | 2103 +++++ cmsis/core_cm7.h | 2646 ++++++ cmsis/core_sc000.h | 1014 +++ cmsis/core_sc300.h | 1901 +++++ cmsis/tz_context.h | 69 + rtos/rtx/cmsis_os.h | 898 ++ rtos/rtx/cmsis_os1.c | 371 + rtos/rtx2/TARGET_CORTEX_M/RTX_Config.c | 63 + rtos/rtx2/TARGET_CORTEX_M/RTX_Config.h | 379 + .../TARGET_M0/TOOLCHAIN_ARM/irq_cm0.s | 155 + .../TARGET_M0/TOOLCHAIN_GCC/irq_cm0.S | 164 + .../TARGET_M0/TOOLCHAIN_IAR/irq_cm0.s | 149 + .../TARGET_M0P/TOOLCHAIN_ARM/irq_cm0.s | 155 + .../TARGET_M0P/TOOLCHAIN_GCC/irq_cm0.S | 164 + .../TARGET_M0P/TOOLCHAIN_IAR/irq_cm0.s | 149 + .../TARGET_M3/TOOLCHAIN_ARM/irq_cm3.s | 133 + .../TARGET_M3/TOOLCHAIN_GCC/irq_cm3.S | 142 + .../TARGET_M3/TOOLCHAIN_IAR/irq_cm3.s | 128 + .../TOOLCHAIN_ARM/irq_cm4f.s | 148 + .../TOOLCHAIN_GCC/irq_cm4f.S | 160 + .../TOOLCHAIN_IAR/irq_cm4f.s | 144 + rtos/rtx2/TARGET_CORTEX_M/cmsis_os2.h | 745 ++ rtos/rtx2/TARGET_CORTEX_M/core_cm.h | 1524 ++++ rtos/rtx2/TARGET_CORTEX_M/rtx_delay.c | 88 + rtos/rtx2/TARGET_CORTEX_M/rtx_evflags.c | 576 ++ rtos/rtx2/TARGET_CORTEX_M/rtx_evr.c | 2079 +++++ rtos/rtx2/TARGET_CORTEX_M/rtx_evr.h | 1844 +++++ rtos/rtx2/TARGET_CORTEX_M/rtx_kernel.c | 633 ++ rtos/rtx2/TARGET_CORTEX_M/rtx_lib.c | 634 ++ rtos/rtx2/TARGET_CORTEX_M/rtx_lib.h | 214 + rtos/rtx2/TARGET_CORTEX_M/rtx_memory.c | 171 + rtos/rtx2/TARGET_CORTEX_M/rtx_mempool.c | 685 ++ rtos/rtx2/TARGET_CORTEX_M/rtx_msgqueue.c | 906 +++ rtos/rtx2/TARGET_CORTEX_M/rtx_mutex.c | 491 ++ rtos/rtx2/TARGET_CORTEX_M/rtx_os.h | 478 ++ rtos/rtx2/TARGET_CORTEX_M/rtx_semaphore.c | 484 ++ rtos/rtx2/TARGET_CORTEX_M/rtx_system.c | 257 + rtos/rtx2/TARGET_CORTEX_M/rtx_thread.c | 1699 ++++ rtos/rtx2/TARGET_CORTEX_M/rtx_timer.c | 415 + 55 files changed, 54144 insertions(+) create mode 100644 cmsis/TARGET_CORTEX_A/TOOLCHAIN_ARM/cmsis_armcc.h create mode 100644 cmsis/TARGET_CORTEX_A/TOOLCHAIN_ARM/cmsis_armclang.h create mode 100644 cmsis/TARGET_CORTEX_A/cmsis_compiler.h create mode 100644 cmsis/TARGET_CORTEX_M/TOOLCHAIN_ARM/cmsis_armcc.h create mode 100644 cmsis/TARGET_CORTEX_M/TOOLCHAIN_ARM/cmsis_armclang.h create mode 100644 cmsis/TARGET_CORTEX_M/TOOLCHAIN_GCC/cmsis_gcc.h create mode 100644 cmsis/TARGET_CORTEX_M/cmsis_compiler.h create mode 100644 cmsis/arm_math.h create mode 100644 cmsis/core_armv8mbl.h create mode 100644 cmsis/core_armv8mml.h create mode 100644 cmsis/core_ca.h create mode 100644 cmsis/core_cm0.h create mode 100644 cmsis/core_cm0plus.h create mode 100644 cmsis/core_cm23.h create mode 100644 cmsis/core_cm3.h create mode 100644 cmsis/core_cm33.h create mode 100644 cmsis/core_cm4.h create mode 100644 cmsis/core_cm7.h create mode 100644 cmsis/core_sc000.h create mode 100644 cmsis/core_sc300.h create mode 100644 cmsis/tz_context.h create mode 100644 rtos/rtx/cmsis_os.h create mode 100644 rtos/rtx/cmsis_os1.c create mode 100644 rtos/rtx2/TARGET_CORTEX_M/RTX_Config.c create mode 100644 rtos/rtx2/TARGET_CORTEX_M/RTX_Config.h create mode 100644 rtos/rtx2/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_ARM/irq_cm0.s create mode 100644 rtos/rtx2/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_GCC/irq_cm0.S create mode 100644 rtos/rtx2/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_IAR/irq_cm0.s create mode 100644 rtos/rtx2/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_ARM/irq_cm0.s create mode 100644 rtos/rtx2/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_GCC/irq_cm0.S create mode 100644 rtos/rtx2/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_IAR/irq_cm0.s create mode 100644 rtos/rtx2/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_ARM/irq_cm3.s create mode 100644 rtos/rtx2/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_GCC/irq_cm3.S create mode 100644 rtos/rtx2/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_IAR/irq_cm3.s create mode 100644 rtos/rtx2/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_ARM/irq_cm4f.s create mode 100644 rtos/rtx2/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_GCC/irq_cm4f.S create mode 100644 rtos/rtx2/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_IAR/irq_cm4f.s create mode 100644 rtos/rtx2/TARGET_CORTEX_M/cmsis_os2.h create mode 100644 rtos/rtx2/TARGET_CORTEX_M/core_cm.h create mode 100644 rtos/rtx2/TARGET_CORTEX_M/rtx_delay.c create mode 100644 rtos/rtx2/TARGET_CORTEX_M/rtx_evflags.c create mode 100644 rtos/rtx2/TARGET_CORTEX_M/rtx_evr.c create mode 100644 rtos/rtx2/TARGET_CORTEX_M/rtx_evr.h create mode 100644 rtos/rtx2/TARGET_CORTEX_M/rtx_kernel.c create mode 100644 rtos/rtx2/TARGET_CORTEX_M/rtx_lib.c create mode 100644 rtos/rtx2/TARGET_CORTEX_M/rtx_lib.h create mode 100644 rtos/rtx2/TARGET_CORTEX_M/rtx_memory.c create mode 100644 rtos/rtx2/TARGET_CORTEX_M/rtx_mempool.c create mode 100644 rtos/rtx2/TARGET_CORTEX_M/rtx_msgqueue.c create mode 100644 rtos/rtx2/TARGET_CORTEX_M/rtx_mutex.c create mode 100644 rtos/rtx2/TARGET_CORTEX_M/rtx_os.h create mode 100644 rtos/rtx2/TARGET_CORTEX_M/rtx_semaphore.c create mode 100644 rtos/rtx2/TARGET_CORTEX_M/rtx_system.c create mode 100644 rtos/rtx2/TARGET_CORTEX_M/rtx_thread.c create mode 100644 rtos/rtx2/TARGET_CORTEX_M/rtx_timer.c diff --git a/cmsis/TARGET_CORTEX_A/TOOLCHAIN_ARM/cmsis_armcc.h b/cmsis/TARGET_CORTEX_A/TOOLCHAIN_ARM/cmsis_armcc.h new file mode 100644 index 00000000000..a6c0d160d5b --- /dev/null +++ b/cmsis/TARGET_CORTEX_A/TOOLCHAIN_ARM/cmsis_armcc.h @@ -0,0 +1,673 @@ +/**************************************************************************//** + * @file cmsis_armcc.h + * @brief CMSIS compiler specific macros, functions, instructions + * @version V1.00 + * @date 22. Feb 2017 + ******************************************************************************/ +/* + * Copyright (c) 2009-2017 ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CMSIS_ARMCC_H +#define __CMSIS_ARMCC_H + +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 400677) + #error "Please use ARM Compiler Toolchain V4.0.677 or later!" +#endif + +/* CMSIS compiler control architecture macros */ +#if (defined (__TARGET_ARCH_7_A ) && (__TARGET_ARCH_7_A == 1)) + #define __ARM_ARCH_7A__ 1 +#endif + +/* CMSIS compiler specific defines */ +#ifndef __ASM + #define __ASM __asm +#endif +#ifndef __INLINE + #define __INLINE __inline +#endif +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static __inline +#endif +#ifndef __STATIC_ASM + #define __STATIC_ASM static __asm +#endif +#ifndef __NO_RETURN + #define __NO_RETURN __declspec(noreturn) +#endif +#ifndef __USED + #define __USED __attribute__((used)) +#endif +#ifndef __WEAK + #define __WEAK __attribute__((weak)) +#endif +#ifndef __UNALIGNED_UINT32 + #define __UNALIGNED_UINT32(x) (*((__packed uint32_t *)(x))) +#endif +#ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) +#endif +#ifndef __PACKED + #define __PACKED __attribute__((packed)) +#endif + + +/* ########################### Core Function Access ########################### */ + +/** + \brief Get FPSCR + \return Floating Point Status/Control register value + */ +__STATIC_INLINE uint32_t __get_FPSCR(void) +{ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) + register uint32_t __regfpscr __ASM("fpscr"); + return(__regfpscr); +#else + return(0U); +#endif +} + +/** + \brief Set FPSCR + \param [in] fpscr Floating Point Status/Control value to set + */ +__STATIC_INLINE void __set_FPSCR(uint32_t fpscr) +{ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) + register uint32_t __regfpscr __ASM("fpscr"); + __regfpscr = (fpscr); +#else + (void)fpscr; +#endif +} + +/* ########################## Core Instruction Access ######################### */ +/** + \brief No Operation + */ +#define __NOP __nop + +/** + \brief Wait For Interrupt + */ +#define __WFI __wfi + +/** + \brief Wait For Event + */ +#define __WFE __wfe + +/** + \brief Send Event + */ +#define __SEV __sev + +/** + \brief Instruction Synchronization Barrier + */ +#define __ISB() do {\ + __schedule_barrier();\ + __isb(0xF);\ + __schedule_barrier();\ + } while (0U) + +/** + \brief Data Synchronization Barrier + */ +#define __DSB() do {\ + __schedule_barrier();\ + __dsb(0xF);\ + __schedule_barrier();\ + } while (0U) + +/** + \brief Data Memory Barrier + */ +#define __DMB() do {\ + __schedule_barrier();\ + __dmb(0xF);\ + __schedule_barrier();\ + } while (0U) + +/** + \brief Reverse byte order (32 bit) + \param [in] value Value to reverse + \return Reversed value + */ +#define __REV __rev + +/** + \brief Reverse byte order (16 bit) + \param [in] value Value to reverse + \return Reversed value + */ +#ifndef __NO_EMBEDDED_ASM +__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value) +{ + rev16 r0, r0 + bx lr +} +#endif + +/** + \brief Reverse byte order in signed short value + \param [in] value Value to reverse + \return Reversed value + */ +#ifndef __NO_EMBEDDED_ASM +__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int32_t __REVSH(int32_t value) +{ + revsh r0, r0 + bx lr +} +#endif + +/** + \brief Rotate Right in unsigned value (32 bit) + \param [in] op1 Value to rotate + \param [in] op2 Number of Bits to rotate + \return Rotated value + */ +#define __ROR __ror + +/** + \brief Breakpoint + \param [in] value is ignored by the processor. + If required, a debugger can use it to store additional information about the breakpoint. + */ +#define __BKPT(value) __breakpoint(value) + +/** + \brief Reverse bit order of value + \param [in] value Value to reverse + \return Reversed value + */ +#define __RBIT __rbit + +/** + \brief Count leading zeros + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +#define __CLZ __clz + +/** \brief Get CPSR Register + \return CPSR Register value + */ +__STATIC_INLINE uint32_t __get_CPSR(void) +{ + register uint32_t __regCPSR __ASM("cpsr"); + return(__regCPSR); +} + + +/** \brief Set CPSR Register + \param [in] cpsr CPSR value to set + */ +__STATIC_INLINE void __set_CPSR(uint32_t cpsr) +{ + register uint32_t __regCPSR __ASM("cpsr"); + __regCPSR = cpsr; +} + +/** \brief Get Mode + \return Processor Mode + */ +__STATIC_INLINE uint32_t __get_mode(void) { + return (__get_CPSR() & 0x1FU); +} + +/** \brief Set Mode + \param [in] mode Mode value to set + */ +__STATIC_INLINE __ASM void __set_mode(uint32_t mode) { + MOV r1, lr + MSR CPSR_C, r0 + BX r1 +} + +/** \brief Set Stack Pointer + \param [in] stack Stack Pointer value to set + */ +__STATIC_INLINE __ASM void __set_SP(uint32_t stack) +{ + MOV sp, r0 + BX lr +} + +/** \brief Set Process Stack Pointer + \param [in] topOfProcStack USR/SYS Stack Pointer value to set + */ +__STATIC_INLINE __ASM void __set_PSP(uint32_t topOfProcStack) +{ + ARM + PRESERVE8 + + BIC R0, R0, #7 ;ensure stack is 8-byte aligned + MRS R1, CPSR + CPS #0x1F ;no effect in USR mode + MOV SP, R0 + MSR CPSR_c, R1 ;no effect in USR mode + ISB + BX LR +} + +/** \brief Set User Mode + */ +__STATIC_INLINE __ASM void __set_CPS_USR(void) +{ + ARM + + CPS #0x10 + BX LR +} + +/** \brief Get FPEXC + \return Floating Point Exception Control register value + */ +__STATIC_INLINE uint32_t __get_FPEXC(void) +{ +#if (__FPU_PRESENT == 1) + register uint32_t __regfpexc __ASM("fpexc"); + return(__regfpexc); +#else + return(0); +#endif +} + +/** \brief Set FPEXC + \param [in] fpexc Floating Point Exception Control value to set + */ +__STATIC_INLINE void __set_FPEXC(uint32_t fpexc) +{ +#if (__FPU_PRESENT == 1) + register uint32_t __regfpexc __ASM("fpexc"); + __regfpexc = (fpexc); +#endif +} + +/** \brief Get CPACR + \return Coprocessor Access Control register value + */ +__STATIC_INLINE uint32_t __get_CPACR(void) +{ + register uint32_t __regCPACR __ASM("cp15:0:c1:c0:2"); + return __regCPACR; +} + +/** \brief Set CPACR + \param [in] cpacr Coprocessor Acccess Control value to set + */ +__STATIC_INLINE void __set_CPACR(uint32_t cpacr) +{ + register uint32_t __regCPACR __ASM("cp15:0:c1:c0:2"); + __regCPACR = cpacr; +} + +/** \brief Get CBAR + \return Configuration Base Address register value + */ +__STATIC_INLINE uint32_t __get_CBAR() { + register uint32_t __regCBAR __ASM("cp15:4:c15:c0:0"); + return(__regCBAR); +} + +/** \brief Get TTBR0 + + This function returns the value of the Translation Table Base Register 0. + + \return Translation Table Base Register 0 value + */ +__STATIC_INLINE uint32_t __get_TTBR0() { + register uint32_t __regTTBR0 __ASM("cp15:0:c2:c0:0"); + return(__regTTBR0); +} + +/** \brief Set TTBR0 + + This function assigns the given value to the Translation Table Base Register 0. + + \param [in] ttbr0 Translation Table Base Register 0 value to set + */ +__STATIC_INLINE void __set_TTBR0(uint32_t ttbr0) { + register uint32_t __regTTBR0 __ASM("cp15:0:c2:c0:0"); + __regTTBR0 = ttbr0; +} + +/** \brief Get DACR + + This function returns the value of the Domain Access Control Register. + + \return Domain Access Control Register value + */ +__STATIC_INLINE uint32_t __get_DACR() { + register uint32_t __regDACR __ASM("cp15:0:c3:c0:0"); + return(__regDACR); +} + +/** \brief Set DACR + + This function assigns the given value to the Domain Access Control Register. + + \param [in] dacr Domain Access Control Register value to set + */ +__STATIC_INLINE void __set_DACR(uint32_t dacr) { + register uint32_t __regDACR __ASM("cp15:0:c3:c0:0"); + __regDACR = dacr; +} + +/** \brief Set SCTLR + + This function assigns the given value to the System Control Register. + + \param [in] sctlr System Control Register value to set + */ +__STATIC_INLINE void __set_SCTLR(uint32_t sctlr) +{ + register uint32_t __regSCTLR __ASM("cp15:0:c1:c0:0"); + __regSCTLR = sctlr; +} + +/** \brief Get SCTLR + \return System Control Register value + */ +__STATIC_INLINE uint32_t __get_SCTLR() { + register uint32_t __regSCTLR __ASM("cp15:0:c1:c0:0"); + return(__regSCTLR); +} + +/** \brief Set ACTRL + \param [in] actrl Auxiliary Control Register value to set + */ +__STATIC_INLINE void __set_ACTRL(uint32_t actrl) +{ + register uint32_t __regACTRL __ASM("cp15:0:c1:c0:1"); + __regACTRL = actrl; +} + +/** \brief Get ACTRL + \return Auxiliary Control Register value + */ +__STATIC_INLINE uint32_t __get_ACTRL(void) +{ + register uint32_t __regACTRL __ASM("cp15:0:c1:c0:1"); + return(__regACTRL); +} + +/** \brief Get MPIDR + + This function returns the value of the Multiprocessor Affinity Register. + + \return Multiprocessor Affinity Register value + */ +__STATIC_INLINE uint32_t __get_MPIDR(void) +{ + register uint32_t __regMPIDR __ASM("cp15:0:c0:c0:5"); + return(__regMPIDR); +} + + /** \brief Get VBAR + + This function returns the value of the Vector Base Address Register. + + \return Vector Base Address Register + */ +__STATIC_INLINE uint32_t __get_VBAR(void) +{ + register uint32_t __regVBAR __ASM("cp15:0:c12:c0:0"); + return(__regVBAR); +} + +/** \brief Set VBAR + + This function assigns the given value to the Vector Base Address Register. + + \param [in] vbar Vector Base Address Register value to set + */ +__STATIC_INLINE void __set_VBAR(uint32_t vbar) +{ + register uint32_t __regVBAR __ASM("cp15:0:c12:c0:0"); + __regVBAR = vbar; +} + +/** \brief Set CNTP_TVAL + + This function assigns the given value to PL1 Physical Timer Value Register (CNTP_TVAL). + + \param [in] value CNTP_TVAL Register value to set +*/ +__STATIC_INLINE void __set_CNTP_TVAL(uint32_t value) { + register uint32_t __regCNTP_TVAL __ASM("cp15:0:c14:c2:0"); + __regCNTP_TVAL = value; +} + +/** \brief Get CNTP_TVAL + + This function returns the value of the PL1 Physical Timer Value Register (CNTP_TVAL). + + \return CNTP_TVAL Register value + */ +__STATIC_INLINE uint32_t __get_CNTP_TVAL() { + register uint32_t __regCNTP_TVAL __ASM("cp15:0:c14:c2:0"); + return(__regCNTP_TVAL); +} + +/** \brief Set CNTP_CTL + + This function assigns the given value to PL1 Physical Timer Control Register (CNTP_CTL). + + \param [in] value CNTP_CTL Register value to set +*/ +__STATIC_INLINE void __set_CNTP_CTL(uint32_t value) { + register uint32_t __regCNTP_CTL __ASM("cp15:0:c14:c2:1"); + __regCNTP_CTL = value; +} + +/** \brief Set TLBIALL + + TLB Invalidate All + */ +__STATIC_INLINE void __set_TLBIALL(uint32_t value) { + register uint32_t __TLBIALL __ASM("cp15:0:c8:c7:0"); + __TLBIALL = value; +} + +/** \brief Set BPIALL. + + Branch Predictor Invalidate All + */ +__STATIC_INLINE void __set_BPIALL(uint32_t value) { + register uint32_t __BPIALL __ASM("cp15:0:c7:c5:6"); + __BPIALL = value; +} + +/** \brief Set ICIALLU + + Instruction Cache Invalidate All + */ +__STATIC_INLINE void __set_ICIALLU(uint32_t value) { + register uint32_t __ICIALLU __ASM("cp15:0:c7:c5:0"); + __ICIALLU = value; +} + +/** \brief Set DCCMVAC + + Data cache clean + */ +__STATIC_INLINE void __set_DCCMVAC(uint32_t value) { + register uint32_t __DCCMVAC __ASM("cp15:0:c7:c10:1"); + __DCCMVAC = value; +} + +/** \brief Set DCIMVAC + + Data cache invalidate + */ +__STATIC_INLINE void __set_DCIMVAC(uint32_t value) { + register uint32_t __DCIMVAC __ASM("cp15:0:c7:c6:1"); + __DCIMVAC = value; +} + +/** \brief Set DCCIMVAC + + Data cache clean and invalidate + */ +__STATIC_INLINE void __set_DCCIMVAC(uint32_t value) { + register uint32_t __DCCIMVAC __ASM("cp15:0:c7:c14:1"); + __DCCIMVAC = value; +} + +/** \brief Clean and Invalidate the entire data or unified cache + + Generic mechanism for cleaning/invalidating the entire data or unified cache to the point of coherency + */ +#pragma push +#pragma arm +__STATIC_INLINE __ASM void __L1C_CleanInvalidateCache(uint32_t op) { + ARM + + PUSH {R4-R11} + + MRC p15, 1, R6, c0, c0, 1 // Read CLIDR + ANDS R3, R6, #0x07000000 // Extract coherency level + MOV R3, R3, LSR #23 // Total cache levels << 1 + BEQ Finished // If 0, no need to clean + + MOV R10, #0 // R10 holds current cache level << 1 +Loop1 ADD R2, R10, R10, LSR #1 // R2 holds cache "Set" position + MOV R1, R6, LSR R2 // Bottom 3 bits are the Cache-type for this level + AND R1, R1, #7 // Isolate those lower 3 bits + CMP R1, #2 + BLT Skip // No cache or only instruction cache at this level + + MCR p15, 2, R10, c0, c0, 0 // Write the Cache Size selection register + ISB // ISB to sync the change to the CacheSizeID reg + MRC p15, 1, R1, c0, c0, 0 // Reads current Cache Size ID register + AND R2, R1, #7 // Extract the line length field + ADD R2, R2, #4 // Add 4 for the line length offset (log2 16 bytes) + LDR R4, =0x3FF + ANDS R4, R4, R1, LSR #3 // R4 is the max number on the way size (right aligned) + CLZ R5, R4 // R5 is the bit position of the way size increment + LDR R7, =0x7FFF + ANDS R7, R7, R1, LSR #13 // R7 is the max number of the index size (right aligned) + +Loop2 MOV R9, R4 // R9 working copy of the max way size (right aligned) + +Loop3 ORR R11, R10, R9, LSL R5 // Factor in the Way number and cache number into R11 + ORR R11, R11, R7, LSL R2 // Factor in the Set number + CMP R0, #0 + BNE Dccsw + MCR p15, 0, R11, c7, c6, 2 // DCISW. Invalidate by Set/Way + B cont +Dccsw CMP R0, #1 + BNE Dccisw + MCR p15, 0, R11, c7, c10, 2 // DCCSW. Clean by Set/Way + B cont +Dccisw MCR p15, 0, R11, c7, c14, 2 // DCCISW. Clean and Invalidate by Set/Way +cont SUBS R9, R9, #1 // Decrement the Way number + BGE Loop3 + SUBS R7, R7, #1 // Decrement the Set number + BGE Loop2 +Skip ADD R10, R10, #2 // Increment the cache number + CMP R3, R10 + BGT Loop1 + +Finished + DSB + POP {R4-R11} + BX lr +} +#pragma pop + +/** \brief Enable Floating Point Unit + + Critical section, called from undef handler, so systick is disabled + */ +#pragma push +#pragma arm +__STATIC_INLINE __ASM void __FPU_Enable(void) { + ARM + + //Permit access to VFP/NEON, registers by modifying CPACR + MRC p15,0,R1,c1,c0,2 + ORR R1,R1,#0x00F00000 + MCR p15,0,R1,c1,c0,2 + + //Ensure that subsequent instructions occur in the context of VFP/NEON access permitted + ISB + + //Enable VFP/NEON + VMRS R1,FPEXC + ORR R1,R1,#0x40000000 + VMSR FPEXC,R1 + + //Initialise VFP/NEON registers to 0 + MOV R2,#0 + IF {TARGET_FEATURE_EXTENSION_REGISTER_COUNT} >= 16 + //Initialise D16 registers to 0 + VMOV D0, R2,R2 + VMOV D1, R2,R2 + VMOV D2, R2,R2 + VMOV D3, R2,R2 + VMOV D4, R2,R2 + VMOV D5, R2,R2 + VMOV D6, R2,R2 + VMOV D7, R2,R2 + VMOV D8, R2,R2 + VMOV D9, R2,R2 + VMOV D10,R2,R2 + VMOV D11,R2,R2 + VMOV D12,R2,R2 + VMOV D13,R2,R2 + VMOV D14,R2,R2 + VMOV D15,R2,R2 + ENDIF + IF {TARGET_FEATURE_EXTENSION_REGISTER_COUNT} == 32 + //Initialise D32 registers to 0 + VMOV D16,R2,R2 + VMOV D17,R2,R2 + VMOV D18,R2,R2 + VMOV D19,R2,R2 + VMOV D20,R2,R2 + VMOV D21,R2,R2 + VMOV D22,R2,R2 + VMOV D23,R2,R2 + VMOV D24,R2,R2 + VMOV D25,R2,R2 + VMOV D26,R2,R2 + VMOV D27,R2,R2 + VMOV D28,R2,R2 + VMOV D29,R2,R2 + VMOV D30,R2,R2 + VMOV D31,R2,R2 + ENDIF + + //Initialise FPSCR to a known state + VMRS R2,FPSCR + LDR R3,=0x00086060 //Mask off all bits that do not have to be preserved. Non-preserved bits can/should be zero. + AND R2,R2,R3 + VMSR FPSCR,R2 + + BX LR +} +#pragma pop + +#endif /* __CMSIS_ARMCC_H */ diff --git a/cmsis/TARGET_CORTEX_A/TOOLCHAIN_ARM/cmsis_armclang.h b/cmsis/TARGET_CORTEX_A/TOOLCHAIN_ARM/cmsis_armclang.h new file mode 100644 index 00000000000..243f6fdbf23 --- /dev/null +++ b/cmsis/TARGET_CORTEX_A/TOOLCHAIN_ARM/cmsis_armclang.h @@ -0,0 +1,646 @@ +/**************************************************************************//** + * @file cmsis_armclang.h + * @brief CMSIS compiler specific macros, functions, instructions + * @version V1.00 + * @date 05. Apr 2017 + ******************************************************************************/ +/* + * Copyright (c) 2009-2017 ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CMSIS_ARMCLANG_H +#define __CMSIS_ARMCLANG_H + +#ifndef __ARM_COMPAT_H +#include /* Compatibility header for ARM Compiler 5 intrinsics */ +#endif + +/* CMSIS compiler specific defines */ +#ifndef __ASM + #define __ASM __asm +#endif +#ifndef __INLINE + #define __INLINE __inline +#endif +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static __inline +#endif +#ifndef __STATIC_ASM + #define __STATIC_ASM static __asm +#endif +#ifndef __NO_RETURN + #define __NO_RETURN __declspec(noreturn) +#endif +#ifndef __USED + #define __USED __attribute__((used)) +#endif +#ifndef __WEAK + #define __WEAK __attribute__((weak)) +#endif +#ifndef __UNALIGNED_UINT32 + #define __UNALIGNED_UINT32(x) (*((__packed uint32_t *)(x))) +#endif +#ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) +#endif +#ifndef __PACKED + #define __PACKED __attribute__((packed)) +#endif + + +/* ########################### Core Function Access ########################### */ + +/** + \brief Get FPSCR + \return Floating Point Status/Control register value + */ +__STATIC_INLINE uint32_t __get_FPSCR(void) +{ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) + uint32_t result; + __ASM volatile("MRS %0, fpscr" : "=r" (result) ); + return(result); +#else + return(0U); +#endif +} + +/** + \brief Set FPSCR + \param [in] fpscr Floating Point Status/Control value to set + */ +__STATIC_INLINE void __set_FPSCR(uint32_t fpscr) +{ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) + __ASM volatile ("MSR fpscr, %0" : : "r" (fpscr) : "memory"); +#else + (void)fpscr; +#endif +} + +/* ########################## Core Instruction Access ######################### */ +/** + \brief No Operation + */ +#define __NOP __builtin_arm_nop + +/** + \brief Wait For Interrupt + */ +#define __WFI __builtin_arm_wfi + +/** + \brief Wait For Event + */ +#define __WFE __builtin_arm_wfe + +/** + \brief Send Event + */ +#define __SEV __builtin_arm_sev + +/** + \brief Instruction Synchronization Barrier + */ +#define __ISB() do {\ + __schedule_barrier();\ + __builtin_arm_isb(0xF);\ + __schedule_barrier();\ + } while (0U) + +/** + \brief Data Synchronization Barrier + */ +#define __DSB() do {\ + __schedule_barrier();\ + __builtin_arm_dsb(0xF);\ + __schedule_barrier();\ + } while (0U) + +/** + \brief Data Memory Barrier + */ +#define __DMB() do {\ + __schedule_barrier();\ + __builtin_arm_dmb(0xF);\ + __schedule_barrier();\ + } while (0U) + +/** + \brief Reverse byte order (32 bit) + \param [in] value Value to reverse + \return Reversed value + */ +#define __REV __builtin_bswap32 + +/** + \brief Reverse byte order (16 bit) + \param [in] value Value to reverse + \return Reversed value + */ +#ifndef __NO_EMBEDDED_ASM +__attribute__((section(".rev16_text"))) __STATIC_INLINE uint32_t __REV16(uint32_t value) +{ + uint32_t result; + __ASM volatile("rev16 %0, %1" : "=r" (result) : "r" (value)); + return result; +} +#endif + +/** + \brief Reverse byte order in signed short value + \param [in] value Value to reverse + \return Reversed value + */ +#ifndef __NO_EMBEDDED_ASM +__attribute__((section(".revsh_text"))) __STATIC_INLINE int32_t __REVSH(int32_t value) +{ + int32_t result; + __ASM volatile("revsh %0, %1" : "=r" (result) : "r" (value)); + return result; +} +#endif + +/** + \brief Rotate Right in unsigned value (32 bit) + \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. + \param [in] op1 Value to rotate + \param [in] op2 Number of Bits to rotate + \return Rotated value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __ROR(uint32_t op1, uint32_t op2) +{ + return (op1 >> op2) | (op1 << (32U - op2)); +} + +/** + \brief Breakpoint + \param [in] value is ignored by the processor. + If required, a debugger can use it to store additional information about the breakpoint. + */ +#define __BKPT(value) __ASM volatile ("bkpt "#value) + +/** + \brief Reverse bit order of value + \param [in] value Value to reverse + \return Reversed value + */ +#define __RBIT __builtin_arm_rbit + +/** + \brief Count leading zeros + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +#define __CLZ __builtin_clz + +/** \brief Get CPSR Register + \return CPSR Register value + */ +__STATIC_INLINE uint32_t __get_CPSR(void) +{ + uint32_t result; + __ASM volatile("MRS %0, cpsr" : "=r" (result) ); + return(result); +} + +/** \brief Get Mode + \return Processor Mode + */ +__STATIC_INLINE uint32_t __get_mode(void) { + return (__get_CPSR() & 0x1FU); +} + +/** \brief Set Mode + \param [in] mode Mode value to set + */ +__STATIC_INLINE void __set_mode(uint32_t mode) { + __ASM volatile("MSR cpsr_c, %0" : : "r" (mode) : "memory"); +} + +/** \brief Set Stack Pointer + \param [in] stack Stack Pointer value to set + */ +__STATIC_INLINE void __set_SP(uint32_t stack) +{ + __ASM volatile("MOV sp, %0" : : "r" (stack) : "memory"); +} + +/** \brief Set Process Stack Pointer + \param [in] topOfProcStack USR/SYS Stack Pointer value to set + */ +__STATIC_INLINE void __set_PSP(uint32_t topOfProcStack) +{ + __ASM volatile( + ".preserve8 \n" + "BIC r0, r0, #7 \n" // ensure stack is 8-byte aligned + "MRS r1, cpsr \n" + "CPS #0x1F \n" // no effect in USR mode + "MOV sp, r0 \n" + "MSR cpsr_c, r1 \n" // no effect in USR mode + "ISB" + ); +} + +/** \brief Set User Mode + */ +__STATIC_INLINE void __set_CPS_USR(void) +{ + __ASM volatile("CPS #0x10"); +} + +/** \brief Get FPEXC + \return Floating Point Exception Control register value + */ +__STATIC_INLINE uint32_t __get_FPEXC(void) +{ +#if (__FPU_PRESENT == 1) + uint32_t result; + __ASM volatile("MRS %0, fpexc" : "=r" (result) ); + return(result); +#else + return(0); +#endif +} + +/** \brief Set FPEXC + \param [in] fpexc Floating Point Exception Control value to set + */ +__STATIC_INLINE void __set_FPEXC(uint32_t fpexc) +{ +#if (__FPU_PRESENT == 1) + __ASM volatile ("MSR fpexc, %0" : : "r" (fpexc) : "memory"); +#endif +} + +/** \brief Get CPACR + \return Coprocessor Access Control register value + */ +__STATIC_INLINE uint32_t __get_CPACR(void) +{ + uint32_t result; + __ASM volatile("MRC p15, 0, %0, c1, c0, 2" : "=r"(result)); + return result; +} + +/** \brief Set CPACR + \param [in] cpacr Coprocessor Acccess Control value to set + */ +__STATIC_INLINE void __set_CPACR(uint32_t cpacr) +{ + __ASM volatile("MCR p15, 0, %0, c1, c0, 2" : : "r"(cpacr) : "memory"); +} + +/** \brief Get CBAR + \return Configuration Base Address register value + */ +__STATIC_INLINE uint32_t __get_CBAR() { + uint32_t result; + __ASM volatile("MRC p15, 4, %0, c15, c0, 0" : "=r"(result)); + return result; +} + +/** \brief Get TTBR0 + + This function returns the value of the Translation Table Base Register 0. + + \return Translation Table Base Register 0 value + */ +__STATIC_INLINE uint32_t __get_TTBR0() { + uint32_t result; + __ASM volatile("MRC p15, 0, %0, c2, c0, 0" : "=r"(result)); + return result; +} + +/** \brief Set TTBR0 + + This function assigns the given value to the Translation Table Base Register 0. + + \param [in] ttbr0 Translation Table Base Register 0 value to set + */ +__STATIC_INLINE void __set_TTBR0(uint32_t ttbr0) { + __ASM volatile("MCR p15, 0, %0, c2, c0, 0" : : "r"(ttbr0) : "memory"); +} + +/** \brief Get DACR + + This function returns the value of the Domain Access Control Register. + + \return Domain Access Control Register value + */ +__STATIC_INLINE uint32_t __get_DACR() { + uint32_t result; + __ASM volatile("MRC p15, 0, %0, c3, c0, 0" : "=r"(result)); + return result; +} + +/** \brief Set DACR + + This function assigns the given value to the Domain Access Control Register. + + \param [in] dacr Domain Access Control Register value to set + */ +__STATIC_INLINE void __set_DACR(uint32_t dacr) { + __ASM volatile("MCR p15, 0, %0, c3, c0, 0" : : "r"(dacr) : "memory"); +} + +/** \brief Set SCTLR + + This function assigns the given value to the System Control Register. + + \param [in] sctlr System Control Register value to set + */ +__STATIC_INLINE void __set_SCTLR(uint32_t sctlr) +{ + __ASM volatile("MCR p15, 0, %0, c1, c0, 0" : : "r"(sctlr) : "memory"); +} + +/** \brief Get SCTLR + \return System Control Register value + */ +__STATIC_INLINE uint32_t __get_SCTLR() { + uint32_t result; + __ASM volatile("MRC p15, 0, %0, c1, c0, 0" : "=r"(result)); + return result; +} + +/** \brief Set ACTRL + \param [in] actrl Auxiliary Control Register value to set + */ +__STATIC_INLINE void __set_ACTRL(uint32_t actrl) +{ + __ASM volatile("MCR p15, 0, %0, c1, c0, 1" : : "r"(actrl) : "memory"); +} + +/** \brief Get ACTRL + \return Auxiliary Control Register value + */ +__STATIC_INLINE uint32_t __get_ACTRL(void) +{ + uint32_t result; + __ASM volatile("MRC p15, 0, %0, c1, c0, 1" : "=r"(result)); + return result; +} + +/** \brief Get MPIDR + + This function returns the value of the Multiprocessor Affinity Register. + + \return Multiprocessor Affinity Register value + */ +__STATIC_INLINE uint32_t __get_MPIDR(void) +{ + uint32_t result; + __ASM volatile("MRC p15, 0, %0, c0, c0, 5" : "=r"(result)); + return result; +} + + /** \brief Get VBAR + + This function returns the value of the Vector Base Address Register. + + \return Vector Base Address Register + */ +__STATIC_INLINE uint32_t __get_VBAR(void) +{ + uint32_t result; + __ASM volatile("MRC p15, 0, %0, c12, c0, 0" : "=r"(result)); + return result; +} + +/** \brief Set VBAR + + This function assigns the given value to the Vector Base Address Register. + + \param [in] vbar Vector Base Address Register value to set + */ +__STATIC_INLINE void __set_VBAR(uint32_t vbar) +{ + __ASM volatile("MCR p15, 0, %0, c12, c0, 1" : : "r"(vbar) : "memory"); +} + +/** \brief Set CNTP_TVAL + + This function assigns the given value to PL1 Physical Timer Value Register (CNTP_TVAL). + + \param [in] value CNTP_TVAL Register value to set +*/ +__STATIC_INLINE void __set_CNTP_TVAL(uint32_t value) { + __ASM volatile("MCR p15, 0, %0, c14, c2, 0" : : "r"(value) : "memory"); +} + +/** \brief Get CNTP_TVAL + + This function returns the value of the PL1 Physical Timer Value Register (CNTP_TVAL). + + \return CNTP_TVAL Register value + */ +__STATIC_INLINE uint32_t __get_CNTP_TVAL() { + uint32_t result; + __ASM volatile("MRC p15, 0, %0, c14, c2, 0" : "=r"(result)); + return result; +} + +/** \brief Set CNTP_CTL + + This function assigns the given value to PL1 Physical Timer Control Register (CNTP_CTL). + + \param [in] value CNTP_CTL Register value to set +*/ +__STATIC_INLINE void __set_CNTP_CTL(uint32_t value) { + __ASM volatile("MCR p15, 0, %0, c14, c2, 1" : : "r"(value) : "memory"); +} + +/** \brief Set TLBIALL + + TLB Invalidate All + */ +__STATIC_INLINE void __set_TLBIALL(uint32_t value) { + __ASM volatile("MCR p15, 0, %0, c8, c7, 0" : : "r"(value) : "memory"); +} + +/** \brief Set BPIALL. + + Branch Predictor Invalidate All + */ +__STATIC_INLINE void __set_BPIALL(uint32_t value) { + __ASM volatile("MCR p15, 0, %0, c7, c5, 6" : : "r"(value) : "memory"); +} + +/** \brief Set ICIALLU + + Instruction Cache Invalidate All + */ +__STATIC_INLINE void __set_ICIALLU(uint32_t value) { + __ASM volatile("MCR p15, 0, %0, c7, c5, 0" : : "r"(value) : "memory"); +} + +/** \brief Set DCCMVAC + + Data cache clean + */ +__STATIC_INLINE void __set_DCCMVAC(uint32_t value) { + __ASM volatile("MCR p15, 0, %0, c7, c10, 1" : : "r"(value) : "memory"); +} + +/** \brief Set DCIMVAC + + Data cache invalidate + */ +__STATIC_INLINE void __set_DCIMVAC(uint32_t value) { + __ASM volatile("MCR p15, 0, %0, c7, c6, 1" : : "r"(value) : "memory"); +} + +/** \brief Set DCCIMVAC + + Data cache clean and invalidate + */ +__STATIC_INLINE void __set_DCCIMVAC(uint32_t value) { + __ASM volatile("MCR p15, 0, %0, c7, c14, 1" : : "r"(value) : "memory"); +} + +/** \brief Clean and Invalidate the entire data or unified cache + + Generic mechanism for cleaning/invalidating the entire data or unified cache to the point of coherency + */ +__STATIC_INLINE void __L1C_CleanInvalidateCache(uint32_t op) { + __ASM volatile( + " PUSH {R4-R11} \n" + + " MRC p15, 1, R6, c0, c0, 1 \n" // Read CLIDR + " ANDS R3, R6, #0x07000000 \n" // Extract coherency level + " MOV R3, R3, LSR #23 \n" // Total cache levels << 1 + " BEQ Finished \n" // If 0, no need to clean + + " MOV R10, #0 \n" // R10 holds current cache level << 1 + "Loop1: ADD R2, R10, R10, LSR #1 \n" // R2 holds cache "Set" position + " MOV R1, R6, LSR R2 \n" // Bottom 3 bits are the Cache-type for this level + " AND R1, R1, #7 \n" // Isolate those lower 3 bits + " CMP R1, #2 \n" + " BLT Skip \n" // No cache or only instruction cache at this level + + " MCR p15, 2, R10, c0, c0, 0 \n" // Write the Cache Size selection register + " ISB \n" // ISB to sync the change to the CacheSizeID reg + " MRC p15, 1, R1, c0, c0, 0 \n" // Reads current Cache Size ID register + " AND R2, R1, #7 \n" // Extract the line length field + " ADD R2, R2, #4 \n" // Add 4 for the line length offset (log2 16 bytes) + " LDR R4, =0x3FF \n" + " ANDS R4, R4, R1, LSR #3 \n" // R4 is the max number on the way size (right aligned) + " CLZ R5, R4 \n" // R5 is the bit position of the way size increment + " LDR R7, =0x7FFF \n" + " ANDS R7, R7, R1, LSR #13 \n" // R7 is the max number of the index size (right aligned) + + "Loop2: MOV R9, R4 \n" // R9 working copy of the max way size (right aligned) + + "Loop3: ORR R11, R10, R9, LSL R5 \n" // Factor in the Way number and cache number into R11 + " ORR R11, R11, R7, LSL R2 \n" // Factor in the Set number + " CMP R0, #0 \n" + " BNE Dccsw \n" + " MCR p15, 0, R11, c7, c6, 2 \n" // DCISW. Invalidate by Set/Way + " B cont \n" + "Dccsw: CMP R0, #1 \n" + " BNE Dccisw \n" + " MCR p15, 0, R11, c7, c10, 2 \n" // DCCSW. Clean by Set/Way + " B cont \n" + "Dccisw: MCR p15, 0, R11, c7, c14, 2 \n" // DCCISW. Clean and Invalidate by Set/Way + "cont: SUBS R9, R9, #1 \n" // Decrement the Way number + " BGE Loop3 \n" + " SUBS R7, R7, #1 \n" // Decrement the Set number + " BGE Loop2 \n" + "Skip: ADD R10, R10, #2 \n" // Increment the cache number + " CMP R3, R10 \n" + " BGT Loop1 \n" + + "Finished: \n" + " DSB \n" + " POP {R4-R11} " + ); +} + +/** \brief Enable Floating Point Unit + + Critical section, called from undef handler, so systick is disabled + */ +__STATIC_INLINE void __FPU_Enable(void) { + __ASM volatile( + //Permit access to VFP/NEON, registers by modifying CPACR + " MRC p15,0,R1,c1,c0,2 \n" + " ORR R1,R1,#0x00F00000 \n" + " MCR p15,0,R1,c1,c0,2 \n" + + //Ensure that subsequent instructions occur in the context of VFP/NEON access permitted + " ISB \n" + + //Enable VFP/NEON + " VMRS R1,FPEXC \n" + " ORR R1,R1,#0x40000000 \n" + " VMSR FPEXC,R1 \n" + + //Initialise VFP/NEON registers to 0 + " MOV R2,#0 \n" +#if 0 // TODO: Initialize FPU registers according to available register count + ".if {TARGET_FEATURE_EXTENSION_REGISTER_COUNT} >= 16 \n" + //Initialise D16 registers to 0 + " VMOV D0, R2,R2 \n" + " VMOV D1, R2,R2 \n" + " VMOV D2, R2,R2 \n" + " VMOV D3, R2,R2 \n" + " VMOV D4, R2,R2 \n" + " VMOV D5, R2,R2 \n" + " VMOV D6, R2,R2 \n" + " VMOV D7, R2,R2 \n" + " VMOV D8, R2,R2 \n" + " VMOV D9, R2,R2 \n" + " VMOV D10,R2,R2 \n" + " VMOV D11,R2,R2 \n" + " VMOV D12,R2,R2 \n" + " VMOV D13,R2,R2 \n" + " VMOV D14,R2,R2 \n" + " VMOV D15,R2,R2 \n" + ".endif \n" + + ".if {TARGET_FEATURE_EXTENSION_REGISTER_COUNT} == 32 \n" + //Initialise D32 registers to 0 + " VMOV D16,R2,R2 \n" + " VMOV D17,R2,R2 \n" + " VMOV D18,R2,R2 \n" + " VMOV D19,R2,R2 \n" + " VMOV D20,R2,R2 \n" + " VMOV D21,R2,R2 \n" + " VMOV D22,R2,R2 \n" + " VMOV D23,R2,R2 \n" + " VMOV D24,R2,R2 \n" + " VMOV D25,R2,R2 \n" + " VMOV D26,R2,R2 \n" + " VMOV D27,R2,R2 \n" + " VMOV D28,R2,R2 \n" + " VMOV D29,R2,R2 \n" + " VMOV D30,R2,R2 \n" + " VMOV D31,R2,R2 \n" + ".endif \n" +#endif + //Initialise FPSCR to a known state + " VMRS R2,FPSCR \n" + " LDR R3,=0x00086060 \n" //Mask off all bits that do not have to be preserved. Non-preserved bits can/should be zero. + " AND R2,R2,R3 \n" + " VMSR FPSCR,R2 " + ); +} + +#endif /* __CMSIS_ARMCC_H */ diff --git a/cmsis/TARGET_CORTEX_A/cmsis_compiler.h b/cmsis/TARGET_CORTEX_A/cmsis_compiler.h new file mode 100644 index 00000000000..9fa0e0ea49d --- /dev/null +++ b/cmsis/TARGET_CORTEX_A/cmsis_compiler.h @@ -0,0 +1,211 @@ +/**************************************************************************//** + * @file cmsis_compiler.h + * @brief CMSIS compiler specific macros, functions, instructions + * @version V1.00 + * @date 22. Feb 2017 + ******************************************************************************/ +/* + * Copyright (c) 2009-2017 ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CMSIS_COMPILER_H +#define __CMSIS_COMPILER_H + +#include + +/* + * ARM Compiler 4/5 + */ +#if defined ( __CC_ARM ) + #include "cmsis_armcc.h" + + +/* + * ARM Compiler 6 (armclang) + */ +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #include "cmsis_armclang.h" + + +/* + * GNU Compiler + */ +#elif defined ( __GNUC__ ) + #include "cmsis_gcc.h" + + +/* + * IAR Compiler + */ +#elif defined ( __ICCARM__ ) + + #ifndef __ASM + #define __ASM __asm + #endif + #ifndef __INLINE + #define __INLINE inline + #endif + #ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline + #endif + + #include + + #ifndef __NO_RETURN + #define __NO_RETURN __noreturn + #endif + #ifndef __USED + #define __USED __root + #endif + #ifndef __WEAK + #define __WEAK __weak + #endif + #ifndef __UNALIGNED_UINT32 + __packed struct T_UINT32 { uint32_t v; }; + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) + #endif + #ifndef __ALIGNED + #warning No compiler specific solution for __ALIGNED. __ALIGNED is ignored. + #define __ALIGNED(x) + #endif + #ifndef __PACKED + #define __PACKED __packed + #endif + + +/* + * TI ARM Compiler + */ +#elif defined ( __TI_ARM__ ) + #include + + #ifndef __ASM + #define __ASM __asm + #endif + #ifndef __INLINE + #define __INLINE inline + #endif + #ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline + #endif + #ifndef __NO_RETURN + #define __NO_RETURN __attribute__((noreturn)) + #endif + #ifndef __USED + #define __USED __attribute__((used)) + #endif + #ifndef __WEAK + #define __WEAK __attribute__((weak)) + #endif + #ifndef __UNALIGNED_UINT32 + struct __attribute__((packed)) T_UINT32 { uint32_t v; }; + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) + #endif + #ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) + #endif + #ifndef __PACKED + #define __PACKED __attribute__((packed)) + #endif + + +/* + * TASKING Compiler + */ +#elif defined ( __TASKING__ ) + /* + * The CMSIS functions have been implemented as intrinsics in the compiler. + * Please use "carm -?i" to get an up to date list of all intrinsics, + * Including the CMSIS ones. + */ + + #ifndef __ASM + #define __ASM __asm + #endif + #ifndef __INLINE + #define __INLINE inline + #endif + #ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline + #endif + #ifndef __NO_RETURN + #define __NO_RETURN __attribute__((noreturn)) + #endif + #ifndef __USED + #define __USED __attribute__((used)) + #endif + #ifndef __WEAK + #define __WEAK __attribute__((weak)) + #endif + #ifndef __UNALIGNED_UINT32 + struct __packed__ T_UINT32 { uint32_t v; }; + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) + #endif + #ifndef __ALIGNED + #define __ALIGNED(x) __align(x) + #endif + #ifndef __PACKED + #define __PACKED __packed__ + #endif + + +/* + * COSMIC Compiler + */ +#elif defined ( __CSMC__ ) + #include + + #ifndef __ASM + #define __ASM _asm + #endif + #ifndef __INLINE + #define __INLINE inline + #endif + #ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline + #endif + #ifndef __NO_RETURN + // NO RETURN is automatically detected hence no warning here + #define __NO_RETURN + #endif + #ifndef __USED + #warning No compiler specific solution for __USED. __USED is ignored. + #define __USED + #endif + #ifndef __WEAK + #define __WEAK __weak + #endif + #ifndef __UNALIGNED_UINT32 + @packed struct T_UINT32 { uint32_t v; }; + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) + #endif + #ifndef __ALIGNED + #warning No compiler specific solution for __ALIGNED. __ALIGNED is ignored. + #define __ALIGNED(x) + #endif + #ifndef __PACKED + #define __PACKED @packed + #endif + + +#else + #error Unknown compiler. +#endif + + +#endif /* __CMSIS_COMPILER_H */ + diff --git a/cmsis/TARGET_CORTEX_M/TOOLCHAIN_ARM/cmsis_armcc.h b/cmsis/TARGET_CORTEX_M/TOOLCHAIN_ARM/cmsis_armcc.h new file mode 100644 index 00000000000..7b2a2847e0e --- /dev/null +++ b/cmsis/TARGET_CORTEX_M/TOOLCHAIN_ARM/cmsis_armcc.h @@ -0,0 +1,809 @@ +/**************************************************************************//** + * @file cmsis_armcc.h + * @brief CMSIS compiler ARMCC (ARM compiler V5) header file + * @version V5.0.2 + * @date 13. February 2017 + ******************************************************************************/ +/* + * Copyright (c) 2009-2017 ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CMSIS_ARMCC_H +#define __CMSIS_ARMCC_H + + +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 400677) + #error "Please use ARM Compiler Toolchain V4.0.677 or later!" +#endif + +/* CMSIS compiler control architecture macros */ +#if ((defined (__TARGET_ARCH_6_M ) && (__TARGET_ARCH_6_M == 1)) || \ + (defined (__TARGET_ARCH_6S_M ) && (__TARGET_ARCH_6S_M == 1)) ) + #define __ARM_ARCH_6M__ 1 +#endif + +#if (defined (__TARGET_ARCH_7_M ) && (__TARGET_ARCH_7_M == 1)) + #define __ARM_ARCH_7M__ 1 +#endif + +#if (defined (__TARGET_ARCH_7E_M) && (__TARGET_ARCH_7E_M == 1)) + #define __ARM_ARCH_7EM__ 1 +#endif + + /* __ARM_ARCH_8M_BASE__ not applicable */ + /* __ARM_ARCH_8M_MAIN__ not applicable */ + + +/* CMSIS compiler specific defines */ +#ifndef __ASM + #define __ASM __asm +#endif +#ifndef __INLINE + #define __INLINE __inline +#endif +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static __inline +#endif +#ifndef __NO_RETURN + #define __NO_RETURN __declspec(noreturn) +#endif +#ifndef __USED + #define __USED __attribute__((used)) +#endif +#ifndef __WEAK + #define __WEAK __attribute__((weak)) +#endif +#ifndef __PACKED + #define __PACKED __attribute__((packed)) +#endif +#ifndef __PACKED_STRUCT + #define __PACKED_STRUCT __packed struct +#endif +#ifndef __UNALIGNED_UINT32 /* deprecated */ + #define __UNALIGNED_UINT32(x) (*((__packed uint32_t *)(x))) +#endif +#ifndef __UNALIGNED_UINT16_WRITE + #define __UNALIGNED_UINT16_WRITE(addr, val) ((*((__packed uint16_t *)(addr))) = (val)) +#endif +#ifndef __UNALIGNED_UINT16_READ + #define __UNALIGNED_UINT16_READ(addr) (*((const __packed uint16_t *)(addr))) +#endif +#ifndef __UNALIGNED_UINT32_WRITE + #define __UNALIGNED_UINT32_WRITE(addr, val) ((*((__packed uint32_t *)(addr))) = (val)) +#endif +#ifndef __UNALIGNED_UINT32_READ + #define __UNALIGNED_UINT32_READ(addr) (*((const __packed uint32_t *)(addr))) +#endif +#ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) +#endif + + +/* ########################### Core Function Access ########################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions + @{ + */ + +/** + \brief Enable IRQ Interrupts + \details Enables IRQ interrupts by clearing the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +/* intrinsic void __enable_irq(); */ + + +/** + \brief Disable IRQ Interrupts + \details Disables IRQ interrupts by setting the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +/* intrinsic void __disable_irq(); */ + +/** + \brief Get Control Register + \details Returns the content of the Control Register. + \return Control Register value + */ +__STATIC_INLINE uint32_t __get_CONTROL(void) +{ + register uint32_t __regControl __ASM("control"); + return(__regControl); +} + + +/** + \brief Set Control Register + \details Writes the given value to the Control Register. + \param [in] control Control Register value to set + */ +__STATIC_INLINE void __set_CONTROL(uint32_t control) +{ + register uint32_t __regControl __ASM("control"); + __regControl = control; +} + + +/** + \brief Get IPSR Register + \details Returns the content of the IPSR Register. + \return IPSR Register value + */ +__STATIC_INLINE uint32_t __get_IPSR(void) +{ + register uint32_t __regIPSR __ASM("ipsr"); + return(__regIPSR); +} + + +/** + \brief Get APSR Register + \details Returns the content of the APSR Register. + \return APSR Register value + */ +__STATIC_INLINE uint32_t __get_APSR(void) +{ + register uint32_t __regAPSR __ASM("apsr"); + return(__regAPSR); +} + + +/** + \brief Get xPSR Register + \details Returns the content of the xPSR Register. + \return xPSR Register value + */ +__STATIC_INLINE uint32_t __get_xPSR(void) +{ + register uint32_t __regXPSR __ASM("xpsr"); + return(__regXPSR); +} + + +/** + \brief Get Process Stack Pointer + \details Returns the current value of the Process Stack Pointer (PSP). + \return PSP Register value + */ +__STATIC_INLINE uint32_t __get_PSP(void) +{ + register uint32_t __regProcessStackPointer __ASM("psp"); + return(__regProcessStackPointer); +} + + +/** + \brief Set Process Stack Pointer + \details Assigns the given value to the Process Stack Pointer (PSP). + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_INLINE void __set_PSP(uint32_t topOfProcStack) +{ + register uint32_t __regProcessStackPointer __ASM("psp"); + __regProcessStackPointer = topOfProcStack; +} + + +/** + \brief Get Main Stack Pointer + \details Returns the current value of the Main Stack Pointer (MSP). + \return MSP Register value + */ +__STATIC_INLINE uint32_t __get_MSP(void) +{ + register uint32_t __regMainStackPointer __ASM("msp"); + return(__regMainStackPointer); +} + + +/** + \brief Set Main Stack Pointer + \details Assigns the given value to the Main Stack Pointer (MSP). + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_INLINE void __set_MSP(uint32_t topOfMainStack) +{ + register uint32_t __regMainStackPointer __ASM("msp"); + __regMainStackPointer = topOfMainStack; +} + + +/** + \brief Get Priority Mask + \details Returns the current state of the priority mask bit from the Priority Mask Register. + \return Priority Mask value + */ +__STATIC_INLINE uint32_t __get_PRIMASK(void) +{ + register uint32_t __regPriMask __ASM("primask"); + return(__regPriMask); +} + + +/** + \brief Set Priority Mask + \details Assigns the given value to the Priority Mask Register. + \param [in] priMask Priority Mask + */ +__STATIC_INLINE void __set_PRIMASK(uint32_t priMask) +{ + register uint32_t __regPriMask __ASM("primask"); + __regPriMask = (priMask); +} + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) + +/** + \brief Enable FIQ + \details Enables FIQ interrupts by clearing the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +#define __enable_fault_irq __enable_fiq + + +/** + \brief Disable FIQ + \details Disables FIQ interrupts by setting the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +#define __disable_fault_irq __disable_fiq + + +/** + \brief Get Base Priority + \details Returns the current value of the Base Priority register. + \return Base Priority register value + */ +__STATIC_INLINE uint32_t __get_BASEPRI(void) +{ + register uint32_t __regBasePri __ASM("basepri"); + return(__regBasePri); +} + + +/** + \brief Set Base Priority + \details Assigns the given value to the Base Priority register. + \param [in] basePri Base Priority value to set + */ +__STATIC_INLINE void __set_BASEPRI(uint32_t basePri) +{ + register uint32_t __regBasePri __ASM("basepri"); + __regBasePri = (basePri & 0xFFU); +} + + +/** + \brief Set Base Priority with condition + \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled, + or the new value increases the BASEPRI priority level. + \param [in] basePri Base Priority value to set + */ +__STATIC_INLINE void __set_BASEPRI_MAX(uint32_t basePri) +{ + register uint32_t __regBasePriMax __ASM("basepri_max"); + __regBasePriMax = (basePri & 0xFFU); +} + + +/** + \brief Get Fault Mask + \details Returns the current value of the Fault Mask register. + \return Fault Mask register value + */ +__STATIC_INLINE uint32_t __get_FAULTMASK(void) +{ + register uint32_t __regFaultMask __ASM("faultmask"); + return(__regFaultMask); +} + + +/** + \brief Set Fault Mask + \details Assigns the given value to the Fault Mask register. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask) +{ + register uint32_t __regFaultMask __ASM("faultmask"); + __regFaultMask = (faultMask & (uint32_t)1U); +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) + +/** + \brief Get FPSCR + \details Returns the current value of the Floating Point Status/Control register. + \return Floating Point Status/Control register value + */ +__STATIC_INLINE uint32_t __get_FPSCR(void) +{ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) + register uint32_t __regfpscr __ASM("fpscr"); + return(__regfpscr); +#else + return(0U); +#endif +} + + +/** + \brief Set FPSCR + \details Assigns the given value to the Floating Point Status/Control register. + \param [in] fpscr Floating Point Status/Control value to set + */ +__STATIC_INLINE void __set_FPSCR(uint32_t fpscr) +{ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) + register uint32_t __regfpscr __ASM("fpscr"); + __regfpscr = (fpscr); +#else + (void)fpscr; +#endif +} + +#endif /* ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */ + + + +/*@} end of CMSIS_Core_RegAccFunctions */ + + +/* ########################## Core Instruction Access ######################### */ +/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface + Access to dedicated instructions + @{ +*/ + +/** + \brief No Operation + \details No Operation does nothing. This instruction can be used for code alignment purposes. + */ +#define __NOP __nop + + +/** + \brief Wait For Interrupt + \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs. + */ +#define __WFI __wfi + + +/** + \brief Wait For Event + \details Wait For Event is a hint instruction that permits the processor to enter + a low-power state until one of a number of events occurs. + */ +#define __WFE __wfe + + +/** + \brief Send Event + \details Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +#define __SEV __sev + + +/** + \brief Instruction Synchronization Barrier + \details Instruction Synchronization Barrier flushes the pipeline in the processor, + so that all instructions following the ISB are fetched from cache or memory, + after the instruction has been completed. + */ +#define __ISB() do {\ + __schedule_barrier();\ + __isb(0xF);\ + __schedule_barrier();\ + } while (0U) + +/** + \brief Data Synchronization Barrier + \details Acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +#define __DSB() do {\ + __schedule_barrier();\ + __dsb(0xF);\ + __schedule_barrier();\ + } while (0U) + +/** + \brief Data Memory Barrier + \details Ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +#define __DMB() do {\ + __schedule_barrier();\ + __dmb(0xF);\ + __schedule_barrier();\ + } while (0U) + +/** + \brief Reverse byte order (32 bit) + \details Reverses the byte order in integer value. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REV __rev + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order in two unsigned short values. + \param [in] value Value to reverse + \return Reversed value + */ +#ifndef __NO_EMBEDDED_ASM +__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value) +{ + rev16 r0, r0 + bx lr +} +#endif + + +/** + \brief Reverse byte order in signed short value + \details Reverses the byte order in a signed short value with sign extension to integer. + \param [in] value Value to reverse + \return Reversed value + */ +#ifndef __NO_EMBEDDED_ASM +__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int32_t __REVSH(int32_t value) +{ + revsh r0, r0 + bx lr +} +#endif + + +/** + \brief Rotate Right in unsigned value (32 bit) + \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. + \param [in] op1 Value to rotate + \param [in] op2 Number of Bits to rotate + \return Rotated value + */ +#define __ROR __ror + + +/** + \brief Breakpoint + \details Causes the processor to enter Debug state. + Debug tools can use this to investigate system state when the instruction at a particular address is reached. + \param [in] value is ignored by the processor. + If required, a debugger can use it to store additional information about the breakpoint. + */ +#define __BKPT(value) __breakpoint(value) + + +/** + \brief Reverse bit order of value + \details Reverses the bit order of the given value. + \param [in] value Value to reverse + \return Reversed value + */ +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) + #define __RBIT __rbit +#else +__attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value) +{ + uint32_t result; + int32_t s = (4 /*sizeof(v)*/ * 8) - 1; /* extra shift needed at end */ + + result = value; /* r will be reversed bits of v; first get LSB of v */ + for (value >>= 1U; value; value >>= 1U) + { + result <<= 1U; + result |= value & 1U; + s--; + } + result <<= s; /* shift when v's highest bits are zero */ + return(result); +} +#endif + + +/** + \brief Count leading zeros + \details Counts the number of leading zeros of a data value. + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +#define __CLZ __clz + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) + +/** + \brief LDR Exclusive (8 bit) + \details Executes a exclusive LDR instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr)) +#else + #define __LDREXB(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint8_t ) __ldrex(ptr)) _Pragma("pop") +#endif + + +/** + \brief LDR Exclusive (16 bit) + \details Executes a exclusive LDR instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __LDREXH(ptr) ((uint16_t) __ldrex(ptr)) +#else + #define __LDREXH(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint16_t) __ldrex(ptr)) _Pragma("pop") +#endif + + +/** + \brief LDR Exclusive (32 bit) + \details Executes a exclusive LDR instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr)) +#else + #define __LDREXW(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint32_t ) __ldrex(ptr)) _Pragma("pop") +#endif + + +/** + \brief STR Exclusive (8 bit) + \details Executes a exclusive STR instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __STREXB(value, ptr) __strex(value, ptr) +#else + #define __STREXB(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop") +#endif + + +/** + \brief STR Exclusive (16 bit) + \details Executes a exclusive STR instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __STREXH(value, ptr) __strex(value, ptr) +#else + #define __STREXH(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop") +#endif + + +/** + \brief STR Exclusive (32 bit) + \details Executes a exclusive STR instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __STREXW(value, ptr) __strex(value, ptr) +#else + #define __STREXW(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop") +#endif + + +/** + \brief Remove the exclusive lock + \details Removes the exclusive lock which is created by LDREX. + */ +#define __CLREX __clrex + + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +#define __SSAT __ssat + + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +#define __USAT __usat + + +/** + \brief Rotate Right with Extend (32 bit) + \details Moves each bit of a bitstring right by one bit. + The carry input is shifted in at the left end of the bitstring. + \param [in] value Value to rotate + \return Rotated value + */ +#ifndef __NO_EMBEDDED_ASM +__attribute__((section(".rrx_text"))) __STATIC_INLINE __ASM uint32_t __RRX(uint32_t value) +{ + rrx r0, r0 + bx lr +} +#endif + + +/** + \brief LDRT Unprivileged (8 bit) + \details Executes a Unprivileged LDRT instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#define __LDRBT(ptr) ((uint8_t ) __ldrt(ptr)) + + +/** + \brief LDRT Unprivileged (16 bit) + \details Executes a Unprivileged LDRT instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#define __LDRHT(ptr) ((uint16_t) __ldrt(ptr)) + + +/** + \brief LDRT Unprivileged (32 bit) + \details Executes a Unprivileged LDRT instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#define __LDRT(ptr) ((uint32_t ) __ldrt(ptr)) + + +/** + \brief STRT Unprivileged (8 bit) + \details Executes a Unprivileged STRT instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +#define __STRBT(value, ptr) __strt(value, ptr) + + +/** + \brief STRT Unprivileged (16 bit) + \details Executes a Unprivileged STRT instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +#define __STRHT(value, ptr) __strt(value, ptr) + + +/** + \brief STRT Unprivileged (32 bit) + \details Executes a Unprivileged STRT instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +#define __STRT(value, ptr) __strt(value, ptr) + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */ + +/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ + + +/* ################### Compiler specific Intrinsics ########################### */ +/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics + Access to dedicated SIMD instructions + @{ +*/ + +#if ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) + +#define __SADD8 __sadd8 +#define __QADD8 __qadd8 +#define __SHADD8 __shadd8 +#define __UADD8 __uadd8 +#define __UQADD8 __uqadd8 +#define __UHADD8 __uhadd8 +#define __SSUB8 __ssub8 +#define __QSUB8 __qsub8 +#define __SHSUB8 __shsub8 +#define __USUB8 __usub8 +#define __UQSUB8 __uqsub8 +#define __UHSUB8 __uhsub8 +#define __SADD16 __sadd16 +#define __QADD16 __qadd16 +#define __SHADD16 __shadd16 +#define __UADD16 __uadd16 +#define __UQADD16 __uqadd16 +#define __UHADD16 __uhadd16 +#define __SSUB16 __ssub16 +#define __QSUB16 __qsub16 +#define __SHSUB16 __shsub16 +#define __USUB16 __usub16 +#define __UQSUB16 __uqsub16 +#define __UHSUB16 __uhsub16 +#define __SASX __sasx +#define __QASX __qasx +#define __SHASX __shasx +#define __UASX __uasx +#define __UQASX __uqasx +#define __UHASX __uhasx +#define __SSAX __ssax +#define __QSAX __qsax +#define __SHSAX __shsax +#define __USAX __usax +#define __UQSAX __uqsax +#define __UHSAX __uhsax +#define __USAD8 __usad8 +#define __USADA8 __usada8 +#define __SSAT16 __ssat16 +#define __USAT16 __usat16 +#define __UXTB16 __uxtb16 +#define __UXTAB16 __uxtab16 +#define __SXTB16 __sxtb16 +#define __SXTAB16 __sxtab16 +#define __SMUAD __smuad +#define __SMUADX __smuadx +#define __SMLAD __smlad +#define __SMLADX __smladx +#define __SMLALD __smlald +#define __SMLALDX __smlaldx +#define __SMUSD __smusd +#define __SMUSDX __smusdx +#define __SMLSD __smlsd +#define __SMLSDX __smlsdx +#define __SMLSLD __smlsld +#define __SMLSLDX __smlsldx +#define __SEL __sel +#define __QADD __qadd +#define __QSUB __qsub + +#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \ + ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) ) + +#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \ + ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) ) + +#define __SMMLA(ARG1,ARG2,ARG3) ( (int32_t)((((int64_t)(ARG1) * (ARG2)) + \ + ((int64_t)(ARG3) << 32U) ) >> 32U)) + +#endif /* ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */ +/*@} end of group CMSIS_SIMD_intrinsics */ + + +#endif /* __CMSIS_ARMCC_H */ diff --git a/cmsis/TARGET_CORTEX_M/TOOLCHAIN_ARM/cmsis_armclang.h b/cmsis/TARGET_CORTEX_M/TOOLCHAIN_ARM/cmsis_armclang.h new file mode 100644 index 00000000000..7c22d84096b --- /dev/null +++ b/cmsis/TARGET_CORTEX_M/TOOLCHAIN_ARM/cmsis_armclang.h @@ -0,0 +1,1795 @@ +/**************************************************************************//** + * @file cmsis_armclang.h + * @brief CMSIS compiler ARMCLANG (ARM compiler V6) header file + * @version V5.0.3 + * @date 27. March 2017 + ******************************************************************************/ +/* + * Copyright (c) 2009-2017 ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +//lint -esym(9058, IRQn) disable MISRA 2012 Rule 2.4 for IRQn + +#ifndef __CMSIS_ARMCLANG_H +#define __CMSIS_ARMCLANG_H + +#ifndef __ARM_COMPAT_H +#include /* Compatibility header for ARM Compiler 5 intrinsics */ +#endif + +/* CMSIS compiler specific defines */ +#ifndef __ASM + #define __ASM __asm +#endif +#ifndef __INLINE + #define __INLINE __inline +#endif +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static __inline +#endif +#ifndef __NO_RETURN + #define __NO_RETURN __attribute__((noreturn)) +#endif +#ifndef __USED + #define __USED __attribute__((used)) +#endif +#ifndef __WEAK + #define __WEAK __attribute__((weak)) +#endif +#ifndef __PACKED + #define __PACKED __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) +#endif +#ifndef __UNALIGNED_UINT32 /* deprecated */ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +//lint -esym(9058, T_UINT32) disable MISRA 2012 Rule 2.4 for T_UINT32 + struct __attribute__((packed)) T_UINT32 { uint32_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) +#endif +#ifndef __UNALIGNED_UINT16_WRITE + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +//lint -esym(9058, T_UINT16_WRITE) disable MISRA 2012 Rule 2.4 for T_UINT16_WRITE + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT16_READ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +//lint -esym(9058, T_UINT16_READ) disable MISRA 2012 Rule 2.4 for T_UINT16_READ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) +#endif +#ifndef __UNALIGNED_UINT32_WRITE + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +//lint -esym(9058, T_UINT32_WRITE) disable MISRA 2012 Rule 2.4 for T_UINT32_WRITE + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT32_READ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) +#endif +#ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) +#endif + + +/* ########################### Core Function Access ########################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions + @{ + */ + +/** + \brief Enable IRQ Interrupts + \details Enables IRQ interrupts by clearing the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +/* intrinsic void __enable_irq(); see arm_compat.h */ + + +/** + \brief Disable IRQ Interrupts + \details Disables IRQ interrupts by setting the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +/* intrinsic void __disable_irq(); see arm_compat.h */ + + +/** + \brief Get Control Register + \details 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); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Control Register (non-secure) + \details Returns the content of the non-secure Control Register when in secure mode. + \return non-secure Control Register value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_CONTROL_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Control Register + \details Writes the given value to the Control Register. + \param [in] control Control Register value to set + */ +__attribute__((always_inline)) __STATIC_INLINE void __set_CONTROL(uint32_t control) +{ + __ASM volatile ("MSR control, %0" : : "r" (control) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Control Register (non-secure) + \details Writes the given value to the non-secure Control Register when in secure state. + \param [in] control Control Register value to set + */ +__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_CONTROL_NS(uint32_t control) +{ + __ASM volatile ("MSR control_ns, %0" : : "r" (control) : "memory"); +} +#endif + + +/** + \brief Get IPSR Register + \details Returns the content of the IPSR Register. + \return IPSR Register value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_IPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, ipsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get APSR Register + \details 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 + \details 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 + \details 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" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Process Stack Pointer (non-secure) + \details Returns the current value of the non-secure Process Stack Pointer (PSP) when in secure state. + \return PSP Register value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_PSP_NS(void) +{ + register uint32_t result; + + __ASM volatile ("MRS %0, psp_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Process Stack Pointer + \details Assigns the given value to the Process Stack Pointer (PSP). + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__attribute__((always_inline)) __STATIC_INLINE void __set_PSP(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp, %0" : : "r" (topOfProcStack) : ); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Process Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Process Stack Pointer (PSP) when in secure state. + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_PSP_NS(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp_ns, %0" : : "r" (topOfProcStack) : ); +} +#endif + + +/** + \brief Get Main Stack Pointer + \details 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" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Main Stack Pointer (non-secure) + \details Returns the current value of the non-secure Main Stack Pointer (MSP) when in secure state. + \return MSP Register value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_MSP_NS(void) +{ + register uint32_t result; + + __ASM volatile ("MRS %0, msp_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Main Stack Pointer + \details Assigns the given value to the Main Stack Pointer (MSP). + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__attribute__((always_inline)) __STATIC_INLINE void __set_MSP(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp, %0" : : "r" (topOfMainStack) : ); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Main Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Main Stack Pointer (MSP) when in secure state. + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_MSP_NS(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp_ns, %0" : : "r" (topOfMainStack) : ); +} +#endif + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Stack Pointer (non-secure) + \details Returns the current value of the non-secure Stack Pointer (SP) when in secure state. + \return SP Register value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_SP_NS(void) +{ + register uint32_t result; + + __ASM volatile ("MRS %0, sp_ns" : "=r" (result) ); + return(result); +} + + +/** + \brief Set Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Stack Pointer (SP) when in secure state. + \param [in] topOfStack Stack Pointer value to set + */ +__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_SP_NS(uint32_t topOfStack) +{ + __ASM volatile ("MSR sp_ns, %0" : : "r" (topOfStack) : ); +} +#endif + + +/** + \brief Get Priority Mask + \details 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); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Priority Mask (non-secure) + \details Returns the current state of the non-secure priority mask bit from the Priority Mask Register when in secure state. + \return Priority Mask value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_PRIMASK_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Priority Mask + \details Assigns the given value to the Priority Mask Register. + \param [in] priMask Priority Mask + */ +__attribute__((always_inline)) __STATIC_INLINE void __set_PRIMASK(uint32_t priMask) +{ + __ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Priority Mask (non-secure) + \details Assigns the given value to the non-secure Priority Mask Register when in secure state. + \param [in] priMask Priority Mask + */ +__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_PRIMASK_NS(uint32_t priMask) +{ + __ASM volatile ("MSR primask_ns, %0" : : "r" (priMask) : "memory"); +} +#endif + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) +/** + \brief Enable FIQ + \details Enables FIQ interrupts by clearing the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +#define __enable_fault_irq __enable_fiq /* see arm_compat.h */ + + +/** + \brief Disable FIQ + \details Disables FIQ interrupts by setting the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +#define __disable_fault_irq __disable_fiq /* see arm_compat.h */ + + +/** + \brief Get Base Priority + \details 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" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Base Priority (non-secure) + \details Returns the current value of the non-secure Base Priority register when in secure state. + \return Base Priority register value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_BASEPRI_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Base Priority + \details 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 basePri) +{ + __ASM volatile ("MSR basepri, %0" : : "r" (basePri) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Base Priority (non-secure) + \details Assigns the given value to the non-secure Base Priority register when in secure state. + \param [in] basePri Base Priority value to set + */ +__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_BASEPRI_NS(uint32_t basePri) +{ + __ASM volatile ("MSR basepri_ns, %0" : : "r" (basePri) : "memory"); +} +#endif + + +/** + \brief Set Base Priority with condition + \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled, + or the new value increases the BASEPRI priority level. + \param [in] basePri Base Priority value to set + */ +__attribute__((always_inline)) __STATIC_INLINE void __set_BASEPRI_MAX(uint32_t basePri) +{ + __ASM volatile ("MSR basepri_max, %0" : : "r" (basePri) : "memory"); +} + + +/** + \brief Get Fault Mask + \details 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); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Fault Mask (non-secure) + \details Returns the current value of the non-secure Fault Mask register when in secure state. + \return Fault Mask register value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_FAULTMASK_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Fault Mask + \details Assigns the given value to the Fault Mask register. + \param [in] faultMask Fault Mask value to set + */ +__attribute__((always_inline)) __STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Fault Mask (non-secure) + \details Assigns the given value to the non-secure Fault Mask register when in secure state. + \param [in] faultMask Fault Mask value to set + */ +__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_FAULTMASK_NS(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask_ns, %0" : : "r" (faultMask) : "memory"); +} +#endif + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) + +/** + \brief Get Process Stack Pointer Limit + \details Returns the current value of the Process Stack Pointer Limit (PSPLIM). + \return PSPLIM Register value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_PSPLIM(void) +{ + register uint32_t result; + + __ASM volatile ("MRS %0, psplim" : "=r" (result) ); + return(result); +} + + +#if ((defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) && \ + (defined (__ARM_ARCH_8M_MAIN__) && (__ARM_ARCH_8M_MAIN__ == 1)) ) +/** + \brief Get Process Stack Pointer Limit (non-secure) + \details Returns the current value of the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \return PSPLIM Register value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_PSPLIM_NS(void) +{ + register uint32_t result; + + __ASM volatile ("MRS %0, psplim_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Process Stack Pointer Limit + \details Assigns the given value to the Process Stack Pointer Limit (PSPLIM). + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__attribute__((always_inline)) __STATIC_INLINE void __set_PSPLIM(uint32_t ProcStackPtrLimit) +{ + __ASM volatile ("MSR psplim, %0" : : "r" (ProcStackPtrLimit)); +} + + +#if ((defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) && \ + (defined (__ARM_ARCH_8M_MAIN__) && (__ARM_ARCH_8M_MAIN__ == 1)) ) +/** + \brief Set Process Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_PSPLIM_NS(uint32_t ProcStackPtrLimit) +{ + __ASM volatile ("MSR psplim_ns, %0\n" : : "r" (ProcStackPtrLimit)); +} +#endif + + +/** + \brief Get Main Stack Pointer Limit + \details Returns the current value of the Main Stack Pointer Limit (MSPLIM). + \return MSPLIM Register value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_MSPLIM(void) +{ + register uint32_t result; + + __ASM volatile ("MRS %0, msplim" : "=r" (result) ); + + return(result); +} + + +#if ((defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) && \ + (defined (__ARM_ARCH_8M_MAIN__) && (__ARM_ARCH_8M_MAIN__ == 1)) ) +/** + \brief Get Main Stack Pointer Limit (non-secure) + \details Returns the current value of the non-secure Main Stack Pointer Limit(MSPLIM) when in secure state. + \return MSPLIM Register value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_MSPLIM_NS(void) +{ + register uint32_t result; + + __ASM volatile ("MRS %0, msplim_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Main Stack Pointer Limit + \details Assigns the given value to the Main Stack Pointer Limit (MSPLIM). + \param [in] MainStackPtrLimit Main Stack Pointer Limit value to set + */ +__attribute__((always_inline)) __STATIC_INLINE void __set_MSPLIM(uint32_t MainStackPtrLimit) +{ + __ASM volatile ("MSR msplim, %0" : : "r" (MainStackPtrLimit)); +} + + +#if ((defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) && \ + (defined (__ARM_ARCH_8M_MAIN__) && (__ARM_ARCH_8M_MAIN__ == 1)) ) +/** + \brief Set Main Stack Pointer Limit (non-secure) + \details Assigns the given value to the non-secure Main Stack Pointer Limit (MSPLIM) when in secure state. + \param [in] MainStackPtrLimit Main Stack Pointer value to set + */ +__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_MSPLIM_NS(uint32_t MainStackPtrLimit) +{ + __ASM volatile ("MSR msplim_ns, %0" : : "r" (MainStackPtrLimit)); +} +#endif + +#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) + +/** + \brief Get FPSCR + \details Returns the current value of the Floating Point Status/Control register. + \return Floating Point Status/Control register value + */ +/* #define __get_FPSCR __builtin_arm_get_fpscr */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_FPSCR(void) +{ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) + uint32_t result; + + __ASM volatile ("VMRS %0, fpscr" : "=r" (result) ); + return(result); +#else + return(0U); +#endif +} + + +/** + \brief Set FPSCR + \details Assigns the given value to the Floating Point Status/Control register. + \param [in] fpscr Floating Point Status/Control value to set + */ +/* #define __set_FPSCR __builtin_arm_set_fpscr */ +__attribute__((always_inline)) __STATIC_INLINE void __set_FPSCR(uint32_t fpscr) +{ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) + __ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) : "memory"); +#else + (void)fpscr; +#endif +} + +#endif /* ((defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + + + +/*@} end of CMSIS_Core_RegAccFunctions */ + + +/* ########################## Core Instruction Access ######################### */ +/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface + Access to dedicated instructions + @{ +*/ + +/* Define macros for porting to both thumb1 and thumb2. + * For thumb1, use low register (r0-r7), specified by constraint "l" + * Otherwise, use general registers, specified by constraint "r" */ +#if defined (__thumb__) && !defined (__thumb2__) +#define __CMSIS_GCC_OUT_REG(r) "=l" (r) +#define __CMSIS_GCC_USE_REG(r) "l" (r) +#else +#define __CMSIS_GCC_OUT_REG(r) "=r" (r) +#define __CMSIS_GCC_USE_REG(r) "r" (r) +#endif + +/** + \brief No Operation + \details No Operation does nothing. This instruction can be used for code alignment purposes. + */ +#define __NOP __builtin_arm_nop + +/** + \brief Wait For Interrupt + \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs. + */ +#define __WFI __builtin_arm_wfi + + +/** + \brief Wait For Event + \details Wait For Event is a hint instruction that permits the processor to enter + a low-power state until one of a number of events occurs. + */ +#define __WFE __builtin_arm_wfe + + +/** + \brief Send Event + \details Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +#define __SEV __builtin_arm_sev + + +/** + \brief Instruction Synchronization Barrier + \details Instruction Synchronization Barrier flushes the pipeline in the processor, + so that all instructions following the ISB are fetched from cache or memory, + after the instruction has been completed. + */ +#define __ISB() __builtin_arm_isb(0xF); + +/** + \brief Data Synchronization Barrier + \details Acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +#define __DSB() __builtin_arm_dsb(0xF); + + +/** + \brief Data Memory Barrier + \details Ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +#define __DMB() __builtin_arm_dmb(0xF); + + +/** + \brief Reverse byte order (32 bit) + \details Reverses the byte order in integer value. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REV __builtin_bswap32 + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order in two unsigned short values. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REV16 __builtin_bswap16 /* ToDo ARMCLANG: check if __builtin_bswap16 could be used */ +#if 0 +__attribute__((always_inline)) __STATIC_INLINE uint32_t __REV16(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rev16 %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return(result); +} +#endif + + +/** + \brief Reverse byte order in signed short value + \details Reverses the byte order in a signed short value with sign extension to integer. + \param [in] value Value to reverse + \return Reversed value + */ + /* ToDo ARMCLANG: check if __builtin_bswap16 could be used */ +__attribute__((always_inline)) __STATIC_INLINE int32_t __REVSH(int32_t value) +{ + int32_t result; + + __ASM volatile ("revsh %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return(result); +} + + +/** + \brief Rotate Right in unsigned value (32 bit) + \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. + \param [in] op1 Value to rotate + \param [in] op2 Number of Bits to rotate + \return Rotated value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __ROR(uint32_t op1, uint32_t op2) +{ + return (op1 >> op2) | (op1 << (32U - op2)); +} + + +/** + \brief Breakpoint + \details Causes the processor to enter Debug state. + Debug tools can use this to investigate system state when the instruction at a particular address is reached. + \param [in] value is ignored by the processor. + If required, a debugger can use it to store additional information about the breakpoint. + */ +#define __BKPT(value) __ASM volatile ("bkpt "#value) + + +/** + \brief Reverse bit order of value + \details Reverses the bit order of the given value. + \param [in] value Value to reverse + \return Reversed value + */ + /* ToDo ARMCLANG: check if __builtin_arm_rbit is supported */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value) +{ + uint32_t result; + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) + __ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) ); +#else + int32_t s = (4 /*sizeof(v)*/ * 8) - 1; /* extra shift needed at end */ + + result = value; /* r will be reversed bits of v; first get LSB of v */ + for (value >>= 1U; value; value >>= 1U) + { + result <<= 1U; + result |= value & 1U; + s--; + } + result <<= s; /* shift when v's highest bits are zero */ +#endif + return(result); +} + + +/** + \brief Count leading zeros + \details Counts the number of leading zeros of a data value. + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +#define __CLZ __builtin_clz + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) +/** + \brief LDR Exclusive (8 bit) + \details Executes a exclusive LDR instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#define __LDREXB (uint8_t)__builtin_arm_ldrex + + +/** + \brief LDR Exclusive (16 bit) + \details Executes a exclusive LDR instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#define __LDREXH (uint16_t)__builtin_arm_ldrex + + +/** + \brief LDR Exclusive (32 bit) + \details Executes a exclusive LDR instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#define __LDREXW (uint32_t)__builtin_arm_ldrex + + +/** + \brief STR Exclusive (8 bit) + \details Executes a exclusive STR instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXB (uint32_t)__builtin_arm_strex + + +/** + \brief STR Exclusive (16 bit) + \details Executes a exclusive STR instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXH (uint32_t)__builtin_arm_strex + + +/** + \brief STR Exclusive (32 bit) + \details Executes a exclusive STR instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXW (uint32_t)__builtin_arm_strex + + +/** + \brief Remove the exclusive lock + \details Removes the exclusive lock which is created by LDREX. + */ +#define __CLREX __builtin_arm_clrex + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +#define __SSAT __builtin_arm_ssat + + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +#define __USAT __builtin_arm_usat + + +/** + \brief Rotate Right with Extend (32 bit) + \details Moves each bit of a bitstring right by one bit. + The carry input is shifted in at the left end of the bitstring. + \param [in] value Value to rotate + \return Rotated value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __RRX(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rrx %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return(result); +} + + +/** + \brief LDRT Unprivileged (8 bit) + \details Executes a Unprivileged LDRT instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__attribute__((always_inline)) __STATIC_INLINE uint8_t __LDRBT(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrbt %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint8_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (16 bit) + \details Executes a Unprivileged LDRT instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__attribute__((always_inline)) __STATIC_INLINE uint16_t __LDRHT(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrht %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint16_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (32 bit) + \details Executes a Unprivileged LDRT instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __LDRT(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrt %0, %1" : "=r" (result) : "Q" (*ptr) ); + return(result); +} + + +/** + \brief STRT Unprivileged (8 bit) + \details Executes a Unprivileged STRT instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__attribute__((always_inline)) __STATIC_INLINE void __STRBT(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("strbt %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (16 bit) + \details Executes a Unprivileged STRT instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__attribute__((always_inline)) __STATIC_INLINE void __STRHT(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("strht %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (32 bit) + \details Executes a Unprivileged STRT instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__attribute__((always_inline)) __STATIC_INLINE void __STRT(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("strt %1, %0" : "=Q" (*ptr) : "r" (value) ); +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) +/** + \brief Load-Acquire (8 bit) + \details Executes a LDAB instruction 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 __LDAB(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldab %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint8_t) result); +} + + +/** + \brief Load-Acquire (16 bit) + \details Executes a LDAH instruction 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 __LDAH(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldah %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint16_t) result); +} + + +/** + \brief Load-Acquire (32 bit) + \details Executes a LDA instruction 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 __LDA(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("lda %0, %1" : "=r" (result) : "Q" (*ptr) ); + return(result); +} + + +/** + \brief Store-Release (8 bit) + \details Executes a STLB instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__attribute__((always_inline)) __STATIC_INLINE void __STLB(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("stlb %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief Store-Release (16 bit) + \details Executes a STLH instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__attribute__((always_inline)) __STATIC_INLINE void __STLH(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("stlh %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief Store-Release (32 bit) + \details Executes a STL instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__attribute__((always_inline)) __STATIC_INLINE void __STL(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("stl %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief Load-Acquire Exclusive (8 bit) + \details Executes a LDAB exclusive instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#define __LDAEXB (uint8_t)__builtin_arm_ldaex + + +/** + \brief Load-Acquire Exclusive (16 bit) + \details Executes a LDAH exclusive instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#define __LDAEXH (uint16_t)__builtin_arm_ldaex + + +/** + \brief Load-Acquire Exclusive (32 bit) + \details Executes a LDA exclusive instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#define __LDAEX (uint32_t)__builtin_arm_ldaex + + +/** + \brief Store-Release Exclusive (8 bit) + \details Executes a STLB exclusive instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STLEXB (uint32_t)__builtin_arm_stlex + + +/** + \brief Store-Release Exclusive (16 bit) + \details Executes a STLH exclusive instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STLEXH (uint32_t)__builtin_arm_stlex + + +/** + \brief Store-Release Exclusive (32 bit) + \details Executes a STL exclusive instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STLEX (uint32_t)__builtin_arm_stlex + +#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + +/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ + + +/* ################### Compiler specific Intrinsics ########################### */ +/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics + Access to dedicated SIMD instructions + @{ +*/ + +#if (defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)) + +__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) \ +({ \ + int32_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); +} + +__attribute__((always_inline)) __STATIC_INLINE uint64_t __SMLALD (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__attribute__((always_inline)) __STATIC_INLINE uint64_t __SMLALDX (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__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); +} + +__attribute__((always_inline)) __STATIC_INLINE uint64_t __SMLSLD (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__attribute__((always_inline)) __STATIC_INLINE uint64_t __SMLSLDX (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__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 int32_t __QADD( int32_t op1, int32_t op2) +{ + int32_t result; + + __ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE int32_t __QSUB( int32_t op1, int32_t op2) +{ + int32_t result; + + __ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +#if 0 +#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; \ + }) +#endif + +#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) ) + +__attribute__((always_inline)) __STATIC_INLINE int32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3) +{ + int32_t result; + + __ASM volatile ("smmla %0, %1, %2, %3" : "=r" (result): "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#endif /* (__ARM_FEATURE_DSP == 1) */ +/*@} end of group CMSIS_SIMD_intrinsics */ + + +#endif /* __CMSIS_ARMCLANG_H */ diff --git a/cmsis/TARGET_CORTEX_M/TOOLCHAIN_GCC/cmsis_gcc.h b/cmsis/TARGET_CORTEX_M/TOOLCHAIN_GCC/cmsis_gcc.h new file mode 100644 index 00000000000..f023d77b230 --- /dev/null +++ b/cmsis/TARGET_CORTEX_M/TOOLCHAIN_GCC/cmsis_gcc.h @@ -0,0 +1,1958 @@ +/**************************************************************************//** + * @file cmsis_gcc.h + * @brief CMSIS compiler GCC header file + * @version V5.0.2 + * @date 13. February 2017 + ******************************************************************************/ +/* + * Copyright (c) 2009-2017 ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CMSIS_GCC_H +#define __CMSIS_GCC_H + +/* ignore some GCC warnings */ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wsign-conversion" +#pragma GCC diagnostic ignored "-Wconversion" +#pragma GCC diagnostic ignored "-Wunused-parameter" + +/* CMSIS compiler specific defines */ +#ifndef __ASM + #define __ASM __asm +#endif +#ifndef __INLINE + #define __INLINE inline +#endif +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline +#endif +#ifndef __NO_RETURN + #define __NO_RETURN __attribute__((noreturn)) +#endif +#ifndef __USED + #define __USED __attribute__((used)) +#endif +#ifndef __WEAK + #define __WEAK __attribute__((weak)) +#endif +#ifndef __PACKED + #define __PACKED __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) +#endif +#ifndef __UNALIGNED_UINT32 /* deprecated */ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + struct __attribute__((packed)) T_UINT32 { uint32_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) +#endif +#ifndef __UNALIGNED_UINT16_WRITE + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT16_READ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) +#endif +#ifndef __UNALIGNED_UINT32_WRITE + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT32_READ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) +#endif +#ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) +#endif + + +/* ########################### Core Function Access ########################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions + @{ + */ + +/** + \brief Enable IRQ Interrupts + \details Enables IRQ interrupts by clearing the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__attribute__((always_inline)) __STATIC_INLINE void __enable_irq(void) +{ + __ASM volatile ("cpsie i" : : : "memory"); +} + + +/** + \brief Disable IRQ Interrupts + \details Disables IRQ interrupts by setting the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__attribute__((always_inline)) __STATIC_INLINE void __disable_irq(void) +{ + __ASM volatile ("cpsid i" : : : "memory"); +} + + +/** + \brief Get Control Register + \details 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); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Control Register (non-secure) + \details Returns the content of the non-secure Control Register when in secure mode. + \return non-secure Control Register value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_CONTROL_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Control Register + \details Writes the given value to the Control Register. + \param [in] control Control Register value to set + */ +__attribute__((always_inline)) __STATIC_INLINE void __set_CONTROL(uint32_t control) +{ + __ASM volatile ("MSR control, %0" : : "r" (control) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Control Register (non-secure) + \details Writes the given value to the non-secure Control Register when in secure state. + \param [in] control Control Register value to set + */ +__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_CONTROL_NS(uint32_t control) +{ + __ASM volatile ("MSR control_ns, %0" : : "r" (control) : "memory"); +} +#endif + + +/** + \brief Get IPSR Register + \details Returns the content of the IPSR Register. + \return IPSR Register value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_IPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, ipsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get APSR Register + \details 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 + \details 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 + \details 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" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Process Stack Pointer (non-secure) + \details Returns the current value of the non-secure Process Stack Pointer (PSP) when in secure state. + \return PSP Register value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_PSP_NS(void) +{ + register uint32_t result; + + __ASM volatile ("MRS %0, psp_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Process Stack Pointer + \details Assigns the given value to the Process Stack Pointer (PSP). + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__attribute__((always_inline)) __STATIC_INLINE void __set_PSP(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp, %0" : : "r" (topOfProcStack) : ); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Process Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Process Stack Pointer (PSP) when in secure state. + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_PSP_NS(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp_ns, %0" : : "r" (topOfProcStack) : ); +} +#endif + + +/** + \brief Get Main Stack Pointer + \details 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" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Main Stack Pointer (non-secure) + \details Returns the current value of the non-secure Main Stack Pointer (MSP) when in secure state. + \return MSP Register value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_MSP_NS(void) +{ + register uint32_t result; + + __ASM volatile ("MRS %0, msp_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Main Stack Pointer + \details Assigns the given value to the Main Stack Pointer (MSP). + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__attribute__((always_inline)) __STATIC_INLINE void __set_MSP(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp, %0" : : "r" (topOfMainStack) : ); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Main Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Main Stack Pointer (MSP) when in secure state. + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_MSP_NS(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp_ns, %0" : : "r" (topOfMainStack) : ); +} +#endif + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Stack Pointer (non-secure) + \details Returns the current value of the non-secure Stack Pointer (SP) when in secure state. + \return SP Register value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_SP_NS(void) +{ + register uint32_t result; + + __ASM volatile ("MRS %0, sp_ns" : "=r" (result) ); + return(result); +} + + +/** + \brief Set Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Stack Pointer (SP) when in secure state. + \param [in] topOfStack Stack Pointer value to set + */ +__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_SP_NS(uint32_t topOfStack) +{ + __ASM volatile ("MSR sp_ns, %0" : : "r" (topOfStack) : ); +} +#endif + + +/** + \brief Get Priority Mask + \details 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); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Priority Mask (non-secure) + \details Returns the current state of the non-secure priority mask bit from the Priority Mask Register when in secure state. + \return Priority Mask value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_PRIMASK_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Priority Mask + \details Assigns the given value to the Priority Mask Register. + \param [in] priMask Priority Mask + */ +__attribute__((always_inline)) __STATIC_INLINE void __set_PRIMASK(uint32_t priMask) +{ + __ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Priority Mask (non-secure) + \details Assigns the given value to the non-secure Priority Mask Register when in secure state. + \param [in] priMask Priority Mask + */ +__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_PRIMASK_NS(uint32_t priMask) +{ + __ASM volatile ("MSR primask_ns, %0" : : "r" (priMask) : "memory"); +} +#endif + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) +/** + \brief Enable FIQ + \details Enables FIQ interrupts by clearing the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__attribute__((always_inline)) __STATIC_INLINE void __enable_fault_irq(void) +{ + __ASM volatile ("cpsie f" : : : "memory"); +} + + +/** + \brief Disable FIQ + \details Disables FIQ interrupts by setting the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__attribute__((always_inline)) __STATIC_INLINE void __disable_fault_irq(void) +{ + __ASM volatile ("cpsid f" : : : "memory"); +} + + +/** + \brief Get Base Priority + \details 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" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Base Priority (non-secure) + \details Returns the current value of the non-secure Base Priority register when in secure state. + \return Base Priority register value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_BASEPRI_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Base Priority + \details 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 basePri) +{ + __ASM volatile ("MSR basepri, %0" : : "r" (basePri) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Base Priority (non-secure) + \details Assigns the given value to the non-secure Base Priority register when in secure state. + \param [in] basePri Base Priority value to set + */ +__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_BASEPRI_NS(uint32_t basePri) +{ + __ASM volatile ("MSR basepri_ns, %0" : : "r" (basePri) : "memory"); +} +#endif + + +/** + \brief Set Base Priority with condition + \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled, + or the new value increases the BASEPRI priority level. + \param [in] basePri Base Priority value to set + */ +__attribute__((always_inline)) __STATIC_INLINE void __set_BASEPRI_MAX(uint32_t basePri) +{ + __ASM volatile ("MSR basepri_max, %0" : : "r" (basePri) : "memory"); +} + + +/** + \brief Get Fault Mask + \details 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); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Fault Mask (non-secure) + \details Returns the current value of the non-secure Fault Mask register when in secure state. + \return Fault Mask register value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_FAULTMASK_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Fault Mask + \details Assigns the given value to the Fault Mask register. + \param [in] faultMask Fault Mask value to set + */ +__attribute__((always_inline)) __STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Fault Mask (non-secure) + \details Assigns the given value to the non-secure Fault Mask register when in secure state. + \param [in] faultMask Fault Mask value to set + */ +__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_FAULTMASK_NS(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask_ns, %0" : : "r" (faultMask) : "memory"); +} +#endif + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) + +/** + \brief Get Process Stack Pointer Limit + \details Returns the current value of the Process Stack Pointer Limit (PSPLIM). + \return PSPLIM Register value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_PSPLIM(void) +{ + register uint32_t result; + + __ASM volatile ("MRS %0, psplim" : "=r" (result) ); + return(result); +} + + +#if ((defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) && \ + (defined (__ARM_ARCH_8M_MAIN__) && (__ARM_ARCH_8M_MAIN__ == 1)) ) +/** + \brief Get Process Stack Pointer Limit (non-secure) + \details Returns the current value of the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \return PSPLIM Register value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_PSPLIM_NS(void) +{ + register uint32_t result; + + __ASM volatile ("MRS %0, psplim_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Process Stack Pointer Limit + \details Assigns the given value to the Process Stack Pointer Limit (PSPLIM). + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__attribute__((always_inline)) __STATIC_INLINE void __set_PSPLIM(uint32_t ProcStackPtrLimit) +{ + __ASM volatile ("MSR psplim, %0" : : "r" (ProcStackPtrLimit)); +} + + +#if ((defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) && \ + (defined (__ARM_ARCH_8M_MAIN__) && (__ARM_ARCH_8M_MAIN__ == 1)) ) +/** + \brief Set Process Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_PSPLIM_NS(uint32_t ProcStackPtrLimit) +{ + __ASM volatile ("MSR psplim_ns, %0\n" : : "r" (ProcStackPtrLimit)); +} +#endif + + +/** + \brief Get Main Stack Pointer Limit + \details Returns the current value of the Main Stack Pointer Limit (MSPLIM). + \return MSPLIM Register value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_MSPLIM(void) +{ + register uint32_t result; + + __ASM volatile ("MRS %0, msplim" : "=r" (result) ); + + return(result); +} + + +#if ((defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) && \ + (defined (__ARM_ARCH_8M_MAIN__) && (__ARM_ARCH_8M_MAIN__ == 1)) ) +/** + \brief Get Main Stack Pointer Limit (non-secure) + \details Returns the current value of the non-secure Main Stack Pointer Limit(MSPLIM) when in secure state. + \return MSPLIM Register value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_MSPLIM_NS(void) +{ + register uint32_t result; + + __ASM volatile ("MRS %0, msplim_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Main Stack Pointer Limit + \details Assigns the given value to the Main Stack Pointer Limit (MSPLIM). + \param [in] MainStackPtrLimit Main Stack Pointer Limit value to set + */ +__attribute__((always_inline)) __STATIC_INLINE void __set_MSPLIM(uint32_t MainStackPtrLimit) +{ + __ASM volatile ("MSR msplim, %0" : : "r" (MainStackPtrLimit)); +} + + +#if ((defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) && \ + (defined (__ARM_ARCH_8M_MAIN__) && (__ARM_ARCH_8M_MAIN__ == 1)) ) +/** + \brief Set Main Stack Pointer Limit (non-secure) + \details Assigns the given value to the non-secure Main Stack Pointer Limit (MSPLIM) when in secure state. + \param [in] MainStackPtrLimit Main Stack Pointer value to set + */ +__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_MSPLIM_NS(uint32_t MainStackPtrLimit) +{ + __ASM volatile ("MSR msplim_ns, %0" : : "r" (MainStackPtrLimit)); +} +#endif + +#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) + +/** + \brief Get FPSCR + \details 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 ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) + uint32_t result; + + __ASM volatile ("VMRS %0, fpscr" : "=r" (result) ); + return(result); +#else + return(0U); +#endif +} + + +/** + \brief Set FPSCR + \details Assigns the given value to the Floating Point Status/Control register. + \param [in] fpscr Floating Point Status/Control value to set + */ +__attribute__((always_inline)) __STATIC_INLINE void __set_FPSCR(uint32_t fpscr) +{ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) + __ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) : "vfpcc", "memory"); +#else + (void)fpscr; +#endif +} + +#endif /* ((defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + + + +/*@} end of CMSIS_Core_RegAccFunctions */ + + +/* ########################## Core Instruction Access ######################### */ +/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface + Access to dedicated instructions + @{ +*/ + +/* Define macros for porting to both thumb1 and thumb2. + * For thumb1, use low register (r0-r7), specified by constraint "l" + * Otherwise, use general registers, specified by constraint "r" */ +#if defined (__thumb__) && !defined (__thumb2__) +#define __CMSIS_GCC_OUT_REG(r) "=l" (r) +#define __CMSIS_GCC_RW_REG(r) "+l" (r) +#define __CMSIS_GCC_USE_REG(r) "l" (r) +#else +#define __CMSIS_GCC_OUT_REG(r) "=r" (r) +#define __CMSIS_GCC_RW_REG(r) "+r" (r) +#define __CMSIS_GCC_USE_REG(r) "r" (r) +#endif + +/** + \brief No Operation + \details No Operation does nothing. This instruction can be used for code alignment purposes. + */ +//__attribute__((always_inline)) __STATIC_INLINE void __NOP(void) +//{ +// __ASM volatile ("nop"); +//} +#define __NOP() __ASM volatile ("nop") /* This implementation generates debug information */ + +/** + \brief Wait For Interrupt + \details 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"); +//} +#define __WFI() __ASM volatile ("wfi") /* This implementation generates debug information */ + + +/** + \brief Wait For Event + \details Wait For Event is a hint instruction that permits the processor to enter + a low-power state until one of a number of events occurs. + */ +//__attribute__((always_inline)) __STATIC_INLINE void __WFE(void) +//{ +// __ASM volatile ("wfe"); +//} +#define __WFE() __ASM volatile ("wfe") /* This implementation generates debug information */ + + +/** + \brief Send Event + \details 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"); +//} +#define __SEV() __ASM volatile ("sev") /* This implementation generates debug information */ + + +/** + \brief Instruction Synchronization Barrier + \details Instruction Synchronization Barrier flushes the pipeline in the processor, + so that all instructions following the ISB are fetched from cache or memory, + after the instruction has been completed. + */ +__attribute__((always_inline)) __STATIC_INLINE void __ISB(void) +{ + __ASM volatile ("isb 0xF":::"memory"); +} + + +/** + \brief Data Synchronization Barrier + \details Acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +__attribute__((always_inline)) __STATIC_INLINE void __DSB(void) +{ + __ASM volatile ("dsb 0xF":::"memory"); +} + + +/** + \brief Data Memory Barrier + \details 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 0xF":::"memory"); +} + + +/** + \brief Reverse byte order (32 bit) + \details Reverses the byte order in integer value. + \param [in] value Value to reverse + \return Reversed value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __REV(uint32_t value) +{ +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) + return __builtin_bswap32(value); +#else + uint32_t result; + + __ASM volatile ("rev %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return(result); +#endif +} + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order in two unsigned short values. + \param [in] value Value to reverse + \return Reversed value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __REV16(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rev16 %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return(result); +} + + +/** + \brief Reverse byte order in signed short value + \details Reverses the byte order in a signed short value with sign extension to integer. + \param [in] value Value to reverse + \return Reversed value + */ +__attribute__((always_inline)) __STATIC_INLINE int32_t __REVSH(int32_t value) +{ +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + return (short)__builtin_bswap16(value); +#else + int32_t result; + + __ASM volatile ("revsh %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return(result); +#endif +} + + +/** + \brief Rotate Right in unsigned value (32 bit) + \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. + \param [in] op1 Value to rotate + \param [in] op2 Number of Bits to rotate + \return Rotated value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __ROR(uint32_t op1, uint32_t op2) +{ + return (op1 >> op2) | (op1 << (32U - op2)); +} + + +/** + \brief Breakpoint + \details Causes the processor to enter Debug state. + Debug tools can use this to investigate system state when the instruction at a particular address is reached. + \param [in] value is ignored by the processor. + If required, a debugger can use it to store additional information about the breakpoint. + */ +#define __BKPT(value) __ASM volatile ("bkpt "#value) + + +/** + \brief Reverse bit order of value + \details Reverses the bit order of the given value. + \param [in] value Value to reverse + \return Reversed value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value) +{ + uint32_t result; + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) + __ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) ); +#else + int32_t s = (4 /*sizeof(v)*/ * 8) - 1; /* extra shift needed at end */ + + result = value; /* r will be reversed bits of v; first get LSB of v */ + for (value >>= 1U; value; value >>= 1U) + { + result <<= 1U; + result |= value & 1U; + s--; + } + result <<= s; /* shift when v's highest bits are zero */ +#endif + return(result); +} + + +/** + \brief Count leading zeros + \details Counts the number of leading zeros of a data value. + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +#define __CLZ __builtin_clz + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) +/** + \brief LDR Exclusive (8 bit) + \details Executes a exclusive LDR instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__attribute__((always_inline)) __STATIC_INLINE uint8_t __LDREXB(volatile uint8_t *addr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrexb %0, %1" : "=r" (result) : "Q" (*addr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); +#endif + return ((uint8_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDR Exclusive (16 bit) + \details Executes a exclusive LDR instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__attribute__((always_inline)) __STATIC_INLINE uint16_t __LDREXH(volatile uint16_t *addr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrexh %0, %1" : "=r" (result) : "Q" (*addr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); +#endif + return ((uint16_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDR Exclusive (32 bit) + \details Executes a exclusive LDR instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __LDREXW(volatile uint32_t *addr) +{ + uint32_t result; + + __ASM volatile ("ldrex %0, %1" : "=r" (result) : "Q" (*addr) ); + return(result); +} + + +/** + \brief STR Exclusive (8 bit) + \details Executes a exclusive STR instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr) +{ + uint32_t result; + + __ASM volatile ("strexb %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) ); + return(result); +} + + +/** + \brief STR Exclusive (16 bit) + \details Executes a exclusive STR instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr) +{ + uint32_t result; + + __ASM volatile ("strexh %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) ); + return(result); +} + + +/** + \brief STR Exclusive (32 bit) + \details Executes a exclusive STR instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr) +{ + uint32_t result; + + __ASM volatile ("strex %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" (value) ); + return(result); +} + + +/** + \brief Remove the exclusive lock + \details Removes the exclusive lock which is created by LDREX. + */ +__attribute__((always_inline)) __STATIC_INLINE void __CLREX(void) +{ + __ASM volatile ("clrex" ::: "memory"); +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +#define __SSAT(ARG1,ARG2) \ +({ \ + int32_t __RES, __ARG1 = (ARG1); \ + __ASM ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +#define __USAT(ARG1,ARG2) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + + +/** + \brief Rotate Right with Extend (32 bit) + \details Moves each bit of a bitstring right by one bit. + The carry input is shifted in at the left end of the bitstring. + \param [in] value Value to rotate + \return Rotated value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __RRX(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rrx %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return(result); +} + + +/** + \brief LDRT Unprivileged (8 bit) + \details Executes a Unprivileged LDRT instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__attribute__((always_inline)) __STATIC_INLINE uint8_t __LDRBT(volatile uint8_t *ptr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrbt %0, %1" : "=r" (result) : "Q" (*ptr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrbt %0, [%1]" : "=r" (result) : "r" (ptr) : "memory" ); +#endif + return ((uint8_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (16 bit) + \details Executes a Unprivileged LDRT instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__attribute__((always_inline)) __STATIC_INLINE uint16_t __LDRHT(volatile uint16_t *ptr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrht %0, %1" : "=r" (result) : "Q" (*ptr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrht %0, [%1]" : "=r" (result) : "r" (ptr) : "memory" ); +#endif + return ((uint16_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (32 bit) + \details Executes a Unprivileged LDRT instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __LDRT(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrt %0, %1" : "=r" (result) : "Q" (*ptr) ); + return(result); +} + + +/** + \brief STRT Unprivileged (8 bit) + \details Executes a Unprivileged STRT instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__attribute__((always_inline)) __STATIC_INLINE void __STRBT(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("strbt %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (16 bit) + \details Executes a Unprivileged STRT instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__attribute__((always_inline)) __STATIC_INLINE void __STRHT(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("strht %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (32 bit) + \details Executes a Unprivileged STRT instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__attribute__((always_inline)) __STATIC_INLINE void __STRT(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("strt %1, %0" : "=Q" (*ptr) : "r" (value) ); +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) +/** + \brief Load-Acquire (8 bit) + \details Executes a LDAB instruction 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 __LDAB(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldab %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint8_t) result); +} + + +/** + \brief Load-Acquire (16 bit) + \details Executes a LDAH instruction 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 __LDAH(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldah %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint16_t) result); +} + + +/** + \brief Load-Acquire (32 bit) + \details Executes a LDA instruction 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 __LDA(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("lda %0, %1" : "=r" (result) : "Q" (*ptr) ); + return(result); +} + + +/** + \brief Store-Release (8 bit) + \details Executes a STLB instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__attribute__((always_inline)) __STATIC_INLINE void __STLB(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("stlb %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief Store-Release (16 bit) + \details Executes a STLH instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__attribute__((always_inline)) __STATIC_INLINE void __STLH(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("stlh %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief Store-Release (32 bit) + \details Executes a STL instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__attribute__((always_inline)) __STATIC_INLINE void __STL(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("stl %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief Load-Acquire Exclusive (8 bit) + \details Executes a LDAB exclusive instruction 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 __LDAEXB(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldaexb %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint8_t) result); +} + + +/** + \brief Load-Acquire Exclusive (16 bit) + \details Executes a LDAH exclusive instruction 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 __LDAEXH(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldaexh %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint16_t) result); +} + + +/** + \brief Load-Acquire Exclusive (32 bit) + \details Executes a LDA exclusive instruction 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 __LDAEX(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldaex %0, %1" : "=r" (result) : "Q" (*ptr) ); + return(result); +} + + +/** + \brief Store-Release Exclusive (8 bit) + \details Executes a STLB exclusive instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __STLEXB(uint8_t value, volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("stlexb %0, %2, %1" : "=&r" (result), "=Q" (*ptr) : "r" ((uint32_t)value) ); + return(result); +} + + +/** + \brief Store-Release Exclusive (16 bit) + \details Executes a STLH exclusive instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __STLEXH(uint16_t value, volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("stlexh %0, %2, %1" : "=&r" (result), "=Q" (*ptr) : "r" ((uint32_t)value) ); + return(result); +} + + +/** + \brief Store-Release Exclusive (32 bit) + \details Executes a STL exclusive instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __STLEX(uint32_t value, volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("stlex %0, %2, %1" : "=&r" (result), "=Q" (*ptr) : "r" ((uint32_t)value) ); + return(result); +} + +#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + +/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ + + +/* ################### Compiler specific Intrinsics ########################### */ +/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics + Access to dedicated SIMD instructions + @{ +*/ + +#if (__ARM_FEATURE_DSP == 1) /* ToDo ARMCLANG: This should be ARCH >= ARMv7-M + SIMD */ + +__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) \ +({ \ + int32_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); +} + +__attribute__((always_inline)) __STATIC_INLINE uint64_t __SMLALD (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__attribute__((always_inline)) __STATIC_INLINE uint64_t __SMLALDX (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__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); +} + +__attribute__((always_inline)) __STATIC_INLINE uint64_t __SMLSLD (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__attribute__((always_inline)) __STATIC_INLINE uint64_t __SMLSLDX (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__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 int32_t __QADD( int32_t op1, int32_t op2) +{ + int32_t result; + + __ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE int32_t __QSUB( int32_t op1, int32_t op2) +{ + int32_t result; + + __ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +#if 0 +#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; \ + }) +#endif + +#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) ) + +__attribute__((always_inline)) __STATIC_INLINE int32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3) +{ + int32_t result; + + __ASM volatile ("smmla %0, %1, %2, %3" : "=r" (result): "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#endif /* (__ARM_FEATURE_DSP == 1) */ +/*@} end of group CMSIS_SIMD_intrinsics */ + + +#pragma GCC diagnostic pop + +#endif /* __CMSIS_GCC_H */ diff --git a/cmsis/TARGET_CORTEX_M/cmsis_compiler.h b/cmsis/TARGET_CORTEX_M/cmsis_compiler.h new file mode 100644 index 00000000000..2ef183fbaaf --- /dev/null +++ b/cmsis/TARGET_CORTEX_M/cmsis_compiler.h @@ -0,0 +1,287 @@ +/**************************************************************************//** + * @file cmsis_compiler.h + * @brief CMSIS compiler generic header file + * @version V5.0.2 + * @date 13. February 2017 + ******************************************************************************/ +/* + * Copyright (c) 2009-2017 ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CMSIS_COMPILER_H +#define __CMSIS_COMPILER_H + +#include + +/* + * ARM Compiler 4/5 + */ +#if defined ( __CC_ARM ) + #include "cmsis_armcc.h" + + +/* + * ARM Compiler 6 (armclang) + */ +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #include "cmsis_armclang.h" + + +/* + * GNU Compiler + */ +#elif defined ( __GNUC__ ) + #include "cmsis_gcc.h" + + +/* + * IAR Compiler + */ +#elif defined ( __ICCARM__ ) + + #ifndef __ASM + #define __ASM __asm + #endif + #ifndef __INLINE + #define __INLINE inline + #endif + #ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline + #endif + + #include + + #ifndef __NO_RETURN + #define __NO_RETURN __noreturn + #endif + #ifndef __USED + #define __USED __root + #endif + #ifndef __WEAK + #define __WEAK __weak + #endif + #ifndef __PACKED + #define __PACKED __packed + #endif + #ifndef __PACKED_STRUCT + #define __PACKED_STRUCT __packed struct + #endif + #ifndef __UNALIGNED_UINT32 /* deprecated */ + __packed struct T_UINT32 { uint32_t v; }; + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) + #endif + #ifndef __UNALIGNED_UINT16_WRITE + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT16_READ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) + #endif + #ifndef __UNALIGNED_UINT32_WRITE + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT32_READ + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) + #endif + #ifndef __ALIGNED + #warning No compiler specific solution for __ALIGNED. __ALIGNED is ignored. + #define __ALIGNED(x) + #endif + + +/* + * TI ARM Compiler + */ +#elif defined ( __TI_ARM__ ) + #include + + #ifndef __ASM + #define __ASM __asm + #endif + #ifndef __INLINE + #define __INLINE inline + #endif + #ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline + #endif + #ifndef __NO_RETURN + #define __NO_RETURN __attribute__((noreturn)) + #endif + #ifndef __USED + #define __USED __attribute__((used)) + #endif + #ifndef __WEAK + #define __WEAK __attribute__((weak)) + #endif + #ifndef __PACKED + #define __PACKED __attribute__((packed)) + #endif + #ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __attribute__((packed)) + #endif + #ifndef __UNALIGNED_UINT32 /* deprecated */ + struct __attribute__((packed)) T_UINT32 { uint32_t v; }; + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) + #endif + #ifndef __UNALIGNED_UINT16_WRITE + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void*)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT16_READ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) + #endif + #ifndef __UNALIGNED_UINT32_WRITE + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT32_READ + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) + #endif + #ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) + #endif + + +/* + * TASKING Compiler + */ +#elif defined ( __TASKING__ ) + /* + * The CMSIS functions have been implemented as intrinsics in the compiler. + * Please use "carm -?i" to get an up to date list of all intrinsics, + * Including the CMSIS ones. + */ + + #ifndef __ASM + #define __ASM __asm + #endif + #ifndef __INLINE + #define __INLINE inline + #endif + #ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline + #endif + #ifndef __NO_RETURN + #define __NO_RETURN __attribute__((noreturn)) + #endif + #ifndef __USED + #define __USED __attribute__((used)) + #endif + #ifndef __WEAK + #define __WEAK __attribute__((weak)) + #endif + #ifndef __PACKED + #define __PACKED __packed__ + #endif + #ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __packed__ + #endif + #ifndef __UNALIGNED_UINT32 /* deprecated */ + struct __packed__ T_UINT32 { uint32_t v; }; + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) + #endif + #ifndef __UNALIGNED_UINT16_WRITE + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT16_READ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) + #endif + #ifndef __UNALIGNED_UINT32_WRITE + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT32_READ + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) + #endif + #ifndef __ALIGNED + #define __ALIGNED(x) __align(x) + #endif + + +/* + * COSMIC Compiler + */ +#elif defined ( __CSMC__ ) + #include + + #ifndef __ASM + #define __ASM _asm + #endif + #ifndef __INLINE + #define __INLINE inline + #endif + #ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline + #endif + #ifndef __NO_RETURN + // NO RETURN is automatically detected hence no warning here + #define __NO_RETURN + #endif + #ifndef __USED + #warning No compiler specific solution for __USED. __USED is ignored. + #define __USED + #endif + #ifndef __WEAK + #define __WEAK __weak + #endif + #ifndef __PACKED + #define __PACKED @packed + #endif + #ifndef __PACKED_STRUCT + #define __PACKED_STRUCT @packed struct + #endif + #ifndef __UNALIGNED_UINT32 /* deprecated */ + @packed struct T_UINT32 { uint32_t v; }; + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) + #endif + #ifndef __UNALIGNED_UINT16_WRITE + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT16_READ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) + #endif + #ifndef __UNALIGNED_UINT32_WRITE + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT32_READ + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) + #endif + #ifndef __ALIGNED + #warning No compiler specific solution for __ALIGNED. __ALIGNED is ignored. + #define __ALIGNED(x) + #endif + + +#else + #error Unknown compiler. +#endif + + +#endif /* __CMSIS_COMPILER_H */ + diff --git a/cmsis/arm_math.h b/cmsis/arm_math.h new file mode 100644 index 00000000000..4be7e8c8488 --- /dev/null +++ b/cmsis/arm_math.h @@ -0,0 +1,7226 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_math.h + * Description: Public header file for CMSIS DSP Library + * + * $Date: 27. January 2017 + * $Revision: V.1.5.1 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * Copyright (C) 2010-2017 ARM Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + \mainpage CMSIS DSP Software Library + * + * Introduction + * ------------ + * + * This user manual describes the CMSIS DSP software library, + * a suite of common signal processing functions for use on Cortex-M processor based devices. + * + * The library is divided into a number of functions each covering a specific category: + * - Basic math functions + * - Fast math functions + * - Complex math functions + * - Filters + * - Matrix functions + * - Transforms + * - Motor control functions + * - Statistical functions + * - Support functions + * - Interpolation functions + * + * The library has separate functions for operating on 8-bit integers, 16-bit integers, + * 32-bit integer and 32-bit floating-point values. + * + * Using the Library + * ------------ + * + * The library installer contains prebuilt versions of the libraries in the Lib folder. + * - arm_cortexM7lfdp_math.lib (Cortex-M7, Little endian, Double Precision Floating Point Unit) + * - arm_cortexM7bfdp_math.lib (Cortex-M7, Big endian, Double Precision Floating Point Unit) + * - arm_cortexM7lfsp_math.lib (Cortex-M7, Little endian, Single Precision Floating Point Unit) + * - arm_cortexM7bfsp_math.lib (Cortex-M7, Big endian and Single Precision Floating Point Unit on) + * - arm_cortexM7l_math.lib (Cortex-M7, Little endian) + * - arm_cortexM7b_math.lib (Cortex-M7, Big endian) + * - arm_cortexM4lf_math.lib (Cortex-M4, Little endian, Floating Point Unit) + * - arm_cortexM4bf_math.lib (Cortex-M4, Big endian, Floating Point Unit) + * - arm_cortexM4l_math.lib (Cortex-M4, Little endian) + * - arm_cortexM4b_math.lib (Cortex-M4, Big endian) + * - arm_cortexM3l_math.lib (Cortex-M3, Little endian) + * - arm_cortexM3b_math.lib (Cortex-M3, Big endian) + * - arm_cortexM0l_math.lib (Cortex-M0 / Cortex-M0+, Little endian) + * - arm_cortexM0b_math.lib (Cortex-M0 / Cortex-M0+, Big endian) + * - arm_ARMv8MBLl_math.lib (ARMv8M Baseline, Little endian) + * - arm_ARMv8MMLl_math.lib (ARMv8M Mainline, Little endian) + * - arm_ARMv8MMLlfsp_math.lib (ARMv8M Mainline, Little endian, Single Precision Floating Point Unit) + * - arm_ARMv8MMLld_math.lib (ARMv8M Mainline, Little endian, DSP instructions) + * - arm_ARMv8MMLldfsp_math.lib (ARMv8M Mainline, Little endian, DSP instructions, Single Precision Floating Point Unit) + * + * 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-M cores 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_CM7 or ARM_MATH_CM4 or ARM_MATH_CM3 or + * ARM_MATH_CM0 or ARM_MATH_CM0PLUS depending on the target processor in the application. + * For ARMv8M cores define pre processor MACRO ARM_MATH_ARMV8MBL or ARM_MATH_ARMV8MML. + * Set Pre processor MACRO __DSP_PRESENT if ARMv8M Mainline core supports DSP instructions. + * + * + * Examples + * -------- + * + * The library ships with a number of examples which demonstrate how to use the library functions. + * + * Toolchain Support + * ------------ + * + * The library has been developed and tested with MDK-ARM version 5.14.0.0 + * The library is being tested in GCC and IAR toolchains and updates on this activity will be made available shortly. + * + * Building the Library + * ------------ + * + * The library installer contains a project file to re build libraries on MDK-ARM Tool chain in the CMSIS\\DSP_Lib\\Source\\ARM folder. + * - arm_cortexM_math.uvprojx + * + * + * The libraries can be built by opening the arm_cortexM_math.uvprojx project in MDK-ARM, selecting a specific target, and defining the optional pre processor MACROs detailed above. + * + * Pre-processor Macros + * ------------ + * + * Each library project have differant pre-processor macros. + * + * - UNALIGNED_SUPPORT_DISABLE: + * + * Define macro UNALIGNED_SUPPORT_DISABLE, If the silicon does not support unaligned memory access + * + * - ARM_MATH_BIG_ENDIAN: + * + * Define macro ARM_MATH_BIG_ENDIAN to build the library for big endian targets. By default library builds for little endian targets. + * + * - ARM_MATH_MATRIX_CHECK: + * + * Define macro ARM_MATH_MATRIX_CHECK for checking on the input and output sizes of matrices + * + * - ARM_MATH_ROUNDING: + * + * Define macro ARM_MATH_ROUNDING for rounding on support functions + * + * - ARM_MATH_CMx: + * + * Define macro ARM_MATH_CM4 for building the library on Cortex-M4 target, ARM_MATH_CM3 for building library on Cortex-M3 target + * and ARM_MATH_CM0 for building library on Cortex-M0 target, ARM_MATH_CM0PLUS for building library on Cortex-M0+ target, and + * ARM_MATH_CM7 for building the library on cortex-M7. + * + * - ARM_MATH_ARMV8MxL: + * + * Define macro ARM_MATH_ARMV8MBL for building the library on ARMv8M Baseline target, ARM_MATH_ARMV8MBL for building library + * on ARMv8M Mainline target. + * + * - __FPU_PRESENT: + * + * Initialize macro __FPU_PRESENT = 1 when building on FPU supported Targets. Enable this macro for floating point libraries. + * + * - __DSP_PRESENT: + * + * Initialize macro __DSP_PRESENT = 1 when ARMv8M Mainline core supports DSP instructions. + * + *
+ * CMSIS-DSP in ARM::CMSIS Pack + * ----------------------------- + * + * The following files relevant to CMSIS-DSP are present in the ARM::CMSIS Pack directories: + * |File/Folder |Content | + * |------------------------------|------------------------------------------------------------------------| + * |\b CMSIS\\Documentation\\DSP | This documentation | + * |\b CMSIS\\DSP_Lib | Software license agreement (license.txt) | + * |\b CMSIS\\DSP_Lib\\Examples | Example projects demonstrating the usage of the library functions | + * |\b CMSIS\\DSP_Lib\\Source | Source files for rebuilding the library | + * + *
+ * Revision History of CMSIS-DSP + * ------------ + * Please refer to \ref ChangeLog_pg. + * + * Copyright Notice + * ------------ + * + * Copyright (C) 2010-2015 ARM Limited. All rights reserved. + */ + + +/** + * @defgroup groupMath Basic Math Functions + */ + +/** + * @defgroup groupFastMath Fast Math Functions + * This set of functions provides a fast approximation to sine, cosine, and square root. + * As compared to most of the other functions in the CMSIS math library, the fast math functions + * operate on individual values and not arrays. + * There are separate functions for Q15, Q31, and floating-point data. + * + */ + +/** + * @defgroup groupCmplxMath Complex Math Functions + * This set of functions operates on complex data vectors. + * The data in the complex arrays is stored in an interleaved fashion + * (real, imag, real, imag, ...). + * In the API functions, the number of samples in a complex array refers + * to the number of complex values; the array contains twice this number of + * real values. + */ + +/** + * @defgroup groupFilters Filtering Functions + */ + +/** + * @defgroup groupMatrix Matrix Functions + * + * This set of functions provides basic matrix math operations. + * The functions operate on matrix data structures. For example, + * the type + * definition for the floating-point matrix structure is shown + * below: + *
+ *     typedef struct
+ *     {
+ *       uint16_t numRows;     // number of rows of the matrix.
+ *       uint16_t numCols;     // number of columns of the matrix.
+ *       float32_t *pData;     // points to the data of the matrix.
+ *     } arm_matrix_instance_f32;
+ * 
+ * There are similar definitions for Q15 and Q31 data types. + * + * The structure specifies the size of the matrix and then points to + * an array of data. The array is of size numRows X numCols + * and the values are arranged in row order. That is, the + * matrix element (i, j) is stored at: + *
+ *     pData[i*numCols + j]
+ * 
+ * + * \par Init Functions + * There is an associated initialization function for each type of matrix + * data structure. + * The initialization function sets the values of the internal structure fields. + * Refer to the function arm_mat_init_f32(), arm_mat_init_q31() + * and arm_mat_init_q15() for floating-point, Q31 and Q15 types, respectively. + * + * \par + * Use of the initialization function is optional. However, if initialization function is used + * then the instance structure cannot be placed into a const data section. + * To place the instance structure in a const data + * section, manually initialize the data structure. For example: + *
+ * arm_matrix_instance_f32 S = {nRows, nColumns, pData};
+ * arm_matrix_instance_q31 S = {nRows, nColumns, pData};
+ * arm_matrix_instance_q15 S = {nRows, nColumns, pData};
+ * 
+ * where nRows specifies the number of rows, nColumns + * specifies the number of columns, and pData points to the + * data array. + * + * \par Size Checking + * By default all of the matrix functions perform size checking on the input and + * output matrices. For example, the matrix addition function verifies that the + * two input matrices and the output matrix all have the same number of rows and + * columns. If the size check fails the functions return: + *
+ *     ARM_MATH_SIZE_MISMATCH
+ * 
+ * Otherwise the functions return + *
+ *     ARM_MATH_SUCCESS
+ * 
+ * There is some overhead associated with this matrix size checking. + * The matrix size checking is enabled via the \#define + *
+ *     ARM_MATH_MATRIX_CHECK
+ * 
+ * within the library project settings. By default this macro is defined + * and size checking is enabled. By changing the project settings and + * undefining this macro size checking is eliminated and the functions + * run a bit faster. With size checking disabled the functions always + * return ARM_MATH_SUCCESS. + */ + +/** + * @defgroup groupTransforms Transform Functions + */ + +/** + * @defgroup groupController Controller Functions + */ + +/** + * @defgroup groupStats Statistics Functions + */ +/** + * @defgroup groupSupport Support Functions + */ + +/** + * @defgroup groupInterpolation Interpolation Functions + * These functions perform 1- and 2-dimensional interpolation of data. + * Linear interpolation is used for 1-dimensional data and + * bilinear interpolation is used for 2-dimensional data. + */ + +/** + * @defgroup groupExamples Examples + */ +#ifndef _ARM_MATH_H +#define _ARM_MATH_H + +/* ignore some GCC warnings */ +#if defined ( __GNUC__ ) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wsign-conversion" +#pragma GCC diagnostic ignored "-Wconversion" +#pragma GCC diagnostic ignored "-Wunused-parameter" +#endif + +#define __CMSIS_GENERIC /* disable NVIC and Systick functions */ + +#if defined(ARM_MATH_CM7) + #include "core_cm7.h" + #define ARM_MATH_DSP +#elif defined (ARM_MATH_CM4) + #include "core_cm4.h" + #define ARM_MATH_DSP +#elif defined (ARM_MATH_CM3) + #include "core_cm3.h" +#elif defined (ARM_MATH_CM0) + #include "core_cm0.h" + #define ARM_MATH_CM0_FAMILY +#elif defined (ARM_MATH_CM0PLUS) + #include "core_cm0plus.h" + #define ARM_MATH_CM0_FAMILY +#elif defined (ARM_MATH_ARMV8MBL) + #include "core_armv8mbl.h" + #define ARM_MATH_CM0_FAMILY +#elif defined (ARM_MATH_ARMV8MML) + #include "core_armv8mml.h" + #if (defined (__DSP_PRESENT) && (__DSP_PRESENT == 1)) + #define ARM_MATH_DSP + #endif +#else + #error "Define according the used Cortex core ARM_MATH_CM7, ARM_MATH_CM4, ARM_MATH_CM3, ARM_MATH_CM0PLUS, ARM_MATH_CM0, ARM_MATH_ARMV8MBL, ARM_MATH_ARMV8MML" +#endif + +#undef __CMSIS_GENERIC /* enable NVIC and Systick functions */ +#include "string.h" +#include "math.h" +#ifdef __cplusplus +extern "C" +{ +#endif + + + /** + * @brief Macros required for reciprocal calculation in Normalized LMS + */ + +#define DELTA_Q31 (0x100) +#define DELTA_Q15 0x5 +#define INDEX_MASK 0x0000003F +#ifndef PI + #define PI 3.14159265358979f +#endif + + /** + * @brief Macros required for SINE and COSINE Fast math approximations + */ + +#define FAST_MATH_TABLE_SIZE 512 +#define FAST_MATH_Q31_SHIFT (32 - 10) +#define FAST_MATH_Q15_SHIFT (16 - 10) +#define CONTROLLER_Q31_SHIFT (32 - 9) +#define TABLE_SPACING_Q31 0x400000 +#define TABLE_SPACING_Q15 0x80 + + /** + * @brief Macros required for SINE and COSINE Controller functions + */ + /* 1.31(q31) Fixed value of 2/360 */ + /* -1 to +1 is divided into 360 values so total spacing is (2/360) */ +#define INPUT_SPACING 0xB60B61 + + /** + * @brief Macro for Unaligned Support + */ +#ifndef UNALIGNED_SUPPORT_DISABLE + #define ALIGN4 +#else + #if defined (__GNUC__) + #define ALIGN4 __attribute__((aligned(4))) + #else + #define ALIGN4 __align(4) + #endif +#endif /* #ifndef UNALIGNED_SUPPORT_DISABLE */ + + /** + * @brief Error status returned by some functions in the library. + */ + + typedef enum + { + ARM_MATH_SUCCESS = 0, /**< No error */ + ARM_MATH_ARGUMENT_ERROR = -1, /**< One or more arguments are incorrect */ + ARM_MATH_LENGTH_ERROR = -2, /**< Length of data buffer is incorrect */ + ARM_MATH_SIZE_MISMATCH = -3, /**< Size of matrices is not compatible with the operation. */ + ARM_MATH_NANINF = -4, /**< Not-a-number (NaN) or infinity is generated */ + ARM_MATH_SINGULAR = -5, /**< Generated by matrix inversion if the input matrix is singular and cannot be inverted. */ + ARM_MATH_TEST_FAILURE = -6 /**< Test Failed */ + } arm_status; + + /** + * @brief 8-bit fractional data type in 1.7 format. + */ + typedef int8_t q7_t; + + /** + * @brief 16-bit fractional data type in 1.15 format. + */ + typedef int16_t q15_t; + + /** + * @brief 32-bit fractional data type in 1.31 format. + */ + typedef int32_t q31_t; + + /** + * @brief 64-bit fractional data type in 1.63 format. + */ + typedef int64_t q63_t; + + /** + * @brief 32-bit floating-point type definition. + */ + typedef float float32_t; + + /** + * @brief 64-bit floating-point type definition. + */ + typedef double float64_t; + + /** + * @brief definition to read/write two 16 bit values. + */ +#if defined ( __CC_ARM ) + #define __SIMD32_TYPE int32_t __packed + #define CMSIS_UNUSED __attribute__((unused)) + #define CMSIS_INLINE __attribute__((always_inline)) + +#elif defined ( __ARMCC_VERSION ) && ( __ARMCC_VERSION >= 6010050 ) + #define __SIMD32_TYPE int32_t + #define CMSIS_UNUSED __attribute__((unused)) + #define CMSIS_INLINE __attribute__((always_inline)) + +#elif defined ( __GNUC__ ) + #define __SIMD32_TYPE int32_t + #define CMSIS_UNUSED __attribute__((unused)) + #define CMSIS_INLINE __attribute__((always_inline)) + +#elif defined ( __ICCARM__ ) + #define __SIMD32_TYPE int32_t __packed + #define CMSIS_UNUSED + #define CMSIS_INLINE + +#elif defined ( __TI_ARM__ ) + #define __SIMD32_TYPE int32_t + #define CMSIS_UNUSED __attribute__((unused)) + #define CMSIS_INLINE + +#elif defined ( __CSMC__ ) + #define __SIMD32_TYPE int32_t + #define CMSIS_UNUSED + #define CMSIS_INLINE + +#elif defined ( __TASKING__ ) + #define __SIMD32_TYPE __unaligned int32_t + #define CMSIS_UNUSED + #define CMSIS_INLINE + +#else + #error Unknown compiler +#endif + +#define __SIMD32(addr) (*(__SIMD32_TYPE **) & (addr)) +#define __SIMD32_CONST(addr) ((__SIMD32_TYPE *)(addr)) +#define _SIMD32_OFFSET(addr) (*(__SIMD32_TYPE *) (addr)) +#define __SIMD64(addr) (*(int64_t **) & (addr)) + +/* #if defined (ARM_MATH_CM3) || defined (ARM_MATH_CM0_FAMILY) */ +#if !defined (ARM_MATH_DSP) + /** + * @brief definition to pack two 16 bit values. + */ +#define __PKHBT(ARG1, ARG2, ARG3) ( (((int32_t)(ARG1) << 0) & (int32_t)0x0000FFFF) | \ + (((int32_t)(ARG2) << ARG3) & (int32_t)0xFFFF0000) ) +#define __PKHTB(ARG1, ARG2, ARG3) ( (((int32_t)(ARG1) << 0) & (int32_t)0xFFFF0000) | \ + (((int32_t)(ARG2) >> ARG3) & (int32_t)0x0000FFFF) ) + +/* #endif // defined (ARM_MATH_CM3) || defined (ARM_MATH_CM0_FAMILY) */ +#endif /* !defined (ARM_MATH_DSP) */ + + /** + * @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. + */ + CMSIS_INLINE __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. + */ + CMSIS_INLINE __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. + */ + CMSIS_INLINE __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. + */ + CMSIS_INLINE __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. + */ + + CMSIS_INLINE __STATIC_INLINE q63_t mult32x64( + q63_t x, + q31_t y) + { + return ((((q63_t) (x & 0x00000000FFFFFFFF) * y) >> 32) + + (((q63_t) (x >> 32) * y))); + } + +/* + #if defined (ARM_MATH_CM0_FAMILY) && defined ( __CC_ARM ) + #define __CLZ __clz + #endif + */ +/* note: function can be removed when all toolchain support __CLZ for Cortex-M0 */ +#if defined (ARM_MATH_CM0_FAMILY) && ((defined (__ICCARM__)) ) + CMSIS_INLINE __STATIC_INLINE uint32_t __CLZ( + q31_t data); + + CMSIS_INLINE __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. + */ + + CMSIS_INLINE __STATIC_INLINE uint32_t arm_recip_q31( + q31_t in, + q31_t * dst, + q31_t * pRecipTable) + { + q31_t out; + uint32_t tempVal; + uint32_t index, i; + uint32_t signBits; + + if (in > 0) + { + signBits = ((uint32_t) (__CLZ( in) - 1)); + } + else + { + signBits = ((uint32_t) (__CLZ(-in) - 1)); + } + + /* Convert input sample to 1.31 format */ + in = (in << signBits); + + /* calculation of index for initial approximated Val */ + index = (uint32_t)(in >> 24); + 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 = (uint32_t) (((q63_t) in * out) >> 31); + tempVal = 0x7FFFFFFFu - tempVal; + /* 1.31 with exp 1 */ + /* out = (q31_t) (((q63_t) out * tempVal) >> 30); */ + out = clip_q63_to_q31(((q63_t) out * tempVal) >> 30); + } + + /* 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. + */ + CMSIS_INLINE __STATIC_INLINE uint32_t arm_recip_q15( + q15_t in, + q15_t * dst, + q15_t * pRecipTable) + { + q15_t out = 0; + uint32_t tempVal = 0; + uint32_t index = 0, i = 0; + uint32_t signBits = 0; + + if (in > 0) + { + signBits = ((uint32_t)(__CLZ( in) - 17)); + } + else + { + signBits = ((uint32_t)(__CLZ(-in) - 17)); + } + + /* Convert input sample to 1.15 format */ + in = (in << signBits); + + /* calculation of index for initial approximated Val */ + index = (uint32_t)(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 = 0u; i < 2u; i++) + { + tempVal = (uint32_t) (((q31_t) in * out) >> 15); + tempVal = 0x7FFFu - tempVal; + /* 1.15 with exp 1 */ + out = (q15_t) (((q31_t) out * tempVal) >> 14); + /* out = clip_q31_to_q15(((q31_t) out * tempVal) >> 14); */ + } + + /* write output */ + *dst = out; + + /* return num of signbits of out = 1/in value */ + return (signBits + 1); + } + + + /* + * @brief C custom defined intrinisic function for only M0 processors + */ +#if defined(ARM_MATH_CM0_FAMILY) + CMSIS_INLINE __STATIC_INLINE q31_t __SSAT( + q31_t x, + uint32_t y) + { + int32_t posMax, negMin; + uint32_t i; + + posMax = 1; + for (i = 0; i < (y - 1); i++) + { + posMax = posMax * 2; + } + + if (x > 0) + { + posMax = (posMax - 1); + + if (x > posMax) + { + x = posMax; + } + } + else + { + negMin = -posMax; + + if (x < negMin) + { + x = negMin; + } + } + return (x); + } +#endif /* end of ARM_MATH_CM0_FAMILY */ + + + /* + * @brief C custom defined intrinsic function for M3 and M0 processors + */ +/* #if defined (ARM_MATH_CM3) || defined (ARM_MATH_CM0_FAMILY) */ +#if !defined (ARM_MATH_DSP) + + /* + * @brief C custom defined QADD8 for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE uint32_t __QADD8( + uint32_t x, + uint32_t y) + { + q31_t r, s, t, u; + + r = __SSAT(((((q31_t)x << 24) >> 24) + (((q31_t)y << 24) >> 24)), 8) & (int32_t)0x000000FF; + s = __SSAT(((((q31_t)x << 16) >> 24) + (((q31_t)y << 16) >> 24)), 8) & (int32_t)0x000000FF; + t = __SSAT(((((q31_t)x << 8) >> 24) + (((q31_t)y << 8) >> 24)), 8) & (int32_t)0x000000FF; + u = __SSAT(((((q31_t)x ) >> 24) + (((q31_t)y ) >> 24)), 8) & (int32_t)0x000000FF; + + return ((uint32_t)((u << 24) | (t << 16) | (s << 8) | (r ))); + } + + + /* + * @brief C custom defined QSUB8 for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE uint32_t __QSUB8( + uint32_t x, + uint32_t y) + { + q31_t r, s, t, u; + + r = __SSAT(((((q31_t)x << 24) >> 24) - (((q31_t)y << 24) >> 24)), 8) & (int32_t)0x000000FF; + s = __SSAT(((((q31_t)x << 16) >> 24) - (((q31_t)y << 16) >> 24)), 8) & (int32_t)0x000000FF; + t = __SSAT(((((q31_t)x << 8) >> 24) - (((q31_t)y << 8) >> 24)), 8) & (int32_t)0x000000FF; + u = __SSAT(((((q31_t)x ) >> 24) - (((q31_t)y ) >> 24)), 8) & (int32_t)0x000000FF; + + return ((uint32_t)((u << 24) | (t << 16) | (s << 8) | (r ))); + } + + + /* + * @brief C custom defined QADD16 for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE uint32_t __QADD16( + uint32_t x, + uint32_t y) + { +/* q31_t r, s; without initialisation 'arm_offset_q15 test' fails but 'intrinsic' tests pass! for armCC */ + q31_t r = 0, s = 0; + + r = __SSAT(((((q31_t)x << 16) >> 16) + (((q31_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF; + s = __SSAT(((((q31_t)x ) >> 16) + (((q31_t)y ) >> 16)), 16) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined SHADD16 for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE uint32_t __SHADD16( + uint32_t x, + uint32_t y) + { + q31_t r, s; + + r = (((((q31_t)x << 16) >> 16) + (((q31_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF; + s = (((((q31_t)x ) >> 16) + (((q31_t)y ) >> 16)) >> 1) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined QSUB16 for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE uint32_t __QSUB16( + uint32_t x, + uint32_t y) + { + q31_t r, s; + + r = __SSAT(((((q31_t)x << 16) >> 16) - (((q31_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF; + s = __SSAT(((((q31_t)x ) >> 16) - (((q31_t)y ) >> 16)), 16) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined SHSUB16 for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE uint32_t __SHSUB16( + uint32_t x, + uint32_t y) + { + q31_t r, s; + + r = (((((q31_t)x << 16) >> 16) - (((q31_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF; + s = (((((q31_t)x ) >> 16) - (((q31_t)y ) >> 16)) >> 1) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined QASX for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE uint32_t __QASX( + uint32_t x, + uint32_t y) + { + q31_t r, s; + + r = __SSAT(((((q31_t)x << 16) >> 16) - (((q31_t)y ) >> 16)), 16) & (int32_t)0x0000FFFF; + s = __SSAT(((((q31_t)x ) >> 16) + (((q31_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined SHASX for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE uint32_t __SHASX( + uint32_t x, + uint32_t y) + { + q31_t r, s; + + r = (((((q31_t)x << 16) >> 16) - (((q31_t)y ) >> 16)) >> 1) & (int32_t)0x0000FFFF; + s = (((((q31_t)x ) >> 16) + (((q31_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined QSAX for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE uint32_t __QSAX( + uint32_t x, + uint32_t y) + { + q31_t r, s; + + r = __SSAT(((((q31_t)x << 16) >> 16) + (((q31_t)y ) >> 16)), 16) & (int32_t)0x0000FFFF; + s = __SSAT(((((q31_t)x ) >> 16) - (((q31_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined SHSAX for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE uint32_t __SHSAX( + uint32_t x, + uint32_t y) + { + q31_t r, s; + + r = (((((q31_t)x << 16) >> 16) + (((q31_t)y ) >> 16)) >> 1) & (int32_t)0x0000FFFF; + s = (((((q31_t)x ) >> 16) - (((q31_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined SMUSDX for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE uint32_t __SMUSDX( + uint32_t x, + uint32_t y) + { + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) - + ((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) )); + } + + /* + * @brief C custom defined SMUADX for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE uint32_t __SMUADX( + uint32_t x, + uint32_t y) + { + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) + + ((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) )); + } + + + /* + * @brief C custom defined QADD for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE int32_t __QADD( + int32_t x, + int32_t y) + { + return ((int32_t)(clip_q63_to_q31((q63_t)x + (q31_t)y))); + } + + + /* + * @brief C custom defined QSUB for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE int32_t __QSUB( + int32_t x, + int32_t y) + { + return ((int32_t)(clip_q63_to_q31((q63_t)x - (q31_t)y))); + } + + + /* + * @brief C custom defined SMLAD for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE uint32_t __SMLAD( + uint32_t x, + uint32_t y, + uint32_t sum) + { + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y << 16) >> 16)) + + ((((q31_t)x ) >> 16) * (((q31_t)y ) >> 16)) + + ( ((q31_t)sum ) ) )); + } + + + /* + * @brief C custom defined SMLADX for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE uint32_t __SMLADX( + uint32_t x, + uint32_t y, + uint32_t sum) + { + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) + + ((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) + + ( ((q31_t)sum ) ) )); + } + + + /* + * @brief C custom defined SMLSDX for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE uint32_t __SMLSDX( + uint32_t x, + uint32_t y, + uint32_t sum) + { + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) - + ((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) + + ( ((q31_t)sum ) ) )); + } + + + /* + * @brief C custom defined SMLALD for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE uint64_t __SMLALD( + uint32_t x, + uint32_t y, + uint64_t sum) + { +/* return (sum + ((q15_t) (x >> 16) * (q15_t) (y >> 16)) + ((q15_t) x * (q15_t) y)); */ + return ((uint64_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y << 16) >> 16)) + + ((((q31_t)x ) >> 16) * (((q31_t)y ) >> 16)) + + ( ((q63_t)sum ) ) )); + } + + + /* + * @brief C custom defined SMLALDX for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE uint64_t __SMLALDX( + uint32_t x, + uint32_t y, + uint64_t sum) + { +/* return (sum + ((q15_t) (x >> 16) * (q15_t) y)) + ((q15_t) x * (q15_t) (y >> 16)); */ + return ((uint64_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) + + ((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) + + ( ((q63_t)sum ) ) )); + } + + + /* + * @brief C custom defined SMUAD for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE uint32_t __SMUAD( + uint32_t x, + uint32_t y) + { + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y << 16) >> 16)) + + ((((q31_t)x ) >> 16) * (((q31_t)y ) >> 16)) )); + } + + + /* + * @brief C custom defined SMUSD for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE uint32_t __SMUSD( + uint32_t x, + uint32_t y) + { + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y << 16) >> 16)) - + ((((q31_t)x ) >> 16) * (((q31_t)y ) >> 16)) )); + } + + + /* + * @brief C custom defined SXTB16 for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE uint32_t __SXTB16( + uint32_t x) + { + return ((uint32_t)(((((q31_t)x << 24) >> 24) & (q31_t)0x0000FFFF) | + ((((q31_t)x << 8) >> 8) & (q31_t)0xFFFF0000) )); + } + + /* + * @brief C custom defined SMMLA for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE int32_t __SMMLA( + int32_t x, + int32_t y, + int32_t sum) + { + return (sum + (int32_t) (((int64_t) x * y) >> 32)); + } + +#if 0 + /* + * @brief C custom defined PKHBT for unavailable DSP extension + */ + CMSIS_INLINE __STATIC_INLINE uint32_t __PKHBT( + uint32_t x, + uint32_t y, + uint32_t leftshift) + { + return ( ((x ) & 0x0000FFFFUL) | + ((y << leftshift) & 0xFFFF0000UL) ); + } + + /* + * @brief C custom defined PKHTB for unavailable DSP extension + */ + CMSIS_INLINE __STATIC_INLINE uint32_t __PKHTB( + uint32_t x, + uint32_t y, + uint32_t rightshift) + { + return ( ((x ) & 0xFFFF0000UL) | + ((y >> rightshift) & 0x0000FFFFUL) ); + } +#endif + +/* #endif // defined (ARM_MATH_CM3) || defined (ARM_MATH_CM0_FAMILY) */ +#endif /* !defined (ARM_MATH_DSP) */ + + + /** + * @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. + */ + 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. + */ + 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. + */ + 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. + */ + 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. + */ + 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. + */ + 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. + */ + 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. + */ + 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. + */ + 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. + */ + 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 + */ + 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. + */ + 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. + */ + 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. + */ + 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 + */ + 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. + */ + 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. + */ + 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 floating-point matrix structure. + */ + typedef struct + { + uint16_t numRows; /**< number of rows of the matrix. */ + uint16_t numCols; /**< number of columns of the matrix. */ + float64_t *pData; /**< points to the data of the matrix. */ + } arm_matrix_instance_f64; + + /** + * @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, complex, 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_cmplx_mult_f32( + const arm_matrix_instance_f32 * pSrcA, + const arm_matrix_instance_f32 * pSrcB, + arm_matrix_instance_f32 * pDst); + + + /** + * @brief Q15, complex, 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_cmplx_mult_q15( + const arm_matrix_instance_q15 * pSrcA, + const arm_matrix_instance_q15 * pSrcB, + arm_matrix_instance_q15 * pDst, + q15_t * pScratch); + + + /** + * @brief Q31, complex, 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_cmplx_mult_q31( + const arm_matrix_instance_q31 * pSrcA, + const arm_matrix_instance_q31 * pSrcB, + arm_matrix_instance_q31 * pDst); + + + /** + * @brief Floating-point matrix transpose. + * @param[in] pSrc points to the input matrix + * @param[out] pDst points to the output matrix + * @return The function returns either ARM_MATH_SIZE_MISMATCH + * or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_trans_f32( + const arm_matrix_instance_f32 * pSrc, + arm_matrix_instance_f32 * pDst); + + + /** + * @brief Q15 matrix transpose. + * @param[in] pSrc points to the input matrix + * @param[out] pDst points to the output matrix + * @return The function returns either ARM_MATH_SIZE_MISMATCH + * or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_trans_q15( + const arm_matrix_instance_q15 * pSrc, + arm_matrix_instance_q15 * pDst); + + + /** + * @brief Q31 matrix transpose. + * @param[in] pSrc points to the input matrix + * @param[out] pDst points to the output matrix + * @return The function returns either ARM_MATH_SIZE_MISMATCH + * or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_trans_q31( + const arm_matrix_instance_q31 * pSrc, + arm_matrix_instance_q31 * pDst); + + + /** + * @brief Floating-point matrix multiplication + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_mult_f32( + const arm_matrix_instance_f32 * pSrcA, + const arm_matrix_instance_f32 * pSrcB, + arm_matrix_instance_f32 * pDst); + + + /** + * @brief Q15 matrix multiplication + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @param[in] pState points to the array for storing intermediate results + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_mult_q15( + const arm_matrix_instance_q15 * pSrcA, + const arm_matrix_instance_q15 * pSrcB, + arm_matrix_instance_q15 * pDst, + q15_t * pState); + + + /** + * @brief Q15 matrix multiplication (fast variant) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @param[in] pState points to the array for storing intermediate results + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_mult_fast_q15( + const arm_matrix_instance_q15 * pSrcA, + const arm_matrix_instance_q15 * pSrcB, + arm_matrix_instance_q15 * pDst, + q15_t * pState); + + + /** + * @brief Q31 matrix multiplication + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_mult_q31( + const arm_matrix_instance_q31 * pSrcA, + const arm_matrix_instance_q31 * pSrcB, + arm_matrix_instance_q31 * pDst); + + + /** + * @brief Q31 matrix multiplication (fast variant) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_mult_fast_q31( + const arm_matrix_instance_q31 * pSrcA, + const arm_matrix_instance_q31 * pSrcB, + arm_matrix_instance_q31 * pDst); + + + /** + * @brief Floating-point matrix subtraction + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_sub_f32( + const arm_matrix_instance_f32 * pSrcA, + const arm_matrix_instance_f32 * pSrcB, + arm_matrix_instance_f32 * pDst); + + + /** + * @brief Q15 matrix subtraction + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_sub_q15( + const arm_matrix_instance_q15 * pSrcA, + const arm_matrix_instance_q15 * pSrcB, + arm_matrix_instance_q15 * pDst); + + + /** + * @brief Q31 matrix subtraction + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_sub_q31( + const arm_matrix_instance_q31 * pSrcA, + const arm_matrix_instance_q31 * pSrcB, + arm_matrix_instance_q31 * pDst); + + + /** + * @brief Floating-point matrix scaling. + * @param[in] pSrc points to the input matrix + * @param[in] scale scale factor + * @param[out] pDst points to the output matrix + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_scale_f32( + const arm_matrix_instance_f32 * pSrc, + float32_t scale, + arm_matrix_instance_f32 * pDst); + + + /** + * @brief Q15 matrix scaling. + * @param[in] pSrc points to input matrix + * @param[in] scaleFract fractional portion of the scale factor + * @param[in] shift number of bits to shift the result by + * @param[out] pDst points to output matrix + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_scale_q15( + const arm_matrix_instance_q15 * pSrc, + q15_t scaleFract, + int32_t shift, + arm_matrix_instance_q15 * pDst); + + + /** + * @brief Q31 matrix scaling. + * @param[in] pSrc points to input matrix + * @param[in] scaleFract fractional portion of the scale factor + * @param[in] shift number of bits to shift the result by + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_scale_q31( + const arm_matrix_instance_q31 * pSrc, + q31_t scaleFract, + int32_t shift, + arm_matrix_instance_q31 * pDst); + + + /** + * @brief Q31 matrix initialization. + * @param[in,out] S points to an instance of the floating-point matrix structure. + * @param[in] nRows number of rows in the matrix. + * @param[in] nColumns number of columns in the matrix. + * @param[in] pData points to the matrix data array. + */ + 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. + */ + 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. + */ + 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 . */ +#if !defined (ARM_MATH_DSP) + 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. + */ + 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 + */ + 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. + */ + 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 + */ + + 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. + */ + 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 + */ + void arm_pid_reset_q15( + arm_pid_instance_q15 * S); + + + /** + * @brief Instance structure for the floating-point Linear Interpolate function. + */ + typedef struct + { + uint32_t nValues; /**< nValues */ + float32_t x1; /**< x1 */ + float32_t xSpacing; /**< xSpacing */ + float32_t *pYData; /**< pointer to the table of Y values */ + } arm_linear_interp_instance_f32; + + /** + * @brief Instance structure for the floating-point bilinear interpolation function. + */ + typedef struct + { + uint16_t numRows; /**< number of rows in the data table. */ + uint16_t numCols; /**< number of columns in the data table. */ + float32_t *pData; /**< points to the data table. */ + } arm_bilinear_interp_instance_f32; + + /** + * @brief Instance structure for the Q31 bilinear interpolation function. + */ + typedef struct + { + uint16_t numRows; /**< number of rows in the data table. */ + uint16_t numCols; /**< number of columns in the data table. */ + q31_t *pData; /**< points to the data table. */ + } arm_bilinear_interp_instance_q31; + + /** + * @brief Instance structure for the Q15 bilinear interpolation function. + */ + typedef struct + { + uint16_t numRows; /**< number of rows in the data table. */ + uint16_t numCols; /**< number of columns in the data table. */ + q15_t *pData; /**< points to the data table. */ + } arm_bilinear_interp_instance_q15; + + /** + * @brief Instance structure for the Q15 bilinear interpolation function. + */ + typedef struct + { + uint16_t numRows; /**< number of rows in the data table. */ + uint16_t numCols; /**< number of columns in the data table. */ + q7_t *pData; /**< points to the data table. */ + } arm_bilinear_interp_instance_q7; + + + /** + * @brief Q7 vector multiplication. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + 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 + */ + 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 + */ + 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 + */ + void arm_mult_f32( + float32_t * pSrcA, + float32_t * pSrcB, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q15 CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + q15_t *pTwiddle; /**< points to the Sin twiddle factor table. */ + uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + } arm_cfft_radix2_instance_q15; + +/* Deprecated */ + arm_status arm_cfft_radix2_init_q15( + arm_cfft_radix2_instance_q15 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + +/* Deprecated */ + void arm_cfft_radix2_q15( + const arm_cfft_radix2_instance_q15 * S, + q15_t * pSrc); + + + /** + * @brief Instance structure for the Q15 CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + q15_t *pTwiddle; /**< points to the twiddle factor table. */ + uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + } arm_cfft_radix4_instance_q15; + +/* Deprecated */ + arm_status arm_cfft_radix4_init_q15( + arm_cfft_radix4_instance_q15 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + +/* Deprecated */ + void arm_cfft_radix4_q15( + const arm_cfft_radix4_instance_q15 * S, + q15_t * pSrc); + + /** + * @brief Instance structure for the Radix-2 Q31 CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + q31_t *pTwiddle; /**< points to the Twiddle factor table. */ + uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + } arm_cfft_radix2_instance_q31; + +/* Deprecated */ + arm_status arm_cfft_radix2_init_q31( + arm_cfft_radix2_instance_q31 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + +/* Deprecated */ + void arm_cfft_radix2_q31( + const arm_cfft_radix2_instance_q31 * S, + q31_t * pSrc); + + /** + * @brief Instance structure for the Q31 CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + q31_t *pTwiddle; /**< points to the twiddle factor table. */ + uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + } arm_cfft_radix4_instance_q31; + +/* Deprecated */ + void arm_cfft_radix4_q31( + const arm_cfft_radix4_instance_q31 * S, + q31_t * pSrc); + +/* Deprecated */ + arm_status arm_cfft_radix4_init_q31( + arm_cfft_radix4_instance_q31 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + + /** + * @brief Instance structure for the floating-point CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + float32_t *pTwiddle; /**< points to the Twiddle factor table. */ + uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + float32_t onebyfftLen; /**< value of 1/fftLen. */ + } arm_cfft_radix2_instance_f32; + +/* Deprecated */ + arm_status arm_cfft_radix2_init_f32( + arm_cfft_radix2_instance_f32 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + +/* Deprecated */ + void arm_cfft_radix2_f32( + const arm_cfft_radix2_instance_f32 * S, + float32_t * pSrc); + + /** + * @brief Instance structure for the floating-point CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + float32_t *pTwiddle; /**< points to the Twiddle factor table. */ + uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + float32_t onebyfftLen; /**< value of 1/fftLen. */ + } arm_cfft_radix4_instance_f32; + +/* Deprecated */ + arm_status arm_cfft_radix4_init_f32( + arm_cfft_radix4_instance_f32 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + +/* Deprecated */ + void arm_cfft_radix4_f32( + const arm_cfft_radix4_instance_f32 * S, + float32_t * pSrc); + + /** + * @brief Instance structure for the fixed-point CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + const q15_t *pTwiddle; /**< points to the Twiddle factor table. */ + const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t bitRevLength; /**< bit reversal table length. */ + } arm_cfft_instance_q15; + +void arm_cfft_q15( + const arm_cfft_instance_q15 * S, + q15_t * p1, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + + /** + * @brief Instance structure for the fixed-point CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + const q31_t *pTwiddle; /**< points to the Twiddle factor table. */ + const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t bitRevLength; /**< bit reversal table length. */ + } arm_cfft_instance_q31; + +void arm_cfft_q31( + const arm_cfft_instance_q31 * S, + q31_t * p1, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + + /** + * @brief Instance structure for the floating-point CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + const float32_t *pTwiddle; /**< points to the Twiddle factor table. */ + const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t bitRevLength; /**< bit reversal table length. */ + } arm_cfft_instance_f32; + + void arm_cfft_f32( + const arm_cfft_instance_f32 * S, + float32_t * p1, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + + /** + * @brief Instance structure for the Q15 RFFT/RIFFT function. + */ + typedef struct + { + uint32_t fftLenReal; /**< length of the real FFT. */ + 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. */ + const arm_cfft_instance_q15 *pCfft; /**< points to the complex FFT instance. */ + } arm_rfft_instance_q15; + + arm_status arm_rfft_init_q15( + arm_rfft_instance_q15 * S, + uint32_t fftLenReal, + uint32_t ifftFlagR, + uint32_t bitReverseFlag); + + void arm_rfft_q15( + const arm_rfft_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst); + + /** + * @brief Instance structure for the Q31 RFFT/RIFFT function. + */ + typedef struct + { + uint32_t fftLenReal; /**< length of the real FFT. */ + 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. */ + const arm_cfft_instance_q31 *pCfft; /**< points to the complex FFT instance. */ + } arm_rfft_instance_q31; + + arm_status arm_rfft_init_q31( + arm_rfft_instance_q31 * S, + uint32_t fftLenReal, + uint32_t ifftFlagR, + uint32_t bitReverseFlag); + + void arm_rfft_q31( + const arm_rfft_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst); + + /** + * @brief Instance structure for the floating-point RFFT/RIFFT function. + */ + typedef struct + { + uint32_t fftLenReal; /**< length of the real FFT. */ + uint16_t fftLenBy2; /**< length of the complex FFT. */ + uint8_t ifftFlagR; /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */ + uint8_t bitReverseFlagR; /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */ + uint32_t twidCoefRModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + float32_t *pTwiddleAReal; /**< points to the real twiddle factor table. */ + float32_t *pTwiddleBReal; /**< points to the imag twiddle factor table. */ + arm_cfft_radix4_instance_f32 *pCfft; /**< points to the complex FFT instance. */ + } arm_rfft_instance_f32; + + arm_status arm_rfft_init_f32( + arm_rfft_instance_f32 * S, + arm_cfft_radix4_instance_f32 * S_CFFT, + uint32_t fftLenReal, + uint32_t ifftFlagR, + uint32_t bitReverseFlag); + + void arm_rfft_f32( + const arm_rfft_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst); + + /** + * @brief Instance structure for the floating-point RFFT/RIFFT function. + */ +typedef struct + { + arm_cfft_instance_f32 Sint; /**< Internal CFFT structure. */ + uint16_t fftLenRFFT; /**< length of the real sequence */ + float32_t * pTwiddleRFFT; /**< Twiddle factors real stage */ + } arm_rfft_fast_instance_f32 ; + +arm_status arm_rfft_fast_init_f32 ( + arm_rfft_fast_instance_f32 * S, + uint16_t fftLen); + +void arm_rfft_fast_f32( + arm_rfft_fast_instance_f32 * S, + float32_t * p, float32_t * pOut, + uint8_t ifftFlag); + + /** + * @brief Instance structure for the floating-point DCT4/IDCT4 function. + */ + typedef struct + { + uint16_t N; /**< length of the DCT4. */ + uint16_t Nby2; /**< half of the length of the DCT4. */ + float32_t normalize; /**< normalizing factor. */ + float32_t *pTwiddle; /**< points to the twiddle factor table. */ + float32_t *pCosFactor; /**< points to the cosFactor table. */ + arm_rfft_instance_f32 *pRfft; /**< points to the real FFT instance. */ + arm_cfft_radix4_instance_f32 *pCfft; /**< points to the complex FFT instance. */ + } arm_dct4_instance_f32; + + + /** + * @brief Initialization function for the floating-point DCT4/IDCT4. + * @param[in,out] S points to an instance of floating-point DCT4/IDCT4 structure. + * @param[in] S_RFFT points to an instance of floating-point RFFT/RIFFT structure. + * @param[in] S_CFFT points to an instance of floating-point CFFT/CIFFT structure. + * @param[in] N length of the DCT4. + * @param[in] Nby2 half of the length of the DCT4. + * @param[in] normalize normalizing factor. + * @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if fftLenReal is not a supported transform length. + */ + arm_status arm_dct4_init_f32( + arm_dct4_instance_f32 * S, + arm_rfft_instance_f32 * S_RFFT, + arm_cfft_radix4_instance_f32 * S_CFFT, + uint16_t N, + uint16_t Nby2, + float32_t normalize); + + + /** + * @brief Processing function for the floating-point DCT4/IDCT4. + * @param[in] S points to an instance of the floating-point DCT4/IDCT4 structure. + * @param[in] pState points to state buffer. + * @param[in,out] pInlineBuffer points to the in-place input and output buffer. + */ + 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. + */ + 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. + */ + 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 + */ + 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 + */ + 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 + */ + 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 + */ + 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 + */ + 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 + */ + 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 + */ + 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 + */ + 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 + */ + 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 + */ + 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 + */ + 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 + */ + 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 + */ + 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 + */ + 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 + */ + 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 + */ + 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 + */ + 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 + */ + 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 + */ + 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 + */ + 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 + */ + 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 + */ + 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 + */ + 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 + */ + 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 + */ + 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 + */ + 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 + */ + 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 + */ + 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 + */ + 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 + */ + 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 + */ + 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 + */ + 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 + */ + 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 + */ + 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 + */ + 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 + */ + 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 + */ + 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 + */ + 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 + */ + 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. + */ + void arm_conv_f32( + float32_t * pSrcA, + uint32_t srcALen, + float32_t * pSrcB, + uint32_t srcBLen, + float32_t * pDst); + + + /** + * @brief Convolution of Q15 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. + * @param[in] pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] pScratch2 points to scratch buffer of size min(srcALen, srcBLen). + */ + void arm_conv_opt_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + q15_t * pScratch1, + q15_t * pScratch2); + + +/** + * @brief Convolution of Q15 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the location where the output result is written. Length srcALen+srcBLen-1. + */ + 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. + */ + void arm_conv_fast_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst); + + + /** + * @brief Convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. + * @param[in] pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] pScratch2 points to scratch buffer of size min(srcALen, srcBLen). + */ + void arm_conv_fast_opt_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + q15_t * pScratch1, + q15_t * pScratch2); + + + /** + * @brief Convolution of Q31 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. + */ + 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. + */ + void arm_conv_fast_q31( + q31_t * pSrcA, + uint32_t srcALen, + q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst); + + + /** + * @brief Convolution of Q7 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. + * @param[in] pScratch1 points to scratch buffer(of type q15_t) of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] pScratch2 points to scratch buffer (of type q15_t) of size min(srcALen, srcBLen). + */ + void arm_conv_opt_q7( + q7_t * pSrcA, + uint32_t srcALen, + q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst, + q15_t * pScratch1, + q15_t * pScratch2); + + + /** + * @brief Convolution of Q7 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. + */ + void arm_conv_q7( + q7_t * pSrcA, + uint32_t srcALen, + q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst); + + + /** + * @brief Partial convolution of floating-point sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_f32( + float32_t * pSrcA, + uint32_t srcALen, + float32_t * pSrcB, + uint32_t srcBLen, + float32_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + + /** + * @brief Partial convolution of Q15 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @param[in] pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] pScratch2 points to scratch buffer of size min(srcALen, srcBLen). + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_opt_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + uint32_t firstIndex, + uint32_t numPoints, + q15_t * pScratch1, + q15_t * pScratch2); + + + /** + * @brief Partial convolution of Q15 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + + /** + * @brief Partial convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_fast_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + + /** + * @brief Partial convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @param[in] pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] pScratch2 points to scratch buffer of size min(srcALen, srcBLen). + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_fast_opt_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + uint32_t firstIndex, + uint32_t numPoints, + q15_t * pScratch1, + q15_t * pScratch2); + + + /** + * @brief Partial convolution of Q31 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_q31( + q31_t * pSrcA, + uint32_t srcALen, + q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + + /** + * @brief Partial convolution of Q31 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_fast_q31( + q31_t * pSrcA, + uint32_t srcALen, + q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + + /** + * @brief Partial convolution of Q7 sequences + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @param[in] pScratch1 points to scratch buffer(of type q15_t) of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] pScratch2 points to scratch buffer (of type q15_t) of size min(srcALen, srcBLen). + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_opt_q7( + q7_t * pSrcA, + uint32_t srcALen, + q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst, + uint32_t firstIndex, + uint32_t numPoints, + q15_t * pScratch1, + q15_t * pScratch2); + + +/** + * @brief Partial convolution of Q7 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_q7( + q7_t * pSrcA, + uint32_t srcALen, + q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + + /** + * @brief Instance structure for the Q15 FIR decimator. + */ + typedef struct + { + uint8_t M; /**< decimation factor. */ + uint16_t numTaps; /**< number of coefficients in the filter. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + } arm_fir_decimate_instance_q15; + + /** + * @brief Instance structure for the Q31 FIR decimator. + */ + typedef struct + { + uint8_t M; /**< decimation factor. */ + uint16_t numTaps; /**< number of coefficients in the filter. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + } arm_fir_decimate_instance_q31; + + /** + * @brief Instance structure for the floating-point FIR decimator. + */ + typedef struct + { + uint8_t M; /**< decimation factor. */ + uint16_t numTaps; /**< number of coefficients in the filter. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + } arm_fir_decimate_instance_f32; + + + /** + * @brief Processing function for the floating-point FIR decimator. + * @param[in] S points to an instance of the floating-point FIR decimator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of input samples to process per call. + */ + 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. + */ + 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. + */ + 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. + */ + 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. + */ + 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. + */ + 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. + */ + 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. + */ + 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. + */ + 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 + */ + 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 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 4*numStages. */ + float32_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */ + } arm_biquad_cascade_stereo_df2T_instance_f32; + + /** + * @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. */ + float64_t *pState; /**< points to the array of state coefficients. The array is of length 2*numStages. */ + float64_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */ + } arm_biquad_cascade_df2T_instance_f64; + + + /** + * @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. + */ + void arm_biquad_cascade_df2T_f32( + const arm_biquad_cascade_df2T_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Processing function for the floating-point transposed direct form II Biquad cascade filter. 2 channels + * @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. + */ + void arm_biquad_cascade_stereo_df2T_f32( + const arm_biquad_cascade_stereo_df2T_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @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. + */ + void arm_biquad_cascade_df2T_f64( + const arm_biquad_cascade_df2T_instance_f64 * S, + float64_t * pSrc, + float64_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. + */ + void arm_biquad_cascade_df2T_init_f32( + arm_biquad_cascade_df2T_instance_f32 * S, + uint8_t numStages, + float32_t * pCoeffs, + float32_t * pState); + + + /** + * @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. + */ + void arm_biquad_cascade_stereo_df2T_init_f32( + arm_biquad_cascade_stereo_df2T_instance_f32 * S, + uint8_t numStages, + float32_t * pCoeffs, + float32_t * pState); + + + /** + * @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. + */ + void arm_biquad_cascade_df2T_init_f64( + arm_biquad_cascade_df2T_instance_f64 * S, + uint8_t numStages, + float64_t * pCoeffs, + float64_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. + */ + 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. + */ + 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. + */ + 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. + */ + 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. + */ + 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. + */ + 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. + */ + 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. + */ + 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. + */ + 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. + */ + 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. + */ + 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. + */ + 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. + */ + 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. + */ + 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. + */ + 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. + */ + 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. + */ + 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. + */ + 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. + */ + 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. + */ + 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. + */ + 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. + */ + 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. + */ + 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. + */ + 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. + */ + void arm_correlate_f32( + float32_t * pSrcA, + uint32_t srcALen, + float32_t * pSrcB, + uint32_t srcBLen, + float32_t * pDst); + + + /** + * @brief Correlation of Q15 sequences + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + * @param[in] pScratch points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + */ + void arm_correlate_opt_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + q15_t * pScratch); + + + /** + * @brief Correlation of Q15 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + */ + + 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. + */ + + void arm_correlate_fast_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst); + + + /** + * @brief Correlation of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + * @param[in] pScratch points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + */ + void arm_correlate_fast_opt_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + q15_t * pScratch); + + + /** + * @brief Correlation of Q31 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + */ + 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. + */ + void arm_correlate_fast_q31( + q31_t * pSrcA, + uint32_t srcALen, + q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst); + + + /** + * @brief Correlation of Q7 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + * @param[in] pScratch1 points to scratch buffer(of type q15_t) of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] pScratch2 points to scratch buffer (of type q15_t) of size min(srcALen, srcBLen). + */ + void arm_correlate_opt_q7( + q7_t * pSrcA, + uint32_t srcALen, + q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst, + q15_t * pScratch1, + q15_t * pScratch2); + + + /** + * @brief Correlation of Q7 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + */ + 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. + */ + 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. + */ + 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. + */ + 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. + */ + 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. + */ + 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. + */ + 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. + */ + 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. + */ + 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. + */ + void arm_sin_cos_f32( + float32_t theta, + float32_t * pSinVal, + float32_t * pCosVal); + + + /** + * @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. + */ + 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 + */ + 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 + */ + 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 + */ + 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 + */ + 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 + */ + 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 + */ + 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. + */ + CMSIS_INLINE __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. + */ + CMSIS_INLINE __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. + */ + CMSIS_INLINE __STATIC_INLINE q15_t arm_pid_q15( + arm_pid_instance_q15 * S, + q15_t in) + { + q63_t acc; + q15_t out; + +#if defined (ARM_MATH_DSP) + __SIMD32_TYPE *vstate; + + /* Implementation of PID controller */ + + /* acc = A0 * x[n] */ + acc = (q31_t) __SMUAD((uint32_t)S->A0, (uint32_t)in); + + /* acc += A1 * x[n-1] + A2 * x[n-2] */ + vstate = __SIMD32_CONST(S->state); + acc = (q63_t)__SMLALD((uint32_t)S->A1, (uint32_t)*vstate, (uint64_t)acc); +#else + /* acc = A0 * x[n] */ + acc = ((q31_t) S->A0) * in; + + /* acc += A1 * x[n-1] + A2 * x[n-2] */ + acc += (q31_t) S->A1 * S->state[0]; + acc += (q31_t) S->A2 * S->state[1]; +#endif + + /* acc += y[n-1] */ + acc += (q31_t) S->state[2] << 15; + + /* saturate the output */ + out = (q15_t) (__SSAT((acc >> 15), 16)); + + /* Update state */ + S->state[1] = S->state[0]; + S->state[0] = in; + S->state[2] = out; + + /* return to application */ + return (out); + } + + /** + * @} end of PID group + */ + + + /** + * @brief Floating-point matrix inverse. + * @param[in] src points to the instance of the input floating-point matrix structure. + * @param[out] dst points to the instance of the output floating-point matrix structure. + * @return The function returns ARM_MATH_SIZE_MISMATCH, if the dimensions do not match. + * If the input matrix is singular (does not have an inverse), then the algorithm terminates and returns error status ARM_MATH_SINGULAR. + */ + arm_status arm_mat_inverse_f32( + const arm_matrix_instance_f32 * src, + arm_matrix_instance_f32 * dst); + + + /** + * @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_f64( + const arm_matrix_instance_f64 * src, + arm_matrix_instance_f64 * 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 + */ + CMSIS_INLINE __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 + * + * 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. + */ + CMSIS_INLINE __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 + */ + 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 + */ + CMSIS_INLINE __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.5f * Ialpha + 0.8660254039f * 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 + * + * 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. + */ + CMSIS_INLINE __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 + */ + 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 + * + * The function implements the forward Park transform. + * + */ + CMSIS_INLINE __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 + * + * 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. + */ + CMSIS_INLINE __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 + */ + 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 + */ + CMSIS_INLINE __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 + * + * 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. + */ + CMSIS_INLINE __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 + */ + 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. + * + */ + CMSIS_INLINE __STATIC_INLINE float32_t arm_linear_interp_f32( + arm_linear_interp_instance_f32 * S, + float32_t x) + { + float32_t y; + float32_t x0, x1; /* Nearest input values */ + float32_t y0, y1; /* Nearest output values */ + float32_t xSpacing = S->xSpacing; /* spacing between input values */ + int32_t i; /* Index variable */ + float32_t *pYData = S->pYData; /* pointer to output table */ + + /* Calculation of index */ + i = (int32_t) ((x - S->x1) / xSpacing); + + if (i < 0) + { + /* Iniatilize output for below specified range as least output value of table */ + y = pYData[0]; + } + else if ((uint32_t)i >= S->nValues) + { + /* Iniatilize output for above specified range as last output value of table */ + y = pYData[S->nValues - 1]; + } + else + { + /* Calculation of nearest input values */ + x0 = S->x1 + i * xSpacing; + x1 = S->x1 + (i + 1) * xSpacing; + + /* Read of nearest output values */ + y0 = pYData[i]; + y1 = pYData[i + 1]; + + /* Calculation of output */ + y = y0 + (x - x0) * ((y1 - y0) / (x1 - x0)); + + } + + /* returns output value */ + return (y); + } + + + /** + * + * @brief Process function for the Q31 Linear Interpolation Function. + * @param[in] pYData pointer to Q31 Linear Interpolation table + * @param[in] x input sample to process + * @param[in] nValues number of table values + * @return y processed output sample. + * + * \par + * Input sample x is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part. + * This function can support maximum of table size 2^12. + * + */ + CMSIS_INLINE __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 & (q31_t)0xFFF00000) >> 20); + + if (index >= (int32_t)(nValues - 1)) + { + return (pYData[nValues - 1]); + } + else if (index < 0) + { + return (pYData[0]); + } + else + { + /* 20 bits for the fractional part */ + /* shift left by 11 to keep fract in 1.31 format */ + fract = (x & 0x000FFFFF) << 11; + + /* Read two nearest output values from the index in 1.31(q31) format */ + y0 = pYData[index]; + y1 = pYData[index + 1]; + + /* 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. + * + */ + CMSIS_INLINE __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 & (int32_t)0xFFF00000) >> 20); + + if (index >= (int32_t)(nValues - 1)) + { + return (pYData[nValues - 1]); + } + else if (index < 0) + { + return (pYData[0]); + } + else + { + /* 20 bits for the fractional part */ + /* fract is in 12.20 format */ + fract = (x & 0x000FFFFF); + + /* Read two nearest output values from the index */ + y0 = pYData[index]; + y1 = pYData[index + 1]; + + /* 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 (q15_t) (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. + */ + CMSIS_INLINE __STATIC_INLINE q7_t arm_linear_interp_q7( + q7_t * pYData, + q31_t x, + uint32_t nValues) + { + q31_t y; /* output */ + q7_t y0, y1; /* Nearest output values */ + q31_t fract; /* fractional part */ + uint32_t index; /* Index to read nearest output values */ + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + if (x < 0) + { + return (pYData[0]); + } + index = (x >> 20) & 0xfff; + + if (index >= (nValues - 1)) + { + return (pYData[nValues - 1]); + } + else + { + /* 20 bits for the fractional part */ + /* fract is in 12.20 format */ + fract = (x & 0x000FFFFF); + + /* Read two nearest output values from the index and are in 1.7(q7) format */ + y0 = pYData[index]; + y1 = pYData[index + 1]; + + /* 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 (q7_t) (y >> 20); + } + } + + /** + * @} 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. + */ + CMSIS_INLINE __STATIC_INLINE arm_status arm_sqrt_f32( + float32_t in, + float32_t * pOut) + { + if (in >= 0.0f) + { + +#if (__FPU_USED == 1) && defined ( __CC_ARM ) + *pOut = __sqrtf(in); +#elif (__FPU_USED == 1) && (defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)) + *pOut = __builtin_sqrtf(in); +#elif (__FPU_USED == 1) && defined(__GNUC__) + *pOut = __builtin_sqrtf(in); +#elif (__FPU_USED == 1) && defined ( __ICCARM__ ) && (__VER__ >= 6040000) + __ASM("VSQRT.F32 %0,%1" : "=t"(*pOut) : "t"(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. + */ + CMSIS_INLINE __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 = (uint16_t)wOffset; + } + + + + /** + * @brief floating-point Circular Read function. + */ + CMSIS_INLINE __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. + */ + CMSIS_INLINE __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 = (uint16_t)wOffset; + } + + + /** + * @brief Q15 Circular Read function. + */ + CMSIS_INLINE __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. + */ + CMSIS_INLINE __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 = (uint16_t)wOffset; + } + + + /** + * @brief Q7 Circular Read function. + */ + CMSIS_INLINE __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. + */ + 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. + */ + 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. + */ + 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. + */ + 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. + */ + 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. + */ + 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. + */ + 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. + */ + 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. + */ + 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. + */ + void arm_var_q31( + q31_t * pSrc, + uint32_t blockSize, + q31_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. + */ + void arm_var_q15( + q15_t * pSrc, + uint32_t blockSize, + q15_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. + */ + 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. + */ + 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. + */ + 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. + */ + 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. + */ + 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. + */ + 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 + */ + 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 + */ + 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 + */ + 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 + */ + 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 + */ + 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 + */ + 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 + */ + 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 + */ + 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 + */ + 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. + */ + 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. + */ + 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. + */ + 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. + */ + 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 + */ + 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 + */ + 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 + */ + 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 + */ + 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 + */ + 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 + */ + 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 + */ + 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 + */ + 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 + */ + 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 + */ + 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 + */ + 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 + */ + 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 + */ + 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 + */ + 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 + */ + 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. + */ + CMSIS_INLINE __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. + */ + CMSIS_INLINE __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 & (q31_t)0xFFF00000) >> 20); + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + cI = ((Y & (q31_t)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 */ + /* 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) + (int32_t)nCols * (cI) ]; + x2 = pYData[(rI) + (int32_t)nCols * (cI) + 1]; + + /* 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) + (int32_t)nCols * (cI + 1) ]; + y2 = pYData[(rI) + (int32_t)nCols * (cI + 1) + 1]; + + /* 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 ((q31_t)(acc << 2)); + } + + + /** + * @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. + */ + CMSIS_INLINE __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 & (q31_t)0xFFF00000) >> 20); + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + cI = ((Y & (q31_t)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[((uint32_t)rI) + nCols * ((uint32_t)cI) ]; + x2 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI) + 1]; + + /* 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[((uint32_t)rI) + nCols * ((uint32_t)cI + 1) ]; + y2 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI + 1) + 1]; + + /* 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 ((q15_t)(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. + */ + CMSIS_INLINE __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 & (q31_t)0xFFF00000) >> 20); + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + cI = ((Y & (q31_t)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 & (q31_t)0x000FFFFF); + + /* Read two nearest output values from the index */ + x1 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI) ]; + x2 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI) + 1]; + + /* 20 bits for the fractional part */ + /* yfract should be in 12.20 format */ + yfract = (Y & (q31_t)0x000FFFFF); + + /* Read two nearest output values from the index */ + y1 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI + 1) ]; + y2 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI + 1) + 1]; + + /* 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 ((q7_t)(acc >> 40)); + } + + /** + * @} end of BilinearInterpolate group + */ + + +/* SMMLAR */ +#define multAcc_32x32_keep32_R(a, x, y) \ + a = (q31_t) (((((q63_t) a) << 32) + ((q63_t) x * y) + 0x80000000LL ) >> 32) + +/* SMMLSR */ +#define multSub_32x32_keep32_R(a, x, y) \ + a = (q31_t) (((((q63_t) a) << 32) - ((q63_t) x * y) + 0x80000000LL ) >> 32) + +/* SMMULR */ +#define mult_32x32_keep32_R(a, x, y) \ + a = (q31_t) (((q63_t) x * y + 0x80000000LL ) >> 32) + +/* SMMLA */ +#define multAcc_32x32_keep32(a, x, y) \ + a += (q31_t) (((q63_t) x * y) >> 32) + +/* SMMLS */ +#define multSub_32x32_keep32(a, x, y) \ + a -= (q31_t) (((q63_t) x * y) >> 32) + +/* SMMUL */ +#define mult_32x32_keep32(a, x, y) \ + a = (q31_t) (((q63_t) x * y ) >> 32) + + +#if defined ( __CC_ARM ) + /* Enter low optimization region - place directly above function definition */ + #if defined( ARM_MATH_CM4 ) || defined( ARM_MATH_CM7) + #define LOW_OPTIMIZATION_ENTER \ + _Pragma ("push") \ + _Pragma ("O1") + #else + #define LOW_OPTIMIZATION_ENTER + #endif + + /* Exit low optimization region - place directly after end of function definition */ + #if defined ( ARM_MATH_CM4 ) || defined ( ARM_MATH_CM7 ) + #define LOW_OPTIMIZATION_EXIT \ + _Pragma ("pop") + #else + #define LOW_OPTIMIZATION_EXIT + #endif + + /* Enter low optimization region - place directly above function definition */ + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER + + /* Exit low optimization region - place directly after end of function definition */ + #define IAR_ONLY_LOW_OPTIMIZATION_EXIT + +#elif defined (__ARMCC_VERSION ) && ( __ARMCC_VERSION >= 6010050 ) + #define LOW_OPTIMIZATION_ENTER + #define LOW_OPTIMIZATION_EXIT + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER + #define IAR_ONLY_LOW_OPTIMIZATION_EXIT + +#elif defined ( __GNUC__ ) + #define LOW_OPTIMIZATION_ENTER \ + __attribute__(( optimize("-O1") )) + #define LOW_OPTIMIZATION_EXIT + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER + #define IAR_ONLY_LOW_OPTIMIZATION_EXIT + +#elif defined ( __ICCARM__ ) + /* Enter low optimization region - place directly above function definition */ + #if defined ( ARM_MATH_CM4 ) || defined ( ARM_MATH_CM7 ) + #define LOW_OPTIMIZATION_ENTER \ + _Pragma ("optimize=low") + #else + #define LOW_OPTIMIZATION_ENTER + #endif + + /* Exit low optimization region - place directly after end of function definition */ + #define LOW_OPTIMIZATION_EXIT + + /* Enter low optimization region - place directly above function definition */ + #if defined ( ARM_MATH_CM4 ) || defined ( ARM_MATH_CM7 ) + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER \ + _Pragma ("optimize=low") + #else + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER + #endif + + /* Exit low optimization region - place directly after end of function definition */ + #define IAR_ONLY_LOW_OPTIMIZATION_EXIT + +#elif defined ( __TI_ARM__ ) + #define LOW_OPTIMIZATION_ENTER + #define LOW_OPTIMIZATION_EXIT + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER + #define IAR_ONLY_LOW_OPTIMIZATION_EXIT + +#elif defined ( __CSMC__ ) + #define LOW_OPTIMIZATION_ENTER + #define LOW_OPTIMIZATION_EXIT + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER + #define IAR_ONLY_LOW_OPTIMIZATION_EXIT + +#elif defined ( __TASKING__ ) + #define LOW_OPTIMIZATION_ENTER + #define LOW_OPTIMIZATION_EXIT + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER + #define IAR_ONLY_LOW_OPTIMIZATION_EXIT + +#endif + + +#ifdef __cplusplus +} +#endif + + +#if defined ( __GNUC__ ) +#pragma GCC diagnostic pop +#endif + +#endif /* _ARM_MATH_H */ + +/** + * + * End of file. + */ diff --git a/cmsis/core_armv8mbl.h b/cmsis/core_armv8mbl.h new file mode 100644 index 00000000000..d03935201ce --- /dev/null +++ b/cmsis/core_armv8mbl.h @@ -0,0 +1,1876 @@ +/**************************************************************************//** + * @file core_armv8mbl.h + * @brief CMSIS ARMv8MBL Core Peripheral Access Layer Header File + * @version V5.0.2 + * @date 13. February 2017 + ******************************************************************************/ +/* + * Copyright (c) 2009-2017 ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_ARMV8MBL_H_GENERIC +#define __CORE_ARMV8MBL_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex_ARMv8MBL + @{ + */ + +/* CMSIS cmGrebe definitions */ +#define __ARMv8MBL_CMSIS_VERSION_MAIN ( 5U) /*!< [31:16] CMSIS HAL main version */ +#define __ARMv8MBL_CMSIS_VERSION_SUB ( 0U) /*!< [15:0] CMSIS HAL sub version */ +#define __ARMv8MBL_CMSIS_VERSION ((__ARMv8MBL_CMSIS_VERSION_MAIN << 16U) | \ + __ARMv8MBL_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */ + +#define __CORTEX_M ( 2U) /*!< Cortex-M Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + This core does not support an FPU at all +*/ +#define __FPU_USED 0U + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_PCS_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_ARMV8MBL_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_ARMV8MBL_H_DEPENDANT +#define __CORE_ARMV8MBL_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __ARMv8MBL_REV + #define __ARMv8MBL_REV 0x0000U + #warning "__ARMv8MBL_REV not defined in device header file; using default!" + #endif + + #ifndef __FPU_PRESENT + #define __FPU_PRESENT 0U + #warning "__FPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __SAUREGION_PRESENT + #define __SAUREGION_PRESENT 0U + #warning "__SAUREGION_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __VTOR_PRESENT + #define __VTOR_PRESENT 0U + #warning "__VTOR_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 2U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif + + #ifndef __ETM_PRESENT + #define __ETM_PRESENT 0U + #warning "__ETM_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __MTB_PRESENT + #define __MTB_PRESENT 0U + #warning "__MTB_PRESENT not defined in device header file; using default!" + #endif + +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group ARMv8MBL */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + - Core SAU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:28; /*!< bit: 0..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack-pointer select */ + uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[16U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[16U]; + __IOM uint32_t ICER[16U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[16U]; + __IOM uint32_t ISPR[16U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[16U]; + __IOM uint32_t ICPR[16U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[16U]; + __IOM uint32_t IABR[16U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[16U]; + __IOM uint32_t ITNS[16U]; /*!< Offset: 0x280 (R/W) Interrupt Non-Secure State Register */ + uint32_t RESERVED5[16U]; + __IOM uint32_t IPR[124U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */ +} NVIC_Type; + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ +#else + uint32_t RESERVED0; +#endif + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + uint32_t RESERVED1; + __IOM uint32_t SHPR[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_PENDNMISET_Pos 31U /*!< SCB ICSR: PENDNMISET Position */ +#define SCB_ICSR_PENDNMISET_Msk (1UL << SCB_ICSR_PENDNMISET_Pos) /*!< SCB ICSR: PENDNMISET Mask */ + +#define SCB_ICSR_PENDNMICLR_Pos 30U /*!< SCB ICSR: PENDNMICLR Position */ +#define SCB_ICSR_PENDNMICLR_Msk (1UL << SCB_ICSR_PENDNMICLR_Pos) /*!< SCB ICSR: PENDNMICLR Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_STTNS_Pos 24U /*!< SCB ICSR: STTNS Position (Security Extension) */ +#define SCB_ICSR_STTNS_Msk (1UL << SCB_ICSR_STTNS_Pos) /*!< SCB ICSR: STTNS Mask (Security Extension) */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) +/* SCB Vector Table Offset Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ +#endif + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIS_Pos 14U /*!< SCB AIRCR: PRIS Position */ +#define SCB_AIRCR_PRIS_Msk (1UL << SCB_AIRCR_PRIS_Pos) /*!< SCB AIRCR: PRIS Mask */ + +#define SCB_AIRCR_BFHFNMINS_Pos 13U /*!< SCB AIRCR: BFHFNMINS Position */ +#define SCB_AIRCR_BFHFNMINS_Msk (1UL << SCB_AIRCR_BFHFNMINS_Pos) /*!< SCB AIRCR: BFHFNMINS Mask */ + +#define SCB_AIRCR_SYSRESETREQS_Pos 3U /*!< SCB AIRCR: SYSRESETREQS Position */ +#define SCB_AIRCR_SYSRESETREQS_Msk (1UL << SCB_AIRCR_SYSRESETREQS_Pos) /*!< SCB AIRCR: SYSRESETREQS Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEPS_Pos 3U /*!< SCB SCR: SLEEPDEEPS Position */ +#define SCB_SCR_SLEEPDEEPS_Msk (1UL << SCB_SCR_SLEEPDEEPS_Pos) /*!< SCB SCR: SLEEPDEEPS Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_BP_Pos 18U /*!< SCB CCR: BP Position */ +#define SCB_CCR_BP_Msk (1UL << SCB_CCR_BP_Pos) /*!< SCB CCR: BP Mask */ + +#define SCB_CCR_IC_Pos 17U /*!< SCB CCR: IC Position */ +#define SCB_CCR_IC_Msk (1UL << SCB_CCR_IC_Pos) /*!< SCB CCR: IC Mask */ + +#define SCB_CCR_DC_Pos 16U /*!< SCB CCR: DC Position */ +#define SCB_CCR_DC_Msk (1UL << SCB_CCR_DC_Pos) /*!< SCB CCR: DC Mask */ + +#define SCB_CCR_STKOFHFNMIGN_Pos 10U /*!< SCB CCR: STKOFHFNMIGN Position */ +#define SCB_CCR_STKOFHFNMIGN_Msk (1UL << SCB_CCR_STKOFHFNMIGN_Pos) /*!< SCB CCR: STKOFHFNMIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< 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 4U /*!< 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 3U /*!< 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 1U /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_HARDFAULTPENDED_Pos 21U /*!< SCB SHCSR: HARDFAULTPENDED Position */ +#define SCB_SHCSR_HARDFAULTPENDED_Msk (1UL << SCB_SHCSR_HARDFAULTPENDED_Pos) /*!< SCB SHCSR: HARDFAULTPENDED Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_NMIACT_Pos 5U /*!< SCB SHCSR: NMIACT Position */ +#define SCB_SHCSR_NMIACT_Msk (1UL << SCB_SHCSR_NMIACT_Pos) /*!< SCB SHCSR: NMIACT Mask */ + +#define SCB_SHCSR_HARDFAULTACT_Pos 2U /*!< SCB SHCSR: HARDFAULTACT Position */ +#define SCB_SHCSR_HARDFAULTACT_Msk (1UL << SCB_SHCSR_HARDFAULTACT_Pos) /*!< SCB SHCSR: HARDFAULTACT Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** + \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + uint32_t RESERVED0[6U]; + __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + uint32_t RESERVED1[1U]; + __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + uint32_t RESERVED3[1U]; + __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED4[1U]; + __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + uint32_t RESERVED5[1U]; + __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED6[1U]; + __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + uint32_t RESERVED7[1U]; + __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ + uint32_t RESERVED8[1U]; + __IOM uint32_t COMP4; /*!< Offset: 0x060 (R/W) Comparator Register 4 */ + uint32_t RESERVED9[1U]; + __IOM uint32_t FUNCTION4; /*!< Offset: 0x068 (R/W) Function Register 4 */ + uint32_t RESERVED10[1U]; + __IOM uint32_t COMP5; /*!< Offset: 0x070 (R/W) Comparator Register 5 */ + uint32_t RESERVED11[1U]; + __IOM uint32_t FUNCTION5; /*!< Offset: 0x078 (R/W) Function Register 5 */ + uint32_t RESERVED12[1U]; + __IOM uint32_t COMP6; /*!< Offset: 0x080 (R/W) Comparator Register 6 */ + uint32_t RESERVED13[1U]; + __IOM uint32_t FUNCTION6; /*!< Offset: 0x088 (R/W) Function Register 6 */ + uint32_t RESERVED14[1U]; + __IOM uint32_t COMP7; /*!< Offset: 0x090 (R/W) Comparator Register 7 */ + uint32_t RESERVED15[1U]; + __IOM uint32_t FUNCTION7; /*!< Offset: 0x098 (R/W) Function Register 7 */ + uint32_t RESERVED16[1U]; + __IOM uint32_t COMP8; /*!< Offset: 0x0A0 (R/W) Comparator Register 8 */ + uint32_t RESERVED17[1U]; + __IOM uint32_t FUNCTION8; /*!< Offset: 0x0A8 (R/W) Function Register 8 */ + uint32_t RESERVED18[1U]; + __IOM uint32_t COMP9; /*!< Offset: 0x0B0 (R/W) Comparator Register 9 */ + uint32_t RESERVED19[1U]; + __IOM uint32_t FUNCTION9; /*!< Offset: 0x0B8 (R/W) Function Register 9 */ + uint32_t RESERVED20[1U]; + __IOM uint32_t COMP10; /*!< Offset: 0x0C0 (R/W) Comparator Register 10 */ + uint32_t RESERVED21[1U]; + __IOM uint32_t FUNCTION10; /*!< Offset: 0x0C8 (R/W) Function Register 10 */ + uint32_t RESERVED22[1U]; + __IOM uint32_t COMP11; /*!< Offset: 0x0D0 (R/W) Comparator Register 11 */ + uint32_t RESERVED23[1U]; + __IOM uint32_t FUNCTION11; /*!< Offset: 0x0D8 (R/W) Function Register 11 */ + uint32_t RESERVED24[1U]; + __IOM uint32_t COMP12; /*!< Offset: 0x0E0 (R/W) Comparator Register 12 */ + uint32_t RESERVED25[1U]; + __IOM uint32_t FUNCTION12; /*!< Offset: 0x0E8 (R/W) Function Register 12 */ + uint32_t RESERVED26[1U]; + __IOM uint32_t COMP13; /*!< Offset: 0x0F0 (R/W) Comparator Register 13 */ + uint32_t RESERVED27[1U]; + __IOM uint32_t FUNCTION13; /*!< Offset: 0x0F8 (R/W) Function Register 13 */ + uint32_t RESERVED28[1U]; + __IOM uint32_t COMP14; /*!< Offset: 0x100 (R/W) Comparator Register 14 */ + uint32_t RESERVED29[1U]; + __IOM uint32_t FUNCTION14; /*!< Offset: 0x108 (R/W) Function Register 14 */ + uint32_t RESERVED30[1U]; + __IOM uint32_t COMP15; /*!< Offset: 0x110 (R/W) Comparator Register 15 */ + uint32_t RESERVED31[1U]; + __IOM uint32_t FUNCTION15; /*!< Offset: 0x118 (R/W) Function Register 15 */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_ID_Pos 27U /*!< DWT FUNCTION: ID Position */ +#define DWT_FUNCTION_ID_Msk (0x1FUL << DWT_FUNCTION_ID_Pos) /*!< DWT FUNCTION: ID Mask */ + +#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_ACTION_Pos 4U /*!< DWT FUNCTION: ACTION Position */ +#define DWT_FUNCTION_ACTION_Msk (0x3UL << DWT_FUNCTION_ACTION_Pos) /*!< DWT FUNCTION: ACTION Mask */ + +#define DWT_FUNCTION_MATCH_Pos 0U /*!< DWT FUNCTION: MATCH Position */ +#define DWT_FUNCTION_MATCH_Msk (0xFUL /*<< DWT_FUNCTION_MATCH_Pos*/) /*!< DWT FUNCTION: MATCH Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** + \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IOM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55U]; + __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131U]; + __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __IM uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ + uint32_t RESERVED3[759U]; + __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER */ + __IM uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ + __IM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ + uint32_t RESERVED4[1U]; + __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */ + __IM uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */ + __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ + uint32_t RESERVED5[39U]; + __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ + __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ + uint32_t RESERVED7[8U]; + __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_PRESCALER_Pos 0U /*!< TPI ACPR: PRESCALER Position */ +#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< TPI ACPR: PRESCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI TRIGGER Register Definitions */ +#define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */ +#define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */ + +/* TPI Integration ETM Data Register Definitions (FIFO0) */ +#define TPI_FIFO0_ITM_ATVALID_Pos 29U /*!< TPI FIFO0: ITM_ATVALID Position */ +#define TPI_FIFO0_ITM_ATVALID_Msk (0x3UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ + +#define TPI_FIFO0_ITM_bytecount_Pos 27U /*!< TPI FIFO0: ITM_bytecount Position */ +#define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */ + +#define TPI_FIFO0_ETM_ATVALID_Pos 26U /*!< TPI FIFO0: ETM_ATVALID Position */ +#define TPI_FIFO0_ETM_ATVALID_Msk (0x3UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ + +#define TPI_FIFO0_ETM_bytecount_Pos 24U /*!< TPI FIFO0: ETM_bytecount Position */ +#define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */ + +#define TPI_FIFO0_ETM2_Pos 16U /*!< TPI FIFO0: ETM2 Position */ +#define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */ + +#define TPI_FIFO0_ETM1_Pos 8U /*!< TPI FIFO0: ETM1 Position */ +#define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */ + +#define TPI_FIFO0_ETM0_Pos 0U /*!< TPI FIFO0: ETM0 Position */ +#define TPI_FIFO0_ETM0_Msk (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/) /*!< TPI FIFO0: ETM0 Mask */ + +/* TPI ITATBCTR2 Register Definitions */ +#define TPI_ITATBCTR2_ATREADY_Pos 0U /*!< TPI ITATBCTR2: ATREADY Position */ +#define TPI_ITATBCTR2_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY_Pos*/) /*!< TPI ITATBCTR2: ATREADY Mask */ + +/* TPI Integration ITM Data Register Definitions (FIFO1) */ +#define TPI_FIFO1_ITM_ATVALID_Pos 29U /*!< TPI FIFO1: ITM_ATVALID Position */ +#define TPI_FIFO1_ITM_ATVALID_Msk (0x3UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ + +#define TPI_FIFO1_ITM_bytecount_Pos 27U /*!< TPI FIFO1: ITM_bytecount Position */ +#define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */ + +#define TPI_FIFO1_ETM_ATVALID_Pos 26U /*!< TPI FIFO1: ETM_ATVALID Position */ +#define TPI_FIFO1_ETM_ATVALID_Msk (0x3UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ + +#define TPI_FIFO1_ETM_bytecount_Pos 24U /*!< TPI FIFO1: ETM_bytecount Position */ +#define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */ + +#define TPI_FIFO1_ITM2_Pos 16U /*!< TPI FIFO1: ITM2 Position */ +#define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */ + +#define TPI_FIFO1_ITM1_Pos 8U /*!< TPI FIFO1: ITM1 Position */ +#define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */ + +#define TPI_FIFO1_ITM0_Pos 0U /*!< TPI FIFO1: ITM0 Position */ +#define TPI_FIFO1_ITM0_Msk (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/) /*!< TPI FIFO1: ITM0 Mask */ + +/* TPI ITATBCTR0 Register Definitions */ +#define TPI_ITATBCTR0_ATREADY_Pos 0U /*!< TPI ITATBCTR0: ATREADY Position */ +#define TPI_ITATBCTR0_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY_Pos*/) /*!< TPI ITATBCTR0: ATREADY Mask */ + +/* TPI Integration Mode Control Register Definitions */ +#define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ +#define TPI_ITCTRL_Mode_Msk (0x1UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_MinBufSz_Pos 6U /*!< TPI DEVID: MinBufSz Position */ +#define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */ + +#define TPI_DEVID_AsynClkIn_Pos 5U /*!< TPI DEVID: AsynClkIn Position */ +#define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */ + +#define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */ +#define TPI_DEVID_NrTraceInput_Msk (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_MajorType_Pos 4U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +#define TPI_DEVTYPE_SubType_Pos 0U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) MPU Region Limit Address Register */ + uint32_t RESERVED0[7U]; + __IOM uint32_t MAIR0; /*!< Offset: 0x030 (R/W) MPU Memory Attribute Indirection Register 0 */ + __IOM uint32_t MAIR1; /*!< Offset: 0x034 (R/W) MPU Memory Attribute Indirection Register 1 */ +} MPU_Type; + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_BASE_Pos 5U /*!< MPU RBAR: BASE Position */ +#define MPU_RBAR_BASE_Msk (0x7FFFFFFUL << MPU_RBAR_BASE_Pos) /*!< MPU RBAR: BASE Mask */ + +#define MPU_RBAR_SH_Pos 3U /*!< MPU RBAR: SH Position */ +#define MPU_RBAR_SH_Msk (0x3UL << MPU_RBAR_SH_Pos) /*!< MPU RBAR: SH Mask */ + +#define MPU_RBAR_AP_Pos 1U /*!< MPU RBAR: AP Position */ +#define MPU_RBAR_AP_Msk (0x3UL << MPU_RBAR_AP_Pos) /*!< MPU RBAR: AP Mask */ + +#define MPU_RBAR_XN_Pos 0U /*!< MPU RBAR: XN Position */ +#define MPU_RBAR_XN_Msk (01UL /*<< MPU_RBAR_XN_Pos*/) /*!< MPU RBAR: XN Mask */ + +/* MPU Region Limit Address Register Definitions */ +#define MPU_RLAR_LIMIT_Pos 5U /*!< MPU RLAR: LIMIT Position */ +#define MPU_RLAR_LIMIT_Msk (0x7FFFFFFUL << MPU_RLAR_LIMIT_Pos) /*!< MPU RLAR: LIMIT Mask */ + +#define MPU_RLAR_AttrIndx_Pos 1U /*!< MPU RLAR: AttrIndx Position */ +#define MPU_RLAR_AttrIndx_Msk (0x7UL << MPU_RLAR_AttrIndx_Pos) /*!< MPU RLAR: AttrIndx Mask */ + +#define MPU_RLAR_EN_Pos 0U /*!< MPU RLAR: EN Position */ +#define MPU_RLAR_EN_Msk (1UL /*<< MPU_RLAR_EN_Pos*/) /*!< MPU RLAR: EN Mask */ + +/* MPU Memory Attribute Indirection Register 0 Definitions */ +#define MPU_MAIR0_Attr3_Pos 24U /*!< MPU MAIR0: Attr3 Position */ +#define MPU_MAIR0_Attr3_Msk (0xFFUL << MPU_MAIR0_Attr3_Pos) /*!< MPU MAIR0: Attr3 Mask */ + +#define MPU_MAIR0_Attr2_Pos 16U /*!< MPU MAIR0: Attr2 Position */ +#define MPU_MAIR0_Attr2_Msk (0xFFUL << MPU_MAIR0_Attr2_Pos) /*!< MPU MAIR0: Attr2 Mask */ + +#define MPU_MAIR0_Attr1_Pos 8U /*!< MPU MAIR0: Attr1 Position */ +#define MPU_MAIR0_Attr1_Msk (0xFFUL << MPU_MAIR0_Attr1_Pos) /*!< MPU MAIR0: Attr1 Mask */ + +#define MPU_MAIR0_Attr0_Pos 0U /*!< MPU MAIR0: Attr0 Position */ +#define MPU_MAIR0_Attr0_Msk (0xFFUL /*<< MPU_MAIR0_Attr0_Pos*/) /*!< MPU MAIR0: Attr0 Mask */ + +/* MPU Memory Attribute Indirection Register 1 Definitions */ +#define MPU_MAIR1_Attr7_Pos 24U /*!< MPU MAIR1: Attr7 Position */ +#define MPU_MAIR1_Attr7_Msk (0xFFUL << MPU_MAIR1_Attr7_Pos) /*!< MPU MAIR1: Attr7 Mask */ + +#define MPU_MAIR1_Attr6_Pos 16U /*!< MPU MAIR1: Attr6 Position */ +#define MPU_MAIR1_Attr6_Msk (0xFFUL << MPU_MAIR1_Attr6_Pos) /*!< MPU MAIR1: Attr6 Mask */ + +#define MPU_MAIR1_Attr5_Pos 8U /*!< MPU MAIR1: Attr5 Position */ +#define MPU_MAIR1_Attr5_Msk (0xFFUL << MPU_MAIR1_Attr5_Pos) /*!< MPU MAIR1: Attr5 Mask */ + +#define MPU_MAIR1_Attr4_Pos 0U /*!< MPU MAIR1: Attr4 Position */ +#define MPU_MAIR1_Attr4_Msk (0xFFUL /*<< MPU_MAIR1_Attr4_Pos*/) /*!< MPU MAIR1: Attr4 Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SAU Security Attribution Unit (SAU) + \brief Type definitions for the Security Attribution Unit (SAU) + @{ + */ + +/** + \brief Structure type to access the Security Attribution Unit (SAU). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SAU Control Register */ + __IM uint32_t TYPE; /*!< Offset: 0x004 (R/ ) SAU Type Register */ +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) SAU Region Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) SAU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) SAU Region Limit Address Register */ +#endif +} SAU_Type; + +/* SAU Control Register Definitions */ +#define SAU_CTRL_ALLNS_Pos 1U /*!< SAU CTRL: ALLNS Position */ +#define SAU_CTRL_ALLNS_Msk (1UL << SAU_CTRL_ALLNS_Pos) /*!< SAU CTRL: ALLNS Mask */ + +#define SAU_CTRL_ENABLE_Pos 0U /*!< SAU CTRL: ENABLE Position */ +#define SAU_CTRL_ENABLE_Msk (1UL /*<< SAU_CTRL_ENABLE_Pos*/) /*!< SAU CTRL: ENABLE Mask */ + +/* SAU Type Register Definitions */ +#define SAU_TYPE_SREGION_Pos 0U /*!< SAU TYPE: SREGION Position */ +#define SAU_TYPE_SREGION_Msk (0xFFUL /*<< SAU_TYPE_SREGION_Pos*/) /*!< SAU TYPE: SREGION Mask */ + +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) +/* SAU Region Number Register Definitions */ +#define SAU_RNR_REGION_Pos 0U /*!< SAU RNR: REGION Position */ +#define SAU_RNR_REGION_Msk (0xFFUL /*<< SAU_RNR_REGION_Pos*/) /*!< SAU RNR: REGION Mask */ + +/* SAU Region Base Address Register Definitions */ +#define SAU_RBAR_BADDR_Pos 5U /*!< SAU RBAR: BADDR Position */ +#define SAU_RBAR_BADDR_Msk (0x7FFFFFFUL << SAU_RBAR_BADDR_Pos) /*!< SAU RBAR: BADDR Mask */ + +/* SAU Region Limit Address Register Definitions */ +#define SAU_RLAR_LADDR_Pos 5U /*!< SAU RLAR: LADDR Position */ +#define SAU_RLAR_LADDR_Msk (0x7FFFFFFUL << SAU_RLAR_LADDR_Pos) /*!< SAU RLAR: LADDR Mask */ + +#define SAU_RLAR_NSC_Pos 1U /*!< SAU RLAR: NSC Position */ +#define SAU_RLAR_NSC_Msk (1UL << SAU_RLAR_NSC_Pos) /*!< SAU RLAR: NSC Mask */ + +#define SAU_RLAR_ENABLE_Pos 0U /*!< SAU RLAR: ENABLE Position */ +#define SAU_RLAR_ENABLE_Msk (1UL /*<< SAU_RLAR_ENABLE_Pos*/) /*!< SAU RLAR: ENABLE Mask */ + +#endif /* defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) */ + +/*@} end of group CMSIS_SAU */ +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** + \brief Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ + uint32_t RESERVED4[1U]; + __IOM uint32_t DAUTHCTRL; /*!< Offset: 0x014 (R/W) Debug Authentication Control Register */ + __IOM uint32_t DSCSR; /*!< Offset: 0x018 (R/W) Debug Security Control and Status Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register Definitions */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESTART_ST_Pos 26U /*!< CoreDebug DHCSR: S_RESTART_ST Position */ +#define CoreDebug_DHCSR_S_RESTART_ST_Msk (1UL << CoreDebug_DHCSR_S_RESTART_ST_Pos) /*!< CoreDebug DHCSR: S_RESTART_ST Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< 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 24U /*!< 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 19U /*!< 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 18U /*!< 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 17U /*!< 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 16U /*!< 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_MASKINTS_Pos 3U /*!< 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 2U /*!< 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 1U /*!< 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 0U /*!< 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 Definitions */ +#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< 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_DWTENA_Pos 24U /*!< CoreDebug DEMCR: DWTENA Position */ +#define CoreDebug_DEMCR_DWTENA_Msk (1UL << CoreDebug_DEMCR_DWTENA_Pos) /*!< CoreDebug DEMCR: DWTENA Mask */ + +#define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< 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_CORERESET_Pos 0U /*!< CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ + +/* Debug Authentication Control Register Definitions */ +#define CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos 3U /*!< CoreDebug DAUTHCTRL: INTSPNIDEN, Position */ +#define CoreDebug_DAUTHCTRL_INTSPNIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos) /*!< CoreDebug DAUTHCTRL: INTSPNIDEN, Mask */ + +#define CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos 2U /*!< CoreDebug DAUTHCTRL: SPNIDENSEL Position */ +#define CoreDebug_DAUTHCTRL_SPNIDENSEL_Msk (1UL << CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos) /*!< CoreDebug DAUTHCTRL: SPNIDENSEL Mask */ + +#define CoreDebug_DAUTHCTRL_INTSPIDEN_Pos 1U /*!< CoreDebug DAUTHCTRL: INTSPIDEN Position */ +#define CoreDebug_DAUTHCTRL_INTSPIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPIDEN_Pos) /*!< CoreDebug DAUTHCTRL: INTSPIDEN Mask */ + +#define CoreDebug_DAUTHCTRL_SPIDENSEL_Pos 0U /*!< CoreDebug DAUTHCTRL: SPIDENSEL Position */ +#define CoreDebug_DAUTHCTRL_SPIDENSEL_Msk (1UL /*<< CoreDebug_DAUTHCTRL_SPIDENSEL_Pos*/) /*!< CoreDebug DAUTHCTRL: SPIDENSEL Mask */ + +/* Debug Security Control and Status Register Definitions */ +#define CoreDebug_DSCSR_CDS_Pos 16U /*!< CoreDebug DSCSR: CDS Position */ +#define CoreDebug_DSCSR_CDS_Msk (1UL << CoreDebug_DSCSR_CDS_Pos) /*!< CoreDebug DSCSR: CDS Mask */ + +#define CoreDebug_DSCSR_SBRSEL_Pos 1U /*!< CoreDebug DSCSR: SBRSEL Position */ +#define CoreDebug_DSCSR_SBRSEL_Msk (1UL << CoreDebug_DSCSR_SBRSEL_Pos) /*!< CoreDebug DSCSR: SBRSEL Mask */ + +#define CoreDebug_DSCSR_SBRSELEN_Pos 0U /*!< CoreDebug DSCSR: SBRSELEN Position */ +#define CoreDebug_DSCSR_SBRSELEN_Msk (1UL /*<< CoreDebug_DSCSR_SBRSELEN_Pos*/) /*!< CoreDebug DSCSR: SBRSELEN Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ + #define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ + #define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ + #define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ + #define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ + #define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ + #define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ + #define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + + + #define 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 DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ + #define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ + #define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE ) /*!< Core Debug configuration struct */ + + #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ + #endif + + #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + #define SAU_BASE (SCS_BASE + 0x0DD0UL) /*!< Security Attribution Unit */ + #define SAU ((SAU_Type *) SAU_BASE ) /*!< Security Attribution Unit */ + #endif + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + #define SCS_BASE_NS (0xE002E000UL) /*!< System Control Space Base Address (non-secure address space) */ + #define CoreDebug_BASE_NS (0xE002EDF0UL) /*!< Core Debug Base Address (non-secure address space) */ + #define SysTick_BASE_NS (SCS_BASE_NS + 0x0010UL) /*!< SysTick Base Address (non-secure address space) */ + #define NVIC_BASE_NS (SCS_BASE_NS + 0x0100UL) /*!< NVIC Base Address (non-secure address space) */ + #define SCB_BASE_NS (SCS_BASE_NS + 0x0D00UL) /*!< System Control Block Base Address (non-secure address space) */ + + #define SCB_NS ((SCB_Type *) SCB_BASE_NS ) /*!< SCB configuration struct (non-secure address space) */ + #define SysTick_NS ((SysTick_Type *) SysTick_BASE_NS ) /*!< SysTick configuration struct (non-secure address space) */ + #define NVIC_NS ((NVIC_Type *) NVIC_BASE_NS ) /*!< NVIC configuration struct (non-secure address space) */ + #define CoreDebug_NS ((CoreDebug_Type *) CoreDebug_BASE_NS) /*!< Core Debug configuration struct (non-secure address space) */ + + #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE_NS (SCS_BASE_NS + 0x0D90UL) /*!< Memory Protection Unit (non-secure address space) */ + #define MPU_NS ((MPU_Type *) MPU_BASE_NS ) /*!< Memory Protection Unit (non-secure address space) */ + #endif + +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else +/*#define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping not available for ARMv8-M Baseline */ +/*#define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping not available for ARMv8-M Baseline */ + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ + #define NVIC_GetActive __NVIC_GetActive + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + +/* Interrupt Priorities are WORD accessible only under ARMv6M */ +/* The following MACROS handle generation of the register offset and byte masks */ +#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL) +#define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) ) +#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) ) + + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt + \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IABR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Get Interrupt Target State + \details Reads the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + \return 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_GetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ITNS[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Target State + \details Sets the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_SetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)(int32_t)IRQn) >> 5UL)] |= ((uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Clear Interrupt Target State + \details Clears the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_ClearTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)(int32_t)IRQn) >> 5UL)] &= ~((uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IPR[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IPR[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } + else + { + SCB->SHPR[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHPR[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IPR[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return((uint32_t)(((SCB->SHPR[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + If VTOR is not present address 0 must be mapped to SRAM. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) + uint32_t *vectors = (uint32_t *)SCB->VTOR; +#else + uint32_t *vectors = (uint32_t *)0x0U; +#endif + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) + uint32_t *vectors = (uint32_t *)SCB->VTOR; +#else + uint32_t *vectors = (uint32_t *)0x0U; +#endif + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + SCB_AIRCR_SYSRESETREQ_Msk); + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Enable Interrupt (non-secure) + \details Enables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_EnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status (non-secure) + \details Returns a device specific interrupt enable status from the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetEnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt (non-secure) + \details Disables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_DisableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Pending Interrupt (non-secure) + \details Reads the NVIC pending register in the non-secure NVIC when in secure state and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } +} + + +/** + \brief Set Pending Interrupt (non-secure) + \details Sets the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_SetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt (non-secure) + \details Clears the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_ClearPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt (non-secure) + \details Reads the active register in non-secure NVIC when in secure state and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetActive_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->IABR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Priority (non-secure) + \details Sets the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every non-secure processor exception. + */ +__STATIC_INLINE void TZ_NVIC_SetPriority_NS(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->IPR[_IP_IDX(IRQn)] = ((uint32_t)(NVIC_NS->IPR[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } + else + { + SCB_NS->SHPR[_SHP_IDX(IRQn)] = ((uint32_t)(SCB_NS->SHPR[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } +} + + +/** + \brief Get Interrupt Priority (non-secure) + \details Reads the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPriority_NS(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->IPR[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return((uint32_t)(((SCB_NS->SHPR[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) &&(__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_NVICFunctions */ + + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + return 0U; /* No FPU */ +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ########################## SAU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SAUFunctions SAU Functions + \brief Functions that configure the SAU. + @{ + */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + +/** + \brief Enable SAU + \details Enables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Enable(void) +{ + SAU->CTRL |= (SAU_CTRL_ENABLE_Msk); +} + + + +/** + \brief Disable SAU + \details Disables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Disable(void) +{ + SAU->CTRL &= ~(SAU_CTRL_ENABLE_Msk); +} + +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_SAUFunctions */ + + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief System Tick Configuration (non-secure) + \details Initializes the non-secure System Timer and its interrupt when in secure state, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function TZ_SysTick_Config_NS is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + + */ +__STATIC_INLINE uint32_t TZ_SysTick_Config_NS(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick_NS->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + TZ_NVIC_SetPriority_NS (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick_NS->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick_NS->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_ARMV8MBL_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/cmsis/core_armv8mml.h b/cmsis/core_armv8mml.h new file mode 100644 index 00000000000..286322f75c4 --- /dev/null +++ b/cmsis/core_armv8mml.h @@ -0,0 +1,2900 @@ +/**************************************************************************//** + * @file core_armv8mml.h + * @brief CMSIS ARMv8MML Core Peripheral Access Layer Header File + * @version V5.0.2 + * @date 13. February 2017 + ******************************************************************************/ +/* + * Copyright (c) 2009-2017 ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_ARMV8MML_H_GENERIC +#define __CORE_ARMV8MML_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex_ARMv8MML + @{ + */ + +/* CMSIS ARMv8MML definitions */ +#define __ARMv8MML_CMSIS_VERSION_MAIN ( 5U) /*!< [31:16] CMSIS HAL main version */ +#define __ARMv8MML_CMSIS_VERSION_SUB ( 0U) /*!< [15:0] CMSIS HAL sub version */ +#define __ARMv8MML_CMSIS_VERSION ((__ARMv8MML_CMSIS_VERSION_MAIN << 16U) | \ + __ARMv8MML_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */ + +#define __CORTEX_M (81U) /*!< Cortex-M Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + For this, __FPU_PRESENT has to be checked prior to making use of FPU specific registers and functions. +*/ +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_PCS_VFP + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_ARMV8MML_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_ARMV8MML_H_DEPENDANT +#define __CORE_ARMV8MML_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __ARMv8MML_REV + #define __ARMv8MML_REV 0x0000U + #warning "__ARMv8MML_REV not defined in device header file; using default!" + #endif + + #ifndef __FPU_PRESENT + #define __FPU_PRESENT 0U + #warning "__FPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __SAUREGION_PRESENT + #define __SAUREGION_PRESENT 0U + #warning "__SAUREGION_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __DSP_PRESENT + #define __DSP_PRESENT 0U + #warning "__DSP_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 3U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group ARMv8MML */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + - Core SAU Register + - Core FPU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + 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 */ + 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; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + +#define APSR_Q_Pos 27U /*!< APSR: Q Position */ +#define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */ + +#define APSR_GE_Pos 16U /*!< APSR: GE Position */ +#define APSR_GE_Msk (0xFUL << APSR_GE_Pos) /*!< APSR: GE Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0: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 */ + 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; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_Q_Pos 27U /*!< xPSR: Q Position */ +#define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */ + +#define xPSR_IT_Pos 25U /*!< xPSR: IT Position */ +#define xPSR_IT_Msk (3UL << xPSR_IT_Pos) /*!< xPSR: IT Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_GE_Pos 16U /*!< xPSR: GE Position */ +#define xPSR_GE_Msk (0xFUL << xPSR_GE_Pos) /*!< xPSR: GE Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack-pointer select */ + uint32_t FPCA:1; /*!< bit: 2 Floating-point context active */ + uint32_t SFPA:1; /*!< bit: 3 Secure floating-point active */ + uint32_t _reserved1:28; /*!< bit: 4..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SFPA_Pos 3U /*!< CONTROL: SFPA Position */ +#define CONTROL_SFPA_Msk (1UL << CONTROL_SFPA_Pos) /*!< CONTROL: SFPA Mask */ + +#define CONTROL_FPCA_Pos 2U /*!< CONTROL: FPCA Position */ +#define CONTROL_FPCA_Msk (1UL << CONTROL_FPCA_Pos) /*!< CONTROL: FPCA Mask */ + +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[16U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[16U]; + __IOM uint32_t ICER[16U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[16U]; + __IOM uint32_t ISPR[16U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[16U]; + __IOM uint32_t ICPR[16U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[16U]; + __IOM uint32_t IABR[16U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[16U]; + __IOM uint32_t ITNS[16U]; /*!< Offset: 0x280 (R/W) Interrupt Non-Secure State Register */ + uint32_t RESERVED5[16U]; + __IOM uint8_t IPR[496U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED6[580U]; + __OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; + +/* Software Triggered Interrupt Register Definitions */ +#define NVIC_STIR_INTID_Pos 0U /*!< STIR: INTLINESNUM Position */ +#define NVIC_STIR_INTID_Msk (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/) /*!< STIR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + __IOM uint8_t SHPR[12U]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IOM uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IOM uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IOM uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IOM uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IOM uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IOM uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __IM uint32_t ID_PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __IM uint32_t ID_DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __IM uint32_t ID_ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __IM uint32_t ID_MMFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __IM uint32_t ID_ISAR[6U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + __IM uint32_t CLIDR; /*!< Offset: 0x078 (R/ ) Cache Level ID register */ + __IM uint32_t CTR; /*!< Offset: 0x07C (R/ ) Cache Type register */ + __IM uint32_t CCSIDR; /*!< Offset: 0x080 (R/ ) Cache Size ID Register */ + __IOM uint32_t CSSELR; /*!< Offset: 0x084 (R/W) Cache Size Selection Register */ + __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ + __IOM uint32_t NSACR; /*!< Offset: 0x08C (R/W) Non-Secure Access Control Register */ + uint32_t RESERVED3[92U]; + __OM uint32_t STIR; /*!< Offset: 0x200 ( /W) Software Triggered Interrupt Register */ + uint32_t RESERVED4[15U]; + __IM uint32_t MVFR0; /*!< Offset: 0x240 (R/ ) Media and VFP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x244 (R/ ) Media and VFP Feature Register 1 */ + __IM uint32_t MVFR2; /*!< Offset: 0x248 (R/ ) Media and VFP Feature Register 1 */ + uint32_t RESERVED5[1U]; + __OM uint32_t ICIALLU; /*!< Offset: 0x250 ( /W) I-Cache Invalidate All to PoU */ + uint32_t RESERVED6[1U]; + __OM uint32_t ICIMVAU; /*!< Offset: 0x258 ( /W) I-Cache Invalidate by MVA to PoU */ + __OM uint32_t DCIMVAC; /*!< Offset: 0x25C ( /W) D-Cache Invalidate by MVA to PoC */ + __OM uint32_t DCISW; /*!< Offset: 0x260 ( /W) D-Cache Invalidate by Set-way */ + __OM uint32_t DCCMVAU; /*!< Offset: 0x264 ( /W) D-Cache Clean by MVA to PoU */ + __OM uint32_t DCCMVAC; /*!< Offset: 0x268 ( /W) D-Cache Clean by MVA to PoC */ + __OM uint32_t DCCSW; /*!< Offset: 0x26C ( /W) D-Cache Clean by Set-way */ + __OM uint32_t DCCIMVAC; /*!< Offset: 0x270 ( /W) D-Cache Clean and Invalidate by MVA to PoC */ + __OM uint32_t DCCISW; /*!< Offset: 0x274 ( /W) D-Cache Clean and Invalidate by Set-way */ + uint32_t RESERVED7[6U]; + __IOM uint32_t ITCMCR; /*!< Offset: 0x290 (R/W) Instruction Tightly-Coupled Memory Control Register */ + __IOM uint32_t DTCMCR; /*!< Offset: 0x294 (R/W) Data Tightly-Coupled Memory Control Registers */ + __IOM uint32_t AHBPCR; /*!< Offset: 0x298 (R/W) AHBP Control Register */ + __IOM uint32_t CACR; /*!< Offset: 0x29C (R/W) L1 Cache Control Register */ + __IOM uint32_t AHBSCR; /*!< Offset: 0x2A0 (R/W) AHB Slave Control Register */ + uint32_t RESERVED8[1U]; + __IOM uint32_t ABFSR; /*!< Offset: 0x2A8 (R/W) Auxiliary Bus Fault Status Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_PENDNMISET_Pos 31U /*!< SCB ICSR: PENDNMISET Position */ +#define SCB_ICSR_PENDNMISET_Msk (1UL << SCB_ICSR_PENDNMISET_Pos) /*!< SCB ICSR: PENDNMISET Mask */ + +#define SCB_ICSR_PENDNMICLR_Pos 30U /*!< SCB ICSR: PENDNMICLR Position */ +#define SCB_ICSR_PENDNMICLR_Msk (1UL << SCB_ICSR_PENDNMICLR_Pos) /*!< SCB ICSR: PENDNMICLR Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_STTNS_Pos 24U /*!< SCB ICSR: STTNS Position (Security Extension) */ +#define SCB_ICSR_STTNS_Msk (1UL << SCB_ICSR_STTNS_Pos) /*!< SCB ICSR: STTNS Mask (Security Extension) */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Vector Table Offset Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 7U /*!< 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 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIS_Pos 14U /*!< SCB AIRCR: PRIS Position */ +#define SCB_AIRCR_PRIS_Msk (1UL << SCB_AIRCR_PRIS_Pos) /*!< SCB AIRCR: PRIS Mask */ + +#define SCB_AIRCR_BFHFNMINS_Pos 13U /*!< SCB AIRCR: BFHFNMINS Position */ +#define SCB_AIRCR_BFHFNMINS_Msk (1UL << SCB_AIRCR_BFHFNMINS_Pos) /*!< SCB AIRCR: BFHFNMINS Mask */ + +#define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */ +#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ + +#define SCB_AIRCR_SYSRESETREQS_Pos 3U /*!< SCB AIRCR: SYSRESETREQS Position */ +#define SCB_AIRCR_SYSRESETREQS_Msk (1UL << SCB_AIRCR_SYSRESETREQS_Pos) /*!< SCB AIRCR: SYSRESETREQS Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEPS_Pos 3U /*!< SCB SCR: SLEEPDEEPS Position */ +#define SCB_SCR_SLEEPDEEPS_Msk (1UL << SCB_SCR_SLEEPDEEPS_Pos) /*!< SCB SCR: SLEEPDEEPS Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_BP_Pos 18U /*!< SCB CCR: BP Position */ +#define SCB_CCR_BP_Msk (1UL << SCB_CCR_BP_Pos) /*!< SCB CCR: BP Mask */ + +#define SCB_CCR_IC_Pos 17U /*!< SCB CCR: IC Position */ +#define SCB_CCR_IC_Msk (1UL << SCB_CCR_IC_Pos) /*!< SCB CCR: IC Mask */ + +#define SCB_CCR_DC_Pos 16U /*!< SCB CCR: DC Position */ +#define SCB_CCR_DC_Msk (1UL << SCB_CCR_DC_Pos) /*!< SCB CCR: DC Mask */ + +#define SCB_CCR_STKOFHFNMIGN_Pos 10U /*!< SCB CCR: STKOFHFNMIGN Position */ +#define SCB_CCR_STKOFHFNMIGN_Msk (1UL << SCB_CCR_STKOFHFNMIGN_Pos) /*!< SCB CCR: STKOFHFNMIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< 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 4U /*!< 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 3U /*!< 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 1U /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_HARDFAULTPENDED_Pos 21U /*!< SCB SHCSR: HARDFAULTPENDED Position */ +#define SCB_SHCSR_HARDFAULTPENDED_Msk (1UL << SCB_SHCSR_HARDFAULTPENDED_Pos) /*!< SCB SHCSR: HARDFAULTPENDED Mask */ + +#define SCB_SHCSR_SECUREFAULTPENDED_Pos 20U /*!< SCB SHCSR: SECUREFAULTPENDED Position */ +#define SCB_SHCSR_SECUREFAULTPENDED_Msk (1UL << SCB_SHCSR_SECUREFAULTPENDED_Pos) /*!< SCB SHCSR: SECUREFAULTPENDED Mask */ + +#define SCB_SHCSR_SECUREFAULTENA_Pos 19U /*!< SCB SHCSR: SECUREFAULTENA Position */ +#define SCB_SHCSR_SECUREFAULTENA_Msk (1UL << SCB_SHCSR_SECUREFAULTENA_Pos) /*!< SCB SHCSR: SECUREFAULTENA Mask */ + +#define SCB_SHCSR_USGFAULTENA_Pos 18U /*!< SCB SHCSR: USGFAULTENA Position */ +#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ + +#define SCB_SHCSR_BUSFAULTENA_Pos 17U /*!< SCB SHCSR: BUSFAULTENA Position */ +#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ + +#define SCB_SHCSR_MEMFAULTENA_Pos 16U /*!< SCB SHCSR: MEMFAULTENA Position */ +#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_BUSFAULTPENDED_Pos 14U /*!< SCB SHCSR: BUSFAULTPENDED Position */ +#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ + +#define SCB_SHCSR_MEMFAULTPENDED_Pos 13U /*!< SCB SHCSR: MEMFAULTPENDED Position */ +#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ + +#define SCB_SHCSR_USGFAULTPENDED_Pos 12U /*!< SCB SHCSR: USGFAULTPENDED Position */ +#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_MONITORACT_Pos 8U /*!< SCB SHCSR: MONITORACT Position */ +#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_NMIACT_Pos 5U /*!< SCB SHCSR: NMIACT Position */ +#define SCB_SHCSR_NMIACT_Msk (1UL << SCB_SHCSR_NMIACT_Pos) /*!< SCB SHCSR: NMIACT Mask */ + +#define SCB_SHCSR_SECUREFAULTACT_Pos 4U /*!< SCB SHCSR: SECUREFAULTACT Position */ +#define SCB_SHCSR_SECUREFAULTACT_Msk (1UL << SCB_SHCSR_SECUREFAULTACT_Pos) /*!< SCB SHCSR: SECUREFAULTACT Mask */ + +#define SCB_SHCSR_USGFAULTACT_Pos 3U /*!< SCB SHCSR: USGFAULTACT Position */ +#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ + +#define SCB_SHCSR_HARDFAULTACT_Pos 2U /*!< SCB SHCSR: HARDFAULTACT Position */ +#define SCB_SHCSR_HARDFAULTACT_Msk (1UL << SCB_SHCSR_HARDFAULTACT_Pos) /*!< SCB SHCSR: HARDFAULTACT Mask */ + +#define SCB_SHCSR_BUSFAULTACT_Pos 1U /*!< SCB SHCSR: BUSFAULTACT Position */ +#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ + +#define SCB_SHCSR_MEMFAULTACT_Pos 0U /*!< SCB SHCSR: MEMFAULTACT Position */ +#define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */ + +/* SCB Configurable Fault Status Register Definitions */ +#define SCB_CFSR_USGFAULTSR_Pos 16U /*!< 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 8U /*!< 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 0U /*!< 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 */ + +/* MemManage Fault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_MMARVALID_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 7U) /*!< SCB CFSR (MMFSR): MMARVALID Position */ +#define SCB_CFSR_MMARVALID_Msk (1UL << SCB_CFSR_MMARVALID_Pos) /*!< SCB CFSR (MMFSR): MMARVALID Mask */ + +#define SCB_CFSR_MLSPERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 5U) /*!< SCB CFSR (MMFSR): MLSPERR Position */ +#define SCB_CFSR_MLSPERR_Msk (1UL << SCB_CFSR_MLSPERR_Pos) /*!< SCB CFSR (MMFSR): MLSPERR Mask */ + +#define SCB_CFSR_MSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 4U) /*!< SCB CFSR (MMFSR): MSTKERR Position */ +#define SCB_CFSR_MSTKERR_Msk (1UL << SCB_CFSR_MSTKERR_Pos) /*!< SCB CFSR (MMFSR): MSTKERR Mask */ + +#define SCB_CFSR_MUNSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 3U) /*!< SCB CFSR (MMFSR): MUNSTKERR Position */ +#define SCB_CFSR_MUNSTKERR_Msk (1UL << SCB_CFSR_MUNSTKERR_Pos) /*!< SCB CFSR (MMFSR): MUNSTKERR Mask */ + +#define SCB_CFSR_DACCVIOL_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 1U) /*!< SCB CFSR (MMFSR): DACCVIOL Position */ +#define SCB_CFSR_DACCVIOL_Msk (1UL << SCB_CFSR_DACCVIOL_Pos) /*!< SCB CFSR (MMFSR): DACCVIOL Mask */ + +#define SCB_CFSR_IACCVIOL_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 0U) /*!< SCB CFSR (MMFSR): IACCVIOL Position */ +#define SCB_CFSR_IACCVIOL_Msk (1UL /*<< SCB_CFSR_IACCVIOL_Pos*/) /*!< SCB CFSR (MMFSR): IACCVIOL Mask */ + +/* BusFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_BFARVALID_Pos (SCB_CFSR_BUSFAULTSR_Pos + 7U) /*!< SCB CFSR (BFSR): BFARVALID Position */ +#define SCB_CFSR_BFARVALID_Msk (1UL << SCB_CFSR_BFARVALID_Pos) /*!< SCB CFSR (BFSR): BFARVALID Mask */ + +#define SCB_CFSR_LSPERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 5U) /*!< SCB CFSR (BFSR): LSPERR Position */ +#define SCB_CFSR_LSPERR_Msk (1UL << SCB_CFSR_LSPERR_Pos) /*!< SCB CFSR (BFSR): LSPERR Mask */ + +#define SCB_CFSR_STKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 4U) /*!< SCB CFSR (BFSR): STKERR Position */ +#define SCB_CFSR_STKERR_Msk (1UL << SCB_CFSR_STKERR_Pos) /*!< SCB CFSR (BFSR): STKERR Mask */ + +#define SCB_CFSR_UNSTKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 3U) /*!< SCB CFSR (BFSR): UNSTKERR Position */ +#define SCB_CFSR_UNSTKERR_Msk (1UL << SCB_CFSR_UNSTKERR_Pos) /*!< SCB CFSR (BFSR): UNSTKERR Mask */ + +#define SCB_CFSR_IMPRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 2U) /*!< SCB CFSR (BFSR): IMPRECISERR Position */ +#define SCB_CFSR_IMPRECISERR_Msk (1UL << SCB_CFSR_IMPRECISERR_Pos) /*!< SCB CFSR (BFSR): IMPRECISERR Mask */ + +#define SCB_CFSR_PRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 1U) /*!< SCB CFSR (BFSR): PRECISERR Position */ +#define SCB_CFSR_PRECISERR_Msk (1UL << SCB_CFSR_PRECISERR_Pos) /*!< SCB CFSR (BFSR): PRECISERR Mask */ + +#define SCB_CFSR_IBUSERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 0U) /*!< SCB CFSR (BFSR): IBUSERR Position */ +#define SCB_CFSR_IBUSERR_Msk (1UL << SCB_CFSR_IBUSERR_Pos) /*!< SCB CFSR (BFSR): IBUSERR Mask */ + +/* UsageFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_DIVBYZERO_Pos (SCB_CFSR_USGFAULTSR_Pos + 9U) /*!< SCB CFSR (UFSR): DIVBYZERO Position */ +#define SCB_CFSR_DIVBYZERO_Msk (1UL << SCB_CFSR_DIVBYZERO_Pos) /*!< SCB CFSR (UFSR): DIVBYZERO Mask */ + +#define SCB_CFSR_UNALIGNED_Pos (SCB_CFSR_USGFAULTSR_Pos + 8U) /*!< SCB CFSR (UFSR): UNALIGNED Position */ +#define SCB_CFSR_UNALIGNED_Msk (1UL << SCB_CFSR_UNALIGNED_Pos) /*!< SCB CFSR (UFSR): UNALIGNED Mask */ + +#define SCB_CFSR_STKOF_Pos (SCB_CFSR_USGFAULTSR_Pos + 4U) /*!< SCB CFSR (UFSR): STKOF Position */ +#define SCB_CFSR_STKOF_Msk (1UL << SCB_CFSR_STKOF_Pos) /*!< SCB CFSR (UFSR): STKOF Mask */ + +#define SCB_CFSR_NOCP_Pos (SCB_CFSR_USGFAULTSR_Pos + 3U) /*!< SCB CFSR (UFSR): NOCP Position */ +#define SCB_CFSR_NOCP_Msk (1UL << SCB_CFSR_NOCP_Pos) /*!< SCB CFSR (UFSR): NOCP Mask */ + +#define SCB_CFSR_INVPC_Pos (SCB_CFSR_USGFAULTSR_Pos + 2U) /*!< SCB CFSR (UFSR): INVPC Position */ +#define SCB_CFSR_INVPC_Msk (1UL << SCB_CFSR_INVPC_Pos) /*!< SCB CFSR (UFSR): INVPC Mask */ + +#define SCB_CFSR_INVSTATE_Pos (SCB_CFSR_USGFAULTSR_Pos + 1U) /*!< SCB CFSR (UFSR): INVSTATE Position */ +#define SCB_CFSR_INVSTATE_Msk (1UL << SCB_CFSR_INVSTATE_Pos) /*!< SCB CFSR (UFSR): INVSTATE Mask */ + +#define SCB_CFSR_UNDEFINSTR_Pos (SCB_CFSR_USGFAULTSR_Pos + 0U) /*!< SCB CFSR (UFSR): UNDEFINSTR Position */ +#define SCB_CFSR_UNDEFINSTR_Msk (1UL << SCB_CFSR_UNDEFINSTR_Pos) /*!< SCB CFSR (UFSR): UNDEFINSTR Mask */ + +/* SCB Hard Fault Status Register Definitions */ +#define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */ +#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ + +#define SCB_HFSR_FORCED_Pos 30U /*!< SCB HFSR: FORCED Position */ +#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ + +#define SCB_HFSR_VECTTBL_Pos 1U /*!< 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 4U /*!< SCB DFSR: EXTERNAL Position */ +#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ + +#define SCB_DFSR_VCATCH_Pos 3U /*!< SCB DFSR: VCATCH Position */ +#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ + +#define SCB_DFSR_DWTTRAP_Pos 2U /*!< SCB DFSR: DWTTRAP Position */ +#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ + +#define SCB_DFSR_BKPT_Pos 1U /*!< SCB DFSR: BKPT Position */ +#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ + +#define SCB_DFSR_HALTED_Pos 0U /*!< SCB DFSR: HALTED Position */ +#define SCB_DFSR_HALTED_Msk (1UL /*<< SCB_DFSR_HALTED_Pos*/) /*!< SCB DFSR: HALTED Mask */ + +/* SCB Non-Secure Access Control Register Definitions */ +#define SCB_NSACR_CP11_Pos 11U /*!< SCB NSACR: CP11 Position */ +#define SCB_NSACR_CP11_Msk (1UL << SCB_NSACR_CP11_Pos) /*!< SCB NSACR: CP11 Mask */ + +#define SCB_NSACR_CP10_Pos 10U /*!< SCB NSACR: CP10 Position */ +#define SCB_NSACR_CP10_Msk (1UL << SCB_NSACR_CP10_Pos) /*!< SCB NSACR: CP10 Mask */ + +#define SCB_NSACR_CPn_Pos 0U /*!< SCB NSACR: CPn Position */ +#define SCB_NSACR_CPn_Msk (1UL /*<< SCB_NSACR_CPn_Pos*/) /*!< SCB NSACR: CPn Mask */ + +/* SCB Cache Level ID Register Definitions */ +#define SCB_CLIDR_LOUU_Pos 27U /*!< SCB CLIDR: LoUU Position */ +#define SCB_CLIDR_LOUU_Msk (7UL << SCB_CLIDR_LOUU_Pos) /*!< SCB CLIDR: LoUU Mask */ + +#define SCB_CLIDR_LOC_Pos 24U /*!< SCB CLIDR: LoC Position */ +#define SCB_CLIDR_LOC_Msk (7UL << SCB_CLIDR_LOC_Pos) /*!< SCB CLIDR: LoC Mask */ + +/* SCB Cache Type Register Definitions */ +#define SCB_CTR_FORMAT_Pos 29U /*!< SCB CTR: Format Position */ +#define SCB_CTR_FORMAT_Msk (7UL << SCB_CTR_FORMAT_Pos) /*!< SCB CTR: Format Mask */ + +#define SCB_CTR_CWG_Pos 24U /*!< SCB CTR: CWG Position */ +#define SCB_CTR_CWG_Msk (0xFUL << SCB_CTR_CWG_Pos) /*!< SCB CTR: CWG Mask */ + +#define SCB_CTR_ERG_Pos 20U /*!< SCB CTR: ERG Position */ +#define SCB_CTR_ERG_Msk (0xFUL << SCB_CTR_ERG_Pos) /*!< SCB CTR: ERG Mask */ + +#define SCB_CTR_DMINLINE_Pos 16U /*!< SCB CTR: DminLine Position */ +#define SCB_CTR_DMINLINE_Msk (0xFUL << SCB_CTR_DMINLINE_Pos) /*!< SCB CTR: DminLine Mask */ + +#define SCB_CTR_IMINLINE_Pos 0U /*!< SCB CTR: ImInLine Position */ +#define SCB_CTR_IMINLINE_Msk (0xFUL /*<< SCB_CTR_IMINLINE_Pos*/) /*!< SCB CTR: ImInLine Mask */ + +/* SCB Cache Size ID Register Definitions */ +#define SCB_CCSIDR_WT_Pos 31U /*!< SCB CCSIDR: WT Position */ +#define SCB_CCSIDR_WT_Msk (1UL << SCB_CCSIDR_WT_Pos) /*!< SCB CCSIDR: WT Mask */ + +#define SCB_CCSIDR_WB_Pos 30U /*!< SCB CCSIDR: WB Position */ +#define SCB_CCSIDR_WB_Msk (1UL << SCB_CCSIDR_WB_Pos) /*!< SCB CCSIDR: WB Mask */ + +#define SCB_CCSIDR_RA_Pos 29U /*!< SCB CCSIDR: RA Position */ +#define SCB_CCSIDR_RA_Msk (1UL << SCB_CCSIDR_RA_Pos) /*!< SCB CCSIDR: RA Mask */ + +#define SCB_CCSIDR_WA_Pos 28U /*!< SCB CCSIDR: WA Position */ +#define SCB_CCSIDR_WA_Msk (1UL << SCB_CCSIDR_WA_Pos) /*!< SCB CCSIDR: WA Mask */ + +#define SCB_CCSIDR_NUMSETS_Pos 13U /*!< SCB CCSIDR: NumSets Position */ +#define SCB_CCSIDR_NUMSETS_Msk (0x7FFFUL << SCB_CCSIDR_NUMSETS_Pos) /*!< SCB CCSIDR: NumSets Mask */ + +#define SCB_CCSIDR_ASSOCIATIVITY_Pos 3U /*!< SCB CCSIDR: Associativity Position */ +#define SCB_CCSIDR_ASSOCIATIVITY_Msk (0x3FFUL << SCB_CCSIDR_ASSOCIATIVITY_Pos) /*!< SCB CCSIDR: Associativity Mask */ + +#define SCB_CCSIDR_LINESIZE_Pos 0U /*!< SCB CCSIDR: LineSize Position */ +#define SCB_CCSIDR_LINESIZE_Msk (7UL /*<< SCB_CCSIDR_LINESIZE_Pos*/) /*!< SCB CCSIDR: LineSize Mask */ + +/* SCB Cache Size Selection Register Definitions */ +#define SCB_CSSELR_LEVEL_Pos 1U /*!< SCB CSSELR: Level Position */ +#define SCB_CSSELR_LEVEL_Msk (7UL << SCB_CSSELR_LEVEL_Pos) /*!< SCB CSSELR: Level Mask */ + +#define SCB_CSSELR_IND_Pos 0U /*!< SCB CSSELR: InD Position */ +#define SCB_CSSELR_IND_Msk (1UL /*<< SCB_CSSELR_IND_Pos*/) /*!< SCB CSSELR: InD Mask */ + +/* SCB Software Triggered Interrupt Register Definitions */ +#define SCB_STIR_INTID_Pos 0U /*!< SCB STIR: INTID Position */ +#define SCB_STIR_INTID_Msk (0x1FFUL /*<< SCB_STIR_INTID_Pos*/) /*!< SCB STIR: INTID Mask */ + +/* SCB D-Cache Invalidate by Set-way Register Definitions */ +#define SCB_DCISW_WAY_Pos 30U /*!< SCB DCISW: Way Position */ +#define SCB_DCISW_WAY_Msk (3UL << SCB_DCISW_WAY_Pos) /*!< SCB DCISW: Way Mask */ + +#define SCB_DCISW_SET_Pos 5U /*!< SCB DCISW: Set Position */ +#define SCB_DCISW_SET_Msk (0x1FFUL << SCB_DCISW_SET_Pos) /*!< SCB DCISW: Set Mask */ + +/* SCB D-Cache Clean by Set-way Register Definitions */ +#define SCB_DCCSW_WAY_Pos 30U /*!< SCB DCCSW: Way Position */ +#define SCB_DCCSW_WAY_Msk (3UL << SCB_DCCSW_WAY_Pos) /*!< SCB DCCSW: Way Mask */ + +#define SCB_DCCSW_SET_Pos 5U /*!< SCB DCCSW: Set Position */ +#define SCB_DCCSW_SET_Msk (0x1FFUL << SCB_DCCSW_SET_Pos) /*!< SCB DCCSW: Set Mask */ + +/* SCB D-Cache Clean and Invalidate by Set-way Register Definitions */ +#define SCB_DCCISW_WAY_Pos 30U /*!< SCB DCCISW: Way Position */ +#define SCB_DCCISW_WAY_Msk (3UL << SCB_DCCISW_WAY_Pos) /*!< SCB DCCISW: Way Mask */ + +#define SCB_DCCISW_SET_Pos 5U /*!< SCB DCCISW: Set Position */ +#define SCB_DCCISW_SET_Msk (0x1FFUL << SCB_DCCISW_SET_Pos) /*!< SCB DCCISW: Set Mask */ + +/* Instruction Tightly-Coupled Memory Control Register Definitions */ +#define SCB_ITCMCR_SZ_Pos 3U /*!< SCB ITCMCR: SZ Position */ +#define SCB_ITCMCR_SZ_Msk (0xFUL << SCB_ITCMCR_SZ_Pos) /*!< SCB ITCMCR: SZ Mask */ + +#define SCB_ITCMCR_RETEN_Pos 2U /*!< SCB ITCMCR: RETEN Position */ +#define SCB_ITCMCR_RETEN_Msk (1UL << SCB_ITCMCR_RETEN_Pos) /*!< SCB ITCMCR: RETEN Mask */ + +#define SCB_ITCMCR_RMW_Pos 1U /*!< SCB ITCMCR: RMW Position */ +#define SCB_ITCMCR_RMW_Msk (1UL << SCB_ITCMCR_RMW_Pos) /*!< SCB ITCMCR: RMW Mask */ + +#define SCB_ITCMCR_EN_Pos 0U /*!< SCB ITCMCR: EN Position */ +#define SCB_ITCMCR_EN_Msk (1UL /*<< SCB_ITCMCR_EN_Pos*/) /*!< SCB ITCMCR: EN Mask */ + +/* Data Tightly-Coupled Memory Control Register Definitions */ +#define SCB_DTCMCR_SZ_Pos 3U /*!< SCB DTCMCR: SZ Position */ +#define SCB_DTCMCR_SZ_Msk (0xFUL << SCB_DTCMCR_SZ_Pos) /*!< SCB DTCMCR: SZ Mask */ + +#define SCB_DTCMCR_RETEN_Pos 2U /*!< SCB DTCMCR: RETEN Position */ +#define SCB_DTCMCR_RETEN_Msk (1UL << SCB_DTCMCR_RETEN_Pos) /*!< SCB DTCMCR: RETEN Mask */ + +#define SCB_DTCMCR_RMW_Pos 1U /*!< SCB DTCMCR: RMW Position */ +#define SCB_DTCMCR_RMW_Msk (1UL << SCB_DTCMCR_RMW_Pos) /*!< SCB DTCMCR: RMW Mask */ + +#define SCB_DTCMCR_EN_Pos 0U /*!< SCB DTCMCR: EN Position */ +#define SCB_DTCMCR_EN_Msk (1UL /*<< SCB_DTCMCR_EN_Pos*/) /*!< SCB DTCMCR: EN Mask */ + +/* AHBP Control Register Definitions */ +#define SCB_AHBPCR_SZ_Pos 1U /*!< SCB AHBPCR: SZ Position */ +#define SCB_AHBPCR_SZ_Msk (7UL << SCB_AHBPCR_SZ_Pos) /*!< SCB AHBPCR: SZ Mask */ + +#define SCB_AHBPCR_EN_Pos 0U /*!< SCB AHBPCR: EN Position */ +#define SCB_AHBPCR_EN_Msk (1UL /*<< SCB_AHBPCR_EN_Pos*/) /*!< SCB AHBPCR: EN Mask */ + +/* L1 Cache Control Register Definitions */ +#define SCB_CACR_FORCEWT_Pos 2U /*!< SCB CACR: FORCEWT Position */ +#define SCB_CACR_FORCEWT_Msk (1UL << SCB_CACR_FORCEWT_Pos) /*!< SCB CACR: FORCEWT Mask */ + +#define SCB_CACR_ECCEN_Pos 1U /*!< SCB CACR: ECCEN Position */ +#define SCB_CACR_ECCEN_Msk (1UL << SCB_CACR_ECCEN_Pos) /*!< SCB CACR: ECCEN Mask */ + +#define SCB_CACR_SIWT_Pos 0U /*!< SCB CACR: SIWT Position */ +#define SCB_CACR_SIWT_Msk (1UL /*<< SCB_CACR_SIWT_Pos*/) /*!< SCB CACR: SIWT Mask */ + +/* AHBS Control Register Definitions */ +#define SCB_AHBSCR_INITCOUNT_Pos 11U /*!< SCB AHBSCR: INITCOUNT Position */ +#define SCB_AHBSCR_INITCOUNT_Msk (0x1FUL << SCB_AHBPCR_INITCOUNT_Pos) /*!< SCB AHBSCR: INITCOUNT Mask */ + +#define SCB_AHBSCR_TPRI_Pos 2U /*!< SCB AHBSCR: TPRI Position */ +#define SCB_AHBSCR_TPRI_Msk (0x1FFUL << SCB_AHBPCR_TPRI_Pos) /*!< SCB AHBSCR: TPRI Mask */ + +#define SCB_AHBSCR_CTL_Pos 0U /*!< SCB AHBSCR: CTL Position*/ +#define SCB_AHBSCR_CTL_Msk (3UL /*<< SCB_AHBPCR_CTL_Pos*/) /*!< SCB AHBSCR: CTL Mask */ + +/* Auxiliary Bus Fault Status Register Definitions */ +#define SCB_ABFSR_AXIMTYPE_Pos 8U /*!< SCB ABFSR: AXIMTYPE Position*/ +#define SCB_ABFSR_AXIMTYPE_Msk (3UL << SCB_ABFSR_AXIMTYPE_Pos) /*!< SCB ABFSR: AXIMTYPE Mask */ + +#define SCB_ABFSR_EPPB_Pos 4U /*!< SCB ABFSR: EPPB Position*/ +#define SCB_ABFSR_EPPB_Msk (1UL << SCB_ABFSR_EPPB_Pos) /*!< SCB ABFSR: EPPB Mask */ + +#define SCB_ABFSR_AXIM_Pos 3U /*!< SCB ABFSR: AXIM Position*/ +#define SCB_ABFSR_AXIM_Msk (1UL << SCB_ABFSR_AXIM_Pos) /*!< SCB ABFSR: AXIM Mask */ + +#define SCB_ABFSR_AHBP_Pos 2U /*!< SCB ABFSR: AHBP Position*/ +#define SCB_ABFSR_AHBP_Msk (1UL << SCB_ABFSR_AHBP_Pos) /*!< SCB ABFSR: AHBP Mask */ + +#define SCB_ABFSR_DTCM_Pos 1U /*!< SCB ABFSR: DTCM Position*/ +#define SCB_ABFSR_DTCM_Msk (1UL << SCB_ABFSR_DTCM_Pos) /*!< SCB ABFSR: DTCM Mask */ + +#define SCB_ABFSR_ITCM_Pos 0U /*!< SCB ABFSR: ITCM Position*/ +#define SCB_ABFSR_ITCM_Msk (1UL /*<< SCB_ABFSR_ITCM_Pos*/) /*!< SCB ABFSR: ITCM Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** + \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IM uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ + __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ + __IOM uint32_t CPPWR; /*!< Offset: 0x00C (R/W) Coprocessor Power Control Register */ +} SCnSCB_Type; + +/* Interrupt Controller Type Register Definitions */ +#define SCnSCB_ICTR_INTLINESNUM_Pos 0U /*!< ICTR: INTLINESNUM Position */ +#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/) /*!< ICTR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) + \brief Type definitions for the Instrumentation Trace Macrocell (ITM) + @{ + */ + +/** + \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). + */ +typedef struct +{ + __OM union + { + __OM uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ + __OM uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ + __OM uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ + } PORT [32U]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ + uint32_t RESERVED0[864U]; + __IOM uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ + uint32_t RESERVED1[15U]; + __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ + uint32_t RESERVED2[15U]; + __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ + uint32_t RESERVED3[29U]; + __OM uint32_t IWR; /*!< Offset: 0xEF8 ( /W) ITM Integration Write Register */ + __IM uint32_t IRR; /*!< Offset: 0xEFC (R/ ) ITM Integration Read Register */ + __IOM uint32_t IMCR; /*!< Offset: 0xF00 (R/W) ITM Integration Mode Control Register */ + uint32_t RESERVED4[43U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ + uint32_t RESERVED5[1U]; + __IM uint32_t DEVARCH; /*!< Offset: 0xFBC (R/ ) ITM Device Architecture Register */ + uint32_t RESERVED6[4U]; + __IM uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ + __IM uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ + __IM uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ + __IM uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ + __IM uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ + __IM uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ + __IM uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ + __IM uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ + __IM uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ + __IM uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ + __IM uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ + __IM uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ +} ITM_Type; + +/* ITM Stimulus Port Register Definitions */ +#define ITM_STIM_DISABLED_Pos 1U /*!< ITM STIM: DISABLED Position */ +#define ITM_STIM_DISABLED_Msk (0x1UL << ITM_STIM_DISABLED_Pos) /*!< ITM STIM: DISABLED Mask */ + +#define ITM_STIM_FIFOREADY_Pos 0U /*!< ITM STIM: FIFOREADY Position */ +#define ITM_STIM_FIFOREADY_Msk (0x1UL /*<< ITM_STIM_FIFOREADY_Pos*/) /*!< ITM STIM: FIFOREADY Mask */ + +/* ITM Trace Privilege Register Definitions */ +#define ITM_TPR_PRIVMASK_Pos 0U /*!< 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 23U /*!< ITM TCR: BUSY Position */ +#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ + +#define ITM_TCR_TRACEBUSID_Pos 16U /*!< ITM TCR: ATBID Position */ +#define ITM_TCR_TRACEBUSID_Msk (0x7FUL << ITM_TCR_TRACEBUSID_Pos) /*!< ITM TCR: ATBID Mask */ + +#define ITM_TCR_GTSFREQ_Pos 10U /*!< 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 8U /*!< ITM TCR: TSPRESCALE Position */ +#define ITM_TCR_TSPRESCALE_Msk (3UL << ITM_TCR_TSPRESCALE_Pos) /*!< ITM TCR: TSPRESCALE Mask */ + +#define ITM_TCR_STALLENA_Pos 5U /*!< ITM TCR: STALLENA Position */ +#define ITM_TCR_STALLENA_Msk (1UL << ITM_TCR_STALLENA_Pos) /*!< ITM TCR: STALLENA Mask */ + +#define ITM_TCR_SWOENA_Pos 4U /*!< ITM TCR: SWOENA Position */ +#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ + +#define ITM_TCR_DWTENA_Pos 3U /*!< ITM TCR: DWTENA Position */ +#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ + +#define ITM_TCR_SYNCENA_Pos 2U /*!< ITM TCR: SYNCENA Position */ +#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ + +#define ITM_TCR_TSENA_Pos 1U /*!< ITM TCR: TSENA Position */ +#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ + +#define ITM_TCR_ITMENA_Pos 0U /*!< ITM TCR: ITM Enable bit Position */ +#define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */ + +/* ITM Integration Write Register Definitions */ +#define ITM_IWR_ATVALIDM_Pos 0U /*!< ITM IWR: ATVALIDM Position */ +#define ITM_IWR_ATVALIDM_Msk (1UL /*<< ITM_IWR_ATVALIDM_Pos*/) /*!< ITM IWR: ATVALIDM Mask */ + +/* ITM Integration Read Register Definitions */ +#define ITM_IRR_ATREADYM_Pos 0U /*!< ITM IRR: ATREADYM Position */ +#define ITM_IRR_ATREADYM_Msk (1UL /*<< ITM_IRR_ATREADYM_Pos*/) /*!< ITM IRR: ATREADYM Mask */ + +/* ITM Integration Mode Control Register Definitions */ +#define ITM_IMCR_INTEGRATION_Pos 0U /*!< ITM IMCR: INTEGRATION Position */ +#define ITM_IMCR_INTEGRATION_Msk (1UL /*<< ITM_IMCR_INTEGRATION_Pos*/) /*!< ITM IMCR: INTEGRATION Mask */ + +/* ITM Lock Status Register Definitions */ +#define ITM_LSR_ByteAcc_Pos 2U /*!< ITM LSR: ByteAcc Position */ +#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ + +#define ITM_LSR_Access_Pos 1U /*!< ITM LSR: Access Position */ +#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ + +#define ITM_LSR_Present_Pos 0U /*!< ITM LSR: Present Position */ +#define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */ + +/*@}*/ /* end of group CMSIS_ITM */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** + \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + __IOM uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ + __IOM uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ + __IOM uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ + __IOM uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ + __IOM uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ + __IOM uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ + __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + uint32_t RESERVED1[1U]; + __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + uint32_t RESERVED3[1U]; + __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED4[1U]; + __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + uint32_t RESERVED5[1U]; + __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED6[1U]; + __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + uint32_t RESERVED7[1U]; + __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ + uint32_t RESERVED8[1U]; + __IOM uint32_t COMP4; /*!< Offset: 0x060 (R/W) Comparator Register 4 */ + uint32_t RESERVED9[1U]; + __IOM uint32_t FUNCTION4; /*!< Offset: 0x068 (R/W) Function Register 4 */ + uint32_t RESERVED10[1U]; + __IOM uint32_t COMP5; /*!< Offset: 0x070 (R/W) Comparator Register 5 */ + uint32_t RESERVED11[1U]; + __IOM uint32_t FUNCTION5; /*!< Offset: 0x078 (R/W) Function Register 5 */ + uint32_t RESERVED12[1U]; + __IOM uint32_t COMP6; /*!< Offset: 0x080 (R/W) Comparator Register 6 */ + uint32_t RESERVED13[1U]; + __IOM uint32_t FUNCTION6; /*!< Offset: 0x088 (R/W) Function Register 6 */ + uint32_t RESERVED14[1U]; + __IOM uint32_t COMP7; /*!< Offset: 0x090 (R/W) Comparator Register 7 */ + uint32_t RESERVED15[1U]; + __IOM uint32_t FUNCTION7; /*!< Offset: 0x098 (R/W) Function Register 7 */ + uint32_t RESERVED16[1U]; + __IOM uint32_t COMP8; /*!< Offset: 0x0A0 (R/W) Comparator Register 8 */ + uint32_t RESERVED17[1U]; + __IOM uint32_t FUNCTION8; /*!< Offset: 0x0A8 (R/W) Function Register 8 */ + uint32_t RESERVED18[1U]; + __IOM uint32_t COMP9; /*!< Offset: 0x0B0 (R/W) Comparator Register 9 */ + uint32_t RESERVED19[1U]; + __IOM uint32_t FUNCTION9; /*!< Offset: 0x0B8 (R/W) Function Register 9 */ + uint32_t RESERVED20[1U]; + __IOM uint32_t COMP10; /*!< Offset: 0x0C0 (R/W) Comparator Register 10 */ + uint32_t RESERVED21[1U]; + __IOM uint32_t FUNCTION10; /*!< Offset: 0x0C8 (R/W) Function Register 10 */ + uint32_t RESERVED22[1U]; + __IOM uint32_t COMP11; /*!< Offset: 0x0D0 (R/W) Comparator Register 11 */ + uint32_t RESERVED23[1U]; + __IOM uint32_t FUNCTION11; /*!< Offset: 0x0D8 (R/W) Function Register 11 */ + uint32_t RESERVED24[1U]; + __IOM uint32_t COMP12; /*!< Offset: 0x0E0 (R/W) Comparator Register 12 */ + uint32_t RESERVED25[1U]; + __IOM uint32_t FUNCTION12; /*!< Offset: 0x0E8 (R/W) Function Register 12 */ + uint32_t RESERVED26[1U]; + __IOM uint32_t COMP13; /*!< Offset: 0x0F0 (R/W) Comparator Register 13 */ + uint32_t RESERVED27[1U]; + __IOM uint32_t FUNCTION13; /*!< Offset: 0x0F8 (R/W) Function Register 13 */ + uint32_t RESERVED28[1U]; + __IOM uint32_t COMP14; /*!< Offset: 0x100 (R/W) Comparator Register 14 */ + uint32_t RESERVED29[1U]; + __IOM uint32_t FUNCTION14; /*!< Offset: 0x108 (R/W) Function Register 14 */ + uint32_t RESERVED30[1U]; + __IOM uint32_t COMP15; /*!< Offset: 0x110 (R/W) Comparator Register 15 */ + uint32_t RESERVED31[1U]; + __IOM uint32_t FUNCTION15; /*!< Offset: 0x118 (R/W) Function Register 15 */ + uint32_t RESERVED32[934U]; + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R ) Lock Status Register */ + uint32_t RESERVED33[1U]; + __IM uint32_t DEVARCH; /*!< Offset: 0xFBC (R/ ) Device Architecture Register */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +#define DWT_CTRL_CYCDISS_Pos 23U /*!< DWT CTRL: CYCDISS Position */ +#define DWT_CTRL_CYCDISS_Msk (0x1UL << DWT_CTRL_CYCDISS_Pos) /*!< DWT CTRL: CYCDISS Mask */ + +#define DWT_CTRL_CYCEVTENA_Pos 22U /*!< DWT CTRL: CYCEVTENA Position */ +#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ + +#define DWT_CTRL_FOLDEVTENA_Pos 21U /*!< DWT CTRL: FOLDEVTENA Position */ +#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ + +#define DWT_CTRL_LSUEVTENA_Pos 20U /*!< DWT CTRL: LSUEVTENA Position */ +#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ + +#define DWT_CTRL_SLEEPEVTENA_Pos 19U /*!< DWT CTRL: SLEEPEVTENA Position */ +#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ + +#define DWT_CTRL_EXCEVTENA_Pos 18U /*!< DWT CTRL: EXCEVTENA Position */ +#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ + +#define DWT_CTRL_CPIEVTENA_Pos 17U /*!< DWT CTRL: CPIEVTENA Position */ +#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ + +#define DWT_CTRL_EXCTRCENA_Pos 16U /*!< DWT CTRL: EXCTRCENA Position */ +#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ + +#define DWT_CTRL_PCSAMPLENA_Pos 12U /*!< DWT CTRL: PCSAMPLENA Position */ +#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ + +#define DWT_CTRL_SYNCTAP_Pos 10U /*!< DWT CTRL: SYNCTAP Position */ +#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ + +#define DWT_CTRL_CYCTAP_Pos 9U /*!< DWT CTRL: CYCTAP Position */ +#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ + +#define DWT_CTRL_POSTINIT_Pos 5U /*!< DWT CTRL: POSTINIT Position */ +#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ + +#define DWT_CTRL_POSTPRESET_Pos 1U /*!< DWT CTRL: POSTPRESET Position */ +#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ + +#define DWT_CTRL_CYCCNTENA_Pos 0U /*!< DWT CTRL: CYCCNTENA Position */ +#define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */ + +/* DWT CPI Count Register Definitions */ +#define DWT_CPICNT_CPICNT_Pos 0U /*!< DWT CPICNT: CPICNT Position */ +#define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */ + +/* DWT Exception Overhead Count Register Definitions */ +#define DWT_EXCCNT_EXCCNT_Pos 0U /*!< DWT EXCCNT: EXCCNT Position */ +#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */ + +/* DWT Sleep Count Register Definitions */ +#define DWT_SLEEPCNT_SLEEPCNT_Pos 0U /*!< DWT SLEEPCNT: SLEEPCNT Position */ +#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ + +/* DWT LSU Count Register Definitions */ +#define DWT_LSUCNT_LSUCNT_Pos 0U /*!< DWT LSUCNT: LSUCNT Position */ +#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */ + +/* DWT Folded-instruction Count Register Definitions */ +#define DWT_FOLDCNT_FOLDCNT_Pos 0U /*!< DWT FOLDCNT: FOLDCNT Position */ +#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_ID_Pos 27U /*!< DWT FUNCTION: ID Position */ +#define DWT_FUNCTION_ID_Msk (0x1FUL << DWT_FUNCTION_ID_Pos) /*!< DWT FUNCTION: ID Mask */ + +#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_ACTION_Pos 4U /*!< DWT FUNCTION: ACTION Position */ +#define DWT_FUNCTION_ACTION_Msk (0x1UL << DWT_FUNCTION_ACTION_Pos) /*!< DWT FUNCTION: ACTION Mask */ + +#define DWT_FUNCTION_MATCH_Pos 0U /*!< DWT FUNCTION: MATCH Position */ +#define DWT_FUNCTION_MATCH_Msk (0xFUL /*<< DWT_FUNCTION_MATCH_Pos*/) /*!< DWT FUNCTION: MATCH Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** + \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IOM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55U]; + __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131U]; + __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __IM uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ + uint32_t RESERVED3[759U]; + __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER */ + __IM uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ + __IM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ + uint32_t RESERVED4[1U]; + __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */ + __IM uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */ + __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ + uint32_t RESERVED5[39U]; + __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ + __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ + uint32_t RESERVED7[8U]; + __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_PRESCALER_Pos 0U /*!< TPI ACPR: PRESCALER Position */ +#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< TPI ACPR: PRESCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI TRIGGER Register Definitions */ +#define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */ +#define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */ + +/* TPI Integration ETM Data Register Definitions (FIFO0) */ +#define TPI_FIFO0_ITM_ATVALID_Pos 29U /*!< TPI FIFO0: ITM_ATVALID Position */ +#define TPI_FIFO0_ITM_ATVALID_Msk (0x3UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ + +#define TPI_FIFO0_ITM_bytecount_Pos 27U /*!< TPI FIFO0: ITM_bytecount Position */ +#define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */ + +#define TPI_FIFO0_ETM_ATVALID_Pos 26U /*!< TPI FIFO0: ETM_ATVALID Position */ +#define TPI_FIFO0_ETM_ATVALID_Msk (0x3UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ + +#define TPI_FIFO0_ETM_bytecount_Pos 24U /*!< TPI FIFO0: ETM_bytecount Position */ +#define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */ + +#define TPI_FIFO0_ETM2_Pos 16U /*!< TPI FIFO0: ETM2 Position */ +#define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */ + +#define TPI_FIFO0_ETM1_Pos 8U /*!< TPI FIFO0: ETM1 Position */ +#define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */ + +#define TPI_FIFO0_ETM0_Pos 0U /*!< TPI FIFO0: ETM0 Position */ +#define TPI_FIFO0_ETM0_Msk (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/) /*!< TPI FIFO0: ETM0 Mask */ + +/* TPI ITATBCTR2 Register Definitions */ +#define TPI_ITATBCTR2_ATREADY_Pos 0U /*!< TPI ITATBCTR2: ATREADY Position */ +#define TPI_ITATBCTR2_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY_Pos*/) /*!< TPI ITATBCTR2: ATREADY Mask */ + +/* TPI Integration ITM Data Register Definitions (FIFO1) */ +#define TPI_FIFO1_ITM_ATVALID_Pos 29U /*!< TPI FIFO1: ITM_ATVALID Position */ +#define TPI_FIFO1_ITM_ATVALID_Msk (0x3UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ + +#define TPI_FIFO1_ITM_bytecount_Pos 27U /*!< TPI FIFO1: ITM_bytecount Position */ +#define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */ + +#define TPI_FIFO1_ETM_ATVALID_Pos 26U /*!< TPI FIFO1: ETM_ATVALID Position */ +#define TPI_FIFO1_ETM_ATVALID_Msk (0x3UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ + +#define TPI_FIFO1_ETM_bytecount_Pos 24U /*!< TPI FIFO1: ETM_bytecount Position */ +#define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */ + +#define TPI_FIFO1_ITM2_Pos 16U /*!< TPI FIFO1: ITM2 Position */ +#define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */ + +#define TPI_FIFO1_ITM1_Pos 8U /*!< TPI FIFO1: ITM1 Position */ +#define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */ + +#define TPI_FIFO1_ITM0_Pos 0U /*!< TPI FIFO1: ITM0 Position */ +#define TPI_FIFO1_ITM0_Msk (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/) /*!< TPI FIFO1: ITM0 Mask */ + +/* TPI ITATBCTR0 Register Definitions */ +#define TPI_ITATBCTR0_ATREADY_Pos 0U /*!< TPI ITATBCTR0: ATREADY Position */ +#define TPI_ITATBCTR0_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY_Pos*/) /*!< TPI ITATBCTR0: ATREADY Mask */ + +/* TPI Integration Mode Control Register Definitions */ +#define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ +#define TPI_ITCTRL_Mode_Msk (0x1UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_MinBufSz_Pos 6U /*!< TPI DEVID: MinBufSz Position */ +#define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */ + +#define TPI_DEVID_AsynClkIn_Pos 5U /*!< TPI DEVID: AsynClkIn Position */ +#define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */ + +#define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */ +#define TPI_DEVID_NrTraceInput_Msk (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_MajorType_Pos 4U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +#define TPI_DEVTYPE_SubType_Pos 0U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) MPU Region Limit Address Register */ + __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Region Base Address Register Alias 1 */ + __IOM uint32_t RLAR_A1; /*!< Offset: 0x018 (R/W) MPU Region Limit Address Register Alias 1 */ + __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Region Base Address Register Alias 2 */ + __IOM uint32_t RLAR_A2; /*!< Offset: 0x020 (R/W) MPU Region Limit Address Register Alias 2 */ + __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Region Base Address Register Alias 3 */ + __IOM uint32_t RLAR_A3; /*!< Offset: 0x028 (R/W) MPU Region Limit Address Register Alias 3 */ + uint32_t RESERVED0[1]; + __IOM uint32_t MAIR0; /*!< Offset: 0x030 (R/W) MPU Memory Attribute Indirection Register 0 */ + __IOM uint32_t MAIR1; /*!< Offset: 0x034 (R/W) MPU Memory Attribute Indirection Register 1 */ +} MPU_Type; + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_ADDR_Pos 5U /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_SH_Pos 3U /*!< MPU RBAR: SH Position */ +#define MPU_RBAR_SH_Msk (0x3UL << MPU_RBAR_SH_Pos) /*!< MPU RBAR: SH Mask */ + +#define MPU_RBAR_AP_Pos 1U /*!< MPU RBAR: AP Position */ +#define MPU_RBAR_AP_Msk (0x3UL << MPU_RBAR_AP_Pos) /*!< MPU RBAR: AP Mask */ + +#define MPU_RBAR_XN_Pos 0U /*!< MPU RBAR: XN Position */ +#define MPU_RBAR_XN_Msk (01UL /*<< MPU_RBAR_XN_Pos*/) /*!< MPU RBAR: XN Mask */ + +/* MPU Region Limit Address Register Definitions */ +#define MPU_RLAR_LIMIT_Pos 5U /*!< MPU RLAR: LIMIT Position */ +#define MPU_RLAR_LIMIT_Msk (0x7FFFFFFUL << MPU_RLAR_LIMIT_Pos) /*!< MPU RLAR: LIMIT Mask */ + +#define MPU_RLAR_AttrIndx_Pos 1U /*!< MPU RLAR: AttrIndx Position */ +#define MPU_RLAR_AttrIndx_Msk (0x7UL << MPU_RLAR_AttrIndx_Pos) /*!< MPU RLAR: AttrIndx Mask */ + +#define MPU_RLAR_EN_Pos 0U /*!< MPU RLAR: Region enable bit Position */ +#define MPU_RLAR_EN_Msk (1UL /*<< MPU_RLAR_EN_Pos*/) /*!< MPU RLAR: Region enable bit Disable Mask */ + +/* MPU Memory Attribute Indirection Register 0 Definitions */ +#define MPU_MAIR0_Attr3_Pos 24U /*!< MPU MAIR0: Attr3 Position */ +#define MPU_MAIR0_Attr3_Msk (0xFFUL << MPU_MAIR0_Attr3_Pos) /*!< MPU MAIR0: Attr3 Mask */ + +#define MPU_MAIR0_Attr2_Pos 16U /*!< MPU MAIR0: Attr2 Position */ +#define MPU_MAIR0_Attr2_Msk (0xFFUL << MPU_MAIR0_Attr2_Pos) /*!< MPU MAIR0: Attr2 Mask */ + +#define MPU_MAIR0_Attr1_Pos 8U /*!< MPU MAIR0: Attr1 Position */ +#define MPU_MAIR0_Attr1_Msk (0xFFUL << MPU_MAIR0_Attr1_Pos) /*!< MPU MAIR0: Attr1 Mask */ + +#define MPU_MAIR0_Attr0_Pos 0U /*!< MPU MAIR0: Attr0 Position */ +#define MPU_MAIR0_Attr0_Msk (0xFFUL /*<< MPU_MAIR0_Attr0_Pos*/) /*!< MPU MAIR0: Attr0 Mask */ + +/* MPU Memory Attribute Indirection Register 1 Definitions */ +#define MPU_MAIR1_Attr7_Pos 24U /*!< MPU MAIR1: Attr7 Position */ +#define MPU_MAIR1_Attr7_Msk (0xFFUL << MPU_MAIR1_Attr7_Pos) /*!< MPU MAIR1: Attr7 Mask */ + +#define MPU_MAIR1_Attr6_Pos 16U /*!< MPU MAIR1: Attr6 Position */ +#define MPU_MAIR1_Attr6_Msk (0xFFUL << MPU_MAIR1_Attr6_Pos) /*!< MPU MAIR1: Attr6 Mask */ + +#define MPU_MAIR1_Attr5_Pos 8U /*!< MPU MAIR1: Attr5 Position */ +#define MPU_MAIR1_Attr5_Msk (0xFFUL << MPU_MAIR1_Attr5_Pos) /*!< MPU MAIR1: Attr5 Mask */ + +#define MPU_MAIR1_Attr4_Pos 0U /*!< MPU MAIR1: Attr4 Position */ +#define MPU_MAIR1_Attr4_Msk (0xFFUL /*<< MPU_MAIR1_Attr4_Pos*/) /*!< MPU MAIR1: Attr4 Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SAU Security Attribution Unit (SAU) + \brief Type definitions for the Security Attribution Unit (SAU) + @{ + */ + +/** + \brief Structure type to access the Security Attribution Unit (SAU). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SAU Control Register */ + __IM uint32_t TYPE; /*!< Offset: 0x004 (R/ ) SAU Type Register */ +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) SAU Region Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) SAU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) SAU Region Limit Address Register */ +#else + uint32_t RESERVED0[3]; +#endif + __IOM uint32_t SFSR; /*!< Offset: 0x014 (R/W) Secure Fault Status Register */ + __IOM uint32_t SFAR; /*!< Offset: 0x018 (R/W) Secure Fault Address Register */ +} SAU_Type; + +/* SAU Control Register Definitions */ +#define SAU_CTRL_ALLNS_Pos 1U /*!< SAU CTRL: ALLNS Position */ +#define SAU_CTRL_ALLNS_Msk (1UL << SAU_CTRL_ALLNS_Pos) /*!< SAU CTRL: ALLNS Mask */ + +#define SAU_CTRL_ENABLE_Pos 0U /*!< SAU CTRL: ENABLE Position */ +#define SAU_CTRL_ENABLE_Msk (1UL /*<< SAU_CTRL_ENABLE_Pos*/) /*!< SAU CTRL: ENABLE Mask */ + +/* SAU Type Register Definitions */ +#define SAU_TYPE_SREGION_Pos 0U /*!< SAU TYPE: SREGION Position */ +#define SAU_TYPE_SREGION_Msk (0xFFUL /*<< SAU_TYPE_SREGION_Pos*/) /*!< SAU TYPE: SREGION Mask */ + +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) +/* SAU Region Number Register Definitions */ +#define SAU_RNR_REGION_Pos 0U /*!< SAU RNR: REGION Position */ +#define SAU_RNR_REGION_Msk (0xFFUL /*<< SAU_RNR_REGION_Pos*/) /*!< SAU RNR: REGION Mask */ + +/* SAU Region Base Address Register Definitions */ +#define SAU_RBAR_BADDR_Pos 5U /*!< SAU RBAR: BADDR Position */ +#define SAU_RBAR_BADDR_Msk (0x7FFFFFFUL << SAU_RBAR_BADDR_Pos) /*!< SAU RBAR: BADDR Mask */ + +/* SAU Region Limit Address Register Definitions */ +#define SAU_RLAR_LADDR_Pos 5U /*!< SAU RLAR: LADDR Position */ +#define SAU_RLAR_LADDR_Msk (0x7FFFFFFUL << SAU_RLAR_LADDR_Pos) /*!< SAU RLAR: LADDR Mask */ + +#define SAU_RLAR_NSC_Pos 1U /*!< SAU RLAR: NSC Position */ +#define SAU_RLAR_NSC_Msk (1UL << SAU_RLAR_NSC_Pos) /*!< SAU RLAR: NSC Mask */ + +#define SAU_RLAR_ENABLE_Pos 0U /*!< SAU RLAR: ENABLE Position */ +#define SAU_RLAR_ENABLE_Msk (1UL /*<< SAU_RLAR_ENABLE_Pos*/) /*!< SAU RLAR: ENABLE Mask */ + +#endif /* defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) */ + +/* Secure Fault Status Register Definitions */ +#define SAU_SFSR_LSERR_Pos 7U /*!< SAU SFSR: LSERR Position */ +#define SAU_SFSR_LSERR_Msk (1UL << SAU_SFSR_LSERR_Pos) /*!< SAU SFSR: LSERR Mask */ + +#define SAU_SFSR_SFARVALID_Pos 6U /*!< SAU SFSR: SFARVALID Position */ +#define SAU_SFSR_SFARVALID_Msk (1UL << SAU_SFSR_SFARVALID_Pos) /*!< SAU SFSR: SFARVALID Mask */ + +#define SAU_SFSR_LSPERR_Pos 5U /*!< SAU SFSR: LSPERR Position */ +#define SAU_SFSR_LSPERR_Msk (1UL << SAU_SFSR_LSPERR_Pos) /*!< SAU SFSR: LSPERR Mask */ + +#define SAU_SFSR_INVTRAN_Pos 4U /*!< SAU SFSR: INVTRAN Position */ +#define SAU_SFSR_INVTRAN_Msk (1UL << SAU_SFSR_INVTRAN_Pos) /*!< SAU SFSR: INVTRAN Mask */ + +#define SAU_SFSR_AUVIOL_Pos 3U /*!< SAU SFSR: AUVIOL Position */ +#define SAU_SFSR_AUVIOL_Msk (1UL << SAU_SFSR_AUVIOL_Pos) /*!< SAU SFSR: AUVIOL Mask */ + +#define SAU_SFSR_INVER_Pos 2U /*!< SAU SFSR: INVER Position */ +#define SAU_SFSR_INVER_Msk (1UL << SAU_SFSR_INVER_Pos) /*!< SAU SFSR: INVER Mask */ + +#define SAU_SFSR_INVIS_Pos 1U /*!< SAU SFSR: INVIS Position */ +#define SAU_SFSR_INVIS_Msk (1UL << SAU_SFSR_INVIS_Pos) /*!< SAU SFSR: INVIS Mask */ + +#define SAU_SFSR_INVEP_Pos 0U /*!< SAU SFSR: INVEP Position */ +#define SAU_SFSR_INVEP_Msk (1UL /*<< SAU_SFSR_INVEP_Pos*/) /*!< SAU SFSR: INVEP Mask */ + +/*@} end of group CMSIS_SAU */ +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_FPU Floating Point Unit (FPU) + \brief Type definitions for the Floating Point Unit (FPU) + @{ + */ + +/** + \brief Structure type to access the Floating Point Unit (FPU). + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IOM uint32_t FPCCR; /*!< Offset: 0x004 (R/W) Floating-Point Context Control Register */ + __IOM uint32_t FPCAR; /*!< Offset: 0x008 (R/W) Floating-Point Context Address Register */ + __IOM uint32_t FPDSCR; /*!< Offset: 0x00C (R/W) Floating-Point Default Status Control Register */ + __IM uint32_t MVFR0; /*!< Offset: 0x010 (R/ ) Media and FP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x014 (R/ ) Media and FP Feature Register 1 */ +} FPU_Type; + +/* Floating-Point Context Control Register Definitions */ +#define FPU_FPCCR_ASPEN_Pos 31U /*!< FPCCR: ASPEN bit Position */ +#define FPU_FPCCR_ASPEN_Msk (1UL << FPU_FPCCR_ASPEN_Pos) /*!< FPCCR: ASPEN bit Mask */ + +#define FPU_FPCCR_LSPEN_Pos 30U /*!< FPCCR: LSPEN Position */ +#define FPU_FPCCR_LSPEN_Msk (1UL << FPU_FPCCR_LSPEN_Pos) /*!< FPCCR: LSPEN bit Mask */ + +#define FPU_FPCCR_LSPENS_Pos 29U /*!< FPCCR: LSPENS Position */ +#define FPU_FPCCR_LSPENS_Msk (1UL << FPU_FPCCR_LSPENS_Pos) /*!< FPCCR: LSPENS bit Mask */ + +#define FPU_FPCCR_CLRONRET_Pos 28U /*!< FPCCR: CLRONRET Position */ +#define FPU_FPCCR_CLRONRET_Msk (1UL << FPU_FPCCR_CLRONRET_Pos) /*!< FPCCR: CLRONRET bit Mask */ + +#define FPU_FPCCR_CLRONRETS_Pos 27U /*!< FPCCR: CLRONRETS Position */ +#define FPU_FPCCR_CLRONRETS_Msk (1UL << FPU_FPCCR_CLRONRETS_Pos) /*!< FPCCR: CLRONRETS bit Mask */ + +#define FPU_FPCCR_TS_Pos 26U /*!< FPCCR: TS Position */ +#define FPU_FPCCR_TS_Msk (1UL << FPU_FPCCR_TS_Pos) /*!< FPCCR: TS bit Mask */ + +#define FPU_FPCCR_UFRDY_Pos 10U /*!< FPCCR: UFRDY Position */ +#define FPU_FPCCR_UFRDY_Msk (1UL << FPU_FPCCR_UFRDY_Pos) /*!< FPCCR: UFRDY bit Mask */ + +#define FPU_FPCCR_SPLIMVIOL_Pos 9U /*!< FPCCR: SPLIMVIOL Position */ +#define FPU_FPCCR_SPLIMVIOL_Msk (1UL << FPU_FPCCR_SPLIMVIOL_Pos) /*!< FPCCR: SPLIMVIOL bit Mask */ + +#define FPU_FPCCR_MONRDY_Pos 8U /*!< FPCCR: MONRDY Position */ +#define FPU_FPCCR_MONRDY_Msk (1UL << FPU_FPCCR_MONRDY_Pos) /*!< FPCCR: MONRDY bit Mask */ + +#define FPU_FPCCR_SFRDY_Pos 7U /*!< FPCCR: SFRDY Position */ +#define FPU_FPCCR_SFRDY_Msk (1UL << FPU_FPCCR_SFRDY_Pos) /*!< FPCCR: SFRDY bit Mask */ + +#define FPU_FPCCR_BFRDY_Pos 6U /*!< FPCCR: BFRDY Position */ +#define FPU_FPCCR_BFRDY_Msk (1UL << FPU_FPCCR_BFRDY_Pos) /*!< FPCCR: BFRDY bit Mask */ + +#define FPU_FPCCR_MMRDY_Pos 5U /*!< FPCCR: MMRDY Position */ +#define FPU_FPCCR_MMRDY_Msk (1UL << FPU_FPCCR_MMRDY_Pos) /*!< FPCCR: MMRDY bit Mask */ + +#define FPU_FPCCR_HFRDY_Pos 4U /*!< FPCCR: HFRDY Position */ +#define FPU_FPCCR_HFRDY_Msk (1UL << FPU_FPCCR_HFRDY_Pos) /*!< FPCCR: HFRDY bit Mask */ + +#define FPU_FPCCR_THREAD_Pos 3U /*!< FPCCR: processor mode bit Position */ +#define FPU_FPCCR_THREAD_Msk (1UL << FPU_FPCCR_THREAD_Pos) /*!< FPCCR: processor mode active bit Mask */ + +#define FPU_FPCCR_S_Pos 2U /*!< FPCCR: Security status of the FP context bit Position */ +#define FPU_FPCCR_S_Msk (1UL << FPU_FPCCR_S_Pos) /*!< FPCCR: Security status of the FP context bit Mask */ + +#define FPU_FPCCR_USER_Pos 1U /*!< 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 0U /*!< 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 Definitions */ +#define FPU_FPCAR_ADDRESS_Pos 3U /*!< FPCAR: ADDRESS bit Position */ +#define FPU_FPCAR_ADDRESS_Msk (0x1FFFFFFFUL << FPU_FPCAR_ADDRESS_Pos) /*!< FPCAR: ADDRESS bit Mask */ + +/* Floating-Point Default Status Control Register Definitions */ +#define FPU_FPDSCR_AHP_Pos 26U /*!< FPDSCR: AHP bit Position */ +#define FPU_FPDSCR_AHP_Msk (1UL << FPU_FPDSCR_AHP_Pos) /*!< FPDSCR: AHP bit Mask */ + +#define FPU_FPDSCR_DN_Pos 25U /*!< FPDSCR: DN bit Position */ +#define FPU_FPDSCR_DN_Msk (1UL << FPU_FPDSCR_DN_Pos) /*!< FPDSCR: DN bit Mask */ + +#define FPU_FPDSCR_FZ_Pos 24U /*!< FPDSCR: FZ bit Position */ +#define FPU_FPDSCR_FZ_Msk (1UL << FPU_FPDSCR_FZ_Pos) /*!< FPDSCR: FZ bit Mask */ + +#define FPU_FPDSCR_RMode_Pos 22U /*!< FPDSCR: RMode bit Position */ +#define FPU_FPDSCR_RMode_Msk (3UL << FPU_FPDSCR_RMode_Pos) /*!< FPDSCR: RMode bit Mask */ + +/* Media and FP Feature Register 0 Definitions */ +#define FPU_MVFR0_FP_rounding_modes_Pos 28U /*!< 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 24U /*!< 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 20U /*!< 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 16U /*!< 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 12U /*!< 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 8U /*!< 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 4U /*!< 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 0U /*!< 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 Definitions */ +#define FPU_MVFR1_FP_fused_MAC_Pos 28U /*!< 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 24U /*!< 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 4U /*!< 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 0U /*!< 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 */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** + \brief Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ + uint32_t RESERVED4[1U]; + __IOM uint32_t DAUTHCTRL; /*!< Offset: 0x014 (R/W) Debug Authentication Control Register */ + __IOM uint32_t DSCSR; /*!< Offset: 0x018 (R/W) Debug Security Control and Status Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register Definitions */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESTART_ST_Pos 26U /*!< CoreDebug DHCSR: S_RESTART_ST Position */ +#define CoreDebug_DHCSR_S_RESTART_ST_Msk (1UL << CoreDebug_DHCSR_S_RESTART_ST_Pos) /*!< CoreDebug DHCSR: S_RESTART_ST Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< 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 24U /*!< 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 19U /*!< 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 18U /*!< 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 17U /*!< 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 16U /*!< 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 5U /*!< 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 3U /*!< 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 2U /*!< 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 1U /*!< 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 0U /*!< 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 Definitions */ +#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register Definitions */ +#define CoreDebug_DEMCR_TRCENA_Pos 24U /*!< CoreDebug DEMCR: TRCENA Position */ +#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ + +#define CoreDebug_DEMCR_MON_REQ_Pos 19U /*!< 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 18U /*!< 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 17U /*!< 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 16U /*!< 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 10U /*!< 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 9U /*!< 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 8U /*!< 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 7U /*!< 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 6U /*!< 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 5U /*!< 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 4U /*!< 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 0U /*!< CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ + +/* Debug Authentication Control Register Definitions */ +#define CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos 3U /*!< CoreDebug DAUTHCTRL: INTSPNIDEN, Position */ +#define CoreDebug_DAUTHCTRL_INTSPNIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos) /*!< CoreDebug DAUTHCTRL: INTSPNIDEN, Mask */ + +#define CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos 2U /*!< CoreDebug DAUTHCTRL: SPNIDENSEL Position */ +#define CoreDebug_DAUTHCTRL_SPNIDENSEL_Msk (1UL << CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos) /*!< CoreDebug DAUTHCTRL: SPNIDENSEL Mask */ + +#define CoreDebug_DAUTHCTRL_INTSPIDEN_Pos 1U /*!< CoreDebug DAUTHCTRL: INTSPIDEN Position */ +#define CoreDebug_DAUTHCTRL_INTSPIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPIDEN_Pos) /*!< CoreDebug DAUTHCTRL: INTSPIDEN Mask */ + +#define CoreDebug_DAUTHCTRL_SPIDENSEL_Pos 0U /*!< CoreDebug DAUTHCTRL: SPIDENSEL Position */ +#define CoreDebug_DAUTHCTRL_SPIDENSEL_Msk (1UL /*<< CoreDebug_DAUTHCTRL_SPIDENSEL_Pos*/) /*!< CoreDebug DAUTHCTRL: SPIDENSEL Mask */ + +/* Debug Security Control and Status Register Definitions */ +#define CoreDebug_DSCSR_CDS_Pos 16U /*!< CoreDebug DSCSR: CDS Position */ +#define CoreDebug_DSCSR_CDS_Msk (1UL << CoreDebug_DSCSR_CDS_Pos) /*!< CoreDebug DSCSR: CDS Mask */ + +#define CoreDebug_DSCSR_SBRSEL_Pos 1U /*!< CoreDebug DSCSR: SBRSEL Position */ +#define CoreDebug_DSCSR_SBRSEL_Msk (1UL << CoreDebug_DSCSR_SBRSEL_Pos) /*!< CoreDebug DSCSR: SBRSEL Mask */ + +#define CoreDebug_DSCSR_SBRSELEN_Pos 0U /*!< CoreDebug DSCSR: SBRSELEN Position */ +#define CoreDebug_DSCSR_SBRSELEN_Msk (1UL /*<< CoreDebug_DSCSR_SBRSELEN_Pos*/) /*!< CoreDebug DSCSR: SBRSELEN Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ + #define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ + #define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ + #define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ + #define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ + #define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ + #define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ + #define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ + #define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + + #define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ + #define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ + #define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ + #define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ + #define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ + #define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ + #define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ + #define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE ) /*!< Core Debug configuration struct */ + + #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ + #endif + + #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + #define SAU_BASE (SCS_BASE + 0x0DD0UL) /*!< Security Attribution Unit */ + #define SAU ((SAU_Type *) SAU_BASE ) /*!< Security Attribution Unit */ + #endif + + #define FPU_BASE (SCS_BASE + 0x0F30UL) /*!< Floating Point Unit */ + #define FPU ((FPU_Type *) FPU_BASE ) /*!< Floating Point Unit */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + #define SCS_BASE_NS (0xE002E000UL) /*!< System Control Space Base Address (non-secure address space) */ + #define CoreDebug_BASE_NS (0xE002EDF0UL) /*!< Core Debug Base Address (non-secure address space) */ + #define SysTick_BASE_NS (SCS_BASE_NS + 0x0010UL) /*!< SysTick Base Address (non-secure address space) */ + #define NVIC_BASE_NS (SCS_BASE_NS + 0x0100UL) /*!< NVIC Base Address (non-secure address space) */ + #define SCB_BASE_NS (SCS_BASE_NS + 0x0D00UL) /*!< System Control Block Base Address (non-secure address space) */ + + #define SCnSCB_NS ((SCnSCB_Type *) SCS_BASE_NS ) /*!< System control Register not in SCB(non-secure address space) */ + #define SCB_NS ((SCB_Type *) SCB_BASE_NS ) /*!< SCB configuration struct (non-secure address space) */ + #define SysTick_NS ((SysTick_Type *) SysTick_BASE_NS ) /*!< SysTick configuration struct (non-secure address space) */ + #define NVIC_NS ((NVIC_Type *) NVIC_BASE_NS ) /*!< NVIC configuration struct (non-secure address space) */ + #define CoreDebug_NS ((CoreDebug_Type *) CoreDebug_BASE_NS) /*!< Core Debug configuration struct (non-secure address space) */ + + #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE_NS (SCS_BASE_NS + 0x0D90UL) /*!< Memory Protection Unit (non-secure address space) */ + #define MPU_NS ((MPU_Type *) MPU_BASE_NS ) /*!< Memory Protection Unit (non-secure address space) */ + #endif + + #define FPU_BASE_NS (SCS_BASE_NS + 0x0F30UL) /*!< Floating Point Unit (non-secure address space) */ + #define FPU_NS ((FPU_Type *) FPU_BASE_NS ) /*!< Floating Point Unit (non-secure address space) */ + +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Debug Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping + #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ + #define NVIC_GetActive __NVIC_GetActive + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + + +/** + \brief Set Priority Grouping + \details 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)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << 8U) ); /* Insert write key and priorty group */ + SCB->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping + \details Reads the priority grouping field from the NVIC Interrupt Controller. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t __NVIC_GetPriorityGrouping(void) +{ + return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt + \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IABR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Get Interrupt Target State + \details Reads the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + \return 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_GetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ITNS[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Target State + \details Sets the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_SetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)(int32_t)IRQn) >> 5UL)] |= ((uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Clear Interrupt Target State + \details Clears the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_ClearTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)(int32_t)IRQn) >> 5UL)] &= ~((uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IPR[((uint32_t)(int32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB->SHPR[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC->IPR[((uint32_t)(int32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB->SHPR[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Set Priority Grouping (non-secure) + \details Sets the non-secure priority grouping field when in secure state 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 TZ_NVIC_SetPriorityGrouping_NS(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB_NS->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << 8U) ); /* Insert write key and priorty group */ + SCB_NS->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping (non-secure) + \details Reads the priority grouping field from the non-secure NVIC when in secure state. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPriorityGrouping_NS(void) +{ + return ((uint32_t)((SCB_NS->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt (non-secure) + \details Enables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_EnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status (non-secure) + \details Returns a device specific interrupt enable status from the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetEnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt (non-secure) + \details Disables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_DisableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Pending Interrupt (non-secure) + \details Reads the NVIC pending register in the non-secure NVIC when in secure state and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt (non-secure) + \details Sets the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_SetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt (non-secure) + \details Clears the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_ClearPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt (non-secure) + \details Reads the active register in non-secure NVIC when in secure state and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetActive_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->IABR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Priority (non-secure) + \details Sets the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every non-secure processor exception. + */ +__STATIC_INLINE void TZ_NVIC_SetPriority_NS(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->IPR[((uint32_t)(int32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB_NS->SHPR[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority (non-secure) + \details Reads the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPriority_NS(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC_NS->IPR[((uint32_t)(int32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB_NS->SHPR[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) &&(__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_NVICFunctions */ + + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + uint32_t mvfr0; + + mvfr0 = FPU->MVFR0; + if ((mvfr0 & (FPU_MVFR0_Single_precision_Msk | FPU_MVFR0_Double_precision_Msk)) == 0x220U) + { + return 2U; /* Double + Single precision FPU */ + } + else if ((mvfr0 & (FPU_MVFR0_Single_precision_Msk | FPU_MVFR0_Double_precision_Msk)) == 0x020U) + { + return 1U; /* Single precision FPU */ + } + else + { + return 0U; /* No FPU */ + } +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ########################## SAU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SAUFunctions SAU Functions + \brief Functions that configure the SAU. + @{ + */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + +/** + \brief Enable SAU + \details Enables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Enable(void) +{ + SAU->CTRL |= (SAU_CTRL_ENABLE_Msk); +} + + + +/** + \brief Disable SAU + \details Disables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Disable(void) +{ + SAU->CTRL &= ~(SAU_CTRL_ENABLE_Msk); +} + +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_SAUFunctions */ + + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief System Tick Configuration (non-secure) + \details Initializes the non-secure System Timer and its interrupt when in secure state, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function TZ_SysTick_Config_NS is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + + */ +__STATIC_INLINE uint32_t TZ_SysTick_Config_NS(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick_NS->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + TZ_NVIC_SetPriority_NS (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick_NS->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick_NS->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + +/* ##################################### Debug In/Output function ########################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_core_DebugFunctions ITM Functions + \brief Functions that access the ITM debug interface. + @{ + */ + +extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ +#define ITM_RXBUFFER_EMPTY ((int32_t)0x5AA55AA5U) /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ + + +/** + \brief ITM Send Character + \details Transmits a character via the ITM channel 0, and + \li Just returns when no debugger is connected that has booked the output. + \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. + \param [in] ch Character to transmit. + \returns Character to transmit. + */ +__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) +{ + if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ + ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */ + { + while (ITM->PORT[0U].u32 == 0UL) + { + __NOP(); + } + ITM->PORT[0U].u8 = (uint8_t)ch; + } + return (ch); +} + + +/** + \brief ITM Receive Character + \details Inputs a character via the external variable \ref ITM_RxBuffer. + \return Received character. + \return -1 No character pending. + */ +__STATIC_INLINE int32_t ITM_ReceiveChar (void) +{ + int32_t ch = -1; /* no character available */ + + if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) + { + ch = ITM_RxBuffer; + ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ + } + + return (ch); +} + + +/** + \brief ITM Check Character + \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. + \return 0 No character available. + \return 1 Character available. + */ +__STATIC_INLINE int32_t ITM_CheckChar (void) +{ + + if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) + { + return (0); /* no character available */ + } + else + { + return (1); /* character available */ + } +} + +/*@} end of CMSIS_core_DebugFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_ARMV8MML_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/cmsis/core_ca.h b/cmsis/core_ca.h new file mode 100644 index 00000000000..6d1e29f60ff --- /dev/null +++ b/cmsis/core_ca.h @@ -0,0 +1,2016 @@ +/**************************************************************************//** + * @file core_ca.h + * @brief CMSIS Cortex-A Core Peripheral Access Layer Header File + * @version V1.00 + * @date 22. Feb 2017 + ******************************************************************************/ +/* + * Copyright (c) 2009-2017 ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#endif + +#ifdef __cplusplus + extern "C" { +#endif + +#ifndef __CORE_CA_H_GENERIC +#define __CORE_CA_H_GENERIC + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ + +/* CMSIS CA definitions */ +#define __CA_CMSIS_VERSION_MAIN (1U) /*!< \brief [31:16] CMSIS HAL main version */ +#define __CA_CMSIS_VERSION_SUB (0U) /*!< \brief [15:0] CMSIS HAL sub version */ +#define __CA_CMSIS_VERSION ((__CA_CMSIS_VERSION_MAIN << 16U) | \ + __CA_CMSIS_VERSION_SUB ) /*!< \brief CMSIS HAL version number */ + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #if (__FPU_PRESENT == 1) + #define __FPU_USED 1U + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #if (__FPU_PRESENT == 1) + #define __FPU_USED 1U + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __TMS470__ ) + #if defined __TI_VFP_SUPPORT__ + #if (__FPU_PRESENT == 1) + #define __FPU_USED 1U + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #if (__FPU_PRESENT == 1) + #define __FPU_USED 1U + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #if (__FPU_PRESENT == 1) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CA_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CA_H_DEPENDANT +#define __CORE_CA_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + + /* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CA_REV + #define __CA_REV 0x0000U + #warning "__CA_REV not defined in device header file; using default!" + #endif + + #ifndef __FPU_PRESENT + #define __FPU_PRESENT 0U + #warning "__FPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __GIC_PRESENT + #define __GIC_PRESENT 1U + #warning "__GIC_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __TIM_PRESENT + #define __TIM_PRESENT 1U + #warning "__TIM_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __L2C_PRESENT + #define __L2C_PRESENT 0U + #warning "__L2C_PRESENT not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +#ifdef __cplusplus + #define __I volatile /*!< \brief Defines 'read only' permissions */ +#else + #define __I volatile const /*!< \brief Defines 'read only' permissions */ +#endif +#define __O volatile /*!< \brief Defines 'write only' permissions */ +#define __IO volatile /*!< \brief Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*!< \brief Defines 'read only' structure member permissions */ +#define __OM volatile /*!< \brief Defines 'write only' structure member permissions */ +#define __IOM volatile /*!< \brief Defines 'read / write' structure member permissions */ + + + /******************************************************************************* + * Register Abstraction + Core Register contain: + - CPSR + - CP15 Registers + - L2C-310 Cache Controller + - Generic Interrupt Controller Distributor + - Generic Interrupt Controller Interface + ******************************************************************************/ + +/* Core Register CPSR */ +typedef union +{ + struct + { + uint32_t M:5; /*!< \brief bit: 0.. 4 Mode field */ + uint32_t T:1; /*!< \brief bit: 5 Thumb execution state bit */ + uint32_t F:1; /*!< \brief bit: 6 FIQ mask bit */ + uint32_t I:1; /*!< \brief bit: 7 IRQ mask bit */ + uint32_t A:1; /*!< \brief bit: 8 Asynchronous abort mask bit */ + uint32_t E:1; /*!< \brief bit: 9 Endianness execution state bit */ + uint32_t IT1:6; /*!< \brief bit: 10..15 If-Then execution state bits 2-7 */ + uint32_t GE:4; /*!< \brief bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved0:4; /*!< \brief bit: 20..23 Reserved */ + uint32_t J:1; /*!< \brief bit: 24 Jazelle bit */ + uint32_t IT0:2; /*!< \brief bit: 25..26 If-Then execution state bits 0-1 */ + uint32_t Q:1; /*!< \brief bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< \brief bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< \brief bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< \brief bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< \brief bit: 31 Negative condition code flag */ + } b; /*!< \brief Structure used for bit access */ + uint32_t w; /*!< \brief Type used for word access */ +} CPSR_Type; + +/* CPSR Register Definitions */ +#define CPSR_N_Pos 31U /*!< \brief CPSR: N Position */ +#define CPSR_N_Msk (1UL << CPSR_N_Pos) /*!< \brief CPSR: N Mask */ + +#define CPSR_Z_Pos 30U /*!< \brief CPSR: Z Position */ +#define CPSR_Z_Msk (1UL << CPSR_Z_Pos) /*!< \brief CPSR: Z Mask */ + +#define CPSR_C_Pos 29U /*!< \brief CPSR: C Position */ +#define CPSR_C_Msk (1UL << CPSR_C_Pos) /*!< \brief CPSR: C Mask */ + +#define CPSR_V_Pos 28U /*!< \brief CPSR: V Position */ +#define CPSR_V_Msk (1UL << CPSR_V_Pos) /*!< \brief CPSR: V Mask */ + +#define CPSR_Q_Pos 27U /*!< \brief CPSR: Q Position */ +#define CPSR_Q_Msk (1UL << CPSR_Q_Pos) /*!< \brief CPSR: Q Mask */ + +#define CPSR_IT0_Pos 25U /*!< \brief CPSR: IT0 Position */ +#define CPSR_IT0_Msk (3UL << CPSR_IT0_Pos) /*!< \brief CPSR: IT0 Mask */ + +#define CPSR_J_Pos 24U /*!< \brief CPSR: J Position */ +#define CPSR_J_Msk (1UL << CPSR_J_Pos) /*!< \brief CPSR: J Mask */ + +#define CPSR_GE_Pos 16U /*!< \brief CPSR: GE Position */ +#define CPSR_GE_Msk (0xFUL << CPSR_GE_Pos) /*!< \brief CPSR: GE Mask */ + +#define CPSR_IT1_Pos 10U /*!< \brief CPSR: IT1 Position */ +#define CPSR_IT1_Msk (0x3FUL << CPSR_IT1_Pos) /*!< \brief CPSR: IT1 Mask */ + +#define CPSR_E_Pos 9U /*!< \brief CPSR: E Position */ +#define CPSR_E_Msk (1UL << CPSR_E_Pos) /*!< \brief CPSR: E Mask */ + +#define CPSR_A_Pos 8U /*!< \brief CPSR: A Position */ +#define CPSR_A_Msk (1UL << CPSR_A_Pos) /*!< \brief CPSR: A Mask */ + +#define CPSR_I_Pos 7U /*!< \brief CPSR: I Position */ +#define CPSR_I_Msk (1UL << CPSR_I_Pos) /*!< \brief CPSR: I Mask */ + +#define CPSR_F_Pos 6U /*!< \brief CPSR: F Position */ +#define CPSR_F_Msk (1UL << CPSR_F_Pos) /*!< \brief CPSR: F Mask */ + +#define CPSR_T_Pos 5U /*!< \brief CPSR: T Position */ +#define CPSR_T_Msk (1UL << CPSR_T_Pos) /*!< \brief CPSR: T Mask */ + +#define CPSR_M_Pos 0U /*!< \brief CPSR: M Position */ +#define CPSR_M_Msk (0x1FUL << CPSR_M_Pos) /*!< \brief CPSR: M Mask */ + +/* CP15 Register SCTLR */ +typedef union +{ + struct + { + uint32_t M:1; /*!< \brief bit: 0 MMU enable */ + uint32_t A:1; /*!< \brief bit: 1 Alignment check enable */ + uint32_t C:1; /*!< \brief bit: 2 Cache enable */ + uint32_t _reserved0:2; /*!< \brief bit: 3.. 4 Reserved */ + uint32_t CP15BEN:1; /*!< \brief bit: 5 CP15 barrier enable */ + uint32_t _reserved1:1; /*!< \brief bit: 6 Reserved */ + uint32_t B:1; /*!< \brief bit: 7 Endianness model */ + uint32_t _reserved2:2; /*!< \brief bit: 8.. 9 Reserved */ + uint32_t SW:1; /*!< \brief bit: 10 SWP and SWPB enable */ + uint32_t Z:1; /*!< \brief bit: 11 Branch prediction enable */ + uint32_t I:1; /*!< \brief bit: 12 Instruction cache enable */ + uint32_t V:1; /*!< \brief bit: 13 Vectors bit */ + uint32_t RR:1; /*!< \brief bit: 14 Round Robin select */ + uint32_t _reserved3:2; /*!< \brief bit:15..16 Reserved */ + uint32_t HA:1; /*!< \brief bit: 17 Hardware Access flag enable */ + uint32_t _reserved4:1; /*!< \brief bit: 18 Reserved */ + uint32_t WXN:1; /*!< \brief bit: 19 Write permission implies XN */ + uint32_t UWXN:1; /*!< \brief bit: 20 Unprivileged write permission implies PL1 XN */ + uint32_t FI:1; /*!< \brief bit: 21 Fast interrupts configuration enable */ + uint32_t U:1; /*!< \brief bit: 22 Alignment model */ + uint32_t _reserved5:1; /*!< \brief bit: 23 Reserved */ + uint32_t VE:1; /*!< \brief bit: 24 Interrupt Vectors Enable */ + uint32_t EE:1; /*!< \brief bit: 25 Exception Endianness */ + uint32_t _reserved6:1; /*!< \brief bit: 26 Reserved */ + uint32_t NMFI:1; /*!< \brief bit: 27 Non-maskable FIQ (NMFI) support */ + uint32_t TRE:1; /*!< \brief bit: 28 TEX remap enable. */ + uint32_t AFE:1; /*!< \brief bit: 29 Access flag enable */ + uint32_t TE:1; /*!< \brief bit: 30 Thumb Exception enable */ + uint32_t _reserved7:1; /*!< \brief bit: 31 Reserved */ + } b; /*!< \brief Structure used for bit access */ + uint32_t w; /*!< \brief Type used for word access */ +} SCTLR_Type; + +#define SCTLR_TE_Pos 30U /*!< \brief SCTLR: TE Position */ +#define SCTLR_TE_Msk (1UL << SCTLR_TE_Pos) /*!< \brief SCTLR: TE Mask */ + +#define SCTLR_AFE_Pos 29U /*!< \brief SCTLR: AFE Position */ +#define SCTLR_AFE_Msk (1UL << SCTLR_AFE_Pos) /*!< \brief SCTLR: AFE Mask */ + +#define SCTLR_TRE_Pos 28U /*!< \brief SCTLR: TRE Position */ +#define SCTLR_TRE_Msk (1UL << SCTLR_TRE_Pos) /*!< \brief SCTLR: TRE Mask */ + +#define SCTLR_NMFI_Pos 27U /*!< \brief SCTLR: NMFI Position */ +#define SCTLR_NMFI_Msk (1UL << SCTLR_NMFI_Pos) /*!< \brief SCTLR: NMFI Mask */ + +#define SCTLR_EE_Pos 25U /*!< \brief SCTLR: EE Position */ +#define SCTLR_EE_Msk (1UL << SCTLR_EE_Pos) /*!< \brief SCTLR: EE Mask */ + +#define SCTLR_VE_Pos 24U /*!< \brief SCTLR: VE Position */ +#define SCTLR_VE_Msk (1UL << SCTLR_VE_Pos) /*!< \brief SCTLR: VE Mask */ + +#define SCTLR_U_Pos 22U /*!< \brief SCTLR: U Position */ +#define SCTLR_U_Msk (1UL << SCTLR_U_Pos) /*!< \brief SCTLR: U Mask */ + +#define SCTLR_FI_Pos 21U /*!< \brief SCTLR: FI Position */ +#define SCTLR_FI_Msk (1UL << SCTLR_FI_Pos) /*!< \brief SCTLR: FI Mask */ + +#define SCTLR_UWXN_Pos 20U /*!< \brief SCTLR: UWXN Position */ +#define SCTLR_UWXN_Msk (1UL << SCTLR_UWXN_Pos) /*!< \brief SCTLR: UWXN Mask */ + +#define SCTLR_WXN_Pos 19U /*!< \brief SCTLR: WXN Position */ +#define SCTLR_WXN_Msk (1UL << SCTLR_WXN_Pos) /*!< \brief SCTLR: WXN Mask */ + +#define SCTLR_HA_Pos 17U /*!< \brief SCTLR: HA Position */ +#define SCTLR_HA_Msk (1UL << SCTLR_HA_Pos) /*!< \brief SCTLR: HA Mask */ + +#define SCTLR_RR_Pos 14U /*!< \brief SCTLR: RR Position */ +#define SCTLR_RR_Msk (1UL << SCTLR_RR_Pos) /*!< \brief SCTLR: RR Mask */ + +#define SCTLR_V_Pos 13U /*!< \brief SCTLR: V Position */ +#define SCTLR_V_Msk (1UL << SCTLR_V_Pos) /*!< \brief SCTLR: V Mask */ + +#define SCTLR_I_Pos 12U /*!< \brief SCTLR: I Position */ +#define SCTLR_I_Msk (1UL << SCTLR_I_Pos) /*!< \brief SCTLR: I Mask */ + +#define SCTLR_Z_Pos 11U /*!< \brief SCTLR: Z Position */ +#define SCTLR_Z_Msk (1UL << SCTLR_Z_Pos) /*!< \brief SCTLR: Z Mask */ + +#define SCTLR_SW_Pos 10U /*!< \brief SCTLR: SW Position */ +#define SCTLR_SW_Msk (1UL << SCTLR_SW_Pos) /*!< \brief SCTLR: SW Mask */ + +#define SCTLR_B_Pos 7U /*!< \brief SCTLR: B Position */ +#define SCTLR_B_Msk (1UL << SCTLR_B_Pos) /*!< \brief SCTLR: B Mask */ + +#define SCTLR_CP15BEN_Pos 5U /*!< \brief SCTLR: CP15BEN Position */ +#define SCTLR_CP15BEN_Msk (1UL << SCTLR_CP15BEN_Pos) /*!< \brief SCTLR: CP15BEN Mask */ + +#define SCTLR_C_Pos 2U /*!< \brief SCTLR: C Position */ +#define SCTLR_C_Msk (1UL << SCTLR_C_Pos) /*!< \brief SCTLR: C Mask */ + +#define SCTLR_A_Pos 1U /*!< \brief SCTLR: A Position */ +#define SCTLR_A_Msk (1UL << SCTLR_A_Pos) /*!< \brief SCTLR: A Mask */ + +#define SCTLR_M_Pos 0U /*!< \brief SCTLR: M Position */ +#define SCTLR_M_Msk (1UL << SCTLR_M_Pos) /*!< \brief SCTLR: M Mask */ + +/* CP15 Register CPACR */ +typedef union +{ + struct + { + uint32_t _reserved0:20; /*!< \brief bit: 0..19 Reserved */ + uint32_t cp10:2; /*!< \brief bit:20..21 Access rights for coprocessor 10 */ + uint32_t cp11:2; /*!< \brief bit:22..23 Access rights for coprocessor 11 */ + uint32_t _reserved1:6; /*!< \brief bit:24..29 Reserved */ + uint32_t D32DIS:1; /*!< \brief bit: 30 Disable use of registers D16-D31 of the VFP register file */ + uint32_t ASEDIS:1; /*!< \brief bit: 31 Disable Advanced SIMD Functionality */ + } b; /*!< \brief Structure used for bit access */ + uint32_t w; /*!< \brief Type used for word access */ +} CPACR_Type; + +#define CPACR_ASEDIS_Pos 31U /*!< \brief CPACR: ASEDIS Position */ +#define CPACR_ASEDIS_Msk (1UL << CPACR_ASEDIS_Pos) /*!< \brief CPACR: ASEDIS Mask */ + +#define CPACR_D32DIS_Pos 30U /*!< \brief CPACR: D32DIS Position */ +#define CPACR_D32DIS_Msk (1UL << CPACR_D32DIS_Pos) /*!< \brief CPACR: D32DIS Mask */ + +#define CPACR_cp11_Pos 22U /*!< \brief CPACR: cp11 Position */ +#define CPACR_cp11_Msk (3UL << CPACR_cp11_Pos) /*!< \brief CPACR: cp11 Mask */ + +#define CPACR_cp10_Pos 20U /*!< \brief CPACR: cp10 Position */ +#define CPACR_cp10_Msk (3UL << CPACR_cp10_Pos) /*!< \brief CPACR: cp10 Mask */ + +/* CP15 Register DFSR */ +typedef union +{ + struct + { + uint32_t FS0:4; /*!< \brief bit: 0.. 3 Fault Status bits bit 0-3 */ + uint32_t Domain:4; /*!< \brief bit: 4.. 7 Fault on which domain */ + uint32_t _reserved0:2; /*!< \brief bit: 8.. 9 Reserved */ + uint32_t FS1:1; /*!< \brief bit: 10 Fault Status bits bit 4 */ + uint32_t WnR:1; /*!< \brief bit: 11 Write not Read bit */ + uint32_t ExT:1; /*!< \brief bit: 12 External abort type */ + uint32_t CM:1; /*!< \brief bit: 13 Cache maintenance fault */ + uint32_t _reserved1:18; /*!< \brief bit:14..31 Reserved */ + } b; /*!< \brief Structure used for bit access */ + uint32_t w; /*!< \brief Type used for word access */ +} DFSR_Type; + +#define DFSR_CM_Pos 13U /*!< \brief DFSR: CM Position */ +#define DFSR_CM_Msk (1UL << DFSR_CM_Pos) /*!< \brief DFSR: CM Mask */ + +#define DFSR_Ext_Pos 12U /*!< \brief DFSR: Ext Position */ +#define DFSR_Ext_Msk (1UL << DFSR_Ext_Pos) /*!< \brief DFSR: Ext Mask */ + +#define DFSR_WnR_Pos 11U /*!< \brief DFSR: WnR Position */ +#define DFSR_WnR_Msk (1UL << DFSR_WnR_Pos) /*!< \brief DFSR: WnR Mask */ + +#define DFSR_FS1_Pos 10U /*!< \brief DFSR: FS1 Position */ +#define DFSR_FS1_Msk (1UL << DFSR_FS1_Pos) /*!< \brief DFSR: FS1 Mask */ + +#define DFSR_Domain_Pos 4U /*!< \brief DFSR: Domain Position */ +#define DFSR_Domain_Msk (0xFUL << DFSR_Domain_Pos) /*!< \brief DFSR: Domain Mask */ + +#define DFSR_FS0_Pos 0U /*!< \brief DFSR: FS0 Position */ +#define DFSR_FS0_Msk (0xFUL << DFSR_FS0_Pos) /*!< \brief DFSR: FS0 Mask */ + +/* CP15 Register IFSR */ +typedef union +{ + struct + { + uint32_t FS0:4; /*!< \brief bit: 0.. 3 Fault Status bits bit 0-3 */ + uint32_t _reserved0:6; /*!< \brief bit: 4.. 9 Reserved */ + uint32_t FS1:1; /*!< \brief bit: 10 Fault Status bits bit 4 */ + uint32_t _reserved1:1; /*!< \brief bit: 11 Reserved */ + uint32_t ExT:1; /*!< \brief bit: 12 External abort type */ + uint32_t _reserved2:19; /*!< \brief bit:13..31 Reserved */ + } b; /*!< \brief Structure used for bit access */ + uint32_t w; /*!< \brief Type used for word access */ +} IFSR_Type; + +#define IFSR_ExT_Pos 12U /*!< \brief IFSR: ExT Position */ +#define IFSR_ExT_Msk (1UL << IFSR_ExT_Pos) /*!< \brief IFSR: ExT Mask */ + +#define IFSR_FS1_Pos 10U /*!< \brief IFSR: FS1 Position */ +#define IFSR_FS1_Msk (1UL << IFSR_FS1_Pos) /*!< \brief IFSR: FS1 Mask */ + +#define IFSR_FS0_Pos 0U /*!< \brief IFSR: FS0 Position */ +#define IFSR_FS0_Msk (0xFUL << IFSR_FS0_Pos) /*!< \brief IFSR: FS0 Mask */ + +/* CP15 Register ISR */ +typedef union +{ + struct + { + uint32_t _reserved0:6; /*!< \brief bit: 0.. 5 Reserved */ + uint32_t F:1; /*!< \brief bit: 6 FIQ pending bit */ + uint32_t I:1; /*!< \brief bit: 7 IRQ pending bit */ + uint32_t A:1; /*!< \brief bit: 8 External abort pending bit */ + uint32_t _reserved1:23; /*!< \brief bit:14..31 Reserved */ + } b; /*!< \brief Structure used for bit access */ + uint32_t w; /*!< \brief Type used for word access */ +} ISR_Type; + +#define ISR_A_Pos 13U /*!< \brief ISR: A Position */ +#define ISR_A_Msk (1UL << ISR_A_Pos) /*!< \brief ISR: A Mask */ + +#define ISR_I_Pos 12U /*!< \brief ISR: I Position */ +#define ISR_I_Msk (1UL << ISR_I_Pos) /*!< \brief ISR: I Mask */ + +#define ISR_F_Pos 11U /*!< \brief ISR: F Position */ +#define ISR_F_Msk (1UL << ISR_F_Pos) /*!< \brief ISR: F Mask */ + + +/** + \brief Union type to access the L2C_310 Cache Controller. +*/ +#if (__L2C_PRESENT == 1U) +typedef struct +{ + __I uint32_t CACHE_ID; /*!< \brief Offset: 0x0000 Cache ID Register */ + __I uint32_t CACHE_TYPE; /*!< \brief Offset: 0x0004 Cache Type Register */ + uint32_t RESERVED0[0x3e]; + __IO uint32_t CONTROL; /*!< \brief Offset: 0x0100 Control Register */ + __IO uint32_t AUX_CNT; /*!< \brief Offset: 0x0104 Auxiliary Control */ + uint32_t RESERVED1[0x3e]; + __IO uint32_t EVENT_CONTROL; /*!< \brief Offset: 0x0200 Event Counter Control */ + __IO uint32_t EVENT_COUNTER1_CONF; /*!< \brief Offset: 0x0204 Event Counter 1 Configuration */ + __IO uint32_t EVENT_COUNTER0_CONF; /*!< \brief Offset: 0x0208 Event Counter 1 Configuration */ + uint32_t RESERVED2[0x2]; + __IO uint32_t INTERRUPT_MASK; /*!< \brief Offset: 0x0214 Interrupt Mask */ + __I uint32_t MASKED_INT_STATUS; /*!< \brief Offset: 0x0218 Masked Interrupt Status */ + __I uint32_t RAW_INT_STATUS; /*!< \brief Offset: 0x021c Raw Interrupt Status */ + __O uint32_t INTERRUPT_CLEAR; /*!< \brief Offset: 0x0220 Interrupt Clear */ + uint32_t RESERVED3[0x143]; + __IO uint32_t CACHE_SYNC; /*!< \brief Offset: 0x0730 Cache Sync */ + uint32_t RESERVED4[0xf]; + __IO uint32_t INV_LINE_PA; /*!< \brief Offset: 0x0770 Invalidate Line By PA */ + uint32_t RESERVED6[2]; + __IO uint32_t INV_WAY; /*!< \brief Offset: 0x077c Invalidate by Way */ + uint32_t RESERVED5[0xc]; + __IO uint32_t CLEAN_LINE_PA; /*!< \brief Offset: 0x07b0 Clean Line by PA */ + uint32_t RESERVED7[1]; + __IO uint32_t CLEAN_LINE_INDEX_WAY; /*!< \brief Offset: 0x07b8 Clean Line by Index/Way */ + __IO uint32_t CLEAN_WAY; /*!< \brief Offset: 0x07bc Clean by Way */ + uint32_t RESERVED8[0xc]; + __IO uint32_t CLEAN_INV_LINE_PA; /*!< \brief Offset: 0x07f0 Clean and Invalidate Line by PA */ + uint32_t RESERVED9[1]; + __IO uint32_t CLEAN_INV_LINE_INDEX_WAY; /*!< \brief Offset: 0x07f8 Clean and Invalidate Line by Index/Way */ + __IO uint32_t CLEAN_INV_WAY; /*!< \brief Offset: 0x07fc Clean and Invalidate by Way */ + uint32_t RESERVED10[0x40]; + __IO uint32_t DATA_LOCK_0_WAY; /*!< \brief Offset: 0x0900 Data Lockdown 0 by Way */ + __IO uint32_t INST_LOCK_0_WAY; /*!< \brief Offset: 0x0904 Instruction Lockdown 0 by Way */ + __IO uint32_t DATA_LOCK_1_WAY; /*!< \brief Offset: 0x0908 Data Lockdown 1 by Way */ + __IO uint32_t INST_LOCK_1_WAY; /*!< \brief Offset: 0x090c Instruction Lockdown 1 by Way */ + __IO uint32_t DATA_LOCK_2_WAY; /*!< \brief Offset: 0x0910 Data Lockdown 2 by Way */ + __IO uint32_t INST_LOCK_2_WAY; /*!< \brief Offset: 0x0914 Instruction Lockdown 2 by Way */ + __IO uint32_t DATA_LOCK_3_WAY; /*!< \brief Offset: 0x0918 Data Lockdown 3 by Way */ + __IO uint32_t INST_LOCK_3_WAY; /*!< \brief Offset: 0x091c Instruction Lockdown 3 by Way */ + __IO uint32_t DATA_LOCK_4_WAY; /*!< \brief Offset: 0x0920 Data Lockdown 4 by Way */ + __IO uint32_t INST_LOCK_4_WAY; /*!< \brief Offset: 0x0924 Instruction Lockdown 4 by Way */ + __IO uint32_t DATA_LOCK_5_WAY; /*!< \brief Offset: 0x0928 Data Lockdown 5 by Way */ + __IO uint32_t INST_LOCK_5_WAY; /*!< \brief Offset: 0x092c Instruction Lockdown 5 by Way */ + __IO uint32_t DATA_LOCK_6_WAY; /*!< \brief Offset: 0x0930 Data Lockdown 5 by Way */ + __IO uint32_t INST_LOCK_6_WAY; /*!< \brief Offset: 0x0934 Instruction Lockdown 5 by Way */ + __IO uint32_t DATA_LOCK_7_WAY; /*!< \brief Offset: 0x0938 Data Lockdown 6 by Way */ + __IO uint32_t INST_LOCK_7_WAY; /*!< \brief Offset: 0x093c Instruction Lockdown 6 by Way */ + uint32_t RESERVED11[0x4]; + __IO uint32_t LOCK_LINE_EN; /*!< \brief Offset: 0x0950 Lockdown by Line Enable */ + __IO uint32_t UNLOCK_ALL_BY_WAY; /*!< \brief Offset: 0x0954 Unlock All Lines by Way */ + uint32_t RESERVED12[0xaa]; + __IO uint32_t ADDRESS_FILTER_START; /*!< \brief Offset: 0x0c00 Address Filtering Start */ + __IO uint32_t ADDRESS_FILTER_END; /*!< \brief Offset: 0x0c04 Address Filtering End */ + uint32_t RESERVED13[0xce]; + __IO uint32_t DEBUG_CONTROL; /*!< \brief Offset: 0x0f40 Debug Control Register */ +} L2C_310_TypeDef; + +#define L2C_310 ((L2C_310_TypeDef *)L2C_310_BASE) /*!< \brief L2C_310 Declaration */ +#endif + +#if (__GIC_PRESENT == 1U) +/** \brief Structure type to access the Generic Interrupt Controller Distributor (GICD) +*/ +typedef struct +{ + __IO uint32_t ICDDCR; + __I uint32_t ICDICTR; + __I uint32_t ICDIIDR; + uint32_t RESERVED0[29]; + __IO uint32_t ICDISR[32]; + __IO uint32_t ICDISER[32]; + __IO uint32_t ICDICER[32]; + __IO uint32_t ICDISPR[32]; + __IO uint32_t ICDICPR[32]; + __I uint32_t ICDABR[32]; + uint32_t RESERVED1[32]; + __IO uint32_t ICDIPR[256]; + __IO uint32_t ICDIPTR[256]; + __IO uint32_t ICDICFR[64]; + uint32_t RESERVED2[128]; + __IO uint32_t ICDSGIR; +} GICDistributor_Type; + +#define GICDistributor ((GICDistributor_Type *) GIC_DISTRIBUTOR_BASE ) /*!< GIC Distributor configuration struct */ + +/** \brief Structure type to access the Generic Interrupt Controller Interface (GICC) +*/ +typedef struct +{ + __IO uint32_t ICCICR; //!< \brief +0x000 - RW - CPU Interface Control Register + __IO uint32_t ICCPMR; //!< \brief +0x004 - RW - Interrupt Priority Mask Register + __IO uint32_t ICCBPR; //!< \brief +0x008 - RW - Binary Point Register + __I uint32_t ICCIAR; //!< \brief +0x00C - RO - Interrupt Acknowledge Register + __IO uint32_t ICCEOIR; //!< \brief +0x010 - WO - End of Interrupt Register + __I uint32_t ICCRPR; //!< \brief +0x014 - RO - Running Priority Register + __I uint32_t ICCHPIR; //!< \brief +0x018 - RO - Highest Pending Interrupt Register + __IO uint32_t ICCABPR; //!< \brief +0x01C - RW - Aliased Binary Point Register + uint32_t RESERVED[55]; + __I uint32_t ICCIIDR; //!< \brief +0x0FC - RO - CPU Interface Identification Register +} GICInterface_Type; + +#define GICInterface ((GICInterface_Type *) GIC_INTERFACE_BASE ) /*!< GIC Interface configuration struct */ +#endif + +#if (__TIM_PRESENT == 1U) +#if ((__CORTEX_A == 5U)||(__CORTEX_A == 9U)) +/** \brief Structure type to access the Private Timer +*/ +typedef struct +{ + __IO uint32_t LOAD; //!< \brief +0x000 - RW - Private Timer Load Register + __IO uint32_t COUNTER; //!< \brief +0x004 - RW - Private Timer Counter Register + __IO uint32_t CONTROL; //!< \brief +0x008 - RW - Private Timer Control Register + __IO uint32_t ISR; //!< \brief +0x00C - RO - Private Timer Interrupt Status Register + uint32_t RESERVED[8]; + __IO uint32_t WLOAD; //!< \brief +0x020 - RW - Watchdog Load Register + __IO uint32_t WCOUNTER; //!< \brief +0x024 - RW - Watchdog Counter Register + __IO uint32_t WCONTROL; //!< \brief +0x028 - RW - Watchdog Control Register + __IO uint32_t WISR; //!< \brief +0x02C - RW - Watchdog Interrupt Status Register + __IO uint32_t WRESET; //!< \brief +0x030 - RW - Watchdog Reset Status Register + __I uint32_t WDISABLE; //!< \brief +0x0FC - RO - Watchdog Disable Register +} Timer_Type; +#define PTIM ((Timer_Type *) TIMER_BASE ) /*!< \brief Timer configuration struct */ +#endif +#endif + + /******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - L1 Cache Functions + - L2C-310 Cache Controller Functions + - PL1 Timer Functions + - GIC Functions + - MMU Functions + ******************************************************************************/ + +/* ########################## L1 Cache functions ################################# */ + +/** \brief Enable Caches + + Enable Caches + */ +__STATIC_INLINE void L1C_EnableCaches(void) { + // Set I bit 12 to enable I Cache + // Set C bit 2 to enable D Cache + __set_SCTLR( __get_SCTLR() | (1 << 12) | (1 << 2)); +} + +/** \brief Disable Caches + + Disable Caches + */ +__STATIC_INLINE void L1C_DisableCaches(void) { + // Clear I bit 12 to disable I Cache + // Clear C bit 2 to disable D Cache + __set_SCTLR( __get_SCTLR() & ~(1 << 12) & ~(1 << 2)); + __ISB(); +} + +/** \brief Enable BTAC + + Enable BTAC + */ +__STATIC_INLINE void L1C_EnableBTAC(void) { + // Set Z bit 11 to enable branch prediction + __set_SCTLR( __get_SCTLR() | (1 << 11)); + __ISB(); +} + +/** \brief Disable BTAC + + Disable BTAC + */ +__STATIC_INLINE void L1C_DisableBTAC(void) { + // Clear Z bit 11 to disable branch prediction + __set_SCTLR( __get_SCTLR() & ~(1 << 11)); +} + +/** \brief Invalidate entire branch predictor array + + BPIALL. Branch Predictor Invalidate All. + */ + +__STATIC_INLINE void L1C_InvalidateBTAC(void) { + __set_BPIALL(0); + __DSB(); //ensure completion of the invalidation + __ISB(); //ensure instruction fetch path sees new state +} + +/** \brief Invalidate the whole I$ + + ICIALLU. Instruction Cache Invalidate All to PoU +*/ +__STATIC_INLINE void L1C_InvalidateICacheAll(void) { + __set_ICIALLU(0); + __DSB(); //ensure completion of the invalidation + __ISB(); //ensure instruction fetch path sees new I cache state +} + +/** \brief Clean D$ by MVA + + DCCMVAC. Data cache clean by MVA to PoC +*/ +__STATIC_INLINE void L1C_CleanDCacheMVA(void *va) { + __set_DCCMVAC((uint32_t)va); + __DMB(); //ensure the ordering of data cache maintenance operations and their effects +} + +/** \brief Invalidate D$ by MVA + + DCIMVAC. Data cache invalidate by MVA to PoC +*/ +__STATIC_INLINE void L1C_InvalidateDCacheMVA(void *va) { + __set_DCIMVAC((uint32_t)va); + __DMB(); //ensure the ordering of data cache maintenance operations and their effects +} + +/** \brief Clean and Invalidate D$ by MVA + + DCCIMVAC. Data cache clean and invalidate by MVA to PoC +*/ +__STATIC_INLINE void L1C_CleanInvalidateDCacheMVA(void *va) { + __set_DCCIMVAC((uint32_t)va); + __DMB(); //ensure the ordering of data cache maintenance operations and their effects +} + +/** \brief Clean and Invalidate the entire data or unified cache + + Generic mechanism for cleaning/invalidating the entire data or unified cache to the point of coherency. +*/ +__STATIC_INLINE void L1C_CleanInvalidateCache(uint32_t op) { + __L1C_CleanInvalidateCache(op); // compiler specific call +} + + +/** \brief Invalidate the whole D$ + + DCISW. Invalidate by Set/Way +*/ + +__STATIC_INLINE void L1C_InvalidateDCacheAll(void) { + L1C_CleanInvalidateCache(0); +} + +/** \brief Clean the whole D$ + + DCCSW. Clean by Set/Way + */ + +__STATIC_INLINE void L1C_CleanDCacheAll(void) { + L1C_CleanInvalidateCache(1); +} + +/** \brief Clean and invalidate the whole D$ + + DCCISW. Clean and Invalidate by Set/Way + */ + +__STATIC_INLINE void L1C_CleanInvalidateDCacheAll(void) { + L1C_CleanInvalidateCache(2); +} + + +/* ########################## L2 Cache functions ################################# */ +#if (__L2C_PRESENT == 1U) +//Cache Sync operation +__STATIC_INLINE void L2C_Sync(void) +{ + L2C_310->CACHE_SYNC = 0x0; +} + +//return Cache controller cache ID +__STATIC_INLINE int L2C_GetID (void) +{ + return L2C_310->CACHE_ID; +} + +//return Cache controller cache Type +__STATIC_INLINE int L2C_GetType (void) +{ + return L2C_310->CACHE_TYPE; +} + +//Invalidate all cache by way +__STATIC_INLINE void L2C_InvAllByWay (void) +{ + unsigned int assoc; + + if (L2C_310->AUX_CNT & (1<<16)) + assoc = 16; + else + assoc = 8; + + L2C_310->INV_WAY = (1 << assoc) - 1; + while(L2C_310->INV_WAY & ((1 << assoc) - 1)); //poll invalidate + + L2C_Sync(); +} + +//Clean and Invalidate all cache by way +__STATIC_INLINE void L2C_CleanInvAllByWay (void) +{ + unsigned int assoc; + + if (L2C_310->AUX_CNT & (1<<16)) + assoc = 16; + else + assoc = 8; + + L2C_310->CLEAN_INV_WAY = (1 << assoc) - 1; + while(L2C_310->CLEAN_INV_WAY & ((1 << assoc) - 1)); //poll invalidate + + L2C_Sync(); +} + +//Enable Cache +__STATIC_INLINE void L2C_Enable(void) +{ + L2C_310->CONTROL = 0; + L2C_310->INTERRUPT_CLEAR = 0x000001FFuL; + L2C_310->DEBUG_CONTROL = 0; + L2C_310->DATA_LOCK_0_WAY = 0; + L2C_310->CACHE_SYNC = 0; + L2C_310->CONTROL = 0x01; + L2C_Sync(); +} +//Disable Cache +__STATIC_INLINE void L2C_Disable(void) +{ + L2C_310->CONTROL = 0x00; + L2C_Sync(); +} + +//Invalidate cache by physical address +__STATIC_INLINE void L2C_InvPa (void *pa) +{ + L2C_310->INV_LINE_PA = (unsigned int)pa; + L2C_Sync(); +} + +//Clean cache by physical address +__STATIC_INLINE void L2C_CleanPa (void *pa) +{ + L2C_310->CLEAN_LINE_PA = (unsigned int)pa; + L2C_Sync(); +} + +//Clean and invalidate cache by physical address +__STATIC_INLINE void L2C_CleanInvPa (void *pa) +{ + L2C_310->CLEAN_INV_LINE_PA = (unsigned int)pa; + L2C_Sync(); +} +#endif + +/* ########################## GIC functions ###################################### */ +#if (__GIC_PRESENT == 1U) + +__STATIC_INLINE void GIC_EnableDistributor(void) +{ + GICDistributor->ICDDCR |= 1; //enable distributor +} + +__STATIC_INLINE void GIC_DisableDistributor(void) +{ + GICDistributor->ICDDCR &=~1; //disable distributor +} + +__STATIC_INLINE uint32_t GIC_DistributorInfo(void) +{ + return (uint32_t)(GICDistributor->ICDICTR); +} + +__STATIC_INLINE uint32_t GIC_DistributorImplementer(void) +{ + return (uint32_t)(GICDistributor->ICDIIDR); +} + +__STATIC_INLINE void GIC_SetTarget(IRQn_Type IRQn, uint32_t cpu_target) +{ + char* field = (char*)&(GICDistributor->ICDIPTR[IRQn / 4]); + field += IRQn % 4; + *field = (char)cpu_target & 0xf; +} + +__STATIC_INLINE void GIC_SetICDICFR (const uint32_t *ICDICFRn) +{ + uint32_t i, num_irq; + + //Get the maximum number of interrupts that the GIC supports + num_irq = 32 * ((GIC_DistributorInfo() & 0x1f) + 1); + + for (i = 0; i < (num_irq/16); i++) + { + GICDistributor->ICDISPR[i] = *ICDICFRn++; + } +} + +__STATIC_INLINE uint32_t GIC_GetTarget(IRQn_Type IRQn) +{ + char* field = (char*)&(GICDistributor->ICDIPTR[IRQn / 4]); + field += IRQn % 4; + return ((uint32_t)*field & 0xf); +} + +__STATIC_INLINE void GIC_EnableInterface(void) +{ + GICInterface->ICCICR |= 1; //enable interface +} + +__STATIC_INLINE void GIC_DisableInterface(void) +{ + GICInterface->ICCICR &=~1; //disable distributor +} + +__STATIC_INLINE IRQn_Type GIC_AcknowledgePending(void) +{ + return (IRQn_Type)(GICInterface->ICCIAR); +} + +__STATIC_INLINE void GIC_EndInterrupt(IRQn_Type IRQn) +{ + GICInterface->ICCEOIR = IRQn; +} + +__STATIC_INLINE void GIC_EnableIRQ(IRQn_Type IRQn) +{ + GICDistributor->ICDISER[IRQn / 32] = 1 << (IRQn % 32); +} + +__STATIC_INLINE void GIC_DisableIRQ(IRQn_Type IRQn) +{ + GICDistributor->ICDICER[IRQn / 32] = 1 << (IRQn % 32); +} + +__STATIC_INLINE void GIC_SetPendingIRQ(IRQn_Type IRQn) +{ + GICDistributor->ICDISPR[IRQn / 32] = 1 << (IRQn % 32); +} + +__STATIC_INLINE void GIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + GICDistributor->ICDICPR[IRQn / 32] = 1 << (IRQn % 32); +} + +__STATIC_INLINE void GIC_SetLevelModel(IRQn_Type IRQn, int8_t edge_level, int8_t model) +{ + // Word-size read/writes must be used to access this register + volatile uint32_t * field = &(GICDistributor->ICDICFR[IRQn / 16]); + unsigned bit_shift = (IRQn % 16)<<1; + unsigned int save_word; + + save_word = *field; + save_word &= (~(3 << bit_shift)); + + *field = (save_word | (((edge_level<<1) | model) << bit_shift)); +} + +__STATIC_INLINE void GIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + char* field = (char*)&(GICDistributor->ICDIPR[IRQn / 4]); + field += IRQn % 4; + *field = (char)priority; +} + +__STATIC_INLINE uint32_t GIC_GetPriority(IRQn_Type IRQn) +{ + char* field = (char*)&(GICDistributor->ICDIPR[IRQn / 4]); + field += IRQn % 4; + return (uint32_t)*field; +} + +__STATIC_INLINE void GIC_InterfacePriorityMask(uint32_t priority) +{ + GICInterface->ICCPMR = priority & 0xff; //set priority mask +} + +__STATIC_INLINE void GIC_SetBinaryPoint(uint32_t binary_point) +{ + GICInterface->ICCBPR = binary_point & 0x07; //set binary point +} + +__STATIC_INLINE uint32_t GIC_GetBinaryPoint(uint32_t binary_point) +{ + return (uint32_t)GICInterface->ICCBPR; +} + +__STATIC_INLINE uint32_t GIC_GetIRQStatus(IRQn_Type IRQn) +{ + uint32_t pending, active; + + active = ((GICDistributor->ICDABR[IRQn / 32]) >> (IRQn % 32)) & 0x1; + pending =((GICDistributor->ICDISPR[IRQn / 32]) >> (IRQn % 32)) & 0x1; + + return ((active<<1) | pending); +} + +__STATIC_INLINE void GIC_SendSGI(IRQn_Type IRQn, uint32_t target_list, uint32_t filter_list) +{ + GICDistributor->ICDSGIR = ((filter_list & 0x3) << 24) | ((target_list & 0xff) << 16) | (IRQn & 0xf); +} + +__STATIC_INLINE void GIC_DistInit(void) +{ + IRQn_Type i; + uint32_t num_irq = 0; + uint32_t priority_field; + + //A reset sets all bits in the ICDISRs corresponding to the SPIs to 0, + //configuring all of the interrupts as Secure. + + //Disable interrupt forwarding + GIC_DisableDistributor(); + //Get the maximum number of interrupts that the GIC supports + num_irq = 32 * ((GIC_DistributorInfo() & 0x1f) + 1); + + /* Priority level is implementation defined. + To determine the number of priority bits implemented write 0xFF to an ICDIPR + priority field and read back the value stored.*/ + GIC_SetPriority((IRQn_Type)0, 0xff); + priority_field = GIC_GetPriority((IRQn_Type)0); + + for (i = (IRQn_Type)32; i < num_irq; i++) + { + //Disable the SPI interrupt + GIC_DisableIRQ(i); + //Set level-sensitive and 1-N model + GIC_SetLevelModel(i, 0, 1); + //Set priority + GIC_SetPriority(i, priority_field/2); + //Set target list to CPU0 + GIC_SetTarget(i, 1); + } + //Enable distributor + GIC_EnableDistributor(); +} + +__STATIC_INLINE void GIC_CPUInterfaceInit(void) +{ + IRQn_Type i; + uint32_t priority_field; + + //A reset sets all bits in the ICDISRs corresponding to the SPIs to 0, + //configuring all of the interrupts as Secure. + + //Disable interrupt forwarding + GIC_DisableInterface(); + + /* Priority level is implementation defined. + To determine the number of priority bits implemented write 0xFF to an ICDIPR + priority field and read back the value stored.*/ + GIC_SetPriority((IRQn_Type)0, 0xff); + priority_field = GIC_GetPriority((IRQn_Type)0); + + //SGI and PPI + for (i = (IRQn_Type)0; i < 32; i++) + { + //Set level-sensitive and 1-N model for PPI + if(i > 15) + GIC_SetLevelModel(i, 0, 1); + //Disable SGI and PPI interrupts + GIC_DisableIRQ(i); + //Set priority + GIC_SetPriority(i, priority_field/2); + } + //Enable interface + GIC_EnableInterface(); + //Set binary point to 0 + GIC_SetBinaryPoint(0); + //Set priority mask + GIC_InterfacePriorityMask(0xff); +} + +__STATIC_INLINE void GIC_Enable(void) +{ + GIC_DistInit(); + GIC_CPUInterfaceInit(); //per CPU +} +#endif + +/* ########################## Generic Timer functions ############################ */ +#if (__TIM_PRESENT == 1U) + +/* PL1 Physical Timer */ +#if (__CORTEX_A == 7U) +__STATIC_INLINE void PL1_SetLoadValue(uint32_t value) { + __set_CNTP_TVAL(value); + __ISB(); +} + +__STATIC_INLINE uint32_t PL1_GetCurrentValue() { + return(__get_CNTP_TVAL()); +} + +__STATIC_INLINE void PL1_SetControl(uint32_t value) { + __set_CNTP_CTL(value); + __ISB(); +} + +/* Private Timer */ +#elif ((__CORTEX_A == 5U)||(__CORTEX_A == 9U)) +__STATIC_INLINE void PTIM_SetLoadValue(uint32_t value) { + PTIM->LOAD = value; +} + +__STATIC_INLINE uint32_t PTIM_GetLoadValue() { + return(PTIM->LOAD); +} + +__STATIC_INLINE uint32_t PTIM_GetCurrentValue() { + return(PTIM->COUNTER); +} + +__STATIC_INLINE void PTIM_SetControl(uint32_t value) { + PTIM->CONTROL = value; +} + +__STATIC_INLINE uint32_t PTIM_GetControl(void) { + return(PTIM->CONTROL); +} + +__STATIC_INLINE void PTIM_ClearEventFlag(void) { + PTIM->ISR = 1; +} +#endif +#endif + +/* ########################## MMU functions ###################################### */ + +#define SECTION_DESCRIPTOR (0x2) +#define SECTION_MASK (0xFFFFFFFC) + +#define SECTION_TEXCB_MASK (0xFFFF8FF3) +#define SECTION_B_SHIFT (2) +#define SECTION_C_SHIFT (3) +#define SECTION_TEX0_SHIFT (12) +#define SECTION_TEX1_SHIFT (13) +#define SECTION_TEX2_SHIFT (14) + +#define SECTION_XN_MASK (0xFFFFFFEF) +#define SECTION_XN_SHIFT (4) + +#define SECTION_DOMAIN_MASK (0xFFFFFE1F) +#define SECTION_DOMAIN_SHIFT (5) + +#define SECTION_P_MASK (0xFFFFFDFF) +#define SECTION_P_SHIFT (9) + +#define SECTION_AP_MASK (0xFFFF73FF) +#define SECTION_AP_SHIFT (10) +#define SECTION_AP2_SHIFT (15) + +#define SECTION_S_MASK (0xFFFEFFFF) +#define SECTION_S_SHIFT (16) + +#define SECTION_NG_MASK (0xFFFDFFFF) +#define SECTION_NG_SHIFT (17) + +#define SECTION_NS_MASK (0xFFF7FFFF) +#define SECTION_NS_SHIFT (19) + +#define PAGE_L1_DESCRIPTOR (0x1) +#define PAGE_L1_MASK (0xFFFFFFFC) + +#define PAGE_L2_4K_DESC (0x2) +#define PAGE_L2_4K_MASK (0xFFFFFFFD) + +#define PAGE_L2_64K_DESC (0x1) +#define PAGE_L2_64K_MASK (0xFFFFFFFC) + +#define PAGE_4K_TEXCB_MASK (0xFFFFFE33) +#define PAGE_4K_B_SHIFT (2) +#define PAGE_4K_C_SHIFT (3) +#define PAGE_4K_TEX0_SHIFT (6) +#define PAGE_4K_TEX1_SHIFT (7) +#define PAGE_4K_TEX2_SHIFT (8) + +#define PAGE_64K_TEXCB_MASK (0xFFFF8FF3) +#define PAGE_64K_B_SHIFT (2) +#define PAGE_64K_C_SHIFT (3) +#define PAGE_64K_TEX0_SHIFT (12) +#define PAGE_64K_TEX1_SHIFT (13) +#define PAGE_64K_TEX2_SHIFT (14) + +#define PAGE_TEXCB_MASK (0xFFFF8FF3) +#define PAGE_B_SHIFT (2) +#define PAGE_C_SHIFT (3) +#define PAGE_TEX_SHIFT (12) + +#define PAGE_XN_4K_MASK (0xFFFFFFFE) +#define PAGE_XN_4K_SHIFT (0) +#define PAGE_XN_64K_MASK (0xFFFF7FFF) +#define PAGE_XN_64K_SHIFT (15) + +#define PAGE_DOMAIN_MASK (0xFFFFFE1F) +#define PAGE_DOMAIN_SHIFT (5) + +#define PAGE_P_MASK (0xFFFFFDFF) +#define PAGE_P_SHIFT (9) + +#define PAGE_AP_MASK (0xFFFFFDCF) +#define PAGE_AP_SHIFT (4) +#define PAGE_AP2_SHIFT (9) + +#define PAGE_S_MASK (0xFFFFFBFF) +#define PAGE_S_SHIFT (10) + +#define PAGE_NG_MASK (0xFFFFF7FF) +#define PAGE_NG_SHIFT (11) + +#define PAGE_NS_MASK (0xFFFFFFF7) +#define PAGE_NS_SHIFT (3) + +#define OFFSET_1M (0x00100000) +#define OFFSET_64K (0x00010000) +#define OFFSET_4K (0x00001000) + +#define DESCRIPTOR_FAULT (0x00000000) + +/* Attributes enumerations */ + +/* Region size attributes */ +typedef enum +{ + SECTION, + PAGE_4k, + PAGE_64k, +} mmu_region_size_Type; + +/* Region type attributes */ +typedef enum +{ + NORMAL, + DEVICE, + SHARED_DEVICE, + NON_SHARED_DEVICE, + STRONGLY_ORDERED +} mmu_memory_Type; + +/* Region cacheability attributes */ +typedef enum +{ + NON_CACHEABLE, + WB_WA, + WT, + WB_NO_WA, +} mmu_cacheability_Type; + +/* Region parity check attributes */ +typedef enum +{ + ECC_DISABLED, + ECC_ENABLED, +} mmu_ecc_check_Type; + +/* Region execution attributes */ +typedef enum +{ + EXECUTE, + NON_EXECUTE, +} mmu_execute_Type; + +/* Region global attributes */ +typedef enum +{ + GLOBAL, + NON_GLOBAL, +} mmu_global_Type; + +/* Region shareability attributes */ +typedef enum +{ + NON_SHARED, + SHARED, +} mmu_shared_Type; + +/* Region security attributes */ +typedef enum +{ + SECURE, + NON_SECURE, +} mmu_secure_Type; + +/* Region access attributes */ +typedef enum +{ + NO_ACCESS, + RW, + READ, +} mmu_access_Type; + +/* Memory Region definition */ +typedef struct RegionStruct { + mmu_region_size_Type rg_t; + mmu_memory_Type mem_t; + uint8_t domain; + mmu_cacheability_Type inner_norm_t; + mmu_cacheability_Type outer_norm_t; + mmu_ecc_check_Type e_t; + mmu_execute_Type xn_t; + mmu_global_Type g_t; + mmu_secure_Type sec_t; + mmu_access_Type priv_t; + mmu_access_Type user_t; + mmu_shared_Type sh_t; + +} mmu_region_attributes_Type; + +//Following macros define the descriptors and attributes +//Sect_Normal. Outer & inner wb/wa, non-shareable, executable, rw, domain 0 +#define section_normal(descriptor_l1, region) region.rg_t = SECTION; \ + region.domain = 0x0; \ + region.e_t = ECC_DISABLED; \ + region.g_t = GLOBAL; \ + region.inner_norm_t = WB_WA; \ + region.outer_norm_t = WB_WA; \ + region.mem_t = NORMAL; \ + region.sec_t = SECURE; \ + region.xn_t = EXECUTE; \ + region.priv_t = RW; \ + region.user_t = RW; \ + region.sh_t = NON_SHARED; \ + MMU_GetSectionDescriptor(&descriptor_l1, region); + +//Sect_Normal_Cod. Outer & inner wb/wa, non-shareable, executable, ro, domain 0 +#define section_normal_cod(descriptor_l1, region) region.rg_t = SECTION; \ + region.domain = 0x0; \ + region.e_t = ECC_DISABLED; \ + region.g_t = GLOBAL; \ + region.inner_norm_t = WB_WA; \ + region.outer_norm_t = WB_WA; \ + region.mem_t = NORMAL; \ + region.sec_t = SECURE; \ + region.xn_t = EXECUTE; \ + region.priv_t = READ; \ + region.user_t = READ; \ + region.sh_t = NON_SHARED; \ + MMU_GetSectionDescriptor(&descriptor_l1, region); + +//Sect_Normal_RO. Sect_Normal_Cod, but not executable +#define section_normal_ro(descriptor_l1, region) region.rg_t = SECTION; \ + region.domain = 0x0; \ + region.e_t = ECC_DISABLED; \ + region.g_t = GLOBAL; \ + region.inner_norm_t = WB_WA; \ + region.outer_norm_t = WB_WA; \ + region.mem_t = NORMAL; \ + region.sec_t = SECURE; \ + region.xn_t = NON_EXECUTE; \ + region.priv_t = READ; \ + region.user_t = READ; \ + region.sh_t = NON_SHARED; \ + MMU_GetSectionDescriptor(&descriptor_l1, region); + +//Sect_Normal_RW. Sect_Normal_Cod, but writeable and not executable +#define section_normal_rw(descriptor_l1, region) region.rg_t = SECTION; \ + region.domain = 0x0; \ + region.e_t = ECC_DISABLED; \ + region.g_t = GLOBAL; \ + region.inner_norm_t = WB_WA; \ + region.outer_norm_t = WB_WA; \ + region.mem_t = NORMAL; \ + region.sec_t = SECURE; \ + region.xn_t = NON_EXECUTE; \ + region.priv_t = RW; \ + region.user_t = RW; \ + region.sh_t = NON_SHARED; \ + MMU_GetSectionDescriptor(&descriptor_l1, region); +//Sect_SO. Strongly-ordered (therefore shareable), not executable, rw, domain 0, base addr 0 +#define section_so(descriptor_l1, region) region.rg_t = SECTION; \ + region.domain = 0x0; \ + region.e_t = ECC_DISABLED; \ + region.g_t = GLOBAL; \ + region.inner_norm_t = NON_CACHEABLE; \ + region.outer_norm_t = NON_CACHEABLE; \ + region.mem_t = STRONGLY_ORDERED; \ + region.sec_t = SECURE; \ + region.xn_t = NON_EXECUTE; \ + region.priv_t = RW; \ + region.user_t = RW; \ + region.sh_t = NON_SHARED; \ + MMU_GetSectionDescriptor(&descriptor_l1, region); + +//Sect_Device_RO. Device, non-shareable, non-executable, ro, domain 0, base addr 0 +#define section_device_ro(descriptor_l1, region) region.rg_t = SECTION; \ + region.domain = 0x0; \ + region.e_t = ECC_DISABLED; \ + region.g_t = GLOBAL; \ + region.inner_norm_t = NON_CACHEABLE; \ + region.outer_norm_t = NON_CACHEABLE; \ + region.mem_t = STRONGLY_ORDERED; \ + region.sec_t = SECURE; \ + region.xn_t = NON_EXECUTE; \ + region.priv_t = READ; \ + region.user_t = READ; \ + region.sh_t = NON_SHARED; \ + MMU_GetSectionDescriptor(&descriptor_l1, region); + +//Sect_Device_RW. Sect_Device_RO, but writeable +#define section_device_rw(descriptor_l1, region) region.rg_t = SECTION; \ + region.domain = 0x0; \ + region.e_t = ECC_DISABLED; \ + region.g_t = GLOBAL; \ + region.inner_norm_t = NON_CACHEABLE; \ + region.outer_norm_t = NON_CACHEABLE; \ + region.mem_t = STRONGLY_ORDERED; \ + region.sec_t = SECURE; \ + region.xn_t = NON_EXECUTE; \ + region.priv_t = RW; \ + region.user_t = RW; \ + region.sh_t = NON_SHARED; \ + MMU_GetSectionDescriptor(&descriptor_l1, region); +//Page_4k_Device_RW. Shared device, not executable, rw, domain 0 +#define page4k_device_rw(descriptor_l1, descriptor_l2, region) region.rg_t = PAGE_4k; \ + region.domain = 0x0; \ + region.e_t = ECC_DISABLED; \ + region.g_t = GLOBAL; \ + region.inner_norm_t = NON_CACHEABLE; \ + region.outer_norm_t = NON_CACHEABLE; \ + region.mem_t = SHARED_DEVICE; \ + region.sec_t = SECURE; \ + region.xn_t = NON_EXECUTE; \ + region.priv_t = RW; \ + region.user_t = RW; \ + region.sh_t = NON_SHARED; \ + MMU_GetPageDescriptor(&descriptor_l1, &descriptor_l2, region); + +//Page_64k_Device_RW. Shared device, not executable, rw, domain 0 +#define page64k_device_rw(descriptor_l1, descriptor_l2, region) region.rg_t = PAGE_64k; \ + region.domain = 0x0; \ + region.e_t = ECC_DISABLED; \ + region.g_t = GLOBAL; \ + region.inner_norm_t = NON_CACHEABLE; \ + region.outer_norm_t = NON_CACHEABLE; \ + region.mem_t = SHARED_DEVICE; \ + region.sec_t = SECURE; \ + region.xn_t = NON_EXECUTE; \ + region.priv_t = RW; \ + region.user_t = RW; \ + region.sh_t = NON_SHARED; \ + MMU_GetPageDescriptor(&descriptor_l1, &descriptor_l2, region); + +/** \brief Set section execution-never attribute + + \param [out] descriptor_l1 L1 descriptor. + \param [in] xn Section execution-never attribute : EXECUTE , NON_EXECUTE. + + \return 0 +*/ +__STATIC_INLINE int MMU_XNSection(uint32_t *descriptor_l1, mmu_execute_Type xn) +{ + *descriptor_l1 &= SECTION_XN_MASK; + *descriptor_l1 |= ((xn & 0x1) << SECTION_XN_SHIFT); + return 0; +} + +/** \brief Set section domain + + \param [out] descriptor_l1 L1 descriptor. + \param [in] domain Section domain + + \return 0 +*/ +__STATIC_INLINE int MMU_DomainSection(uint32_t *descriptor_l1, uint8_t domain) +{ + *descriptor_l1 &= SECTION_DOMAIN_MASK; + *descriptor_l1 |= ((domain & 0xF) << SECTION_DOMAIN_SHIFT); + return 0; +} + +/** \brief Set section parity check + + \param [out] descriptor_l1 L1 descriptor. + \param [in] p_bit Parity check: ECC_DISABLED, ECC_ENABLED + + \return 0 +*/ +__STATIC_INLINE int MMU_PSection(uint32_t *descriptor_l1, mmu_ecc_check_Type p_bit) +{ + *descriptor_l1 &= SECTION_P_MASK; + *descriptor_l1 |= ((p_bit & 0x1) << SECTION_P_SHIFT); + return 0; +} + +/** \brief Set section access privileges + + \param [out] descriptor_l1 L1 descriptor. + \param [in] user User Level Access: NO_ACCESS, RW, READ + \param [in] priv Privilege Level Access: NO_ACCESS, RW, READ + \param [in] afe Access flag enable + + \return 0 +*/ +__STATIC_INLINE int MMU_APSection(uint32_t *descriptor_l1, mmu_access_Type user, mmu_access_Type priv, uint32_t afe) +{ + uint32_t ap = 0; + + if (afe == 0) { //full access + if ((priv == NO_ACCESS) && (user == NO_ACCESS)) { ap = 0x0; } + else if ((priv == RW) && (user == NO_ACCESS)) { ap = 0x1; } + else if ((priv == RW) && (user == READ)) { ap = 0x2; } + else if ((priv == RW) && (user == RW)) { ap = 0x3; } + else if ((priv == READ) && (user == NO_ACCESS)) { ap = 0x5; } + else if ((priv == READ) && (user == READ)) { ap = 0x7; } + } + + else { //Simplified access + if ((priv == RW) && (user == NO_ACCESS)) { ap = 0x1; } + else if ((priv == RW) && (user == RW)) { ap = 0x3; } + else if ((priv == READ) && (user == NO_ACCESS)) { ap = 0x5; } + else if ((priv == READ) && (user == READ)) { ap = 0x7; } + } + + *descriptor_l1 &= SECTION_AP_MASK; + *descriptor_l1 |= (ap & 0x3) << SECTION_AP_SHIFT; + *descriptor_l1 |= ((ap & 0x4)>>2) << SECTION_AP2_SHIFT; + + return 0; +} + +/** \brief Set section shareability + + \param [out] descriptor_l1 L1 descriptor. + \param [in] s_bit Section shareability: NON_SHARED, SHARED + + \return 0 +*/ +__STATIC_INLINE int MMU_SharedSection(uint32_t *descriptor_l1, mmu_shared_Type s_bit) +{ + *descriptor_l1 &= SECTION_S_MASK; + *descriptor_l1 |= ((s_bit & 0x1) << SECTION_S_SHIFT); + return 0; +} + +/** \brief Set section Global attribute + + \param [out] descriptor_l1 L1 descriptor. + \param [in] g_bit Section attribute: GLOBAL, NON_GLOBAL + + \return 0 +*/ +__STATIC_INLINE int MMU_GlobalSection(uint32_t *descriptor_l1, mmu_global_Type g_bit) +{ + *descriptor_l1 &= SECTION_NG_MASK; + *descriptor_l1 |= ((g_bit & 0x1) << SECTION_NG_SHIFT); + return 0; +} + +/** \brief Set section Security attribute + + \param [out] descriptor_l1 L1 descriptor. + \param [in] s_bit Section Security attribute: SECURE, NON_SECURE + + \return 0 +*/ +__STATIC_INLINE int MMU_SecureSection(uint32_t *descriptor_l1, mmu_secure_Type s_bit) +{ + *descriptor_l1 &= SECTION_NS_MASK; + *descriptor_l1 |= ((s_bit & 0x1) << SECTION_NS_SHIFT); + return 0; +} + +/* Page 4k or 64k */ +/** \brief Set 4k/64k page execution-never attribute + + \param [out] descriptor_l2 L2 descriptor. + \param [in] xn Page execution-never attribute : EXECUTE , NON_EXECUTE. + \param [in] page Page size: PAGE_4k, PAGE_64k, + + \return 0 +*/ +__STATIC_INLINE int MMU_XNPage(uint32_t *descriptor_l2, mmu_execute_Type xn, mmu_region_size_Type page) +{ + if (page == PAGE_4k) + { + *descriptor_l2 &= PAGE_XN_4K_MASK; + *descriptor_l2 |= ((xn & 0x1) << PAGE_XN_4K_SHIFT); + } + else + { + *descriptor_l2 &= PAGE_XN_64K_MASK; + *descriptor_l2 |= ((xn & 0x1) << PAGE_XN_64K_SHIFT); + } + return 0; +} + +/** \brief Set 4k/64k page domain + + \param [out] descriptor_l1 L1 descriptor. + \param [in] domain Page domain + + \return 0 +*/ +__STATIC_INLINE int MMU_DomainPage(uint32_t *descriptor_l1, uint8_t domain) +{ + *descriptor_l1 &= PAGE_DOMAIN_MASK; + *descriptor_l1 |= ((domain & 0xf) << PAGE_DOMAIN_SHIFT); + return 0; +} + +/** \brief Set 4k/64k page parity check + + \param [out] descriptor_l1 L1 descriptor. + \param [in] p_bit Parity check: ECC_DISABLED, ECC_ENABLED + + \return 0 +*/ +__STATIC_INLINE int MMU_PPage(uint32_t *descriptor_l1, mmu_ecc_check_Type p_bit) +{ + *descriptor_l1 &= SECTION_P_MASK; + *descriptor_l1 |= ((p_bit & 0x1) << SECTION_P_SHIFT); + return 0; +} + +/** \brief Set 4k/64k page access privileges + + \param [out] descriptor_l2 L2 descriptor. + \param [in] user User Level Access: NO_ACCESS, RW, READ + \param [in] priv Privilege Level Access: NO_ACCESS, RW, READ + \param [in] afe Access flag enable + + \return 0 +*/ +__STATIC_INLINE int MMU_APPage(uint32_t *descriptor_l2, mmu_access_Type user, mmu_access_Type priv, uint32_t afe) +{ + uint32_t ap = 0; + + if (afe == 0) { //full access + if ((priv == NO_ACCESS) && (user == NO_ACCESS)) { ap = 0x0; } + else if ((priv == RW) && (user == NO_ACCESS)) { ap = 0x1; } + else if ((priv == RW) && (user == READ)) { ap = 0x2; } + else if ((priv == RW) && (user == RW)) { ap = 0x3; } + else if ((priv == READ) && (user == NO_ACCESS)) { ap = 0x5; } + else if ((priv == READ) && (user == READ)) { ap = 0x6; } + } + + else { //Simplified access + if ((priv == RW) && (user == NO_ACCESS)) { ap = 0x1; } + else if ((priv == RW) && (user == RW)) { ap = 0x3; } + else if ((priv == READ) && (user == NO_ACCESS)) { ap = 0x5; } + else if ((priv == READ) && (user == READ)) { ap = 0x7; } + } + + *descriptor_l2 &= PAGE_AP_MASK; + *descriptor_l2 |= (ap & 0x3) << PAGE_AP_SHIFT; + *descriptor_l2 |= ((ap & 0x4)>>2) << PAGE_AP2_SHIFT; + + return 0; +} + +/** \brief Set 4k/64k page shareability + + \param [out] descriptor_l2 L2 descriptor. + \param [in] s_bit 4k/64k page shareability: NON_SHARED, SHARED + + \return 0 +*/ +__STATIC_INLINE int MMU_SharedPage(uint32_t *descriptor_l2, mmu_shared_Type s_bit) +{ + *descriptor_l2 &= PAGE_S_MASK; + *descriptor_l2 |= ((s_bit & 0x1) << PAGE_S_SHIFT); + return 0; +} + +/** \brief Set 4k/64k page Global attribute + + \param [out] descriptor_l2 L2 descriptor. + \param [in] g_bit 4k/64k page attribute: GLOBAL, NON_GLOBAL + + \return 0 +*/ +__STATIC_INLINE int MMU_GlobalPage(uint32_t *descriptor_l2, mmu_global_Type g_bit) +{ + *descriptor_l2 &= PAGE_NG_MASK; + *descriptor_l2 |= ((g_bit & 0x1) << PAGE_NG_SHIFT); + return 0; +} + +/** \brief Set 4k/64k page Security attribute + + \param [out] descriptor_l1 L1 descriptor. + \param [in] s_bit 4k/64k page Security attribute: SECURE, NON_SECURE + + \return 0 +*/ +__STATIC_INLINE int MMU_SecurePage(uint32_t *descriptor_l1, mmu_secure_Type s_bit) +{ + *descriptor_l1 &= PAGE_NS_MASK; + *descriptor_l1 |= ((s_bit & 0x1) << PAGE_NS_SHIFT); + return 0; +} + +/** \brief Set Section memory attributes + + \param [out] descriptor_l1 L1 descriptor. + \param [in] mem Section memory type: NORMAL, DEVICE, SHARED_DEVICE, NON_SHARED_DEVICE, STRONGLY_ORDERED + \param [in] outer Outer cacheability: NON_CACHEABLE, WB_WA, WT, WB_NO_WA, + \param [in] inner Inner cacheability: NON_CACHEABLE, WB_WA, WT, WB_NO_WA, + + \return 0 +*/ +__STATIC_INLINE int MMU_MemorySection(uint32_t *descriptor_l1, mmu_memory_Type mem, mmu_cacheability_Type outer, mmu_cacheability_Type inner) +{ + *descriptor_l1 &= SECTION_TEXCB_MASK; + + if (STRONGLY_ORDERED == mem) + { + return 0; + } + else if (SHARED_DEVICE == mem) + { + *descriptor_l1 |= (1 << SECTION_B_SHIFT); + } + else if (NON_SHARED_DEVICE == mem) + { + *descriptor_l1 |= (1 << SECTION_TEX1_SHIFT); + } + else if (NORMAL == mem) + { + *descriptor_l1 |= 1 << SECTION_TEX2_SHIFT; + switch(inner) + { + case NON_CACHEABLE: + break; + case WB_WA: + *descriptor_l1 |= (1 << SECTION_B_SHIFT); + break; + case WT: + *descriptor_l1 |= 1 << SECTION_C_SHIFT; + break; + case WB_NO_WA: + *descriptor_l1 |= (1 << SECTION_B_SHIFT) | (1 << SECTION_C_SHIFT); + break; + } + switch(outer) + { + case NON_CACHEABLE: + break; + case WB_WA: + *descriptor_l1 |= (1 << SECTION_TEX0_SHIFT); + break; + case WT: + *descriptor_l1 |= 1 << SECTION_TEX1_SHIFT; + break; + case WB_NO_WA: + *descriptor_l1 |= (1 << SECTION_TEX0_SHIFT) | (1 << SECTION_TEX0_SHIFT); + break; + } + } + return 0; +} + +/** \brief Set 4k/64k page memory attributes + + \param [out] descriptor_l2 L2 descriptor. + \param [in] mem 4k/64k page memory type: NORMAL, DEVICE, SHARED_DEVICE, NON_SHARED_DEVICE, STRONGLY_ORDERED + \param [in] outer Outer cacheability: NON_CACHEABLE, WB_WA, WT, WB_NO_WA, + \param [in] inner Inner cacheability: NON_CACHEABLE, WB_WA, WT, WB_NO_WA, + \param [in] page Page size + + \return 0 +*/ +__STATIC_INLINE int MMU_MemoryPage(uint32_t *descriptor_l2, mmu_memory_Type mem, mmu_cacheability_Type outer, mmu_cacheability_Type inner, mmu_region_size_Type page) +{ + *descriptor_l2 &= PAGE_4K_TEXCB_MASK; + + if (page == PAGE_64k) + { + //same as section + MMU_MemorySection(descriptor_l2, mem, outer, inner); + } + else + { + if (STRONGLY_ORDERED == mem) + { + return 0; + } + else if (SHARED_DEVICE == mem) + { + *descriptor_l2 |= (1 << PAGE_4K_B_SHIFT); + } + else if (NON_SHARED_DEVICE == mem) + { + *descriptor_l2 |= (1 << PAGE_4K_TEX1_SHIFT); + } + else if (NORMAL == mem) + { + *descriptor_l2 |= 1 << PAGE_4K_TEX2_SHIFT; + switch(inner) + { + case NON_CACHEABLE: + break; + case WB_WA: + *descriptor_l2 |= (1 << PAGE_4K_B_SHIFT); + break; + case WT: + *descriptor_l2 |= 1 << PAGE_4K_C_SHIFT; + break; + case WB_NO_WA: + *descriptor_l2 |= (1 << PAGE_4K_B_SHIFT) | (1 << PAGE_4K_C_SHIFT); + break; + } + switch(outer) + { + case NON_CACHEABLE: + break; + case WB_WA: + *descriptor_l2 |= (1 << PAGE_4K_TEX0_SHIFT); + break; + case WT: + *descriptor_l2 |= 1 << PAGE_4K_TEX1_SHIFT; + break; + case WB_NO_WA: + *descriptor_l2 |= (1 << PAGE_4K_TEX0_SHIFT) | (1 << PAGE_4K_TEX0_SHIFT); + break; + } + } + } + + return 0; +} + +/** \brief Create a L1 section descriptor + + \param [out] descriptor L1 descriptor + \param [in] reg Section attributes + + \return 0 +*/ +__STATIC_INLINE int MMU_GetSectionDescriptor(uint32_t *descriptor, mmu_region_attributes_Type reg) +{ + *descriptor = 0; + + MMU_MemorySection(descriptor, reg.mem_t, reg.outer_norm_t, reg.inner_norm_t); + MMU_XNSection(descriptor,reg.xn_t); + MMU_DomainSection(descriptor, reg.domain); + MMU_PSection(descriptor, reg.e_t); + MMU_APSection(descriptor, reg.priv_t, reg.user_t, 1); + MMU_SharedSection(descriptor,reg.sh_t); + MMU_GlobalSection(descriptor,reg.g_t); + MMU_SecureSection(descriptor,reg.sec_t); + *descriptor &= SECTION_MASK; + *descriptor |= SECTION_DESCRIPTOR; + + return 0; +} + + +/** \brief Create a L1 and L2 4k/64k page descriptor + + \param [out] descriptor L1 descriptor + \param [out] descriptor2 L2 descriptor + \param [in] reg 4k/64k page attributes + + \return 0 +*/ +__STATIC_INLINE int MMU_GetPageDescriptor(uint32_t *descriptor, uint32_t *descriptor2, mmu_region_attributes_Type reg) +{ + *descriptor = 0; + *descriptor2 = 0; + + switch (reg.rg_t) + { + case PAGE_4k: + MMU_MemoryPage(descriptor2, reg.mem_t, reg.outer_norm_t, reg.inner_norm_t, PAGE_4k); + MMU_XNPage(descriptor2, reg.xn_t, PAGE_4k); + MMU_DomainPage(descriptor, reg.domain); + MMU_PPage(descriptor, reg.e_t); + MMU_APPage(descriptor2, reg.priv_t, reg.user_t, 1); + MMU_SharedPage(descriptor2,reg.sh_t); + MMU_GlobalPage(descriptor2,reg.g_t); + MMU_SecurePage(descriptor,reg.sec_t); + *descriptor &= PAGE_L1_MASK; + *descriptor |= PAGE_L1_DESCRIPTOR; + *descriptor2 &= PAGE_L2_4K_MASK; + *descriptor2 |= PAGE_L2_4K_DESC; + break; + + case PAGE_64k: + MMU_MemoryPage(descriptor2, reg.mem_t, reg.outer_norm_t, reg.inner_norm_t, PAGE_64k); + MMU_XNPage(descriptor2, reg.xn_t, PAGE_64k); + MMU_DomainPage(descriptor, reg.domain); + MMU_PPage(descriptor, reg.e_t); + MMU_APPage(descriptor2, reg.priv_t, reg.user_t, 1); + MMU_SharedPage(descriptor2,reg.sh_t); + MMU_GlobalPage(descriptor2,reg.g_t); + MMU_SecurePage(descriptor,reg.sec_t); + *descriptor &= PAGE_L1_MASK; + *descriptor |= PAGE_L1_DESCRIPTOR; + *descriptor2 &= PAGE_L2_64K_MASK; + *descriptor2 |= PAGE_L2_64K_DESC; + break; + + case SECTION: + //error + break; + } + + return 0; +} + +/** \brief Create a 1MB Section + + \param [in] ttb Translation table base address + \param [in] base_address Section base address + \param [in] count Number of sections to create + \param [in] descriptor_l1 L1 descriptor (region attributes) + +*/ +__STATIC_INLINE void MMU_TTSection(uint32_t *ttb, uint32_t base_address, uint32_t count, uint32_t descriptor_l1) +{ + uint32_t offset; + uint32_t entry; + uint32_t i; + + offset = base_address >> 20; + entry = (base_address & 0xFFF00000) | descriptor_l1; + + //4 bytes aligned + ttb = ttb + offset; + + for (i = 0; i < count; i++ ) + { + //4 bytes aligned + *ttb++ = entry; + entry += OFFSET_1M; + } +} + +/** \brief Create a 4k page entry + + \param [in] ttb L1 table base address + \param [in] base_address 4k base address + \param [in] count Number of 4k pages to create + \param [in] descriptor_l1 L1 descriptor (region attributes) + \param [in] ttb_l2 L2 table base address + \param [in] descriptor_l2 L2 descriptor (region attributes) + +*/ +__STATIC_INLINE void MMU_TTPage4k(uint32_t *ttb, uint32_t base_address, uint32_t count, uint32_t descriptor_l1, uint32_t *ttb_l2, uint32_t descriptor_l2 ) +{ + + uint32_t offset, offset2; + uint32_t entry, entry2; + uint32_t i; + + offset = base_address >> 20; + entry = ((int)ttb_l2 & 0xFFFFFC00) | descriptor_l1; + + //4 bytes aligned + ttb += offset; + //create l1_entry + *ttb = entry; + + offset2 = (base_address & 0xff000) >> 12; + ttb_l2 += offset2; + entry2 = (base_address & 0xFFFFF000) | descriptor_l2; + for (i = 0; i < count; i++ ) + { + //4 bytes aligned + *ttb_l2++ = entry2; + entry2 += OFFSET_4K; + } +} + +/** \brief Create a 64k page entry + + \param [in] ttb L1 table base address + \param [in] base_address 64k base address + \param [in] count Number of 64k pages to create + \param [in] descriptor_l1 L1 descriptor (region attributes) + \param [in] ttb_l2 L2 table base address + \param [in] descriptor_l2 L2 descriptor (region attributes) + +*/ +__STATIC_INLINE void MMU_TTPage64k(uint32_t *ttb, uint32_t base_address, uint32_t count, uint32_t descriptor_l1, uint32_t *ttb_l2, uint32_t descriptor_l2 ) +{ + uint32_t offset, offset2; + uint32_t entry, entry2; + uint32_t i,j; + + + offset = base_address >> 20; + entry = ((int)ttb_l2 & 0xFFFFFC00) | descriptor_l1; + + //4 bytes aligned + ttb += offset; + //create l1_entry + *ttb = entry; + + offset2 = (base_address & 0xff000) >> 12; + ttb_l2 += offset2; + entry2 = (base_address & 0xFFFF0000) | descriptor_l2; + for (i = 0; i < count; i++ ) + { + //create 16 entries + for (j = 0; j < 16; j++) + { + //4 bytes aligned + *ttb_l2++ = entry2; + } + entry2 += OFFSET_64K; + } +} + +/** \brief Enable MMU + + Enable MMU +*/ +__STATIC_INLINE void MMU_Enable(void) { + // Set M bit 0 to enable the MMU + // Set AFE bit to enable simplified access permissions model + // Clear TRE bit to disable TEX remap and A bit to disable strict alignment fault checking + __set_SCTLR( (__get_SCTLR() & ~(1 << 28) & ~(1 << 1)) | 1 | (1 << 29)); + __ISB(); +} + +/** \brief Disable MMU + + Disable MMU +*/ +__STATIC_INLINE void MMU_Disable(void) { + // Clear M bit 0 to disable the MMU + __set_SCTLR( __get_SCTLR() & ~1); + __ISB(); +} + +/** \brief Invalidate entire unified TLB + + TLBIALL. Invalidate entire unified TLB +*/ + +__STATIC_INLINE void MMU_InvalidateTLB(void) { + __set_TLBIALL(0); + __DSB(); //ensure completion of the invalidation + __ISB(); //ensure instruction fetch path sees new state +} + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CA_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/cmsis/core_cm0.h b/cmsis/core_cm0.h new file mode 100644 index 00000000000..f1fbbe9c172 --- /dev/null +++ b/cmsis/core_cm0.h @@ -0,0 +1,886 @@ +/**************************************************************************//** + * @file core_cm0.h + * @brief CMSIS Cortex-M0 Core Peripheral Access Layer Header File + * @version V5.0.2 + * @date 13. February 2017 + ******************************************************************************/ +/* + * Copyright (c) 2009-2017 ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_CM0_H_GENERIC +#define __CORE_CM0_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex_M0 + @{ + */ + +/* CMSIS CM0 definitions */ +#define __CM0_CMSIS_VERSION_MAIN ( 5U) /*!< [31:16] CMSIS HAL main version */ +#define __CM0_CMSIS_VERSION_SUB ( 0U) /*!< [15:0] CMSIS HAL sub version */ +#define __CM0_CMSIS_VERSION ((__CM0_CMSIS_VERSION_MAIN << 16U) | \ + __CM0_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */ + +#define __CORTEX_M (0U) /*!< Cortex-M Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + This core does not support an FPU at all +*/ +#define __FPU_USED 0U + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_PCS_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM0_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM0_H_DEPENDANT +#define __CORE_CM0_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM0_REV + #define __CM0_REV 0x0000U + #warning "__CM0_REV not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 2U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group Cortex_M0 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:28; /*!< bit: 0..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t _reserved0:1; /*!< bit: 0 Reserved */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[1U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[31U]; + __IOM uint32_t ICER[1U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[31U]; + __IOM uint32_t ISPR[1U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[31U]; + __IOM uint32_t ICPR[1U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[31U]; + uint32_t RESERVED4[64U]; + __IOM uint32_t IP[8U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */ +} NVIC_Type; + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + uint32_t RESERVED0; + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + uint32_t RESERVED1; + __IOM uint32_t SHP[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Cortex-M0 Core Debug Registers (DCB registers, SHCSR, and DFSR) are only accessible over DAP and not via processor. + Therefore they are not covered by the Cortex-M0 header file. + @{ + */ +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ + + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else +/*#define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping not available for Cortex-M0 */ +/*#define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping not available for Cortex-M0 */ + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ +/*#define NVIC_GetActive __NVIC_GetActive not available for Cortex-M0 */ + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + +/* Interrupt Priorities are WORD accessible only under ARMv6M */ +/* The following MACROS handle generation of the register offset and byte masks */ +#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL) +#define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) ) +#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) ) + + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[0U] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IP[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } + else + { + SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + Address 0 must be mapped to SRAM. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ + uint32_t *vectors = (uint32_t *)0x0U; + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ + uint32_t *vectors = (uint32_t *)0x0U; + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + SCB_AIRCR_SYSRESETREQ_Msk); + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +/*@} end of CMSIS_Core_NVICFunctions */ + + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + return 0U; /* No FPU */ +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM0_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/cmsis/core_cm0plus.h b/cmsis/core_cm0plus.h new file mode 100644 index 00000000000..2dca31a3cf1 --- /dev/null +++ b/cmsis/core_cm0plus.h @@ -0,0 +1,1012 @@ +/**************************************************************************//** + * @file core_cm0plus.h + * @brief CMSIS Cortex-M0+ Core Peripheral Access Layer Header File + * @version V5.0.2 + * @date 13. February 2017 + ******************************************************************************/ +/* + * Copyright (c) 2009-2017 ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_CM0PLUS_H_GENERIC +#define __CORE_CM0PLUS_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex-M0+ + @{ + */ + +/* CMSIS CM0+ definitions */ +#define __CM0PLUS_CMSIS_VERSION_MAIN ( 5U) /*!< [31:16] CMSIS HAL main version */ +#define __CM0PLUS_CMSIS_VERSION_SUB ( 0U) /*!< [15:0] CMSIS HAL sub version */ +#define __CM0PLUS_CMSIS_VERSION ((__CM0PLUS_CMSIS_VERSION_MAIN << 16U) | \ + __CM0PLUS_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */ + +#define __CORTEX_M (0U) /*!< Cortex-M Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + This core does not support an FPU at all +*/ +#define __FPU_USED 0U + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_PCS_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM0PLUS_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM0PLUS_H_DEPENDANT +#define __CORE_CM0PLUS_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM0PLUS_REV + #define __CM0PLUS_REV 0x0000U + #warning "__CM0PLUS_REV not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __VTOR_PRESENT + #define __VTOR_PRESENT 0U + #warning "__VTOR_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 2U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group Cortex-M0+ */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core MPU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:28; /*!< bit: 0..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[1U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[31U]; + __IOM uint32_t ICER[1U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[31U]; + __IOM uint32_t ISPR[1U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[31U]; + __IOM uint32_t ICPR[1U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[31U]; + uint32_t RESERVED4[64U]; + __IOM uint32_t IP[8U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */ +} NVIC_Type; + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ +#else + uint32_t RESERVED0; +#endif + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + uint32_t RESERVED1; + __IOM uint32_t SHP[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) +/* SCB Interrupt Control State Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 8U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0xFFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ +#endif + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ +} MPU_Type; + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_ADDR_Pos 8U /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0xFFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */ +#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ + +#define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */ +#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */ + +/* MPU Region Attribute and Size Register Definitions */ +#define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */ +#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ + +#define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */ +#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ + +#define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */ +#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ + +#define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */ +#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ + +#define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */ +#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ + +#define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */ +#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ + +#define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */ +#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ + +#define MPU_RASR_SRD_Pos 8U /*!< MPU RASR: Sub-Region Disable Position */ +#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ + +#define MPU_RASR_SIZE_Pos 1U /*!< MPU RASR: Region Size Field Position */ +#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ + +#define MPU_RASR_ENABLE_Pos 0U /*!< MPU RASR: Region enable bit Position */ +#define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Cortex-M0+ Core Debug Registers (DCB registers, SHCSR, and DFSR) are only accessible over DAP and not via processor. + Therefore they are not covered by the Cortex-M0+ header file. + @{ + */ +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ +#endif + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else +/*#define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping not available for Cortex-M0+ */ +/*#define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping not available for Cortex-M0+ */ + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ +/*#define NVIC_GetActive __NVIC_GetActive not available for Cortex-M0+ */ + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + +/* Interrupt Priorities are WORD accessible only under ARMv6M */ +/* The following MACROS handle generation of the register offset and byte masks */ +#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL) +#define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) ) +#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) ) + + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[0U] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IP[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } + else + { + SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + If VTOR is not present address 0 must be mapped to SRAM. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) + uint32_t *vectors = (uint32_t *)SCB->VTOR; +#else + uint32_t *vectors = (uint32_t *)0x0U; +#endif + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) + uint32_t *vectors = (uint32_t *)SCB->VTOR; +#else + uint32_t *vectors = (uint32_t *)0x0U; +#endif + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; + +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + SCB_AIRCR_SYSRESETREQ_Msk); + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +/*@} end of CMSIS_Core_NVICFunctions */ + + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + return 0U; /* No FPU */ +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM0PLUS_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/cmsis/core_cm23.h b/cmsis/core_cm23.h new file mode 100644 index 00000000000..378c69beeb2 --- /dev/null +++ b/cmsis/core_cm23.h @@ -0,0 +1,1876 @@ +/**************************************************************************//** + * @file core_cm23.h + * @brief CMSIS Cortex-M23 Core Peripheral Access Layer Header File + * @version V5.0.2 + * @date 13. February 2017 + ******************************************************************************/ +/* + * Copyright (c) 2009-2017 ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_CM23_H_GENERIC +#define __CORE_CM23_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex_M23 + @{ + */ + +/* CMSIS cmGrebe definitions */ +#define __CM23_CMSIS_VERSION_MAIN ( 5U) /*!< [31:16] CMSIS HAL main version */ +#define __CM23_CMSIS_VERSION_SUB ( 0U) /*!< [15:0] CMSIS HAL sub version */ +#define __CM23_CMSIS_VERSION ((__CM23_CMSIS_VERSION_MAIN << 16U) | \ + __CM23_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */ + +#define __CORTEX_M (23U) /*!< Cortex-M Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + This core does not support an FPU at all +*/ +#define __FPU_USED 0U + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_PCS_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM23_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM23_H_DEPENDANT +#define __CORE_CM23_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM23_REV + #define __CM23_REV 0x0000U + #warning "__CM23_REV not defined in device header file; using default!" + #endif + + #ifndef __FPU_PRESENT + #define __FPU_PRESENT 0U + #warning "__FPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __SAUREGION_PRESENT + #define __SAUREGION_PRESENT 0U + #warning "__SAUREGION_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __VTOR_PRESENT + #define __VTOR_PRESENT 0U + #warning "__VTOR_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 2U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif + + #ifndef __ETM_PRESENT + #define __ETM_PRESENT 0U + #warning "__ETM_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __MTB_PRESENT + #define __MTB_PRESENT 0U + #warning "__MTB_PRESENT not defined in device header file; using default!" + #endif + +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group Cortex_M23 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + - Core SAU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:28; /*!< bit: 0..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack-pointer select */ + uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[16U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[16U]; + __IOM uint32_t ICER[16U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[16U]; + __IOM uint32_t ISPR[16U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[16U]; + __IOM uint32_t ICPR[16U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[16U]; + __IOM uint32_t IABR[16U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[16U]; + __IOM uint32_t ITNS[16U]; /*!< Offset: 0x280 (R/W) Interrupt Non-Secure State Register */ + uint32_t RESERVED5[16U]; + __IOM uint32_t IPR[124U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */ +} NVIC_Type; + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ +#else + uint32_t RESERVED0; +#endif + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + uint32_t RESERVED1; + __IOM uint32_t SHPR[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_PENDNMISET_Pos 31U /*!< SCB ICSR: PENDNMISET Position */ +#define SCB_ICSR_PENDNMISET_Msk (1UL << SCB_ICSR_PENDNMISET_Pos) /*!< SCB ICSR: PENDNMISET Mask */ + +#define SCB_ICSR_PENDNMICLR_Pos 30U /*!< SCB ICSR: PENDNMICLR Position */ +#define SCB_ICSR_PENDNMICLR_Msk (1UL << SCB_ICSR_PENDNMICLR_Pos) /*!< SCB ICSR: PENDNMICLR Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_STTNS_Pos 24U /*!< SCB ICSR: STTNS Position (Security Extension) */ +#define SCB_ICSR_STTNS_Msk (1UL << SCB_ICSR_STTNS_Pos) /*!< SCB ICSR: STTNS Mask (Security Extension) */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) +/* SCB Vector Table Offset Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ +#endif + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIS_Pos 14U /*!< SCB AIRCR: PRIS Position */ +#define SCB_AIRCR_PRIS_Msk (1UL << SCB_AIRCR_PRIS_Pos) /*!< SCB AIRCR: PRIS Mask */ + +#define SCB_AIRCR_BFHFNMINS_Pos 13U /*!< SCB AIRCR: BFHFNMINS Position */ +#define SCB_AIRCR_BFHFNMINS_Msk (1UL << SCB_AIRCR_BFHFNMINS_Pos) /*!< SCB AIRCR: BFHFNMINS Mask */ + +#define SCB_AIRCR_SYSRESETREQS_Pos 3U /*!< SCB AIRCR: SYSRESETREQS Position */ +#define SCB_AIRCR_SYSRESETREQS_Msk (1UL << SCB_AIRCR_SYSRESETREQS_Pos) /*!< SCB AIRCR: SYSRESETREQS Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEPS_Pos 3U /*!< SCB SCR: SLEEPDEEPS Position */ +#define SCB_SCR_SLEEPDEEPS_Msk (1UL << SCB_SCR_SLEEPDEEPS_Pos) /*!< SCB SCR: SLEEPDEEPS Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_BP_Pos 18U /*!< SCB CCR: BP Position */ +#define SCB_CCR_BP_Msk (1UL << SCB_CCR_BP_Pos) /*!< SCB CCR: BP Mask */ + +#define SCB_CCR_IC_Pos 17U /*!< SCB CCR: IC Position */ +#define SCB_CCR_IC_Msk (1UL << SCB_CCR_IC_Pos) /*!< SCB CCR: IC Mask */ + +#define SCB_CCR_DC_Pos 16U /*!< SCB CCR: DC Position */ +#define SCB_CCR_DC_Msk (1UL << SCB_CCR_DC_Pos) /*!< SCB CCR: DC Mask */ + +#define SCB_CCR_STKOFHFNMIGN_Pos 10U /*!< SCB CCR: STKOFHFNMIGN Position */ +#define SCB_CCR_STKOFHFNMIGN_Msk (1UL << SCB_CCR_STKOFHFNMIGN_Pos) /*!< SCB CCR: STKOFHFNMIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< 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 4U /*!< 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 3U /*!< 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 1U /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_HARDFAULTPENDED_Pos 21U /*!< SCB SHCSR: HARDFAULTPENDED Position */ +#define SCB_SHCSR_HARDFAULTPENDED_Msk (1UL << SCB_SHCSR_HARDFAULTPENDED_Pos) /*!< SCB SHCSR: HARDFAULTPENDED Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_NMIACT_Pos 5U /*!< SCB SHCSR: NMIACT Position */ +#define SCB_SHCSR_NMIACT_Msk (1UL << SCB_SHCSR_NMIACT_Pos) /*!< SCB SHCSR: NMIACT Mask */ + +#define SCB_SHCSR_HARDFAULTACT_Pos 2U /*!< SCB SHCSR: HARDFAULTACT Position */ +#define SCB_SHCSR_HARDFAULTACT_Msk (1UL << SCB_SHCSR_HARDFAULTACT_Pos) /*!< SCB SHCSR: HARDFAULTACT Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** + \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + uint32_t RESERVED0[6U]; + __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + uint32_t RESERVED1[1U]; + __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + uint32_t RESERVED3[1U]; + __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED4[1U]; + __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + uint32_t RESERVED5[1U]; + __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED6[1U]; + __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + uint32_t RESERVED7[1U]; + __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ + uint32_t RESERVED8[1U]; + __IOM uint32_t COMP4; /*!< Offset: 0x060 (R/W) Comparator Register 4 */ + uint32_t RESERVED9[1U]; + __IOM uint32_t FUNCTION4; /*!< Offset: 0x068 (R/W) Function Register 4 */ + uint32_t RESERVED10[1U]; + __IOM uint32_t COMP5; /*!< Offset: 0x070 (R/W) Comparator Register 5 */ + uint32_t RESERVED11[1U]; + __IOM uint32_t FUNCTION5; /*!< Offset: 0x078 (R/W) Function Register 5 */ + uint32_t RESERVED12[1U]; + __IOM uint32_t COMP6; /*!< Offset: 0x080 (R/W) Comparator Register 6 */ + uint32_t RESERVED13[1U]; + __IOM uint32_t FUNCTION6; /*!< Offset: 0x088 (R/W) Function Register 6 */ + uint32_t RESERVED14[1U]; + __IOM uint32_t COMP7; /*!< Offset: 0x090 (R/W) Comparator Register 7 */ + uint32_t RESERVED15[1U]; + __IOM uint32_t FUNCTION7; /*!< Offset: 0x098 (R/W) Function Register 7 */ + uint32_t RESERVED16[1U]; + __IOM uint32_t COMP8; /*!< Offset: 0x0A0 (R/W) Comparator Register 8 */ + uint32_t RESERVED17[1U]; + __IOM uint32_t FUNCTION8; /*!< Offset: 0x0A8 (R/W) Function Register 8 */ + uint32_t RESERVED18[1U]; + __IOM uint32_t COMP9; /*!< Offset: 0x0B0 (R/W) Comparator Register 9 */ + uint32_t RESERVED19[1U]; + __IOM uint32_t FUNCTION9; /*!< Offset: 0x0B8 (R/W) Function Register 9 */ + uint32_t RESERVED20[1U]; + __IOM uint32_t COMP10; /*!< Offset: 0x0C0 (R/W) Comparator Register 10 */ + uint32_t RESERVED21[1U]; + __IOM uint32_t FUNCTION10; /*!< Offset: 0x0C8 (R/W) Function Register 10 */ + uint32_t RESERVED22[1U]; + __IOM uint32_t COMP11; /*!< Offset: 0x0D0 (R/W) Comparator Register 11 */ + uint32_t RESERVED23[1U]; + __IOM uint32_t FUNCTION11; /*!< Offset: 0x0D8 (R/W) Function Register 11 */ + uint32_t RESERVED24[1U]; + __IOM uint32_t COMP12; /*!< Offset: 0x0E0 (R/W) Comparator Register 12 */ + uint32_t RESERVED25[1U]; + __IOM uint32_t FUNCTION12; /*!< Offset: 0x0E8 (R/W) Function Register 12 */ + uint32_t RESERVED26[1U]; + __IOM uint32_t COMP13; /*!< Offset: 0x0F0 (R/W) Comparator Register 13 */ + uint32_t RESERVED27[1U]; + __IOM uint32_t FUNCTION13; /*!< Offset: 0x0F8 (R/W) Function Register 13 */ + uint32_t RESERVED28[1U]; + __IOM uint32_t COMP14; /*!< Offset: 0x100 (R/W) Comparator Register 14 */ + uint32_t RESERVED29[1U]; + __IOM uint32_t FUNCTION14; /*!< Offset: 0x108 (R/W) Function Register 14 */ + uint32_t RESERVED30[1U]; + __IOM uint32_t COMP15; /*!< Offset: 0x110 (R/W) Comparator Register 15 */ + uint32_t RESERVED31[1U]; + __IOM uint32_t FUNCTION15; /*!< Offset: 0x118 (R/W) Function Register 15 */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_ID_Pos 27U /*!< DWT FUNCTION: ID Position */ +#define DWT_FUNCTION_ID_Msk (0x1FUL << DWT_FUNCTION_ID_Pos) /*!< DWT FUNCTION: ID Mask */ + +#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_ACTION_Pos 4U /*!< DWT FUNCTION: ACTION Position */ +#define DWT_FUNCTION_ACTION_Msk (0x3UL << DWT_FUNCTION_ACTION_Pos) /*!< DWT FUNCTION: ACTION Mask */ + +#define DWT_FUNCTION_MATCH_Pos 0U /*!< DWT FUNCTION: MATCH Position */ +#define DWT_FUNCTION_MATCH_Msk (0xFUL /*<< DWT_FUNCTION_MATCH_Pos*/) /*!< DWT FUNCTION: MATCH Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** + \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IOM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55U]; + __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131U]; + __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __IM uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ + uint32_t RESERVED3[759U]; + __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER */ + __IM uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ + __IM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ + uint32_t RESERVED4[1U]; + __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */ + __IM uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */ + __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ + uint32_t RESERVED5[39U]; + __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ + __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ + uint32_t RESERVED7[8U]; + __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_PRESCALER_Pos 0U /*!< TPI ACPR: PRESCALER Position */ +#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< TPI ACPR: PRESCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI TRIGGER Register Definitions */ +#define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */ +#define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */ + +/* TPI Integration ETM Data Register Definitions (FIFO0) */ +#define TPI_FIFO0_ITM_ATVALID_Pos 29U /*!< TPI FIFO0: ITM_ATVALID Position */ +#define TPI_FIFO0_ITM_ATVALID_Msk (0x3UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ + +#define TPI_FIFO0_ITM_bytecount_Pos 27U /*!< TPI FIFO0: ITM_bytecount Position */ +#define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */ + +#define TPI_FIFO0_ETM_ATVALID_Pos 26U /*!< TPI FIFO0: ETM_ATVALID Position */ +#define TPI_FIFO0_ETM_ATVALID_Msk (0x3UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ + +#define TPI_FIFO0_ETM_bytecount_Pos 24U /*!< TPI FIFO0: ETM_bytecount Position */ +#define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */ + +#define TPI_FIFO0_ETM2_Pos 16U /*!< TPI FIFO0: ETM2 Position */ +#define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */ + +#define TPI_FIFO0_ETM1_Pos 8U /*!< TPI FIFO0: ETM1 Position */ +#define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */ + +#define TPI_FIFO0_ETM0_Pos 0U /*!< TPI FIFO0: ETM0 Position */ +#define TPI_FIFO0_ETM0_Msk (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/) /*!< TPI FIFO0: ETM0 Mask */ + +/* TPI ITATBCTR2 Register Definitions */ +#define TPI_ITATBCTR2_ATREADY_Pos 0U /*!< TPI ITATBCTR2: ATREADY Position */ +#define TPI_ITATBCTR2_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY_Pos*/) /*!< TPI ITATBCTR2: ATREADY Mask */ + +/* TPI Integration ITM Data Register Definitions (FIFO1) */ +#define TPI_FIFO1_ITM_ATVALID_Pos 29U /*!< TPI FIFO1: ITM_ATVALID Position */ +#define TPI_FIFO1_ITM_ATVALID_Msk (0x3UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ + +#define TPI_FIFO1_ITM_bytecount_Pos 27U /*!< TPI FIFO1: ITM_bytecount Position */ +#define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */ + +#define TPI_FIFO1_ETM_ATVALID_Pos 26U /*!< TPI FIFO1: ETM_ATVALID Position */ +#define TPI_FIFO1_ETM_ATVALID_Msk (0x3UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ + +#define TPI_FIFO1_ETM_bytecount_Pos 24U /*!< TPI FIFO1: ETM_bytecount Position */ +#define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */ + +#define TPI_FIFO1_ITM2_Pos 16U /*!< TPI FIFO1: ITM2 Position */ +#define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */ + +#define TPI_FIFO1_ITM1_Pos 8U /*!< TPI FIFO1: ITM1 Position */ +#define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */ + +#define TPI_FIFO1_ITM0_Pos 0U /*!< TPI FIFO1: ITM0 Position */ +#define TPI_FIFO1_ITM0_Msk (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/) /*!< TPI FIFO1: ITM0 Mask */ + +/* TPI ITATBCTR0 Register Definitions */ +#define TPI_ITATBCTR0_ATREADY_Pos 0U /*!< TPI ITATBCTR0: ATREADY Position */ +#define TPI_ITATBCTR0_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY_Pos*/) /*!< TPI ITATBCTR0: ATREADY Mask */ + +/* TPI Integration Mode Control Register Definitions */ +#define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ +#define TPI_ITCTRL_Mode_Msk (0x1UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_MinBufSz_Pos 6U /*!< TPI DEVID: MinBufSz Position */ +#define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */ + +#define TPI_DEVID_AsynClkIn_Pos 5U /*!< TPI DEVID: AsynClkIn Position */ +#define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */ + +#define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */ +#define TPI_DEVID_NrTraceInput_Msk (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_MajorType_Pos 4U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +#define TPI_DEVTYPE_SubType_Pos 0U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) MPU Region Limit Address Register */ + uint32_t RESERVED0[7U]; + __IOM uint32_t MAIR0; /*!< Offset: 0x030 (R/W) MPU Memory Attribute Indirection Register 0 */ + __IOM uint32_t MAIR1; /*!< Offset: 0x034 (R/W) MPU Memory Attribute Indirection Register 1 */ +} MPU_Type; + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_BASE_Pos 5U /*!< MPU RBAR: BASE Position */ +#define MPU_RBAR_BASE_Msk (0x7FFFFFFUL << MPU_RBAR_BASE_Pos) /*!< MPU RBAR: BASE Mask */ + +#define MPU_RBAR_SH_Pos 3U /*!< MPU RBAR: SH Position */ +#define MPU_RBAR_SH_Msk (0x3UL << MPU_RBAR_SH_Pos) /*!< MPU RBAR: SH Mask */ + +#define MPU_RBAR_AP_Pos 1U /*!< MPU RBAR: AP Position */ +#define MPU_RBAR_AP_Msk (0x3UL << MPU_RBAR_AP_Pos) /*!< MPU RBAR: AP Mask */ + +#define MPU_RBAR_XN_Pos 0U /*!< MPU RBAR: XN Position */ +#define MPU_RBAR_XN_Msk (01UL /*<< MPU_RBAR_XN_Pos*/) /*!< MPU RBAR: XN Mask */ + +/* MPU Region Limit Address Register Definitions */ +#define MPU_RLAR_LIMIT_Pos 5U /*!< MPU RLAR: LIMIT Position */ +#define MPU_RLAR_LIMIT_Msk (0x7FFFFFFUL << MPU_RLAR_LIMIT_Pos) /*!< MPU RLAR: LIMIT Mask */ + +#define MPU_RLAR_AttrIndx_Pos 1U /*!< MPU RLAR: AttrIndx Position */ +#define MPU_RLAR_AttrIndx_Msk (0x7UL << MPU_RLAR_AttrIndx_Pos) /*!< MPU RLAR: AttrIndx Mask */ + +#define MPU_RLAR_EN_Pos 0U /*!< MPU RLAR: EN Position */ +#define MPU_RLAR_EN_Msk (1UL /*<< MPU_RLAR_EN_Pos*/) /*!< MPU RLAR: EN Mask */ + +/* MPU Memory Attribute Indirection Register 0 Definitions */ +#define MPU_MAIR0_Attr3_Pos 24U /*!< MPU MAIR0: Attr3 Position */ +#define MPU_MAIR0_Attr3_Msk (0xFFUL << MPU_MAIR0_Attr3_Pos) /*!< MPU MAIR0: Attr3 Mask */ + +#define MPU_MAIR0_Attr2_Pos 16U /*!< MPU MAIR0: Attr2 Position */ +#define MPU_MAIR0_Attr2_Msk (0xFFUL << MPU_MAIR0_Attr2_Pos) /*!< MPU MAIR0: Attr2 Mask */ + +#define MPU_MAIR0_Attr1_Pos 8U /*!< MPU MAIR0: Attr1 Position */ +#define MPU_MAIR0_Attr1_Msk (0xFFUL << MPU_MAIR0_Attr1_Pos) /*!< MPU MAIR0: Attr1 Mask */ + +#define MPU_MAIR0_Attr0_Pos 0U /*!< MPU MAIR0: Attr0 Position */ +#define MPU_MAIR0_Attr0_Msk (0xFFUL /*<< MPU_MAIR0_Attr0_Pos*/) /*!< MPU MAIR0: Attr0 Mask */ + +/* MPU Memory Attribute Indirection Register 1 Definitions */ +#define MPU_MAIR1_Attr7_Pos 24U /*!< MPU MAIR1: Attr7 Position */ +#define MPU_MAIR1_Attr7_Msk (0xFFUL << MPU_MAIR1_Attr7_Pos) /*!< MPU MAIR1: Attr7 Mask */ + +#define MPU_MAIR1_Attr6_Pos 16U /*!< MPU MAIR1: Attr6 Position */ +#define MPU_MAIR1_Attr6_Msk (0xFFUL << MPU_MAIR1_Attr6_Pos) /*!< MPU MAIR1: Attr6 Mask */ + +#define MPU_MAIR1_Attr5_Pos 8U /*!< MPU MAIR1: Attr5 Position */ +#define MPU_MAIR1_Attr5_Msk (0xFFUL << MPU_MAIR1_Attr5_Pos) /*!< MPU MAIR1: Attr5 Mask */ + +#define MPU_MAIR1_Attr4_Pos 0U /*!< MPU MAIR1: Attr4 Position */ +#define MPU_MAIR1_Attr4_Msk (0xFFUL /*<< MPU_MAIR1_Attr4_Pos*/) /*!< MPU MAIR1: Attr4 Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SAU Security Attribution Unit (SAU) + \brief Type definitions for the Security Attribution Unit (SAU) + @{ + */ + +/** + \brief Structure type to access the Security Attribution Unit (SAU). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SAU Control Register */ + __IM uint32_t TYPE; /*!< Offset: 0x004 (R/ ) SAU Type Register */ +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) SAU Region Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) SAU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) SAU Region Limit Address Register */ +#endif +} SAU_Type; + +/* SAU Control Register Definitions */ +#define SAU_CTRL_ALLNS_Pos 1U /*!< SAU CTRL: ALLNS Position */ +#define SAU_CTRL_ALLNS_Msk (1UL << SAU_CTRL_ALLNS_Pos) /*!< SAU CTRL: ALLNS Mask */ + +#define SAU_CTRL_ENABLE_Pos 0U /*!< SAU CTRL: ENABLE Position */ +#define SAU_CTRL_ENABLE_Msk (1UL /*<< SAU_CTRL_ENABLE_Pos*/) /*!< SAU CTRL: ENABLE Mask */ + +/* SAU Type Register Definitions */ +#define SAU_TYPE_SREGION_Pos 0U /*!< SAU TYPE: SREGION Position */ +#define SAU_TYPE_SREGION_Msk (0xFFUL /*<< SAU_TYPE_SREGION_Pos*/) /*!< SAU TYPE: SREGION Mask */ + +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) +/* SAU Region Number Register Definitions */ +#define SAU_RNR_REGION_Pos 0U /*!< SAU RNR: REGION Position */ +#define SAU_RNR_REGION_Msk (0xFFUL /*<< SAU_RNR_REGION_Pos*/) /*!< SAU RNR: REGION Mask */ + +/* SAU Region Base Address Register Definitions */ +#define SAU_RBAR_BADDR_Pos 5U /*!< SAU RBAR: BADDR Position */ +#define SAU_RBAR_BADDR_Msk (0x7FFFFFFUL << SAU_RBAR_BADDR_Pos) /*!< SAU RBAR: BADDR Mask */ + +/* SAU Region Limit Address Register Definitions */ +#define SAU_RLAR_LADDR_Pos 5U /*!< SAU RLAR: LADDR Position */ +#define SAU_RLAR_LADDR_Msk (0x7FFFFFFUL << SAU_RLAR_LADDR_Pos) /*!< SAU RLAR: LADDR Mask */ + +#define SAU_RLAR_NSC_Pos 1U /*!< SAU RLAR: NSC Position */ +#define SAU_RLAR_NSC_Msk (1UL << SAU_RLAR_NSC_Pos) /*!< SAU RLAR: NSC Mask */ + +#define SAU_RLAR_ENABLE_Pos 0U /*!< SAU RLAR: ENABLE Position */ +#define SAU_RLAR_ENABLE_Msk (1UL /*<< SAU_RLAR_ENABLE_Pos*/) /*!< SAU RLAR: ENABLE Mask */ + +#endif /* defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) */ + +/*@} end of group CMSIS_SAU */ +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** + \brief Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ + uint32_t RESERVED4[1U]; + __IOM uint32_t DAUTHCTRL; /*!< Offset: 0x014 (R/W) Debug Authentication Control Register */ + __IOM uint32_t DSCSR; /*!< Offset: 0x018 (R/W) Debug Security Control and Status Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register Definitions */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESTART_ST_Pos 26U /*!< CoreDebug DHCSR: S_RESTART_ST Position */ +#define CoreDebug_DHCSR_S_RESTART_ST_Msk (1UL << CoreDebug_DHCSR_S_RESTART_ST_Pos) /*!< CoreDebug DHCSR: S_RESTART_ST Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< 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 24U /*!< 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 19U /*!< 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 18U /*!< 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 17U /*!< 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 16U /*!< 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_MASKINTS_Pos 3U /*!< 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 2U /*!< 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 1U /*!< 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 0U /*!< 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 Definitions */ +#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< 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_DWTENA_Pos 24U /*!< CoreDebug DEMCR: DWTENA Position */ +#define CoreDebug_DEMCR_DWTENA_Msk (1UL << CoreDebug_DEMCR_DWTENA_Pos) /*!< CoreDebug DEMCR: DWTENA Mask */ + +#define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< 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_CORERESET_Pos 0U /*!< CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ + +/* Debug Authentication Control Register Definitions */ +#define CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos 3U /*!< CoreDebug DAUTHCTRL: INTSPNIDEN, Position */ +#define CoreDebug_DAUTHCTRL_INTSPNIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos) /*!< CoreDebug DAUTHCTRL: INTSPNIDEN, Mask */ + +#define CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos 2U /*!< CoreDebug DAUTHCTRL: SPNIDENSEL Position */ +#define CoreDebug_DAUTHCTRL_SPNIDENSEL_Msk (1UL << CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos) /*!< CoreDebug DAUTHCTRL: SPNIDENSEL Mask */ + +#define CoreDebug_DAUTHCTRL_INTSPIDEN_Pos 1U /*!< CoreDebug DAUTHCTRL: INTSPIDEN Position */ +#define CoreDebug_DAUTHCTRL_INTSPIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPIDEN_Pos) /*!< CoreDebug DAUTHCTRL: INTSPIDEN Mask */ + +#define CoreDebug_DAUTHCTRL_SPIDENSEL_Pos 0U /*!< CoreDebug DAUTHCTRL: SPIDENSEL Position */ +#define CoreDebug_DAUTHCTRL_SPIDENSEL_Msk (1UL /*<< CoreDebug_DAUTHCTRL_SPIDENSEL_Pos*/) /*!< CoreDebug DAUTHCTRL: SPIDENSEL Mask */ + +/* Debug Security Control and Status Register Definitions */ +#define CoreDebug_DSCSR_CDS_Pos 16U /*!< CoreDebug DSCSR: CDS Position */ +#define CoreDebug_DSCSR_CDS_Msk (1UL << CoreDebug_DSCSR_CDS_Pos) /*!< CoreDebug DSCSR: CDS Mask */ + +#define CoreDebug_DSCSR_SBRSEL_Pos 1U /*!< CoreDebug DSCSR: SBRSEL Position */ +#define CoreDebug_DSCSR_SBRSEL_Msk (1UL << CoreDebug_DSCSR_SBRSEL_Pos) /*!< CoreDebug DSCSR: SBRSEL Mask */ + +#define CoreDebug_DSCSR_SBRSELEN_Pos 0U /*!< CoreDebug DSCSR: SBRSELEN Position */ +#define CoreDebug_DSCSR_SBRSELEN_Msk (1UL /*<< CoreDebug_DSCSR_SBRSELEN_Pos*/) /*!< CoreDebug DSCSR: SBRSELEN Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ + #define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ + #define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ + #define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ + #define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ + #define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ + #define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ + #define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + + + #define 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 DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ + #define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ + #define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE ) /*!< Core Debug configuration struct */ + + #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ + #endif + + #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + #define SAU_BASE (SCS_BASE + 0x0DD0UL) /*!< Security Attribution Unit */ + #define SAU ((SAU_Type *) SAU_BASE ) /*!< Security Attribution Unit */ + #endif + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + #define SCS_BASE_NS (0xE002E000UL) /*!< System Control Space Base Address (non-secure address space) */ + #define CoreDebug_BASE_NS (0xE002EDF0UL) /*!< Core Debug Base Address (non-secure address space) */ + #define SysTick_BASE_NS (SCS_BASE_NS + 0x0010UL) /*!< SysTick Base Address (non-secure address space) */ + #define NVIC_BASE_NS (SCS_BASE_NS + 0x0100UL) /*!< NVIC Base Address (non-secure address space) */ + #define SCB_BASE_NS (SCS_BASE_NS + 0x0D00UL) /*!< System Control Block Base Address (non-secure address space) */ + + #define SCB_NS ((SCB_Type *) SCB_BASE_NS ) /*!< SCB configuration struct (non-secure address space) */ + #define SysTick_NS ((SysTick_Type *) SysTick_BASE_NS ) /*!< SysTick configuration struct (non-secure address space) */ + #define NVIC_NS ((NVIC_Type *) NVIC_BASE_NS ) /*!< NVIC configuration struct (non-secure address space) */ + #define CoreDebug_NS ((CoreDebug_Type *) CoreDebug_BASE_NS) /*!< Core Debug configuration struct (non-secure address space) */ + + #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE_NS (SCS_BASE_NS + 0x0D90UL) /*!< Memory Protection Unit (non-secure address space) */ + #define MPU_NS ((MPU_Type *) MPU_BASE_NS ) /*!< Memory Protection Unit (non-secure address space) */ + #endif + +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else +/*#define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping not available for Cortex-M23 */ +/*#define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping not available for Cortex-M23 */ + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ + #define NVIC_GetActive __NVIC_GetActive + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + +/* Interrupt Priorities are WORD accessible only under ARMv6M */ +/* The following MACROS handle generation of the register offset and byte masks */ +#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL) +#define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) ) +#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) ) + + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt + \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IABR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Get Interrupt Target State + \details Reads the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + \return 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_GetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ITNS[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Target State + \details Sets the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_SetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)(int32_t)IRQn) >> 5UL)] |= ((uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Clear Interrupt Target State + \details Clears the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_ClearTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)(int32_t)IRQn) >> 5UL)] &= ~((uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IPR[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IPR[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } + else + { + SCB->SHPR[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHPR[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IPR[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return((uint32_t)(((SCB->SHPR[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + If VTOR is not present address 0 must be mapped to SRAM. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) + uint32_t *vectors = (uint32_t *)SCB->VTOR; +#else + uint32_t *vectors = (uint32_t *)0x0U; +#endif + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) + uint32_t *vectors = (uint32_t *)SCB->VTOR; +#else + uint32_t *vectors = (uint32_t *)0x0U; +#endif + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + SCB_AIRCR_SYSRESETREQ_Msk); + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Enable Interrupt (non-secure) + \details Enables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_EnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status (non-secure) + \details Returns a device specific interrupt enable status from the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetEnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt (non-secure) + \details Disables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_DisableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Pending Interrupt (non-secure) + \details Reads the NVIC pending register in the non-secure NVIC when in secure state and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } +} + + +/** + \brief Set Pending Interrupt (non-secure) + \details Sets the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_SetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt (non-secure) + \details Clears the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_ClearPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt (non-secure) + \details Reads the active register in non-secure NVIC when in secure state and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetActive_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->IABR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Priority (non-secure) + \details Sets the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every non-secure processor exception. + */ +__STATIC_INLINE void TZ_NVIC_SetPriority_NS(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->IPR[_IP_IDX(IRQn)] = ((uint32_t)(NVIC_NS->IPR[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } + else + { + SCB_NS->SHPR[_SHP_IDX(IRQn)] = ((uint32_t)(SCB_NS->SHPR[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } +} + + +/** + \brief Get Interrupt Priority (non-secure) + \details Reads the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPriority_NS(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->IPR[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return((uint32_t)(((SCB_NS->SHPR[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) &&(__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_NVICFunctions */ + + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + return 0U; /* No FPU */ +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ########################## SAU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SAUFunctions SAU Functions + \brief Functions that configure the SAU. + @{ + */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + +/** + \brief Enable SAU + \details Enables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Enable(void) +{ + SAU->CTRL |= (SAU_CTRL_ENABLE_Msk); +} + + + +/** + \brief Disable SAU + \details Disables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Disable(void) +{ + SAU->CTRL &= ~(SAU_CTRL_ENABLE_Msk); +} + +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_SAUFunctions */ + + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief System Tick Configuration (non-secure) + \details Initializes the non-secure System Timer and its interrupt when in secure state, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function TZ_SysTick_Config_NS is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + + */ +__STATIC_INLINE uint32_t TZ_SysTick_Config_NS(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick_NS->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + TZ_NVIC_SetPriority_NS (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick_NS->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick_NS->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM23_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/cmsis/core_cm3.h b/cmsis/core_cm3.h new file mode 100644 index 00000000000..cfeb58bea91 --- /dev/null +++ b/cmsis/core_cm3.h @@ -0,0 +1,1919 @@ +/**************************************************************************//** + * @file core_cm3.h + * @brief CMSIS Cortex-M3 Core Peripheral Access Layer Header File + * @version V5.0.2 + * @date 13. February 2017 + ******************************************************************************/ +/* + * Copyright (c) 2009-2017 ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_CM3_H_GENERIC +#define __CORE_CM3_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex_M3 + @{ + */ + +/* CMSIS CM3 definitions */ +#define __CM3_CMSIS_VERSION_MAIN ( 5U) /*!< [31:16] CMSIS HAL main version */ +#define __CM3_CMSIS_VERSION_SUB ( 0U) /*!< [15:0] CMSIS HAL sub version */ +#define __CM3_CMSIS_VERSION ((__CM3_CMSIS_VERSION_MAIN << 16U) | \ + __CM3_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */ + +#define __CORTEX_M (3U) /*!< Cortex-M Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + This core does not support an FPU at all +*/ +#define __FPU_USED 0U + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_PCS_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM3_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM3_H_DEPENDANT +#define __CORE_CM3_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM3_REV + #define __CM3_REV 0x0200U + #warning "__CM3_REV not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 3U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group Cortex_M3 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:27; /*!< bit: 0..26 Reserved */ + 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; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + +#define APSR_Q_Pos 27U /*!< APSR: Q Position */ +#define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:1; /*!< bit: 9 Reserved */ + uint32_t ICI_IT_1:6; /*!< bit: 10..15 ICI/IT part 1 */ + uint32_t _reserved1:8; /*!< bit: 16..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit */ + uint32_t ICI_IT_2:2; /*!< bit: 25..26 ICI/IT part 2 */ + 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; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_Q_Pos 27U /*!< xPSR: Q Position */ +#define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */ + +#define xPSR_ICI_IT_2_Pos 25U /*!< xPSR: ICI/IT part 2 Position */ +#define xPSR_ICI_IT_2_Msk (3UL << xPSR_ICI_IT_2_Pos) /*!< xPSR: ICI/IT part 2 Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_ICI_IT_1_Pos 10U /*!< xPSR: ICI/IT part 1 Position */ +#define xPSR_ICI_IT_1_Msk (0x3FUL << xPSR_ICI_IT_1_Pos) /*!< xPSR: ICI/IT part 1 Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[8U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[24U]; + __IOM uint32_t ICER[8U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[24U]; + __IOM uint32_t ISPR[8U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[24U]; + __IOM uint32_t ICPR[8U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[24U]; + __IOM uint32_t IABR[8U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[56U]; + __IOM uint8_t IP[240U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED5[644U]; + __OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; + +/* Software Triggered Interrupt Register Definitions */ +#define NVIC_STIR_INTID_Pos 0U /*!< STIR: INTLINESNUM Position */ +#define NVIC_STIR_INTID_Msk (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/) /*!< STIR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + __IOM uint8_t SHP[12U]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IOM uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IOM uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IOM uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IOM uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IOM uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IOM uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __IM uint32_t PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __IM uint32_t DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __IM uint32_t ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __IM uint32_t MMFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __IM uint32_t ISAR[5U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + uint32_t RESERVED0[5U]; + __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Vector Table Offset Register Definitions */ +#if defined (__CM3_REV) && (__CM3_REV < 0x0201U) /* core r2p1 */ +#define SCB_VTOR_TBLBASE_Pos 29U /*!< SCB VTOR: TBLBASE Position */ +#define SCB_VTOR_TBLBASE_Msk (1UL << SCB_VTOR_TBLBASE_Pos) /*!< SCB VTOR: TBLBASE Mask */ + +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x3FFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ +#else +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ +#endif + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */ +#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +#define SCB_AIRCR_VECTRESET_Pos 0U /*!< 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 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< 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 4U /*!< 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 3U /*!< 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 1U /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +#define SCB_CCR_NONBASETHRDENA_Pos 0U /*!< 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 18U /*!< SCB SHCSR: USGFAULTENA Position */ +#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ + +#define SCB_SHCSR_BUSFAULTENA_Pos 17U /*!< SCB SHCSR: BUSFAULTENA Position */ +#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ + +#define SCB_SHCSR_MEMFAULTENA_Pos 16U /*!< SCB SHCSR: MEMFAULTENA Position */ +#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_BUSFAULTPENDED_Pos 14U /*!< SCB SHCSR: BUSFAULTPENDED Position */ +#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ + +#define SCB_SHCSR_MEMFAULTPENDED_Pos 13U /*!< SCB SHCSR: MEMFAULTPENDED Position */ +#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ + +#define SCB_SHCSR_USGFAULTPENDED_Pos 12U /*!< SCB SHCSR: USGFAULTPENDED Position */ +#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_MONITORACT_Pos 8U /*!< SCB SHCSR: MONITORACT Position */ +#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_USGFAULTACT_Pos 3U /*!< SCB SHCSR: USGFAULTACT Position */ +#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ + +#define SCB_SHCSR_BUSFAULTACT_Pos 1U /*!< SCB SHCSR: BUSFAULTACT Position */ +#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ + +#define SCB_SHCSR_MEMFAULTACT_Pos 0U /*!< SCB SHCSR: MEMFAULTACT Position */ +#define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */ + +/* SCB Configurable Fault Status Register Definitions */ +#define SCB_CFSR_USGFAULTSR_Pos 16U /*!< 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 8U /*!< 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 0U /*!< 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 */ + +/* MemManage Fault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_MMARVALID_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 7U) /*!< SCB CFSR (MMFSR): MMARVALID Position */ +#define SCB_CFSR_MMARVALID_Msk (1UL << SCB_CFSR_MMARVALID_Pos) /*!< SCB CFSR (MMFSR): MMARVALID Mask */ + +#define SCB_CFSR_MSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 4U) /*!< SCB CFSR (MMFSR): MSTKERR Position */ +#define SCB_CFSR_MSTKERR_Msk (1UL << SCB_CFSR_MSTKERR_Pos) /*!< SCB CFSR (MMFSR): MSTKERR Mask */ + +#define SCB_CFSR_MUNSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 3U) /*!< SCB CFSR (MMFSR): MUNSTKERR Position */ +#define SCB_CFSR_MUNSTKERR_Msk (1UL << SCB_CFSR_MUNSTKERR_Pos) /*!< SCB CFSR (MMFSR): MUNSTKERR Mask */ + +#define SCB_CFSR_DACCVIOL_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 1U) /*!< SCB CFSR (MMFSR): DACCVIOL Position */ +#define SCB_CFSR_DACCVIOL_Msk (1UL << SCB_CFSR_DACCVIOL_Pos) /*!< SCB CFSR (MMFSR): DACCVIOL Mask */ + +#define SCB_CFSR_IACCVIOL_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 0U) /*!< SCB CFSR (MMFSR): IACCVIOL Position */ +#define SCB_CFSR_IACCVIOL_Msk (1UL /*<< SCB_CFSR_IACCVIOL_Pos*/) /*!< SCB CFSR (MMFSR): IACCVIOL Mask */ + +/* BusFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_BFARVALID_Pos (SCB_CFSR_BUSFAULTSR_Pos + 7U) /*!< SCB CFSR (BFSR): BFARVALID Position */ +#define SCB_CFSR_BFARVALID_Msk (1UL << SCB_CFSR_BFARVALID_Pos) /*!< SCB CFSR (BFSR): BFARVALID Mask */ + +#define SCB_CFSR_STKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 4U) /*!< SCB CFSR (BFSR): STKERR Position */ +#define SCB_CFSR_STKERR_Msk (1UL << SCB_CFSR_STKERR_Pos) /*!< SCB CFSR (BFSR): STKERR Mask */ + +#define SCB_CFSR_UNSTKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 3U) /*!< SCB CFSR (BFSR): UNSTKERR Position */ +#define SCB_CFSR_UNSTKERR_Msk (1UL << SCB_CFSR_UNSTKERR_Pos) /*!< SCB CFSR (BFSR): UNSTKERR Mask */ + +#define SCB_CFSR_IMPRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 2U) /*!< SCB CFSR (BFSR): IMPRECISERR Position */ +#define SCB_CFSR_IMPRECISERR_Msk (1UL << SCB_CFSR_IMPRECISERR_Pos) /*!< SCB CFSR (BFSR): IMPRECISERR Mask */ + +#define SCB_CFSR_PRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 1U) /*!< SCB CFSR (BFSR): PRECISERR Position */ +#define SCB_CFSR_PRECISERR_Msk (1UL << SCB_CFSR_PRECISERR_Pos) /*!< SCB CFSR (BFSR): PRECISERR Mask */ + +#define SCB_CFSR_IBUSERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 0U) /*!< SCB CFSR (BFSR): IBUSERR Position */ +#define SCB_CFSR_IBUSERR_Msk (1UL << SCB_CFSR_IBUSERR_Pos) /*!< SCB CFSR (BFSR): IBUSERR Mask */ + +/* UsageFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_DIVBYZERO_Pos (SCB_CFSR_USGFAULTSR_Pos + 9U) /*!< SCB CFSR (UFSR): DIVBYZERO Position */ +#define SCB_CFSR_DIVBYZERO_Msk (1UL << SCB_CFSR_DIVBYZERO_Pos) /*!< SCB CFSR (UFSR): DIVBYZERO Mask */ + +#define SCB_CFSR_UNALIGNED_Pos (SCB_CFSR_USGFAULTSR_Pos + 8U) /*!< SCB CFSR (UFSR): UNALIGNED Position */ +#define SCB_CFSR_UNALIGNED_Msk (1UL << SCB_CFSR_UNALIGNED_Pos) /*!< SCB CFSR (UFSR): UNALIGNED Mask */ + +#define SCB_CFSR_NOCP_Pos (SCB_CFSR_USGFAULTSR_Pos + 3U) /*!< SCB CFSR (UFSR): NOCP Position */ +#define SCB_CFSR_NOCP_Msk (1UL << SCB_CFSR_NOCP_Pos) /*!< SCB CFSR (UFSR): NOCP Mask */ + +#define SCB_CFSR_INVPC_Pos (SCB_CFSR_USGFAULTSR_Pos + 2U) /*!< SCB CFSR (UFSR): INVPC Position */ +#define SCB_CFSR_INVPC_Msk (1UL << SCB_CFSR_INVPC_Pos) /*!< SCB CFSR (UFSR): INVPC Mask */ + +#define SCB_CFSR_INVSTATE_Pos (SCB_CFSR_USGFAULTSR_Pos + 1U) /*!< SCB CFSR (UFSR): INVSTATE Position */ +#define SCB_CFSR_INVSTATE_Msk (1UL << SCB_CFSR_INVSTATE_Pos) /*!< SCB CFSR (UFSR): INVSTATE Mask */ + +#define SCB_CFSR_UNDEFINSTR_Pos (SCB_CFSR_USGFAULTSR_Pos + 0U) /*!< SCB CFSR (UFSR): UNDEFINSTR Position */ +#define SCB_CFSR_UNDEFINSTR_Msk (1UL << SCB_CFSR_UNDEFINSTR_Pos) /*!< SCB CFSR (UFSR): UNDEFINSTR Mask */ + +/* SCB Hard Fault Status Register Definitions */ +#define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */ +#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ + +#define SCB_HFSR_FORCED_Pos 30U /*!< SCB HFSR: FORCED Position */ +#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ + +#define SCB_HFSR_VECTTBL_Pos 1U /*!< 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 4U /*!< SCB DFSR: EXTERNAL Position */ +#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ + +#define SCB_DFSR_VCATCH_Pos 3U /*!< SCB DFSR: VCATCH Position */ +#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ + +#define SCB_DFSR_DWTTRAP_Pos 2U /*!< SCB DFSR: DWTTRAP Position */ +#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ + +#define SCB_DFSR_BKPT_Pos 1U /*!< SCB DFSR: BKPT Position */ +#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ + +#define SCB_DFSR_HALTED_Pos 0U /*!< SCB DFSR: HALTED Position */ +#define SCB_DFSR_HALTED_Msk (1UL /*<< SCB_DFSR_HALTED_Pos*/) /*!< SCB DFSR: HALTED Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** + \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IM uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ +#if defined (__CM3_REV) && (__CM3_REV >= 0x200U) + __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ +#else + uint32_t RESERVED1[1U]; +#endif +} SCnSCB_Type; + +/* Interrupt Controller Type Register Definitions */ +#define SCnSCB_ICTR_INTLINESNUM_Pos 0U /*!< 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 2U /*!< ACTLR: DISFOLD Position */ +#define SCnSCB_ACTLR_DISFOLD_Msk (1UL << SCnSCB_ACTLR_DISFOLD_Pos) /*!< ACTLR: DISFOLD Mask */ + +#define SCnSCB_ACTLR_DISDEFWBUF_Pos 1U /*!< ACTLR: DISDEFWBUF Position */ +#define SCnSCB_ACTLR_DISDEFWBUF_Msk (1UL << SCnSCB_ACTLR_DISDEFWBUF_Pos) /*!< ACTLR: DISDEFWBUF Mask */ + +#define SCnSCB_ACTLR_DISMCYCINT_Pos 0U /*!< ACTLR: DISMCYCINT Position */ +#define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL /*<< SCnSCB_ACTLR_DISMCYCINT_Pos*/) /*!< ACTLR: DISMCYCINT Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) + \brief Type definitions for the Instrumentation Trace Macrocell (ITM) + @{ + */ + +/** + \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). + */ +typedef struct +{ + __OM union + { + __OM uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ + __OM uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ + __OM uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ + } PORT [32U]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ + uint32_t RESERVED0[864U]; + __IOM uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ + uint32_t RESERVED1[15U]; + __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ + uint32_t RESERVED2[15U]; + __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ + uint32_t RESERVED3[29U]; + __OM uint32_t IWR; /*!< Offset: 0xEF8 ( /W) ITM Integration Write Register */ + __IM uint32_t IRR; /*!< Offset: 0xEFC (R/ ) ITM Integration Read Register */ + __IOM uint32_t IMCR; /*!< Offset: 0xF00 (R/W) ITM Integration Mode Control Register */ + uint32_t RESERVED4[43U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ + uint32_t RESERVED5[6U]; + __IM uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ + __IM uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ + __IM uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ + __IM uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ + __IM uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ + __IM uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ + __IM uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ + __IM uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ + __IM uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ + __IM uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ + __IM uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ + __IM uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ +} ITM_Type; + +/* ITM Trace Privilege Register Definitions */ +#define ITM_TPR_PRIVMASK_Pos 0U /*!< 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 23U /*!< ITM TCR: BUSY Position */ +#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ + +#define ITM_TCR_TraceBusID_Pos 16U /*!< ITM TCR: ATBID Position */ +#define ITM_TCR_TraceBusID_Msk (0x7FUL << ITM_TCR_TraceBusID_Pos) /*!< ITM TCR: ATBID Mask */ + +#define ITM_TCR_GTSFREQ_Pos 10U /*!< 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 8U /*!< ITM TCR: TSPrescale Position */ +#define ITM_TCR_TSPrescale_Msk (3UL << ITM_TCR_TSPrescale_Pos) /*!< ITM TCR: TSPrescale Mask */ + +#define ITM_TCR_SWOENA_Pos 4U /*!< ITM TCR: SWOENA Position */ +#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ + +#define ITM_TCR_DWTENA_Pos 3U /*!< ITM TCR: DWTENA Position */ +#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ + +#define ITM_TCR_SYNCENA_Pos 2U /*!< ITM TCR: SYNCENA Position */ +#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ + +#define ITM_TCR_TSENA_Pos 1U /*!< ITM TCR: TSENA Position */ +#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ + +#define ITM_TCR_ITMENA_Pos 0U /*!< ITM TCR: ITM Enable bit Position */ +#define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */ + +/* ITM Integration Write Register Definitions */ +#define ITM_IWR_ATVALIDM_Pos 0U /*!< ITM IWR: ATVALIDM Position */ +#define ITM_IWR_ATVALIDM_Msk (1UL /*<< ITM_IWR_ATVALIDM_Pos*/) /*!< ITM IWR: ATVALIDM Mask */ + +/* ITM Integration Read Register Definitions */ +#define ITM_IRR_ATREADYM_Pos 0U /*!< ITM IRR: ATREADYM Position */ +#define ITM_IRR_ATREADYM_Msk (1UL /*<< ITM_IRR_ATREADYM_Pos*/) /*!< ITM IRR: ATREADYM Mask */ + +/* ITM Integration Mode Control Register Definitions */ +#define ITM_IMCR_INTEGRATION_Pos 0U /*!< ITM IMCR: INTEGRATION Position */ +#define ITM_IMCR_INTEGRATION_Msk (1UL /*<< ITM_IMCR_INTEGRATION_Pos*/) /*!< ITM IMCR: INTEGRATION Mask */ + +/* ITM Lock Status Register Definitions */ +#define ITM_LSR_ByteAcc_Pos 2U /*!< ITM LSR: ByteAcc Position */ +#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ + +#define ITM_LSR_Access_Pos 1U /*!< ITM LSR: Access Position */ +#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ + +#define ITM_LSR_Present_Pos 0U /*!< ITM LSR: Present Position */ +#define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */ + +/*@}*/ /* end of group CMSIS_ITM */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** + \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + __IOM uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ + __IOM uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ + __IOM uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ + __IOM uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ + __IOM uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ + __IOM uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ + __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + __IOM uint32_t MASK0; /*!< Offset: 0x024 (R/W) Mask Register 0 */ + __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED0[1U]; + __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + __IOM uint32_t MASK1; /*!< Offset: 0x034 (R/W) Mask Register 1 */ + __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED1[1U]; + __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + __IOM uint32_t MASK2; /*!< Offset: 0x044 (R/W) Mask Register 2 */ + __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + __IOM uint32_t MASK3; /*!< Offset: 0x054 (R/W) Mask Register 3 */ + __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +#define DWT_CTRL_CYCEVTENA_Pos 22U /*!< DWT CTRL: CYCEVTENA Position */ +#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ + +#define DWT_CTRL_FOLDEVTENA_Pos 21U /*!< DWT CTRL: FOLDEVTENA Position */ +#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ + +#define DWT_CTRL_LSUEVTENA_Pos 20U /*!< DWT CTRL: LSUEVTENA Position */ +#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ + +#define DWT_CTRL_SLEEPEVTENA_Pos 19U /*!< DWT CTRL: SLEEPEVTENA Position */ +#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ + +#define DWT_CTRL_EXCEVTENA_Pos 18U /*!< DWT CTRL: EXCEVTENA Position */ +#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ + +#define DWT_CTRL_CPIEVTENA_Pos 17U /*!< DWT CTRL: CPIEVTENA Position */ +#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ + +#define DWT_CTRL_EXCTRCENA_Pos 16U /*!< DWT CTRL: EXCTRCENA Position */ +#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ + +#define DWT_CTRL_PCSAMPLENA_Pos 12U /*!< DWT CTRL: PCSAMPLENA Position */ +#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ + +#define DWT_CTRL_SYNCTAP_Pos 10U /*!< DWT CTRL: SYNCTAP Position */ +#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ + +#define DWT_CTRL_CYCTAP_Pos 9U /*!< DWT CTRL: CYCTAP Position */ +#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ + +#define DWT_CTRL_POSTINIT_Pos 5U /*!< DWT CTRL: POSTINIT Position */ +#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ + +#define DWT_CTRL_POSTPRESET_Pos 1U /*!< DWT CTRL: POSTPRESET Position */ +#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ + +#define DWT_CTRL_CYCCNTENA_Pos 0U /*!< DWT CTRL: CYCCNTENA Position */ +#define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */ + +/* DWT CPI Count Register Definitions */ +#define DWT_CPICNT_CPICNT_Pos 0U /*!< DWT CPICNT: CPICNT Position */ +#define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */ + +/* DWT Exception Overhead Count Register Definitions */ +#define DWT_EXCCNT_EXCCNT_Pos 0U /*!< DWT EXCCNT: EXCCNT Position */ +#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */ + +/* DWT Sleep Count Register Definitions */ +#define DWT_SLEEPCNT_SLEEPCNT_Pos 0U /*!< DWT SLEEPCNT: SLEEPCNT Position */ +#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ + +/* DWT LSU Count Register Definitions */ +#define DWT_LSUCNT_LSUCNT_Pos 0U /*!< DWT LSUCNT: LSUCNT Position */ +#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */ + +/* DWT Folded-instruction Count Register Definitions */ +#define DWT_FOLDCNT_FOLDCNT_Pos 0U /*!< DWT FOLDCNT: FOLDCNT Position */ +#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */ + +/* DWT Comparator Mask Register Definitions */ +#define DWT_MASK_MASK_Pos 0U /*!< DWT MASK: MASK Position */ +#define DWT_MASK_MASK_Msk (0x1FUL /*<< DWT_MASK_MASK_Pos*/) /*!< DWT MASK: MASK Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVADDR1_Pos 16U /*!< DWT FUNCTION: DATAVADDR1 Position */ +#define DWT_FUNCTION_DATAVADDR1_Msk (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos) /*!< DWT FUNCTION: DATAVADDR1 Mask */ + +#define DWT_FUNCTION_DATAVADDR0_Pos 12U /*!< DWT FUNCTION: DATAVADDR0 Position */ +#define DWT_FUNCTION_DATAVADDR0_Msk (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos) /*!< DWT FUNCTION: DATAVADDR0 Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_LNK1ENA_Pos 9U /*!< DWT FUNCTION: LNK1ENA Position */ +#define DWT_FUNCTION_LNK1ENA_Msk (0x1UL << DWT_FUNCTION_LNK1ENA_Pos) /*!< DWT FUNCTION: LNK1ENA Mask */ + +#define DWT_FUNCTION_DATAVMATCH_Pos 8U /*!< DWT FUNCTION: DATAVMATCH Position */ +#define DWT_FUNCTION_DATAVMATCH_Msk (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos) /*!< DWT FUNCTION: DATAVMATCH Mask */ + +#define DWT_FUNCTION_CYCMATCH_Pos 7U /*!< DWT FUNCTION: CYCMATCH Position */ +#define DWT_FUNCTION_CYCMATCH_Msk (0x1UL << DWT_FUNCTION_CYCMATCH_Pos) /*!< DWT FUNCTION: CYCMATCH Mask */ + +#define DWT_FUNCTION_EMITRANGE_Pos 5U /*!< DWT FUNCTION: EMITRANGE Position */ +#define DWT_FUNCTION_EMITRANGE_Msk (0x1UL << DWT_FUNCTION_EMITRANGE_Pos) /*!< DWT FUNCTION: EMITRANGE Mask */ + +#define DWT_FUNCTION_FUNCTION_Pos 0U /*!< DWT FUNCTION: FUNCTION Position */ +#define DWT_FUNCTION_FUNCTION_Msk (0xFUL /*<< DWT_FUNCTION_FUNCTION_Pos*/) /*!< DWT FUNCTION: FUNCTION Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** + \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IOM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55U]; + __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131U]; + __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __IM uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ + uint32_t RESERVED3[759U]; + __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER */ + __IM uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ + __IM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ + uint32_t RESERVED4[1U]; + __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */ + __IM uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */ + __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ + uint32_t RESERVED5[39U]; + __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ + __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ + uint32_t RESERVED7[8U]; + __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_PRESCALER_Pos 0U /*!< TPI ACPR: PRESCALER Position */ +#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< TPI ACPR: PRESCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI TRIGGER Register Definitions */ +#define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */ +#define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */ + +/* TPI Integration ETM Data Register Definitions (FIFO0) */ +#define TPI_FIFO0_ITM_ATVALID_Pos 29U /*!< TPI FIFO0: ITM_ATVALID Position */ +#define TPI_FIFO0_ITM_ATVALID_Msk (0x3UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ + +#define TPI_FIFO0_ITM_bytecount_Pos 27U /*!< TPI FIFO0: ITM_bytecount Position */ +#define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */ + +#define TPI_FIFO0_ETM_ATVALID_Pos 26U /*!< TPI FIFO0: ETM_ATVALID Position */ +#define TPI_FIFO0_ETM_ATVALID_Msk (0x3UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ + +#define TPI_FIFO0_ETM_bytecount_Pos 24U /*!< TPI FIFO0: ETM_bytecount Position */ +#define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */ + +#define TPI_FIFO0_ETM2_Pos 16U /*!< TPI FIFO0: ETM2 Position */ +#define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */ + +#define TPI_FIFO0_ETM1_Pos 8U /*!< TPI FIFO0: ETM1 Position */ +#define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */ + +#define TPI_FIFO0_ETM0_Pos 0U /*!< TPI FIFO0: ETM0 Position */ +#define TPI_FIFO0_ETM0_Msk (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/) /*!< TPI FIFO0: ETM0 Mask */ + +/* TPI ITATBCTR2 Register Definitions */ +#define TPI_ITATBCTR2_ATREADY_Pos 0U /*!< TPI ITATBCTR2: ATREADY Position */ +#define TPI_ITATBCTR2_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY_Pos*/) /*!< TPI ITATBCTR2: ATREADY Mask */ + +/* TPI Integration ITM Data Register Definitions (FIFO1) */ +#define TPI_FIFO1_ITM_ATVALID_Pos 29U /*!< TPI FIFO1: ITM_ATVALID Position */ +#define TPI_FIFO1_ITM_ATVALID_Msk (0x3UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ + +#define TPI_FIFO1_ITM_bytecount_Pos 27U /*!< TPI FIFO1: ITM_bytecount Position */ +#define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */ + +#define TPI_FIFO1_ETM_ATVALID_Pos 26U /*!< TPI FIFO1: ETM_ATVALID Position */ +#define TPI_FIFO1_ETM_ATVALID_Msk (0x3UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ + +#define TPI_FIFO1_ETM_bytecount_Pos 24U /*!< TPI FIFO1: ETM_bytecount Position */ +#define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */ + +#define TPI_FIFO1_ITM2_Pos 16U /*!< TPI FIFO1: ITM2 Position */ +#define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */ + +#define TPI_FIFO1_ITM1_Pos 8U /*!< TPI FIFO1: ITM1 Position */ +#define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */ + +#define TPI_FIFO1_ITM0_Pos 0U /*!< TPI FIFO1: ITM0 Position */ +#define TPI_FIFO1_ITM0_Msk (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/) /*!< TPI FIFO1: ITM0 Mask */ + +/* TPI ITATBCTR0 Register Definitions */ +#define TPI_ITATBCTR0_ATREADY_Pos 0U /*!< TPI ITATBCTR0: ATREADY Position */ +#define TPI_ITATBCTR0_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY_Pos*/) /*!< TPI ITATBCTR0: ATREADY Mask */ + +/* TPI Integration Mode Control Register Definitions */ +#define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ +#define TPI_ITCTRL_Mode_Msk (0x1UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_MinBufSz_Pos 6U /*!< TPI DEVID: MinBufSz Position */ +#define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */ + +#define TPI_DEVID_AsynClkIn_Pos 5U /*!< TPI DEVID: AsynClkIn Position */ +#define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */ + +#define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */ +#define TPI_DEVID_NrTraceInput_Msk (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_MajorType_Pos 4U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +#define TPI_DEVTYPE_SubType_Pos 0U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ + __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Alias 1 Region Base Address Register */ + __IOM uint32_t RASR_A1; /*!< Offset: 0x018 (R/W) MPU Alias 1 Region Attribute and Size Register */ + __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Alias 2 Region Base Address Register */ + __IOM uint32_t RASR_A2; /*!< Offset: 0x020 (R/W) MPU Alias 2 Region Attribute and Size Register */ + __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Alias 3 Region Base Address Register */ + __IOM uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */ +} MPU_Type; + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_ADDR_Pos 5U /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */ +#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ + +#define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */ +#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */ + +/* MPU Region Attribute and Size Register Definitions */ +#define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */ +#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ + +#define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */ +#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ + +#define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */ +#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ + +#define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */ +#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ + +#define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */ +#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ + +#define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */ +#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ + +#define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */ +#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ + +#define MPU_RASR_SRD_Pos 8U /*!< MPU RASR: Sub-Region Disable Position */ +#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ + +#define MPU_RASR_SIZE_Pos 1U /*!< MPU RASR: Region Size Field Position */ +#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ + +#define MPU_RASR_ENABLE_Pos 0U /*!< MPU RASR: Region enable bit Position */ +#define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** + \brief Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register Definitions */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< 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 25U /*!< 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 24U /*!< 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 19U /*!< 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 18U /*!< 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 17U /*!< 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 16U /*!< 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 5U /*!< 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 3U /*!< 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 2U /*!< 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 1U /*!< 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 0U /*!< 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 Definitions */ +#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register Definitions */ +#define CoreDebug_DEMCR_TRCENA_Pos 24U /*!< CoreDebug DEMCR: TRCENA Position */ +#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ + +#define CoreDebug_DEMCR_MON_REQ_Pos 19U /*!< 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 18U /*!< 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 17U /*!< 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 16U /*!< 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 10U /*!< 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 9U /*!< 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 8U /*!< 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 7U /*!< 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 6U /*!< 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 5U /*!< 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 4U /*!< 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 0U /*!< CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ +#define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ +#define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ +#define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ +#define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ +#define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ +#define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ +#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ +#endif + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Debug Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping + #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ + #define NVIC_GetActive __NVIC_GetActive + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + + +/** + \brief Set Priority Grouping + \details 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)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << 8U) ); /* Insert write key and priorty group */ + SCB->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping + \details Reads the priority grouping field from the NVIC Interrupt Controller. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t __NVIC_GetPriorityGrouping(void) +{ + return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt + \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IABR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IP[((uint32_t)(int32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB->SHP[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC->IP[((uint32_t)(int32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB->SHP[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +/*@} end of CMSIS_Core_NVICFunctions */ + + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + return 0U; /* No FPU */ +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + +/* ##################################### Debug In/Output function ########################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_core_DebugFunctions ITM Functions + \brief Functions that access the ITM debug interface. + @{ + */ + +extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ +#define ITM_RXBUFFER_EMPTY ((int32_t)0x5AA55AA5U) /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ + + +/** + \brief ITM Send Character + \details Transmits a character via the ITM channel 0, and + \li Just returns when no debugger is connected that has booked the output. + \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. + \param [in] ch Character to transmit. + \returns Character to transmit. + */ +__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) +{ + if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ + ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */ + { + while (ITM->PORT[0U].u32 == 0UL) + { + __NOP(); + } + ITM->PORT[0U].u8 = (uint8_t)ch; + } + return (ch); +} + + +/** + \brief ITM Receive Character + \details Inputs a character via the external variable \ref ITM_RxBuffer. + \return Received character. + \return -1 No character pending. + */ +__STATIC_INLINE int32_t ITM_ReceiveChar (void) +{ + int32_t ch = -1; /* no character available */ + + if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) + { + ch = ITM_RxBuffer; + ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ + } + + return (ch); +} + + +/** + \brief ITM Check Character + \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. + \return 0 No character available. + \return 1 Character available. + */ +__STATIC_INLINE int32_t ITM_CheckChar (void) +{ + + if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) + { + return (0); /* no character available */ + } + else + { + return (1); /* character available */ + } +} + +/*@} end of CMSIS_core_DebugFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM3_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/cmsis/core_cm33.h b/cmsis/core_cm33.h new file mode 100644 index 00000000000..9e880ae7dc9 --- /dev/null +++ b/cmsis/core_cm33.h @@ -0,0 +1,2896 @@ +/**************************************************************************//** + * @file core_cm33.h + * @brief CMSIS Cortex-M33 Core Peripheral Access Layer Header File + * @version V5.0.2 + * @date 13. February 2017 + ******************************************************************************/ +/* + * Copyright (c) 2009-2017 ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_CM33_H_GENERIC +#define __CORE_CM33_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex_M33 + @{ + */ + +/* CMSIS CM33 definitions */ +#define __CM33_CMSIS_VERSION_MAIN ( 5U) /*!< [31:16] CMSIS HAL main version */ +#define __CM33_CMSIS_VERSION_SUB ( 0U) /*!< [15:0] CMSIS HAL sub version */ +#define __CM33_CMSIS_VERSION ((__CM33_CMSIS_VERSION_MAIN << 16U) | \ + __CM33_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */ + +#define __CORTEX_M (33U) /*!< Cortex-M Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + For this, __FPU_PRESENT has to be checked prior to making use of FPU specific registers and functions. +*/ +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_PCS_VFP + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM33_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM33_H_DEPENDANT +#define __CORE_CM33_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM33_REV + #define __CM33_REV 0x0000U + #warning "__CM33_REV not defined in device header file; using default!" + #endif + + #ifndef __FPU_PRESENT + #define __FPU_PRESENT 0U + #warning "__FPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __SAUREGION_PRESENT + #define __SAUREGION_PRESENT 0U + #warning "__SAUREGION_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __DSP_PRESENT + #define __DSP_PRESENT 0U + #warning "__DSP_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 3U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group Cortex_M33 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + - Core SAU Register + - Core FPU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + 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 */ + 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; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + +#define APSR_Q_Pos 27U /*!< APSR: Q Position */ +#define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */ + +#define APSR_GE_Pos 16U /*!< APSR: GE Position */ +#define APSR_GE_Msk (0xFUL << APSR_GE_Pos) /*!< APSR: GE Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0: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 */ + 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; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_Q_Pos 27U /*!< xPSR: Q Position */ +#define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */ + +#define xPSR_IT_Pos 25U /*!< xPSR: IT Position */ +#define xPSR_IT_Msk (3UL << xPSR_IT_Pos) /*!< xPSR: IT Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_GE_Pos 16U /*!< xPSR: GE Position */ +#define xPSR_GE_Msk (0xFUL << xPSR_GE_Pos) /*!< xPSR: GE Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack-pointer select */ + uint32_t FPCA:1; /*!< bit: 2 Floating-point context active */ + uint32_t SFPA:1; /*!< bit: 3 Secure floating-point active */ + uint32_t _reserved1:28; /*!< bit: 4..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SFPA_Pos 3U /*!< CONTROL: SFPA Position */ +#define CONTROL_SFPA_Msk (1UL << CONTROL_SFPA_Pos) /*!< CONTROL: SFPA Mask */ + +#define CONTROL_FPCA_Pos 2U /*!< CONTROL: FPCA Position */ +#define CONTROL_FPCA_Msk (1UL << CONTROL_FPCA_Pos) /*!< CONTROL: FPCA Mask */ + +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[16U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[16U]; + __IOM uint32_t ICER[16U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[16U]; + __IOM uint32_t ISPR[16U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[16U]; + __IOM uint32_t ICPR[16U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[16U]; + __IOM uint32_t IABR[16U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[16U]; + __IOM uint32_t ITNS[16U]; /*!< Offset: 0x280 (R/W) Interrupt Non-Secure State Register */ + uint32_t RESERVED5[16U]; + __IOM uint8_t IPR[496U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED6[580U]; + __OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; + +/* Software Triggered Interrupt Register Definitions */ +#define NVIC_STIR_INTID_Pos 0U /*!< STIR: INTLINESNUM Position */ +#define NVIC_STIR_INTID_Msk (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/) /*!< STIR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + __IOM uint8_t SHPR[12U]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IOM uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IOM uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IOM uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IOM uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IOM uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IOM uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __IM uint32_t ID_PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __IM uint32_t ID_DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __IM uint32_t ID_ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __IM uint32_t ID_MMFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __IM uint32_t ID_ISAR[6U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + __IM uint32_t CLIDR; /*!< Offset: 0x078 (R/ ) Cache Level ID register */ + __IM uint32_t CTR; /*!< Offset: 0x07C (R/ ) Cache Type register */ + __IM uint32_t CCSIDR; /*!< Offset: 0x080 (R/ ) Cache Size ID Register */ + __IOM uint32_t CSSELR; /*!< Offset: 0x084 (R/W) Cache Size Selection Register */ + __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ + __IOM uint32_t NSACR; /*!< Offset: 0x08C (R/W) Non-Secure Access Control Register */ + uint32_t RESERVED3[92U]; + __OM uint32_t STIR; /*!< Offset: 0x200 ( /W) Software Triggered Interrupt Register */ + uint32_t RESERVED4[15U]; + __IM uint32_t MVFR0; /*!< Offset: 0x240 (R/ ) Media and VFP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x244 (R/ ) Media and VFP Feature Register 1 */ + __IM uint32_t MVFR2; /*!< Offset: 0x248 (R/ ) Media and VFP Feature Register 1 */ + uint32_t RESERVED5[1U]; + __OM uint32_t ICIALLU; /*!< Offset: 0x250 ( /W) I-Cache Invalidate All to PoU */ + uint32_t RESERVED6[1U]; + __OM uint32_t ICIMVAU; /*!< Offset: 0x258 ( /W) I-Cache Invalidate by MVA to PoU */ + __OM uint32_t DCIMVAC; /*!< Offset: 0x25C ( /W) D-Cache Invalidate by MVA to PoC */ + __OM uint32_t DCISW; /*!< Offset: 0x260 ( /W) D-Cache Invalidate by Set-way */ + __OM uint32_t DCCMVAU; /*!< Offset: 0x264 ( /W) D-Cache Clean by MVA to PoU */ + __OM uint32_t DCCMVAC; /*!< Offset: 0x268 ( /W) D-Cache Clean by MVA to PoC */ + __OM uint32_t DCCSW; /*!< Offset: 0x26C ( /W) D-Cache Clean by Set-way */ + __OM uint32_t DCCIMVAC; /*!< Offset: 0x270 ( /W) D-Cache Clean and Invalidate by MVA to PoC */ + __OM uint32_t DCCISW; /*!< Offset: 0x274 ( /W) D-Cache Clean and Invalidate by Set-way */ + uint32_t RESERVED7[6U]; + __IOM uint32_t ITCMCR; /*!< Offset: 0x290 (R/W) Instruction Tightly-Coupled Memory Control Register */ + __IOM uint32_t DTCMCR; /*!< Offset: 0x294 (R/W) Data Tightly-Coupled Memory Control Registers */ + __IOM uint32_t AHBPCR; /*!< Offset: 0x298 (R/W) AHBP Control Register */ + __IOM uint32_t CACR; /*!< Offset: 0x29C (R/W) L1 Cache Control Register */ + __IOM uint32_t AHBSCR; /*!< Offset: 0x2A0 (R/W) AHB Slave Control Register */ + uint32_t RESERVED8[1U]; + __IOM uint32_t ABFSR; /*!< Offset: 0x2A8 (R/W) Auxiliary Bus Fault Status Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_PENDNMISET_Pos 31U /*!< SCB ICSR: PENDNMISET Position */ +#define SCB_ICSR_PENDNMISET_Msk (1UL << SCB_ICSR_PENDNMISET_Pos) /*!< SCB ICSR: PENDNMISET Mask */ + +#define SCB_ICSR_PENDNMICLR_Pos 30U /*!< SCB ICSR: PENDNMICLR Position */ +#define SCB_ICSR_PENDNMICLR_Msk (1UL << SCB_ICSR_PENDNMICLR_Pos) /*!< SCB ICSR: PENDNMICLR Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_STTNS_Pos 24U /*!< SCB ICSR: STTNS Position (Security Extension) */ +#define SCB_ICSR_STTNS_Msk (1UL << SCB_ICSR_STTNS_Pos) /*!< SCB ICSR: STTNS Mask (Security Extension) */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Vector Table Offset Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 7U /*!< 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 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIS_Pos 14U /*!< SCB AIRCR: PRIS Position */ +#define SCB_AIRCR_PRIS_Msk (1UL << SCB_AIRCR_PRIS_Pos) /*!< SCB AIRCR: PRIS Mask */ + +#define SCB_AIRCR_BFHFNMINS_Pos 13U /*!< SCB AIRCR: BFHFNMINS Position */ +#define SCB_AIRCR_BFHFNMINS_Msk (1UL << SCB_AIRCR_BFHFNMINS_Pos) /*!< SCB AIRCR: BFHFNMINS Mask */ + +#define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */ +#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ + +#define SCB_AIRCR_SYSRESETREQS_Pos 3U /*!< SCB AIRCR: SYSRESETREQS Position */ +#define SCB_AIRCR_SYSRESETREQS_Msk (1UL << SCB_AIRCR_SYSRESETREQS_Pos) /*!< SCB AIRCR: SYSRESETREQS Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEPS_Pos 3U /*!< SCB SCR: SLEEPDEEPS Position */ +#define SCB_SCR_SLEEPDEEPS_Msk (1UL << SCB_SCR_SLEEPDEEPS_Pos) /*!< SCB SCR: SLEEPDEEPS Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_BP_Pos 18U /*!< SCB CCR: BP Position */ +#define SCB_CCR_BP_Msk (1UL << SCB_CCR_BP_Pos) /*!< SCB CCR: BP Mask */ + +#define SCB_CCR_IC_Pos 17U /*!< SCB CCR: IC Position */ +#define SCB_CCR_IC_Msk (1UL << SCB_CCR_IC_Pos) /*!< SCB CCR: IC Mask */ + +#define SCB_CCR_DC_Pos 16U /*!< SCB CCR: DC Position */ +#define SCB_CCR_DC_Msk (1UL << SCB_CCR_DC_Pos) /*!< SCB CCR: DC Mask */ + +#define SCB_CCR_STKOFHFNMIGN_Pos 10U /*!< SCB CCR: STKOFHFNMIGN Position */ +#define SCB_CCR_STKOFHFNMIGN_Msk (1UL << SCB_CCR_STKOFHFNMIGN_Pos) /*!< SCB CCR: STKOFHFNMIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< 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 4U /*!< 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 3U /*!< 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 1U /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_HARDFAULTPENDED_Pos 21U /*!< SCB SHCSR: HARDFAULTPENDED Position */ +#define SCB_SHCSR_HARDFAULTPENDED_Msk (1UL << SCB_SHCSR_HARDFAULTPENDED_Pos) /*!< SCB SHCSR: HARDFAULTPENDED Mask */ + +#define SCB_SHCSR_SECUREFAULTPENDED_Pos 20U /*!< SCB SHCSR: SECUREFAULTPENDED Position */ +#define SCB_SHCSR_SECUREFAULTPENDED_Msk (1UL << SCB_SHCSR_SECUREFAULTPENDED_Pos) /*!< SCB SHCSR: SECUREFAULTPENDED Mask */ + +#define SCB_SHCSR_SECUREFAULTENA_Pos 19U /*!< SCB SHCSR: SECUREFAULTENA Position */ +#define SCB_SHCSR_SECUREFAULTENA_Msk (1UL << SCB_SHCSR_SECUREFAULTENA_Pos) /*!< SCB SHCSR: SECUREFAULTENA Mask */ + +#define SCB_SHCSR_USGFAULTENA_Pos 18U /*!< SCB SHCSR: USGFAULTENA Position */ +#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ + +#define SCB_SHCSR_BUSFAULTENA_Pos 17U /*!< SCB SHCSR: BUSFAULTENA Position */ +#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ + +#define SCB_SHCSR_MEMFAULTENA_Pos 16U /*!< SCB SHCSR: MEMFAULTENA Position */ +#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_BUSFAULTPENDED_Pos 14U /*!< SCB SHCSR: BUSFAULTPENDED Position */ +#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ + +#define SCB_SHCSR_MEMFAULTPENDED_Pos 13U /*!< SCB SHCSR: MEMFAULTPENDED Position */ +#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ + +#define SCB_SHCSR_USGFAULTPENDED_Pos 12U /*!< SCB SHCSR: USGFAULTPENDED Position */ +#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_MONITORACT_Pos 8U /*!< SCB SHCSR: MONITORACT Position */ +#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_NMIACT_Pos 5U /*!< SCB SHCSR: NMIACT Position */ +#define SCB_SHCSR_NMIACT_Msk (1UL << SCB_SHCSR_NMIACT_Pos) /*!< SCB SHCSR: NMIACT Mask */ + +#define SCB_SHCSR_SECUREFAULTACT_Pos 4U /*!< SCB SHCSR: SECUREFAULTACT Position */ +#define SCB_SHCSR_SECUREFAULTACT_Msk (1UL << SCB_SHCSR_SECUREFAULTACT_Pos) /*!< SCB SHCSR: SECUREFAULTACT Mask */ + +#define SCB_SHCSR_USGFAULTACT_Pos 3U /*!< SCB SHCSR: USGFAULTACT Position */ +#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ + +#define SCB_SHCSR_HARDFAULTACT_Pos 2U /*!< SCB SHCSR: HARDFAULTACT Position */ +#define SCB_SHCSR_HARDFAULTACT_Msk (1UL << SCB_SHCSR_HARDFAULTACT_Pos) /*!< SCB SHCSR: HARDFAULTACT Mask */ + +#define SCB_SHCSR_BUSFAULTACT_Pos 1U /*!< SCB SHCSR: BUSFAULTACT Position */ +#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ + +#define SCB_SHCSR_MEMFAULTACT_Pos 0U /*!< SCB SHCSR: MEMFAULTACT Position */ +#define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */ + +/* SCB Configurable Fault Status Register Definitions */ +#define SCB_CFSR_USGFAULTSR_Pos 16U /*!< 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 8U /*!< 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 0U /*!< 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 */ + +/* MemManage Fault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_MMARVALID_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 7U) /*!< SCB CFSR (MMFSR): MMARVALID Position */ +#define SCB_CFSR_MMARVALID_Msk (1UL << SCB_CFSR_MMARVALID_Pos) /*!< SCB CFSR (MMFSR): MMARVALID Mask */ + +#define SCB_CFSR_MLSPERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 5U) /*!< SCB CFSR (MMFSR): MLSPERR Position */ +#define SCB_CFSR_MLSPERR_Msk (1UL << SCB_CFSR_MLSPERR_Pos) /*!< SCB CFSR (MMFSR): MLSPERR Mask */ + +#define SCB_CFSR_MSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 4U) /*!< SCB CFSR (MMFSR): MSTKERR Position */ +#define SCB_CFSR_MSTKERR_Msk (1UL << SCB_CFSR_MSTKERR_Pos) /*!< SCB CFSR (MMFSR): MSTKERR Mask */ + +#define SCB_CFSR_MUNSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 3U) /*!< SCB CFSR (MMFSR): MUNSTKERR Position */ +#define SCB_CFSR_MUNSTKERR_Msk (1UL << SCB_CFSR_MUNSTKERR_Pos) /*!< SCB CFSR (MMFSR): MUNSTKERR Mask */ + +#define SCB_CFSR_DACCVIOL_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 1U) /*!< SCB CFSR (MMFSR): DACCVIOL Position */ +#define SCB_CFSR_DACCVIOL_Msk (1UL << SCB_CFSR_DACCVIOL_Pos) /*!< SCB CFSR (MMFSR): DACCVIOL Mask */ + +#define SCB_CFSR_IACCVIOL_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 0U) /*!< SCB CFSR (MMFSR): IACCVIOL Position */ +#define SCB_CFSR_IACCVIOL_Msk (1UL /*<< SCB_CFSR_IACCVIOL_Pos*/) /*!< SCB CFSR (MMFSR): IACCVIOL Mask */ + +/* BusFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_BFARVALID_Pos (SCB_CFSR_BUSFAULTSR_Pos + 7U) /*!< SCB CFSR (BFSR): BFARVALID Position */ +#define SCB_CFSR_BFARVALID_Msk (1UL << SCB_CFSR_BFARVALID_Pos) /*!< SCB CFSR (BFSR): BFARVALID Mask */ + +#define SCB_CFSR_LSPERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 5U) /*!< SCB CFSR (BFSR): LSPERR Position */ +#define SCB_CFSR_LSPERR_Msk (1UL << SCB_CFSR_LSPERR_Pos) /*!< SCB CFSR (BFSR): LSPERR Mask */ + +#define SCB_CFSR_STKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 4U) /*!< SCB CFSR (BFSR): STKERR Position */ +#define SCB_CFSR_STKERR_Msk (1UL << SCB_CFSR_STKERR_Pos) /*!< SCB CFSR (BFSR): STKERR Mask */ + +#define SCB_CFSR_UNSTKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 3U) /*!< SCB CFSR (BFSR): UNSTKERR Position */ +#define SCB_CFSR_UNSTKERR_Msk (1UL << SCB_CFSR_UNSTKERR_Pos) /*!< SCB CFSR (BFSR): UNSTKERR Mask */ + +#define SCB_CFSR_IMPRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 2U) /*!< SCB CFSR (BFSR): IMPRECISERR Position */ +#define SCB_CFSR_IMPRECISERR_Msk (1UL << SCB_CFSR_IMPRECISERR_Pos) /*!< SCB CFSR (BFSR): IMPRECISERR Mask */ + +#define SCB_CFSR_PRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 1U) /*!< SCB CFSR (BFSR): PRECISERR Position */ +#define SCB_CFSR_PRECISERR_Msk (1UL << SCB_CFSR_PRECISERR_Pos) /*!< SCB CFSR (BFSR): PRECISERR Mask */ + +#define SCB_CFSR_IBUSERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 0U) /*!< SCB CFSR (BFSR): IBUSERR Position */ +#define SCB_CFSR_IBUSERR_Msk (1UL << SCB_CFSR_IBUSERR_Pos) /*!< SCB CFSR (BFSR): IBUSERR Mask */ + +/* UsageFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_DIVBYZERO_Pos (SCB_CFSR_USGFAULTSR_Pos + 9U) /*!< SCB CFSR (UFSR): DIVBYZERO Position */ +#define SCB_CFSR_DIVBYZERO_Msk (1UL << SCB_CFSR_DIVBYZERO_Pos) /*!< SCB CFSR (UFSR): DIVBYZERO Mask */ + +#define SCB_CFSR_UNALIGNED_Pos (SCB_CFSR_USGFAULTSR_Pos + 8U) /*!< SCB CFSR (UFSR): UNALIGNED Position */ +#define SCB_CFSR_UNALIGNED_Msk (1UL << SCB_CFSR_UNALIGNED_Pos) /*!< SCB CFSR (UFSR): UNALIGNED Mask */ + +#define SCB_CFSR_STKOF_Pos (SCB_CFSR_USGFAULTSR_Pos + 4U) /*!< SCB CFSR (UFSR): STKOF Position */ +#define SCB_CFSR_STKOF_Msk (1UL << SCB_CFSR_STKOF_Pos) /*!< SCB CFSR (UFSR): STKOF Mask */ + +#define SCB_CFSR_NOCP_Pos (SCB_CFSR_USGFAULTSR_Pos + 3U) /*!< SCB CFSR (UFSR): NOCP Position */ +#define SCB_CFSR_NOCP_Msk (1UL << SCB_CFSR_NOCP_Pos) /*!< SCB CFSR (UFSR): NOCP Mask */ + +#define SCB_CFSR_INVPC_Pos (SCB_CFSR_USGFAULTSR_Pos + 2U) /*!< SCB CFSR (UFSR): INVPC Position */ +#define SCB_CFSR_INVPC_Msk (1UL << SCB_CFSR_INVPC_Pos) /*!< SCB CFSR (UFSR): INVPC Mask */ + +#define SCB_CFSR_INVSTATE_Pos (SCB_CFSR_USGFAULTSR_Pos + 1U) /*!< SCB CFSR (UFSR): INVSTATE Position */ +#define SCB_CFSR_INVSTATE_Msk (1UL << SCB_CFSR_INVSTATE_Pos) /*!< SCB CFSR (UFSR): INVSTATE Mask */ + +#define SCB_CFSR_UNDEFINSTR_Pos (SCB_CFSR_USGFAULTSR_Pos + 0U) /*!< SCB CFSR (UFSR): UNDEFINSTR Position */ +#define SCB_CFSR_UNDEFINSTR_Msk (1UL << SCB_CFSR_UNDEFINSTR_Pos) /*!< SCB CFSR (UFSR): UNDEFINSTR Mask */ + +/* SCB Hard Fault Status Register Definitions */ +#define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */ +#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ + +#define SCB_HFSR_FORCED_Pos 30U /*!< SCB HFSR: FORCED Position */ +#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ + +#define SCB_HFSR_VECTTBL_Pos 1U /*!< 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 4U /*!< SCB DFSR: EXTERNAL Position */ +#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ + +#define SCB_DFSR_VCATCH_Pos 3U /*!< SCB DFSR: VCATCH Position */ +#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ + +#define SCB_DFSR_DWTTRAP_Pos 2U /*!< SCB DFSR: DWTTRAP Position */ +#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ + +#define SCB_DFSR_BKPT_Pos 1U /*!< SCB DFSR: BKPT Position */ +#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ + +#define SCB_DFSR_HALTED_Pos 0U /*!< SCB DFSR: HALTED Position */ +#define SCB_DFSR_HALTED_Msk (1UL /*<< SCB_DFSR_HALTED_Pos*/) /*!< SCB DFSR: HALTED Mask */ + +/* SCB Non-Secure Access Control Register Definitions */ +#define SCB_NSACR_CP11_Pos 11U /*!< SCB NSACR: CP11 Position */ +#define SCB_NSACR_CP11_Msk (1UL << SCB_NSACR_CP11_Pos) /*!< SCB NSACR: CP11 Mask */ + +#define SCB_NSACR_CP10_Pos 10U /*!< SCB NSACR: CP10 Position */ +#define SCB_NSACR_CP10_Msk (1UL << SCB_NSACR_CP10_Pos) /*!< SCB NSACR: CP10 Mask */ + +#define SCB_NSACR_CPn_Pos 0U /*!< SCB NSACR: CPn Position */ +#define SCB_NSACR_CPn_Msk (1UL /*<< SCB_NSACR_CPn_Pos*/) /*!< SCB NSACR: CPn Mask */ + +/* SCB Cache Level ID Register Definitions */ +#define SCB_CLIDR_LOUU_Pos 27U /*!< SCB CLIDR: LoUU Position */ +#define SCB_CLIDR_LOUU_Msk (7UL << SCB_CLIDR_LOUU_Pos) /*!< SCB CLIDR: LoUU Mask */ + +#define SCB_CLIDR_LOC_Pos 24U /*!< SCB CLIDR: LoC Position */ +#define SCB_CLIDR_LOC_Msk (7UL << SCB_CLIDR_LOC_Pos) /*!< SCB CLIDR: LoC Mask */ + +/* SCB Cache Type Register Definitions */ +#define SCB_CTR_FORMAT_Pos 29U /*!< SCB CTR: Format Position */ +#define SCB_CTR_FORMAT_Msk (7UL << SCB_CTR_FORMAT_Pos) /*!< SCB CTR: Format Mask */ + +#define SCB_CTR_CWG_Pos 24U /*!< SCB CTR: CWG Position */ +#define SCB_CTR_CWG_Msk (0xFUL << SCB_CTR_CWG_Pos) /*!< SCB CTR: CWG Mask */ + +#define SCB_CTR_ERG_Pos 20U /*!< SCB CTR: ERG Position */ +#define SCB_CTR_ERG_Msk (0xFUL << SCB_CTR_ERG_Pos) /*!< SCB CTR: ERG Mask */ + +#define SCB_CTR_DMINLINE_Pos 16U /*!< SCB CTR: DminLine Position */ +#define SCB_CTR_DMINLINE_Msk (0xFUL << SCB_CTR_DMINLINE_Pos) /*!< SCB CTR: DminLine Mask */ + +#define SCB_CTR_IMINLINE_Pos 0U /*!< SCB CTR: ImInLine Position */ +#define SCB_CTR_IMINLINE_Msk (0xFUL /*<< SCB_CTR_IMINLINE_Pos*/) /*!< SCB CTR: ImInLine Mask */ + +/* SCB Cache Size ID Register Definitions */ +#define SCB_CCSIDR_WT_Pos 31U /*!< SCB CCSIDR: WT Position */ +#define SCB_CCSIDR_WT_Msk (1UL << SCB_CCSIDR_WT_Pos) /*!< SCB CCSIDR: WT Mask */ + +#define SCB_CCSIDR_WB_Pos 30U /*!< SCB CCSIDR: WB Position */ +#define SCB_CCSIDR_WB_Msk (1UL << SCB_CCSIDR_WB_Pos) /*!< SCB CCSIDR: WB Mask */ + +#define SCB_CCSIDR_RA_Pos 29U /*!< SCB CCSIDR: RA Position */ +#define SCB_CCSIDR_RA_Msk (1UL << SCB_CCSIDR_RA_Pos) /*!< SCB CCSIDR: RA Mask */ + +#define SCB_CCSIDR_WA_Pos 28U /*!< SCB CCSIDR: WA Position */ +#define SCB_CCSIDR_WA_Msk (1UL << SCB_CCSIDR_WA_Pos) /*!< SCB CCSIDR: WA Mask */ + +#define SCB_CCSIDR_NUMSETS_Pos 13U /*!< SCB CCSIDR: NumSets Position */ +#define SCB_CCSIDR_NUMSETS_Msk (0x7FFFUL << SCB_CCSIDR_NUMSETS_Pos) /*!< SCB CCSIDR: NumSets Mask */ + +#define SCB_CCSIDR_ASSOCIATIVITY_Pos 3U /*!< SCB CCSIDR: Associativity Position */ +#define SCB_CCSIDR_ASSOCIATIVITY_Msk (0x3FFUL << SCB_CCSIDR_ASSOCIATIVITY_Pos) /*!< SCB CCSIDR: Associativity Mask */ + +#define SCB_CCSIDR_LINESIZE_Pos 0U /*!< SCB CCSIDR: LineSize Position */ +#define SCB_CCSIDR_LINESIZE_Msk (7UL /*<< SCB_CCSIDR_LINESIZE_Pos*/) /*!< SCB CCSIDR: LineSize Mask */ + +/* SCB Cache Size Selection Register Definitions */ +#define SCB_CSSELR_LEVEL_Pos 1U /*!< SCB CSSELR: Level Position */ +#define SCB_CSSELR_LEVEL_Msk (7UL << SCB_CSSELR_LEVEL_Pos) /*!< SCB CSSELR: Level Mask */ + +#define SCB_CSSELR_IND_Pos 0U /*!< SCB CSSELR: InD Position */ +#define SCB_CSSELR_IND_Msk (1UL /*<< SCB_CSSELR_IND_Pos*/) /*!< SCB CSSELR: InD Mask */ + +/* SCB Software Triggered Interrupt Register Definitions */ +#define SCB_STIR_INTID_Pos 0U /*!< SCB STIR: INTID Position */ +#define SCB_STIR_INTID_Msk (0x1FFUL /*<< SCB_STIR_INTID_Pos*/) /*!< SCB STIR: INTID Mask */ + +/* SCB D-Cache Invalidate by Set-way Register Definitions */ +#define SCB_DCISW_WAY_Pos 30U /*!< SCB DCISW: Way Position */ +#define SCB_DCISW_WAY_Msk (3UL << SCB_DCISW_WAY_Pos) /*!< SCB DCISW: Way Mask */ + +#define SCB_DCISW_SET_Pos 5U /*!< SCB DCISW: Set Position */ +#define SCB_DCISW_SET_Msk (0x1FFUL << SCB_DCISW_SET_Pos) /*!< SCB DCISW: Set Mask */ + +/* SCB D-Cache Clean by Set-way Register Definitions */ +#define SCB_DCCSW_WAY_Pos 30U /*!< SCB DCCSW: Way Position */ +#define SCB_DCCSW_WAY_Msk (3UL << SCB_DCCSW_WAY_Pos) /*!< SCB DCCSW: Way Mask */ + +#define SCB_DCCSW_SET_Pos 5U /*!< SCB DCCSW: Set Position */ +#define SCB_DCCSW_SET_Msk (0x1FFUL << SCB_DCCSW_SET_Pos) /*!< SCB DCCSW: Set Mask */ + +/* SCB D-Cache Clean and Invalidate by Set-way Register Definitions */ +#define SCB_DCCISW_WAY_Pos 30U /*!< SCB DCCISW: Way Position */ +#define SCB_DCCISW_WAY_Msk (3UL << SCB_DCCISW_WAY_Pos) /*!< SCB DCCISW: Way Mask */ + +#define SCB_DCCISW_SET_Pos 5U /*!< SCB DCCISW: Set Position */ +#define SCB_DCCISW_SET_Msk (0x1FFUL << SCB_DCCISW_SET_Pos) /*!< SCB DCCISW: Set Mask */ + +/* Instruction Tightly-Coupled Memory Control Register Definitions */ +#define SCB_ITCMCR_SZ_Pos 3U /*!< SCB ITCMCR: SZ Position */ +#define SCB_ITCMCR_SZ_Msk (0xFUL << SCB_ITCMCR_SZ_Pos) /*!< SCB ITCMCR: SZ Mask */ + +#define SCB_ITCMCR_RETEN_Pos 2U /*!< SCB ITCMCR: RETEN Position */ +#define SCB_ITCMCR_RETEN_Msk (1UL << SCB_ITCMCR_RETEN_Pos) /*!< SCB ITCMCR: RETEN Mask */ + +#define SCB_ITCMCR_RMW_Pos 1U /*!< SCB ITCMCR: RMW Position */ +#define SCB_ITCMCR_RMW_Msk (1UL << SCB_ITCMCR_RMW_Pos) /*!< SCB ITCMCR: RMW Mask */ + +#define SCB_ITCMCR_EN_Pos 0U /*!< SCB ITCMCR: EN Position */ +#define SCB_ITCMCR_EN_Msk (1UL /*<< SCB_ITCMCR_EN_Pos*/) /*!< SCB ITCMCR: EN Mask */ + +/* Data Tightly-Coupled Memory Control Register Definitions */ +#define SCB_DTCMCR_SZ_Pos 3U /*!< SCB DTCMCR: SZ Position */ +#define SCB_DTCMCR_SZ_Msk (0xFUL << SCB_DTCMCR_SZ_Pos) /*!< SCB DTCMCR: SZ Mask */ + +#define SCB_DTCMCR_RETEN_Pos 2U /*!< SCB DTCMCR: RETEN Position */ +#define SCB_DTCMCR_RETEN_Msk (1UL << SCB_DTCMCR_RETEN_Pos) /*!< SCB DTCMCR: RETEN Mask */ + +#define SCB_DTCMCR_RMW_Pos 1U /*!< SCB DTCMCR: RMW Position */ +#define SCB_DTCMCR_RMW_Msk (1UL << SCB_DTCMCR_RMW_Pos) /*!< SCB DTCMCR: RMW Mask */ + +#define SCB_DTCMCR_EN_Pos 0U /*!< SCB DTCMCR: EN Position */ +#define SCB_DTCMCR_EN_Msk (1UL /*<< SCB_DTCMCR_EN_Pos*/) /*!< SCB DTCMCR: EN Mask */ + +/* AHBP Control Register Definitions */ +#define SCB_AHBPCR_SZ_Pos 1U /*!< SCB AHBPCR: SZ Position */ +#define SCB_AHBPCR_SZ_Msk (7UL << SCB_AHBPCR_SZ_Pos) /*!< SCB AHBPCR: SZ Mask */ + +#define SCB_AHBPCR_EN_Pos 0U /*!< SCB AHBPCR: EN Position */ +#define SCB_AHBPCR_EN_Msk (1UL /*<< SCB_AHBPCR_EN_Pos*/) /*!< SCB AHBPCR: EN Mask */ + +/* L1 Cache Control Register Definitions */ +#define SCB_CACR_FORCEWT_Pos 2U /*!< SCB CACR: FORCEWT Position */ +#define SCB_CACR_FORCEWT_Msk (1UL << SCB_CACR_FORCEWT_Pos) /*!< SCB CACR: FORCEWT Mask */ + +#define SCB_CACR_ECCEN_Pos 1U /*!< SCB CACR: ECCEN Position */ +#define SCB_CACR_ECCEN_Msk (1UL << SCB_CACR_ECCEN_Pos) /*!< SCB CACR: ECCEN Mask */ + +#define SCB_CACR_SIWT_Pos 0U /*!< SCB CACR: SIWT Position */ +#define SCB_CACR_SIWT_Msk (1UL /*<< SCB_CACR_SIWT_Pos*/) /*!< SCB CACR: SIWT Mask */ + +/* AHBS Control Register Definitions */ +#define SCB_AHBSCR_INITCOUNT_Pos 11U /*!< SCB AHBSCR: INITCOUNT Position */ +#define SCB_AHBSCR_INITCOUNT_Msk (0x1FUL << SCB_AHBPCR_INITCOUNT_Pos) /*!< SCB AHBSCR: INITCOUNT Mask */ + +#define SCB_AHBSCR_TPRI_Pos 2U /*!< SCB AHBSCR: TPRI Position */ +#define SCB_AHBSCR_TPRI_Msk (0x1FFUL << SCB_AHBPCR_TPRI_Pos) /*!< SCB AHBSCR: TPRI Mask */ + +#define SCB_AHBSCR_CTL_Pos 0U /*!< SCB AHBSCR: CTL Position*/ +#define SCB_AHBSCR_CTL_Msk (3UL /*<< SCB_AHBPCR_CTL_Pos*/) /*!< SCB AHBSCR: CTL Mask */ + +/* Auxiliary Bus Fault Status Register Definitions */ +#define SCB_ABFSR_AXIMTYPE_Pos 8U /*!< SCB ABFSR: AXIMTYPE Position*/ +#define SCB_ABFSR_AXIMTYPE_Msk (3UL << SCB_ABFSR_AXIMTYPE_Pos) /*!< SCB ABFSR: AXIMTYPE Mask */ + +#define SCB_ABFSR_EPPB_Pos 4U /*!< SCB ABFSR: EPPB Position*/ +#define SCB_ABFSR_EPPB_Msk (1UL << SCB_ABFSR_EPPB_Pos) /*!< SCB ABFSR: EPPB Mask */ + +#define SCB_ABFSR_AXIM_Pos 3U /*!< SCB ABFSR: AXIM Position*/ +#define SCB_ABFSR_AXIM_Msk (1UL << SCB_ABFSR_AXIM_Pos) /*!< SCB ABFSR: AXIM Mask */ + +#define SCB_ABFSR_AHBP_Pos 2U /*!< SCB ABFSR: AHBP Position*/ +#define SCB_ABFSR_AHBP_Msk (1UL << SCB_ABFSR_AHBP_Pos) /*!< SCB ABFSR: AHBP Mask */ + +#define SCB_ABFSR_DTCM_Pos 1U /*!< SCB ABFSR: DTCM Position*/ +#define SCB_ABFSR_DTCM_Msk (1UL << SCB_ABFSR_DTCM_Pos) /*!< SCB ABFSR: DTCM Mask */ + +#define SCB_ABFSR_ITCM_Pos 0U /*!< SCB ABFSR: ITCM Position*/ +#define SCB_ABFSR_ITCM_Msk (1UL /*<< SCB_ABFSR_ITCM_Pos*/) /*!< SCB ABFSR: ITCM Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** + \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IM uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ + __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ + __IOM uint32_t CPPWR; /*!< Offset: 0x00C (R/W) Coprocessor Power Control Register */ +} SCnSCB_Type; + +/* Interrupt Controller Type Register Definitions */ +#define SCnSCB_ICTR_INTLINESNUM_Pos 0U /*!< ICTR: INTLINESNUM Position */ +#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/) /*!< ICTR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) + \brief Type definitions for the Instrumentation Trace Macrocell (ITM) + @{ + */ + +/** + \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). + */ +typedef struct +{ + __OM union + { + __OM uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ + __OM uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ + __OM uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ + } PORT [32U]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ + uint32_t RESERVED0[864U]; + __IOM uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ + uint32_t RESERVED1[15U]; + __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ + uint32_t RESERVED2[15U]; + __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ + uint32_t RESERVED3[29U]; + __OM uint32_t IWR; /*!< Offset: 0xEF8 ( /W) ITM Integration Write Register */ + __IM uint32_t IRR; /*!< Offset: 0xEFC (R/ ) ITM Integration Read Register */ + __IOM uint32_t IMCR; /*!< Offset: 0xF00 (R/W) ITM Integration Mode Control Register */ + uint32_t RESERVED4[43U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ + uint32_t RESERVED5[1U]; + __IM uint32_t DEVARCH; /*!< Offset: 0xFBC (R/ ) ITM Device Architecture Register */ + uint32_t RESERVED6[4U]; + __IM uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ + __IM uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ + __IM uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ + __IM uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ + __IM uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ + __IM uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ + __IM uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ + __IM uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ + __IM uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ + __IM uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ + __IM uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ + __IM uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ +} ITM_Type; + +/* ITM Stimulus Port Register Definitions */ +#define ITM_STIM_DISABLED_Pos 1U /*!< ITM STIM: DISABLED Position */ +#define ITM_STIM_DISABLED_Msk (0x1UL << ITM_STIM_DISABLED_Pos) /*!< ITM STIM: DISABLED Mask */ + +#define ITM_STIM_FIFOREADY_Pos 0U /*!< ITM STIM: FIFOREADY Position */ +#define ITM_STIM_FIFOREADY_Msk (0x1UL /*<< ITM_STIM_FIFOREADY_Pos*/) /*!< ITM STIM: FIFOREADY Mask */ + +/* ITM Trace Privilege Register Definitions */ +#define ITM_TPR_PRIVMASK_Pos 0U /*!< 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 23U /*!< ITM TCR: BUSY Position */ +#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ + +#define ITM_TCR_TRACEBUSID_Pos 16U /*!< ITM TCR: ATBID Position */ +#define ITM_TCR_TRACEBUSID_Msk (0x7FUL << ITM_TCR_TRACEBUSID_Pos) /*!< ITM TCR: ATBID Mask */ + +#define ITM_TCR_GTSFREQ_Pos 10U /*!< 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 8U /*!< ITM TCR: TSPRESCALE Position */ +#define ITM_TCR_TSPRESCALE_Msk (3UL << ITM_TCR_TSPRESCALE_Pos) /*!< ITM TCR: TSPRESCALE Mask */ + +#define ITM_TCR_STALLENA_Pos 5U /*!< ITM TCR: STALLENA Position */ +#define ITM_TCR_STALLENA_Msk (1UL << ITM_TCR_STALLENA_Pos) /*!< ITM TCR: STALLENA Mask */ + +#define ITM_TCR_SWOENA_Pos 4U /*!< ITM TCR: SWOENA Position */ +#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ + +#define ITM_TCR_DWTENA_Pos 3U /*!< ITM TCR: DWTENA Position */ +#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ + +#define ITM_TCR_SYNCENA_Pos 2U /*!< ITM TCR: SYNCENA Position */ +#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ + +#define ITM_TCR_TSENA_Pos 1U /*!< ITM TCR: TSENA Position */ +#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ + +#define ITM_TCR_ITMENA_Pos 0U /*!< ITM TCR: ITM Enable bit Position */ +#define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */ + +/* ITM Integration Write Register Definitions */ +#define ITM_IWR_ATVALIDM_Pos 0U /*!< ITM IWR: ATVALIDM Position */ +#define ITM_IWR_ATVALIDM_Msk (1UL /*<< ITM_IWR_ATVALIDM_Pos*/) /*!< ITM IWR: ATVALIDM Mask */ + +/* ITM Integration Read Register Definitions */ +#define ITM_IRR_ATREADYM_Pos 0U /*!< ITM IRR: ATREADYM Position */ +#define ITM_IRR_ATREADYM_Msk (1UL /*<< ITM_IRR_ATREADYM_Pos*/) /*!< ITM IRR: ATREADYM Mask */ + +/* ITM Integration Mode Control Register Definitions */ +#define ITM_IMCR_INTEGRATION_Pos 0U /*!< ITM IMCR: INTEGRATION Position */ +#define ITM_IMCR_INTEGRATION_Msk (1UL /*<< ITM_IMCR_INTEGRATION_Pos*/) /*!< ITM IMCR: INTEGRATION Mask */ + +/* ITM Lock Status Register Definitions */ +#define ITM_LSR_ByteAcc_Pos 2U /*!< ITM LSR: ByteAcc Position */ +#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ + +#define ITM_LSR_Access_Pos 1U /*!< ITM LSR: Access Position */ +#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ + +#define ITM_LSR_Present_Pos 0U /*!< ITM LSR: Present Position */ +#define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */ + +/*@}*/ /* end of group CMSIS_ITM */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** + \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + __IOM uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ + __IOM uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ + __IOM uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ + __IOM uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ + __IOM uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ + __IOM uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ + __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + uint32_t RESERVED1[1U]; + __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + uint32_t RESERVED3[1U]; + __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED4[1U]; + __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + uint32_t RESERVED5[1U]; + __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED6[1U]; + __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + uint32_t RESERVED7[1U]; + __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ + uint32_t RESERVED8[1U]; + __IOM uint32_t COMP4; /*!< Offset: 0x060 (R/W) Comparator Register 4 */ + uint32_t RESERVED9[1U]; + __IOM uint32_t FUNCTION4; /*!< Offset: 0x068 (R/W) Function Register 4 */ + uint32_t RESERVED10[1U]; + __IOM uint32_t COMP5; /*!< Offset: 0x070 (R/W) Comparator Register 5 */ + uint32_t RESERVED11[1U]; + __IOM uint32_t FUNCTION5; /*!< Offset: 0x078 (R/W) Function Register 5 */ + uint32_t RESERVED12[1U]; + __IOM uint32_t COMP6; /*!< Offset: 0x080 (R/W) Comparator Register 6 */ + uint32_t RESERVED13[1U]; + __IOM uint32_t FUNCTION6; /*!< Offset: 0x088 (R/W) Function Register 6 */ + uint32_t RESERVED14[1U]; + __IOM uint32_t COMP7; /*!< Offset: 0x090 (R/W) Comparator Register 7 */ + uint32_t RESERVED15[1U]; + __IOM uint32_t FUNCTION7; /*!< Offset: 0x098 (R/W) Function Register 7 */ + uint32_t RESERVED16[1U]; + __IOM uint32_t COMP8; /*!< Offset: 0x0A0 (R/W) Comparator Register 8 */ + uint32_t RESERVED17[1U]; + __IOM uint32_t FUNCTION8; /*!< Offset: 0x0A8 (R/W) Function Register 8 */ + uint32_t RESERVED18[1U]; + __IOM uint32_t COMP9; /*!< Offset: 0x0B0 (R/W) Comparator Register 9 */ + uint32_t RESERVED19[1U]; + __IOM uint32_t FUNCTION9; /*!< Offset: 0x0B8 (R/W) Function Register 9 */ + uint32_t RESERVED20[1U]; + __IOM uint32_t COMP10; /*!< Offset: 0x0C0 (R/W) Comparator Register 10 */ + uint32_t RESERVED21[1U]; + __IOM uint32_t FUNCTION10; /*!< Offset: 0x0C8 (R/W) Function Register 10 */ + uint32_t RESERVED22[1U]; + __IOM uint32_t COMP11; /*!< Offset: 0x0D0 (R/W) Comparator Register 11 */ + uint32_t RESERVED23[1U]; + __IOM uint32_t FUNCTION11; /*!< Offset: 0x0D8 (R/W) Function Register 11 */ + uint32_t RESERVED24[1U]; + __IOM uint32_t COMP12; /*!< Offset: 0x0E0 (R/W) Comparator Register 12 */ + uint32_t RESERVED25[1U]; + __IOM uint32_t FUNCTION12; /*!< Offset: 0x0E8 (R/W) Function Register 12 */ + uint32_t RESERVED26[1U]; + __IOM uint32_t COMP13; /*!< Offset: 0x0F0 (R/W) Comparator Register 13 */ + uint32_t RESERVED27[1U]; + __IOM uint32_t FUNCTION13; /*!< Offset: 0x0F8 (R/W) Function Register 13 */ + uint32_t RESERVED28[1U]; + __IOM uint32_t COMP14; /*!< Offset: 0x100 (R/W) Comparator Register 14 */ + uint32_t RESERVED29[1U]; + __IOM uint32_t FUNCTION14; /*!< Offset: 0x108 (R/W) Function Register 14 */ + uint32_t RESERVED30[1U]; + __IOM uint32_t COMP15; /*!< Offset: 0x110 (R/W) Comparator Register 15 */ + uint32_t RESERVED31[1U]; + __IOM uint32_t FUNCTION15; /*!< Offset: 0x118 (R/W) Function Register 15 */ + uint32_t RESERVED32[934U]; + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R ) Lock Status Register */ + uint32_t RESERVED33[1U]; + __IM uint32_t DEVARCH; /*!< Offset: 0xFBC (R/ ) Device Architecture Register */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +#define DWT_CTRL_CYCDISS_Pos 23U /*!< DWT CTRL: CYCDISS Position */ +#define DWT_CTRL_CYCDISS_Msk (0x1UL << DWT_CTRL_CYCDISS_Pos) /*!< DWT CTRL: CYCDISS Mask */ + +#define DWT_CTRL_CYCEVTENA_Pos 22U /*!< DWT CTRL: CYCEVTENA Position */ +#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ + +#define DWT_CTRL_FOLDEVTENA_Pos 21U /*!< DWT CTRL: FOLDEVTENA Position */ +#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ + +#define DWT_CTRL_LSUEVTENA_Pos 20U /*!< DWT CTRL: LSUEVTENA Position */ +#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ + +#define DWT_CTRL_SLEEPEVTENA_Pos 19U /*!< DWT CTRL: SLEEPEVTENA Position */ +#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ + +#define DWT_CTRL_EXCEVTENA_Pos 18U /*!< DWT CTRL: EXCEVTENA Position */ +#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ + +#define DWT_CTRL_CPIEVTENA_Pos 17U /*!< DWT CTRL: CPIEVTENA Position */ +#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ + +#define DWT_CTRL_EXCTRCENA_Pos 16U /*!< DWT CTRL: EXCTRCENA Position */ +#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ + +#define DWT_CTRL_PCSAMPLENA_Pos 12U /*!< DWT CTRL: PCSAMPLENA Position */ +#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ + +#define DWT_CTRL_SYNCTAP_Pos 10U /*!< DWT CTRL: SYNCTAP Position */ +#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ + +#define DWT_CTRL_CYCTAP_Pos 9U /*!< DWT CTRL: CYCTAP Position */ +#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ + +#define DWT_CTRL_POSTINIT_Pos 5U /*!< DWT CTRL: POSTINIT Position */ +#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ + +#define DWT_CTRL_POSTPRESET_Pos 1U /*!< DWT CTRL: POSTPRESET Position */ +#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ + +#define DWT_CTRL_CYCCNTENA_Pos 0U /*!< DWT CTRL: CYCCNTENA Position */ +#define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */ + +/* DWT CPI Count Register Definitions */ +#define DWT_CPICNT_CPICNT_Pos 0U /*!< DWT CPICNT: CPICNT Position */ +#define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */ + +/* DWT Exception Overhead Count Register Definitions */ +#define DWT_EXCCNT_EXCCNT_Pos 0U /*!< DWT EXCCNT: EXCCNT Position */ +#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */ + +/* DWT Sleep Count Register Definitions */ +#define DWT_SLEEPCNT_SLEEPCNT_Pos 0U /*!< DWT SLEEPCNT: SLEEPCNT Position */ +#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ + +/* DWT LSU Count Register Definitions */ +#define DWT_LSUCNT_LSUCNT_Pos 0U /*!< DWT LSUCNT: LSUCNT Position */ +#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */ + +/* DWT Folded-instruction Count Register Definitions */ +#define DWT_FOLDCNT_FOLDCNT_Pos 0U /*!< DWT FOLDCNT: FOLDCNT Position */ +#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_ID_Pos 27U /*!< DWT FUNCTION: ID Position */ +#define DWT_FUNCTION_ID_Msk (0x1FUL << DWT_FUNCTION_ID_Pos) /*!< DWT FUNCTION: ID Mask */ + +#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_ACTION_Pos 4U /*!< DWT FUNCTION: ACTION Position */ +#define DWT_FUNCTION_ACTION_Msk (0x1UL << DWT_FUNCTION_ACTION_Pos) /*!< DWT FUNCTION: ACTION Mask */ + +#define DWT_FUNCTION_MATCH_Pos 0U /*!< DWT FUNCTION: MATCH Position */ +#define DWT_FUNCTION_MATCH_Msk (0xFUL /*<< DWT_FUNCTION_MATCH_Pos*/) /*!< DWT FUNCTION: MATCH Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** + \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IOM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55U]; + __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131U]; + __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __IM uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ + uint32_t RESERVED3[759U]; + __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER */ + __IM uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ + __IM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ + uint32_t RESERVED4[1U]; + __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */ + __IM uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */ + __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ + uint32_t RESERVED5[39U]; + __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ + __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ + uint32_t RESERVED7[8U]; + __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_PRESCALER_Pos 0U /*!< TPI ACPR: PRESCALER Position */ +#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< TPI ACPR: PRESCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI TRIGGER Register Definitions */ +#define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */ +#define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */ + +/* TPI Integration ETM Data Register Definitions (FIFO0) */ +#define TPI_FIFO0_ITM_ATVALID_Pos 29U /*!< TPI FIFO0: ITM_ATVALID Position */ +#define TPI_FIFO0_ITM_ATVALID_Msk (0x3UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ + +#define TPI_FIFO0_ITM_bytecount_Pos 27U /*!< TPI FIFO0: ITM_bytecount Position */ +#define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */ + +#define TPI_FIFO0_ETM_ATVALID_Pos 26U /*!< TPI FIFO0: ETM_ATVALID Position */ +#define TPI_FIFO0_ETM_ATVALID_Msk (0x3UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ + +#define TPI_FIFO0_ETM_bytecount_Pos 24U /*!< TPI FIFO0: ETM_bytecount Position */ +#define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */ + +#define TPI_FIFO0_ETM2_Pos 16U /*!< TPI FIFO0: ETM2 Position */ +#define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */ + +#define TPI_FIFO0_ETM1_Pos 8U /*!< TPI FIFO0: ETM1 Position */ +#define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */ + +#define TPI_FIFO0_ETM0_Pos 0U /*!< TPI FIFO0: ETM0 Position */ +#define TPI_FIFO0_ETM0_Msk (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/) /*!< TPI FIFO0: ETM0 Mask */ + +/* TPI ITATBCTR2 Register Definitions */ +#define TPI_ITATBCTR2_ATREADY_Pos 0U /*!< TPI ITATBCTR2: ATREADY Position */ +#define TPI_ITATBCTR2_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY_Pos*/) /*!< TPI ITATBCTR2: ATREADY Mask */ + +/* TPI Integration ITM Data Register Definitions (FIFO1) */ +#define TPI_FIFO1_ITM_ATVALID_Pos 29U /*!< TPI FIFO1: ITM_ATVALID Position */ +#define TPI_FIFO1_ITM_ATVALID_Msk (0x3UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ + +#define TPI_FIFO1_ITM_bytecount_Pos 27U /*!< TPI FIFO1: ITM_bytecount Position */ +#define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */ + +#define TPI_FIFO1_ETM_ATVALID_Pos 26U /*!< TPI FIFO1: ETM_ATVALID Position */ +#define TPI_FIFO1_ETM_ATVALID_Msk (0x3UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ + +#define TPI_FIFO1_ETM_bytecount_Pos 24U /*!< TPI FIFO1: ETM_bytecount Position */ +#define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */ + +#define TPI_FIFO1_ITM2_Pos 16U /*!< TPI FIFO1: ITM2 Position */ +#define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */ + +#define TPI_FIFO1_ITM1_Pos 8U /*!< TPI FIFO1: ITM1 Position */ +#define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */ + +#define TPI_FIFO1_ITM0_Pos 0U /*!< TPI FIFO1: ITM0 Position */ +#define TPI_FIFO1_ITM0_Msk (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/) /*!< TPI FIFO1: ITM0 Mask */ + +/* TPI ITATBCTR0 Register Definitions */ +#define TPI_ITATBCTR0_ATREADY_Pos 0U /*!< TPI ITATBCTR0: ATREADY Position */ +#define TPI_ITATBCTR0_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY_Pos*/) /*!< TPI ITATBCTR0: ATREADY Mask */ + +/* TPI Integration Mode Control Register Definitions */ +#define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ +#define TPI_ITCTRL_Mode_Msk (0x1UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_MinBufSz_Pos 6U /*!< TPI DEVID: MinBufSz Position */ +#define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */ + +#define TPI_DEVID_AsynClkIn_Pos 5U /*!< TPI DEVID: AsynClkIn Position */ +#define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */ + +#define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */ +#define TPI_DEVID_NrTraceInput_Msk (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_MajorType_Pos 4U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +#define TPI_DEVTYPE_SubType_Pos 0U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) MPU Region Limit Address Register */ + __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Region Base Address Register Alias 1 */ + __IOM uint32_t RLAR_A1; /*!< Offset: 0x018 (R/W) MPU Region Limit Address Register Alias 1 */ + __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Region Base Address Register Alias 2 */ + __IOM uint32_t RLAR_A2; /*!< Offset: 0x020 (R/W) MPU Region Limit Address Register Alias 2 */ + __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Region Base Address Register Alias 3 */ + __IOM uint32_t RLAR_A3; /*!< Offset: 0x028 (R/W) MPU Region Limit Address Register Alias 3 */ + uint32_t RESERVED0[1]; + __IOM uint32_t MAIR0; /*!< Offset: 0x030 (R/W) MPU Memory Attribute Indirection Register 0 */ + __IOM uint32_t MAIR1; /*!< Offset: 0x034 (R/W) MPU Memory Attribute Indirection Register 1 */ +} MPU_Type; + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_ADDR_Pos 5U /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_SH_Pos 3U /*!< MPU RBAR: SH Position */ +#define MPU_RBAR_SH_Msk (0x3UL << MPU_RBAR_SH_Pos) /*!< MPU RBAR: SH Mask */ + +#define MPU_RBAR_AP_Pos 1U /*!< MPU RBAR: AP Position */ +#define MPU_RBAR_AP_Msk (0x3UL << MPU_RBAR_AP_Pos) /*!< MPU RBAR: AP Mask */ + +#define MPU_RBAR_XN_Pos 0U /*!< MPU RBAR: XN Position */ +#define MPU_RBAR_XN_Msk (01UL /*<< MPU_RBAR_XN_Pos*/) /*!< MPU RBAR: XN Mask */ + +/* MPU Region Limit Address Register Definitions */ +#define MPU_RLAR_LIMIT_Pos 5U /*!< MPU RLAR: LIMIT Position */ +#define MPU_RLAR_LIMIT_Msk (0x7FFFFFFUL << MPU_RLAR_LIMIT_Pos) /*!< MPU RLAR: LIMIT Mask */ + +#define MPU_RLAR_AttrIndx_Pos 1U /*!< MPU RLAR: AttrIndx Position */ +#define MPU_RLAR_AttrIndx_Msk (0x7UL << MPU_RLAR_AttrIndx_Pos) /*!< MPU RLAR: AttrIndx Mask */ + +#define MPU_RLAR_EN_Pos 0U /*!< MPU RLAR: Region enable bit Position */ +#define MPU_RLAR_EN_Msk (1UL /*<< MPU_RLAR_EN_Pos*/) /*!< MPU RLAR: Region enable bit Disable Mask */ + +/* MPU Memory Attribute Indirection Register 0 Definitions */ +#define MPU_MAIR0_Attr3_Pos 24U /*!< MPU MAIR0: Attr3 Position */ +#define MPU_MAIR0_Attr3_Msk (0xFFUL << MPU_MAIR0_Attr3_Pos) /*!< MPU MAIR0: Attr3 Mask */ + +#define MPU_MAIR0_Attr2_Pos 16U /*!< MPU MAIR0: Attr2 Position */ +#define MPU_MAIR0_Attr2_Msk (0xFFUL << MPU_MAIR0_Attr2_Pos) /*!< MPU MAIR0: Attr2 Mask */ + +#define MPU_MAIR0_Attr1_Pos 8U /*!< MPU MAIR0: Attr1 Position */ +#define MPU_MAIR0_Attr1_Msk (0xFFUL << MPU_MAIR0_Attr1_Pos) /*!< MPU MAIR0: Attr1 Mask */ + +#define MPU_MAIR0_Attr0_Pos 0U /*!< MPU MAIR0: Attr0 Position */ +#define MPU_MAIR0_Attr0_Msk (0xFFUL /*<< MPU_MAIR0_Attr0_Pos*/) /*!< MPU MAIR0: Attr0 Mask */ + +/* MPU Memory Attribute Indirection Register 1 Definitions */ +#define MPU_MAIR1_Attr7_Pos 24U /*!< MPU MAIR1: Attr7 Position */ +#define MPU_MAIR1_Attr7_Msk (0xFFUL << MPU_MAIR1_Attr7_Pos) /*!< MPU MAIR1: Attr7 Mask */ + +#define MPU_MAIR1_Attr6_Pos 16U /*!< MPU MAIR1: Attr6 Position */ +#define MPU_MAIR1_Attr6_Msk (0xFFUL << MPU_MAIR1_Attr6_Pos) /*!< MPU MAIR1: Attr6 Mask */ + +#define MPU_MAIR1_Attr5_Pos 8U /*!< MPU MAIR1: Attr5 Position */ +#define MPU_MAIR1_Attr5_Msk (0xFFUL << MPU_MAIR1_Attr5_Pos) /*!< MPU MAIR1: Attr5 Mask */ + +#define MPU_MAIR1_Attr4_Pos 0U /*!< MPU MAIR1: Attr4 Position */ +#define MPU_MAIR1_Attr4_Msk (0xFFUL /*<< MPU_MAIR1_Attr4_Pos*/) /*!< MPU MAIR1: Attr4 Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SAU Security Attribution Unit (SAU) + \brief Type definitions for the Security Attribution Unit (SAU) + @{ + */ + +/** + \brief Structure type to access the Security Attribution Unit (SAU). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SAU Control Register */ + __IM uint32_t TYPE; /*!< Offset: 0x004 (R/ ) SAU Type Register */ +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) SAU Region Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) SAU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) SAU Region Limit Address Register */ +#else + uint32_t RESERVED0[3]; +#endif + __IOM uint32_t SFSR; /*!< Offset: 0x014 (R/W) Secure Fault Status Register */ + __IOM uint32_t SFAR; /*!< Offset: 0x018 (R/W) Secure Fault Address Register */ +} SAU_Type; + +/* SAU Control Register Definitions */ +#define SAU_CTRL_ALLNS_Pos 1U /*!< SAU CTRL: ALLNS Position */ +#define SAU_CTRL_ALLNS_Msk (1UL << SAU_CTRL_ALLNS_Pos) /*!< SAU CTRL: ALLNS Mask */ + +#define SAU_CTRL_ENABLE_Pos 0U /*!< SAU CTRL: ENABLE Position */ +#define SAU_CTRL_ENABLE_Msk (1UL /*<< SAU_CTRL_ENABLE_Pos*/) /*!< SAU CTRL: ENABLE Mask */ + +/* SAU Type Register Definitions */ +#define SAU_TYPE_SREGION_Pos 0U /*!< SAU TYPE: SREGION Position */ +#define SAU_TYPE_SREGION_Msk (0xFFUL /*<< SAU_TYPE_SREGION_Pos*/) /*!< SAU TYPE: SREGION Mask */ + +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) +/* SAU Region Number Register Definitions */ +#define SAU_RNR_REGION_Pos 0U /*!< SAU RNR: REGION Position */ +#define SAU_RNR_REGION_Msk (0xFFUL /*<< SAU_RNR_REGION_Pos*/) /*!< SAU RNR: REGION Mask */ + +/* SAU Region Base Address Register Definitions */ +#define SAU_RBAR_BADDR_Pos 5U /*!< SAU RBAR: BADDR Position */ +#define SAU_RBAR_BADDR_Msk (0x7FFFFFFUL << SAU_RBAR_BADDR_Pos) /*!< SAU RBAR: BADDR Mask */ + +/* SAU Region Limit Address Register Definitions */ +#define SAU_RLAR_LADDR_Pos 5U /*!< SAU RLAR: LADDR Position */ +#define SAU_RLAR_LADDR_Msk (0x7FFFFFFUL << SAU_RLAR_LADDR_Pos) /*!< SAU RLAR: LADDR Mask */ + +#define SAU_RLAR_NSC_Pos 1U /*!< SAU RLAR: NSC Position */ +#define SAU_RLAR_NSC_Msk (1UL << SAU_RLAR_NSC_Pos) /*!< SAU RLAR: NSC Mask */ + +#define SAU_RLAR_ENABLE_Pos 0U /*!< SAU RLAR: ENABLE Position */ +#define SAU_RLAR_ENABLE_Msk (1UL /*<< SAU_RLAR_ENABLE_Pos*/) /*!< SAU RLAR: ENABLE Mask */ + +#endif /* defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) */ + +/* Secure Fault Status Register Definitions */ +#define SAU_SFSR_LSERR_Pos 7U /*!< SAU SFSR: LSERR Position */ +#define SAU_SFSR_LSERR_Msk (1UL << SAU_SFSR_LSERR_Pos) /*!< SAU SFSR: LSERR Mask */ + +#define SAU_SFSR_SFARVALID_Pos 6U /*!< SAU SFSR: SFARVALID Position */ +#define SAU_SFSR_SFARVALID_Msk (1UL << SAU_SFSR_SFARVALID_Pos) /*!< SAU SFSR: SFARVALID Mask */ + +#define SAU_SFSR_LSPERR_Pos 5U /*!< SAU SFSR: LSPERR Position */ +#define SAU_SFSR_LSPERR_Msk (1UL << SAU_SFSR_LSPERR_Pos) /*!< SAU SFSR: LSPERR Mask */ + +#define SAU_SFSR_INVTRAN_Pos 4U /*!< SAU SFSR: INVTRAN Position */ +#define SAU_SFSR_INVTRAN_Msk (1UL << SAU_SFSR_INVTRAN_Pos) /*!< SAU SFSR: INVTRAN Mask */ + +#define SAU_SFSR_AUVIOL_Pos 3U /*!< SAU SFSR: AUVIOL Position */ +#define SAU_SFSR_AUVIOL_Msk (1UL << SAU_SFSR_AUVIOL_Pos) /*!< SAU SFSR: AUVIOL Mask */ + +#define SAU_SFSR_INVER_Pos 2U /*!< SAU SFSR: INVER Position */ +#define SAU_SFSR_INVER_Msk (1UL << SAU_SFSR_INVER_Pos) /*!< SAU SFSR: INVER Mask */ + +#define SAU_SFSR_INVIS_Pos 1U /*!< SAU SFSR: INVIS Position */ +#define SAU_SFSR_INVIS_Msk (1UL << SAU_SFSR_INVIS_Pos) /*!< SAU SFSR: INVIS Mask */ + +#define SAU_SFSR_INVEP_Pos 0U /*!< SAU SFSR: INVEP Position */ +#define SAU_SFSR_INVEP_Msk (1UL /*<< SAU_SFSR_INVEP_Pos*/) /*!< SAU SFSR: INVEP Mask */ + +/*@} end of group CMSIS_SAU */ +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_FPU Floating Point Unit (FPU) + \brief Type definitions for the Floating Point Unit (FPU) + @{ + */ + +/** + \brief Structure type to access the Floating Point Unit (FPU). + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IOM uint32_t FPCCR; /*!< Offset: 0x004 (R/W) Floating-Point Context Control Register */ + __IOM uint32_t FPCAR; /*!< Offset: 0x008 (R/W) Floating-Point Context Address Register */ + __IOM uint32_t FPDSCR; /*!< Offset: 0x00C (R/W) Floating-Point Default Status Control Register */ + __IM uint32_t MVFR0; /*!< Offset: 0x010 (R/ ) Media and FP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x014 (R/ ) Media and FP Feature Register 1 */ +} FPU_Type; + +/* Floating-Point Context Control Register Definitions */ +#define FPU_FPCCR_ASPEN_Pos 31U /*!< FPCCR: ASPEN bit Position */ +#define FPU_FPCCR_ASPEN_Msk (1UL << FPU_FPCCR_ASPEN_Pos) /*!< FPCCR: ASPEN bit Mask */ + +#define FPU_FPCCR_LSPEN_Pos 30U /*!< FPCCR: LSPEN Position */ +#define FPU_FPCCR_LSPEN_Msk (1UL << FPU_FPCCR_LSPEN_Pos) /*!< FPCCR: LSPEN bit Mask */ + +#define FPU_FPCCR_LSPENS_Pos 29U /*!< FPCCR: LSPENS Position */ +#define FPU_FPCCR_LSPENS_Msk (1UL << FPU_FPCCR_LSPENS_Pos) /*!< FPCCR: LSPENS bit Mask */ + +#define FPU_FPCCR_CLRONRET_Pos 28U /*!< FPCCR: CLRONRET Position */ +#define FPU_FPCCR_CLRONRET_Msk (1UL << FPU_FPCCR_CLRONRET_Pos) /*!< FPCCR: CLRONRET bit Mask */ + +#define FPU_FPCCR_CLRONRETS_Pos 27U /*!< FPCCR: CLRONRETS Position */ +#define FPU_FPCCR_CLRONRETS_Msk (1UL << FPU_FPCCR_CLRONRETS_Pos) /*!< FPCCR: CLRONRETS bit Mask */ + +#define FPU_FPCCR_TS_Pos 26U /*!< FPCCR: TS Position */ +#define FPU_FPCCR_TS_Msk (1UL << FPU_FPCCR_TS_Pos) /*!< FPCCR: TS bit Mask */ + +#define FPU_FPCCR_UFRDY_Pos 10U /*!< FPCCR: UFRDY Position */ +#define FPU_FPCCR_UFRDY_Msk (1UL << FPU_FPCCR_UFRDY_Pos) /*!< FPCCR: UFRDY bit Mask */ + +#define FPU_FPCCR_SPLIMVIOL_Pos 9U /*!< FPCCR: SPLIMVIOL Position */ +#define FPU_FPCCR_SPLIMVIOL_Msk (1UL << FPU_FPCCR_SPLIMVIOL_Pos) /*!< FPCCR: SPLIMVIOL bit Mask */ + +#define FPU_FPCCR_MONRDY_Pos 8U /*!< FPCCR: MONRDY Position */ +#define FPU_FPCCR_MONRDY_Msk (1UL << FPU_FPCCR_MONRDY_Pos) /*!< FPCCR: MONRDY bit Mask */ + +#define FPU_FPCCR_SFRDY_Pos 7U /*!< FPCCR: SFRDY Position */ +#define FPU_FPCCR_SFRDY_Msk (1UL << FPU_FPCCR_SFRDY_Pos) /*!< FPCCR: SFRDY bit Mask */ + +#define FPU_FPCCR_BFRDY_Pos 6U /*!< FPCCR: BFRDY Position */ +#define FPU_FPCCR_BFRDY_Msk (1UL << FPU_FPCCR_BFRDY_Pos) /*!< FPCCR: BFRDY bit Mask */ + +#define FPU_FPCCR_MMRDY_Pos 5U /*!< FPCCR: MMRDY Position */ +#define FPU_FPCCR_MMRDY_Msk (1UL << FPU_FPCCR_MMRDY_Pos) /*!< FPCCR: MMRDY bit Mask */ + +#define FPU_FPCCR_HFRDY_Pos 4U /*!< FPCCR: HFRDY Position */ +#define FPU_FPCCR_HFRDY_Msk (1UL << FPU_FPCCR_HFRDY_Pos) /*!< FPCCR: HFRDY bit Mask */ + +#define FPU_FPCCR_THREAD_Pos 3U /*!< FPCCR: processor mode bit Position */ +#define FPU_FPCCR_THREAD_Msk (1UL << FPU_FPCCR_THREAD_Pos) /*!< FPCCR: processor mode active bit Mask */ + +#define FPU_FPCCR_S_Pos 2U /*!< FPCCR: Security status of the FP context bit Position */ +#define FPU_FPCCR_S_Msk (1UL << FPU_FPCCR_S_Pos) /*!< FPCCR: Security status of the FP context bit Mask */ + +#define FPU_FPCCR_USER_Pos 1U /*!< 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 0U /*!< 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 Definitions */ +#define FPU_FPCAR_ADDRESS_Pos 3U /*!< FPCAR: ADDRESS bit Position */ +#define FPU_FPCAR_ADDRESS_Msk (0x1FFFFFFFUL << FPU_FPCAR_ADDRESS_Pos) /*!< FPCAR: ADDRESS bit Mask */ + +/* Floating-Point Default Status Control Register Definitions */ +#define FPU_FPDSCR_AHP_Pos 26U /*!< FPDSCR: AHP bit Position */ +#define FPU_FPDSCR_AHP_Msk (1UL << FPU_FPDSCR_AHP_Pos) /*!< FPDSCR: AHP bit Mask */ + +#define FPU_FPDSCR_DN_Pos 25U /*!< FPDSCR: DN bit Position */ +#define FPU_FPDSCR_DN_Msk (1UL << FPU_FPDSCR_DN_Pos) /*!< FPDSCR: DN bit Mask */ + +#define FPU_FPDSCR_FZ_Pos 24U /*!< FPDSCR: FZ bit Position */ +#define FPU_FPDSCR_FZ_Msk (1UL << FPU_FPDSCR_FZ_Pos) /*!< FPDSCR: FZ bit Mask */ + +#define FPU_FPDSCR_RMode_Pos 22U /*!< FPDSCR: RMode bit Position */ +#define FPU_FPDSCR_RMode_Msk (3UL << FPU_FPDSCR_RMode_Pos) /*!< FPDSCR: RMode bit Mask */ + +/* Media and FP Feature Register 0 Definitions */ +#define FPU_MVFR0_FP_rounding_modes_Pos 28U /*!< 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 24U /*!< 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 20U /*!< 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 16U /*!< 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 12U /*!< 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 8U /*!< 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 4U /*!< 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 0U /*!< 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 Definitions */ +#define FPU_MVFR1_FP_fused_MAC_Pos 28U /*!< 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 24U /*!< 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 4U /*!< 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 0U /*!< 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 */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** + \brief Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ + uint32_t RESERVED4[1U]; + __IOM uint32_t DAUTHCTRL; /*!< Offset: 0x014 (R/W) Debug Authentication Control Register */ + __IOM uint32_t DSCSR; /*!< Offset: 0x018 (R/W) Debug Security Control and Status Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register Definitions */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESTART_ST_Pos 26U /*!< CoreDebug DHCSR: S_RESTART_ST Position */ +#define CoreDebug_DHCSR_S_RESTART_ST_Msk (1UL << CoreDebug_DHCSR_S_RESTART_ST_Pos) /*!< CoreDebug DHCSR: S_RESTART_ST Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< 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 24U /*!< 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 19U /*!< 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 18U /*!< 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 17U /*!< 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 16U /*!< 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 5U /*!< 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 3U /*!< 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 2U /*!< 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 1U /*!< 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 0U /*!< 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 Definitions */ +#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register Definitions */ +#define CoreDebug_DEMCR_TRCENA_Pos 24U /*!< CoreDebug DEMCR: TRCENA Position */ +#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ + +#define CoreDebug_DEMCR_MON_REQ_Pos 19U /*!< 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 18U /*!< 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 17U /*!< 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 16U /*!< 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 10U /*!< 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 9U /*!< 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 8U /*!< 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 7U /*!< 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 6U /*!< 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 5U /*!< 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 4U /*!< 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 0U /*!< CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ + +/* Debug Authentication Control Register Definitions */ +#define CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos 3U /*!< CoreDebug DAUTHCTRL: INTSPNIDEN, Position */ +#define CoreDebug_DAUTHCTRL_INTSPNIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos) /*!< CoreDebug DAUTHCTRL: INTSPNIDEN, Mask */ + +#define CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos 2U /*!< CoreDebug DAUTHCTRL: SPNIDENSEL Position */ +#define CoreDebug_DAUTHCTRL_SPNIDENSEL_Msk (1UL << CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos) /*!< CoreDebug DAUTHCTRL: SPNIDENSEL Mask */ + +#define CoreDebug_DAUTHCTRL_INTSPIDEN_Pos 1U /*!< CoreDebug DAUTHCTRL: INTSPIDEN Position */ +#define CoreDebug_DAUTHCTRL_INTSPIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPIDEN_Pos) /*!< CoreDebug DAUTHCTRL: INTSPIDEN Mask */ + +#define CoreDebug_DAUTHCTRL_SPIDENSEL_Pos 0U /*!< CoreDebug DAUTHCTRL: SPIDENSEL Position */ +#define CoreDebug_DAUTHCTRL_SPIDENSEL_Msk (1UL /*<< CoreDebug_DAUTHCTRL_SPIDENSEL_Pos*/) /*!< CoreDebug DAUTHCTRL: SPIDENSEL Mask */ + +/* Debug Security Control and Status Register Definitions */ +#define CoreDebug_DSCSR_CDS_Pos 16U /*!< CoreDebug DSCSR: CDS Position */ +#define CoreDebug_DSCSR_CDS_Msk (1UL << CoreDebug_DSCSR_CDS_Pos) /*!< CoreDebug DSCSR: CDS Mask */ + +#define CoreDebug_DSCSR_SBRSEL_Pos 1U /*!< CoreDebug DSCSR: SBRSEL Position */ +#define CoreDebug_DSCSR_SBRSEL_Msk (1UL << CoreDebug_DSCSR_SBRSEL_Pos) /*!< CoreDebug DSCSR: SBRSEL Mask */ + +#define CoreDebug_DSCSR_SBRSELEN_Pos 0U /*!< CoreDebug DSCSR: SBRSELEN Position */ +#define CoreDebug_DSCSR_SBRSELEN_Msk (1UL /*<< CoreDebug_DSCSR_SBRSELEN_Pos*/) /*!< CoreDebug DSCSR: SBRSELEN Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ + #define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ + #define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ + #define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ + #define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ + #define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ + #define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ + #define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ + #define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + + #define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ + #define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ + #define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ + #define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ + #define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ + #define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ + #define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ + #define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE ) /*!< Core Debug configuration struct */ + + #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ + #endif + + #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + #define SAU_BASE (SCS_BASE + 0x0DD0UL) /*!< Security Attribution Unit */ + #define SAU ((SAU_Type *) SAU_BASE ) /*!< Security Attribution Unit */ + #endif + + #define FPU_BASE (SCS_BASE + 0x0F30UL) /*!< Floating Point Unit */ + #define FPU ((FPU_Type *) FPU_BASE ) /*!< Floating Point Unit */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + #define SCS_BASE_NS (0xE002E000UL) /*!< System Control Space Base Address (non-secure address space) */ + #define CoreDebug_BASE_NS (0xE002EDF0UL) /*!< Core Debug Base Address (non-secure address space) */ + #define SysTick_BASE_NS (SCS_BASE_NS + 0x0010UL) /*!< SysTick Base Address (non-secure address space) */ + #define NVIC_BASE_NS (SCS_BASE_NS + 0x0100UL) /*!< NVIC Base Address (non-secure address space) */ + #define SCB_BASE_NS (SCS_BASE_NS + 0x0D00UL) /*!< System Control Block Base Address (non-secure address space) */ + + #define SCnSCB_NS ((SCnSCB_Type *) SCS_BASE_NS ) /*!< System control Register not in SCB(non-secure address space) */ + #define SCB_NS ((SCB_Type *) SCB_BASE_NS ) /*!< SCB configuration struct (non-secure address space) */ + #define SysTick_NS ((SysTick_Type *) SysTick_BASE_NS ) /*!< SysTick configuration struct (non-secure address space) */ + #define NVIC_NS ((NVIC_Type *) NVIC_BASE_NS ) /*!< NVIC configuration struct (non-secure address space) */ + #define CoreDebug_NS ((CoreDebug_Type *) CoreDebug_BASE_NS) /*!< Core Debug configuration struct (non-secure address space) */ + + #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE_NS (SCS_BASE_NS + 0x0D90UL) /*!< Memory Protection Unit (non-secure address space) */ + #define MPU_NS ((MPU_Type *) MPU_BASE_NS ) /*!< Memory Protection Unit (non-secure address space) */ + #endif + + #define FPU_BASE_NS (SCS_BASE_NS + 0x0F30UL) /*!< Floating Point Unit (non-secure address space) */ + #define FPU_NS ((FPU_Type *) FPU_BASE_NS ) /*!< Floating Point Unit (non-secure address space) */ + +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Debug Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping + #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ + #define NVIC_GetActive __NVIC_GetActive + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + + +/** + \brief Set Priority Grouping + \details 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)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << 8U) ); /* Insert write key and priorty group */ + SCB->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping + \details Reads the priority grouping field from the NVIC Interrupt Controller. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t __NVIC_GetPriorityGrouping(void) +{ + return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt + \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IABR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Get Interrupt Target State + \details Reads the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + \return 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_GetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ITNS[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Target State + \details Sets the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_SetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)(int32_t)IRQn) >> 5UL)] |= ((uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Clear Interrupt Target State + \details Clears the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_ClearTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)(int32_t)IRQn) >> 5UL)] &= ~((uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IPR[((uint32_t)(int32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB->SHPR[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC->IPR[((uint32_t)(int32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB->SHPR[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Set Priority Grouping (non-secure) + \details Sets the non-secure priority grouping field when in secure state 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 TZ_NVIC_SetPriorityGrouping_NS(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB_NS->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << 8U) ); /* Insert write key and priorty group */ + SCB_NS->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping (non-secure) + \details Reads the priority grouping field from the non-secure NVIC when in secure state. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPriorityGrouping_NS(void) +{ + return ((uint32_t)((SCB_NS->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt (non-secure) + \details Enables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_EnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status (non-secure) + \details Returns a device specific interrupt enable status from the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetEnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt (non-secure) + \details Disables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_DisableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Pending Interrupt (non-secure) + \details Reads the NVIC pending register in the non-secure NVIC when in secure state and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } +} + + +/** + \brief Set Pending Interrupt (non-secure) + \details Sets the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_SetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt (non-secure) + \details Clears the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_ClearPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt (non-secure) + \details Reads the active register in non-secure NVIC when in secure state and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetActive_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->IABR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Priority (non-secure) + \details Sets the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every non-secure processor exception. + */ +__STATIC_INLINE void TZ_NVIC_SetPriority_NS(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->IPR[((uint32_t)(int32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB_NS->SHPR[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority (non-secure) + \details Reads the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPriority_NS(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC_NS->IPR[((uint32_t)(int32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB_NS->SHPR[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) &&(__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_NVICFunctions */ + + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + uint32_t mvfr0; + + mvfr0 = FPU->MVFR0; + if ((mvfr0 & (FPU_MVFR0_Single_precision_Msk | FPU_MVFR0_Double_precision_Msk)) == 0x220U) + { + return 2U; /* Double + Single precision FPU */ + } + else if ((mvfr0 & (FPU_MVFR0_Single_precision_Msk | FPU_MVFR0_Double_precision_Msk)) == 0x020U) + { + return 1U; /* Single precision FPU */ + } + else + { + return 0U; /* No FPU */ + } +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ########################## SAU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SAUFunctions SAU Functions + \brief Functions that configure the SAU. + @{ + */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + +/** + \brief Enable SAU + \details Enables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Enable(void) +{ + SAU->CTRL |= (SAU_CTRL_ENABLE_Msk); +} + + + +/** + \brief Disable SAU + \details Disables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Disable(void) +{ + SAU->CTRL &= ~(SAU_CTRL_ENABLE_Msk); +} + +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_SAUFunctions */ + + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief System Tick Configuration (non-secure) + \details Initializes the non-secure System Timer and its interrupt when in secure state, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function TZ_SysTick_Config_NS is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + + */ +__STATIC_INLINE uint32_t TZ_SysTick_Config_NS(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick_NS->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + TZ_NVIC_SetPriority_NS (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick_NS->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick_NS->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + +/* ##################################### Debug In/Output function ########################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_core_DebugFunctions ITM Functions + \brief Functions that access the ITM debug interface. + @{ + */ + +extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ +#define ITM_RXBUFFER_EMPTY ((int32_t)0x5AA55AA5U) /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ + + +/** + \brief ITM Send Character + \details Transmits a character via the ITM channel 0, and + \li Just returns when no debugger is connected that has booked the output. + \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. + \param [in] ch Character to transmit. + \returns Character to transmit. + */ +__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) +{ + if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ + ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */ + { + while (ITM->PORT[0U].u32 == 0UL) + { + __NOP(); + } + ITM->PORT[0U].u8 = (uint8_t)ch; + } + return (ch); +} + + +/** + \brief ITM Receive Character + \details Inputs a character via the external variable \ref ITM_RxBuffer. + \return Received character. + \return -1 No character pending. + */ +__STATIC_INLINE int32_t ITM_ReceiveChar (void) +{ + int32_t ch = -1; /* no character available */ + + if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) + { + ch = ITM_RxBuffer; + ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ + } + + return (ch); +} + + +/** + \brief ITM Check Character + \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. + \return 0 No character available. + \return 1 Character available. + */ +__STATIC_INLINE int32_t ITM_CheckChar (void) +{ + + if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) + { + return (0); /* no character available */ + } + else + { + return (1); /* character available */ + } +} + +/*@} end of CMSIS_core_DebugFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM33_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/cmsis/core_cm4.h b/cmsis/core_cm4.h new file mode 100644 index 00000000000..bdaedcf9f31 --- /dev/null +++ b/cmsis/core_cm4.h @@ -0,0 +1,2103 @@ +/**************************************************************************//** + * @file core_cm4.h + * @brief CMSIS Cortex-M4 Core Peripheral Access Layer Header File + * @version V5.0.2 + * @date 13. February 2017 + ******************************************************************************/ +/* + * Copyright (c) 2009-2017 ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_CM4_H_GENERIC +#define __CORE_CM4_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex_M4 + @{ + */ + +/* CMSIS CM4 definitions */ +#define __CM4_CMSIS_VERSION_MAIN ( 5U) /*!< [31:16] CMSIS HAL main version */ +#define __CM4_CMSIS_VERSION_SUB ( 0U) /*!< [15:0] CMSIS HAL sub version */ +#define __CM4_CMSIS_VERSION ((__CM4_CMSIS_VERSION_MAIN << 16U) | \ + __CM4_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */ + +#define __CORTEX_M (4U) /*!< Cortex-M Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + For this, __FPU_PRESENT has to be checked prior to making use of FPU specific registers and functions. +*/ +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_PCS_VFP + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM4_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM4_H_DEPENDANT +#define __CORE_CM4_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM4_REV + #define __CM4_REV 0x0000U + #warning "__CM4_REV not defined in device header file; using default!" + #endif + + #ifndef __FPU_PRESENT + #define __FPU_PRESENT 0U + #warning "__FPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 3U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group Cortex_M4 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + - Core FPU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + 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 */ + 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; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + +#define APSR_Q_Pos 27U /*!< APSR: Q Position */ +#define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */ + +#define APSR_GE_Pos 16U /*!< APSR: GE Position */ +#define APSR_GE_Msk (0xFUL << APSR_GE_Pos) /*!< APSR: GE Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:1; /*!< bit: 9 Reserved */ + uint32_t ICI_IT_1:6; /*!< bit: 10..15 ICI/IT part 1 */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit */ + uint32_t ICI_IT_2:2; /*!< bit: 25..26 ICI/IT part 2 */ + 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; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_Q_Pos 27U /*!< xPSR: Q Position */ +#define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */ + +#define xPSR_ICI_IT_2_Pos 25U /*!< xPSR: ICI/IT part 2 Position */ +#define xPSR_ICI_IT_2_Msk (3UL << xPSR_ICI_IT_2_Pos) /*!< xPSR: ICI/IT part 2 Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_GE_Pos 16U /*!< xPSR: GE Position */ +#define xPSR_GE_Msk (0xFUL << xPSR_GE_Pos) /*!< xPSR: GE Mask */ + +#define xPSR_ICI_IT_1_Pos 10U /*!< xPSR: ICI/IT part 1 Position */ +#define xPSR_ICI_IT_1_Msk (0x3FUL << xPSR_ICI_IT_1_Pos) /*!< xPSR: ICI/IT part 1 Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t 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; + +/* CONTROL Register Definitions */ +#define CONTROL_FPCA_Pos 2U /*!< CONTROL: FPCA Position */ +#define CONTROL_FPCA_Msk (1UL << CONTROL_FPCA_Pos) /*!< CONTROL: FPCA Mask */ + +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[8U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[24U]; + __IOM uint32_t ICER[8U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[24U]; + __IOM uint32_t ISPR[8U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[24U]; + __IOM uint32_t ICPR[8U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[24U]; + __IOM uint32_t IABR[8U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[56U]; + __IOM uint8_t IP[240U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED5[644U]; + __OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; + +/* Software Triggered Interrupt Register Definitions */ +#define NVIC_STIR_INTID_Pos 0U /*!< STIR: INTLINESNUM Position */ +#define NVIC_STIR_INTID_Msk (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/) /*!< STIR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + __IOM uint8_t SHP[12U]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IOM uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IOM uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IOM uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IOM uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IOM uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IOM uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __IM uint32_t PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __IM uint32_t DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __IM uint32_t ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __IM uint32_t MMFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __IM uint32_t ISAR[5U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + uint32_t RESERVED0[5U]; + __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Vector Table Offset Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 7U /*!< 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 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */ +#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +#define SCB_AIRCR_VECTRESET_Pos 0U /*!< 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 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< 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 4U /*!< 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 3U /*!< 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 1U /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +#define SCB_CCR_NONBASETHRDENA_Pos 0U /*!< 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 18U /*!< SCB SHCSR: USGFAULTENA Position */ +#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ + +#define SCB_SHCSR_BUSFAULTENA_Pos 17U /*!< SCB SHCSR: BUSFAULTENA Position */ +#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ + +#define SCB_SHCSR_MEMFAULTENA_Pos 16U /*!< SCB SHCSR: MEMFAULTENA Position */ +#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_BUSFAULTPENDED_Pos 14U /*!< SCB SHCSR: BUSFAULTPENDED Position */ +#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ + +#define SCB_SHCSR_MEMFAULTPENDED_Pos 13U /*!< SCB SHCSR: MEMFAULTPENDED Position */ +#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ + +#define SCB_SHCSR_USGFAULTPENDED_Pos 12U /*!< SCB SHCSR: USGFAULTPENDED Position */ +#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_MONITORACT_Pos 8U /*!< SCB SHCSR: MONITORACT Position */ +#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_USGFAULTACT_Pos 3U /*!< SCB SHCSR: USGFAULTACT Position */ +#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ + +#define SCB_SHCSR_BUSFAULTACT_Pos 1U /*!< SCB SHCSR: BUSFAULTACT Position */ +#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ + +#define SCB_SHCSR_MEMFAULTACT_Pos 0U /*!< SCB SHCSR: MEMFAULTACT Position */ +#define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */ + +/* SCB Configurable Fault Status Register Definitions */ +#define SCB_CFSR_USGFAULTSR_Pos 16U /*!< 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 8U /*!< 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 0U /*!< 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 */ + +/* MemManage Fault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_MMARVALID_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 7U) /*!< SCB CFSR (MMFSR): MMARVALID Position */ +#define SCB_CFSR_MMARVALID_Msk (1UL << SCB_CFSR_MMARVALID_Pos) /*!< SCB CFSR (MMFSR): MMARVALID Mask */ + +#define SCB_CFSR_MLSPERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 5U) /*!< SCB CFSR (MMFSR): MLSPERR Position */ +#define SCB_CFSR_MLSPERR_Msk (1UL << SCB_CFSR_MLSPERR_Pos) /*!< SCB CFSR (MMFSR): MLSPERR Mask */ + +#define SCB_CFSR_MSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 4U) /*!< SCB CFSR (MMFSR): MSTKERR Position */ +#define SCB_CFSR_MSTKERR_Msk (1UL << SCB_CFSR_MSTKERR_Pos) /*!< SCB CFSR (MMFSR): MSTKERR Mask */ + +#define SCB_CFSR_MUNSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 3U) /*!< SCB CFSR (MMFSR): MUNSTKERR Position */ +#define SCB_CFSR_MUNSTKERR_Msk (1UL << SCB_CFSR_MUNSTKERR_Pos) /*!< SCB CFSR (MMFSR): MUNSTKERR Mask */ + +#define SCB_CFSR_DACCVIOL_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 1U) /*!< SCB CFSR (MMFSR): DACCVIOL Position */ +#define SCB_CFSR_DACCVIOL_Msk (1UL << SCB_CFSR_DACCVIOL_Pos) /*!< SCB CFSR (MMFSR): DACCVIOL Mask */ + +#define SCB_CFSR_IACCVIOL_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 0U) /*!< SCB CFSR (MMFSR): IACCVIOL Position */ +#define SCB_CFSR_IACCVIOL_Msk (1UL /*<< SCB_CFSR_IACCVIOL_Pos*/) /*!< SCB CFSR (MMFSR): IACCVIOL Mask */ + +/* BusFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_BFARVALID_Pos (SCB_CFSR_BUSFAULTSR_Pos + 7U) /*!< SCB CFSR (BFSR): BFARVALID Position */ +#define SCB_CFSR_BFARVALID_Msk (1UL << SCB_CFSR_BFARVALID_Pos) /*!< SCB CFSR (BFSR): BFARVALID Mask */ + +#define SCB_CFSR_LSPERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 5U) /*!< SCB CFSR (BFSR): LSPERR Position */ +#define SCB_CFSR_LSPERR_Msk (1UL << SCB_CFSR_LSPERR_Pos) /*!< SCB CFSR (BFSR): LSPERR Mask */ + +#define SCB_CFSR_STKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 4U) /*!< SCB CFSR (BFSR): STKERR Position */ +#define SCB_CFSR_STKERR_Msk (1UL << SCB_CFSR_STKERR_Pos) /*!< SCB CFSR (BFSR): STKERR Mask */ + +#define SCB_CFSR_UNSTKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 3U) /*!< SCB CFSR (BFSR): UNSTKERR Position */ +#define SCB_CFSR_UNSTKERR_Msk (1UL << SCB_CFSR_UNSTKERR_Pos) /*!< SCB CFSR (BFSR): UNSTKERR Mask */ + +#define SCB_CFSR_IMPRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 2U) /*!< SCB CFSR (BFSR): IMPRECISERR Position */ +#define SCB_CFSR_IMPRECISERR_Msk (1UL << SCB_CFSR_IMPRECISERR_Pos) /*!< SCB CFSR (BFSR): IMPRECISERR Mask */ + +#define SCB_CFSR_PRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 1U) /*!< SCB CFSR (BFSR): PRECISERR Position */ +#define SCB_CFSR_PRECISERR_Msk (1UL << SCB_CFSR_PRECISERR_Pos) /*!< SCB CFSR (BFSR): PRECISERR Mask */ + +#define SCB_CFSR_IBUSERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 0U) /*!< SCB CFSR (BFSR): IBUSERR Position */ +#define SCB_CFSR_IBUSERR_Msk (1UL << SCB_CFSR_IBUSERR_Pos) /*!< SCB CFSR (BFSR): IBUSERR Mask */ + +/* UsageFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_DIVBYZERO_Pos (SCB_CFSR_USGFAULTSR_Pos + 9U) /*!< SCB CFSR (UFSR): DIVBYZERO Position */ +#define SCB_CFSR_DIVBYZERO_Msk (1UL << SCB_CFSR_DIVBYZERO_Pos) /*!< SCB CFSR (UFSR): DIVBYZERO Mask */ + +#define SCB_CFSR_UNALIGNED_Pos (SCB_CFSR_USGFAULTSR_Pos + 8U) /*!< SCB CFSR (UFSR): UNALIGNED Position */ +#define SCB_CFSR_UNALIGNED_Msk (1UL << SCB_CFSR_UNALIGNED_Pos) /*!< SCB CFSR (UFSR): UNALIGNED Mask */ + +#define SCB_CFSR_NOCP_Pos (SCB_CFSR_USGFAULTSR_Pos + 3U) /*!< SCB CFSR (UFSR): NOCP Position */ +#define SCB_CFSR_NOCP_Msk (1UL << SCB_CFSR_NOCP_Pos) /*!< SCB CFSR (UFSR): NOCP Mask */ + +#define SCB_CFSR_INVPC_Pos (SCB_CFSR_USGFAULTSR_Pos + 2U) /*!< SCB CFSR (UFSR): INVPC Position */ +#define SCB_CFSR_INVPC_Msk (1UL << SCB_CFSR_INVPC_Pos) /*!< SCB CFSR (UFSR): INVPC Mask */ + +#define SCB_CFSR_INVSTATE_Pos (SCB_CFSR_USGFAULTSR_Pos + 1U) /*!< SCB CFSR (UFSR): INVSTATE Position */ +#define SCB_CFSR_INVSTATE_Msk (1UL << SCB_CFSR_INVSTATE_Pos) /*!< SCB CFSR (UFSR): INVSTATE Mask */ + +#define SCB_CFSR_UNDEFINSTR_Pos (SCB_CFSR_USGFAULTSR_Pos + 0U) /*!< SCB CFSR (UFSR): UNDEFINSTR Position */ +#define SCB_CFSR_UNDEFINSTR_Msk (1UL << SCB_CFSR_UNDEFINSTR_Pos) /*!< SCB CFSR (UFSR): UNDEFINSTR Mask */ + +/* SCB Hard Fault Status Register Definitions */ +#define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */ +#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ + +#define SCB_HFSR_FORCED_Pos 30U /*!< SCB HFSR: FORCED Position */ +#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ + +#define SCB_HFSR_VECTTBL_Pos 1U /*!< 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 4U /*!< SCB DFSR: EXTERNAL Position */ +#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ + +#define SCB_DFSR_VCATCH_Pos 3U /*!< SCB DFSR: VCATCH Position */ +#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ + +#define SCB_DFSR_DWTTRAP_Pos 2U /*!< SCB DFSR: DWTTRAP Position */ +#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ + +#define SCB_DFSR_BKPT_Pos 1U /*!< SCB DFSR: BKPT Position */ +#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ + +#define SCB_DFSR_HALTED_Pos 0U /*!< SCB DFSR: HALTED Position */ +#define SCB_DFSR_HALTED_Msk (1UL /*<< SCB_DFSR_HALTED_Pos*/) /*!< SCB DFSR: HALTED Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** + \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IM uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ + __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ +} SCnSCB_Type; + +/* Interrupt Controller Type Register Definitions */ +#define SCnSCB_ICTR_INTLINESNUM_Pos 0U /*!< 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 9U /*!< ACTLR: DISOOFP Position */ +#define SCnSCB_ACTLR_DISOOFP_Msk (1UL << SCnSCB_ACTLR_DISOOFP_Pos) /*!< ACTLR: DISOOFP Mask */ + +#define SCnSCB_ACTLR_DISFPCA_Pos 8U /*!< ACTLR: DISFPCA Position */ +#define SCnSCB_ACTLR_DISFPCA_Msk (1UL << SCnSCB_ACTLR_DISFPCA_Pos) /*!< ACTLR: DISFPCA Mask */ + +#define SCnSCB_ACTLR_DISFOLD_Pos 2U /*!< ACTLR: DISFOLD Position */ +#define SCnSCB_ACTLR_DISFOLD_Msk (1UL << SCnSCB_ACTLR_DISFOLD_Pos) /*!< ACTLR: DISFOLD Mask */ + +#define SCnSCB_ACTLR_DISDEFWBUF_Pos 1U /*!< ACTLR: DISDEFWBUF Position */ +#define SCnSCB_ACTLR_DISDEFWBUF_Msk (1UL << SCnSCB_ACTLR_DISDEFWBUF_Pos) /*!< ACTLR: DISDEFWBUF Mask */ + +#define SCnSCB_ACTLR_DISMCYCINT_Pos 0U /*!< ACTLR: DISMCYCINT Position */ +#define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL /*<< SCnSCB_ACTLR_DISMCYCINT_Pos*/) /*!< ACTLR: DISMCYCINT Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) + \brief Type definitions for the Instrumentation Trace Macrocell (ITM) + @{ + */ + +/** + \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). + */ +typedef struct +{ + __OM union + { + __OM uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ + __OM uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ + __OM uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ + } PORT [32U]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ + uint32_t RESERVED0[864U]; + __IOM uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ + uint32_t RESERVED1[15U]; + __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ + uint32_t RESERVED2[15U]; + __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ + uint32_t RESERVED3[29U]; + __OM uint32_t IWR; /*!< Offset: 0xEF8 ( /W) ITM Integration Write Register */ + __IM uint32_t IRR; /*!< Offset: 0xEFC (R/ ) ITM Integration Read Register */ + __IOM uint32_t IMCR; /*!< Offset: 0xF00 (R/W) ITM Integration Mode Control Register */ + uint32_t RESERVED4[43U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ + uint32_t RESERVED5[6U]; + __IM uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ + __IM uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ + __IM uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ + __IM uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ + __IM uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ + __IM uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ + __IM uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ + __IM uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ + __IM uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ + __IM uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ + __IM uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ + __IM uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ +} ITM_Type; + +/* ITM Trace Privilege Register Definitions */ +#define ITM_TPR_PRIVMASK_Pos 0U /*!< 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 23U /*!< ITM TCR: BUSY Position */ +#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ + +#define ITM_TCR_TraceBusID_Pos 16U /*!< ITM TCR: ATBID Position */ +#define ITM_TCR_TraceBusID_Msk (0x7FUL << ITM_TCR_TraceBusID_Pos) /*!< ITM TCR: ATBID Mask */ + +#define ITM_TCR_GTSFREQ_Pos 10U /*!< 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 8U /*!< ITM TCR: TSPrescale Position */ +#define ITM_TCR_TSPrescale_Msk (3UL << ITM_TCR_TSPrescale_Pos) /*!< ITM TCR: TSPrescale Mask */ + +#define ITM_TCR_SWOENA_Pos 4U /*!< ITM TCR: SWOENA Position */ +#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ + +#define ITM_TCR_DWTENA_Pos 3U /*!< ITM TCR: DWTENA Position */ +#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ + +#define ITM_TCR_SYNCENA_Pos 2U /*!< ITM TCR: SYNCENA Position */ +#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ + +#define ITM_TCR_TSENA_Pos 1U /*!< ITM TCR: TSENA Position */ +#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ + +#define ITM_TCR_ITMENA_Pos 0U /*!< ITM TCR: ITM Enable bit Position */ +#define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */ + +/* ITM Integration Write Register Definitions */ +#define ITM_IWR_ATVALIDM_Pos 0U /*!< ITM IWR: ATVALIDM Position */ +#define ITM_IWR_ATVALIDM_Msk (1UL /*<< ITM_IWR_ATVALIDM_Pos*/) /*!< ITM IWR: ATVALIDM Mask */ + +/* ITM Integration Read Register Definitions */ +#define ITM_IRR_ATREADYM_Pos 0U /*!< ITM IRR: ATREADYM Position */ +#define ITM_IRR_ATREADYM_Msk (1UL /*<< ITM_IRR_ATREADYM_Pos*/) /*!< ITM IRR: ATREADYM Mask */ + +/* ITM Integration Mode Control Register Definitions */ +#define ITM_IMCR_INTEGRATION_Pos 0U /*!< ITM IMCR: INTEGRATION Position */ +#define ITM_IMCR_INTEGRATION_Msk (1UL /*<< ITM_IMCR_INTEGRATION_Pos*/) /*!< ITM IMCR: INTEGRATION Mask */ + +/* ITM Lock Status Register Definitions */ +#define ITM_LSR_ByteAcc_Pos 2U /*!< ITM LSR: ByteAcc Position */ +#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ + +#define ITM_LSR_Access_Pos 1U /*!< ITM LSR: Access Position */ +#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ + +#define ITM_LSR_Present_Pos 0U /*!< ITM LSR: Present Position */ +#define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */ + +/*@}*/ /* end of group CMSIS_ITM */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** + \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + __IOM uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ + __IOM uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ + __IOM uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ + __IOM uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ + __IOM uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ + __IOM uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ + __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + __IOM uint32_t MASK0; /*!< Offset: 0x024 (R/W) Mask Register 0 */ + __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED0[1U]; + __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + __IOM uint32_t MASK1; /*!< Offset: 0x034 (R/W) Mask Register 1 */ + __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED1[1U]; + __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + __IOM uint32_t MASK2; /*!< Offset: 0x044 (R/W) Mask Register 2 */ + __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + __IOM uint32_t MASK3; /*!< Offset: 0x054 (R/W) Mask Register 3 */ + __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +#define DWT_CTRL_CYCEVTENA_Pos 22U /*!< DWT CTRL: CYCEVTENA Position */ +#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ + +#define DWT_CTRL_FOLDEVTENA_Pos 21U /*!< DWT CTRL: FOLDEVTENA Position */ +#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ + +#define DWT_CTRL_LSUEVTENA_Pos 20U /*!< DWT CTRL: LSUEVTENA Position */ +#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ + +#define DWT_CTRL_SLEEPEVTENA_Pos 19U /*!< DWT CTRL: SLEEPEVTENA Position */ +#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ + +#define DWT_CTRL_EXCEVTENA_Pos 18U /*!< DWT CTRL: EXCEVTENA Position */ +#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ + +#define DWT_CTRL_CPIEVTENA_Pos 17U /*!< DWT CTRL: CPIEVTENA Position */ +#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ + +#define DWT_CTRL_EXCTRCENA_Pos 16U /*!< DWT CTRL: EXCTRCENA Position */ +#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ + +#define DWT_CTRL_PCSAMPLENA_Pos 12U /*!< DWT CTRL: PCSAMPLENA Position */ +#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ + +#define DWT_CTRL_SYNCTAP_Pos 10U /*!< DWT CTRL: SYNCTAP Position */ +#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ + +#define DWT_CTRL_CYCTAP_Pos 9U /*!< DWT CTRL: CYCTAP Position */ +#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ + +#define DWT_CTRL_POSTINIT_Pos 5U /*!< DWT CTRL: POSTINIT Position */ +#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ + +#define DWT_CTRL_POSTPRESET_Pos 1U /*!< DWT CTRL: POSTPRESET Position */ +#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ + +#define DWT_CTRL_CYCCNTENA_Pos 0U /*!< DWT CTRL: CYCCNTENA Position */ +#define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */ + +/* DWT CPI Count Register Definitions */ +#define DWT_CPICNT_CPICNT_Pos 0U /*!< DWT CPICNT: CPICNT Position */ +#define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */ + +/* DWT Exception Overhead Count Register Definitions */ +#define DWT_EXCCNT_EXCCNT_Pos 0U /*!< DWT EXCCNT: EXCCNT Position */ +#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */ + +/* DWT Sleep Count Register Definitions */ +#define DWT_SLEEPCNT_SLEEPCNT_Pos 0U /*!< DWT SLEEPCNT: SLEEPCNT Position */ +#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ + +/* DWT LSU Count Register Definitions */ +#define DWT_LSUCNT_LSUCNT_Pos 0U /*!< DWT LSUCNT: LSUCNT Position */ +#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */ + +/* DWT Folded-instruction Count Register Definitions */ +#define DWT_FOLDCNT_FOLDCNT_Pos 0U /*!< DWT FOLDCNT: FOLDCNT Position */ +#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */ + +/* DWT Comparator Mask Register Definitions */ +#define DWT_MASK_MASK_Pos 0U /*!< DWT MASK: MASK Position */ +#define DWT_MASK_MASK_Msk (0x1FUL /*<< DWT_MASK_MASK_Pos*/) /*!< DWT MASK: MASK Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVADDR1_Pos 16U /*!< DWT FUNCTION: DATAVADDR1 Position */ +#define DWT_FUNCTION_DATAVADDR1_Msk (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos) /*!< DWT FUNCTION: DATAVADDR1 Mask */ + +#define DWT_FUNCTION_DATAVADDR0_Pos 12U /*!< DWT FUNCTION: DATAVADDR0 Position */ +#define DWT_FUNCTION_DATAVADDR0_Msk (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos) /*!< DWT FUNCTION: DATAVADDR0 Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_LNK1ENA_Pos 9U /*!< DWT FUNCTION: LNK1ENA Position */ +#define DWT_FUNCTION_LNK1ENA_Msk (0x1UL << DWT_FUNCTION_LNK1ENA_Pos) /*!< DWT FUNCTION: LNK1ENA Mask */ + +#define DWT_FUNCTION_DATAVMATCH_Pos 8U /*!< DWT FUNCTION: DATAVMATCH Position */ +#define DWT_FUNCTION_DATAVMATCH_Msk (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos) /*!< DWT FUNCTION: DATAVMATCH Mask */ + +#define DWT_FUNCTION_CYCMATCH_Pos 7U /*!< DWT FUNCTION: CYCMATCH Position */ +#define DWT_FUNCTION_CYCMATCH_Msk (0x1UL << DWT_FUNCTION_CYCMATCH_Pos) /*!< DWT FUNCTION: CYCMATCH Mask */ + +#define DWT_FUNCTION_EMITRANGE_Pos 5U /*!< DWT FUNCTION: EMITRANGE Position */ +#define DWT_FUNCTION_EMITRANGE_Msk (0x1UL << DWT_FUNCTION_EMITRANGE_Pos) /*!< DWT FUNCTION: EMITRANGE Mask */ + +#define DWT_FUNCTION_FUNCTION_Pos 0U /*!< DWT FUNCTION: FUNCTION Position */ +#define DWT_FUNCTION_FUNCTION_Msk (0xFUL /*<< DWT_FUNCTION_FUNCTION_Pos*/) /*!< DWT FUNCTION: FUNCTION Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** + \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IOM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55U]; + __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131U]; + __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __IM uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ + uint32_t RESERVED3[759U]; + __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER */ + __IM uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ + __IM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ + uint32_t RESERVED4[1U]; + __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */ + __IM uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */ + __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ + uint32_t RESERVED5[39U]; + __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ + __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ + uint32_t RESERVED7[8U]; + __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_PRESCALER_Pos 0U /*!< TPI ACPR: PRESCALER Position */ +#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< TPI ACPR: PRESCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI TRIGGER Register Definitions */ +#define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */ +#define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */ + +/* TPI Integration ETM Data Register Definitions (FIFO0) */ +#define TPI_FIFO0_ITM_ATVALID_Pos 29U /*!< TPI FIFO0: ITM_ATVALID Position */ +#define TPI_FIFO0_ITM_ATVALID_Msk (0x3UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ + +#define TPI_FIFO0_ITM_bytecount_Pos 27U /*!< TPI FIFO0: ITM_bytecount Position */ +#define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */ + +#define TPI_FIFO0_ETM_ATVALID_Pos 26U /*!< TPI FIFO0: ETM_ATVALID Position */ +#define TPI_FIFO0_ETM_ATVALID_Msk (0x3UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ + +#define TPI_FIFO0_ETM_bytecount_Pos 24U /*!< TPI FIFO0: ETM_bytecount Position */ +#define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */ + +#define TPI_FIFO0_ETM2_Pos 16U /*!< TPI FIFO0: ETM2 Position */ +#define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */ + +#define TPI_FIFO0_ETM1_Pos 8U /*!< TPI FIFO0: ETM1 Position */ +#define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */ + +#define TPI_FIFO0_ETM0_Pos 0U /*!< TPI FIFO0: ETM0 Position */ +#define TPI_FIFO0_ETM0_Msk (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/) /*!< TPI FIFO0: ETM0 Mask */ + +/* TPI ITATBCTR2 Register Definitions */ +#define TPI_ITATBCTR2_ATREADY_Pos 0U /*!< TPI ITATBCTR2: ATREADY Position */ +#define TPI_ITATBCTR2_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY_Pos*/) /*!< TPI ITATBCTR2: ATREADY Mask */ + +/* TPI Integration ITM Data Register Definitions (FIFO1) */ +#define TPI_FIFO1_ITM_ATVALID_Pos 29U /*!< TPI FIFO1: ITM_ATVALID Position */ +#define TPI_FIFO1_ITM_ATVALID_Msk (0x3UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ + +#define TPI_FIFO1_ITM_bytecount_Pos 27U /*!< TPI FIFO1: ITM_bytecount Position */ +#define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */ + +#define TPI_FIFO1_ETM_ATVALID_Pos 26U /*!< TPI FIFO1: ETM_ATVALID Position */ +#define TPI_FIFO1_ETM_ATVALID_Msk (0x3UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ + +#define TPI_FIFO1_ETM_bytecount_Pos 24U /*!< TPI FIFO1: ETM_bytecount Position */ +#define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */ + +#define TPI_FIFO1_ITM2_Pos 16U /*!< TPI FIFO1: ITM2 Position */ +#define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */ + +#define TPI_FIFO1_ITM1_Pos 8U /*!< TPI FIFO1: ITM1 Position */ +#define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */ + +#define TPI_FIFO1_ITM0_Pos 0U /*!< TPI FIFO1: ITM0 Position */ +#define TPI_FIFO1_ITM0_Msk (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/) /*!< TPI FIFO1: ITM0 Mask */ + +/* TPI ITATBCTR0 Register Definitions */ +#define TPI_ITATBCTR0_ATREADY_Pos 0U /*!< TPI ITATBCTR0: ATREADY Position */ +#define TPI_ITATBCTR0_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY_Pos*/) /*!< TPI ITATBCTR0: ATREADY Mask */ + +/* TPI Integration Mode Control Register Definitions */ +#define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ +#define TPI_ITCTRL_Mode_Msk (0x1UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_MinBufSz_Pos 6U /*!< TPI DEVID: MinBufSz Position */ +#define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */ + +#define TPI_DEVID_AsynClkIn_Pos 5U /*!< TPI DEVID: AsynClkIn Position */ +#define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */ + +#define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */ +#define TPI_DEVID_NrTraceInput_Msk (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_MajorType_Pos 4U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +#define TPI_DEVTYPE_SubType_Pos 0U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ + __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Alias 1 Region Base Address Register */ + __IOM uint32_t RASR_A1; /*!< Offset: 0x018 (R/W) MPU Alias 1 Region Attribute and Size Register */ + __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Alias 2 Region Base Address Register */ + __IOM uint32_t RASR_A2; /*!< Offset: 0x020 (R/W) MPU Alias 2 Region Attribute and Size Register */ + __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Alias 3 Region Base Address Register */ + __IOM uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */ +} MPU_Type; + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_ADDR_Pos 5U /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */ +#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ + +#define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */ +#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */ + +/* MPU Region Attribute and Size Register Definitions */ +#define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */ +#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ + +#define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */ +#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ + +#define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */ +#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ + +#define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */ +#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ + +#define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */ +#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ + +#define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */ +#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ + +#define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */ +#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ + +#define MPU_RASR_SRD_Pos 8U /*!< MPU RASR: Sub-Region Disable Position */ +#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ + +#define MPU_RASR_SIZE_Pos 1U /*!< MPU RASR: Region Size Field Position */ +#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ + +#define MPU_RASR_ENABLE_Pos 0U /*!< MPU RASR: Region enable bit Position */ +#define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */ + +/*@} end of group CMSIS_MPU */ +#endif /* defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_FPU Floating Point Unit (FPU) + \brief Type definitions for the Floating Point Unit (FPU) + @{ + */ + +/** + \brief Structure type to access the Floating Point Unit (FPU). + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IOM uint32_t FPCCR; /*!< Offset: 0x004 (R/W) Floating-Point Context Control Register */ + __IOM uint32_t FPCAR; /*!< Offset: 0x008 (R/W) Floating-Point Context Address Register */ + __IOM uint32_t FPDSCR; /*!< Offset: 0x00C (R/W) Floating-Point Default Status Control Register */ + __IM uint32_t MVFR0; /*!< Offset: 0x010 (R/ ) Media and FP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x014 (R/ ) Media and FP Feature Register 1 */ +} FPU_Type; + +/* Floating-Point Context Control Register Definitions */ +#define FPU_FPCCR_ASPEN_Pos 31U /*!< FPCCR: ASPEN bit Position */ +#define FPU_FPCCR_ASPEN_Msk (1UL << FPU_FPCCR_ASPEN_Pos) /*!< FPCCR: ASPEN bit Mask */ + +#define FPU_FPCCR_LSPEN_Pos 30U /*!< FPCCR: LSPEN Position */ +#define FPU_FPCCR_LSPEN_Msk (1UL << FPU_FPCCR_LSPEN_Pos) /*!< FPCCR: LSPEN bit Mask */ + +#define FPU_FPCCR_MONRDY_Pos 8U /*!< FPCCR: MONRDY Position */ +#define FPU_FPCCR_MONRDY_Msk (1UL << FPU_FPCCR_MONRDY_Pos) /*!< FPCCR: MONRDY bit Mask */ + +#define FPU_FPCCR_BFRDY_Pos 6U /*!< FPCCR: BFRDY Position */ +#define FPU_FPCCR_BFRDY_Msk (1UL << FPU_FPCCR_BFRDY_Pos) /*!< FPCCR: BFRDY bit Mask */ + +#define FPU_FPCCR_MMRDY_Pos 5U /*!< FPCCR: MMRDY Position */ +#define FPU_FPCCR_MMRDY_Msk (1UL << FPU_FPCCR_MMRDY_Pos) /*!< FPCCR: MMRDY bit Mask */ + +#define FPU_FPCCR_HFRDY_Pos 4U /*!< FPCCR: HFRDY Position */ +#define FPU_FPCCR_HFRDY_Msk (1UL << FPU_FPCCR_HFRDY_Pos) /*!< FPCCR: HFRDY bit Mask */ + +#define FPU_FPCCR_THREAD_Pos 3U /*!< 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 1U /*!< 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 0U /*!< 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 Definitions */ +#define FPU_FPCAR_ADDRESS_Pos 3U /*!< FPCAR: ADDRESS bit Position */ +#define FPU_FPCAR_ADDRESS_Msk (0x1FFFFFFFUL << FPU_FPCAR_ADDRESS_Pos) /*!< FPCAR: ADDRESS bit Mask */ + +/* Floating-Point Default Status Control Register Definitions */ +#define FPU_FPDSCR_AHP_Pos 26U /*!< FPDSCR: AHP bit Position */ +#define FPU_FPDSCR_AHP_Msk (1UL << FPU_FPDSCR_AHP_Pos) /*!< FPDSCR: AHP bit Mask */ + +#define FPU_FPDSCR_DN_Pos 25U /*!< FPDSCR: DN bit Position */ +#define FPU_FPDSCR_DN_Msk (1UL << FPU_FPDSCR_DN_Pos) /*!< FPDSCR: DN bit Mask */ + +#define FPU_FPDSCR_FZ_Pos 24U /*!< FPDSCR: FZ bit Position */ +#define FPU_FPDSCR_FZ_Msk (1UL << FPU_FPDSCR_FZ_Pos) /*!< FPDSCR: FZ bit Mask */ + +#define FPU_FPDSCR_RMode_Pos 22U /*!< FPDSCR: RMode bit Position */ +#define FPU_FPDSCR_RMode_Msk (3UL << FPU_FPDSCR_RMode_Pos) /*!< FPDSCR: RMode bit Mask */ + +/* Media and FP Feature Register 0 Definitions */ +#define FPU_MVFR0_FP_rounding_modes_Pos 28U /*!< 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 24U /*!< 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 20U /*!< 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 16U /*!< 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 12U /*!< 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 8U /*!< 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 4U /*!< 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 0U /*!< 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 Definitions */ +#define FPU_MVFR1_FP_fused_MAC_Pos 28U /*!< 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 24U /*!< 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 4U /*!< 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 0U /*!< 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 */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** + \brief Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register Definitions */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< 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 25U /*!< 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 24U /*!< 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 19U /*!< 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 18U /*!< 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 17U /*!< 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 16U /*!< 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 5U /*!< 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 3U /*!< 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 2U /*!< 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 1U /*!< 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 0U /*!< 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 Definitions */ +#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register Definitions */ +#define CoreDebug_DEMCR_TRCENA_Pos 24U /*!< CoreDebug DEMCR: TRCENA Position */ +#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ + +#define CoreDebug_DEMCR_MON_REQ_Pos 19U /*!< 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 18U /*!< 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 17U /*!< 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 16U /*!< 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 10U /*!< 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 9U /*!< 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 8U /*!< 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 7U /*!< 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 6U /*!< 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 5U /*!< 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 4U /*!< 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 0U /*!< CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ +#define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ +#define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ +#define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ +#define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ +#define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ +#define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ +#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ +#endif + +#define FPU_BASE (SCS_BASE + 0x0F30UL) /*!< Floating Point Unit */ +#define FPU ((FPU_Type *) FPU_BASE ) /*!< Floating Point Unit */ + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Debug Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping + #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ + #define NVIC_GetActive __NVIC_GetActive + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + + +/** + \brief Set Priority Grouping + \details 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)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << 8U) ); /* Insert write key and priorty group */ + SCB->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping + \details Reads the priority grouping field from the NVIC Interrupt Controller. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t __NVIC_GetPriorityGrouping(void) +{ + return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt + \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IABR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IP[((uint32_t)(int32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB->SHP[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC->IP[((uint32_t)(int32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB->SHP[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +/*@} end of CMSIS_Core_NVICFunctions */ + + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + uint32_t mvfr0; + + mvfr0 = FPU->MVFR0; + if ((mvfr0 & (FPU_MVFR0_Single_precision_Msk | FPU_MVFR0_Double_precision_Msk)) == 0x020U) + { + return 1U; /* Single precision FPU */ + } + else + { + return 0U; /* No FPU */ + } +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + +/* ##################################### Debug In/Output function ########################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_core_DebugFunctions ITM Functions + \brief Functions that access the ITM debug interface. + @{ + */ + +extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ +#define ITM_RXBUFFER_EMPTY ((int32_t)0x5AA55AA5U) /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ + + +/** + \brief ITM Send Character + \details Transmits a character via the ITM channel 0, and + \li Just returns when no debugger is connected that has booked the output. + \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. + \param [in] ch Character to transmit. + \returns Character to transmit. + */ +__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) +{ + if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ + ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */ + { + while (ITM->PORT[0U].u32 == 0UL) + { + __NOP(); + } + ITM->PORT[0U].u8 = (uint8_t)ch; + } + return (ch); +} + + +/** + \brief ITM Receive Character + \details Inputs a character via the external variable \ref ITM_RxBuffer. + \return Received character. + \return -1 No character pending. + */ +__STATIC_INLINE int32_t ITM_ReceiveChar (void) +{ + int32_t ch = -1; /* no character available */ + + if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) + { + ch = ITM_RxBuffer; + ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ + } + + return (ch); +} + + +/** + \brief ITM Check Character + \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. + \return 0 No character available. + \return 1 Character available. + */ +__STATIC_INLINE int32_t ITM_CheckChar (void) +{ + + if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) + { + return (0); /* no character available */ + } + else + { + return (1); /* character available */ + } +} + +/*@} end of CMSIS_core_DebugFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM4_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/cmsis/core_cm7.h b/cmsis/core_cm7.h new file mode 100644 index 00000000000..fee3d0c977a --- /dev/null +++ b/cmsis/core_cm7.h @@ -0,0 +1,2646 @@ +/**************************************************************************//** + * @file core_cm7.h + * @brief CMSIS Cortex-M7 Core Peripheral Access Layer Header File + * @version V5.0.2 + * @date 13. February 2017 + ******************************************************************************/ +/* + * Copyright (c) 2009-2017 ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_CM7_H_GENERIC +#define __CORE_CM7_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex_M7 + @{ + */ + +/* CMSIS CM7 definitions */ +#define __CM7_CMSIS_VERSION_MAIN ( 5U) /*!< [31:16] CMSIS HAL main version */ +#define __CM7_CMSIS_VERSION_SUB ( 0U) /*!< [15:0] CMSIS HAL sub version */ +#define __CM7_CMSIS_VERSION ((__CM7_CMSIS_VERSION_MAIN << 16U) | \ + __CM7_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */ + +#define __CORTEX_M (7U) /*!< Cortex-M Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + For this, __FPU_PRESENT has to be checked prior to making use of FPU specific registers and functions. +*/ +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_PCS_VFP + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM7_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM7_H_DEPENDANT +#define __CORE_CM7_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM7_REV + #define __CM7_REV 0x0000U + #warning "__CM7_REV not defined in device header file; using default!" + #endif + + #ifndef __FPU_PRESENT + #define __FPU_PRESENT 0U + #warning "__FPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __ICACHE_PRESENT + #define __ICACHE_PRESENT 0U + #warning "__ICACHE_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __DCACHE_PRESENT + #define __DCACHE_PRESENT 0U + #warning "__DCACHE_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __DTCM_PRESENT + #define __DTCM_PRESENT 0U + #warning "__DTCM_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 3U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group Cortex_M7 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + - Core FPU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + 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 */ + 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; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + +#define APSR_Q_Pos 27U /*!< APSR: Q Position */ +#define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */ + +#define APSR_GE_Pos 16U /*!< APSR: GE Position */ +#define APSR_GE_Msk (0xFUL << APSR_GE_Pos) /*!< APSR: GE Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:1; /*!< bit: 9 Reserved */ + uint32_t ICI_IT_1:6; /*!< bit: 10..15 ICI/IT part 1 */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit */ + uint32_t ICI_IT_2:2; /*!< bit: 25..26 ICI/IT part 2 */ + 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; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_Q_Pos 27U /*!< xPSR: Q Position */ +#define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */ + +#define xPSR_ICI_IT_2_Pos 25U /*!< xPSR: ICI/IT part 2 Position */ +#define xPSR_ICI_IT_2_Msk (3UL << xPSR_ICI_IT_2_Pos) /*!< xPSR: ICI/IT part 2 Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_GE_Pos 16U /*!< xPSR: GE Position */ +#define xPSR_GE_Msk (0xFUL << xPSR_GE_Pos) /*!< xPSR: GE Mask */ + +#define xPSR_ICI_IT_1_Pos 10U /*!< xPSR: ICI/IT part 1 Position */ +#define xPSR_ICI_IT_1_Msk (0x3FUL << xPSR_ICI_IT_1_Pos) /*!< xPSR: ICI/IT part 1 Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t 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; + +/* CONTROL Register Definitions */ +#define CONTROL_FPCA_Pos 2U /*!< CONTROL: FPCA Position */ +#define CONTROL_FPCA_Msk (1UL << CONTROL_FPCA_Pos) /*!< CONTROL: FPCA Mask */ + +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[8U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[24U]; + __IOM uint32_t ICER[8U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[24U]; + __IOM uint32_t ISPR[8U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[24U]; + __IOM uint32_t ICPR[8U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[24U]; + __IOM uint32_t IABR[8U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[56U]; + __IOM uint8_t IP[240U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED5[644U]; + __OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; + +/* Software Triggered Interrupt Register Definitions */ +#define NVIC_STIR_INTID_Pos 0U /*!< STIR: INTLINESNUM Position */ +#define NVIC_STIR_INTID_Msk (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/) /*!< STIR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + __IOM uint8_t SHPR[12U]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IOM uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IOM uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IOM uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IOM uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IOM uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IOM uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __IM uint32_t ID_PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __IM uint32_t ID_DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __IM uint32_t ID_AFR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __IM uint32_t ID_MFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __IM uint32_t ID_ISAR[5U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + uint32_t RESERVED0[1U]; + __IM uint32_t CLIDR; /*!< Offset: 0x078 (R/ ) Cache Level ID register */ + __IM uint32_t CTR; /*!< Offset: 0x07C (R/ ) Cache Type register */ + __IM uint32_t CCSIDR; /*!< Offset: 0x080 (R/ ) Cache Size ID Register */ + __IOM uint32_t CSSELR; /*!< Offset: 0x084 (R/W) Cache Size Selection Register */ + __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ + uint32_t RESERVED3[93U]; + __OM uint32_t STIR; /*!< Offset: 0x200 ( /W) Software Triggered Interrupt Register */ + uint32_t RESERVED4[15U]; + __IM uint32_t MVFR0; /*!< Offset: 0x240 (R/ ) Media and VFP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x244 (R/ ) Media and VFP Feature Register 1 */ + __IM uint32_t MVFR2; /*!< Offset: 0x248 (R/ ) Media and VFP Feature Register 1 */ + uint32_t RESERVED5[1U]; + __OM uint32_t ICIALLU; /*!< Offset: 0x250 ( /W) I-Cache Invalidate All to PoU */ + uint32_t RESERVED6[1U]; + __OM uint32_t ICIMVAU; /*!< Offset: 0x258 ( /W) I-Cache Invalidate by MVA to PoU */ + __OM uint32_t DCIMVAC; /*!< Offset: 0x25C ( /W) D-Cache Invalidate by MVA to PoC */ + __OM uint32_t DCISW; /*!< Offset: 0x260 ( /W) D-Cache Invalidate by Set-way */ + __OM uint32_t DCCMVAU; /*!< Offset: 0x264 ( /W) D-Cache Clean by MVA to PoU */ + __OM uint32_t DCCMVAC; /*!< Offset: 0x268 ( /W) D-Cache Clean by MVA to PoC */ + __OM uint32_t DCCSW; /*!< Offset: 0x26C ( /W) D-Cache Clean by Set-way */ + __OM uint32_t DCCIMVAC; /*!< Offset: 0x270 ( /W) D-Cache Clean and Invalidate by MVA to PoC */ + __OM uint32_t DCCISW; /*!< Offset: 0x274 ( /W) D-Cache Clean and Invalidate by Set-way */ + uint32_t RESERVED7[6U]; + __IOM uint32_t ITCMCR; /*!< Offset: 0x290 (R/W) Instruction Tightly-Coupled Memory Control Register */ + __IOM uint32_t DTCMCR; /*!< Offset: 0x294 (R/W) Data Tightly-Coupled Memory Control Registers */ + __IOM uint32_t AHBPCR; /*!< Offset: 0x298 (R/W) AHBP Control Register */ + __IOM uint32_t CACR; /*!< Offset: 0x29C (R/W) L1 Cache Control Register */ + __IOM uint32_t AHBSCR; /*!< Offset: 0x2A0 (R/W) AHB Slave Control Register */ + uint32_t RESERVED8[1U]; + __IOM uint32_t ABFSR; /*!< Offset: 0x2A8 (R/W) Auxiliary Bus Fault Status Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Vector Table Offset Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 7U /*!< 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 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */ +#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +#define SCB_AIRCR_VECTRESET_Pos 0U /*!< 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 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_BP_Pos 18U /*!< SCB CCR: Branch prediction enable bit Position */ +#define SCB_CCR_BP_Msk (1UL << SCB_CCR_BP_Pos) /*!< SCB CCR: Branch prediction enable bit Mask */ + +#define SCB_CCR_IC_Pos 17U /*!< SCB CCR: Instruction cache enable bit Position */ +#define SCB_CCR_IC_Msk (1UL << SCB_CCR_IC_Pos) /*!< SCB CCR: Instruction cache enable bit Mask */ + +#define SCB_CCR_DC_Pos 16U /*!< SCB CCR: Cache enable bit Position */ +#define SCB_CCR_DC_Msk (1UL << SCB_CCR_DC_Pos) /*!< SCB CCR: Cache enable bit Mask */ + +#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< 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 4U /*!< 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 3U /*!< 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 1U /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +#define SCB_CCR_NONBASETHRDENA_Pos 0U /*!< 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 18U /*!< SCB SHCSR: USGFAULTENA Position */ +#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ + +#define SCB_SHCSR_BUSFAULTENA_Pos 17U /*!< SCB SHCSR: BUSFAULTENA Position */ +#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ + +#define SCB_SHCSR_MEMFAULTENA_Pos 16U /*!< SCB SHCSR: MEMFAULTENA Position */ +#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_BUSFAULTPENDED_Pos 14U /*!< SCB SHCSR: BUSFAULTPENDED Position */ +#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ + +#define SCB_SHCSR_MEMFAULTPENDED_Pos 13U /*!< SCB SHCSR: MEMFAULTPENDED Position */ +#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ + +#define SCB_SHCSR_USGFAULTPENDED_Pos 12U /*!< SCB SHCSR: USGFAULTPENDED Position */ +#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_MONITORACT_Pos 8U /*!< SCB SHCSR: MONITORACT Position */ +#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_USGFAULTACT_Pos 3U /*!< SCB SHCSR: USGFAULTACT Position */ +#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ + +#define SCB_SHCSR_BUSFAULTACT_Pos 1U /*!< SCB SHCSR: BUSFAULTACT Position */ +#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ + +#define SCB_SHCSR_MEMFAULTACT_Pos 0U /*!< SCB SHCSR: MEMFAULTACT Position */ +#define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */ + +/* SCB Configurable Fault Status Register Definitions */ +#define SCB_CFSR_USGFAULTSR_Pos 16U /*!< 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 8U /*!< 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 0U /*!< 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 */ + +/* MemManage Fault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_MMARVALID_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 7U) /*!< SCB CFSR (MMFSR): MMARVALID Position */ +#define SCB_CFSR_MMARVALID_Msk (1UL << SCB_CFSR_MMARVALID_Pos) /*!< SCB CFSR (MMFSR): MMARVALID Mask */ + +#define SCB_CFSR_MLSPERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 5U) /*!< SCB CFSR (MMFSR): MLSPERR Position */ +#define SCB_CFSR_MLSPERR_Msk (1UL << SCB_CFSR_MLSPERR_Pos) /*!< SCB CFSR (MMFSR): MLSPERR Mask */ + +#define SCB_CFSR_MSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 4U) /*!< SCB CFSR (MMFSR): MSTKERR Position */ +#define SCB_CFSR_MSTKERR_Msk (1UL << SCB_CFSR_MSTKERR_Pos) /*!< SCB CFSR (MMFSR): MSTKERR Mask */ + +#define SCB_CFSR_MUNSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 3U) /*!< SCB CFSR (MMFSR): MUNSTKERR Position */ +#define SCB_CFSR_MUNSTKERR_Msk (1UL << SCB_CFSR_MUNSTKERR_Pos) /*!< SCB CFSR (MMFSR): MUNSTKERR Mask */ + +#define SCB_CFSR_DACCVIOL_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 1U) /*!< SCB CFSR (MMFSR): DACCVIOL Position */ +#define SCB_CFSR_DACCVIOL_Msk (1UL << SCB_CFSR_DACCVIOL_Pos) /*!< SCB CFSR (MMFSR): DACCVIOL Mask */ + +#define SCB_CFSR_IACCVIOL_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 0U) /*!< SCB CFSR (MMFSR): IACCVIOL Position */ +#define SCB_CFSR_IACCVIOL_Msk (1UL /*<< SCB_CFSR_IACCVIOL_Pos*/) /*!< SCB CFSR (MMFSR): IACCVIOL Mask */ + +/* BusFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_BFARVALID_Pos (SCB_CFSR_BUSFAULTSR_Pos + 7U) /*!< SCB CFSR (BFSR): BFARVALID Position */ +#define SCB_CFSR_BFARVALID_Msk (1UL << SCB_CFSR_BFARVALID_Pos) /*!< SCB CFSR (BFSR): BFARVALID Mask */ + +#define SCB_CFSR_LSPERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 5U) /*!< SCB CFSR (BFSR): LSPERR Position */ +#define SCB_CFSR_LSPERR_Msk (1UL << SCB_CFSR_LSPERR_Pos) /*!< SCB CFSR (BFSR): LSPERR Mask */ + +#define SCB_CFSR_STKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 4U) /*!< SCB CFSR (BFSR): STKERR Position */ +#define SCB_CFSR_STKERR_Msk (1UL << SCB_CFSR_STKERR_Pos) /*!< SCB CFSR (BFSR): STKERR Mask */ + +#define SCB_CFSR_UNSTKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 3U) /*!< SCB CFSR (BFSR): UNSTKERR Position */ +#define SCB_CFSR_UNSTKERR_Msk (1UL << SCB_CFSR_UNSTKERR_Pos) /*!< SCB CFSR (BFSR): UNSTKERR Mask */ + +#define SCB_CFSR_IMPRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 2U) /*!< SCB CFSR (BFSR): IMPRECISERR Position */ +#define SCB_CFSR_IMPRECISERR_Msk (1UL << SCB_CFSR_IMPRECISERR_Pos) /*!< SCB CFSR (BFSR): IMPRECISERR Mask */ + +#define SCB_CFSR_PRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 1U) /*!< SCB CFSR (BFSR): PRECISERR Position */ +#define SCB_CFSR_PRECISERR_Msk (1UL << SCB_CFSR_PRECISERR_Pos) /*!< SCB CFSR (BFSR): PRECISERR Mask */ + +#define SCB_CFSR_IBUSERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 0U) /*!< SCB CFSR (BFSR): IBUSERR Position */ +#define SCB_CFSR_IBUSERR_Msk (1UL << SCB_CFSR_IBUSERR_Pos) /*!< SCB CFSR (BFSR): IBUSERR Mask */ + +/* UsageFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_DIVBYZERO_Pos (SCB_CFSR_USGFAULTSR_Pos + 9U) /*!< SCB CFSR (UFSR): DIVBYZERO Position */ +#define SCB_CFSR_DIVBYZERO_Msk (1UL << SCB_CFSR_DIVBYZERO_Pos) /*!< SCB CFSR (UFSR): DIVBYZERO Mask */ + +#define SCB_CFSR_UNALIGNED_Pos (SCB_CFSR_USGFAULTSR_Pos + 8U) /*!< SCB CFSR (UFSR): UNALIGNED Position */ +#define SCB_CFSR_UNALIGNED_Msk (1UL << SCB_CFSR_UNALIGNED_Pos) /*!< SCB CFSR (UFSR): UNALIGNED Mask */ + +#define SCB_CFSR_NOCP_Pos (SCB_CFSR_USGFAULTSR_Pos + 3U) /*!< SCB CFSR (UFSR): NOCP Position */ +#define SCB_CFSR_NOCP_Msk (1UL << SCB_CFSR_NOCP_Pos) /*!< SCB CFSR (UFSR): NOCP Mask */ + +#define SCB_CFSR_INVPC_Pos (SCB_CFSR_USGFAULTSR_Pos + 2U) /*!< SCB CFSR (UFSR): INVPC Position */ +#define SCB_CFSR_INVPC_Msk (1UL << SCB_CFSR_INVPC_Pos) /*!< SCB CFSR (UFSR): INVPC Mask */ + +#define SCB_CFSR_INVSTATE_Pos (SCB_CFSR_USGFAULTSR_Pos + 1U) /*!< SCB CFSR (UFSR): INVSTATE Position */ +#define SCB_CFSR_INVSTATE_Msk (1UL << SCB_CFSR_INVSTATE_Pos) /*!< SCB CFSR (UFSR): INVSTATE Mask */ + +#define SCB_CFSR_UNDEFINSTR_Pos (SCB_CFSR_USGFAULTSR_Pos + 0U) /*!< SCB CFSR (UFSR): UNDEFINSTR Position */ +#define SCB_CFSR_UNDEFINSTR_Msk (1UL << SCB_CFSR_UNDEFINSTR_Pos) /*!< SCB CFSR (UFSR): UNDEFINSTR Mask */ + +/* SCB Hard Fault Status Register Definitions */ +#define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */ +#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ + +#define SCB_HFSR_FORCED_Pos 30U /*!< SCB HFSR: FORCED Position */ +#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ + +#define SCB_HFSR_VECTTBL_Pos 1U /*!< 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 4U /*!< SCB DFSR: EXTERNAL Position */ +#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ + +#define SCB_DFSR_VCATCH_Pos 3U /*!< SCB DFSR: VCATCH Position */ +#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ + +#define SCB_DFSR_DWTTRAP_Pos 2U /*!< SCB DFSR: DWTTRAP Position */ +#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ + +#define SCB_DFSR_BKPT_Pos 1U /*!< SCB DFSR: BKPT Position */ +#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ + +#define SCB_DFSR_HALTED_Pos 0U /*!< SCB DFSR: HALTED Position */ +#define SCB_DFSR_HALTED_Msk (1UL /*<< SCB_DFSR_HALTED_Pos*/) /*!< SCB DFSR: HALTED Mask */ + +/* SCB Cache Level ID Register Definitions */ +#define SCB_CLIDR_LOUU_Pos 27U /*!< SCB CLIDR: LoUU Position */ +#define SCB_CLIDR_LOUU_Msk (7UL << SCB_CLIDR_LOUU_Pos) /*!< SCB CLIDR: LoUU Mask */ + +#define SCB_CLIDR_LOC_Pos 24U /*!< SCB CLIDR: LoC Position */ +#define SCB_CLIDR_LOC_Msk (7UL << SCB_CLIDR_LOC_Pos) /*!< SCB CLIDR: LoC Mask */ + +/* SCB Cache Type Register Definitions */ +#define SCB_CTR_FORMAT_Pos 29U /*!< SCB CTR: Format Position */ +#define SCB_CTR_FORMAT_Msk (7UL << SCB_CTR_FORMAT_Pos) /*!< SCB CTR: Format Mask */ + +#define SCB_CTR_CWG_Pos 24U /*!< SCB CTR: CWG Position */ +#define SCB_CTR_CWG_Msk (0xFUL << SCB_CTR_CWG_Pos) /*!< SCB CTR: CWG Mask */ + +#define SCB_CTR_ERG_Pos 20U /*!< SCB CTR: ERG Position */ +#define SCB_CTR_ERG_Msk (0xFUL << SCB_CTR_ERG_Pos) /*!< SCB CTR: ERG Mask */ + +#define SCB_CTR_DMINLINE_Pos 16U /*!< SCB CTR: DminLine Position */ +#define SCB_CTR_DMINLINE_Msk (0xFUL << SCB_CTR_DMINLINE_Pos) /*!< SCB CTR: DminLine Mask */ + +#define SCB_CTR_IMINLINE_Pos 0U /*!< SCB CTR: ImInLine Position */ +#define SCB_CTR_IMINLINE_Msk (0xFUL /*<< SCB_CTR_IMINLINE_Pos*/) /*!< SCB CTR: ImInLine Mask */ + +/* SCB Cache Size ID Register Definitions */ +#define SCB_CCSIDR_WT_Pos 31U /*!< SCB CCSIDR: WT Position */ +#define SCB_CCSIDR_WT_Msk (1UL << SCB_CCSIDR_WT_Pos) /*!< SCB CCSIDR: WT Mask */ + +#define SCB_CCSIDR_WB_Pos 30U /*!< SCB CCSIDR: WB Position */ +#define SCB_CCSIDR_WB_Msk (1UL << SCB_CCSIDR_WB_Pos) /*!< SCB CCSIDR: WB Mask */ + +#define SCB_CCSIDR_RA_Pos 29U /*!< SCB CCSIDR: RA Position */ +#define SCB_CCSIDR_RA_Msk (1UL << SCB_CCSIDR_RA_Pos) /*!< SCB CCSIDR: RA Mask */ + +#define SCB_CCSIDR_WA_Pos 28U /*!< SCB CCSIDR: WA Position */ +#define SCB_CCSIDR_WA_Msk (1UL << SCB_CCSIDR_WA_Pos) /*!< SCB CCSIDR: WA Mask */ + +#define SCB_CCSIDR_NUMSETS_Pos 13U /*!< SCB CCSIDR: NumSets Position */ +#define SCB_CCSIDR_NUMSETS_Msk (0x7FFFUL << SCB_CCSIDR_NUMSETS_Pos) /*!< SCB CCSIDR: NumSets Mask */ + +#define SCB_CCSIDR_ASSOCIATIVITY_Pos 3U /*!< SCB CCSIDR: Associativity Position */ +#define SCB_CCSIDR_ASSOCIATIVITY_Msk (0x3FFUL << SCB_CCSIDR_ASSOCIATIVITY_Pos) /*!< SCB CCSIDR: Associativity Mask */ + +#define SCB_CCSIDR_LINESIZE_Pos 0U /*!< SCB CCSIDR: LineSize Position */ +#define SCB_CCSIDR_LINESIZE_Msk (7UL /*<< SCB_CCSIDR_LINESIZE_Pos*/) /*!< SCB CCSIDR: LineSize Mask */ + +/* SCB Cache Size Selection Register Definitions */ +#define SCB_CSSELR_LEVEL_Pos 1U /*!< SCB CSSELR: Level Position */ +#define SCB_CSSELR_LEVEL_Msk (7UL << SCB_CSSELR_LEVEL_Pos) /*!< SCB CSSELR: Level Mask */ + +#define SCB_CSSELR_IND_Pos 0U /*!< SCB CSSELR: InD Position */ +#define SCB_CSSELR_IND_Msk (1UL /*<< SCB_CSSELR_IND_Pos*/) /*!< SCB CSSELR: InD Mask */ + +/* SCB Software Triggered Interrupt Register Definitions */ +#define SCB_STIR_INTID_Pos 0U /*!< SCB STIR: INTID Position */ +#define SCB_STIR_INTID_Msk (0x1FFUL /*<< SCB_STIR_INTID_Pos*/) /*!< SCB STIR: INTID Mask */ + +/* SCB D-Cache Invalidate by Set-way Register Definitions */ +#define SCB_DCISW_WAY_Pos 30U /*!< SCB DCISW: Way Position */ +#define SCB_DCISW_WAY_Msk (3UL << SCB_DCISW_WAY_Pos) /*!< SCB DCISW: Way Mask */ + +#define SCB_DCISW_SET_Pos 5U /*!< SCB DCISW: Set Position */ +#define SCB_DCISW_SET_Msk (0x1FFUL << SCB_DCISW_SET_Pos) /*!< SCB DCISW: Set Mask */ + +/* SCB D-Cache Clean by Set-way Register Definitions */ +#define SCB_DCCSW_WAY_Pos 30U /*!< SCB DCCSW: Way Position */ +#define SCB_DCCSW_WAY_Msk (3UL << SCB_DCCSW_WAY_Pos) /*!< SCB DCCSW: Way Mask */ + +#define SCB_DCCSW_SET_Pos 5U /*!< SCB DCCSW: Set Position */ +#define SCB_DCCSW_SET_Msk (0x1FFUL << SCB_DCCSW_SET_Pos) /*!< SCB DCCSW: Set Mask */ + +/* SCB D-Cache Clean and Invalidate by Set-way Register Definitions */ +#define SCB_DCCISW_WAY_Pos 30U /*!< SCB DCCISW: Way Position */ +#define SCB_DCCISW_WAY_Msk (3UL << SCB_DCCISW_WAY_Pos) /*!< SCB DCCISW: Way Mask */ + +#define SCB_DCCISW_SET_Pos 5U /*!< SCB DCCISW: Set Position */ +#define SCB_DCCISW_SET_Msk (0x1FFUL << SCB_DCCISW_SET_Pos) /*!< SCB DCCISW: Set Mask */ + +/* Instruction Tightly-Coupled Memory Control Register Definitions */ +#define SCB_ITCMCR_SZ_Pos 3U /*!< SCB ITCMCR: SZ Position */ +#define SCB_ITCMCR_SZ_Msk (0xFUL << SCB_ITCMCR_SZ_Pos) /*!< SCB ITCMCR: SZ Mask */ + +#define SCB_ITCMCR_RETEN_Pos 2U /*!< SCB ITCMCR: RETEN Position */ +#define SCB_ITCMCR_RETEN_Msk (1UL << SCB_ITCMCR_RETEN_Pos) /*!< SCB ITCMCR: RETEN Mask */ + +#define SCB_ITCMCR_RMW_Pos 1U /*!< SCB ITCMCR: RMW Position */ +#define SCB_ITCMCR_RMW_Msk (1UL << SCB_ITCMCR_RMW_Pos) /*!< SCB ITCMCR: RMW Mask */ + +#define SCB_ITCMCR_EN_Pos 0U /*!< SCB ITCMCR: EN Position */ +#define SCB_ITCMCR_EN_Msk (1UL /*<< SCB_ITCMCR_EN_Pos*/) /*!< SCB ITCMCR: EN Mask */ + +/* Data Tightly-Coupled Memory Control Register Definitions */ +#define SCB_DTCMCR_SZ_Pos 3U /*!< SCB DTCMCR: SZ Position */ +#define SCB_DTCMCR_SZ_Msk (0xFUL << SCB_DTCMCR_SZ_Pos) /*!< SCB DTCMCR: SZ Mask */ + +#define SCB_DTCMCR_RETEN_Pos 2U /*!< SCB DTCMCR: RETEN Position */ +#define SCB_DTCMCR_RETEN_Msk (1UL << SCB_DTCMCR_RETEN_Pos) /*!< SCB DTCMCR: RETEN Mask */ + +#define SCB_DTCMCR_RMW_Pos 1U /*!< SCB DTCMCR: RMW Position */ +#define SCB_DTCMCR_RMW_Msk (1UL << SCB_DTCMCR_RMW_Pos) /*!< SCB DTCMCR: RMW Mask */ + +#define SCB_DTCMCR_EN_Pos 0U /*!< SCB DTCMCR: EN Position */ +#define SCB_DTCMCR_EN_Msk (1UL /*<< SCB_DTCMCR_EN_Pos*/) /*!< SCB DTCMCR: EN Mask */ + +/* AHBP Control Register Definitions */ +#define SCB_AHBPCR_SZ_Pos 1U /*!< SCB AHBPCR: SZ Position */ +#define SCB_AHBPCR_SZ_Msk (7UL << SCB_AHBPCR_SZ_Pos) /*!< SCB AHBPCR: SZ Mask */ + +#define SCB_AHBPCR_EN_Pos 0U /*!< SCB AHBPCR: EN Position */ +#define SCB_AHBPCR_EN_Msk (1UL /*<< SCB_AHBPCR_EN_Pos*/) /*!< SCB AHBPCR: EN Mask */ + +/* L1 Cache Control Register Definitions */ +#define SCB_CACR_FORCEWT_Pos 2U /*!< SCB CACR: FORCEWT Position */ +#define SCB_CACR_FORCEWT_Msk (1UL << SCB_CACR_FORCEWT_Pos) /*!< SCB CACR: FORCEWT Mask */ + +#define SCB_CACR_ECCEN_Pos 1U /*!< SCB CACR: ECCEN Position */ +#define SCB_CACR_ECCEN_Msk (1UL << SCB_CACR_ECCEN_Pos) /*!< SCB CACR: ECCEN Mask */ + +#define SCB_CACR_SIWT_Pos 0U /*!< SCB CACR: SIWT Position */ +#define SCB_CACR_SIWT_Msk (1UL /*<< SCB_CACR_SIWT_Pos*/) /*!< SCB CACR: SIWT Mask */ + +/* AHBS Control Register Definitions */ +#define SCB_AHBSCR_INITCOUNT_Pos 11U /*!< SCB AHBSCR: INITCOUNT Position */ +#define SCB_AHBSCR_INITCOUNT_Msk (0x1FUL << SCB_AHBPCR_INITCOUNT_Pos) /*!< SCB AHBSCR: INITCOUNT Mask */ + +#define SCB_AHBSCR_TPRI_Pos 2U /*!< SCB AHBSCR: TPRI Position */ +#define SCB_AHBSCR_TPRI_Msk (0x1FFUL << SCB_AHBPCR_TPRI_Pos) /*!< SCB AHBSCR: TPRI Mask */ + +#define SCB_AHBSCR_CTL_Pos 0U /*!< SCB AHBSCR: CTL Position*/ +#define SCB_AHBSCR_CTL_Msk (3UL /*<< SCB_AHBPCR_CTL_Pos*/) /*!< SCB AHBSCR: CTL Mask */ + +/* Auxiliary Bus Fault Status Register Definitions */ +#define SCB_ABFSR_AXIMTYPE_Pos 8U /*!< SCB ABFSR: AXIMTYPE Position*/ +#define SCB_ABFSR_AXIMTYPE_Msk (3UL << SCB_ABFSR_AXIMTYPE_Pos) /*!< SCB ABFSR: AXIMTYPE Mask */ + +#define SCB_ABFSR_EPPB_Pos 4U /*!< SCB ABFSR: EPPB Position*/ +#define SCB_ABFSR_EPPB_Msk (1UL << SCB_ABFSR_EPPB_Pos) /*!< SCB ABFSR: EPPB Mask */ + +#define SCB_ABFSR_AXIM_Pos 3U /*!< SCB ABFSR: AXIM Position*/ +#define SCB_ABFSR_AXIM_Msk (1UL << SCB_ABFSR_AXIM_Pos) /*!< SCB ABFSR: AXIM Mask */ + +#define SCB_ABFSR_AHBP_Pos 2U /*!< SCB ABFSR: AHBP Position*/ +#define SCB_ABFSR_AHBP_Msk (1UL << SCB_ABFSR_AHBP_Pos) /*!< SCB ABFSR: AHBP Mask */ + +#define SCB_ABFSR_DTCM_Pos 1U /*!< SCB ABFSR: DTCM Position*/ +#define SCB_ABFSR_DTCM_Msk (1UL << SCB_ABFSR_DTCM_Pos) /*!< SCB ABFSR: DTCM Mask */ + +#define SCB_ABFSR_ITCM_Pos 0U /*!< SCB ABFSR: ITCM Position*/ +#define SCB_ABFSR_ITCM_Msk (1UL /*<< SCB_ABFSR_ITCM_Pos*/) /*!< SCB ABFSR: ITCM Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** + \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IM uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ + __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ +} SCnSCB_Type; + +/* Interrupt Controller Type Register Definitions */ +#define SCnSCB_ICTR_INTLINESNUM_Pos 0U /*!< ICTR: INTLINESNUM Position */ +#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/) /*!< ICTR: INTLINESNUM Mask */ + +/* Auxiliary Control Register Definitions */ +#define SCnSCB_ACTLR_DISITMATBFLUSH_Pos 12U /*!< ACTLR: DISITMATBFLUSH Position */ +#define SCnSCB_ACTLR_DISITMATBFLUSH_Msk (1UL << SCnSCB_ACTLR_DISITMATBFLUSH_Pos) /*!< ACTLR: DISITMATBFLUSH Mask */ + +#define SCnSCB_ACTLR_DISRAMODE_Pos 11U /*!< ACTLR: DISRAMODE Position */ +#define SCnSCB_ACTLR_DISRAMODE_Msk (1UL << SCnSCB_ACTLR_DISRAMODE_Pos) /*!< ACTLR: DISRAMODE Mask */ + +#define SCnSCB_ACTLR_FPEXCODIS_Pos 10U /*!< ACTLR: FPEXCODIS Position */ +#define SCnSCB_ACTLR_FPEXCODIS_Msk (1UL << SCnSCB_ACTLR_FPEXCODIS_Pos) /*!< ACTLR: FPEXCODIS Mask */ + +#define SCnSCB_ACTLR_DISFOLD_Pos 2U /*!< ACTLR: DISFOLD Position */ +#define SCnSCB_ACTLR_DISFOLD_Msk (1UL << SCnSCB_ACTLR_DISFOLD_Pos) /*!< ACTLR: DISFOLD Mask */ + +#define SCnSCB_ACTLR_DISMCYCINT_Pos 0U /*!< ACTLR: DISMCYCINT Position */ +#define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL /*<< SCnSCB_ACTLR_DISMCYCINT_Pos*/) /*!< ACTLR: DISMCYCINT Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) + \brief Type definitions for the Instrumentation Trace Macrocell (ITM) + @{ + */ + +/** + \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). + */ +typedef struct +{ + __OM union + { + __OM uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ + __OM uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ + __OM uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ + } PORT [32U]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ + uint32_t RESERVED0[864U]; + __IOM uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ + uint32_t RESERVED1[15U]; + __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ + uint32_t RESERVED2[15U]; + __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ + uint32_t RESERVED3[29U]; + __OM uint32_t IWR; /*!< Offset: 0xEF8 ( /W) ITM Integration Write Register */ + __IM uint32_t IRR; /*!< Offset: 0xEFC (R/ ) ITM Integration Read Register */ + __IOM uint32_t IMCR; /*!< Offset: 0xF00 (R/W) ITM Integration Mode Control Register */ + uint32_t RESERVED4[43U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ + uint32_t RESERVED5[6U]; + __IM uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ + __IM uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ + __IM uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ + __IM uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ + __IM uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ + __IM uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ + __IM uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ + __IM uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ + __IM uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ + __IM uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ + __IM uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ + __IM uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ +} ITM_Type; + +/* ITM Trace Privilege Register Definitions */ +#define ITM_TPR_PRIVMASK_Pos 0U /*!< 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 23U /*!< ITM TCR: BUSY Position */ +#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ + +#define ITM_TCR_TraceBusID_Pos 16U /*!< ITM TCR: ATBID Position */ +#define ITM_TCR_TraceBusID_Msk (0x7FUL << ITM_TCR_TraceBusID_Pos) /*!< ITM TCR: ATBID Mask */ + +#define ITM_TCR_GTSFREQ_Pos 10U /*!< 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 8U /*!< ITM TCR: TSPrescale Position */ +#define ITM_TCR_TSPrescale_Msk (3UL << ITM_TCR_TSPrescale_Pos) /*!< ITM TCR: TSPrescale Mask */ + +#define ITM_TCR_SWOENA_Pos 4U /*!< ITM TCR: SWOENA Position */ +#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ + +#define ITM_TCR_DWTENA_Pos 3U /*!< ITM TCR: DWTENA Position */ +#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ + +#define ITM_TCR_SYNCENA_Pos 2U /*!< ITM TCR: SYNCENA Position */ +#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ + +#define ITM_TCR_TSENA_Pos 1U /*!< ITM TCR: TSENA Position */ +#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ + +#define ITM_TCR_ITMENA_Pos 0U /*!< ITM TCR: ITM Enable bit Position */ +#define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */ + +/* ITM Integration Write Register Definitions */ +#define ITM_IWR_ATVALIDM_Pos 0U /*!< ITM IWR: ATVALIDM Position */ +#define ITM_IWR_ATVALIDM_Msk (1UL /*<< ITM_IWR_ATVALIDM_Pos*/) /*!< ITM IWR: ATVALIDM Mask */ + +/* ITM Integration Read Register Definitions */ +#define ITM_IRR_ATREADYM_Pos 0U /*!< ITM IRR: ATREADYM Position */ +#define ITM_IRR_ATREADYM_Msk (1UL /*<< ITM_IRR_ATREADYM_Pos*/) /*!< ITM IRR: ATREADYM Mask */ + +/* ITM Integration Mode Control Register Definitions */ +#define ITM_IMCR_INTEGRATION_Pos 0U /*!< ITM IMCR: INTEGRATION Position */ +#define ITM_IMCR_INTEGRATION_Msk (1UL /*<< ITM_IMCR_INTEGRATION_Pos*/) /*!< ITM IMCR: INTEGRATION Mask */ + +/* ITM Lock Status Register Definitions */ +#define ITM_LSR_ByteAcc_Pos 2U /*!< ITM LSR: ByteAcc Position */ +#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ + +#define ITM_LSR_Access_Pos 1U /*!< ITM LSR: Access Position */ +#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ + +#define ITM_LSR_Present_Pos 0U /*!< ITM LSR: Present Position */ +#define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */ + +/*@}*/ /* end of group CMSIS_ITM */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** + \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + __IOM uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ + __IOM uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ + __IOM uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ + __IOM uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ + __IOM uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ + __IOM uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ + __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + __IOM uint32_t MASK0; /*!< Offset: 0x024 (R/W) Mask Register 0 */ + __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED0[1U]; + __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + __IOM uint32_t MASK1; /*!< Offset: 0x034 (R/W) Mask Register 1 */ + __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED1[1U]; + __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + __IOM uint32_t MASK2; /*!< Offset: 0x044 (R/W) Mask Register 2 */ + __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + __IOM uint32_t MASK3; /*!< Offset: 0x054 (R/W) Mask Register 3 */ + __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ + uint32_t RESERVED3[981U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( W) Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R ) Lock Status Register */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +#define DWT_CTRL_CYCEVTENA_Pos 22U /*!< DWT CTRL: CYCEVTENA Position */ +#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ + +#define DWT_CTRL_FOLDEVTENA_Pos 21U /*!< DWT CTRL: FOLDEVTENA Position */ +#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ + +#define DWT_CTRL_LSUEVTENA_Pos 20U /*!< DWT CTRL: LSUEVTENA Position */ +#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ + +#define DWT_CTRL_SLEEPEVTENA_Pos 19U /*!< DWT CTRL: SLEEPEVTENA Position */ +#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ + +#define DWT_CTRL_EXCEVTENA_Pos 18U /*!< DWT CTRL: EXCEVTENA Position */ +#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ + +#define DWT_CTRL_CPIEVTENA_Pos 17U /*!< DWT CTRL: CPIEVTENA Position */ +#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ + +#define DWT_CTRL_EXCTRCENA_Pos 16U /*!< DWT CTRL: EXCTRCENA Position */ +#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ + +#define DWT_CTRL_PCSAMPLENA_Pos 12U /*!< DWT CTRL: PCSAMPLENA Position */ +#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ + +#define DWT_CTRL_SYNCTAP_Pos 10U /*!< DWT CTRL: SYNCTAP Position */ +#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ + +#define DWT_CTRL_CYCTAP_Pos 9U /*!< DWT CTRL: CYCTAP Position */ +#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ + +#define DWT_CTRL_POSTINIT_Pos 5U /*!< DWT CTRL: POSTINIT Position */ +#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ + +#define DWT_CTRL_POSTPRESET_Pos 1U /*!< DWT CTRL: POSTPRESET Position */ +#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ + +#define DWT_CTRL_CYCCNTENA_Pos 0U /*!< DWT CTRL: CYCCNTENA Position */ +#define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */ + +/* DWT CPI Count Register Definitions */ +#define DWT_CPICNT_CPICNT_Pos 0U /*!< DWT CPICNT: CPICNT Position */ +#define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */ + +/* DWT Exception Overhead Count Register Definitions */ +#define DWT_EXCCNT_EXCCNT_Pos 0U /*!< DWT EXCCNT: EXCCNT Position */ +#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */ + +/* DWT Sleep Count Register Definitions */ +#define DWT_SLEEPCNT_SLEEPCNT_Pos 0U /*!< DWT SLEEPCNT: SLEEPCNT Position */ +#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ + +/* DWT LSU Count Register Definitions */ +#define DWT_LSUCNT_LSUCNT_Pos 0U /*!< DWT LSUCNT: LSUCNT Position */ +#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */ + +/* DWT Folded-instruction Count Register Definitions */ +#define DWT_FOLDCNT_FOLDCNT_Pos 0U /*!< DWT FOLDCNT: FOLDCNT Position */ +#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */ + +/* DWT Comparator Mask Register Definitions */ +#define DWT_MASK_MASK_Pos 0U /*!< DWT MASK: MASK Position */ +#define DWT_MASK_MASK_Msk (0x1FUL /*<< DWT_MASK_MASK_Pos*/) /*!< DWT MASK: MASK Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVADDR1_Pos 16U /*!< DWT FUNCTION: DATAVADDR1 Position */ +#define DWT_FUNCTION_DATAVADDR1_Msk (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos) /*!< DWT FUNCTION: DATAVADDR1 Mask */ + +#define DWT_FUNCTION_DATAVADDR0_Pos 12U /*!< DWT FUNCTION: DATAVADDR0 Position */ +#define DWT_FUNCTION_DATAVADDR0_Msk (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos) /*!< DWT FUNCTION: DATAVADDR0 Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_LNK1ENA_Pos 9U /*!< DWT FUNCTION: LNK1ENA Position */ +#define DWT_FUNCTION_LNK1ENA_Msk (0x1UL << DWT_FUNCTION_LNK1ENA_Pos) /*!< DWT FUNCTION: LNK1ENA Mask */ + +#define DWT_FUNCTION_DATAVMATCH_Pos 8U /*!< DWT FUNCTION: DATAVMATCH Position */ +#define DWT_FUNCTION_DATAVMATCH_Msk (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos) /*!< DWT FUNCTION: DATAVMATCH Mask */ + +#define DWT_FUNCTION_CYCMATCH_Pos 7U /*!< DWT FUNCTION: CYCMATCH Position */ +#define DWT_FUNCTION_CYCMATCH_Msk (0x1UL << DWT_FUNCTION_CYCMATCH_Pos) /*!< DWT FUNCTION: CYCMATCH Mask */ + +#define DWT_FUNCTION_EMITRANGE_Pos 5U /*!< DWT FUNCTION: EMITRANGE Position */ +#define DWT_FUNCTION_EMITRANGE_Msk (0x1UL << DWT_FUNCTION_EMITRANGE_Pos) /*!< DWT FUNCTION: EMITRANGE Mask */ + +#define DWT_FUNCTION_FUNCTION_Pos 0U /*!< DWT FUNCTION: FUNCTION Position */ +#define DWT_FUNCTION_FUNCTION_Msk (0xFUL /*<< DWT_FUNCTION_FUNCTION_Pos*/) /*!< DWT FUNCTION: FUNCTION Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** + \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IOM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55U]; + __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131U]; + __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __IM uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ + uint32_t RESERVED3[759U]; + __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER */ + __IM uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ + __IM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ + uint32_t RESERVED4[1U]; + __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */ + __IM uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */ + __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ + uint32_t RESERVED5[39U]; + __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ + __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ + uint32_t RESERVED7[8U]; + __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_PRESCALER_Pos 0U /*!< TPI ACPR: PRESCALER Position */ +#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< TPI ACPR: PRESCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI TRIGGER Register Definitions */ +#define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */ +#define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */ + +/* TPI Integration ETM Data Register Definitions (FIFO0) */ +#define TPI_FIFO0_ITM_ATVALID_Pos 29U /*!< TPI FIFO0: ITM_ATVALID Position */ +#define TPI_FIFO0_ITM_ATVALID_Msk (0x3UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ + +#define TPI_FIFO0_ITM_bytecount_Pos 27U /*!< TPI FIFO0: ITM_bytecount Position */ +#define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */ + +#define TPI_FIFO0_ETM_ATVALID_Pos 26U /*!< TPI FIFO0: ETM_ATVALID Position */ +#define TPI_FIFO0_ETM_ATVALID_Msk (0x3UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ + +#define TPI_FIFO0_ETM_bytecount_Pos 24U /*!< TPI FIFO0: ETM_bytecount Position */ +#define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */ + +#define TPI_FIFO0_ETM2_Pos 16U /*!< TPI FIFO0: ETM2 Position */ +#define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */ + +#define TPI_FIFO0_ETM1_Pos 8U /*!< TPI FIFO0: ETM1 Position */ +#define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */ + +#define TPI_FIFO0_ETM0_Pos 0U /*!< TPI FIFO0: ETM0 Position */ +#define TPI_FIFO0_ETM0_Msk (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/) /*!< TPI FIFO0: ETM0 Mask */ + +/* TPI ITATBCTR2 Register Definitions */ +#define TPI_ITATBCTR2_ATREADY_Pos 0U /*!< TPI ITATBCTR2: ATREADY Position */ +#define TPI_ITATBCTR2_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY_Pos*/) /*!< TPI ITATBCTR2: ATREADY Mask */ + +/* TPI Integration ITM Data Register Definitions (FIFO1) */ +#define TPI_FIFO1_ITM_ATVALID_Pos 29U /*!< TPI FIFO1: ITM_ATVALID Position */ +#define TPI_FIFO1_ITM_ATVALID_Msk (0x3UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ + +#define TPI_FIFO1_ITM_bytecount_Pos 27U /*!< TPI FIFO1: ITM_bytecount Position */ +#define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */ + +#define TPI_FIFO1_ETM_ATVALID_Pos 26U /*!< TPI FIFO1: ETM_ATVALID Position */ +#define TPI_FIFO1_ETM_ATVALID_Msk (0x3UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ + +#define TPI_FIFO1_ETM_bytecount_Pos 24U /*!< TPI FIFO1: ETM_bytecount Position */ +#define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */ + +#define TPI_FIFO1_ITM2_Pos 16U /*!< TPI FIFO1: ITM2 Position */ +#define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */ + +#define TPI_FIFO1_ITM1_Pos 8U /*!< TPI FIFO1: ITM1 Position */ +#define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */ + +#define TPI_FIFO1_ITM0_Pos 0U /*!< TPI FIFO1: ITM0 Position */ +#define TPI_FIFO1_ITM0_Msk (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/) /*!< TPI FIFO1: ITM0 Mask */ + +/* TPI ITATBCTR0 Register Definitions */ +#define TPI_ITATBCTR0_ATREADY_Pos 0U /*!< TPI ITATBCTR0: ATREADY Position */ +#define TPI_ITATBCTR0_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY_Pos*/) /*!< TPI ITATBCTR0: ATREADY Mask */ + +/* TPI Integration Mode Control Register Definitions */ +#define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ +#define TPI_ITCTRL_Mode_Msk (0x1UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_MinBufSz_Pos 6U /*!< TPI DEVID: MinBufSz Position */ +#define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */ + +#define TPI_DEVID_AsynClkIn_Pos 5U /*!< TPI DEVID: AsynClkIn Position */ +#define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */ + +#define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */ +#define TPI_DEVID_NrTraceInput_Msk (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_MajorType_Pos 4U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +#define TPI_DEVTYPE_SubType_Pos 0U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ + __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Alias 1 Region Base Address Register */ + __IOM uint32_t RASR_A1; /*!< Offset: 0x018 (R/W) MPU Alias 1 Region Attribute and Size Register */ + __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Alias 2 Region Base Address Register */ + __IOM uint32_t RASR_A2; /*!< Offset: 0x020 (R/W) MPU Alias 2 Region Attribute and Size Register */ + __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Alias 3 Region Base Address Register */ + __IOM uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */ +} MPU_Type; + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_ADDR_Pos 5U /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */ +#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ + +#define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */ +#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */ + +/* MPU Region Attribute and Size Register Definitions */ +#define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */ +#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ + +#define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */ +#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ + +#define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */ +#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ + +#define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */ +#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ + +#define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */ +#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ + +#define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */ +#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ + +#define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */ +#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ + +#define MPU_RASR_SRD_Pos 8U /*!< MPU RASR: Sub-Region Disable Position */ +#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ + +#define MPU_RASR_SIZE_Pos 1U /*!< MPU RASR: Region Size Field Position */ +#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ + +#define MPU_RASR_ENABLE_Pos 0U /*!< MPU RASR: Region enable bit Position */ +#define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */ + +/*@} end of group CMSIS_MPU */ +#endif /* defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_FPU Floating Point Unit (FPU) + \brief Type definitions for the Floating Point Unit (FPU) + @{ + */ + +/** + \brief Structure type to access the Floating Point Unit (FPU). + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IOM uint32_t FPCCR; /*!< Offset: 0x004 (R/W) Floating-Point Context Control Register */ + __IOM uint32_t FPCAR; /*!< Offset: 0x008 (R/W) Floating-Point Context Address Register */ + __IOM uint32_t FPDSCR; /*!< Offset: 0x00C (R/W) Floating-Point Default Status Control Register */ + __IM uint32_t MVFR0; /*!< Offset: 0x010 (R/ ) Media and FP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x014 (R/ ) Media and FP Feature Register 1 */ + __IM uint32_t MVFR2; /*!< Offset: 0x018 (R/ ) Media and FP Feature Register 2 */ +} FPU_Type; + +/* Floating-Point Context Control Register Definitions */ +#define FPU_FPCCR_ASPEN_Pos 31U /*!< FPCCR: ASPEN bit Position */ +#define FPU_FPCCR_ASPEN_Msk (1UL << FPU_FPCCR_ASPEN_Pos) /*!< FPCCR: ASPEN bit Mask */ + +#define FPU_FPCCR_LSPEN_Pos 30U /*!< FPCCR: LSPEN Position */ +#define FPU_FPCCR_LSPEN_Msk (1UL << FPU_FPCCR_LSPEN_Pos) /*!< FPCCR: LSPEN bit Mask */ + +#define FPU_FPCCR_MONRDY_Pos 8U /*!< FPCCR: MONRDY Position */ +#define FPU_FPCCR_MONRDY_Msk (1UL << FPU_FPCCR_MONRDY_Pos) /*!< FPCCR: MONRDY bit Mask */ + +#define FPU_FPCCR_BFRDY_Pos 6U /*!< FPCCR: BFRDY Position */ +#define FPU_FPCCR_BFRDY_Msk (1UL << FPU_FPCCR_BFRDY_Pos) /*!< FPCCR: BFRDY bit Mask */ + +#define FPU_FPCCR_MMRDY_Pos 5U /*!< FPCCR: MMRDY Position */ +#define FPU_FPCCR_MMRDY_Msk (1UL << FPU_FPCCR_MMRDY_Pos) /*!< FPCCR: MMRDY bit Mask */ + +#define FPU_FPCCR_HFRDY_Pos 4U /*!< FPCCR: HFRDY Position */ +#define FPU_FPCCR_HFRDY_Msk (1UL << FPU_FPCCR_HFRDY_Pos) /*!< FPCCR: HFRDY bit Mask */ + +#define FPU_FPCCR_THREAD_Pos 3U /*!< 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 1U /*!< 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 0U /*!< 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 Definitions */ +#define FPU_FPCAR_ADDRESS_Pos 3U /*!< FPCAR: ADDRESS bit Position */ +#define FPU_FPCAR_ADDRESS_Msk (0x1FFFFFFFUL << FPU_FPCAR_ADDRESS_Pos) /*!< FPCAR: ADDRESS bit Mask */ + +/* Floating-Point Default Status Control Register Definitions */ +#define FPU_FPDSCR_AHP_Pos 26U /*!< FPDSCR: AHP bit Position */ +#define FPU_FPDSCR_AHP_Msk (1UL << FPU_FPDSCR_AHP_Pos) /*!< FPDSCR: AHP bit Mask */ + +#define FPU_FPDSCR_DN_Pos 25U /*!< FPDSCR: DN bit Position */ +#define FPU_FPDSCR_DN_Msk (1UL << FPU_FPDSCR_DN_Pos) /*!< FPDSCR: DN bit Mask */ + +#define FPU_FPDSCR_FZ_Pos 24U /*!< FPDSCR: FZ bit Position */ +#define FPU_FPDSCR_FZ_Msk (1UL << FPU_FPDSCR_FZ_Pos) /*!< FPDSCR: FZ bit Mask */ + +#define FPU_FPDSCR_RMode_Pos 22U /*!< FPDSCR: RMode bit Position */ +#define FPU_FPDSCR_RMode_Msk (3UL << FPU_FPDSCR_RMode_Pos) /*!< FPDSCR: RMode bit Mask */ + +/* Media and FP Feature Register 0 Definitions */ +#define FPU_MVFR0_FP_rounding_modes_Pos 28U /*!< 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 24U /*!< 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 20U /*!< 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 16U /*!< 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 12U /*!< 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 8U /*!< 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 4U /*!< 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 0U /*!< 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 Definitions */ +#define FPU_MVFR1_FP_fused_MAC_Pos 28U /*!< 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 24U /*!< 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 4U /*!< 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 0U /*!< MVFR1: FtZ mode bits Position */ +#define FPU_MVFR1_FtZ_mode_Msk (0xFUL /*<< FPU_MVFR1_FtZ_mode_Pos*/) /*!< MVFR1: FtZ mode bits Mask */ + +/* Media and FP Feature Register 2 Definitions */ + +/*@} end of group CMSIS_FPU */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** + \brief Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register Definitions */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< 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 25U /*!< 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 24U /*!< 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 19U /*!< 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 18U /*!< 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 17U /*!< 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 16U /*!< 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 5U /*!< 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 3U /*!< 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 2U /*!< 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 1U /*!< 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 0U /*!< 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 Definitions */ +#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register Definitions */ +#define CoreDebug_DEMCR_TRCENA_Pos 24U /*!< CoreDebug DEMCR: TRCENA Position */ +#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ + +#define CoreDebug_DEMCR_MON_REQ_Pos 19U /*!< 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 18U /*!< 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 17U /*!< 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 16U /*!< 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 10U /*!< 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 9U /*!< 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 8U /*!< 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 7U /*!< 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 6U /*!< 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 5U /*!< 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 4U /*!< 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 0U /*!< CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ +#define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ +#define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ +#define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ +#define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ +#define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ +#define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ +#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ +#endif + +#define FPU_BASE (SCS_BASE + 0x0F30UL) /*!< Floating Point Unit */ +#define FPU ((FPU_Type *) FPU_BASE ) /*!< Floating Point Unit */ + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Debug Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping + #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ + #define NVIC_GetActive __NVIC_GetActive + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + + +/** + \brief Set Priority Grouping + \details 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)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << 8U) ); /* Insert write key and priorty group */ + SCB->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping + \details Reads the priority grouping field from the NVIC Interrupt Controller. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t __NVIC_GetPriorityGrouping(void) +{ + return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt + \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IABR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IP[((uint32_t)(int32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB->SHPR[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC->IP[((uint32_t)(int32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB->SHPR[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +/*@} end of CMSIS_Core_NVICFunctions */ + + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + uint32_t mvfr0; + + mvfr0 = SCB->MVFR0; + if ((mvfr0 & (FPU_MVFR0_Single_precision_Msk | FPU_MVFR0_Double_precision_Msk)) == 0x220U) + { + return 2U; /* Double + Single precision FPU */ + } + else if ((mvfr0 & (FPU_MVFR0_Single_precision_Msk | FPU_MVFR0_Double_precision_Msk)) == 0x020U) + { + return 1U; /* Single precision FPU */ + } + else + { + return 0U; /* No FPU */ + } +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ########################## Cache functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_CacheFunctions Cache Functions + \brief Functions that configure Instruction and Data cache. + @{ + */ + +/* Cache Size ID Register Macros */ +#define CCSIDR_WAYS(x) (((x) & SCB_CCSIDR_ASSOCIATIVITY_Msk) >> SCB_CCSIDR_ASSOCIATIVITY_Pos) +#define CCSIDR_SETS(x) (((x) & SCB_CCSIDR_NUMSETS_Msk ) >> SCB_CCSIDR_NUMSETS_Pos ) + + +/** + \brief Enable I-Cache + \details Turns on I-Cache + */ +__STATIC_INLINE void SCB_EnableICache (void) +{ + #if defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U) + __DSB(); + __ISB(); + SCB->ICIALLU = 0UL; /* invalidate I-Cache */ + __DSB(); + __ISB(); + SCB->CCR |= (uint32_t)SCB_CCR_IC_Msk; /* enable I-Cache */ + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Disable I-Cache + \details Turns off I-Cache + */ +__STATIC_INLINE void SCB_DisableICache (void) +{ + #if defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U) + __DSB(); + __ISB(); + SCB->CCR &= ~(uint32_t)SCB_CCR_IC_Msk; /* disable I-Cache */ + SCB->ICIALLU = 0UL; /* invalidate I-Cache */ + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Invalidate I-Cache + \details Invalidates I-Cache + */ +__STATIC_INLINE void SCB_InvalidateICache (void) +{ + #if defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U) + __DSB(); + __ISB(); + SCB->ICIALLU = 0UL; + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Enable D-Cache + \details Turns on D-Cache + */ +__STATIC_INLINE void SCB_EnableDCache (void) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + uint32_t ccsidr; + uint32_t sets; + uint32_t ways; + + SCB->CSSELR = 0U; /*(0U << 1U) | 0U;*/ /* Level 1 data cache */ + __DSB(); + + ccsidr = SCB->CCSIDR; + + /* invalidate D-Cache */ + sets = (uint32_t)(CCSIDR_SETS(ccsidr)); + do { + ways = (uint32_t)(CCSIDR_WAYS(ccsidr)); + do { + SCB->DCISW = (((sets << SCB_DCISW_SET_Pos) & SCB_DCISW_SET_Msk) | + ((ways << SCB_DCISW_WAY_Pos) & SCB_DCISW_WAY_Msk) ); + #if defined ( __CC_ARM ) + __schedule_barrier(); + #endif + } while (ways-- != 0U); + } while(sets-- != 0U); + __DSB(); + + SCB->CCR |= (uint32_t)SCB_CCR_DC_Msk; /* enable D-Cache */ + + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Disable D-Cache + \details Turns off D-Cache + */ +__STATIC_INLINE void SCB_DisableDCache (void) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + register uint32_t ccsidr; + register uint32_t sets; + register uint32_t ways; + + SCB->CSSELR = 0U; /*(0U << 1U) | 0U;*/ /* Level 1 data cache */ + __DSB(); + + SCB->CCR &= ~(uint32_t)SCB_CCR_DC_Msk; /* disable D-Cache */ + __DSB(); + + ccsidr = SCB->CCSIDR; + + /* clean & invalidate D-Cache */ + sets = (uint32_t)(CCSIDR_SETS(ccsidr)); + do { + ways = (uint32_t)(CCSIDR_WAYS(ccsidr)); + do { + SCB->DCCISW = (((sets << SCB_DCCISW_SET_Pos) & SCB_DCCISW_SET_Msk) | + ((ways << SCB_DCCISW_WAY_Pos) & SCB_DCCISW_WAY_Msk) ); + #if defined ( __CC_ARM ) + __schedule_barrier(); + #endif + } while (ways-- != 0U); + } while(sets-- != 0U); + + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Invalidate D-Cache + \details Invalidates D-Cache + */ +__STATIC_INLINE void SCB_InvalidateDCache (void) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + uint32_t ccsidr; + uint32_t sets; + uint32_t ways; + + SCB->CSSELR = 0U; /*(0U << 1U) | 0U;*/ /* Level 1 data cache */ + __DSB(); + + ccsidr = SCB->CCSIDR; + + /* invalidate D-Cache */ + sets = (uint32_t)(CCSIDR_SETS(ccsidr)); + do { + ways = (uint32_t)(CCSIDR_WAYS(ccsidr)); + do { + SCB->DCISW = (((sets << SCB_DCISW_SET_Pos) & SCB_DCISW_SET_Msk) | + ((ways << SCB_DCISW_WAY_Pos) & SCB_DCISW_WAY_Msk) ); + #if defined ( __CC_ARM ) + __schedule_barrier(); + #endif + } while (ways-- != 0U); + } while(sets-- != 0U); + + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Clean D-Cache + \details Cleans D-Cache + */ +__STATIC_INLINE void SCB_CleanDCache (void) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + uint32_t ccsidr; + uint32_t sets; + uint32_t ways; + + SCB->CSSELR = 0U; /*(0U << 1U) | 0U;*/ /* Level 1 data cache */ + __DSB(); + + ccsidr = SCB->CCSIDR; + + /* clean D-Cache */ + sets = (uint32_t)(CCSIDR_SETS(ccsidr)); + do { + ways = (uint32_t)(CCSIDR_WAYS(ccsidr)); + do { + SCB->DCCSW = (((sets << SCB_DCCSW_SET_Pos) & SCB_DCCSW_SET_Msk) | + ((ways << SCB_DCCSW_WAY_Pos) & SCB_DCCSW_WAY_Msk) ); + #if defined ( __CC_ARM ) + __schedule_barrier(); + #endif + } while (ways-- != 0U); + } while(sets-- != 0U); + + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Clean & Invalidate D-Cache + \details Cleans and Invalidates D-Cache + */ +__STATIC_INLINE void SCB_CleanInvalidateDCache (void) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + uint32_t ccsidr; + uint32_t sets; + uint32_t ways; + + SCB->CSSELR = 0U; /*(0U << 1U) | 0U;*/ /* Level 1 data cache */ + __DSB(); + + ccsidr = SCB->CCSIDR; + + /* clean & invalidate D-Cache */ + sets = (uint32_t)(CCSIDR_SETS(ccsidr)); + do { + ways = (uint32_t)(CCSIDR_WAYS(ccsidr)); + do { + SCB->DCCISW = (((sets << SCB_DCCISW_SET_Pos) & SCB_DCCISW_SET_Msk) | + ((ways << SCB_DCCISW_WAY_Pos) & SCB_DCCISW_WAY_Msk) ); + #if defined ( __CC_ARM ) + __schedule_barrier(); + #endif + } while (ways-- != 0U); + } while(sets-- != 0U); + + __DSB(); + __ISB(); + #endif +} + + +/** + \brief D-Cache Invalidate by address + \details Invalidates D-Cache for the given address + \param[in] addr address (aligned to 32-byte boundary) + \param[in] dsize size of memory block (in number of bytes) +*/ +__STATIC_INLINE void SCB_InvalidateDCache_by_Addr (uint32_t *addr, int32_t dsize) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + int32_t op_size = dsize; + uint32_t op_addr = (uint32_t)addr; + int32_t linesize = 32; /* in Cortex-M7 size of cache line is fixed to 8 words (32 bytes) */ + + __DSB(); + + while (op_size > 0) { + SCB->DCIMVAC = op_addr; + op_addr += (uint32_t)linesize; + op_size -= linesize; + } + + __DSB(); + __ISB(); + #endif +} + + +/** + \brief D-Cache Clean by address + \details Cleans D-Cache for the given address + \param[in] addr address (aligned to 32-byte boundary) + \param[in] dsize size of memory block (in number of bytes) +*/ +__STATIC_INLINE void SCB_CleanDCache_by_Addr (uint32_t *addr, int32_t dsize) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + int32_t op_size = dsize; + uint32_t op_addr = (uint32_t) addr; + int32_t linesize = 32; /* in Cortex-M7 size of cache line is fixed to 8 words (32 bytes) */ + + __DSB(); + + while (op_size > 0) { + SCB->DCCMVAC = op_addr; + op_addr += (uint32_t)linesize; + op_size -= linesize; + } + + __DSB(); + __ISB(); + #endif +} + + +/** + \brief D-Cache Clean and Invalidate by address + \details Cleans and invalidates D_Cache for the given address + \param[in] addr address (aligned to 32-byte boundary) + \param[in] dsize size of memory block (in number of bytes) +*/ +__STATIC_INLINE void SCB_CleanInvalidateDCache_by_Addr (uint32_t *addr, int32_t dsize) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + int32_t op_size = dsize; + uint32_t op_addr = (uint32_t) addr; + int32_t linesize = 32; /* in Cortex-M7 size of cache line is fixed to 8 words (32 bytes) */ + + __DSB(); + + while (op_size > 0) { + SCB->DCCIMVAC = op_addr; + op_addr += (uint32_t)linesize; + op_size -= linesize; + } + + __DSB(); + __ISB(); + #endif +} + + +/*@} end of CMSIS_Core_CacheFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + +/* ##################################### Debug In/Output function ########################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_core_DebugFunctions ITM Functions + \brief Functions that access the ITM debug interface. + @{ + */ + +extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ +#define ITM_RXBUFFER_EMPTY ((int32_t)0x5AA55AA5U) /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ + + +/** + \brief ITM Send Character + \details Transmits a character via the ITM channel 0, and + \li Just returns when no debugger is connected that has booked the output. + \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. + \param [in] ch Character to transmit. + \returns Character to transmit. + */ +__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) +{ + if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ + ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */ + { + while (ITM->PORT[0U].u32 == 0UL) + { + __NOP(); + } + ITM->PORT[0U].u8 = (uint8_t)ch; + } + return (ch); +} + + +/** + \brief ITM Receive Character + \details Inputs a character via the external variable \ref ITM_RxBuffer. + \return Received character. + \return -1 No character pending. + */ +__STATIC_INLINE int32_t ITM_ReceiveChar (void) +{ + int32_t ch = -1; /* no character available */ + + if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) + { + ch = ITM_RxBuffer; + ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ + } + + return (ch); +} + + +/** + \brief ITM Check Character + \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. + \return 0 No character available. + \return 1 Character available. + */ +__STATIC_INLINE int32_t ITM_CheckChar (void) +{ + + if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) + { + return (0); /* no character available */ + } + else + { + return (1); /* character available */ + } +} + +/*@} end of CMSIS_core_DebugFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM7_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/cmsis/core_sc000.h b/cmsis/core_sc000.h new file mode 100644 index 00000000000..53dfaadd8b3 --- /dev/null +++ b/cmsis/core_sc000.h @@ -0,0 +1,1014 @@ +/**************************************************************************//** + * @file core_sc000.h + * @brief CMSIS SC000 Core Peripheral Access Layer Header File + * @version V5.0.2 + * @date 13. February 2017 + ******************************************************************************/ +/* + * Copyright (c) 2009-2017 ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_SC000_H_GENERIC +#define __CORE_SC000_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup SC000 + @{ + */ + +/* CMSIS SC000 definitions */ +#define __SC000_CMSIS_VERSION_MAIN ( 5U) /*!< [31:16] CMSIS HAL main version */ +#define __SC000_CMSIS_VERSION_SUB ( 0U) /*!< [15:0] CMSIS HAL sub version */ +#define __SC000_CMSIS_VERSION ((__SC000_CMSIS_VERSION_MAIN << 16U) | \ + __SC000_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */ + +#define __CORTEX_SC (000U) /*!< Cortex secure core */ + +/** __FPU_USED indicates whether an FPU is used or not. + This core does not support an FPU at all +*/ +#define __FPU_USED 0U + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_PCS_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_SC000_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_SC000_H_DEPENDANT +#define __CORE_SC000_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __SC000_REV + #define __SC000_REV 0x0000U + #warning "__SC000_REV not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 2U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group SC000 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core MPU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:28; /*!< bit: 0..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t _reserved0:1; /*!< bit: 0 Reserved */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[1U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[31U]; + __IOM uint32_t ICER[1U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[31U]; + __IOM uint32_t ISPR[1U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[31U]; + __IOM uint32_t ICPR[1U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[31U]; + uint32_t RESERVED4[64U]; + __IOM uint32_t IP[8U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */ +} NVIC_Type; + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + uint32_t RESERVED0[1U]; + __IOM uint32_t SHP[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + uint32_t RESERVED1[154U]; + __IOM uint32_t SFCR; /*!< Offset: 0x290 (R/W) Security Features Control Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 7U /*!< 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 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** + \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ +} SCnSCB_Type; + +/* Auxiliary Control Register Definitions */ +#define SCnSCB_ACTLR_DISMCYCINT_Pos 0U /*!< ACTLR: DISMCYCINT Position */ +#define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL /*<< SCnSCB_ACTLR_DISMCYCINT_Pos*/) /*!< ACTLR: DISMCYCINT Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ +} MPU_Type; + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_ADDR_Pos 8U /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0xFFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */ +#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ + +#define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */ +#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */ + +/* MPU Region Attribute and Size Register Definitions */ +#define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */ +#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ + +#define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */ +#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ + +#define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */ +#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ + +#define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */ +#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ + +#define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */ +#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ + +#define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */ +#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ + +#define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */ +#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ + +#define MPU_RASR_SRD_Pos 8U /*!< MPU RASR: Sub-Region Disable Position */ +#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ + +#define MPU_RASR_SIZE_Pos 1U /*!< MPU RASR: Region Size Field Position */ +#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ + +#define MPU_RASR_ENABLE_Pos 0U /*!< MPU RASR: Region enable bit Position */ +#define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief SC000 Core Debug Registers (DCB registers, SHCSR, and DFSR) are only accessible over DAP and not via processor. + Therefore they are not covered by the SC000 header file. + @{ + */ +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ +#endif + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else +/*#define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping not available for SC000 */ +/*#define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping not available for SC000 */ + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ +/*#define NVIC_GetActive __NVIC_GetActive not available for SC000 */ + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + +/* Interrupt Priorities are WORD accessible only under ARMv6M */ +/* The following MACROS handle generation of the register offset and byte masks */ +#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL) +#define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) ) +#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) ) + + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[0U] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IP[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } + else + { + SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + SCB_AIRCR_SYSRESETREQ_Msk); + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +/*@} end of CMSIS_Core_NVICFunctions */ + + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + return 0U; /* No FPU */ +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_SC000_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/cmsis/core_sc300.h b/cmsis/core_sc300.h new file mode 100644 index 00000000000..78450e0f7c5 --- /dev/null +++ b/cmsis/core_sc300.h @@ -0,0 +1,1901 @@ +/**************************************************************************//** + * @file core_sc300.h + * @brief CMSIS SC300 Core Peripheral Access Layer Header File + * @version V5.0.2 + * @date 13. February 2017 + ******************************************************************************/ +/* + * Copyright (c) 2009-2017 ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_SC300_H_GENERIC +#define __CORE_SC300_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup SC3000 + @{ + */ + +/* CMSIS SC300 definitions */ +#define __SC300_CMSIS_VERSION_MAIN ( 5U) /*!< [31:16] CMSIS HAL main version */ +#define __SC300_CMSIS_VERSION_SUB ( 0U) /*!< [15:0] CMSIS HAL sub version */ +#define __SC300_CMSIS_VERSION ((__SC300_CMSIS_VERSION_MAIN << 16U) | \ + __SC300_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */ + +#define __CORTEX_SC (300U) /*!< Cortex secure core */ + +/** __FPU_USED indicates whether an FPU is used or not. + This core does not support an FPU at all +*/ +#define __FPU_USED 0U + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_PCS_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_SC300_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_SC300_H_DEPENDANT +#define __CORE_SC300_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __SC300_REV + #define __SC300_REV 0x0000U + #warning "__SC300_REV not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 3U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group SC300 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:27; /*!< bit: 0..26 Reserved */ + 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; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + +#define APSR_Q_Pos 27U /*!< APSR: Q Position */ +#define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:1; /*!< bit: 9 Reserved */ + uint32_t ICI_IT_1:6; /*!< bit: 10..15 ICI/IT part 1 */ + uint32_t _reserved1:8; /*!< bit: 16..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit */ + uint32_t ICI_IT_2:2; /*!< bit: 25..26 ICI/IT part 2 */ + 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; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_Q_Pos 27U /*!< xPSR: Q Position */ +#define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */ + +#define xPSR_ICI_IT_2_Pos 25U /*!< xPSR: ICI/IT part 2 Position */ +#define xPSR_ICI_IT_2_Msk (3UL << xPSR_ICI_IT_2_Pos) /*!< xPSR: ICI/IT part 2 Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_ICI_IT_1_Pos 10U /*!< xPSR: ICI/IT part 1 Position */ +#define xPSR_ICI_IT_1_Msk (0x3FUL << xPSR_ICI_IT_1_Pos) /*!< xPSR: ICI/IT part 1 Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[8U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[24U]; + __IOM uint32_t ICER[8U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[24U]; + __IOM uint32_t ISPR[8U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[24U]; + __IOM uint32_t ICPR[8U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[24U]; + __IOM uint32_t IABR[8U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[56U]; + __IOM uint8_t IP[240U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED5[644U]; + __OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; + +/* Software Triggered Interrupt Register Definitions */ +#define NVIC_STIR_INTID_Pos 0U /*!< STIR: INTLINESNUM Position */ +#define NVIC_STIR_INTID_Msk (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/) /*!< STIR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + __IOM uint8_t SHP[12U]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IOM uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IOM uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IOM uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IOM uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IOM uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IOM uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __IM uint32_t PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __IM uint32_t DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __IM uint32_t ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __IM uint32_t MMFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __IM uint32_t ISAR[5U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + uint32_t RESERVED0[5U]; + __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ + uint32_t RESERVED1[129U]; + __IOM uint32_t SFCR; /*!< Offset: 0x290 (R/W) Security Features Control Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Vector Table Offset Register Definitions */ +#define SCB_VTOR_TBLBASE_Pos 29U /*!< SCB VTOR: TBLBASE Position */ +#define SCB_VTOR_TBLBASE_Msk (1UL << SCB_VTOR_TBLBASE_Pos) /*!< SCB VTOR: TBLBASE Mask */ + +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x3FFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */ +#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +#define SCB_AIRCR_VECTRESET_Pos 0U /*!< 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 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< 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 4U /*!< 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 3U /*!< 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 1U /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +#define SCB_CCR_NONBASETHRDENA_Pos 0U /*!< 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 18U /*!< SCB SHCSR: USGFAULTENA Position */ +#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ + +#define SCB_SHCSR_BUSFAULTENA_Pos 17U /*!< SCB SHCSR: BUSFAULTENA Position */ +#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ + +#define SCB_SHCSR_MEMFAULTENA_Pos 16U /*!< SCB SHCSR: MEMFAULTENA Position */ +#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_BUSFAULTPENDED_Pos 14U /*!< SCB SHCSR: BUSFAULTPENDED Position */ +#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ + +#define SCB_SHCSR_MEMFAULTPENDED_Pos 13U /*!< SCB SHCSR: MEMFAULTPENDED Position */ +#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ + +#define SCB_SHCSR_USGFAULTPENDED_Pos 12U /*!< SCB SHCSR: USGFAULTPENDED Position */ +#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_MONITORACT_Pos 8U /*!< SCB SHCSR: MONITORACT Position */ +#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_USGFAULTACT_Pos 3U /*!< SCB SHCSR: USGFAULTACT Position */ +#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ + +#define SCB_SHCSR_BUSFAULTACT_Pos 1U /*!< SCB SHCSR: BUSFAULTACT Position */ +#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ + +#define SCB_SHCSR_MEMFAULTACT_Pos 0U /*!< SCB SHCSR: MEMFAULTACT Position */ +#define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */ + +/* SCB Configurable Fault Status Register Definitions */ +#define SCB_CFSR_USGFAULTSR_Pos 16U /*!< 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 8U /*!< 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 0U /*!< 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 */ + +/* MemManage Fault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_MMARVALID_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 7U) /*!< SCB CFSR (MMFSR): MMARVALID Position */ +#define SCB_CFSR_MMARVALID_Msk (1UL << SCB_CFSR_MMARVALID_Pos) /*!< SCB CFSR (MMFSR): MMARVALID Mask */ + +#define SCB_CFSR_MSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 4U) /*!< SCB CFSR (MMFSR): MSTKERR Position */ +#define SCB_CFSR_MSTKERR_Msk (1UL << SCB_CFSR_MSTKERR_Pos) /*!< SCB CFSR (MMFSR): MSTKERR Mask */ + +#define SCB_CFSR_MUNSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 3U) /*!< SCB CFSR (MMFSR): MUNSTKERR Position */ +#define SCB_CFSR_MUNSTKERR_Msk (1UL << SCB_CFSR_MUNSTKERR_Pos) /*!< SCB CFSR (MMFSR): MUNSTKERR Mask */ + +#define SCB_CFSR_DACCVIOL_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 1U) /*!< SCB CFSR (MMFSR): DACCVIOL Position */ +#define SCB_CFSR_DACCVIOL_Msk (1UL << SCB_CFSR_DACCVIOL_Pos) /*!< SCB CFSR (MMFSR): DACCVIOL Mask */ + +#define SCB_CFSR_IACCVIOL_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 0U) /*!< SCB CFSR (MMFSR): IACCVIOL Position */ +#define SCB_CFSR_IACCVIOL_Msk (1UL /*<< SCB_CFSR_IACCVIOL_Pos*/) /*!< SCB CFSR (MMFSR): IACCVIOL Mask */ + +/* BusFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_BFARVALID_Pos (SCB_CFSR_BUSFAULTSR_Pos + 7U) /*!< SCB CFSR (BFSR): BFARVALID Position */ +#define SCB_CFSR_BFARVALID_Msk (1UL << SCB_CFSR_BFARVALID_Pos) /*!< SCB CFSR (BFSR): BFARVALID Mask */ + +#define SCB_CFSR_STKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 4U) /*!< SCB CFSR (BFSR): STKERR Position */ +#define SCB_CFSR_STKERR_Msk (1UL << SCB_CFSR_STKERR_Pos) /*!< SCB CFSR (BFSR): STKERR Mask */ + +#define SCB_CFSR_UNSTKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 3U) /*!< SCB CFSR (BFSR): UNSTKERR Position */ +#define SCB_CFSR_UNSTKERR_Msk (1UL << SCB_CFSR_UNSTKERR_Pos) /*!< SCB CFSR (BFSR): UNSTKERR Mask */ + +#define SCB_CFSR_IMPRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 2U) /*!< SCB CFSR (BFSR): IMPRECISERR Position */ +#define SCB_CFSR_IMPRECISERR_Msk (1UL << SCB_CFSR_IMPRECISERR_Pos) /*!< SCB CFSR (BFSR): IMPRECISERR Mask */ + +#define SCB_CFSR_PRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 1U) /*!< SCB CFSR (BFSR): PRECISERR Position */ +#define SCB_CFSR_PRECISERR_Msk (1UL << SCB_CFSR_PRECISERR_Pos) /*!< SCB CFSR (BFSR): PRECISERR Mask */ + +#define SCB_CFSR_IBUSERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 0U) /*!< SCB CFSR (BFSR): IBUSERR Position */ +#define SCB_CFSR_IBUSERR_Msk (1UL << SCB_CFSR_IBUSERR_Pos) /*!< SCB CFSR (BFSR): IBUSERR Mask */ + +/* UsageFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_DIVBYZERO_Pos (SCB_CFSR_USGFAULTSR_Pos + 9U) /*!< SCB CFSR (UFSR): DIVBYZERO Position */ +#define SCB_CFSR_DIVBYZERO_Msk (1UL << SCB_CFSR_DIVBYZERO_Pos) /*!< SCB CFSR (UFSR): DIVBYZERO Mask */ + +#define SCB_CFSR_UNALIGNED_Pos (SCB_CFSR_USGFAULTSR_Pos + 8U) /*!< SCB CFSR (UFSR): UNALIGNED Position */ +#define SCB_CFSR_UNALIGNED_Msk (1UL << SCB_CFSR_UNALIGNED_Pos) /*!< SCB CFSR (UFSR): UNALIGNED Mask */ + +#define SCB_CFSR_NOCP_Pos (SCB_CFSR_USGFAULTSR_Pos + 3U) /*!< SCB CFSR (UFSR): NOCP Position */ +#define SCB_CFSR_NOCP_Msk (1UL << SCB_CFSR_NOCP_Pos) /*!< SCB CFSR (UFSR): NOCP Mask */ + +#define SCB_CFSR_INVPC_Pos (SCB_CFSR_USGFAULTSR_Pos + 2U) /*!< SCB CFSR (UFSR): INVPC Position */ +#define SCB_CFSR_INVPC_Msk (1UL << SCB_CFSR_INVPC_Pos) /*!< SCB CFSR (UFSR): INVPC Mask */ + +#define SCB_CFSR_INVSTATE_Pos (SCB_CFSR_USGFAULTSR_Pos + 1U) /*!< SCB CFSR (UFSR): INVSTATE Position */ +#define SCB_CFSR_INVSTATE_Msk (1UL << SCB_CFSR_INVSTATE_Pos) /*!< SCB CFSR (UFSR): INVSTATE Mask */ + +#define SCB_CFSR_UNDEFINSTR_Pos (SCB_CFSR_USGFAULTSR_Pos + 0U) /*!< SCB CFSR (UFSR): UNDEFINSTR Position */ +#define SCB_CFSR_UNDEFINSTR_Msk (1UL << SCB_CFSR_UNDEFINSTR_Pos) /*!< SCB CFSR (UFSR): UNDEFINSTR Mask */ + +/* SCB Hard Fault Status Register Definitions */ +#define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */ +#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ + +#define SCB_HFSR_FORCED_Pos 30U /*!< SCB HFSR: FORCED Position */ +#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ + +#define SCB_HFSR_VECTTBL_Pos 1U /*!< 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 4U /*!< SCB DFSR: EXTERNAL Position */ +#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ + +#define SCB_DFSR_VCATCH_Pos 3U /*!< SCB DFSR: VCATCH Position */ +#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ + +#define SCB_DFSR_DWTTRAP_Pos 2U /*!< SCB DFSR: DWTTRAP Position */ +#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ + +#define SCB_DFSR_BKPT_Pos 1U /*!< SCB DFSR: BKPT Position */ +#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ + +#define SCB_DFSR_HALTED_Pos 0U /*!< SCB DFSR: HALTED Position */ +#define SCB_DFSR_HALTED_Msk (1UL /*<< SCB_DFSR_HALTED_Pos*/) /*!< SCB DFSR: HALTED Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** + \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IM uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ + uint32_t RESERVED1[1U]; +} SCnSCB_Type; + +/* Interrupt Controller Type Register Definitions */ +#define SCnSCB_ICTR_INTLINESNUM_Pos 0U /*!< ICTR: INTLINESNUM Position */ +#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/) /*!< ICTR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) + \brief Type definitions for the Instrumentation Trace Macrocell (ITM) + @{ + */ + +/** + \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). + */ +typedef struct +{ + __OM union + { + __OM uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ + __OM uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ + __OM uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ + } PORT [32U]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ + uint32_t RESERVED0[864U]; + __IOM uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ + uint32_t RESERVED1[15U]; + __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ + uint32_t RESERVED2[15U]; + __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ + uint32_t RESERVED3[29U]; + __OM uint32_t IWR; /*!< Offset: 0xEF8 ( /W) ITM Integration Write Register */ + __IM uint32_t IRR; /*!< Offset: 0xEFC (R/ ) ITM Integration Read Register */ + __IOM uint32_t IMCR; /*!< Offset: 0xF00 (R/W) ITM Integration Mode Control Register */ + uint32_t RESERVED4[43U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ + uint32_t RESERVED5[6U]; + __IM uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ + __IM uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ + __IM uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ + __IM uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ + __IM uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ + __IM uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ + __IM uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ + __IM uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ + __IM uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ + __IM uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ + __IM uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ + __IM uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ +} ITM_Type; + +/* ITM Trace Privilege Register Definitions */ +#define ITM_TPR_PRIVMASK_Pos 0U /*!< 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 23U /*!< ITM TCR: BUSY Position */ +#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ + +#define ITM_TCR_TraceBusID_Pos 16U /*!< ITM TCR: ATBID Position */ +#define ITM_TCR_TraceBusID_Msk (0x7FUL << ITM_TCR_TraceBusID_Pos) /*!< ITM TCR: ATBID Mask */ + +#define ITM_TCR_GTSFREQ_Pos 10U /*!< 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 8U /*!< ITM TCR: TSPrescale Position */ +#define ITM_TCR_TSPrescale_Msk (3UL << ITM_TCR_TSPrescale_Pos) /*!< ITM TCR: TSPrescale Mask */ + +#define ITM_TCR_SWOENA_Pos 4U /*!< ITM TCR: SWOENA Position */ +#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ + +#define ITM_TCR_DWTENA_Pos 3U /*!< ITM TCR: DWTENA Position */ +#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ + +#define ITM_TCR_SYNCENA_Pos 2U /*!< ITM TCR: SYNCENA Position */ +#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ + +#define ITM_TCR_TSENA_Pos 1U /*!< ITM TCR: TSENA Position */ +#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ + +#define ITM_TCR_ITMENA_Pos 0U /*!< ITM TCR: ITM Enable bit Position */ +#define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */ + +/* ITM Integration Write Register Definitions */ +#define ITM_IWR_ATVALIDM_Pos 0U /*!< ITM IWR: ATVALIDM Position */ +#define ITM_IWR_ATVALIDM_Msk (1UL /*<< ITM_IWR_ATVALIDM_Pos*/) /*!< ITM IWR: ATVALIDM Mask */ + +/* ITM Integration Read Register Definitions */ +#define ITM_IRR_ATREADYM_Pos 0U /*!< ITM IRR: ATREADYM Position */ +#define ITM_IRR_ATREADYM_Msk (1UL /*<< ITM_IRR_ATREADYM_Pos*/) /*!< ITM IRR: ATREADYM Mask */ + +/* ITM Integration Mode Control Register Definitions */ +#define ITM_IMCR_INTEGRATION_Pos 0U /*!< ITM IMCR: INTEGRATION Position */ +#define ITM_IMCR_INTEGRATION_Msk (1UL /*<< ITM_IMCR_INTEGRATION_Pos*/) /*!< ITM IMCR: INTEGRATION Mask */ + +/* ITM Lock Status Register Definitions */ +#define ITM_LSR_ByteAcc_Pos 2U /*!< ITM LSR: ByteAcc Position */ +#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ + +#define ITM_LSR_Access_Pos 1U /*!< ITM LSR: Access Position */ +#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ + +#define ITM_LSR_Present_Pos 0U /*!< ITM LSR: Present Position */ +#define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */ + +/*@}*/ /* end of group CMSIS_ITM */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** + \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + __IOM uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ + __IOM uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ + __IOM uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ + __IOM uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ + __IOM uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ + __IOM uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ + __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + __IOM uint32_t MASK0; /*!< Offset: 0x024 (R/W) Mask Register 0 */ + __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED0[1U]; + __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + __IOM uint32_t MASK1; /*!< Offset: 0x034 (R/W) Mask Register 1 */ + __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED1[1U]; + __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + __IOM uint32_t MASK2; /*!< Offset: 0x044 (R/W) Mask Register 2 */ + __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + __IOM uint32_t MASK3; /*!< Offset: 0x054 (R/W) Mask Register 3 */ + __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +#define DWT_CTRL_CYCEVTENA_Pos 22U /*!< DWT CTRL: CYCEVTENA Position */ +#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ + +#define DWT_CTRL_FOLDEVTENA_Pos 21U /*!< DWT CTRL: FOLDEVTENA Position */ +#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ + +#define DWT_CTRL_LSUEVTENA_Pos 20U /*!< DWT CTRL: LSUEVTENA Position */ +#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ + +#define DWT_CTRL_SLEEPEVTENA_Pos 19U /*!< DWT CTRL: SLEEPEVTENA Position */ +#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ + +#define DWT_CTRL_EXCEVTENA_Pos 18U /*!< DWT CTRL: EXCEVTENA Position */ +#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ + +#define DWT_CTRL_CPIEVTENA_Pos 17U /*!< DWT CTRL: CPIEVTENA Position */ +#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ + +#define DWT_CTRL_EXCTRCENA_Pos 16U /*!< DWT CTRL: EXCTRCENA Position */ +#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ + +#define DWT_CTRL_PCSAMPLENA_Pos 12U /*!< DWT CTRL: PCSAMPLENA Position */ +#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ + +#define DWT_CTRL_SYNCTAP_Pos 10U /*!< DWT CTRL: SYNCTAP Position */ +#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ + +#define DWT_CTRL_CYCTAP_Pos 9U /*!< DWT CTRL: CYCTAP Position */ +#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ + +#define DWT_CTRL_POSTINIT_Pos 5U /*!< DWT CTRL: POSTINIT Position */ +#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ + +#define DWT_CTRL_POSTPRESET_Pos 1U /*!< DWT CTRL: POSTPRESET Position */ +#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ + +#define DWT_CTRL_CYCCNTENA_Pos 0U /*!< DWT CTRL: CYCCNTENA Position */ +#define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */ + +/* DWT CPI Count Register Definitions */ +#define DWT_CPICNT_CPICNT_Pos 0U /*!< DWT CPICNT: CPICNT Position */ +#define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */ + +/* DWT Exception Overhead Count Register Definitions */ +#define DWT_EXCCNT_EXCCNT_Pos 0U /*!< DWT EXCCNT: EXCCNT Position */ +#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */ + +/* DWT Sleep Count Register Definitions */ +#define DWT_SLEEPCNT_SLEEPCNT_Pos 0U /*!< DWT SLEEPCNT: SLEEPCNT Position */ +#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ + +/* DWT LSU Count Register Definitions */ +#define DWT_LSUCNT_LSUCNT_Pos 0U /*!< DWT LSUCNT: LSUCNT Position */ +#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */ + +/* DWT Folded-instruction Count Register Definitions */ +#define DWT_FOLDCNT_FOLDCNT_Pos 0U /*!< DWT FOLDCNT: FOLDCNT Position */ +#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */ + +/* DWT Comparator Mask Register Definitions */ +#define DWT_MASK_MASK_Pos 0U /*!< DWT MASK: MASK Position */ +#define DWT_MASK_MASK_Msk (0x1FUL /*<< DWT_MASK_MASK_Pos*/) /*!< DWT MASK: MASK Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVADDR1_Pos 16U /*!< DWT FUNCTION: DATAVADDR1 Position */ +#define DWT_FUNCTION_DATAVADDR1_Msk (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos) /*!< DWT FUNCTION: DATAVADDR1 Mask */ + +#define DWT_FUNCTION_DATAVADDR0_Pos 12U /*!< DWT FUNCTION: DATAVADDR0 Position */ +#define DWT_FUNCTION_DATAVADDR0_Msk (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos) /*!< DWT FUNCTION: DATAVADDR0 Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_LNK1ENA_Pos 9U /*!< DWT FUNCTION: LNK1ENA Position */ +#define DWT_FUNCTION_LNK1ENA_Msk (0x1UL << DWT_FUNCTION_LNK1ENA_Pos) /*!< DWT FUNCTION: LNK1ENA Mask */ + +#define DWT_FUNCTION_DATAVMATCH_Pos 8U /*!< DWT FUNCTION: DATAVMATCH Position */ +#define DWT_FUNCTION_DATAVMATCH_Msk (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos) /*!< DWT FUNCTION: DATAVMATCH Mask */ + +#define DWT_FUNCTION_CYCMATCH_Pos 7U /*!< DWT FUNCTION: CYCMATCH Position */ +#define DWT_FUNCTION_CYCMATCH_Msk (0x1UL << DWT_FUNCTION_CYCMATCH_Pos) /*!< DWT FUNCTION: CYCMATCH Mask */ + +#define DWT_FUNCTION_EMITRANGE_Pos 5U /*!< DWT FUNCTION: EMITRANGE Position */ +#define DWT_FUNCTION_EMITRANGE_Msk (0x1UL << DWT_FUNCTION_EMITRANGE_Pos) /*!< DWT FUNCTION: EMITRANGE Mask */ + +#define DWT_FUNCTION_FUNCTION_Pos 0U /*!< DWT FUNCTION: FUNCTION Position */ +#define DWT_FUNCTION_FUNCTION_Msk (0xFUL /*<< DWT_FUNCTION_FUNCTION_Pos*/) /*!< DWT FUNCTION: FUNCTION Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** + \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IOM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55U]; + __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131U]; + __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __IM uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ + uint32_t RESERVED3[759U]; + __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER */ + __IM uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ + __IM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ + uint32_t RESERVED4[1U]; + __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */ + __IM uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */ + __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ + uint32_t RESERVED5[39U]; + __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ + __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ + uint32_t RESERVED7[8U]; + __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_PRESCALER_Pos 0U /*!< TPI ACPR: PRESCALER Position */ +#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< TPI ACPR: PRESCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI TRIGGER Register Definitions */ +#define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */ +#define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */ + +/* TPI Integration ETM Data Register Definitions (FIFO0) */ +#define TPI_FIFO0_ITM_ATVALID_Pos 29U /*!< TPI FIFO0: ITM_ATVALID Position */ +#define TPI_FIFO0_ITM_ATVALID_Msk (0x3UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ + +#define TPI_FIFO0_ITM_bytecount_Pos 27U /*!< TPI FIFO0: ITM_bytecount Position */ +#define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */ + +#define TPI_FIFO0_ETM_ATVALID_Pos 26U /*!< TPI FIFO0: ETM_ATVALID Position */ +#define TPI_FIFO0_ETM_ATVALID_Msk (0x3UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ + +#define TPI_FIFO0_ETM_bytecount_Pos 24U /*!< TPI FIFO0: ETM_bytecount Position */ +#define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */ + +#define TPI_FIFO0_ETM2_Pos 16U /*!< TPI FIFO0: ETM2 Position */ +#define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */ + +#define TPI_FIFO0_ETM1_Pos 8U /*!< TPI FIFO0: ETM1 Position */ +#define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */ + +#define TPI_FIFO0_ETM0_Pos 0U /*!< TPI FIFO0: ETM0 Position */ +#define TPI_FIFO0_ETM0_Msk (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/) /*!< TPI FIFO0: ETM0 Mask */ + +/* TPI ITATBCTR2 Register Definitions */ +#define TPI_ITATBCTR2_ATREADY_Pos 0U /*!< TPI ITATBCTR2: ATREADY Position */ +#define TPI_ITATBCTR2_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY_Pos*/) /*!< TPI ITATBCTR2: ATREADY Mask */ + +/* TPI Integration ITM Data Register Definitions (FIFO1) */ +#define TPI_FIFO1_ITM_ATVALID_Pos 29U /*!< TPI FIFO1: ITM_ATVALID Position */ +#define TPI_FIFO1_ITM_ATVALID_Msk (0x3UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ + +#define TPI_FIFO1_ITM_bytecount_Pos 27U /*!< TPI FIFO1: ITM_bytecount Position */ +#define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */ + +#define TPI_FIFO1_ETM_ATVALID_Pos 26U /*!< TPI FIFO1: ETM_ATVALID Position */ +#define TPI_FIFO1_ETM_ATVALID_Msk (0x3UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ + +#define TPI_FIFO1_ETM_bytecount_Pos 24U /*!< TPI FIFO1: ETM_bytecount Position */ +#define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */ + +#define TPI_FIFO1_ITM2_Pos 16U /*!< TPI FIFO1: ITM2 Position */ +#define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */ + +#define TPI_FIFO1_ITM1_Pos 8U /*!< TPI FIFO1: ITM1 Position */ +#define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */ + +#define TPI_FIFO1_ITM0_Pos 0U /*!< TPI FIFO1: ITM0 Position */ +#define TPI_FIFO1_ITM0_Msk (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/) /*!< TPI FIFO1: ITM0 Mask */ + +/* TPI ITATBCTR0 Register Definitions */ +#define TPI_ITATBCTR0_ATREADY_Pos 0U /*!< TPI ITATBCTR0: ATREADY Position */ +#define TPI_ITATBCTR0_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY_Pos*/) /*!< TPI ITATBCTR0: ATREADY Mask */ + +/* TPI Integration Mode Control Register Definitions */ +#define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ +#define TPI_ITCTRL_Mode_Msk (0x1UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_MinBufSz_Pos 6U /*!< TPI DEVID: MinBufSz Position */ +#define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */ + +#define TPI_DEVID_AsynClkIn_Pos 5U /*!< TPI DEVID: AsynClkIn Position */ +#define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */ + +#define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */ +#define TPI_DEVID_NrTraceInput_Msk (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_MajorType_Pos 4U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +#define TPI_DEVTYPE_SubType_Pos 0U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ + __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Alias 1 Region Base Address Register */ + __IOM uint32_t RASR_A1; /*!< Offset: 0x018 (R/W) MPU Alias 1 Region Attribute and Size Register */ + __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Alias 2 Region Base Address Register */ + __IOM uint32_t RASR_A2; /*!< Offset: 0x020 (R/W) MPU Alias 2 Region Attribute and Size Register */ + __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Alias 3 Region Base Address Register */ + __IOM uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */ +} MPU_Type; + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_ADDR_Pos 5U /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */ +#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ + +#define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */ +#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */ + +/* MPU Region Attribute and Size Register Definitions */ +#define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */ +#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ + +#define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */ +#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ + +#define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */ +#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ + +#define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */ +#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ + +#define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */ +#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ + +#define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */ +#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ + +#define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */ +#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ + +#define MPU_RASR_SRD_Pos 8U /*!< MPU RASR: Sub-Region Disable Position */ +#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ + +#define MPU_RASR_SIZE_Pos 1U /*!< MPU RASR: Region Size Field Position */ +#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ + +#define MPU_RASR_ENABLE_Pos 0U /*!< MPU RASR: Region enable bit Position */ +#define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** + \brief Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register Definitions */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< 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 25U /*!< 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 24U /*!< 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 19U /*!< 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 18U /*!< 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 17U /*!< 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 16U /*!< 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 5U /*!< 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 3U /*!< 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 2U /*!< 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 1U /*!< 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 0U /*!< 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 Definitions */ +#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register Definitions */ +#define CoreDebug_DEMCR_TRCENA_Pos 24U /*!< CoreDebug DEMCR: TRCENA Position */ +#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ + +#define CoreDebug_DEMCR_MON_REQ_Pos 19U /*!< 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 18U /*!< 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 17U /*!< 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 16U /*!< 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 10U /*!< 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 9U /*!< 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 8U /*!< 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 7U /*!< 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 6U /*!< 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 5U /*!< 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 4U /*!< 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 0U /*!< CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ +#define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ +#define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ +#define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ +#define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ +#define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ +#define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ +#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ +#endif + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Debug Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping + #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ + #define NVIC_GetActive __NVIC_GetActive + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + + +/** + \brief Set Priority Grouping + \details 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)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << 8U) ); /* Insert write key and priorty group */ + SCB->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping + \details Reads the priority grouping field from the NVIC Interrupt Controller. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t __NVIC_GetPriorityGrouping(void) +{ + return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt + \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IABR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IP[((uint32_t)(int32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB->SHP[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC->IP[((uint32_t)(int32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB->SHP[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +/*@} end of CMSIS_Core_NVICFunctions */ + + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + return 0U; /* No FPU */ +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + +/* ##################################### Debug In/Output function ########################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_core_DebugFunctions ITM Functions + \brief Functions that access the ITM debug interface. + @{ + */ + +extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ +#define ITM_RXBUFFER_EMPTY ((int32_t)0x5AA55AA5U) /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ + + +/** + \brief ITM Send Character + \details Transmits a character via the ITM channel 0, and + \li Just returns when no debugger is connected that has booked the output. + \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. + \param [in] ch Character to transmit. + \returns Character to transmit. + */ +__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) +{ + if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ + ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */ + { + while (ITM->PORT[0U].u32 == 0UL) + { + __NOP(); + } + ITM->PORT[0U].u8 = (uint8_t)ch; + } + return (ch); +} + + +/** + \brief ITM Receive Character + \details Inputs a character via the external variable \ref ITM_RxBuffer. + \return Received character. + \return -1 No character pending. + */ +__STATIC_INLINE int32_t ITM_ReceiveChar (void) +{ + int32_t ch = -1; /* no character available */ + + if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) + { + ch = ITM_RxBuffer; + ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ + } + + return (ch); +} + + +/** + \brief ITM Check Character + \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. + \return 0 No character available. + \return 1 Character available. + */ +__STATIC_INLINE int32_t ITM_CheckChar (void) +{ + + if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) + { + return (0); /* no character available */ + } + else + { + return (1); /* character available */ + } +} + +/*@} end of CMSIS_core_DebugFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_SC300_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/cmsis/tz_context.h b/cmsis/tz_context.h new file mode 100644 index 00000000000..0784d26cac9 --- /dev/null +++ b/cmsis/tz_context.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2015-2016 ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ---------------------------------------------------------------------------- + * + * $Date: 21. September 2016 + * $Revision: V1.0 + * + * Project: TrustZone for ARMv8-M + * Title: Context Management for ARMv8-M TrustZone + * + * Version 1.0 + * Initial Release + *---------------------------------------------------------------------------*/ + +#ifndef TZ_CONTEXT_H +#define TZ_CONTEXT_H + +#include + +#ifndef TZ_MODULEID_T +#define TZ_MODULEID_T +/// \details Data type that identifies secure software modules called by a process. +typedef uint32_t TZ_ModuleId_t; +#endif + +/// \details TZ Memory ID identifies an allocated memory slot. +typedef uint32_t TZ_MemoryId_t; + +/// Initialize secure context memory system +/// \return execution status (1: success, 0: error) +uint32_t TZ_InitContextSystem_S (void); + +/// Allocate context memory for calling secure software modules in TrustZone +/// \param[in] module identifies software modules called from non-secure mode +/// \return value != 0 id TrustZone memory slot identifier +/// \return value 0 no memory available or internal error +TZ_MemoryId_t TZ_AllocModuleContext_S (TZ_ModuleId_t module); + +/// Free context memory that was previously allocated with \ref TZ_AllocModuleContext_S +/// \param[in] id TrustZone memory slot identifier +/// \return execution status (1: success, 0: error) +uint32_t TZ_FreeModuleContext_S (TZ_MemoryId_t id); + +/// Load secure context (called on RTOS thread context switch) +/// \param[in] id TrustZone memory slot identifier +/// \return execution status (1: success, 0: error) +uint32_t TZ_LoadContext_S (TZ_MemoryId_t id); + +/// Store secure context (called on RTOS thread context switch) +/// \param[in] id TrustZone memory slot identifier +/// \return execution status (1: success, 0: error) +uint32_t TZ_StoreContext_S (TZ_MemoryId_t id); + +#endif // TZ_CONTEXT_H diff --git a/rtos/rtx/cmsis_os.h b/rtos/rtx/cmsis_os.h new file mode 100644 index 00000000000..9a7ab76b600 --- /dev/null +++ b/rtos/rtx/cmsis_os.h @@ -0,0 +1,898 @@ +/* + * Copyright (c) 2013-2017 ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ---------------------------------------------------------------------- + * + * $Date: 10. January 2017 + * $Revision: V2.1.0 + * + * Project: CMSIS-RTOS API + * Title: cmsis_os.h RTX header file + * + * Version 0.02 + * Initial Proposal Phase + * Version 0.03 + * osKernelStart added, optional feature: main started as thread + * osSemaphores have standard behavior + * osTimerCreate does not start the timer, added osTimerStart + * osThreadPass is renamed to osThreadYield + * Version 1.01 + * Support for C++ interface + * - const attribute removed from the osXxxxDef_t typedefs + * - const attribute added to the osXxxxDef macros + * Added: osTimerDelete, osMutexDelete, osSemaphoreDelete + * Added: osKernelInitialize + * Version 1.02 + * Control functions for short timeouts in microsecond resolution: + * Added: osKernelSysTick, osKernelSysTickFrequency, osKernelSysTickMicroSec + * Removed: osSignalGet + * Version 2.0.0 + * OS objects creation without macros (dynamic creation and resource allocation): + * - added: osXxxxNew functions which replace osXxxxCreate + * - added: osXxxxAttr_t structures + * - deprecated: osXxxxCreate functions, osXxxxDef_t structures + * - deprecated: osXxxxDef and osXxxx macros + * osStatus codes simplified and renamed to osStatus_t + * osEvent return structure deprecated + * Kernel: + * - added: osKernelInfo_t and osKernelGetInfo + * - added: osKernelState_t and osKernelGetState (replaces osKernelRunning) + * - added: osKernelLock, osKernelUnlock + * - added: osKernelSuspend, osKernelResume + * - added: osKernelGetTickCount, osKernelGetTickFreq + * - renamed osKernelSysTick to osKernelGetSysTimerCount + * - replaced osKernelSysTickFrequency with osKernelGetSysTimerFreq + * - deprecated osKernelSysTickMicroSec + * Thread: + * - extended number of thread priorities + * - renamed osPrioriry to osPrioriry_t + * - replaced osThreadCreate with osThreadNew + * - added: osThreadGetName + * - added: osThreadState_t and osThreadGetState + * - added: osThreadGetStackSize, osThreadGetStackSpace + * - added: osThreadSuspend, osThreadResume + * - added: osThreadJoin, osThreadDetach, osThreadExit + * - added: osThreadGetCount, osThreadEnumerate + * - added: Thread Flags (moved from Signals) + * Signals: + * - renamed osSignals to osThreadFlags (moved to Thread Flags) + * - changed return value of Set/Clear/Wait functions + * - Clear function limited to current running thread + * - extended Wait function (options) + * - added: osThreadFlagsGet + * Event Flags: + * - added new independent object for handling Event Flags + * Delay and Wait functions: + * - added: osDelayUntil + * - deprecated: osWait + * Timer: + * - replaced osTimerCreate with osTimerNew + * - added: osTimerGetName, osTimerIsRunning + * Mutex: + * - extended: attributes (Recursive, Priority Inherit, Robust) + * - replaced osMutexCreate with osMutexNew + * - renamed osMutexWait to osMutexAcquire + * - added: osMutexGetName, osMutexGetOwner + * Semaphore: + * - extended: maximum and initial token count + * - replaced osSemaphoreCreate with osSemaphoreNew + * - renamed osSemaphoreWait to osSemaphoreAcquire (changed return value) + * - added: osSemaphoreGetName, osSemaphoreGetCount + * Memory Pool: + * - using osMemoryPool prefix instead of osPool + * - replaced osPoolCreate with osMemoryPoolNew + * - extended osMemoryPoolAlloc (timeout) + * - added: osMemoryPoolGetName + * - added: osMemoryPoolGetCapacity, osMemoryPoolGetBlockSize + * - added: osMemoryPoolGetCount, osMemoryPoolGetSpace + * - added: osMemoryPoolDelete + * - deprecated: osPoolCAlloc + * Message Queue: + * - extended: fixed size message instead of a single 32-bit value + * - using osMessageQueue prefix instead of osMessage + * - replaced osMessageCreate with osMessageQueueNew + * - updated: osMessageQueuePut, osMessageQueueGet + * - added: osMessageQueueGetName + * - added: osMessageQueueGetCapacity, osMessageQueueGetMsgSize + * - added: osMessageQueueGetCount, osMessageQueueGetSpace + * - added: osMessageQueueReset, osMessageQueueDelete + * Mail Queue: + * - deprecated (superseded by extended Message Queue functionality) + * Version 2.1.0 + * Support for critical and uncritical sections (nesting safe): + * - updated: osKernelLock, osKernelUnlock + * - added: osKernelRestoreLock + * Updated Thread and Event Flags: + * - changed flags parameter and return type from int32_t to uint32_t + *---------------------------------------------------------------------------*/ + +#ifndef CMSIS_OS_H_ +#define CMSIS_OS_H_ + +#define osCMSIS 0x20001U ///< API version (main[31:16].sub[15:0]) + +#define osCMSIS_RTX 0x50001U ///< RTOS identification and version (main[31:16].sub[15:0]) + +#define osKernelSystemId "RTX V5.1" ///< RTOS identification string + +#define osFeature_MainThread 0 ///< main thread 1=main can be thread, 0=not available +#define osFeature_Signals 31U ///< maximum number of Signal Flags available per thread +#define osFeature_Semaphore 65535U ///< maximum count for \ref osSemaphoreCreate function +#define osFeature_Wait 0 ///< osWait function: 1=available, 0=not available +#define osFeature_SysTick 1 ///< osKernelSysTick functions: 1=available, 0=not available +#define osFeature_Pool 1 ///< Memory Pools: 1=available, 0=not available +#define osFeature_MessageQ 1 ///< Message Queues: 1=available, 0=not available +#define osFeature_MailQ 1 ///< Mail Queues: 1=available, 0=not available + +#if defined(__CC_ARM) +#define os_InRegs __value_in_regs +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) +#define os_InRegs __attribute__((value_in_regs)) +#else +#define os_InRegs +#endif + +#if (osCMSIS >= 0x20000U) +#include "cmsis_os2.h" +#else +#include +#include +#endif +#include "rtx_os.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + + +// ==== Enumerations, structures, defines ==== + +/// Priority values. +#if (osCMSIS < 0x20000U) +typedef enum { + osPriorityIdle = -3, ///< Priority: idle (lowest) + osPriorityLow = -2, ///< Priority: low + osPriorityBelowNormal = -1, ///< Priority: below normal + osPriorityNormal = 0, ///< Priority: normal (default) + osPriorityAboveNormal = +1, ///< Priority: above normal + osPriorityHigh = +2, ///< Priority: high + osPriorityRealtime = +3, ///< Priority: realtime (highest) + osPriorityError = 0x84, ///< System cannot determine priority or illegal priority. + osPriorityReserved = 0x7FFFFFFF ///< Prevents enum down-size compiler optimization. +} osPriority; +#else +#define osPriority osPriority_t +#endif + +/// Entry point of a thread. +typedef void (*os_pthread) (void const *argument); + +/// Entry point of a timer call back function. +typedef void (*os_ptimer) (void const *argument); + +/// Timer type. +#if (osCMSIS < 0x20000U) +typedef enum { + osTimerOnce = 0, ///< One-shot timer. + osTimerPeriodic = 1 ///< Repeating timer. +} os_timer_type; +#else +#define os_timer_type osTimerType_t +#endif + +/// Timeout value. +#define osWaitForever 0xFFFFFFFFU ///< Wait forever timeout value. + +/// Status code values returned by CMSIS-RTOS functions. +#if (osCMSIS < 0x20000U) +typedef enum { + osOK = 0, ///< Function completed; no error or event occurred. + osEventSignal = 0x08, ///< Function completed; signal event occurred. + osEventMessage = 0x10, ///< Function completed; message event occurred. + osEventMail = 0x20, ///< Function completed; mail event occurred. + osEventTimeout = 0x40, ///< Function completed; timeout occurred. + osErrorParameter = 0x80, ///< Parameter error: a mandatory parameter was missing or specified an incorrect object. + osErrorResource = 0x81, ///< Resource not available: a specified resource was not available. + osErrorTimeoutResource = 0xC1, ///< Resource not available within given time: a specified resource was not available within the timeout period. + osErrorISR = 0x82, ///< Not allowed in ISR context: the function cannot be called from interrupt service routines. + osErrorISRRecursive = 0x83, ///< Function called multiple times from ISR with same object. + osErrorPriority = 0x84, ///< System cannot determine priority or thread has illegal priority. + osErrorNoMemory = 0x85, ///< System is out of memory: it was impossible to allocate or reserve memory for the operation. + osErrorValue = 0x86, ///< Value of a parameter is out of range. + osErrorOS = 0xFF, ///< Unspecified RTOS error: run-time error but no other error message fits. + osStatusReserved = 0x7FFFFFFF ///< Prevents enum down-size compiler optimization. +} osStatus; +#else +typedef int32_t osStatus; +#define osEventSignal (0x08) +#define osEventMessage (0x10) +#define osEventMail (0x20) +#define osEventTimeout (0x40) +#define osErrorOS osError +#define osErrorTimeoutResource osErrorTimeout +#define osErrorISRRecursive (-126) +#define osErrorValue (-127) +#define osErrorPriority (-128) +#endif + + +// >>> the following data type definitions may be adapted towards a specific RTOS + +/// Thread ID identifies the thread. +#if (osCMSIS < 0x20000U) +typedef void *osThreadId; +#else +#define osThreadId osThreadId_t +#endif + +/// Timer ID identifies the timer. +#if (osCMSIS < 0x20000U) +typedef void *osTimerId; +#else +#define osTimerId osTimerId_t +#endif + +/// Mutex ID identifies the mutex. +#if (osCMSIS < 0x20000U) +typedef void *osMutexId; +#else +#define osMutexId osMutexId_t +#endif + +/// Semaphore ID identifies the semaphore. +#if (osCMSIS < 0x20000U) +typedef void *osSemaphoreId; +#else +#define osSemaphoreId osSemaphoreId_t +#endif + +/// Pool ID identifies the memory pool. +typedef void *osPoolId; + +/// Message ID identifies the message queue. +typedef void *osMessageQId; + +/// Mail ID identifies the mail queue. +typedef void *osMailQId; + + +/// Thread Definition structure contains startup information of a thread. +#if (osCMSIS < 0x20000U) +typedef struct os_thread_def { + os_pthread pthread; ///< start address of thread function + osPriority tpriority; ///< initial thread priority + uint32_t instances; ///< maximum number of instances of that thread function + uint32_t stacksize; ///< stack size requirements in bytes; 0 is default stack size +} osThreadDef_t; +#else +typedef struct os_thread_def { + os_pthread pthread; ///< start address of thread function + osThreadAttr_t attr; ///< thread attributes +} osThreadDef_t; +#endif + +/// Timer Definition structure contains timer parameters. +#if (osCMSIS < 0x20000U) +typedef struct os_timer_def { + os_ptimer ptimer; ///< start address of a timer function +} osTimerDef_t; +#else +typedef struct os_timer_def { + os_ptimer ptimer; ///< start address of a timer function + osTimerAttr_t attr; ///< timer attributes +} osTimerDef_t; +#endif + +/// Mutex Definition structure contains setup information for a mutex. +#if (osCMSIS < 0x20000U) +typedef struct os_mutex_def { + uint32_t dummy; ///< dummy value +} osMutexDef_t; +#else +#define osMutexDef_t osMutexAttr_t +#endif + +/// Semaphore Definition structure contains setup information for a semaphore. +#if (osCMSIS < 0x20000U) +typedef struct os_semaphore_def { + uint32_t dummy; ///< dummy value +} osSemaphoreDef_t; +#else +#define osSemaphoreDef_t osSemaphoreAttr_t +#endif + +/// Definition structure for memory block allocation. +#if (osCMSIS < 0x20000U) +typedef struct os_pool_def { + uint32_t pool_sz; ///< number of items (elements) in the pool + uint32_t item_sz; ///< size of an item + void *pool; ///< pointer to memory for pool +} osPoolDef_t; +#else +typedef struct os_pool_def { + uint32_t pool_sz; ///< number of items (elements) in the pool + uint32_t item_sz; ///< size of an item + osMemoryPoolAttr_t attr; ///< memory pool attributes +} osPoolDef_t; +#endif + +/// Definition structure for message queue. +#if (osCMSIS < 0x20000U) +typedef struct os_messageQ_def { + uint32_t queue_sz; ///< number of elements in the queue + void *pool; ///< memory array for messages +} osMessageQDef_t; +#else +typedef struct os_messageQ_def { + uint32_t queue_sz; ///< number of elements in the queue + osMessageQueueAttr_t attr; ///< message queue attributes +} osMessageQDef_t; +#endif + +/// Definition structure for mail queue. +#if (osCMSIS < 0x20000U) +typedef struct os_mailQ_def { + uint32_t queue_sz; ///< number of elements in the queue + uint32_t item_sz; ///< size of an item + void *pool; ///< memory array for mail +} osMailQDef_t; +#else +typedef struct os_mailQ_def { + uint32_t queue_sz; ///< number of elements in the queue + uint32_t item_sz; ///< size of an item + void *mail; ///< pointer to mail + osMemoryPoolAttr_t mp_attr; ///< memory pool attributes + osMessageQueueAttr_t mq_attr; ///< message queue attributes +} osMailQDef_t; +#endif + + +/// Event structure contains detailed information about an event. +typedef struct { + osStatus status; ///< status code: event or error information + union { + uint32_t v; ///< message as 32-bit value + void *p; ///< message or mail as void pointer + int32_t signals; ///< signal flags + } value; ///< event value + union { + osMailQId mail_id; ///< mail id obtained by \ref osMailCreate + osMessageQId message_id; ///< message id obtained by \ref osMessageCreate + } def; ///< event definition +} osEvent; + + +// ==== Kernel Management Functions ==== + +/// Initialize the RTOS Kernel for creating objects. +/// \return status code that indicates the execution status of the function. +#if (osCMSIS < 0x20000U) +osStatus osKernelInitialize (void); +#endif + +/// Start the RTOS Kernel scheduler. +/// \return status code that indicates the execution status of the function. +#if (osCMSIS < 0x20000U) +osStatus osKernelStart (void); +#endif + +/// Check if the RTOS kernel is already started. +/// \return 0 RTOS is not started, 1 RTOS is started. +#if (osCMSIS < 0x20000U) +int32_t osKernelRunning(void); +#endif + +#if (defined(osFeature_SysTick) && (osFeature_SysTick != 0)) // System Timer available + +/// Get the RTOS kernel system timer counter. +/// \return RTOS kernel system timer as 32-bit value +#if (osCMSIS < 0x20000U) +uint32_t osKernelSysTick (void); +#else +#define osKernelSysTick osKernelGetSysTimerCount +#endif + +/// The RTOS kernel system timer frequency in Hz. +/// \note Reflects the system timer setting and is typically defined in a configuration file. +#if (osCMSIS < 0x20000U) +#define osKernelSysTickFrequency 100000000 +#endif + +/// Convert a microseconds value to a RTOS kernel system timer value. +/// \param microsec time value in microseconds. +/// \return time value normalized to the \ref osKernelSysTickFrequency +#if (osCMSIS < 0x20000U) +#define osKernelSysTickMicroSec(microsec) (((uint64_t)microsec * (osKernelSysTickFrequency)) / 1000000) +#else +#define osKernelSysTickMicroSec(microsec) (((uint64_t)microsec * osKernelGetSysTimerFreq()) / 1000000) +#endif + +#endif // System Timer available + + +// ==== Thread Management Functions ==== + +/// Create a Thread Definition with function, priority, and stack requirements. +/// \param name name of the thread function. +/// \param priority initial priority of the thread function. +/// \param instances number of possible thread instances. +/// \param stacksz stack size (in bytes) requirements for the thread function. +#if defined (osObjectsExternal) // object is external +#define osThreadDef(name, priority, instances, stacksz) \ +extern const osThreadDef_t os_thread_def_##name +#else // define the object +#if (osCMSIS < 0x20000U) +#define osThreadDef(name, priority, instances, stacksz) \ +const osThreadDef_t os_thread_def_##name = \ +{ (name), (priority), (instances), (stacksz) } +#else +#define osThreadDef(name, priority, instances, stacksz) \ +static uint64_t os_thread_stack##name[(stacksz)?(((stacksz+7)/8)):1] __attribute__((section(".bss.os.thread.stack"))); \ +static osRtxThread_t os_thread_cb_##name __attribute__((section(".bss.os.thread.cb"))); \ +const osThreadDef_t os_thread_def_##name = \ +{ (name), \ + { NULL, osThreadDetached, \ + (instances == 1) ? (&os_thread_cb_##name) : NULL,\ + (instances == 1) ? osRtxThreadCbSize : 0U, \ + ((stacksz) && (instances == 1)) ? (&os_thread_stack##name) : NULL, \ + 8*((stacksz+7)/8), \ + (priority), 0U, 0U } } +#endif +#endif + +/// Access a Thread definition. +/// \param name name of the thread definition object. +#define osThread(name) \ +&os_thread_def_##name + +/// Create a thread and add it to Active Threads and set it to state READY. +/// \param[in] thread_def thread definition referenced with \ref osThread. +/// \param[in] argument pointer that is passed to the thread function as start argument. +/// \return thread ID for reference by other functions or NULL in case of error. +osThreadId osThreadCreate (const osThreadDef_t *thread_def, void *argument); + +/// Return the thread ID of the current running thread. +/// \return thread ID for reference by other functions or NULL in case of error. +#if (osCMSIS < 0x20000U) +osThreadId osThreadGetId (void); +#endif + +/// Change priority of a thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. +/// \param[in] priority new priority value for the thread function. +/// \return status code that indicates the execution status of the function. +#if (osCMSIS < 0x20000U) +osStatus osThreadSetPriority (osThreadId thread_id, osPriority priority); +#endif + +/// Get current priority of a thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. +/// \return current priority value of the specified thread. +#if (osCMSIS < 0x20000U) +osPriority osThreadGetPriority (osThreadId thread_id); +#endif + +/// Pass control to next thread that is in state \b READY. +/// \return status code that indicates the execution status of the function. +#if (osCMSIS < 0x20000U) +osStatus osThreadYield (void); +#endif + +/// Terminate execution of a thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. +/// \return status code that indicates the execution status of the function. +#if (osCMSIS < 0x20000U) +osStatus osThreadTerminate (osThreadId thread_id); +#endif + + +// ==== Signal Management ==== + +/// Set the specified Signal Flags of an active thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. +/// \param[in] signals specifies the signal flags of the thread that should be set. +/// \return previous signal flags of the specified thread or 0x80000000 in case of incorrect parameters. +int32_t osSignalSet (osThreadId thread_id, int32_t signals); + +/// Clear the specified Signal Flags of an active thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. +/// \param[in] signals specifies the signal flags of the thread that shall be cleared. +/// \return previous signal flags of the specified thread or 0x80000000 in case of incorrect parameters or call from ISR. +int32_t osSignalClear (osThreadId thread_id, int32_t signals); + +/// Wait for one or more Signal Flags to become signaled for the current \b RUNNING thread. +/// \param[in] signals wait until all specified signal flags set or 0 for any single signal flag. +/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +/// \return event flag information or error code. +os_InRegs osEvent osSignalWait (int32_t signals, uint32_t millisec); + + +// ==== Generic Wait Functions ==== + +/// Wait for Timeout (Time Delay). +/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue "time delay" value +/// \return status code that indicates the execution status of the function. +#if (osCMSIS < 0x20000U) +osStatus osDelay (uint32_t millisec); +#endif + +#if (defined (osFeature_Wait) && (osFeature_Wait != 0)) // Generic Wait available + +/// Wait for Signal, Message, Mail, or Timeout. +/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out +/// \return event that contains signal, message, or mail information or error code. +os_InRegs osEvent osWait (uint32_t millisec); + +#endif // Generic Wait available + + +// ==== Timer Management Functions ==== + +/// Define a Timer object. +/// \param name name of the timer object. +/// \param function name of the timer call back function. +#if defined (osObjectsExternal) // object is external +#define osTimerDef(name, function) \ +extern const osTimerDef_t os_timer_def_##name +#else // define the object +#if (osCMSIS < 0x20000U) +#define osTimerDef(name, function) \ +const osTimerDef_t os_timer_def_##name = { (function) } +#else +#define osTimerDef(name, function) \ +static osRtxTimer_t os_timer_cb_##name __attribute__((section(".bss.os.timer.cb"))); \ +const osTimerDef_t os_timer_def_##name = \ +{ (function), { NULL, 0U, (&os_timer_cb_##name), osRtxTimerCbSize } } +#endif +#endif + +/// Access a Timer definition. +/// \param name name of the timer object. +#define osTimer(name) \ +&os_timer_def_##name + +/// Create and Initialize a timer. +/// \param[in] timer_def timer object referenced with \ref osTimer. +/// \param[in] type osTimerOnce for one-shot or osTimerPeriodic for periodic behavior. +/// \param[in] argument argument to the timer call back function. +/// \return timer ID for reference by other functions or NULL in case of error. +osTimerId osTimerCreate (const osTimerDef_t *timer_def, os_timer_type type, void *argument); + +/// Start or restart a timer. +/// \param[in] timer_id timer ID obtained by \ref osTimerCreate. +/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue "time delay" value of the timer. +/// \return status code that indicates the execution status of the function. +#if (osCMSIS < 0x20000U) +osStatus osTimerStart (osTimerId timer_id, uint32_t millisec); +#endif + +/// Stop a timer. +/// \param[in] timer_id timer ID obtained by \ref osTimerCreate. +/// \return status code that indicates the execution status of the function. +#if (osCMSIS < 0x20000U) +osStatus osTimerStop (osTimerId timer_id); +#endif + +/// Delete a timer. +/// \param[in] timer_id timer ID obtained by \ref osTimerCreate. +/// \return status code that indicates the execution status of the function. +#if (osCMSIS < 0x20000U) +osStatus osTimerDelete (osTimerId timer_id); +#endif + + +// ==== Mutex Management Functions ==== + +/// Define a Mutex. +/// \param name name of the mutex object. +#if defined (osObjectsExternal) // object is external +#define osMutexDef(name) \ +extern const osMutexDef_t os_mutex_def_##name +#else // define the object +#if (osCMSIS < 0x20000U) +#define osMutexDef(name) \ +const osMutexDef_t os_mutex_def_##name = { 0 } +#else +#define osMutexDef(name) \ +static osRtxMutex_t os_mutex_cb_##name __attribute__((section(".bss.os.mutex.cb"))); \ +const osMutexDef_t os_mutex_def_##name = \ +{ NULL, osMutexRecursive | osMutexPrioInherit | osMutexRobust, (&os_mutex_cb_##name), osRtxMutexCbSize } +#endif +#endif + +/// Access a Mutex definition. +/// \param name name of the mutex object. +#define osMutex(name) \ +&os_mutex_def_##name + +/// Create and Initialize a Mutex object. +/// \param[in] mutex_def mutex definition referenced with \ref osMutex. +/// \return mutex ID for reference by other functions or NULL in case of error. +osMutexId osMutexCreate (const osMutexDef_t *mutex_def); + +/// Wait until a Mutex becomes available. +/// \param[in] mutex_id mutex ID obtained by \ref osMutexCreate. +/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +/// \return status code that indicates the execution status of the function. +#if (osCMSIS < 0x20000U) +osStatus osMutexWait (osMutexId mutex_id, uint32_t millisec); +#else +#define osMutexWait osMutexAcquire +#endif + +/// Release a Mutex that was obtained by \ref osMutexWait. +/// \param[in] mutex_id mutex ID obtained by \ref osMutexCreate. +/// \return status code that indicates the execution status of the function. +#if (osCMSIS < 0x20000U) +osStatus osMutexRelease (osMutexId mutex_id); +#endif + +/// Delete a Mutex object. +/// \param[in] mutex_id mutex ID obtained by \ref osMutexCreate. +/// \return status code that indicates the execution status of the function. +#if (osCMSIS < 0x20000U) +osStatus osMutexDelete (osMutexId mutex_id); +#endif + + +// ==== Semaphore Management Functions ==== + +#if (defined (osFeature_Semaphore) && (osFeature_Semaphore != 0U)) // Semaphore available + +/// Define a Semaphore object. +/// \param name name of the semaphore object. +#if defined (osObjectsExternal) // object is external +#define osSemaphoreDef(name) \ +extern const osSemaphoreDef_t os_semaphore_def_##name +#else // define the object +#if (osCMSIS < 0x20000U) +#define osSemaphoreDef(name) \ +const osSemaphoreDef_t os_semaphore_def_##name = { 0 } +#else +#define osSemaphoreDef(name) \ +static osRtxSemaphore_t os_semaphore_cb_##name __attribute__((section(".bss.os.semaphore.cb"))); \ +const osSemaphoreDef_t os_semaphore_def_##name = \ +{ NULL, 0U, (&os_semaphore_cb_##name), osRtxSemaphoreCbSize } +#endif +#endif + +/// Access a Semaphore definition. +/// \param name name of the semaphore object. +#define osSemaphore(name) \ +&os_semaphore_def_##name + +/// Create and Initialize a Semaphore object. +/// \param[in] semaphore_def semaphore definition referenced with \ref osSemaphore. +/// \param[in] count maximum and initial number of available tokens. +/// \return semaphore ID for reference by other functions or NULL in case of error. +osSemaphoreId osSemaphoreCreate (const osSemaphoreDef_t *semaphore_def, int32_t count); + +/// Wait until a Semaphore token becomes available. +/// \param[in] semaphore_id semaphore object referenced with \ref osSemaphoreCreate. +/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +/// \return number of available tokens, or -1 in case of incorrect parameters. +int32_t osSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec); + +/// Release a Semaphore token. +/// \param[in] semaphore_id semaphore object referenced with \ref osSemaphoreCreate. +/// \return status code that indicates the execution status of the function. +#if (osCMSIS < 0x20000U) +osStatus osSemaphoreRelease (osSemaphoreId semaphore_id); +#endif + +/// Delete a Semaphore object. +/// \param[in] semaphore_id semaphore object referenced with \ref osSemaphoreCreate. +/// \return status code that indicates the execution status of the function. +#if (osCMSIS < 0x20000U) +osStatus osSemaphoreDelete (osSemaphoreId semaphore_id); +#endif + +#endif // Semaphore available + + +// ==== Memory Pool Management Functions ==== + +#if (defined(osFeature_Pool) && (osFeature_Pool != 0)) // Memory Pool available + +/// \brief Define a Memory Pool. +/// \param name name of the memory pool. +/// \param no maximum number of blocks (objects) in the memory pool. +/// \param type data type of a single block (object). +#if defined (osObjectsExternal) // object is external +#define osPoolDef(name, no, type) \ +extern const osPoolDef_t os_pool_def_##name +#else // define the object +#if (osCMSIS < 0x20000U) +#define osPoolDef(name, no, type) \ +const osPoolDef_t os_pool_def_##name = \ +{ (no), sizeof(type), NULL } +#else +#define osPoolDef(name, no, type) \ +static osRtxMemoryPool_t os_mp_cb_##name __attribute__((section(".bss.os.mempool.cb"))); \ +static uint32_t os_mp_data_##name[osRtxMemoryPoolMemSize((no),sizeof(type))/4] __attribute__((section(".bss.os.mempool.mem"))); \ +const osPoolDef_t os_pool_def_##name = \ +{ (no), sizeof(type), \ + { NULL, 0U, (&os_mp_cb_##name), osRtxMemoryPoolCbSize, \ + (&os_mp_data_##name), sizeof(os_mp_data_##name) } } +#endif +#endif + +/// \brief Access a Memory Pool definition. +/// \param name name of the memory pool +#define osPool(name) \ +&os_pool_def_##name + +/// Create and Initialize a Memory Pool object. +/// \param[in] pool_def memory pool definition referenced with \ref osPool. +/// \return memory pool ID for reference by other functions or NULL in case of error. +osPoolId osPoolCreate (const osPoolDef_t *pool_def); + +/// Allocate a memory block from a Memory Pool. +/// \param[in] pool_id memory pool ID obtain referenced with \ref osPoolCreate. +/// \return address of the allocated memory block or NULL in case of no memory available. +void *osPoolAlloc (osPoolId pool_id); + +/// Allocate a memory block from a Memory Pool and set memory block to zero. +/// \param[in] pool_id memory pool ID obtain referenced with \ref osPoolCreate. +/// \return address of the allocated memory block or NULL in case of no memory available. +void *osPoolCAlloc (osPoolId pool_id); + +/// Return an allocated memory block back to a Memory Pool. +/// \param[in] pool_id memory pool ID obtain referenced with \ref osPoolCreate. +/// \param[in] block address of the allocated memory block to be returned to the memory pool. +/// \return status code that indicates the execution status of the function. +osStatus osPoolFree (osPoolId pool_id, void *block); + +#endif // Memory Pool available + + +// ==== Message Queue Management Functions ==== + +#if (defined(osFeature_MessageQ) && (osFeature_MessageQ != 0)) // Message Queue available + +/// \brief Create a Message Queue Definition. +/// \param name name of the queue. +/// \param queue_sz maximum number of messages in the queue. +/// \param type data type of a single message element (for debugger). +#if defined (osObjectsExternal) // object is external +#define osMessageQDef(name, queue_sz, type) \ +extern const osMessageQDef_t os_messageQ_def_##name +#else // define the object +#if (osCMSIS < 0x20000U) +#define osMessageQDef(name, queue_sz, type) \ +const osMessageQDef_t os_messageQ_def_##name = \ +{ (queue_sz), NULL } +#else +#define osMessageQDef(name, queue_sz, type) \ +static osRtxMessageQueue_t os_mq_cb_##name __attribute__((section(".bss.os.msgqueue.cb"))); \ +static uint32_t os_mq_data_##name[osRtxMessageQueueMemSize((queue_sz),sizeof(uint32_t))/4] __attribute__((section(".bss.os.msgqueue.mem"))); \ +const osMessageQDef_t os_messageQ_def_##name = \ +{ (queue_sz), \ + { NULL, 0U, (&os_mq_cb_##name), osRtxMessageQueueCbSize, \ + (&os_mq_data_##name), sizeof(os_mq_data_##name) } } +#endif +#endif + +/// \brief Access a Message Queue Definition. +/// \param name name of the queue +#define osMessageQ(name) \ +&os_messageQ_def_##name + +/// Create and Initialize a Message Queue object. +/// \param[in] queue_def message queue definition referenced with \ref osMessageQ. +/// \param[in] thread_id thread ID (obtained by \ref osThreadCreate or \ref osThreadGetId) or NULL. +/// \return message queue ID for reference by other functions or NULL in case of error. +osMessageQId osMessageCreate (const osMessageQDef_t *queue_def, osThreadId thread_id); + +/// Put a Message to a Queue. +/// \param[in] queue_id message queue ID obtained with \ref osMessageCreate. +/// \param[in] info message information. +/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +/// \return status code that indicates the execution status of the function. +osStatus osMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec); + +/// Get a Message from a Queue or timeout if Queue is empty. +/// \param[in] queue_id message queue ID obtained with \ref osMessageCreate. +/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +/// \return event information that includes status code. +os_InRegs osEvent osMessageGet (osMessageQId queue_id, uint32_t millisec); + +#endif // Message Queue available + + +// ==== Mail Queue Management Functions ==== + +#if (defined(osFeature_MailQ) && (osFeature_MailQ != 0)) // Mail Queue available + +/// \brief Create a Mail Queue Definition. +/// \param name name of the queue. +/// \param queue_sz maximum number of mails in the queue. +/// \param type data type of a single mail element. +#if defined (osObjectsExternal) // object is external +#define osMailQDef(name, queue_sz, type) \ +extern const osMailQDef_t os_mailQ_def_##name +#else // define the object +#if (osCMSIS < 0x20000U) +#define osMailQDef(name, queue_sz, type) \ +const osMailQDef_t os_mailQ_def_##name = \ +{ (queue_sz), sizeof(type), NULL } +#else +#define osMailQDef(name, queue_sz, type) \ +static void *os_mail_p_##name[2] __attribute__((section(".bss.os"))); \ +static osRtxMemoryPool_t os_mail_mp_cb_##name __attribute__((section(".bss.os.mempool.cb"))); \ +static osRtxMessageQueue_t os_mail_mq_cb_##name __attribute__((section(".bss.os.msgqueue.cb"))); \ +static uint32_t os_mail_mp_data_##name[osRtxMemoryPoolMemSize ((queue_sz),sizeof(type) )/4] __attribute__((section(".bss.os.mempool.mem"))); \ +static uint32_t os_mail_mq_data_##name[osRtxMessageQueueMemSize((queue_sz),sizeof(void*))/4] __attribute__((section(".bss.os.msgqueue.mem"))); \ +const osMailQDef_t os_mailQ_def_##name = \ +{ (queue_sz), sizeof(type), (&os_mail_p_##name), \ + { NULL, 0U, (&os_mail_mp_cb_##name), osRtxMemoryPoolCbSize, \ + (&os_mail_mp_data_##name), sizeof(os_mail_mp_data_##name) }, \ + { NULL, 0U, (&os_mail_mq_cb_##name), osRtxMessageQueueCbSize, \ + (&os_mail_mq_data_##name), sizeof(os_mail_mq_data_##name) } } +#endif +#endif + +/// \brief Access a Mail Queue Definition. +/// \param name name of the queue +#define osMailQ(name) \ +&os_mailQ_def_##name + +/// Create and Initialize a Mail Queue object. +/// \param[in] queue_def mail queue definition referenced with \ref osMailQ. +/// \param[in] thread_id thread ID (obtained by \ref osThreadCreate or \ref osThreadGetId) or NULL. +/// \return mail queue ID for reference by other functions or NULL in case of error. +osMailQId osMailCreate (const osMailQDef_t *queue_def, osThreadId thread_id); + +/// Allocate a memory block for mail from a mail memory pool. +/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. +/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out +/// \return pointer to memory block that can be filled with mail or NULL in case of error. +void *osMailAlloc (osMailQId queue_id, uint32_t millisec); + +/// Allocate a memory block for mail from a mail memory pool and set memory block to zero. +/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. +/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out +/// \return pointer to memory block that can be filled with mail or NULL in case of error. +void *osMailCAlloc (osMailQId queue_id, uint32_t millisec); + +/// Put a Mail into a Queue. +/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. +/// \param[in] mail pointer to memory with mail to put into a queue. +/// \return status code that indicates the execution status of the function. +osStatus osMailPut (osMailQId queue_id, const void *mail); + +/// Get a Mail from a Queue or timeout if Queue is empty. +/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. +/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +/// \return event information that includes status code. +os_InRegs osEvent osMailGet (osMailQId queue_id, uint32_t millisec); + +/// Free a memory block by returning it to a mail memory pool. +/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. +/// \param[in] mail pointer to memory block that was obtained with \ref osMailGet. +/// \return status code that indicates the execution status of the function. +osStatus osMailFree (osMailQId queue_id, void *mail); + +#endif // Mail Queue available + + +#ifdef __cplusplus +} +#endif + +#endif // CMSIS_OS_H_ diff --git a/rtos/rtx/cmsis_os1.c b/rtos/rtx/cmsis_os1.c new file mode 100644 index 00000000000..a68eb0a1d8b --- /dev/null +++ b/rtos/rtx/cmsis_os1.c @@ -0,0 +1,371 @@ +/* + * Copyright (c) 2013-2017 ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ---------------------------------------------------------------------- + * + * $Date: 10. January 2017 + * $Revision: V1.2 + * + * Project: CMSIS-RTOS API V1 + * Title: cmsis_os_v1.c V1 module file + *---------------------------------------------------------------------------*/ + +#include +#include "cmsis_os.h" + +#if (osCMSIS >= 0x20000U) && !defined(os1_Disable) + + +// Thread +#if !defined(os1_Disable_Thread) +osThreadId osThreadCreate (const osThreadDef_t *thread_def, void *argument) { + + if (thread_def == NULL) { + return NULL; + } + return osThreadNew((osThreadFunc_t)thread_def->pthread, argument, &thread_def->attr); +} +#endif + + +// Signals + +#if !defined(os1_Disable_Signal) + +#define SignalMask ((1U< 0U) && (flags < 0x80000000U)) { + event.status = osEventSignal; + event.value.signals = (int32_t)flags; + } else { + switch ((int32_t)flags) { + case osErrorResource: + event.status = osOK; + break; + case osErrorTimeout: + event.status = osEventTimeout; + break; + case osErrorParameter: + event.status = osErrorValue; + break; + default: + event.status = (osStatus)flags; + break; + } + } + return event; +} + +#endif // Signal + + +// Timer +#if !defined(os1_Disable_Timer) +osTimerId osTimerCreate (const osTimerDef_t *timer_def, os_timer_type type, void *argument) { + + if (timer_def == NULL) { + return NULL; + } + return osTimerNew((osTimerFunc_t)timer_def->ptimer, type, argument, &timer_def->attr); +} +#endif + + +// Mutex +#if !defined(os1_Disable_Mutex) +osMutexId osMutexCreate (const osMutexDef_t *mutex_def) { + + if (mutex_def == NULL) { + return NULL; + } + return osMutexNew(mutex_def); +} +#endif + + +// Semaphore + +#if (defined (osFeature_Semaphore) && (osFeature_Semaphore != 0U)) && !defined(os1_Disable_Semaphore) + +osSemaphoreId osSemaphoreCreate (const osSemaphoreDef_t *semaphore_def, int32_t count) { + + if (semaphore_def == NULL) { + return NULL; + } + return osSemaphoreNew((uint32_t)count, (uint32_t)count, semaphore_def); +} + +int32_t osSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec) { + osStatus_t status; + uint32_t count; + + status = osSemaphoreAcquire(semaphore_id, millisec); + switch (status) { + case osOK: + count = osSemaphoreGetCount(semaphore_id); + return ((int32_t)count + 1); + case osErrorResource: + case osErrorTimeout: + return 0; + default: + break; + } + return -1; +} + +#endif // Semaphore + + +// Memory Pool + +#if (defined(osFeature_Pool) && (osFeature_Pool != 0))&& !defined(os1_Disable_Pool) + +osPoolId osPoolCreate (const osPoolDef_t *pool_def) { + + if (pool_def == NULL) { + return NULL; + } + return osMemoryPoolNew(pool_def->pool_sz, pool_def->item_sz, &pool_def->attr); +} + +void *osPoolAlloc (osPoolId pool_id) { + return osMemoryPoolAlloc(pool_id, 0U); +} + +void *osPoolCAlloc (osPoolId pool_id) { + void *block; + uint32_t block_size; + + block_size = osMemoryPoolGetBlockSize((osMemoryPoolId_t)pool_id); + if (block_size == 0U) { + return NULL; + } + block = osMemoryPoolAlloc(pool_id, 0U); + if (block != NULL) { + memset(block, 0, block_size); + } + return block; +} + +osStatus osPoolFree (osPoolId pool_id, void *block) { + return osMemoryPoolFree(pool_id, block); +} + +#endif // Memory Pool + + +// Message Queue + +#if (defined(osFeature_MessageQ) && (osFeature_MessageQ != 0)) && !defined(os1_Disable_MessageQ) + +osMessageQId osMessageCreate (const osMessageQDef_t *queue_def, osThreadId thread_id) { + (void)thread_id; + + if (queue_def == NULL) { + return NULL; + } + return osMessageQueueNew(queue_def->queue_sz, sizeof(uint32_t), &queue_def->attr); +} + +osStatus osMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec) { + return osMessageQueuePut(queue_id, &info, 0U, millisec); +} + +os_InRegs osEvent osMessageGet (osMessageQId queue_id, uint32_t millisec) { + osStatus_t status; + osEvent event; + uint32_t message; + + status = osMessageQueueGet(queue_id, &message, NULL, millisec); + switch (status) { + case osOK: + event.status = osEventMessage; + event.value.v = message; + break; + case osErrorResource: + event.status = osOK; + break; + case osErrorTimeout: + event.status = osEventTimeout; + break; + default: + event.status = status; + break; + } + return event; +} + +#endif // Message Queue + + +// Mail Queue + +#if (defined(osFeature_MailQ) && (osFeature_MailQ != 0)) && !defined(os1_Disable_MailQ) + +typedef struct os_mail_queue_s { + osMemoryPoolId_t mp_id; + osMessageQueueId_t mq_id; +} os_mail_queue_t; + +osMailQId osMailCreate (const osMailQDef_t *queue_def, osThreadId thread_id) { + os_mail_queue_t *ptr; + (void)thread_id; + + if (queue_def == NULL) { + return NULL; + } + + ptr = queue_def->mail; + if (ptr == NULL) { + return NULL; + } + + ptr->mp_id = osMemoryPoolNew (queue_def->queue_sz, queue_def->item_sz, &queue_def->mp_attr); + ptr->mq_id = osMessageQueueNew(queue_def->queue_sz, sizeof(void *), &queue_def->mq_attr); + if ((ptr->mp_id == NULL) || (ptr->mq_id == NULL)) { + if (ptr->mp_id != NULL) { + osMemoryPoolDelete(ptr->mp_id); + } + if (ptr->mq_id != NULL) { + osMessageQueueDelete(ptr->mq_id); + } + return NULL; + } + + return ptr; +} + +void *osMailAlloc (osMailQId queue_id, uint32_t millisec) { + os_mail_queue_t *ptr = (os_mail_queue_t *)queue_id; + + if (ptr == NULL) { + return NULL; + } + return osMemoryPoolAlloc(ptr->mp_id, millisec); +} + +void *osMailCAlloc (osMailQId queue_id, uint32_t millisec) { + os_mail_queue_t *ptr = (os_mail_queue_t *)queue_id; + void *block; + uint32_t block_size; + + if (ptr == NULL) { + return NULL; + } + block_size = osMemoryPoolGetBlockSize(ptr->mp_id); + if (block_size == 0U) { + return NULL; + } + block = osMemoryPoolAlloc(ptr->mp_id, millisec); + if (block != NULL) { + memset(block, 0, block_size); + } + + return block; + +} + +osStatus osMailPut (osMailQId queue_id, const void *mail) { + os_mail_queue_t *ptr = (os_mail_queue_t *)queue_id; + + if (ptr == NULL) { + return osErrorParameter; + } + if (mail == NULL) { + return osErrorValue; + } + return osMessageQueuePut(ptr->mq_id, &mail, 0U, 0U); +} + +os_InRegs osEvent osMailGet (osMailQId queue_id, uint32_t millisec) { + os_mail_queue_t *ptr = (os_mail_queue_t *)queue_id; + osStatus_t status; + osEvent event; + void *mail; + + if (ptr == NULL) { + event.status = osErrorParameter; + return event; + } + + status = osMessageQueueGet(ptr->mq_id, &mail, NULL, millisec); + switch (status) { + case osOK: + event.status = osEventMail; + event.value.p = mail; + break; + case osErrorResource: + event.status = osOK; + break; + case osErrorTimeout: + event.status = osEventTimeout; + break; + default: + event.status = status; + break; + } + return event; +} + +osStatus osMailFree (osMailQId queue_id, void *mail) { + os_mail_queue_t *ptr = (os_mail_queue_t *)queue_id; + + if (ptr == NULL) { + return osErrorParameter; + } + if (mail == NULL) { + return osErrorValue; + } + return osMemoryPoolFree(ptr->mp_id, mail); +} + +#endif // Mail Queue + + +#endif // osCMSIS diff --git a/rtos/rtx2/TARGET_CORTEX_M/RTX_Config.c b/rtos/rtx2/TARGET_CORTEX_M/RTX_Config.c new file mode 100644 index 00000000000..69c8179dfb1 --- /dev/null +++ b/rtos/rtx2/TARGET_CORTEX_M/RTX_Config.c @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2013-2017 ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ----------------------------------------------------------------------------- + * + * $Revision: V5.1.0 + * + * Project: CMSIS-RTOS RTX + * Title: RTX Configuration + * + * ----------------------------------------------------------------------------- + */ + +#include "cmsis_compiler.h" +#include "rtx_os.h" + +// OS Idle Thread +__WEAK __NO_RETURN void osRtxIdleThread (void *argument) { + (void)argument; + + for (;;) {} +} + +// OS Error Callback function +__WEAK uint32_t osRtxErrorNotify (uint32_t code, void *object_id) { + (void)object_id; + + switch (code) { + case osRtxErrorStackUnderflow: + // Stack underflow detected for thread (thread_id=object_id) + break; + case osRtxErrorISRQueueOverflow: + // ISR Queue overflow detected when inserting object (object_id) + break; + case osRtxErrorTimerQueueOverflow: + // User Timer Callback Queue overflow detected for timer (timer_id=object_id) + break; + case osRtxErrorClibSpace: + // Standard C/C++ library libspace not available: increase OS_THREAD_LIBSPACE_NUM + break; + case osRtxErrorClibMutex: + // Standard C/C++ library mutex initialization failed + break; + default: + break; + } + for (;;) {} +//return 0U; +} diff --git a/rtos/rtx2/TARGET_CORTEX_M/RTX_Config.h b/rtos/rtx2/TARGET_CORTEX_M/RTX_Config.h new file mode 100644 index 00000000000..6cacee82488 --- /dev/null +++ b/rtos/rtx2/TARGET_CORTEX_M/RTX_Config.h @@ -0,0 +1,379 @@ +/* + * Copyright (c) 2013-2017 ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ----------------------------------------------------------------------------- + * + * $Revision: V5.1.0 + * + * Project: CMSIS-RTOS RTX + * Title: RTX Configuration definitions + * + * ----------------------------------------------------------------------------- + */ + +#ifndef RTX_CONFIG_H_ +#define RTX_CONFIG_H_ + +//-------- <<< Use Configuration Wizard in Context Menu >>> -------------------- + +// System Configuration +// ======================= + +// Global Dynamic Memory size [bytes] <0-1073741824:8> +// Defines the combined global dynamic memory size. +// Default: 4096 +#ifndef OS_DYNAMIC_MEM_SIZE +#define OS_DYNAMIC_MEM_SIZE 4096 +#endif + +// Kernel Tick Frequency [Hz] <1-1000000> +// Defines base time unit for delays and timeouts. +// Default: 1000 (1ms tick) +#ifndef OS_TICK_FREQ +#define OS_TICK_FREQ 1000 +#endif + +// Round-Robin Thread switching +// Enables Round-Robin Thread switching. +#ifndef OS_ROBIN_ENABLE +#define OS_ROBIN_ENABLE 1 +#endif + +// Round-Robin Timeout <1-1000> +// Defines how many ticks a thread will execute before a thread switch. +// Default: 5 +#ifndef OS_ROBIN_TIMEOUT +#define OS_ROBIN_TIMEOUT 5 +#endif + +// + +// Event Recording + +// Memory Management +// Enables Memory Management events recording. +#ifndef OS_EVR_MEMORY +#define OS_EVR_MEMORY 1 +#endif + +// Kernel +// Enables Kernel events recording. +#ifndef OS_EVR_KERNEL +#define OS_EVR_KERNEL 1 +#endif + +// Thread +// Enables Thread events recording. +#ifndef OS_EVR_THREAD +#define OS_EVR_THREAD 1 +#endif + +// Timer +// Enables Timer events recording. +#ifndef OS_EVR_TIMER +#define OS_EVR_TIMER 1 +#endif + +// Event Flags +// Enables Event Flags events recording. +#ifndef OS_EVR_EVFLAGS +#define OS_EVR_EVFLAGS 1 +#endif + +// Mutex +// Enables Mutex events recording. +#ifndef OS_EVR_MUTEX +#define OS_EVR_MUTEX 1 +#endif + +// Semaphore +// Enables Semaphore events recording. +#ifndef OS_EVR_SEMAPHORE +#define OS_EVR_SEMAPHORE 1 +#endif + +// Memory Pool +// Enables Memory Pool events recording. +#ifndef OS_EVR_MEMPOOL +#define OS_EVR_MEMPOOL 1 +#endif + +// Message Queue +// Enables Message Queue events recording. +#ifndef OS_EVR_MSGQUEUE +#define OS_EVR_MSGQUEUE 1 +#endif + +// + +// ISR FIFO Queue +// <4=> 4 entries <8=> 8 entries <12=> 12 entries <16=> 16 entries +// <24=> 24 entries <32=> 32 entries <48=> 48 entries <64=> 64 entries +// <96=> 96 entries <128=> 128 entries <196=> 196 entries <256=> 256 entries +// RTOS Functions called from ISR store requests to this buffer. +// Default: 16 entries +#ifndef OS_ISR_FIFO_QUEUE +#define OS_ISR_FIFO_QUEUE 16 +#endif + +// + +// Thread Configuration +// ======================= + +// Object specific Memory allocation +// Enables object specific memory allocation. +#ifndef OS_THREAD_OBJ_MEM +#define OS_THREAD_OBJ_MEM 0 +#endif + +// Number of user Threads <1-1000> +// Defines maximum number of user threads that can be active at the same time. +// Applies to user threads with system provided memory for control blocks. +#ifndef OS_THREAD_NUM +#define OS_THREAD_NUM 1 +#endif + +// Number of user Threads with default Stack size <0-1000> +// Defines maximum number of user threads with default stack size. +// Applies to user threads with zero stack size specified. +#ifndef OS_THREAD_DEF_STACK_NUM +#define OS_THREAD_DEF_STACK_NUM 0 +#endif + +// Total Stack size [bytes] for user Threads with user-provided Stack size <0-1073741824:8> +// Defines the combined stack size for user threads with user-provided stack size. +// Applies to user threads with user-provided stack size and system provided memory for stack. +// Default: 0 +#ifndef OS_THREAD_USER_STACK_SIZE +#define OS_THREAD_USER_STACK_SIZE 0 +#endif + +// + +// Default Thread Stack size [bytes] <96-1073741824:8> +// Defines stack size for threads with zero stack size specified. +// Default: 200 +#ifndef OS_STACK_SIZE +#define OS_STACK_SIZE 200 +#endif + +// Idle Thread Stack size [bytes] <72-1073741824:8> +// Defines stack size for Idle thread. +// Default: 200 +#ifndef OS_IDLE_THREAD_STACK_SIZE +#define OS_IDLE_THREAD_STACK_SIZE 200 +#endif + +// Stack overrun checking +// Enable stack overrun checks at thread switch. +// Enabling this option increases slightly the execution time of a thread switch. +#ifndef OS_STACK_CHECK +#define OS_STACK_CHECK 1 +#endif + +// Stack usage watermark +// Initialize thread stack with watermark pattern for analyzing stack usage. +// Enabling this option increases significantly the execution time of thread creation. +#ifndef OS_STACK_WATERMARK +#define OS_STACK_WATERMARK 0 +#endif + +// Processor mode for Thread execution +// <0=> Unprivileged mode +// <1=> Privileged mode +// Default: Privileged mode +#ifndef OS_PRIVILEGE_MODE +#define OS_PRIVILEGE_MODE 1 +#endif + +// + +// Timer Configuration +// ====================== + +// Object specific Memory allocation +// Enables object specific memory allocation. +#ifndef OS_TIMER_OBJ_MEM +#define OS_TIMER_OBJ_MEM 0 +#endif + +// Number of Timer objects <1-1000> +// Defines maximum number of objects that can be active at the same time. +// Applies to objects with system provided memory for control blocks. +#ifndef OS_TIMER_NUM +#define OS_TIMER_NUM 1 +#endif + +// + +// Timer Thread Priority +// <8=> Low +// <16=> Below Normal <24=> Normal <32=> Above Normal +// <40=> High +// <48=> Realtime +// Defines priority for timer thread +// Default: High +#ifndef OS_TIMER_THREAD_PRIO +#define OS_TIMER_THREAD_PRIO 40 +#endif + +// Timer Thread Stack size [bytes] <0-1073741824:8> +// Defines stack size for Timer thread. +// May be set to 0 when timers are not used. +// Default: 200 +#ifndef OS_TIMER_THREAD_STACK_SIZE +#define OS_TIMER_THREAD_STACK_SIZE 200 +#endif + +// Timer Callback Queue entries <0-256> +// Number of concurrent active timer callback functions. +// May be set to 0 when timers are not used. +// Default: 4 +#ifndef OS_TIMER_CB_QUEUE +#define OS_TIMER_CB_QUEUE 4 +#endif + +// + +// Event Flags Configuration +// ============================ + +// Object specific Memory allocation +// Enables object specific memory allocation. +#ifndef OS_EVFLAGS_OBJ_MEM +#define OS_EVFLAGS_OBJ_MEM 0 +#endif + +// Number of Event Flags objects <1-1000> +// Defines maximum number of objects that can be active at the same time. +// Applies to objects with system provided memory for control blocks. +#ifndef OS_EVFLAGS_NUM +#define OS_EVFLAGS_NUM 1 +#endif + +// + +// + +// Mutex Configuration +// ====================== + +// Object specific Memory allocation +// Enables object specific memory allocation. +#ifndef OS_MUTEX_OBJ_MEM +#define OS_MUTEX_OBJ_MEM 0 +#endif + +// Number of Mutex objects <1-1000> +// Defines maximum number of objects that can be active at the same time. +// Applies to objects with system provided memory for control blocks. +#ifndef OS_MUTEX_NUM +#define OS_MUTEX_NUM 1 +#endif + +// + +// + +// Semaphore Configuration +// ========================== + +// Object specific Memory allocation +// Enables object specific memory allocation. +#ifndef OS_SEMAPHORE_OBJ_MEM +#define OS_SEMAPHORE_OBJ_MEM 0 +#endif + +// Number of Semaphore objects <1-1000> +// Defines maximum number of objects that can be active at the same time. +// Applies to objects with system provided memory for control blocks. +#ifndef OS_SEMAPHORE_NUM +#define OS_SEMAPHORE_NUM 1 +#endif + +// + +// + +// Memory Pool Configuration +// ============================ + +// Object specific Memory allocation +// Enables object specific memory allocation. +#ifndef OS_MEMPOOL_OBJ_MEM +#define OS_MEMPOOL_OBJ_MEM 0 +#endif + +// Number of Memory Pool objects <1-1000> +// Defines maximum number of objects that can be active at the same time. +// Applies to objects with system provided memory for control blocks. +#ifndef OS_MEMPOOL_NUM +#define OS_MEMPOOL_NUM 1 +#endif + +// Data Storage Memory size [bytes] <0-1073741824:8> +// Defines the combined data storage memory size. +// Applies to objects with system provided memory for data storage. +// Default: 0 +#ifndef OS_MEMPOOL_DATA_SIZE +#define OS_MEMPOOL_DATA_SIZE 0 +#endif + +// + +// + +// Message Queue Configuration +// ============================== + +// Object specific Memory allocation +// Enables object specific memory allocation. +#ifndef OS_MSGQUEUE_OBJ_MEM +#define OS_MSGQUEUE_OBJ_MEM 0 +#endif + +// Number of Message Queue objects <1-1000> +// Defines maximum number of objects that can be active at the same time. +// Applies to objects with system provided memory for control blocks. +#ifndef OS_MSGQUEUE_NUM +#define OS_MSGQUEUE_NUM 1 +#endif + +// Data Storage Memory size [bytes] <0-1073741824:8> +// Defines the combined data storage memory size. +// Applies to objects with system provided memory for data storage. +// Default: 0 +#ifndef OS_MSGQUEUE_DATA_SIZE +#define OS_MSGQUEUE_DATA_SIZE 0 +#endif + +// + +// + +// Number of Threads which use standard C/C++ library libspace +// (when thread specific memory allocation is not used). +#if (OS_THREAD_OBJ_MEM == 0) +#define OS_THREAD_LIBSPACE_NUM 4 +#else +#define OS_THREAD_LIBSPACE_NUM OS_THREAD_NUM +#endif + +//------------- <<< end of configuration section >>> --------------------------- + +#endif // RTX_CONFIG_H_ diff --git a/rtos/rtx2/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_ARM/irq_cm0.s b/rtos/rtx2/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_ARM/irq_cm0.s new file mode 100644 index 00000000000..74c8a84a45c --- /dev/null +++ b/rtos/rtx2/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_ARM/irq_cm0.s @@ -0,0 +1,155 @@ +;/* +; * Copyright (c) 2013-2017 ARM Limited. All rights reserved. +; * +; * SPDX-License-Identifier: Apache-2.0 +; * +; * Licensed under the Apache License, Version 2.0 (the License); you may +; * not use this file except in compliance with the License. +; * You may obtain a copy of the License at +; * +; * www.apache.org/licenses/LICENSE-2.0 +; * +; * Unless required by applicable law or agreed to in writing, software +; * distributed under the License is distributed on an AS IS BASIS, WITHOUT +; * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; * See the License for the specific language governing permissions and +; * limitations under the License. +; * +; * ----------------------------------------------------------------------------- +; * +; * Project: CMSIS-RTOS RTX +; * Title: Cortex-M0 Exception handlers +; * +; * ----------------------------------------------------------------------------- +; */ + + +I_T_RUN_OFS EQU 28 ; osRtxInfo.thread.run offset +TCB_SP_OFS EQU 56 ; TCB.SP offset + + + PRESERVE8 + THUMB + + + AREA |.constdata|, DATA, READONLY + EXPORT irqRtxLib +irqRtxLib DCB 0 ; Non weak library reference + + + AREA |.text|, CODE, READONLY + + +SVC_Handler PROC + EXPORT SVC_Handler + IMPORT osRtxUserSVC + IMPORT osRtxInfo + + MRS R0,PSP ; Get PSP + LDR R1,[R0,#24] ; Load saved PC from stack + SUBS R1,R1,#2 ; Point to SVC instruction + LDRB R1,[R1] ; Load SVC number + CMP R1,#0 + BNE SVC_User ; Branch if not SVC 0 + + PUSH {R0,LR} ; Save PSP and EXC_RETURN + LDMIA R0,{R0-R3} ; Load function parameters from stack + BLX R7 ; Call service function + POP {R2,R3} ; Restore PSP and EXC_RETURN + STMIA R2!,{R0-R1} ; Store function return values + MOV LR,R3 ; Set EXC_RETURN + +SVC_Context + LDR R3,=osRtxInfo+I_T_RUN_OFS; Load address of osRtxInfo.run + LDMIA R3!,{R1,R2} ; Load osRtxInfo.thread.run: curr & next + CMP R1,R2 ; Check if thread switch is required + BEQ SVC_Exit ; Branch when threads are the same + + CMP R1,#0 + BEQ SVC_ContextSwitch ; Branch if running thread is deleted + +SVC_ContextSave + MRS R0,PSP ; Get PSP + SUBS R0,R0,#32 ; Adjust address + STR R0,[R1,#TCB_SP_OFS] ; Store SP + STMIA R0!,{R4-R7} ; Save R4..R7 + MOV R4,R8 + MOV R5,R9 + MOV R6,R10 + MOV R7,R11 + STMIA R0!,{R4-R7} ; Save R8..R11 + +SVC_ContextSwitch + SUBS R3,R3,#8 + STR R2,[R3] ; osRtxInfo.thread.run: curr = next + +SVC_ContextRestore + LDR R0,[R2,#TCB_SP_OFS] ; Load SP + ADDS R0,R0,#16 ; Adjust address + LDMIA R0!,{R4-R7} ; Restore R8..R11 + MOV R8,R4 + MOV R9,R5 + MOV R10,R6 + MOV R11,R7 + MSR PSP,R0 ; Set PSP + SUBS R0,R0,#32 ; Adjust address + LDMIA R0!,{R4-R7} ; Restore R4..R7 + + MOVS R0,#~0xFFFFFFFD + MVNS R0,R0 ; Set EXC_RETURN value + BX R0 ; Exit from handler + +SVC_Exit + BX LR ; Exit from handler + +SVC_User + PUSH {R4,LR} ; Save registers + LDR R2,=osRtxUserSVC ; Load address of SVC table + LDR R3,[R2] ; Load SVC maximum number + CMP R1,R3 ; Check SVC number range + BHI SVC_Done ; Branch if out of range + + LSLS R1,R1,#2 + LDR R4,[R2,R1] ; Load address of SVC function + + LDMIA R0,{R0-R3} ; Load function parameters from stack + BLX R4 ; Call service function + MRS R4,PSP ; Get PSP + STMIA R4!,{R0-R3} ; Store function return values + +SVC_Done + POP {R4,PC} ; Return from handler + + ALIGN + ENDP + + +PendSV_Handler PROC + EXPORT PendSV_Handler + IMPORT osRtxPendSV_Handler + + PUSH {R0,LR} ; Save EXC_RETURN + BL osRtxPendSV_Handler ; Call osRtxPendSV_Handler + POP {R0,R1} ; Restore EXC_RETURN + MOV LR,R1 ; Set EXC_RETURN + B SVC_Context + + ALIGN + ENDP + + +SysTick_Handler PROC + EXPORT SysTick_Handler + IMPORT osRtxTick_Handler + + PUSH {R0,LR} ; Save EXC_RETURN + BL osRtxTick_Handler ; Call osRtxTick_Handler + POP {R0,R1} ; Restore EXC_RETURN + MOV LR,R1 ; Set EXC_RETURN + B SVC_Context + + ALIGN + ENDP + + + END diff --git a/rtos/rtx2/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_GCC/irq_cm0.S b/rtos/rtx2/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_GCC/irq_cm0.S new file mode 100644 index 00000000000..5362c196960 --- /dev/null +++ b/rtos/rtx2/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_GCC/irq_cm0.S @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2013-2017 ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ----------------------------------------------------------------------------- + * + * Project: CMSIS-RTOS RTX + * Title: Cortex-M0 Exception handlers + * + * ----------------------------------------------------------------------------- + */ + + + .file "irq_cm0.S" + .syntax unified + + .equ I_T_RUN_OFS, 28 // osRtxInfo.thread.run offset + .equ TCB_SP_OFS, 56 // TCB.SP offset + + .section ".rodata" + .global irqRtxLib // Non weak library reference +irqRtxLib: + .byte 0 + + + .thumb + .section ".text" + .align 2 + + + .thumb_func + .type SVC_Handler, %function + .global SVC_Handler + .fnstart + .cantunwind +SVC_Handler: + + MRS R0,PSP // Get PSP + LDR R1,[R0,#24] // Load saved PC from stack + SUBS R1,R1,#2 // Point to SVC instruction + LDRB R1,[R1] // Load SVC number + CMP R1,#0 + BNE SVC_User // Branch if not SVC 0 + + PUSH {R0,LR} // Save PSP and EXC_RETURN + LDMIA R0,{R0-R3} // Load function parameters from stack + BLX R7 // Call service function + POP {R2,R3} // Restore PSP and EXC_RETURN + STMIA R2!,{R0-R1} // Store function return values + MOV LR,R3 // Set EXC_RETURN + +SVC_Context: + LDR R3,=osRtxInfo+I_T_RUN_OFS // Load address of osRtxInfo.run + LDMIA R3!,{R1,R2} // Load osRtxInfo.thread.run: curr & next + CMP R1,R2 // Check if thread switch is required + BEQ SVC_Exit // Branch when threads are the same + + CMP R1,#0 + BEQ SVC_ContextSwitch // Branch if running thread is deleted + +SVC_ContextSave: + MRS R0,PSP // Get PSP + SUBS R0,R0,#32 // Adjust address + STR R0,[R1,#TCB_SP_OFS]; // Store SP + STMIA R0!,{R4-R7} // Save R4..R7 + MOV R4,R8 + MOV R5,R9 + MOV R6,R10 + MOV R7,R11 + STMIA R0!,{R4-R7} // Save R8..R11 + +SVC_ContextSwitch: + SUBS R3,R3,#8 + STR R2,[R3] // osRtxInfo.thread.run: curr = next + +SVC_ContextRestore: + LDR R0,[R2,#TCB_SP_OFS] // Load SP + ADDS R0,R0,#16 // Adjust address + LDMIA R0!,{R4-R7} // Restore R8..R11 + MOV R8,R4 + MOV R9,R5 + MOV R10,R6 + MOV R11,R7 + MSR PSP,R0 // Set PSP + SUBS R0,R0,#32 // Adjust address + LDMIA R0!,{R4-R7} // Restore R4..R7 + + MOVS R0,#~0xFFFFFFFD + MVNS R0,R0 // Set EXC_RETURN value + BX R0 // Exit from handler + +SVC_Exit: + BX LR // Exit from handler + +SVC_User: + PUSH {R4,LR} // Save registers + LDR R2,=osRtxUserSVC // Load address of SVC table + LDR R3,[R2] // Load SVC maximum number + CMP R1,R3 // Check SVC number range + BHI SVC_Done // Branch if out of range + + LSLS R1,R1,#2 + LDR R4,[R2,R1] // Load address of SVC function + + LDMIA R0,{R0-R3} // Load function parameters from stack + BLX R4 // Call service function + MRS R4,PSP // Get PSP + STMIA R4!,{R0-R3} // Store function return values + +SVC_Done: + POP {R4,PC} // Return from handler + + .fnend + .size SVC_Handler, .-SVC_Handler + + + .thumb_func + .type PendSV_Handler, %function + .global PendSV_Handler + .fnstart + .cantunwind +PendSV_Handler: + + PUSH {R0,LR} // Save EXC_RETURN + BL osRtxPendSV_Handler // Call osRtxPendSV_Handler + POP {R0,R1} // Restore EXC_RETURN + MOV LR,R1 // Set EXC_RETURN + B SVC_Context + + .fnend + .size PendSV_Handler, .-PendSV_Handler + + + .thumb_func + .type SysTick_Handler, %function + .global SysTick_Handler + .fnstart + .cantunwind +SysTick_Handler: + + PUSH {R0,LR} // Save EXC_RETURN + BL osRtxTick_Handler // Call osRtxTick_Handler + POP {R0,R1} // Restore EXC_RETURN + MOV LR,R1 // Set EXC_RETURN + B SVC_Context + + .fnend + .size SysTick_Handler, .-SysTick_Handler + + + .end diff --git a/rtos/rtx2/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_IAR/irq_cm0.s b/rtos/rtx2/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_IAR/irq_cm0.s new file mode 100644 index 00000000000..023aae3a9e7 --- /dev/null +++ b/rtos/rtx2/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_IAR/irq_cm0.s @@ -0,0 +1,149 @@ +;/* +; * Copyright (c) 2013-2017 ARM Limited. All rights reserved. +; * +; * SPDX-License-Identifier: Apache-2.0 +; * +; * Licensed under the Apache License, Version 2.0 (the License); you may +; * not use this file except in compliance with the License. +; * You may obtain a copy of the License at +; * +; * www.apache.org/licenses/LICENSE-2.0 +; * +; * Unless required by applicable law or agreed to in writing, software +; * distributed under the License is distributed on an AS IS BASIS, WITHOUT +; * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; * See the License for the specific language governing permissions and +; * limitations under the License. +; * +; * ----------------------------------------------------------------------------- +; * +; * Project: CMSIS-RTOS RTX +; * Title: Cortex-M0 Exception handlers +; * +; * ----------------------------------------------------------------------------- +; */ + + + NAME irq_cm0.s + + +I_T_RUN_OFS EQU 28 ; osRtxInfo.thread.run offset +TCB_SP_OFS EQU 56 ; TCB.SP offset + + + PRESERVE8 + SECTION .rodata:DATA:NOROOT(2) + + + EXPORT irqRtxLib +irqRtxLib DCB 0 ; Non weak library reference + + + THUMB + SECTION .text:CODE:NOROOT(2) + + +SVC_Handler + EXPORT SVC_Handler + IMPORT osRtxUserSVC + IMPORT osRtxInfo + + MRS R0,PSP ; Get PSP + LDR R1,[R0,#24] ; Load saved PC from stack + SUBS R1,R1,#2 ; Point to SVC instruction + LDRB R1,[R1] ; Load SVC number + CMP R1,#0 + BNE SVC_User ; Branch if not SVC 0 + + PUSH {R0,LR} ; Save PSP and EXC_RETURN + LDMIA R0,{R0-R3} ; Load function parameters from stack + BLX R7 ; Call service function + POP {R2,R3} ; Restore PSP and EXC_RETURN + STMIA R2!,{R0-R1} ; Store function return values + MOV LR,R3 ; Set EXC_RETURN + +SVC_Context + LDR R3,=osRtxInfo+I_T_RUN_OFS; Load address of osRtxInfo.run + LDMIA R3!,{R1,R2} ; Load osRtxInfo.thread.run: curr & next + CMP R1,R2 ; Check if thread switch is required + BEQ SVC_Exit ; Branch when threads are the same + + CMP R1,#0 + BEQ SVC_ContextSwitch ; Branch if running thread is deleted + +SVC_ContextSave + MRS R0,PSP ; Get PSP + SUBS R0,R0,#32 ; Adjust address + STR R0,[R1,#TCB_SP_OFS] ; Store SP + STMIA R0!,{R4-R7} ; Save R4..R7 + MOV R4,R8 + MOV R5,R9 + MOV R6,R10 + MOV R7,R11 + STMIA R0!,{R4-R7} ; Save R8..R11 + +SVC_ContextSwitch + SUBS R3,R3,#8 + STR R2,[R3] ; osRtxInfo.thread.run: curr = next + +SVC_ContextRestore + LDR R0,[R2,#TCB_SP_OFS] ; Load SP + ADDS R0,R0,#16 ; Adjust address + LDMIA R0!,{R4-R7} ; Restore R8..R11 + MOV R8,R4 + MOV R9,R5 + MOV R10,R6 + MOV R11,R7 + MSR PSP,R0 ; Set PSP + SUBS R0,R0,#32 ; Adjust address + LDMIA R0!,{R4-R7} ; Restore R4..R7 + + MOVS R0,#~0xFFFFFFFD + MVNS R0,R0 ; Set EXC_RETURN value + BX R0 ; Exit from handler + +SVC_Exit + BX LR ; Exit from handler + +SVC_User + PUSH {R4,LR} ; Save registers + LDR R2,=osRtxUserSVC ; Load address of SVC table + LDR R3,[R2] ; Load SVC maximum number + CMP R1,R3 ; Check SVC number range + BHI SVC_Done ; Branch if out of range + + LSLS R1,R1,#2 + LDR R4,[R2,R1] ; Load address of SVC function + + LDMIA R0,{R0-R3} ; Load function parameters from stack + BLX R4 ; Call service function + MRS R4,PSP ; Get PSP + STMIA R4!,{R0-R3} ; Store function return values + +SVC_Done + POP {R4,PC} ; Return from handler + + +PendSV_Handler + EXPORT PendSV_Handler + IMPORT osRtxPendSV_Handler + + PUSH {R0,LR} ; Save EXC_RETURN + BL osRtxPendSV_Handler ; Call osRtxPendSV_Handler + POP {R0,R1} ; Restore EXC_RETURN + MOV LR,R1 ; Set EXC_RETURN + B SVC_Context + + +SysTick_Handler + EXPORT SysTick_Handler + IMPORT osRtxTick_Handler + + PUSH {R0,LR} ; Save EXC_RETURN + BL osRtxTick_Handler ; Call osRtxTick_Handler + POP {R0,R1} ; Restore EXC_RETURN + MOV LR,R1 ; Set EXC_RETURN + B SVC_Context + + + END diff --git a/rtos/rtx2/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_ARM/irq_cm0.s b/rtos/rtx2/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_ARM/irq_cm0.s new file mode 100644 index 00000000000..74c8a84a45c --- /dev/null +++ b/rtos/rtx2/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_ARM/irq_cm0.s @@ -0,0 +1,155 @@ +;/* +; * Copyright (c) 2013-2017 ARM Limited. All rights reserved. +; * +; * SPDX-License-Identifier: Apache-2.0 +; * +; * Licensed under the Apache License, Version 2.0 (the License); you may +; * not use this file except in compliance with the License. +; * You may obtain a copy of the License at +; * +; * www.apache.org/licenses/LICENSE-2.0 +; * +; * Unless required by applicable law or agreed to in writing, software +; * distributed under the License is distributed on an AS IS BASIS, WITHOUT +; * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; * See the License for the specific language governing permissions and +; * limitations under the License. +; * +; * ----------------------------------------------------------------------------- +; * +; * Project: CMSIS-RTOS RTX +; * Title: Cortex-M0 Exception handlers +; * +; * ----------------------------------------------------------------------------- +; */ + + +I_T_RUN_OFS EQU 28 ; osRtxInfo.thread.run offset +TCB_SP_OFS EQU 56 ; TCB.SP offset + + + PRESERVE8 + THUMB + + + AREA |.constdata|, DATA, READONLY + EXPORT irqRtxLib +irqRtxLib DCB 0 ; Non weak library reference + + + AREA |.text|, CODE, READONLY + + +SVC_Handler PROC + EXPORT SVC_Handler + IMPORT osRtxUserSVC + IMPORT osRtxInfo + + MRS R0,PSP ; Get PSP + LDR R1,[R0,#24] ; Load saved PC from stack + SUBS R1,R1,#2 ; Point to SVC instruction + LDRB R1,[R1] ; Load SVC number + CMP R1,#0 + BNE SVC_User ; Branch if not SVC 0 + + PUSH {R0,LR} ; Save PSP and EXC_RETURN + LDMIA R0,{R0-R3} ; Load function parameters from stack + BLX R7 ; Call service function + POP {R2,R3} ; Restore PSP and EXC_RETURN + STMIA R2!,{R0-R1} ; Store function return values + MOV LR,R3 ; Set EXC_RETURN + +SVC_Context + LDR R3,=osRtxInfo+I_T_RUN_OFS; Load address of osRtxInfo.run + LDMIA R3!,{R1,R2} ; Load osRtxInfo.thread.run: curr & next + CMP R1,R2 ; Check if thread switch is required + BEQ SVC_Exit ; Branch when threads are the same + + CMP R1,#0 + BEQ SVC_ContextSwitch ; Branch if running thread is deleted + +SVC_ContextSave + MRS R0,PSP ; Get PSP + SUBS R0,R0,#32 ; Adjust address + STR R0,[R1,#TCB_SP_OFS] ; Store SP + STMIA R0!,{R4-R7} ; Save R4..R7 + MOV R4,R8 + MOV R5,R9 + MOV R6,R10 + MOV R7,R11 + STMIA R0!,{R4-R7} ; Save R8..R11 + +SVC_ContextSwitch + SUBS R3,R3,#8 + STR R2,[R3] ; osRtxInfo.thread.run: curr = next + +SVC_ContextRestore + LDR R0,[R2,#TCB_SP_OFS] ; Load SP + ADDS R0,R0,#16 ; Adjust address + LDMIA R0!,{R4-R7} ; Restore R8..R11 + MOV R8,R4 + MOV R9,R5 + MOV R10,R6 + MOV R11,R7 + MSR PSP,R0 ; Set PSP + SUBS R0,R0,#32 ; Adjust address + LDMIA R0!,{R4-R7} ; Restore R4..R7 + + MOVS R0,#~0xFFFFFFFD + MVNS R0,R0 ; Set EXC_RETURN value + BX R0 ; Exit from handler + +SVC_Exit + BX LR ; Exit from handler + +SVC_User + PUSH {R4,LR} ; Save registers + LDR R2,=osRtxUserSVC ; Load address of SVC table + LDR R3,[R2] ; Load SVC maximum number + CMP R1,R3 ; Check SVC number range + BHI SVC_Done ; Branch if out of range + + LSLS R1,R1,#2 + LDR R4,[R2,R1] ; Load address of SVC function + + LDMIA R0,{R0-R3} ; Load function parameters from stack + BLX R4 ; Call service function + MRS R4,PSP ; Get PSP + STMIA R4!,{R0-R3} ; Store function return values + +SVC_Done + POP {R4,PC} ; Return from handler + + ALIGN + ENDP + + +PendSV_Handler PROC + EXPORT PendSV_Handler + IMPORT osRtxPendSV_Handler + + PUSH {R0,LR} ; Save EXC_RETURN + BL osRtxPendSV_Handler ; Call osRtxPendSV_Handler + POP {R0,R1} ; Restore EXC_RETURN + MOV LR,R1 ; Set EXC_RETURN + B SVC_Context + + ALIGN + ENDP + + +SysTick_Handler PROC + EXPORT SysTick_Handler + IMPORT osRtxTick_Handler + + PUSH {R0,LR} ; Save EXC_RETURN + BL osRtxTick_Handler ; Call osRtxTick_Handler + POP {R0,R1} ; Restore EXC_RETURN + MOV LR,R1 ; Set EXC_RETURN + B SVC_Context + + ALIGN + ENDP + + + END diff --git a/rtos/rtx2/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_GCC/irq_cm0.S b/rtos/rtx2/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_GCC/irq_cm0.S new file mode 100644 index 00000000000..5362c196960 --- /dev/null +++ b/rtos/rtx2/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_GCC/irq_cm0.S @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2013-2017 ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ----------------------------------------------------------------------------- + * + * Project: CMSIS-RTOS RTX + * Title: Cortex-M0 Exception handlers + * + * ----------------------------------------------------------------------------- + */ + + + .file "irq_cm0.S" + .syntax unified + + .equ I_T_RUN_OFS, 28 // osRtxInfo.thread.run offset + .equ TCB_SP_OFS, 56 // TCB.SP offset + + .section ".rodata" + .global irqRtxLib // Non weak library reference +irqRtxLib: + .byte 0 + + + .thumb + .section ".text" + .align 2 + + + .thumb_func + .type SVC_Handler, %function + .global SVC_Handler + .fnstart + .cantunwind +SVC_Handler: + + MRS R0,PSP // Get PSP + LDR R1,[R0,#24] // Load saved PC from stack + SUBS R1,R1,#2 // Point to SVC instruction + LDRB R1,[R1] // Load SVC number + CMP R1,#0 + BNE SVC_User // Branch if not SVC 0 + + PUSH {R0,LR} // Save PSP and EXC_RETURN + LDMIA R0,{R0-R3} // Load function parameters from stack + BLX R7 // Call service function + POP {R2,R3} // Restore PSP and EXC_RETURN + STMIA R2!,{R0-R1} // Store function return values + MOV LR,R3 // Set EXC_RETURN + +SVC_Context: + LDR R3,=osRtxInfo+I_T_RUN_OFS // Load address of osRtxInfo.run + LDMIA R3!,{R1,R2} // Load osRtxInfo.thread.run: curr & next + CMP R1,R2 // Check if thread switch is required + BEQ SVC_Exit // Branch when threads are the same + + CMP R1,#0 + BEQ SVC_ContextSwitch // Branch if running thread is deleted + +SVC_ContextSave: + MRS R0,PSP // Get PSP + SUBS R0,R0,#32 // Adjust address + STR R0,[R1,#TCB_SP_OFS]; // Store SP + STMIA R0!,{R4-R7} // Save R4..R7 + MOV R4,R8 + MOV R5,R9 + MOV R6,R10 + MOV R7,R11 + STMIA R0!,{R4-R7} // Save R8..R11 + +SVC_ContextSwitch: + SUBS R3,R3,#8 + STR R2,[R3] // osRtxInfo.thread.run: curr = next + +SVC_ContextRestore: + LDR R0,[R2,#TCB_SP_OFS] // Load SP + ADDS R0,R0,#16 // Adjust address + LDMIA R0!,{R4-R7} // Restore R8..R11 + MOV R8,R4 + MOV R9,R5 + MOV R10,R6 + MOV R11,R7 + MSR PSP,R0 // Set PSP + SUBS R0,R0,#32 // Adjust address + LDMIA R0!,{R4-R7} // Restore R4..R7 + + MOVS R0,#~0xFFFFFFFD + MVNS R0,R0 // Set EXC_RETURN value + BX R0 // Exit from handler + +SVC_Exit: + BX LR // Exit from handler + +SVC_User: + PUSH {R4,LR} // Save registers + LDR R2,=osRtxUserSVC // Load address of SVC table + LDR R3,[R2] // Load SVC maximum number + CMP R1,R3 // Check SVC number range + BHI SVC_Done // Branch if out of range + + LSLS R1,R1,#2 + LDR R4,[R2,R1] // Load address of SVC function + + LDMIA R0,{R0-R3} // Load function parameters from stack + BLX R4 // Call service function + MRS R4,PSP // Get PSP + STMIA R4!,{R0-R3} // Store function return values + +SVC_Done: + POP {R4,PC} // Return from handler + + .fnend + .size SVC_Handler, .-SVC_Handler + + + .thumb_func + .type PendSV_Handler, %function + .global PendSV_Handler + .fnstart + .cantunwind +PendSV_Handler: + + PUSH {R0,LR} // Save EXC_RETURN + BL osRtxPendSV_Handler // Call osRtxPendSV_Handler + POP {R0,R1} // Restore EXC_RETURN + MOV LR,R1 // Set EXC_RETURN + B SVC_Context + + .fnend + .size PendSV_Handler, .-PendSV_Handler + + + .thumb_func + .type SysTick_Handler, %function + .global SysTick_Handler + .fnstart + .cantunwind +SysTick_Handler: + + PUSH {R0,LR} // Save EXC_RETURN + BL osRtxTick_Handler // Call osRtxTick_Handler + POP {R0,R1} // Restore EXC_RETURN + MOV LR,R1 // Set EXC_RETURN + B SVC_Context + + .fnend + .size SysTick_Handler, .-SysTick_Handler + + + .end diff --git a/rtos/rtx2/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_IAR/irq_cm0.s b/rtos/rtx2/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_IAR/irq_cm0.s new file mode 100644 index 00000000000..023aae3a9e7 --- /dev/null +++ b/rtos/rtx2/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_IAR/irq_cm0.s @@ -0,0 +1,149 @@ +;/* +; * Copyright (c) 2013-2017 ARM Limited. All rights reserved. +; * +; * SPDX-License-Identifier: Apache-2.0 +; * +; * Licensed under the Apache License, Version 2.0 (the License); you may +; * not use this file except in compliance with the License. +; * You may obtain a copy of the License at +; * +; * www.apache.org/licenses/LICENSE-2.0 +; * +; * Unless required by applicable law or agreed to in writing, software +; * distributed under the License is distributed on an AS IS BASIS, WITHOUT +; * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; * See the License for the specific language governing permissions and +; * limitations under the License. +; * +; * ----------------------------------------------------------------------------- +; * +; * Project: CMSIS-RTOS RTX +; * Title: Cortex-M0 Exception handlers +; * +; * ----------------------------------------------------------------------------- +; */ + + + NAME irq_cm0.s + + +I_T_RUN_OFS EQU 28 ; osRtxInfo.thread.run offset +TCB_SP_OFS EQU 56 ; TCB.SP offset + + + PRESERVE8 + SECTION .rodata:DATA:NOROOT(2) + + + EXPORT irqRtxLib +irqRtxLib DCB 0 ; Non weak library reference + + + THUMB + SECTION .text:CODE:NOROOT(2) + + +SVC_Handler + EXPORT SVC_Handler + IMPORT osRtxUserSVC + IMPORT osRtxInfo + + MRS R0,PSP ; Get PSP + LDR R1,[R0,#24] ; Load saved PC from stack + SUBS R1,R1,#2 ; Point to SVC instruction + LDRB R1,[R1] ; Load SVC number + CMP R1,#0 + BNE SVC_User ; Branch if not SVC 0 + + PUSH {R0,LR} ; Save PSP and EXC_RETURN + LDMIA R0,{R0-R3} ; Load function parameters from stack + BLX R7 ; Call service function + POP {R2,R3} ; Restore PSP and EXC_RETURN + STMIA R2!,{R0-R1} ; Store function return values + MOV LR,R3 ; Set EXC_RETURN + +SVC_Context + LDR R3,=osRtxInfo+I_T_RUN_OFS; Load address of osRtxInfo.run + LDMIA R3!,{R1,R2} ; Load osRtxInfo.thread.run: curr & next + CMP R1,R2 ; Check if thread switch is required + BEQ SVC_Exit ; Branch when threads are the same + + CMP R1,#0 + BEQ SVC_ContextSwitch ; Branch if running thread is deleted + +SVC_ContextSave + MRS R0,PSP ; Get PSP + SUBS R0,R0,#32 ; Adjust address + STR R0,[R1,#TCB_SP_OFS] ; Store SP + STMIA R0!,{R4-R7} ; Save R4..R7 + MOV R4,R8 + MOV R5,R9 + MOV R6,R10 + MOV R7,R11 + STMIA R0!,{R4-R7} ; Save R8..R11 + +SVC_ContextSwitch + SUBS R3,R3,#8 + STR R2,[R3] ; osRtxInfo.thread.run: curr = next + +SVC_ContextRestore + LDR R0,[R2,#TCB_SP_OFS] ; Load SP + ADDS R0,R0,#16 ; Adjust address + LDMIA R0!,{R4-R7} ; Restore R8..R11 + MOV R8,R4 + MOV R9,R5 + MOV R10,R6 + MOV R11,R7 + MSR PSP,R0 ; Set PSP + SUBS R0,R0,#32 ; Adjust address + LDMIA R0!,{R4-R7} ; Restore R4..R7 + + MOVS R0,#~0xFFFFFFFD + MVNS R0,R0 ; Set EXC_RETURN value + BX R0 ; Exit from handler + +SVC_Exit + BX LR ; Exit from handler + +SVC_User + PUSH {R4,LR} ; Save registers + LDR R2,=osRtxUserSVC ; Load address of SVC table + LDR R3,[R2] ; Load SVC maximum number + CMP R1,R3 ; Check SVC number range + BHI SVC_Done ; Branch if out of range + + LSLS R1,R1,#2 + LDR R4,[R2,R1] ; Load address of SVC function + + LDMIA R0,{R0-R3} ; Load function parameters from stack + BLX R4 ; Call service function + MRS R4,PSP ; Get PSP + STMIA R4!,{R0-R3} ; Store function return values + +SVC_Done + POP {R4,PC} ; Return from handler + + +PendSV_Handler + EXPORT PendSV_Handler + IMPORT osRtxPendSV_Handler + + PUSH {R0,LR} ; Save EXC_RETURN + BL osRtxPendSV_Handler ; Call osRtxPendSV_Handler + POP {R0,R1} ; Restore EXC_RETURN + MOV LR,R1 ; Set EXC_RETURN + B SVC_Context + + +SysTick_Handler + EXPORT SysTick_Handler + IMPORT osRtxTick_Handler + + PUSH {R0,LR} ; Save EXC_RETURN + BL osRtxTick_Handler ; Call osRtxTick_Handler + POP {R0,R1} ; Restore EXC_RETURN + MOV LR,R1 ; Set EXC_RETURN + B SVC_Context + + + END diff --git a/rtos/rtx2/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_ARM/irq_cm3.s b/rtos/rtx2/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_ARM/irq_cm3.s new file mode 100644 index 00000000000..b951538c826 --- /dev/null +++ b/rtos/rtx2/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_ARM/irq_cm3.s @@ -0,0 +1,133 @@ +;/* +; * Copyright (c) 2013-2017 ARM Limited. All rights reserved. +; * +; * SPDX-License-Identifier: Apache-2.0 +; * +; * Licensed under the Apache License, Version 2.0 (the License); you may +; * not use this file except in compliance with the License. +; * You may obtain a copy of the License at +; * +; * www.apache.org/licenses/LICENSE-2.0 +; * +; * Unless required by applicable law or agreed to in writing, software +; * distributed under the License is distributed on an AS IS BASIS, WITHOUT +; * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; * See the License for the specific language governing permissions and +; * limitations under the License. +; * +; * ----------------------------------------------------------------------------- +; * +; * Project: CMSIS-RTOS RTX +; * Title: Cortex-M3 Exception handlers +; * +; * ----------------------------------------------------------------------------- +; */ + + +I_T_RUN_OFS EQU 28 ; osRtxInfo.thread.run offset +TCB_SP_OFS EQU 56 ; TCB.SP offset + + + PRESERVE8 + THUMB + + + AREA |.constdata|, DATA, READONLY + EXPORT irqRtxLib +irqRtxLib DCB 0 ; Non weak library reference + + + AREA |.text|, CODE, READONLY + + +SVC_Handler PROC + EXPORT SVC_Handler + IMPORT osRtxUserSVC + IMPORT osRtxInfo + + MRS R0,PSP ; Get PSP + LDR R1,[R0,#24] ; Load saved PC from stack + LDRB R1,[R1,#-2] ; Load SVC number + CBNZ R1,SVC_User ; Branch if not SVC 0 + + PUSH {R0,LR} ; Save PSP and EXC_RETURN + LDM R0,{R0-R3,R12} ; Load function parameters and address from stack + BLX R12 ; Call service function + POP {R12,LR} ; Restore PSP and EXC_RETURN + STM R12,{R0-R1} ; Store function return values + +SVC_Context + LDR R3,=osRtxInfo+I_T_RUN_OFS; Load address of osRtxInfo.run + LDM R3,{R1,R2} ; Load osRtxInfo.thread.run: curr & next + CMP R1,R2 ; Check if thread switch is required + BXEQ LR ; Exit when threads are the same + + CBZ R1,SVC_ContextSwitch ; Branch if running thread is deleted + +SVC_ContextSave + STMDB R12!,{R4-R11} ; Save R4..R11 + STR R12,[R1,#TCB_SP_OFS] ; Store SP + +SVC_ContextSwitch + STR R2,[R3] ; osRtxInfo.thread.run: curr = next + +SVC_ContextRestore + LDR R0,[R2,#TCB_SP_OFS] ; Load SP + LDMIA R0!,{R4-R11} ; Restore R4..R11 + MSR PSP,R0 ; Set PSP + + MVN LR,#~0xFFFFFFFD ; Set EXC_RETURN value + +SVC_Exit + BX LR ; Exit from handler + +SVC_User + PUSH {R4,LR} ; Save registers + LDR R2,=osRtxUserSVC ; Load address of SVC table + LDR R3,[R2] ; Load SVC maximum number + CMP R1,R3 ; Check SVC number range + BHI SVC_Done ; Branch if out of range + + LDR R4,[R2,R1,LSL #2] ; Load address of SVC function + + LDM R0,{R0-R3} ; Load function parameters from stack + BLX R4 ; Call service function + MRS R4,PSP ; Get PSP + STR R0,[R4] ; Store function return value + +SVC_Done + POP {R4,PC} ; Return from handler + + ALIGN + ENDP + + +PendSV_Handler PROC + EXPORT PendSV_Handler + IMPORT osRtxPendSV_Handler + + PUSH {R4,LR} ; Save EXC_RETURN + BL osRtxPendSV_Handler ; Call osRtxPendSV_Handler + POP {R4,LR} ; Restore EXC_RETURN + MRS R12,PSP + B SVC_Context + + ALIGN + ENDP + + +SysTick_Handler PROC + EXPORT SysTick_Handler + IMPORT osRtxTick_Handler + + PUSH {R4,LR} ; Save EXC_RETURN + BL osRtxTick_Handler ; Call osRtxTick_Handler + POP {R4,LR} ; Restore EXC_RETURN + MRS R12,PSP + B SVC_Context + + ALIGN + ENDP + + + END diff --git a/rtos/rtx2/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_GCC/irq_cm3.S b/rtos/rtx2/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_GCC/irq_cm3.S new file mode 100644 index 00000000000..22ccf3683e1 --- /dev/null +++ b/rtos/rtx2/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_GCC/irq_cm3.S @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2013-2017 ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ----------------------------------------------------------------------------- + * + * Project: CMSIS-RTOS RTX + * Title: Cortex-M3 Exception handlers + * + * ----------------------------------------------------------------------------- + */ + + + .file "irq_cm3.S" + .syntax unified + + .equ I_T_RUN_OFS, 28 // osRtxInfo.thread.run offset + .equ TCB_SP_OFS, 56 // TCB.SP offset + + .section ".rodata" + .global irqRtxLib // Non weak library reference +irqRtxLib: + .byte 0 + + + .thumb + .section ".text" + .align 2 + + + .thumb_func + .type SVC_Handler, %function + .global SVC_Handler + .fnstart + .cantunwind +SVC_Handler: + + MRS R0,PSP // Get PSP + LDR R1,[R0,#24] // Load saved PC from stack + LDRB R1,[R1,#-2] // Load SVC number + CBNZ R1,SVC_User // Branch if not SVC 0 + + PUSH {R0,LR} // Save PSP and EXC_RETURN + LDM R0,{R0-R3,R12} // Load function parameters and address from stack + BLX R12 // Call service function + POP {R12,LR} // Restore PSP and EXC_RETURN + STM R12,{R0-R1} // Store function return values + +SVC_Context: + LDR R3,=osRtxInfo+I_T_RUN_OFS // Load address of osRtxInfo.run + LDM R3,{R1,R2} // Load osRtxInfo.thread.run: curr & next + CMP R1,R2 // Check if thread switch is required + IT EQ + BXEQ LR // Exit when threads are the same + + CBZ R1,SVC_ContextSwitch // Branch if running thread is deleted + +SVC_ContextSave: + STMDB R12!,{R4-R11} // Save R4..R11 + STR R12,[R1,#TCB_SP_OFS] // Store SP + +SVC_ContextSwitch: + STR R2,[R3] // osRtxInfo.thread.run: curr = next + +SVC_ContextRestore: + LDR R0,[R2,#TCB_SP_OFS] // Load SP + LDMIA R0!,{R4-R11} // Restore R4..R11 + MSR PSP,R0 // Set PSP + MVN LR,#~0xFFFFFFFD // Set EXC_RETURN value + +SVC_Exit: + BX LR // Exit from handler + +SVC_User: + PUSH {R4,LR} // Save registers + LDR R2,=osRtxUserSVC // Load address of SVC table + LDR R3,[R2] // Load SVC maximum number + CMP R1,R3 // Check SVC number range + BHI SVC_Done // Branch if out of range + + LDR R4,[R2,R1,LSL #2] // Load address of SVC function + + LDM R0,{R0-R3} // Load function parameters from stack + BLX R4 // Call service function + MRS R4,PSP // Get PSP + STR R0,[R4] // Store function return value + +SVC_Done: + POP {R4,PC} // Return from handler + + .fnend + .size SVC_Handler, .-SVC_Handler + + + .thumb_func + .type PendSV_Handler, %function + .global PendSV_Handler + .fnstart + .cantunwind +PendSV_Handler: + + PUSH {R4,LR} // Save EXC_RETURN + BL osRtxPendSV_Handler // Call osRtxPendSV_Handler + POP {R4,LR} // Restore EXC_RETURN + MRS R12,PSP + B SVC_Context + + .fnend + .size PendSV_Handler, .-PendSV_Handler + + + .thumb_func + .type SysTick_Handler, %function + .global SysTick_Handler + .fnstart + .cantunwind +SysTick_Handler: + + PUSH {R4,LR} // Save EXC_RETURN + BL osRtxTick_Handler // Call osRtxTick_Handler + POP {R4,LR} // Restore EXC_RETURN + MRS R12,PSP + B SVC_Context + + .fnend + .size SysTick_Handler, .-SysTick_Handler + + + .end diff --git a/rtos/rtx2/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_IAR/irq_cm3.s b/rtos/rtx2/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_IAR/irq_cm3.s new file mode 100644 index 00000000000..bfc3b33d410 --- /dev/null +++ b/rtos/rtx2/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_IAR/irq_cm3.s @@ -0,0 +1,128 @@ +;/* +; * Copyright (c) 2013-2017 ARM Limited. All rights reserved. +; * +; * SPDX-License-Identifier: Apache-2.0 +; * +; * Licensed under the Apache License, Version 2.0 (the License); you may +; * not use this file except in compliance with the License. +; * You may obtain a copy of the License at +; * +; * www.apache.org/licenses/LICENSE-2.0 +; * +; * Unless required by applicable law or agreed to in writing, software +; * distributed under the License is distributed on an AS IS BASIS, WITHOUT +; * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; * See the License for the specific language governing permissions and +; * limitations under the License. +; * +; * ----------------------------------------------------------------------------- +; * +; * Project: CMSIS-RTOS RTX +; * Title: Cortex-M3 Exception handlers +; * +; * ----------------------------------------------------------------------------- +; */ + + + NAME irq_cm3.s + + +I_T_RUN_OFS EQU 28 ; osRtxInfo.thread.run offset +TCB_SP_OFS EQU 56 ; TCB.SP offset + + + PRESERVE8 + SECTION .rodata:DATA:NOROOT(2) + + + EXPORT irqRtxLib +irqRtxLib DCB 0 ; Non weak library reference + + + THUMB + SECTION .text:CODE:NOROOT(2) + + +SVC_Handler + EXPORT SVC_Handler + IMPORT osRtxUserSVC + IMPORT osRtxInfo + + MRS R0,PSP ; Get PSP + LDR R1,[R0,#24] ; Load saved PC from stack + LDRB R1,[R1,#-2] ; Load SVC number + CBNZ R1,SVC_User ; Branch if not SVC 0 + + PUSH {R0,LR} ; Save PSP and EXC_RETURN + LDM R0,{R0-R3,R12} ; Load function parameters and address from stack + BLX R12 ; Call service function + POP {R12,LR} ; Restore PSP and EXC_RETURN + STM R12,{R0-R1} ; Store function return values + +SVC_Context + LDR R3,=osRtxInfo+I_T_RUN_OFS; Load address of osRtxInfo.run + LDM R3,{R1,R2} ; Load osRtxInfo.thread.run: curr & next + CMP R1,R2 ; Check if thread switch is required + IT EQ + BXEQ LR ; Exit when threads are the same + + CBZ R1,SVC_ContextSwitch ; Branch if running thread is deleted + +SVC_ContextSave + STMDB R12!,{R4-R11} ; Save R4..R11 + STR R12,[R1,#TCB_SP_OFS] ; Store SP + +SVC_ContextSwitch + STR R2,[R3] ; osRtxInfo.thread.run: curr = next + +SVC_ContextRestore + LDR R0,[R2,#TCB_SP_OFS] ; Load SP + LDMIA R0!,{R4-R11} ; Restore R4..R11 + MSR PSP,R0 ; Set PSP + + MVN LR,#~0xFFFFFFFD ; Set EXC_RETURN value + +SVC_Exit + BX LR ; Exit from handler + +SVC_User + PUSH {R4,LR} ; Save registers + LDR R2,=osRtxUserSVC ; Load address of SVC table + LDR R3,[R2] ; Load SVC maximum number + CMP R1,R3 ; Check SVC number range + BHI SVC_Done ; Branch if out of range + + LDR R4,[R2,R1,LSL #2] ; Load address of SVC function + + LDM R0,{R0-R3} ; Load function parameters from stack + BLX R4 ; Call service function + MRS R4,PSP ; Get PSP + STR R0,[R4] ; Store function return value + +SVC_Done + POP {R4,PC} ; Return from handler + + +PendSV_Handler + EXPORT PendSV_Handler + IMPORT osRtxPendSV_Handler + + PUSH {R4,LR} ; Save EXC_RETURN + BL osRtxPendSV_Handler ; Call osRtxPendSV_Handler + POP {R4,LR} ; Restore EXC_RETURN + MRS R12,PSP + B SVC_Context + + +SysTick_Handler + EXPORT SysTick_Handler + IMPORT osRtxTick_Handler + + PUSH {R4,LR} ; Save EXC_RETURN + BL osRtxTick_Handler ; Call osRtxTick_Handler + POP {R4,LR} ; Restore EXC_RETURN + MRS R12,PSP + B SVC_Context + + + END diff --git a/rtos/rtx2/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_ARM/irq_cm4f.s b/rtos/rtx2/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_ARM/irq_cm4f.s new file mode 100644 index 00000000000..746c7c170a3 --- /dev/null +++ b/rtos/rtx2/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_ARM/irq_cm4f.s @@ -0,0 +1,148 @@ +;/* +; * Copyright (c) 2013-2017 ARM Limited. All rights reserved. +; * +; * SPDX-License-Identifier: Apache-2.0 +; * +; * Licensed under the Apache License, Version 2.0 (the License); you may +; * not use this file except in compliance with the License. +; * You may obtain a copy of the License at +; * +; * www.apache.org/licenses/LICENSE-2.0 +; * +; * Unless required by applicable law or agreed to in writing, software +; * distributed under the License is distributed on an AS IS BASIS, WITHOUT +; * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; * See the License for the specific language governing permissions and +; * limitations under the License. +; * +; * ----------------------------------------------------------------------------- +; * +; * Project: CMSIS-RTOS RTX +; * Title: Cortex-M4F Exception handlers +; * +; * ----------------------------------------------------------------------------- +; */ + + +I_T_RUN_OFS EQU 28 ; osRtxInfo.thread.run offset +TCB_SP_OFS EQU 56 ; TCB.SP offset +TCB_SF_OFS EQU 34 ; TCB.stack_frame offset + + + PRESERVE8 + THUMB + + + AREA |.constdata|, DATA, READONLY + EXPORT irqRtxLib +irqRtxLib DCB 0 ; Non weak library reference + + + AREA |.text|, CODE, READONLY + + +SVC_Handler PROC + EXPORT SVC_Handler + IMPORT osRtxUserSVC + IMPORT osRtxInfo + + MRS R0,PSP ; Get PSP + LDR R1,[R0,#24] ; Load saved PC from stack + LDRB R1,[R1,#-2] ; Load SVC number + CBNZ R1,SVC_User ; Branch if not SVC 0 + + PUSH {R0,LR} ; Save PSP and EXC_RETURN + LDM R0,{R0-R3,R12} ; Load function parameters and address from stack + BLX R12 ; Call service function + POP {R12,LR} ; Restore PSP and EXC_RETURN + STM R12,{R0-R1} ; Store function return values + +SVC_Context + LDR R3,=osRtxInfo+I_T_RUN_OFS; Load address of osRtxInfo.run + LDM R3,{R1,R2} ; Load osRtxInfo.thread.run: curr & next + CMP R1,R2 ; Check if thread switch is required + BXEQ LR ; Exit when threads are the same + + CBNZ R1,SVC_ContextSave ; Branch if running thread is not deleted + TST LR,#0x10 ; Check if extended stack frame + BNE SVC_ContextSwitch + LDR R1,=0xE000EF34 ; FPCCR Address + LDR R0,[R1] ; Load FPCCR + BIC R0,#1 ; Clear LSPACT (Lazy state) + STR R0,[R1] ; Store FPCCR + B SVC_ContextSwitch + +SVC_ContextSave + STMDB R12!,{R4-R11} ; Save R4..R11 + TST LR,#0x10 ; Check if extended stack frame + VSTMDBEQ R12!,{S16-S31} ; Save VFP S16.S31 + + STR R12,[R1,#TCB_SP_OFS] ; Store SP + STRB LR, [R1,#TCB_SF_OFS] ; Store stack frame information + +SVC_ContextSwitch + STR R2,[R3] ; osRtxInfo.thread.run: curr = next + +SVC_ContextRestore + LDRB R1,[R2,#TCB_SF_OFS] ; Load stack frame information + LDR R0,[R2,#TCB_SP_OFS] ; Load SP + ORR LR,R1,#0xFFFFFF00 ; Set EXC_RETURN + + TST LR,#0x10 ; Check if extended stack frame + VLDMIAEQ R0!,{S16-S31} ; Restore VFP S16..S31 + LDMIA R0!,{R4-R11} ; Restore R4..R11 + MSR PSP,R0 ; Set PSP + +SVC_Exit + BX LR ; Exit from handler + +SVC_User + PUSH {R4,LR} ; Save registers + LDR R2,=osRtxUserSVC ; Load address of SVC table + LDR R3,[R2] ; Load SVC maximum number + CMP R1,R3 ; Check SVC number range + BHI SVC_Done ; Branch if out of range + + LDR R4,[R2,R1,LSL #2] ; Load address of SVC function + + LDM R0,{R0-R3} ; Load function parameters from stack + BLX R4 ; Call service function + MRS R4,PSP ; Get PSP + STR R0,[R4] ; Store function return value + +SVC_Done + POP {R4,PC} ; Return from handler + + ALIGN + ENDP + + +PendSV_Handler PROC + EXPORT PendSV_Handler + IMPORT osRtxPendSV_Handler + + PUSH {R4,LR} ; Save EXC_RETURN + BL osRtxPendSV_Handler ; Call osRtxPendSV_Handler + POP {R4,LR} ; Restore EXC_RETURN + MRS R12,PSP + B SVC_Context + + ALIGN + ENDP + + +SysTick_Handler PROC + EXPORT SysTick_Handler + IMPORT osRtxTick_Handler + + PUSH {R4,LR} ; Save EXC_RETURN + BL osRtxTick_Handler ; Call osRtxTick_Handler + POP {R4,LR} ; Restore EXC_RETURN + MRS R12,PSP + B SVC_Context + + ALIGN + ENDP + + + END diff --git a/rtos/rtx2/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_GCC/irq_cm4f.S b/rtos/rtx2/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_GCC/irq_cm4f.S new file mode 100644 index 00000000000..23942f718b0 --- /dev/null +++ b/rtos/rtx2/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_GCC/irq_cm4f.S @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2013-2017 ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ----------------------------------------------------------------------------- + * + * Project: CMSIS-RTOS RTX + * Title: Cortex-M4F Exception handlers + * + * ----------------------------------------------------------------------------- + */ + + + .file "irq_cm4f.S" + .syntax unified + + .equ I_T_RUN_OFS, 28 // osRtxInfo.thread.run offset + .equ TCB_SP_OFS, 56 // TCB.SP offset + .equ TCB_SF_OFS, 34 // TCB.stack_frame offset + + .section ".rodata" + .global irqRtxLib // Non weak library reference +irqRtxLib: + .byte 0 + + + .thumb + .section ".text" + .align 2 + + + .thumb_func + .type SVC_Handler, %function + .global SVC_Handler + .fnstart + .cantunwind +SVC_Handler: + + MRS R0,PSP // Get PSP + LDR R1,[R0,#24] // Load saved PC from stack + LDRB R1,[R1,#-2] // Load SVC number + CBNZ R1,SVC_User // Branch if not SVC 0 + + PUSH {R0,LR} // Save PSP and EXC_RETURN + LDM R0,{R0-R3,R12} // Load function parameters and address from stack + BLX R12 // Call service function + POP {R12,LR} // Restore PSP and EXC_RETURN + STM R12,{R0-R1} // Store function return values + +SVC_Context: + LDR R3,=osRtxInfo+I_T_RUN_OFS // Load address of osRtxInfo.run + LDM R3,{R1,R2} // Load osRtxInfo.thread.run: curr & next + CMP R1,R2 // Check if thread switch is required + IT EQ + BXEQ LR // Exit when threads are the same + + CBNZ R1,SVC_ContextSave // Branch if running thread is not deleted + TST LR,#0x10 // Check if extended stack frame + BNE SVC_ContextSwitch + LDR R1,=0xE000EF34 // FPCCR Address + LDR R0,[R1] // Load FPCCR + BIC R0,#1 // Clear LSPACT (Lazy state) + STR R0,[R1] // Store FPCCR + B SVC_ContextSwitch + +SVC_ContextSave: + STMDB R12!,{R4-R11} // Save R4..R11 + TST LR,#0x10 // Check if extended stack frame + IT EQ + VSTMDBEQ R12!,{S16-S31} // Save VFP S16.S31 + + STR R12,[R1,#TCB_SP_OFS] // Store SP + STRB LR, [R1,#TCB_SF_OFS] // Store stack frame information + +SVC_ContextSwitch: + STR R2,[R3] // osRtxInfo.thread.run: curr = next + +SVC_ContextRestore: + LDRB R1,[R2,#TCB_SF_OFS] // Load stack frame information + LDR R0,[R2,#TCB_SP_OFS] // Load SP + ORR LR,R1,#0xFFFFFF00 // Set EXC_RETURN + + TST LR,#0x10 // Check if extended stack frame + IT EQ + VLDMIAEQ R0!,{S16-S31} // Restore VFP S16..S31 + LDMIA R0!,{R4-R11} // Restore R4..R11 + MSR PSP,R0 // Set PSP + +SVC_Exit: + BX LR // Exit from handler + +SVC_User: + PUSH {R4,LR} // Save registers + LDR R2,=osRtxUserSVC // Load address of SVC table + LDR R3,[R2] // Load SVC maximum number + CMP R1,R3 // Check SVC number range + BHI SVC_Done // Branch if out of range + + LDR R4,[R2,R1,LSL #2] // Load address of SVC function + + LDM R0,{R0-R3} // Load function parameters from stack + BLX R4 // Call service function + MRS R4,PSP // Get PSP + STR R0,[R4] // Store function return value + +SVC_Done: + POP {R4,PC} // Return from handler + + .fnend + .size SVC_Handler, .-SVC_Handler + + + .thumb_func + .type PendSV_Handler, %function + .global PendSV_Handler + .fnstart + .cantunwind +PendSV_Handler: + + PUSH {R4,LR} // Save EXC_RETURN + BL osRtxPendSV_Handler // Call osRtxPendSV_Handler + POP {R4,LR} // Restore EXC_RETURN + MRS R12,PSP + B SVC_Context + + .fnend + .size PendSV_Handler, .-PendSV_Handler + + + .thumb_func + .type SysTick_Handler, %function + .global SysTick_Handler + .fnstart + .cantunwind +SysTick_Handler: + + PUSH {R4,LR} // Save EXC_RETURN + BL osRtxTick_Handler // Call osRtxTick_Handler + POP {R4,LR} // Restore EXC_RETURN + MRS R12,PSP + B SVC_Context + + .fnend + .size SysTick_Handler, .-SysTick_Handler + + + .end diff --git a/rtos/rtx2/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_IAR/irq_cm4f.s b/rtos/rtx2/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_IAR/irq_cm4f.s new file mode 100644 index 00000000000..4af43869c9c --- /dev/null +++ b/rtos/rtx2/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_IAR/irq_cm4f.s @@ -0,0 +1,144 @@ +;/* +; * Copyright (c) 2013-2017 ARM Limited. All rights reserved. +; * +; * SPDX-License-Identifier: Apache-2.0 +; * +; * Licensed under the Apache License, Version 2.0 (the License); you may +; * not use this file except in compliance with the License. +; * You may obtain a copy of the License at +; * +; * www.apache.org/licenses/LICENSE-2.0 +; * +; * Unless required by applicable law or agreed to in writing, software +; * distributed under the License is distributed on an AS IS BASIS, WITHOUT +; * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; * See the License for the specific language governing permissions and +; * limitations under the License. +; * +; * ----------------------------------------------------------------------------- +; * +; * Project: CMSIS-RTOS RTX +; * Title: Cortex-M4F Exception handlers +; * +; * ----------------------------------------------------------------------------- +; */ + + + NAME irq_cm4f.s + + +I_T_RUN_OFS EQU 28 ; osRtxInfo.thread.run offset +TCB_SP_OFS EQU 56 ; TCB.SP offset +TCB_SF_OFS EQU 34 ; TCB.stack_frame offset + + + PRESERVE8 + SECTION .rodata:DATA:NOROOT(2) + + + EXPORT irqRtxLib +irqRtxLib DCB 0 ; Non weak library reference + + + THUMB + SECTION .text:CODE:NOROOT(2) + +SVC_Handler + EXPORT SVC_Handler + IMPORT osRtxUserSVC + IMPORT osRtxInfo + + MRS R0,PSP ; Get PSP + LDR R1,[R0,#24] ; Load saved PC from stack + LDRB R1,[R1,#-2] ; Load SVC number + CBNZ R1,SVC_User ; Branch if not SVC 0 + + PUSH {R0,LR} ; Save PSP and EXC_RETURN + LDM R0,{R0-R3,R12} ; Load function parameters and address from stack + BLX R12 ; Call service function + POP {R12,LR} ; Restore PSP and EXC_RETURN + STM R12,{R0-R1} ; Store function return values + +SVC_Context + LDR R3,=osRtxInfo+I_T_RUN_OFS; Load address of osRtxInfo.run + LDM R3,{R1,R2} ; Load osRtxInfo.thread.run: curr & next + CMP R1,R2 ; Check if thread switch is required + IT EQ + BXEQ LR ; Exit when threads are the same + + CBNZ R1,SVC_ContextSave ; Branch if running thread is not deleted + TST LR,#0x10 ; Check if extended stack frame + BNE SVC_ContextSwitch + LDR R1,=0xE000EF34 ; FPCCR Address + LDR R0,[R1] ; Load FPCCR + BIC R0,R0,#1 ; Clear LSPACT (Lazy state) + STR R0,[R1] ; Store FPCCR + B SVC_ContextSwitch + +SVC_ContextSave + STMDB R12!,{R4-R11} ; Save R4..R11 + TST LR,#0x10 ; Check if extended stack frame + IT EQ + VSTMDBEQ R12!,{S16-S31} ; Save VFP S16.S31 + + STR R12,[R1,#TCB_SP_OFS] ; Store SP + STRB LR, [R1,#TCB_SF_OFS] ; Store stack frame information + +SVC_ContextSwitch + STR R2,[R3] ; osRtxInfo.thread.run: curr = next + +SVC_ContextRestore + LDRB R1,[R2,#TCB_SF_OFS] ; Load stack frame information + LDR R0,[R2,#TCB_SP_OFS] ; Load SP + ORR LR,R1,#0xFFFFFF00 ; Set EXC_RETURN + + TST LR,#0x10 ; Check if extended stack frame + IT EQ + VLDMIAEQ R0!,{S16-S31} ; Restore VFP S16..S31 + LDMIA R0!,{R4-R11} ; Restore R4..R11 + MSR PSP,R0 ; Set PSP + +SVC_Exit + BX LR ; Exit from handler + +SVC_User + PUSH {R4,LR} ; Save registers + LDR R2,=osRtxUserSVC ; Load address of SVC table + LDR R3,[R2] ; Load SVC maximum number + CMP R1,R3 ; Check SVC number range + BHI SVC_Done ; Branch if out of range + + LDR R4,[R2,R1,LSL #2] ; Load address of SVC function + + LDM R0,{R0-R3} ; Load function parameters from stack + BLX R4 ; Call service function + MRS R4,PSP ; Get PSP + STR R0,[R4] ; Store function return value + +SVC_Done + POP {R4,PC} ; Return from handler + + +PendSV_Handler + EXPORT PendSV_Handler + IMPORT osRtxPendSV_Handler + + PUSH {R4,LR} ; Save EXC_RETURN + BL osRtxPendSV_Handler ; Call osRtxPendSV_Handler + POP {R4,LR} ; Restore EXC_RETURN + MRS R12,PSP + B SVC_Context + + +SysTick_Handler + EXPORT SysTick_Handler + IMPORT osRtxTick_Handler + + PUSH {R4,LR} ; Save EXC_RETURN + BL osRtxTick_Handler ; Call osRtxTick_Handler + POP {R4,LR} ; Restore EXC_RETURN + MRS R12,PSP + B SVC_Context + + + END diff --git a/rtos/rtx2/TARGET_CORTEX_M/cmsis_os2.h b/rtos/rtx2/TARGET_CORTEX_M/cmsis_os2.h new file mode 100644 index 00000000000..d25edfa06a8 --- /dev/null +++ b/rtos/rtx2/TARGET_CORTEX_M/cmsis_os2.h @@ -0,0 +1,745 @@ +/* + * Copyright (c) 2013-2017 ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ---------------------------------------------------------------------- + * + * $Date: 10. January 2017 + * $Revision: V2.1.0 + * + * Project: CMSIS-RTOS2 API + * Title: cmsis_os2.h header file + * + * Version 2.1.0 + * Support for critical and uncritical sections (nesting safe): + * - updated: osKernelLock, osKernelUnlock + * - added: osKernelRestoreLock + * Updated Thread and Event Flags: + * - changed flags parameter and return type from int32_t to uint32_t + * Version 2.0.0 + * Initial Release + *---------------------------------------------------------------------------*/ + +#ifndef CMSIS_OS2_H_ +#define CMSIS_OS2_H_ + +#ifndef __NO_RETURN +#if defined(__CC_ARM) +#define __NO_RETURN __declspec(noreturn) +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) +#define __NO_RETURN __attribute__((noreturn)) +#elif defined(__GNUC__) +#define __NO_RETURN __attribute__((noreturn)) +#elif defined(__ICCARM__) +#define __NO_RETURN __noreturn +#else +#define __NO_RETURN +#endif +#endif + +#include +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + + +// ==== Enumerations, structures, defines ==== + +/// Version information. +typedef struct { + uint32_t api; ///< API version (major.minor.rev: mmnnnrrrr dec). + uint32_t kernel; ///< Kernel version (major.minor.rev: mmnnnrrrr dec). +} osVersion_t; + +/// Kernel state. +typedef enum { + osKernelInactive = 0, ///< Inactive. + osKernelReady = 1, ///< Ready. + osKernelRunning = 2, ///< Running. + osKernelLocked = 3, ///< Locked. + osKernelSuspended = 4, ///< Suspended. + osKernelError = -1, ///< Error. + osKernelReserved = 0x7FFFFFFFU ///< Prevents enum down-size compiler optimization. +} osKernelState_t; + +/// Thread state. +typedef enum { + osThreadInactive = 0, ///< Inactive. + osThreadReady = 1, ///< Ready. + osThreadRunning = 2, ///< Running. + osThreadBlocked = 3, ///< Blocked. + osThreadTerminated = 4, ///< Terminated. + osThreadError = -1, ///< Error. + osThreadReserved = 0x7FFFFFFF ///< Prevents enum down-size compiler optimization. +} osThreadState_t; + +/// Priority values. +typedef enum { + osPriorityNone = 0, ///< No priority (not initialized). + osPriorityIdle = 1, ///< Reserved for Idle thread. + osPriorityLow = 8, ///< Priority: low + osPriorityLow1 = 8+1, ///< Priority: low + 1 + osPriorityLow2 = 8+2, ///< Priority: low + 2 + osPriorityLow3 = 8+3, ///< Priority: low + 3 + osPriorityLow4 = 8+4, ///< Priority: low + 4 + osPriorityLow5 = 8+5, ///< Priority: low + 5 + osPriorityLow6 = 8+6, ///< Priority: low + 6 + osPriorityLow7 = 8+7, ///< Priority: low + 7 + osPriorityBelowNormal = 16, ///< Priority: below normal + osPriorityBelowNormal1 = 16+1, ///< Priority: below normal + 1 + osPriorityBelowNormal2 = 16+2, ///< Priority: below normal + 2 + osPriorityBelowNormal3 = 16+3, ///< Priority: below normal + 3 + osPriorityBelowNormal4 = 16+4, ///< Priority: below normal + 4 + osPriorityBelowNormal5 = 16+5, ///< Priority: below normal + 5 + osPriorityBelowNormal6 = 16+6, ///< Priority: below normal + 6 + osPriorityBelowNormal7 = 16+7, ///< Priority: below normal + 7 + osPriorityNormal = 24, ///< Priority: normal + osPriorityNormal1 = 24+1, ///< Priority: normal + 1 + osPriorityNormal2 = 24+2, ///< Priority: normal + 2 + osPriorityNormal3 = 24+3, ///< Priority: normal + 3 + osPriorityNormal4 = 24+4, ///< Priority: normal + 4 + osPriorityNormal5 = 24+5, ///< Priority: normal + 5 + osPriorityNormal6 = 24+6, ///< Priority: normal + 6 + osPriorityNormal7 = 24+7, ///< Priority: normal + 7 + osPriorityAboveNormal = 32, ///< Priority: above normal + osPriorityAboveNormal1 = 32+1, ///< Priority: above normal + 1 + osPriorityAboveNormal2 = 32+2, ///< Priority: above normal + 2 + osPriorityAboveNormal3 = 32+3, ///< Priority: above normal + 3 + osPriorityAboveNormal4 = 32+4, ///< Priority: above normal + 4 + osPriorityAboveNormal5 = 32+5, ///< Priority: above normal + 5 + osPriorityAboveNormal6 = 32+6, ///< Priority: above normal + 6 + osPriorityAboveNormal7 = 32+7, ///< Priority: above normal + 7 + osPriorityHigh = 40, ///< Priority: high + osPriorityHigh1 = 40+1, ///< Priority: high + 1 + osPriorityHigh2 = 40+2, ///< Priority: high + 2 + osPriorityHigh3 = 40+3, ///< Priority: high + 3 + osPriorityHigh4 = 40+4, ///< Priority: high + 4 + osPriorityHigh5 = 40+5, ///< Priority: high + 5 + osPriorityHigh6 = 40+6, ///< Priority: high + 6 + osPriorityHigh7 = 40+7, ///< Priority: high + 7 + osPriorityRealtime = 48, ///< Priority: realtime + osPriorityRealtime1 = 48+1, ///< Priority: realtime + 1 + osPriorityRealtime2 = 48+2, ///< Priority: realtime + 2 + osPriorityRealtime3 = 48+3, ///< Priority: realtime + 3 + osPriorityRealtime4 = 48+4, ///< Priority: realtime + 4 + osPriorityRealtime5 = 48+5, ///< Priority: realtime + 5 + osPriorityRealtime6 = 48+6, ///< Priority: realtime + 6 + osPriorityRealtime7 = 48+7, ///< Priority: realtime + 7 + osPriorityISR = 56, ///< Reserved for ISR deferred thread. + osPriorityError = -1, ///< System cannot determine priority or illegal priority. + osPriorityReserved = 0x7FFFFFFF ///< Prevents enum down-size compiler optimization. +} osPriority_t; + +/// Entry point of a thread. +typedef void (*osThreadFunc_t) (void *argument); + +/// Entry point of a timer call back function. +typedef void (*osTimerFunc_t) (void *argument); + +/// Timer type. +typedef enum { + osTimerOnce = 0, ///< One-shot timer. + osTimerPeriodic = 1 ///< Repeating timer. +} osTimerType_t; + +/// Timeout value. +#define osWaitForever 0xFFFFFFFFU ///< Wait forever timeout value. + +/// Flags options (\ref osThreadFlagsWait and \ref osEventFlagsWait). +#define osFlagsWaitAny 0x00000000U ///< Wait for any flag (default). +#define osFlagsWaitAll 0x00000001U ///< Wait for all flags. +#define osFlagsNoClear 0x00000002U ///< Do not clear flags which have been specified to wait for. + +/// Flags errors (returned by osThreadFlagsXxxx and osEventFlagsXxxx). +#define osFlagsError 0x80000000U ///< Error indicator. +#define osFlagsErrorUnknown 0xFFFFFFFFU ///< osError (-1). +#define osFlagsErrorTimeout 0xFFFFFFFEU ///< osErrorTimeout (-2). +#define osFlagsErrorResource 0xFFFFFFFDU ///< osErrorResource (-3). +#define osFlagsErrorParameter 0xFFFFFFFCU ///< osErrorParameter (-4). +#define osFlagsErrorISR 0xFFFFFFFAU ///< osErrorISR (-6). + +/// Thread attributes (attr_bits in \ref osThreadAttr_t). +#define osThreadDetached 0x00000000U ///< Thread created in detached state (default) +#define osThreadJoinable 0x00000001U ///< Thread created in joinable state + +/// Mutex attributes (attr_bits in \ref osMutexAttr_t). +#define osMutexRecursive 0x00000001U ///< Recursive mutex. +#define osMutexPrioInherit 0x00000002U ///< Priority inherit protocol. +#define osMutexRobust 0x00000008U ///< Robust mutex. + +/// Status code values returned by CMSIS-RTOS functions. +typedef enum { + osOK = 0, ///< Operation completed successfully. + osError = -1, ///< Unspecified RTOS error: run-time error but no other error message fits. + osErrorTimeout = -2, ///< Operation not completed within the timeout period. + osErrorResource = -3, ///< Resource not available. + osErrorParameter = -4, ///< Parameter error. + osErrorNoMemory = -5, ///< System is out of memory: it was impossible to allocate or reserve memory for the operation. + osErrorISR = -6, ///< Not allowed in ISR context: the function cannot be called from interrupt service routines. + osStatusReserved = 0x7FFFFFFF ///< Prevents enum down-size compiler optimization. +} osStatus_t; + + +/// \details Thread ID identifies the thread. +typedef void *osThreadId_t; + +/// \details Timer ID identifies the timer. +typedef void *osTimerId_t; + +/// \details Event Flags ID identifies the event flags. +typedef void *osEventFlagsId_t; + +/// \details Mutex ID identifies the mutex. +typedef void *osMutexId_t; + +/// \details Semaphore ID identifies the semaphore. +typedef void *osSemaphoreId_t; + +/// \details Memory Pool ID identifies the memory pool. +typedef void *osMemoryPoolId_t; + +/// \details Message Queue ID identifies the message queue. +typedef void *osMessageQueueId_t; + + +#ifndef TZ_MODULEID_T +#define TZ_MODULEID_T +/// \details Data type that identifies secure software modules called by a process. +typedef uint32_t TZ_ModuleId_t; +#endif + + +/// Attributes structure for thread. +typedef struct { + const char *name; ///< name of the thread + uint32_t attr_bits; ///< attribute bits + void *cb_mem; ///< memory for control block + uint32_t cb_size; ///< size of provided memory for control block + void *stack_mem; ///< memory for stack + uint32_t stack_size; ///< size of stack + osPriority_t priority; ///< initial thread priority (default: osPriorityNormal) + TZ_ModuleId_t tz_module; ///< TrustZone module identifier + uint32_t reserved; ///< reserved (must be 0) +} osThreadAttr_t; + +/// Attributes structure for timer. +typedef struct { + const char *name; ///< name of the timer + uint32_t attr_bits; ///< attribute bits + void *cb_mem; ///< memory for control block + uint32_t cb_size; ///< size of provided memory for control block +} osTimerAttr_t; + +/// Attributes structure for event flags. +typedef struct { + const char *name; ///< name of the event flags + uint32_t attr_bits; ///< attribute bits + void *cb_mem; ///< memory for control block + uint32_t cb_size; ///< size of provided memory for control block +} osEventFlagsAttr_t; + +/// Attributes structure for mutex. +typedef struct { + const char *name; ///< name of the mutex + uint32_t attr_bits; ///< attribute bits + void *cb_mem; ///< memory for control block + uint32_t cb_size; ///< size of provided memory for control block +} osMutexAttr_t; + +/// Attributes structure for semaphore. +typedef struct { + const char *name; ///< name of the semaphore + uint32_t attr_bits; ///< attribute bits + void *cb_mem; ///< memory for control block + uint32_t cb_size; ///< size of provided memory for control block +} osSemaphoreAttr_t; + +/// Attributes structure for memory pool. +typedef struct { + const char *name; ///< name of the memory pool + uint32_t attr_bits; ///< attribute bits + void *cb_mem; ///< memory for control block + uint32_t cb_size; ///< size of provided memory for control block + void *mp_mem; ///< memory for data storage + uint32_t mp_size; ///< size of provided memory for data storage +} osMemoryPoolAttr_t; + +/// Attributes structure for message queue. +typedef struct { + const char *name; ///< name of the message queue + uint32_t attr_bits; ///< attribute bits + void *cb_mem; ///< memory for control block + uint32_t cb_size; ///< size of provided memory for control block + void *mq_mem; ///< memory for data storage + uint32_t mq_size; ///< size of provided memory for data storage +} osMessageQueueAttr_t; + + +// ==== Kernel Management Functions ==== + +/// Initialize the RTOS Kernel. +/// \return status code that indicates the execution status of the function. +osStatus_t osKernelInitialize (void); + +/// Get RTOS Kernel Information. +/// \param[out] version pointer to buffer for retrieving version information. +/// \param[out] id_buf pointer to buffer for retrieving kernel identification string. +/// \param[in] id_size size of buffer for kernel identification string. +/// \return status code that indicates the execution status of the function. +osStatus_t osKernelGetInfo (osVersion_t *version, char *id_buf, uint32_t id_size); + +/// Get the current RTOS Kernel state. +/// \return current RTOS Kernel state. +osKernelState_t osKernelGetState (void); + +/// Start the RTOS Kernel scheduler. +/// \return status code that indicates the execution status of the function. +osStatus_t osKernelStart (void); + +/// Lock the RTOS Kernel scheduler. +/// \return previous lock state (1 - locked, 0 - not locked, error code if negative). +int32_t osKernelLock (void); + +/// Unlock the RTOS Kernel scheduler. +/// \return previous lock state (1 - locked, 0 - not locked, error code if negative). +int32_t osKernelUnlock (void); + +/// Restore the RTOS Kernel scheduler lock state. +/// \param[in] lock lock state obtained by \ref osKernelLock or \ref osKernelUnlock. +/// \return new lock state (1 - locked, 0 - not locked, error code if negative). +int32_t osKernelRestoreLock (int32_t lock); + +/// Suspend the RTOS Kernel scheduler. +/// \return time in ticks, for how long the system can sleep or power-down. +uint32_t osKernelSuspend (void); + +/// Resume the RTOS Kernel scheduler. +/// \param[in] sleep_ticks time in ticks for how long the system was in sleep or power-down mode. +void osKernelResume (uint32_t sleep_ticks); + +/// Get the RTOS kernel tick count. +/// \return RTOS kernel current tick count. +uint64_t osKernelGetTickCount (void); + +/// Get the RTOS kernel tick frequency. +/// \return frequency of the kernel tick. +uint32_t osKernelGetTickFreq (void); + +/// Get the RTOS kernel system timer count. +/// \return RTOS kernel current system timer count as 32-bit value. +uint32_t osKernelGetSysTimerCount (void); + +/// Get the RTOS kernel system timer frequency. +/// \return frequency of the system timer. +uint32_t osKernelGetSysTimerFreq (void); + + +// ==== Thread Management Functions ==== + +/// Create a thread and add it to Active Threads. +/// \param[in] func thread function. +/// \param[in] argument pointer that is passed to the thread function as start argument. +/// \param[in] attr thread attributes; NULL: default values. +/// \return thread ID for reference by other functions or NULL in case of error. +osThreadId_t osThreadNew (osThreadFunc_t func, void *argument, const osThreadAttr_t *attr); + +/// Get name of a thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +/// \return name as NULL terminated string. +const char *osThreadGetName (osThreadId_t thread_id); + +/// Return the thread ID of the current running thread. +/// \return thread ID for reference by other functions or NULL in case of error. +osThreadId_t osThreadGetId (void); + +/// Get current thread state of a thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +/// \return current thread state of the specified thread. +osThreadState_t osThreadGetState (osThreadId_t thread_id); + +/// Get stack size of a thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +/// \return stack size in bytes. +uint32_t osThreadGetStackSize (osThreadId_t thread_id); + +/// Get available stack space of a thread based on stack watermark recording during execution. +/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +/// \return remaining stack space in bytes. +uint32_t osThreadGetStackSpace (osThreadId_t thread_id); + +/// Change priority of a thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +/// \param[in] priority new priority value for the thread function. +/// \return status code that indicates the execution status of the function. +osStatus_t osThreadSetPriority (osThreadId_t thread_id, osPriority_t priority); + +/// Get current priority of a thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +/// \return current priority value of the specified thread. +osPriority_t osThreadGetPriority (osThreadId_t thread_id); + +/// Pass control to next thread that is in state \b READY. +/// \return status code that indicates the execution status of the function. +osStatus_t osThreadYield (void); + +/// Suspend execution of a thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +/// \return status code that indicates the execution status of the function. +osStatus_t osThreadSuspend (osThreadId_t thread_id); + +/// Resume execution of a thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +/// \return status code that indicates the execution status of the function. +osStatus_t osThreadResume (osThreadId_t thread_id); + +/// Detach a thread (thread storage can be reclaimed when thread terminates). +/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +/// \return status code that indicates the execution status of the function. +osStatus_t osThreadDetach (osThreadId_t thread_id); + +/// Wait for specified thread to terminate. +/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +/// \return status code that indicates the execution status of the function. +osStatus_t osThreadJoin (osThreadId_t thread_id); + +/// Terminate execution of current running thread. +__NO_RETURN void osThreadExit (void); + +/// Terminate execution of a thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +/// \return status code that indicates the execution status of the function. +osStatus_t osThreadTerminate (osThreadId_t thread_id); + +/// Get number of active threads. +/// \return number of active threads. +uint32_t osThreadGetCount (void); + +/// Enumerate active threads. +/// \param[out] thread_array pointer to array for retrieving thread IDs. +/// \param[in] array_items maximum number of items in array for retrieving thread IDs. +/// \return number of enumerated threads. +uint32_t osThreadEnumerate (osThreadId_t *thread_array, uint32_t array_items); + + +// ==== Thread Flags Functions ==== + +/// Set the specified Thread Flags of a thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +/// \param[in] flags specifies the flags of the thread that shall be set. +/// \return thread flags after setting or error code if highest bit set. +uint32_t osThreadFlagsSet (osThreadId_t thread_id, uint32_t flags); + +/// Clear the specified Thread Flags of current running thread. +/// \param[in] flags specifies the flags of the thread that shall be cleared. +/// \return thread flags before clearing or error code if highest bit set. +uint32_t osThreadFlagsClear (uint32_t flags); + +/// Get the current Thread Flags of current running thread. +/// \return current thread flags. +uint32_t osThreadFlagsGet (void); + +/// Wait for one or more Thread Flags of the current running thread to become signaled. +/// \param[in] flags specifies the flags to wait for. +/// \param[in] options specifies flags options (osFlagsXxxx). +/// \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +/// \return thread flags before clearing or error code if highest bit set. +uint32_t osThreadFlagsWait (uint32_t flags, uint32_t options, uint32_t timeout); + + +// ==== Generic Wait Functions ==== + +/// Wait for Timeout (Time Delay). +/// \param[in] ticks \ref CMSIS_RTOS_TimeOutValue "time ticks" value +/// \return status code that indicates the execution status of the function. +osStatus_t osDelay (uint32_t ticks); + +/// Wait until specified time. +/// \param[in] ticks absolute time in ticks +/// \return status code that indicates the execution status of the function. +osStatus_t osDelayUntil (uint64_t ticks); + + +// ==== Timer Management Functions ==== + +/// Create and Initialize a timer. +/// \param[in] func start address of a timer call back function. +/// \param[in] type osTimerOnce for one-shot or osTimerPeriodic for periodic behavior. +/// \param[in] argument argument to the timer call back function. +/// \param[in] attr timer attributes; NULL: default values. +/// \return timer ID for reference by other functions or NULL in case of error. +osTimerId_t osTimerNew (osTimerFunc_t func, osTimerType_t type, void *argument, const osTimerAttr_t *attr); + +/// Get name of a timer. +/// \param[in] timer_id timer ID obtained by \ref osTimerNew. +/// \return name as NULL terminated string. +const char *osTimerGetName (osTimerId_t timer_id); + +/// Start or restart a timer. +/// \param[in] timer_id timer ID obtained by \ref osTimerNew. +/// \param[in] ticks \ref CMSIS_RTOS_TimeOutValue "time ticks" value of the timer. +/// \return status code that indicates the execution status of the function. +osStatus_t osTimerStart (osTimerId_t timer_id, uint32_t ticks); + +/// Stop a timer. +/// \param[in] timer_id timer ID obtained by \ref osTimerNew. +/// \return status code that indicates the execution status of the function. +osStatus_t osTimerStop (osTimerId_t timer_id); + +/// Check if a timer is running. +/// \param[in] timer_id timer ID obtained by \ref osTimerNew. +/// \return 0 not running, 1 running. +uint32_t osTimerIsRunning (osTimerId_t timer_id); + +/// Delete a timer. +/// \param[in] timer_id timer ID obtained by \ref osTimerNew. +/// \return status code that indicates the execution status of the function. +osStatus_t osTimerDelete (osTimerId_t timer_id); + + +// ==== Event Flags Management Functions ==== + +/// Create and Initialize an Event Flags object. +/// \param[in] attr event flags attributes; NULL: default values. +/// \return event flags ID for reference by other functions or NULL in case of error. +osEventFlagsId_t osEventFlagsNew (const osEventFlagsAttr_t *attr); + +/// Get name of an Event Flags object. +/// \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew. +/// \return name as NULL terminated string. +const char *osEventFlagsGetName (osEventFlagsId_t ef_id); + +/// Set the specified Event Flags. +/// \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew. +/// \param[in] flags specifies the flags that shall be set. +/// \return event flags after setting or error code if highest bit set. +uint32_t osEventFlagsSet (osEventFlagsId_t ef_id, uint32_t flags); + +/// Clear the specified Event Flags. +/// \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew. +/// \param[in] flags specifies the flags that shall be cleared. +/// \return event flags before clearing or error code if highest bit set. +uint32_t osEventFlagsClear (osEventFlagsId_t ef_id, uint32_t flags); + +/// Get the current Event Flags. +/// \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew. +/// \return current event flags. +uint32_t osEventFlagsGet (osEventFlagsId_t ef_id); + +/// Wait for one or more Event Flags to become signaled. +/// \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew. +/// \param[in] flags specifies the flags to wait for. +/// \param[in] options specifies flags options (osFlagsXxxx). +/// \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +/// \return event flags before clearing or error code if highest bit set. +uint32_t osEventFlagsWait (osEventFlagsId_t ef_id, uint32_t flags, uint32_t options, uint32_t timeout); + +/// Delete an Event Flags object. +/// \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew. +/// \return status code that indicates the execution status of the function. +osStatus_t osEventFlagsDelete (osEventFlagsId_t ef_id); + + +// ==== Mutex Management Functions ==== + +/// Create and Initialize a Mutex object. +/// \param[in] attr mutex attributes; NULL: default values. +/// \return mutex ID for reference by other functions or NULL in case of error. +osMutexId_t osMutexNew (const osMutexAttr_t *attr); + +/// Get name of a Mutex object. +/// \param[in] mutex_id mutex ID obtained by \ref osMutexNew. +/// \return name as NULL terminated string. +const char *osMutexGetName (osMutexId_t mutex_id); + +/// Acquire a Mutex or timeout if it is locked. +/// \param[in] mutex_id mutex ID obtained by \ref osMutexNew. +/// \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +/// \return status code that indicates the execution status of the function. +osStatus_t osMutexAcquire (osMutexId_t mutex_id, uint32_t timeout); + +/// Release a Mutex that was acquired by \ref osMutexAcquire. +/// \param[in] mutex_id mutex ID obtained by \ref osMutexNew. +/// \return status code that indicates the execution status of the function. +osStatus_t osMutexRelease (osMutexId_t mutex_id); + +/// Get Thread which owns a Mutex object. +/// \param[in] mutex_id mutex ID obtained by \ref osMutexNew. +/// \return thread ID of owner thread or NULL when mutex was not acquired. +osThreadId_t osMutexGetOwner (osMutexId_t mutex_id); + +/// Delete a Mutex object. +/// \param[in] mutex_id mutex ID obtained by \ref osMutexNew. +/// \return status code that indicates the execution status of the function. +osStatus_t osMutexDelete (osMutexId_t mutex_id); + + +// ==== Semaphore Management Functions ==== + +/// Create and Initialize a Semaphore object. +/// \param[in] max_count maximum number of available tokens. +/// \param[in] initial_count initial number of available tokens. +/// \param[in] attr semaphore attributes; NULL: default values. +/// \return semaphore ID for reference by other functions or NULL in case of error. +osSemaphoreId_t osSemaphoreNew (uint32_t max_count, uint32_t initial_count, const osSemaphoreAttr_t *attr); + +/// Get name of a Semaphore object. +/// \param[in] semaphore_id semaphore ID obtained by \ref osSemaphoreNew. +/// \return name as NULL terminated string. +const char *osSemaphoreGetName (osSemaphoreId_t semaphore_id); + +/// Acquire a Semaphore token or timeout if no tokens are available. +/// \param[in] semaphore_id semaphore ID obtained by \ref osSemaphoreNew. +/// \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +/// \return status code that indicates the execution status of the function. +osStatus_t osSemaphoreAcquire (osSemaphoreId_t semaphore_id, uint32_t timeout); + +/// Release a Semaphore token that was acquired by \ref osSemaphoreAcquire. +/// \param[in] semaphore_id semaphore ID obtained by \ref osSemaphoreNew. +/// \return status code that indicates the execution status of the function. +osStatus_t osSemaphoreRelease (osSemaphoreId_t semaphore_id); + +/// Get current Semaphore token count. +/// \param[in] semaphore_id semaphore ID obtained by \ref osSemaphoreNew. +/// \return number of tokens available. +uint32_t osSemaphoreGetCount (osSemaphoreId_t semaphore_id); + +/// Delete a Semaphore object. +/// \param[in] semaphore_id semaphore ID obtained by \ref osSemaphoreNew. +/// \return status code that indicates the execution status of the function. +osStatus_t osSemaphoreDelete (osSemaphoreId_t semaphore_id); + + +// ==== Memory Pool Management Functions ==== + +/// Create and Initialize a Memory Pool object. +/// \param[in] block_count maximum number of memory blocks in memory pool. +/// \param[in] block_size memory block size in bytes. +/// \param[in] attr memory pool attributes; NULL: default values. +/// \return memory pool ID for reference by other functions or NULL in case of error. +osMemoryPoolId_t osMemoryPoolNew (uint32_t block_count, uint32_t block_size, const osMemoryPoolAttr_t *attr); + +/// Get name of a Memory Pool object. +/// \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew. +/// \return name as NULL terminated string. +const char *osMemoryPoolGetName (osMemoryPoolId_t mp_id); + +/// Allocate a memory block from a Memory Pool. +/// \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew. +/// \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +/// \return address of the allocated memory block or NULL in case of no memory is available. +void *osMemoryPoolAlloc (osMemoryPoolId_t mp_id, uint32_t timeout); + +/// Return an allocated memory block back to a Memory Pool. +/// \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew. +/// \param[in] block address of the allocated memory block to be returned to the memory pool. +/// \return status code that indicates the execution status of the function. +osStatus_t osMemoryPoolFree (osMemoryPoolId_t mp_id, void *block); + +/// Get maximum number of memory blocks in a Memory Pool. +/// \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew. +/// \return maximum number of memory blocks. +uint32_t osMemoryPoolGetCapacity (osMemoryPoolId_t mp_id); + +/// Get memory block size in a Memory Pool. +/// \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew. +/// \return memory block size in bytes. +uint32_t osMemoryPoolGetBlockSize (osMemoryPoolId_t mp_id); + +/// Get number of memory blocks used in a Memory Pool. +/// \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew. +/// \return number of memory blocks used. +uint32_t osMemoryPoolGetCount (osMemoryPoolId_t mp_id); + +/// Get number of memory blocks available in a Memory Pool. +/// \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew. +/// \return number of memory blocks available. +uint32_t osMemoryPoolGetSpace (osMemoryPoolId_t mp_id); + +/// Delete a Memory Pool object. +/// \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew. +/// \return status code that indicates the execution status of the function. +osStatus_t osMemoryPoolDelete (osMemoryPoolId_t mp_id); + + +// ==== Message Queue Management Functions ==== + +/// Create and Initialize a Message Queue object. +/// \param[in] msg_count maximum number of messages in queue. +/// \param[in] msg_size maximum message size in bytes. +/// \param[in] attr message queue attributes; NULL: default values. +/// \return message queue ID for reference by other functions or NULL in case of error. +osMessageQueueId_t osMessageQueueNew (uint32_t msg_count, uint32_t msg_size, const osMessageQueueAttr_t *attr); + +/// Get name of a Message Queue object. +/// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. +/// \return name as NULL terminated string. +const char *osMessageQueueGetName (osMessageQueueId_t mq_id); + +/// Put a Message into a Queue or timeout if Queue is full. +/// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. +/// \param[in] msg_ptr pointer to buffer with message to put into a queue. +/// \param[in] msg_prio message priority. +/// \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +/// \return status code that indicates the execution status of the function. +osStatus_t osMessageQueuePut (osMessageQueueId_t mq_id, const void *msg_ptr, uint8_t msg_prio, uint32_t timeout); + +/// Get a Message from a Queue or timeout if Queue is empty. +/// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. +/// \param[out] msg_ptr pointer to buffer for message to get from a queue. +/// \param[out] msg_prio pointer to buffer for message priority or NULL. +/// \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +/// \return status code that indicates the execution status of the function. +osStatus_t osMessageQueueGet (osMessageQueueId_t mq_id, void *msg_ptr, uint8_t *msg_prio, uint32_t timeout); + +/// Get maximum number of messages in a Message Queue. +/// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. +/// \return maximum number of messages. +uint32_t osMessageQueueGetCapacity (osMessageQueueId_t mq_id); + +/// Get maximum message size in a Memory Pool. +/// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. +/// \return maximum message size in bytes. +uint32_t osMessageQueueGetMsgSize (osMessageQueueId_t mq_id); + +/// Get number of queued messages in a Message Queue. +/// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. +/// \return number of queued messages. +uint32_t osMessageQueueGetCount (osMessageQueueId_t mq_id); + +/// Get number of available slots for messages in a Message Queue. +/// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. +/// \return number of available slots for messages. +uint32_t osMessageQueueGetSpace (osMessageQueueId_t mq_id); + +/// Reset a Message Queue to initial empty state. +/// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. +/// \return status code that indicates the execution status of the function. +osStatus_t osMessageQueueReset (osMessageQueueId_t mq_id); + +/// Delete a Message Queue object. +/// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. +/// \return status code that indicates the execution status of the function. +osStatus_t osMessageQueueDelete (osMessageQueueId_t mq_id); + + +#ifdef __cplusplus +} +#endif + +#endif // CMSIS_OS2_H_ diff --git a/rtos/rtx2/TARGET_CORTEX_M/core_cm.h b/rtos/rtx2/TARGET_CORTEX_M/core_cm.h new file mode 100644 index 00000000000..93c77e1531c --- /dev/null +++ b/rtos/rtx2/TARGET_CORTEX_M/core_cm.h @@ -0,0 +1,1524 @@ +/* + * Copyright (c) 2013-2017 ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ----------------------------------------------------------------------------- + * + * Project: CMSIS-RTOS RTX + * Title: Cortex-M Core definitions + * + * ----------------------------------------------------------------------------- + */ + +#ifndef CORE_CM_H_ +#define CORE_CM_H_ + +#include "RTE_Components.h" +#include CMSIS_device_header + +#ifndef __ARM_ARCH_6M__ +#define __ARM_ARCH_6M__ 0U +#endif +#ifndef __ARM_ARCH_7M__ +#define __ARM_ARCH_7M__ 0U +#endif +#ifndef __ARM_ARCH_7EM__ +#define __ARM_ARCH_7EM__ 0U +#endif +#ifndef __ARM_ARCH_8M_BASE__ +#define __ARM_ARCH_8M_BASE__ 0U +#endif +#ifndef __ARM_ARCH_8M_MAIN__ +#define __ARM_ARCH_8M_MAIN__ 0U +#endif + +#if ((__ARM_ARCH_6M__ + \ + __ARM_ARCH_7M__ + \ + __ARM_ARCH_7EM__ + \ + __ARM_ARCH_8M_BASE__ + \ + __ARM_ARCH_8M_MAIN__) != 1U) +#error "Unknown ARM Architecture!" +#endif + +#ifdef RTE_CMSIS_RTOS2_RTX5_ARMV8M_NS +#define __DOMAIN_NS 1U +#endif + +#ifndef __DOMAIN_NS +#define __DOMAIN_NS 0U +#elif ((__DOMAIN_NS == 1U) && \ + ((__ARM_ARCH_6M__ == 1U) || \ + (__ARM_ARCH_7M__ == 1U) || \ + (__ARM_ARCH_7EM__ == 1U))) +#error "Non-secure domain requires ARMv8-M Architecture!" +#endif + +#ifndef __EXCLUSIVE_ACCESS +#if ((__ARM_ARCH_7M__ == 1U) || \ + (__ARM_ARCH_7EM__ == 1U) || \ + (__ARM_ARCH_8M_BASE__ == 1U) || \ + (__ARM_ARCH_8M_MAIN__ == 1U)) +#define __EXCLUSIVE_ACCESS 1U +#else +#define __EXCLUSIVE_ACCESS 0U +#endif +#endif + + +#define IS_PRIVILEGED() ((__get_CONTROL() & 1U) == 0U) + +#define IS_IRQ_MODE() (__get_IPSR() != 0U) + +#if ((__ARM_ARCH_7M__ == 1U) || \ + (__ARM_ARCH_7EM__ == 1U) || \ + (__ARM_ARCH_8M_MAIN__ == 1U)) +#define IS_IRQ_MASKED() ((__get_PRIMASK() != 0U) || (__get_BASEPRI() != 0U)) +#else +#define IS_IRQ_MASKED() (__get_PRIMASK() != 0U) +#endif + +#define XPSR_INITIAL_VALUE 0x01000000U + +#if (__DOMAIN_NS == 1U) +#define STACK_FRAME_INIT 0xBCU +#else +#define STACK_FRAME_INIT 0xFDU +#endif + +#define IS_EXTENDED_STACK_FRAME(n) (((n) & 0x10U) == 0U) + + +// ==== Service Calls definitions ==== + +#if defined(__CC_ARM) + +#if ((__ARM_ARCH_7M__ == 1U) || \ + (__ARM_ARCH_7EM__ == 1U) || \ + (__ARM_ARCH_8M_MAIN__ == 1U)) +#define __SVC_INDIRECT(n) __svc_indirect(n) +#elif ((__ARM_ARCH_6M__ == 1U) || \ + (__ARM_ARCH_8M_BASE__ == 1U)) +#define __SVC_INDIRECT(n) __svc_indirect_r7(n) +#endif + +#if (__FPU_USED == 1U) +#define SVC_SETUP_PSP \ + uint32_t control = __get_CONTROL(); \ + if ((control & 2U) == 0U) { \ + __set_PSP((__get_MSP() - ((control & 4U) ? 104U : 32U)) & ~7U); \ + } +#else +#define SVC_SETUP_PSP \ + uint32_t control = __get_CONTROL(); \ + if ((control & 2U) == 0U) { \ + __set_PSP((__get_MSP() - 32U) & ~7U); \ + } +#endif + +#define SVC0_0N(f,t) \ +__SVC_INDIRECT(0) t svc##f (t(*)()); \ + t svcRtx##f (void); \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (void) { \ + svc##f(svcRtx##f); \ +} + +#define SVC0_0(f,t) \ +__SVC_INDIRECT(0) t svc##f (t(*)()); \ + t svcRtx##f (void); \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (void) { \ + return svc##f(svcRtx##f); \ +} + +#define SVC0_0M(f,t) \ +__SVC_INDIRECT(0) t svc##f (t(*)()); \ + t svcRtx##f (void); \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (void) { \ + SVC_SETUP_PSP \ + return svc##f(svcRtx##f); \ +} + +#define SVC0_0D SVC0_0 + +#define SVC0_1N(f,t,t1) \ +__SVC_INDIRECT(0) t svc##f (t(*)(t1),t1); \ + t svcRtx##f (t1 a1); \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (t1 a1) { \ + svc##f(svcRtx##f,a1); \ +} + +#define SVC0_1(f,t,t1) \ +__SVC_INDIRECT(0) t svc##f (t(*)(t1),t1); \ + t svcRtx##f (t1 a1); \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (t1 a1) { \ + return svc##f(svcRtx##f,a1); \ +} + +#define SVC0_1M(f,t,t1) \ +__SVC_INDIRECT(0) t svc##f (t(*)(t1),t1); \ + t svcRtx##f (t1 a1); \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (t1 a1) { \ + SVC_SETUP_PSP \ + return svc##f(svcRtx##f,a1); \ +} + +#define SVC0_2(f,t,t1,t2) \ +__SVC_INDIRECT(0) t svc##f (t(*)(t1,t2),t1,t2); \ + t svcRtx##f (t1 a1, t2 a2); \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (t1 a1, t2 a2) { \ + return svc##f(svcRtx##f,a1,a2); \ +} + +#define SVC0_2M(f,t,t1,t2) \ +__SVC_INDIRECT(0) t svc##f (t(*)(t1,t2),t1,t2); \ + t svcRtx##f (t1 a1, t2 a2); \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (t1 a1, t2 a2) { \ + SVC_SETUP_PSP \ + return svc##f(svcRtx##f,a1,a2); \ +} + +#define SVC0_3(f,t,t1,t2,t3) \ +__SVC_INDIRECT(0) t svc##f (t(*)(t1,t2,t3),t1,t2,t3); \ + t svcRtx##f (t1 a1, t2 a2, t3 a3); \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (t1 a1, t2 a2, t3 a3) { \ + return svc##f(svcRtx##f,a1,a2,a3); \ +} + +#define SVC0_3M(f,t,t1,t2,t3) \ +__SVC_INDIRECT(0) t svc##f (t(*)(t1,t2,t3),t1,t2,t3); \ + t svcRtx##f (t1 a1, t2 a2, t3 a3); \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (t1 a1, t2 a2, t3 a3) { \ + SVC_SETUP_PSP \ + return svc##f(svcRtx##f,a1,a2,a3); \ +} + +#define SVC0_4(f,t,t1,t2,t3,t4) \ +__SVC_INDIRECT(0) t svc##f (t(*)(t1,t2,t3,t4),t1,t2,t3,t4); \ + t svcRtx##f (t1 a1, t2 a2, t3 a3, t4 a4); \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (t1 a1, t2 a2, t3 a3, t4 a4) { \ + return svc##f(svcRtx##f,a1,a2,a3,a4); \ +} + +#define SVC0_4M(f,t,t1,t2,t3,t4) \ +__SVC_INDIRECT(0) t svc##f (t(*)(t1,t2,t3,t4),t1,t2,t3,t4); \ + t svcRtx##f (t1 a1, t2 a2, t3 a3, t4 a4); \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (t1 a1, t2 a2, t3 a3, t4 a4) { \ + SVC_SETUP_PSP \ + return svc##f(svcRtx##f,a1,a2,a3,a4); \ +} + +#elif defined(__ICCARM__) + +#if ((__ARM_ARCH_7M__ == 1U) || \ + (__ARM_ARCH_7EM__ == 1U) || \ + (__ARM_ARCH_8M_MAIN__ == 1U)) +#define SVC_Setup(f) \ + __asm( \ + "mov r12,%0\n" \ + :: "r"(&f): "r12" \ + ); +#elif ((__ARM_ARCH_6M__ == 1U) || \ + (__ARM_ARCH_8M_BASE__ == 1U)) +#define SVC_Setup(f) \ + __asm( \ + "mov r7,%0\n" \ + :: "r"(&f): "r7" \ + ); +#endif + +#define STRINGIFY(a) #a +#define __SVC_INDIRECT(n) _Pragma(STRINGIFY(swi_number = n)) __swi + +#if (__FPU_USED == 1U) +#define SVC_SETUP_PSP \ + uint32_t control = __get_CONTROL(); \ + if ((control & 2U) == 0U) { \ + __set_PSP((__get_MSP() - ((control & 4U) ? 104U : 32U)) & ~7U); \ + } +#else +#define SVC_SETUP_PSP \ + uint32_t control = __get_CONTROL(); \ + if ((control & 2U) == 0U) { \ + __set_PSP((__get_MSP() - 32U) & ~7U); \ + } +#endif + +#define SVC0_0N(f,t) \ +__SVC_INDIRECT(0) t svc##f (); \ + t svcRtx##f (void); \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (void) { \ + SVC_Setup(svcRtx##f); \ + svc##f(); \ +} + +#define SVC0_0(f,t) \ +__SVC_INDIRECT(0) t svc##f (); \ + t svcRtx##f (void); \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (void) { \ + SVC_Setup(svcRtx##f); \ + return svc##f(); \ +} + +#define SVC0_0M(f,t) \ +__SVC_INDIRECT(0) t svc##f (); \ + t svcRtx##f (void); \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (void) { \ + SVC_SETUP_PSP \ + SVC_Setup(svcRtx##f); \ + return svc##f(); \ +} + +#define SVC0_0D SVC0_0 + +#define SVC0_1N(f,t,t1) \ +__SVC_INDIRECT(0) t svc##f (t1 a1); \ + t svcRtx##f (t1 a1); \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (t1 a1) { \ + SVC_Setup(svcRtx##f); \ + svc##f(a1); \ +} + +#define SVC0_1(f,t,t1) \ +__SVC_INDIRECT(0) t svc##f (t1 a1); \ + t svcRtx##f (t1 a1); \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (t1 a1) { \ + SVC_Setup(svcRtx##f); \ + return svc##f(a1); \ +} + +#define SVC0_1M(f,t,t1) \ +__SVC_INDIRECT(0) t svc##f (t1 a1); \ + t svcRtx##f (t1 a1); \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (t1 a1) { \ + SVC_SETUP_PSP \ + SVC_Setup(svcRtx##f); \ + return svc##f(a1); \ +} + +#define SVC0_2(f,t,t1,t2) \ +__SVC_INDIRECT(0) t svc##f (t1 a1, t2 a2); \ + t svcRtx##f (t1 a1, t2 a2); \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (t1 a1, t2 a2) { \ + SVC_Setup(svcRtx##f); \ + return svc##f(a1,a2); \ +} + +#define SVC0_2M(f,t,t1,t2) \ +__SVC_INDIRECT(0) t svc##f (t1 a1, t2 a2); \ + t svcRtx##f (t1 a1, t2 a2); \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (t1 a1, t2 a2) { \ + SVC_SETUP_PSP \ + SVC_Setup(svcRtx##f); \ + return svc##f(a1,a2); \ +} + +#define SVC0_3(f,t,t1,t2,t3) \ +__SVC_INDIRECT(0) t svc##f (t1 a1, t2 a2, t3 a3); \ + t svcRtx##f (t1 a1, t2 a2, t3 a3); \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (t1 a1, t2 a2, t3 a3) { \ + SVC_Setup(svcRtx##f); \ + return svc##f(a1,a2,a3); \ +} + +#define SVC0_3M(f,t,t1,t2,t3) \ +__SVC_INDIRECT(0) t svc##f (t1 a1, t2 a2, t3 a3); \ + t svcRtx##f (t1 a1, t2 a2, t3 a3); \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (t1 a1, t2 a2, t3 a3) { \ + SVC_SETUP_PSP \ + SVC_Setup(svcRtx##f); \ + return svc##f(a1,a2,a3); \ +} + +#define SVC0_4(f,t,t1,t2,t3,t4) \ +__SVC_INDIRECT(0) t svc##f (t1 a1, t2 a2, t3 a3, t4 a4); \ + t svcRtx##f (t1 a1, t2 a2, t3 a3, t4 a4); \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (t1 a1, t2 a2, t3 a3, t4 a4) { \ + SVC_Setup(svcRtx##f); \ + return svc##f(a1,a2,a3,a4); \ +} + +#define SVC0_4M(f,t,t1,t2,t3,t4) \ +__SVC_INDIRECT(0) t svc##f (t1 a1, t2 a2, t3 a3, t4 a4); \ + t svcRtx##f (t1 a1, t2 a2, t3 a3, t4 a4); \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (t1 a1, t2 a2, t3 a3, t4 a4) { \ + SVC_SETUP_PSP \ + SVC_Setup(svcRtx##f); \ + return svc##f(a1,a2,a3,a4); \ +} + +#else // !(defined(__CC_ARM) || defined(__ICCARM__)) + +#if ((__ARM_ARCH_7M__ == 1U) || \ + (__ARM_ARCH_7EM__ == 1U) || \ + (__ARM_ARCH_8M_MAIN__ == 1U)) +#define SVC_RegF "r12" +#elif ((__ARM_ARCH_6M__ == 1U) || \ + (__ARM_ARCH_8M_BASE__ == 1U)) +#define SVC_RegF "r7" +#endif + +#define SVC_ArgN(n) \ +register uint32_t __r##n __ASM("r"#n) + +#define SVC_ArgR(n,a) \ +register uint32_t __r##n __ASM("r"#n) = (uint32_t)a + +#define SVC_ArgF(f) \ +register uint32_t __rf __ASM(SVC_RegF) = (uint32_t)f + +#define SVC_In0 "r"(__rf) +#define SVC_In1 "r"(__rf),"r"(__r0) +#define SVC_In2 "r"(__rf),"r"(__r0),"r"(__r1) +#define SVC_In3 "r"(__rf),"r"(__r0),"r"(__r1),"r"(__r2) +#define SVC_In4 "r"(__rf),"r"(__r0),"r"(__r1),"r"(__r2),"r"(__r3) + +#define SVC_Out0 +#define SVC_Out1 "=r"(__r0) +#define SVC_Out2 "=r"(__r0),"=r"(__r1) + +#define SVC_CL0 +#define SVC_CL1 "r1" +#define SVC_CL2 "r0","r1" + +#define SVC_Call0(in, out, cl) \ + __ASM volatile ("svc 0" : out : in : cl) + +#if ((__ARM_ARCH_7M__ == 1U) || \ + (__ARM_ARCH_7EM__ == 1U) || \ + (__ARM_ARCH_8M_MAIN__ == 1U)) +#if (__FPU_USED == 1U) +#define SVC_Call0M(in, out, cl) \ + register uint32_t val; \ + __ASM volatile ( \ + ".syntax unified\n\t" \ + "mrs %[val],control\n\t" \ + "tst %[val],#2\n\t" \ + "bne 0f\n\t" \ + "tst %[val],#4\n\t" \ + "mrs %[val],msp\n\t" \ + "ite eq\n\t" \ + "subeq %[val],#32\n\t" \ + "subne %[val],#104\n\t" \ + "bic %[val],#7\n\t" \ + "msr psp,%[val]\n\t" \ + "0:\n\t" \ + "svc 0" \ + : out, [val] "=&l" (val) : in : cl) +#else +#define SVC_Call0M(in, out, cl) \ + register uint32_t val; \ + __ASM volatile ( \ + ".syntax unified\n\t" \ + "mrs %[val],control\n\t" \ + "tst %[val],#2\n\t" \ + "bne 0f\n\t" \ + "mrs %[val],msp\n\t" \ + "subs %[val],#32\n\t" \ + "bic %[val],#7\n\t" \ + "msr psp,%[val]\n\t" \ + "0:\n\t" \ + "svc 0" \ + : out, [val] "=&l" (val) : in : cl) +#endif +#elif ((__ARM_ARCH_6M__ == 1U) || \ + (__ARM_ARCH_8M_BASE__ == 1U)) +#define SVC_Call0M(in, out, cl) \ + register uint32_t val; \ + __ASM volatile ( \ + ".syntax unified\n\t" \ + "mrs %[val],control\n\t" \ + "lsls %[val],#30\n\t" \ + "bmi 0f\n\t" \ + "mrs %[val],msp\n\t" \ + "subs %[val],#32\n\t" \ + "lsrs %[val],#3\n\t" \ + "lsls %[val],#3\n\t" \ + "msr psp,%[val]\n\t" \ + "0:\n\t" \ + "svc 0" \ + : out, [val] "=&l" (val) : in : cl) +#endif + +#define SVC0_0N(f,t) \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (void) { \ + SVC_ArgF(svcRtx##f); \ + SVC_Call0(SVC_In0, SVC_Out0, SVC_CL2); \ +} + +#define SVC0_0(f,t) \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (void) { \ + SVC_ArgN(0); \ + SVC_ArgF(svcRtx##f); \ + SVC_Call0(SVC_In0, SVC_Out1, SVC_CL1); \ + return (t) __r0; \ +} + +#define SVC0_0M(f,t) \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (void) { \ + SVC_ArgN(0); \ + SVC_ArgF(svcRtx##f); \ + SVC_Call0M(SVC_In0, SVC_Out1, SVC_CL1); \ + return (t) __r0; \ +} + +#define SVC0_0D(f,t) \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (void) { \ + SVC_ArgN(0); \ + SVC_ArgN(1); \ + SVC_ArgF(svcRtx##f); \ + SVC_Call0(SVC_In0, SVC_Out2, SVC_CL0); \ + return (((t) __r0) | (((t) __r1) << 32)); \ +} + +#define SVC0_1N(f,t,t1) \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (t1 a1) { \ + SVC_ArgR(0,a1); \ + SVC_ArgF(svcRtx##f); \ + SVC_Call0(SVC_In1, SVC_Out0, SVC_CL1); \ +} + +#define SVC0_1(f,t,t1) \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (t1 a1) { \ + SVC_ArgR(0,a1); \ + SVC_ArgF(svcRtx##f); \ + SVC_Call0(SVC_In1, SVC_Out1, SVC_CL1); \ + return (t) __r0; \ +} + +#define SVC0_1M(f,t,t1) \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (t1 a1) { \ + SVC_ArgR(0,a1); \ + SVC_ArgF(svcRtx##f); \ + SVC_Call0M(SVC_In1, SVC_Out1, SVC_CL1); \ + return (t) __r0; \ +} + +#define SVC0_2(f,t,t1,t2) \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (t1 a1, t2 a2) { \ + SVC_ArgR(0,a1); \ + SVC_ArgR(1,a2); \ + SVC_ArgF(svcRtx##f); \ + SVC_Call0(SVC_In2, SVC_Out1, SVC_CL0); \ + return (t) __r0; \ +} + +#define SVC0_2M(f,t,t1,t2) \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (t1 a1, t2 a2) { \ + SVC_ArgR(0,a1); \ + SVC_ArgR(1,a2); \ + SVC_ArgF(svcRtx##f); \ + SVC_Call0M(SVC_In2, SVC_Out1, SVC_CL0); \ + return (t) __r0; \ +} + +#define SVC0_3(f,t,t1,t2,t3) \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (t1 a1, t2 a2, t3 a3) { \ + SVC_ArgR(0,a1); \ + SVC_ArgR(1,a2); \ + SVC_ArgR(2,a3); \ + SVC_ArgF(svcRtx##f); \ + SVC_Call0(SVC_In3, SVC_Out1, SVC_CL0); \ + return (t) __r0; \ +} + +#define SVC0_3M(f,t,t1,t2,t3) \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (t1 a1, t2 a2, t3 a3) { \ + SVC_ArgR(0,a1); \ + SVC_ArgR(1,a2); \ + SVC_ArgR(2,a3); \ + SVC_ArgF(svcRtx##f); \ + SVC_Call0M(SVC_In3, SVC_Out1, SVC_CL0); \ + return (t) __r0; \ +} + +#define SVC0_4(f,t,t1,t2,t3,t4) \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (t1 a1, t2 a2, t3 a3, t4 a4) { \ + SVC_ArgR(0,a1); \ + SVC_ArgR(1,a2); \ + SVC_ArgR(2,a3); \ + SVC_ArgR(3,a4); \ + SVC_ArgF(svcRtx##f); \ + SVC_Call0(SVC_In4, SVC_Out1, SVC_CL0); \ + return (t) __r0; \ +} + +#define SVC0_4M(f,t,t1,t2,t3,t4) \ +__attribute__((always_inline)) \ +__STATIC_INLINE t __svc##f (t1 a1, t2 a2, t3 a3, t4 a4) { \ + SVC_ArgR(0,a1); \ + SVC_ArgR(1,a2); \ + SVC_ArgR(2,a3); \ + SVC_ArgR(3,a4); \ + SVC_ArgF(svcRtx##f); \ + SVC_Call0M(SVC_In4, SVC_Out1, SVC_CL0); \ + return (t) __r0; \ +} + +#endif + + +// ==== Core Peripherals functions ==== + +extern uint32_t SystemCoreClock; // System Clock Frequency (Core Clock) + + +/// Initialize SVC and PendSV System Service Calls +__STATIC_INLINE void SVC_Initialize (void) { +#if ((__ARM_ARCH_8M_MAIN__ == 1U) || (defined(__CORTEX_M) && (__CORTEX_M == 7U))) + uint32_t p, n; + + SCB->SHPR[10] = 0xFFU; + n = 32U - (uint32_t)__CLZ(~(SCB->SHPR[10] | 0xFFFFFF00U)); + p = NVIC_GetPriorityGrouping(); + if (p >= n) { + n = p + 1U; + } + SCB->SHPR[7] = (uint8_t)(0xFEU << n); +#elif (__ARM_ARCH_8M_BASE__ == 1U) + SCB->SHPR[1] |= 0x00FF0000U; + SCB->SHPR[0] |= (SCB->SHPR[1] << (8+1)) & 0xFC000000U; +#elif ((__ARM_ARCH_7M__ == 1U) || \ + (__ARM_ARCH_7EM__ == 1U)) + uint32_t p, n; + + SCB->SHP[10] = 0xFFU; + n = 32U - (uint32_t)__CLZ(~(SCB->SHP[10] | 0xFFFFFF00U)); + p = NVIC_GetPriorityGrouping(); + if (p >= n) { + n = p + 1U; + } + SCB->SHP[7] = (uint8_t)(0xFEU << n); +#elif (__ARM_ARCH_6M__ == 1U) + SCB->SHP[1] |= 0x00FF0000U; + SCB->SHP[0] |= (SCB->SHP[1] << (8+1)) & 0xFC000000U; +#endif +} + +/// Setup SysTick Timer +/// \param[in] period Timer Load value +__STATIC_INLINE void SysTick_Setup (uint32_t period) { + SysTick->LOAD = period - 1U; + SysTick->VAL = 0U; +#if ((__ARM_ARCH_8M_MAIN__ == 1U) || (defined(__CORTEX_M) && (__CORTEX_M == 7U))) + SCB->SHPR[11] = 0xFFU; +#elif (__ARM_ARCH_8M_BASE__ == 1U) + SCB->SHPR[1] |= 0xFF000000U; +#elif ((__ARM_ARCH_7M__ == 1U) || \ + (__ARM_ARCH_7EM__ == 1U)) + SCB->SHP[11] = 0xFFU; +#elif (__ARM_ARCH_6M__ == 1U) + SCB->SHP[1] |= 0xFF000000U; +#endif +} + +/// Get SysTick Period +/// \return SysTick Period +__STATIC_INLINE uint32_t SysTick_GetPeriod (void) { + return (SysTick->LOAD + 1U); +} + +/// Get SysTick Value +/// \return SysTick Value +__STATIC_INLINE uint32_t SysTick_GetVal (void) { + uint32_t load = SysTick->LOAD; + return (load - SysTick->VAL); +} + +/// Get SysTick Overflow (Auto Clear) +/// \return SysTick Overflow flag +__STATIC_INLINE uint32_t SysTick_GetOvf (void) { + return ((SysTick->CTRL >> 16) & 1U); +} + +/// Enable SysTick Timer +__STATIC_INLINE void SysTick_Enable (void) { + SysTick->CTRL = SysTick_CTRL_ENABLE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_CLKSOURCE_Msk; +} + +/// Disable SysTick Timer +__STATIC_INLINE void SysTick_Disable (void) { + SysTick->CTRL = 0U; +} + +/// Setup External Tick Timer Interrupt +/// \param[in] irqn Interrupt number +__STATIC_INLINE void ExtTick_SetupIRQ (int32_t irqn) { +#if (__ARM_ARCH_8M_MAIN__ == 1U) + NVIC->IPR[irqn] = 0xFFU; +#elif (__ARM_ARCH_8M_BASE__ == 1U) + NVIC->IPR[irqn >> 2] = (NVIC->IPR[irqn >> 2] & ~(0xFFU << ((irqn & 3) << 3))) | + (0xFFU << ((irqn & 3) << 3)); +#elif ((__ARM_ARCH_7M__ == 1U) || \ + (__ARM_ARCH_7EM__ == 1U)) + NVIC->IP[irqn] = 0xFFU; +#elif (__ARM_ARCH_6M__ == 1U) + NVIC->IP[irqn >> 2] = (NVIC->IP[irqn >> 2] & ~(0xFFU << ((irqn & 3) << 3))) | + (0xFFU << ((irqn & 3) << 3)); +#endif +} + +/// Enable External Tick Timer Interrupt +/// \param[in] irqn Interrupt number +__STATIC_INLINE void ExtTick_EnableIRQ (int32_t irqn) { + NVIC->ISER[irqn >> 5] = 1U << (irqn & 0x1F); +} + +/// Disable External Tick Timer Interrupt +/// \param[in] irqn Interrupt number +__STATIC_INLINE void ExtTick_DisableIRQ (int32_t irqn) { + NVIC->ICER[irqn >> 5] = 1U << (irqn & 0x1F); +} + +/// Get Pending SV (Service Call) and ST (SysTick) Flags +/// \return Pending SV&ST Flags +__STATIC_INLINE uint8_t GetPendSV_ST (void) { + return ((uint8_t)((SCB->ICSR & (SCB_ICSR_PENDSVSET_Msk | SCB_ICSR_PENDSTSET_Msk)) >> 24)); +} + +/// Get Pending SV (Service Call) Flag +/// \return Pending SV Flag +__STATIC_INLINE uint8_t GetPendSV (void) { + return ((uint8_t)((SCB->ICSR & (SCB_ICSR_PENDSVSET_Msk)) >> 24)); +} + +/// Clear Pending SV (Service Call) and ST (SysTick) Flags +__STATIC_INLINE void ClrPendSV_ST (void) { + SCB->ICSR = SCB_ICSR_PENDSVCLR_Msk | SCB_ICSR_PENDSTCLR_Msk; +} + +/// Clear Pending SV (Service Call) Flag +__STATIC_INLINE void ClrPendSV (void) { + SCB->ICSR = SCB_ICSR_PENDSVCLR_Msk; +} + +/// Set Pending SV (Service Call) Flag +__STATIC_INLINE void SetPendSV (void) { + SCB->ICSR = SCB_ICSR_PENDSVSET_Msk; +} + +/// Set Pending Flags +/// \param[in] flags Flags to set +__STATIC_INLINE void SetPendFlags (uint8_t flags) { + SCB->ICSR = ((uint32_t)flags << 24); +} + + +// ==== Exclusive Access Operation ==== + +#if (__EXCLUSIVE_ACCESS == 1U) + +/// Atomic Access Operation: Write (8-bit) +/// \param[in] mem Memory address +/// \param[in] val Value to write +/// \return Previous value +#if defined(__CC_ARM) +static __asm uint8_t atomic_wr8 (uint8_t *mem, uint8_t val) { + mov r2,r0 +1 + ldrexb r0,[r2] + strexb r3,r1,[r2] + cbz r3,%F2 + b %B1 +2 + bx lr +} +#else +__STATIC_INLINE uint8_t atomic_wr8 (uint8_t *mem, uint8_t val) { +#ifdef __ICCARM__ +#pragma diag_suppress=Pe550 +#endif + register uint32_t res; +#ifdef __ICCARM__ +#pragma diag_default=Pe550 +#endif + register uint8_t ret; + + __ASM volatile ( +#ifndef __ICCARM__ + ".syntax unified\n\t" +#endif + "1:\n\t" + "ldrexb %[ret],[%[mem]]\n\t" + "strexb %[res],%[val],[%[mem]]\n\t" + "cbz %[res],2f\n\t" + "b 1b\n" + "2:" + : [ret] "=&l" (ret), + [res] "=&l" (res) + : [mem] "l" (mem), + [val] "l" (val) + : "memory" + ); + + return ret; +} +#endif + +/// Atomic Access Operation: Set bits (32-bit) +/// \param[in] mem Memory address +/// \param[in] bits Bit mask +/// \return New value +#if defined(__CC_ARM) +static __asm uint32_t atomic_set32 (uint32_t *mem, uint32_t bits) { + mov r2,r0 +1 + ldrex r0,[r2] + orr r0,r0,r1 + strex r3,r0,[r2] + cbz r3,%F2 + b %B1 +2 + bx lr +} +#else +__STATIC_INLINE uint32_t atomic_set32 (uint32_t *mem, uint32_t bits) { +#ifdef __ICCARM__ +#pragma diag_suppress=Pe550 +#endif + register uint32_t val, res; +#ifdef __ICCARM__ +#pragma diag_default=Pe550 +#endif + register uint32_t ret; + + __ASM volatile ( +#ifndef __ICCARM__ + ".syntax unified\n\t" +#endif + "1:\n\t" + "ldrex %[val],[%[mem]]\n\t" +#if (__ARM_ARCH_8M_BASE__ == 1U) + "mov %[ret],%[val]\n\t" + "orrs %[ret],%[bits]\n\t" +#else + "orr %[ret],%[val],%[bits]\n\t" +#endif + "strex %[res],%[ret],[%[mem]]\n\t" + "cbz %[res],2f\n\t" + "b 1b\n" + "2:" + : [ret] "=&l" (ret), + [val] "=&l" (val), + [res] "=&l" (res) + : [mem] "l" (mem), + [bits] "l" (bits) +#if (__ARM_ARCH_8M_BASE__ == 1U) + : "memory", "cc" +#else + : "memory" +#endif + ); + + return ret; +} +#endif + +/// Atomic Access Operation: Clear bits (32-bit) +/// \param[in] mem Memory address +/// \param[in] bits Bit mask +/// \return Previous value +#if defined(__CC_ARM) +static __asm uint32_t atomic_clr32 (uint32_t *mem, uint32_t bits) { + push {r4,lr} + mov r2,r0 +1 + ldrex r0,[r2] + bic r4,r0,r1 + strex r3,r4,[r2] + cbz r3,%F2 + b %B1 +2 + pop {r4,pc} +} +#else +__STATIC_INLINE uint32_t atomic_clr32 (uint32_t *mem, uint32_t bits) { +#ifdef __ICCARM__ +#pragma diag_suppress=Pe550 +#endif + register uint32_t val, res; +#ifdef __ICCARM__ +#pragma diag_default=Pe550 +#endif + register uint32_t ret; + + __ASM volatile ( +#ifndef __ICCARM__ + ".syntax unified\n\t" +#endif + "1:\n\t" + "ldrex %[ret],[%[mem]]\n\t" +#if (__ARM_ARCH_8M_BASE__ == 1U) + "mov %[val],%[ret]\n\t" + "bics %[val],%[bits]\n\t" +#else + "bic %[val],%[ret],%[bits]\n\t" +#endif + "strex %[res],%[val],[%[mem]]\n\t" + "cbz %[res],2f\n\t" + "b 1b\n" + "2:" + : [ret] "=&l" (ret), + [val] "=&l" (val), + [res] "=&l" (res) + : [mem] "l" (mem), + [bits] "l" (bits) +#if (__ARM_ARCH_8M_BASE__ == 1U) + : "memory", "cc" +#else + : "memory" +#endif + ); + + return ret; +} +#endif + +/// Atomic Access Operation: Check if all specified bits (32-bit) are active and clear them +/// \param[in] mem Memory address +/// \param[in] bits Bit mask +/// \return Active bits before clearing or 0 if not active +#if defined(__CC_ARM) +static __asm uint32_t atomic_chk32_all (uint32_t *mem, uint32_t bits) { + push {r4,lr} + mov r2,r0 +1 + ldrex r0,[r2] + and r4,r0,r1 + cmp r4,r1 + beq %F2 + clrex + movs r0,#0 + pop {r4,pc} +2 + bic r4,r0,r1 + strex r3,r4,[r2] + cbz r3,%F3 + b %B1 +3 + pop {r4,pc} +} +#else +__STATIC_INLINE uint32_t atomic_chk32_all (uint32_t *mem, uint32_t bits) { +#ifdef __ICCARM__ +#pragma diag_suppress=Pe550 +#endif + register uint32_t val, res; +#ifdef __ICCARM__ +#pragma diag_default=Pe550 +#endif + register uint32_t ret; + + __ASM volatile ( +#ifndef __ICCARM__ + ".syntax unified\n\t" +#endif + "1:\n\t" + "ldrex %[ret],[%[mem]]\n\t" +#if (__ARM_ARCH_8M_BASE__ == 1U) + "mov %[val],%[ret]\n\t" + "ands %[val],%[bits]\n\t" +#else + "and %[val],%[ret],%[bits]\n\t" +#endif + "cmp %[val],%[bits]\n\t" + "beq 2f\n\t" + "clrex\n\t" + "movs %[ret],#0\n\t" + "b 3f\n" + "2:\n\t" +#if (__ARM_ARCH_8M_BASE__ == 1U) + "mov %[val],%[ret]\n\t" + "bics %[val],%[bits]\n\t" +#else + "bic %[val],%[ret],%[bits]\n\t" +#endif + "strex %[res],%[val],[%[mem]]\n\t" + "cbz %[res],3f\n\t" + "b 1b\n" + "3:" + : [ret] "=&l" (ret), + [val] "=&l" (val), + [res] "=&l" (res) + : [mem] "l" (mem), + [bits] "l" (bits) + : "cc", "memory" + ); + + return ret; +} +#endif + +/// Atomic Access Operation: Check if any specified bits (32-bit) are active and clear them +/// \param[in] mem Memory address +/// \param[in] bits Bit mask +/// \return Active bits before clearing or 0 if not active +#if defined(__CC_ARM) +static __asm uint32_t atomic_chk32_any (uint32_t *mem, uint32_t bits) { + push {r4,lr} + mov r2,r0 +1 + ldrex r0,[r2] + tst r0,r1 + bne %F2 + clrex + movs r0,#0 + pop {r4,pc} +2 + bic r4,r0,r1 + strex r3,r4,[r2] + cbz r3,%F3 + b %B1 +3 + pop {r4,pc} +} +#else +__STATIC_INLINE uint32_t atomic_chk32_any (uint32_t *mem, uint32_t bits) { +#ifdef __ICCARM__ +#pragma diag_suppress=Pe550 +#endif + register uint32_t val, res; +#ifdef __ICCARM__ +#pragma diag_default=Pe550 +#endif + register uint32_t ret; + + __ASM volatile ( +#ifndef __ICCARM__ + ".syntax unified\n\t" +#endif + "1:\n\t" + "ldrex %[ret],[%[mem]]\n\t" + "tst %[ret],%[bits]\n\t" + "bne 2f\n\t" + "clrex\n\t" + "movs %[ret],#0\n\t" + "b 3f\n" + "2:\n\t" +#if (__ARM_ARCH_8M_BASE__ == 1U) + "mov %[val],%[ret]\n\t" + "bics %[val],%[bits]\n\t" +#else + "bic %[val],%[ret],%[bits]\n\t" +#endif + "strex %[res],%[val],[%[mem]]\n\t" + "cbz %[res],3f\n\t" + "b 1b\n" + "3:" + : [ret] "=&l" (ret), + [val] "=&l" (val), + [res] "=&l" (res) + : [mem] "l" (mem), + [bits] "l" (bits) + : "cc", "memory" + ); + + return ret; +} +#endif + +/// Atomic Access Operation: Increment (32-bit) +/// \param[in] mem Memory address +/// \return Previous value +#if defined(__CC_ARM) +static __asm uint32_t atomic_inc32 (uint32_t *mem) { + mov r2,r0 +1 + ldrex r0,[r2] + adds r1,r0,#1 + strex r3,r1,[r2] + cbz r3,%F2 + b %B1 +2 + bx lr +} +#else +__STATIC_INLINE uint32_t atomic_inc32 (uint32_t *mem) { +#ifdef __ICCARM__ +#pragma diag_suppress=Pe550 +#endif + register uint32_t val, res; +#ifdef __ICCARM__ +#pragma diag_default=Pe550 +#endif + register uint32_t ret; + + __ASM volatile ( +#ifndef __ICCARM__ + ".syntax unified\n\t" +#endif + "1:\n\t" + "ldrex %[ret],[%[mem]]\n\t" + "adds %[val],%[ret],#1\n\t" + "strex %[res],%[val],[%[mem]]\n\t" + "cbz %[res],2f\n\t" + "b 1b\n" + "2:" + : [ret] "=&l" (ret), + [val] "=&l" (val), + [res] "=&l" (res) + : [mem] "l" (mem) + : "cc", "memory" + ); + + return ret; +} +#endif + +/// atomic Access Operation: Increment (32-bit) if Less Than +/// \param[in] mem Memory address +/// \param[in] max Maximum value +/// \return Previous value +#if defined(__CC_ARM) +static __asm uint32_t atomic_inc32_lt (uint32_t *mem, uint32_t max) { + push {r4,lr} + mov r2,r0 +1 + ldrex r0,[r2] + cmp r1,r0 + bhi %F2 + clrex + pop {r4,pc} +2 + adds r4,r0,#1 + strex r3,r4,[r2] + cbz r3,%F3 + b %B1 +3 + pop {r4,pc} +} +#else +__STATIC_INLINE uint32_t atomic_inc32_lt (uint32_t *mem, uint32_t max) { +#ifdef __ICCARM__ +#pragma diag_suppress=Pe550 +#endif + register uint32_t val, res; +#ifdef __ICCARM__ +#pragma diag_default=Pe550 +#endif + register uint32_t ret; + + __ASM volatile ( +#ifndef __ICCARM__ + ".syntax unified\n\t" +#endif + "1:\n\t" + "ldrex %[ret],[%[mem]]\n\t" + "cmp %[max],%[ret]\n\t" + "bhi 2f\n\t" + "clrex\n\t" + "b 3f\n" + "2:\n\t" + "adds %[val],%[ret],#1\n\t" + "strex %[res],%[val],[%[mem]]\n\t" + "cbz %[res],3f\n\t" + "b 1b\n" + "3:" + : [ret] "=&l" (ret), + [val] "=&l" (val), + [res] "=&l" (res) + : [mem] "l" (mem), + [max] "l" (max) + : "cc", "memory" + ); + + return ret; +} +#endif + +/// Atomic Access Operation: Increment (16-bit) if Less Than +/// \param[in] mem Memory address +/// \param[in] max Maximum value +/// \return Previous value +#if defined(__CC_ARM) +static __asm uint16_t atomic_inc16_lt (uint16_t *mem, uint16_t max) { + push {r4,lr} + mov r2,r0 +1 + ldrexh r0,[r2] + cmp r1,r0 + bhi %F2 + clrex + pop {r4,pc} +2 + adds r4,r0,#1 + strexh r3,r4,[r2] + cbz r3,%F3 + b %B1 +3 + pop {r4,pc} +} +#else +__STATIC_INLINE uint16_t atomic_inc16_lt (uint16_t *mem, uint16_t max) { +#ifdef __ICCARM__ +#pragma diag_suppress=Pe550 +#endif + register uint32_t val, res; +#ifdef __ICCARM__ +#pragma diag_default=Pe550 +#endif + register uint16_t ret; + + __ASM volatile ( +#ifndef __ICCARM__ + ".syntax unified\n\t" +#endif + "1:\n\t" + "ldrexh %[ret],[%[mem]]\n\t" + "cmp %[max],%[ret]\n\t" + "bhi 2f\n\t" + "clrex\n\t" + "b 3f\n" + "2:\n\t" + "adds %[val],%[ret],#1\n\t" + "strexh %[res],%[val],[%[mem]]\n\t" + "cbz %[res],3f\n\t" + "b 1b\n" + "3:" + : [ret] "=&l" (ret), + [val] "=&l" (val), + [res] "=&l" (res) + : [mem] "l" (mem), + [max] "l" (max) + : "cc", "memory" + ); + + return ret; +} +#endif + +/// Atomic Access Operation: Increment (16-bit) and clear on Limit +/// \param[in] mem Memory address +/// \param[in] max Maximum value +/// \return Previous value +#if defined(__CC_ARM) +static __asm uint16_t atomic_inc16_lim (uint16_t *mem, uint16_t lim) { + push {r4,lr} + mov r2,r0 +1 + ldrexh r0,[r2] + adds r4,r0,#1 + cmp r1,r4 + bhi %F2 + movs r4,#0 +2 + strexh r3,r4,[r2] + cbz r3,%F3 + b %B1 +3 + pop {r4,pc} +} +#else +__STATIC_INLINE uint16_t atomic_inc16_lim (uint16_t *mem, uint16_t lim) { +#ifdef __ICCARM__ +#pragma diag_suppress=Pe550 +#endif + register uint32_t val, res; +#ifdef __ICCARM__ +#pragma diag_default=Pe550 +#endif + register uint16_t ret; + + __ASM volatile ( +#ifndef __ICCARM__ + ".syntax unified\n\t" +#endif + "1:\n\t" + "ldrexh %[ret],[%[mem]]\n\t" + "adds %[val],%[ret],#1\n\t" + "cmp %[lim],%[val]\n\t" + "bhi 2f\n\t" + "movs %[val],#0\n" + "2:\n\t" + "strexh %[res],%[val],[%[mem]]\n\t" + "cbz %[res],3f\n\t" + "b 1b\n" + "3:" + : [ret] "=&l" (ret), + [val] "=&l" (val), + [res] "=&l" (res) + : [mem] "l" (mem), + [lim] "l" (lim) + : "cc", "memory" + ); + + return ret; +} +#endif + +/// Atomic Access Operation: Decrement (32-bit) if Not Zero +/// \param[in] mem Memory address +/// \return Previous value +#if defined(__CC_ARM) +static __asm uint32_t atomic_dec32_nz (uint32_t *mem) { + mov r2,r0 +1 + ldrex r0,[r2] + cbnz r0,%F2 + clrex + bx lr +2 + subs r1,r0,#1 + strex r3,r1,[r2] + cbz r3,%F3 + b %B1 +3 + bx lr +} +#else +__STATIC_INLINE uint32_t atomic_dec32_nz (uint32_t *mem) { +#ifdef __ICCARM__ +#pragma diag_suppress=Pe550 +#endif + register uint32_t val, res; +#ifdef __ICCARM__ +#pragma diag_default=Pe550 +#endif + register uint32_t ret; + + __ASM volatile ( +#ifndef __ICCARM__ + ".syntax unified\n\t" +#endif + "1:\n\t" + "ldrex %[ret],[%[mem]]\n\t" + "cbnz %[ret],2f\n\t" + "clrex\n\t" + "b 3f\n" + "2:\n\t" + "subs %[val],%[ret],#1\n\t" + "strex %[res],%[val],[%[mem]]\n\t" + "cbz %[res],3f\n\t" + "b 1b\n" + "3:" + : [ret] "=&l" (ret), + [val] "=&l" (val), + [res] "=&l" (res) + : [mem] "l" (mem) + : "cc", "memory" + ); + + return ret; +} +#endif + +/// Atomic Access Operation: Decrement (16-bit) if Not Zero +/// \param[in] mem Memory address +/// \return Previous value +#if defined(__CC_ARM) +static __asm uint16_t atomic_dec16_nz (uint16_t *mem) { + mov r2,r0 +1 + ldrexh r0,[r2] + cbnz r0,%F2 + clrex + bx lr +2 + subs r1,r0,#1 + strexh r3,r1,[r2] + cbz r3,%F3 + b %B1 +3 + bx lr +} +#else +__STATIC_INLINE uint16_t atomic_dec16_nz (uint16_t *mem) { +#ifdef __ICCARM__ +#pragma diag_suppress=Pe550 +#endif + register uint32_t val, res; +#ifdef __ICCARM__ +#pragma diag_default=Pe550 +#endif + register uint16_t ret; + + __ASM volatile ( +#ifndef __ICCARM__ + ".syntax unified\n\t" +#endif + "1:\n\t" + "ldrexh %[ret],[%[mem]]\n\t" + "cbnz %[ret],2f\n\t" + "clrex\n\t" + "b 3f\n" + "2:\n\t" + "subs %[val],%[ret],#1\n\t" + "strexh %[res],%[val],[%[mem]]\n\t" + "cbz %[res],3f\n\t" + "b 1b\n" + "3:" + : [ret] "=&l" (ret), + [val] "=&l" (val), + [res] "=&l" (res) + : [mem] "l" (mem) + : "cc", "memory" + ); + + return ret; +} +#endif + +/// Atomic Access Operation: Link Get +/// \param[in] root Root address +/// \return Link +#if defined(__CC_ARM) +static __asm void *atomic_link_get (void **root) { + mov r2,r0 +1 + ldrex r0,[r2] + cbnz r0,%F2 + clrex + bx lr +2 + ldr r1,[r0] + strex r3,r1,[r2] + cbz r3,%F3 + b %B1 +3 + bx lr +} +#else +__STATIC_INLINE void *atomic_link_get (void **root) { +#ifdef __ICCARM__ +#pragma diag_suppress=Pe550 +#endif + register uint32_t val, res; +#ifdef __ICCARM__ +#pragma diag_default=Pe550 +#endif + register void *ret; + + __ASM volatile ( +#ifndef __ICCARM__ + ".syntax unified\n\t" +#endif + "1:\n\t" + "ldrex %[ret],[%[root]]\n\t" + "cbnz %[ret],2f\n\t" + "clrex\n\t" + "b 3f\n" + "2:\n\t" + "ldr %[val],[%[ret]]\n\t" + "strex %[res],%[val],[%[root]]\n\t" + "cbz %[res],3f\n\t" + "b 1b\n" + "3:" + : [ret] "=&l" (ret), + [val] "=&l" (val), + [res] "=&l" (res) + : [root] "l" (root) + : "cc", "memory" + ); + + return ret; +} +#endif + +/// Atomic Access Operation: Link Put +/// \param[in] root Root address +/// \param[in] lnk Link +#if defined(__CC_ARM) +static __asm void atomic_link_put (void **root, void *link) { +1 + ldr r2,[r0] + str r2,[r1] + dmb + ldrex r2,[r0] + ldr r3,[r1] + cmp r3,r2 + bne %B1 + strex r3,r1,[r0] + cbz r3,%F2 + b %B1 +2 + bx lr +} +#else +__STATIC_INLINE void atomic_link_put (void **root, void *link) { +#ifdef __ICCARM__ +#pragma diag_suppress=Pe550 +#endif + register uint32_t val1, val2, res; +#ifdef __ICCARM__ +#pragma diag_default=Pe550 +#endif + + __ASM volatile ( +#ifndef __ICCARM__ + ".syntax unified\n\t" +#endif + "1:\n\t" + "ldr %[val1],[%[root]]\n\t" + "str %[val1],[%[link]]\n\t" + "dmb\n\t" + "ldrex %[val1],[%[root]]\n\t" + "ldr %[val2],[%[link]]\n\t" + "cmp %[val2],%[val1]\n\t" + "bne 1b\n\t" + "strex %[res],%[link],[%[root]]\n\t" + "cbz %[res],2f\n\t" + "b 1b\n" + "2:" + : [val1] "=&l" (val1), + [val2] "=&l" (val2), + [res] "=&l" (res) + : [root] "l" (root), + [link] "l" (link) + : "cc", "memory" + ); +} +#endif + +#endif // (__EXCLUSIVE_ACCESS == 1U) + + +#endif // CORE_CM_H_ diff --git a/rtos/rtx2/TARGET_CORTEX_M/rtx_delay.c b/rtos/rtx2/TARGET_CORTEX_M/rtx_delay.c new file mode 100644 index 00000000000..a7e71b7777b --- /dev/null +++ b/rtos/rtx2/TARGET_CORTEX_M/rtx_delay.c @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2013-2017 ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ----------------------------------------------------------------------------- + * + * Project: CMSIS-RTOS RTX + * Title: Delay functions + * + * ----------------------------------------------------------------------------- + */ + +#include "rtx_lib.h" + + +// ==== Service Calls ==== + +// Service Calls definitions +SVC0_1(Delay, osStatus_t, uint32_t) +SVC0_2(DelayUntil, osStatus_t, uint32_t, uint32_t) + +/// Wait for Timeout (Time Delay). +/// \note API identical to osDelay +osStatus_t svcRtxDelay (uint32_t ticks) { + + if (ticks == 0U) { + return osOK; + } + + osRtxThreadWaitEnter(osRtxThreadWaitingDelay, ticks); + + return osOK; +} + +/// Wait until specified time. +/// \note API identical to osDelayUntil +osStatus_t svcRtxDelayUntil (uint32_t ticks_l, uint32_t ticks_h) { + uint64_t ticks = ((uint64_t)ticks_l) | ((uint64_t)ticks_h << 32); + + ticks -= osRtxInfo.kernel.tick; + if (ticks >= 0xFFFFFFFFU) { + EvrRtxThreadError(NULL, osErrorParameter); + return osErrorParameter; + } + if (ticks == 0U) { + return osOK; + } + + osRtxThreadWaitEnter(osRtxThreadWaitingDelay, (uint32_t)ticks); + + return osOK; +} + + +// ==== Public API ==== + +/// Wait for Timeout (Time Delay). +osStatus_t osDelay (uint32_t ticks) { + EvrRtxThreadDelay(ticks); + if (IS_IRQ_MODE() || IS_IRQ_MASKED()) { + EvrRtxThreadError(NULL, osErrorISR); + return osErrorISR; + } + return __svcDelay(ticks); +} + +/// Wait until specified time. +osStatus_t osDelayUntil (uint64_t ticks) { + EvrRtxThreadDelayUntil(ticks); + if (IS_IRQ_MODE() || IS_IRQ_MASKED()) { + EvrRtxThreadError(NULL, osErrorISR); + return osErrorISR; + } + return __svcDelayUntil((uint32_t)ticks, (uint32_t)(ticks >> 32)); +} diff --git a/rtos/rtx2/TARGET_CORTEX_M/rtx_evflags.c b/rtos/rtx2/TARGET_CORTEX_M/rtx_evflags.c new file mode 100644 index 00000000000..1c534d5ca3a --- /dev/null +++ b/rtos/rtx2/TARGET_CORTEX_M/rtx_evflags.c @@ -0,0 +1,576 @@ +/* + * Copyright (c) 2013-2017 ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ----------------------------------------------------------------------------- + * + * Project: CMSIS-RTOS RTX + * Title: Event Flags functions + * + * ----------------------------------------------------------------------------- + */ + +#include "rtx_lib.h" + + +// ==== Helper functions ==== + +/// Set Event Flags. +/// \param[in] ef event flags object. +/// \param[in] flags specifies the flags to set. +/// \return event flags after setting. +static uint32_t EventFlagsSet (os_event_flags_t *ef, uint32_t flags) { +#if (__EXCLUSIVE_ACCESS == 0U) + uint32_t primask = __get_PRIMASK(); +#endif + uint32_t event_flags; + +#if (__EXCLUSIVE_ACCESS == 0U) + __disable_irq(); + + ef->event_flags |= flags; + event_flags = ef->event_flags; + + if (primask == 0U) { + __enable_irq(); + } +#else + event_flags = atomic_set32(&ef->event_flags, flags); +#endif + + return event_flags; +} + +/// Clear Event Flags. +/// \param[in] ef event flags object. +/// \param[in] flags specifies the flags to clear. +/// \return event flags before clearing. +static uint32_t EventFlagsClear (os_event_flags_t *ef, uint32_t flags) { +#if (__EXCLUSIVE_ACCESS == 0U) + uint32_t primask = __get_PRIMASK(); +#endif + uint32_t event_flags; + +#if (__EXCLUSIVE_ACCESS == 0U) + __disable_irq(); + + event_flags = ef->event_flags; + ef->event_flags &= ~flags; + + if (primask == 0U) { + __enable_irq(); + } +#else + event_flags = atomic_clr32(&ef->event_flags, flags); +#endif + + return event_flags; +} + +/// Check Event Flags. +/// \param[in] ef event flags object. +/// \param[in] flags specifies the flags to check. +/// \param[in] options specifies flags options (osFlagsXxxx). +/// \return event flags before clearing or 0 if specified flags have not been set. +static uint32_t EventFlagsCheck (os_event_flags_t *ef, uint32_t flags, uint32_t options) { +#if (__EXCLUSIVE_ACCESS == 0U) + uint32_t primask; +#endif + uint32_t event_flags; + + if ((options & osFlagsNoClear) == 0U) { +#if (__EXCLUSIVE_ACCESS == 0U) + primask = __get_PRIMASK(); + __disable_irq(); + + event_flags = ef->event_flags; + if ((((options & osFlagsWaitAll) != 0U) && ((event_flags & flags) != flags)) || + (((options & osFlagsWaitAll) == 0U) && ((event_flags & flags) == 0U))) { + event_flags = 0U; + } else { + ef->event_flags &= ~flags; + } + + if (primask == 0U) { + __enable_irq(); + } +#else + if ((options & osFlagsWaitAll) != 0U) { + event_flags = atomic_chk32_all(&ef->event_flags, flags); + } else { + event_flags = atomic_chk32_any(&ef->event_flags, flags); + } +#endif + } else { + event_flags = ef->event_flags; + if ((((options & osFlagsWaitAll) != 0U) && ((event_flags & flags) != flags)) || + (((options & osFlagsWaitAll) == 0U) && ((event_flags & flags) == 0U))) { + event_flags = 0U; + } + } + + return event_flags; +} + + +// ==== Library functions ==== + +/// Event Flags post ISR processing. +/// \param[in] ef event flags object. +void osRtxEventFlagsPostProcess (os_event_flags_t *ef) { + os_thread_t *thread; + os_thread_t *thread_next; + uint32_t event_flags; + + if (ef->state == osRtxObjectInactive) { + return; + } + + // Check if Threads are waiting for Event Flags + thread = ef->thread_list; + while (thread != NULL) { + thread_next = thread->thread_next; + event_flags = EventFlagsCheck(ef, thread->wait_flags, thread->flags_options); + if (event_flags != 0U) { + osRtxThreadListRemove(thread); + osRtxThreadWaitExit(thread, event_flags, false); + EvrRtxEventFlagsWaitCompleted(ef, thread->wait_flags, thread->flags_options, event_flags); + } + thread = thread_next; + } +} + + +// ==== Service Calls ==== + +// Service Calls definitions +SVC0_1M(EventFlagsNew, osEventFlagsId_t, const osEventFlagsAttr_t *) +SVC0_1 (EventFlagsGetName, const char *, osEventFlagsId_t) +SVC0_2 (EventFlagsSet, uint32_t, osEventFlagsId_t, uint32_t) +SVC0_2 (EventFlagsClear, uint32_t, osEventFlagsId_t, uint32_t) +SVC0_1 (EventFlagsGet, uint32_t, osEventFlagsId_t) +SVC0_4 (EventFlagsWait, uint32_t, osEventFlagsId_t, uint32_t, uint32_t, uint32_t) +SVC0_1 (EventFlagsDelete, osStatus_t, osEventFlagsId_t) + +/// Create and Initialize an Event Flags object. +/// \note API identical to osEventFlagsNew +osEventFlagsId_t svcRtxEventFlagsNew (const osEventFlagsAttr_t *attr) { + os_event_flags_t *ef; + uint8_t flags; + const char *name; + + // Process attributes + if (attr != NULL) { + name = attr->name; + ef = attr->cb_mem; + if (ef != NULL) { + if (((uint32_t)ef & 3U) || (attr->cb_size < sizeof(os_event_flags_t))) { + EvrRtxEventFlagsError(NULL, osRtxErrorInvalidControlBlock); + return NULL; + } + } else { + if (attr->cb_size != 0U) { + EvrRtxEventFlagsError(NULL, osRtxErrorInvalidControlBlock); + return NULL; + } + } + } else { + name = NULL; + ef = NULL; + } + + // Allocate object memory if not provided + if (ef == NULL) { + if (osRtxInfo.mpi.event_flags != NULL) { + ef = osRtxMemoryPoolAlloc(osRtxInfo.mpi.event_flags); + } else { + ef = osRtxMemoryAlloc(osRtxInfo.mem.common, sizeof(os_event_flags_t), 1U); + } + if (ef == NULL) { + EvrRtxEventFlagsError(NULL, osErrorNoMemory); + return NULL; + } + flags = osRtxFlagSystemObject; + } else { + flags = 0U; + } + + // Initialize control block + ef->id = osRtxIdEventFlags; + ef->state = osRtxObjectActive; + ef->flags = flags; + ef->name = name; + ef->thread_list = NULL; + ef->event_flags = 0U; + + // Register post ISR processing function + osRtxInfo.post_process.event_flags = osRtxEventFlagsPostProcess; + + EvrRtxEventFlagsCreated(ef); + + return ef; +} + +/// Get name of an Event Flags object. +/// \note API identical to osEventFlagsGetName +const char *svcRtxEventFlagsGetName (osEventFlagsId_t ef_id) { + os_event_flags_t *ef = (os_event_flags_t *)ef_id; + + // Check parameters + if ((ef == NULL) || (ef->id != osRtxIdEventFlags)) { + EvrRtxEventFlagsGetName(ef, NULL); + return NULL; + } + + // Check object state + if (ef->state == osRtxObjectInactive) { + EvrRtxEventFlagsGetName(ef, NULL); + return NULL; + } + + EvrRtxEventFlagsGetName(ef, ef->name); + + return ef->name; +} + +/// Set the specified Event Flags. +/// \note API identical to osEventFlagsSet +uint32_t svcRtxEventFlagsSet (osEventFlagsId_t ef_id, uint32_t flags) { + os_event_flags_t *ef = (os_event_flags_t *)ef_id; + os_thread_t *thread; + os_thread_t *thread_next; + uint32_t event_flags; + uint32_t event_flags0; + + // Check parameters + if ((ef == NULL) || (ef->id != osRtxIdEventFlags) || + (flags & ~((1U << osRtxEventFlagsLimit) - 1U))) { + EvrRtxEventFlagsError(ef, osErrorParameter); + return ((uint32_t)osErrorParameter); + } + + // Check object state + if (ef->state == osRtxObjectInactive) { + EvrRtxEventFlagsError(ef, osErrorResource); + return ((uint32_t)osErrorResource); + } + + // Set Event Flags + event_flags = EventFlagsSet(ef, flags); + + // Check if Threads are waiting for Event Flags + thread = ef->thread_list; + while (thread != NULL) { + thread_next = thread->thread_next; + event_flags0 = EventFlagsCheck(ef, thread->wait_flags, thread->flags_options); + if (event_flags0 != 0U) { + if ((thread->flags_options & osFlagsNoClear) == 0U) { + event_flags = event_flags0 & ~thread->wait_flags; + } else { + event_flags = event_flags0; + } + osRtxThreadListRemove(thread); + osRtxThreadWaitExit(thread, event_flags0, false); + EvrRtxEventFlagsWaitCompleted(ef, thread->wait_flags, thread->flags_options, event_flags0); + } + thread = thread_next; + } + osRtxThreadDispatch(NULL); + + EvrRtxEventFlagsSetDone(ef, event_flags); + + return event_flags; +} + +/// Clear the specified Event Flags. +/// \note API identical to osEventFlagsClear +uint32_t svcRtxEventFlagsClear (osEventFlagsId_t ef_id, uint32_t flags) { + os_event_flags_t *ef = (os_event_flags_t *)ef_id; + uint32_t event_flags; + + // Check parameters + if ((ef == NULL) || (ef->id != osRtxIdEventFlags) || + (flags & ~((1U << osRtxEventFlagsLimit) - 1U))) { + EvrRtxEventFlagsError(ef, osErrorParameter); + return ((uint32_t)osErrorParameter); + } + + // Check object state + if (ef->state == osRtxObjectInactive) { + EvrRtxEventFlagsError(ef, osErrorResource); + return ((uint32_t)osErrorResource); + } + + // Clear Event Flags + event_flags = EventFlagsClear(ef, flags); + + EvrRtxEventFlagsClearDone(ef, event_flags); + + return event_flags; +} + +/// Get the current Event Flags. +/// \note API identical to osEventFlagsGet +uint32_t svcRtxEventFlagsGet (osEventFlagsId_t ef_id) { + os_event_flags_t *ef = (os_event_flags_t *)ef_id; + + // Check parameters + if ((ef == NULL) || (ef->id != osRtxIdEventFlags)) { + EvrRtxEventFlagsGet(ef, 0U); + return 0U; + } + + // Check object state + if (ef->state == osRtxObjectInactive) { + EvrRtxEventFlagsGet(ef, 0U); + return 0U; + } + + EvrRtxEventFlagsGet(ef, ef->event_flags); + + return ef->event_flags; +} + +/// Wait for one or more Event Flags to become signaled. +/// \note API identical to osEventFlagsWait +uint32_t svcRtxEventFlagsWait (osEventFlagsId_t ef_id, uint32_t flags, uint32_t options, uint32_t timeout) { + os_event_flags_t *ef = (os_event_flags_t *)ef_id; + os_thread_t *running_thread; + uint32_t event_flags; + + running_thread = osRtxThreadGetRunning(); + if (running_thread == NULL) { + EvrRtxEventFlagsError(ef, osRtxErrorKernelNotRunning); + return ((uint32_t)osError); + } + + // Check parameters + if ((ef == NULL) || (ef->id != osRtxIdEventFlags) || + (flags & ~((1U << osRtxEventFlagsLimit) - 1U))) { + EvrRtxEventFlagsError(ef, osErrorParameter); + return ((uint32_t)osErrorParameter); + } + + // Check object state + if (ef->state == osRtxObjectInactive) { + EvrRtxEventFlagsError(ef, osErrorResource); + return ((uint32_t)osErrorResource); + } + + // Check Event Flags + event_flags = EventFlagsCheck(ef, flags, options); + if (event_flags != 0U) { + EvrRtxEventFlagsWaitCompleted(ef, flags, options, event_flags); + return event_flags; + } + + // Check if timeout is specified + if (timeout != 0U) { + EvrRtxEventFlagsWaitPending(ef, flags, options, timeout); + // Store waiting flags and options + running_thread->wait_flags = flags; + running_thread->flags_options = (uint8_t)options; + // Suspend current Thread + osRtxThreadListPut((os_object_t*)ef, running_thread); + osRtxThreadWaitEnter(osRtxThreadWaitingEventFlags, timeout); + return ((uint32_t)osErrorTimeout); + } + + EvrRtxEventFlagsWaitNotCompleted(ef, flags, options); + + return ((uint32_t)osErrorResource); +} + +/// Delete an Event Flags object. +/// \note API identical to osEventFlagsDelete +osStatus_t svcRtxEventFlagsDelete (osEventFlagsId_t ef_id) { + os_event_flags_t *ef = (os_event_flags_t *)ef_id; + os_thread_t *thread; + + // Check parameters + if ((ef == NULL) || (ef->id != osRtxIdEventFlags)) { + EvrRtxEventFlagsError(ef, osErrorParameter); + return osErrorParameter; + } + + // Check object state + if (ef->state == osRtxObjectInactive) { + EvrRtxEventFlagsError(ef, osErrorResource); + return osErrorResource; + } + + // Mark object as inactive + ef->state = osRtxObjectInactive; + + // Unblock waiting threads + if (ef->thread_list != NULL) { + do { + thread = osRtxThreadListGet((os_object_t*)ef); + osRtxThreadWaitExit(thread, (uint32_t)osErrorResource, false); + } while (ef->thread_list != NULL); + osRtxThreadDispatch(NULL); + } + + // Free object memory + if (ef->flags & osRtxFlagSystemObject) { + if (osRtxInfo.mpi.event_flags != NULL) { + osRtxMemoryPoolFree(osRtxInfo.mpi.event_flags, ef); + } else { + osRtxMemoryFree(osRtxInfo.mem.common, ef); + } + } + + EvrRtxEventFlagsDestroyed(ef); + + return osOK; +} + + +// ==== ISR Calls ==== + +/// Set the specified Event Flags. +/// \note API identical to osEventFlagsSet +__STATIC_INLINE +uint32_t isrRtxEventFlagsSet (osEventFlagsId_t ef_id, uint32_t flags) { + os_event_flags_t *ef = (os_event_flags_t *)ef_id; + uint32_t event_flags; + + // Check parameters + if ((ef == NULL) || (ef->id != osRtxIdEventFlags) || + (flags & ~((1U << osRtxEventFlagsLimit) - 1U))) { + EvrRtxEventFlagsError(ef, osErrorParameter); + return ((uint32_t)osErrorParameter); + } + + // Check object state + if (ef->state == osRtxObjectInactive) { + EvrRtxEventFlagsError(ef, osErrorResource); + return ((uint32_t)osErrorResource); + } + + // Set Event Flags + event_flags = EventFlagsSet(ef, flags); + + // Register post ISR processing + osRtxPostProcess((os_object_t *)ef); + + EvrRtxEventFlagsSetDone(ef, event_flags); + + return event_flags; +} + +/// Wait for one or more Event Flags to become signaled. +/// \note API identical to osEventFlagsWait +__STATIC_INLINE +uint32_t isrRtxEventFlagsWait (osEventFlagsId_t ef_id, uint32_t flags, uint32_t options, uint32_t timeout) { + os_event_flags_t *ef = (os_event_flags_t *)ef_id; + uint32_t event_flags; + + // Check parameters + if ((ef == NULL) || (ef->id != osRtxIdEventFlags) || (timeout != 0U) || + (flags & ~((1U << osRtxEventFlagsLimit) - 1U))) { + EvrRtxEventFlagsError(ef, osErrorParameter); + return ((uint32_t)osErrorParameter); + } + + // Check object state + if (ef->state == osRtxObjectInactive) { + EvrRtxEventFlagsError(ef, osErrorResource); + return ((uint32_t)osErrorResource); + } + + // Check Event Flags + event_flags = EventFlagsCheck(ef, flags, options); + if (event_flags != 0U) { + EvrRtxEventFlagsWaitCompleted(ef, flags, options, event_flags); + return ((uint32_t)event_flags); + } + + EvrRtxEventFlagsWaitNotCompleted(ef, flags, options); + + return ((uint32_t)osErrorResource); +} + + +// ==== Public API ==== + +/// Create and Initialize an Event Flags object. +osEventFlagsId_t osEventFlagsNew (const osEventFlagsAttr_t *attr) { + EvrRtxEventFlagsNew(attr); + if (IS_IRQ_MODE() || IS_IRQ_MASKED()) { + EvrRtxEventFlagsError(NULL, osErrorISR); + return NULL; + } + return __svcEventFlagsNew(attr); +} + +/// Get name of an Event Flags object. +const char *osEventFlagsGetName (osEventFlagsId_t ef_id) { + if (IS_IRQ_MODE() || IS_IRQ_MASKED()) { + EvrRtxEventFlagsGetName(ef_id, NULL); + return NULL; + } + return __svcEventFlagsGetName(ef_id); +} + +/// Set the specified Event Flags. +uint32_t osEventFlagsSet (osEventFlagsId_t ef_id, uint32_t flags) { + EvrRtxEventFlagsSet(ef_id, flags); + if (IS_IRQ_MODE() || IS_IRQ_MASKED()) { + return isrRtxEventFlagsSet(ef_id, flags); + } else { + return __svcEventFlagsSet(ef_id, flags); + } +} + +/// Clear the specified Event Flags. +uint32_t osEventFlagsClear (osEventFlagsId_t ef_id, uint32_t flags) { + EvrRtxEventFlagsClear(ef_id, flags); + if (IS_IRQ_MODE() || IS_IRQ_MASKED()) { + return svcRtxEventFlagsClear(ef_id, flags); + } else { + return __svcEventFlagsClear(ef_id, flags); + } +} + +/// Get the current Event Flags. +uint32_t osEventFlagsGet (osEventFlagsId_t ef_id) { + if (IS_IRQ_MODE() || IS_IRQ_MASKED()) { + return svcRtxEventFlagsGet(ef_id); + } else { + return __svcEventFlagsGet(ef_id); + } +} + +/// Wait for one or more Event Flags to become signaled. +uint32_t osEventFlagsWait (osEventFlagsId_t ef_id, uint32_t flags, uint32_t options, uint32_t timeout) { + EvrRtxEventFlagsWait(ef_id, flags, options, timeout); + if (IS_IRQ_MODE() || IS_IRQ_MASKED()) { + return isrRtxEventFlagsWait(ef_id, flags, options, timeout); + } else { + return __svcEventFlagsWait(ef_id, flags, options, timeout); + } +} + +/// Delete an Event Flags object. +osStatus_t osEventFlagsDelete (osEventFlagsId_t ef_id) { + EvrRtxEventFlagsDelete(ef_id); + if (IS_IRQ_MODE() || IS_IRQ_MASKED()) { + EvrRtxEventFlagsError(ef_id, osErrorISR); + return osErrorISR; + } + return __svcEventFlagsDelete(ef_id); +} diff --git a/rtos/rtx2/TARGET_CORTEX_M/rtx_evr.c b/rtos/rtx2/TARGET_CORTEX_M/rtx_evr.c new file mode 100644 index 00000000000..8785e26cec2 --- /dev/null +++ b/rtos/rtx2/TARGET_CORTEX_M/rtx_evr.c @@ -0,0 +1,2079 @@ +/* + * Copyright (c) 2013-2017 ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ----------------------------------------------------------------------------- + * + * Project: CMSIS-RTOS RTX + * Title: RTX Event Recorder + * + * ----------------------------------------------------------------------------- + */ + +#include +#include "cmsis_compiler.h" +#include "rtx_evr.h" // RTX Event Recorder definitions + +#include "RTE_Components.h" + +#ifdef RTE_Compiler_EventRecorder + +#include "EventRecorder.h" // Keil::Compiler:Event Recorder + +/// RTOS component number +#define EvtRtxMemoryNo (0xF0U) +#define EvtRtxKernelNo (0xF1U) +#define EvtRtxThreadNo (0xF2U) +#define EvtRtxTimerNo (0xF3U) +#define EvtRtxEventFlagsNo (0xF4U) +#define EvtRtxMutexNo (0xF5U) +#define EvtRtxSemaphoreNo (0xF6U) +#define EvtRtxMemoryPoolNo (0xF7U) +#define EvtRtxMessageQueueNo (0xF8U) + +/// Event IDs for "RTX Memory Management" +#define EvtRtxMemoryInit EventID(EventLevelOp, EvtRtxMemoryNo, 0x00U) +#define EvtRtxMemoryAlloc EventID(EventLevelOp, EvtRtxMemoryNo, 0x01U) +#define EvtRtxMemoryFree EventID(EventLevelOp, EvtRtxMemoryNo, 0x02U) +#define EvtRtxMemoryBlockInit EventID(EventLevelOp, EvtRtxMemoryNo, 0x03U) +#define EvtRtxMemoryBlockAlloc EventID(EventLevelOp, EvtRtxMemoryNo, 0x04U) +#define EvtRtxMemoryBlockFree EventID(EventLevelOp, EvtRtxMemoryNo, 0x05U) + +/// Event IDs for "RTX Kernel" +#define EvtRtxKernelError EventID(EventLevelError, EvtRtxKernelNo, 0x00U) +#define EvtRtxKernelInitialize EventID(EventLevelAPI, EvtRtxKernelNo, 0x01U) +#define EvtRtxKernelInitializeCompleted EventID(EventLevelOp, EvtRtxKernelNo, 0x02U) +#define EvtRtxKernelGetInfo EventID(EventLevelAPI, EvtRtxKernelNo, 0x03U) +#define EvtRtxKernelInfoRetrieved EventID(EventLevelOp, EvtRtxKernelNo, 0x04U) +#define EvtRtxKernelInfoRetrieved_Detail EventID(EventLevelDetail, EvtRtxKernelNo, 0x05U) +#define EvtRtxKernelGetState EventID(EventLevelAPI, EvtRtxKernelNo, 0x06U) +#define EvtRtxKernelStart EventID(EventLevelAPI, EvtRtxKernelNo, 0x07U) +#define EvtRtxKernelStarted EventID(EventLevelOp, EvtRtxKernelNo, 0x08U) +#define EvtRtxKernelLock EventID(EventLevelAPI, EvtRtxKernelNo, 0x09U) +#define EvtRtxKernelLocked EventID(EventLevelOp, EvtRtxKernelNo, 0x0AU) +#define EvtRtxKernelUnlock EventID(EventLevelAPI, EvtRtxKernelNo, 0x0BU) +#define EvtRtxKernelUnlocked EventID(EventLevelOp, EvtRtxKernelNo, 0x0CU) +#define EvtRtxKernelRestoreLock EventID(EventLevelAPI, EvtRtxKernelNo, 0x0DU) +#define EvtRtxKernelLockRestored EventID(EventLevelOp, EvtRtxKernelNo, 0x0EU) +#define EvtRtxKernelSuspend EventID(EventLevelAPI, EvtRtxKernelNo, 0x0FU) +#define EvtRtxKernelSuspended EventID(EventLevelOp, EvtRtxKernelNo, 0x10U) +#define EvtRtxKernelResume EventID(EventLevelAPI, EvtRtxKernelNo, 0x11U) +#define EvtRtxKernelResumed EventID(EventLevelOp, EvtRtxKernelNo, 0x12U) +#define EvtRtxKernelGetTickCount EventID(EventLevelAPI, EvtRtxKernelNo, 0x13U) +#define EvtRtxKernelGetTickFreq EventID(EventLevelAPI, EvtRtxKernelNo, 0x14U) +#define EvtRtxKernelGetSysTimerCount EventID(EventLevelAPI, EvtRtxKernelNo, 0x15U) +#define EvtRtxKernelGetSysTimerFreq EventID(EventLevelAPI, EvtRtxKernelNo, 0x16U) + +/// Event IDs for "RTX Thread" +#define EvtRtxThreadError EventID(EventLevelError, EvtRtxThreadNo, 0x00U) +#define EvtRtxThreadNew EventID(EventLevelAPI, EvtRtxThreadNo, 0x01U) +#define EvtRtxThreadNew_Detail EventID(EventLevelDetail, EvtRtxThreadNo, 0x02U) +#define EvtRtxThreadCreated EventID(EventLevelOp, EvtRtxThreadNo, 0x03U) +#define EvtRtxThreadGetName EventID(EventLevelAPI, EvtRtxThreadNo, 0x04U) +#define EvtRtxThreadGetName_Detail EventID(EventLevelDetail, EvtRtxThreadNo, 0x05U) +#define EvtRtxThreadGetId EventID(EventLevelAPI, EvtRtxThreadNo, 0x06U) +#define EvtRtxThreadGetState EventID(EventLevelAPI, EvtRtxThreadNo, 0x07U) +#define EvtRtxThreadGetStackSize EventID(EventLevelAPI, EvtRtxThreadNo, 0x08U) +#define EvtRtxThreadGetStackSpace EventID(EventLevelAPI, EvtRtxThreadNo, 0x09U) +#define EvtRtxThreadSetPriority EventID(EventLevelAPI, EvtRtxThreadNo, 0x0AU) +#define EvtRtxThreadGetPriority EventID(EventLevelAPI, EvtRtxThreadNo, 0x0BU) +#define EvtRtxThreadYield EventID(EventLevelAPI, EvtRtxThreadNo, 0x0CU) +#define EvtRtxThreadSuspend EventID(EventLevelAPI, EvtRtxThreadNo, 0x0DU) +#define EvtRtxThreadSuspended EventID(EventLevelOp, EvtRtxThreadNo, 0x0EU) +#define EvtRtxThreadResume EventID(EventLevelAPI, EvtRtxThreadNo, 0x0FU) +#define EvtRtxThreadResumed EventID(EventLevelOp, EvtRtxThreadNo, 0x10U) +#define EvtRtxThreadDetach EventID(EventLevelAPI, EvtRtxThreadNo, 0x11U) +#define EvtRtxThreadDetached EventID(EventLevelOp, EvtRtxThreadNo, 0x12U) +#define EvtRtxThreadJoin EventID(EventLevelAPI, EvtRtxThreadNo, 0x13U) +#define EvtRtxThreadJoinPending EventID(EventLevelOp, EvtRtxThreadNo, 0x14U) +#define EvtRtxThreadJoined EventID(EventLevelOp, EvtRtxThreadNo, 0x15U) +#define EvtRtxThreadBlocked EventID(EventLevelOp, EvtRtxThreadNo, 0x16U) +#define EvtRtxThreadUnblocked EventID(EventLevelOp, EvtRtxThreadNo, 0x17U) +#define EvtRtxThreadSwitch EventID(EventLevelOp, EvtRtxThreadNo, 0x18U) +#define EvtRtxThreadExit EventID(EventLevelAPI, EvtRtxThreadNo, 0x19U) +#define EvtRtxThreadTerminate EventID(EventLevelAPI, EvtRtxThreadNo, 0x1AU) +#define EvtRtxThreadDestroyed EventID(EventLevelOp, EvtRtxThreadNo, 0x1BU) +#define EvtRtxThreadGetCount EventID(EventLevelAPI, EvtRtxThreadNo, 0x1CU) +#define EvtRtxThreadEnumerate EventID(EventLevelAPI, EvtRtxThreadNo, 0x1DU) +#define EvtRtxThreadFlagsSet EventID(EventLevelAPI, EvtRtxThreadNo, 0x1EU) +#define EvtRtxThreadFlagsSetDone EventID(EventLevelOp, EvtRtxThreadNo, 0x1FU) +#define EvtRtxThreadFlagsClear EventID(EventLevelAPI, EvtRtxThreadNo, 0x20U) +#define EvtRtxThreadFlagsClearDone EventID(EventLevelOp, EvtRtxThreadNo, 0x21U) +#define EvtRtxThreadFlagsGet EventID(EventLevelAPI, EvtRtxThreadNo, 0x22U) +#define EvtRtxThreadFlagsWait EventID(EventLevelAPI, EvtRtxThreadNo, 0x23U) +#define EvtRtxThreadFlagsWaitPending EventID(EventLevelOp, EvtRtxThreadNo, 0x24U) +#define EvtRtxThreadFlagsWaitTimeout EventID(EventLevelOp, EvtRtxThreadNo, 0x25U) +#define EvtRtxThreadFlagsWaitCompleted EventID(EventLevelOp, EvtRtxThreadNo, 0x26U) +#define EvtRtxThreadFlagsWaitNotCompleted EventID(EventLevelOp, EvtRtxThreadNo, 0x27U) +#define EvtRtxThreadDelay EventID(EventLevelAPI, EvtRtxThreadNo, 0x28U) +#define EvtRtxThreadDelayUntil EventID(EventLevelAPI, EvtRtxThreadNo, 0x29U) +#define EvtRtxThreadDelayCompleted EventID(EventLevelOp, EvtRtxThreadNo, 0x2AU) + +/// Event IDs for "RTX Timer" +#define EvtRtxTimerError EventID(EventLevelError, EvtRtxTimerNo, 0x00U) +#define EvtRtxTimerCallback EventID(EventLevelOp, EvtRtxTimerNo, 0x01U) +#define EvtRtxTimerNew EventID(EventLevelAPI, EvtRtxTimerNo, 0x02U) +#define EvtRtxTimerNew_Detail EventID(EventLevelDetail, EvtRtxTimerNo, 0x03U) +#define EvtRtxTimerCreated EventID(EventLevelOp, EvtRtxTimerNo, 0x04U) +#define EvtRtxTimerGetName EventID(EventLevelAPI, EvtRtxTimerNo, 0x05U) +#define EvtRtxTimerGetName_Detail EventID(EventLevelDetail, EvtRtxTimerNo, 0x06U) +#define EvtRtxTimerStart EventID(EventLevelAPI, EvtRtxTimerNo, 0x07U) +#define EvtRtxTimerStarted EventID(EventLevelOp, EvtRtxTimerNo, 0x08U) +#define EvtRtxTimerStop EventID(EventLevelAPI, EvtRtxTimerNo, 0x09U) +#define EvtRtxTimerStopped EventID(EventLevelOp, EvtRtxTimerNo, 0x0AU) +#define EvtRtxTimerIsRunning EventID(EventLevelAPI, EvtRtxTimerNo, 0x0BU) +#define EvtRtxTimerDelete EventID(EventLevelAPI, EvtRtxTimerNo, 0x0CU) +#define EvtRtxTimerDestroyed EventID(EventLevelOp, EvtRtxTimerNo, 0x0DU) + +/// Event IDs for "RTX Event Flags" +#define EvtRtxEventFlagsError EventID(EventLevelError, EvtRtxEventFlagsNo, 0x00U) +#define EvtRtxEventFlagsNew EventID(EventLevelAPI, EvtRtxEventFlagsNo, 0x01U) +#define EvtRtxEventFlagsNew_Detail EventID(EventLevelDetail, EvtRtxEventFlagsNo, 0x02U) +#define EvtRtxEventFlagsCreated EventID(EventLevelOp, EvtRtxEventFlagsNo, 0x03U) +#define EvtRtxEventFlagsGetName EventID(EventLevelAPI, EvtRtxEventFlagsNo, 0x04U) +#define EvtRtxEventFlagsGetName_Detail EventID(EventLevelDetail, EvtRtxEventFlagsNo, 0x05U) +#define EvtRtxEventFlagsSet EventID(EventLevelAPI, EvtRtxEventFlagsNo, 0x06U) +#define EvtRtxEventFlagsSetDone EventID(EventLevelOp, EvtRtxEventFlagsNo, 0x07U) +#define EvtRtxEventFlagsClear EventID(EventLevelAPI, EvtRtxEventFlagsNo, 0x08U) +#define EvtRtxEventFlagsClearDone EventID(EventLevelOp, EvtRtxEventFlagsNo, 0x09U) +#define EvtRtxEventFlagsGet EventID(EventLevelAPI, EvtRtxEventFlagsNo, 0x0AU) +#define EvtRtxEventFlagsWait EventID(EventLevelAPI, EvtRtxEventFlagsNo, 0x0BU) +#define EvtRtxEventFlagsWaitPending EventID(EventLevelOp, EvtRtxEventFlagsNo, 0x0CU) +#define EvtRtxEventFlagsWaitTimeout EventID(EventLevelOp, EvtRtxEventFlagsNo, 0x0DU) +#define EvtRtxEventFlagsWaitCompleted EventID(EventLevelOp, EvtRtxEventFlagsNo, 0x0EU) +#define EvtRtxEventFlagsWaitNotCompleted EventID(EventLevelOp, EvtRtxEventFlagsNo, 0x0FU) +#define EvtRtxEventFlagsDelete EventID(EventLevelAPI, EvtRtxEventFlagsNo, 0x10U) +#define EvtRtxEventFlagsDestroyed EventID(EventLevelOp, EvtRtxEventFlagsNo, 0x11U) + +/// Event IDs for "RTX Mutex" +#define EvtRtxMutexError EventID(EventLevelError, EvtRtxMutexNo, 0x00U) +#define EvtRtxMutexNew EventID(EventLevelAPI, EvtRtxMutexNo, 0x01U) +#define EvtRtxMutexNew_Detail EventID(EventLevelDetail, EvtRtxMutexNo, 0x02U) +#define EvtRtxMutexCreated EventID(EventLevelOp, EvtRtxMutexNo, 0x03U) +#define EvtRtxMutexGetName EventID(EventLevelAPI, EvtRtxMutexNo, 0x04U) +#define EvtRtxMutexGetName_Detail EventID(EventLevelDetail, EvtRtxMutexNo, 0x05U) +#define EvtRtxMutexAcquire EventID(EventLevelAPI, EvtRtxMutexNo, 0x06U) +#define EvtRtxMutexAcquirePending EventID(EventLevelError, EvtRtxMutexNo, 0x07U) +#define EvtRtxMutexAcquireTimeout EventID(EventLevelError, EvtRtxMutexNo, 0x08U) +#define EvtRtxMutexAcquired EventID(EventLevelOp, EvtRtxMutexNo, 0x09U) +#define EvtRtxMutexNotAcquired EventID(EventLevelOp, EvtRtxMutexNo, 0x0AU) +#define EvtRtxMutexRelease EventID(EventLevelAPI, EvtRtxMutexNo, 0x0BU) +#define EvtRtxMutexReleased EventID(EventLevelOp, EvtRtxMutexNo, 0x0CU) +#define EvtRtxMutexGetOwner EventID(EventLevelAPI, EvtRtxMutexNo, 0x0DU) +#define EvtRtxMutexDelete EventID(EventLevelAPI, EvtRtxMutexNo, 0x0EU) +#define EvtRtxMutexDestroyed EventID(EventLevelOp, EvtRtxMutexNo, 0x0FU) + +/// Event IDs for "RTX Semaphore" +#define EvtRtxSemaphoreError EventID(EventLevelError, EvtRtxSemaphoreNo, 0x00U) +#define EvtRtxSemaphoreNew EventID(EventLevelAPI, EvtRtxSemaphoreNo, 0x01U) +#define EvtRtxSemaphoreNew_Detail EventID(EventLevelDetail, EvtRtxSemaphoreNo, 0x02U) +#define EvtRtxSemaphoreCreated EventID(EventLevelOp, EvtRtxSemaphoreNo, 0x03U) +#define EvtRtxSemaphoreGetName EventID(EventLevelAPI, EvtRtxSemaphoreNo, 0x04U) +#define EvtRtxSemaphoreGetName_Detail EventID(EventLevelDetail, EvtRtxSemaphoreNo, 0x05U) +#define EvtRtxSemaphoreAcquire EventID(EventLevelAPI, EvtRtxSemaphoreNo, 0x06U) +#define EvtRtxSemaphoreAcquirePending EventID(EventLevelOp, EvtRtxSemaphoreNo, 0x07U) +#define EvtRtxSemaphoreAcquireTimeout EventID(EventLevelOp, EvtRtxSemaphoreNo, 0x08U) +#define EvtRtxSemaphoreAcquired EventID(EventLevelOp, EvtRtxSemaphoreNo, 0x09U) +#define EvtRtxSemaphoreNotAcquired EventID(EventLevelOp, EvtRtxSemaphoreNo, 0x0AU) +#define EvtRtxSemaphoreRelease EventID(EventLevelAPI, EvtRtxSemaphoreNo, 0x0BU) +#define EvtRtxSemaphoreReleased EventID(EventLevelOp, EvtRtxSemaphoreNo, 0x0CU) +#define EvtRtxSemaphoreGetCount EventID(EventLevelAPI, EvtRtxSemaphoreNo, 0x0DU) +#define EvtRtxSemaphoreDelete EventID(EventLevelAPI, EvtRtxSemaphoreNo, 0x0EU) +#define EvtRtxSemaphoreDestroyed EventID(EventLevelOp, EvtRtxSemaphoreNo, 0x0FU) + +/// Event IDs for "RTX Memory Pool" +#define EvtRtxMemoryPoolError EventID(EventLevelError, EvtRtxMemoryPoolNo, 0x00U) +#define EvtRtxMemoryPoolNew EventID(EventLevelAPI, EvtRtxMemoryPoolNo, 0x01U) +#define EvtRtxMemoryPoolNew_Detail EventID(EventLevelDetail, EvtRtxMemoryPoolNo, 0x02U) +#define EvtRtxMemoryPoolCreated EventID(EventLevelOp, EvtRtxMemoryPoolNo, 0x03U) +#define EvtRtxMemoryPoolGetName EventID(EventLevelAPI, EvtRtxMemoryPoolNo, 0x04U) +#define EvtRtxMemoryPoolGetName_Detail EventID(EventLevelDetail, EvtRtxMemoryPoolNo, 0x05U) +#define EvtRtxMemoryPoolAlloc EventID(EventLevelAPI, EvtRtxMemoryPoolNo, 0x06U) +#define EvtRtxMemoryPoolAllocPending EventID(EventLevelOp, EvtRtxMemoryPoolNo, 0x07U) +#define EvtRtxMemoryPoolAllocTimeout EventID(EventLevelOp, EvtRtxMemoryPoolNo, 0x08U) +#define EvtRtxMemoryPoolAllocated EventID(EventLevelOp, EvtRtxMemoryPoolNo, 0x09U) +#define EvtRtxMemoryPoolAllocFailed EventID(EventLevelOp, EvtRtxMemoryPoolNo, 0x0AU) +#define EvtRtxMemoryPoolFree EventID(EventLevelAPI, EvtRtxMemoryPoolNo, 0x0BU) +#define EvtRtxMemoryPoolDeallocated EventID(EventLevelOp, EvtRtxMemoryPoolNo, 0x0CU) +#define EvtRtxMemoryPoolFreeFailed EventID(EventLevelOp, EvtRtxMemoryPoolNo, 0x0DU) +#define EvtRtxMemoryPoolGetCapacity EventID(EventLevelAPI, EvtRtxMemoryPoolNo, 0x0EU) +#define EvtRtxMemoryPoolGetBlockSize EventID(EventLevelAPI, EvtRtxMemoryPoolNo, 0x0FU) +#define EvtRtxMemoryPoolGetCount EventID(EventLevelAPI, EvtRtxMemoryPoolNo, 0x10U) +#define EvtRtxMemoryPoolGetSpace EventID(EventLevelAPI, EvtRtxMemoryPoolNo, 0x11U) +#define EvtRtxMemoryPoolDelete EventID(EventLevelAPI, EvtRtxMemoryPoolNo, 0x12U) +#define EvtRtxMemoryPoolDestroyed EventID(EventLevelOp, EvtRtxMemoryPoolNo, 0x13U) + +/// Event IDs for "RTX Message Queue" +#define EvtRtxMessageQueueError EventID(EventLevelError, EvtRtxMessageQueueNo, 0x00U) +#define EvtRtxMessageQueueNew EventID(EventLevelAPI, EvtRtxMessageQueueNo, 0x01U) +#define EvtRtxMessageQueueNew_Detail EventID(EventLevelDetail, EvtRtxMessageQueueNo, 0x02U) +#define EvtRtxMessageQueueCreated EventID(EventLevelOp, EvtRtxMessageQueueNo, 0x03U) +#define EvtRtxMessageQueueGetName EventID(EventLevelAPI, EvtRtxMessageQueueNo, 0x04U) +#define EvtRtxMessageQueueGetName_Detail EventID(EventLevelDetail, EvtRtxMessageQueueNo, 0x05U) +#define EvtRtxMessageQueuePut EventID(EventLevelAPI, EvtRtxMessageQueueNo, 0x06U) +#define EvtRtxMessageQueuePutPending EventID(EventLevelOp, EvtRtxMessageQueueNo, 0x07U) +#define EvtRtxMessageQueuePutTimeout EventID(EventLevelOp, EvtRtxMessageQueueNo, 0x08U) +#define EvtRtxMessageQueueInsertPending EventID(EventLevelOp, EvtRtxMessageQueueNo, 0x09U) +#define EvtRtxMessageQueueInserted EventID(EventLevelOp, EvtRtxMessageQueueNo, 0x0AU) +#define EvtRtxMessageQueueNotInserted EventID(EventLevelOp, EvtRtxMessageQueueNo, 0x0BU) +#define EvtRtxMessageQueueGet EventID(EventLevelAPI, EvtRtxMessageQueueNo, 0x0CU) +#define EvtRtxMessageQueueGetPending EventID(EventLevelOp, EvtRtxMessageQueueNo, 0x0DU) +#define EvtRtxMessageQueueGetTimeout EventID(EventLevelOp, EvtRtxMessageQueueNo, 0x0EU) +#define EvtRtxMessageQueueRetrieved EventID(EventLevelOp, EvtRtxMessageQueueNo, 0x0FU) +#define EvtRtxMessageQueueNotRetrieved EventID(EventLevelOp, EvtRtxMessageQueueNo, 0x10U) +#define EvtRtxMessageQueueGetCapacity EventID(EventLevelAPI, EvtRtxMessageQueueNo, 0x11U) +#define EvtRtxMessageQueueGetMsgSize EventID(EventLevelAPI, EvtRtxMessageQueueNo, 0x12U) +#define EvtRtxMessageQueueGetCount EventID(EventLevelAPI, EvtRtxMessageQueueNo, 0x13U) +#define EvtRtxMessageQueueGetSpace EventID(EventLevelAPI, EvtRtxMessageQueueNo, 0x14U) +#define EvtRtxMessageQueueReset EventID(EventLevelAPI, EvtRtxMessageQueueNo, 0x15U) +#define EvtRtxMessageQueueResetDone EventID(EventLevelOp, EvtRtxMessageQueueNo, 0x16U) +#define EvtRtxMessageQueueDelete EventID(EventLevelAPI, EvtRtxMessageQueueNo, 0x17U) +#define EvtRtxMessageQueueDestroyed EventID(EventLevelOp, EvtRtxMessageQueueNo, 0x18U) + +#endif // RTE_Compiler_EventRecorder + + +// ==== Memory Events ==== + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMORY != 0) && !defined(EVR_RTX_MEMORY_INIT_DISABLE)) +__WEAK void EvrRtxMemoryInit (void *mem, uint32_t size, uint32_t result) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord4(EvtRtxMemoryInit, (uint32_t)mem, size, result, 0U); +#else + (void)mem; + (void)size; + (void)result; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMORY != 0) && !defined(EVR_RTX_MEMORY_ALLOC_DISABLE)) +__WEAK void EvrRtxMemoryAlloc (void *mem, uint32_t size, uint32_t type, void *block) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord4(EvtRtxMemoryAlloc, (uint32_t)mem, size, type, (uint32_t)block); +#else + (void)mem; + (void)size; + (void)type; + (void)block; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMORY != 0) && !defined(EVR_RTX_MEMORY_FREE_DISABLE)) +__WEAK void EvrRtxMemoryFree (void *mem, void *block, uint32_t result) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord4(EvtRtxMemoryFree, (uint32_t)mem, (uint32_t)block, result, 0U); +#else + (void)mem; + (void)block; + (void)result; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMORY != 0) && !defined(EVR_RTX_MEMORY_BLOCK_INIT_DISABLE)) +__WEAK void EvrRtxMemoryBlockInit (osRtxMpInfo_t *mp_info, uint32_t block_count, uint32_t block_size, void *block_mem) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord4(EvtRtxMemoryBlockInit, (uint32_t)mp_info, block_count, block_size, (uint32_t)block_mem); +#else + (void)mp_info; + (void)block_count; + (void)block_size; + (void)block_mem; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMORY != 0) && !defined(EVR_RTX_MEMORY_BLOCK_ALLOC_DISABLE)) +__WEAK void EvrRtxMemoryBlockAlloc (osRtxMpInfo_t *mp_info, void *block) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxMemoryBlockAlloc, (uint32_t)mp_info, (uint32_t)block); +#else + (void)mp_info; + (void)block; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMORY != 0) && !defined(EVR_RTX_MEMORY_BLOCK_FREE_DISABLE)) +__WEAK void EvrRtxMemoryBlockFree (osRtxMpInfo_t *mp_info, void *block, int32_t status) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord4(EvtRtxMemoryBlockFree, (uint32_t)mp_info, (uint32_t)block, (uint32_t)status, 0U); +#else + (void)mp_info; + (void)block; + (void)status; +#endif +} +#endif + + +// ==== Kernel Events ==== + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_ERROR_DISABLE)) +__WEAK void EvrRtxKernelError (int32_t status) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxKernelError, (uint32_t)status, 0U); +#else + (void)status; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_INITIALIZE_DISABLE)) +__WEAK void EvrRtxKernelInitialize (void) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxKernelInitialize, 0U, 0U); +#else +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_INITIALIZE_COMPLETED_DISABLE)) +__WEAK void EvrRtxKernelInitializeCompleted (void) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxKernelInitializeCompleted, 0U, 0U); +#else +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_GET_INFO_DISABLE)) +__WEAK void EvrRtxKernelGetInfo (osVersion_t *version, char *id_buf, uint32_t id_size) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord4(EvtRtxKernelGetInfo, (uint32_t)version, (uint32_t)id_buf, id_size, 0U); +#else + (void)version; + (void)id_buf; + (void)id_size; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_INFO_RETRIEVED_DISABLE)) +__WEAK void EvrRtxKernelInfoRetrieved (osVersion_t *version, char *id_buf) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxKernelInfoRetrieved, (uint32_t)version, (uint32_t)id_buf); + if (id_buf != NULL) { + EventRecordData(EvtRtxKernelInfoRetrieved_Detail, id_buf, strlen(id_buf)); + } +#else + (void)version; + (void)id_buf; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_GET_STATE_DISABLE)) +__WEAK void EvrRtxKernelGetState (osKernelState_t state) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxKernelGetState, (uint32_t)state, 0U); +#else + (void)state; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_START_DISABLE)) +__WEAK void EvrRtxKernelStart (void) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxKernelStart, 0U, 0U); +#else +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_STARTED_DISABLE)) +__WEAK void EvrRtxKernelStarted (void) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxKernelStarted, 0U, 0U); +#else +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_LOCK_DISABLE)) +__WEAK void EvrRtxKernelLock (void) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxKernelLock, 0U, 0U); +#else +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_LOCKED_DISABLE)) +__WEAK void EvrRtxKernelLocked (int32_t lock) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxKernelLocked, (uint32_t)lock, 0U); +#else + (void)lock; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_UNLOCK_DISABLE)) +__WEAK void EvrRtxKernelUnlock (void) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxKernelUnlock, 0U, 0U); +#else +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_UNLOCKED_DISABLE)) +__WEAK void EvrRtxKernelUnlocked (int32_t lock) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxKernelUnlocked, (uint32_t)lock, 0U); +#else + (void)lock; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_RESTORE_LOCK_DISABLE)) +__WEAK void EvrRtxKernelRestoreLock (int32_t lock) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxKernelRestoreLock, (uint32_t)lock, 0U); +#else + (void)lock; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_LOCK_RESTORED_DISABLE)) +__WEAK void EvrRtxKernelLockRestored (int32_t lock) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxKernelLockRestored, (uint32_t)lock, 0U); +#else + (void)lock; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_SUSPEND_DISABLE)) +__WEAK void EvrRtxKernelSuspend (void) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxKernelSuspend, 0U, 0U); +#else +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_SUSPENDED_DISABLE)) +__WEAK void EvrRtxKernelSuspended (uint32_t sleep_ticks) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxKernelSuspended, sleep_ticks, 0U); +#else + (void)sleep_ticks; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_RESUME_DISABLE)) +__WEAK void EvrRtxKernelResume (uint32_t sleep_ticks) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxKernelResume, sleep_ticks, 0U); +#else + (void)sleep_ticks; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_RESUMED_DISABLE)) +__WEAK void EvrRtxKernelResumed (void) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxKernelResumed, 0U, 0U); +#else +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_GET_TICK_COUNT_DISABLE)) +__WEAK void EvrRtxKernelGetTickCount (uint64_t count) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxKernelGetTickCount, (uint32_t)count, (uint32_t)(count>>32)); +#else + (void)count; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_GET_TICK_FREQ_DISABLE)) +__WEAK void EvrRtxKernelGetTickFreq (uint32_t freq) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxKernelGetTickFreq, freq, 0U); +#else + (void)freq; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_GET_SYS_TIMER_COUNT_DISABLE)) +__WEAK void EvrRtxKernelGetSysTimerCount (uint32_t count) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxKernelGetSysTimerCount, count, 0U); +#else + (void)count; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_GET_SYS_TIMER_FREQ_DISABLE)) +__WEAK void EvrRtxKernelGetSysTimerFreq (uint32_t freq) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxKernelGetSysTimerFreq, freq, 0U); +#else + (void)freq; +#endif +} +#endif + + +// ==== Thread Events ==== + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_ERROR_DISABLE)) +__WEAK void EvrRtxThreadError (osThreadId_t thread_id, int32_t status) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxThreadError, (uint32_t)thread_id, (uint32_t)status); +#else + (void)thread_id; + (void)status; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_NEW_DISABLE)) +__WEAK void EvrRtxThreadNew (osThreadFunc_t func, void *argument, const osThreadAttr_t *attr) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord4(EvtRtxThreadNew, (uint32_t)func, (uint32_t)argument, (uint32_t)attr, 0U); + if (attr != NULL) { + EventRecordData(EvtRtxThreadNew_Detail, attr, sizeof (osThreadAttr_t)); + } +#else + (void)func; + (void)argument; + (void)attr; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_CREATED_DISABLE)) +__WEAK void EvrRtxThreadCreated (osThreadId_t thread_id) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxThreadCreated, (uint32_t)thread_id, 0U); +#else + (void)thread_id; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_GET_NAME_DISABLE)) +__WEAK void EvrRtxThreadGetName (osThreadId_t thread_id, const char *name) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxThreadGetName, (uint32_t)thread_id, (uint32_t)name); + if (name != NULL) { + EventRecordData(EvtRtxThreadGetName_Detail, name, strlen(name)); + } +#else + (void)thread_id; + (void)name; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_GET_ID_DISABLE)) +__WEAK void EvrRtxThreadGetId (osThreadId_t thread_id) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxThreadGetId, (uint32_t)thread_id, 0U); +#else + (void)thread_id; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_GET_STATE_DISABLE)) +__WEAK void EvrRtxThreadGetState (osThreadId_t thread_id, osThreadState_t state) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxThreadGetState, (uint32_t)thread_id, (uint32_t)state); +#else + (void)thread_id; + (void)state; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_GET_STACK_SIZE_DISABLE)) +__WEAK void EvrRtxThreadGetStackSize (osThreadId_t thread_id, uint32_t stack_size) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxThreadGetStackSize, (uint32_t)thread_id, stack_size); +#else + (void)thread_id; + (void)stack_size; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_GET_STACK_SPACE_DISABLE)) +__WEAK void EvrRtxThreadGetStackSpace (osThreadId_t thread_id, uint32_t stack_space) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxThreadGetStackSpace, (uint32_t)thread_id, stack_space); +#else + (void)thread_id; + (void)stack_space; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_SET_PRIORITY_DISABLE)) +__WEAK void EvrRtxThreadSetPriority (osThreadId_t thread_id, osPriority_t priority) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxThreadSetPriority, (uint32_t)thread_id, (uint32_t)priority); +#else + (void)thread_id; + (void)priority; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_GET_PRIORITY_DISABLE)) +__WEAK void EvrRtxThreadGetPriority (osThreadId_t thread_id, osPriority_t priority) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxThreadGetPriority, (uint32_t)thread_id, (uint32_t)priority); +#else + (void)thread_id; + (void)priority; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_YIELD_DISABLE)) +__WEAK void EvrRtxThreadYield (void) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxThreadYield, 0U, 0U); +#else +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_SUSPEND_DISABLE)) +__WEAK void EvrRtxThreadSuspend (osThreadId_t thread_id) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxThreadSuspend, (uint32_t)thread_id, 0U); +#else + (void)thread_id; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_SUSPENDED_DISABLE)) +__WEAK void EvrRtxThreadSuspended (osThreadId_t thread_id) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxThreadSuspended, (uint32_t)thread_id, 0U); +#else + (void)thread_id; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_RESUME_DISABLE)) +__WEAK void EvrRtxThreadResume (osThreadId_t thread_id) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxThreadResume, (uint32_t)thread_id, 0U); +#else + (void)thread_id; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_RESUMED_DISABLE)) +__WEAK void EvrRtxThreadResumed (osThreadId_t thread_id) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxThreadResumed, (uint32_t)thread_id, 0U); +#else + (void)thread_id; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_DETACH_DISABLE)) +__WEAK void EvrRtxThreadDetach (osThreadId_t thread_id) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxThreadDetach, (uint32_t)thread_id, 0U); +#else + (void)thread_id; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_DETACHED_DISABLE)) +__WEAK void EvrRtxThreadDetached (osThreadId_t thread_id) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxThreadDetached, (uint32_t)thread_id, 0U); +#else + (void)thread_id; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_JOIN_DISABLE)) +__WEAK void EvrRtxThreadJoin (osThreadId_t thread_id) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxThreadJoin, (uint32_t)thread_id, 0U); +#else + (void)thread_id; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_JOIN_PENDING_DISABLE)) +__WEAK void EvrRtxThreadJoinPending (osThreadId_t thread_id) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxThreadJoinPending, (uint32_t)thread_id, 0U); +#else + (void)thread_id; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_JOINED_DISABLE)) +__WEAK void EvrRtxThreadJoined (osThreadId_t thread_id) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxThreadJoined, (uint32_t)thread_id, 0U); +#else + (void)thread_id; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_BLOCKED_DISABLE)) +__WEAK void EvrRtxThreadBlocked (osThreadId_t thread_id, uint32_t timeout) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxThreadBlocked, (uint32_t)thread_id, timeout); +#else + (void)thread_id; + (void)timeout; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_UNBLOCKED_DISABLE)) +__WEAK void EvrRtxThreadUnblocked (osThreadId_t thread_id, uint32_t ret_val) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxThreadUnblocked, (uint32_t)thread_id, ret_val); +#else + (void)thread_id; + (void)ret_val; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_SWITCH_DISABLE)) +__WEAK void EvrRtxThreadSwitch (osThreadId_t thread_id) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxThreadSwitch, (uint32_t)thread_id, 0U); +#else + (void)thread_id; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_EXIT_DISABLE)) +__WEAK void EvrRtxThreadExit (void) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxThreadExit, 0U, 0U); +#else +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_TERMINATE_DISABLE)) +__WEAK void EvrRtxThreadTerminate (osThreadId_t thread_id) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxThreadTerminate, (uint32_t)thread_id, 0U); +#else + (void)thread_id; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_DESTROYED_DISABLE)) +__WEAK void EvrRtxThreadDestroyed (osThreadId_t thread_id) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxThreadDestroyed, (uint32_t)thread_id, 0U); +#else + (void)thread_id; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_GET_COUNT_DISABLE)) +__WEAK void EvrRtxThreadGetCount (uint32_t count) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxThreadGetCount, count, 0U); +#else + (void)count; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_ENUMERATE_DISABLE)) +__WEAK void EvrRtxThreadEnumerate (osThreadId_t *thread_array, uint32_t array_items, uint32_t count) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord4(EvtRtxThreadEnumerate, (uint32_t)thread_array, array_items, count, 0U); +#else + (void)thread_array; + (void)array_items; + (void)count; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_FLAGS_SET_DISABLE)) +__WEAK void EvrRtxThreadFlagsSet (osThreadId_t thread_id, uint32_t flags) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxThreadFlagsSet, (uint32_t)thread_id, flags); +#else + (void)thread_id; + (void)flags; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_FLAGS_SET_DONE_DISABLE)) +__WEAK void EvrRtxThreadFlagsSetDone (osThreadId_t thread_id, uint32_t thread_flags) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxThreadFlagsSetDone, (uint32_t)thread_id, thread_flags); +#else + (void)thread_id; + (void)thread_flags; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_FLAGS_CLEAR_DISABLE)) +__WEAK void EvrRtxThreadFlagsClear (uint32_t flags) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxThreadFlagsClear, flags, 0U); +#else + (void)flags; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_FLAGS_CLEAR_DONE_DISABLE)) +__WEAK void EvrRtxThreadFlagsClearDone (uint32_t thread_flags) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxThreadFlagsClearDone, thread_flags, 0U); +#else + (void)thread_flags; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_FLAGS_GET_DISABLE)) +__WEAK void EvrRtxThreadFlagsGet (uint32_t thread_flags) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxThreadFlagsGet, thread_flags, 0U); +#else + (void)thread_flags; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_FLAGS_WAIT_DISABLE)) +__WEAK void EvrRtxThreadFlagsWait (uint32_t flags, uint32_t options, uint32_t timeout) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord4(EvtRtxThreadFlagsWait, flags, options, timeout, 0U); +#else + (void)flags; + (void)options; + (void)timeout; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_FLAGS_WAIT_PENDING_DISABLE)) +__WEAK void EvrRtxThreadFlagsWaitPending (uint32_t flags, uint32_t options, uint32_t timeout) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord4(EvtRtxThreadFlagsWaitPending, flags, options, timeout, 0U); +#else + (void)flags; + (void)options; + (void)timeout; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_FLAGS_WAIT_TIMEOUT_DISABLE)) +__WEAK void EvrRtxThreadFlagsWaitTimeout (void) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxThreadFlagsWaitTimeout, 0U, 0U); +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_FLAGS_WAIT_COMPLETED_DISABLE)) +__WEAK void EvrRtxThreadFlagsWaitCompleted (uint32_t flags, uint32_t options, uint32_t thread_flags) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord4(EvtRtxThreadFlagsWaitCompleted, flags, options, thread_flags, 0U); +#else + (void)flags; + (void)options; + (void)thread_flags; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_FLAGS_WAIT_NOT_COMPLETED_DISABLE)) +__WEAK void EvrRtxThreadFlagsWaitNotCompleted (uint32_t flags, uint32_t options) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxThreadFlagsWaitNotCompleted, flags, options); +#else + (void)flags; + (void)options; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_DELAY_DISABLE)) +__WEAK void EvrRtxThreadDelay (uint32_t ticks) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxThreadDelay, ticks, 0U); +#else + (void)ticks; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_DELAY_UNTIL_DISABLE)) +__WEAK void EvrRtxThreadDelayUntil (uint64_t ticks) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxThreadDelayUntil, (uint32_t)ticks, (uint32_t)(ticks >> 32)); +#else + (void)ticks; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_DELAY_COMPLETED_DISABLE)) +__WEAK void EvrRtxThreadDelayCompleted (void) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxThreadDelayCompleted, 0U, 0U); +#endif +} +#endif + + +// ==== Timer Events ==== + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_TIMER != 0) && !defined(EVR_RTX_TIMER_ERROR_DISABLE)) +__WEAK void EvrRtxTimerError (osTimerId_t timer_id, int32_t status) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxTimerError, (uint32_t)timer_id, (uint32_t)status); +#else + (void)timer_id; + (void)status; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_TIMER != 0) && !defined(EVR_RTX_TIMER_CALLBACK_DISABLE)) +__WEAK void EvrRtxTimerCallback (osTimerFunc_t func, void *argument) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxTimerCallback, (uint32_t)func, (uint32_t)argument); +#else + (void)func; + (void)argument; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_TIMER != 0) && !defined(EVR_RTX_TIMER_NEW_DISABLE)) +__WEAK void EvrRtxTimerNew (osTimerFunc_t func, osTimerType_t type, void *argument, const osTimerAttr_t *attr) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord4(EvtRtxTimerNew, (uint32_t)func, (uint32_t)type, (uint32_t)argument, (uint32_t)attr); + if (attr != NULL) { + EventRecordData(EvtRtxTimerNew_Detail, attr, sizeof (osTimerAttr_t)); + } +#else + (void)func; + (void)type; + (void)argument; + (void)attr; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_TIMER != 0) && !defined(EVR_RTX_TIMER_CREATED_DISABLE)) +__WEAK void EvrRtxTimerCreated (osTimerId_t timer_id) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxTimerCreated, (uint32_t)timer_id, 0U); +#else + (void)timer_id; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_TIMER != 0) && !defined(EVR_RTX_TIMER_GET_NAME_DISABLE)) +__WEAK void EvrRtxTimerGetName (osTimerId_t timer_id, const char *name) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxTimerGetName, (uint32_t)timer_id, (uint32_t)name); + if (name != NULL) { + EventRecordData(EvtRtxTimerGetName_Detail, name, strlen(name)); + } +#else + (void)timer_id; + (void)name; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_TIMER != 0) && !defined(EVR_RTX_TIMER_START_DISABLE)) +__WEAK void EvrRtxTimerStart (osTimerId_t timer_id, uint32_t ticks) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxTimerStart, (uint32_t)timer_id, ticks); +#else + (void)timer_id; + (void)ticks; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_TIMER != 0) && !defined(EVR_RTX_TIMER_STARTED_DISABLE)) +__WEAK void EvrRtxTimerStarted (osTimerId_t timer_id) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxTimerStarted, (uint32_t)timer_id, 0U); +#else + (void)timer_id; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_TIMER != 0) && !defined(EVR_RTX_TIMER_STOP_DISABLE)) +__WEAK void EvrRtxTimerStop (osTimerId_t timer_id) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxTimerStop, (uint32_t)timer_id, 0U); +#else + (void)timer_id; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_TIMER != 0) && !defined(EVR_RTX_TIMER_STOPPED_DISABLE)) +__WEAK void EvrRtxTimerStopped (osTimerId_t timer_id) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxTimerStopped, (uint32_t)timer_id, 0U); +#else + (void)timer_id; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_TIMER != 0) && !defined(EVR_RTX_TIMER_IS_RUNNING_DISABLE)) +__WEAK void EvrRtxTimerIsRunning (osTimerId_t timer_id, uint32_t running) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxTimerIsRunning, (uint32_t)timer_id, running); +#else + (void)timer_id; + (void)running; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_TIMER != 0) && !defined(EVR_RTX_TIMER_DELETE_DISABLE)) +__WEAK void EvrRtxTimerDelete (osTimerId_t timer_id) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxTimerDelete, (uint32_t)timer_id, 0U); +#else + (void)timer_id; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_TIMER != 0) && !defined(EVR_RTX_TIMER_DESTROYED_DISABLE)) +__WEAK void EvrRtxTimerDestroyed (osTimerId_t timer_id) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxTimerDestroyed, (uint32_t)timer_id, 0U); +#else + (void)timer_id; +#endif +} +#endif + + +// ==== Event Flags Events ==== + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_EVFLAGS != 0) && !defined(EVR_RTX_EVENT_FLAGS_ERROR_DISABLE)) +__WEAK void EvrRtxEventFlagsError (osEventFlagsId_t ef_id, int32_t status) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxEventFlagsError, (uint32_t)ef_id, (uint32_t)status); +#else + (void)ef_id; + (void)status; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_EVFLAGS != 0) && !defined(EVR_RTX_EVENT_FLAGS_NEW_DISABLE)) +__WEAK void EvrRtxEventFlagsNew (const osEventFlagsAttr_t *attr) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxEventFlagsNew, (uint32_t)attr, 0U); + if (attr != NULL) { + EventRecordData(EvtRtxEventFlagsNew_Detail, attr, sizeof (osEventFlagsAttr_t)); + } +#else + (void)attr; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_EVFLAGS != 0) && !defined(EVR_RTX_EVENT_FLAGS_CREATED_DISABLE)) +__WEAK void EvrRtxEventFlagsCreated (osEventFlagsId_t ef_id) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxEventFlagsCreated, (uint32_t)ef_id, 0U); +#else + (void)ef_id; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_EVFLAGS != 0) && !defined(EVR_RTX_EVENT_FLAGS_GET_NAME_DISABLE)) +__WEAK void EvrRtxEventFlagsGetName (osEventFlagsId_t ef_id, const char *name) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxEventFlagsGetName, (uint32_t)ef_id, (uint32_t)name); + if (name != NULL) { + EventRecordData(EvtRtxEventFlagsGetName_Detail, name, strlen(name)); + } +#else + (void)ef_id; + (void)name; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_EVFLAGS != 0) && !defined(EVR_RTX_EVENT_FLAGS_SET_DISABLE)) +__WEAK void EvrRtxEventFlagsSet (osEventFlagsId_t ef_id, uint32_t flags) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxEventFlagsSet, (uint32_t)ef_id, flags); +#else + (void)ef_id; + (void)flags; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_EVFLAGS != 0) && !defined(EVR_RTX_EVENT_FLAGS_SET_DONE_DISABLE)) +__WEAK void EvrRtxEventFlagsSetDone (osEventFlagsId_t ef_id, uint32_t event_flags) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxEventFlagsSetDone, (uint32_t)ef_id, event_flags); +#else + (void)ef_id; + (void)event_flags; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_EVFLAGS != 0) && !defined(EVR_RTX_EVENT_FLAGS_CLEAR_DISABLE)) +__WEAK void EvrRtxEventFlagsClear (osEventFlagsId_t ef_id, uint32_t flags) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxEventFlagsClear, (uint32_t)ef_id, flags); +#else + (void)ef_id; + (void)flags; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_EVFLAGS != 0) && !defined(EVR_RTX_EVENT_FLAGS_CLEAR_DONE_DISABLE)) +__WEAK void EvrRtxEventFlagsClearDone (osEventFlagsId_t ef_id, uint32_t event_flags) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxEventFlagsClearDone, (uint32_t)ef_id, event_flags); +#else + (void)ef_id; + (void)event_flags; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_EVFLAGS != 0) && !defined(EVR_RTX_EVENT_FLAGS_GET_DISABLE)) +__WEAK void EvrRtxEventFlagsGet (osEventFlagsId_t ef_id, uint32_t event_flags) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxEventFlagsGet, (uint32_t)ef_id, event_flags); +#else + (void)ef_id; + (void)event_flags; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_EVFLAGS != 0) && !defined(EVR_RTX_EVENT_FLAGS_WAIT_DISABLE)) +__WEAK void EvrRtxEventFlagsWait (osEventFlagsId_t ef_id, uint32_t flags, uint32_t options, uint32_t timeout) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord4(EvtRtxEventFlagsWait, (uint32_t)ef_id, flags, options, timeout); +#else + (void)ef_id; + (void)flags; + (void)options; + (void)timeout; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_EVFLAGS != 0) && !defined(EVR_RTX_EVENT_FLAGS_WAIT_PENDING_DISABLE)) +__WEAK void EvrRtxEventFlagsWaitPending (osEventFlagsId_t ef_id, uint32_t flags, uint32_t options, uint32_t timeout) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord4(EvtRtxEventFlagsWaitPending, (uint32_t)ef_id, flags, options, timeout); +#else + (void)ef_id; + (void)flags; + (void)options; + (void)timeout; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_EVFLAGS != 0) && !defined(EVR_RTX_EVENT_FLAGS_WAIT_TIMEOUT_DISABLE)) +__WEAK void EvrRtxEventFlagsWaitTimeout (osEventFlagsId_t ef_id) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxEventFlagsWaitTimeout, (uint32_t)ef_id, 0U); +#else + (void)ef_id; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_EVFLAGS != 0) && !defined(EVR_RTX_EVENT_FLAGS_WAIT_COMPLETED_DISABLE)) +__WEAK void EvrRtxEventFlagsWaitCompleted (osEventFlagsId_t ef_id, uint32_t flags, uint32_t options, uint32_t event_flags) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord4(EvtRtxEventFlagsWaitCompleted, (uint32_t)ef_id, flags, options, event_flags); +#else + (void)ef_id; + (void)flags; + (void)options; + (void)event_flags; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_EVFLAGS != 0) && !defined(EVR_RTX_EVENT_FLAGS_WAIT_NOT_COMPLETED_DISABLE)) +__WEAK void EvrRtxEventFlagsWaitNotCompleted (osEventFlagsId_t ef_id, uint32_t flags, uint32_t options) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord4(EvtRtxEventFlagsWaitNotCompleted, (uint32_t)ef_id, flags, options, 0U); +#else + (void)ef_id; + (void)flags; + (void)options; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_EVFLAGS != 0) && !defined(EVR_RTX_EVENT_FLAGS_DELETE_DISABLE)) +__WEAK void EvrRtxEventFlagsDelete (osEventFlagsId_t ef_id) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxEventFlagsDelete, (uint32_t)ef_id, 0U); +#else + (void)ef_id; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_EVFLAGS != 0) && !defined(EVR_RTX_EVENT_FLAGS_DESTROYED_DISABLE)) +__WEAK void EvrRtxEventFlagsDestroyed (osEventFlagsId_t ef_id) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxEventFlagsDestroyed, (uint32_t)ef_id, 0U); +#else + (void)ef_id; +#endif +} +#endif + + +// ==== Mutex Events ==== + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MUTEX != 0) && !defined(EVR_RTX_MUTEX_ERROR_DISABLE)) +__WEAK void EvrRtxMutexError (osMutexId_t mutex_id, int32_t status) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxMutexError, (uint32_t)mutex_id, (uint32_t)status); +#else + (void)mutex_id; + (void)status; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MUTEX != 0) && !defined(EVR_RTX_MUTEX_NEW_DISABLE)) +__WEAK void EvrRtxMutexNew (const osMutexAttr_t *attr) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxMutexNew, (uint32_t)attr, 0U); + if (attr != NULL) { + EventRecordData(EvtRtxMutexNew_Detail, attr, sizeof (osMutexAttr_t)); + } +#else + (void)attr; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MUTEX != 0) && !defined(EVR_RTX_MUTEX_CREATED_DISABLE)) +__WEAK void EvrRtxMutexCreated (osMutexId_t mutex_id) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxMutexCreated, (uint32_t)mutex_id, 0U); +#else + (void)mutex_id; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MUTEX != 0) && !defined(EVR_RTX_MUTEX_GET_NAME_DISABLE)) +__WEAK void EvrRtxMutexGetName (osMutexId_t mutex_id, const char *name) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxMutexGetName, (uint32_t)mutex_id, (uint32_t)name); + if (name != NULL) { + EventRecordData(EvtRtxMutexGetName_Detail, name, strlen(name)); + } +#else + (void)mutex_id; + (void)name; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MUTEX != 0) && !defined(EVR_RTX_MUTEX_ACQUIRE_DISABLE)) +__WEAK void EvrRtxMutexAcquire (osMutexId_t mutex_id, uint32_t timeout) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxMutexAcquire, (uint32_t)mutex_id, timeout); +#else + (void)mutex_id; + (void)timeout; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MUTEX != 0) && !defined(EVR_RTX_MUTEX_ACQUIRE_PENDING_DISABLE)) +__WEAK void EvrRtxMutexAcquirePending (osMutexId_t mutex_id, uint32_t timeout) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxMutexAcquirePending, (uint32_t)mutex_id, timeout); +#else + (void)mutex_id; + (void)timeout; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MUTEX != 0) && !defined(EVR_RTX_MUTEX_ACQUIRE_TIMEOUT_DISABLE)) +__WEAK void EvrRtxMutexAcquireTimeout (osMutexId_t mutex_id) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxMutexAcquireTimeout, (uint32_t)mutex_id, 0U); +#else + (void)mutex_id; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MUTEX != 0) && !defined(EVR_RTX_MUTEX_ACQUIRED_DISABLE)) +__WEAK void EvrRtxMutexAcquired (osMutexId_t mutex_id, uint32_t lock) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxMutexAcquired, (uint32_t)mutex_id, lock); +#else + (void)mutex_id; + (void)lock; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MUTEX != 0) && !defined(EVR_RTX_MUTEX_NOT_ACQUIRED_DISABLE)) +__WEAK void EvrRtxMutexNotAcquired (osMutexId_t mutex_id) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxMutexNotAcquired, (uint32_t)mutex_id, 0U); +#else + (void)mutex_id; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MUTEX != 0) && !defined(EVR_RTX_MUTEX_RELEASE_DISABLE)) +__WEAK void EvrRtxMutexRelease (osMutexId_t mutex_id) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxMutexRelease, (uint32_t)mutex_id, 0U); +#else + (void)mutex_id; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MUTEX != 0) && !defined(EVR_RTX_MUTEX_RELEASED_DISABLE)) +__WEAK void EvrRtxMutexReleased (osMutexId_t mutex_id, uint32_t lock) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxMutexReleased, (uint32_t)mutex_id, lock); +#else + (void)mutex_id; + (void)lock; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MUTEX != 0) && !defined(EVR_RTX_MUTEX_GET_OWNER_DISABLE)) +__WEAK void EvrRtxMutexGetOwner (osMutexId_t mutex_id, osThreadId_t thread_id) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxMutexGetOwner, (uint32_t)mutex_id, (uint32_t)thread_id); +#else + (void)mutex_id; + (void)thread_id; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MUTEX != 0) && !defined(EVR_RTX_MUTEX_DELETE_DISABLE)) +__WEAK void EvrRtxMutexDelete (osMutexId_t mutex_id) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxMutexDelete, (uint32_t)mutex_id, 0U); +#else + (void)mutex_id; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MUTEX != 0) && !defined(EVR_RTX_MUTEX_DESTROYED_DISABLE)) +__WEAK void EvrRtxMutexDestroyed (osMutexId_t mutex_id) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxMutexDestroyed, (uint32_t)mutex_id, 0U); +#else + (void)mutex_id; +#endif +} +#endif + + +// ==== Semaphore Events ==== + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_SEMAPHORE != 0) && !defined(EVR_RTX_SEMAPHORE_ERROR_DISABLE)) +__WEAK void EvrRtxSemaphoreError (osSemaphoreId_t semaphore_id, int32_t status) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxSemaphoreError, (uint32_t)semaphore_id, (uint32_t)status); +#else + (void)semaphore_id; + (void)status; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_SEMAPHORE != 0) && !defined(EVR_RTX_SEMAPHORE_NEW_DISABLE)) +__WEAK void EvrRtxSemaphoreNew (uint32_t max_count, uint32_t initial_count, const osSemaphoreAttr_t *attr) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord4(EvtRtxSemaphoreNew, max_count, initial_count, (uint32_t)attr, 0U); + if (attr != NULL) { + EventRecordData(EvtRtxSemaphoreNew_Detail, attr, sizeof (osSemaphoreAttr_t)); + } +#else + (void)max_count; + (void)initial_count; + (void)attr; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_SEMAPHORE != 0) && !defined(EVR_RTX_SEMAPHORE_CREATED_DISABLE)) +__WEAK void EvrRtxSemaphoreCreated (osSemaphoreId_t semaphore_id) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxSemaphoreCreated, (uint32_t)semaphore_id, 0U); +#else + (void)semaphore_id; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_SEMAPHORE != 0) && !defined(EVR_RTX_SEMAPHORE_GET_NAME_DISABLE)) +__WEAK void EvrRtxSemaphoreGetName (osSemaphoreId_t semaphore_id, const char *name) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxSemaphoreGetName, (uint32_t)semaphore_id, (uint32_t)name); + if (name != NULL) { + EventRecordData(EvtRtxSemaphoreGetName_Detail, name, strlen(name)); + } +#else +#endif + (void)semaphore_id; + (void)name; +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_SEMAPHORE != 0) && !defined(EVR_RTX_SEMAPHORE_ACQUIRE_DISABLE)) +__WEAK void EvrRtxSemaphoreAcquire (osSemaphoreId_t semaphore_id, uint32_t timeout) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxSemaphoreAcquire, (uint32_t)semaphore_id, timeout); +#else + (void)semaphore_id; + (void)timeout; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_SEMAPHORE != 0) && !defined(EVR_RTX_SEMAPHORE_ACQUIRE_PENDING_DISABLE)) +__WEAK void EvrRtxSemaphoreAcquirePending (osSemaphoreId_t semaphore_id, uint32_t timeout) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxSemaphoreAcquirePending, (uint32_t)semaphore_id, (uint32_t)timeout); +#else + (void)semaphore_id; + (void)timeout; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_SEMAPHORE != 0) && !defined(EVR_RTX_SEMAPHORE_ACQUIRE_TIMEOUT_DISABLE)) +__WEAK void EvrRtxSemaphoreAcquireTimeout (osSemaphoreId_t semaphore_id) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxSemaphoreAcquireTimeout, (uint32_t)semaphore_id, 0U); +#else + (void)semaphore_id; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_SEMAPHORE != 0) && !defined(EVR_RTX_SEMAPHORE_ACQUIRED_DISABLE)) +__WEAK void EvrRtxSemaphoreAcquired (osSemaphoreId_t semaphore_id) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxSemaphoreAcquired, (uint32_t)semaphore_id, 0U); +#else + (void)semaphore_id; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_SEMAPHORE != 0) && !defined(EVR_RTX_SEMAPHORE_NOT_ACQUIRED_DISABLE)) +__WEAK void EvrRtxSemaphoreNotAcquired (osSemaphoreId_t semaphore_id) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxSemaphoreNotAcquired, (uint32_t)semaphore_id, 0U); +#else + (void)semaphore_id; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_SEMAPHORE != 0) && !defined(EVR_RTX_SEMAPHORE_RELEASE_DISABLE)) +__WEAK void EvrRtxSemaphoreRelease (osSemaphoreId_t semaphore_id) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxSemaphoreRelease, (uint32_t)semaphore_id, 0U); +#else + (void)semaphore_id; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_SEMAPHORE != 0) && !defined(EVR_RTX_SEMAPHORE_RELEASED_DISABLE)) +__WEAK void EvrRtxSemaphoreReleased (osSemaphoreId_t semaphore_id) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxSemaphoreReleased, (uint32_t)semaphore_id, 0U); +#else + (void)semaphore_id; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_SEMAPHORE != 0) && !defined(EVR_RTX_SEMAPHORE_GET_COUNT_DISABLE)) +__WEAK void EvrRtxSemaphoreGetCount (osSemaphoreId_t semaphore_id, uint32_t count) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxSemaphoreGetCount, (uint32_t)semaphore_id, count); +#else + (void)semaphore_id; + (void)count; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_SEMAPHORE != 0) && !defined(EVR_RTX_SEMAPHORE_DELETE_DISABLE)) +__WEAK void EvrRtxSemaphoreDelete (osSemaphoreId_t semaphore_id) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxSemaphoreDelete, (uint32_t)semaphore_id, 0U); +#else + (void)semaphore_id; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_SEMAPHORE != 0) && !defined(EVR_RTX_SEMAPHORE_DESTROYED_DISABLE)) +__WEAK void EvrRtxSemaphoreDestroyed (osSemaphoreId_t semaphore_id) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxSemaphoreDestroyed, (uint32_t)semaphore_id, 0U); +#else + (void)semaphore_id; +#endif +} +#endif + + +// ==== Memory Pool Events ==== + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMPOOL != 0) && !defined(EVR_RTX_MEMORY_POOL_ERROR_DISABLE)) +__WEAK void EvrRtxMemoryPoolError (osMemoryPoolId_t mp_id, int32_t status) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxMemoryPoolError, (uint32_t)mp_id, (uint32_t)status); +#else + (void)mp_id; + (void)status; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMPOOL != 0) && !defined(EVR_RTX_MEMORY_POOL_NEW_DISABLE)) +__WEAK void EvrRtxMemoryPoolNew (uint32_t block_count, uint32_t block_size, const osMemoryPoolAttr_t *attr) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord4(EvtRtxMemoryPoolNew, block_count, block_size, (uint32_t)attr, 0U); + if (attr != NULL) { + EventRecordData(EvtRtxMemoryPoolNew_Detail, attr, sizeof (osMemoryPoolAttr_t)); + } +#else + (void)block_count; + (void)block_size; + (void)attr; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMPOOL != 0) && !defined(EVR_RTX_MEMORY_POOL_CREATED_DISABLE)) +__WEAK void EvrRtxMemoryPoolCreated (osMemoryPoolId_t mp_id) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxMemoryPoolCreated, (uint32_t)mp_id, 0U); +#else + (void)mp_id; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMPOOL != 0) && !defined(EVR_RTX_MEMORY_POOL_GET_NAME_DISABLE)) +__WEAK void EvrRtxMemoryPoolGetName (osMemoryPoolId_t mp_id, const char *name) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxMemoryPoolGetName, (uint32_t)mp_id, (uint32_t)name); + if (name != NULL) { + EventRecordData(EvtRtxMemoryPoolGetName_Detail, name, strlen(name)); + } +#else + (void)mp_id; + (void)name; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMPOOL != 0) && !defined(EVR_RTX_MEMORY_POOL_ALLOC_DISABLE)) +__WEAK void EvrRtxMemoryPoolAlloc (osMemoryPoolId_t mp_id, uint32_t timeout) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxMemoryPoolAlloc, (uint32_t)mp_id, timeout); +#else + (void)mp_id; + (void)timeout; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMPOOL != 0) && !defined(EVR_RTX_MEMORY_POOL_ALLOC_PENDING_DISABLE)) +__WEAK void EvrRtxMemoryPoolAllocPending (osMemoryPoolId_t mp_id, uint32_t timeout) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxMemoryPoolAllocPending, (uint32_t)mp_id, timeout); +#else + (void)mp_id; + (void)timeout; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMPOOL != 0) && !defined(EVR_RTX_MEMORY_POOL_ALLOC_TIMEOUT_DISABLE)) +__WEAK void EvrRtxMemoryPoolAllocTimeout (osMemoryPoolId_t mp_id) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxMemoryPoolAllocTimeout, (uint32_t)mp_id, 0U); +#else + (void)mp_id; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMPOOL != 0) && !defined(EVR_RTX_MEMORY_POOL_ALLOCATED_DISABLE)) +__WEAK void EvrRtxMemoryPoolAllocated (osMemoryPoolId_t mp_id, void *block) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxMemoryPoolAllocated, (uint32_t)mp_id, (uint32_t)block); +#else + (void)mp_id; + (void)block; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMPOOL != 0) && !defined(EVR_RTX_MEMORY_POOL_ALLOC_FAILED_DISABLE)) +__WEAK void EvrRtxMemoryPoolAllocFailed (osMemoryPoolId_t mp_id) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxMemoryPoolAllocFailed, (uint32_t)mp_id, 0U); +#else + (void)mp_id; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMPOOL != 0) && !defined(EVR_RTX_MEMORY_POOL_FREE_DISABLE)) +__WEAK void EvrRtxMemoryPoolFree (osMemoryPoolId_t mp_id, void *block) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxMemoryPoolFree, (uint32_t)mp_id, (uint32_t)block); +#else + (void)mp_id; + (void)block; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMPOOL != 0) && !defined(EVR_RTX_MEMORY_POOL_DEALLOCATED_DISABLE)) +__WEAK void EvrRtxMemoryPoolDeallocated (osMemoryPoolId_t mp_id, void *block) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxMemoryPoolDeallocated, (uint32_t)mp_id, (uint32_t)block); +#else + (void)mp_id; + (void)block; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMPOOL != 0) && !defined(EVR_RTX_MEMORY_POOL_FREE_FAILED_DISABLE)) +__WEAK void EvrRtxMemoryPoolFreeFailed (osMemoryPoolId_t mp_id, void *block) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxMemoryPoolFreeFailed, (uint32_t)mp_id, (uint32_t)block); +#else + (void)mp_id; + (void)block; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMPOOL != 0) && !defined(EVR_RTX_MEMORY_POOL_GET_CAPACITY_DISABLE)) +__WEAK void EvrRtxMemoryPoolGetCapacity (osMemoryPoolId_t mp_id, uint32_t capacity) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxMemoryPoolGetCapacity, (uint32_t)mp_id, capacity); +#else + (void)mp_id; + (void)capacity; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMPOOL != 0) && !defined(EVR_RTX_MEMORY_POOL_GET_BLOCK_SZIE_DISABLE)) +__WEAK void EvrRtxMemoryPoolGetBlockSize (osMemoryPoolId_t mp_id, uint32_t block_size) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxMemoryPoolGetBlockSize, (uint32_t)mp_id, block_size); +#else + (void)mp_id; + (void)block_size; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMPOOL != 0) && !defined(EVR_RTX_MEMORY_POOL_GET_COUNT_DISABLE)) +__WEAK void EvrRtxMemoryPoolGetCount (osMemoryPoolId_t mp_id, uint32_t count) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxMemoryPoolGetCount, (uint32_t)mp_id, count); +#else + (void)mp_id; + (void)count; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMPOOL != 0) && !defined(EVR_RTX_MEMORY_POOL_GET_SPACE_DISABLE)) +__WEAK void EvrRtxMemoryPoolGetSpace (osMemoryPoolId_t mp_id, uint32_t space) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxMemoryPoolGetSpace, (uint32_t)mp_id, space); +#else + (void)mp_id; + (void)space; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMPOOL != 0) && !defined(EVR_RTX_MEMORY_POOL_DELETE_DISABLE)) +__WEAK void EvrRtxMemoryPoolDelete (osMemoryPoolId_t mp_id) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxMemoryPoolDelete, (uint32_t)mp_id, 0U); +#else + (void)mp_id; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMPOOL != 0) && !defined(EVR_RTX_MEMORY_POOL_DESTROYED_DISABLE)) +__WEAK void EvrRtxMemoryPoolDestroyed (osMemoryPoolId_t mp_id) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxMemoryPoolDestroyed, (uint32_t)mp_id, 0U); +#else + (void)mp_id; +#endif +} +#endif + + +// ==== Message Queue Events ==== + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_ERROR_DISABLE)) +__WEAK void EvrRtxMessageQueueError (osMessageQueueId_t mq_id, int32_t status) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2 (EvtRtxMessageQueueError, (uint32_t)mq_id, (uint32_t)status); +#else + (void)mq_id; + (void)status; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_NEW_DISABLE)) +__WEAK void EvrRtxMessageQueueNew (uint32_t msg_count, uint32_t msg_size, const osMessageQueueAttr_t *attr) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord4(EvtRtxMessageQueueNew, msg_count, msg_size, (uint32_t)attr, 0U); + if (attr != NULL) { + EventRecordData(EvtRtxMessageQueueNew_Detail, attr, sizeof (osMemoryPoolAttr_t)); + } +#else + (void)msg_count; + (void)msg_size; + (void)attr; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_CREATED_DISABLE)) +__WEAK void EvrRtxMessageQueueCreated (osMessageQueueId_t mq_id) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxMessageQueueCreated, (uint32_t)mq_id, 0U); +#else + (void)mq_id; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_GET_NAME_DISABLE)) +__WEAK void EvrRtxMessageQueueGetName (osMessageQueueId_t mq_id, const char *name) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxMessageQueueGetName, (uint32_t)mq_id, (uint32_t)name); + if (name != NULL) { + EventRecordData(EvtRtxMessageQueueGetName_Detail, name, strlen(name)); + } +#else + (void)mq_id; + (void)name; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_PUT_DISABLE)) +__WEAK void EvrRtxMessageQueuePut (osMessageQueueId_t mq_id, const void *msg_ptr, uint8_t msg_prio, uint32_t timeout) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord4(EvtRtxMessageQueuePut, (uint32_t)mq_id, (uint32_t)msg_ptr, (uint32_t)msg_prio, timeout); +#else + (void)mq_id; + (void)msg_ptr; + (void)msg_prio; + (void)timeout; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_PUT_PENDING_DISABLE)) +__WEAK void EvrRtxMessageQueuePutPending (osMessageQueueId_t mq_id, const void *msg_ptr, uint32_t timeout) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord4(EvtRtxMessageQueuePutPending, (uint32_t)mq_id, (uint32_t)msg_ptr, timeout, 0U); +#else + (void)mq_id; + (void)msg_ptr; + (void)timeout; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_PUT_TIMEOUT_DISABLE)) +__WEAK void EvrRtxMessageQueuePutTimeout (osMessageQueueId_t mq_id) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxMessageQueuePutTimeout, (uint32_t)mq_id, 0U); +#else + (void)mq_id; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_INSERT_PENDING_DISABLE)) +__WEAK void EvrRtxMessageQueueInsertPending (osMessageQueueId_t mq_id, const void *msg_ptr) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxMessageQueueInsertPending, (uint32_t)mq_id, (uint32_t)msg_ptr); +#else + (void)mq_id; + (void)msg_ptr; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_INSERTED_DISABLE)) +__WEAK void EvrRtxMessageQueueInserted (osMessageQueueId_t mq_id, const void *msg_ptr) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxMessageQueueInserted, (uint32_t)mq_id, (uint32_t)msg_ptr); +#else + (void)mq_id; + (void)msg_ptr; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_NOT_INSERTED_DISABLE)) +__WEAK void EvrRtxMessageQueueNotInserted (osMessageQueueId_t mq_id, const void *msg_ptr) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxMessageQueueNotInserted, (uint32_t)mq_id, (uint32_t)msg_ptr); +#else + (void)mq_id; + (void)msg_ptr; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_GET_DISABLE)) +__WEAK void EvrRtxMessageQueueGet (osMessageQueueId_t mq_id, void *msg_ptr, uint8_t *msg_prio, uint32_t timeout) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord4(EvtRtxMessageQueueGet, (uint32_t)mq_id, (uint32_t)msg_ptr, (uint32_t)msg_prio, timeout); +#else + (void)mq_id; + (void)msg_ptr; + (void)msg_prio; + (void)timeout; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_GET_PENDING_DISABLE)) +__WEAK void EvrRtxMessageQueueGetPending (osMessageQueueId_t mq_id, void *msg_ptr, uint32_t timeout) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord4(EvtRtxMessageQueueGetPending, (uint32_t)mq_id, (uint32_t)msg_ptr, timeout, 0U); +#else + (void)mq_id; + (void)msg_ptr; + (void)timeout; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_GET_TIMEOUT_DISABLE)) +__WEAK void EvrRtxMessageQueueGetTimeout (osMessageQueueId_t mq_id) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxMessageQueueGetTimeout, (uint32_t)mq_id, 0U); +#else + (void)mq_id; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_RETRIEVED_DISABLE)) +__WEAK void EvrRtxMessageQueueRetrieved (osMessageQueueId_t mq_id, void *msg_ptr) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxMessageQueueRetrieved, (uint32_t)mq_id, (uint32_t)msg_ptr); +#else + (void)mq_id; + (void)msg_ptr; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_NOT_RETRIEVED_DISABLE)) +__WEAK void EvrRtxMessageQueueNotRetrieved (osMessageQueueId_t mq_id, void *msg_ptr) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxMessageQueueNotRetrieved, (uint32_t)mq_id, (uint32_t)msg_ptr); +#else + (void)mq_id; + (void)msg_ptr; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_GET_CAPACITY_DISABLE)) +__WEAK void EvrRtxMessageQueueGetCapacity (osMessageQueueId_t mq_id, uint32_t capacity) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxMessageQueueGetCapacity, (uint32_t)mq_id, capacity); +#else + (void)mq_id; + (void)capacity; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_GET_MSG_SIZE_DISABLE)) +__WEAK void EvrRtxMessageQueueGetMsgSize (osMessageQueueId_t mq_id, uint32_t msg_size) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxMessageQueueGetMsgSize, (uint32_t)mq_id, msg_size); +#else + (void)mq_id; + (void)msg_size; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_GET_COUNT_DISABLE)) +__WEAK void EvrRtxMessageQueueGetCount (osMessageQueueId_t mq_id, uint32_t count) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxMessageQueueGetCount, (uint32_t)mq_id, count); +#else + (void)mq_id; + (void)count; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_GET_SPACE_DISABLE)) +__WEAK void EvrRtxMessageQueueGetSpace (osMessageQueueId_t mq_id, uint32_t space) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxMessageQueueGetSpace, (uint32_t)mq_id, space); +#else + (void)mq_id; + (void)space; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_RESET_DISABLE)) +__WEAK void EvrRtxMessageQueueReset (osMessageQueueId_t mq_id) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxMessageQueueReset, (uint32_t)mq_id, 0U); +#else + (void)mq_id; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_RESET_DONE_DISABLE)) +__WEAK void EvrRtxMessageQueueResetDone (osMessageQueueId_t mq_id) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxMessageQueueResetDone, (uint32_t)mq_id, 0U); +#else + (void)mq_id; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_DELETE_DISABLE)) +__WEAK void EvrRtxMessageQueueDelete (osMessageQueueId_t mq_id) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxMessageQueueDelete, (uint32_t)mq_id, 0U); +#else + (void)mq_id; +#endif +} +#endif + +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_DESTROYED_DISABLE)) +__WEAK void EvrRtxMessageQueueDestroyed (osMessageQueueId_t mq_id) { +#if defined(RTE_Compiler_EventRecorder) + EventRecord2(EvtRtxMessageQueueDestroyed, (uint32_t)mq_id, 0U); +#else + (void)mq_id; +#endif +} +#endif diff --git a/rtos/rtx2/TARGET_CORTEX_M/rtx_evr.h b/rtos/rtx2/TARGET_CORTEX_M/rtx_evr.h new file mode 100644 index 00000000000..e18c2d766e5 --- /dev/null +++ b/rtos/rtx2/TARGET_CORTEX_M/rtx_evr.h @@ -0,0 +1,1844 @@ +/* + * Copyright (c) 2013-2017 ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ----------------------------------------------------------------------------- + * + * Project: CMSIS-RTOS RTX + * Title: RTX Event Recorder definitions + * + * ----------------------------------------------------------------------------- + */ + +#ifndef RTX_EVR_H_ +#define RTX_EVR_H_ + +#include "cmsis_os2.h" // CMSIS RTOS API +#include "rtx_os.h" // RTX OS definitions +#include "RTX_Config.h" + + +/// Extended Status codes +#define osRtxErrorKernelNotReady (-7) +#define osRtxErrorKernelNotRunning (-8) +#define osRtxErrorInvalidControlBlock (-9) +#define osRtxErrorInvalidDataMemory (-10) +#define osRtxErrorInvalidThreadStack (-11) +#define osRtxErrorInvalidPriority (-12) +#define osRtxErrorThreadNotJoinable (-13) +#define osRtxErrorMutexNotOwned (-14) +#define osRtxErrorMutexNotLocked (-15) +#define osRtxErrorMutexLockLimit (-16) +#define osRtxErrorSemaphoreCountLimit (-17) +#define osRtxErrorTZ_InitContext_S (-18) +#define osRtxErrorTZ_AllocContext_S (-19) +#define osRtxErrorTZ_FreeContext_S (-20) +#define osRtxErrorTZ_LoadContext_S (-21) +#define osRtxErrorTZ_SaveContext_S (-22) + + +// ==== Memory Events ==== + +/** + \brief Event on memory initialization (Op) + \param[in] mem pointer to memory pool. + \param[in] size size of a memory pool in bytes. + \param[in] result execution status: 1 - success, 0 - failure. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMORY != 0) && !defined(EVR_RTX_MEMORY_INIT_DISABLE)) +extern void EvrRtxMemoryInit (void *mem, uint32_t size, uint32_t result); +#else +#define EvrRtxMemoryInit(mem, size, result) +#endif + +/** + \brief Event on memory allocate (Op) + \param[in] mem pointer to memory pool. + \param[in] size size of a memory block in bytes. + \param[in] type memory block type: 0 - generic, 1 - control block + \param[in] block pointer to allocated memory block or NULL in case of no memory is available. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMORY != 0) && !defined(EVR_RTX_MEMORY_ALLOC_DISABLE)) +extern void EvrRtxMemoryAlloc (void *mem, uint32_t size, uint32_t type, void *block); +#else +#define EvrRtxMemoryAlloc(mem, size, type, block) +#endif + +/** + \brief Event on memory free (Op) + \param[in] mem pointer to memory pool. + \param[in] block memory block to be returned to the memory pool. + \param[in] result execution status: 1 - success, 0 - failure. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMORY != 0) && !defined(EVR_RTX_MEMORY_FREE_DISABLE)) +extern void EvrRtxMemoryFree (void *mem, void *block, uint32_t result); +#else +#define EvrRtxMemoryFree(mem, block, result) +#endif + +/** + \brief Event on memory block initialization (Op) + \param[in] mp_info memory pool info. + \param[in] block_count maximum number of memory blocks in memory pool. + \param[in] block_size size of a memory block in bytes. + \param[in] block_mem pointer to memory for block storage. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMORY != 0) && !defined(EVR_RTX_MEMORY_BLOCK_INIT_DISABLE)) +extern void EvrRtxMemoryBlockInit (osRtxMpInfo_t *mp_info, uint32_t block_count, uint32_t block_size, void *block_mem); +#else +#define EvrRtxMemoryBlockInit(mp_info, block_count, block_size, block_mem) +#endif + +/** + \brief Event on memory block alloc (Op) + \param[in] mp_info memory pool info. + \param[in] block address of the allocated memory block or NULL in case of no memory is available. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMORY != 0) && !defined(EVR_RTX_MEMORY_BLOCK_ALLOC_DISABLE)) +extern void EvrRtxMemoryBlockAlloc (osRtxMpInfo_t *mp_info, void *block); +#else +#define EvrRtxMemoryBlockAlloc(mp_info, block) +#endif + +/** + \brief Event on memory block free (Op) + \param[in] mp_info memory pool info. + \param[in] block address of the allocated memory block to be returned to the memory pool. + \param[in] status extended execution status. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMORY != 0) && !defined(EVR_RTX_MEMORY_BLOCK_FREE_DISABLE)) +extern void EvrRtxMemoryBlockFree (osRtxMpInfo_t *mp_info, void *block, int32_t status); +#else +#define EvrRtxMemoryBlockFree(mp_info, block, status) +#endif + + +// ==== Kernel Events ==== + +/** + \brief Event on RTOS kernel error (Error) + \param[in] status extended execution status. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_ERROR_DISABLE)) +extern void EvrRtxKernelError (int32_t status); +#else +#define EvrRtxKernelError(status) +#endif + +/** + \brief Event on RTOS kernel initialize (API) +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_INITIALIZE_DISABLE)) +extern void EvrRtxKernelInitialize (void); +#else +#define EvrRtxKernelInitialize() +#endif + +/** + \brief Event on successful RTOS kernel initialize (Op) +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_INITIALIZE_COMPLETED_DISABLE)) +extern void EvrRtxKernelInitializeCompleted (void); +#else +#define EvrRtxKernelInitializeCompleted() +#endif + +/** + \brief Event on RTOS kernel information retrieve (API) + \param[in] version pointer to buffer for retrieving version information. + \param[in] id_buf pointer to buffer for retrieving kernel identification string. + \param[in] id_size size of buffer for kernel identification string. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_GET_INFO_DISABLE)) +extern void EvrRtxKernelGetInfo (osVersion_t *version, char *id_buf, uint32_t id_size); +#else +#define EvrRtxKernelGetInfo(version, id_buf, id_size) +#endif + +/** + \brief Event on successful RTOS kernel information retrieve (Op) + \param[in] version pointer to buffer for retrieving version information. + \param[in] id_buf pointer to buffer for retrieving kernel identification string. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_INFO_RETRIEVED_DISABLE)) +extern void EvrRtxKernelInfoRetrieved (osVersion_t *version, char *id_buf); +#else +#define EvrRtxKernelInfoRetrieved(version, id_buf) +#endif + +/** + \brief Event on current RTOS Kernel state retrieve (API) + \param[in] state current RTOS Kernel state. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_GET_STATE_DISABLE)) +extern void EvrRtxKernelGetState (osKernelState_t state); +#else +#define EvrRtxKernelGetState(state) +#endif + +/** + \brief Event on RTOS Kernel scheduler start (API) +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_START_DISABLE)) +extern void EvrRtxKernelStart (void); +#else +#define EvrRtxKernelStart() +#endif + +/** + \brief Event on successful RTOS Kernel scheduler start (Op) +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_STARTED_DISABLE)) +extern void EvrRtxKernelStarted (void); +#else +#define EvrRtxKernelStarted() +#endif + +/** + \brief Event on RTOS Kernel scheduler lock (API) +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_LOCK_DISABLE)) +extern void EvrRtxKernelLock (void); +#else +#define EvrRtxKernelLock() +#endif + +/** + \brief Event on successful RTOS Kernel scheduler lock (Op) + \param[in] lock previous lock state (1 - locked, 0 - not locked). +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_LOCKED_DISABLE)) +extern void EvrRtxKernelLocked (int32_t lock); +#else +#define EvrRtxKernelLocked(lock) +#endif + +/** + \brief Event on RTOS Kernel scheduler unlock (API) +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_UNLOCK_DISABLE)) +extern void EvrRtxKernelUnlock (void); +#else +#define EvrRtxKernelUnlock() +#endif + +/** + \brief Event on successful RTOS Kernel scheduler unlock (Op) + \param[in] lock previous lock state (1 - locked, 0 - not locked). +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_UNLOCKED_DISABLE)) +extern void EvrRtxKernelUnlocked (int32_t lock); +#else +#define EvrRtxKernelUnlocked(lock) +#endif + +/** + \brief Event on RTOS Kernel scheduler lock state restore (API) + \param[in] lock lock state obtained by \ref osKernelLock or \ref osKernelUnlock. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_RESTORE_LOCK_DISABLE)) +extern void EvrRtxKernelRestoreLock (int32_t lock); +#else +#define EvrRtxKernelRestoreLock(lock) +#endif + +/** + \brief Event on successful RTOS Kernel scheduler lock state restore (Op) + \param[in] lock new lock state (1 - locked, 0 - not locked). +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_LOCK_RESTORED_DISABLE)) +extern void EvrRtxKernelLockRestored (int32_t lock); +#else +#define EvrRtxKernelLockRestored(lock) +#endif + +/** + \brief Event on RTOS Kernel scheduler suspend (API) +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_SUSPEND_DISABLE)) +extern void EvrRtxKernelSuspend (void); +#else +#define EvrRtxKernelSuspend() +#endif + +/** + \brief Event on successful RTOS Kernel scheduler suspend (Op) + \param[in] sleep_ticks time in ticks, for how long the system can sleep or power-down. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_SUSPENDED_DISABLE)) +extern void EvrRtxKernelSuspended (uint32_t sleep_ticks); +#else +#define EvrRtxKernelSuspended(sleep_ticks) +#endif + +/** + \brief Event on RTOS Kernel scheduler resume (API) + \param[in] sleep_ticks time in ticks, for how long the system was in sleep or power-down mode. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_RESUME_DISABLE)) +extern void EvrRtxKernelResume (uint32_t sleep_ticks); +#else +#define EvrRtxKernelResume(sleep_ticks) +#endif + +/** + \brief Event on successful RTOS Kernel scheduler resume (Op) +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_RESUMED_DISABLE)) +extern void EvrRtxKernelResumed (void); +#else +#define EvrRtxKernelResumed() +#endif + +/** + \brief Event on RTOS kernel tick count retrieve (API) + \param[in] count RTOS kernel current tick count. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_GET_TICK_COUNT_DISABLE)) +extern void EvrRtxKernelGetTickCount (uint64_t count); +#else +#define EvrRtxKernelGetTickCount(count) +#endif + +/** + \brief Event on RTOS kernel tick frequency retrieve (API) + \param[in] freq frequency of the kernel tick. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_GET_TICK_FREQ_DISABLE)) +extern void EvrRtxKernelGetTickFreq (uint32_t freq); +#else +#define EvrRtxKernelGetTickFreq(freq) +#endif + +/** + \brief Event on RTOS kernel system timer count retrieve (API) + \param[in] count RTOS kernel current system timer count as 32-bit value. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_GET_SYS_TIMER_COUNT_DISABLE)) +extern void EvrRtxKernelGetSysTimerCount (uint32_t count); +#else +#define EvrRtxKernelGetSysTimerCount(count) +#endif + +/** + \brief Event on RTOS kernel system timer frequency retrieve (API) + \param[in] freq frequency of the system timer. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_GET_SYS_TIMER_FREQ_DISABLE)) +extern void EvrRtxKernelGetSysTimerFreq (uint32_t freq); +#else +#define EvrRtxKernelGetSysTimerFreq(freq) +#endif + + +// ==== Thread Events ==== + +/** + \brief Event on thread error (Error) + \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId or NULL when ID is unknown. + \param[in] status extended execution status. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_ERROR_DISABLE)) +extern void EvrRtxThreadError (osThreadId_t thread_id, int32_t status); +#else +#define EvrRtxThreadError(thread_id, status) +#endif + +/** + \brief Event on thread create and intialize (API) + \param[in] func thread function. + \param[in] argument pointer that is passed to the thread function as start argument. + \param[in] attr thread attributes. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_NEW_DISABLE)) +extern void EvrRtxThreadNew (osThreadFunc_t func, void *argument, const osThreadAttr_t *attr); +#else +#define EvrRtxThreadNew(func, argument, attr) +#endif + +/** + \brief Event on successful thread create (Op) + \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_CREATED_DISABLE)) +extern void EvrRtxThreadCreated (osThreadId_t thread_id); +#else +#define EvrRtxThreadCreated(thread_id) +#endif + +/** + \brief Event on thread name retrieve (API) + \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. + \param[in] name pointer to thread object name +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_GET_NAME_DISABLE)) +extern void EvrRtxThreadGetName (osThreadId_t thread_id, const char *name); +#else +#define EvrRtxThreadGetName(thread_id, name) +#endif + +/** + \brief Event on current running thread ID retrieve (API) + \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_GET_ID_DISABLE)) +extern void EvrRtxThreadGetId (osThreadId_t thread_id); +#else +#define EvrRtxThreadGetId(thread_id) +#endif + +/** + \brief Event on thread state retrieve (API) + \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. + \param[in] state current thread state of the specified thread. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_GET_STATE_DISABLE)) +extern void EvrRtxThreadGetState (osThreadId_t thread_id, osThreadState_t state); +#else +#define EvrRtxThreadGetState(thread_id, state) +#endif + +/** + \brief Event on thread stack size retrieve (API) + \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. + \param[in] stack_size stack size in bytes. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_GET_STACK_SIZE_DISABLE)) +extern void EvrRtxThreadGetStackSize (osThreadId_t thread_id, uint32_t stack_size); +#else +#define EvrRtxThreadGetStackSize(thread_id, stack_size) +#endif + +/** + \brief Event on available stack space retrieve (API) + \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. + \param[in] stack_space remaining stack space in bytes. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_GET_STACK_SPACE_DISABLE)) +extern void EvrRtxThreadGetStackSpace (osThreadId_t thread_id, uint32_t stack_space); +#else +#define EvrRtxThreadGetStackSpace(thread_id, stack_space) +#endif + +/** + \brief Event on thread priority set (API) + \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. + \param[in] priority new priority value for the thread function. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_SET_PRIORITY_DISABLE)) +extern void EvrRtxThreadSetPriority (osThreadId_t thread_id, osPriority_t priority); +#else +#define EvrRtxThreadSetPriority(thread_id, priority) +#endif + +/** + \brief Event on thread priority retrieve (API) + \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. + \param[in] priority current priority value of the specified thread. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_GET_PRIORITY_DISABLE)) +extern void EvrRtxThreadGetPriority (osThreadId_t thread_id, osPriority_t priority); +#else +#define EvrRtxThreadGetPriority(thread_id, priority) +#endif + +/** + \brief Event on thread yield (API) +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_YIELD_DISABLE)) +extern void EvrRtxThreadYield (void); +#else +#define EvrRtxThreadYield() +#endif + +/** + \brief Event on thread suspend (API) + \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_SUSPEND_DISABLE)) +extern void EvrRtxThreadSuspend (osThreadId_t thread_id); +#else +#define EvrRtxThreadSuspend(thread_id) +#endif + +/** + \brief Event on successful thread suspend (Op) + \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_SUSPENDED_DISABLE)) +extern void EvrRtxThreadSuspended (osThreadId_t thread_id); +#else +#define EvrRtxThreadSuspended(thread_id) +#endif + +/** + \brief Event on thread resume (API) + \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_RESUME_DISABLE)) +extern void EvrRtxThreadResume (osThreadId_t thread_id); +#else +#define EvrRtxThreadResume(thread_id) +#endif + +/** + \brief Event on successful thread resume (Op) + \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_RESUMED_DISABLE)) +extern void EvrRtxThreadResumed (osThreadId_t thread_id); +#else +#define EvrRtxThreadResumed(thread_id) +#endif + +/** + \brief Event on thread detach (API) + \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_DETACH_DISABLE)) +extern void EvrRtxThreadDetach (osThreadId_t thread_id); +#else +#define EvrRtxThreadDetach(thread_id) +#endif + +/** + \brief Event on successful thread detach (Op) + \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_DETACHED_DISABLE)) +extern void EvrRtxThreadDetached (osThreadId_t thread_id); +#else +#define EvrRtxThreadDetached(thread_id) +#endif + +/** + \brief Event on thread join (API) + \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_JOIN_DISABLE)) +extern void EvrRtxThreadJoin (osThreadId_t thread_id); +#else +#define EvrRtxThreadJoin(thread_id) +#endif + +/** + \brief Event on pending thread join (Op) + \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_JOIN_PENDING_DISABLE)) +extern void EvrRtxThreadJoinPending (osThreadId_t thread_id); +#else +#define EvrRtxThreadJoinPending(thread_id) +#endif + +/** + \brief Event on successful thread join (Op) + \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_JOINED_DISABLE)) +extern void EvrRtxThreadJoined (osThreadId_t thread_id); +#else +#define EvrRtxThreadJoined(thread_id) +#endif + +/** + \brief Event on thread execution block (Op) + \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. + \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_BLOCKED_DISABLE)) +extern void EvrRtxThreadBlocked (osThreadId_t thread_id, uint32_t timeout); +#else +#define EvrRtxThreadBlocked(thread_id, timeout) +#endif + +/** + \brief Event on blocked thread release (Op) + \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. + \param[in] ret_val extended execution status of the thread. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_UNBLOCKED_DISABLE)) +extern void EvrRtxThreadUnblocked (osThreadId_t thread_id, uint32_t ret_val); +#else +#define EvrRtxThreadUnblocked(thread_id, ret_val) +#endif + +/** + \brief Event on current running thread switch (Op) + \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_SWITCH_DISABLE)) +extern void EvrRtxThreadSwitch (osThreadId_t thread_id); +#else +#define EvrRtxThreadSwitch(thread_id) +#endif + +/** + \brief Event on thread exit (API) +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_EXIT_DISABLE)) +extern void EvrRtxThreadExit (void); +#else +#define EvrRtxThreadExit() +#endif + +/** + \brief Event on thread terminate (API) + \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_TERMINATE_DISABLE)) +extern void EvrRtxThreadTerminate (osThreadId_t thread_id); +#else +#define EvrRtxThreadTerminate(thread_id) +#endif + +/** + \brief Event on successful thread terminate (Op) + \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_DESTROYED_DISABLE)) +extern void EvrRtxThreadDestroyed (osThreadId_t thread_id); +#else +#define EvrRtxThreadDestroyed(thread_id) +#endif + +/** + \brief Event on active thread count retrieve (API) + \param[in] count number of active threads. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_GET_COUNT_DISABLE)) +extern void EvrRtxThreadGetCount (uint32_t count); +#else +#define EvrRtxThreadGetCount(count) +#endif + +/** + \brief Event on active threads enumerate (API) + \param[in] thread_array pointer to array for retrieving thread IDs. + \param[in] array_items maximum number of items in array for retrieving thread IDs. + \param[in] count number of enumerated threads. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_ENUMERATE_DISABLE)) +extern void EvrRtxThreadEnumerate (osThreadId_t *thread_array, uint32_t array_items, uint32_t count); +#else +#define EvrRtxThreadEnumerate(thread_array, array_items, count) +#endif + +/** + \brief Event on thread flags set (API) + \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. + \param[in] flags flags of the thread that shall be set. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_FLAGS_SET_DISABLE)) +extern void EvrRtxThreadFlagsSet (osThreadId_t thread_id, uint32_t flags); +#else +#define EvrRtxThreadFlagsSet(thread_id, flags) +#endif + +/** + \brief Event on successful thread flags set (Op) + \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. + \param[in] thread_flags thread flags after setting +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_FLAGS_SET_DONE_DISABLE)) +extern void EvrRtxThreadFlagsSetDone (osThreadId_t thread_id, uint32_t thread_flags); +#else +#define EvrRtxThreadFlagsSetDone(thread_id, thread_flags) +#endif + +/** + \brief Event on thread flags clear (API) + \param[in] flags flags of the thread that shall be cleared. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_FLAGS_CLEAR_DISABLE)) +extern void EvrRtxThreadFlagsClear (uint32_t flags); +#else +#define EvrRtxThreadFlagsClear(flags) +#endif + +/** + \brief Event on successful thread flags clear (Op) + \param[in] thread_flags thread flags before clearing +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_FLAGS_CLEAR_DONE_DISABLE)) +extern void EvrRtxThreadFlagsClearDone (uint32_t thread_flags); +#else +#define EvrRtxThreadFlagsClearDone(thread_flags) +#endif + +/** + \brief Event on thread flags retrieve (API) + \param[in] thread_flags current thread flags. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_FLAGS_GET_DISABLE)) +extern void EvrRtxThreadFlagsGet (uint32_t thread_flags); +#else +#define EvrRtxThreadFlagsGet(thread_flags) +#endif + +/** + \brief Event on wait for thread flags (API) + \param[in] flags flags to wait for. + \param[in] options flags options (osFlagsXxxx). + \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_FLAGS_WAIT_DISABLE)) +extern void EvrRtxThreadFlagsWait (uint32_t flags, uint32_t options, uint32_t timeout); +#else +#define EvrRtxThreadFlagsWait(flags, options, timeout) +#endif + +/** + \brief Event on pending wait for thread flags (Op) + \param[in] flags flags to wait for. + \param[in] options flags options (osFlagsXxxx). + \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_FLAGS_WAIT_PENDING_DISABLE)) +extern void EvrRtxThreadFlagsWaitPending (uint32_t flags, uint32_t options, uint32_t timeout); +#else +#define EvrRtxThreadFlagsWaitPending(flags, options, timeout) +#endif + +/** + \brief Event on wait timeout for thread flags (Op) +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_FLAGS_WAIT_TIMEOUT_DISABLE)) +extern void EvrRtxThreadFlagsWaitTimeout (void); +#else +#define EvrRtxThreadFlagsWaitTimeout() +#endif + +/** + \brief Event on successful wait for thread flags (Op) + \param[in] flags flags to wait for. + \param[in] options flags options (osFlagsXxxx). + \param[in] thread_flags thread flags before clearing +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_FLAGS_WAIT_COMPLETED_DISABLE)) +extern void EvrRtxThreadFlagsWaitCompleted (uint32_t flags, uint32_t options, uint32_t thread_flags); +#else +#define EvrRtxThreadFlagsWaitCompleted(flags, options, thread_flags) +#endif + +/** + \brief Event on unsuccessful wait for thread flags (Op) + \param[in] flags flags to wait for. + \param[in] options flags options (osFlagsXxxx). +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_FLAGS_WAIT_NOT_COMPLETED_DISABLE)) +extern void EvrRtxThreadFlagsWaitNotCompleted (uint32_t flags, uint32_t options); +#else +#define EvrRtxThreadFlagsWaitNotCompleted(flags, options) +#endif + +/** + \brief Event on wait for timeout (API) + \param[in] ticks \ref CMSIS_RTOS_TimeOutValue "time ticks" value +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_DELAY_DISABLE)) +extern void EvrRtxThreadDelay (uint32_t ticks); +#else +#define EvrRtxThreadDelay(ticks) +#endif + +/** + \brief Event on wait until specified time (API) + \param[in] ticks absolute time in ticks +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_DELAY_UNTIL_DISABLE)) +extern void EvrRtxThreadDelayUntil (uint64_t ticks); +#else +#define EvrRtxThreadDelayUntil(ticks) +#endif + +/** + \brief Event on completed wait (Op) +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_DELAY_COMPLETED_DISABLE)) +extern void EvrRtxThreadDelayCompleted (void); +#else +#define EvrRtxThreadDelayCompleted() +#endif + + + +// ==== Timer Events ==== + +/** + \brief Event on timer error (Error) + \param[in] timer_id timer ID obtained by \ref osTimerNew or NULL when ID is unknown. + \param[in] status extended execution status. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_TIMER != 0) && !defined(EVR_RTX_TIMER_ERROR_DISABLE)) +extern void EvrRtxTimerError (osTimerId_t timer_id, int32_t status); +#else +#define EvrRtxTimerError(timer_id, status); +#endif + +/** + \brief Event on timer callback call (Op) + \param[in] func start address of a timer call back function. + \param[in] argument argument to the timer call back function. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_TIMER != 0) && !defined(EVR_RTX_TIMER_CALLBACK_DISABLE)) +extern void EvrRtxTimerCallback (osTimerFunc_t func, void *argument); +#else +#define EvrRtxTimerCallback(func, argument); +#endif + +/** + \brief Event on timer create and initialize (API) + \param[in] func start address of a timer call back function. + \param[in] type osTimerOnce for one-shot or osTimerPeriodic for periodic behavior. + \param[in] argument argument to the timer call back function. + \param[in] attr timer attributes. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_TIMER != 0) && !defined(EVR_RTX_TIMER_NEW_DISABLE)) +extern void EvrRtxTimerNew (osTimerFunc_t func, osTimerType_t type, void *argument, const osTimerAttr_t *attr); +#else +#define EvrRtxTimerNew(func, type, argument, attr); +#endif + +/** + \brief Event on successful timer create (Op) + \param[in] timer_id timer ID obtained by \ref osTimerNew +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_TIMER != 0) && !defined(EVR_RTX_TIMER_CREATED_DISABLE)) +extern void EvrRtxTimerCreated (osTimerId_t timer_id); +#else +#define EvrRtxTimerCreated(timer_id); +#endif + +/** + \brief Event on timer name retrieve (API) + \param[in] timer_id timer ID obtained by \ref osTimerNew + \param[in] name pointer to timer object name. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_TIMER != 0) && !defined(EVR_RTX_TIMER_GET_NAME_DISABLE)) +extern void EvrRtxTimerGetName (osTimerId_t timer_id, const char *name); +#else +#define EvrRtxTimerGetName(timer_id, name); +#endif + +/** + \brief Event on timer start (API) + \param[in] timer_id timer ID obtained by \ref osTimerNew + \param[in] ticks \ref CMSIS_RTOS_TimeOutValue "time ticks" value of the timer. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_TIMER != 0) && !defined(EVR_RTX_TIMER_START_DISABLE)) +extern void EvrRtxTimerStart (osTimerId_t timer_id, uint32_t ticks); +#else +#define EvrRtxTimerStart(timer_id, ticks); +#endif + +/** + \brief Event on successful timer start (Op) + \param[in] timer_id timer ID obtained by \ref osTimerNew +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_TIMER != 0) && !defined(EVR_RTX_TIMER_STARTED_DISABLE)) +extern void EvrRtxTimerStarted (osTimerId_t timer_id); +#else +#define EvrRtxTimerStarted(timer_id); +#endif + +/** + \brief Event on timer stop (API) + \param[in] timer_id timer ID obtained by \ref osTimerNew +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_TIMER != 0) && !defined(EVR_RTX_TIMER_STOP_DISABLE)) +extern void EvrRtxTimerStop (osTimerId_t timer_id); +#else +#define EvrRtxTimerStop(timer_id); +#endif + +/** + \brief Event on successful timer stop (Op) + \param[in] timer_id timer ID obtained by \ref osTimerNew +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_TIMER != 0) && !defined(EVR_RTX_TIMER_STOPPED_DISABLE)) +extern void EvrRtxTimerStopped (osTimerId_t timer_id); +#else +#define EvrRtxTimerStopped(timer_id); +#endif + +/** + \brief Event on timer running state check (API) + \param[in] timer_id timer ID obtained by \ref osTimerNew + \param[in] running running state: 0 not running, 1 running +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_TIMER != 0) && !defined(EVR_RTX_TIMER_IS_RUNNING_DISABLE)) +extern void EvrRtxTimerIsRunning (osTimerId_t timer_id, uint32_t running); +#else +#define EvrRtxTimerIsRunning(timer_id, running); +#endif + +/** + \brief Event on timer delete (API) + \param[in] timer_id timer ID obtained by \ref osTimerNew +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_TIMER != 0) && !defined(EVR_RTX_TIMER_DELETE_DISABLE)) +extern void EvrRtxTimerDelete (osTimerId_t timer_id); +#else +#define EvrRtxTimerDelete(timer_id); +#endif + +/** + \brief Event on successful timer delete (Op) + \param[in] timer_id timer ID obtained by \ref osTimerNew +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_TIMER != 0) && !defined(EVR_RTX_TIMER_DESTROYED_DISABLE)) +extern void EvrRtxTimerDestroyed (osTimerId_t timer_id); +#else +#define EvrRtxTimerDestroyed(timer_id); +#endif + + +// ==== Event Flags Events ==== + +/** + \brief Event on event flags error (Error) + \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew or NULL when ID is unknown. + \param[in] status extended execution status. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_EVFLAGS != 0) && !defined(EVR_RTX_EVENT_FLAGS_ERROR_DISABLE)) +extern void EvrRtxEventFlagsError (osEventFlagsId_t ef_id, int32_t status); +#else +#define EvrRtxEventFlagsError(ef_id, status) +#endif + +/** + \brief Event on event flags create and initialize (API) + \param[in] attr event flags attributes +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_EVFLAGS != 0) && !defined(EVR_RTX_EVENT_FLAGS_NEW_DISABLE)) +extern void EvrRtxEventFlagsNew (const osEventFlagsAttr_t *attr); +#else +#define EvrRtxEventFlagsNew(attr) +#endif + +/** + \brief Event on successful event flags create (Op) + \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_EVFLAGS != 0) && !defined(EVR_RTX_EVENT_FLAGS_CREATED_DISABLE)) +extern void EvrRtxEventFlagsCreated (osEventFlagsId_t ef_id); +#else +#define EvrRtxEventFlagsCreated(ef_id) +#endif + +/** + \brief Event on event flags name retrieve (API) + \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew. + \param[in] name pointer to event flags object name. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_EVFLAGS != 0) && !defined(EVR_RTX_EVENT_FLAGS_GET_NAME_DISABLE)) +extern void EvrRtxEventFlagsGetName (osEventFlagsId_t ef_id, const char *name); +#else +#define EvrRtxEventFlagsGetName(ef_id, name) +#endif + +/** + \brief Event on event flags set (API) + \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew. + \param[in] flags flags that shall be set. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_EVFLAGS != 0) && !defined(EVR_RTX_EVENT_FLAGS_SET_DISABLE)) +extern void EvrRtxEventFlagsSet (osEventFlagsId_t ef_id, uint32_t flags); +#else +#define EvrRtxEventFlagsSet(ef_id, flags) +#endif + +/** + \brief Event on successful event flags set (Op) + \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew. + \param[in] event_flags event flags after setting +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_EVFLAGS != 0) && !defined(EVR_RTX_EVENT_FLAGS_SET_DONE_DISABLE)) +extern void EvrRtxEventFlagsSetDone (osEventFlagsId_t ef_id, uint32_t event_flags); +#else +#define EvrRtxEventFlagsSetDone(ef_id, event_flags) +#endif + +/** + \brief Event on event flags clear (API) + \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew. + \param[in] flags flags that shall be cleared. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_EVFLAGS != 0) && !defined(EVR_RTX_EVENT_FLAGS_CLEAR_DISABLE)) +extern void EvrRtxEventFlagsClear (osEventFlagsId_t ef_id, uint32_t flags); +#else +#define EvrRtxEventFlagsClear(ef_id, flags) +#endif + +/** + \brief Event on successful event flags clear (Op) + \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew. + \param[in] event_flags event flags before clearing +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_EVFLAGS != 0) && !defined(EVR_RTX_EVENT_FLAGS_CLEAR_DONE_DISABLE)) +extern void EvrRtxEventFlagsClearDone (osEventFlagsId_t ef_id, uint32_t event_flags); +#else +#define EvrRtxEventFlagsClearDone(ef_id, event_flags) +#endif + +/** + \brief Event on event flags retrieve (API) + \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew. + \param[in] event_flags current event flags. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_EVFLAGS != 0) && !defined(EVR_RTX_EVENT_FLAGS_GET_DISABLE)) +extern void EvrRtxEventFlagsGet (osEventFlagsId_t ef_id, uint32_t event_flags); +#else +#define EvrRtxEventFlagsGet(ef_id, event_flags) +#endif + +/** + \brief Event on wait for event flags (API) + \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew. + \param[in] flags flags to wait for. + \param[in] options flags options (osFlagsXxxx). + \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_EVFLAGS != 0) && !defined(EVR_RTX_EVENT_FLAGS_WAIT_DISABLE)) +extern void EvrRtxEventFlagsWait (osEventFlagsId_t ef_id, uint32_t flags, uint32_t options, uint32_t timeout); +#else +#define EvrRtxEventFlagsWait(ef_id, flags, options, timeout) +#endif + +/** + \brief Event on pending wait for event flags (Op) + \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew. + \param[in] flags flags to wait for. + \param[in] options flags options (osFlagsXxxx). + \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_EVFLAGS != 0) && !defined(EVR_RTX_EVENT_FLAGS_WAIT_PENDING_DISABLE)) +extern void EvrRtxEventFlagsWaitPending (osEventFlagsId_t ef_id, uint32_t flags, uint32_t options, uint32_t timeout); +#else +#define EvrRtxEventFlagsWaitPending(ef_id, flags, options, timeout) +#endif + +/** + \brief Event on wait timeout for event flags (Op) + \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_EVFLAGS != 0) && !defined(EVR_RTX_EVENT_FLAGS_WAIT_TIMEOUT_DISABLE)) +extern void EvrRtxEventFlagsWaitTimeout (osEventFlagsId_t ef_id); +#else +#define EvrRtxEventFlagsWaitTimeout(ef_id) +#endif + +/** + \brief Event on successful wait for event flags (Op) + \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew. + \param[in] flags flags to wait for. + \param[in] options flags options (osFlagsXxxx). + \param[in] event_flags event flags before clearing or 0 if specified flags have not been set. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_EVFLAGS != 0) && !defined(EVR_RTX_EVENT_FLAGS_WAIT_COMPLETED_DISABLE)) +extern void EvrRtxEventFlagsWaitCompleted (osEventFlagsId_t ef_id, uint32_t flags, uint32_t options, uint32_t event_flags); +#else +#define EvrRtxEventFlagsWaitCompleted(ef_id, flags, options, event_flags) +#endif + +/** + \brief Event on unsuccessful wait for event flags (Op) + \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew. + \param[in] flags flags to wait for. + \param[in] options flags options (osFlagsXxxx). +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_EVFLAGS != 0) && !defined(EVR_RTX_EVENT_FLAGS_WAIT_NOT_COMPLETED_DISABLE)) +extern void EvrRtxEventFlagsWaitNotCompleted (osEventFlagsId_t ef_id, uint32_t flags, uint32_t options); +#else +#define EvrRtxEventFlagsWaitNotCompleted(ef_id, flags, options) +#endif + +/** + \brief Event on event flags delete (API) + \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_EVFLAGS != 0) && !defined(EVR_RTX_EVENT_FLAGS_DELETE_DISABLE)) +extern void EvrRtxEventFlagsDelete (osEventFlagsId_t ef_id); +#else +#define EvrRtxEventFlagsDelete(ef_id) +#endif + +/** + \brief Event on successful event flags delete (Op) + \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_EVFLAGS != 0) && !defined(EVR_RTX_EVENT_FLAGS_DESTROYED_DISABLE)) +extern void EvrRtxEventFlagsDestroyed (osEventFlagsId_t ef_id); +#else +#define EvrRtxEventFlagsDestroyed(ef_id) +#endif + + +// ==== Mutex Events ==== + +/** + \brief Event on mutex error (Error) + \param[in] mutex_id mutex ID obtained by \ref osMutexNew or NULL when ID is unknown. + \param[in] status extended execution status. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MUTEX != 0) && !defined(EVR_RTX_MUTEX_ERROR_DISABLE)) +extern void EvrRtxMutexError (osMutexId_t mutex_id, int32_t status); +#else +#define EvrRtxMutexError(mutex_id, status) +#endif + +/** + \brief Event on mutex create and initialize (API) + \param[in] attr mutex attributes +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MUTEX != 0) && !defined(EVR_RTX_MUTEX_NEW_DISABLE)) +extern void EvrRtxMutexNew (const osMutexAttr_t *attr); +#else +#define EvrRtxMutexNew(attr) +#endif + +/** + \brief Event on successful mutex create (Op) + \param[in] mutex_id mutex ID obtained by \ref osMutexNew. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MUTEX != 0) && !defined(EVR_RTX_MUTEX_CREATED_DISABLE)) +extern void EvrRtxMutexCreated (osMutexId_t mutex_id); +#else +#define EvrRtxMutexCreated(mutex_id) +#endif + +/** + \brief Event on mutex name retrieve (API) + \param[in] mutex_id mutex ID obtained by \ref osMutexNew. + \param[in] name pointer to mutex object name +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MUTEX != 0) && !defined(EVR_RTX_MUTEX_GET_NAME_DISABLE)) +extern void EvrRtxMutexGetName (osMutexId_t mutex_id, const char *name); +#else +#define EvrRtxMutexGetName(mutex_id, name) +#endif + +/** + \brief Event on mutex acquire (API) + \param[in] mutex_id mutex ID obtained by \ref osMutexNew. + \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MUTEX != 0) && !defined(EVR_RTX_MUTEX_ACQUIRE_DISABLE)) +extern void EvrRtxMutexAcquire (osMutexId_t mutex_id, uint32_t timeout); +#else +#define EvrRtxMutexAcquire(mutex_id, timeout) +#endif + +/** + \brief Event on pending mutex acquire (Op) + \param[in] mutex_id mutex ID obtained by \ref osMutexNew. + \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MUTEX != 0) && !defined(EVR_RTX_MUTEX_ACQUIRE_PENDING_DISABLE)) +extern void EvrRtxMutexAcquirePending (osMutexId_t mutex_id, uint32_t timeout); +#else +#define EvrRtxMutexAcquirePending(mutex_id, timeout); +#endif + +/** + \brief Event on mutex acquire timeout (Op) + \param[in] mutex_id mutex ID obtained by \ref osMutexNew. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MUTEX != 0) && !defined(EVR_RTX_MUTEX_ACQUIRE_TIMEOUT_DISABLE)) +extern void EvrRtxMutexAcquireTimeout (osMutexId_t mutex_id); +#else +#define EvrRtxMutexAcquireTimeout(mutex_id) +#endif + +/** + \brief Event on successful mutex acquire (Op) + \param[in] mutex_id mutex ID obtained by \ref osMutexNew. + \param[in] lock current number of times mutex object is locked +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MUTEX != 0) && !defined(EVR_RTX_MUTEX_ACQUIRED_DISABLE)) +extern void EvrRtxMutexAcquired (osMutexId_t mutex_id, uint32_t lock); +#else +#define EvrRtxMutexAcquired(mutex_id, lock) +#endif + +/** + \brief Event on unsuccessful mutex acquire (Op) + \param[in] mutex_id mutex ID obtained by \ref osMutexNew. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MUTEX != 0) && !defined(EVR_RTX_MUTEX_NOT_ACQUIRED_DISABLE)) +extern void EvrRtxMutexNotAcquired (osMutexId_t mutex_id); +#else +#define EvrRtxMutexNotAcquired(mutex_id) +#endif + +/** + \brief Event on mutex release (API) + \param[in] mutex_id mutex ID obtained by \ref osMutexNew. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MUTEX != 0) && !defined(EVR_RTX_MUTEX_RELEASE_DISABLE)) +extern void EvrRtxMutexRelease (osMutexId_t mutex_id); +#else +#define EvrRtxMutexRelease(mutex_id) +#endif + +/** + \brief Event on successful mutex release (Op) + \param[in] mutex_id mutex ID obtained by \ref osMutexNew. + \param[in] lock current number of times mutex object is locked +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MUTEX != 0) && !defined(EVR_RTX_MUTEX_RELEASED_DISABLE)) +extern void EvrRtxMutexReleased (osMutexId_t mutex_id, uint32_t lock); +#else +#define EvrRtxMutexReleased(mutex_id, lock) +#endif + +/** + \brief Event on mutex owner retrieve (API) + \param[in] mutex_id mutex ID obtained by \ref osMutexNew. + \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MUTEX != 0) && !defined(EVR_RTX_MUTEX_GET_OWNER_DISABLE)) +extern void EvrRtxMutexGetOwner (osMutexId_t mutex_id, osThreadId_t thread_id); +#else +#define EvrRtxMutexGetOwner(mutex_id, thread_id) +#endif + +/** + \brief Event on mutex delete (API) + \param[in] mutex_id mutex ID obtained by \ref osMutexNew. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MUTEX != 0) && !defined(EVR_RTX_MUTEX_DELETE_DISABLE)) +extern void EvrRtxMutexDelete (osMutexId_t mutex_id); +#else +#define EvrRtxMutexDelete(mutex_id) +#endif + +/** + \brief Event on successful mutex delete (Op) + \param[in] mutex_id mutex ID obtained by \ref osMutexNew. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MUTEX != 0) && !defined(EVR_RTX_MUTEX_DESTROYED_DISABLE)) +extern void EvrRtxMutexDestroyed (osMutexId_t mutex_id); +#else +#define EvrRtxMutexDestroyed(mutex_id) +#endif + + +// ==== Semaphore Events ==== + +/** + \brief Event on semaphore error (Error) + \param[in] semaphore_id semaphore ID obtained by \ref osSemaphoreNew or NULL when ID is unknown. + \param[in] status extended execution status. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_SEMAPHORE != 0) && !defined(EVR_RTX_SEMAPHORE_ERROR_DISABLE)) +extern void EvrRtxSemaphoreError (osSemaphoreId_t semaphore_id, int32_t status); +#else +#define EvrRtxSemaphoreError(semaphore_id, status) +#endif + +/** + \brief Event on semaphore create and initialize (API) + \param[in] max_count maximum number of available tokens. + \param[in] initial_count initial number of available tokens. + \param[in] attr semaphore attributes. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_SEMAPHORE != 0) && !defined(EVR_RTX_SEMAPHORE_NEW_DISABLE)) +extern void EvrRtxSemaphoreNew (uint32_t max_count, uint32_t initial_count, const osSemaphoreAttr_t *attr); +#else +#define EvrRtxSemaphoreNew(max_count, initial_count, attr) +#endif + +/** + \brief Event on successful semaphore create (Op) + \param[in] semaphore_id semaphore ID obtained by \ref osSemaphoreNew. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_SEMAPHORE != 0) && !defined(EVR_RTX_SEMAPHORE_CREATED_DISABLE)) +extern void EvrRtxSemaphoreCreated (osSemaphoreId_t semaphore_id); +#else +#define EvrRtxSemaphoreCreated(semaphore_id) +#endif + +/** + \brief Event on semaphore name retrieve (API) + \param[in] semaphore_id semaphore ID obtained by \ref osSemaphoreNew. + \param[in] name pointer to semaphore object name. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_SEMAPHORE != 0) && !defined(EVR_RTX_SEMAPHORE_GET_NAME_DISABLE)) +extern void EvrRtxSemaphoreGetName (osSemaphoreId_t semaphore_id, const char *name); +#else +#define EvrRtxSemaphoreGetName(semaphore_id, name) +#endif + +/** + \brief Event on semaphore acquire (API) + \param[in] semaphore_id semaphore ID obtained by \ref osSemaphoreNew. + \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_SEMAPHORE != 0) && !defined(EVR_RTX_SEMAPHORE_ACQUIRE_DISABLE)) +extern void EvrRtxSemaphoreAcquire (osSemaphoreId_t semaphore_id, uint32_t timeout); +#else +#define EvrRtxSemaphoreAcquire(semaphore_id, timeout) +#endif + +/** + \brief Event on pending semaphore acquire (Op) + \param[in] semaphore_id semaphore ID obtained by \ref osSemaphoreNew. + \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_SEMAPHORE != 0) && !defined(EVR_RTX_SEMAPHORE_ACQUIRE_PENDING_DISABLE)) +extern void EvrRtxSemaphoreAcquirePending (osSemaphoreId_t semaphore_id, uint32_t timeout); +#else +#define EvrRtxSemaphoreAcquirePending(semaphore_id, timeout); +#endif + +/** + \brief Event on semaphore acquire timeout (Op) + \param[in] semaphore_id semaphore ID obtained by \ref osSemaphoreNew. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_SEMAPHORE != 0) && !defined(EVR_RTX_SEMAPHORE_ACQUIRE_TIMEOUT_DISABLE)) +extern void EvrRtxSemaphoreAcquireTimeout (osSemaphoreId_t semaphore_id); +#else +#define EvrRtxSemaphoreAcquireTimeout(semaphore_id) +#endif + +/** + \brief Event on successful semaphore acquire (Op) + \param[in] semaphore_id semaphore ID obtained by \ref osSemaphoreNew. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_SEMAPHORE != 0) && !defined(EVR_RTX_SEMAPHORE_ACQUIRED_DISABLE)) +extern void EvrRtxSemaphoreAcquired (osSemaphoreId_t semaphore_id); +#else +#define EvrRtxSemaphoreAcquired(semaphore_id) +#endif + +/** + \brief Event on unsuccessful semaphore acquire (Op) + \param[in] semaphore_id semaphore ID obtained by \ref osSemaphoreNew. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_SEMAPHORE != 0) && !defined(EVR_RTX_SEMAPHORE_NOT_ACQUIRED_DISABLE)) +extern void EvrRtxSemaphoreNotAcquired (osSemaphoreId_t semaphore_id); +#else +#define EvrRtxSemaphoreNotAcquired(semaphore_id) +#endif + +/** + \brief Event on semaphore release (API) + \param[in] semaphore_id semaphore ID obtained by \ref osSemaphoreNew. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_SEMAPHORE != 0) && !defined(EVR_RTX_SEMAPHORE_RELEASE_DISABLE)) +extern void EvrRtxSemaphoreRelease (osSemaphoreId_t semaphore_id); +#else +#define EvrRtxSemaphoreRelease(semaphore_id) +#endif + +/** + \brief Event on successful semaphore release (Op) + \param[in] semaphore_id semaphore ID obtained by \ref osSemaphoreNew. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_SEMAPHORE != 0) && !defined(EVR_RTX_SEMAPHORE_RELEASED_DISABLE)) +extern void EvrRtxSemaphoreReleased (osSemaphoreId_t semaphore_id); +#else +#define EvrRtxSemaphoreReleased(semaphore_id) +#endif + +/** + \brief Event on semaphore token count retrieval (API) + \param[in] semaphore_id semaphore ID obtained by \ref osSemaphoreNew. + \param[in] count current number of available tokens. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_SEMAPHORE != 0) && !defined(EVR_RTX_SEMAPHORE_GET_COUNT_DISABLE)) +extern void EvrRtxSemaphoreGetCount (osSemaphoreId_t semaphore_id, uint32_t count); +#else +#define EvrRtxSemaphoreGetCount(semaphore_id, count) +#endif + +/** + \brief Event on semaphore delete (API) + \param[in] semaphore_id semaphore ID obtained by \ref osSemaphoreNew. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_SEMAPHORE != 0) && !defined(EVR_RTX_SEMAPHORE_DELETE_DISABLE)) +extern void EvrRtxSemaphoreDelete (osSemaphoreId_t semaphore_id); +#else +#define EvrRtxSemaphoreDelete(semaphore_id) +#endif + +/** + \brief Event on successful semaphore delete (Op) + \param[in] semaphore_id semaphore ID obtained by \ref osSemaphoreNew. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_SEMAPHORE != 0) && !defined(EVR_RTX_SEMAPHORE_DESTROYED_DISABLE)) +extern void EvrRtxSemaphoreDestroyed (osSemaphoreId_t semaphore_id); +#else +#define EvrRtxSemaphoreDestroyed(semaphore_id) +#endif + + +// ==== Memory Pool Events ==== + +/** + \brief Event on memory pool error (Error) + \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew or NULL when ID is unknown. + \param[in] status extended execution status. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMPOOL != 0) && !defined(EVR_RTX_MEMORY_POOL_ERROR_DISABLE)) +extern void EvrRtxMemoryPoolError (osMemoryPoolId_t mp_id, int32_t status); +#else +#define EvrRtxMemoryPoolError(mp_id, status) +#endif + +/** + \brief Event on memory pool create and initialize (API) + \param[in] block_count maximum number of memory blocks in memory pool. + \param[in] block_size memory block size in bytes. + \param[in] attr memory pool attributes; NULL: default values. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMPOOL != 0) && !defined(EVR_RTX_MEMORY_POOL_NEW_DISABLE)) +extern void EvrRtxMemoryPoolNew (uint32_t block_count, uint32_t block_size, const osMemoryPoolAttr_t *attr); +#else +#define EvrRtxMemoryPoolNew(block_count, block_size, attr) +#endif + +/** + \brief Event on successful memory pool create (Op) + \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMPOOL != 0) && !defined(EVR_RTX_MEMORY_POOL_CREATED_DISABLE)) +extern void EvrRtxMemoryPoolCreated (osMemoryPoolId_t mp_id); +#else +#define EvrRtxMemoryPoolCreated(mp_id) +#endif + +/** + \brief Event on memory pool name retrieve (API) + \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew. + \param[in] name pointer to memory pool object name. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMPOOL != 0) && !defined(EVR_RTX_MEMORY_POOL_GET_NAME_DISABLE)) +extern void EvrRtxMemoryPoolGetName (osMemoryPoolId_t mp_id, const char *name); +#else +#define EvrRtxMemoryPoolGetName(mp_id, name) +#endif + +/** + \brief Event on memory pool allocation (API) + \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew. + \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMPOOL != 0) && !defined(EVR_RTX_MEMORY_POOL_ALLOC_DISABLE)) +extern void EvrRtxMemoryPoolAlloc (osMemoryPoolId_t mp_id, uint32_t timeout); +#else +#define EvrRtxMemoryPoolAlloc(mp_id, timeout) +#endif + +/** + \brief Event on pending memory pool allocation (Op) + \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew. + \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMPOOL != 0) && !defined(EVR_RTX_MEMORY_POOL_ALLOC_PENDING_DISABLE)) +extern void EvrRtxMemoryPoolAllocPending (osMemoryPoolId_t mp_id, uint32_t timeout); +#else +#define EvrRtxMemoryPoolAllocPending(mp_id, timeout) +#endif + +/** + \brief Event on memory pool allocation timeout (Op) + \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMPOOL != 0) && !defined(EVR_RTX_MEMORY_POOL_ALLOC_TIMEOUT_DISABLE)) +extern void EvrRtxMemoryPoolAllocTimeout (osMemoryPoolId_t mp_id); +#else +#define EvrRtxMemoryPoolAllocTimeout(mp_id) +#endif + +/** + \brief Event on successful memory pool allocation (Op) + \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew. + \param[in] block address of the allocated memory block. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMPOOL != 0) && !defined(EVR_RTX_MEMORY_POOL_ALLOCATED_DISABLE)) +extern void EvrRtxMemoryPoolAllocated (osMemoryPoolId_t mp_id, void *block); +#else +#define EvrRtxMemoryPoolAllocated(mp_id, block) +#endif + +/** + \brief Event on unsuccessful memory pool allocation (Op) + \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMPOOL != 0) && !defined(EVR_RTX_MEMORY_POOL_ALLOC_FAILED_DISABLE)) +extern void EvrRtxMemoryPoolAllocFailed (osMemoryPoolId_t mp_id); +#else +#define EvrRtxMemoryPoolAllocFailed(mp_id) +#endif + +/** + \brief Event on memory pool free (API) + \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew. + \param[in] block address of the allocated memory block to be returned to the memory pool. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMPOOL != 0) && !defined(EVR_RTX_MEMORY_POOL_FREE_DISABLE)) +extern void EvrRtxMemoryPoolFree (osMemoryPoolId_t mp_id, void *block); +#else +#define EvrRtxMemoryPoolFree(mp_id, block) +#endif + +/** + \brief Event on successful memory pool free (Op) + \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew. + \param[in] block address of the allocated memory block to be returned to the memory pool. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMPOOL != 0) && !defined(EVR_RTX_MEMORY_POOL_DEALLOCATED_DISABLE)) +extern void EvrRtxMemoryPoolDeallocated (osMemoryPoolId_t mp_id, void *block); +#else +#define EvrRtxMemoryPoolDeallocated(mp_id, block) +#endif + +/** + \brief Event on unsuccessful memory pool free (Op) + \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew. + \param[in] block address of the allocated memory block to be returned to the memory pool. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMPOOL != 0) && !defined(EVR_RTX_MEMORY_POOL_FREE_FAILED_DISABLE)) +extern void EvrRtxMemoryPoolFreeFailed (osMemoryPoolId_t mp_id, void *block); +#else +#define EvrRtxMemoryPoolFreeFailed(mp_id, block) +#endif + +/** + \brief Event on memory pool capacity retrieve (API) + \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew. + \param[in] capacity maximum number of memory blocks. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMPOOL != 0) && !defined(EVR_RTX_MEMORY_POOL_GET_CAPACITY_DISABLE)) +extern void EvrRtxMemoryPoolGetCapacity (osMemoryPoolId_t mp_id, uint32_t capacity); +#else +#define EvrRtxMemoryPoolGetCapacity(mp_id, capacity) +#endif + +/** + \brief Event on memory pool block size retrieve (API) + \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew. + \param[in] block_size memory block size in bytes. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMPOOL != 0) && !defined(EVR_RTX_MEMORY_POOL_GET_BLOCK_SZIE_DISABLE)) +extern void EvrRtxMemoryPoolGetBlockSize (osMemoryPoolId_t mp_id, uint32_t block_size); +#else +#define EvrRtxMemoryPoolGetBlockSize(mp_id, block_size) +#endif + +/** + \brief Event on used memory pool blocks retrieve (API) + \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew. + \param[in] count number of memory blocks used. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMPOOL != 0) && !defined(EVR_RTX_MEMORY_POOL_GET_COUNT_DISABLE)) +extern void EvrRtxMemoryPoolGetCount (osMemoryPoolId_t mp_id, uint32_t count); +#else +#define EvrRtxMemoryPoolGetCount(mp_id, count) +#endif + +/** + \brief Event on available memory pool blocks retrieve (API) + \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew. + \param[in] space number of memory blocks available. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMPOOL != 0) && !defined(EVR_RTX_MEMORY_POOL_GET_SPACE_DISABLE)) +extern void EvrRtxMemoryPoolGetSpace (osMemoryPoolId_t mp_id, uint32_t space); +#else +#define EvrRtxMemoryPoolGetSpace(mp_id, space) +#endif + +/** + \brief Event on memory pool delete (API) + \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMPOOL != 0) && !defined(EVR_RTX_MEMORY_POOL_DELETE_DISABLE)) +extern void EvrRtxMemoryPoolDelete (osMemoryPoolId_t mp_id); +#else +#define EvrRtxMemoryPoolDelete(mp_id) +#endif + +/** + \brief Event on successful memory pool delete (Op) + \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MEMPOOL != 0) && !defined(EVR_RTX_MEMORY_POOL_DESTROYED_DISABLE)) +extern void EvrRtxMemoryPoolDestroyed (osMemoryPoolId_t mp_id); +#else +#define EvrRtxMemoryPoolDestroyed(mp_id) +#endif + + +// ==== Message Queue Events ==== + +/** + \brief Event on message queue error (Error) + \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew or NULL when ID is unknown. + \param[in] status extended execution status. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_ERROR_DISABLE)) +extern void EvrRtxMessageQueueError (osMessageQueueId_t mq_id, int32_t status); +#else +#define EvrRtxMessageQueueError(mq_id, status) +#endif + +/** + \brief Event on message queue create and initialization (API) + \param[in] msg_count maximum number of messages in queue. + \param[in] msg_size maximum message size in bytes. + \param[in] attr message queue attributes; NULL: default values. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_NEW_DISABLE)) +extern void EvrRtxMessageQueueNew (uint32_t msg_count, uint32_t msg_size, const osMessageQueueAttr_t *attr); +#else +#define EvrRtxMessageQueueNew(msg_count, msg_size, attr) +#endif + +/** + \brief Event on successful message queue create (Op) + \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_CREATED_DISABLE)) +extern void EvrRtxMessageQueueCreated (osMessageQueueId_t mq_id); +#else +#define EvrRtxMessageQueueCreated(mq_id) +#endif + +/** + \brief Event on message queue name retrieve(API) + \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. + \param[in] name pointer to message queue object name. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_GET_NAME_DISABLE)) +extern void EvrRtxMessageQueueGetName (osMessageQueueId_t mq_id, const char *name); +#else +#define EvrRtxMessageQueueGetName(mq_id, name) +#endif + +/** + \brief Event on message put (API) + \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. + \param[in] msg_ptr pointer to buffer with message to put into a queue. + \param[in] msg_prio message priority. + \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_PUT_DISABLE)) +extern void EvrRtxMessageQueuePut (osMessageQueueId_t mq_id, const void *msg_ptr, uint8_t msg_prio, uint32_t timeout); +#else +#define EvrRtxMessageQueuePut(mq_id, msg_ptr, msg_prio, timeout) +#endif + +/** + \brief Event on pending message put (Op) + \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. + \param[in] msg_ptr pointer to buffer with message to put into a queue. + \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_PUT_PENDING_DISABLE)) +extern void EvrRtxMessageQueuePutPending (osMessageQueueId_t mq_id, const void *msg_ptr, uint32_t timeout); +#else +#define EvrRtxMessageQueuePutPending(mq_id, msg_ptr, timeout) +#endif + +/** + \brief Event on message put timeout (Op) + \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_PUT_TIMEOUT_DISABLE)) +extern void EvrRtxMessageQueuePutTimeout (osMessageQueueId_t mq_id); +#else +#define EvrRtxMessageQueuePutTimeout(mq_id) +#endif + +/** + \brief Event on pending message insert (Op) + \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. + \param[in] msg_ptr pointer to buffer with message to put into a queue. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_INSERT_PENDING_DISABLE)) +extern void EvrRtxMessageQueueInsertPending (osMessageQueueId_t mq_id, const void *msg_ptr); +#else +#define EvrRtxMessageQueueInsertPending(mq_id, msg_ptr) +#endif + +/** + \brief Event on successful message insert (Op) + \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. + \param[in] msg_ptr pointer to buffer with message to put into a queue. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_INSERTED_DISABLE)) +extern void EvrRtxMessageQueueInserted (osMessageQueueId_t mq_id, const void *msg_ptr); +#else +#define EvrRtxMessageQueueInserted(mq_id, msg_ptr) +#endif + +/** + \brief Event on unsuccessful message insert (Op) + \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. + \param[in] msg_ptr pointer to buffer with message to put into a queue. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_NOT_INSERTED_DISABLE)) +extern void EvrRtxMessageQueueNotInserted (osMessageQueueId_t mq_id, const void *msg_ptr); +#else +#define EvrRtxMessageQueueNotInserted(mq_id, msg_ptr) +#endif + +/** + \brief Event on message get (API) + \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. + \param[in] msg_ptr pointer to buffer for message to get from a queue. + \param[in] msg_prio message priority. + \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_GET_DISABLE)) +extern void EvrRtxMessageQueueGet (osMessageQueueId_t mq_id, void *msg_ptr, uint8_t *msg_prio, uint32_t timeout); +#else +#define EvrRtxMessageQueueGet(mq_id, msg_ptr, msg_prio, timeout) +#endif + +/** + \brief Event on pending message get (Op) + \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. + \param[in] msg_ptr pointer to buffer for message to get from a queue. + \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_GET_PENDING_DISABLE)) +extern void EvrRtxMessageQueueGetPending (osMessageQueueId_t mq_id, void *msg_ptr, uint32_t timeout); +#else +#define EvrRtxMessageQueueGetPending(mq_id, msg_ptr, timeout) +#endif + +/** + \brief Event on message get timeout (Op) + \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_GET_TIMEOUT_DISABLE)) +extern void EvrRtxMessageQueueGetTimeout (osMessageQueueId_t mq_id); +#else +#define EvrRtxMessageQueueGetTimeout(mq_id) +#endif + +/** + \brief Event on successful message get (Op) + \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. + \param[in] msg_ptr pointer to buffer for message to get from a queue. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_RETRIEVED_DISABLE)) +extern void EvrRtxMessageQueueRetrieved (osMessageQueueId_t mq_id, void *msg_ptr); +#else +#define EvrRtxMessageQueueRetrieved(mq_id, msg_ptr) +#endif + +/** + \brief Event on unsuccessful message get (Op) + \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. + \param[in] msg_ptr pointer to buffer for message to get from a queue. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_NOT_RETRIEVED_DISABLE)) +extern void EvrRtxMessageQueueNotRetrieved (osMessageQueueId_t mq_id, void *msg_ptr); +#else +#define EvrRtxMessageQueueNotRetrieved(mq_id, msg_ptr) +#endif + +/** + \brief Event on message queue capacity retrieve (API) + \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. + \param[in] capacity maximum number of messages. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_GET_CAPACITY_DISABLE)) +extern void EvrRtxMessageQueueGetCapacity (osMessageQueueId_t mq_id, uint32_t capacity); +#else +#define EvrRtxMessageQueueGetCapacity(mq_id, capacity) +#endif + +/** + \brief Event on message queue message size retrieve (API) + \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. + \param[in] msg_size maximum message size in bytes. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_GET_MSG_SIZE_DISABLE)) +extern void EvrRtxMessageQueueGetMsgSize (osMessageQueueId_t mq_id, uint32_t msg_size); +#else +#define EvrRtxMessageQueueGetMsgSize(mq_id, msg_size) +#endif + +/** + \brief Event on message queue message count retrieve (API) + \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. + \param[in] count number of queued messages. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_GET_COUNT_DISABLE)) +extern void EvrRtxMessageQueueGetCount (osMessageQueueId_t mq_id, uint32_t count); +#else +#define EvrRtxMessageQueueGetCount(mq_id, count) +#endif + +/** + \brief Event on message queue message slots retrieve (API) + \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. + \param[in] space number of available slots for messages. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_GET_SPACE_DISABLE)) +extern void EvrRtxMessageQueueGetSpace (osMessageQueueId_t mq_id, uint32_t space); +#else +#define EvrRtxMessageQueueGetSpace(mq_id, space) +#endif + +/** + \brief Event on message queue reset (API) + \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_RESET_DISABLE)) +extern void EvrRtxMessageQueueReset (osMessageQueueId_t mq_id); +#else +#define EvrRtxMessageQueueReset(mq_id) +#endif + +/** + \brief Event on successful message queue reset (Op) + \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_RESET_DONE_DISABLE)) +extern void EvrRtxMessageQueueResetDone (osMessageQueueId_t mq_id); +#else +#define EvrRtxMessageQueueResetDone(mq_id) +#endif + +/** + \brief Event on message queue delete (API) + \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_DELETE_DISABLE)) +extern void EvrRtxMessageQueueDelete (osMessageQueueId_t mq_id); +#else +#define EvrRtxMessageQueueDelete(mq_id) +#endif + +/** + \brief Event on successful message queue delete (Op) + \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. +*/ +#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_MSGQUEUE != 0) && !defined(EVR_RTX_MESSAGE_QUEUE_DESTROYED_DISABLE)) +extern void EvrRtxMessageQueueDestroyed (osMessageQueueId_t mq_id); +#else +#define EvrRtxMessageQueueDestroyed(mq_id) +#endif + + +#endif // RTX_EVR_H_ diff --git a/rtos/rtx2/TARGET_CORTEX_M/rtx_kernel.c b/rtos/rtx2/TARGET_CORTEX_M/rtx_kernel.c new file mode 100644 index 00000000000..72207a7d489 --- /dev/null +++ b/rtos/rtx2/TARGET_CORTEX_M/rtx_kernel.c @@ -0,0 +1,633 @@ +/* + * Copyright (c) 2013-2017 ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ----------------------------------------------------------------------------- + * + * Project: CMSIS-RTOS RTX + * Title: Kernel functions + * + * ----------------------------------------------------------------------------- + */ + +#include "rtx_lib.h" + + +// OS Runtime Information +osRtxInfo_t osRtxInfo __attribute__((section(".data.os"))) = +{ .os_id = osRtxKernelId, .version = osRtxVersionKernel, .kernel.state = osRtxKernelInactive }; + + +// ==== Helper functions ==== + +/// Block Kernel (disable: thread switching, time tick, post ISR processing). +static void KernelBlock (void) { + + if (osRtxInfo.tick_irqn >= 0) { + ExtTick_DisableIRQ(osRtxInfo.tick_irqn); + } + osRtxSysTimerDisable(); + osRtxInfo.kernel.blocked = 1U; + __DSB(); + if (osRtxInfo.tick_irqn < 0) { + osRtxInfo.kernel.pendISR = GetPendSV_ST(); + ClrPendSV_ST(); + } else { + osRtxInfo.kernel.pendISR = GetPendSV(); + ClrPendSV(); + } +} + +/// Unblock Kernel +static void KernelUnblock (void) { + + osRtxInfo.kernel.blocked = 0U; + __DSB(); + if (osRtxInfo.kernel.pendSV != 0U) { + osRtxInfo.kernel.pendSV = 0U; + SetPendSV(); + } + if (osRtxInfo.kernel.pendISR != 0U) { + SetPendFlags(osRtxInfo.kernel.pendISR); + } + if (osRtxInfo.tick_irqn >= 0) { + ExtTick_EnableIRQ(osRtxInfo.tick_irqn); + } + osRtxSysTimerEnable(); +} + + +// ==== Service Calls ==== + +// Service Calls definitions +SVC0_0M(KernelInitialize, osStatus_t) +SVC0_3 (KernelGetInfo, osStatus_t, osVersion_t *, char *, uint32_t) +SVC0_0M(KernelStart, osStatus_t) +SVC0_0 (KernelLock, int32_t) +SVC0_0 (KernelUnlock, int32_t) +SVC0_1 (KernelRestoreLock, int32_t, int32_t) +SVC0_0 (KernelSuspend, uint32_t) +SVC0_1N(KernelResume, void, uint32_t) +SVC0_0 (KernelGetState, osKernelState_t) +SVC0_0D(KernelGetTickCount, uint64_t) +SVC0_0 (KernelGetTickFreq, uint32_t) +SVC0_0 (KernelGetSysTimerCount, uint32_t) +SVC0_0 (KernelGetSysTimerFreq, uint32_t) + +/// Initialize the RTOS Kernel. +/// \note API identical to osKernelInitialize +osStatus_t svcRtxKernelInitialize (void) { + + if (osRtxInfo.kernel.state == osRtxKernelReady) { + EvrRtxKernelInitializeCompleted(); + return osOK; + } + if (osRtxInfo.kernel.state != osKernelInactive) { + EvrRtxKernelError(osError); + return osError; + } + + // Initialize osRtxInfo + memset(&osRtxInfo.kernel, 0, sizeof(osRtxInfo) - offsetof(osRtxInfo_t, kernel)); + + if (osRtxConfig.thread_stack_size < (64U + 8U)) { + EvrRtxKernelError(osRtxErrorInvalidThreadStack); + return osError; + } + + if ((osRtxConfig.isr_queue.data == NULL) || (osRtxConfig.isr_queue.max == 0U)) { + EvrRtxKernelError(osError); + return osError; + } + osRtxInfo.isr_queue.data = osRtxConfig.isr_queue.data; + osRtxInfo.isr_queue.max = osRtxConfig.isr_queue.max; + + osRtxInfo.thread.robin.timeout = osRtxConfig.robin_timeout; + + // Initialize Memory Pools (Variable Block Size) + if (osRtxMemoryInit(osRtxConfig.mem.common_addr, osRtxConfig.mem.common_size) != 0U) { + osRtxInfo.mem.common = osRtxConfig.mem.common_addr; + } + if (osRtxMemoryInit(osRtxConfig.mem.stack_addr, osRtxConfig.mem.stack_size) != 0U) { + osRtxInfo.mem.stack = osRtxConfig.mem.stack_addr; + } else { + osRtxInfo.mem.stack = osRtxInfo.mem.common; + } + if (osRtxMemoryInit(osRtxConfig.mem.mp_data_addr, osRtxConfig.mem.mp_data_size) != 0U) { + osRtxInfo.mem.mp_data = osRtxConfig.mem.mp_data_addr; + } else { + osRtxInfo.mem.mp_data = osRtxInfo.mem.common; + } + if (osRtxMemoryInit(osRtxConfig.mem.mq_data_addr, osRtxConfig.mem.mq_data_size) != 0U) { + osRtxInfo.mem.mq_data = osRtxConfig.mem.mq_data_addr; + } else { + osRtxInfo.mem.mq_data = osRtxInfo.mem.common; + } + + // Initialize Memory Pools (Fixed Block Size) + if ((osRtxConfig.mpi.stack != NULL) && + (osRtxMemoryPoolInit(osRtxConfig.mpi.stack, + osRtxConfig.mpi.stack->max_blocks, + osRtxConfig.mpi.stack->block_size, + osRtxConfig.mpi.stack->block_base) != 0U)) { + osRtxInfo.mpi.stack = osRtxConfig.mpi.stack; + } + if ((osRtxConfig.mpi.thread != NULL) && + (osRtxMemoryPoolInit(osRtxConfig.mpi.thread, + osRtxConfig.mpi.thread->max_blocks, + osRtxConfig.mpi.thread->block_size, + osRtxConfig.mpi.thread->block_base) != 0U)) { + osRtxInfo.mpi.thread = osRtxConfig.mpi.thread; + } + if ((osRtxConfig.mpi.timer != NULL) && + (osRtxMemoryPoolInit(osRtxConfig.mpi.timer, + osRtxConfig.mpi.timer->max_blocks, + osRtxConfig.mpi.timer->block_size, + osRtxConfig.mpi.timer->block_base) != 0U)) { + osRtxInfo.mpi.timer = osRtxConfig.mpi.timer; + } + if ((osRtxConfig.mpi.event_flags != NULL) && + (osRtxMemoryPoolInit(osRtxConfig.mpi.event_flags, + osRtxConfig.mpi.event_flags->max_blocks, + osRtxConfig.mpi.event_flags->block_size, + osRtxConfig.mpi.event_flags->block_base) != 0U)) { + osRtxInfo.mpi.event_flags = osRtxConfig.mpi.event_flags; + } + if ((osRtxConfig.mpi.mutex != NULL) && + (osRtxMemoryPoolInit(osRtxConfig.mpi.mutex, + osRtxConfig.mpi.mutex->max_blocks, + osRtxConfig.mpi.mutex->block_size, + osRtxConfig.mpi.mutex->block_base) != 0U)) { + osRtxInfo.mpi.mutex = osRtxConfig.mpi.mutex; + } + if ((osRtxConfig.mpi.semaphore != NULL) && + (osRtxMemoryPoolInit(osRtxConfig.mpi.semaphore, + osRtxConfig.mpi.semaphore->max_blocks, + osRtxConfig.mpi.semaphore->block_size, + osRtxConfig.mpi.semaphore->block_base) != 0U)) { + osRtxInfo.mpi.semaphore = osRtxConfig.mpi.semaphore; + } + if ((osRtxConfig.mpi.memory_pool != NULL) && + (osRtxMemoryPoolInit(osRtxConfig.mpi.memory_pool, + osRtxConfig.mpi.memory_pool->max_blocks, + osRtxConfig.mpi.memory_pool->block_size, + osRtxConfig.mpi.memory_pool->block_base) != 0U)) { + osRtxInfo.mpi.memory_pool = osRtxConfig.mpi.memory_pool; + } + if ((osRtxConfig.mpi.message_queue != NULL) && + (osRtxMemoryPoolInit(osRtxConfig.mpi.message_queue, + osRtxConfig.mpi.message_queue->max_blocks, + osRtxConfig.mpi.message_queue->block_size, + osRtxConfig.mpi.message_queue->block_base) != 0U)) { + osRtxInfo.mpi.message_queue = osRtxConfig.mpi.message_queue; + } + +#if (__DOMAIN_NS == 1U) + // Initialize Secure Process Stack + if (TZ_InitContextSystem_S() == 0U) { + EvrRtxKernelError(osRtxErrorTZ_InitContext_S); + return osError; + } +#endif + + // Initialize SVC and PendSV System Service Calls + SVC_Initialize(); + + osRtxInfo.kernel.state = osRtxKernelReady; + + EvrRtxKernelInitializeCompleted(); + + return osOK; +} + +/// Get RTOS Kernel Information. +/// \note API identical to osKernelGetInfo +osStatus_t svcRtxKernelGetInfo (osVersion_t *version, char *id_buf, uint32_t id_size) { + + if (version != NULL) { + version->api = osRtxVersionAPI; + version->kernel = osRtxVersionKernel; + } + + if ((id_buf != NULL) && (id_size != 0U)) { + if (id_size > sizeof(osRtxKernelId)) { + id_size = sizeof(osRtxKernelId); + } + memcpy(id_buf, osRtxKernelId, id_size); + } + + EvrRtxKernelInfoRetrieved(version, id_buf); + + return osOK; +} + +/// Get the current RTOS Kernel state. +/// \note API identical to osKernelGetState +osKernelState_t svcRtxKernelGetState (void) { + EvrRtxKernelGetState((osKernelState_t)(osRtxInfo.kernel.state)); + return ((osKernelState_t)(osRtxInfo.kernel.state)); +} + +/// Start the RTOS Kernel scheduler. +/// \note API identical to osKernelStart +osStatus_t svcRtxKernelStart (void) { + os_thread_t *thread; + + if (osRtxInfo.kernel.state != osRtxKernelReady) { + EvrRtxKernelError(osRtxErrorKernelNotReady); + return osError; + } + + // Create Idle Thread + if (osRtxInfo.thread.idle == NULL) { + osRtxInfo.thread.idle = svcRtxThreadNew(osRtxIdleThread, NULL, osRtxConfig.idle_thread_attr); + if (osRtxInfo.thread.idle == NULL) { + EvrRtxKernelError(osError); + return osError; + } + } + + // Create Timer Thread + if (osRtxConfig.timer_mq_mcnt != 0U) { + if (osRtxInfo.timer.thread == NULL) { + osRtxInfo.timer.thread = svcRtxThreadNew(osRtxTimerThread, NULL, osRtxConfig.timer_thread_attr); + if (osRtxInfo.timer.thread == NULL) { + EvrRtxKernelError(osError); + return osError; + } + } + } + + // Switch to Ready Thread with highest Priority + thread = osRtxThreadListGet(&osRtxInfo.thread.ready); + if (thread == NULL) { + EvrRtxKernelError(osError); + return osError; + } + osRtxThreadSwitch(thread); + + if ((osRtxConfig.flags & osRtxConfigPrivilegedMode) != 0U) { + // Privileged Thread mode & PSP + __set_CONTROL(0x02U); + } else { + // Unprivileged Thread mode & PSP + __set_CONTROL(0x03U); + } + + osRtxInfo.kernel.sys_freq = SystemCoreClock; + + // Setup and Enable System Timer + osRtxInfo.tick_irqn = osRtxSysTimerSetup(); + if (osRtxInfo.tick_irqn >= 0) { + ExtTick_SetupIRQ (osRtxInfo.tick_irqn); + ExtTick_EnableIRQ(osRtxInfo.tick_irqn); + } + osRtxSysTimerEnable(); + + osRtxInfo.kernel.state = osRtxKernelRunning; + + EvrRtxKernelStarted(); + + return osOK; +} + +/// Lock the RTOS Kernel scheduler. +/// \note API identical to osKernelLock +int32_t svcRtxKernelLock (void) { + + if (osRtxInfo.kernel.state == osRtxKernelLocked) { + EvrRtxKernelLocked(1); + return 1; + } + if (osRtxInfo.kernel.state == osRtxKernelRunning) { + osRtxInfo.kernel.state = osRtxKernelLocked; + EvrRtxKernelLocked(0); + return 0; + } + + EvrRtxKernelError(osError); + return osError; +} + +/// Unlock the RTOS Kernel scheduler. +/// \note API identical to osKernelUnlock +int32_t svcRtxKernelUnlock (void) { + + if (osRtxInfo.kernel.state == osRtxKernelLocked) { + osRtxInfo.kernel.state = osRtxKernelRunning; + EvrRtxKernelUnlocked(1); + return 1; + } + if (osRtxInfo.kernel.state == osRtxKernelRunning) { + EvrRtxKernelUnlocked(0); + return 0; + } + + EvrRtxKernelError(osError); + return osError; +} + +/// Restore the RTOS Kernel scheduler lock state. +/// \note API identical to osKernelRestoreLock +int32_t svcRtxKernelRestoreLock (int32_t lock) { + + if ((osRtxInfo.kernel.state == osRtxKernelRunning) || + (osRtxInfo.kernel.state == osRtxKernelLocked)) { + switch (lock) { + case 1: + osRtxInfo.kernel.state = osRtxKernelLocked; + EvrRtxKernelLockRestored(1); + return 1; + case 0: + osRtxInfo.kernel.state = osRtxKernelRunning; + EvrRtxKernelLockRestored(0); + return 0; + default: + break; + } + } + + EvrRtxKernelError(osError); + return osError; +} + +/// Suspend the RTOS Kernel scheduler. +/// \note API identical to osKernelSuspend +uint32_t svcRtxKernelSuspend (void) { + os_thread_t *thread; + os_timer_t *timer; + uint32_t delay; + + if (osRtxInfo.kernel.state != osRtxKernelRunning) { + EvrRtxKernelError(osRtxErrorKernelNotRunning); + return 0U; + } + + KernelBlock(); + + delay = osWaitForever; + + // Check Thread Delay list + thread = osRtxInfo.thread.delay_list; + if (thread != NULL) { + delay = thread->delay; + } + + // Check Active Timer list + timer = osRtxInfo.timer.list; + if (timer != NULL) { + if (timer->tick < delay) { + delay = timer->tick; + } + } + + osRtxInfo.kernel.state = osRtxKernelSuspended; + + EvrRtxKernelSuspended(delay); + + return delay; +} + +/// Resume the RTOS Kernel scheduler. +/// \note API identical to osKernelResume +void svcRtxKernelResume (uint32_t sleep_ticks) { + os_thread_t *thread; + os_timer_t *timer; + uint32_t delay; + + if (osRtxInfo.kernel.state != osRtxKernelSuspended) { + EvrRtxKernelResumed(); + return; + } + + // Process Thread Delay list + thread = osRtxInfo.thread.delay_list; + if (thread != NULL) { + delay = sleep_ticks; + if (delay >= thread->delay) { + delay -= thread->delay; + osRtxInfo.kernel.tick += thread->delay; + thread->delay = 1U; + do { + osRtxThreadDelayTick(); + if (delay == 0U) { + break; + } + delay--; + osRtxInfo.kernel.tick++; + } while (osRtxInfo.thread.delay_list != NULL); + } else { + thread->delay -= delay; + osRtxInfo.kernel.tick += delay; + } + } else { + osRtxInfo.kernel.tick += sleep_ticks; + } + + // Process Active Timer list + timer = osRtxInfo.timer.list; + if (timer != NULL) { + if (sleep_ticks >= timer->tick) { + sleep_ticks -= timer->tick; + timer->tick = 1U; + do { + osRtxInfo.timer.tick(); + if (sleep_ticks == 0U) { + break; + } + sleep_ticks--; + } while (osRtxInfo.timer.list != NULL); + } else { + timer->tick -= sleep_ticks; + } + } + + osRtxInfo.kernel.state = osRtxKernelRunning; + + osRtxThreadDispatch(NULL); + + KernelUnblock(); + + EvrRtxKernelResumed(); +} + +/// Get the RTOS kernel tick count. +/// \note API identical to osKernelGetTickCount +uint64_t svcRtxKernelGetTickCount (void) { + EvrRtxKernelGetTickCount(osRtxInfo.kernel.tick); + return osRtxInfo.kernel.tick; +} + +/// Get the RTOS kernel tick frequency. +/// \note API identical to osKernelGetTickFreq +uint32_t svcRtxKernelGetTickFreq (void) { + EvrRtxKernelGetTickFreq(osRtxConfig.tick_freq); + return osRtxConfig.tick_freq; +} + +/// Get the RTOS kernel system timer count. +/// \note API identical to osKernelGetSysTimerCount +uint32_t svcRtxKernelGetSysTimerCount (void) { + uint32_t count = osRtxSysTimerGetCount(); + EvrRtxKernelGetSysTimerCount(count); + return count; +} + +/// Get the RTOS kernel system timer frequency. +/// \note API identical to osKernelGetSysTimerFreq +uint32_t svcRtxKernelGetSysTimerFreq (void) { + uint32_t freq = osRtxSysTimerGetFreq(); + EvrRtxKernelGetSysTimerFreq(freq); + return freq; +} + + +// ==== Public API ==== + +/// Initialize the RTOS Kernel. +osStatus_t osKernelInitialize (void) { + EvrRtxKernelInitialize(); + if (IS_IRQ_MODE() || IS_IRQ_MASKED()) { + EvrRtxKernelError(osErrorISR); + return osErrorISR; + } + return __svcKernelInitialize(); +} + +/// Get RTOS Kernel Information. +osStatus_t osKernelGetInfo (osVersion_t *version, char *id_buf, uint32_t id_size) { + EvrRtxKernelGetInfo(version, id_buf, id_size); + if (IS_IRQ_MODE() || IS_IRQ_MASKED()) { + EvrRtxKernelError(osErrorISR); + return osErrorISR; + } + if (IS_PRIVILEGED()) { + return svcRtxKernelGetInfo(version, id_buf, id_size); + } else { + return __svcKernelGetInfo(version, id_buf, id_size); + } +} + +/// Get the current RTOS Kernel state. +osKernelState_t osKernelGetState (void) { + if (IS_IRQ_MODE() || IS_IRQ_MASKED()) { + EvrRtxKernelGetState(osKernelError); + return osKernelError; + } + if (IS_PRIVILEGED()) { + return svcRtxKernelGetState(); + } else { + return __svcKernelGetState(); + } +} + +/// Start the RTOS Kernel scheduler. +osStatus_t osKernelStart (void) { + EvrRtxKernelStart(); + if (IS_IRQ_MODE() || IS_IRQ_MASKED()) { + EvrRtxKernelError(osErrorISR); + return osErrorISR; + } + return __svcKernelStart(); +} + +/// Lock the RTOS Kernel scheduler. +int32_t osKernelLock (void) { + EvrRtxKernelLock(); + if (IS_IRQ_MODE() || IS_IRQ_MASKED()) { + EvrRtxKernelError(osErrorISR); + return osErrorISR; + } + return __svcKernelLock(); +} + +/// Unlock the RTOS Kernel scheduler. +int32_t osKernelUnlock (void) { + EvrRtxKernelUnlock(); + if (IS_IRQ_MODE() || IS_IRQ_MASKED()) { + EvrRtxKernelError(osErrorISR); + return osErrorISR; + } + return __svcKernelUnlock(); +} + +/// Restore the RTOS Kernel scheduler lock state. +int32_t osKernelRestoreLock (int32_t lock) { + EvrRtxKernelRestoreLock(lock); + if (IS_IRQ_MODE() || IS_IRQ_MASKED()) { + EvrRtxKernelError(osErrorISR); + return osErrorISR; + } + return __svcKernelRestoreLock(lock); +} + +/// Suspend the RTOS Kernel scheduler. +uint32_t osKernelSuspend (void) { + EvrRtxKernelSuspend(); + if (IS_IRQ_MODE() || IS_IRQ_MASKED()) { + EvrRtxKernelError(osErrorISR); + return 0U; + } + return __svcKernelSuspend(); +} + +/// Resume the RTOS Kernel scheduler. +void osKernelResume (uint32_t sleep_ticks) { + EvrRtxKernelResume(sleep_ticks); + if (IS_IRQ_MODE() || IS_IRQ_MASKED()) { + EvrRtxKernelError(osErrorISR); + return; + } + __svcKernelResume(sleep_ticks); +} + +/// Get the RTOS kernel tick count. +uint64_t osKernelGetTickCount (void) { + if (IS_IRQ_MODE() || IS_IRQ_MASKED()) { + EvrRtxKernelGetTickCount(0U); + return 0U; + } else { + return __svcKernelGetTickCount(); + } +} + +/// Get the RTOS kernel tick frequency. +uint32_t osKernelGetTickFreq (void) { + if (IS_IRQ_MODE() || IS_IRQ_MASKED()) { + EvrRtxKernelGetTickFreq(0U); + return 0U; + } else { + return __svcKernelGetTickFreq(); + } +} + +/// Get the RTOS kernel system timer count. +uint32_t osKernelGetSysTimerCount (void) { + if (IS_IRQ_MODE() || IS_IRQ_MASKED()) { + return svcRtxKernelGetSysTimerCount(); + } else { + return __svcKernelGetSysTimerCount(); + } +} + +/// Get the RTOS kernel system timer frequency. +uint32_t osKernelGetSysTimerFreq (void) { + if (IS_IRQ_MODE() || IS_IRQ_MASKED()) { + return svcRtxKernelGetSysTimerFreq(); + } else { + return __svcKernelGetSysTimerFreq(); + } +} diff --git a/rtos/rtx2/TARGET_CORTEX_M/rtx_lib.c b/rtos/rtx2/TARGET_CORTEX_M/rtx_lib.c new file mode 100644 index 00000000000..1020f7adabc --- /dev/null +++ b/rtos/rtx2/TARGET_CORTEX_M/rtx_lib.c @@ -0,0 +1,634 @@ +/* + * Copyright (c) 2013-2017 ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ----------------------------------------------------------------------------- + * + * Project: CMSIS-RTOS RTX + * Title: RTX Library Configuration + * + * ----------------------------------------------------------------------------- + */ + +#include "cmsis_compiler.h" +#include "rtx_os.h" +#include "RTX_Config.h" + + +// System Configuration +// ==================== + +// Dynamic Memory +#if (OS_DYNAMIC_MEM_SIZE != 0) +#if ((OS_DYNAMIC_MEM_SIZE & 7) != 0) +#error "Invalid Dynamic Memory size!" +#endif +static uint64_t os_mem[OS_DYNAMIC_MEM_SIZE/8] \ +__attribute__((section(".bss.os"))); +#endif + +// Kernel Tick Frequency +#if (OS_TICK_FREQ < 1) +#error "Invalid Kernel Tick Frequency!" +#endif + +// ISR FIFO Queue +static void *os_isr_queue[OS_ISR_FIFO_QUEUE] \ +__attribute__((section(".bss.os"))); + + +// Thread Configuration +// ==================== + +#if (((OS_STACK_SIZE & 7) != 0) || (OS_STACK_SIZE < 72)) +#error "Invalid default Thread Stack size!" +#endif + +#if (((OS_IDLE_THREAD_STACK_SIZE & 7) != 0) || (OS_IDLE_THREAD_STACK_SIZE < 72)) +#error "Invalid Idle Thread Stack size!" +#endif + + +#if (OS_THREAD_OBJ_MEM != 0) + +#if (OS_THREAD_NUM == 0) +#error "Invalid number of user Threads!" +#endif + +#if ((OS_THREAD_USER_STACK_SIZE != 0) && ((OS_THREAD_USER_STACK_SIZE & 7) != 0)) +#error "Invalid total Stack size!" +#endif + +// Thread Control Blocks +static osRtxThread_t os_thread_cb[OS_THREAD_NUM] \ +__attribute__((section(".bss.os.thread.cb"))); + +// Thread Default Stack +#if (OS_THREAD_DEF_STACK_NUM != 0) +static uint64_t os_thread_def_stack[OS_THREAD_DEF_STACK_NUM*(OS_STACK_SIZE/8)] \ +__attribute__((section(".bss.os.thread.stack"))); +#endif + +// Memory Pool for Thread Control Blocks +static osRtxMpInfo_t os_mpi_thread \ +__attribute__((section(".data.os.thread.mpi"))) = +{ (uint32_t)OS_THREAD_NUM, 0U, (uint32_t)osRtxThreadCbSize, &os_thread_cb, NULL, NULL }; + +// Memory Pool for Thread Default Stack +#if (OS_THREAD_DEF_STACK_NUM != 0) +static osRtxMpInfo_t os_mpi_def_stack \ +__attribute__((section(".data.os.thread.mpi"))) = +{ (uint32_t)OS_THREAD_DEF_STACK_NUM, 0U, (uint32_t)OS_STACK_SIZE, &os_thread_def_stack, NULL, NULL }; +#endif + +// Memory Pool for Thread Stack +#if (OS_THREAD_USER_STACK_SIZE != 0) +static uint64_t os_thread_stack[OS_THREAD_USER_STACK_SIZE/8] \ +__attribute__((section(".bss.os.thread.stack"))); +#endif + +#endif // (OS_THREAD_OBJ_MEM != 0) + + +// Stack overrun checking +#if (OS_STACK_CHECK == 0) +// Override library function +void osRtxThreadStackCheck (void); +void osRtxThreadStackCheck (void) {} +#endif + + +// Idle Thread Control Block +static osRtxThread_t os_idle_thread_cb \ +__attribute__((section(".bss.os.thread.cb"))); + +// Idle Thread Stack +static uint64_t os_idle_thread_stack[OS_IDLE_THREAD_STACK_SIZE/8] \ +__attribute__((section(".bss.os.thread.stack"))); + +// Idle Thread Attributes +static const osThreadAttr_t os_idle_thread_attr = { + NULL, + osThreadDetached, + &os_idle_thread_cb, + (uint32_t)sizeof(os_idle_thread_cb), + &os_idle_thread_stack, + (uint32_t)sizeof(os_idle_thread_stack), + osPriorityIdle, + 0U, 0U +}; + + +// Timer Configuration +// =================== + +#if (OS_TIMER_OBJ_MEM != 0) + +#if (OS_TIMER_NUM == 0) +#error "Invalid number of Timer objects!" +#endif + +// Timer Control Blocks +static osRtxTimer_t os_timer_cb[OS_TIMER_NUM] \ +__attribute__((section(".bss.os.timer.cb"))); + +// Memory Pool for Timer Control Blocks +static osRtxMpInfo_t os_mpi_timer \ +__attribute__((section(".data.os.timer.mpi"))) = +{ (uint32_t)OS_TIMER_NUM, 0U, (uint32_t)osRtxTimerCbSize, &os_timer_cb, NULL, NULL }; + +#endif // (OS_TIMER_OBJ_MEM != 0) + + +#if ((OS_TIMER_THREAD_STACK_SIZE != 0) && (OS_TIMER_CB_QUEUE != 0)) + +#if (((OS_TIMER_THREAD_STACK_SIZE & 7) != 0) || (OS_TIMER_THREAD_STACK_SIZE < 96)) +#error "Invalid Timer Thread Stack size!" +#endif + +// Timer Thread Control Block +static osRtxThread_t os_timer_thread_cb \ +__attribute__((section(".bss.os.thread.cb"))); + +// Timer Thread Stack +static uint64_t os_timer_thread_stack[OS_TIMER_THREAD_STACK_SIZE/8] \ +__attribute__((section(".bss.os.thread.stack"))); + +// Timer Thread Attributes +static const osThreadAttr_t os_timer_thread_attr = { + NULL, + osThreadDetached, + &os_timer_thread_cb, + (uint32_t)sizeof(os_timer_thread_cb), + &os_timer_thread_stack, + (uint32_t)sizeof(os_timer_thread_stack), + (osPriority_t)OS_TIMER_THREAD_PRIO, + 0U, 0U +}; + +// Timer Message Queue Control Block +static osRtxMessageQueue_t os_timer_mq_cb \ +__attribute__((section(".bss.os.msgqueue.cb"))); + +// Timer Message Queue Data +static uint32_t os_timer_mq_data[osRtxMessageQueueMemSize(OS_TIMER_CB_QUEUE,8)/4] \ +__attribute__((section(".bss.os.msgqueue.mem"))); + +// Timer Message Queue Attributes +static const osMessageQueueAttr_t os_timer_mq_attr = { + NULL, + 0U, + &os_timer_mq_cb, + (uint32_t)sizeof(os_timer_mq_cb), + &os_timer_mq_data, + (uint32_t)sizeof(os_timer_mq_data) +}; + +#else + +extern void osRtxTimerThread (void *argument); + void osRtxTimerThread (void *argument) {} + +#endif // ((OS_TIMER_THREAD_STACK_SIZE != 0) && (OS_TIMER_CB_QUEUE != 0)) + + +// Event Flags Configuration +// ========================= + +#if (OS_EVFLAGS_OBJ_MEM != 0) + +#if (OS_EVFLAGS_NUM == 0) +#error "Invalid number of Event Flags objects!" +#endif + +// Event Flags Control Blocks +static osRtxEventFlags_t os_ef_cb[OS_EVFLAGS_NUM] \ +__attribute__((section(".bss.os.evflags.cb"))); + +// Memory Pool for Event Flags Control Blocks +static osRtxMpInfo_t os_mpi_ef \ +__attribute__((section(".data.os.evflags.mpi"))) = +{ (uint32_t)OS_EVFLAGS_NUM, 0U, (uint32_t)osRtxEventFlagsCbSize, &os_ef_cb, NULL, NULL }; + +#endif // (OS_EVFLAGS_OBJ_MEM != 0) + + +// Mutex Configuration +// =================== + +#if (OS_MUTEX_OBJ_MEM != 0) + +#if (OS_MUTEX_NUM == 0) +#error "Invalid number of Mutex objects!" +#endif + +// Mutex Control Blocks +static osRtxMutex_t os_mutex_cb[OS_MUTEX_NUM] \ +__attribute__((section(".bss.os.mutex.cb"))); + +// Memory Pool for Mutex Control Blocks +static osRtxMpInfo_t os_mpi_mutex \ +__attribute__((section(".data.os.mutex.mpi"))) = +{ (uint32_t)OS_MUTEX_NUM, 0U, (uint32_t)osRtxMutexCbSize, &os_mutex_cb, NULL, NULL }; + +#endif // (OS_MUTEX_OBJ_MEM != 0) + + +// Semaphore Configuration +// ======================= + +#if (OS_SEMAPHORE_OBJ_MEM != 0) + +#if (OS_SEMAPHORE_NUM == 0) +#error "Invalid number of Semaphore objects!" +#endif + +// Semaphore Control Blocks +static osRtxSemaphore_t os_semaphore_cb[OS_SEMAPHORE_NUM] \ +__attribute__((section(".bss.os.semaphore.cb"))); + +// Memory Pool for Semaphore Control Blocks +static osRtxMpInfo_t os_mpi_semaphore \ +__attribute__((section(".data.os.semaphore.mpi"))) = +{ (uint32_t)OS_SEMAPHORE_NUM, 0U, (uint32_t)osRtxSemaphoreCbSize, &os_semaphore_cb, NULL, NULL }; + +#endif // (OS_SEMAPHORE_OBJ_MEM != 0) + + +// Memory Pool Configuration +// ========================= + +#if (OS_MEMPOOL_OBJ_MEM != 0) + +#if (OS_MEMPOOL_NUM == 0) +#error "Invalid number of Memory Pool objects!" +#endif + +// Memory Pool Control Blocks +static osRtxMemoryPool_t os_mp_cb[OS_MEMPOOL_NUM] \ +__attribute__((section(".bss.os.mempool.cb"))); + +// Memory Pool for Memory Pool Control Blocks +static osRtxMpInfo_t os_mpi_mp \ +__attribute__((section(".data.os.mempool.mpi"))) = +{ (uint32_t)OS_MEMPOOL_NUM, 0U, (uint32_t)osRtxMemoryPoolCbSize, &os_mp_cb, NULL, NULL }; + +// Memory Pool for Memory Pool Data Storage +#if (OS_MEMPOOL_DATA_SIZE != 0) +#if ((OS_MEMPOOL_DATA_SIZE & 7) != 0) +#error "Invalid Data Memory size for Memory Pools!" +#endif +static uint64_t os_mp_data[OS_MEMPOOL_DATA_SIZE/8] \ +__attribute__((section(".bss.os.mempool.mem"))); +#endif + +#endif // (OS_MEMPOOL_OBJ_MEM != 0) + + +// Message Queue Configuration +// =========================== + +#if (OS_MSGQUEUE_OBJ_MEM != 0) + +#if (OS_MSGQUEUE_NUM == 0) +#error "Invalid number of Message Queue objects!" +#endif + +// Message Queue Control Blocks +static osRtxMessageQueue_t os_mq_cb[OS_MSGQUEUE_NUM] \ +__attribute__((section(".bss.os.msgqueue.cb"))); + +// Memory Pool for Message Queue Control Blocks +static osRtxMpInfo_t os_mpi_mq \ +__attribute__((section(".data.os.msgqueue.mpi"))) = +{ (uint32_t)OS_MSGQUEUE_NUM, 0U, (uint32_t)osRtxMessageQueueCbSize, &os_mq_cb, NULL, NULL }; + +// Memory Pool for Message Queue Data Storage +#if (OS_MSGQUEUE_DATA_SIZE != 0) +#if ((OS_MSGQUEUE_DATA_SIZE & 7) != 0) +#error "Invalid Data Memory size for Message Queues!" +#endif +static uint64_t os_mq_data[OS_MSGQUEUE_DATA_SIZE/8] \ +__attribute__((section(".bss.os.msgqueue.mem"))); +#endif + +#endif // (OS_MSGQUEUE_OBJ_MEM != 0) + + +// OS Configuration +// ================ + +__USED +__attribute__((section(".rodata"))) +const osRtxConfig_t osRtxConfig = { + 0U // Flags +#if (OS_PRIVILEGE_MODE != 0) + | osRtxConfigPrivilegedMode +#endif +#if (OS_STACK_CHECK != 0) + | osRtxConfigStackCheck +#endif +#if (OS_STACK_WATERMARK != 0) + | osRtxConfigStackWatermark +#endif + , + (uint32_t)OS_TICK_FREQ, +#if (OS_ROBIN_ENABLE != 0) + (uint32_t)OS_ROBIN_TIMEOUT, +#else + 0U, +#endif + { &os_isr_queue[0], sizeof(os_isr_queue)/sizeof(void *), 0U }, + { + // Memory Pools (Variable Block Size) +#if ((OS_THREAD_OBJ_MEM != 0) && (OS_THREAD_USER_STACK_SIZE != 0)) + &os_thread_stack, (uint32_t)OS_THREAD_USER_STACK_SIZE, +#else + NULL, 0U, +#endif +#if ((OS_MEMPOOL_OBJ_MEM != 0) && (OS_MEMPOOL_DATA_SIZE != 0)) + &os_mp_data, (uint32_t)OS_MEMPOOL_DATA_SIZE, +#else + NULL, 0U, +#endif +#if ((OS_MSGQUEUE_OBJ_MEM != 0) && (OS_MSGQUEUE_DATA_SIZE != 0)) + &os_mq_data, (uint32_t)OS_MSGQUEUE_DATA_SIZE, +#else + NULL, 0U, +#endif +#if (OS_DYNAMIC_MEM_SIZE != 0) + &os_mem, (uint32_t)OS_DYNAMIC_MEM_SIZE, +#else + NULL, 0U +#endif + }, + { + // Memory Pools (Fixed Block Size) +#if (OS_THREAD_OBJ_MEM != 0) +#if (OS_THREAD_DEF_STACK_NUM != 0) + &os_mpi_def_stack, +#else + NULL, +#endif + &os_mpi_thread, +#else + NULL, + NULL, +#endif +#if (OS_TIMER_OBJ_MEM != 0) + &os_mpi_timer, +#else + NULL, +#endif +#if (OS_EVFLAGS_OBJ_MEM != 0) + &os_mpi_ef, +#else + NULL, +#endif +#if (OS_MUTEX_OBJ_MEM != 0) + &os_mpi_mutex, +#else + NULL, +#endif +#if (OS_SEMAPHORE_OBJ_MEM != 0) + &os_mpi_semaphore, +#else + NULL, +#endif +#if (OS_MEMPOOL_OBJ_MEM != 0) + &os_mpi_mp, +#else + NULL, +#endif +#if (OS_MSGQUEUE_OBJ_MEM != 0) + &os_mpi_mq, +#else + NULL, +#endif + }, + (uint32_t)OS_STACK_SIZE, + &os_idle_thread_attr, +#if ((OS_TIMER_THREAD_STACK_SIZE != 0) && (OS_TIMER_CB_QUEUE != 0)) + &os_timer_thread_attr, + &os_timer_mq_attr, + (uint32_t)OS_TIMER_CB_QUEUE +#else + NULL, + NULL, + 0U +#endif +}; + + +// Non weak reference to library irq module +extern uint8_t irqRtxLib; +extern const uint8_t *irqRtxLibRef; + const uint8_t *irqRtxLibRef = &irqRtxLib; + +// Default User SVC Table +extern void * const osRtxUserSVC[]; +__WEAK void * const osRtxUserSVC[1] = { (void *)0 }; + + +// OS Sections +// =========== + +#if (defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)) +__asm ( + ".weakref __os_thread_cb_start__, .bss.os.thread.cb$$Base\n\t" + ".weakref __os_thread_cb_end__, .bss.os.thread.cb$$Limit\n\t" + ".weakref __os_timer_cb_start__, .bss.os.timer.cb$$Base\n\t" + ".weakref __os_timer_cb_end__, .bss.os.timer.cb$$Limit\n\t" + ".weakref __os_evflags_cb_start__, .bss.os.evflags.cb$$Base\n\t" + ".weakref __os_evflags_cb_end__, .bss.os.evflags.cb$$Limit\n\t" + ".weakref __os_mutex_cb_start__, .bss.os.mutex.cb$$Base\n\t" + ".weakref __os_mutex_cb_end__, .bss.os.mutex.cb$$Limit\n\t" + ".weakref __os_semaphore_cb_start__, .bss.os.semaphore.cb$$Base\n\t" + ".weakref __os_semaphore_cb_end__, .bss.os.semaphore.cb$$Limit\n\t" + ".weakref __os_mempool_cb_start__, .bss.os.mempool.cb$$Base\n\t" + ".weakref __os_mempool_cb_end__, .bss.os.mempool.cb$$Limit\n\t" + ".weakref __os_msgqueue_cb_start__, .bss.os.msgqueue.cb$$Base\n\t" + ".weakref __os_msgqueue_cb_end__, .bss.os.msgqueue.cb$$Limit\n\t" +); +#endif + +#if (defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)) || \ + (defined(__GNUC__) && !defined(__CC_ARM)) + +extern __attribute__((weak)) uint32_t __os_thread_cb_start__; +extern __attribute__((weak)) uint32_t __os_thread_cb_end__; +extern __attribute__((weak)) uint32_t __os_timer_cb_start__; +extern __attribute__((weak)) uint32_t __os_timer_cb_end__; +extern __attribute__((weak)) uint32_t __os_evflags_cb_start__; +extern __attribute__((weak)) uint32_t __os_evflags_cb_end__; +extern __attribute__((weak)) uint32_t __os_mutex_cb_start__; +extern __attribute__((weak)) uint32_t __os_mutex_cb_end__; +extern __attribute__((weak)) uint32_t __os_semaphore_cb_start__; +extern __attribute__((weak)) uint32_t __os_semaphore_cb_end__; +extern __attribute__((weak)) uint32_t __os_mempool_cb_start__; +extern __attribute__((weak)) uint32_t __os_mempool_cb_end__; +extern __attribute__((weak)) uint32_t __os_msgqueue_cb_start__; +extern __attribute__((weak)) uint32_t __os_msgqueue_cb_end__; + +__asm (".global os_cb_sections"); + +extern const uint32_t os_cb_sections[]; + +__attribute__((section(".rodata"))) +const uint32_t os_cb_sections[] = { + (uint32_t)&__os_thread_cb_start__, + (uint32_t)&__os_thread_cb_end__, + (uint32_t)&__os_timer_cb_start__, + (uint32_t)&__os_timer_cb_end__, + (uint32_t)&__os_evflags_cb_start__, + (uint32_t)&__os_evflags_cb_end__, + (uint32_t)&__os_mutex_cb_start__, + (uint32_t)&__os_mutex_cb_end__, + (uint32_t)&__os_semaphore_cb_start__, + (uint32_t)&__os_semaphore_cb_end__, + (uint32_t)&__os_mempool_cb_start__, + (uint32_t)&__os_mempool_cb_end__, + (uint32_t)&__os_msgqueue_cb_start__, + (uint32_t)&__os_msgqueue_cb_end__ +}; + +#endif + + +// OS Initialization +// ================= + +#if defined(__CC_ARM) || \ + (defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)) + +#ifndef __MICROLIB +extern void _platform_post_stackheap_init (void); +__WEAK void _platform_post_stackheap_init (void) { + osKernelInitialize(); +} +#endif + +#elif defined(__GNUC__) + +extern void software_init_hook (void); +__WEAK void software_init_hook (void) { + osKernelInitialize(); +} + +#endif + + +// C/C++ Standard Library Multithreading Interface +// =============================================== + +#if (( defined(__CC_ARM) || \ + (defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050))) && \ + !defined(__MICROLIB)) + +#define LIBSPACE_SIZE 96 + +// Memory for libspace +static uint32_t os_libspace[OS_THREAD_LIBSPACE_NUM+1][LIBSPACE_SIZE/sizeof(uint32_t)] \ +__attribute__((section(".bss.os"))); + +// Thread IDs for libspace +static osThreadId_t os_libspace_id[OS_THREAD_LIBSPACE_NUM] \ +__attribute__((section(".bss.os"))); + +// Check if Kernel has been started +static uint32_t os_kernel_is_active (void) { + static uint8_t os_kernel_active = 0U; + + if (os_kernel_active == 0U) { + if (osKernelGetState() > osKernelReady) { + os_kernel_active = 1U; + return 1U; + } + return 0U; + } else { + return 1U; + } +} + +// Provide libspace for current thread +void *__user_perthread_libspace (void); +void *__user_perthread_libspace (void) { + osThreadId_t id; + uint32_t n; + + if (!os_kernel_is_active()) { + return (void *)&os_libspace[OS_THREAD_LIBSPACE_NUM][0]; + } + + id = osThreadGetId(); + for (n = 0U; n < OS_THREAD_LIBSPACE_NUM; n++) { + if (os_libspace_id[n] == NULL) { + os_libspace_id[n] = id; + return (void *)&os_libspace[n][0]; + } + if (os_libspace_id[n] == id) { + return (void *)&os_libspace[n][0]; + } + } + + if (n == OS_THREAD_LIBSPACE_NUM) { + osRtxErrorNotify(osRtxErrorClibSpace, id); + } + + return (void *)&os_libspace[n][0]; +} + +// Mutex identifier +typedef void *mutex; + +// Initialize mutex +__USED +int _mutex_initialize(mutex *m); +int _mutex_initialize(mutex *m) { + *m = osMutexNew(NULL); + if (*m == NULL) { + osRtxErrorNotify(osRtxErrorClibMutex, m); + return 0; + } + return 1; +} + +// Acquire mutex +__USED +void _mutex_acquire(mutex *m); +void _mutex_acquire(mutex *m) { + if (os_kernel_is_active()) { + osMutexAcquire(*m, osWaitForever); + } +} + +// Release mutex +__USED +void _mutex_release(mutex *m); +void _mutex_release(mutex *m) { + if (os_kernel_is_active()) { + osMutexRelease(*m); + } +} + +// Free mutex +__USED +void _mutex_free(mutex *m); +void _mutex_free(mutex *m) { + osMutexDelete(*m); +} + +#endif diff --git a/rtos/rtx2/TARGET_CORTEX_M/rtx_lib.h b/rtos/rtx2/TARGET_CORTEX_M/rtx_lib.h new file mode 100644 index 00000000000..75d6fca46f3 --- /dev/null +++ b/rtos/rtx2/TARGET_CORTEX_M/rtx_lib.h @@ -0,0 +1,214 @@ +/* + * Copyright (c) 2013-2017 ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ----------------------------------------------------------------------------- + * + * Project: CMSIS-RTOS RTX + * Title: RTX Library definitions + * + * ----------------------------------------------------------------------------- + */ + +#ifndef RTX_LIB_H_ +#define RTX_LIB_H_ + +#include +#include +#include "core_cm.h" // Cortex-M definitions +#include "tz_context.h" // TrustZone Context API +#include "cmsis_os2.h" // CMSIS RTOS API +#include "rtx_os.h" // RTX OS definitions +#include "rtx_evr.h" // RTX Event Recorder definitions + + +// ==== Library defines ==== + +#define os_thread_t osRtxThread_t +#define os_timer_t osRtxTimer_t +#define os_timer_finfo_t osRtxTimerFinfo_t +#define os_event_flags_t osRtxEventFlags_t +#define os_mutex_t osRtxMutex_t +#define os_semaphore_t osRtxSemaphore_t +#define os_mp_info_t osRtxMpInfo_t +#define os_memory_pool_t osRtxMemoryPool_t +#define os_message_t osRtxMessage_t +#define os_message_queue_t osRtxMessageQueue_t +#define os_object_t osRtxObject_t + +// ==== Inline functions ==== + +// Kernel Inline functions +__STATIC_INLINE uint8_t osRtxKernelGetState (void) { return osRtxInfo.kernel.state; } + +// Thread Inline functions +__STATIC_INLINE os_thread_t *osRtxThreadGetRunning (void) { return osRtxInfo.thread.run.curr; } +__STATIC_INLINE void osRtxThreadSetRunning (os_thread_t *thread) { osRtxInfo.thread.run.curr = thread; } + + +// ==== Library functions ==== + +// Thread Library functions +extern void osRtxThreadListPut (volatile os_object_t *object, os_thread_t *thread); +extern os_thread_t *osRtxThreadListGet (volatile os_object_t *object); +extern void *osRtxThreadListRoot (os_thread_t *thread); +extern void osRtxThreadListSort (os_thread_t *thread); +extern void osRtxThreadListRemove (os_thread_t *thread); +extern void osRtxThreadListUnlink (os_thread_t **thread_list, os_thread_t *thread); +extern void osRtxThreadReadyPut (os_thread_t *thread); +extern void osRtxThreadDelayInsert (os_thread_t *thread, uint32_t delay); +extern void osRtxThreadDelayRemove (os_thread_t *thread); +extern void osRtxThreadDelayTick (void); +extern uint32_t *osRtxThreadRegPtr (os_thread_t *thread); +extern void osRtxThreadBlock (os_thread_t *thread); +extern void osRtxThreadSwitch (os_thread_t *thread); +extern void osRtxThreadDispatch (os_thread_t *thread); +extern void osRtxThreadWaitExit (os_thread_t *thread, uint32_t ret_val, bool dispatch); +extern bool osRtxThreadWaitEnter (uint8_t state, uint32_t timeout); +extern void osRtxThreadStackCheck (void); + +// Timer Library functions +extern void osRtxTimerTick (void); +extern void osRtxTimerThread (void *argument); + +// Mutex Library functions +extern void osRtxMutexOwnerRelease (os_mutex_t *mutex_list); + +// Memory Heap Library functions +extern uint32_t osRtxMemoryInit (void *mem, uint32_t size); +extern void *osRtxMemoryAlloc(void *mem, uint32_t size, uint32_t type); +extern uint32_t osRtxMemoryFree (void *mem, void *block); + +// Memory Pool Library functions +extern uint32_t osRtxMemoryPoolInit (os_mp_info_t *mp_info, uint32_t blocks, uint32_t block_size, void *block_mem); +extern void *osRtxMemoryPoolAlloc (os_mp_info_t *mp_info); +extern osStatus_t osRtxMemoryPoolFree (os_mp_info_t *mp_info, void *block); + +// System Library functions +extern void osRtxTick_Handler (void); +extern void osRtxPendSV_Handler (void); +extern void osRtxPostProcess (os_object_t *object); + +// Post ISR processing functions +extern void osRtxThreadPostProcess (os_thread_t *thread); +extern void osRtxEventFlagsPostProcess (os_event_flags_t *ef); +extern void osRtxSemaphorePostProcess (os_semaphore_t *semaphore); +extern void osRtxMemoryPoolPostProcess (os_memory_pool_t *mp); +extern void osRtxMessageQueuePostProcess (os_message_t *msg); + + +// ==== Service Calls ==== + +// Kernel Service Calls +extern osStatus_t svcRtxKernelInitialize (void); +extern osStatus_t svcRtxKernelGetInfo (osVersion_t *version, char *id_buf, uint32_t id_size); +extern osKernelState_t svcRtxKernelGetState (void); +extern osStatus_t svcRtxKernelStart (void); +extern int32_t svcRtxKernelLock (void); +extern int32_t svcRtxKernelUnlock (void); +extern int32_t svcRtxKernelRestoreLock (int32_t lock); +extern uint32_t svcRtxKernelSuspend (void); +extern void svcRtxKernelResume (uint32_t sleep_ticks); +extern uint64_t svcRtxKernelGetTickCount (void); +extern uint32_t svcRtxKernelGetTickFreq (void); +extern uint32_t svcRtxKernelGetSysTimerCount (void); +extern uint32_t svcRtxKernelGetSysTimerFreq (void); + +// Thread Service Calls +extern osThreadId_t svcRtxThreadNew (osThreadFunc_t func, void *argument, const osThreadAttr_t *attr); +extern const char * svcRtxThreadGetName (osThreadId_t thread_id); +extern osThreadId_t svcRtxThreadGetId (void); +extern osThreadState_t svcRtxThreadGetState (osThreadId_t thread_id); +extern uint32_t svcRtxThreadGetStackSize (osThreadId_t thread_id); +extern uint32_t svcRtxThreadGetStackSpace(osThreadId_t thread_id); +extern osStatus_t svcRtxThreadSetPriority (osThreadId_t thread_id, osPriority_t priority); +extern osPriority_t svcRtxThreadGetPriority (osThreadId_t thread_id); +extern osStatus_t svcRtxThreadYield (void); +extern osStatus_t svcRtxThreadSuspend (osThreadId_t thread_id); +extern osStatus_t svcRtxThreadResume (osThreadId_t thread_id); +extern osStatus_t svcRtxThreadDetach (osThreadId_t thread_id); +extern osStatus_t svcRtxThreadJoin (osThreadId_t thread_id); +extern void svcRtxThreadExit (void); +extern osStatus_t svcRtxThreadTerminate (osThreadId_t thread_id); +extern uint32_t svcRtxThreadGetCount (void); +extern uint32_t svcRtxThreadEnumerate (osThreadId_t *thread_array, uint32_t array_items); +extern uint32_t svcRtxThreadFlagsSet (osThreadId_t thread_id, uint32_t flags); +extern uint32_t svcRtxThreadFlagsClear (uint32_t flags); +extern uint32_t svcRtxThreadFlagsGet (void); +extern uint32_t svcRtxThreadFlagsWait (uint32_t flags, uint32_t options, uint32_t timeout); + +// Delay Service Calls +extern osStatus_t svcRtxDelay (uint32_t ticks); +extern osStatus_t svcRtxDelayUntil (uint32_t ticks_l, uint32_t ticks_h); + +// Timer Service Calls +extern osTimerId_t svcRtxTimerNew (osTimerFunc_t func, osTimerType_t type, void *argument, const osTimerAttr_t *attr); +extern const char * svcRtxTimerGetName (osTimerId_t timer_id); +extern osStatus_t svcRtxTimerStart (osTimerId_t timer_id, uint32_t ticks); +extern osStatus_t svcRtxTimerStop (osTimerId_t timer_id); +extern uint32_t svcRtxTimerIsRunning (osTimerId_t timer_id); +extern osStatus_t svcRtxTimerDelete (osTimerId_t timer_id); + +// Event Flags Service Calls +extern osEventFlagsId_t svcRtxEventFlagsNew (const osEventFlagsAttr_t *attr); +extern const char * svcRtxEventFlagsGetName (osEventFlagsId_t ef_id); +extern uint32_t svcRtxEventFlagsSet (osEventFlagsId_t ef_id, uint32_t flags); +extern uint32_t svcRtxEventFlagsClear (osEventFlagsId_t ef_id, uint32_t flags); +extern uint32_t svcRtxEventFlagsGet (osEventFlagsId_t ef_id); +extern uint32_t svcRtxEventFlagsWait (osEventFlagsId_t ef_id, uint32_t flags, uint32_t options, uint32_t timeout); +extern osStatus_t svcRtxEventFlagsDelete (osEventFlagsId_t ef_id); + +// Mutex Service Calls +extern osMutexId_t svcRtxMutexNew (const osMutexAttr_t *attr); +extern const char * svcRtxMutexGetName (osMutexId_t mutex_id); +extern osStatus_t svcRtxMutexAcquire (osMutexId_t mutex_id, uint32_t timeout); +extern osStatus_t svcRtxMutexRelease (osMutexId_t mutex_id); +extern osThreadId_t svcRtxMutexGetOwner (osMutexId_t mutex_id); +extern osStatus_t svcRtxMutexDelete (osMutexId_t mutex_id); + +// Semaphore Service Calls +extern osSemaphoreId_t svcRtxSemaphoreNew (uint32_t max_count, uint32_t initial_count, const osSemaphoreAttr_t *attr); +extern const char * svcRtxSemaphoreGetName (osSemaphoreId_t semaphore_id); +extern osStatus_t svcRtxSemaphoreRelease (osSemaphoreId_t semaphore_id); +extern osStatus_t svcRtxSemaphoreAcquire (osSemaphoreId_t semaphore_id, uint32_t timeout); +extern uint32_t svcRtxSemaphoreGetCount(osSemaphoreId_t semaphore_id); +extern osStatus_t svcRtxSemaphoreDelete (osSemaphoreId_t semaphore_id); + +// Memory Pool Service Calls +extern osMemoryPoolId_t svcRtxMemoryPoolNew (uint32_t blocks, uint32_t block_size, const osMemoryPoolAttr_t *attr); +extern const char * svcRtxMemoryPoolGetName (osMemoryPoolId_t mp_id); +extern void * svcRtxMemoryPoolAlloc (osMemoryPoolId_t mp_id, uint32_t timeout); +extern osStatus_t svcRtxMemoryPoolFree (osMemoryPoolId_t mp_id, void *block); +extern uint32_t svcRtxMemoryPoolGetCapacity (osMemoryPoolId_t mp_id); +extern uint32_t svcRtxMemoryPoolGetBlockSize (osMemoryPoolId_t mp_id); +extern uint32_t svcRtxMemoryPoolGetCount (osMemoryPoolId_t mp_id); +extern uint32_t svcRtxMemoryPoolGetSpace (osMemoryPoolId_t mp_id); +extern osStatus_t svcRtxMemoryPoolDelete (osMemoryPoolId_t mp_id); + +// Message Queue Service Calls +extern osMessageQueueId_t svcRtxMessageQueueNew (uint32_t msg_count, uint32_t msg_size, const osMessageQueueAttr_t *attr); +extern const char * svcRtxMessageQueueGetName (osMessageQueueId_t mq_id); +extern osStatus_t svcRtxMessageQueuePut (osMessageQueueId_t mq_id, const void *msg_ptr, uint8_t msg_prio, uint32_t timeout); +extern osStatus_t svcRtxMessageQueueGet (osMessageQueueId_t mq_id, void *msg_ptr, uint8_t *msg_prio, uint32_t timeout); +extern uint32_t svcRtxMessageQueueGetCapacity (osMessageQueueId_t mq_id); +extern uint32_t svcRtxMessageQueueGetMsgSize (osMessageQueueId_t mq_id); +extern uint32_t svcRtxMessageQueueGetCount (osMessageQueueId_t mq_id); +extern uint32_t svcRtxMessageQueueGetSpace (osMessageQueueId_t mq_id); +extern osStatus_t svcRtxMessageQueueReset (osMessageQueueId_t mq_id); +extern osStatus_t svcRtxMessageQueueDelete (osMessageQueueId_t mq_id); + + +#endif // RTX_LIB_H_ diff --git a/rtos/rtx2/TARGET_CORTEX_M/rtx_memory.c b/rtos/rtx2/TARGET_CORTEX_M/rtx_memory.c new file mode 100644 index 00000000000..f86e802ebcb --- /dev/null +++ b/rtos/rtx2/TARGET_CORTEX_M/rtx_memory.c @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2013-2017 ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ----------------------------------------------------------------------------- + * + * Project: CMSIS-RTOS RTX + * Title: Memory functions + * + * ----------------------------------------------------------------------------- + */ + +#include "rtx_lib.h" + + +// Memory Pool Header structure +typedef struct mem_head_s { + uint32_t size; // Memory Pool size + uint32_t used; // Used Memory +} mem_head_t; + +// Memory Block Header structure +typedef struct mem_block_s { + struct mem_block_s *next; // Next Memory Block in list + uint32_t info; // Info: length = <31:2>:'00', type = <1:0> +} mem_block_t; + +#define MB_INFO_LEN_MASK 0xFFFFFFFCU +#define MB_INFO_TYPE_MASK 0x00000003U + + +// ==== Library functions ==== + +/// Initialize Memory Pool with variable block size. +/// \param[in] mem pointer to memory pool. +/// \param[in] size size of a memory pool in bytes. +/// \return 1 - success, 0 - failure. +__WEAK uint32_t osRtxMemoryInit (void *mem, uint32_t size) { + mem_head_t *head; + mem_block_t *ptr; + + if ((mem == NULL) || ((uint32_t)mem & 7U) || (size & 7U) || + (size < (sizeof(mem_head_t) + 2*sizeof(mem_block_t)))) { + EvrRtxMemoryInit(mem, size, 0U); + return 0U; + } + + head = (mem_head_t *)mem; + head->size = size; + head->used = sizeof(mem_head_t) + sizeof(mem_block_t); + + ptr = (mem_block_t *)((uint32_t)mem + sizeof(mem_head_t)); + ptr->next = (mem_block_t *)((uint32_t)mem + size - sizeof(mem_block_t)); + ptr->next->next = NULL; + ptr->info = 0U; + + EvrRtxMemoryInit(mem, size, 1U); + + return 1U; +} + +/// Allocate a memory block from a Memory Pool. +/// \param[in] mem pointer to memory pool. +/// \param[in] size size of a memory block in bytes. +/// \param[in] type memory block type: 0 - generic, 1 - control block +/// \return allocated memory block or NULL in case of no memory is available. +__WEAK void *osRtxMemoryAlloc (void *mem, uint32_t size, uint32_t type) { + mem_block_t *p, *p_new, *ptr; + uint32_t hole_size; + + if ((mem == NULL) || (size == 0U) || (type & ~MB_INFO_TYPE_MASK)) { + EvrRtxMemoryAlloc(mem, size, type, NULL); + return NULL; + } + + // Add header to size + size += sizeof(mem_block_t); + // Make sure that block is 8-byte aligned + size = (size + 7U) & ~((uint32_t)7U); + + // Search for hole big enough + p = (mem_block_t *)((uint32_t)mem + sizeof(mem_head_t)); + for (;;) { + hole_size = (uint32_t)p->next - (uint32_t)p; + hole_size -= p->info & MB_INFO_LEN_MASK; + if (hole_size >= size) { + // Hole found + break; + } + p = p->next; + if (p->next == NULL) { + // Failed (end of list) + EvrRtxMemoryAlloc(mem, size, type, NULL); + return NULL; + } + } + + ((mem_head_t *)mem)->used += size; + + if (p->info == 0U) { + // No block allocated, set info of first element + p->info = size | type; + ptr = (mem_block_t *)((uint32_t)p + sizeof(mem_block_t)); + } else { + // Insert new element into the list + p_new = (mem_block_t *)((uint32_t)p + (p->info & MB_INFO_LEN_MASK)); + p_new->next = p->next; + p_new->info = size | type; + p->next = p_new; + ptr = (mem_block_t *)((uint32_t)p_new + sizeof(mem_block_t)); + } + + EvrRtxMemoryAlloc(mem, size, type, ptr); + + return ptr; +} + +/// Return an allocated memory block back to a Memory Pool. +/// \param[in] mem pointer to memory pool. +/// \param[in] block memory block to be returned to the memory pool. +/// \return 1 - success, 0 - failure. +__WEAK uint32_t osRtxMemoryFree (void *mem, void *block) { + mem_block_t *p, *p_prev, *ptr; + + if ((mem == NULL) || (block == NULL)) { + EvrRtxMemoryFree(mem, block, 0U); + return 0U; + } + + ptr = (mem_block_t *)((uint32_t)block - sizeof(mem_block_t)); + + // Search for header + p_prev = NULL; + p = (mem_block_t *)((uint32_t)mem + sizeof(mem_head_t)); + while (p != ptr) { + p_prev = p; + p = p->next; + if (p == NULL) { + // Not found + EvrRtxMemoryFree(mem, block, 0U); + return 0U; + } + } + + ((mem_head_t *)mem)->used -= p->info & MB_INFO_LEN_MASK; + + if (p_prev == NULL) { + // Release first block, only set info to 0 + p->info = 0U; + } else { + // Discard block from chained list + p_prev->next = p->next; + } + + EvrRtxMemoryFree(mem, block, 1U); + + return 1U; +} diff --git a/rtos/rtx2/TARGET_CORTEX_M/rtx_mempool.c b/rtos/rtx2/TARGET_CORTEX_M/rtx_mempool.c new file mode 100644 index 00000000000..63bb32a4e37 --- /dev/null +++ b/rtos/rtx2/TARGET_CORTEX_M/rtx_mempool.c @@ -0,0 +1,685 @@ +/* + * Copyright (c) 2013-2017 ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ----------------------------------------------------------------------------- + * + * Project: CMSIS-RTOS RTX + * Title: Memory Pool functions + * + * ----------------------------------------------------------------------------- + */ + +#include "rtx_lib.h" + + +// ==== Library functions ==== + +/// Initialize Memory Pool. +/// \param[in] mp_info memory pool info. +/// \param[in] block_count maximum number of memory blocks in memory pool. +/// \param[in] block_size size of a memory block in bytes. +/// \param[in] block_mem pointer to memory for block storage. +/// \return 1 - success, 0 - failure. +uint32_t osRtxMemoryPoolInit (os_mp_info_t *mp_info, uint32_t block_count, uint32_t block_size, void *block_mem) { + void *block; + + // Check parameters + if ((mp_info == NULL) || (block_count == 0U) || (block_size == 0U) || (block_mem == NULL)) { + return 0U; + } + + // Initialize information structure + mp_info->max_blocks = block_count; + mp_info->used_blocks = 0U; + mp_info->block_size = block_size; + mp_info->block_base = block_mem; + mp_info->block_free = block_mem; + mp_info->block_lim = (uint8_t *)block_mem + (block_count * block_size); + + EvrRtxMemoryBlockInit(mp_info, block_count, block_size, block_mem); + + // Link all free blocks + while (--block_count) { + block = (uint8_t *)block_mem + block_size; + *((void **)block_mem) = block; + block_mem = block; + } + *((void **)block_mem) = NULL; + + return 1U; +} + +/// Allocate a memory block from a Memory Pool. +/// \param[in] mp_info memory pool info. +/// \return address of the allocated memory block or NULL in case of no memory is available. +void *osRtxMemoryPoolAlloc (os_mp_info_t *mp_info) { +#if (__EXCLUSIVE_ACCESS == 0U) + uint32_t primask = __get_PRIMASK(); +#endif + void *block; + + if (mp_info == NULL) { + EvrRtxMemoryBlockAlloc(NULL, NULL); + return NULL; + } + +#if (__EXCLUSIVE_ACCESS == 0U) + __disable_irq(); + + if (mp_info->used_blocks < mp_info->max_blocks) { + mp_info->used_blocks++; + block = mp_info->block_free; + if (block != NULL) { + mp_info->block_free = *((void **)block); + } + } else { + block = NULL; + } + + if (primask == 0U) { + __enable_irq(); + } +#else + if (atomic_inc32_lt(&mp_info->used_blocks, mp_info->max_blocks) < mp_info->max_blocks) { + block = atomic_link_get(&mp_info->block_free); + } else { + block = NULL; + } +#endif + + EvrRtxMemoryBlockAlloc(mp_info, block); + + return block; +} + +/// Return an allocated memory block back to a Memory Pool. +/// \param[in] mp_info memory pool info. +/// \param[in] block address of the allocated memory block to be returned to the memory pool. +/// \return status code that indicates the execution status of the function. +osStatus_t osRtxMemoryPoolFree (os_mp_info_t *mp_info, void *block) { +#if (__EXCLUSIVE_ACCESS == 0U) + uint32_t primask = __get_PRIMASK(); +#endif + osStatus_t status; + + if ((mp_info == NULL) || (block < mp_info->block_base) || (block >= mp_info->block_lim)) { + EvrRtxMemoryBlockFree(mp_info, block, osErrorParameter); + return osErrorParameter; + } + +#if (__EXCLUSIVE_ACCESS == 0U) + __disable_irq(); + + if (mp_info->used_blocks != 0U) { + mp_info->used_blocks--; + *((void **)block) = mp_info->block_free; + mp_info->block_free = block; + status = osOK; + } else { + status = osErrorResource; + } + + if (primask == 0U) { + __enable_irq(); + } +#else + if (atomic_dec32_nz(&mp_info->used_blocks) != 0U) { + atomic_link_put(&mp_info->block_free, block); + status = osOK; + } else { + status = osErrorResource; + } +#endif + + EvrRtxMemoryBlockFree(mp_info, block, status); + + return status; +} + +/// Memory Pool post ISR processing. +/// \param[in] mp memory pool object. +void osRtxMemoryPoolPostProcess (os_memory_pool_t *mp) { + void *block; + os_thread_t *thread; + + if (mp->state == osRtxObjectInactive) { + return; + } + + // Check if Thread is waiting to allocate memory + if (mp->thread_list != NULL) { + // Allocate memory + block = osRtxMemoryPoolAlloc(&mp->mp_info); + if (block != NULL) { + // Wakeup waiting Thread with highest Priority + thread = osRtxThreadListGet((os_object_t*)mp); + osRtxThreadWaitExit(thread, (uint32_t)block, false); + EvrRtxMemoryPoolAllocated(mp, block); + } + } +} + + +// ==== Service Calls ==== + +// Service Calls definitions +SVC0_3M(MemoryPoolNew, osMemoryPoolId_t, uint32_t, uint32_t, const osMemoryPoolAttr_t *) +SVC0_1 (MemoryPoolGetName, const char *, osMemoryPoolId_t) +SVC0_2 (MemoryPoolAlloc, void *, osMemoryPoolId_t, uint32_t) +SVC0_2 (MemoryPoolFree, osStatus_t, osMemoryPoolId_t, void *) +SVC0_1 (MemoryPoolGetCapacity, uint32_t, osMemoryPoolId_t) +SVC0_1 (MemoryPoolGetBlockSize, uint32_t, osMemoryPoolId_t) +SVC0_1 (MemoryPoolGetCount, uint32_t, osMemoryPoolId_t) +SVC0_1 (MemoryPoolGetSpace, uint32_t, osMemoryPoolId_t) +SVC0_1 (MemoryPoolDelete, osStatus_t, osMemoryPoolId_t) + +/// Create and Initialize a Memory Pool object. +/// \note API identical to osMemoryPoolNew +osMemoryPoolId_t svcRtxMemoryPoolNew (uint32_t block_count, uint32_t block_size, const osMemoryPoolAttr_t *attr) { + os_memory_pool_t *mp; + void *mp_mem; + uint32_t mp_size; + uint32_t size; + uint8_t flags; + const char *name; + + // Check parameters + if ((block_count == 0U) || (block_size == 0U)) { + EvrRtxMemoryPoolError(NULL, osErrorParameter); + return NULL; + } + block_size = (block_size + 3U) & ~3UL; + if ((__CLZ(block_count) + __CLZ(block_size)) < 32) { + EvrRtxMemoryPoolError(NULL, osErrorParameter); + return NULL; + } + + size = block_count * block_size; + + // Process attributes + if (attr != NULL) { + name = attr->name; + mp = attr->cb_mem; + mp_mem = attr->mp_mem; + mp_size = attr->mp_size; + if (mp != NULL) { + if (((uint32_t)mp & 3U) || (attr->cb_size < sizeof(os_memory_pool_t))) { + EvrRtxMemoryPoolError(NULL, osRtxErrorInvalidControlBlock); + return NULL; + } + } else { + if (attr->cb_size != 0U) { + EvrRtxMemoryPoolError(NULL, osRtxErrorInvalidControlBlock); + return NULL; + } + } + if (mp_mem != NULL) { + if (((uint32_t)mp_mem & 3U) || (mp_size < size)) { + EvrRtxMemoryPoolError(NULL, osRtxErrorInvalidDataMemory); + return NULL; + } + } else { + if (mp_size != 0U) { + EvrRtxMemoryPoolError(NULL, osRtxErrorInvalidDataMemory); + return NULL; + } + } + } else { + name = NULL; + mp = NULL; + mp_mem = NULL; + } + + // Allocate object memory if not provided + if (mp == NULL) { + if (osRtxInfo.mpi.memory_pool != NULL) { + mp = osRtxMemoryPoolAlloc(osRtxInfo.mpi.memory_pool); + } else { + mp = osRtxMemoryAlloc(osRtxInfo.mem.common, sizeof(os_memory_pool_t), 1U); + } + if (mp == NULL) { + EvrRtxMemoryPoolError(NULL, osErrorNoMemory); + return NULL; + } + flags = osRtxFlagSystemObject; + } else { + flags = 0U; + } + + // Allocate data memory if not provided + if (mp_mem == NULL) { + mp_mem = osRtxMemoryAlloc(osRtxInfo.mem.mp_data, size, 0U); + if (mp_mem == NULL) { + EvrRtxMemoryPoolError(NULL, osErrorNoMemory); + if (flags & osRtxFlagSystemObject) { + if (osRtxInfo.mpi.memory_pool != NULL) { + osRtxMemoryPoolFree(osRtxInfo.mpi.memory_pool, mp); + } else { + osRtxMemoryFree(osRtxInfo.mem.common, mp); + } + } + return NULL; + } + memset(mp_mem, 0, size); + flags |= osRtxFlagSystemMemory; + } + + // Initialize control block + mp->id = osRtxIdMemoryPool; + mp->state = osRtxObjectActive; + mp->flags = flags; + mp->name = name; + mp->thread_list = NULL; + osRtxMemoryPoolInit(&mp->mp_info, block_count, block_size, mp_mem); + + // Register post ISR processing function + osRtxInfo.post_process.memory_pool = osRtxMemoryPoolPostProcess; + + EvrRtxMemoryPoolCreated(mp); + + return mp; +} + +/// Get name of a Memory Pool object. +/// \note API identical to osMemoryPoolGetName +const char *svcRtxMemoryPoolGetName (osMemoryPoolId_t mp_id) { + os_memory_pool_t *mp = (os_memory_pool_t *)mp_id; + + // Check parameters + if ((mp == NULL) || (mp->id != osRtxIdMemoryPool)) { + EvrRtxMemoryPoolGetName(mp, NULL); + return NULL; + } + + // Check object state + if (mp->state == osRtxObjectInactive) { + EvrRtxMemoryPoolGetName(mp, NULL); + return NULL; + } + + EvrRtxMemoryPoolGetName(mp, mp->name); + + return mp->name; +} + +/// Allocate a memory block from a Memory Pool. +/// \note API identical to osMemoryPoolAlloc +void *svcRtxMemoryPoolAlloc (osMemoryPoolId_t mp_id, uint32_t timeout) { + os_memory_pool_t *mp = (os_memory_pool_t *)mp_id; + void *block; + + // Check parameters + if ((mp == NULL) || (mp->id != osRtxIdMemoryPool)) { + EvrRtxMemoryPoolError(mp, osErrorParameter); + return NULL; + } + + // Check object state + if (mp->state == osRtxObjectInactive) { + EvrRtxMemoryPoolError(mp, osErrorResource); + return NULL; + } + + // Allocate memory + block = osRtxMemoryPoolAlloc(&mp->mp_info); + if (block == NULL) { + // No memory available + if (timeout != 0U) { + EvrRtxMemoryPoolAllocPending(mp, timeout); + // Suspend current Thread + osRtxThreadListPut((os_object_t*)mp, osRtxThreadGetRunning()); + osRtxThreadWaitEnter(osRtxThreadWaitingMemoryPool, timeout); + } else { + EvrRtxMemoryPoolAllocFailed(mp); + } + } else { + EvrRtxMemoryPoolAllocated(mp, block); + } + + return block; +} + +/// Return an allocated memory block back to a Memory Pool. +/// \note API identical to osMemoryPoolFree +osStatus_t svcRtxMemoryPoolFree (osMemoryPoolId_t mp_id, void *block) { + os_memory_pool_t *mp = (os_memory_pool_t *)mp_id; + os_thread_t *thread; + osStatus_t status; + + // Check parameters + if ((mp == NULL) || (mp->id != osRtxIdMemoryPool)) { + EvrRtxMemoryPoolError(mp, osErrorParameter); + return osErrorParameter; + } + + // Check object state + if (mp->state == osRtxObjectInactive) { + EvrRtxMemoryPoolError(mp, osErrorResource); + return osErrorResource; + } + + // Free memory + status = osRtxMemoryPoolFree(&mp->mp_info, block); + if (status == osOK) { + EvrRtxMemoryPoolDeallocated(mp, block); + // Check if Thread is waiting to allocate memory + if (mp->thread_list != NULL) { + // Allocate memory + block = osRtxMemoryPoolAlloc(&mp->mp_info); + if (block != NULL) { + // Wakeup waiting Thread with highest Priority + thread = osRtxThreadListGet((os_object_t*)mp); + osRtxThreadWaitExit(thread, (uint32_t)block, true); + EvrRtxMemoryPoolAllocated(mp, block); + } + } + } else { + EvrRtxMemoryPoolFreeFailed(mp, block); + } + + return status; +} + +/// Get maximum number of memory blocks in a Memory Pool. +/// \note API identical to osMemoryPoolGetCapacity +uint32_t svcRtxMemoryPoolGetCapacity (osMemoryPoolId_t mp_id) { + os_memory_pool_t *mp = (os_memory_pool_t *)mp_id; + + // Check parameters + if ((mp == NULL) || (mp->id != osRtxIdMemoryPool)) { + EvrRtxMemoryPoolGetCapacity(mp, 0U); + return 0U; + } + + // Check object state + if (mp->state == osRtxObjectInactive) { + EvrRtxMemoryPoolGetCapacity(mp, 0U); + return 0U; + } + + EvrRtxMemoryPoolGetCapacity(mp, mp->mp_info.max_blocks); + + return mp->mp_info.max_blocks; +} + +/// Get memory block size in a Memory Pool. +/// \note API identical to osMemoryPoolGetBlockSize +uint32_t svcRtxMemoryPoolGetBlockSize (osMemoryPoolId_t mp_id) { + os_memory_pool_t *mp = (os_memory_pool_t *)mp_id; + + // Check parameters + if ((mp == NULL) || (mp->id != osRtxIdMemoryPool)) { + EvrRtxMemoryPoolGetBlockSize(mp, 0U); + return 0U; + } + + // Check object state + if (mp->state == osRtxObjectInactive) { + EvrRtxMemoryPoolGetBlockSize(mp, 0U); + return 0U; + } + + EvrRtxMemoryPoolGetBlockSize(mp, mp->mp_info.block_size); + + return mp->mp_info.block_size; +} + +/// Get number of memory blocks used in a Memory Pool. +/// \note API identical to osMemoryPoolGetCount +uint32_t svcRtxMemoryPoolGetCount (osMemoryPoolId_t mp_id) { + os_memory_pool_t *mp = (os_memory_pool_t *)mp_id; + + // Check parameters + if ((mp == NULL) || (mp->id != osRtxIdMemoryPool)) { + EvrRtxMemoryPoolGetCount(mp, 0U); + return 0U; + } + + // Check object state + if (mp->state == osRtxObjectInactive) { + EvrRtxMemoryPoolGetCount(mp, 0U); + return 0U; + } + + EvrRtxMemoryPoolGetCount(mp, mp->mp_info.used_blocks); + + return mp->mp_info.used_blocks; +} + +/// Get number of memory blocks available in a Memory Pool. +/// \note API identical to osMemoryPoolGetSpace +uint32_t svcRtxMemoryPoolGetSpace (osMemoryPoolId_t mp_id) { + os_memory_pool_t *mp = (os_memory_pool_t *)mp_id; + + // Check parameters + if ((mp == NULL) || (mp->id != osRtxIdMemoryPool)) { + EvrRtxMemoryPoolGetSpace(mp, 0U); + return 0U; + } + + // Check object state + if (mp->state == osRtxObjectInactive) { + EvrRtxMemoryPoolGetSpace(mp, 0U); + return 0U; + } + + EvrRtxMemoryPoolGetSpace(mp, mp->mp_info.max_blocks - mp->mp_info.used_blocks); + + return (mp->mp_info.max_blocks - mp->mp_info.used_blocks); +} + +/// Delete a Memory Pool object. +/// \note API identical to osMemoryPoolDelete +osStatus_t svcRtxMemoryPoolDelete (osMemoryPoolId_t mp_id) { + os_memory_pool_t *mp = (os_memory_pool_t *)mp_id; + os_thread_t *thread; + + // Check parameters + if ((mp == NULL) || (mp->id != osRtxIdMemoryPool)) { + EvrRtxMemoryPoolError(mp, osErrorParameter); + return osErrorParameter; + } + + // Check object state + if (mp->state == osRtxObjectInactive) { + EvrRtxMemoryPoolError(mp, osErrorResource); + return osErrorResource; + } + + // Mark object as inactive + mp->state = osRtxObjectInactive; + + // Unblock waiting threads + if (mp->thread_list != NULL) { + do { + thread = osRtxThreadListGet((os_object_t*)mp); + osRtxThreadWaitExit(thread, 0U, false); + } while (mp->thread_list != NULL); + osRtxThreadDispatch(NULL); + } + + // Free data memory + if (mp->flags & osRtxFlagSystemMemory) { + osRtxMemoryFree(osRtxInfo.mem.mp_data, mp->mp_info.block_base); + } + + // Free object memory + if (mp->flags & osRtxFlagSystemObject) { + if (osRtxInfo.mpi.memory_pool != NULL) { + osRtxMemoryPoolFree(osRtxInfo.mpi.memory_pool, mp); + } else { + osRtxMemoryFree(osRtxInfo.mem.common, mp); + } + } + + EvrRtxMemoryPoolDestroyed(mp); + + return osOK; +} + + +// ==== ISR Calls ==== + +/// Allocate a memory block from a Memory Pool. +/// \note API identical to osMemoryPoolAlloc +__STATIC_INLINE +void *isrRtxMemoryPoolAlloc (osMemoryPoolId_t mp_id, uint32_t timeout) { + os_memory_pool_t *mp = (os_memory_pool_t *)mp_id; + void *block; + + // Check parameters + if ((mp == NULL) || (mp->id != osRtxIdMemoryPool) || (timeout != 0U)) { + EvrRtxMemoryPoolError(mp, osErrorParameter); + return NULL; + } + + // Check object state + if (mp->state == osRtxObjectInactive) { + EvrRtxMemoryPoolError(mp, osErrorResource); + return NULL; + } + + // Allocate memory + block = osRtxMemoryPoolAlloc(&mp->mp_info); + if (block == NULL) { + EvrRtxMemoryPoolAllocFailed(mp); + } else { + EvrRtxMemoryPoolAllocated(mp, block); + } + + return block; +} + +/// Return an allocated memory block back to a Memory Pool. +/// \note API identical to osMemoryPoolFree +__STATIC_INLINE +osStatus_t isrRtxMemoryPoolFree (osMemoryPoolId_t mp_id, void *block) { + os_memory_pool_t *mp = (os_memory_pool_t *)mp_id; + osStatus_t status; + + // Check parameters + if ((mp == NULL) || (mp->id != osRtxIdMemoryPool)) { + EvrRtxMemoryPoolError(mp, osErrorParameter); + return osErrorParameter; + } + + // Check object state + if (mp->state == osRtxObjectInactive) { + EvrRtxMemoryPoolError(mp, osErrorResource); + return osErrorResource; + } + + // Free memory + status = osRtxMemoryPoolFree(&mp->mp_info, block); + if (status == osOK) { + // Register post ISR processing + osRtxPostProcess((os_object_t *)mp); + EvrRtxMemoryPoolDeallocated(mp, block); + } else { + EvrRtxMemoryPoolFreeFailed(mp, block); + } + + return status; +} + + +// ==== Public API ==== + +/// Create and Initialize a Memory Pool object. +osMemoryPoolId_t osMemoryPoolNew (uint32_t block_count, uint32_t block_size, const osMemoryPoolAttr_t *attr) { + EvrRtxMemoryPoolNew(block_count, block_size, attr); + if (IS_IRQ_MODE() || IS_IRQ_MASKED()) { + EvrRtxMemoryPoolError(NULL, osErrorISR); + return NULL; + } + return __svcMemoryPoolNew(block_count, block_size, attr); +} + +/// Get name of a Memory Pool object. +const char *osMemoryPoolGetName (osMemoryPoolId_t mp_id) { + if (IS_IRQ_MODE() || IS_IRQ_MASKED()) { + EvrRtxMemoryPoolGetName(mp_id, NULL); + return NULL; + } + return __svcMemoryPoolGetName(mp_id); +} + +/// Allocate a memory block from a Memory Pool. +void *osMemoryPoolAlloc (osMemoryPoolId_t mp_id, uint32_t timeout) { + EvrRtxMemoryPoolAlloc(mp_id, timeout); + if (IS_IRQ_MODE() || IS_IRQ_MASKED()) { + return isrRtxMemoryPoolAlloc(mp_id, timeout); + } else { + return __svcMemoryPoolAlloc(mp_id, timeout); + } +} + +/// Return an allocated memory block back to a Memory Pool. +osStatus_t osMemoryPoolFree (osMemoryPoolId_t mp_id, void *block) { + EvrRtxMemoryPoolFree(mp_id, block); + if (IS_IRQ_MODE() || IS_IRQ_MASKED()) { + return isrRtxMemoryPoolFree(mp_id, block); + } else { + return __svcMemoryPoolFree(mp_id, block); + } +} + +/// Get maximum number of memory blocks in a Memory Pool. +uint32_t osMemoryPoolGetCapacity (osMemoryPoolId_t mp_id) { + if (IS_IRQ_MODE() || IS_IRQ_MASKED()) { + return svcRtxMemoryPoolGetCapacity(mp_id); + } else { + return __svcMemoryPoolGetCapacity(mp_id); + } +} + +/// Get memory block size in a Memory Pool. +uint32_t osMemoryPoolGetBlockSize (osMemoryPoolId_t mp_id) { + if (IS_IRQ_MODE() || IS_IRQ_MASKED()) { + return svcRtxMemoryPoolGetBlockSize(mp_id); + } else { + return __svcMemoryPoolGetBlockSize(mp_id); + } +} + +/// Get number of memory blocks used in a Memory Pool. +uint32_t osMemoryPoolGetCount (osMemoryPoolId_t mp_id) { + if (IS_IRQ_MODE() || IS_IRQ_MASKED()) { + return svcRtxMemoryPoolGetCount(mp_id); + } else { + return __svcMemoryPoolGetCount(mp_id); + } +} + +/// Get number of memory blocks available in a Memory Pool. +uint32_t osMemoryPoolGetSpace (osMemoryPoolId_t mp_id) { + if (IS_IRQ_MODE() || IS_IRQ_MASKED()) { + return svcRtxMemoryPoolGetSpace(mp_id); + } else { + return __svcMemoryPoolGetSpace(mp_id); + } +} + +/// Delete a Memory Pool object. +osStatus_t osMemoryPoolDelete (osMemoryPoolId_t mp_id) { + EvrRtxMemoryPoolDelete(mp_id); + if (IS_IRQ_MODE() || IS_IRQ_MASKED()) { + EvrRtxMemoryPoolError(mp_id, osErrorISR); + return osErrorISR; + } + return __svcMemoryPoolDelete(mp_id); +} diff --git a/rtos/rtx2/TARGET_CORTEX_M/rtx_msgqueue.c b/rtos/rtx2/TARGET_CORTEX_M/rtx_msgqueue.c new file mode 100644 index 00000000000..d147e81c2f2 --- /dev/null +++ b/rtos/rtx2/TARGET_CORTEX_M/rtx_msgqueue.c @@ -0,0 +1,906 @@ +/* + * Copyright (c) 2013-2017 ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ----------------------------------------------------------------------------- + * + * Project: CMSIS-RTOS RTX + * Title: Message Queue functions + * + * ----------------------------------------------------------------------------- + */ + +#include "rtx_lib.h" + + +// ==== Helper functions ==== + +/// Put a Message into Queue sorted by Priority (Highest at Head). +/// \param[in] mq message queue object. +/// \param[in] msg message object. +static void MessageQueuePut (os_message_queue_t *mq, os_message_t *msg) { +#if (__EXCLUSIVE_ACCESS == 0U) + uint32_t primask = __get_PRIMASK(); +#endif + os_message_t *prev, *next; + + if (mq->msg_last != NULL) { + prev = mq->msg_last; + next = NULL; + while ((prev != NULL) && (prev->priority < msg->priority)) { + next = prev; + prev = prev->prev; + } + msg->prev = prev; + msg->next = next; + if (prev != NULL) { + prev->next = msg; + } else { + mq->msg_first = msg; + } + if (next != NULL) { + next->prev = msg; + } else { + mq->msg_last = msg; + } + } else { + msg->prev = NULL; + msg->next = NULL; + mq->msg_first= msg; + mq->msg_last = msg; + } + +#if (__EXCLUSIVE_ACCESS == 0U) + __disable_irq(); + + mq->msg_count++; + + if (primask == 0U) { + __enable_irq(); + } +#else + atomic_inc32(&mq->msg_count); +#endif +} + +/// Get a Message from Queue with Highest Priority. +/// \param[in] mq message queue object. +/// \return message object or NULL. +static os_message_t *MessageQueueGet (os_message_queue_t *mq) { +#if (__EXCLUSIVE_ACCESS == 0U) + uint32_t primask = __get_PRIMASK(); +#endif + os_message_t *msg; + uint32_t count; + uint8_t flags; + +#if (__EXCLUSIVE_ACCESS == 0U) + __disable_irq(); + + count = mq->msg_count; + if (count != 0U) { + mq->msg_count--; + } + + if (primask == 0U) { + __enable_irq(); + } +#else + count = atomic_dec32_nz(&mq->msg_count); +#endif + + if (count == 0U) { + return NULL; + } + + msg = mq->msg_first; + + while (msg != NULL) { +#if (__EXCLUSIVE_ACCESS == 0U) + __disable_irq(); + + flags = msg->flags; + msg->flags = 1U; + + if (primask == 0U) { + __enable_irq(); + } +#else + flags = atomic_wr8(&msg->flags, 1U); +#endif + if (flags == 0U) { + break; + } + msg = msg->next; + } + + return msg; +} + +/// Remove a Message from Queue +/// \param[in] mq message queue object. +/// \param[in] msg message object. +static void MessageQueueRemove (os_message_queue_t *mq, os_message_t *msg) { + + if (msg->prev != NULL) { + msg->prev->next = msg->next; + } else { + mq->msg_first = msg->next; + } + if (msg->next != NULL) { + msg->next->prev = msg->prev; + } else { + mq->msg_last = msg->prev; + } +} + + +// ==== Library functions ==== + +/// Message Queue post ISR processing. +/// \param[in] msg message object. +void osRtxMessageQueuePostProcess (os_message_t *msg) { + os_message_queue_t *mq; + os_thread_t *thread; + uint32_t *reg; + void **ptr; + + if (msg->state == osRtxObjectInactive) { + return; + } + + if (msg->flags != 0U) { + // Remove Message + ptr = (void *)((uint8_t *)msg + sizeof(os_message_t)); + mq = *ptr; + if (mq->state == osRtxObjectInactive) { + return; + } + MessageQueueRemove(mq, msg); + // Free memory + msg->state = osRtxObjectInactive; + osRtxMemoryPoolFree(&mq->mp_info, msg); + // Check if Thread is waiting to send a Message + if ((mq->thread_list != NULL) && (mq->thread_list->state == osRtxThreadWaitingMessagePut)) { + // Try to allocate memory + msg = osRtxMemoryPoolAlloc(&mq->mp_info); + if (msg != NULL) { + // Wakeup waiting Thread with highest Priority + thread = osRtxThreadListGet((os_object_t*)mq); + osRtxThreadWaitExit(thread, (uint32_t)osOK, false); + // Copy Message (R2: const void *msg_ptr, R3: uint8_t msg_prio) + reg = osRtxThreadRegPtr(thread); + memcpy((uint8_t *)msg + sizeof(os_message_t), (void *)reg[2], mq->msg_size); + // Store Message into Queue + msg->id = osRtxIdMessage; + msg->state = osRtxObjectActive; + msg->flags = 0U; + msg->priority = (uint8_t)reg[3]; + MessageQueuePut(mq, msg); + EvrRtxMessageQueueInserted(mq, (void *)reg[2]); + } + } + } else { + // New Message + mq = (void *)msg->next; + if (mq->state == osRtxObjectInactive) { + return; + } + // Check if Thread is waiting to receive a Message + if ((mq->thread_list != NULL) && (mq->thread_list->state == osRtxThreadWaitingMessageGet)) { + EvrRtxMessageQueueInserted(mq, (void *)msg->prev); + // Wakeup waiting Thread with highest Priority + thread = osRtxThreadListGet((os_object_t*)mq); + osRtxThreadWaitExit(thread, (uint32_t)osOK, false); + // Copy Message (R2: void *msg_ptr, R3: uint8_t *msg_prio) + reg = osRtxThreadRegPtr(thread); + memcpy((void *)reg[2], (uint8_t *)msg + sizeof(os_message_t), mq->msg_size); + if (reg[3] != 0U) { + *((uint8_t *)reg[3]) = msg->priority; + } + EvrRtxMessageQueueRetrieved(mq, (void *)reg[2]); + // Free memory + msg->state = osRtxObjectInactive; + osRtxMemoryPoolFree(&mq->mp_info, msg); + } else { + EvrRtxMessageQueueInserted(mq, (void *)msg->prev); + MessageQueuePut(mq, msg); + } + } +} + + +// ==== Service Calls ==== + +SVC0_3M(MessageQueueNew, osMessageQueueId_t, uint32_t, uint32_t, const osMessageQueueAttr_t *) +SVC0_1 (MessageQueueGetName, const char *, osMessageQueueId_t) +SVC0_4 (MessageQueuePut, osStatus_t, osMessageQueueId_t, const void *, uint8_t, uint32_t) +SVC0_4 (MessageQueueGet, osStatus_t, osMessageQueueId_t, void *, uint8_t *, uint32_t) +SVC0_1 (MessageQueueGetCapacity, uint32_t, osMessageQueueId_t) +SVC0_1 (MessageQueueGetMsgSize, uint32_t, osMessageQueueId_t) +SVC0_1 (MessageQueueGetCount, uint32_t, osMessageQueueId_t) +SVC0_1 (MessageQueueGetSpace, uint32_t, osMessageQueueId_t) +SVC0_1 (MessageQueueReset, osStatus_t, osMessageQueueId_t) +SVC0_1 (MessageQueueDelete, osStatus_t, osMessageQueueId_t) + +/// Create and Initialize a Message Queue object. +/// \note API identical to osMessageQueueNew +osMessageQueueId_t svcRtxMessageQueueNew (uint32_t msg_count, uint32_t msg_size, const osMessageQueueAttr_t *attr) { + os_message_queue_t *mq; + void *mq_mem; + uint32_t mq_size; + uint32_t block_size; + uint32_t size; + uint8_t flags; + const char *name; + + // Check parameters + if ((msg_count == 0U) || (msg_size == 0U)) { + EvrRtxMessageQueueError(NULL, osErrorParameter); + return NULL; + } + msg_size = (msg_size + 3U) & ~3UL; + block_size = msg_size + sizeof(os_message_t); + if ((__CLZ(msg_count) + __CLZ(block_size)) < 32) { + EvrRtxMessageQueueError(NULL, osErrorParameter); + return NULL; + } + + size = msg_count * block_size; + + // Process attributes + if (attr != NULL) { + name = attr->name; + mq = attr->cb_mem; + mq_mem = attr->mq_mem; + mq_size = attr->mq_size; + if (mq != NULL) { + if (((uint32_t)mq & 3U) || (attr->cb_size < sizeof(os_message_queue_t))) { + EvrRtxMessageQueueError(NULL, osRtxErrorInvalidControlBlock); + return NULL; + } + } else { + if (attr->cb_size != 0U) { + EvrRtxMessageQueueError(NULL, osRtxErrorInvalidControlBlock); + return NULL; + } + } + if (mq_mem != NULL) { + if (((uint32_t)mq_mem & 3U) || (mq_size < size)) { + EvrRtxMessageQueueError(NULL, osRtxErrorInvalidDataMemory); + return NULL; + } + } else { + if (mq_size != 0U) { + EvrRtxMessageQueueError(NULL, osRtxErrorInvalidDataMemory); + return NULL; + } + } + } else { + name = NULL; + mq = NULL; + mq_mem = NULL; + } + + // Allocate object memory if not provided + if (mq == NULL) { + if (osRtxInfo.mpi.message_queue != NULL) { + mq = osRtxMemoryPoolAlloc(osRtxInfo.mpi.message_queue); + } else { + mq = osRtxMemoryAlloc(osRtxInfo.mem.common, sizeof(os_message_queue_t), 1U); + } + if (mq == NULL) { + EvrRtxMessageQueueError(NULL, osErrorNoMemory); + return NULL; + } + flags = osRtxFlagSystemObject; + } else { + flags = 0U; + } + + // Allocate data memory if not provided + if (mq_mem == NULL) { + mq_mem = osRtxMemoryAlloc(osRtxInfo.mem.mq_data, size, 0U); + if (mq_mem == NULL) { + EvrRtxMessageQueueError(NULL, osErrorNoMemory); + if (flags & osRtxFlagSystemObject) { + if (osRtxInfo.mpi.message_queue != NULL) { + osRtxMemoryPoolFree(osRtxInfo.mpi.message_queue, mq); + } else { + osRtxMemoryFree(osRtxInfo.mem.common, mq); + } + } + return NULL; + } + memset(mq_mem, 0, size); + flags |= osRtxFlagSystemMemory; + } + + // Initialize control block + mq->id = osRtxIdMessageQueue; + mq->state = osRtxObjectActive; + mq->flags = flags; + mq->name = name; + mq->thread_list = NULL; + mq->msg_size = msg_size; + mq->msg_count = 0U; + mq->msg_first = NULL; + mq->msg_last = NULL; + osRtxMemoryPoolInit(&mq->mp_info, msg_count, block_size, mq_mem); + + // Register post ISR processing function + osRtxInfo.post_process.message_queue = osRtxMessageQueuePostProcess; + + EvrRtxMessageQueueCreated(mq); + + return mq; +} + +/// Get name of a Message Queue object. +/// \note API identical to osMessageQueueGetName +const char *svcRtxMessageQueueGetName (osMessageQueueId_t mq_id) { + os_message_queue_t *mq = (os_message_queue_t *)mq_id; + + // Check parameters + if ((mq == NULL) || (mq->id != osRtxIdMessageQueue)) { + EvrRtxMessageQueueGetName(mq, NULL); + return NULL; + } + + // Check object state + if (mq->state == osRtxObjectInactive) { + EvrRtxMessageQueueGetName(mq, NULL); + return NULL; + } + + EvrRtxMessageQueueGetName(mq, mq->name); + + return mq->name; +} + +/// Put a Message into a Queue or timeout if Queue is full. +/// \note API identical to osMessageQueuePut +osStatus_t svcRtxMessageQueuePut (osMessageQueueId_t mq_id, const void *msg_ptr, uint8_t msg_prio, uint32_t timeout) { + os_message_queue_t *mq = (os_message_queue_t *)mq_id; + os_message_t *msg; + os_thread_t *thread; + uint32_t *reg; + + // Check parameters + if ((mq == NULL) || (mq->id != osRtxIdMessageQueue) || (msg_ptr == NULL)) { + EvrRtxMessageQueueError(mq, osErrorParameter); + return osErrorParameter; + } + + // Check object state + if (mq->state == osRtxObjectInactive) { + EvrRtxMessageQueueError(mq, osErrorResource); + return osErrorResource; + } + + // Check if Thread is waiting to receive a Message + if ((mq->thread_list != NULL) && (mq->thread_list->state == osRtxThreadWaitingMessageGet)) { + EvrRtxMessageQueueInserted(mq, msg_ptr); + // Wakeup waiting Thread with highest Priority + thread = osRtxThreadListGet((os_object_t*)mq); + osRtxThreadWaitExit(thread, (uint32_t)osOK, true); + // Copy Message (R2: void *msg_ptr, R3: uint8_t *msg_prio) + reg = osRtxThreadRegPtr(thread); + memcpy((void *)reg[2], msg_ptr, mq->msg_size); + if (reg[3] != 0U) { + *((uint8_t *)reg[3]) = msg_prio; + } + EvrRtxMessageQueueRetrieved(mq, (void *)reg[2]); + return osOK; + } + + // Try to allocate memory + msg = osRtxMemoryPoolAlloc(&mq->mp_info); + if (msg != NULL) { + // Copy Message + memcpy((uint8_t *)msg + sizeof(os_message_t), msg_ptr, mq->msg_size); + // Put Message into Queue + msg->id = osRtxIdMessage; + msg->state = osRtxObjectActive; + msg->flags = 0U; + msg->priority = msg_prio; + MessageQueuePut(mq, msg); + } else { + // No memory available + if (timeout != 0U) { + EvrRtxMessageQueuePutPending(mq, msg_ptr, timeout); + // Suspend current Thread + osRtxThreadListPut((os_object_t*)mq, osRtxThreadGetRunning()); + osRtxThreadWaitEnter(osRtxThreadWaitingMessagePut, timeout); + // Save arguments (R2: const void *msg_ptr, R3: uint8_t msg_prio) + reg = (uint32_t *)(__get_PSP()); + reg[2] = (uint32_t)msg_ptr; + reg[3] = (uint32_t)msg_prio; + return osErrorTimeout; + } else { + EvrRtxMessageQueueNotInserted(mq, msg_ptr); + return osErrorResource; + } + } + + EvrRtxMessageQueueInserted(mq, msg_ptr); + + return osOK; +} + +/// Get a Message from a Queue or timeout if Queue is empty. +/// \note API identical to osMessageQueueGet +osStatus_t svcRtxMessageQueueGet (osMessageQueueId_t mq_id, void *msg_ptr, uint8_t *msg_prio, uint32_t timeout) { + os_message_queue_t *mq = (os_message_queue_t *)mq_id; + os_message_t *msg; + os_thread_t *thread; + uint32_t *reg; + + // Check parameters + if ((mq == NULL) || (mq->id != osRtxIdMessageQueue) || (msg_ptr == NULL)) { + EvrRtxMessageQueueError(mq, osErrorParameter); + return osErrorParameter; + } + + // Check object state + if (mq->state == osRtxObjectInactive) { + EvrRtxMessageQueueError(mq, osErrorResource); + return osErrorResource; + } + + // Get Message from Queue + msg = MessageQueueGet(mq); + if (msg != NULL) { + MessageQueueRemove(mq, msg); + // Copy Message + memcpy(msg_ptr, (uint8_t *)msg + sizeof(os_message_t), mq->msg_size); + if (msg_prio != NULL) { + *msg_prio = msg->priority; + } + EvrRtxMessageQueueRetrieved(mq, msg_ptr); + // Free memory + msg->state = osRtxObjectInactive; + osRtxMemoryPoolFree(&mq->mp_info, msg); + } else { + // No Message available + if (timeout != 0U) { + EvrRtxMessageQueueGetPending(mq, msg_ptr, timeout); + // Suspend current Thread + osRtxThreadListPut((os_object_t*)mq, osRtxThreadGetRunning()); + osRtxThreadWaitEnter(osRtxThreadWaitingMessageGet, timeout); + // Save arguments (R2: void *msg_ptr, R3: uint8_t *msg_prio) + reg = (uint32_t *)(__get_PSP()); + reg[2] = (uint32_t)msg_ptr; + reg[3] = (uint32_t)msg_prio; + return osErrorTimeout; + } else { + EvrRtxMessageQueueNotRetrieved(mq, msg_ptr); + return osErrorResource; + } + } + + // Check if Thread is waiting to send a Message + if ((mq->thread_list != NULL) && (mq->thread_list->state == osRtxThreadWaitingMessagePut)) { + // Try to allocate memory + msg = osRtxMemoryPoolAlloc(&mq->mp_info); + if (msg != NULL) { + // Wakeup waiting Thread with highest Priority + thread = osRtxThreadListGet((os_object_t*)mq); + osRtxThreadWaitExit(thread, (uint32_t)osOK, true); + // Copy Message (R2: const void *msg_ptr, R3: uint8_t msg_prio) + reg = osRtxThreadRegPtr(thread); + memcpy((uint8_t *)msg + sizeof(os_message_t), (void *)reg[2], mq->msg_size); + // Store Message into Queue + msg->id = osRtxIdMessage; + msg->state = osRtxObjectActive; + msg->flags = 0U; + msg->priority = (uint8_t)reg[3]; + MessageQueuePut(mq, msg); + EvrRtxMessageQueueInserted(mq, (void *)reg[2]); + } + } + + return osOK; +} + +/// Get maximum number of messages in a Message Queue. +/// \note API identical to osMessageGetCapacity +uint32_t svcRtxMessageQueueGetCapacity (osMessageQueueId_t mq_id) { + os_message_queue_t *mq = (os_message_queue_t *)mq_id; + + // Check parameters + if ((mq == NULL) || (mq->id != osRtxIdMessageQueue)) { + EvrRtxMessageQueueGetCapacity(mq, 0U); + return 0U; + } + + // Check object state + if (mq->state == osRtxObjectInactive) { + EvrRtxMessageQueueGetCapacity(mq, 0U); + return 0U; + } + + EvrRtxMessageQueueGetCapacity(mq, mq->mp_info.max_blocks); + + return mq->mp_info.max_blocks; +} + +/// Get maximum message size in a Memory Pool. +/// \note API identical to osMessageGetMsgSize +uint32_t svcRtxMessageQueueGetMsgSize (osMessageQueueId_t mq_id) { + os_message_queue_t *mq = (os_message_queue_t *)mq_id; + + // Check parameters + if ((mq == NULL) || (mq->id != osRtxIdMessageQueue)) { + EvrRtxMessageQueueGetMsgSize(mq, 0U); + return 0U; + } + + // Check object state + if (mq->state == osRtxObjectInactive) { + EvrRtxMessageQueueGetMsgSize(mq, 0U); + return 0U; + } + + EvrRtxMessageQueueGetMsgSize(mq, mq->msg_size); + + return mq->msg_size; +} + +/// Get number of queued messages in a Message Queue. +/// \note API identical to osMessageGetCount +uint32_t svcRtxMessageQueueGetCount (osMessageQueueId_t mq_id) { + os_message_queue_t *mq = (os_message_queue_t *)mq_id; + + // Check parameters + if ((mq == NULL) || (mq->id != osRtxIdMessageQueue)) { + EvrRtxMessageQueueGetCount(mq, 0U); + return 0U; + } + + // Check object state + if (mq->state == osRtxObjectInactive) { + EvrRtxMessageQueueGetCount(mq, 0U); + return 0U; + } + + EvrRtxMessageQueueGetCount(mq, mq->msg_count); + + return mq->msg_count; +} + +/// Get number of available slots for messages in a Message Queue. +/// \note API identical to osMessageGetSpace +uint32_t svcRtxMessageQueueGetSpace (osMessageQueueId_t mq_id) { + os_message_queue_t *mq = (os_message_queue_t *)mq_id; + + // Check parameters + if ((mq == NULL) || (mq->id != osRtxIdMessageQueue)) { + EvrRtxMessageQueueGetSpace(mq, 0U); + return 0U; + } + + // Check object state + if (mq->state == osRtxObjectInactive) { + EvrRtxMessageQueueGetSpace(mq, 0U); + return 0U; + } + + EvrRtxMessageQueueGetSpace(mq, mq->mp_info.max_blocks - mq->msg_count); + + return (mq->mp_info.max_blocks - mq->msg_count); +} + +/// Reset a Message Queue to initial empty state. +/// \note API identical to osMessageQueueReset +osStatus_t svcRtxMessageQueueReset (osMessageQueueId_t mq_id) { + os_message_queue_t *mq = (os_message_queue_t *)mq_id; + os_message_t *msg; + os_thread_t *thread; + uint32_t *reg; + + // Check parameters + if ((mq == NULL) || (mq->id != osRtxIdMessageQueue)) { + EvrRtxMessageQueueError(mq, osErrorParameter); + return osErrorParameter; + } + + // Check object state + if (mq->state == osRtxObjectInactive) { + EvrRtxMessageQueueError(mq, osErrorResource); + return osErrorResource; + } + + // Remove Messages from Queue + for (;;) { + // Get Message from Queue + msg = MessageQueueGet(mq); + if (msg == NULL) { + break; + } + MessageQueueRemove(mq, msg); + EvrRtxMessageQueueRetrieved(mq, NULL); + // Free memory + msg->state = osRtxObjectInactive; + osRtxMemoryPoolFree(&mq->mp_info, msg); + } + + // Check if Threads are waiting to send Messages + if ((mq->thread_list != NULL) && (mq->thread_list->state == osRtxThreadWaitingMessagePut)) { + do { + // Try to allocate memory + msg = osRtxMemoryPoolAlloc(&mq->mp_info); + if (msg != NULL) { + // Wakeup waiting Thread with highest Priority + thread = osRtxThreadListGet((os_object_t*)mq); + osRtxThreadWaitExit(thread, (uint32_t)osOK, false); + // Copy Message (R2: const void *msg_ptr, R3: uint8_t msg_prio) + reg = osRtxThreadRegPtr(thread); + memcpy((uint8_t *)msg + sizeof(os_message_t), (void *)reg[2], mq->msg_size); + // Store Message into Queue + msg->id = osRtxIdMessage; + msg->state = osRtxObjectActive; + msg->flags = 0U; + msg->priority = (uint8_t)reg[3]; + MessageQueuePut(mq, msg); + EvrRtxMessageQueueInserted(mq, (void *)reg[2]); + } + } while ((msg != NULL) && (mq->thread_list != NULL)); + osRtxThreadDispatch(NULL); + } + + EvrRtxMessageQueueResetDone(mq); + + return osOK; +} + +/// Delete a Message Queue object. +/// \note API identical to osMessageQueueDelete +osStatus_t svcRtxMessageQueueDelete (osMessageQueueId_t mq_id) { + os_message_queue_t *mq = (os_message_queue_t *)mq_id; + os_thread_t *thread; + + // Check parameters + if ((mq == NULL) || (mq->id != osRtxIdMessageQueue)) { + EvrRtxMessageQueueError(mq, osErrorParameter); + return osErrorParameter; + } + + // Check object state + if (mq->state == osRtxObjectInactive) { + EvrRtxMessageQueueError(mq, osErrorResource); + return osErrorResource; + } + + // Mark object as inactive + mq->state = osRtxObjectInactive; + + // Unblock waiting threads + if (mq->thread_list != NULL) { + do { + thread = osRtxThreadListGet((os_object_t*)mq); + osRtxThreadWaitExit(thread, (uint32_t)osErrorResource, false); + } while (mq->thread_list != NULL); + osRtxThreadDispatch(NULL); + } + + // Free data memory + if (mq->flags & osRtxFlagSystemMemory) { + osRtxMemoryFree(osRtxInfo.mem.mq_data, mq->mp_info.block_base); + } + + // Free object memory + if (mq->flags & osRtxFlagSystemObject) { + if (osRtxInfo.mpi.message_queue != NULL) { + osRtxMemoryPoolFree(osRtxInfo.mpi.message_queue, mq); + } else { + osRtxMemoryFree(osRtxInfo.mem.common, mq); + } + } + + EvrRtxMessageQueueDestroyed(mq); + + return osOK; +} + + +// ==== ISR Calls ==== + +/// Put a Message into a Queue or timeout if Queue is full. +/// \note API identical to osMessageQueuePut +__STATIC_INLINE +osStatus_t isrRtxMessageQueuePut (osMessageQueueId_t mq_id, const void *msg_ptr, uint8_t msg_prio, uint32_t timeout) { + os_message_queue_t *mq = (os_message_queue_t *)mq_id; + os_message_t *msg; + const void **ptr; + + // Check parameters + if ((mq == NULL) || (mq->id != osRtxIdMessageQueue) || (msg_ptr == NULL) || (timeout != 0U)) { + EvrRtxMessageQueueError(mq, osErrorParameter); + return osErrorParameter; + } + + // Check object state + if (mq->state == osRtxObjectInactive) { + EvrRtxMessageQueueError(mq, osErrorResource); + return osErrorResource; + } + + // Try to allocate memory + msg = osRtxMemoryPoolAlloc(&mq->mp_info); + if (msg != NULL) { + // Copy Message + memcpy((uint8_t *)msg + sizeof(os_message_t), msg_ptr, mq->msg_size); + msg->id = osRtxIdMessage; + msg->state = osRtxObjectActive; + msg->flags = 0U; + msg->priority = msg_prio; + // Register post ISR processing + ptr = (void *)&msg->prev; + *ptr = msg_ptr; + ptr = (void *)&msg->next; + *ptr = mq; + osRtxPostProcess((os_object_t *)msg); + } else { + // No memory available + EvrRtxMessageQueueNotInserted(mq, msg_ptr); + return osErrorResource; + } + + EvrRtxMessageQueueInsertPending(mq, msg_ptr); + + return osOK; +} + +/// Get a Message from a Queue or timeout if Queue is empty. +/// \note API identical to osMessageQueueGet +__STATIC_INLINE +osStatus_t isrRtxMessageQueueGet (osMessageQueueId_t mq_id, void *msg_ptr, uint8_t *msg_prio, uint32_t timeout) { + os_message_queue_t *mq = (os_message_queue_t *)mq_id; + os_message_t *msg; + void **ptr; + + // Check parameters + if ((mq == NULL) || (mq->id != osRtxIdMessageQueue) || (msg_ptr == NULL) || (timeout != 0U)) { + EvrRtxMessageQueueError(mq, osErrorParameter); + return osErrorParameter; + } + + // Check object state + if (mq->state == osRtxObjectInactive) { + EvrRtxMessageQueueError(mq, osErrorResource); + return osErrorResource; + } + + // Get Message from Queue + msg = MessageQueueGet(mq); + if (msg != NULL) { + // Copy Message + memcpy(msg_ptr, (uint8_t *)msg + sizeof(os_message_t), mq->msg_size); + if (msg_prio != NULL) { + *msg_prio = msg->priority; + } + EvrRtxMessageQueueRetrieved(mq, msg_ptr); + // Register post ISR processing + ptr = (void *)((uint8_t *)msg + sizeof(os_message_t)); + *ptr = mq; + osRtxPostProcess((os_object_t *)msg); + } else { + // No Message available + EvrRtxMessageQueueNotRetrieved(mq, msg_ptr); + return osErrorResource; + } + + return osOK; +} + + +// ==== Public API ==== + +/// Create and Initialize a Message Queue object. +osMessageQueueId_t osMessageQueueNew (uint32_t msg_count, uint32_t msg_size, const osMessageQueueAttr_t *attr) { + EvrRtxMessageQueueNew(msg_count, msg_size, attr); + if (IS_IRQ_MODE() || IS_IRQ_MASKED()) { + EvrRtxMessageQueueError(NULL, osErrorISR); + return NULL; + } + return __svcMessageQueueNew(msg_count, msg_size, attr); +} + +/// Get name of a Message Queue object. +const char *osMessageQueueGetName (osMessageQueueId_t mq_id) { + if (IS_IRQ_MODE() || IS_IRQ_MASKED()) { + EvrRtxMessageQueueGetName(mq_id, NULL); + return NULL; + } + return __svcMessageQueueGetName(mq_id); +} + +/// Put a Message into a Queue or timeout if Queue is full. +osStatus_t osMessageQueuePut (osMessageQueueId_t mq_id, const void *msg_ptr, uint8_t msg_prio, uint32_t timeout) { + EvrRtxMessageQueuePut(mq_id, msg_ptr, msg_prio, timeout); + if (IS_IRQ_MODE() || IS_IRQ_MASKED()) { + return isrRtxMessageQueuePut(mq_id, msg_ptr, msg_prio, timeout); + } else { + return __svcMessageQueuePut(mq_id, msg_ptr, msg_prio, timeout); + } +} + +/// Get a Message from a Queue or timeout if Queue is empty. +osStatus_t osMessageQueueGet (osMessageQueueId_t mq_id, void *msg_ptr, uint8_t *msg_prio, uint32_t timeout) { + EvrRtxMessageQueueGet(mq_id, msg_ptr, msg_prio, timeout); + if (IS_IRQ_MODE() || IS_IRQ_MASKED()) { + return isrRtxMessageQueueGet(mq_id, msg_ptr, msg_prio, timeout); + } else { + return __svcMessageQueueGet(mq_id, msg_ptr, msg_prio, timeout); + } +} + +/// Get maximum number of messages in a Message Queue. +uint32_t osMessageQueueGetCapacity (osMessageQueueId_t mq_id) { + if (IS_IRQ_MODE() || IS_IRQ_MASKED()) { + return svcRtxMessageQueueGetCapacity(mq_id); + } else { + return __svcMessageQueueGetCapacity(mq_id); + } +} + +/// Get maximum message size in a Memory Pool. +uint32_t osMessageQueueGetMsgSize (osMessageQueueId_t mq_id) { + if (IS_IRQ_MODE() || IS_IRQ_MASKED()) { + return svcRtxMessageQueueGetMsgSize(mq_id); + } else { + return __svcMessageQueueGetMsgSize(mq_id); + } +} + +/// Get number of queued messages in a Message Queue. +uint32_t osMessageQueueGetCount (osMessageQueueId_t mq_id) { + if (IS_IRQ_MODE() || IS_IRQ_MASKED()) { + return svcRtxMessageQueueGetCount(mq_id); + } else { + return __svcMessageQueueGetCount(mq_id); + } +} + +/// Get number of available slots for messages in a Message Queue. +uint32_t osMessageQueueGetSpace (osMessageQueueId_t mq_id) { + if (IS_IRQ_MODE() || IS_IRQ_MASKED()) { + return svcRtxMessageQueueGetSpace(mq_id); + } else { + return __svcMessageQueueGetSpace(mq_id); + } +} + +/// Reset a Message Queue to initial empty state. +osStatus_t osMessageQueueReset (osMessageQueueId_t mq_id) { + EvrRtxMessageQueueReset(mq_id); + if (IS_IRQ_MODE() || IS_IRQ_MASKED()) { + EvrRtxMessageQueueError(mq_id, osErrorISR); + return osErrorISR; + } + return __svcMessageQueueReset(mq_id); +} + +/// Delete a Message Queue object. +osStatus_t osMessageQueueDelete (osMessageQueueId_t mq_id) { + EvrRtxMessageQueueDelete(mq_id); + if (IS_IRQ_MODE() || IS_IRQ_MASKED()) { + EvrRtxMessageQueueError(mq_id, osErrorISR); + return osErrorISR; + } + return __svcMessageQueueDelete(mq_id); +} diff --git a/rtos/rtx2/TARGET_CORTEX_M/rtx_mutex.c b/rtos/rtx2/TARGET_CORTEX_M/rtx_mutex.c new file mode 100644 index 00000000000..c123d7f7cd4 --- /dev/null +++ b/rtos/rtx2/TARGET_CORTEX_M/rtx_mutex.c @@ -0,0 +1,491 @@ +/* + * Copyright (c) 2013-2017 ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ----------------------------------------------------------------------------- + * + * Project: CMSIS-RTOS RTX + * Title: Mutex functions + * + * ----------------------------------------------------------------------------- + */ + +#include "rtx_lib.h" + + +// ==== Library functions ==== + +/// Release Mutex list when owner Thread terminates. +/// \param[in] mutex mutex object. +/// \return 1 - success, 0 - failure. +void osRtxMutexOwnerRelease (os_mutex_t *mutex_list) { + os_mutex_t *mutex; + os_thread_t *thread; + + mutex = mutex_list; + while (mutex) { + mutex_list = mutex->owner_next; + // Check if Mutex is Robust + if (mutex->attr & osMutexRobust) { + // Clear Lock counter + mutex->lock = 0U; + EvrRtxMutexReleased(mutex, 0U); + // Check if Thread is waiting for a Mutex + if (mutex->thread_list != NULL) { + // Wakeup waiting Thread with highest Priority + thread = osRtxThreadListGet((os_object_t*)mutex); + osRtxThreadWaitExit(thread, (uint32_t)osOK, false); + // Thread is the new Mutex owner + mutex->owner_thread = thread; + mutex->owner_next = thread->mutex_list; + mutex->owner_prev = NULL; + thread->mutex_list = mutex; + mutex->lock = 1U; + EvrRtxMutexAcquired(mutex, 1U); + } + } + mutex = mutex_list; + } +} + + +// ==== Service Calls ==== + +// Service Calls definitions +SVC0_1M(MutexNew, osMutexId_t, const osMutexAttr_t *) +SVC0_1 (MutexGetName, const char *, osMutexId_t) +SVC0_2 (MutexAcquire, osStatus_t, osMutexId_t, uint32_t) +SVC0_1 (MutexRelease, osStatus_t, osMutexId_t) +SVC0_1 (MutexGetOwner, osThreadId_t, osMutexId_t) +SVC0_1 (MutexDelete, osStatus_t, osMutexId_t) + +/// Create and Initialize a Mutex object. +/// \note API identical to osMutexNew +osMutexId_t svcRtxMutexNew (const osMutexAttr_t *attr) { + os_mutex_t *mutex; + uint32_t attr_bits; + uint8_t flags; + const char *name; + + // Process attributes + if (attr != NULL) { + name = attr->name; + attr_bits = attr->attr_bits; + mutex = attr->cb_mem; + if (mutex != NULL) { + if (((uint32_t)mutex & 3U) || (attr->cb_size < sizeof(os_mutex_t))) { + EvrRtxMutexError(NULL, osRtxErrorInvalidControlBlock); + return NULL; + } + } else { + if (attr->cb_size != 0U) { + EvrRtxMutexError(NULL, osRtxErrorInvalidControlBlock); + return NULL; + } + } + } else { + name = NULL; + attr_bits = 0U; + mutex = NULL; + } + + // Allocate object memory if not provided + if (mutex == NULL) { + if (osRtxInfo.mpi.mutex != NULL) { + mutex = osRtxMemoryPoolAlloc(osRtxInfo.mpi.mutex); + } else { + mutex = osRtxMemoryAlloc(osRtxInfo.mem.common, sizeof(os_mutex_t), 1U); + } + if (mutex == NULL) { + EvrRtxMutexError(NULL, osErrorNoMemory); + return NULL; + } + flags = osRtxFlagSystemObject; + } else { + flags = 0U; + } + + // Initialize control block + mutex->id = osRtxIdMutex; + mutex->state = osRtxObjectActive; + mutex->flags = flags; + mutex->attr = (uint8_t)attr_bits; + mutex->name = name; + mutex->thread_list = NULL; + mutex->owner_thread = NULL; + mutex->owner_prev = NULL; + mutex->owner_next = NULL; + mutex->lock = 0U; + + EvrRtxMutexCreated(mutex); + + return mutex; +} + +/// Get name of a Mutex object. +/// \note API identical to osMutexGetName +const char *svcRtxMutexGetName (osMutexId_t mutex_id) { + os_mutex_t *mutex = (os_mutex_t *)mutex_id; + + // Check parameters + if ((mutex == NULL) || (mutex->id != osRtxIdMutex)) { + EvrRtxMutexGetName(mutex, NULL); + return NULL; + } + + // Check object state + if (mutex->state == osRtxObjectInactive) { + EvrRtxMutexGetName(mutex, NULL); + return NULL; + } + + EvrRtxMutexGetName(mutex, mutex->name); + + return mutex->name; +} + +/// Acquire a Mutex or timeout if it is locked. +/// \note API identical to osMutexAcquire +osStatus_t svcRtxMutexAcquire (osMutexId_t mutex_id, uint32_t timeout) { + os_mutex_t *mutex = (os_mutex_t *)mutex_id; + os_thread_t *runnig_thread; + + runnig_thread = osRtxThreadGetRunning(); + if (runnig_thread == NULL) { + EvrRtxMutexError(mutex, osRtxErrorKernelNotRunning); + return osError; + } + + // Check parameters + if ((mutex == NULL) || (mutex->id != osRtxIdMutex)) { + EvrRtxMutexError(mutex, osErrorParameter); + return osErrorParameter; + } + + // Check object state + if (mutex->state == osRtxObjectInactive) { + EvrRtxMutexError(mutex, osErrorResource); + return osErrorResource; + } + + // Check if Mutex is not locked + if (mutex->lock == 0U) { + // Acquire Mutex + mutex->owner_thread = runnig_thread; + mutex->owner_next = runnig_thread->mutex_list; + mutex->owner_prev = NULL; + runnig_thread->mutex_list = mutex; + mutex->lock = 1U; + EvrRtxMutexAcquired(mutex, mutex->lock); + return osOK; + } + + // Check if Mutex is recursive and running Thread is the owner + if ((mutex->attr & osMutexRecursive) && (mutex->owner_thread == runnig_thread)) { + // Increment lock counter + if (mutex->lock == osRtxMutexLockLimit) { + EvrRtxMutexError(mutex, osRtxErrorMutexLockLimit); + return osErrorResource; + } + mutex->lock++; + EvrRtxMutexAcquired(mutex, mutex->lock); + return osOK; + } + + // Check if timeout is specified + if (timeout != 0U) { + // Check if Priority inheritance protocol is enabled + if (mutex->attr & osMutexPrioInherit) { + // Raise priority of owner Thread if lower than priority of running Thread + if (mutex->owner_thread->priority < runnig_thread->priority) { + mutex->owner_thread->priority = runnig_thread->priority; + osRtxThreadListSort(mutex->owner_thread); + } + } + EvrRtxMutexAcquirePending(mutex, timeout); + // Suspend current Thread + osRtxThreadListPut((os_object_t*)mutex, runnig_thread); + osRtxThreadWaitEnter(osRtxThreadWaitingMutex, timeout); + return osErrorTimeout; + } + + // Mutex was not acquired + EvrRtxMutexNotAcquired(mutex); + + return osErrorResource; +} + +/// Release a Mutex that was acquired by osMutexAcquire. +/// \note API identical to osMutexRelease +osStatus_t svcRtxMutexRelease (osMutexId_t mutex_id) { + os_mutex_t *mutex = (os_mutex_t *)mutex_id; + os_mutex_t *mutex0; + os_thread_t *thread; + os_thread_t *runnig_thread; + int8_t priority; + + runnig_thread = osRtxThreadGetRunning(); + if (runnig_thread == NULL) { + EvrRtxMutexError(mutex, osRtxErrorKernelNotRunning); + return osError; + } + + // Check parameters + if ((mutex == NULL) || (mutex->id != osRtxIdMutex)) { + EvrRtxMutexError(mutex, osErrorParameter); + return osErrorParameter; + } + + // Check object state + if (mutex->state == osRtxObjectInactive) { + EvrRtxMutexError(mutex, osErrorResource); + return osErrorResource; + } + + // Check if running Thread is not the owner + if (mutex->owner_thread != runnig_thread) { + EvrRtxMutexError(mutex, osRtxErrorMutexNotOwned); + return osErrorResource; + } + + // Check if Mutex is not locked + if (mutex->lock == 0U) { + EvrRtxMutexError(mutex, osRtxErrorMutexNotLocked); + return osErrorResource; + } + + // Decrement Lock counter + mutex->lock--; + EvrRtxMutexReleased(mutex, mutex->lock); + + // Check Lock counter + if (mutex->lock != 0U) { + return osOK; + } + + // Remove Mutex from Thread owner list + if (mutex->owner_next != NULL) { + mutex->owner_next->owner_prev = mutex->owner_prev; + } + if (mutex->owner_prev != NULL) { + mutex->owner_prev->owner_next = mutex->owner_next; + } else { + runnig_thread->mutex_list = mutex->owner_next; + } + + // Restore running Thread priority + if (mutex->attr & osMutexPrioInherit) { + priority = runnig_thread->priority_base; + mutex0 = runnig_thread->mutex_list; + while (mutex0) { + // Mutexes owned by running Thread + if ((mutex0->thread_list != NULL) && (mutex0->thread_list->priority > priority)) { + // Higher priority Thread is waiting for Mutex + priority = mutex0->thread_list->priority; + } + mutex0 = mutex0->owner_next; + } + runnig_thread->priority = priority; + } + + // Check if Thread is waiting for a Mutex + if (mutex->thread_list != NULL) { + // Wakeup waiting Thread with highest Priority + thread = osRtxThreadListGet((os_object_t*)mutex); + osRtxThreadWaitExit(thread, (uint32_t)osOK, false); + // Thread is the new Mutex owner + mutex->owner_thread = thread; + mutex->owner_next = thread->mutex_list; + mutex->owner_prev = NULL; + thread->mutex_list = mutex; + mutex->lock = 1U; + EvrRtxMutexAcquired(mutex, 1U); + } + + osRtxThreadDispatch(NULL); + + return osOK; +} + +/// Get Thread which owns a Mutex object. +/// \note API identical to osMutexGetOwner +osThreadId_t svcRtxMutexGetOwner (osMutexId_t mutex_id) { + os_mutex_t *mutex = (os_mutex_t *)mutex_id; + + // Check parameters + if ((mutex == NULL) || (mutex->id != osRtxIdMutex)) { + EvrRtxMutexGetOwner(mutex, NULL); + return NULL; + } + + // Check object state + if (mutex->state == osRtxObjectInactive) { + EvrRtxMutexGetOwner(mutex, NULL); + return NULL; + } + + // Check if Mutex is not locked + if (mutex->lock == 0U) { + EvrRtxMutexGetOwner(mutex, NULL); + return NULL; + } + + EvrRtxMutexGetOwner(mutex, mutex->owner_thread); + + return mutex->owner_thread; +} + +/// Delete a Mutex object. +/// \note API identical to osMutexDelete +osStatus_t svcRtxMutexDelete (osMutexId_t mutex_id) { + os_mutex_t *mutex = (os_mutex_t *)mutex_id; + os_mutex_t *mutex0; + os_thread_t *thread; + int8_t priority; + + // Check parameters + if ((mutex == NULL) || (mutex->id != osRtxIdMutex)) { + EvrRtxMutexError(mutex, osErrorParameter); + return osErrorParameter; + } + + // Check object state + if (mutex->state == osRtxObjectInactive) { + EvrRtxMutexError(mutex, osErrorResource); + return osErrorResource; + } + + // Mark object as inactive + mutex->state = osRtxObjectInactive; + + // Check if Mutex is locked + if (mutex->lock != 0U) { + + thread = mutex->owner_thread; + + // Remove Mutex from Thread owner list + if (mutex->owner_next != NULL) { + mutex->owner_next->owner_prev = mutex->owner_prev; + } + if (mutex->owner_prev != NULL) { + mutex->owner_prev->owner_next = mutex->owner_next; + } else { + thread->mutex_list = mutex->owner_next; + } + + // Restore owner Thread priority + if (mutex->attr & osMutexPrioInherit) { + priority = thread->priority_base; + mutex0 = thread->mutex_list; + while (mutex0) { + // Mutexes owned by running Thread + if ((mutex0->thread_list != NULL) && (mutex0->thread_list->priority > priority)) { + // Higher priority Thread is waiting for Mutex + priority = mutex0->thread_list->priority; + } + mutex0 = mutex0->owner_next; + } + if (thread->priority != priority) { + thread->priority = priority; + osRtxThreadListSort(thread); + } + } + + // Unblock waiting threads + if (mutex->thread_list != NULL) { + do { + thread = osRtxThreadListGet((os_object_t*)mutex); + osRtxThreadWaitExit(thread, (uint32_t)osErrorResource, false); + } while (mutex->thread_list != NULL); + } + + osRtxThreadDispatch(NULL); + } + + // Free object memory + if (mutex->flags & osRtxFlagSystemObject) { + if (osRtxInfo.mpi.mutex != NULL) { + osRtxMemoryPoolFree(osRtxInfo.mpi.mutex, mutex); + } else { + osRtxMemoryFree(osRtxInfo.mem.common, mutex); + } + } + + EvrRtxMutexDestroyed(mutex); + + return osOK; +} + + +// ==== Public API ==== + +/// Create and Initialize a Mutex object. +osMutexId_t osMutexNew (const osMutexAttr_t *attr) { + EvrRtxMutexNew(attr); + if (IS_IRQ_MODE() || IS_IRQ_MASKED()) { + EvrRtxMutexError(NULL, osErrorISR); + return NULL; + } + return __svcMutexNew(attr); +} + +/// Get name of a Mutex object. +const char *osMutexGetName (osMutexId_t mutex_id) { + if (IS_IRQ_MODE() || IS_IRQ_MASKED()) { + EvrRtxMutexGetName(mutex_id, NULL); + return NULL; + } + return __svcMutexGetName(mutex_id); +} + +/// Acquire a Mutex or timeout if it is locked. +osStatus_t osMutexAcquire (osMutexId_t mutex_id, uint32_t timeout) { + EvrRtxMutexAcquire(mutex_id, timeout); + if (IS_IRQ_MODE() || IS_IRQ_MASKED()) { + EvrRtxMutexError(mutex_id, osErrorISR); + return osErrorISR; + } + return __svcMutexAcquire(mutex_id, timeout); +} + +/// Release a Mutex that was acquired by \ref osMutexAcquire. +osStatus_t osMutexRelease (osMutexId_t mutex_id) { + EvrRtxMutexRelease(mutex_id); + if (IS_IRQ_MODE() || IS_IRQ_MASKED()) { + EvrRtxMutexError(mutex_id, osErrorISR); + return osErrorISR; + } + return __svcMutexRelease(mutex_id); +} + +/// Get Thread which owns a Mutex object. +osThreadId_t osMutexGetOwner (osMutexId_t mutex_id) { + if (IS_IRQ_MODE() || IS_IRQ_MASKED()) { + EvrRtxMutexGetOwner(mutex_id, NULL); + return NULL; + } + return __svcMutexGetOwner(mutex_id); +} + +/// Delete a Mutex object. +osStatus_t osMutexDelete (osMutexId_t mutex_id) { + EvrRtxMutexDelete(mutex_id); + if (IS_IRQ_MODE() || IS_IRQ_MASKED()) { + EvrRtxMutexError(mutex_id, osErrorISR); + return osErrorISR; + } + return __svcMutexDelete(mutex_id); +} diff --git a/rtos/rtx2/TARGET_CORTEX_M/rtx_os.h b/rtos/rtx2/TARGET_CORTEX_M/rtx_os.h new file mode 100644 index 00000000000..02c3906b3e4 --- /dev/null +++ b/rtos/rtx2/TARGET_CORTEX_M/rtx_os.h @@ -0,0 +1,478 @@ +/* + * Copyright (c) 2013-2017 ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ----------------------------------------------------------------------------- + * + * Project: CMSIS-RTOS RTX + * Title: RTX OS definitions + * + * ----------------------------------------------------------------------------- + */ + +#ifndef RTX_OS_H_ +#define RTX_OS_H_ + +#include +#include +#include "cmsis_os2.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + + +/// Kernel Information +#define osRtxVersionAPI 20010000 ///< API version (2.1.0) +#define osRtxVersionKernel 50010001 ///< Kernel version (5.1.1) +#define osRtxKernelId "RTX V5.1.1" ///< Kernel identification string + + +// ==== Common definitions ==== + +/// Object Identifier definitions +#define osRtxIdInvalid 0x00U +#define osRtxIdThread 0x01U +#define osRtxIdTimer 0x02U +#define osRtxIdEventFlags 0x03U +#define osRtxIdMutex 0x04U +#define osRtxIdSemaphore 0x05U +#define osRtxIdMemoryPool 0x06U +#define osRtxIdMessage 0x07U +#define osRtxIdMessageQueue 0x08U + +/// Object State definitions (except for Threads and Timers) +#define osRtxObjectInactive 0x00U +#define osRtxObjectActive 0x01U + +/// Object Flags definitions +#define osRtxFlagSystemObject 0x01U +#define osRtxFlagSystemMemory 0x02U + + +// ==== Kernel definitions ==== + +/// Kernel State definitions +#define osRtxKernelInactive ((uint8_t)osKernelInactive) +#define osRtxKernelReady ((uint8_t)osKernelReady) +#define osRtxKernelRunning ((uint8_t)osKernelRunning) +#define osRtxKernelLocked ((uint8_t)osKernelLocked) +#define osRtxKernelSuspended ((uint8_t)osKernelSuspended) + + +// ==== Thread definitions ==== + +/// Thread State definitions (extending osThreadState) +#define osRtxThreadStateMask 0x0FU + +#define osRtxThreadInactive ((uint8_t)osThreadInactive) +#define osRtxThreadReady ((uint8_t)osThreadReady) +#define osRtxThreadRunning ((uint8_t)osThreadRunning) +#define osRtxThreadBlocked ((uint8_t)osThreadBlocked) +#define osRtxThreadTerminated ((uint8_t)osThreadTerminated) + +#define osRtxThreadWaitingDelay (osRtxThreadBlocked | 0x10U) +#define osRtxThreadWaitingJoin (osRtxThreadBlocked | 0x20U) +#define osRtxThreadWaitingThreadFlags (osRtxThreadBlocked | 0x30U) +#define osRtxThreadWaitingEventFlags (osRtxThreadBlocked | 0x40U) +#define osRtxThreadWaitingMutex (osRtxThreadBlocked | 0x50U) +#define osRtxThreadWaitingSemaphore (osRtxThreadBlocked | 0x60U) +#define osRtxThreadWaitingMemoryPool (osRtxThreadBlocked | 0x70U) +#define osRtxThreadWaitingMessageGet (osRtxThreadBlocked | 0x80U) +#define osRtxThreadWaitingMessagePut (osRtxThreadBlocked | 0x90U) + +/// Thread Flags definitions +#define osRtxThreadFlagDefStack 0x10U ///< Default Stack flag + +/// Stack Marker definitions +#define osRtxStackMagicWord 0xE25A2EA5U ///< Stack Magic Word (Stack Base) +#define osRtxStackFillPattern 0xCCCCCCCCU ///< Stack Fill Pattern + +/// Thread Control Block +typedef struct osRtxThread_s { + uint8_t id; ///< Object Identifier + uint8_t state; ///< Object State + uint8_t flags; ///< Object Flags + uint8_t attr; ///< Object Attributes + const char *name; ///< Object Name + struct osRtxThread_s *thread_next; ///< Link pointer to next Thread in Object list + struct osRtxThread_s *thread_prev; ///< Link pointer to previous Thread in Object list + struct osRtxThread_s *delay_next; ///< Link pointer to next Thread in Delay list + struct osRtxThread_s *delay_prev; ///< Link pointer to previous Thread in Delay list + struct osRtxThread_s *thread_join; ///< Thread waiting to Join + uint32_t delay; ///< Delay Time + int8_t priority; ///< Thread Priority + int8_t priority_base; ///< Base Priority + uint8_t stack_frame; ///< Stack Frame (EXC_RETURN[7..0]) + uint8_t flags_options; ///< Thread/Event Flags Options + uint32_t wait_flags; ///< Waiting Thread/Event Flags + uint32_t thread_flags; ///< Thread Flags + struct osRtxMutex_s *mutex_list; ///< Link pointer to list of owned Mutexes + void *stack_mem; ///< Stack Memory + uint32_t stack_size; ///< Stack Size + uint32_t sp; ///< Current Stack Pointer + uint32_t thread_addr; ///< Thread entry address + uint32_t tz_memory; ///< TrustZone Memory Identifier +} osRtxThread_t; + + +// ==== Timer definitions ==== + +/// Timer State definitions +#define osRtxTimerInactive 0x00U ///< Timer Inactive +#define osRtxTimerStopped 0x01U ///< Timer Stopped +#define osRtxTimerRunning 0x02U ///< Timer Running + +/// Timer Type definitions +#define osRtxTimerPeriodic ((uint8_t)osTimerPeriodic) + +/// Timer Function Information +typedef struct { + void *fp; ///< Function Pointer + void *arg; ///< Function Argument +} osRtxTimerFinfo_t; + +/// Timer Control Block +typedef struct osRtxTimer_s { + uint8_t id; ///< Object Identifier + uint8_t state; ///< Object State + uint8_t flags; ///< Object Flags + uint8_t type; ///< Timer Type (Periodic/One-shot) + const char *name; ///< Object Name + struct osRtxTimer_s *prev; ///< Pointer to previous active Timer + struct osRtxTimer_s *next; ///< Pointer to next active Timer + uint32_t tick; ///< Timer current Tick + uint32_t load; ///< Timer Load value + osRtxTimerFinfo_t finfo; ///< Timer Function Info +} osRtxTimer_t; + + +// ==== Event Flags definitions ==== + +/// Event Flags Control Block +typedef struct osRtxEventFlags_s { + uint8_t id; ///< Object Identifier + uint8_t state; ///< Object State + uint8_t flags; ///< Object Flags + uint8_t reserved; + const char *name; ///< Object Name + osRtxThread_t *thread_list; ///< Waiting Threads List + uint32_t event_flags; ///< Event Flags +} osRtxEventFlags_t; + + +// ==== Mutex definitions ==== + +/// Mutex Control Block +typedef struct osRtxMutex_s { + uint8_t id; ///< Object Identifier + uint8_t state; ///< Object State + uint8_t flags; ///< Object Flags + uint8_t attr; ///< Object Attributes + const char *name; ///< Object Name + osRtxThread_t *thread_list; ///< Waiting Threads List + osRtxThread_t *owner_thread; ///< Owner Thread + struct osRtxMutex_s *owner_prev; ///< Pointer to previous owned Mutex + struct osRtxMutex_s *owner_next; ///< Pointer to next owned Mutex + uint8_t lock; ///< Lock counter + uint8_t padding[3]; +} osRtxMutex_t; + + +// ==== Semaphore definitions ==== + +/// Semaphore Control Block +typedef struct osRtxSemaphore_s { + uint8_t id; ///< Object Identifier + uint8_t state; ///< Object State + uint8_t flags; ///< Object Flags + uint8_t reserved; + const char *name; ///< Object Name + osRtxThread_t *thread_list; ///< Waiting Threads List + uint16_t tokens; ///< Current number of tokens + uint16_t max_tokens; ///< Maximum number of tokens +} osRtxSemaphore_t; + + +// ==== Memory Pool definitions ==== + +/// Memory Pool Information +typedef struct osRtxMpInfo_s { + uint32_t max_blocks; ///< Maximum number of Blocks + uint32_t used_blocks; ///< Number of used Blocks + uint32_t block_size; ///< Block Size + void *block_base; ///< Block Memory Base Address + void *block_lim; ///< Block Memory Limit Address + void *block_free; ///< First free Block Address +} osRtxMpInfo_t; + +/// Memory Pool Control Block +typedef struct osRtxMemoryPool_s { + uint8_t id; ///< Object Identifier + uint8_t state; ///< Object State + uint8_t flags; ///< Object Flags + uint8_t reserved; + const char *name; ///< Object Name + osRtxThread_t *thread_list; ///< Waiting Threads List + osRtxMpInfo_t mp_info; ///< Memory Pool Info +} osRtxMemoryPool_t; + + +// ==== Message Queue definitions ==== + +/// Message Control Block +typedef struct osRtxMessage_s { + uint8_t id; ///< Object Identifier + uint8_t state; ///< Object State + uint8_t flags; ///< Object Flags + uint8_t priority; ///< Message Priority + struct osRtxMessage_s *prev; ///< Pointer to previous Message + struct osRtxMessage_s *next; ///< Pointer to next Message +} osRtxMessage_t; + +/// Message Queue Control Block +typedef struct osRtxMessageQueue_s { + uint8_t id; ///< Object Identifier + uint8_t state; ///< Object State + uint8_t flags; ///< Object Flags + uint8_t reserved; + const char *name; ///< Object Name + osRtxThread_t *thread_list; ///< Waiting Threads List + osRtxMpInfo_t mp_info; ///< Memory Pool Info + uint32_t msg_size; ///< Message Size + uint32_t msg_count; ///< Number of queued Messages + osRtxMessage_t *msg_first; ///< Pointer to first Message + osRtxMessage_t *msg_last; ///< Pointer to last Message +} osRtxMessageQueue_t; + + +// ==== Generic Object definitions ==== + +/// Generic Object Control Block +typedef struct osRtxObject_s { + uint8_t id; ///< Object Identifier + uint8_t state; ///< Object State + uint8_t flags; ///< Object Flags + uint8_t reserved; + const char *name; ///< Object Name + osRtxThread_t *thread_list; ///< Threads List +} osRtxObject_t; + + +// ==== OS Runtime Information definitions ==== + +/// OS Runtime Information structure +typedef struct { + const char *os_id; ///< OS Identification + uint32_t version; ///< OS Version + struct { ///< Kernel Info + uint8_t state; ///< State + volatile uint8_t blocked; ///< Blocked + uint8_t pendISR; ///< Pending ISR (SV and SysTick) + uint8_t pendSV; ///< Pending SV + uint32_t sys_freq; ///< System Frequency + uint64_t tick; ///< Tick counter + } kernel; + int32_t tick_irqn; ///< Tick Timer IRQ Number + struct { ///< Thread Info + struct { ///< Thread Run Info + osRtxThread_t *curr; ///< Current running Thread + osRtxThread_t *next; ///< Next Thread to Run + } run; + volatile osRtxObject_t ready; ///< Ready List Object + osRtxThread_t *idle; ///< Idle Thread + osRtxThread_t *delay_list; ///< Delay List + osRtxThread_t *wait_list; ///< Wait List (no Timeout) + osRtxThread_t *terminate_list; ///< Terminate Thread List + struct { ///< Thread Round Robin Info + osRtxThread_t *thread; ///< Round Robin Thread + uint32_t tick; ///< Round Robin Time Tick + uint32_t timeout; ///< Round Robin Timeout + } robin; + } thread; + struct { ///< Timer Info + osRtxTimer_t *list; ///< Active Timer List + osRtxThread_t *thread; ///< Timer Thread + osRtxMessageQueue_t *mq; ///< Timer Message Queue + void (*tick)(void); ///< Timer Tick Function + } timer; + struct { ///< ISR Post Processing Queue + uint16_t max; ///< Maximum Items + uint16_t cnt; ///< Item Count + uint16_t in; ///< Incoming Item Index + uint16_t out; ///< Outgoing Item Index + void **data; ///< Queue Data + } isr_queue; + struct { ///< ISR Post Processing functions + void (*thread)(osRtxThread_t*); ///< Thread Post Processing function + void (*event_flags)(osRtxEventFlags_t*); ///< Event Flags Post Processing function + void (*semaphore)(osRtxSemaphore_t*); ///< Semaphore Post Processing function + void (*memory_pool)(osRtxMemoryPool_t*); ///< Memory Pool Post Processing function + void (*message_queue)(osRtxMessage_t*); ///< Message Queue Post Processing function + } post_process; + struct { ///< Memory Pools (Variable Block Size) + void *stack; ///< Stack Memory + void *mp_data; ///< Memory Pool Data Memory + void *mq_data; ///< Message Queue Data Memory + void *common; ///< Common Memory + } mem; + struct { ///< Memory Pools (Fixed Block Size) + osRtxMpInfo_t *stack; ///< Stack for Threads + osRtxMpInfo_t *thread; ///< Thread Control Blocks + osRtxMpInfo_t *timer; ///< Timer Control Blocks + osRtxMpInfo_t *event_flags; ///< Event Flags Control Blocks + osRtxMpInfo_t *mutex; ///< Mutex Control Blocks + osRtxMpInfo_t *semaphore; ///< Semaphore Control Blocks + osRtxMpInfo_t *memory_pool; ///< Memory Pool Control Blocks + osRtxMpInfo_t *message_queue; ///< Message Queue Control Blocks + } mpi; + uint32_t padding; +} osRtxInfo_t; + +extern osRtxInfo_t osRtxInfo; ///< OS Runtime Information + + +// ==== OS API definitions ==== + +/// Object Limits definitions +#define osRtxThreadFlagsLimit 31U ///< number of Thread Flags available per thread +#define osRtxEventFlagsLimit 31U ///< number of Event Flags available per object +#define osRtxMutexLockLimit 255U ///< maximum number of recursive mutex locks +#define osRtxSemaphoreTokenLimit 65535U ///< maximum number of tokens per semaphore + +/// Control Block sizes +#define osRtxThreadCbSize sizeof(osRtxThread_t) +#define osRtxTimerCbSize sizeof(osRtxTimer_t) +#define osRtxEventFlagsCbSize sizeof(osRtxEventFlags_t) +#define osRtxMutexCbSize sizeof(osRtxMutex_t) +#define osRtxSemaphoreCbSize sizeof(osRtxSemaphore_t) +#define osRtxMemoryPoolCbSize sizeof(osRtxMemoryPool_t) +#define osRtxMessageQueueCbSize sizeof(osRtxMessageQueue_t) + +/// Memory size in bytes for Memory Pool storage. +/// \param block_count maximum number of memory blocks in memory pool. +/// \param block_size memory block size in bytes. +#define osRtxMemoryPoolMemSize(block_count, block_size) \ + (4*(block_count)*(((block_size)+3)/4)) + +/// Memory size in bytes for Message Queue storage. +/// \param msg_count maximum number of messages in queue. +/// \param msg_size maximum message size in bytes. +#define osRtxMessageQueueMemSize(msg_count, msg_size) \ + (4*(msg_count)*(3+(((msg_size)+3)/4))) + + +// ==== OS External Functions ==== + +/// OS Error Codes +#define osRtxErrorStackUnderflow 1U +#define osRtxErrorISRQueueOverflow 2U +#define osRtxErrorTimerQueueOverflow 3U +#define osRtxErrorClibSpace 4U +#define osRtxErrorClibMutex 5U + +/// OS Error Callback function +extern uint32_t osRtxErrorNotify (uint32_t code, void *object_id); + +/// OS Idle Thread +extern void osRtxIdleThread (void *argument); + +/// OS Exception handlers +extern void SVC_Handler (void); +extern void PendSV_Handler (void); +extern void SysTick_Handler (void); + + +/// OS System Timer functions (default implementation uses SysTick) + +/// Setup System Timer. +/// \return system timer IRQ number. +extern int32_t osRtxSysTimerSetup (void); + +/// Enable System Timer. +extern void osRtxSysTimerEnable (void); + +/// Disable System Timer. +extern void osRtxSysTimerDisable (void); + +/// Acknowledge System Timer IRQ. +extern void osRtxSysTimerAckIRQ (void); + +/// Get System Timer count. +/// \return system timer count. +extern uint32_t osRtxSysTimerGetCount (void); + +/// Get System Timer frequency. +/// \return system timer frequency. +extern uint32_t osRtxSysTimerGetFreq (void); + + +// ==== OS External Configuration ==== + +/// OS Configuration flags +#define osRtxConfigPrivilegedMode (1UL<<0) ///< Threads in Privileged mode +#define osRtxConfigStackCheck (1UL<<1) ///< Stack overrun checking +#define osRtxConfigStackWatermark (1UL<<2) ///< Stack usage Watermark + +/// OS Configuration structure +typedef struct { + uint32_t flags; ///< OS Configuration Flags + uint32_t tick_freq; ///< Kernel Tick Frequency + uint32_t robin_timeout; ///< Round Robin Timeout Tick + struct { ///< ISR Post Processing Queue + void **data; ///< Queue Data + uint16_t max; ///< Maximum Items + uint16_t padding; + } isr_queue; + struct { ///< Memory Pools (Variable Block Size) + void *stack_addr; ///< Stack Memory Address + uint32_t stack_size; ///< Stack Memory Size + void *mp_data_addr; ///< Memory Pool Memory Address + uint32_t mp_data_size; ///< Memory Pool Memory Size + void *mq_data_addr; ///< Message Queue Data Memory Address + uint32_t mq_data_size; ///< Message Queue Data Memory Size + void *common_addr; ///< Common Memory Address + uint32_t common_size; ///< Common Memory Size + } mem; + struct { ///< Memory Pools (Fixed Block Size) + osRtxMpInfo_t *stack; ///< Stack for Threads + osRtxMpInfo_t *thread; ///< Thread Control Blocks + osRtxMpInfo_t *timer; ///< Timer Control Blocks + osRtxMpInfo_t *event_flags; ///< Event Flags Control Blocks + osRtxMpInfo_t *mutex; ///< Mutex Control Blocks + osRtxMpInfo_t *semaphore; ///< Semaphore Control Blocks + osRtxMpInfo_t *memory_pool; ///< Memory Pool Control Blocks + osRtxMpInfo_t *message_queue; ///< Message Queue Control Blocks + } mpi; + uint32_t thread_stack_size; ///< Default Thread Stack Size + const + osThreadAttr_t *idle_thread_attr; ///< Idle Thread Attributes + const + osThreadAttr_t *timer_thread_attr; ///< Timer Thread Attributes + const + osMessageQueueAttr_t *timer_mq_attr; ///< Timer Message Queue Attributes + uint32_t timer_mq_mcnt; ///< Timer Message Queue maximum Messages +} osRtxConfig_t; + +extern const osRtxConfig_t osRtxConfig; ///< OS Configuration + + +#ifdef __cplusplus +} +#endif + +#endif // RTX_OS_H_ diff --git a/rtos/rtx2/TARGET_CORTEX_M/rtx_semaphore.c b/rtos/rtx2/TARGET_CORTEX_M/rtx_semaphore.c new file mode 100644 index 00000000000..f0a3c40cdfb --- /dev/null +++ b/rtos/rtx2/TARGET_CORTEX_M/rtx_semaphore.c @@ -0,0 +1,484 @@ +/* + * Copyright (c) 2013-2017 ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ----------------------------------------------------------------------------- + * + * Project: CMSIS-RTOS RTX + * Title: Semaphore functions + * + * ----------------------------------------------------------------------------- + */ + +#include "rtx_lib.h" + + +// ==== Helper functions ==== + +/// Decrement Semaphore tokens. +/// \param[in] semaphore semaphore object. +/// \return 1 - success, 0 - failure. +static uint32_t SemaphoreTokenDecrement (os_semaphore_t *semaphore) { +#if (__EXCLUSIVE_ACCESS == 0U) + uint32_t primask = __get_PRIMASK(); +#endif + uint32_t ret; + +#if (__EXCLUSIVE_ACCESS == 0U) + __disable_irq(); + + if (semaphore->tokens != 0U) { + semaphore->tokens--; + ret = 1U; + } else { + ret = 0U; + } + + if (primask == 0U) { + __enable_irq(); + } +#else + if (atomic_dec16_nz(&semaphore->tokens) != 0U) { + ret = 1U; + } else { + ret = 0U; + } +#endif + + return ret; +} + +/// Increment Semaphore tokens. +/// \param[in] semaphore semaphore object. +/// \return 1 - success, 0 - failure. +static uint32_t SemaphoreTokenIncrement (os_semaphore_t *semaphore) { +#if (__EXCLUSIVE_ACCESS == 0U) + uint32_t primask = __get_PRIMASK(); +#endif + uint32_t ret; + +#if (__EXCLUSIVE_ACCESS == 0U) + __disable_irq(); + + if (semaphore->tokens < semaphore->max_tokens) { + semaphore->tokens++; + ret = 1U; + } else { + ret = 0U; + } + + if (primask == 0U) { + __enable_irq(); + } +#else + if (atomic_inc16_lt(&semaphore->tokens, semaphore->max_tokens) < semaphore->max_tokens) { + ret = 1U; + } else { + ret = 0U; + } +#endif + + return ret; +} + + +// ==== Library functions ==== + +/// Semaphore post ISR processing. +/// \param[in] semaphore semaphore object. +void osRtxSemaphorePostProcess (os_semaphore_t *semaphore) { + os_thread_t *thread; + + if (semaphore->state == osRtxObjectInactive) { + return; + } + + // Check if Thread is waiting for a token + if (semaphore->thread_list != NULL) { + // Try to acquire token + if (SemaphoreTokenDecrement(semaphore) != 0U) { + // Wakeup waiting Thread with highest Priority + thread = osRtxThreadListGet((os_object_t*)semaphore); + osRtxThreadWaitExit(thread, (uint32_t)osOK, false); + EvrRtxSemaphoreAcquired(semaphore); + } + } +} + + +// ==== Service Calls ==== + +// Service Calls definitions +SVC0_3M(SemaphoreNew, osSemaphoreId_t, uint32_t, uint32_t, const osSemaphoreAttr_t *) +SVC0_1 (SemaphoreGetName, const char *, osSemaphoreId_t) +SVC0_2 (SemaphoreAcquire, osStatus_t, osSemaphoreId_t, uint32_t) +SVC0_1 (SemaphoreRelease, osStatus_t, osSemaphoreId_t) +SVC0_1 (SemaphoreGetCount, uint32_t, osSemaphoreId_t) +SVC0_1 (SemaphoreDelete, osStatus_t, osSemaphoreId_t) + +/// Create and Initialize a Semaphore object. +/// \note API identical to osSemaphoreNew +osSemaphoreId_t svcRtxSemaphoreNew (uint32_t max_count, uint32_t initial_count, const osSemaphoreAttr_t *attr) { + os_semaphore_t *semaphore; + uint8_t flags; + const char *name; + + // Check parameters + if ((max_count == 0U) || (max_count > osRtxSemaphoreTokenLimit) || (initial_count > max_count)) { + EvrRtxSemaphoreError(NULL, osErrorParameter); + return NULL; + } + + // Process attributes + if (attr != NULL) { + name = attr->name; + semaphore = attr->cb_mem; + if (semaphore != NULL) { + if (((uint32_t)semaphore & 3U) || (attr->cb_size < sizeof(os_semaphore_t))) { + EvrRtxSemaphoreError(NULL, osRtxErrorInvalidControlBlock); + return NULL; + } + } else { + if (attr->cb_size != 0U) { + EvrRtxSemaphoreError(NULL, osRtxErrorInvalidControlBlock); + return NULL; + } + } + } else { + name = NULL; + semaphore = NULL; + } + + // Allocate object memory if not provided + if (semaphore == NULL) { + if (osRtxInfo.mpi.semaphore != NULL) { + semaphore = osRtxMemoryPoolAlloc(osRtxInfo.mpi.semaphore); + } else { + semaphore = osRtxMemoryAlloc(osRtxInfo.mem.common, sizeof(os_semaphore_t), 1U); + } + if (semaphore == NULL) { + EvrRtxSemaphoreError(NULL, osErrorNoMemory); + return NULL; + } + flags = osRtxFlagSystemObject; + } else { + flags = 0U; + } + + // Initialize control block + semaphore->id = osRtxIdSemaphore; + semaphore->state = osRtxObjectActive; + semaphore->flags = flags; + semaphore->name = name; + semaphore->thread_list = NULL; + semaphore->tokens = (uint16_t)initial_count; + semaphore->max_tokens = (uint16_t)max_count; + + // Register post ISR processing function + osRtxInfo.post_process.semaphore = osRtxSemaphorePostProcess; + + EvrRtxSemaphoreCreated(semaphore); + + return semaphore; +} + +/// Get name of a Semaphore object. +/// \note API identical to osSemaphoreGetName +const char *svcRtxSemaphoreGetName (osSemaphoreId_t semaphore_id) { + os_semaphore_t *semaphore = (os_semaphore_t *)semaphore_id; + + // Check parameters + if ((semaphore == NULL) || (semaphore->id != osRtxIdSemaphore)) { + EvrRtxSemaphoreGetName(semaphore, NULL); + return NULL; + } + + // Check object state + if (semaphore->state == osRtxObjectInactive) { + EvrRtxSemaphoreGetName(semaphore, NULL); + return NULL; + } + + EvrRtxSemaphoreGetName(semaphore, semaphore->name); + + return semaphore->name; +} + +/// Acquire a Semaphore token or timeout if no tokens are available. +/// \note API identical to osSemaphoreAcquire +osStatus_t svcRtxSemaphoreAcquire (osSemaphoreId_t semaphore_id, uint32_t timeout) { + os_semaphore_t *semaphore = (os_semaphore_t *)semaphore_id; + + // Check parameters + if ((semaphore == NULL) || (semaphore->id != osRtxIdSemaphore)) { + EvrRtxSemaphoreError(semaphore, osErrorParameter); + return osErrorParameter; + } + + // Check object state + if (semaphore->state == osRtxObjectInactive) { + EvrRtxSemaphoreError(semaphore, osErrorResource); + return osErrorResource; + } + + // Try to acquire token + if (SemaphoreTokenDecrement(semaphore) == 0U) { + // No token available + if (timeout != 0U) { + EvrRtxSemaphoreAcquirePending(semaphore, timeout); + // Suspend current Thread + osRtxThreadListPut((os_object_t*)semaphore, osRtxThreadGetRunning()); + osRtxThreadWaitEnter(osRtxThreadWaitingSemaphore, timeout); + return osErrorTimeout; + } else { + EvrRtxSemaphoreNotAcquired(semaphore); + return osErrorResource; + } + } + + EvrRtxSemaphoreAcquired(semaphore); + + return osOK; +} + +/// Release a Semaphore token that was acquired by osSemaphoreAcquire. +/// \note API identical to osSemaphoreRelease +osStatus_t svcRtxSemaphoreRelease (osSemaphoreId_t semaphore_id) { + os_semaphore_t *semaphore = (os_semaphore_t *)semaphore_id; + os_thread_t *thread; + + // Check parameters + if ((semaphore == NULL) || (semaphore->id != osRtxIdSemaphore)) { + EvrRtxSemaphoreError(semaphore, osErrorParameter); + return osErrorParameter; + } + + // Check object state + if (semaphore->state == osRtxObjectInactive) { + EvrRtxSemaphoreError(semaphore, osErrorResource); + return osErrorResource; + } + + // Check if Thread is waiting for a token + if (semaphore->thread_list != NULL) { + EvrRtxSemaphoreReleased(semaphore); + // Wakeup waiting Thread with highest Priority + thread = osRtxThreadListGet((os_object_t*)semaphore); + osRtxThreadWaitExit(thread, (uint32_t)osOK, true); + EvrRtxSemaphoreAcquired(semaphore); + } else { + // Try to release token + if (SemaphoreTokenIncrement(semaphore) == 0U) { + EvrRtxSemaphoreError(semaphore, osRtxErrorSemaphoreCountLimit); + return osErrorResource; + } + EvrRtxSemaphoreReleased(semaphore); + } + + return osOK; +} + +/// Get current Semaphore token count. +/// \note API identical to osSemaphoreGetCount +uint32_t svcRtxSemaphoreGetCount (osSemaphoreId_t semaphore_id) { + os_semaphore_t *semaphore = (os_semaphore_t *)semaphore_id; + + // Check parameters + if ((semaphore == NULL) || (semaphore->id != osRtxIdSemaphore)) { + EvrRtxSemaphoreGetCount(semaphore, 0U); + return 0U; + } + + // Check object state + if (semaphore->state == osRtxObjectInactive) { + EvrRtxSemaphoreGetCount(semaphore, 0U); + return 0U; + } + + EvrRtxSemaphoreGetCount(semaphore, semaphore->tokens); + + return semaphore->tokens; +} + +/// Delete a Semaphore object. +/// \note API identical to osSemaphoreDelete +osStatus_t svcRtxSemaphoreDelete (osSemaphoreId_t semaphore_id) { + os_semaphore_t *semaphore = (os_semaphore_t *)semaphore_id; + os_thread_t *thread; + + // Check parameters + if ((semaphore == NULL) || (semaphore->id != osRtxIdSemaphore)) { + EvrRtxSemaphoreError(semaphore, osErrorParameter); + return osErrorParameter; + } + + // Check object state + if (semaphore->state == osRtxObjectInactive) { + EvrRtxSemaphoreError(semaphore, osErrorResource); + return osErrorResource; + } + + // Mark object as inactive + semaphore->state = osRtxObjectInactive; + + // Unblock waiting threads + if (semaphore->thread_list != NULL) { + do { + thread = osRtxThreadListGet((os_object_t*)semaphore); + osRtxThreadWaitExit(thread, (uint32_t)osErrorResource, false); + } while (semaphore->thread_list != NULL); + osRtxThreadDispatch(NULL); + } + + // Free object memory + if (semaphore->flags & osRtxFlagSystemObject) { + if (osRtxInfo.mpi.semaphore != NULL) { + osRtxMemoryPoolFree(osRtxInfo.mpi.semaphore, semaphore); + } else { + osRtxMemoryFree(osRtxInfo.mem.common, semaphore); + } + } + + EvrRtxSemaphoreDestroyed(semaphore); + + return osOK; +} + + +// ==== ISR Calls ==== + +/// Acquire a Semaphore token or timeout if no tokens are available. +/// \note API identical to osSemaphoreAcquire +__STATIC_INLINE +osStatus_t isrRtxSemaphoreAcquire (osSemaphoreId_t semaphore_id, uint32_t timeout) { + os_semaphore_t *semaphore = (os_semaphore_t *)semaphore_id; + + // Check parameters + if ((semaphore == NULL) || (semaphore->id != osRtxIdSemaphore) || (timeout != 0U)) { + EvrRtxSemaphoreError(semaphore, osErrorParameter); + return osErrorParameter; + } + + // Check object state + if (semaphore->state == osRtxObjectInactive) { + EvrRtxSemaphoreError(semaphore, osErrorResource); + return osErrorResource; + } + + // Try to acquire token + if (SemaphoreTokenDecrement(semaphore) == 0U) { + // No token available + EvrRtxSemaphoreNotAcquired(semaphore); + return osErrorResource; + } + + EvrRtxSemaphoreAcquired(semaphore); + + return osOK; +} + +/// Release a Semaphore token that was acquired by osSemaphoreAcquire. +/// \note API identical to osSemaphoreRelease +__STATIC_INLINE +osStatus_t isrRtxSemaphoreRelease (osSemaphoreId_t semaphore_id) { + os_semaphore_t *semaphore = (os_semaphore_t *)semaphore_id; + + // Check parameters + if ((semaphore == NULL) || (semaphore->id != osRtxIdSemaphore)) { + EvrRtxSemaphoreError(semaphore, osErrorParameter); + return osErrorParameter; + } + + // Check object state + if (semaphore->state == osRtxObjectInactive) { + EvrRtxSemaphoreError(semaphore, osErrorResource); + return osErrorResource; + } + + // Try to release token + if (SemaphoreTokenIncrement(semaphore) != 0U) { + // Register post ISR processing + osRtxPostProcess((os_object_t *)semaphore); + } else { + EvrRtxSemaphoreError(semaphore, osRtxErrorSemaphoreCountLimit); + return osErrorResource; + } + + EvrRtxSemaphoreReleased(semaphore); + + return osOK; +} + + +// ==== Public API ==== + +/// Create and Initialize a Semaphore object. +osSemaphoreId_t osSemaphoreNew (uint32_t max_count, uint32_t initial_count, const osSemaphoreAttr_t *attr) { + EvrRtxSemaphoreNew(max_count, initial_count, attr); + if (IS_IRQ_MODE() || IS_IRQ_MASKED()) { + EvrRtxSemaphoreError(NULL, osErrorISR); + return NULL; + } + return __svcSemaphoreNew(max_count, initial_count, attr); +} + +/// Get name of a Semaphore object. +const char *osSemaphoreGetName (osSemaphoreId_t semaphore_id) { + if (IS_IRQ_MODE() || IS_IRQ_MASKED()) { + EvrRtxSemaphoreGetName(semaphore_id, NULL); + return NULL; + } + return __svcSemaphoreGetName(semaphore_id); +} + +/// Acquire a Semaphore token or timeout if no tokens are available. +osStatus_t osSemaphoreAcquire (osSemaphoreId_t semaphore_id, uint32_t timeout) { + EvrRtxSemaphoreAcquire(semaphore_id, timeout); + if (IS_IRQ_MODE() || IS_IRQ_MASKED()) { + return isrRtxSemaphoreAcquire(semaphore_id, timeout); + } else { + return __svcSemaphoreAcquire(semaphore_id, timeout); + } +} + +/// Release a Semaphore token that was acquired by osSemaphoreAcquire. +osStatus_t osSemaphoreRelease (osSemaphoreId_t semaphore_id) { + EvrRtxSemaphoreRelease(semaphore_id); + if (IS_IRQ_MODE() || IS_IRQ_MASKED()) { + return isrRtxSemaphoreRelease(semaphore_id); + } else { + return __svcSemaphoreRelease(semaphore_id); + } +} + +/// Get current Semaphore token count. +uint32_t osSemaphoreGetCount (osSemaphoreId_t semaphore_id) { + if (IS_IRQ_MODE() || IS_IRQ_MASKED()) { + return svcRtxSemaphoreGetCount(semaphore_id); + } else { + return __svcSemaphoreGetCount(semaphore_id); + } +} + +/// Delete a Semaphore object. +osStatus_t osSemaphoreDelete (osSemaphoreId_t semaphore_id) { + EvrRtxSemaphoreDelete(semaphore_id); + if (IS_IRQ_MODE() || IS_IRQ_MASKED()) { + EvrRtxSemaphoreError(semaphore_id, osErrorISR); + return osErrorISR; + } + return __svcSemaphoreDelete(semaphore_id); +} diff --git a/rtos/rtx2/TARGET_CORTEX_M/rtx_system.c b/rtos/rtx2/TARGET_CORTEX_M/rtx_system.c new file mode 100644 index 00000000000..c8715cd54d5 --- /dev/null +++ b/rtos/rtx2/TARGET_CORTEX_M/rtx_system.c @@ -0,0 +1,257 @@ +/* + * Copyright (c) 2013-2017 ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ----------------------------------------------------------------------------- + * + * Project: CMSIS-RTOS RTX + * Title: System functions + * + * ----------------------------------------------------------------------------- + */ + +#include "rtx_lib.h" + + +// ==== Helper functions ==== + +/// Put Object into ISR Queue. +/// \param[in] object object. +/// \return 1 - success, 0 - failure. +static uint32_t isr_queue_put (void *object) { +#if (__EXCLUSIVE_ACCESS == 0U) + uint32_t primask = __get_PRIMASK(); +#else + uint32_t n; +#endif + uint16_t max; + uint32_t ret; + + max = osRtxInfo.isr_queue.max; + +#if (__EXCLUSIVE_ACCESS == 0U) + __disable_irq(); + + if (osRtxInfo.isr_queue.cnt < max) { + osRtxInfo.isr_queue.cnt++; + osRtxInfo.isr_queue.data[osRtxInfo.isr_queue.in] = object; + if (++osRtxInfo.isr_queue.in == max) { + osRtxInfo.isr_queue.in = 0U; + } + ret = 1U; + } else { + ret = 0U; + } + + if (primask == 0U) { + __enable_irq(); + } +#else + if (atomic_inc16_lt(&osRtxInfo.isr_queue.cnt, max) < max) { + n = atomic_inc16_lim(&osRtxInfo.isr_queue.in, max); + osRtxInfo.isr_queue.data[n] = object; + ret = 1U; + } else { + ret = 0U; + } +#endif + + return ret; +} + +/// Get Object from ISR Queue. +/// \return object or NULL. +static void *isr_queue_get (void) { +#if (__EXCLUSIVE_ACCESS == 0U) + uint32_t primask = __get_PRIMASK(); +#else + uint32_t n; +#endif + uint16_t max; + void *ret; + + max = osRtxInfo.isr_queue.max; + +#if (__EXCLUSIVE_ACCESS == 0U) + __disable_irq(); + + if (osRtxInfo.isr_queue.cnt != 0U) { + osRtxInfo.isr_queue.cnt--; + ret = osRtxInfo.isr_queue.data[osRtxInfo.isr_queue.out]; + if (++osRtxInfo.isr_queue.out == max) { + osRtxInfo.isr_queue.out = 0U; + } + } else { + ret = NULL; + } + + if (primask == 0U) { + __enable_irq(); + } +#else + if (atomic_dec16_nz(&osRtxInfo.isr_queue.cnt) != 0U) { + n = atomic_inc16_lim(&osRtxInfo.isr_queue.out, max); + ret = osRtxInfo.isr_queue.data[n]; + } else { + ret = NULL; + } +#endif + + return ret; +} + + +// ==== Library Functions ==== + +/// Tick Handler. +void osRtxTick_Handler (void) { + os_thread_t *thread; + + osRtxSysTimerAckIRQ(); + osRtxInfo.kernel.tick++; + + // Process Timers + if (osRtxInfo.timer.tick != NULL) { + osRtxInfo.timer.tick(); + } + + // Process Thread Delays + osRtxThreadDelayTick(); + + osRtxThreadDispatch(NULL); + + // Check Round Robin timeout + if (osRtxInfo.thread.robin.timeout != 0U) { + if (osRtxInfo.thread.robin.thread != osRtxInfo.thread.run.next) { + // Reset Round Robin + osRtxInfo.thread.robin.thread = osRtxInfo.thread.run.next; + osRtxInfo.thread.robin.tick = osRtxInfo.thread.robin.timeout; + } else { + if (osRtxInfo.thread.robin.tick != 0U) { + osRtxInfo.thread.robin.tick--; + } + if (osRtxInfo.thread.robin.tick == 0U) { + // Round Robin Timeout + if (osRtxKernelGetState() == osRtxKernelRunning) { + thread = osRtxInfo.thread.ready.thread_list; + if ((thread != NULL) && (thread->priority == osRtxInfo.thread.robin.thread->priority)) { + osRtxThreadListRemove(thread); + osRtxThreadReadyPut(osRtxInfo.thread.robin.thread); + osRtxThreadSwitch(thread); + osRtxInfo.thread.robin.thread = thread; + osRtxInfo.thread.robin.tick = osRtxInfo.thread.robin.timeout; + } + } + } + } + } +} + +/// Pending Service Call Handler. +void osRtxPendSV_Handler (void) { + os_object_t *object; + + for (;;) { + object = isr_queue_get(); + if (object == NULL) { + break; + } + switch (object->id) { + case osRtxIdThread: + osRtxInfo.post_process.thread((os_thread_t *)object); + break; + case osRtxIdEventFlags: + osRtxInfo.post_process.event_flags((os_event_flags_t *)object); + break; + case osRtxIdSemaphore: + osRtxInfo.post_process.semaphore((os_semaphore_t *)object); + break; + case osRtxIdMemoryPool: + osRtxInfo.post_process.memory_pool((os_memory_pool_t *)object); + break; + case osRtxIdMessage: + osRtxInfo.post_process.message_queue((os_message_t *)object); + break; + default: + break; + } + } + + osRtxThreadDispatch(NULL); +} + +/// Register post ISR processing. +/// \param[in] object generic object. +void osRtxPostProcess (os_object_t *object) { + + if (isr_queue_put(object) != 0U) { + if (osRtxInfo.kernel.blocked == 0U) { + SetPendSV(); + } else { + osRtxInfo.kernel.pendSV = 1U; + } + } else { + osRtxErrorNotify(osRtxErrorISRQueueOverflow, object); + } +} + + +// ==== Public API ==== + +/// Setup System Timer. +__WEAK int32_t osRtxSysTimerSetup (void) { + + // Setup SysTick Timer + SysTick_Setup(osRtxInfo.kernel.sys_freq / osRtxConfig.tick_freq); + + return SysTick_IRQn; // Return IRQ number of SysTick +} + +/// Enable System Timer. +__WEAK void osRtxSysTimerEnable (void) { + SysTick_Enable(); +} + +/// Disable System Timer. +__WEAK void osRtxSysTimerDisable (void) { + SysTick_Disable(); +} + +/// Acknowledge System Timer IRQ. +__WEAK void osRtxSysTimerAckIRQ (void) { + SysTick_GetOvf(); +} + +/// Get System Timer count. +__WEAK uint32_t osRtxSysTimerGetCount (void) { + uint32_t tick; + uint32_t val; + + tick = (uint32_t)osRtxInfo.kernel.tick; + val = SysTick_GetVal(); + if (SysTick_GetOvf()) { + val = SysTick_GetVal(); + tick++; + } + val += tick * SysTick_GetPeriod(); + + return val; +} + +/// Get System Timer frequency. +__WEAK uint32_t osRtxSysTimerGetFreq (void) { + return osRtxInfo.kernel.sys_freq; +} diff --git a/rtos/rtx2/TARGET_CORTEX_M/rtx_thread.c b/rtos/rtx2/TARGET_CORTEX_M/rtx_thread.c new file mode 100644 index 00000000000..b49abd36afc --- /dev/null +++ b/rtos/rtx2/TARGET_CORTEX_M/rtx_thread.c @@ -0,0 +1,1699 @@ +/* + * Copyright (c) 2013-2017 ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ----------------------------------------------------------------------------- + * + * Project: CMSIS-RTOS RTX + * Title: Thread functions + * + * ----------------------------------------------------------------------------- + */ + +#include "rtx_lib.h" + + +// ==== Helper functions ==== + +/// Set Thread Flags. +/// \param[in] thread thread object. +/// \param[in] flags specifies the flags to set. +/// \return thread flags after setting. +static uint32_t ThreadFlagsSet (os_thread_t *thread, uint32_t flags) { +#if (__EXCLUSIVE_ACCESS == 0U) + uint32_t primask = __get_PRIMASK(); +#endif + uint32_t thread_flags; + +#if (__EXCLUSIVE_ACCESS == 0U) + __disable_irq(); + + thread->thread_flags |= flags; + thread_flags = thread->thread_flags; + + if (primask == 0U) { + __enable_irq(); + } +#else + thread_flags = atomic_set32(&thread->thread_flags, flags); +#endif + + return thread_flags; +} + +/// Clear Thread Flags. +/// \param[in] thread thread object. +/// \param[in] flags specifies the flags to clear. +/// \return thread flags before clearing. +static uint32_t ThreadFlagsClear (os_thread_t *thread, uint32_t flags) { +#if (__EXCLUSIVE_ACCESS == 0U) + uint32_t primask = __get_PRIMASK(); +#endif + uint32_t thread_flags; + +#if (__EXCLUSIVE_ACCESS == 0U) + __disable_irq(); + + thread_flags = thread->thread_flags; + thread->thread_flags &= ~flags; + + if (primask == 0U) { + __enable_irq(); + } +#else + thread_flags = atomic_clr32(&thread->thread_flags, flags); +#endif + + return thread_flags; +} + +/// Check Thread Flags. +/// \param[in] thread thread object. +/// \param[in] flags specifies the flags to check. +/// \param[in] options specifies flags options (osFlagsXxxx). +/// \return thread flags before clearing or 0 if specified flags have not been set. +static uint32_t ThreadFlagsCheck (os_thread_t *thread, uint32_t flags, uint32_t options) { +#if (__EXCLUSIVE_ACCESS == 0U) + uint32_t primask; +#endif + uint32_t thread_flags; + + if ((options & osFlagsNoClear) == 0U) { +#if (__EXCLUSIVE_ACCESS == 0U) + primask = __get_PRIMASK(); + __disable_irq(); + + thread_flags = thread->thread_flags; + if ((((options & osFlagsWaitAll) != 0U) && ((thread_flags & flags) != flags)) || + (((options & osFlagsWaitAll) == 0U) && ((thread_flags & flags) == 0U))) { + thread_flags = 0U; + } else { + thread->thread_flags &= ~flags; + } + + if (primask == 0U) { + __enable_irq(); + } +#else + if ((options & osFlagsWaitAll) != 0U) { + thread_flags = atomic_chk32_all(&thread->thread_flags, flags); + } else { + thread_flags = atomic_chk32_any(&thread->thread_flags, flags); + } +#endif + } else { + thread_flags = thread->thread_flags; + if ((((options & osFlagsWaitAll) != 0U) && ((thread_flags & flags) != flags)) || + (((options & osFlagsWaitAll) == 0U) && ((thread_flags & flags) == 0U))) { + thread_flags = 0U; + } + } + + return thread_flags; +} + + +// ==== Library functions ==== + +/// Put a Thread into specified Object list sorted by Priority (Highest at Head). +/// \param[in] object generic object. +/// \param[in] thread thread object. +void osRtxThreadListPut (volatile os_object_t *object, os_thread_t *thread) { + os_thread_t *prev, *next; + int32_t priority; + + if (thread == NULL) { + return; + } + + priority = thread->priority; + + prev = (os_thread_t *)(uint32_t)object; + next = object->thread_list; + while ((next != NULL) && (next->priority >= priority)) { + prev = next; + next = next->thread_next; + } + thread->thread_prev = prev; + thread->thread_next = next; + prev->thread_next = thread; + if (next != NULL) { + next->thread_prev = thread; + } +} + +/// Get a Thread with Highest Priority from specified Object list and remove it. +/// \param[in] object generic object. +/// \return thread object. +os_thread_t *osRtxThreadListGet (volatile os_object_t *object) { + os_thread_t *thread; + + thread = object->thread_list; + if (thread != NULL) { + object->thread_list = thread->thread_next; + if (thread->thread_next != NULL) { + thread->thread_next->thread_prev = (os_thread_t *)(uint32_t)object; + } + thread->thread_prev = NULL; + } + + return thread; +} + +/// Retrieve Thread list root. +/// \param[in] thread thread object. +void *osRtxThreadListRoot (os_thread_t *thread) { + + while ((thread != NULL) && (thread->id == osRtxIdThread)) { + thread = thread->thread_prev; + } + return ((void *)thread); +} + +/// Re-sort a Thread in linked Object list by Priority (Highest at Head). +/// \param[in] thread thread object. +void osRtxThreadListSort (os_thread_t *thread) { + os_object_t *object; + os_thread_t *thread0; + + // Search for object + thread0 = thread; + while (thread0->id == osRtxIdThread) { + thread0 = thread0->thread_prev; + if (thread0 == NULL) { + return; + } + } + object = (os_object_t *)thread0; + + osRtxThreadListRemove(thread); + osRtxThreadListPut(object, thread); +} + +/// Remove a Thread from linked Object list. +/// \param[in] thread thread object. +void osRtxThreadListRemove (os_thread_t *thread) { + + if (thread->thread_prev != NULL) { + thread->thread_prev->thread_next = thread->thread_next; + if (thread->thread_next != NULL) { + thread->thread_next->thread_prev = thread->thread_prev; + } + thread->thread_prev = NULL; + } +} + +/// Unlink a Thread from specified linked list. +/// \param[in] thread thread object. +void osRtxThreadListUnlink (os_thread_t **thread_list, os_thread_t *thread) { + + if (thread->thread_next != NULL) { + thread->thread_next->thread_prev = thread->thread_prev; + } + if (thread->thread_prev != NULL) { + thread->thread_prev->thread_next = thread->thread_next; + thread->thread_prev = NULL; + } else { + *thread_list = thread->thread_next; + } +} + +/// Mark a Thread as Ready and put it into Ready list (sorted by Priority). +/// \param[in] thread thread object. +void osRtxThreadReadyPut (os_thread_t *thread) { + + thread->state = osRtxThreadReady; + osRtxThreadListPut(&osRtxInfo.thread.ready, thread); +} + +/// Insert a Thread into the Delay list sorted by Delay (Lowest at Head). +/// \param[in] thread thread object. +/// \param[in] delay delay value. +void osRtxThreadDelayInsert (os_thread_t *thread, uint32_t delay) { + os_thread_t *prev, *next; + + if (delay == osWaitForever) { + prev = NULL; + next = osRtxInfo.thread.wait_list; + while (next != NULL) { + prev = next; + next = next->delay_next; + } + thread->delay = delay; + thread->delay_prev = prev; + thread->delay_next = next; + if (prev != NULL) { + prev->delay_next = thread; + } else { + osRtxInfo.thread.wait_list = thread; + } + if (next != NULL) { + next->delay_prev = thread; + } + } else { + prev = NULL; + next = osRtxInfo.thread.delay_list; + while ((next != NULL) && (next->delay <= delay)) { + delay -= next->delay; + prev = next; + next = next->delay_next; + } + thread->delay = delay; + thread->delay_prev = prev; + thread->delay_next = next; + if (prev != NULL) { + prev->delay_next = thread; + } else { + osRtxInfo.thread.delay_list = thread; + } + if (next != NULL) { + next->delay -= delay; + next->delay_prev = thread; + } + } +} + +/// Remove a Thread from the Delay list. +/// \param[in] thread thread object. +void osRtxThreadDelayRemove (os_thread_t *thread) { + + if (thread->delay == osWaitForever) { + if ((thread->delay_prev == NULL) && (osRtxInfo.thread.wait_list != thread)) { + return; + } + if (thread->delay_next != NULL) { + thread->delay_next->delay_prev = thread->delay_prev; + } + if (thread->delay_prev != NULL) { + thread->delay_prev->delay_next = thread->delay_next; + thread->delay_prev = NULL; + } else { + osRtxInfo.thread.wait_list = thread->delay_next; + } + } else { + if ((thread->delay_prev == NULL) && (osRtxInfo.thread.delay_list != thread)) { + return; + } + if (thread->delay_next != NULL) { + thread->delay_next->delay += thread->delay; + thread->delay_next->delay_prev = thread->delay_prev; + } + if (thread->delay_prev != NULL) { + thread->delay_prev->delay_next = thread->delay_next; + thread->delay_prev = NULL; + } else { + osRtxInfo.thread.delay_list = thread->delay_next; + } + } +} + +/// Process Thread Delay Tick (executed each System Tick). +void osRtxThreadDelayTick (void) { + os_thread_t *thread; + + thread = osRtxInfo.thread.delay_list; + if (thread == NULL) { + return; + } + + thread->delay--; + + if (thread->delay == 0U) { + do { + switch (thread->state) { + case osRtxThreadWaitingDelay: + EvrRtxThreadDelayCompleted(); + break; + case osRtxThreadWaitingThreadFlags: + EvrRtxThreadFlagsWaitTimeout(); + break; + case osRtxThreadWaitingEventFlags: + EvrRtxEventFlagsWaitTimeout((osEventFlagsId_t)osRtxThreadListRoot(thread)); + break; + case osRtxThreadWaitingMutex: + EvrRtxMutexAcquireTimeout((osMutexId_t)osRtxThreadListRoot(thread)); + break; + case osRtxThreadWaitingSemaphore: + EvrRtxSemaphoreAcquireTimeout((osSemaphoreId_t)osRtxThreadListRoot(thread)); + break; + case osRtxThreadWaitingMemoryPool: + EvrRtxMemoryPoolAllocTimeout((osMemoryPoolId_t)osRtxThreadListRoot(thread)); + break; + case osRtxThreadWaitingMessageGet: + EvrRtxMessageQueueGetTimeout((osMessageQueueId_t)osRtxThreadListRoot(thread)); + break; + case osRtxThreadWaitingMessagePut: + EvrRtxMessageQueuePutTimeout((osMessageQueueId_t)osRtxThreadListRoot(thread)); + break; + default: + break; + } + EvrRtxThreadUnblocked(thread, (osRtxThreadRegPtr(thread))[0]); + osRtxThreadListRemove(thread); + osRtxThreadReadyPut(thread); + thread = thread->delay_next; + } while ((thread != NULL) && (thread->delay == 0U)); + if (thread != NULL) { + thread->delay_prev = NULL; + } + osRtxInfo.thread.delay_list = thread; + } +} + +/// Get pointer to Thread registers (R0..R3) +/// \param[in] thread thread object. +/// \return pointer to registers R0-R3. +uint32_t *osRtxThreadRegPtr (os_thread_t *thread) { + +#if (__FPU_USED == 1U) + if (IS_EXTENDED_STACK_FRAME(thread->stack_frame)) { + // Extended Stack Frame: S16-S31, R4-R11, R0-R3, R12, LR, PC, xPSR, S0-S15, FPSCR + return ((uint32_t *)(thread->sp + (16U+8U)*4U)); + } else { + // Basic Stack Frame: R4-R11, R0-R3, R12, LR, PC, xPSR + return ((uint32_t *)(thread->sp + 8U *4U)); + } +#else + // Stack Frame: R4-R11, R0-R3, R12, LR, PC, xPSR + return ((uint32_t *)(thread->sp + 8U*4U)); +#endif +} + +/// Block running Thread execution and register it as Ready to Run. +/// \param[in] thread running thread object. +void osRtxThreadBlock (os_thread_t *thread) { + os_thread_t *prev, *next; + int32_t priority; + + thread->state = osRtxThreadReady; + + priority = thread->priority; + + prev = (os_thread_t *)(uint32_t)&osRtxInfo.thread.ready; + next = prev->thread_next; + + while ((next != NULL) && (next->priority > priority)) { + prev = next; + next = next->thread_next; + } + thread->thread_prev = prev; + thread->thread_next = next; + prev->thread_next = thread; + if (next != NULL) { + next->thread_prev = thread; + } +} + +/// Switch to specified Thread. +/// \param[in] thread thread object. +void osRtxThreadSwitch (os_thread_t *thread) { + + thread->state = osRtxThreadRunning; + osRtxInfo.thread.run.next = thread; + osRtxThreadStackCheck(); + EvrRtxThreadSwitch(thread); +} + +/// Dispatch specified Thread or Ready Thread with Highest Priority. +/// \param[in] thread thread object or NULL. +void osRtxThreadDispatch (os_thread_t *thread) { + uint8_t kernel_state; + os_thread_t *thread_running; + + kernel_state = osRtxKernelGetState(); + thread_running = osRtxThreadGetRunning(); + + if (thread == NULL) { + thread = osRtxInfo.thread.ready.thread_list; + if ((kernel_state == osRtxKernelRunning) && + (thread_running != NULL) && (thread != NULL) && + (thread->priority > thread_running->priority)) { + // Preempt running Thread + osRtxThreadListRemove(thread); + osRtxThreadBlock(thread_running); + osRtxThreadSwitch(thread); + } + } else { + if ((kernel_state == osRtxKernelRunning) && + (thread_running != NULL) && + (thread->priority > thread_running->priority)) { + // Preempt running Thread + osRtxThreadBlock(thread_running); + osRtxThreadSwitch(thread); + } else { + // Put Thread into Ready list + osRtxThreadReadyPut(thread); + } + } +} + +/// Exit Thread wait state. +/// \param[in] thread thread object. +/// \param[in] ret_val return value. +/// \param[in] dispatch dispatch flag. +void osRtxThreadWaitExit (os_thread_t *thread, uint32_t ret_val, bool dispatch) { + uint32_t *reg; + + EvrRtxThreadUnblocked(thread, ret_val); + + reg = osRtxThreadRegPtr(thread); + reg[0] = ret_val; + + osRtxThreadDelayRemove(thread); + if (dispatch) { + osRtxThreadDispatch(thread); + } else { + osRtxThreadReadyPut(thread); + } +} + +/// Enter Thread wait state. +/// \param[in] state new thread state. +/// \param[in] timeout timeout. +/// \return true - success, false - failure. +bool osRtxThreadWaitEnter (uint8_t state, uint32_t timeout) { + os_thread_t *thread; + + thread = osRtxThreadGetRunning(); + if (thread == NULL) { + return false; + } + + if (osRtxKernelGetState() != osRtxKernelRunning) { + osRtxThreadListRemove(thread); + return false; + } + + if (osRtxInfo.thread.ready.thread_list == NULL) { + return false; + } + + EvrRtxThreadBlocked(thread, timeout); + + thread->state = state; + osRtxThreadDelayInsert(thread, timeout); + thread = osRtxThreadListGet(&osRtxInfo.thread.ready); + osRtxThreadSwitch(thread); + + return true; +} + +/// Check current running Thread Stack. +__WEAK void osRtxThreadStackCheck (void) { + os_thread_t *thread; + + thread = osRtxThreadGetRunning(); + if (thread != NULL) { + if ((thread->sp <= (uint32_t)thread->stack_mem) || + (*((uint32_t *)thread->stack_mem) != osRtxStackMagicWord)) { + osRtxErrorNotify(osRtxErrorStackUnderflow, thread); + } + } +} + +/// Thread post ISR processing. +/// \param[in] thread thread object. +void osRtxThreadPostProcess (os_thread_t *thread) { + uint32_t thread_flags; + + if ((thread->state == osRtxThreadInactive) || + (thread->state == osRtxThreadTerminated)) { + return; + } + + // Check if Thread is waiting for Thread Flags + if (thread->state == osRtxThreadWaitingThreadFlags) { + thread_flags = ThreadFlagsCheck(thread, thread->wait_flags, thread->flags_options); + if (thread_flags != 0U) { + osRtxThreadWaitExit(thread, thread_flags, false); + EvrRtxThreadFlagsWaitCompleted(thread->wait_flags, thread->flags_options, thread_flags); + } + } +} + + +// ==== Service Calls ==== + +// Service Calls definitions +SVC0_3M(ThreadNew, osThreadId_t, osThreadFunc_t, void *, const osThreadAttr_t *) +SVC0_1 (ThreadGetName, const char *, osThreadId_t) +SVC0_0 (ThreadGetId, osThreadId_t) +SVC0_1 (ThreadGetState, osThreadState_t, osThreadId_t) +SVC0_1 (ThreadGetStackSize, uint32_t, osThreadId_t) +SVC0_1 (ThreadGetStackSpace, uint32_t, osThreadId_t) +SVC0_2 (ThreadSetPriority, osStatus_t, osThreadId_t, osPriority_t) +SVC0_1 (ThreadGetPriority, osPriority_t, osThreadId_t) +SVC0_0 (ThreadYield, osStatus_t) +SVC0_1 (ThreadSuspend, osStatus_t, osThreadId_t) +SVC0_1 (ThreadResume, osStatus_t, osThreadId_t) +SVC0_1 (ThreadDetach, osStatus_t, osThreadId_t) +SVC0_1 (ThreadJoin, osStatus_t, osThreadId_t) +SVC0_0N(ThreadExit, void) +SVC0_1 (ThreadTerminate, osStatus_t, osThreadId_t) +SVC0_0 (ThreadGetCount, uint32_t) +SVC0_2 (ThreadEnumerate, uint32_t, osThreadId_t *, uint32_t) +SVC0_2 (ThreadFlagsSet, uint32_t, osThreadId_t, uint32_t) +SVC0_1 (ThreadFlagsClear, uint32_t, uint32_t) +SVC0_0 (ThreadFlagsGet, uint32_t) +SVC0_3 (ThreadFlagsWait, uint32_t, uint32_t, uint32_t, uint32_t) + +/// Create a thread and add it to Active Threads. +/// \note API identical to osThreadNew +osThreadId_t svcRtxThreadNew (osThreadFunc_t func, void *argument, const osThreadAttr_t *attr) { + os_thread_t *thread; + uint32_t attr_bits; + void *stack_mem; + uint32_t stack_size; + osPriority_t priority; + uint8_t flags; + const char *name; + uint32_t *ptr; + uint32_t n; +#if (__DOMAIN_NS == 1U) + TZ_ModuleId_t tz_module; + TZ_MemoryId_t tz_memory; +#endif + + // Check parameters + if (func == NULL) { + EvrRtxThreadError(NULL, osErrorParameter); + return NULL; + } + + // Process attributes + if (attr != NULL) { + name = attr->name; + attr_bits = attr->attr_bits; + thread = attr->cb_mem; + stack_mem = attr->stack_mem; + stack_size = attr->stack_size; + priority = attr->priority; +#if (__DOMAIN_NS == 1U) + tz_module = attr->tz_module; +#endif + if (thread != NULL) { + if (((uint32_t)thread & 3U) || (attr->cb_size < sizeof(os_thread_t))) { + EvrRtxThreadError(NULL, osRtxErrorInvalidControlBlock); + return NULL; + } + } else { + if (attr->cb_size != 0U) { + EvrRtxThreadError(NULL, osRtxErrorInvalidControlBlock); + return NULL; + } + } + if (stack_mem != NULL) { + if (((uint32_t)stack_mem & 7U) || (stack_size == 0U)) { + EvrRtxThreadError(NULL, osRtxErrorInvalidThreadStack); + return NULL; + } + } + if (priority == osPriorityNone) { + priority = osPriorityNormal; + } else { + if ((priority < osPriorityIdle) || (priority > osPriorityISR)) { + EvrRtxThreadError(NULL, osRtxErrorInvalidPriority); + return NULL; + } + } + } else { + name = NULL; + attr_bits = 0U; + thread = NULL; + stack_mem = NULL; + stack_size = 0U; + priority = osPriorityNormal; +#if (__DOMAIN_NS == 1U) + tz_module = 0U; +#endif + } + + // Check stack size + if ((stack_size != 0U) && ((stack_size & 7U) || (stack_size < (64U + 8U)))) { + EvrRtxThreadError(NULL, osRtxErrorInvalidThreadStack); + return NULL; + } + + // Allocate object memory if not provided + if (thread == NULL) { + if (osRtxInfo.mpi.thread != NULL) { + thread = osRtxMemoryPoolAlloc(osRtxInfo.mpi.thread); + } else { + thread = osRtxMemoryAlloc(osRtxInfo.mem.common, sizeof(os_thread_t), 1U); + } + if (thread == NULL) { + EvrRtxThreadError(NULL, osErrorNoMemory); + return NULL; + } + flags = osRtxFlagSystemObject; + } else { + flags = 0U; + } + + // Allocate stack memory if not provided + if (stack_mem == NULL) { + if (stack_size == 0U) { + stack_size = osRtxConfig.thread_stack_size; + if (osRtxInfo.mpi.stack != NULL) { + stack_mem = osRtxMemoryPoolAlloc(osRtxInfo.mpi.stack); + if (stack_mem != NULL) { + flags |= osRtxThreadFlagDefStack; + } + } else { + stack_mem = osRtxMemoryAlloc(osRtxInfo.mem.stack, stack_size, 0U); + } + } else { + stack_mem = osRtxMemoryAlloc(osRtxInfo.mem.stack, stack_size, 0U); + } + if (stack_mem == NULL) { + EvrRtxThreadError(NULL, osErrorNoMemory); + if (flags & osRtxFlagSystemObject) { + if (osRtxInfo.mpi.thread != NULL) { + osRtxMemoryPoolFree(osRtxInfo.mpi.thread, thread); + } else { + osRtxMemoryFree(osRtxInfo.mem.common, thread); + } + } + return NULL; + } + flags |= osRtxFlagSystemMemory; + } + +#if (__DOMAIN_NS == 1U) + // Allocate secure process stack + if (tz_module != 0U) { + tz_memory = TZ_AllocModuleContext_S(tz_module); + if (tz_memory == 0U) { + EvrRtxThreadError(NULL, osRtxErrorTZ_AllocContext_S); + if (flags & osRtxFlagSystemMemory) { + if (flags & osRtxThreadFlagDefStack) { + osRtxMemoryPoolFree(osRtxInfo.mpi.stack, thread->stack_mem); + } else { + osRtxMemoryFree(osRtxInfo.mem.stack, thread->stack_mem); + } + } + if (flags & osRtxFlagSystemObject) { + if (osRtxInfo.mpi.thread != NULL) { + osRtxMemoryPoolFree(osRtxInfo.mpi.thread, thread); + } else { + osRtxMemoryFree(osRtxInfo.mem.common, thread); + } + } + return NULL; + } + } else { + tz_memory = 0U; + } +#endif + + // Initialize control block + thread->id = osRtxIdThread; + thread->state = osRtxThreadReady; + thread->flags = flags; + thread->attr = (uint8_t)attr_bits; + thread->name = name; + thread->thread_next = NULL; + thread->thread_prev = NULL; + thread->delay_next = NULL; + thread->delay_prev = NULL; + thread->thread_join = NULL; + thread->delay = 0U; + thread->priority = (int8_t)priority; + thread->priority_base = (int8_t)priority; + thread->stack_frame = STACK_FRAME_INIT; + thread->flags_options = 0U; + thread->wait_flags = 0U; + thread->thread_flags = 0U; + thread->mutex_list = NULL; + thread->stack_mem = stack_mem; + thread->stack_size = stack_size; + thread->sp = (uint32_t)stack_mem + stack_size - 64U; + thread->thread_addr = (uint32_t)func; +#if (__DOMAIN_NS == 1U) + thread->tz_memory = tz_memory; +#endif + + // Initialize stack + ptr = (uint32_t *)stack_mem; + *ptr++ = osRtxStackMagicWord; + if (osRtxConfig.flags & osRtxConfigStackWatermark) { + for (n = (stack_size/4U) - (16U + 1U); n; n--) { + *ptr++ = osRtxStackFillPattern; + } + } else { + ptr = (uint32_t *)thread->sp; + } + for (n = 13U; n; n--) { + *ptr++ = 0U; // R4..R11, R0..R3, R12 + } + *ptr++ = (uint32_t)osThreadExit; // LR + *ptr++ = (uint32_t)func; // PC + *ptr++ = XPSR_INITIAL_VALUE; // xPSR + *(ptr-8) = (uint32_t)argument; // R0 + + // Register post ISR processing function + osRtxInfo.post_process.thread = osRtxThreadPostProcess; + + EvrRtxThreadCreated(thread); + + osRtxThreadDispatch(thread); + + return thread; +} + +/// Get name of a thread. +/// \note API identical to osThreadGetName +const char *svcRtxThreadGetName (osThreadId_t thread_id) { + os_thread_t *thread = (os_thread_t *)thread_id; + + // Check parameters + if ((thread == NULL) || (thread->id != osRtxIdThread)) { + EvrRtxThreadGetName(thread, NULL); + return NULL; + } + + // Check object state + if (thread->state == osRtxObjectInactive) { + EvrRtxThreadGetName(thread, NULL); + return NULL; + } + + EvrRtxThreadGetName(thread, thread->name); + + return thread->name; +} + +/// Return the thread ID of the current running thread. +/// \note API identical to osThreadGetId +osThreadId_t svcRtxThreadGetId (void) { + os_thread_t *thread; + + thread = osRtxThreadGetRunning(); + EvrRtxThreadGetId(thread); + return thread; +} + +/// Get current thread state of a thread. +/// \note API identical to osThreadGetState +osThreadState_t svcRtxThreadGetState (osThreadId_t thread_id) { + os_thread_t *thread = (os_thread_t *)thread_id; + + // Check parameters + if ((thread == NULL) || (thread->id != osRtxIdThread)) { + EvrRtxThreadGetState(thread, osThreadError); + return osThreadError; + } + + EvrRtxThreadGetState(thread, (osThreadState_t)(thread->state & osRtxThreadStateMask)); + + return ((osThreadState_t)(thread->state & osRtxThreadStateMask)); +} + +/// Get stack size of a thread. +/// \note API identical to osThreadGetStackSize +uint32_t svcRtxThreadGetStackSize (osThreadId_t thread_id) { + os_thread_t *thread = (os_thread_t *)thread_id; + + // Check parameters + if ((thread == NULL) || (thread->id != osRtxIdThread)) { + EvrRtxThreadGetStackSize(thread, 0U); + return 0U; + } + + // Check object state + if (thread->state == osRtxObjectInactive) { + EvrRtxThreadGetStackSize(thread, 0U); + return 0U; + } + + EvrRtxThreadGetStackSize(thread, thread->stack_size); + + return thread->stack_size; +} + +/// Get available stack space of a thread based on stack watermark recording during execution. +/// \note API identical to osThreadGetStackSpace +uint32_t svcRtxThreadGetStackSpace (osThreadId_t thread_id) { + os_thread_t *thread = (os_thread_t *)thread_id; + uint32_t *stack; + uint32_t space; + + // Check parameters + if ((thread == NULL) || (thread->id != osRtxIdThread)) { + EvrRtxThreadGetStackSpace(thread, 0U); + return 0U; + } + + // Check object state + if (thread->state == osRtxObjectInactive) { + EvrRtxThreadGetStackSpace(thread, 0U); + return 0U; + } + + if ((osRtxConfig.flags & osRtxConfigStackWatermark) == 0U) { + EvrRtxThreadGetStackSpace(thread, 0U); + return 0U; + } + + stack = thread->stack_mem; + if (*stack++ != osRtxStackMagicWord) { + EvrRtxThreadGetStackSpace(thread, 0U); + return 0U; + } + for (space = 4U; space < thread->stack_size; space += 4U) { + if (*stack++ != osRtxStackFillPattern) { + break; + } + } + + EvrRtxThreadGetStackSpace(thread, space); + + return space; +} + +/// Change priority of a thread. +/// \note API identical to osThreadSetPriority +osStatus_t svcRtxThreadSetPriority (osThreadId_t thread_id, osPriority_t priority) { + os_thread_t *thread = (os_thread_t *)thread_id; + + // Check parameters + if ((thread == NULL) || (thread->id != osRtxIdThread) || + (priority < osPriorityIdle) || (priority > osPriorityISR)) { + EvrRtxThreadError(thread, osErrorParameter); + return osErrorParameter; + } + + // Check object state + if ((thread->state == osRtxThreadInactive) || + (thread->state == osRtxThreadTerminated)) { + EvrRtxThreadError(thread, osErrorResource); + return osErrorResource; + } + + if (thread->priority != (int8_t)priority) { + thread->priority = (int8_t)priority; + thread->priority_base = (int8_t)priority; + osRtxThreadListSort(thread); + osRtxThreadDispatch(NULL); + } + + return osOK; +} + +/// Get current priority of a thread. +/// \note API identical to osThreadGetPriority +osPriority_t svcRtxThreadGetPriority (osThreadId_t thread_id) { + os_thread_t *thread = (os_thread_t *)thread_id; + + // Check parameters + if ((thread == NULL) || (thread->id != osRtxIdThread)) { + EvrRtxThreadGetPriority(thread, osPriorityError); + return osPriorityError; + } + + // Check object state + if ((thread->state == osRtxThreadInactive) || + (thread->state == osRtxThreadTerminated)) { + EvrRtxThreadGetPriority(thread, osPriorityError); + return osPriorityError; + } + + EvrRtxThreadGetPriority(thread, (osPriority_t)thread->priority); + + return ((osPriority_t)thread->priority); +} + +/// Pass control to next thread that is in state READY. +/// \note API identical to osThreadYield +osStatus_t svcRtxThreadYield (void) { + uint8_t kernel_state; + os_thread_t *thread_running; + os_thread_t *thread_ready; + + kernel_state = osRtxKernelGetState(); + thread_running = osRtxThreadGetRunning(); + thread_ready = osRtxInfo.thread.ready.thread_list; + if ((kernel_state == osRtxKernelRunning) && + (thread_ready != NULL) && (thread_running != NULL) && + (thread_ready->priority == thread_running->priority)) { + osRtxThreadListRemove(thread_ready); + osRtxThreadReadyPut(thread_running); + osRtxThreadSwitch(thread_ready); + } + + return osOK; +} + +/// Suspend execution of a thread. +/// \note API identical to osThreadSuspend +osStatus_t svcRtxThreadSuspend (osThreadId_t thread_id) { + os_thread_t *thread = (os_thread_t *)thread_id; + + // Check parameters + if ((thread == NULL) || (thread->id != osRtxIdThread)) { + EvrRtxThreadError(thread, osErrorParameter); + return osErrorParameter; + } + + // Check object state + switch (thread->state & osRtxThreadStateMask) { + case osRtxThreadRunning: + if ((osRtxKernelGetState() != osRtxKernelRunning) || + (osRtxInfo.thread.ready.thread_list == NULL)) { + EvrRtxThreadError(thread, osErrorResource); + return osErrorResource; + } + break; + case osRtxThreadReady: + osRtxThreadListRemove(thread); + break; + case osRtxThreadBlocked: + osRtxThreadListRemove(thread); + osRtxThreadDelayRemove(thread); + break; + case osRtxThreadInactive: + case osRtxThreadTerminated: + default: + EvrRtxThreadError(thread, osErrorResource); + return osErrorResource; + } + + EvrRtxThreadSuspended(thread); + + if (thread->state == osRtxThreadRunning) { + osRtxThreadSwitch(osRtxThreadListGet(&osRtxInfo.thread.ready)); + } + + // Update Thread State and put it into Delay list + thread->state = osRtxThreadBlocked; + thread->thread_prev = NULL; + thread->thread_next = NULL; + osRtxThreadDelayInsert(thread, osWaitForever); + + return osOK; +} + +/// Resume execution of a thread. +/// \note API identical to osThreadResume +osStatus_t svcRtxThreadResume (osThreadId_t thread_id) { + os_thread_t *thread = (os_thread_t *)thread_id; + + // Check parameters + if ((thread == NULL) || (thread->id != osRtxIdThread)) { + EvrRtxThreadError(thread, osErrorParameter); + return osErrorParameter; + } + + // Check object state + if ((thread->state & osRtxThreadStateMask) != osRtxThreadBlocked) { + EvrRtxThreadError(thread, osErrorResource); + return osErrorResource; + } + + EvrRtxThreadResumed(thread); + + // Wakeup Thread + osRtxThreadListRemove(thread); + osRtxThreadDelayRemove(thread); + osRtxThreadDispatch(thread); + + return osOK; +} + +/// Free Thread resources. +/// \param[in] thread thread object. +static void osRtxThreadFree (os_thread_t *thread) { + + // Mark object as inactive + thread->state = osRtxThreadInactive; + +#if (__DOMAIN_NS == 1U) + // Free secure process stack + if (thread->tz_memory != 0U) { + TZ_FreeModuleContext_S(thread->tz_memory); + } +#endif + + // Free stack memory + if (thread->flags & osRtxFlagSystemMemory) { + if (thread->flags & osRtxThreadFlagDefStack) { + osRtxMemoryPoolFree(osRtxInfo.mpi.stack, thread->stack_mem); + } else { + osRtxMemoryFree(osRtxInfo.mem.stack, thread->stack_mem); + } + } + + // Free object memory + if (thread->flags & osRtxFlagSystemObject) { + if (osRtxInfo.mpi.thread != NULL) { + osRtxMemoryPoolFree(osRtxInfo.mpi.thread, thread); + } else { + osRtxMemoryFree(osRtxInfo.mem.common, thread); + } + } +} + +/// Detach a thread (thread storage can be reclaimed when thread terminates). +/// \note API identical to osThreadDetach +osStatus_t svcRtxThreadDetach (osThreadId_t thread_id) { + os_thread_t *thread = (os_thread_t *)thread_id; + + // Check parameters + if ((thread == NULL) || (thread->id != osRtxIdThread)) { + EvrRtxThreadError(thread, osErrorParameter); + return osErrorParameter; + } + + // Check object attributes + if ((thread->attr & osThreadJoinable) == 0U) { + EvrRtxThreadError(thread, osRtxErrorThreadNotJoinable); + return osErrorResource; + } + + // Check object state + if (thread->state == osRtxThreadInactive) { + EvrRtxThreadError(thread, osErrorResource); + return osErrorResource; + } + + if (thread->state == osRtxThreadTerminated) { + osRtxThreadListUnlink(&osRtxInfo.thread.terminate_list, thread); + osRtxThreadFree(thread); + } else { + thread->attr &= ~osThreadJoinable; + } + + EvrRtxThreadDetached(thread); + + return osOK; +} + +/// Wait for specified thread to terminate. +/// \note API identical to osThreadJoin +osStatus_t svcRtxThreadJoin (osThreadId_t thread_id) { + os_thread_t *thread = (os_thread_t *)thread_id; + + // Check parameters + if ((thread == NULL) || (thread->id != osRtxIdThread)) { + EvrRtxThreadError(thread, osErrorParameter); + return osErrorParameter; + } + + // Check object attributes + if ((thread->attr & osThreadJoinable) == 0U) { + EvrRtxThreadError(thread, osRtxErrorThreadNotJoinable); + return osErrorResource; + } + + // Check object state + if ((thread->state == osRtxThreadInactive) || + (thread->state == osRtxThreadRunning)) { + EvrRtxThreadError(thread, osErrorResource); + return osErrorResource; + } + + if (thread->state == osRtxThreadTerminated) { + osRtxThreadListUnlink(&osRtxInfo.thread.terminate_list, thread); + osRtxThreadFree(thread); + } else { + EvrRtxThreadJoinPending(thread); + // Suspend current Thread + if (osRtxThreadWaitEnter(osRtxThreadWaitingJoin, osWaitForever)) { + thread->thread_join = osRtxThreadGetRunning(); + } + return osErrorResource; + } + + EvrRtxThreadJoined(thread); + + return osOK; +} + +/// Terminate execution of current running thread. +/// \note API identical to osThreadExit +void svcRtxThreadExit (void) { + os_thread_t *thread; + + thread = osRtxThreadGetRunning(); + if (thread == NULL) { + return; + } + + // Release owned Mutexes + osRtxMutexOwnerRelease(thread->mutex_list); + + // Wakeup Thread waiting to Join + if (thread->thread_join != NULL) { + osRtxThreadWaitExit(thread->thread_join, (uint32_t)osOK, false); + EvrRtxThreadJoined(thread->thread_join); + } + + // Switch to next Ready Thread + if ((osRtxKernelGetState() != osRtxKernelRunning) || + (osRtxInfo.thread.ready.thread_list == NULL)) { + return; + } + thread->sp = __get_PSP(); + osRtxThreadSwitch(osRtxThreadListGet(&osRtxInfo.thread.ready)); + osRtxThreadSetRunning(NULL); + + if (((thread->attr & osThreadJoinable) == 0U) || (thread->thread_join != NULL)) { + osRtxThreadFree(thread); + } else { + // Update Thread State and put it into Terminate Thread list + thread->state = osRtxThreadTerminated; + thread->thread_prev = NULL; + thread->thread_next = osRtxInfo.thread.terminate_list; + if (osRtxInfo.thread.terminate_list != NULL) { + osRtxInfo.thread.terminate_list->thread_prev = thread; + } + osRtxInfo.thread.terminate_list = thread; + } + + EvrRtxThreadDestroyed(thread); +} + +/// Terminate execution of a thread. +/// \note API identical to osThreadTerminate +osStatus_t svcRtxThreadTerminate (osThreadId_t thread_id) { + os_thread_t *thread = (os_thread_t *)thread_id; + + // Check parameters + if ((thread == NULL) || (thread->id != osRtxIdThread)) { + EvrRtxThreadError(thread, osErrorParameter); + return osErrorParameter; + } + + // Check object state + switch (thread->state & osRtxThreadStateMask) { + case osRtxThreadRunning: + break; + case osRtxThreadReady: + osRtxThreadListRemove(thread); + break; + case osRtxThreadBlocked: + osRtxThreadListRemove(thread); + osRtxThreadDelayRemove(thread); + break; + case osRtxThreadInactive: + case osRtxThreadTerminated: + default: + EvrRtxThreadError(thread, osErrorResource); + return osErrorResource; + } + + // Release owned Mutexes + osRtxMutexOwnerRelease(thread->mutex_list); + + // Wakeup Thread waiting to Join + if (thread->thread_join != NULL) { + osRtxThreadWaitExit(thread->thread_join, (uint32_t)osOK, false); + EvrRtxThreadJoined(thread->thread_join); + } + + // Switch to next Ready Thread when terminating running Thread + if (thread->state == osRtxThreadRunning) { + if ((osRtxKernelGetState() != osRtxKernelRunning) || + (osRtxInfo.thread.ready.thread_list == NULL)) { + EvrRtxThreadError(thread, osErrorResource); + return osErrorResource; + } + thread->sp = __get_PSP(); + osRtxThreadSwitch(osRtxThreadListGet(&osRtxInfo.thread.ready)); + osRtxThreadSetRunning(NULL); + } else { + osRtxThreadDispatch(NULL); + } + + if (((thread->attr & osThreadJoinable) == 0U) || (thread->thread_join != NULL)) { + osRtxThreadFree(thread); + } else { + // Update Thread State and put it into Terminate Thread list + thread->state = osRtxThreadTerminated; + thread->thread_prev = NULL; + thread->thread_next = osRtxInfo.thread.terminate_list; + if (osRtxInfo.thread.terminate_list != NULL) { + osRtxInfo.thread.terminate_list->thread_prev = thread; + } + osRtxInfo.thread.terminate_list = thread; + } + + EvrRtxThreadDestroyed(thread); + + return osOK; +} + +/// Get number of active threads. +/// \note API identical to osThreadGetCount +uint32_t svcRtxThreadGetCount (void) { + os_thread_t *thread; + uint32_t count; + + // Running Thread + count = 1U; + + // Ready List + for (thread = osRtxInfo.thread.ready.thread_list; + (thread != NULL); thread = thread->thread_next, count++) {}; + + // Delay List + for (thread = osRtxInfo.thread.delay_list; + (thread != NULL); thread = thread->delay_next, count++) {}; + + // Wait List + for (thread = osRtxInfo.thread.wait_list; + (thread != NULL); thread = thread->delay_next, count++) {}; + + EvrRtxThreadGetCount(count); + + return count; +} + +/// Enumerate active threads. +/// \note API identical to osThreadEnumerate +uint32_t svcRtxThreadEnumerate (osThreadId_t *thread_array, uint32_t array_items) { + os_thread_t *thread; + uint32_t count; + + // Check parameters + if ((thread_array == NULL) || (array_items == 0U)) { + EvrRtxThreadEnumerate(thread_array, array_items, 0U); + return 0U; + } + + // Running Thread + *thread_array++ = osRtxThreadGetRunning(); + count = 1U; + + // Ready List + for (thread = osRtxInfo.thread.ready.thread_list; + (thread != NULL) && (count < array_items); thread = thread->thread_next, count++) { + *thread_array++ = thread; + } + + // Delay List + for (thread = osRtxInfo.thread.delay_list; + (thread != NULL) && (count < array_items); thread = thread->delay_next, count++) { + *thread_array++ = thread; + } + + // Wait List + for (thread = osRtxInfo.thread.wait_list; + (thread != NULL) && (count < array_items); thread = thread->delay_next, count++) { + *thread_array++ = thread; + } + + EvrRtxThreadEnumerate(thread_array - count, array_items, count); + + return count; +} + +/// Set the specified Thread Flags of a thread. +/// \note API identical to osThreadFlagsSet +uint32_t svcRtxThreadFlagsSet (osThreadId_t thread_id, uint32_t flags) { + os_thread_t *thread = (os_thread_t *)thread_id; + uint32_t thread_flags; + uint32_t thread_flags0; + + // Check parameters + if ((thread == NULL) || (thread->id != osRtxIdThread) || + (flags & ~((1U << osRtxThreadFlagsLimit) - 1U))) { + EvrRtxThreadError(thread, osErrorParameter); + return ((uint32_t)osErrorParameter); + } + + // Check object state + if ((thread->state == osRtxThreadInactive) || + (thread->state == osRtxThreadTerminated)) { + EvrRtxThreadError(thread, osErrorResource); + return ((uint32_t)osErrorResource); + } + + // Set Thread Flags + thread_flags = ThreadFlagsSet(thread, flags); + + // Check if Thread is waiting for Thread Flags + if (thread->state == osRtxThreadWaitingThreadFlags) { + thread_flags0 = ThreadFlagsCheck(thread, thread->wait_flags, thread->flags_options); + if (thread_flags0 != 0U) { + if ((thread->flags_options & osFlagsNoClear) == 0U) { + thread_flags = thread_flags0 & ~thread->wait_flags; + } else { + thread_flags = thread_flags0; + } + osRtxThreadWaitExit(thread, thread_flags0, true); + EvrRtxThreadFlagsWaitCompleted(thread->wait_flags, thread->flags_options, thread_flags0); + } + } + + EvrRtxThreadFlagsSetDone(thread, thread_flags); + + return thread_flags; +} + +/// Clear the specified Thread Flags of current running thread. +/// \note API identical to osThreadFlagsClear +uint32_t svcRtxThreadFlagsClear (uint32_t flags) { + os_thread_t *thread; + uint32_t thread_flags; + + thread = osRtxThreadGetRunning(); + if (thread == NULL) { + EvrRtxThreadError(NULL, osRtxErrorKernelNotRunning); + return ((uint32_t)osError); + } + + // Check parameters + if (flags & ~((1U << osRtxThreadFlagsLimit) - 1U)) { + EvrRtxThreadError(thread, osErrorParameter); + return ((uint32_t)osErrorParameter); + } + + // Check object state + if ((thread->state == osRtxThreadInactive) || + (thread->state == osRtxThreadTerminated)) { + EvrRtxThreadError(thread, osErrorResource); + return ((uint32_t)osErrorResource); + } + + // Clear Thread Flags + thread_flags = ThreadFlagsClear(thread, flags); + + EvrRtxThreadFlagsClearDone(thread_flags); + + return thread_flags; +} + +/// Get the current Thread Flags of current running thread. +/// \note API identical to osThreadFlagsGet +uint32_t svcRtxThreadFlagsGet (void) { + os_thread_t *thread; + + thread = osRtxThreadGetRunning(); + if (thread == NULL) { + EvrRtxThreadFlagsGet(0U); + return 0U; + } + + // Check object state + if ((thread->state == osRtxThreadInactive) || + (thread->state == osRtxThreadTerminated)) { + EvrRtxThreadFlagsGet(0U); + return 0U; + } + + EvrRtxThreadFlagsGet(thread->thread_flags); + + return thread->thread_flags; +} + +/// Wait for one or more Thread Flags of the current running thread to become signaled. +/// \note API identical to osThreadFlagsWait +uint32_t svcRtxThreadFlagsWait (uint32_t flags, uint32_t options, uint32_t timeout) { + os_thread_t *thread; + uint32_t thread_flags; + + thread = osRtxThreadGetRunning(); + if (thread == NULL) { + EvrRtxThreadError(NULL, osRtxErrorKernelNotRunning); + return ((uint32_t)osError); + } + + // Check parameters + if (flags & ~((1U << osRtxThreadFlagsLimit) - 1U)) { + EvrRtxThreadError(thread, osErrorParameter); + return ((uint32_t)osErrorParameter); + } + + // Check Thread Flags + thread_flags = ThreadFlagsCheck(thread, flags, options); + if (thread_flags != 0U) { + EvrRtxThreadFlagsWaitCompleted(flags, options, thread_flags); + return thread_flags; + } + + // Check if timeout is specified + if (timeout != 0U) { + // Store waiting flags and options + EvrRtxThreadFlagsWaitPending(flags, options, timeout); + thread->wait_flags = flags; + thread->flags_options = (uint8_t)options; + // Suspend current Thread + osRtxThreadWaitEnter(osRtxThreadWaitingThreadFlags, timeout); + return ((uint32_t)osErrorTimeout); + } + + EvrRtxThreadFlagsWaitNotCompleted(flags, options); + + return ((uint32_t)osErrorResource); +} + + +// ==== ISR Calls ==== + +/// Set the specified Thread Flags of a thread. +/// \note API identical to osThreadFlagsSet +__STATIC_INLINE +uint32_t isrRtxThreadFlagsSet (osThreadId_t thread_id, uint32_t flags) { + os_thread_t *thread = (os_thread_t *)thread_id; + uint32_t thread_flags; + + // Check parameters + if ((thread == NULL) || (thread->id != osRtxIdThread) || + (flags & ~((1U << osRtxThreadFlagsLimit) - 1U))) { + EvrRtxThreadError(thread, osErrorParameter); + return ((uint32_t)osErrorParameter); + } + + // Check object state + if ((thread->state == osRtxThreadInactive) || + (thread->state == osRtxThreadTerminated)) { + EvrRtxThreadError(thread, osErrorResource); + return ((uint32_t)osErrorResource); + } + + // Set Thread Flags + thread_flags = ThreadFlagsSet(thread, flags); + + // Register post ISR processing + osRtxPostProcess((os_object_t *)thread); + + EvrRtxThreadFlagsSetDone(thread, thread_flags); + + return thread_flags; +} + + +// ==== Public API ==== + +/// Create a thread and add it to Active Threads. +osThreadId_t osThreadNew (osThreadFunc_t func, void *argument, const osThreadAttr_t *attr) { + EvrRtxThreadNew(func, argument, attr); + if (IS_IRQ_MODE() || IS_IRQ_MASKED()) { + EvrRtxThreadError(NULL, osErrorISR); + return NULL; + } + return __svcThreadNew(func, argument, attr); +} + +/// Get name of a thread. +const char *osThreadGetName (osThreadId_t thread_id) { + if (IS_IRQ_MODE() || IS_IRQ_MASKED()) { + EvrRtxThreadGetName(thread_id, NULL); + return NULL; + } + return __svcThreadGetName(thread_id); +} + +/// Return the thread ID of the current running thread. +osThreadId_t osThreadGetId (void) { + if (IS_IRQ_MODE() || IS_IRQ_MASKED()) { + EvrRtxThreadGetId(NULL); + return NULL; + } + return __svcThreadGetId(); +} + +/// Get current thread state of a thread. +osThreadState_t osThreadGetState (osThreadId_t thread_id) { + if (IS_IRQ_MODE() || IS_IRQ_MASKED()) { + EvrRtxThreadGetState(thread_id, osThreadError); + return osThreadError; + } + return __svcThreadGetState(thread_id); +} + +/// Get stack size of a thread. +uint32_t osThreadGetStackSize (osThreadId_t thread_id) { + if (IS_IRQ_MODE() || IS_IRQ_MASKED()) { + EvrRtxThreadGetStackSize(thread_id, 0U); + return 0U; + } + return __svcThreadGetStackSize(thread_id); +} + +/// Get available stack space of a thread based on stack watermark recording during execution. +uint32_t osThreadGetStackSpace (osThreadId_t thread_id) { + if (IS_IRQ_MODE() || IS_IRQ_MASKED()) { + EvrRtxThreadGetStackSpace(thread_id, 0U); + return 0U; + } + return __svcThreadGetStackSpace(thread_id); +} + +/// Change priority of a thread. +osStatus_t osThreadSetPriority (osThreadId_t thread_id, osPriority_t priority) { + EvrRtxThreadSetPriority(thread_id, priority); + if (IS_IRQ_MODE() || IS_IRQ_MASKED()) { + EvrRtxThreadError(thread_id, osErrorISR); + return osErrorISR; + } + return __svcThreadSetPriority(thread_id, priority); +} + +/// Get current priority of a thread. +osPriority_t osThreadGetPriority (osThreadId_t thread_id) { + if (IS_IRQ_MODE() || IS_IRQ_MASKED()) { + EvrRtxThreadGetPriority(thread_id, osPriorityError); + return osPriorityError; + } + return __svcThreadGetPriority(thread_id); +} + +/// Pass control to next thread that is in state READY. +osStatus_t osThreadYield (void) { + EvrRtxThreadYield(); + if (IS_IRQ_MODE() || IS_IRQ_MASKED()) { + EvrRtxThreadError(NULL, osErrorISR); + return osErrorISR; + } + return __svcThreadYield(); +} + +/// Suspend execution of a thread. +osStatus_t osThreadSuspend (osThreadId_t thread_id) { + EvrRtxThreadSuspend(thread_id); + if (IS_IRQ_MODE() || IS_IRQ_MASKED()) { + EvrRtxThreadError(thread_id, osErrorISR); + return osErrorISR; + } + return __svcThreadSuspend(thread_id); +} + +/// Resume execution of a thread. +osStatus_t osThreadResume (osThreadId_t thread_id) { + EvrRtxThreadResume(thread_id); + if (IS_IRQ_MODE() || IS_IRQ_MASKED()) { + EvrRtxThreadError(thread_id, osErrorISR); + return osErrorISR; + } + return __svcThreadResume(thread_id); +} + +/// Detach a thread (thread storage can be reclaimed when thread terminates). +osStatus_t osThreadDetach (osThreadId_t thread_id) { + EvrRtxThreadDetach(thread_id); + if (IS_IRQ_MODE() || IS_IRQ_MASKED()) { + EvrRtxThreadError(thread_id, osErrorISR); + return osErrorISR; + } + return __svcThreadDetach(thread_id); +} + +/// Wait for specified thread to terminate. +osStatus_t osThreadJoin (osThreadId_t thread_id) { + EvrRtxThreadJoin(thread_id); + if (IS_IRQ_MODE() || IS_IRQ_MASKED()) { + EvrRtxThreadError(thread_id, osErrorISR); + return osErrorISR; + } + return __svcThreadJoin(thread_id); +} + +/// Terminate execution of current running thread. +__NO_RETURN void osThreadExit (void) { + EvrRtxThreadExit(); + __svcThreadExit(); + EvrRtxThreadError(NULL, osError); + for (;;); +} + +/// Terminate execution of a thread. +osStatus_t osThreadTerminate (osThreadId_t thread_id) { + EvrRtxThreadTerminate(thread_id); + if (IS_IRQ_MODE() || IS_IRQ_MASKED()) { + EvrRtxThreadError(thread_id, osErrorISR); + return osErrorISR; + } + return __svcThreadTerminate(thread_id); +} + +/// Get number of active threads. +uint32_t osThreadGetCount (void) { + if (IS_IRQ_MODE() || IS_IRQ_MASKED()) { + EvrRtxThreadGetCount(0U); + return 0U; + } + return __svcThreadGetCount(); +} + +/// Enumerate active threads. +uint32_t osThreadEnumerate (osThreadId_t *thread_array, uint32_t array_items) { + if (IS_IRQ_MODE() || IS_IRQ_MASKED()) { + EvrRtxThreadEnumerate(thread_array, array_items, 0U); + return 0U; + } + return __svcThreadEnumerate(thread_array, array_items); +} + +/// Set the specified Thread Flags of a thread. +uint32_t osThreadFlagsSet (osThreadId_t thread_id, uint32_t flags) { + EvrRtxThreadFlagsSet(thread_id, flags); + if (IS_IRQ_MODE() || IS_IRQ_MASKED()) { + return isrRtxThreadFlagsSet(thread_id, flags); + } else { + return __svcThreadFlagsSet(thread_id, flags); + } +} + +/// Clear the specified Thread Flags of current running thread. +uint32_t osThreadFlagsClear (uint32_t flags) { + EvrRtxThreadFlagsClear(flags); + if (IS_IRQ_MODE() || IS_IRQ_MASKED()) { + EvrRtxThreadError(NULL, osErrorISR); + return ((uint32_t)osErrorISR); + } + return __svcThreadFlagsClear(flags); +} + +/// Get the current Thread Flags of current running thread. +uint32_t osThreadFlagsGet (void) { + if (IS_IRQ_MODE() || IS_IRQ_MASKED()) { + EvrRtxThreadFlagsGet(0U); + return 0U; + } + return __svcThreadFlagsGet(); +} + +/// Wait for one or more Thread Flags of the current running thread to become signaled. +uint32_t osThreadFlagsWait (uint32_t flags, uint32_t options, uint32_t timeout) { + EvrRtxThreadFlagsWait(flags, options, timeout); + if (IS_IRQ_MODE() || IS_IRQ_MASKED()) { + EvrRtxThreadError(NULL, osErrorISR); + return ((uint32_t)osErrorISR); + } + return __svcThreadFlagsWait(flags, options, timeout); +} diff --git a/rtos/rtx2/TARGET_CORTEX_M/rtx_timer.c b/rtos/rtx2/TARGET_CORTEX_M/rtx_timer.c new file mode 100644 index 00000000000..90bd795fa76 --- /dev/null +++ b/rtos/rtx2/TARGET_CORTEX_M/rtx_timer.c @@ -0,0 +1,415 @@ +/* + * Copyright (c) 2013-2017 ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ----------------------------------------------------------------------------- + * + * Project: CMSIS-RTOS RTX + * Title: Timer functions + * + * ----------------------------------------------------------------------------- + */ + +#include "rtx_lib.h" + + +// ==== Helper functions ==== + +/// Insert Timer into the Timer List sorted by Time. +/// \param[in] timer timer object. +/// \param[in] tick timer tick. +static void TimerInsert (os_timer_t *timer, uint32_t tick) { + os_timer_t *prev, *next; + + prev = NULL; + next = osRtxInfo.timer.list; + while ((next != NULL) && (next->tick <= tick)) { + tick -= next->tick; + prev = next; + next = next->next; + } + timer->tick = tick; + timer->prev = prev; + timer->next = next; + if (next != NULL) { + next->tick -= timer->tick; + next->prev = timer; + } + if (prev != NULL) { + prev->next = timer; + } else { + osRtxInfo.timer.list = timer; + } +} + +/// Remove Timer from the Timer List. +/// \param[in] timer timer object. +static void TimerRemove (os_timer_t *timer) { + + if (timer->next != NULL) { + timer->next->tick += timer->tick; + timer->next->prev = timer->prev; + } + if (timer->prev != NULL) { + timer->prev->next = timer->next; + } else { + osRtxInfo.timer.list = timer->next; + } +} + +/// Unlink Timer from the Timer List Head. +/// \param[in] timer timer object. +static void TimerUnlink (os_timer_t *timer) { + + if (timer->next != NULL) { + timer->next->prev = timer->prev; + } + osRtxInfo.timer.list = timer->next; +} + + +// ==== Library functions ==== + +/// Timer Tick (called each SysTick). +void osRtxTimerTick (void) { + os_timer_t *timer; + osStatus_t status; + + timer = osRtxInfo.timer.list; + if (timer == NULL) { + return; + } + + timer->tick--; + while ((timer != NULL) && (timer->tick == 0U)) { + TimerUnlink(timer); + status = osMessageQueuePut(osRtxInfo.timer.mq, &timer->finfo, 0U, 0U); + if (status != osOK) { + osRtxErrorNotify(osRtxErrorTimerQueueOverflow, timer); + } + if (timer->type == osRtxTimerPeriodic) { + TimerInsert(timer, timer->load); + } else { + timer->state = osRtxTimerStopped; + } + timer = osRtxInfo.timer.list; + } +} + +/// Timer Thread +__WEAK void osRtxTimerThread (void *argument) { + os_timer_finfo_t finfo; + osStatus_t status; + (void) argument; + + osRtxInfo.timer.mq = osMessageQueueNew(osRtxConfig.timer_mq_mcnt, sizeof(os_timer_finfo_t), osRtxConfig.timer_mq_attr); + if (osRtxInfo.timer.mq == NULL) { + return; + } + osRtxInfo.timer.tick = osRtxTimerTick; + for (;;) { + status = osMessageQueueGet(osRtxInfo.timer.mq, &finfo, NULL, osWaitForever); + if (status == osOK) { + EvrRtxTimerCallback(*(osTimerFunc_t)finfo.fp, finfo.arg); + (*(osTimerFunc_t)finfo.fp)(finfo.arg); + } + } +} + +// ==== Service Calls ==== + +// Service Calls definitions +SVC0_4M(TimerNew, osTimerId_t, osTimerFunc_t, osTimerType_t, void *, const osTimerAttr_t *) +SVC0_1 (TimerGetName, const char *, osTimerId_t) +SVC0_2 (TimerStart, osStatus_t, osTimerId_t, uint32_t) +SVC0_1 (TimerStop, osStatus_t, osTimerId_t) +SVC0_1 (TimerIsRunning, uint32_t, osTimerId_t) +SVC0_1 (TimerDelete, osStatus_t, osTimerId_t) + +/// Create and Initialize a timer. +/// \note API identical to osTimerNew +osTimerId_t svcRtxTimerNew (osTimerFunc_t func, osTimerType_t type, void *argument, const osTimerAttr_t *attr) { + os_timer_t *timer; + uint8_t flags; + const char *name; + + // Check parameters + if ((func == NULL) || ((type != osTimerOnce) && (type != osTimerPeriodic))) { + EvrRtxTimerError(NULL, osErrorParameter); + return NULL; + } + + // Process attributes + if (attr != NULL) { + name = attr->name; + timer = attr->cb_mem; + if (timer != NULL) { + if (((uint32_t)timer & 3U) || (attr->cb_size < sizeof(os_timer_t))) { + EvrRtxTimerError(NULL, osRtxErrorInvalidControlBlock); + return NULL; + } + } else { + if (attr->cb_size != 0U) { + EvrRtxTimerError(NULL, osRtxErrorInvalidControlBlock); + return NULL; + } + } + } else { + name = NULL; + timer = NULL; + } + + // Allocate object memory if not provided + if (timer == NULL) { + if (osRtxInfo.mpi.timer != NULL) { + timer = osRtxMemoryPoolAlloc(osRtxInfo.mpi.timer); + } else { + timer = osRtxMemoryAlloc(osRtxInfo.mem.common, sizeof(os_timer_t), 1U); + } + if (timer == NULL) { + EvrRtxTimerError(NULL, osErrorNoMemory); + return NULL; + } + flags = osRtxFlagSystemObject; + } else { + flags = 0U; + } + + // Initialize control block + timer->id = osRtxIdTimer; + timer->state = osRtxTimerStopped; + timer->flags = flags; + timer->type = (uint8_t)type; + timer->name = name; + timer->prev = NULL; + timer->next = NULL; + timer->tick = 0U; + timer->load = 0U; + timer->finfo.fp = (void *)func; + timer->finfo.arg = argument; + + EvrRtxTimerCreated(timer); + + return timer; +} + +/// Get name of a timer. +/// \note API identical to osTimerGetName +const char *svcRtxTimerGetName (osTimerId_t timer_id) { + os_timer_t *timer = (os_timer_t *)timer_id; + + // Check parameters + if ((timer == NULL) || (timer->id != osRtxIdTimer)) { + EvrRtxTimerGetName(timer, NULL); + return NULL; + } + + // Check object state + if (timer->state == osRtxObjectInactive) { + EvrRtxTimerGetName(timer, NULL); + return NULL; + } + + EvrRtxTimerGetName(timer, timer->name); + + return timer->name; +} + +/// Start or restart a timer. +/// \note API identical to osTimerStart +osStatus_t svcRtxTimerStart (osTimerId_t timer_id, uint32_t ticks) { + os_timer_t *timer = (os_timer_t *)timer_id; + + // Check parameters + if ((timer == NULL) || (timer->id != osRtxIdTimer) || (ticks == 0U)) { + EvrRtxTimerError(timer, osErrorParameter); + return osErrorParameter; + } + + // Check object state + switch (timer->state) { + case osRtxTimerStopped: + if (osRtxInfo.timer.tick == NULL) { + EvrRtxTimerError(timer, osErrorResource); + return osErrorResource; + } + timer->state = osRtxTimerRunning; + timer->load = ticks; + break; + case osRtxTimerRunning: + TimerRemove(timer); + break; + case osRtxTimerInactive: + default: + EvrRtxTimerError(timer, osErrorResource); + return osErrorResource; + } + + TimerInsert(timer, ticks); + + EvrRtxTimerStarted(timer); + + return osOK; +} + +/// Stop a timer. +/// \note API identical to osTimerStop +osStatus_t svcRtxTimerStop (osTimerId_t timer_id) { + os_timer_t *timer = (os_timer_t *)timer_id; + + // Check parameters + if ((timer == NULL) || (timer->id != osRtxIdTimer)) { + EvrRtxTimerError(timer, osErrorParameter); + return osErrorParameter; + } + + // Check object state + if (timer->state != osRtxTimerRunning) { + EvrRtxTimerError(timer, osErrorResource); + return osErrorResource; + } + + timer->state = osRtxTimerStopped; + + TimerRemove(timer); + + EvrRtxTimerStopped(timer); + + return osOK; +} + +/// Check if a timer is running. +/// \note API identical to osTimerIsRunning +uint32_t svcRtxTimerIsRunning (osTimerId_t timer_id) { + os_timer_t *timer = (os_timer_t *)timer_id; + + // Check parameters + if ((timer == NULL) || (timer->id != osRtxIdTimer)) { + EvrRtxTimerIsRunning(timer, 0U); + return 0U; + } + + // Check object state + if (timer->state == osRtxTimerRunning) { + EvrRtxTimerIsRunning(timer, 1U); + return 1U; + } + + EvrRtxTimerIsRunning(timer, 0U); + return 0U; +} + +/// Delete a timer. +/// \note API identical to osTimerDelete +osStatus_t svcRtxTimerDelete (osTimerId_t timer_id) { + os_timer_t *timer = (os_timer_t *)timer_id; + + // Check parameters + if ((timer == NULL) || (timer->id != osRtxIdTimer)) { + EvrRtxTimerError(timer, osErrorParameter); + return osErrorParameter; + } + + // Check object state + switch (timer->state) { + case osRtxTimerStopped: + break; + case osRtxTimerRunning: + TimerRemove(timer); + break; + case osRtxTimerInactive: + default: + EvrRtxTimerError(timer, osErrorResource); + return osErrorResource; + } + + // Mark object as inactive + timer->state = osRtxTimerInactive; + + // Free object memory + if (timer->flags & osRtxFlagSystemObject) { + if (osRtxInfo.mpi.timer != NULL) { + osRtxMemoryPoolFree(osRtxInfo.mpi.timer, timer); + } else { + osRtxMemoryFree(osRtxInfo.mem.common, timer); + } + } + + EvrRtxTimerDestroyed(timer); + + return osOK; +} + + +// ==== Public API ==== + +/// Create and Initialize a timer. +osTimerId_t osTimerNew (osTimerFunc_t func, osTimerType_t type, void *argument, const osTimerAttr_t *attr) { + EvrRtxTimerNew(func, type, argument, attr); + if (IS_IRQ_MODE() || IS_IRQ_MASKED()) { + EvrRtxTimerError(NULL, osErrorISR); + return NULL; + } + return __svcTimerNew(func, type, argument, attr); +} + +/// Get name of a timer. +const char *osTimerGetName (osTimerId_t timer_id) { + if (IS_IRQ_MODE() || IS_IRQ_MASKED()) { + EvrRtxTimerGetName(timer_id, NULL); + return NULL; + } + return __svcTimerGetName(timer_id); +} + +/// Start or restart a timer. +osStatus_t osTimerStart (osTimerId_t timer_id, uint32_t ticks) { + EvrRtxTimerStart(timer_id, ticks); + if (IS_IRQ_MODE() || IS_IRQ_MASKED()) { + EvrRtxTimerError(timer_id, osErrorISR); + return osErrorISR; + } + return __svcTimerStart(timer_id, ticks); +} + +/// Stop a timer. +osStatus_t osTimerStop (osTimerId_t timer_id) { + EvrRtxTimerStop(timer_id); + if (IS_IRQ_MODE() || IS_IRQ_MASKED()) { + EvrRtxTimerError(timer_id, osErrorISR); + return osErrorISR; + } + return __svcTimerStop(timer_id); +} + +/// Check if a timer is running. +uint32_t osTimerIsRunning (osTimerId_t timer_id) { + if (IS_IRQ_MODE() || IS_IRQ_MASKED()) { + EvrRtxTimerIsRunning(timer_id, 0U); + return 0U; + } + return __svcTimerIsRunning(timer_id); +} + +/// Delete a timer. +osStatus_t osTimerDelete (osTimerId_t timer_id) { + EvrRtxTimerDelete(timer_id); + if (IS_IRQ_MODE() || IS_IRQ_MASKED()) { + EvrRtxTimerError(timer_id, osErrorISR); + return osErrorISR; + } + return __svcTimerDelete(timer_id); +} From 25021f271a3e1258e9831a4134118b68ad5e7378 Mon Sep 17 00:00:00 2001 From: Jaeden Amero Date: Mon, 30 Jan 2017 13:10:54 +0000 Subject: [PATCH 03/24] RTX5: uVisor: Defer to uVisor for SVCall priority Only set the SVCall priority if uVisor is not present. If uVisor is present, keep using whatever priorities it has already set up. --- rtos/rtx2/TARGET_CORTEX_M/core_cm.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/rtos/rtx2/TARGET_CORTEX_M/core_cm.h b/rtos/rtx2/TARGET_CORTEX_M/core_cm.h index 93c77e1531c..6e228d0f09c 100644 --- a/rtos/rtx2/TARGET_CORTEX_M/core_cm.h +++ b/rtos/rtx2/TARGET_CORTEX_M/core_cm.h @@ -635,7 +635,11 @@ __STATIC_INLINE void SVC_Initialize (void) { if (p >= n) { n = p + 1U; } + +/* Only change the SVCall priority if uVisor is not present. */ +#if !(defined(FEATURE_UVISOR) && defined(TARGET_UVISOR_SUPPORTED)) SCB->SHP[7] = (uint8_t)(0xFEU << n); +#endif #elif (__ARM_ARCH_6M__ == 1U) SCB->SHP[1] |= 0x00FF0000U; SCB->SHP[0] |= (SCB->SHP[1] << (8+1)) & 0xFC000000U; From 756e0cae999147da37a3e38ae705ba4944f86744 Mon Sep 17 00:00:00 2001 From: Jaeden Amero Date: Thu, 19 Jan 2017 13:41:05 +0000 Subject: [PATCH 04/24] RTX5: uVisor: Add OsEventObserver Add the OsEventObserver mechanism. A client interested in receiving notifications on certain OS events can register to receive notifications with osRegisterForOsEvents. This is useful for clients like the secure memory allocator, which observes thread switching events in order to swap in and out different memory allocator objects. --- .../rtx2/TARGET_CORTEX_M/rt_OsEventObserver.c | 51 +++++++++++++++++++ .../rtx2/TARGET_CORTEX_M/rt_OsEventObserver.h | 51 +++++++++++++++++++ 2 files changed, 102 insertions(+) create mode 100644 rtos/rtx2/TARGET_CORTEX_M/rt_OsEventObserver.c create mode 100644 rtos/rtx2/TARGET_CORTEX_M/rt_OsEventObserver.h diff --git a/rtos/rtx2/TARGET_CORTEX_M/rt_OsEventObserver.c b/rtos/rtx2/TARGET_CORTEX_M/rt_OsEventObserver.c new file mode 100644 index 00000000000..5fee0aab390 --- /dev/null +++ b/rtos/rtx2/TARGET_CORTEX_M/rt_OsEventObserver.c @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2013-2016 ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ----------------------------------------------------------------------------- + * + * Project: CMSIS-RTOS RTX + * Title: OS Event Observer + * + * ----------------------------------------------------------------------------- + */ +#include "rt_OsEventObserver.h" + +/* + * _____ _____ ____ __ _____ + * | ___|_ _\ \/ / \/ | ____| + * | |_ | | \ /| |\/| | _| + * | _| | | / \| | | | |___ + * |_| |___/_/\_\_| |_|_____| + * + * FIXME: + * The osEventObs variable must be in protected memory. If not every box + * and box 0 can modify osEventObs to point to any handler to run code + * privileged. This issue is tracked at + * . + */ +const OsEventObserver *osEventObs; + +void osRegisterForOsEvents(const OsEventObserver *observer) +{ + static uint8_t has_been_called = 0; + if (has_been_called) { + return; + } + has_been_called = 1; + + osEventObs = observer; +} diff --git a/rtos/rtx2/TARGET_CORTEX_M/rt_OsEventObserver.h b/rtos/rtx2/TARGET_CORTEX_M/rt_OsEventObserver.h new file mode 100644 index 00000000000..899f319029f --- /dev/null +++ b/rtos/rtx2/TARGET_CORTEX_M/rt_OsEventObserver.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2013-2016 ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ----------------------------------------------------------------------------- + * + * Project: CMSIS-RTOS RTX + * Title: OS Event Observer + * + * ----------------------------------------------------------------------------- + */ +#ifndef _RT_OS_EVENT_OBSERVER_H +#define _RT_OS_EVENT_OBSERVER_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + uint32_t version; + void (*pre_start)(void); + void *(*thread_create)(int thread_id, void *context); + void (*thread_destroy)(void *context); + void (*thread_switch)(void *context); +} OsEventObserver; +extern const OsEventObserver *osEventObs; + +void osRegisterForOsEvents(const OsEventObserver *observer); + +#ifdef __cplusplus +}; +#endif + +#endif + +/** @}*/ From 24c60f6cc7df4b4fcd41b0048d6bdee7a7e6407b Mon Sep 17 00:00:00 2001 From: Jaeden Amero Date: Wed, 25 Jan 2017 17:19:27 +0000 Subject: [PATCH 05/24] RTX5: uVisor: Extend thread control block with context OsEventObserver objects expect a context to be maintained per thread on their behalf. Add this context to the thread control block and extend the thread creation functions with the ability to supply a context. --- rtos/rtx2/TARGET_CORTEX_M/cmsis_os2.h | 1 + rtos/rtx2/TARGET_CORTEX_M/rtx_kernel.c | 4 ++-- rtos/rtx2/TARGET_CORTEX_M/rtx_lib.h | 2 +- rtos/rtx2/TARGET_CORTEX_M/rtx_os.h | 1 + rtos/rtx2/TARGET_CORTEX_M/rtx_thread.c | 12 ++++++++---- 5 files changed, 13 insertions(+), 7 deletions(-) diff --git a/rtos/rtx2/TARGET_CORTEX_M/cmsis_os2.h b/rtos/rtx2/TARGET_CORTEX_M/cmsis_os2.h index d25edfa06a8..60fd37b5b29 100644 --- a/rtos/rtx2/TARGET_CORTEX_M/cmsis_os2.h +++ b/rtos/rtx2/TARGET_CORTEX_M/cmsis_os2.h @@ -358,6 +358,7 @@ uint32_t osKernelGetSysTimerFreq (void); /// \param[in] attr thread attributes; NULL: default values. /// \return thread ID for reference by other functions or NULL in case of error. osThreadId_t osThreadNew (osThreadFunc_t func, void *argument, const osThreadAttr_t *attr); +osThreadId_t osThreadContextNew (osThreadFunc_t func, void *argument, const osThreadAttr_t *attr, void *context); /// Get name of a thread. /// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. diff --git a/rtos/rtx2/TARGET_CORTEX_M/rtx_kernel.c b/rtos/rtx2/TARGET_CORTEX_M/rtx_kernel.c index 72207a7d489..ab2816baf8f 100644 --- a/rtos/rtx2/TARGET_CORTEX_M/rtx_kernel.c +++ b/rtos/rtx2/TARGET_CORTEX_M/rtx_kernel.c @@ -253,7 +253,7 @@ osStatus_t svcRtxKernelStart (void) { // Create Idle Thread if (osRtxInfo.thread.idle == NULL) { - osRtxInfo.thread.idle = svcRtxThreadNew(osRtxIdleThread, NULL, osRtxConfig.idle_thread_attr); + osRtxInfo.thread.idle = svcRtxThreadNew(osRtxIdleThread, NULL, osRtxConfig.idle_thread_attr, NULL); if (osRtxInfo.thread.idle == NULL) { EvrRtxKernelError(osError); return osError; @@ -263,7 +263,7 @@ osStatus_t svcRtxKernelStart (void) { // Create Timer Thread if (osRtxConfig.timer_mq_mcnt != 0U) { if (osRtxInfo.timer.thread == NULL) { - osRtxInfo.timer.thread = svcRtxThreadNew(osRtxTimerThread, NULL, osRtxConfig.timer_thread_attr); + osRtxInfo.timer.thread = svcRtxThreadNew(osRtxTimerThread, NULL, osRtxConfig.timer_thread_attr, NULL); if (osRtxInfo.timer.thread == NULL) { EvrRtxKernelError(osError); return osError; diff --git a/rtos/rtx2/TARGET_CORTEX_M/rtx_lib.h b/rtos/rtx2/TARGET_CORTEX_M/rtx_lib.h index 75d6fca46f3..c656a7284af 100644 --- a/rtos/rtx2/TARGET_CORTEX_M/rtx_lib.h +++ b/rtos/rtx2/TARGET_CORTEX_M/rtx_lib.h @@ -128,7 +128,7 @@ extern uint32_t svcRtxKernelGetSysTimerCount (void); extern uint32_t svcRtxKernelGetSysTimerFreq (void); // Thread Service Calls -extern osThreadId_t svcRtxThreadNew (osThreadFunc_t func, void *argument, const osThreadAttr_t *attr); +extern osThreadId_t svcRtxThreadNew (osThreadFunc_t func, void *argument, const osThreadAttr_t *attr, void *context); extern const char * svcRtxThreadGetName (osThreadId_t thread_id); extern osThreadId_t svcRtxThreadGetId (void); extern osThreadState_t svcRtxThreadGetState (osThreadId_t thread_id); diff --git a/rtos/rtx2/TARGET_CORTEX_M/rtx_os.h b/rtos/rtx2/TARGET_CORTEX_M/rtx_os.h index 02c3906b3e4..fbc243c4194 100644 --- a/rtos/rtx2/TARGET_CORTEX_M/rtx_os.h +++ b/rtos/rtx2/TARGET_CORTEX_M/rtx_os.h @@ -127,6 +127,7 @@ typedef struct osRtxThread_s { uint32_t sp; ///< Current Stack Pointer uint32_t thread_addr; ///< Thread entry address uint32_t tz_memory; ///< TrustZone Memory Identifier + void *context; ///< Context for OsEventObserver objects } osRtxThread_t; diff --git a/rtos/rtx2/TARGET_CORTEX_M/rtx_thread.c b/rtos/rtx2/TARGET_CORTEX_M/rtx_thread.c index b49abd36afc..5a22022a34f 100644 --- a/rtos/rtx2/TARGET_CORTEX_M/rtx_thread.c +++ b/rtos/rtx2/TARGET_CORTEX_M/rtx_thread.c @@ -548,7 +548,7 @@ void osRtxThreadPostProcess (os_thread_t *thread) { // ==== Service Calls ==== // Service Calls definitions -SVC0_3M(ThreadNew, osThreadId_t, osThreadFunc_t, void *, const osThreadAttr_t *) +SVC0_4M(ThreadNew, osThreadId_t, osThreadFunc_t, void *, const osThreadAttr_t *, void *) SVC0_1 (ThreadGetName, const char *, osThreadId_t) SVC0_0 (ThreadGetId, osThreadId_t) SVC0_1 (ThreadGetState, osThreadState_t, osThreadId_t) @@ -571,8 +571,8 @@ SVC0_0 (ThreadFlagsGet, uint32_t) SVC0_3 (ThreadFlagsWait, uint32_t, uint32_t, uint32_t, uint32_t) /// Create a thread and add it to Active Threads. -/// \note API identical to osThreadNew -osThreadId_t svcRtxThreadNew (osThreadFunc_t func, void *argument, const osThreadAttr_t *attr) { +/// \note API identical to osThreadContextNew +osThreadId_t svcRtxThreadNew (osThreadFunc_t func, void *argument, const osThreadAttr_t *attr, void *context) { os_thread_t *thread; uint32_t attr_bits; void *stack_mem; @@ -1501,12 +1501,16 @@ uint32_t isrRtxThreadFlagsSet (osThreadId_t thread_id, uint32_t flags) { /// Create a thread and add it to Active Threads. osThreadId_t osThreadNew (osThreadFunc_t func, void *argument, const osThreadAttr_t *attr) { + return osThreadContextNew(func, argument, attr, NULL); +} + +osThreadId_t osThreadContextNew (osThreadFunc_t func, void *argument, const osThreadAttr_t *attr, void *context) { EvrRtxThreadNew(func, argument, attr); if (IS_IRQ_MODE() || IS_IRQ_MASKED()) { EvrRtxThreadError(NULL, osErrorISR); return NULL; } - return __svcThreadNew(func, argument, attr); + return __svcThreadNew(func, argument, attr, context); } /// Get name of a thread. From 7ae2e6e9ec566037e3b4b9dd59e554a895072860 Mon Sep 17 00:00:00 2001 From: Jaeden Amero Date: Thu, 19 Jan 2017 13:34:56 +0000 Subject: [PATCH 06/24] RTX5: uVisor: Use OsEventObserver --- rtos/rtx2/TARGET_CORTEX_M/rtx_kernel.c | 10 ++++++++++ rtos/rtx2/TARGET_CORTEX_M/rtx_thread.c | 16 ++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/rtos/rtx2/TARGET_CORTEX_M/rtx_kernel.c b/rtos/rtx2/TARGET_CORTEX_M/rtx_kernel.c index ab2816baf8f..d9b9a7a7a59 100644 --- a/rtos/rtx2/TARGET_CORTEX_M/rtx_kernel.c +++ b/rtos/rtx2/TARGET_CORTEX_M/rtx_kernel.c @@ -24,6 +24,7 @@ */ #include "rtx_lib.h" +#include "rt_OsEventObserver.h" // OS Runtime Information @@ -541,6 +542,15 @@ osStatus_t osKernelStart (void) { EvrRtxKernelError(osErrorISR); return osErrorISR; } + + /* Call the pre-start event (from unprivileged mode) if the handler exists + * and the kernel is not running. */ + /* FIXME osEventObs needs to be readable but not writable from unprivileged + * code. */ + if (osKernelGetState() != osKernelRunning && osEventObs && osEventObs->pre_start) { + osEventObs->pre_start(); + } + return __svcKernelStart(); } diff --git a/rtos/rtx2/TARGET_CORTEX_M/rtx_thread.c b/rtos/rtx2/TARGET_CORTEX_M/rtx_thread.c index 5a22022a34f..05c4ab6dbac 100644 --- a/rtos/rtx2/TARGET_CORTEX_M/rtx_thread.c +++ b/rtos/rtx2/TARGET_CORTEX_M/rtx_thread.c @@ -24,6 +24,7 @@ */ #include "rtx_lib.h" +#include "rt_OsEventObserver.h" // ==== Helper functions ==== @@ -425,6 +426,10 @@ void osRtxThreadSwitch (os_thread_t *thread) { osRtxInfo.thread.run.next = thread; osRtxThreadStackCheck(); EvrRtxThreadSwitch(thread); + + if (osEventObs && osEventObs->thread_switch) { + osEventObs->thread_switch(thread->context); + } } /// Dispatch specified Thread or Ready Thread with Highest Priority. @@ -769,6 +774,13 @@ osThreadId_t svcRtxThreadNew (osThreadFunc_t func, void *argument, const osThrea EvrRtxThreadCreated(thread); + /* Notify the OS event observer of a new thread. */ + if (osEventObs && osEventObs->thread_create) { + thread->context = osEventObs->thread_create((int)thread, context); + } else { + thread->context = context; + } + osRtxThreadDispatch(thread); return thread; @@ -1215,6 +1227,10 @@ osStatus_t svcRtxThreadTerminate (osThreadId_t thread_id) { return osErrorResource; } + if (osEventObs && osEventObs->thread_destroy) { + osEventObs->thread_destroy(thread->context); + } + // Release owned Mutexes osRtxMutexOwnerRelease(thread->mutex_list); From 7b022f8785431b5179c77fec9babb78ed1017e80 Mon Sep 17 00:00:00 2001 From: Bartek Szatkowski Date: Mon, 15 May 2017 11:33:34 -0500 Subject: [PATCH 07/24] Modify CMSIS 5 so it is suitable for mbed-os Make changes to the files taken from RTX5/CMSIS5 so they work with mbed-os and uvisor. --- .../TOOLCHAIN_ARM/cmsis_armcc.h | 2 +- .../TOOLCHAIN_ARM/cmsis_armclang.h | 16 ++++---- cmsis/TARGET_CORTEX_M/cmsis_compiler.h | 20 ++++++++++ cmsis/arm_math.h | 37 +++++++++++++++++-- rtos/rtx/cmsis_os.h | 16 ++++---- rtos/rtx2/TARGET_CORTEX_M/RTX_Config.c | 2 +- rtos/rtx2/TARGET_CORTEX_M/RTX_Config.h | 7 +++- .../TOOLCHAIN_ARM/irq_cm4f.s | 6 +++ .../TOOLCHAIN_GCC/irq_cm4f.S | 7 ++++ .../TOOLCHAIN_IAR/irq_cm4f.s | 6 +++ rtos/rtx2/TARGET_CORTEX_M/cmsis_os2.h | 4 ++ rtos/rtx2/TARGET_CORTEX_M/core_cm.h | 10 ++++- rtos/rtx2/TARGET_CORTEX_M/rtx_evr.c | 2 - rtos/rtx2/TARGET_CORTEX_M/rtx_evr.h | 3 ++ rtos/rtx2/TARGET_CORTEX_M/rtx_lib.h | 4 +- 15 files changed, 115 insertions(+), 27 deletions(-) diff --git a/cmsis/TARGET_CORTEX_A/TOOLCHAIN_ARM/cmsis_armcc.h b/cmsis/TARGET_CORTEX_A/TOOLCHAIN_ARM/cmsis_armcc.h index a6c0d160d5b..80f9dd95791 100644 --- a/cmsis/TARGET_CORTEX_A/TOOLCHAIN_ARM/cmsis_armcc.h +++ b/cmsis/TARGET_CORTEX_A/TOOLCHAIN_ARM/cmsis_armcc.h @@ -232,7 +232,7 @@ __STATIC_INLINE void __set_CPSR(uint32_t cpsr) \return Processor Mode */ __STATIC_INLINE uint32_t __get_mode(void) { - return (__get_CPSR() & 0x1FU); + return (__get_CPSR() & 0x1FU); } /** \brief Set Mode diff --git a/cmsis/TARGET_CORTEX_A/TOOLCHAIN_ARM/cmsis_armclang.h b/cmsis/TARGET_CORTEX_A/TOOLCHAIN_ARM/cmsis_armclang.h index 243f6fdbf23..40069837d15 100644 --- a/cmsis/TARGET_CORTEX_A/TOOLCHAIN_ARM/cmsis_armclang.h +++ b/cmsis/TARGET_CORTEX_A/TOOLCHAIN_ARM/cmsis_armclang.h @@ -224,7 +224,7 @@ __STATIC_INLINE uint32_t __get_CPSR(void) \return Processor Mode */ __STATIC_INLINE uint32_t __get_mode(void) { - return (__get_CPSR() & 0x1FU); + return (__get_CPSR() & 0x1FU); } /** \brief Set Mode @@ -579,24 +579,24 @@ __STATIC_INLINE void __L1C_CleanInvalidateCache(uint32_t op) { */ __STATIC_INLINE void __FPU_Enable(void) { __ASM volatile( - //Permit access to VFP/NEON, registers by modifying CPACR + //Permit access to VFP/NEON, registers by modifying CPACR " MRC p15,0,R1,c1,c0,2 \n" " ORR R1,R1,#0x00F00000 \n" " MCR p15,0,R1,c1,c0,2 \n" - //Ensure that subsequent instructions occur in the context of VFP/NEON access permitted + //Ensure that subsequent instructions occur in the context of VFP/NEON access permitted " ISB \n" - //Enable VFP/NEON + //Enable VFP/NEON " VMRS R1,FPEXC \n" " ORR R1,R1,#0x40000000 \n" " VMSR FPEXC,R1 \n" - //Initialise VFP/NEON registers to 0 + //Initialise VFP/NEON registers to 0 " MOV R2,#0 \n" #if 0 // TODO: Initialize FPU registers according to available register count ".if {TARGET_FEATURE_EXTENSION_REGISTER_COUNT} >= 16 \n" - //Initialise D16 registers to 0 + //Initialise D16 registers to 0 " VMOV D0, R2,R2 \n" " VMOV D1, R2,R2 \n" " VMOV D2, R2,R2 \n" @@ -616,7 +616,7 @@ __STATIC_INLINE void __FPU_Enable(void) { ".endif \n" ".if {TARGET_FEATURE_EXTENSION_REGISTER_COUNT} == 32 \n" - //Initialise D32 registers to 0 + //Initialise D32 registers to 0 " VMOV D16,R2,R2 \n" " VMOV D17,R2,R2 \n" " VMOV D18,R2,R2 \n" @@ -635,7 +635,7 @@ __STATIC_INLINE void __FPU_Enable(void) { " VMOV D31,R2,R2 \n" ".endif \n" #endif - //Initialise FPSCR to a known state + //Initialise FPSCR to a known state " VMRS R2,FPSCR \n" " LDR R3,=0x00086060 \n" //Mask off all bits that do not have to be preserved. Non-preserved bits can/should be zero. " AND R2,R2,R3 \n" diff --git a/cmsis/TARGET_CORTEX_M/cmsis_compiler.h b/cmsis/TARGET_CORTEX_M/cmsis_compiler.h index 2ef183fbaaf..582ada4a401 100644 --- a/cmsis/TARGET_CORTEX_M/cmsis_compiler.h +++ b/cmsis/TARGET_CORTEX_M/cmsis_compiler.h @@ -65,6 +65,26 @@ #include + /* CMSIS compiler control architecture macros */ + #if (__CORE__ == __ARM6M__) || (__CORE__ == __ARM6SM__) + #ifndef __ARM_ARCH_6M__ + #define __ARM_ARCH_6M__ 1 + #endif + #elif (__CORE__ == __ARM7M__) + #ifndef __ARM_ARCH_7M__ + #define __ARM_ARCH_7M__ 1 + #endif + #elif (__CORE__ == __ARM7EM__) + #ifndef __ARM_ARCH_7EM__ + #define __ARM_ARCH_7EM__ 1 + #endif + #endif + + // IAR version 7.8.1 and earlier do not include __ALIGNED + #ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) + #endif + #ifndef __NO_RETURN #define __NO_RETURN __noreturn #endif diff --git a/cmsis/arm_math.h b/cmsis/arm_math.h index 4be7e8c8488..6d754018966 100644 --- a/cmsis/arm_math.h +++ b/cmsis/arm_math.h @@ -293,14 +293,30 @@ #ifndef _ARM_MATH_H #define _ARM_MATH_H -/* ignore some GCC warnings */ -#if defined ( __GNUC__ ) +/* Compiler specific diagnostic adjustment */ +#if defined ( __CC_ARM ) + +#elif defined ( __ARMCC_VERSION ) && ( __ARMCC_VERSION >= 6010050 ) + +#elif defined ( __GNUC__ ) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wsign-conversion" #pragma GCC diagnostic ignored "-Wconversion" #pragma GCC diagnostic ignored "-Wunused-parameter" + +#elif defined ( __ICCARM__ ) + +#elif defined ( __TI_ARM__ ) + +#elif defined ( __CSMC__ ) + +#elif defined ( __TASKING__ ) + +#else + #error Unknown compiler #endif + #define __CMSIS_GENERIC /* disable NVIC and Systick functions */ #if defined(ARM_MATH_CM7) @@ -7213,9 +7229,24 @@ void arm_rfft_fast_f32( } #endif +/* Compiler specific diagnostic adjustment */ +#if defined ( __CC_ARM ) + +#elif defined ( __ARMCC_VERSION ) && ( __ARMCC_VERSION >= 6010050 ) -#if defined ( __GNUC__ ) +#elif defined ( __GNUC__ ) #pragma GCC diagnostic pop + +#elif defined ( __ICCARM__ ) + +#elif defined ( __TI_ARM__ ) + +#elif defined ( __CSMC__ ) + +#elif defined ( __TASKING__ ) + +#else + #error Unknown compiler #endif #endif /* _ARM_MATH_H */ diff --git a/rtos/rtx/cmsis_os.h b/rtos/rtx/cmsis_os.h index 9a7ab76b600..4f7ba115df9 100644 --- a/rtos/rtx/cmsis_os.h +++ b/rtos/rtx/cmsis_os.h @@ -433,23 +433,23 @@ uint32_t osKernelSysTick (void); /// \param instances number of possible thread instances. /// \param stacksz stack size (in bytes) requirements for the thread function. #if defined (osObjectsExternal) // object is external -#define osThreadDef(name, priority, instances, stacksz) \ +#define osThreadDef(name, priority, stacksz) \ extern const osThreadDef_t os_thread_def_##name #else // define the object #if (osCMSIS < 0x20000U) -#define osThreadDef(name, priority, instances, stacksz) \ +#define osThreadDef(name, priority, stacksz) \ const osThreadDef_t os_thread_def_##name = \ -{ (name), (priority), (instances), (stacksz) } +{ (name), (priority), (1), (stacksz) } #else -#define osThreadDef(name, priority, instances, stacksz) \ -static uint64_t os_thread_stack##name[(stacksz)?(((stacksz+7)/8)):1] __attribute__((section(".bss.os.thread.stack"))); \ +#define osThreadDef(name, priority, stacksz) \ +uint64_t os_thread_stack##name[(stacksz)?(((stacksz+7)/8)):1] __attribute__((section(".bss.os.thread.stack"))); \ static osRtxThread_t os_thread_cb_##name __attribute__((section(".bss.os.thread.cb"))); \ const osThreadDef_t os_thread_def_##name = \ { (name), \ { NULL, osThreadDetached, \ - (instances == 1) ? (&os_thread_cb_##name) : NULL,\ - (instances == 1) ? osRtxThreadCbSize : 0U, \ - ((stacksz) && (instances == 1)) ? (&os_thread_stack##name) : NULL, \ + (&os_thread_cb_##name),\ + osRtxThreadCbSize, \ + (stacksz) ? (&os_thread_stack##name) : NULL, \ 8*((stacksz+7)/8), \ (priority), 0U, 0U } } #endif diff --git a/rtos/rtx2/TARGET_CORTEX_M/RTX_Config.c b/rtos/rtx2/TARGET_CORTEX_M/RTX_Config.c index 69c8179dfb1..6572cf0a498 100644 --- a/rtos/rtx2/TARGET_CORTEX_M/RTX_Config.c +++ b/rtos/rtx2/TARGET_CORTEX_M/RTX_Config.c @@ -24,7 +24,7 @@ * * ----------------------------------------------------------------------------- */ - + #include "cmsis_compiler.h" #include "rtx_os.h" diff --git a/rtos/rtx2/TARGET_CORTEX_M/RTX_Config.h b/rtos/rtx2/TARGET_CORTEX_M/RTX_Config.h index 6cacee82488..6d95b78099d 100644 --- a/rtos/rtx2/TARGET_CORTEX_M/RTX_Config.h +++ b/rtos/rtx2/TARGET_CORTEX_M/RTX_Config.h @@ -1,3 +1,5 @@ +/** \addtogroup rtos */ +/** @{*/ /* * Copyright (c) 2013-2017 ARM Limited. All rights reserved. * @@ -27,7 +29,9 @@ #ifndef RTX_CONFIG_H_ #define RTX_CONFIG_H_ - + +#include "rtx2/mbed_rtx_conf.h" + //-------- <<< Use Configuration Wizard in Context Menu >>> -------------------- // System Configuration @@ -377,3 +381,4 @@ //------------- <<< end of configuration section >>> --------------------------- #endif // RTX_CONFIG_H_ +/** @}*/ diff --git a/rtos/rtx2/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_ARM/irq_cm4f.s b/rtos/rtx2/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_ARM/irq_cm4f.s index 746c7c170a3..84ad0b53618 100644 --- a/rtos/rtx2/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_ARM/irq_cm4f.s +++ b/rtos/rtx2/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_ARM/irq_cm4f.s @@ -66,16 +66,20 @@ SVC_Context CBNZ R1,SVC_ContextSave ; Branch if running thread is not deleted TST LR,#0x10 ; Check if extended stack frame BNE SVC_ContextSwitch +#ifdef __FPU_PRESENT LDR R1,=0xE000EF34 ; FPCCR Address LDR R0,[R1] ; Load FPCCR BIC R0,#1 ; Clear LSPACT (Lazy state) STR R0,[R1] ; Store FPCCR B SVC_ContextSwitch +#endif SVC_ContextSave STMDB R12!,{R4-R11} ; Save R4..R11 +#ifdef __FPU_PRESENT TST LR,#0x10 ; Check if extended stack frame VSTMDBEQ R12!,{S16-S31} ; Save VFP S16.S31 +#endif STR R12,[R1,#TCB_SP_OFS] ; Store SP STRB LR, [R1,#TCB_SF_OFS] ; Store stack frame information @@ -88,8 +92,10 @@ SVC_ContextRestore LDR R0,[R2,#TCB_SP_OFS] ; Load SP ORR LR,R1,#0xFFFFFF00 ; Set EXC_RETURN +#ifdef __FPU_PRESENT TST LR,#0x10 ; Check if extended stack frame VLDMIAEQ R0!,{S16-S31} ; Restore VFP S16..S31 +#endif LDMIA R0!,{R4-R11} ; Restore R4..R11 MSR PSP,R0 ; Set PSP diff --git a/rtos/rtx2/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_GCC/irq_cm4f.S b/rtos/rtx2/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_GCC/irq_cm4f.S index 23942f718b0..2a110eda53f 100644 --- a/rtos/rtx2/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_GCC/irq_cm4f.S +++ b/rtos/rtx2/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_GCC/irq_cm4f.S @@ -70,17 +70,22 @@ SVC_Context: CBNZ R1,SVC_ContextSave // Branch if running thread is not deleted TST LR,#0x10 // Check if extended stack frame BNE SVC_ContextSwitch +#ifdef __FPU_PRESENT LDR R1,=0xE000EF34 // FPCCR Address LDR R0,[R1] // Load FPCCR BIC R0,#1 // Clear LSPACT (Lazy state) STR R0,[R1] // Store FPCCR B SVC_ContextSwitch +#endif SVC_ContextSave: STMDB R12!,{R4-R11} // Save R4..R11 + +#ifdef __FPU_PRESENT TST LR,#0x10 // Check if extended stack frame IT EQ VSTMDBEQ R12!,{S16-S31} // Save VFP S16.S31 +#endif STR R12,[R1,#TCB_SP_OFS] // Store SP STRB LR, [R1,#TCB_SF_OFS] // Store stack frame information @@ -93,9 +98,11 @@ SVC_ContextRestore: LDR R0,[R2,#TCB_SP_OFS] // Load SP ORR LR,R1,#0xFFFFFF00 // Set EXC_RETURN +#ifdef __FPU_PRESENT TST LR,#0x10 // Check if extended stack frame IT EQ VLDMIAEQ R0!,{S16-S31} // Restore VFP S16..S31 +#endif LDMIA R0!,{R4-R11} // Restore R4..R11 MSR PSP,R0 // Set PSP diff --git a/rtos/rtx2/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_IAR/irq_cm4f.s b/rtos/rtx2/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_IAR/irq_cm4f.s index 4af43869c9c..e194af196c1 100644 --- a/rtos/rtx2/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_IAR/irq_cm4f.s +++ b/rtos/rtx2/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_IAR/irq_cm4f.s @@ -69,17 +69,21 @@ SVC_Context CBNZ R1,SVC_ContextSave ; Branch if running thread is not deleted TST LR,#0x10 ; Check if extended stack frame BNE SVC_ContextSwitch +#ifdef __FPU_PRESENT LDR R1,=0xE000EF34 ; FPCCR Address LDR R0,[R1] ; Load FPCCR BIC R0,R0,#1 ; Clear LSPACT (Lazy state) STR R0,[R1] ; Store FPCCR B SVC_ContextSwitch +#endif SVC_ContextSave STMDB R12!,{R4-R11} ; Save R4..R11 +#ifdef __FPU_PRESENT TST LR,#0x10 ; Check if extended stack frame IT EQ VSTMDBEQ R12!,{S16-S31} ; Save VFP S16.S31 +#endif STR R12,[R1,#TCB_SP_OFS] ; Store SP STRB LR, [R1,#TCB_SF_OFS] ; Store stack frame information @@ -92,9 +96,11 @@ SVC_ContextRestore LDR R0,[R2,#TCB_SP_OFS] ; Load SP ORR LR,R1,#0xFFFFFF00 ; Set EXC_RETURN +#ifdef __FPU_PRESENT TST LR,#0x10 ; Check if extended stack frame IT EQ VLDMIAEQ R0!,{S16-S31} ; Restore VFP S16..S31 +#endif LDMIA R0!,{R4-R11} ; Restore R4..R11 MSR PSP,R0 ; Set PSP diff --git a/rtos/rtx2/TARGET_CORTEX_M/cmsis_os2.h b/rtos/rtx2/TARGET_CORTEX_M/cmsis_os2.h index 60fd37b5b29..6ae65137b7c 100644 --- a/rtos/rtx2/TARGET_CORTEX_M/cmsis_os2.h +++ b/rtos/rtx2/TARGET_CORTEX_M/cmsis_os2.h @@ -1,3 +1,5 @@ +/** \addtogroup rtos */ +/** @{*/ /* * Copyright (c) 2013-2017 ARM Limited. All rights reserved. * @@ -744,3 +746,5 @@ osStatus_t osMessageQueueDelete (osMessageQueueId_t mq_id); #endif #endif // CMSIS_OS2_H_ + +/** @}*/ diff --git a/rtos/rtx2/TARGET_CORTEX_M/core_cm.h b/rtos/rtx2/TARGET_CORTEX_M/core_cm.h index 6e228d0f09c..1590bd6c65a 100644 --- a/rtos/rtx2/TARGET_CORTEX_M/core_cm.h +++ b/rtos/rtx2/TARGET_CORTEX_M/core_cm.h @@ -1,3 +1,5 @@ +/** \addtogroup rtos */ +/** @{*/ /* * Copyright (c) 2013-2017 ARM Limited. All rights reserved. * @@ -26,8 +28,10 @@ #ifndef CORE_CM_H_ #define CORE_CM_H_ -#include "RTE_Components.h" -#include CMSIS_device_header +#include +#include "cmsis.h" +#include "cmsis_compiler.h" +#include "arm_math.h" #ifndef __ARM_ARCH_6M__ #define __ARM_ARCH_6M__ 0U @@ -1526,3 +1530,5 @@ __STATIC_INLINE void atomic_link_put (void **root, void *link) { #endif // CORE_CM_H_ + +/** @}*/ diff --git a/rtos/rtx2/TARGET_CORTEX_M/rtx_evr.c b/rtos/rtx2/TARGET_CORTEX_M/rtx_evr.c index 8785e26cec2..f368df828a8 100644 --- a/rtos/rtx2/TARGET_CORTEX_M/rtx_evr.c +++ b/rtos/rtx2/TARGET_CORTEX_M/rtx_evr.c @@ -27,8 +27,6 @@ #include "cmsis_compiler.h" #include "rtx_evr.h" // RTX Event Recorder definitions -#include "RTE_Components.h" - #ifdef RTE_Compiler_EventRecorder #include "EventRecorder.h" // Keil::Compiler:Event Recorder diff --git a/rtos/rtx2/TARGET_CORTEX_M/rtx_evr.h b/rtos/rtx2/TARGET_CORTEX_M/rtx_evr.h index e18c2d766e5..5bc4baa89fe 100644 --- a/rtos/rtx2/TARGET_CORTEX_M/rtx_evr.h +++ b/rtos/rtx2/TARGET_CORTEX_M/rtx_evr.h @@ -1,3 +1,5 @@ +/** \addtogroup rtos */ +/** @{*/ /* * Copyright (c) 2013-2017 ARM Limited. All rights reserved. * @@ -1842,3 +1844,4 @@ extern void EvrRtxMessageQueueDestroyed (osMessageQueueId_t mq_id); #endif // RTX_EVR_H_ +/** @}*/ diff --git a/rtos/rtx2/TARGET_CORTEX_M/rtx_lib.h b/rtos/rtx2/TARGET_CORTEX_M/rtx_lib.h index c656a7284af..fb7423db1d7 100644 --- a/rtos/rtx2/TARGET_CORTEX_M/rtx_lib.h +++ b/rtos/rtx2/TARGET_CORTEX_M/rtx_lib.h @@ -1,3 +1,5 @@ +/** \addtogroup rtos */ +/** @{*/ /* * Copyright (c) 2013-2017 ARM Limited. All rights reserved. * @@ -210,5 +212,5 @@ extern uint32_t svcRtxMessageQueueGetSpace (osMessageQueueId_t mq_i extern osStatus_t svcRtxMessageQueueReset (osMessageQueueId_t mq_id); extern osStatus_t svcRtxMessageQueueDelete (osMessageQueueId_t mq_id); - #endif // RTX_LIB_H_ +/** @}*/ From b97ffe8fdce9473138b0b05984658fe5dc7c7713 Mon Sep 17 00:00:00 2001 From: Bartek Szatkowski Date: Mon, 24 Oct 2016 17:34:01 +0100 Subject: [PATCH 08/24] CMSIS5: Replace target defined NVIC_Set/GetVector with CMSIS implementation --- .../TARGET_BEETLE/device/cmsis_nvic.c | 43 -------- .../TARGET_BEETLE/device/cmsis_nvic.h | 20 +--- .../TARGET_IOTSS_BEID/device/cmsis_nvic.c | 58 ---------- .../TARGET_IOTSS_BEID/device/cmsis_nvic.h | 19 +--- .../TARGET_MPS2_M0/device/cmsis_nvic.c | 54 --------- .../TARGET_MPS2_M0/device/cmsis_nvic.h | 19 +--- .../TARGET_MPS2_M0P/device/cmsis_nvic.c | 54 --------- .../TARGET_MPS2_M0P/device/cmsis_nvic.h | 19 +--- .../TARGET_MPS2_M3/device/cmsis_nvic.c | 58 ---------- .../TARGET_MPS2_M3/device/cmsis_nvic.h | 19 +--- .../TARGET_MPS2_M4/device/cmsis_nvic.c | 58 ---------- .../TARGET_MPS2_M4/device/cmsis_nvic.h | 19 +--- .../TARGET_MPS2_M7/device/cmsis_nvic.c | 58 ---------- .../TARGET_MPS2_M7/device/cmsis_nvic.h | 19 +--- .../TARGET_SAMD21/device/cmsis_nvic.c | 57 ---------- .../TARGET_SAMD21/device/cmsis_nvic.h | 18 +-- .../TARGET_SAML21/device/cmsis_nvic.c | 58 ---------- .../TARGET_SAML21/device/cmsis_nvic.h | 18 +-- .../TARGET_SAMR21/device/cmsis_nvic.c | 58 ---------- .../TARGET_SAMR21/device/cmsis_nvic.h | 18 +-- .../TARGET_SAMG55/device/cmsis_nvic.c | 57 ---------- .../TARGET_SAMG55/device/cmsis_nvic.h | 18 +-- .../TARGET_K20D50M/device/cmsis_nvic.c | 55 ---------- .../TARGET_K20D50M/device/cmsis_nvic.h | 18 +-- .../TARGET_TEENSY3_1/device/cmsis_nvic.c | 55 ---------- .../TARGET_TEENSY3_1/device/cmsis_nvic.h | 18 +-- .../TARGET_KL05Z/device/cmsis_nvic.c | 55 ---------- .../TARGET_KL05Z/device/cmsis_nvic.h | 18 +-- .../TARGET_KL25Z/device/cmsis_nvic.c | 55 ---------- .../TARGET_KL25Z/device/cmsis_nvic.h | 18 +-- .../TARGET_KL26Z/device/cmsis_nvic.c | 55 ---------- .../TARGET_KL26Z/device/cmsis_nvic.h | 18 +-- .../TARGET_KL46Z/device/cmsis_nvic.c | 55 ---------- .../TARGET_KL46Z/device/cmsis_nvic.h | 18 +-- .../TARGET_K66F/device/cmsis_nvic.c | 44 -------- .../TARGET_K66F/device/cmsis_nvic.h | 22 ++-- .../TARGET_K82F/device/cmsis_nvic.c | 44 -------- .../TARGET_K82F/device/cmsis_nvic.h | 21 ++-- .../TARGET_KL27Z/device/cmsis_nvic.c | 44 -------- .../TARGET_KL27Z/device/cmsis_nvic.h | 22 ++-- .../TARGET_KL43Z/device/cmsis_nvic.c | 44 -------- .../TARGET_KL43Z/device/cmsis_nvic.h | 22 ++-- .../TARGET_KL82Z/device/cmsis_nvic.c | 44 -------- .../TARGET_KL82Z/device/cmsis_nvic.h | 22 ++-- .../TARGET_KW24D/device/cmsis_nvic.c | 44 -------- .../TARGET_KW24D/device/cmsis_nvic.h | 22 ++-- .../TARGET_KW41Z/device/cmsis_nvic.c | 44 -------- .../TARGET_KW41Z/device/cmsis_nvic.h | 21 ++-- .../TARGET_MCU_K22F512/device/cmsis_nvic.c | 44 -------- .../TARGET_MCU_K22F512/device/cmsis_nvic.h | 24 ++-- .../TARGET_MCU_K24F1M/device/cmsis_nvic.c | 42 ------- .../TARGET_MCU_K24F1M/device/cmsis_nvic.h | 22 ++-- .../TARGET_MCU_K64F/device/cmsis_nvic.c | 44 -------- .../TARGET_MCU_K64F/device/cmsis_nvic.h | 24 ++-- .../TARGET_MAX32600/device/cmsis_nvic.c | 65 ----------- .../TARGET_MAX32600/device/cmsis_nvic.h | 17 +-- .../TARGET_MAX32600/device/device_nvic.c | 24 ++++ .../TARGET_MAX32610/device/cmsis_nvic.c | 65 ----------- .../TARGET_MAX32610/device/cmsis_nvic.h | 17 +-- .../TARGET_MAX32610/device/device_nvic.c | 24 ++++ .../TARGET_MAX32620/device/cmsis_nvic.c | 65 ----------- .../TARGET_MAX32620/device/cmsis_nvic.h | 17 +-- .../TARGET_MAX32620/device/device_nvic.c | 24 ++++ .../TARGET_MAX32625/device/cmsis_nvic.c | 65 ----------- .../TARGET_MAX32625/device/cmsis_nvic.h | 18 +-- .../TARGET_MAX32625/device/device_nvic.c | 24 ++++ .../TARGET_MAX32630/device/device_nvic.c | 24 ++++ .../TARGET_MAX32630/mxc/nvic_table.c | 93 ---------------- .../TARGET_MAX32630/mxc/nvic_table.h | 43 +------- .../TARGET_MCU_NRF51822/device/cmsis_nvic.c | 103 ------------------ .../TARGET_MCU_NRF51822/device/cmsis_nvic.h | 19 +--- .../TARGET_MCU_NRF52832/device/cmsis_nvic.h | 1 - .../TARGET_M451/device/cmsis_nvic.c | 39 ------- .../TARGET_M451/device/cmsis_nvic.h | 50 +-------- .../TARGET_NUC472/device/cmsis_nvic.c | 39 ------- .../TARGET_NUC472/device/cmsis_nvic.h | 44 +------- .../TARGET_LPC11U6X/device/cmsis_nvic.c | 55 ---------- .../TARGET_LPC11U6X/device/cmsis_nvic.h | 18 +-- .../TARGET_LPC11UXX/device/cmsis_nvic.c | 81 -------------- .../TARGET_LPC11UXX/device/cmsis_nvic.h | 17 +-- .../TARGET_LPC11XX_11CXX/device/cmsis_nvic.c | 82 -------------- .../TARGET_LPC11XX_11CXX/device/cmsis_nvic.h | 15 +-- .../TARGET_LPC13XX/device/cmsis_nvic.c | 56 ---------- .../TARGET_LPC13XX/device/cmsis_nvic.h | 18 +-- .../TARGET_LPC15XX/device/cmsis_nvic.c | 55 ---------- .../TARGET_LPC15XX/device/cmsis_nvic.h | 18 +-- .../TARGET_LPC176X/device/cmsis_nvic.c | 56 ---------- .../TARGET_LPC176X/device/cmsis_nvic.h | 18 +-- .../TARGET_LPC408X/device/cmsis_nvic.c | 56 ---------- .../TARGET_LPC408X/device/cmsis_nvic.h | 18 +-- .../TARGET_LPC43XX/device/cmsis_nvic.c | 61 ----------- .../TARGET_LPC43XX/device/cmsis_nvic.h | 18 +-- .../TARGET_LPC81X/device/cmsis_nvic.c | 55 ---------- .../TARGET_LPC81X/device/cmsis_nvic.h | 18 +-- .../TARGET_LPC82X/device/cmsis_nvic.c | 55 ---------- .../TARGET_LPC82X/device/cmsis_nvic.h | 18 +-- .../TARGET_NCS36510/device/cmsis_nvic.c | 43 -------- .../TARGET_NCS36510/device/cmsis_nvic.h | 4 +- .../TARGET_DISCO_F051R8/device/cmsis_nvic.c | 56 ---------- .../TARGET_DISCO_F051R8/device/cmsis_nvic.h | 17 +-- .../TARGET_NUCLEO_F030R8/device/cmsis_nvic.c | 57 ---------- .../TARGET_NUCLEO_F030R8/device/cmsis_nvic.h | 17 +-- .../TARGET_NUCLEO_F031K6/device/cmsis_nvic.c | 57 ---------- .../TARGET_NUCLEO_F031K6/device/cmsis_nvic.h | 17 +-- .../TARGET_NUCLEO_F042K6/device/cmsis_nvic.c | 57 ---------- .../TARGET_NUCLEO_F042K6/device/cmsis_nvic.h | 17 +-- .../TARGET_NUCLEO_F070RB/device/cmsis_nvic.c | 57 ---------- .../TARGET_NUCLEO_F070RB/device/cmsis_nvic.h | 17 +-- .../TARGET_NUCLEO_F072RB/device/cmsis_nvic.c | 57 ---------- .../TARGET_NUCLEO_F072RB/device/cmsis_nvic.h | 17 +-- .../TARGET_NUCLEO_F091RC/device/cmsis_nvic.c | 56 ---------- .../TARGET_NUCLEO_F091RC/device/cmsis_nvic.h | 17 +-- .../device/cmsis_nvic.c | 55 ---------- .../device/cmsis_nvic.h | 20 +--- .../TARGET_DISCO_F100RB/device/cmsis_nvic.c | 55 ---------- .../TARGET_DISCO_F100RB/device/cmsis_nvic.h | 20 +--- .../TARGET_NUCLEO_F103RB/device/cmsis_nvic.c | 55 ---------- .../TARGET_NUCLEO_F103RB/device/cmsis_nvic.h | 20 +--- .../TARGET_NUCLEO_F207ZG/device/cmsis_nvic.c | 57 ---------- .../TARGET_NUCLEO_F207ZG/device/cmsis_nvic.h | 18 +-- .../TARGET_STM32F302x8/device/cmsis_nvic.c | 54 --------- .../TARGET_STM32F302x8/device/cmsis_nvic.h | 20 +--- .../TARGET_STM32F303x8/device/cmsis_nvic.c | 54 --------- .../TARGET_STM32F303x8/device/cmsis_nvic.h | 20 +--- .../TARGET_STM32F303xC/device/cmsis_nvic.c | 54 --------- .../TARGET_STM32F303xC/device/cmsis_nvic.h | 20 +--- .../TARGET_STM32F303xE/device/cmsis_nvic.c | 54 --------- .../TARGET_STM32F303xE/device/cmsis_nvic.h | 20 +--- .../TARGET_STM32F334x8/device/cmsis_nvic.c | 54 --------- .../TARGET_STM32F334x8/device/cmsis_nvic.h | 20 +--- .../device/cmsis_nvic.c | 55 ---------- .../device/cmsis_nvic.h | 20 +--- .../device/cmsis_nvic.c | 55 ---------- .../device/cmsis_nvic.h | 20 +--- .../device/cmsis_nvic.c | 55 ---------- .../device/cmsis_nvic.h | 20 +--- .../TARGET_STM32F401xC/device/cmsis_nvic.c | 55 ---------- .../TARGET_STM32F401xC/device/cmsis_nvic.h | 20 +--- .../TARGET_STM32F401xE/device/cmsis_nvic.c | 55 ---------- .../TARGET_STM32F401xE/device/cmsis_nvic.h | 20 +--- .../TARGET_STM32F407xG/device/cmsis_nvic.c | 55 ---------- .../TARGET_STM32F407xG/device/cmsis_nvic.h | 20 +--- .../TARGET_STM32F410xB/device/cmsis_nvic.c | 55 ---------- .../TARGET_STM32F410xB/device/cmsis_nvic.h | 20 +--- .../TARGET_STM32F411xE/device/cmsis_nvic.c | 55 ---------- .../TARGET_STM32F411xE/device/cmsis_nvic.h | 20 +--- .../TARGET_STM32F412xG/device/cmsis_nvic.c | 55 ---------- .../TARGET_STM32F412xG/device/cmsis_nvic.h | 16 +-- .../TARGET_STM32F429xI/device/cmsis_nvic.c | 55 ---------- .../TARGET_STM32F429xI/device/cmsis_nvic.h | 20 +--- .../TARGET_STM32F437xG/device/cmsis_nvic.c | 55 ---------- .../TARGET_STM32F437xG/device/cmsis_nvic.h | 17 +-- .../TARGET_STM32F439xI/device/cmsis_nvic.c | 55 ---------- .../TARGET_STM32F439xI/device/cmsis_nvic.h | 20 +--- .../TARGET_STM32F446xE/device/cmsis_nvic.c | 55 ---------- .../TARGET_STM32F446xE/device/cmsis_nvic.h | 20 +--- .../TARGET_STM32F469xI/device/cmsis_nvic.c | 55 ---------- .../TARGET_STM32F469xI/device/cmsis_nvic.h | 20 +--- .../device/cmsis_nvic.c | 55 ---------- .../device/cmsis_nvic.h | 20 +--- .../TARGET_STM32F746xG/device/cmsis_nvic.c | 55 ---------- .../TARGET_STM32F746xG/device/cmsis_nvic.h | 18 +-- .../TARGET_STM32F756xG/device/cmsis_nvic.c | 55 ---------- .../TARGET_STM32F756xG/device/cmsis_nvic.h | 20 +--- .../TARGET_STM32F767xI/device/cmsis_nvic.c | 55 ---------- .../TARGET_STM32F767xI/device/cmsis_nvic.h | 20 +--- .../TARGET_STM32F769xI/device/cmsis_nvic.c | 55 ---------- .../TARGET_STM32F769xI/device/cmsis_nvic.h | 20 +--- .../TARGET_DISCO_L053C8/device/cmsis_nvic.c | 55 ---------- .../TARGET_DISCO_L053C8/device/cmsis_nvic.h | 20 +--- .../device/cmsis_nvic.c | 55 ---------- .../device/cmsis_nvic.h | 15 +-- .../TARGET_NUCLEO_L011K4/device/cmsis_nvic.c | 55 ---------- .../TARGET_NUCLEO_L011K4/device/cmsis_nvic.h | 20 +--- .../TARGET_NUCLEO_L031K6/device/cmsis_nvic.c | 55 ---------- .../TARGET_NUCLEO_L031K6/device/cmsis_nvic.h | 18 +-- .../TARGET_NUCLEO_L053R8/device/cmsis_nvic.c | 55 ---------- .../TARGET_NUCLEO_L053R8/device/cmsis_nvic.h | 20 +--- .../TARGET_NUCLEO_L073RZ/device/cmsis_nvic.c | 55 ---------- .../TARGET_NUCLEO_L073RZ/device/cmsis_nvic.h | 20 +--- .../TARGET_MOTE_L152RC/device/cmsis_nvic.c | 55 ---------- .../TARGET_MOTE_L152RC/device/cmsis_nvic.h | 20 +--- .../TARGET_NUCLEO_L152RE/device/cmsis_nvic.c | 55 ---------- .../TARGET_NUCLEO_L152RE/device/cmsis_nvic.h | 20 +--- .../TARGET_NZ32_SC151/device/cmsis_nvic.c | 55 ---------- .../TARGET_NZ32_SC151/device/cmsis_nvic.h | 20 +--- .../TARGET_XDOT_L151CC/device/cmsis_nvic.c | 55 ---------- .../TARGET_XDOT_L151CC/device/cmsis_nvic.h | 20 +--- .../TARGET_STM32L432xC/device/cmsis_nvic.c | 55 ---------- .../TARGET_STM32L432xC/device/cmsis_nvic.h | 20 +--- .../TARGET_STM32L476xG/device/cmsis_nvic.c | 55 ---------- .../TARGET_STM32L476xG/device/cmsis_nvic.h | 20 +--- .../TARGET_STM32L486xG/device/cmsis_nvic.c | 55 ---------- .../TARGET_STM32L486xG/device/cmsis_nvic.h | 20 +--- .../TARGET_EFM32/common/cmsis_nvic.c | 47 -------- .../TARGET_EFM32/common/cmsis_nvic.h | 31 ++---- .../TARGET_W7500x/device/cmsis_nvic.c | 47 -------- .../TARGET_W7500x/device/cmsis_nvic.h | 17 +-- .../TARGET_HI2110/device/cmsis_nvic.c | 50 --------- .../TARGET_HI2110/device/cmsis_nvic.h | 18 +-- 200 files changed, 424 insertions(+), 6988 deletions(-) delete mode 100644 targets/TARGET_ARM_SSG/TARGET_BEETLE/device/cmsis_nvic.c delete mode 100644 targets/TARGET_ARM_SSG/TARGET_IOTSS/TARGET_IOTSS_BEID/device/cmsis_nvic.c delete mode 100644 targets/TARGET_ARM_SSG/TARGET_MPS2/TARGET_MPS2_M0/device/cmsis_nvic.c delete mode 100644 targets/TARGET_ARM_SSG/TARGET_MPS2/TARGET_MPS2_M0P/device/cmsis_nvic.c delete mode 100644 targets/TARGET_ARM_SSG/TARGET_MPS2/TARGET_MPS2_M3/device/cmsis_nvic.c delete mode 100644 targets/TARGET_ARM_SSG/TARGET_MPS2/TARGET_MPS2_M4/device/cmsis_nvic.c delete mode 100644 targets/TARGET_ARM_SSG/TARGET_MPS2/TARGET_MPS2_M7/device/cmsis_nvic.c delete mode 100644 targets/TARGET_Atmel/TARGET_SAM_CortexM0P/TARGET_SAMD21/device/cmsis_nvic.c delete mode 100644 targets/TARGET_Atmel/TARGET_SAM_CortexM0P/TARGET_SAML21/device/cmsis_nvic.c delete mode 100644 targets/TARGET_Atmel/TARGET_SAM_CortexM0P/TARGET_SAMR21/device/cmsis_nvic.c delete mode 100644 targets/TARGET_Atmel/TARGET_SAM_CortexM4/TARGET_SAMG55/device/cmsis_nvic.c delete mode 100644 targets/TARGET_Freescale/TARGET_K20XX/TARGET_K20D50M/device/cmsis_nvic.c delete mode 100644 targets/TARGET_Freescale/TARGET_K20XX/TARGET_TEENSY3_1/device/cmsis_nvic.c delete mode 100644 targets/TARGET_Freescale/TARGET_KLXX/TARGET_KL05Z/device/cmsis_nvic.c delete mode 100644 targets/TARGET_Freescale/TARGET_KLXX/TARGET_KL25Z/device/cmsis_nvic.c delete mode 100644 targets/TARGET_Freescale/TARGET_KLXX/TARGET_KL26Z/device/cmsis_nvic.c delete mode 100644 targets/TARGET_Freescale/TARGET_KLXX/TARGET_KL46Z/device/cmsis_nvic.c delete mode 100644 targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/device/cmsis_nvic.c delete mode 100644 targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K82F/device/cmsis_nvic.c delete mode 100644 targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL27Z/device/cmsis_nvic.c delete mode 100644 targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL43Z/device/cmsis_nvic.c delete mode 100644 targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL82Z/device/cmsis_nvic.c delete mode 100644 targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KW24D/device/cmsis_nvic.c delete mode 100644 targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KW41Z/device/cmsis_nvic.c delete mode 100644 targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K22F/TARGET_MCU_K22F512/device/cmsis_nvic.c delete mode 100644 targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K24F/TARGET_MCU_K24F1M/device/cmsis_nvic.c delete mode 100644 targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/device/cmsis_nvic.c delete mode 100644 targets/TARGET_Maxim/TARGET_MAX32600/device/cmsis_nvic.c create mode 100644 targets/TARGET_Maxim/TARGET_MAX32600/device/device_nvic.c delete mode 100644 targets/TARGET_Maxim/TARGET_MAX32610/device/cmsis_nvic.c create mode 100644 targets/TARGET_Maxim/TARGET_MAX32610/device/device_nvic.c delete mode 100644 targets/TARGET_Maxim/TARGET_MAX32620/device/cmsis_nvic.c create mode 100644 targets/TARGET_Maxim/TARGET_MAX32620/device/device_nvic.c delete mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/device/cmsis_nvic.c create mode 100644 targets/TARGET_Maxim/TARGET_MAX32625/device/device_nvic.c create mode 100644 targets/TARGET_Maxim/TARGET_MAX32630/device/device_nvic.c delete mode 100644 targets/TARGET_Maxim/TARGET_MAX32630/mxc/nvic_table.c delete mode 100644 targets/TARGET_NORDIC/TARGET_MCU_NRF51822/device/cmsis_nvic.c delete mode 100644 targets/TARGET_NUVOTON/TARGET_M451/device/cmsis_nvic.c delete mode 100644 targets/TARGET_NUVOTON/TARGET_NUC472/device/cmsis_nvic.c delete mode 100644 targets/TARGET_NXP/TARGET_LPC11U6X/device/cmsis_nvic.c delete mode 100644 targets/TARGET_NXP/TARGET_LPC11UXX/device/cmsis_nvic.c delete mode 100644 targets/TARGET_NXP/TARGET_LPC11XX_11CXX/device/cmsis_nvic.c delete mode 100644 targets/TARGET_NXP/TARGET_LPC13XX/device/cmsis_nvic.c delete mode 100644 targets/TARGET_NXP/TARGET_LPC15XX/device/cmsis_nvic.c delete mode 100644 targets/TARGET_NXP/TARGET_LPC176X/device/cmsis_nvic.c delete mode 100644 targets/TARGET_NXP/TARGET_LPC408X/device/cmsis_nvic.c delete mode 100644 targets/TARGET_NXP/TARGET_LPC43XX/device/cmsis_nvic.c delete mode 100644 targets/TARGET_NXP/TARGET_LPC81X/device/cmsis_nvic.c delete mode 100644 targets/TARGET_NXP/TARGET_LPC82X/device/cmsis_nvic.c delete mode 100644 targets/TARGET_ONSEMI/TARGET_NCS36510/device/cmsis_nvic.c delete mode 100644 targets/TARGET_STM/TARGET_STM32F0/TARGET_DISCO_F051R8/device/cmsis_nvic.c delete mode 100644 targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F030R8/device/cmsis_nvic.c delete mode 100644 targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F031K6/device/cmsis_nvic.c delete mode 100644 targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F042K6/device/cmsis_nvic.c delete mode 100644 targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F070RB/device/cmsis_nvic.c delete mode 100644 targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F072RB/device/cmsis_nvic.c delete mode 100644 targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F091RC/device/cmsis_nvic.c delete mode 100644 targets/TARGET_STM/TARGET_STM32F1/TARGET_BLUEPILL_F103C8/device/cmsis_nvic.c delete mode 100644 targets/TARGET_STM/TARGET_STM32F1/TARGET_DISCO_F100RB/device/cmsis_nvic.c delete mode 100644 targets/TARGET_STM/TARGET_STM32F1/TARGET_NUCLEO_F103RB/device/cmsis_nvic.c delete mode 100644 targets/TARGET_STM/TARGET_STM32F2/TARGET_NUCLEO_F207ZG/device/cmsis_nvic.c delete mode 100644 targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F302x8/device/cmsis_nvic.c delete mode 100644 targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F303x8/device/cmsis_nvic.c delete mode 100644 targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F303xC/device/cmsis_nvic.c delete mode 100644 targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F303xE/device/cmsis_nvic.c delete mode 100644 targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F334x8/device/cmsis_nvic.c delete mode 100644 targets/TARGET_STM/TARGET_STM32F4/TARGET_MTS_DRAGONFLY_F411RE/device/cmsis_nvic.c delete mode 100644 targets/TARGET_STM/TARGET_STM32F4/TARGET_MTS_MDOT_F405RG/device/cmsis_nvic.c delete mode 100644 targets/TARGET_STM/TARGET_STM32F4/TARGET_MTS_MDOT_F411RE/device/cmsis_nvic.c delete mode 100644 targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F401xC/device/cmsis_nvic.c delete mode 100644 targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F401xE/device/cmsis_nvic.c delete mode 100644 targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F407xG/device/cmsis_nvic.c delete mode 100644 targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F410xB/device/cmsis_nvic.c delete mode 100644 targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F411xE/device/cmsis_nvic.c delete mode 100644 targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F412xG/device/cmsis_nvic.c delete mode 100644 targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F429xI/device/cmsis_nvic.c delete mode 100644 targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F437xG/device/cmsis_nvic.c delete mode 100644 targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F439xI/device/cmsis_nvic.c delete mode 100644 targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F446xE/device/cmsis_nvic.c delete mode 100644 targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F469xI/device/cmsis_nvic.c delete mode 100644 targets/TARGET_STM/TARGET_STM32F4/TARGET_UBLOX_EVK_ODIN_W2/device/cmsis_nvic.c delete mode 100644 targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F746xG/device/cmsis_nvic.c delete mode 100644 targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F756xG/device/cmsis_nvic.c delete mode 100644 targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F767xI/device/cmsis_nvic.c delete mode 100644 targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F769xI/device/cmsis_nvic.c delete mode 100644 targets/TARGET_STM/TARGET_STM32L0/TARGET_DISCO_L053C8/device/cmsis_nvic.c delete mode 100644 targets/TARGET_STM/TARGET_STM32L0/TARGET_DISCO_L072CZ_LRWAN1/device/cmsis_nvic.c delete mode 100644 targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L011K4/device/cmsis_nvic.c delete mode 100644 targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L031K6/device/cmsis_nvic.c delete mode 100644 targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L053R8/device/cmsis_nvic.c delete mode 100644 targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L073RZ/device/cmsis_nvic.c delete mode 100644 targets/TARGET_STM/TARGET_STM32L1/TARGET_MOTE_L152RC/device/cmsis_nvic.c delete mode 100644 targets/TARGET_STM/TARGET_STM32L1/TARGET_NUCLEO_L152RE/device/cmsis_nvic.c delete mode 100644 targets/TARGET_STM/TARGET_STM32L1/TARGET_NZ32_SC151/device/cmsis_nvic.c delete mode 100644 targets/TARGET_STM/TARGET_STM32L1/TARGET_XDOT_L151CC/device/cmsis_nvic.c delete mode 100644 targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L432xC/device/cmsis_nvic.c delete mode 100644 targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/device/cmsis_nvic.c delete mode 100644 targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L486xG/device/cmsis_nvic.c delete mode 100644 targets/TARGET_Silicon_Labs/TARGET_EFM32/common/cmsis_nvic.c delete mode 100644 targets/TARGET_WIZNET/TARGET_W7500x/device/cmsis_nvic.c delete mode 100644 targets/TARGET_ublox/TARGET_HI2110/device/cmsis_nvic.c diff --git a/targets/TARGET_ARM_SSG/TARGET_BEETLE/device/cmsis_nvic.c b/targets/TARGET_ARM_SSG/TARGET_BEETLE/device/cmsis_nvic.c deleted file mode 100644 index c0bc3280f3f..00000000000 --- a/targets/TARGET_ARM_SSG/TARGET_BEETLE/device/cmsis_nvic.c +++ /dev/null @@ -1,43 +0,0 @@ -/* mbed Microcontroller Library - * Copyright (c) 2015-2016 ARM Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/* - * CMSIS-style functionality to support dynamic vectors - */ -#include "cmsis_nvic.h" - -#define NVIC_RAM_VECTOR_ADDRESS (0x20000000) //Location of vectors in RAM -#define NVIC_FLASH_VECTOR_ADDRESS (0x00000000) //Initial vector position in flash - -void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { - uint32_t *vectors = (uint32_t*)SCB->VTOR; - uint32_t i; - - // Copy and switch to dynamic vectors if the first time called - if (SCB->VTOR == NVIC_FLASH_VECTOR_ADDRESS) { - uint32_t *old_vectors = vectors; - vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS; - for (i=0; iVTOR = (uint32_t)NVIC_RAM_VECTOR_ADDRESS; - } - vectors[IRQn + NVIC_USER_IRQ_OFFSET] = vector; -} - -uint32_t __NVIC_GetVector(IRQn_Type IRQn) { - uint32_t *vectors = (uint32_t*)SCB->VTOR; - return vectors[IRQn + NVIC_USER_IRQ_OFFSET]; -} diff --git a/targets/TARGET_ARM_SSG/TARGET_BEETLE/device/cmsis_nvic.h b/targets/TARGET_ARM_SSG/TARGET_BEETLE/device/cmsis_nvic.h index 37a863866b0..00473b4e3c4 100644 --- a/targets/TARGET_ARM_SSG/TARGET_BEETLE/device/cmsis_nvic.h +++ b/targets/TARGET_ARM_SSG/TARGET_BEETLE/device/cmsis_nvic.h @@ -13,27 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -/* - * CMSIS-style functionality to support dynamic vectors - */ #ifndef MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H -#include "cmsis.h" - -#define NVIC_NUM_VECTORS (16 + 48) -#define NVIC_USER_IRQ_OFFSET 16 - -#ifdef __cplusplus -extern "C" { -#endif - -void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t __NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +#define NVIC_NUM_VECTORS (16 + 48) +#define NVIC_RAM_VECTOR_ADDRESS 0x20000000 //Location of vectors in RAM #endif diff --git a/targets/TARGET_ARM_SSG/TARGET_IOTSS/TARGET_IOTSS_BEID/device/cmsis_nvic.c b/targets/TARGET_ARM_SSG/TARGET_IOTSS/TARGET_IOTSS_BEID/device/cmsis_nvic.c deleted file mode 100644 index 9ac558cceb3..00000000000 --- a/targets/TARGET_ARM_SSG/TARGET_IOTSS/TARGET_IOTSS_BEID/device/cmsis_nvic.c +++ /dev/null @@ -1,58 +0,0 @@ -/* MPS2 CMSIS Library -* -* Copyright (c) 2006-2016 ARM Limited -* All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, -* this list of conditions and the following disclaimer. -* -* 2. Redistributions in binary form must reproduce the above copyright notice, -* this list of conditions and the following disclaimer in the documentation -* and/or other materials provided with the distribution. -* -* 3. Neither the name of the copyright holder nor the names of its contributors -* may be used to endorse or promote products derived from this software without -* specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. -******************************************************************************* -* CMSIS-style functionality to support dynamic vectors -*******************************************************************************/ -#include "cmsis_nvic.h" - -#define NVIC_RAM_VECTOR_ADDRESS (0x20000000) // Location of vectors in RAM -#define NVIC_FLASH_VECTOR_ADDRESS (0x00000000) // Initial vector position in flash - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { - uint32_t *vectors = (uint32_t*)SCB->VTOR; - uint32_t i; - - // Copy and switch to dynamic vectors if the first time called - if (SCB->VTOR == NVIC_FLASH_VECTOR_ADDRESS) { - uint32_t *old_vectors = vectors; - vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS; - for (i=0; iVTOR = (uint32_t)NVIC_RAM_VECTOR_ADDRESS; - } - vectors[IRQn + NVIC_USER_IRQ_OFFSET] = vector; -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) { - uint32_t *vectors = (uint32_t*)SCB->VTOR; - return vectors[IRQn + NVIC_USER_IRQ_OFFSET]; -} diff --git a/targets/TARGET_ARM_SSG/TARGET_IOTSS/TARGET_IOTSS_BEID/device/cmsis_nvic.h b/targets/TARGET_ARM_SSG/TARGET_IOTSS/TARGET_IOTSS_BEID/device/cmsis_nvic.h index f8c6e871cb4..b3a8842e00c 100644 --- a/targets/TARGET_ARM_SSG/TARGET_IOTSS/TARGET_IOTSS_BEID/device/cmsis_nvic.h +++ b/targets/TARGET_ARM_SSG/TARGET_IOTSS/TARGET_IOTSS_BEID/device/cmsis_nvic.h @@ -28,27 +28,12 @@ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. -******************************************************************************* -* CMSIS-style functionality to support dynamic vectors *******************************************************************************/ #ifndef MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H -#include "cmsis.h" - -#define NVIC_NUM_VECTORS (16 + 64) -#define NVIC_USER_IRQ_OFFSET 16 - -#ifdef __cplusplus -extern "C" { -#endif - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +#define NVIC_NUM_VECTORS (16 + 64) +#define NVIC_RAM_VECTOR_ADDRESS 0x20000000 // Location of vectors in RAM #endif diff --git a/targets/TARGET_ARM_SSG/TARGET_MPS2/TARGET_MPS2_M0/device/cmsis_nvic.c b/targets/TARGET_ARM_SSG/TARGET_MPS2/TARGET_MPS2_M0/device/cmsis_nvic.c deleted file mode 100644 index 159fce69aeb..00000000000 --- a/targets/TARGET_ARM_SSG/TARGET_MPS2/TARGET_MPS2_M0/device/cmsis_nvic.c +++ /dev/null @@ -1,54 +0,0 @@ -/* MPS2 CMSIS Library -* -* Copyright (c) 2006-2016 ARM Limited -* All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, -* this list of conditions and the following disclaimer. -* -* 2. Redistributions in binary form must reproduce the above copyright notice, -* this list of conditions and the following disclaimer in the documentation -* and/or other materials provided with the distribution. -* -* 3. Neither the name of the copyright holder nor the names of its contributors -* may be used to endorse or promote products derived from this software without -* specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. -******************************************************************************* -* CMSIS-style functionality to support dynamic vectors -*******************************************************************************/ -#include "cmsis_nvic.h" - -#define NVIC_RAM_VECTOR_ADDRESS (0x20000000) // Location of vectors in RAM -#define NVIC_FLASH_VECTOR_ADDRESS (0x00000000) // Initial vector position in flash - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { - // int i; - // Space for dynamic vectors, initialised to allocate in R/W - static volatile uint32_t* vectors = (uint32_t*)NVIC_FLASH_VECTOR_ADDRESS; - - // Set the vector - vectors[IRQn + 16] = vector; -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) { - // We can always read vectors at 0x0, as the addresses are remapped - uint32_t *vectors = (uint32_t*)NVIC_FLASH_VECTOR_ADDRESS; - - // Return the vector - return vectors[IRQn + 16]; -} diff --git a/targets/TARGET_ARM_SSG/TARGET_MPS2/TARGET_MPS2_M0/device/cmsis_nvic.h b/targets/TARGET_ARM_SSG/TARGET_MPS2/TARGET_MPS2_M0/device/cmsis_nvic.h index 8ad5fdcd634..e3cd294bf94 100644 --- a/targets/TARGET_ARM_SSG/TARGET_MPS2/TARGET_MPS2_M0/device/cmsis_nvic.h +++ b/targets/TARGET_ARM_SSG/TARGET_MPS2/TARGET_MPS2_M0/device/cmsis_nvic.h @@ -28,27 +28,12 @@ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. -******************************************************************************* -* CMSIS-style functionality to support dynamic vectors *******************************************************************************/ #ifndef MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H -#include "cmsis.h" - -#define NVIC_NUM_VECTORS (16 + 48) -#define NVIC_USER_IRQ_OFFSET 16 - -#ifdef __cplusplus -extern "C" { -#endif - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +#define NVIC_NUM_VECTORS (16 + 48) +#define NVIC_RAM_VECTOR_ADDRESS 0x20000000 // Location of vectors in RAM #endif diff --git a/targets/TARGET_ARM_SSG/TARGET_MPS2/TARGET_MPS2_M0P/device/cmsis_nvic.c b/targets/TARGET_ARM_SSG/TARGET_MPS2/TARGET_MPS2_M0P/device/cmsis_nvic.c deleted file mode 100644 index 159fce69aeb..00000000000 --- a/targets/TARGET_ARM_SSG/TARGET_MPS2/TARGET_MPS2_M0P/device/cmsis_nvic.c +++ /dev/null @@ -1,54 +0,0 @@ -/* MPS2 CMSIS Library -* -* Copyright (c) 2006-2016 ARM Limited -* All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, -* this list of conditions and the following disclaimer. -* -* 2. Redistributions in binary form must reproduce the above copyright notice, -* this list of conditions and the following disclaimer in the documentation -* and/or other materials provided with the distribution. -* -* 3. Neither the name of the copyright holder nor the names of its contributors -* may be used to endorse or promote products derived from this software without -* specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. -******************************************************************************* -* CMSIS-style functionality to support dynamic vectors -*******************************************************************************/ -#include "cmsis_nvic.h" - -#define NVIC_RAM_VECTOR_ADDRESS (0x20000000) // Location of vectors in RAM -#define NVIC_FLASH_VECTOR_ADDRESS (0x00000000) // Initial vector position in flash - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { - // int i; - // Space for dynamic vectors, initialised to allocate in R/W - static volatile uint32_t* vectors = (uint32_t*)NVIC_FLASH_VECTOR_ADDRESS; - - // Set the vector - vectors[IRQn + 16] = vector; -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) { - // We can always read vectors at 0x0, as the addresses are remapped - uint32_t *vectors = (uint32_t*)NVIC_FLASH_VECTOR_ADDRESS; - - // Return the vector - return vectors[IRQn + 16]; -} diff --git a/targets/TARGET_ARM_SSG/TARGET_MPS2/TARGET_MPS2_M0P/device/cmsis_nvic.h b/targets/TARGET_ARM_SSG/TARGET_MPS2/TARGET_MPS2_M0P/device/cmsis_nvic.h index 8ad5fdcd634..e3cd294bf94 100644 --- a/targets/TARGET_ARM_SSG/TARGET_MPS2/TARGET_MPS2_M0P/device/cmsis_nvic.h +++ b/targets/TARGET_ARM_SSG/TARGET_MPS2/TARGET_MPS2_M0P/device/cmsis_nvic.h @@ -28,27 +28,12 @@ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. -******************************************************************************* -* CMSIS-style functionality to support dynamic vectors *******************************************************************************/ #ifndef MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H -#include "cmsis.h" - -#define NVIC_NUM_VECTORS (16 + 48) -#define NVIC_USER_IRQ_OFFSET 16 - -#ifdef __cplusplus -extern "C" { -#endif - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +#define NVIC_NUM_VECTORS (16 + 48) +#define NVIC_RAM_VECTOR_ADDRESS 0x20000000 // Location of vectors in RAM #endif diff --git a/targets/TARGET_ARM_SSG/TARGET_MPS2/TARGET_MPS2_M3/device/cmsis_nvic.c b/targets/TARGET_ARM_SSG/TARGET_MPS2/TARGET_MPS2_M3/device/cmsis_nvic.c deleted file mode 100644 index 9ac558cceb3..00000000000 --- a/targets/TARGET_ARM_SSG/TARGET_MPS2/TARGET_MPS2_M3/device/cmsis_nvic.c +++ /dev/null @@ -1,58 +0,0 @@ -/* MPS2 CMSIS Library -* -* Copyright (c) 2006-2016 ARM Limited -* All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, -* this list of conditions and the following disclaimer. -* -* 2. Redistributions in binary form must reproduce the above copyright notice, -* this list of conditions and the following disclaimer in the documentation -* and/or other materials provided with the distribution. -* -* 3. Neither the name of the copyright holder nor the names of its contributors -* may be used to endorse or promote products derived from this software without -* specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. -******************************************************************************* -* CMSIS-style functionality to support dynamic vectors -*******************************************************************************/ -#include "cmsis_nvic.h" - -#define NVIC_RAM_VECTOR_ADDRESS (0x20000000) // Location of vectors in RAM -#define NVIC_FLASH_VECTOR_ADDRESS (0x00000000) // Initial vector position in flash - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { - uint32_t *vectors = (uint32_t*)SCB->VTOR; - uint32_t i; - - // Copy and switch to dynamic vectors if the first time called - if (SCB->VTOR == NVIC_FLASH_VECTOR_ADDRESS) { - uint32_t *old_vectors = vectors; - vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS; - for (i=0; iVTOR = (uint32_t)NVIC_RAM_VECTOR_ADDRESS; - } - vectors[IRQn + NVIC_USER_IRQ_OFFSET] = vector; -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) { - uint32_t *vectors = (uint32_t*)SCB->VTOR; - return vectors[IRQn + NVIC_USER_IRQ_OFFSET]; -} diff --git a/targets/TARGET_ARM_SSG/TARGET_MPS2/TARGET_MPS2_M3/device/cmsis_nvic.h b/targets/TARGET_ARM_SSG/TARGET_MPS2/TARGET_MPS2_M3/device/cmsis_nvic.h index 8ad5fdcd634..e3cd294bf94 100644 --- a/targets/TARGET_ARM_SSG/TARGET_MPS2/TARGET_MPS2_M3/device/cmsis_nvic.h +++ b/targets/TARGET_ARM_SSG/TARGET_MPS2/TARGET_MPS2_M3/device/cmsis_nvic.h @@ -28,27 +28,12 @@ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. -******************************************************************************* -* CMSIS-style functionality to support dynamic vectors *******************************************************************************/ #ifndef MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H -#include "cmsis.h" - -#define NVIC_NUM_VECTORS (16 + 48) -#define NVIC_USER_IRQ_OFFSET 16 - -#ifdef __cplusplus -extern "C" { -#endif - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +#define NVIC_NUM_VECTORS (16 + 48) +#define NVIC_RAM_VECTOR_ADDRESS 0x20000000 // Location of vectors in RAM #endif diff --git a/targets/TARGET_ARM_SSG/TARGET_MPS2/TARGET_MPS2_M4/device/cmsis_nvic.c b/targets/TARGET_ARM_SSG/TARGET_MPS2/TARGET_MPS2_M4/device/cmsis_nvic.c deleted file mode 100644 index 9ac558cceb3..00000000000 --- a/targets/TARGET_ARM_SSG/TARGET_MPS2/TARGET_MPS2_M4/device/cmsis_nvic.c +++ /dev/null @@ -1,58 +0,0 @@ -/* MPS2 CMSIS Library -* -* Copyright (c) 2006-2016 ARM Limited -* All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, -* this list of conditions and the following disclaimer. -* -* 2. Redistributions in binary form must reproduce the above copyright notice, -* this list of conditions and the following disclaimer in the documentation -* and/or other materials provided with the distribution. -* -* 3. Neither the name of the copyright holder nor the names of its contributors -* may be used to endorse or promote products derived from this software without -* specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. -******************************************************************************* -* CMSIS-style functionality to support dynamic vectors -*******************************************************************************/ -#include "cmsis_nvic.h" - -#define NVIC_RAM_VECTOR_ADDRESS (0x20000000) // Location of vectors in RAM -#define NVIC_FLASH_VECTOR_ADDRESS (0x00000000) // Initial vector position in flash - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { - uint32_t *vectors = (uint32_t*)SCB->VTOR; - uint32_t i; - - // Copy and switch to dynamic vectors if the first time called - if (SCB->VTOR == NVIC_FLASH_VECTOR_ADDRESS) { - uint32_t *old_vectors = vectors; - vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS; - for (i=0; iVTOR = (uint32_t)NVIC_RAM_VECTOR_ADDRESS; - } - vectors[IRQn + NVIC_USER_IRQ_OFFSET] = vector; -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) { - uint32_t *vectors = (uint32_t*)SCB->VTOR; - return vectors[IRQn + NVIC_USER_IRQ_OFFSET]; -} diff --git a/targets/TARGET_ARM_SSG/TARGET_MPS2/TARGET_MPS2_M4/device/cmsis_nvic.h b/targets/TARGET_ARM_SSG/TARGET_MPS2/TARGET_MPS2_M4/device/cmsis_nvic.h index 8ad5fdcd634..e3cd294bf94 100644 --- a/targets/TARGET_ARM_SSG/TARGET_MPS2/TARGET_MPS2_M4/device/cmsis_nvic.h +++ b/targets/TARGET_ARM_SSG/TARGET_MPS2/TARGET_MPS2_M4/device/cmsis_nvic.h @@ -28,27 +28,12 @@ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. -******************************************************************************* -* CMSIS-style functionality to support dynamic vectors *******************************************************************************/ #ifndef MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H -#include "cmsis.h" - -#define NVIC_NUM_VECTORS (16 + 48) -#define NVIC_USER_IRQ_OFFSET 16 - -#ifdef __cplusplus -extern "C" { -#endif - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +#define NVIC_NUM_VECTORS (16 + 48) +#define NVIC_RAM_VECTOR_ADDRESS 0x20000000 // Location of vectors in RAM #endif diff --git a/targets/TARGET_ARM_SSG/TARGET_MPS2/TARGET_MPS2_M7/device/cmsis_nvic.c b/targets/TARGET_ARM_SSG/TARGET_MPS2/TARGET_MPS2_M7/device/cmsis_nvic.c deleted file mode 100644 index f42fb77ad22..00000000000 --- a/targets/TARGET_ARM_SSG/TARGET_MPS2/TARGET_MPS2_M7/device/cmsis_nvic.c +++ /dev/null @@ -1,58 +0,0 @@ -/* MPS2 CMSIS Library -* -* Copyright (c) 2006-2015 ARM Limited -* All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, -* this list of conditions and the following disclaimer. -* -* 2. Redistributions in binary form must reproduce the above copyright notice, -* this list of conditions and the following disclaimer in the documentation -* and/or other materials provided with the distribution. -* -* 3. Neither the name of the copyright holder nor the names of its contributors -* may be used to endorse or promote products derived from this software without -* specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. -******************************************************************************* -* CMSIS-style functionality to support dynamic vectors -*******************************************************************************/ -#include "cmsis_nvic.h" - -#define NVIC_RAM_VECTOR_ADDRESS (0x20000000) // Location of vectors in RAM -#define NVIC_FLASH_VECTOR_ADDRESS (0x00000000) // Initial vector position in flash - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { - uint32_t *vectors = (uint32_t*)SCB->VTOR; - uint32_t i; - - // Copy and switch to dynamic vectors if the first time called - if (SCB->VTOR == NVIC_FLASH_VECTOR_ADDRESS) { - uint32_t *old_vectors = vectors; - vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS; - for (i=0; iVTOR = (uint32_t)NVIC_RAM_VECTOR_ADDRESS; - } - vectors[IRQn + NVIC_USER_IRQ_OFFSET] = vector; -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) { - uint32_t *vectors = (uint32_t*)SCB->VTOR; - return vectors[IRQn + NVIC_USER_IRQ_OFFSET]; -} diff --git a/targets/TARGET_ARM_SSG/TARGET_MPS2/TARGET_MPS2_M7/device/cmsis_nvic.h b/targets/TARGET_ARM_SSG/TARGET_MPS2/TARGET_MPS2_M7/device/cmsis_nvic.h index 04f376f4e40..b530cb39a71 100644 --- a/targets/TARGET_ARM_SSG/TARGET_MPS2/TARGET_MPS2_M7/device/cmsis_nvic.h +++ b/targets/TARGET_ARM_SSG/TARGET_MPS2/TARGET_MPS2_M7/device/cmsis_nvic.h @@ -28,27 +28,12 @@ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. -******************************************************************************* -* CMSIS-style functionality to support dynamic vectors *******************************************************************************/ #ifndef MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H -#include "cmsis.h" - -#define NVIC_NUM_VECTORS (16 + 48) -#define NVIC_USER_IRQ_OFFSET 16 - -#ifdef __cplusplus -extern "C" { -#endif - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +#define NVIC_NUM_VECTORS (16 + 48) +#define NVIC_RAM_VECTOR_ADDRESS 0x20000000 // Location of vectors in RAM #endif diff --git a/targets/TARGET_Atmel/TARGET_SAM_CortexM0P/TARGET_SAMD21/device/cmsis_nvic.c b/targets/TARGET_Atmel/TARGET_SAM_CortexM0P/TARGET_SAMD21/device/cmsis_nvic.c deleted file mode 100644 index 70207a8936c..00000000000 --- a/targets/TARGET_Atmel/TARGET_SAM_CortexM0P/TARGET_SAMD21/device/cmsis_nvic.c +++ /dev/null @@ -1,57 +0,0 @@ -/* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors - ******************************************************************************* - * Copyright (c) 2011 ARM Limited. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of ARM Limited nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "cmsis_nvic.h" - -#define NVIC_RAM_VECTOR_ADDRESS (0x20000000) // Vectors positioned at start of RAM -#define NVIC_FLASH_VECTOR_ADDRESS (0x0) // Initial vector position in flash - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) -{ - uint32_t *vectors = (uint32_t*)SCB->VTOR; - uint32_t i; - - // Copy and switch to dynamic vectors if the first time called - if (SCB->VTOR == NVIC_FLASH_VECTOR_ADDRESS) { - uint32_t *old_vectors = vectors; - vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS; - for (i=0; iVTOR = (uint32_t)NVIC_RAM_VECTOR_ADDRESS; - } - vectors[IRQn + 16] = vector; -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) -{ - uint32_t *vectors = (uint32_t*)SCB->VTOR; - return vectors[IRQn + 16]; -} diff --git a/targets/TARGET_Atmel/TARGET_SAM_CortexM0P/TARGET_SAMD21/device/cmsis_nvic.h b/targets/TARGET_Atmel/TARGET_SAM_CortexM0P/TARGET_SAMD21/device/cmsis_nvic.h index ce2eff93d34..3d787468a37 100644 --- a/targets/TARGET_Atmel/TARGET_SAM_CortexM0P/TARGET_SAMD21/device/cmsis_nvic.h +++ b/targets/TARGET_Atmel/TARGET_SAM_CortexM0P/TARGET_SAMD21/device/cmsis_nvic.h @@ -1,5 +1,4 @@ /* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors ******************************************************************************* * Copyright (c) 2011 ARM Limited. All rights reserved. * All rights reserved. @@ -32,20 +31,7 @@ #ifndef MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H -#define NVIC_NUM_VECTORS (16 +29) // CORE + MCU Peripherals -#define NVIC_USER_IRQ_OFFSET 16 - -#include "cmsis.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +#define NVIC_NUM_VECTORS (16 + 29) // CORE + MCU Peripherals +#define NVIC_RAM_VECTOR_ADDRESS 0x20000000 // Vectors positioned at start of RAM #endif diff --git a/targets/TARGET_Atmel/TARGET_SAM_CortexM0P/TARGET_SAML21/device/cmsis_nvic.c b/targets/TARGET_Atmel/TARGET_SAM_CortexM0P/TARGET_SAML21/device/cmsis_nvic.c deleted file mode 100644 index c9e1799d28c..00000000000 --- a/targets/TARGET_Atmel/TARGET_SAM_CortexM0P/TARGET_SAML21/device/cmsis_nvic.c +++ /dev/null @@ -1,58 +0,0 @@ -/* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors - ******************************************************************************* - * Copyright (c) 2011 ARM Limited. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of ARM Limited nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "cmsis_nvic.h" - -#define NVIC_RAM_VECTOR_ADDRESS (0x20000000) // Vectors positioned at start of RAM -//extern uint32_t _sdvectors; -#define NVIC_FLASH_VECTOR_ADDRESS (0x0) // Initial vector position in flash - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) -{ - uint32_t *vectors = (uint32_t*)SCB->VTOR; - uint32_t i; - - // Copy and switch to dynamic vectors if the first time called - if (SCB->VTOR == NVIC_FLASH_VECTOR_ADDRESS) { - uint32_t *old_vectors = vectors; - vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS; - for (i=0; iVTOR = (uint32_t)NVIC_RAM_VECTOR_ADDRESS; - } - vectors[IRQn + 16] = vector; -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) -{ - uint32_t *vectors = (uint32_t*)SCB->VTOR; - return vectors[IRQn + 16]; -} diff --git a/targets/TARGET_Atmel/TARGET_SAM_CortexM0P/TARGET_SAML21/device/cmsis_nvic.h b/targets/TARGET_Atmel/TARGET_SAM_CortexM0P/TARGET_SAML21/device/cmsis_nvic.h index ce2eff93d34..3d787468a37 100644 --- a/targets/TARGET_Atmel/TARGET_SAM_CortexM0P/TARGET_SAML21/device/cmsis_nvic.h +++ b/targets/TARGET_Atmel/TARGET_SAM_CortexM0P/TARGET_SAML21/device/cmsis_nvic.h @@ -1,5 +1,4 @@ /* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors ******************************************************************************* * Copyright (c) 2011 ARM Limited. All rights reserved. * All rights reserved. @@ -32,20 +31,7 @@ #ifndef MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H -#define NVIC_NUM_VECTORS (16 +29) // CORE + MCU Peripherals -#define NVIC_USER_IRQ_OFFSET 16 - -#include "cmsis.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +#define NVIC_NUM_VECTORS (16 + 29) // CORE + MCU Peripherals +#define NVIC_RAM_VECTOR_ADDRESS 0x20000000 // Vectors positioned at start of RAM #endif diff --git a/targets/TARGET_Atmel/TARGET_SAM_CortexM0P/TARGET_SAMR21/device/cmsis_nvic.c b/targets/TARGET_Atmel/TARGET_SAM_CortexM0P/TARGET_SAMR21/device/cmsis_nvic.c deleted file mode 100644 index c9e1799d28c..00000000000 --- a/targets/TARGET_Atmel/TARGET_SAM_CortexM0P/TARGET_SAMR21/device/cmsis_nvic.c +++ /dev/null @@ -1,58 +0,0 @@ -/* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors - ******************************************************************************* - * Copyright (c) 2011 ARM Limited. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of ARM Limited nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "cmsis_nvic.h" - -#define NVIC_RAM_VECTOR_ADDRESS (0x20000000) // Vectors positioned at start of RAM -//extern uint32_t _sdvectors; -#define NVIC_FLASH_VECTOR_ADDRESS (0x0) // Initial vector position in flash - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) -{ - uint32_t *vectors = (uint32_t*)SCB->VTOR; - uint32_t i; - - // Copy and switch to dynamic vectors if the first time called - if (SCB->VTOR == NVIC_FLASH_VECTOR_ADDRESS) { - uint32_t *old_vectors = vectors; - vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS; - for (i=0; iVTOR = (uint32_t)NVIC_RAM_VECTOR_ADDRESS; - } - vectors[IRQn + 16] = vector; -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) -{ - uint32_t *vectors = (uint32_t*)SCB->VTOR; - return vectors[IRQn + 16]; -} diff --git a/targets/TARGET_Atmel/TARGET_SAM_CortexM0P/TARGET_SAMR21/device/cmsis_nvic.h b/targets/TARGET_Atmel/TARGET_SAM_CortexM0P/TARGET_SAMR21/device/cmsis_nvic.h index 6dd7e72f961..e53c6057f94 100644 --- a/targets/TARGET_Atmel/TARGET_SAM_CortexM0P/TARGET_SAMR21/device/cmsis_nvic.h +++ b/targets/TARGET_Atmel/TARGET_SAM_CortexM0P/TARGET_SAMR21/device/cmsis_nvic.h @@ -1,5 +1,4 @@ /* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors ******************************************************************************* * Copyright (c) 2011 ARM Limited. All rights reserved. * All rights reserved. @@ -32,20 +31,7 @@ #ifndef MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H -#define NVIC_NUM_VECTORS (16 +28) // CORE + MCU Peripherals -#define NVIC_USER_IRQ_OFFSET 16 - -#include "cmsis.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +#define NVIC_NUM_VECTORS (16 + 28) // CORE + MCU Peripherals +#define NVIC_RAM_VECTOR_ADDRESS 0x20000000 // Vectors positioned at start of RAM #endif diff --git a/targets/TARGET_Atmel/TARGET_SAM_CortexM4/TARGET_SAMG55/device/cmsis_nvic.c b/targets/TARGET_Atmel/TARGET_SAM_CortexM4/TARGET_SAMG55/device/cmsis_nvic.c deleted file mode 100644 index 1d08745a1c6..00000000000 --- a/targets/TARGET_Atmel/TARGET_SAM_CortexM4/TARGET_SAMG55/device/cmsis_nvic.c +++ /dev/null @@ -1,57 +0,0 @@ -/* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors - ******************************************************************************* - * Copyright (c) 2011 ARM Limited. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of ARM Limited nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "cmsis_nvic.h" - -#define NVIC_RAM_VECTOR_ADDRESS (0x20000000) // Vectors positioned at start of RAM -#define NVIC_FLASH_VECTOR_ADDRESS (0x00400000)// Initial vector position in flash - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) -{ - uint32_t *vectors = (uint32_t*)SCB->VTOR; - uint32_t i; - - // Copy and switch to dynamic vectors if the first time called - if (SCB->VTOR == NVIC_FLASH_VECTOR_ADDRESS) { - uint32_t *old_vectors = vectors; - vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS; - for (i=0; iVTOR = (uint32_t)NVIC_RAM_VECTOR_ADDRESS; - } - vectors[IRQn + 16] = vector; -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) -{ - uint32_t *vectors = (uint32_t*)SCB->VTOR; - return vectors[IRQn + 16]; -} diff --git a/targets/TARGET_Atmel/TARGET_SAM_CortexM4/TARGET_SAMG55/device/cmsis_nvic.h b/targets/TARGET_Atmel/TARGET_SAM_CortexM4/TARGET_SAMG55/device/cmsis_nvic.h index cc99792ba89..08fc2933aad 100644 --- a/targets/TARGET_Atmel/TARGET_SAM_CortexM4/TARGET_SAMG55/device/cmsis_nvic.h +++ b/targets/TARGET_Atmel/TARGET_SAM_CortexM4/TARGET_SAMG55/device/cmsis_nvic.h @@ -1,5 +1,4 @@ /* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors ******************************************************************************* * Copyright (c) 2011 ARM Limited. All rights reserved. * All rights reserved. @@ -32,20 +31,7 @@ #ifndef MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H -#define NVIC_NUM_VECTORS (16 +50) // CORE + MCU Peripherals -#define NVIC_USER_IRQ_OFFSET 16 - -#include "cmsis.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +#define NVIC_NUM_VECTORS (16 + 50) // CORE + MCU Peripherals +#define NVIC_RAM_VECTOR_ADDRESS 0x20000000 // Vectors positioned at start of RAM #endif diff --git a/targets/TARGET_Freescale/TARGET_K20XX/TARGET_K20D50M/device/cmsis_nvic.c b/targets/TARGET_Freescale/TARGET_K20XX/TARGET_K20D50M/device/cmsis_nvic.c deleted file mode 100644 index 16d1b1f7e4d..00000000000 --- a/targets/TARGET_Freescale/TARGET_K20XX/TARGET_K20D50M/device/cmsis_nvic.c +++ /dev/null @@ -1,55 +0,0 @@ -/* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors - ******************************************************************************* - * Copyright (c) 2015 ARM Limited. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of ARM Limited nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "cmsis_nvic.h" - -#define NVIC_RAM_VECTOR_ADDRESS (0x1FFFE000) // Vectors positioned at start of RAM -#define NVIC_FLASH_VECTOR_ADDRESS (0x0) // Initial vector position in flash - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { - uint32_t *vectors = (uint32_t*)SCB->VTOR; - uint32_t i; - - // Copy and switch to dynamic vectors if the first time called - if (SCB->VTOR == NVIC_FLASH_VECTOR_ADDRESS) { - uint32_t *old_vectors = vectors; - vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS; - for (i=0; iVTOR = (uint32_t)NVIC_RAM_VECTOR_ADDRESS; - } - vectors[IRQn + 16] = vector; -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) { - uint32_t *vectors = (uint32_t*)SCB->VTOR; - return vectors[IRQn + 16]; -} diff --git a/targets/TARGET_Freescale/TARGET_K20XX/TARGET_K20D50M/device/cmsis_nvic.h b/targets/TARGET_Freescale/TARGET_K20XX/TARGET_K20D50M/device/cmsis_nvic.h index 04cf15b21f9..cee94f64986 100644 --- a/targets/TARGET_Freescale/TARGET_K20XX/TARGET_K20D50M/device/cmsis_nvic.h +++ b/targets/TARGET_Freescale/TARGET_K20XX/TARGET_K20D50M/device/cmsis_nvic.h @@ -1,5 +1,4 @@ /* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors ******************************************************************************* * Copyright (c) 2015 ARM Limited. All rights reserved. * All rights reserved. @@ -32,20 +31,7 @@ #ifndef MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H -#define NVIC_NUM_VECTORS (16 + 46) // CORE + MCU Peripherals -#define NVIC_USER_IRQ_OFFSET 16 - -#include "cmsis.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +#define NVIC_NUM_VECTORS (16 + 46) // CORE + MCU Peripherals +#define NVIC_RAM_VECTOR_ADDRESS 0x1FFFE000 // Vectors positioned at start of RAM #endif diff --git a/targets/TARGET_Freescale/TARGET_K20XX/TARGET_TEENSY3_1/device/cmsis_nvic.c b/targets/TARGET_Freescale/TARGET_K20XX/TARGET_TEENSY3_1/device/cmsis_nvic.c deleted file mode 100644 index 8148ba87ffc..00000000000 --- a/targets/TARGET_Freescale/TARGET_K20XX/TARGET_TEENSY3_1/device/cmsis_nvic.c +++ /dev/null @@ -1,55 +0,0 @@ -/* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors - ******************************************************************************* - * Copyright (c) 2012 ARM Limited. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of ARM Limited nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "cmsis_nvic.h" - -#define NVIC_RAM_VECTOR_ADDRESS (0x1FFF8000) // Vectors positioned at start of RAM -#define NVIC_FLASH_VECTOR_ADDRESS (0x0) // Initial vector position in flash - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { - uint32_t *vectors = (uint32_t*)SCB->VTOR; - uint32_t i; - - // Copy and switch to dynamic vectors if the first time called - if (SCB->VTOR == NVIC_FLASH_VECTOR_ADDRESS) { - uint32_t *old_vectors = vectors; - vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS; - for (i=0; iVTOR = (uint32_t)NVIC_RAM_VECTOR_ADDRESS; - } - vectors[IRQn + 16] = vector; -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) { - uint32_t *vectors = (uint32_t*)SCB->VTOR; - return vectors[IRQn + 16]; -} diff --git a/targets/TARGET_Freescale/TARGET_K20XX/TARGET_TEENSY3_1/device/cmsis_nvic.h b/targets/TARGET_Freescale/TARGET_K20XX/TARGET_TEENSY3_1/device/cmsis_nvic.h index ce9de13c98a..c835de230c4 100644 --- a/targets/TARGET_Freescale/TARGET_K20XX/TARGET_TEENSY3_1/device/cmsis_nvic.h +++ b/targets/TARGET_Freescale/TARGET_K20XX/TARGET_TEENSY3_1/device/cmsis_nvic.h @@ -1,5 +1,4 @@ /* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors ******************************************************************************* * Copyright (c) 2015 ARM Limited. All rights reserved. * All rights reserved. @@ -32,20 +31,7 @@ #ifndef MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H -#define NVIC_NUM_VECTORS (16 + 95) // CORE + MCU Peripherals -#define NVIC_USER_IRQ_OFFSET 16 - -#include "cmsis.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +#define NVIC_NUM_VECTORS (16 + 95) // CORE + MCU Peripherals +#define NVIC_RAM_VECTOR_ADDRESS 0x1FFF8000 // Vectors positioned at start of RAM #endif diff --git a/targets/TARGET_Freescale/TARGET_KLXX/TARGET_KL05Z/device/cmsis_nvic.c b/targets/TARGET_Freescale/TARGET_KLXX/TARGET_KL05Z/device/cmsis_nvic.c deleted file mode 100644 index cce960bdf33..00000000000 --- a/targets/TARGET_Freescale/TARGET_KLXX/TARGET_KL05Z/device/cmsis_nvic.c +++ /dev/null @@ -1,55 +0,0 @@ -/* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors - ******************************************************************************* - * Copyright (c) 2011 ARM Limited. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of ARM Limited nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "cmsis_nvic.h" - -#define NVIC_RAM_VECTOR_ADDRESS (0x1FFFFC00) // Vectors positioned at start of RAM -#define NVIC_FLASH_VECTOR_ADDRESS (0x0) // Initial vector position in flash - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { - uint32_t *vectors = (uint32_t*)SCB->VTOR; - uint32_t i; - - // Copy and switch to dynamic vectors if the first time called - if (SCB->VTOR == NVIC_FLASH_VECTOR_ADDRESS) { - uint32_t *old_vectors = vectors; - vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS; - for (i=0; iVTOR = (uint32_t)NVIC_RAM_VECTOR_ADDRESS; - } - vectors[IRQn + 16] = vector; -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) { - uint32_t *vectors = (uint32_t*)SCB->VTOR; - return vectors[IRQn + 16]; -} diff --git a/targets/TARGET_Freescale/TARGET_KLXX/TARGET_KL05Z/device/cmsis_nvic.h b/targets/TARGET_Freescale/TARGET_KLXX/TARGET_KL05Z/device/cmsis_nvic.h index 324e797047f..88010cf0500 100644 --- a/targets/TARGET_Freescale/TARGET_KLXX/TARGET_KL05Z/device/cmsis_nvic.h +++ b/targets/TARGET_Freescale/TARGET_KLXX/TARGET_KL05Z/device/cmsis_nvic.h @@ -1,5 +1,4 @@ /* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors ******************************************************************************* * Copyright (c) 2011 ARM Limited. All rights reserved. * All rights reserved. @@ -32,20 +31,7 @@ #ifndef MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H -#include "cmsis.h" - -#define NVIC_NUM_VECTORS (16 + 32) // CORE + MCU Peripherals -#define NVIC_USER_IRQ_OFFSET 16 - -#ifdef __cplusplus -extern "C" { -#endif - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +#define NVIC_NUM_VECTORS (16 + 32) // CORE + MCU Peripherals +#define NVIC_RAM_VECTOR_ADDRESS 0x1FFFFC00 // Vectors positioned at start of RAM #endif diff --git a/targets/TARGET_Freescale/TARGET_KLXX/TARGET_KL25Z/device/cmsis_nvic.c b/targets/TARGET_Freescale/TARGET_KLXX/TARGET_KL25Z/device/cmsis_nvic.c deleted file mode 100644 index cb17abc0d18..00000000000 --- a/targets/TARGET_Freescale/TARGET_KLXX/TARGET_KL25Z/device/cmsis_nvic.c +++ /dev/null @@ -1,55 +0,0 @@ -/* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors - ******************************************************************************* - * Copyright (c) 2011 ARM Limited. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of ARM Limited nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "cmsis_nvic.h" - -#define NVIC_RAM_VECTOR_ADDRESS (0x1FFFF000) // Vectors positioned at start of RAM -#define NVIC_FLASH_VECTOR_ADDRESS (0x0) // Initial vector position in flash - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { - uint32_t *vectors = (uint32_t*)SCB->VTOR; - uint32_t i; - - // Copy and switch to dynamic vectors if the first time called - if (SCB->VTOR == NVIC_FLASH_VECTOR_ADDRESS) { - uint32_t *old_vectors = vectors; - vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS; - for (i=0; iVTOR = (uint32_t)NVIC_RAM_VECTOR_ADDRESS; - } - vectors[IRQn + 16] = vector; -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) { - uint32_t *vectors = (uint32_t*)SCB->VTOR; - return vectors[IRQn + 16]; -} diff --git a/targets/TARGET_Freescale/TARGET_KLXX/TARGET_KL25Z/device/cmsis_nvic.h b/targets/TARGET_Freescale/TARGET_KLXX/TARGET_KL25Z/device/cmsis_nvic.h index 64f36b31671..6ac00ce1f0b 100644 --- a/targets/TARGET_Freescale/TARGET_KLXX/TARGET_KL25Z/device/cmsis_nvic.h +++ b/targets/TARGET_Freescale/TARGET_KLXX/TARGET_KL25Z/device/cmsis_nvic.h @@ -1,5 +1,4 @@ /* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors ******************************************************************************* * Copyright (c) 2011 ARM Limited. All rights reserved. * All rights reserved. @@ -32,20 +31,7 @@ #ifndef MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H -#define NVIC_NUM_VECTORS (16 + 32) // CORE + MCU Peripherals -#define NVIC_USER_IRQ_OFFSET 16 - -#include "cmsis.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +#define NVIC_NUM_VECTORS (16 + 32) // CORE + MCU Peripherals +#define NVIC_RAM_VECTOR_ADDRESS 0x1FFFF000 // Vectors positioned at start of RAM #endif diff --git a/targets/TARGET_Freescale/TARGET_KLXX/TARGET_KL26Z/device/cmsis_nvic.c b/targets/TARGET_Freescale/TARGET_KLXX/TARGET_KL26Z/device/cmsis_nvic.c deleted file mode 100644 index cb17abc0d18..00000000000 --- a/targets/TARGET_Freescale/TARGET_KLXX/TARGET_KL26Z/device/cmsis_nvic.c +++ /dev/null @@ -1,55 +0,0 @@ -/* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors - ******************************************************************************* - * Copyright (c) 2011 ARM Limited. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of ARM Limited nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "cmsis_nvic.h" - -#define NVIC_RAM_VECTOR_ADDRESS (0x1FFFF000) // Vectors positioned at start of RAM -#define NVIC_FLASH_VECTOR_ADDRESS (0x0) // Initial vector position in flash - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { - uint32_t *vectors = (uint32_t*)SCB->VTOR; - uint32_t i; - - // Copy and switch to dynamic vectors if the first time called - if (SCB->VTOR == NVIC_FLASH_VECTOR_ADDRESS) { - uint32_t *old_vectors = vectors; - vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS; - for (i=0; iVTOR = (uint32_t)NVIC_RAM_VECTOR_ADDRESS; - } - vectors[IRQn + 16] = vector; -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) { - uint32_t *vectors = (uint32_t*)SCB->VTOR; - return vectors[IRQn + 16]; -} diff --git a/targets/TARGET_Freescale/TARGET_KLXX/TARGET_KL26Z/device/cmsis_nvic.h b/targets/TARGET_Freescale/TARGET_KLXX/TARGET_KL26Z/device/cmsis_nvic.h index 64f36b31671..6ac00ce1f0b 100644 --- a/targets/TARGET_Freescale/TARGET_KLXX/TARGET_KL26Z/device/cmsis_nvic.h +++ b/targets/TARGET_Freescale/TARGET_KLXX/TARGET_KL26Z/device/cmsis_nvic.h @@ -1,5 +1,4 @@ /* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors ******************************************************************************* * Copyright (c) 2011 ARM Limited. All rights reserved. * All rights reserved. @@ -32,20 +31,7 @@ #ifndef MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H -#define NVIC_NUM_VECTORS (16 + 32) // CORE + MCU Peripherals -#define NVIC_USER_IRQ_OFFSET 16 - -#include "cmsis.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +#define NVIC_NUM_VECTORS (16 + 32) // CORE + MCU Peripherals +#define NVIC_RAM_VECTOR_ADDRESS 0x1FFFF000 // Vectors positioned at start of RAM #endif diff --git a/targets/TARGET_Freescale/TARGET_KLXX/TARGET_KL46Z/device/cmsis_nvic.c b/targets/TARGET_Freescale/TARGET_KLXX/TARGET_KL46Z/device/cmsis_nvic.c deleted file mode 100644 index 971c9d5b7a1..00000000000 --- a/targets/TARGET_Freescale/TARGET_KLXX/TARGET_KL46Z/device/cmsis_nvic.c +++ /dev/null @@ -1,55 +0,0 @@ -/* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors - ******************************************************************************* - * Copyright (c) 2011 ARM Limited. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of ARM Limited nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "cmsis_nvic.h" - -#define NVIC_RAM_VECTOR_ADDRESS (0x1FFFE000) // Vectors positioned at start of RAM -#define NVIC_FLASH_VECTOR_ADDRESS (__vector_table) // Initial vector position in flash - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { - uint32_t *vectors = (uint32_t*)SCB->VTOR; - uint32_t i; - - // Copy and switch to dynamic vectors if the first time called - if (SCB->VTOR < NVIC_RAM_VECTOR_ADDRESS) { - uint32_t *old_vectors = vectors; - vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS; - for (i=0; iVTOR = (uint32_t)NVIC_RAM_VECTOR_ADDRESS; - } - vectors[IRQn + 16] = vector; -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) { - uint32_t *vectors = (uint32_t*)SCB->VTOR; - return vectors[IRQn + 16]; -} diff --git a/targets/TARGET_Freescale/TARGET_KLXX/TARGET_KL46Z/device/cmsis_nvic.h b/targets/TARGET_Freescale/TARGET_KLXX/TARGET_KL46Z/device/cmsis_nvic.h index 64f36b31671..431f0020ebf 100644 --- a/targets/TARGET_Freescale/TARGET_KLXX/TARGET_KL46Z/device/cmsis_nvic.h +++ b/targets/TARGET_Freescale/TARGET_KLXX/TARGET_KL46Z/device/cmsis_nvic.h @@ -1,5 +1,4 @@ /* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors ******************************************************************************* * Copyright (c) 2011 ARM Limited. All rights reserved. * All rights reserved. @@ -32,20 +31,7 @@ #ifndef MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H -#define NVIC_NUM_VECTORS (16 + 32) // CORE + MCU Peripherals -#define NVIC_USER_IRQ_OFFSET 16 - -#include "cmsis.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +#define NVIC_NUM_VECTORS (16 + 32) // CORE + MCU Peripherals +#define NVIC_RAM_VECTOR_ADDRESS 0x1FFFE000 // Vectors positioned at start of RAM #endif diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/device/cmsis_nvic.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/device/cmsis_nvic.c deleted file mode 100644 index e2ce6f15320..00000000000 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/device/cmsis_nvic.c +++ /dev/null @@ -1,44 +0,0 @@ -/* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors - ******************************************************************************* - * Copyright (c) 2011 ARM Limited. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of ARM Limited nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "cmsis_nvic.h" - -extern void InstallIRQHandler(IRQn_Type irq, uint32_t irqHandler); - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) -{ - InstallIRQHandler(IRQn, vector); -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) -{ - uint32_t *vectors = (uint32_t*)SCB->VTOR; - return vectors[IRQn + 16]; -} diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/device/cmsis_nvic.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/device/cmsis_nvic.h index 4cf5ebe4586..93a590e880f 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/device/cmsis_nvic.h +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/device/cmsis_nvic.h @@ -1,5 +1,4 @@ /* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors ******************************************************************************* * Copyright (c) 2011 ARM Limited. All rights reserved. * All rights reserved. @@ -32,20 +31,15 @@ #ifndef MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H -#define NVIC_NUM_VECTORS (16 + 100) // CORE + MCU Peripherals -#define NVIC_USER_IRQ_OFFSET 16 - -#include "cmsis.h" - -#ifdef __cplusplus -extern "C" { +#if defined(__CC_ARM) +extern uint32_t Image$$VECTOR_RAM$$Base[]; +#define __VECTOR_RAM Image$$VECTOR_RAM$$Base +#else +extern uint32_t __VECTOR_RAM[]; #endif -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +/* Symbols defined by the linker script */ +#define NVIC_NUM_VECTORS (16 + 240) // CORE + MCU Peripherals +#define NVIC_RAM_VECTOR_ADDRESS (__VECTOR_RAM) // Vectors positioned at start of RAM #endif diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K82F/device/cmsis_nvic.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K82F/device/cmsis_nvic.c deleted file mode 100644 index 769e21e37bb..00000000000 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K82F/device/cmsis_nvic.c +++ /dev/null @@ -1,44 +0,0 @@ -/* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors - ******************************************************************************* - * Copyright (c) 2011 ARM Limited. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of ARM Limited nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "cmsis_nvic.h" - -extern void InstallIRQHandler(IRQn_Type irq, uint32_t irqHandler); - -void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) -{ - InstallIRQHandler(IRQn, vector); -} - -uint32_t __NVIC_GetVector(IRQn_Type IRQn) -{ - uint32_t *vectors = (uint32_t*)SCB->VTOR; - return vectors[IRQn + 16]; -} diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K82F/device/cmsis_nvic.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K82F/device/cmsis_nvic.h index 5b794a1cf11..86df2b2deb1 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K82F/device/cmsis_nvic.h +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K82F/device/cmsis_nvic.h @@ -32,20 +32,15 @@ #ifndef MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H -#define NVIC_NUM_VECTORS (16 + 107) // CORE + MCU Peripherals -#define NVIC_USER_IRQ_OFFSET 16 - -#include "cmsis.h" - -#ifdef __cplusplus -extern "C" { +#if defined(__CC_ARM) +extern uint32_t Image$$VECTOR_RAM$$Base[]; +#define __VECTOR_RAM Image$$VECTOR_RAM$$Base +#else +extern uint32_t __VECTOR_RAM[]; #endif -void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t __NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +/* Symbols defined by the linker script */ +#define NVIC_NUM_VECTORS (16 + 107) // CORE + MCU Peripherals +#define NVIC_RAM_VECTOR_ADDRESS (__VECTOR_RAM) // Vectors positioned at start of RAM #endif diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL27Z/device/cmsis_nvic.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL27Z/device/cmsis_nvic.c deleted file mode 100644 index e2ce6f15320..00000000000 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL27Z/device/cmsis_nvic.c +++ /dev/null @@ -1,44 +0,0 @@ -/* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors - ******************************************************************************* - * Copyright (c) 2011 ARM Limited. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of ARM Limited nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "cmsis_nvic.h" - -extern void InstallIRQHandler(IRQn_Type irq, uint32_t irqHandler); - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) -{ - InstallIRQHandler(IRQn, vector); -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) -{ - uint32_t *vectors = (uint32_t*)SCB->VTOR; - return vectors[IRQn + 16]; -} diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL27Z/device/cmsis_nvic.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL27Z/device/cmsis_nvic.h index 64f36b31671..93a590e880f 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL27Z/device/cmsis_nvic.h +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL27Z/device/cmsis_nvic.h @@ -1,5 +1,4 @@ /* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors ******************************************************************************* * Copyright (c) 2011 ARM Limited. All rights reserved. * All rights reserved. @@ -32,20 +31,15 @@ #ifndef MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H -#define NVIC_NUM_VECTORS (16 + 32) // CORE + MCU Peripherals -#define NVIC_USER_IRQ_OFFSET 16 - -#include "cmsis.h" - -#ifdef __cplusplus -extern "C" { +#if defined(__CC_ARM) +extern uint32_t Image$$VECTOR_RAM$$Base[]; +#define __VECTOR_RAM Image$$VECTOR_RAM$$Base +#else +extern uint32_t __VECTOR_RAM[]; #endif -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +/* Symbols defined by the linker script */ +#define NVIC_NUM_VECTORS (16 + 240) // CORE + MCU Peripherals +#define NVIC_RAM_VECTOR_ADDRESS (__VECTOR_RAM) // Vectors positioned at start of RAM #endif diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL43Z/device/cmsis_nvic.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL43Z/device/cmsis_nvic.c deleted file mode 100644 index e2ce6f15320..00000000000 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL43Z/device/cmsis_nvic.c +++ /dev/null @@ -1,44 +0,0 @@ -/* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors - ******************************************************************************* - * Copyright (c) 2011 ARM Limited. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of ARM Limited nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "cmsis_nvic.h" - -extern void InstallIRQHandler(IRQn_Type irq, uint32_t irqHandler); - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) -{ - InstallIRQHandler(IRQn, vector); -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) -{ - uint32_t *vectors = (uint32_t*)SCB->VTOR; - return vectors[IRQn + 16]; -} diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL43Z/device/cmsis_nvic.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL43Z/device/cmsis_nvic.h index 64f36b31671..93a590e880f 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL43Z/device/cmsis_nvic.h +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL43Z/device/cmsis_nvic.h @@ -1,5 +1,4 @@ /* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors ******************************************************************************* * Copyright (c) 2011 ARM Limited. All rights reserved. * All rights reserved. @@ -32,20 +31,15 @@ #ifndef MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H -#define NVIC_NUM_VECTORS (16 + 32) // CORE + MCU Peripherals -#define NVIC_USER_IRQ_OFFSET 16 - -#include "cmsis.h" - -#ifdef __cplusplus -extern "C" { +#if defined(__CC_ARM) +extern uint32_t Image$$VECTOR_RAM$$Base[]; +#define __VECTOR_RAM Image$$VECTOR_RAM$$Base +#else +extern uint32_t __VECTOR_RAM[]; #endif -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +/* Symbols defined by the linker script */ +#define NVIC_NUM_VECTORS (16 + 240) // CORE + MCU Peripherals +#define NVIC_RAM_VECTOR_ADDRESS (__VECTOR_RAM) // Vectors positioned at start of RAM #endif diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL82Z/device/cmsis_nvic.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL82Z/device/cmsis_nvic.c deleted file mode 100644 index e2ce6f15320..00000000000 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL82Z/device/cmsis_nvic.c +++ /dev/null @@ -1,44 +0,0 @@ -/* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors - ******************************************************************************* - * Copyright (c) 2011 ARM Limited. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of ARM Limited nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "cmsis_nvic.h" - -extern void InstallIRQHandler(IRQn_Type irq, uint32_t irqHandler); - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) -{ - InstallIRQHandler(IRQn, vector); -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) -{ - uint32_t *vectors = (uint32_t*)SCB->VTOR; - return vectors[IRQn + 16]; -} diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL82Z/device/cmsis_nvic.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL82Z/device/cmsis_nvic.h index 64f36b31671..93a590e880f 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL82Z/device/cmsis_nvic.h +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL82Z/device/cmsis_nvic.h @@ -1,5 +1,4 @@ /* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors ******************************************************************************* * Copyright (c) 2011 ARM Limited. All rights reserved. * All rights reserved. @@ -32,20 +31,15 @@ #ifndef MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H -#define NVIC_NUM_VECTORS (16 + 32) // CORE + MCU Peripherals -#define NVIC_USER_IRQ_OFFSET 16 - -#include "cmsis.h" - -#ifdef __cplusplus -extern "C" { +#if defined(__CC_ARM) +extern uint32_t Image$$VECTOR_RAM$$Base[]; +#define __VECTOR_RAM Image$$VECTOR_RAM$$Base +#else +extern uint32_t __VECTOR_RAM[]; #endif -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +/* Symbols defined by the linker script */ +#define NVIC_NUM_VECTORS (16 + 240) // CORE + MCU Peripherals +#define NVIC_RAM_VECTOR_ADDRESS (__VECTOR_RAM) // Vectors positioned at start of RAM #endif diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KW24D/device/cmsis_nvic.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KW24D/device/cmsis_nvic.c deleted file mode 100644 index e2ce6f15320..00000000000 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KW24D/device/cmsis_nvic.c +++ /dev/null @@ -1,44 +0,0 @@ -/* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors - ******************************************************************************* - * Copyright (c) 2011 ARM Limited. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of ARM Limited nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "cmsis_nvic.h" - -extern void InstallIRQHandler(IRQn_Type irq, uint32_t irqHandler); - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) -{ - InstallIRQHandler(IRQn, vector); -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) -{ - uint32_t *vectors = (uint32_t*)SCB->VTOR; - return vectors[IRQn + 16]; -} diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KW24D/device/cmsis_nvic.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KW24D/device/cmsis_nvic.h index 89ef7386361..93a590e880f 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KW24D/device/cmsis_nvic.h +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KW24D/device/cmsis_nvic.h @@ -1,5 +1,4 @@ /* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors ******************************************************************************* * Copyright (c) 2011 ARM Limited. All rights reserved. * All rights reserved. @@ -32,20 +31,15 @@ #ifndef MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H -#define NVIC_NUM_VECTORS (16 + 65) // CORE + MCU Peripherals -#define NVIC_USER_IRQ_OFFSET 16 - -#include "cmsis.h" - -#ifdef __cplusplus -extern "C" { +#if defined(__CC_ARM) +extern uint32_t Image$$VECTOR_RAM$$Base[]; +#define __VECTOR_RAM Image$$VECTOR_RAM$$Base +#else +extern uint32_t __VECTOR_RAM[]; #endif -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +/* Symbols defined by the linker script */ +#define NVIC_NUM_VECTORS (16 + 240) // CORE + MCU Peripherals +#define NVIC_RAM_VECTOR_ADDRESS (__VECTOR_RAM) // Vectors positioned at start of RAM #endif diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KW41Z/device/cmsis_nvic.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KW41Z/device/cmsis_nvic.c deleted file mode 100644 index e2ce6f15320..00000000000 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KW41Z/device/cmsis_nvic.c +++ /dev/null @@ -1,44 +0,0 @@ -/* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors - ******************************************************************************* - * Copyright (c) 2011 ARM Limited. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of ARM Limited nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "cmsis_nvic.h" - -extern void InstallIRQHandler(IRQn_Type irq, uint32_t irqHandler); - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) -{ - InstallIRQHandler(IRQn, vector); -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) -{ - uint32_t *vectors = (uint32_t*)SCB->VTOR; - return vectors[IRQn + 16]; -} diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KW41Z/device/cmsis_nvic.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KW41Z/device/cmsis_nvic.h index 64f36b31671..094bdc4da03 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KW41Z/device/cmsis_nvic.h +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KW41Z/device/cmsis_nvic.h @@ -32,20 +32,15 @@ #ifndef MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H -#define NVIC_NUM_VECTORS (16 + 32) // CORE + MCU Peripherals -#define NVIC_USER_IRQ_OFFSET 16 - -#include "cmsis.h" - -#ifdef __cplusplus -extern "C" { +#if defined(__CC_ARM) +extern uint32_t Image$$VECTOR_RAM$$Base[]; +#define __VECTOR_RAM Image$$VECTOR_RAM$$Base +#else +extern uint32_t __VECTOR_RAM[]; #endif -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +/* Symbols defined by the linker script */ +#define NVIC_NUM_VECTORS (16 + 32) // CORE + MCU Peripherals +#define NVIC_RAM_VECTOR_ADDRESS (__VECTOR_RAM) // Vectors positioned at start of RAM #endif diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K22F/TARGET_MCU_K22F512/device/cmsis_nvic.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K22F/TARGET_MCU_K22F512/device/cmsis_nvic.c deleted file mode 100644 index e2ce6f15320..00000000000 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K22F/TARGET_MCU_K22F512/device/cmsis_nvic.c +++ /dev/null @@ -1,44 +0,0 @@ -/* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors - ******************************************************************************* - * Copyright (c) 2011 ARM Limited. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of ARM Limited nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "cmsis_nvic.h" - -extern void InstallIRQHandler(IRQn_Type irq, uint32_t irqHandler); - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) -{ - InstallIRQHandler(IRQn, vector); -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) -{ - uint32_t *vectors = (uint32_t*)SCB->VTOR; - return vectors[IRQn + 16]; -} diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K22F/TARGET_MCU_K22F512/device/cmsis_nvic.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K22F/TARGET_MCU_K22F512/device/cmsis_nvic.h index 49e981494dc..490274f50d7 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K22F/TARGET_MCU_K22F512/device/cmsis_nvic.h +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K22F/TARGET_MCU_K22F512/device/cmsis_nvic.h @@ -1,5 +1,4 @@ /* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors ******************************************************************************* * Copyright (c) 2011 ARM Limited. All rights reserved. * All rights reserved. @@ -32,20 +31,15 @@ #ifndef MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H -#define NVIC_NUM_VECTORS (16 + 74) // CORE + MCU Peripherals -#define NVIC_USER_IRQ_OFFSET 16 +#if defined(__CC_ARM) +extern uint32_t Image$$VECTOR_RAM$$Base[]; +#define __VECTOR_RAM Image$$VECTOR_RAM$$Base +#else +extern uint32_t __VECTOR_RAM[]; +#endif /* defined(__CC_ARM) */ -#include "cmsis.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +/* Symbols defined by the linker script */ +#define NVIC_NUM_VECTORS (16 + 240) // CORE + MCU Peripherals +#define NVIC_RAM_VECTOR_ADDRESS (__VECTOR_RAM) // Vectors positioned at start of RAM #endif diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K24F/TARGET_MCU_K24F1M/device/cmsis_nvic.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K24F/TARGET_MCU_K24F1M/device/cmsis_nvic.c deleted file mode 100644 index 0de56f35da8..00000000000 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K24F/TARGET_MCU_K24F1M/device/cmsis_nvic.c +++ /dev/null @@ -1,42 +0,0 @@ -/* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors - ******************************************************************************* - * Copyright (c) 2017 ARM Limited. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of ARM Limited nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "cmsis_nvic.h" - -extern void InstallIRQHandler(IRQn_Type irq, uint32_t irqHandler); - -void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { - InstallIRQHandler(IRQn, vector); -} - -uint32_t __NVIC_GetVector(IRQn_Type IRQn) { - uint32_t *vectors = (uint32_t*)SCB->VTOR; - return vectors[IRQn + 16]; -} diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K24F/TARGET_MCU_K24F1M/device/cmsis_nvic.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K24F/TARGET_MCU_K24F1M/device/cmsis_nvic.h index 68f955d408b..001c9aec44d 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K24F/TARGET_MCU_K24F1M/device/cmsis_nvic.h +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K24F/TARGET_MCU_K24F1M/device/cmsis_nvic.h @@ -32,20 +32,14 @@ #ifndef MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H -#define NVIC_NUM_VECTORS (16 + 86) // CORE + MCU Peripherals -#define NVIC_USER_IRQ_OFFSET 16 +#if defined(__CC_ARM) +extern uint32_t Image$$VECTOR_RAM$$Base[]; +#define __VECTOR_RAM Image$$VECTOR_RAM$$Base +#else +extern uint32_t __VECTOR_RAM[]; +#endif /* defined(__CC_ARM) */ -#include "cmsis.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t __NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +#define NVIC_NUM_VECTORS (16 + 86) // CORE + MCU Peripherals +#define NVIC_RAM_VECTOR_ADDRESS (__VECTOR_RAM) // Vectors positioned at start of RAM #endif diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/device/cmsis_nvic.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/device/cmsis_nvic.c deleted file mode 100644 index 769e21e37bb..00000000000 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/device/cmsis_nvic.c +++ /dev/null @@ -1,44 +0,0 @@ -/* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors - ******************************************************************************* - * Copyright (c) 2011 ARM Limited. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of ARM Limited nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "cmsis_nvic.h" - -extern void InstallIRQHandler(IRQn_Type irq, uint32_t irqHandler); - -void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) -{ - InstallIRQHandler(IRQn, vector); -} - -uint32_t __NVIC_GetVector(IRQn_Type IRQn) -{ - uint32_t *vectors = (uint32_t*)SCB->VTOR; - return vectors[IRQn + 16]; -} diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/device/cmsis_nvic.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/device/cmsis_nvic.h index 5260d276ced..490274f50d7 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/device/cmsis_nvic.h +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/device/cmsis_nvic.h @@ -1,5 +1,4 @@ /* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors ******************************************************************************* * Copyright (c) 2011 ARM Limited. All rights reserved. * All rights reserved. @@ -32,20 +31,15 @@ #ifndef MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H -#define NVIC_NUM_VECTORS (16 + 86) // CORE + MCU Peripherals -#define NVIC_USER_IRQ_OFFSET 16 +#if defined(__CC_ARM) +extern uint32_t Image$$VECTOR_RAM$$Base[]; +#define __VECTOR_RAM Image$$VECTOR_RAM$$Base +#else +extern uint32_t __VECTOR_RAM[]; +#endif /* defined(__CC_ARM) */ -#include "cmsis.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t __NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +/* Symbols defined by the linker script */ +#define NVIC_NUM_VECTORS (16 + 240) // CORE + MCU Peripherals +#define NVIC_RAM_VECTOR_ADDRESS (__VECTOR_RAM) // Vectors positioned at start of RAM #endif diff --git a/targets/TARGET_Maxim/TARGET_MAX32600/device/cmsis_nvic.c b/targets/TARGET_Maxim/TARGET_MAX32600/device/cmsis_nvic.c deleted file mode 100644 index 3694273047b..00000000000 --- a/targets/TARGET_Maxim/TARGET_MAX32600/device/cmsis_nvic.c +++ /dev/null @@ -1,65 +0,0 @@ -/******************************************************************************* - * Copyright (C) 2015 Maxim Integrated Products, Inc., All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES - * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Except as contained in this notice, the name of Maxim Integrated - * Products, Inc. shall not be used except as stated in the Maxim Integrated - * Products, Inc. Branding Policy. - * - * The mere transfer of this software does not imply any licenses - * of trade secrets, proprietary technology, copyrights, patents, - * trademarks, maskwork rights, or any other form of intellectual - * property whatsoever. Maxim Integrated Products, Inc. retains all - * ownership rights. - ******************************************************************************* - */ - -#include "cmsis_nvic.h" - -#if defined(TOOLCHAIN_GCC_ARM) || defined(TOOLCHAIN_ARM_STD) -__attribute__((aligned(256))) -#endif -#if defined(TOOLCHAIN_IAR) -#pragma data_alignment=256 -#endif -static void (*ramVectorTable[MXC_IRQ_COUNT])(void); - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) -{ - uint32_t *vectors = (uint32_t*)SCB->VTOR; - uint32_t i; - - // Copy and switch to dynamic vectors if the first time called - if (SCB->VTOR != (uint32_t)ramVectorTable) { - uint32_t *old_vectors = (uint32_t*)SCB->VTOR; - vectors = (uint32_t*)ramVectorTable; - for (i = 0; i < NVIC_NUM_VECTORS; i++) { - vectors[i] = old_vectors[i]; - } - SCB->VTOR = (uint32_t)ramVectorTable; - } - vectors[IRQn + NVIC_USER_IRQ_OFFSET] = vector; -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) -{ - uint32_t *vectors = (uint32_t*)SCB->VTOR; - return vectors[IRQn + NVIC_USER_IRQ_OFFSET]; -} diff --git a/targets/TARGET_Maxim/TARGET_MAX32600/device/cmsis_nvic.h b/targets/TARGET_Maxim/TARGET_MAX32600/device/cmsis_nvic.h index d3e54476142..ef6874ae013 100644 --- a/targets/TARGET_Maxim/TARGET_MAX32600/device/cmsis_nvic.h +++ b/targets/TARGET_Maxim/TARGET_MAX32600/device/cmsis_nvic.h @@ -34,20 +34,9 @@ #ifndef MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H -#include "cmsis.h" +extern void (*ramVectorTable[MXC_IRQ_COUNT])(void); -#define NVIC_NUM_VECTORS MXC_IRQ_COUNT -#define NVIC_USER_IRQ_OFFSET 16 - -#ifdef __cplusplus -extern "C" { -#endif - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +#define NVIC_NUM_VECTORS (MXC_IRQ_COUNT) +#define NVIC_RAM_VECTOR_ADDRESS (ramVectorTable) // Vectors positioned at start of RAM #endif /* MBED_CMSIS_NVIC_H */ diff --git a/targets/TARGET_Maxim/TARGET_MAX32600/device/device_nvic.c b/targets/TARGET_Maxim/TARGET_MAX32600/device/device_nvic.c new file mode 100644 index 00000000000..e28ceb1700d --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32600/device/device_nvic.c @@ -0,0 +1,24 @@ +/* mbed Microcontroller Library + * Copyright (c) 2017 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "cmsis.h" +#include "mbed_toolchain.h" + +/* RAM vector_table needs to be aligned with the size of the vector table */ +/* TODO: Use MXC_IRQ_COUNT to automatically set this alignment per DUI0553A 4.3.4 */ +/* Vector Table Offset which requires the next-power-of-two alignment. This */ +/* can be calculated by 4*pow(2,ceil(log2(MXC_IRQ_COUNT))) */ +MBED_ALIGN(512) +void (*ramVectorTable[MXC_IRQ_COUNT])(void); diff --git a/targets/TARGET_Maxim/TARGET_MAX32610/device/cmsis_nvic.c b/targets/TARGET_Maxim/TARGET_MAX32610/device/cmsis_nvic.c deleted file mode 100644 index 3694273047b..00000000000 --- a/targets/TARGET_Maxim/TARGET_MAX32610/device/cmsis_nvic.c +++ /dev/null @@ -1,65 +0,0 @@ -/******************************************************************************* - * Copyright (C) 2015 Maxim Integrated Products, Inc., All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES - * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Except as contained in this notice, the name of Maxim Integrated - * Products, Inc. shall not be used except as stated in the Maxim Integrated - * Products, Inc. Branding Policy. - * - * The mere transfer of this software does not imply any licenses - * of trade secrets, proprietary technology, copyrights, patents, - * trademarks, maskwork rights, or any other form of intellectual - * property whatsoever. Maxim Integrated Products, Inc. retains all - * ownership rights. - ******************************************************************************* - */ - -#include "cmsis_nvic.h" - -#if defined(TOOLCHAIN_GCC_ARM) || defined(TOOLCHAIN_ARM_STD) -__attribute__((aligned(256))) -#endif -#if defined(TOOLCHAIN_IAR) -#pragma data_alignment=256 -#endif -static void (*ramVectorTable[MXC_IRQ_COUNT])(void); - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) -{ - uint32_t *vectors = (uint32_t*)SCB->VTOR; - uint32_t i; - - // Copy and switch to dynamic vectors if the first time called - if (SCB->VTOR != (uint32_t)ramVectorTable) { - uint32_t *old_vectors = (uint32_t*)SCB->VTOR; - vectors = (uint32_t*)ramVectorTable; - for (i = 0; i < NVIC_NUM_VECTORS; i++) { - vectors[i] = old_vectors[i]; - } - SCB->VTOR = (uint32_t)ramVectorTable; - } - vectors[IRQn + NVIC_USER_IRQ_OFFSET] = vector; -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) -{ - uint32_t *vectors = (uint32_t*)SCB->VTOR; - return vectors[IRQn + NVIC_USER_IRQ_OFFSET]; -} diff --git a/targets/TARGET_Maxim/TARGET_MAX32610/device/cmsis_nvic.h b/targets/TARGET_Maxim/TARGET_MAX32610/device/cmsis_nvic.h index d3e54476142..ef6874ae013 100644 --- a/targets/TARGET_Maxim/TARGET_MAX32610/device/cmsis_nvic.h +++ b/targets/TARGET_Maxim/TARGET_MAX32610/device/cmsis_nvic.h @@ -34,20 +34,9 @@ #ifndef MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H -#include "cmsis.h" +extern void (*ramVectorTable[MXC_IRQ_COUNT])(void); -#define NVIC_NUM_VECTORS MXC_IRQ_COUNT -#define NVIC_USER_IRQ_OFFSET 16 - -#ifdef __cplusplus -extern "C" { -#endif - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +#define NVIC_NUM_VECTORS (MXC_IRQ_COUNT) +#define NVIC_RAM_VECTOR_ADDRESS (ramVectorTable) // Vectors positioned at start of RAM #endif /* MBED_CMSIS_NVIC_H */ diff --git a/targets/TARGET_Maxim/TARGET_MAX32610/device/device_nvic.c b/targets/TARGET_Maxim/TARGET_MAX32610/device/device_nvic.c new file mode 100644 index 00000000000..e28ceb1700d --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32610/device/device_nvic.c @@ -0,0 +1,24 @@ +/* mbed Microcontroller Library + * Copyright (c) 2017 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "cmsis.h" +#include "mbed_toolchain.h" + +/* RAM vector_table needs to be aligned with the size of the vector table */ +/* TODO: Use MXC_IRQ_COUNT to automatically set this alignment per DUI0553A 4.3.4 */ +/* Vector Table Offset which requires the next-power-of-two alignment. This */ +/* can be calculated by 4*pow(2,ceil(log2(MXC_IRQ_COUNT))) */ +MBED_ALIGN(512) +void (*ramVectorTable[MXC_IRQ_COUNT])(void); diff --git a/targets/TARGET_Maxim/TARGET_MAX32620/device/cmsis_nvic.c b/targets/TARGET_Maxim/TARGET_MAX32620/device/cmsis_nvic.c deleted file mode 100644 index 22b7e08ed01..00000000000 --- a/targets/TARGET_Maxim/TARGET_MAX32620/device/cmsis_nvic.c +++ /dev/null @@ -1,65 +0,0 @@ -/******************************************************************************* - * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES - * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Except as contained in this notice, the name of Maxim Integrated - * Products, Inc. shall not be used except as stated in the Maxim Integrated - * Products, Inc. Branding Policy. - * - * The mere transfer of this software does not imply any licenses - * of trade secrets, proprietary technology, copyrights, patents, - * trademarks, maskwork rights, or any other form of intellectual - * property whatsoever. Maxim Integrated Products, Inc. retains all - * ownership rights. - ******************************************************************************* - */ - -#include "cmsis_nvic.h" - -#if defined(TOOLCHAIN_GCC_ARM) || defined(TOOLCHAIN_ARM_STD) -__attribute__((aligned(256))) -#endif -#if defined(TOOLCHAIN_IAR) -#pragma data_alignment=256 -#endif -static void (*ramVectorTable[MXC_IRQ_COUNT])(void); - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) -{ - uint32_t *vectors = (uint32_t*)SCB->VTOR; - uint32_t i; - - // Copy and switch to dynamic vectors if the first time called - if (SCB->VTOR != (uint32_t)ramVectorTable) { - uint32_t *old_vectors = (uint32_t*)SCB->VTOR; - vectors = (uint32_t*)ramVectorTable; - for (i = 0; i < NVIC_NUM_VECTORS; i++) { - vectors[i] = old_vectors[i]; - } - SCB->VTOR = (uint32_t)ramVectorTable; - } - vectors[IRQn + NVIC_USER_IRQ_OFFSET] = vector; -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) -{ - uint32_t *vectors = (uint32_t*)SCB->VTOR; - return vectors[IRQn + NVIC_USER_IRQ_OFFSET]; -} diff --git a/targets/TARGET_Maxim/TARGET_MAX32620/device/cmsis_nvic.h b/targets/TARGET_Maxim/TARGET_MAX32620/device/cmsis_nvic.h index 91c94e7c9bb..5639fd178c2 100644 --- a/targets/TARGET_Maxim/TARGET_MAX32620/device/cmsis_nvic.h +++ b/targets/TARGET_Maxim/TARGET_MAX32620/device/cmsis_nvic.h @@ -34,20 +34,9 @@ #ifndef MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H -#include "cmsis.h" +extern void (*ramVectorTable[MXC_IRQ_COUNT])(void); -#define NVIC_NUM_VECTORS MXC_IRQ_COUNT -#define NVIC_USER_IRQ_OFFSET 16 - -#ifdef __cplusplus -extern "C" { -#endif - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +#define NVIC_NUM_VECTORS (MXC_IRQ_COUNT) +#define NVIC_RAM_VECTOR_ADDRESS (ramVectorTable) // Vectors positioned at start of RAM #endif /* MBED_CMSIS_NVIC_H */ diff --git a/targets/TARGET_Maxim/TARGET_MAX32620/device/device_nvic.c b/targets/TARGET_Maxim/TARGET_MAX32620/device/device_nvic.c new file mode 100644 index 00000000000..e28ceb1700d --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32620/device/device_nvic.c @@ -0,0 +1,24 @@ +/* mbed Microcontroller Library + * Copyright (c) 2017 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "cmsis.h" +#include "mbed_toolchain.h" + +/* RAM vector_table needs to be aligned with the size of the vector table */ +/* TODO: Use MXC_IRQ_COUNT to automatically set this alignment per DUI0553A 4.3.4 */ +/* Vector Table Offset which requires the next-power-of-two alignment. This */ +/* can be calculated by 4*pow(2,ceil(log2(MXC_IRQ_COUNT))) */ +MBED_ALIGN(512) +void (*ramVectorTable[MXC_IRQ_COUNT])(void); diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/device/cmsis_nvic.c b/targets/TARGET_Maxim/TARGET_MAX32625/device/cmsis_nvic.c deleted file mode 100644 index b3dbadaa5f4..00000000000 --- a/targets/TARGET_Maxim/TARGET_MAX32625/device/cmsis_nvic.c +++ /dev/null @@ -1,65 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2016 Maxim Integrated Products, Inc., All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES - * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Except as contained in this notice, the name of Maxim Integrated - * Products, Inc. shall not be used except as stated in the Maxim Integrated - * Products, Inc. Branding Policy. - * - * The mere transfer of this software does not imply any licenses - * of trade secrets, proprietary technology, copyrights, patents, - * trademarks, maskwork rights, or any other form of intellectual - * property whatsoever. Maxim Integrated Products, Inc. retains all - * ownership rights. - ******************************************************************************* - */ - -#include "cmsis_nvic.h" - -#if defined(TOOLCHAIN_GCC_ARM) || defined(TOOLCHAIN_ARM_STD) -__attribute__((aligned(256))) -#endif -#if defined(TOOLCHAIN_IAR) -#pragma data_alignment=256 -#endif -static void (*ramVectorTable[MXC_IRQ_COUNT])(void); - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) -{ - uint32_t *vectors = (uint32_t*)SCB->VTOR; - uint32_t i; - - // Copy and switch to dynamic vectors if the first time called - if (SCB->VTOR != (uint32_t)ramVectorTable) { - uint32_t *old_vectors = (uint32_t*)SCB->VTOR; - vectors = (uint32_t*)ramVectorTable; - for (i = 0; i < NVIC_NUM_VECTORS; i++) { - vectors[i] = old_vectors[i]; - } - SCB->VTOR = (uint32_t)ramVectorTable; - } - vectors[IRQn + NVIC_USER_IRQ_OFFSET] = vector; -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) -{ - uint32_t *vectors = (uint32_t*)SCB->VTOR; - return vectors[IRQn + NVIC_USER_IRQ_OFFSET]; -} diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/device/cmsis_nvic.h b/targets/TARGET_Maxim/TARGET_MAX32625/device/cmsis_nvic.h index 5f44cc56d9d..9db4c149fdf 100644 --- a/targets/TARGET_Maxim/TARGET_MAX32625/device/cmsis_nvic.h +++ b/targets/TARGET_Maxim/TARGET_MAX32625/device/cmsis_nvic.h @@ -34,20 +34,10 @@ #ifndef MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H -#include "cmsis.h" +extern void (*ramVectorTable[MXC_IRQ_COUNT])(void); -#define NVIC_NUM_VECTORS MXC_IRQ_COUNT -#define NVIC_USER_IRQ_OFFSET 16 - -#ifdef __cplusplus -extern "C" { -#endif - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +#define NVIC_NUM_VECTORS (MXC_IRQ_COUNT) +#define NVIC_RAM_VECTOR_ADDRESS (ramVectorTable) // Vectors positioned at start of RAM #endif /* MBED_CMSIS_NVIC_H */ + diff --git a/targets/TARGET_Maxim/TARGET_MAX32625/device/device_nvic.c b/targets/TARGET_Maxim/TARGET_MAX32625/device/device_nvic.c new file mode 100644 index 00000000000..e28ceb1700d --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32625/device/device_nvic.c @@ -0,0 +1,24 @@ +/* mbed Microcontroller Library + * Copyright (c) 2017 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "cmsis.h" +#include "mbed_toolchain.h" + +/* RAM vector_table needs to be aligned with the size of the vector table */ +/* TODO: Use MXC_IRQ_COUNT to automatically set this alignment per DUI0553A 4.3.4 */ +/* Vector Table Offset which requires the next-power-of-two alignment. This */ +/* can be calculated by 4*pow(2,ceil(log2(MXC_IRQ_COUNT))) */ +MBED_ALIGN(512) +void (*ramVectorTable[MXC_IRQ_COUNT])(void); diff --git a/targets/TARGET_Maxim/TARGET_MAX32630/device/device_nvic.c b/targets/TARGET_Maxim/TARGET_MAX32630/device/device_nvic.c new file mode 100644 index 00000000000..e28ceb1700d --- /dev/null +++ b/targets/TARGET_Maxim/TARGET_MAX32630/device/device_nvic.c @@ -0,0 +1,24 @@ +/* mbed Microcontroller Library + * Copyright (c) 2017 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "cmsis.h" +#include "mbed_toolchain.h" + +/* RAM vector_table needs to be aligned with the size of the vector table */ +/* TODO: Use MXC_IRQ_COUNT to automatically set this alignment per DUI0553A 4.3.4 */ +/* Vector Table Offset which requires the next-power-of-two alignment. This */ +/* can be calculated by 4*pow(2,ceil(log2(MXC_IRQ_COUNT))) */ +MBED_ALIGN(512) +void (*ramVectorTable[MXC_IRQ_COUNT])(void); diff --git a/targets/TARGET_Maxim/TARGET_MAX32630/mxc/nvic_table.c b/targets/TARGET_Maxim/TARGET_MAX32630/mxc/nvic_table.c deleted file mode 100644 index 4bd18960b3b..00000000000 --- a/targets/TARGET_Maxim/TARGET_MAX32630/mxc/nvic_table.c +++ /dev/null @@ -1,93 +0,0 @@ -/** - * @file - * @brief This file contains the implementations of the vendor - * defined NVIC function. - * - */ -/* **************************************************************************** - * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES - * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Except as contained in this notice, the name of Maxim Integrated - * Products, Inc. shall not be used except as stated in the Maxim Integrated - * Products, Inc. Branding Policy. - * - * The mere transfer of this software does not imply any licenses - * of trade secrets, proprietary technology, copyrights, patents, - * trademarks, maskwork rights, or any other form of intellectual - * property whatsoever. Maxim Integrated Products, Inc. retains all - * ownership rights. - * - * $Date: 2016-09-28 10:27:00 -0500 (Wed, 28 Sep 2016) $ - * $Revision: 24512 $ - * - *************************************************************************** */ - -/** - * @ingroup mxc_nvic - * @{ - */ - -/* **** Includes **** */ -#include "mxc_config.h" -#include -#include "nvic_table.h" - -/* RAM vector_table needs to be aligned with the size of the vector table */ -/* TODO: Use MXC_IRQ_COUNT to automatically set this alignment per DUI0553A 4.3.4 */ -/* Vector Table Offset which requires the next-power-of-two alignment. This */ -/* can be calculated by 4*pow(2,ceil(log2(MXC_IRQ_COUNT))) */ -#if defined ( __ICCARM__ ) -#pragma data_alignment = 512 -#define __isr_vector __vector_table -#else -__attribute__ ((aligned (512))) -#endif -static void (*ramVectorTable[MXC_IRQ_COUNT])(void); - -/* **** Definitions **** */ - -/* **** Globals **** */ - -/* **** Functions **** */ - -/* ************************************************************************* */ -void NVIC_SetRAM(void) -{ - memcpy(&ramVectorTable, (uint32_t*)SCB->VTOR, sizeof(ramVectorTable)); - SCB->VTOR = (uint32_t)&ramVectorTable; -} - -/* ************************************************************************* */ -int NVIC_SetVector(IRQn_Type irqn, uint32_t irq_handler) -{ - int index = irqn + 16; /* offset for externals */ - - /* If not copied, do copy */ - if(SCB->VTOR != (uint32_t)&ramVectorTable) { - NVIC_SetRAM(); - } - - ramVectorTable[index] = (void(*)(void))irq_handler; - NVIC_EnableIRQ(irqn); - - return 0; -} -/**@} end of group mxc_nvic */ diff --git a/targets/TARGET_Maxim/TARGET_MAX32630/mxc/nvic_table.h b/targets/TARGET_Maxim/TARGET_MAX32630/mxc/nvic_table.h index 385253802d8..9b5f9153561 100644 --- a/targets/TARGET_Maxim/TARGET_MAX32630/mxc/nvic_table.h +++ b/targets/TARGET_Maxim/TARGET_MAX32630/mxc/nvic_table.h @@ -43,46 +43,9 @@ #ifndef _NVIC_TABLE_H #define _NVIC_TABLE_H -#ifdef __cplusplus -extern "C" { -#endif +extern void (*ramVectorTable[MXC_IRQ_COUNT])(void); -/** - * @defgroup mxc_nvic NVIC Functions - * @ingroup sysconfig - * @brief Utility function for setting an IRQ handler dynamically - * @{ - */ - -/** - * @brief Type alias for an IRQ handler. - * @details Type alias for an IRQ handler function with prototype:. - * @code - * void irq_handler(void); - * @endcode - * - */ -typedef void (*irq_fn)(void); - -/** - * @brief Set an IRQ hander function for an IRQ specified by @p irqn. - * @details If the IRQ table is in flash, this function will copy the IRQ table to RAM. - * - * @param irqn ARM external IRQ number, see #IRQn_Type - * @param irq_handler Function to be called at IRQ context - */ -int NVIC_SetVector(IRQn_Type irqn, uint32_t irq_handler); - -/** - * @brief Copy NVIC vector table to RAM and set NVIC to RAM based table. - * - */ -void NVIC_SetRAM(void); - -/**@} end of group mxc_nvic */ - -#ifdef __cplusplus -} -#endif +#define NVIC_NUM_VECTORS (MXC_IRQ_COUNT) +#define NVIC_RAM_VECTOR_ADDRESS (ramVectorTable) // Vectors positioned at start of RAM #endif /* _NVIC_TABLE_H */ diff --git a/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/device/cmsis_nvic.c b/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/device/cmsis_nvic.c deleted file mode 100644 index 5fe8d89d6f4..00000000000 --- a/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/device/cmsis_nvic.c +++ /dev/null @@ -1,103 +0,0 @@ -/* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors - ******************************************************************************* - * Copyright (c) 2011 ARM Limited. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of ARM Limited nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "cmsis_nvic.h" - -/* In the M0, there is no VTOR. In the LPC range such as the LPC11U, - * whilst the vector table may only be something like 48 entries (192 bytes, 0xC0), - * the SYSMEMREMAP register actually remaps the memory from 0x10000000-0x100001FF - * to adress 0x0-0x1FF. In this case, RAM can be addressed at both 0x10000000 and 0x0 - * - * If we just copy the vectors to RAM and switch the SYSMEMMAP, any accesses to FLASH - * above the vector table before 0x200 will actually go to RAM. So we need to provide - * a solution where the compiler gets the right results based on the memory map - * - * Option 1 - We allocate and copy 0x200 of RAM rather than just the table - * - const data and instructions before 0x200 will be copied to and fetched/exec from RAM - * - RAM overhead: 0x200 - 0xC0 = 320 bytes, FLASH overhead: 0 - * - * Option 2 - We pad the flash to 0x200 to ensure the compiler doesn't allocate anything there - * - No flash accesses will go to ram, as there will be nothing there - * - RAM only needs to be allocated for the vectors, as all other ram addresses are normal - * - RAM overhead: 0, FLASH overhead: 320 bytes - * - * Option 2 is the one to go for, as RAM is the most valuable resource - */ - - -#define NVIC_RAM_VECTOR_ADDRESS (0x10000000) // Location of vectors in RAM -#define NVIC_FLASH_VECTOR_ADDRESS (0x0) // Initial vector position in flash -/* -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { - uint32_t *vectors = (uint32_t*)SCB->VTOR; - uint32_t i; - - // Copy and switch to dynamic vectors if the first time called - if (SCB->VTOR == NVIC_FLASH_VECTOR_ADDRESS) { - uint32_t *old_vectors = vectors; - vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS; - for (i=0; iVTOR = (uint32_t)NVIC_RAM_VECTOR_ADDRESS; - } - vectors[IRQn + 16] = vector; -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) { - uint32_t *vectors = (uint32_t*)SCB->VTOR; - return vectors[IRQn + 16]; -}*/ - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { - // int i; - // Space for dynamic vectors, initialised to allocate in R/W - static volatile uint32_t* vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS; - /* - // Copy and switch to dynamic vectors if first time called - if((LPC_SYSCON->SYSMEMREMAP & 0x3) != 0x1) { - uint32_t *old_vectors = (uint32_t *)0; // FLASH vectors are at 0x0 - for(i = 0; i < NVIC_NUM_VECTORS; i++) { - vectors[i] = old_vectors[i]; - } - LPC_SYSCON->SYSMEMREMAP = 0x1; // Remaps 0x0-0x1FF FLASH block to RAM block - }*/ - - // Set the vector - vectors[IRQn + 16] = vector; -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) { - // We can always read vectors at 0x0, as the addresses are remapped - uint32_t *vectors = (uint32_t*)0; - - // Return the vector - return vectors[IRQn + 16]; -} diff --git a/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/device/cmsis_nvic.h b/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/device/cmsis_nvic.h index ab365b2a795..50fa6a7b08a 100644 --- a/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/device/cmsis_nvic.h +++ b/targets/TARGET_NORDIC/TARGET_MCU_NRF51822/device/cmsis_nvic.h @@ -32,22 +32,7 @@ #ifndef MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H -#define NVIC_NUM_VECTORS (16 + 32) // CORE + MCU Peripherals -#define NVIC_USER_IRQ_OFFSET 16 - -#include "nrf51.h" -#include "cmsis.h" - - -#ifdef __cplusplus -extern "C" { -#endif - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +#define NVIC_NUM_VECTORS (16 + 32) // CORE + MCU Peripherals +#define NVIC_RAM_VECTOR_ADDRESS (0x10000000) #endif diff --git a/targets/TARGET_NORDIC/TARGET_NRF5/TARGET_MCU_NRF52832/device/cmsis_nvic.h b/targets/TARGET_NORDIC/TARGET_NRF5/TARGET_MCU_NRF52832/device/cmsis_nvic.h index 0837075c40c..48cc0f9a159 100644 --- a/targets/TARGET_NORDIC/TARGET_NRF5/TARGET_MCU_NRF52832/device/cmsis_nvic.h +++ b/targets/TARGET_NORDIC/TARGET_NRF5/TARGET_MCU_NRF52832/device/cmsis_nvic.h @@ -1,5 +1,4 @@ /* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors ******************************************************************************* * Copyright (c) 2016 ARM Limited. All rights reserved. * All rights reserved. diff --git a/targets/TARGET_NUVOTON/TARGET_M451/device/cmsis_nvic.c b/targets/TARGET_NUVOTON/TARGET_M451/device/cmsis_nvic.c deleted file mode 100644 index 13e150669a0..00000000000 --- a/targets/TARGET_NUVOTON/TARGET_M451/device/cmsis_nvic.c +++ /dev/null @@ -1,39 +0,0 @@ -/* mbed Microcontroller Library - * Copyright (c) 2015-2016 Nuvoton - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include "cmsis_nvic.h" - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) -{ - uint32_t *vectors = (uint32_t *) SCB->VTOR; - uint32_t i; - - /* Copy and switch to dynamic vectors if the first time called */ - if (SCB->VTOR != NVIC_RAM_VECTOR_ADDRESS) { - uint32_t *old_vectors = (uint32_t *) NVIC_FLASH_VECTOR_ADDRESS; - vectors = (uint32_t *) NVIC_RAM_VECTOR_ADDRESS; - for (i = 0; i < NVIC_NUM_VECTORS; i++) { - vectors[i] = old_vectors[i]; - } - SCB->VTOR = (uint32_t) NVIC_RAM_VECTOR_ADDRESS; - } - vectors[IRQn + NVIC_USER_IRQ_OFFSET] = vector; -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) -{ - uint32_t *vectors = (uint32_t *) SCB->VTOR; - return vectors[IRQn + NVIC_USER_IRQ_OFFSET]; -} diff --git a/targets/TARGET_NUVOTON/TARGET_M451/device/cmsis_nvic.h b/targets/TARGET_NUVOTON/TARGET_M451/device/cmsis_nvic.h index 26049c886f3..5fe2a7d143c 100644 --- a/targets/TARGET_NUVOTON/TARGET_M451/device/cmsis_nvic.h +++ b/targets/TARGET_NUVOTON/TARGET_M451/device/cmsis_nvic.h @@ -17,57 +17,15 @@ #ifndef MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H -#include "cmsis.h" - -#define NVIC_USER_IRQ_OFFSET 16 -#define NVIC_USER_IRQ_NUMBER 64 -#define NVIC_NUM_VECTORS (NVIC_USER_IRQ_OFFSET + NVIC_USER_IRQ_NUMBER) +#define NVIC_NUM_VECTORS (16 + 64) #if defined(__CC_ARM) -# define NVIC_RAM_VECTOR_ADDRESS ((uint32_t) &Image$$ER_IRAMVEC$$ZI$$Base) +# define NVIC_RAM_VECTOR_ADDRESS ((uint32_t) &Image$$ER_IRAMVEC$$ZI$$Base) #elif defined(__ICCARM__) # pragma section = "IRAMVEC" -# define NVIC_RAM_VECTOR_ADDRESS ((uint32_t) __section_begin("IRAMVEC")) -#elif defined(__GNUC__) -# define NVIC_RAM_VECTOR_ADDRESS ((uint32_t) &__start_vector_table__) -#endif - -#if defined(__CC_ARM) - extern uint32_t Load$$LR$$LR_IROM1$$Base[]; - #define NVIC_FLASH_VECTOR_ADDRESS ((uint32_t)Load$$LR$$LR_IROM1$$Base) -#elif defined(__ICCARM__) - #pragma section=".intvec" - #define NVIC_FLASH_VECTOR_ADDRESS ((uint32_t)__section_begin(".intvec")) +# define NVIC_RAM_VECTOR_ADDRESS ((uint32_t) __section_begin("IRAMVEC")) #elif defined(__GNUC__) - extern uint32_t __vector_table; - #define NVIC_FLASH_VECTOR_ADDRESS ((uint32_t)&__vector_table) -#else - #error "Flash vector address not set for this toolchain" -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/** Set the ISR for IRQn - * - * Sets an Interrupt Service Routine vector for IRQn; if the feature is available, the vector table is relocated to SRAM - * the first time this function is called - * @param[in] IRQn The Interrupt Request number for which a vector will be registered - * @param[in] vector The ISR vector to register for IRQn - */ -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); - -/** Get the ISR registered for IRQn - * - * Reads the Interrupt Service Routine currently registered for IRQn - * @param[in] IRQn The Interrupt Request number the vector of which will be read - * @return Returns the ISR registered for IRQn - */ -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} +# define NVIC_RAM_VECTOR_ADDRESS ((uint32_t) &__start_vector_table__) #endif #endif diff --git a/targets/TARGET_NUVOTON/TARGET_NUC472/device/cmsis_nvic.c b/targets/TARGET_NUVOTON/TARGET_NUC472/device/cmsis_nvic.c deleted file mode 100644 index 13e150669a0..00000000000 --- a/targets/TARGET_NUVOTON/TARGET_NUC472/device/cmsis_nvic.c +++ /dev/null @@ -1,39 +0,0 @@ -/* mbed Microcontroller Library - * Copyright (c) 2015-2016 Nuvoton - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include "cmsis_nvic.h" - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) -{ - uint32_t *vectors = (uint32_t *) SCB->VTOR; - uint32_t i; - - /* Copy and switch to dynamic vectors if the first time called */ - if (SCB->VTOR != NVIC_RAM_VECTOR_ADDRESS) { - uint32_t *old_vectors = (uint32_t *) NVIC_FLASH_VECTOR_ADDRESS; - vectors = (uint32_t *) NVIC_RAM_VECTOR_ADDRESS; - for (i = 0; i < NVIC_NUM_VECTORS; i++) { - vectors[i] = old_vectors[i]; - } - SCB->VTOR = (uint32_t) NVIC_RAM_VECTOR_ADDRESS; - } - vectors[IRQn + NVIC_USER_IRQ_OFFSET] = vector; -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) -{ - uint32_t *vectors = (uint32_t *) SCB->VTOR; - return vectors[IRQn + NVIC_USER_IRQ_OFFSET]; -} diff --git a/targets/TARGET_NUVOTON/TARGET_NUC472/device/cmsis_nvic.h b/targets/TARGET_NUVOTON/TARGET_NUC472/device/cmsis_nvic.h index e5e797a87a3..1c402d84c6f 100644 --- a/targets/TARGET_NUVOTON/TARGET_NUC472/device/cmsis_nvic.h +++ b/targets/TARGET_NUVOTON/TARGET_NUC472/device/cmsis_nvic.h @@ -17,11 +17,7 @@ #ifndef MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H -#include "cmsis.h" - -#define NVIC_USER_IRQ_OFFSET 16 -#define NVIC_USER_IRQ_NUMBER 142 -#define NVIC_NUM_VECTORS (NVIC_USER_IRQ_OFFSET + NVIC_USER_IRQ_NUMBER) +#define NVIC_NUM_VECTORS (16 + 142) #if defined(__CC_ARM) # define NVIC_RAM_VECTOR_ADDRESS ((uint32_t) &Image$$ER_IRAMVEC$$ZI$$Base) @@ -32,42 +28,4 @@ # define NVIC_RAM_VECTOR_ADDRESS ((uint32_t) &__start_vector_table__) #endif -#if defined(__CC_ARM) - extern uint32_t Load$$LR$$LR_IROM1$$Base[]; - #define NVIC_FLASH_VECTOR_ADDRESS ((uint32_t)Load$$LR$$LR_IROM1$$Base) -#elif defined(__ICCARM__) - #pragma section=".intvec" - #define NVIC_FLASH_VECTOR_ADDRESS ((uint32_t)__section_begin(".intvec")) -#elif defined(__GNUC__) - extern uint32_t __vector_table; - #define NVIC_FLASH_VECTOR_ADDRESS ((uint32_t)&__vector_table) -#else - #error "Flash vector address not set for this toolchain" -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/** Set the ISR for IRQn - * - * Sets an Interrupt Service Routine vector for IRQn; if the feature is available, the vector table is relocated to SRAM - * the first time this function is called - * @param[in] IRQn The Interrupt Request number for which a vector will be registered - * @param[in] vector The ISR vector to register for IRQn - */ -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); - -/** Get the ISR registered for IRQn - * - * Reads the Interrupt Service Routine currently registered for IRQn - * @param[in] IRQn The Interrupt Request number the vector of which will be read - * @return Returns the ISR registered for IRQn - */ -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif - #endif diff --git a/targets/TARGET_NXP/TARGET_LPC11U6X/device/cmsis_nvic.c b/targets/TARGET_NXP/TARGET_LPC11U6X/device/cmsis_nvic.c deleted file mode 100644 index ee0e4a7186c..00000000000 --- a/targets/TARGET_NXP/TARGET_LPC11U6X/device/cmsis_nvic.c +++ /dev/null @@ -1,55 +0,0 @@ -/* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors - ******************************************************************************* - * Copyright (c) 2011 ARM Limited. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of ARM Limited nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "cmsis_nvic.h" - -#define NVIC_RAM_VECTOR_ADDRESS (0x10000000) // Vectors positioned at start of RAM -#define NVIC_FLASH_VECTOR_ADDRESS (0x0) // Initial vector position in flash - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { - uint32_t *vectors = (uint32_t*)SCB->VTOR; - uint32_t i; - - // Copy and switch to dynamic vectors if the first time called - if (SCB->VTOR == NVIC_FLASH_VECTOR_ADDRESS) { - uint32_t *old_vectors = vectors; - vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS; - for (i=0; iVTOR = (uint32_t)NVIC_RAM_VECTOR_ADDRESS; - } - vectors[IRQn + 16] = vector; -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) { - uint32_t *vectors = (uint32_t*)SCB->VTOR; - return vectors[IRQn + 16]; -} diff --git a/targets/TARGET_NXP/TARGET_LPC11U6X/device/cmsis_nvic.h b/targets/TARGET_NXP/TARGET_LPC11U6X/device/cmsis_nvic.h index 64f36b31671..673754cf2ad 100644 --- a/targets/TARGET_NXP/TARGET_LPC11U6X/device/cmsis_nvic.h +++ b/targets/TARGET_NXP/TARGET_LPC11U6X/device/cmsis_nvic.h @@ -1,5 +1,4 @@ /* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors ******************************************************************************* * Copyright (c) 2011 ARM Limited. All rights reserved. * All rights reserved. @@ -32,20 +31,7 @@ #ifndef MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H -#define NVIC_NUM_VECTORS (16 + 32) // CORE + MCU Peripherals -#define NVIC_USER_IRQ_OFFSET 16 - -#include "cmsis.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +#define NVIC_NUM_VECTORS (16 + 32) // CORE + MCU Peripherals +#define NVIC_RAM_VECTOR_ADDRESS 0x10000000 // Vectors positioned at start of RAM #endif diff --git a/targets/TARGET_NXP/TARGET_LPC11UXX/device/cmsis_nvic.c b/targets/TARGET_NXP/TARGET_LPC11UXX/device/cmsis_nvic.c deleted file mode 100644 index 4127988d620..00000000000 --- a/targets/TARGET_NXP/TARGET_LPC11UXX/device/cmsis_nvic.c +++ /dev/null @@ -1,81 +0,0 @@ -/* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors - ******************************************************************************* - * Copyright (c) 2011 ARM Limited. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of ARM Limited nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "cmsis_nvic.h" - -/* In the M0, there is no VTOR. In the LPC range such as the LPC11U, - * whilst the vector table may only be something like 48 entries (192 bytes, 0xC0), - * the SYSMEMREMAP register actually remaps the memory from 0x10000000-0x100001FF - * to adress 0x0-0x1FF. In this case, RAM can be addressed at both 0x10000000 and 0x0 - * - * If we just copy the vectors to RAM and switch the SYSMEMMAP, any accesses to FLASH - * above the vector table before 0x200 will actually go to RAM. So we need to provide - * a solution where the compiler gets the right results based on the memory map - * - * Option 1 - We allocate and copy 0x200 of RAM rather than just the table - * - const data and instructions before 0x200 will be copied to and fetched/exec from RAM - * - RAM overhead: 0x200 - 0xC0 = 320 bytes, FLASH overhead: 0 - * - * Option 2 - We pad the flash to 0x200 to ensure the compiler doesn't allocate anything there - * - No flash accesses will go to ram, as there will be nothing there - * - RAM only needs to be allocated for the vectors, as all other ram addresses are normal - * - RAM overhead: 0, FLASH overhead: 320 bytes - * - * Option 2 is the one to go for, as RAM is the most valuable resource - */ - -#define NVIC_RAM_VECTOR_ADDRESS (0x10000000) // Vectors positioned at start of RAM - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { - int i; - // Space for dynamic vectors, initialised to allocate in R/W - static volatile uint32_t* vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS; - - // Copy and switch to dynamic vectors if first time called - if((LPC_SYSCON->SYSMEMREMAP & 0x3) != 0x1) { - uint32_t *old_vectors = (uint32_t *)0; // FLASH vectors are at 0x0 - for(i = 0; i < NVIC_NUM_VECTORS; i++) { - vectors[i] = old_vectors[i]; - } - LPC_SYSCON->SYSMEMREMAP = 0x1; // Remaps 0x0-0x1FF FLASH block to RAM block - } - - // Set the vector - vectors[IRQn + 16] = vector; -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) { - // We can always read vectors at 0x0, as the addresses are remapped - uint32_t *vectors = (uint32_t*)0; - - // Return the vector - return vectors[IRQn + 16]; -} - diff --git a/targets/TARGET_NXP/TARGET_LPC11UXX/device/cmsis_nvic.h b/targets/TARGET_NXP/TARGET_LPC11UXX/device/cmsis_nvic.h index 324e797047f..50fa6a7b08a 100644 --- a/targets/TARGET_NXP/TARGET_LPC11UXX/device/cmsis_nvic.h +++ b/targets/TARGET_NXP/TARGET_LPC11UXX/device/cmsis_nvic.h @@ -32,20 +32,7 @@ #ifndef MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H -#include "cmsis.h" - -#define NVIC_NUM_VECTORS (16 + 32) // CORE + MCU Peripherals -#define NVIC_USER_IRQ_OFFSET 16 - -#ifdef __cplusplus -extern "C" { -#endif - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +#define NVIC_NUM_VECTORS (16 + 32) // CORE + MCU Peripherals +#define NVIC_RAM_VECTOR_ADDRESS (0x10000000) #endif diff --git a/targets/TARGET_NXP/TARGET_LPC11XX_11CXX/device/cmsis_nvic.c b/targets/TARGET_NXP/TARGET_LPC11XX_11CXX/device/cmsis_nvic.c deleted file mode 100644 index 3057d555123..00000000000 --- a/targets/TARGET_NXP/TARGET_LPC11XX_11CXX/device/cmsis_nvic.c +++ /dev/null @@ -1,82 +0,0 @@ -/* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors - ******************************************************************************* - * Copyright (c) 2011 ARM Limited. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of ARM Limited nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ - -#include "cmsis_nvic.h" - -/* In the M0, there is no VTOR. In the LPC range such as the LPC11U, - * whilst the vector table may only be something like 48 entries (192 bytes, 0xC0), - * the SYSMEMREMAP register actually remaps the memory from 0x10000000-0x100001FF - * to adress 0x0-0x1FF. In this case, RAM can be addressed at both 0x10000000 and 0x0 - * - * If we just copy the vectors to RAM and switch the SYSMEMMAP, any accesses to FLASH - * above the vector table before 0x200 will actually go to RAM. So we need to provide - * a solution where the compiler gets the right results based on the memory map - * - * Option 1 - We allocate and copy 0x200 of RAM rather than just the table - * - const data and instructions before 0x200 will be copied to and fetched/exec from RAM - * - RAM overhead: 0x200 - 0xC0 = 320 bytes, FLASH overhead: 0 - * - * Option 2 - We pad the flash to 0x200 to ensure the compiler doesn't allocate anything there - * - No flash accesses will go to ram, as there will be nothing there - * - RAM only needs to be allocated for the vectors, as all other ram addresses are normal - * - RAM overhead: 0, FLASH overhead: 320 bytes - * - * Option 2 is the one to go for, as RAM is the most valuable resource - */ - -#define NVIC_RAM_VECTOR_ADDRESS (0x10000000) // Vectors positioned at start of RAM - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { - int i; - // Space for dynamic vectors, initialised to allocate in R/W - static volatile uint32_t* vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS; - - // Copy and switch to dynamic vectors if first time called - if((LPC_SYSCON->SYSMEMREMAP & 0x3) != 0x1) { - uint32_t *old_vectors = (uint32_t *)0; // FLASH vectors are at 0x0 - for(i = 0; i < NVIC_NUM_VECTORS; i++) { - vectors[i] = old_vectors[i]; - } - LPC_SYSCON->SYSMEMREMAP = 0x1; // Remaps 0x0-0x1FF FLASH block to RAM block - } - - // Set the vector - vectors[IRQn + 16] = vector; -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) { - // We can always read vectors at 0x0, as the addresses are remapped - uint32_t *vectors = (uint32_t*)0; - - // Return the vector - return vectors[IRQn + 16]; -} - diff --git a/targets/TARGET_NXP/TARGET_LPC11XX_11CXX/device/cmsis_nvic.h b/targets/TARGET_NXP/TARGET_LPC11XX_11CXX/device/cmsis_nvic.h index 324e797047f..8a0db6b9692 100644 --- a/targets/TARGET_NXP/TARGET_LPC11XX_11CXX/device/cmsis_nvic.h +++ b/targets/TARGET_NXP/TARGET_LPC11XX_11CXX/device/cmsis_nvic.h @@ -34,18 +34,7 @@ #include "cmsis.h" -#define NVIC_NUM_VECTORS (16 + 32) // CORE + MCU Peripherals -#define NVIC_USER_IRQ_OFFSET 16 - -#ifdef __cplusplus -extern "C" { -#endif - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +#define NVIC_NUM_VECTORS (16 + 32) // CORE + MCU Peripherals +#define NVIC_RAM_VECTOR_ADDRESS (0x10000000) // Vectors positioned at start of RAM #endif diff --git a/targets/TARGET_NXP/TARGET_LPC13XX/device/cmsis_nvic.c b/targets/TARGET_NXP/TARGET_LPC13XX/device/cmsis_nvic.c deleted file mode 100644 index c057a64d92c..00000000000 --- a/targets/TARGET_NXP/TARGET_LPC13XX/device/cmsis_nvic.c +++ /dev/null @@ -1,56 +0,0 @@ -/* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors - ******************************************************************************* - * Copyright (c) 2011 ARM Limited. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of ARM Limited nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "cmsis_nvic.h" - -#define NVIC_RAM_VECTOR_ADDRESS (0x10000000) // Location of vectors in RAM -#define NVIC_FLASH_VECTOR_ADDRESS (0x0) // Initial vector position in flash - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { - uint32_t *vectors = (uint32_t*)SCB->VTOR; - uint32_t i; - - // Copy and switch to dynamic vectors if the first time called - if (SCB->VTOR == NVIC_FLASH_VECTOR_ADDRESS) { - uint32_t *old_vectors = vectors; - vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS; - for (i=0; iVTOR = (uint32_t)NVIC_RAM_VECTOR_ADDRESS; - } - vectors[IRQn + 16] = vector; -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) { - uint32_t *vectors = (uint32_t*)SCB->VTOR; - return vectors[IRQn + 16]; -} - diff --git a/targets/TARGET_NXP/TARGET_LPC13XX/device/cmsis_nvic.h b/targets/TARGET_NXP/TARGET_LPC13XX/device/cmsis_nvic.h index 324e797047f..68dd41fd836 100644 --- a/targets/TARGET_NXP/TARGET_LPC13XX/device/cmsis_nvic.h +++ b/targets/TARGET_NXP/TARGET_LPC13XX/device/cmsis_nvic.h @@ -1,5 +1,4 @@ /* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors ******************************************************************************* * Copyright (c) 2011 ARM Limited. All rights reserved. * All rights reserved. @@ -32,20 +31,7 @@ #ifndef MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H -#include "cmsis.h" - -#define NVIC_NUM_VECTORS (16 + 32) // CORE + MCU Peripherals -#define NVIC_USER_IRQ_OFFSET 16 - -#ifdef __cplusplus -extern "C" { -#endif - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +#define NVIC_NUM_VECTORS (16 + 32) // CORE + MCU Peripherals +#define NVIC_RAM_VECTOR_ADDRESS 0x10000000 // Location of vectors in RAM #endif diff --git a/targets/TARGET_NXP/TARGET_LPC15XX/device/cmsis_nvic.c b/targets/TARGET_NXP/TARGET_LPC15XX/device/cmsis_nvic.c deleted file mode 100644 index d1c12690d32..00000000000 --- a/targets/TARGET_NXP/TARGET_LPC15XX/device/cmsis_nvic.c +++ /dev/null @@ -1,55 +0,0 @@ -/* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors - ******************************************************************************* - * Copyright (c) 2011 ARM Limited. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of ARM Limited nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "cmsis_nvic.h" - -#define NVIC_RAM_VECTOR_ADDRESS (0x02000000) // Vectors positioned at start of RAM -#define NVIC_FLASH_VECTOR_ADDRESS (0x0) // Initial vector position in flash - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { - uint32_t *vectors = (uint32_t*)SCB->VTOR; - uint32_t i; - - // Copy and switch to dynamic vectors if the first time called - if (SCB->VTOR == NVIC_FLASH_VECTOR_ADDRESS) { - uint32_t *old_vectors = vectors; - vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS; - for (i=0; iVTOR = (uint32_t)NVIC_RAM_VECTOR_ADDRESS; - } - vectors[IRQn + 16] = vector; -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) { - uint32_t *vectors = (uint32_t*)SCB->VTOR; - return vectors[IRQn + 16]; -} diff --git a/targets/TARGET_NXP/TARGET_LPC15XX/device/cmsis_nvic.h b/targets/TARGET_NXP/TARGET_LPC15XX/device/cmsis_nvic.h index 0d94c036458..9b7be8845b9 100644 --- a/targets/TARGET_NXP/TARGET_LPC15XX/device/cmsis_nvic.h +++ b/targets/TARGET_NXP/TARGET_LPC15XX/device/cmsis_nvic.h @@ -1,5 +1,4 @@ /* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors ******************************************************************************* * Copyright (c) 2011 ARM Limited. All rights reserved. * All rights reserved. @@ -32,20 +31,7 @@ #ifndef MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H -#define NVIC_NUM_VECTORS (16 + 47) // CORE + MCU Peripherals -#define NVIC_USER_IRQ_OFFSET 16 - -#include "cmsis.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +#define NVIC_NUM_VECTORS (16 + 47) // CORE + MCU Peripherals +#define NVIC_RAM_VECTOR_ADDRESS 0x02000000 // Vectors positioned at start of RAM #endif diff --git a/targets/TARGET_NXP/TARGET_LPC176X/device/cmsis_nvic.c b/targets/TARGET_NXP/TARGET_LPC176X/device/cmsis_nvic.c deleted file mode 100644 index 1c25784683f..00000000000 --- a/targets/TARGET_NXP/TARGET_LPC176X/device/cmsis_nvic.c +++ /dev/null @@ -1,56 +0,0 @@ -/* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors - ******************************************************************************* - * Copyright (c) 2011 ARM Limited. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of ARM Limited nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "cmsis_nvic.h" - -#define NVIC_RAM_VECTOR_ADDRESS (0x10000000) // Location of vectors in RAM -#define NVIC_FLASH_VECTOR_ADDRESS (0x0) // Initial vector position in flash - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { - uint32_t *vectors = (uint32_t*)SCB->VTOR; - uint32_t i; - - // Copy and switch to dynamic vectors if the first time called - if (SCB->VTOR < NVIC_RAM_VECTOR_ADDRESS) { - uint32_t *old_vectors = vectors; - vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS; - for (i=0; iVTOR = (uint32_t)NVIC_RAM_VECTOR_ADDRESS; - } - vectors[IRQn + NVIC_USER_IRQ_OFFSET] = vector; -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) { - uint32_t *vectors = (uint32_t*)SCB->VTOR; - return vectors[IRQn + NVIC_USER_IRQ_OFFSET]; -} - diff --git a/targets/TARGET_NXP/TARGET_LPC176X/device/cmsis_nvic.h b/targets/TARGET_NXP/TARGET_LPC176X/device/cmsis_nvic.h index 9b81fd25b8c..2ea4323b43b 100644 --- a/targets/TARGET_NXP/TARGET_LPC176X/device/cmsis_nvic.h +++ b/targets/TARGET_NXP/TARGET_LPC176X/device/cmsis_nvic.h @@ -1,5 +1,4 @@ /* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors ******************************************************************************* * Copyright (c) 2011 ARM Limited. All rights reserved. * All rights reserved. @@ -32,20 +31,7 @@ #ifndef MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H -#include "cmsis.h" - -#define NVIC_NUM_VECTORS (16 + 33) -#define NVIC_USER_IRQ_OFFSET 16 - -#ifdef __cplusplus -extern "C" { -#endif - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +#define NVIC_NUM_VECTORS (16 + 33) +#define NVIC_RAM_VECTOR_ADDRESS 0x10000000 // Location of vectors in RAM #endif diff --git a/targets/TARGET_NXP/TARGET_LPC408X/device/cmsis_nvic.c b/targets/TARGET_NXP/TARGET_LPC408X/device/cmsis_nvic.c deleted file mode 100644 index c057a64d92c..00000000000 --- a/targets/TARGET_NXP/TARGET_LPC408X/device/cmsis_nvic.c +++ /dev/null @@ -1,56 +0,0 @@ -/* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors - ******************************************************************************* - * Copyright (c) 2011 ARM Limited. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of ARM Limited nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "cmsis_nvic.h" - -#define NVIC_RAM_VECTOR_ADDRESS (0x10000000) // Location of vectors in RAM -#define NVIC_FLASH_VECTOR_ADDRESS (0x0) // Initial vector position in flash - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { - uint32_t *vectors = (uint32_t*)SCB->VTOR; - uint32_t i; - - // Copy and switch to dynamic vectors if the first time called - if (SCB->VTOR == NVIC_FLASH_VECTOR_ADDRESS) { - uint32_t *old_vectors = vectors; - vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS; - for (i=0; iVTOR = (uint32_t)NVIC_RAM_VECTOR_ADDRESS; - } - vectors[IRQn + 16] = vector; -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) { - uint32_t *vectors = (uint32_t*)SCB->VTOR; - return vectors[IRQn + 16]; -} - diff --git a/targets/TARGET_NXP/TARGET_LPC408X/device/cmsis_nvic.h b/targets/TARGET_NXP/TARGET_LPC408X/device/cmsis_nvic.h index 4f773ecdf0b..f13e0af88e4 100644 --- a/targets/TARGET_NXP/TARGET_LPC408X/device/cmsis_nvic.h +++ b/targets/TARGET_NXP/TARGET_LPC408X/device/cmsis_nvic.h @@ -1,5 +1,4 @@ /* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors ******************************************************************************* * Copyright (c) 2011 ARM Limited. All rights reserved. * All rights reserved. @@ -32,20 +31,7 @@ #ifndef MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H -#define NVIC_NUM_VECTORS (16 + 41) // CORE + MCU Peripherals -#define NVIC_USER_IRQ_OFFSET 16 - -#include "cmsis.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +#define NVIC_NUM_VECTORS (16 + 41) // CORE + MCU Peripherals +#define NVIC_RAM_VECTOR_ADDRESS 0x10000000 // Location of vectors in RAM #endif diff --git a/targets/TARGET_NXP/TARGET_LPC43XX/device/cmsis_nvic.c b/targets/TARGET_NXP/TARGET_LPC43XX/device/cmsis_nvic.c deleted file mode 100644 index fe3e253f563..00000000000 --- a/targets/TARGET_NXP/TARGET_LPC43XX/device/cmsis_nvic.c +++ /dev/null @@ -1,61 +0,0 @@ -/* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors - ******************************************************************************* - * Copyright (c) 2011 ARM Limited. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of ARM Limited nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "cmsis_nvic.h" - -#define NVIC_RAM_VECTOR_ADDRESS (0x10000000) // Location of vectors in RAM - -// The LPC43xx can boot from multiple memories (internal Flash, external NOR, -// external SPIFI) so we don't know the initial value of VTOR. Thus we use -// a variable to keep track if the vector table was relocated or not -static unsigned char vtor_relocated; - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { - uint32_t *vectors = (uint32_t*)SCB->VTOR; - uint32_t i; - - // Copy and switch to dynamic vectors if first time called - if (!vtor_relocated) { - uint32_t *old_vectors = vectors; - vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS; - for (i=0; iVTOR = (uint32_t)NVIC_RAM_VECTOR_ADDRESS; - vtor_relocated = 1; - } - vectors[IRQn + 16] = vector; -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) { - uint32_t *vectors = (uint32_t*)SCB->VTOR; - return vectors[IRQn + 16]; -} - diff --git a/targets/TARGET_NXP/TARGET_LPC43XX/device/cmsis_nvic.h b/targets/TARGET_NXP/TARGET_LPC43XX/device/cmsis_nvic.h index b4ec7704ac8..ff5f53492c6 100644 --- a/targets/TARGET_NXP/TARGET_LPC43XX/device/cmsis_nvic.h +++ b/targets/TARGET_NXP/TARGET_LPC43XX/device/cmsis_nvic.h @@ -1,5 +1,4 @@ /* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors ******************************************************************************* * Copyright (c) 2011 ARM Limited. All rights reserved. * All rights reserved. @@ -32,20 +31,7 @@ #ifndef MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H -#define NVIC_NUM_VECTORS (16 + 53) // CORE + MCU Peripherals -#define NVIC_USER_IRQ_OFFSET 16 - -#include "cmsis.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +#define NVIC_NUM_VECTORS (16 + 53) // CORE + MCU Peripherals +#define NVIC_RAM_VECTOR_ADDRESS 0x10000000 // Location of vectors in RAM #endif diff --git a/targets/TARGET_NXP/TARGET_LPC81X/device/cmsis_nvic.c b/targets/TARGET_NXP/TARGET_LPC81X/device/cmsis_nvic.c deleted file mode 100644 index ee0e4a7186c..00000000000 --- a/targets/TARGET_NXP/TARGET_LPC81X/device/cmsis_nvic.c +++ /dev/null @@ -1,55 +0,0 @@ -/* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors - ******************************************************************************* - * Copyright (c) 2011 ARM Limited. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of ARM Limited nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "cmsis_nvic.h" - -#define NVIC_RAM_VECTOR_ADDRESS (0x10000000) // Vectors positioned at start of RAM -#define NVIC_FLASH_VECTOR_ADDRESS (0x0) // Initial vector position in flash - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { - uint32_t *vectors = (uint32_t*)SCB->VTOR; - uint32_t i; - - // Copy and switch to dynamic vectors if the first time called - if (SCB->VTOR == NVIC_FLASH_VECTOR_ADDRESS) { - uint32_t *old_vectors = vectors; - vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS; - for (i=0; iVTOR = (uint32_t)NVIC_RAM_VECTOR_ADDRESS; - } - vectors[IRQn + 16] = vector; -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) { - uint32_t *vectors = (uint32_t*)SCB->VTOR; - return vectors[IRQn + 16]; -} diff --git a/targets/TARGET_NXP/TARGET_LPC81X/device/cmsis_nvic.h b/targets/TARGET_NXP/TARGET_LPC81X/device/cmsis_nvic.h index 64f36b31671..673754cf2ad 100644 --- a/targets/TARGET_NXP/TARGET_LPC81X/device/cmsis_nvic.h +++ b/targets/TARGET_NXP/TARGET_LPC81X/device/cmsis_nvic.h @@ -1,5 +1,4 @@ /* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors ******************************************************************************* * Copyright (c) 2011 ARM Limited. All rights reserved. * All rights reserved. @@ -32,20 +31,7 @@ #ifndef MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H -#define NVIC_NUM_VECTORS (16 + 32) // CORE + MCU Peripherals -#define NVIC_USER_IRQ_OFFSET 16 - -#include "cmsis.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +#define NVIC_NUM_VECTORS (16 + 32) // CORE + MCU Peripherals +#define NVIC_RAM_VECTOR_ADDRESS 0x10000000 // Vectors positioned at start of RAM #endif diff --git a/targets/TARGET_NXP/TARGET_LPC82X/device/cmsis_nvic.c b/targets/TARGET_NXP/TARGET_LPC82X/device/cmsis_nvic.c deleted file mode 100644 index ee0e4a7186c..00000000000 --- a/targets/TARGET_NXP/TARGET_LPC82X/device/cmsis_nvic.c +++ /dev/null @@ -1,55 +0,0 @@ -/* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors - ******************************************************************************* - * Copyright (c) 2011 ARM Limited. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of ARM Limited nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "cmsis_nvic.h" - -#define NVIC_RAM_VECTOR_ADDRESS (0x10000000) // Vectors positioned at start of RAM -#define NVIC_FLASH_VECTOR_ADDRESS (0x0) // Initial vector position in flash - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { - uint32_t *vectors = (uint32_t*)SCB->VTOR; - uint32_t i; - - // Copy and switch to dynamic vectors if the first time called - if (SCB->VTOR == NVIC_FLASH_VECTOR_ADDRESS) { - uint32_t *old_vectors = vectors; - vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS; - for (i=0; iVTOR = (uint32_t)NVIC_RAM_VECTOR_ADDRESS; - } - vectors[IRQn + 16] = vector; -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) { - uint32_t *vectors = (uint32_t*)SCB->VTOR; - return vectors[IRQn + 16]; -} diff --git a/targets/TARGET_NXP/TARGET_LPC82X/device/cmsis_nvic.h b/targets/TARGET_NXP/TARGET_LPC82X/device/cmsis_nvic.h index 64f36b31671..673754cf2ad 100644 --- a/targets/TARGET_NXP/TARGET_LPC82X/device/cmsis_nvic.h +++ b/targets/TARGET_NXP/TARGET_LPC82X/device/cmsis_nvic.h @@ -1,5 +1,4 @@ /* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors ******************************************************************************* * Copyright (c) 2011 ARM Limited. All rights reserved. * All rights reserved. @@ -32,20 +31,7 @@ #ifndef MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H -#define NVIC_NUM_VECTORS (16 + 32) // CORE + MCU Peripherals -#define NVIC_USER_IRQ_OFFSET 16 - -#include "cmsis.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +#define NVIC_NUM_VECTORS (16 + 32) // CORE + MCU Peripherals +#define NVIC_RAM_VECTOR_ADDRESS 0x10000000 // Vectors positioned at start of RAM #endif diff --git a/targets/TARGET_ONSEMI/TARGET_NCS36510/device/cmsis_nvic.c b/targets/TARGET_ONSEMI/TARGET_NCS36510/device/cmsis_nvic.c deleted file mode 100644 index 76ed0fd68d8..00000000000 --- a/targets/TARGET_ONSEMI/TARGET_NCS36510/device/cmsis_nvic.c +++ /dev/null @@ -1,43 +0,0 @@ -/** -****************************************************************************** -* @file cmsis_nvic.c -* @brief Contains relocatable exception table. -* @internal -* @author ON Semiconductor. -* $Rev: 0.1 $ -* $Date: 2015-11-06 $ -****************************************************************************** -* Copyright 2016 Semiconductor Components Industries LLC (d/b/a “ON Semiconductor”). -* All rights reserved. This software and/or documentation is licensed by ON Semiconductor -* under limited terms and conditions. The terms and conditions pertaining to the software -* and/or documentation are available at http://www.onsemi.com/site/pdf/ONSEMI_T&C.pdf -* (“ON Semiconductor Standard Terms and Conditions of Sale, Section 8 Software”) and -* if applicable the software license agreement. Do not use this software and/or -* documentation unless you have carefully read and you agree to the limited terms and -* conditions. By using this software and/or documentation, you agree to the limited -* terms and conditions. -* -* 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. -* ON SEMICONDUCTOR SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, -* INCIDENTAL, OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. -* @endinternal -* -* @ingroup -* -* @details -*/ - -#include - -#define NVIC_RAM_VECTOR_ADDRESS (0x3FFF4000) // Vectors positioned at start of RAM -#define NVIC_FLASH_VECTOR_ADDRESS (0x00000000) // Initial vector position in flash - - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) -{ - static volatile uint32_t *vectors = (uint32_t *)NVIC_FLASH_VECTOR_ADDRESS; - - vectors[IRQn + 16] = vector; -} diff --git a/targets/TARGET_ONSEMI/TARGET_NCS36510/device/cmsis_nvic.h b/targets/TARGET_ONSEMI/TARGET_NCS36510/device/cmsis_nvic.h index 792d4a2b7d1..665638b571d 100644 --- a/targets/TARGET_ONSEMI/TARGET_NCS36510/device/cmsis_nvic.h +++ b/targets/TARGET_ONSEMI/TARGET_NCS36510/device/cmsis_nvic.h @@ -28,6 +28,6 @@ * * @details */ -#include "NCS36510.h" -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); +#define NVIC_NUM_VECTORS (16 + 20) +#define NVIC_RAM_VECTOR_ADDRESS 0x3FFF4000 // Vectors positioned at start of RAM diff --git a/targets/TARGET_STM/TARGET_STM32F0/TARGET_DISCO_F051R8/device/cmsis_nvic.c b/targets/TARGET_STM/TARGET_STM32F0/TARGET_DISCO_F051R8/device/cmsis_nvic.c deleted file mode 100644 index a5d638105a1..00000000000 --- a/targets/TARGET_STM/TARGET_STM32F0/TARGET_DISCO_F051R8/device/cmsis_nvic.c +++ /dev/null @@ -1,56 +0,0 @@ -/* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors - ******************************************************************************* - * Copyright (c) 2015, STMicroelectronics - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "cmsis_nvic.h" - -#define NVIC_RAM_VECTOR_ADDRESS (0x20000000) // Vectors positioned at start of RAM -#define NVIC_FLASH_VECTOR_ADDRESS (0x08000000) // Initial vector position in flash - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { - int i; - - // Copy and switch to dynamic vectors if first time called - if ((SYSCFG->CFGR1 & SYSCFG_CFGR1_MEM_MODE) != SYSCFG_CFGR1_MEM_MODE) { - uint32_t *old_vectors = (uint32_t *)NVIC_FLASH_VECTOR_ADDRESS; - for (i = 0; i < NVIC_NUM_VECTORS; i++) { - *((uint32_t *)(NVIC_RAM_VECTOR_ADDRESS + (i*4))) = old_vectors[i]; - } - SYSCFG->CFGR1 |= SYSCFG_CFGR1_MEM_MODE; // Embedded SRAM mapped at 0x00000000 - } - - // Set the vector - *((uint32_t *)(NVIC_RAM_VECTOR_ADDRESS + (IRQn*4) + (NVIC_USER_IRQ_OFFSET*4))) = vector; -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) { - uint32_t *vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS; - // Return the vector - return vectors[IRQn + 16]; -} diff --git a/targets/TARGET_STM/TARGET_STM32F0/TARGET_DISCO_F051R8/device/cmsis_nvic.h b/targets/TARGET_STM/TARGET_STM32F0/TARGET_DISCO_F051R8/device/cmsis_nvic.h index 019fc7d6f83..33af5deedae 100644 --- a/targets/TARGET_STM/TARGET_STM32F0/TARGET_DISCO_F051R8/device/cmsis_nvic.h +++ b/targets/TARGET_STM/TARGET_STM32F0/TARGET_DISCO_F051R8/device/cmsis_nvic.h @@ -36,20 +36,7 @@ // CORE: 16 vectors = 64 bytes from 0x00 to 0x3F // MCU Peripherals: 32 vectors = 128 bytes from 0x40 to 0xBF // Total: 48 vectors = 192 bytes (0xC0) to be reserved in RAM -#define NVIC_NUM_VECTORS (16 + 32 ) -#define NVIC_USER_IRQ_OFFSET 16 - -#include "cmsis.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +#define NVIC_NUM_VECTORS (16 + 32 ) +#define NVIC_RAM_VECTOR_ADDRESS (0x20000000) // Vectors positioned at start of RAM #endif diff --git a/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F030R8/device/cmsis_nvic.c b/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F030R8/device/cmsis_nvic.c deleted file mode 100644 index 2e9e8638bb9..00000000000 --- a/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F030R8/device/cmsis_nvic.c +++ /dev/null @@ -1,57 +0,0 @@ -/* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors - ******************************************************************************* - * Copyright (c) 2015, STMicroelectronics - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "cmsis_nvic.h" - -#define NVIC_RAM_VECTOR_ADDRESS (0x20000000) // Vectors positioned at start of RAM -#define NVIC_FLASH_VECTOR_ADDRESS (0x08000000) // Initial vector position in flash - - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { - int i; - - // Copy and switch to dynamic vectors if first time called - if ((SYSCFG->CFGR1 & SYSCFG_CFGR1_MEM_MODE) != SYSCFG_CFGR1_MEM_MODE) { - uint32_t *old_vectors = (uint32_t *)NVIC_FLASH_VECTOR_ADDRESS; - for (i = 0; i < NVIC_NUM_VECTORS; i++) { - *((uint32_t *)(NVIC_RAM_VECTOR_ADDRESS + (i*4))) = old_vectors[i]; - } - SYSCFG->CFGR1 |= SYSCFG_CFGR1_MEM_MODE; // Embedded SRAM mapped at 0x00000000 - } - - // Set the vector - *((uint32_t *)(NVIC_RAM_VECTOR_ADDRESS + (IRQn*4) + (NVIC_USER_IRQ_OFFSET*4))) = vector; -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) { - uint32_t *vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS; - // Return the vector - return vectors[IRQn + 16]; -} diff --git a/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F030R8/device/cmsis_nvic.h b/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F030R8/device/cmsis_nvic.h index 570550abfdb..b02ba60cc0c 100644 --- a/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F030R8/device/cmsis_nvic.h +++ b/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F030R8/device/cmsis_nvic.h @@ -36,20 +36,7 @@ // CORE: 16 vectors = 64 bytes from 0x00 to 0x3F // MCU Peripherals: 29 vectors = 116 bytes from 0x40 to 0xB3 // Total: 45 vectors = 180 bytes (0xB4) to be reserved in RAM -#define NVIC_NUM_VECTORS 45 -#define NVIC_USER_IRQ_OFFSET 16 - -#include "cmsis.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +#define NVIC_NUM_VECTORS 45 +#define NVIC_RAM_VECTOR_ADDRESS (0x20000000) // Vectors positioned at start of RAM #endif diff --git a/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F031K6/device/cmsis_nvic.c b/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F031K6/device/cmsis_nvic.c deleted file mode 100644 index 2e9e8638bb9..00000000000 --- a/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F031K6/device/cmsis_nvic.c +++ /dev/null @@ -1,57 +0,0 @@ -/* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors - ******************************************************************************* - * Copyright (c) 2015, STMicroelectronics - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "cmsis_nvic.h" - -#define NVIC_RAM_VECTOR_ADDRESS (0x20000000) // Vectors positioned at start of RAM -#define NVIC_FLASH_VECTOR_ADDRESS (0x08000000) // Initial vector position in flash - - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { - int i; - - // Copy and switch to dynamic vectors if first time called - if ((SYSCFG->CFGR1 & SYSCFG_CFGR1_MEM_MODE) != SYSCFG_CFGR1_MEM_MODE) { - uint32_t *old_vectors = (uint32_t *)NVIC_FLASH_VECTOR_ADDRESS; - for (i = 0; i < NVIC_NUM_VECTORS; i++) { - *((uint32_t *)(NVIC_RAM_VECTOR_ADDRESS + (i*4))) = old_vectors[i]; - } - SYSCFG->CFGR1 |= SYSCFG_CFGR1_MEM_MODE; // Embedded SRAM mapped at 0x00000000 - } - - // Set the vector - *((uint32_t *)(NVIC_RAM_VECTOR_ADDRESS + (IRQn*4) + (NVIC_USER_IRQ_OFFSET*4))) = vector; -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) { - uint32_t *vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS; - // Return the vector - return vectors[IRQn + 16]; -} diff --git a/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F031K6/device/cmsis_nvic.h b/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F031K6/device/cmsis_nvic.h index 5f887e1eb6e..9a6d7d6115b 100644 --- a/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F031K6/device/cmsis_nvic.h +++ b/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F031K6/device/cmsis_nvic.h @@ -36,20 +36,7 @@ // CORE: 16 vectors = 64 bytes from 0x00 to 0x3F // MCU Peripherals: 28 vectors = 112 bytes from 0x40 to 0xAF // Total: 44 vectors = 176 bytes (0xB0) to be reserved in RAM -#define NVIC_NUM_VECTORS 44 -#define NVIC_USER_IRQ_OFFSET 16 - -#include "cmsis.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +#define NVIC_NUM_VECTORS 44 +#define NVIC_RAM_VECTOR_ADDRESS (0x20000000) // Vectors positioned at start of RAM #endif diff --git a/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F042K6/device/cmsis_nvic.c b/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F042K6/device/cmsis_nvic.c deleted file mode 100644 index 2e9e8638bb9..00000000000 --- a/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F042K6/device/cmsis_nvic.c +++ /dev/null @@ -1,57 +0,0 @@ -/* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors - ******************************************************************************* - * Copyright (c) 2015, STMicroelectronics - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "cmsis_nvic.h" - -#define NVIC_RAM_VECTOR_ADDRESS (0x20000000) // Vectors positioned at start of RAM -#define NVIC_FLASH_VECTOR_ADDRESS (0x08000000) // Initial vector position in flash - - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { - int i; - - // Copy and switch to dynamic vectors if first time called - if ((SYSCFG->CFGR1 & SYSCFG_CFGR1_MEM_MODE) != SYSCFG_CFGR1_MEM_MODE) { - uint32_t *old_vectors = (uint32_t *)NVIC_FLASH_VECTOR_ADDRESS; - for (i = 0; i < NVIC_NUM_VECTORS; i++) { - *((uint32_t *)(NVIC_RAM_VECTOR_ADDRESS + (i*4))) = old_vectors[i]; - } - SYSCFG->CFGR1 |= SYSCFG_CFGR1_MEM_MODE; // Embedded SRAM mapped at 0x00000000 - } - - // Set the vector - *((uint32_t *)(NVIC_RAM_VECTOR_ADDRESS + (IRQn*4) + (NVIC_USER_IRQ_OFFSET*4))) = vector; -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) { - uint32_t *vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS; - // Return the vector - return vectors[IRQn + 16]; -} diff --git a/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F042K6/device/cmsis_nvic.h b/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F042K6/device/cmsis_nvic.h index 75bb632dbac..b4e55a0f04b 100644 --- a/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F042K6/device/cmsis_nvic.h +++ b/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F042K6/device/cmsis_nvic.h @@ -36,20 +36,7 @@ // CORE: 16 vectors = 64 bytes from 0x00 to 0x3F // MCU Peripherals: 32 vectors = 128 bytes from 0x40 to 0xBF // Total: 48 vectors = 192 bytes (0xC0) to be reserved in RAM -#define NVIC_NUM_VECTORS 48 -#define NVIC_USER_IRQ_OFFSET 16 - -#include "cmsis.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +#define NVIC_NUM_VECTORS 48 +#define NVIC_RAM_VECTOR_ADDRESS (0x20000000) // Vectors positioned at start of RAM #endif diff --git a/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F070RB/device/cmsis_nvic.c b/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F070RB/device/cmsis_nvic.c deleted file mode 100644 index 2e9e8638bb9..00000000000 --- a/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F070RB/device/cmsis_nvic.c +++ /dev/null @@ -1,57 +0,0 @@ -/* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors - ******************************************************************************* - * Copyright (c) 2015, STMicroelectronics - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "cmsis_nvic.h" - -#define NVIC_RAM_VECTOR_ADDRESS (0x20000000) // Vectors positioned at start of RAM -#define NVIC_FLASH_VECTOR_ADDRESS (0x08000000) // Initial vector position in flash - - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { - int i; - - // Copy and switch to dynamic vectors if first time called - if ((SYSCFG->CFGR1 & SYSCFG_CFGR1_MEM_MODE) != SYSCFG_CFGR1_MEM_MODE) { - uint32_t *old_vectors = (uint32_t *)NVIC_FLASH_VECTOR_ADDRESS; - for (i = 0; i < NVIC_NUM_VECTORS; i++) { - *((uint32_t *)(NVIC_RAM_VECTOR_ADDRESS + (i*4))) = old_vectors[i]; - } - SYSCFG->CFGR1 |= SYSCFG_CFGR1_MEM_MODE; // Embedded SRAM mapped at 0x00000000 - } - - // Set the vector - *((uint32_t *)(NVIC_RAM_VECTOR_ADDRESS + (IRQn*4) + (NVIC_USER_IRQ_OFFSET*4))) = vector; -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) { - uint32_t *vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS; - // Return the vector - return vectors[IRQn + 16]; -} diff --git a/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F070RB/device/cmsis_nvic.h b/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F070RB/device/cmsis_nvic.h index 63246b8025d..b0bc28fc1fa 100644 --- a/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F070RB/device/cmsis_nvic.h +++ b/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F070RB/device/cmsis_nvic.h @@ -35,20 +35,7 @@ // CORE: 16 vectors = 64 bytes from 0x00 to 0x3F // MCU Peripherals: 32 vectors = 128 bytes from 0x40 to 0xBF // Total: 48 vectors = 192 bytes (0xC0) to be reserved in RAM -#define NVIC_NUM_VECTORS 48 -#define NVIC_USER_IRQ_OFFSET 16 - -#include "cmsis.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +#define NVIC_NUM_VECTORS 48 +#define NVIC_RAM_VECTOR_ADDRESS (0x20000000) // Vectors positioned at start of RAM #endif diff --git a/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F072RB/device/cmsis_nvic.c b/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F072RB/device/cmsis_nvic.c deleted file mode 100644 index 2e9e8638bb9..00000000000 --- a/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F072RB/device/cmsis_nvic.c +++ /dev/null @@ -1,57 +0,0 @@ -/* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors - ******************************************************************************* - * Copyright (c) 2015, STMicroelectronics - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "cmsis_nvic.h" - -#define NVIC_RAM_VECTOR_ADDRESS (0x20000000) // Vectors positioned at start of RAM -#define NVIC_FLASH_VECTOR_ADDRESS (0x08000000) // Initial vector position in flash - - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { - int i; - - // Copy and switch to dynamic vectors if first time called - if ((SYSCFG->CFGR1 & SYSCFG_CFGR1_MEM_MODE) != SYSCFG_CFGR1_MEM_MODE) { - uint32_t *old_vectors = (uint32_t *)NVIC_FLASH_VECTOR_ADDRESS; - for (i = 0; i < NVIC_NUM_VECTORS; i++) { - *((uint32_t *)(NVIC_RAM_VECTOR_ADDRESS + (i*4))) = old_vectors[i]; - } - SYSCFG->CFGR1 |= SYSCFG_CFGR1_MEM_MODE; // Embedded SRAM mapped at 0x00000000 - } - - // Set the vector - *((uint32_t *)(NVIC_RAM_VECTOR_ADDRESS + (IRQn*4) + (NVIC_USER_IRQ_OFFSET*4))) = vector; -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) { - uint32_t *vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS; - // Return the vector - return vectors[IRQn + 16]; -} diff --git a/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F072RB/device/cmsis_nvic.h b/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F072RB/device/cmsis_nvic.h index 5b41f231dd8..4292bcc34ce 100644 --- a/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F072RB/device/cmsis_nvic.h +++ b/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F072RB/device/cmsis_nvic.h @@ -36,20 +36,7 @@ // CORE: 16 vectors = 64 bytes from 0x00 to 0x3F // MCU Peripherals: 32 vectors = 128 bytes from 0x40 to 0xBF // Total: 48 vectors = 192 bytes (0xC0) to be reserved in RAM -#define NVIC_NUM_VECTORS 48 -#define NVIC_USER_IRQ_OFFSET 16 - -#include "cmsis.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +#define NVIC_NUM_VECTORS 48 +#define NVIC_RAM_VECTOR_ADDRESS (0x20000000) // Vectors positioned at start of RAM #endif diff --git a/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F091RC/device/cmsis_nvic.c b/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F091RC/device/cmsis_nvic.c deleted file mode 100644 index a5d638105a1..00000000000 --- a/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F091RC/device/cmsis_nvic.c +++ /dev/null @@ -1,56 +0,0 @@ -/* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors - ******************************************************************************* - * Copyright (c) 2015, STMicroelectronics - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "cmsis_nvic.h" - -#define NVIC_RAM_VECTOR_ADDRESS (0x20000000) // Vectors positioned at start of RAM -#define NVIC_FLASH_VECTOR_ADDRESS (0x08000000) // Initial vector position in flash - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { - int i; - - // Copy and switch to dynamic vectors if first time called - if ((SYSCFG->CFGR1 & SYSCFG_CFGR1_MEM_MODE) != SYSCFG_CFGR1_MEM_MODE) { - uint32_t *old_vectors = (uint32_t *)NVIC_FLASH_VECTOR_ADDRESS; - for (i = 0; i < NVIC_NUM_VECTORS; i++) { - *((uint32_t *)(NVIC_RAM_VECTOR_ADDRESS + (i*4))) = old_vectors[i]; - } - SYSCFG->CFGR1 |= SYSCFG_CFGR1_MEM_MODE; // Embedded SRAM mapped at 0x00000000 - } - - // Set the vector - *((uint32_t *)(NVIC_RAM_VECTOR_ADDRESS + (IRQn*4) + (NVIC_USER_IRQ_OFFSET*4))) = vector; -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) { - uint32_t *vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS; - // Return the vector - return vectors[IRQn + 16]; -} diff --git a/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F091RC/device/cmsis_nvic.h b/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F091RC/device/cmsis_nvic.h index 3b7329585d6..a50e0305c5a 100644 --- a/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F091RC/device/cmsis_nvic.h +++ b/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F091RC/device/cmsis_nvic.h @@ -36,20 +36,7 @@ // CORE: 16 vectors = 64 bytes from 0x00 to 0x3F // MCU Peripherals: 32 vectors = 128 bytes from 0x40 to 0xBF // Total: 48 vectors = 192 bytes (0xC0) to be reserved in RAM -#define NVIC_NUM_VECTORS 48 -#define NVIC_USER_IRQ_OFFSET 16 - -#include "cmsis.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +#define NVIC_NUM_VECTORS 48 +#define NVIC_RAM_VECTOR_ADDRESS (0x20000000) // Vectors positioned at start of RAM #endif diff --git a/targets/TARGET_STM/TARGET_STM32F1/TARGET_BLUEPILL_F103C8/device/cmsis_nvic.c b/targets/TARGET_STM/TARGET_STM32F1/TARGET_BLUEPILL_F103C8/device/cmsis_nvic.c deleted file mode 100644 index 70fe00f0f4e..00000000000 --- a/targets/TARGET_STM/TARGET_STM32F1/TARGET_BLUEPILL_F103C8/device/cmsis_nvic.c +++ /dev/null @@ -1,55 +0,0 @@ -/* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors - ******************************************************************************* - * Copyright (c) 2016, STMicroelectronics - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "cmsis_nvic.h" - -#define NVIC_RAM_VECTOR_ADDRESS (0x20000000) // Vectors positioned at start of RAM -#define NVIC_FLASH_VECTOR_ADDRESS (0x08000000) // Initial vector position in flash - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { - uint32_t *vectors = (uint32_t *)SCB->VTOR; - uint32_t i; - - // Copy and switch to dynamic vectors if the first time called - if (SCB->VTOR == NVIC_FLASH_VECTOR_ADDRESS) { - uint32_t *old_vectors = vectors; - vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS; - for (i=0; iVTOR = (uint32_t)NVIC_RAM_VECTOR_ADDRESS; - } - vectors[IRQn + NVIC_USER_IRQ_OFFSET] = vector; -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) { - uint32_t *vectors = (uint32_t*)SCB->VTOR; - return vectors[IRQn + NVIC_USER_IRQ_OFFSET]; -} diff --git a/targets/TARGET_STM/TARGET_STM32F1/TARGET_BLUEPILL_F103C8/device/cmsis_nvic.h b/targets/TARGET_STM/TARGET_STM32F1/TARGET_BLUEPILL_F103C8/device/cmsis_nvic.h index fc3356b5abc..f1334d99ecb 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/TARGET_BLUEPILL_F103C8/device/cmsis_nvic.h +++ b/targets/TARGET_STM/TARGET_STM32F1/TARGET_BLUEPILL_F103C8/device/cmsis_nvic.h @@ -1,5 +1,4 @@ /* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors ******************************************************************************* * Copyright (c) 2016, STMicroelectronics * All rights reserved. @@ -27,7 +26,7 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ******************************************************************************* - */ + */ #ifndef MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H @@ -35,20 +34,7 @@ // CORE: 16 vectors (= 64 bytes from 0x00 to 0x3F) // MCU Peripherals: 43 vectors (= 172 bytes from 0x40 to 0xEB) // Total: 236 bytes to be reserved in RAM (see scatter file) -#define NVIC_NUM_VECTORS (16 + 43) -#define NVIC_USER_IRQ_OFFSET 16 - -#include "cmsis.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +#define NVIC_NUM_VECTORS (16 + 43) +#define NVIC_RAM_VECTOR_ADDRESS 0x20000000 // Vectors positioned at start of RAM #endif diff --git a/targets/TARGET_STM/TARGET_STM32F1/TARGET_DISCO_F100RB/device/cmsis_nvic.c b/targets/TARGET_STM/TARGET_STM32F1/TARGET_DISCO_F100RB/device/cmsis_nvic.c deleted file mode 100644 index 70fe00f0f4e..00000000000 --- a/targets/TARGET_STM/TARGET_STM32F1/TARGET_DISCO_F100RB/device/cmsis_nvic.c +++ /dev/null @@ -1,55 +0,0 @@ -/* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors - ******************************************************************************* - * Copyright (c) 2016, STMicroelectronics - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "cmsis_nvic.h" - -#define NVIC_RAM_VECTOR_ADDRESS (0x20000000) // Vectors positioned at start of RAM -#define NVIC_FLASH_VECTOR_ADDRESS (0x08000000) // Initial vector position in flash - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { - uint32_t *vectors = (uint32_t *)SCB->VTOR; - uint32_t i; - - // Copy and switch to dynamic vectors if the first time called - if (SCB->VTOR == NVIC_FLASH_VECTOR_ADDRESS) { - uint32_t *old_vectors = vectors; - vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS; - for (i=0; iVTOR = (uint32_t)NVIC_RAM_VECTOR_ADDRESS; - } - vectors[IRQn + NVIC_USER_IRQ_OFFSET] = vector; -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) { - uint32_t *vectors = (uint32_t*)SCB->VTOR; - return vectors[IRQn + NVIC_USER_IRQ_OFFSET]; -} diff --git a/targets/TARGET_STM/TARGET_STM32F1/TARGET_DISCO_F100RB/device/cmsis_nvic.h b/targets/TARGET_STM/TARGET_STM32F1/TARGET_DISCO_F100RB/device/cmsis_nvic.h index b1ab96e94c4..df6ccc3907a 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/TARGET_DISCO_F100RB/device/cmsis_nvic.h +++ b/targets/TARGET_STM/TARGET_STM32F1/TARGET_DISCO_F100RB/device/cmsis_nvic.h @@ -1,5 +1,4 @@ /* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors ******************************************************************************* * Copyright (c) 2016, STMicroelectronics * All rights reserved. @@ -27,7 +26,7 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ******************************************************************************* - */ + */ #ifndef MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H @@ -35,20 +34,7 @@ // CORE: 16 vectors (= 64 bytes from 0x00 to 0x3F) // MCU Peripherals: 61 vectors (= 244 bytes from 0x40 to 0x134) // Total: 308 bytes to be reserved in RAM (see scatter file) -#define NVIC_NUM_VECTORS (16 + 61) -#define NVIC_USER_IRQ_OFFSET 16 - -#include "cmsis.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +#define NVIC_NUM_VECTORS (16 + 61) +#define NVIC_RAM_VECTOR_ADDRESS 0x20000000 // Vectors positioned at start of RAM #endif diff --git a/targets/TARGET_STM/TARGET_STM32F1/TARGET_NUCLEO_F103RB/device/cmsis_nvic.c b/targets/TARGET_STM/TARGET_STM32F1/TARGET_NUCLEO_F103RB/device/cmsis_nvic.c deleted file mode 100644 index 70fe00f0f4e..00000000000 --- a/targets/TARGET_STM/TARGET_STM32F1/TARGET_NUCLEO_F103RB/device/cmsis_nvic.c +++ /dev/null @@ -1,55 +0,0 @@ -/* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors - ******************************************************************************* - * Copyright (c) 2016, STMicroelectronics - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "cmsis_nvic.h" - -#define NVIC_RAM_VECTOR_ADDRESS (0x20000000) // Vectors positioned at start of RAM -#define NVIC_FLASH_VECTOR_ADDRESS (0x08000000) // Initial vector position in flash - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { - uint32_t *vectors = (uint32_t *)SCB->VTOR; - uint32_t i; - - // Copy and switch to dynamic vectors if the first time called - if (SCB->VTOR == NVIC_FLASH_VECTOR_ADDRESS) { - uint32_t *old_vectors = vectors; - vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS; - for (i=0; iVTOR = (uint32_t)NVIC_RAM_VECTOR_ADDRESS; - } - vectors[IRQn + NVIC_USER_IRQ_OFFSET] = vector; -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) { - uint32_t *vectors = (uint32_t*)SCB->VTOR; - return vectors[IRQn + NVIC_USER_IRQ_OFFSET]; -} diff --git a/targets/TARGET_STM/TARGET_STM32F1/TARGET_NUCLEO_F103RB/device/cmsis_nvic.h b/targets/TARGET_STM/TARGET_STM32F1/TARGET_NUCLEO_F103RB/device/cmsis_nvic.h index fc3356b5abc..f1334d99ecb 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/TARGET_NUCLEO_F103RB/device/cmsis_nvic.h +++ b/targets/TARGET_STM/TARGET_STM32F1/TARGET_NUCLEO_F103RB/device/cmsis_nvic.h @@ -1,5 +1,4 @@ /* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors ******************************************************************************* * Copyright (c) 2016, STMicroelectronics * All rights reserved. @@ -27,7 +26,7 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ******************************************************************************* - */ + */ #ifndef MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H @@ -35,20 +34,7 @@ // CORE: 16 vectors (= 64 bytes from 0x00 to 0x3F) // MCU Peripherals: 43 vectors (= 172 bytes from 0x40 to 0xEB) // Total: 236 bytes to be reserved in RAM (see scatter file) -#define NVIC_NUM_VECTORS (16 + 43) -#define NVIC_USER_IRQ_OFFSET 16 - -#include "cmsis.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +#define NVIC_NUM_VECTORS (16 + 43) +#define NVIC_RAM_VECTOR_ADDRESS 0x20000000 // Vectors positioned at start of RAM #endif diff --git a/targets/TARGET_STM/TARGET_STM32F2/TARGET_NUCLEO_F207ZG/device/cmsis_nvic.c b/targets/TARGET_STM/TARGET_STM32F2/TARGET_NUCLEO_F207ZG/device/cmsis_nvic.c deleted file mode 100644 index ef04f29944d..00000000000 --- a/targets/TARGET_STM/TARGET_STM32F2/TARGET_NUCLEO_F207ZG/device/cmsis_nvic.c +++ /dev/null @@ -1,57 +0,0 @@ -/* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors - ******************************************************************************* - * Copyright (c) 2016, STMicroelectronics - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "cmsis_nvic.h" - -#define NVIC_RAM_VECTOR_ADDRESS (0x20000000) // Vectors positioned at start of RAM -#define NVIC_FLASH_VECTOR_ADDRESS (0x08000000) // Initial vector position in flash - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) -{ - uint32_t *vectors = (uint32_t *)SCB->VTOR; - uint32_t i; - - // Copy and switch to dynamic vectors if the first time called - if (SCB->VTOR == NVIC_FLASH_VECTOR_ADDRESS) { - uint32_t *old_vectors = vectors; - vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS; - for (i = 0; i < NVIC_NUM_VECTORS; i++) { - vectors[i] = old_vectors[i]; - } - SCB->VTOR = (uint32_t)NVIC_RAM_VECTOR_ADDRESS; - } - vectors[IRQn + NVIC_USER_IRQ_OFFSET] = vector; -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) -{ - uint32_t *vectors = (uint32_t*)SCB->VTOR; - return vectors[IRQn + NVIC_USER_IRQ_OFFSET]; -} diff --git a/targets/TARGET_STM/TARGET_STM32F2/TARGET_NUCLEO_F207ZG/device/cmsis_nvic.h b/targets/TARGET_STM/TARGET_STM32F2/TARGET_NUCLEO_F207ZG/device/cmsis_nvic.h index f34526530c8..128c6edd44f 100644 --- a/targets/TARGET_STM/TARGET_STM32F2/TARGET_NUCLEO_F207ZG/device/cmsis_nvic.h +++ b/targets/TARGET_STM/TARGET_STM32F2/TARGET_NUCLEO_F207ZG/device/cmsis_nvic.h @@ -1,5 +1,4 @@ /* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors ******************************************************************************* * Copyright (c) 2016, STMicroelectronics * All rights reserved. @@ -35,20 +34,7 @@ // CORE: 16 vectors (= 64 bytes from 0x00 to 0x3F) // MCU Peripherals: 81 vectors // Total: 388 bytes to be reserved in RAM (see scatter file) -#define NVIC_NUM_VECTORS 97 -#define NVIC_USER_IRQ_OFFSET 16 - -#include "cmsis.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +#define NVIC_NUM_VECTORS 97 +#define NVIC_RAM_VECTOR_ADDRESS 0x20000000 // Vectors positioned at start of RAM #endif diff --git a/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F302x8/device/cmsis_nvic.c b/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F302x8/device/cmsis_nvic.c deleted file mode 100644 index e13696e415f..00000000000 --- a/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F302x8/device/cmsis_nvic.c +++ /dev/null @@ -1,54 +0,0 @@ -/* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors - ******************************************************************************* - * Copyright (c) 2014, STMicroelectronics - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "cmsis_nvic.h" - -#define NVIC_RAM_VECTOR_ADDRESS (0x20000000) // Vectors positioned at start of RAM - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { - uint32_t *vectors = (uint32_t *)SCB->VTOR; - uint32_t i; - - // Copy and switch to dynamic vectors if the first time called - if (SCB->VTOR != NVIC_RAM_VECTOR_ADDRESS) { - uint32_t *old_vectors = vectors; - vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS; - for (i=0; iVTOR = (uint32_t)NVIC_RAM_VECTOR_ADDRESS; - } - vectors[IRQn + NVIC_USER_IRQ_OFFSET] = vector; -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) { - uint32_t *vectors = (uint32_t*)SCB->VTOR; - return vectors[IRQn + NVIC_USER_IRQ_OFFSET]; -} diff --git a/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F302x8/device/cmsis_nvic.h b/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F302x8/device/cmsis_nvic.h index 43f761e5b7a..37e0080c836 100644 --- a/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F302x8/device/cmsis_nvic.h +++ b/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F302x8/device/cmsis_nvic.h @@ -1,5 +1,4 @@ /* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors ******************************************************************************* * Copyright (c) 2014, STMicroelectronics * All rights reserved. @@ -27,7 +26,7 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ******************************************************************************* - */ + */ #ifndef MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H @@ -36,20 +35,7 @@ // CORE: 16 vectors = 64 bytes from 0x00 to 0x3F // MCU Peripherals: 82 vectors = 328 bytes from 0x40 to 0x187 // Total: 98 vectors = 392 bytes (0x188) to be reserved in RAM -#define NVIC_NUM_VECTORS 98 -#define NVIC_USER_IRQ_OFFSET 16 - -#include "cmsis.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +#define NVIC_NUM_VECTORS 98 +#define NVIC_RAM_VECTOR_ADDRESS 0x20000000 // Vectors positioned at start of RAM #endif diff --git a/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F303x8/device/cmsis_nvic.c b/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F303x8/device/cmsis_nvic.c deleted file mode 100644 index e13696e415f..00000000000 --- a/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F303x8/device/cmsis_nvic.c +++ /dev/null @@ -1,54 +0,0 @@ -/* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors - ******************************************************************************* - * Copyright (c) 2014, STMicroelectronics - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "cmsis_nvic.h" - -#define NVIC_RAM_VECTOR_ADDRESS (0x20000000) // Vectors positioned at start of RAM - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { - uint32_t *vectors = (uint32_t *)SCB->VTOR; - uint32_t i; - - // Copy and switch to dynamic vectors if the first time called - if (SCB->VTOR != NVIC_RAM_VECTOR_ADDRESS) { - uint32_t *old_vectors = vectors; - vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS; - for (i=0; iVTOR = (uint32_t)NVIC_RAM_VECTOR_ADDRESS; - } - vectors[IRQn + NVIC_USER_IRQ_OFFSET] = vector; -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) { - uint32_t *vectors = (uint32_t*)SCB->VTOR; - return vectors[IRQn + NVIC_USER_IRQ_OFFSET]; -} diff --git a/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F303x8/device/cmsis_nvic.h b/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F303x8/device/cmsis_nvic.h index d4a4c2c0ed4..963dacf6f16 100644 --- a/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F303x8/device/cmsis_nvic.h +++ b/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F303x8/device/cmsis_nvic.h @@ -1,5 +1,4 @@ /* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors ******************************************************************************* * Copyright (c) 2014, STMicroelectronics * All rights reserved. @@ -27,25 +26,12 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ******************************************************************************* - */ + */ #ifndef MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H -#define NVIC_NUM_VECTORS 98 -#define NVIC_USER_IRQ_OFFSET 16 - -#include "cmsis.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +#define NVIC_NUM_VECTORS 98 +#define NVIC_RAM_VECTOR_ADDRESS 0x20000000 // Vectors positioned at start of RAM #endif diff --git a/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F303xC/device/cmsis_nvic.c b/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F303xC/device/cmsis_nvic.c deleted file mode 100644 index e13696e415f..00000000000 --- a/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F303xC/device/cmsis_nvic.c +++ /dev/null @@ -1,54 +0,0 @@ -/* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors - ******************************************************************************* - * Copyright (c) 2014, STMicroelectronics - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "cmsis_nvic.h" - -#define NVIC_RAM_VECTOR_ADDRESS (0x20000000) // Vectors positioned at start of RAM - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { - uint32_t *vectors = (uint32_t *)SCB->VTOR; - uint32_t i; - - // Copy and switch to dynamic vectors if the first time called - if (SCB->VTOR != NVIC_RAM_VECTOR_ADDRESS) { - uint32_t *old_vectors = vectors; - vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS; - for (i=0; iVTOR = (uint32_t)NVIC_RAM_VECTOR_ADDRESS; - } - vectors[IRQn + NVIC_USER_IRQ_OFFSET] = vector; -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) { - uint32_t *vectors = (uint32_t*)SCB->VTOR; - return vectors[IRQn + NVIC_USER_IRQ_OFFSET]; -} diff --git a/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F303xC/device/cmsis_nvic.h b/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F303xC/device/cmsis_nvic.h index 3a6218bd70a..44d9f4c566d 100644 --- a/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F303xC/device/cmsis_nvic.h +++ b/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F303xC/device/cmsis_nvic.h @@ -1,5 +1,4 @@ /* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors ******************************************************************************* * Copyright (c) 2014, STMicroelectronics * All rights reserved. @@ -27,7 +26,7 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ******************************************************************************* - */ + */ #ifndef MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H @@ -36,20 +35,7 @@ // CORE: 16 vectors (= 64 bytes from 0x00 to 0x3F) // MCU Peripherals: 82 vectors (= 328 bytes from 0x40 to ...) // Total: 392(0x188) bytes to be reserved in RAM (see scatter file) -#define NVIC_NUM_VECTORS (16 + 82) -#define NVIC_USER_IRQ_OFFSET 16 - -#include "cmsis.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +#define NVIC_NUM_VECTORS (16 + 82) +#define NVIC_RAM_VECTOR_ADDRESS 0x20000000 // Vectors positioned at start of RAM #endif diff --git a/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F303xE/device/cmsis_nvic.c b/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F303xE/device/cmsis_nvic.c deleted file mode 100644 index e13696e415f..00000000000 --- a/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F303xE/device/cmsis_nvic.c +++ /dev/null @@ -1,54 +0,0 @@ -/* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors - ******************************************************************************* - * Copyright (c) 2014, STMicroelectronics - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "cmsis_nvic.h" - -#define NVIC_RAM_VECTOR_ADDRESS (0x20000000) // Vectors positioned at start of RAM - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { - uint32_t *vectors = (uint32_t *)SCB->VTOR; - uint32_t i; - - // Copy and switch to dynamic vectors if the first time called - if (SCB->VTOR != NVIC_RAM_VECTOR_ADDRESS) { - uint32_t *old_vectors = vectors; - vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS; - for (i=0; iVTOR = (uint32_t)NVIC_RAM_VECTOR_ADDRESS; - } - vectors[IRQn + NVIC_USER_IRQ_OFFSET] = vector; -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) { - uint32_t *vectors = (uint32_t*)SCB->VTOR; - return vectors[IRQn + NVIC_USER_IRQ_OFFSET]; -} diff --git a/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F303xE/device/cmsis_nvic.h b/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F303xE/device/cmsis_nvic.h index eb09b74d89c..78a22d7cee1 100644 --- a/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F303xE/device/cmsis_nvic.h +++ b/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F303xE/device/cmsis_nvic.h @@ -1,5 +1,4 @@ /* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors ******************************************************************************* * Copyright (c) 2014, STMicroelectronics * All rights reserved. @@ -27,7 +26,7 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ******************************************************************************* - */ + */ #ifndef MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H @@ -36,20 +35,7 @@ // CORE: 16 vectors = 64 bytes from 0x00 to 0x3F // MCU Peripherals: 85 vectors = 340 bytes from 0x40 to 0x193 // Total: 101 vectors = 404 bytes (0x194) to be reserved in RAM -#define NVIC_NUM_VECTORS 101 -#define NVIC_USER_IRQ_OFFSET 16 - -#include "cmsis.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +#define NVIC_NUM_VECTORS 101 +#define NVIC_RAM_VECTOR_ADDRESS 0x20000000 // Vectors positioned at start of RAM #endif diff --git a/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F334x8/device/cmsis_nvic.c b/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F334x8/device/cmsis_nvic.c deleted file mode 100644 index e13696e415f..00000000000 --- a/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F334x8/device/cmsis_nvic.c +++ /dev/null @@ -1,54 +0,0 @@ -/* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors - ******************************************************************************* - * Copyright (c) 2014, STMicroelectronics - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "cmsis_nvic.h" - -#define NVIC_RAM_VECTOR_ADDRESS (0x20000000) // Vectors positioned at start of RAM - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { - uint32_t *vectors = (uint32_t *)SCB->VTOR; - uint32_t i; - - // Copy and switch to dynamic vectors if the first time called - if (SCB->VTOR != NVIC_RAM_VECTOR_ADDRESS) { - uint32_t *old_vectors = vectors; - vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS; - for (i=0; iVTOR = (uint32_t)NVIC_RAM_VECTOR_ADDRESS; - } - vectors[IRQn + NVIC_USER_IRQ_OFFSET] = vector; -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) { - uint32_t *vectors = (uint32_t*)SCB->VTOR; - return vectors[IRQn + NVIC_USER_IRQ_OFFSET]; -} diff --git a/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F334x8/device/cmsis_nvic.h b/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F334x8/device/cmsis_nvic.h index 2f89fe76aa0..796f87c3fd6 100644 --- a/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F334x8/device/cmsis_nvic.h +++ b/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F334x8/device/cmsis_nvic.h @@ -1,5 +1,4 @@ /* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors ******************************************************************************* * Copyright (c) 2014, STMicroelectronics * All rights reserved. @@ -27,7 +26,7 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ******************************************************************************* - */ + */ #ifndef MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H @@ -36,20 +35,7 @@ // CORE: 16 vectors = 64 bytes from 0x00 to 0x3F // MCU Peripherals: 82 vectors = 328 bytes from 0x40 to 0x187 // Total: 98 vectors = 392 bytes (0x188) to be reserved in RAM -#define NVIC_NUM_VECTORS 98 -#define NVIC_USER_IRQ_OFFSET 16 - -#include "cmsis.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +#define NVIC_NUM_VECTORS 98 +#define NVIC_RAM_VECTOR_ADDRESS 0x20000000 // Vectors positioned at start of RAM #endif diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_MTS_DRAGONFLY_F411RE/device/cmsis_nvic.c b/targets/TARGET_STM/TARGET_STM32F4/TARGET_MTS_DRAGONFLY_F411RE/device/cmsis_nvic.c deleted file mode 100644 index 9fb76a72a5a..00000000000 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_MTS_DRAGONFLY_F411RE/device/cmsis_nvic.c +++ /dev/null @@ -1,55 +0,0 @@ -/* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors - ******************************************************************************* - * Copyright (c) 2014, STMicroelectronics - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "cmsis_nvic.h" - -#define NVIC_RAM_VECTOR_ADDRESS (0x20000000) // Vectors positioned at start of RAM -#define NVIC_FLASH_VECTOR_ADDRESS (FLASH_BASE | VECT_TAB_OFFSET) // Initial vector position in flash - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { - uint32_t *vectors = (uint32_t *)SCB->VTOR; - uint32_t i; - - // Copy and switch to dynamic vectors if the first time called - if (SCB->VTOR == NVIC_FLASH_VECTOR_ADDRESS) { - uint32_t *old_vectors = vectors; - vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS; - for (i=0; iVTOR = (uint32_t)NVIC_RAM_VECTOR_ADDRESS; - } - vectors[IRQn + NVIC_USER_IRQ_OFFSET] = vector; -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) { - uint32_t *vectors = (uint32_t*)SCB->VTOR; - return vectors[IRQn + NVIC_USER_IRQ_OFFSET]; -} diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_MTS_DRAGONFLY_F411RE/device/cmsis_nvic.h b/targets/TARGET_STM/TARGET_STM32F4/TARGET_MTS_DRAGONFLY_F411RE/device/cmsis_nvic.h index a98d56f154a..e44a1ce9f61 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_MTS_DRAGONFLY_F411RE/device/cmsis_nvic.h +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_MTS_DRAGONFLY_F411RE/device/cmsis_nvic.h @@ -1,5 +1,4 @@ /* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors ******************************************************************************* * Copyright (c) 2014, STMicroelectronics * All rights reserved. @@ -27,7 +26,7 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ******************************************************************************* - */ + */ #ifndef MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H @@ -36,20 +35,7 @@ // CORE: 16 vectors = 64 bytes from 0x00 to 0x3F // MCU Peripherals: 86 vectors = 344 bytes from 0x40 to 0x197 // Total: 102 vectors = 408 bytes (0x198) to be reserved in RAM -#define NVIC_NUM_VECTORS 102 -#define NVIC_USER_IRQ_OFFSET 16 - -#include "cmsis.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +#define NVIC_NUM_VECTORS 102 +#define NVIC_RAM_VECTOR_ADDRESS 0x20000000 // Vectors positioned at start of RAM #endif diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_MTS_MDOT_F405RG/device/cmsis_nvic.c b/targets/TARGET_STM/TARGET_STM32F4/TARGET_MTS_MDOT_F405RG/device/cmsis_nvic.c deleted file mode 100644 index 2da63fc9af8..00000000000 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_MTS_MDOT_F405RG/device/cmsis_nvic.c +++ /dev/null @@ -1,55 +0,0 @@ -/* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors - ******************************************************************************* - * Copyright (c) 2014, STMicroelectronics - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "cmsis_nvic.h" - -#define NVIC_RAM_VECTOR_ADDRESS (0x20000000) // Vectors positioned at start of RAM -#define NVIC_FLASH_VECTOR_ADDRESS (0x08000000) // Initial vector position in flash - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { - uint32_t *vectors = (uint32_t *)SCB->VTOR; - uint32_t i; - - // Copy and switch to dynamic vectors if the first time called - if (SCB->VTOR == NVIC_FLASH_VECTOR_ADDRESS) { - uint32_t *old_vectors = vectors; - vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS; - for (i=0; iVTOR = (uint32_t)NVIC_RAM_VECTOR_ADDRESS; - } - vectors[IRQn + NVIC_USER_IRQ_OFFSET] = vector; -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) { - uint32_t *vectors = (uint32_t*)SCB->VTOR; - return vectors[IRQn + NVIC_USER_IRQ_OFFSET]; -} diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_MTS_MDOT_F405RG/device/cmsis_nvic.h b/targets/TARGET_STM/TARGET_STM32F4/TARGET_MTS_MDOT_F405RG/device/cmsis_nvic.h index 6e6c1b57b87..993af5cf124 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_MTS_MDOT_F405RG/device/cmsis_nvic.h +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_MTS_MDOT_F405RG/device/cmsis_nvic.h @@ -1,5 +1,4 @@ /* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors ******************************************************************************* * Copyright (c) 2014, STMicroelectronics * All rights reserved. @@ -27,7 +26,7 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ******************************************************************************* - */ + */ #ifndef MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H @@ -36,20 +35,7 @@ // CORE: 16 vectors = 64 bytes from 0x00 to 0x3F // MCU Peripherals: 82 vectors = 328 bytes from 0x40 to ... // Total: 98 vectors = 392 bytes (0x188) to be reserved in RAM -#define NVIC_NUM_VECTORS 98 -#define NVIC_USER_IRQ_OFFSET 16 - -#include "cmsis.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +#define NVIC_NUM_VECTORS 98 +#define NVIC_RAM_VECTOR_ADDRESS 0x20000000 // Vectors positioned at start of RAM #endif diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_MTS_MDOT_F411RE/device/cmsis_nvic.c b/targets/TARGET_STM/TARGET_STM32F4/TARGET_MTS_MDOT_F411RE/device/cmsis_nvic.c deleted file mode 100644 index 9fb76a72a5a..00000000000 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_MTS_MDOT_F411RE/device/cmsis_nvic.c +++ /dev/null @@ -1,55 +0,0 @@ -/* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors - ******************************************************************************* - * Copyright (c) 2014, STMicroelectronics - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "cmsis_nvic.h" - -#define NVIC_RAM_VECTOR_ADDRESS (0x20000000) // Vectors positioned at start of RAM -#define NVIC_FLASH_VECTOR_ADDRESS (FLASH_BASE | VECT_TAB_OFFSET) // Initial vector position in flash - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { - uint32_t *vectors = (uint32_t *)SCB->VTOR; - uint32_t i; - - // Copy and switch to dynamic vectors if the first time called - if (SCB->VTOR == NVIC_FLASH_VECTOR_ADDRESS) { - uint32_t *old_vectors = vectors; - vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS; - for (i=0; iVTOR = (uint32_t)NVIC_RAM_VECTOR_ADDRESS; - } - vectors[IRQn + NVIC_USER_IRQ_OFFSET] = vector; -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) { - uint32_t *vectors = (uint32_t*)SCB->VTOR; - return vectors[IRQn + NVIC_USER_IRQ_OFFSET]; -} diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_MTS_MDOT_F411RE/device/cmsis_nvic.h b/targets/TARGET_STM/TARGET_STM32F4/TARGET_MTS_MDOT_F411RE/device/cmsis_nvic.h index a98d56f154a..e44a1ce9f61 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_MTS_MDOT_F411RE/device/cmsis_nvic.h +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_MTS_MDOT_F411RE/device/cmsis_nvic.h @@ -1,5 +1,4 @@ /* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors ******************************************************************************* * Copyright (c) 2014, STMicroelectronics * All rights reserved. @@ -27,7 +26,7 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ******************************************************************************* - */ + */ #ifndef MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H @@ -36,20 +35,7 @@ // CORE: 16 vectors = 64 bytes from 0x00 to 0x3F // MCU Peripherals: 86 vectors = 344 bytes from 0x40 to 0x197 // Total: 102 vectors = 408 bytes (0x198) to be reserved in RAM -#define NVIC_NUM_VECTORS 102 -#define NVIC_USER_IRQ_OFFSET 16 - -#include "cmsis.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +#define NVIC_NUM_VECTORS 102 +#define NVIC_RAM_VECTOR_ADDRESS 0x20000000 // Vectors positioned at start of RAM #endif diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F401xC/device/cmsis_nvic.c b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F401xC/device/cmsis_nvic.c deleted file mode 100644 index 2da63fc9af8..00000000000 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F401xC/device/cmsis_nvic.c +++ /dev/null @@ -1,55 +0,0 @@ -/* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors - ******************************************************************************* - * Copyright (c) 2014, STMicroelectronics - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "cmsis_nvic.h" - -#define NVIC_RAM_VECTOR_ADDRESS (0x20000000) // Vectors positioned at start of RAM -#define NVIC_FLASH_VECTOR_ADDRESS (0x08000000) // Initial vector position in flash - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { - uint32_t *vectors = (uint32_t *)SCB->VTOR; - uint32_t i; - - // Copy and switch to dynamic vectors if the first time called - if (SCB->VTOR == NVIC_FLASH_VECTOR_ADDRESS) { - uint32_t *old_vectors = vectors; - vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS; - for (i=0; iVTOR = (uint32_t)NVIC_RAM_VECTOR_ADDRESS; - } - vectors[IRQn + NVIC_USER_IRQ_OFFSET] = vector; -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) { - uint32_t *vectors = (uint32_t*)SCB->VTOR; - return vectors[IRQn + NVIC_USER_IRQ_OFFSET]; -} diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F401xC/device/cmsis_nvic.h b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F401xC/device/cmsis_nvic.h index 4f3819fdeb8..97b89d65702 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F401xC/device/cmsis_nvic.h +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F401xC/device/cmsis_nvic.h @@ -1,5 +1,4 @@ /* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors ******************************************************************************* * Copyright (c) 2014, STMicroelectronics * All rights reserved. @@ -27,7 +26,7 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ******************************************************************************* - */ + */ #ifndef MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H @@ -36,20 +35,7 @@ // CORE: 16 vectors = 64 bytes from 0x00 to 0x3F // MCU Peripherals: 85 vectors = 340 bytes from 0x40 to ... // Total: 101 vectors = 404 bytes (0x194) to be reserved in RAM -#define NVIC_NUM_VECTORS 101 -#define NVIC_USER_IRQ_OFFSET 16 - -#include "cmsis.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +#define NVIC_NUM_VECTORS 101 +#define NVIC_RAM_VECTOR_ADDRESS 0x20000000 // Vectors positioned at start of RAM #endif diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F401xE/device/cmsis_nvic.c b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F401xE/device/cmsis_nvic.c deleted file mode 100644 index 2da63fc9af8..00000000000 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F401xE/device/cmsis_nvic.c +++ /dev/null @@ -1,55 +0,0 @@ -/* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors - ******************************************************************************* - * Copyright (c) 2014, STMicroelectronics - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "cmsis_nvic.h" - -#define NVIC_RAM_VECTOR_ADDRESS (0x20000000) // Vectors positioned at start of RAM -#define NVIC_FLASH_VECTOR_ADDRESS (0x08000000) // Initial vector position in flash - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { - uint32_t *vectors = (uint32_t *)SCB->VTOR; - uint32_t i; - - // Copy and switch to dynamic vectors if the first time called - if (SCB->VTOR == NVIC_FLASH_VECTOR_ADDRESS) { - uint32_t *old_vectors = vectors; - vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS; - for (i=0; iVTOR = (uint32_t)NVIC_RAM_VECTOR_ADDRESS; - } - vectors[IRQn + NVIC_USER_IRQ_OFFSET] = vector; -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) { - uint32_t *vectors = (uint32_t*)SCB->VTOR; - return vectors[IRQn + NVIC_USER_IRQ_OFFSET]; -} diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F401xE/device/cmsis_nvic.h b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F401xE/device/cmsis_nvic.h index 4f3819fdeb8..97b89d65702 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F401xE/device/cmsis_nvic.h +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F401xE/device/cmsis_nvic.h @@ -1,5 +1,4 @@ /* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors ******************************************************************************* * Copyright (c) 2014, STMicroelectronics * All rights reserved. @@ -27,7 +26,7 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ******************************************************************************* - */ + */ #ifndef MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H @@ -36,20 +35,7 @@ // CORE: 16 vectors = 64 bytes from 0x00 to 0x3F // MCU Peripherals: 85 vectors = 340 bytes from 0x40 to ... // Total: 101 vectors = 404 bytes (0x194) to be reserved in RAM -#define NVIC_NUM_VECTORS 101 -#define NVIC_USER_IRQ_OFFSET 16 - -#include "cmsis.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +#define NVIC_NUM_VECTORS 101 +#define NVIC_RAM_VECTOR_ADDRESS 0x20000000 // Vectors positioned at start of RAM #endif diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F407xG/device/cmsis_nvic.c b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F407xG/device/cmsis_nvic.c deleted file mode 100644 index 2da63fc9af8..00000000000 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F407xG/device/cmsis_nvic.c +++ /dev/null @@ -1,55 +0,0 @@ -/* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors - ******************************************************************************* - * Copyright (c) 2014, STMicroelectronics - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "cmsis_nvic.h" - -#define NVIC_RAM_VECTOR_ADDRESS (0x20000000) // Vectors positioned at start of RAM -#define NVIC_FLASH_VECTOR_ADDRESS (0x08000000) // Initial vector position in flash - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { - uint32_t *vectors = (uint32_t *)SCB->VTOR; - uint32_t i; - - // Copy and switch to dynamic vectors if the first time called - if (SCB->VTOR == NVIC_FLASH_VECTOR_ADDRESS) { - uint32_t *old_vectors = vectors; - vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS; - for (i=0; iVTOR = (uint32_t)NVIC_RAM_VECTOR_ADDRESS; - } - vectors[IRQn + NVIC_USER_IRQ_OFFSET] = vector; -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) { - uint32_t *vectors = (uint32_t*)SCB->VTOR; - return vectors[IRQn + NVIC_USER_IRQ_OFFSET]; -} diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F407xG/device/cmsis_nvic.h b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F407xG/device/cmsis_nvic.h index 013c08f29d0..5a1a746c46e 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F407xG/device/cmsis_nvic.h +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F407xG/device/cmsis_nvic.h @@ -1,5 +1,4 @@ /* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors ******************************************************************************* * Copyright (c) 2014, STMicroelectronics * All rights reserved. @@ -27,7 +26,7 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ******************************************************************************* - */ + */ #ifndef MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H @@ -37,20 +36,7 @@ // MCU Peripherals: 82 vectors = 328 bytes from 0x40 to ... // Total: 98 vectors = 392 bytes (0x188) to be reserved in RAM -#define NVIC_NUM_VECTORS 98 -#define NVIC_USER_IRQ_OFFSET 16 - -#include "cmsis.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +#define NVIC_NUM_VECTORS 98 +#define NVIC_RAM_VECTOR_ADDRESS 0x20000000 // Vectors positioned at start of RAM #endif diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F410xB/device/cmsis_nvic.c b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F410xB/device/cmsis_nvic.c deleted file mode 100644 index 2da63fc9af8..00000000000 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F410xB/device/cmsis_nvic.c +++ /dev/null @@ -1,55 +0,0 @@ -/* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors - ******************************************************************************* - * Copyright (c) 2014, STMicroelectronics - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "cmsis_nvic.h" - -#define NVIC_RAM_VECTOR_ADDRESS (0x20000000) // Vectors positioned at start of RAM -#define NVIC_FLASH_VECTOR_ADDRESS (0x08000000) // Initial vector position in flash - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { - uint32_t *vectors = (uint32_t *)SCB->VTOR; - uint32_t i; - - // Copy and switch to dynamic vectors if the first time called - if (SCB->VTOR == NVIC_FLASH_VECTOR_ADDRESS) { - uint32_t *old_vectors = vectors; - vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS; - for (i=0; iVTOR = (uint32_t)NVIC_RAM_VECTOR_ADDRESS; - } - vectors[IRQn + NVIC_USER_IRQ_OFFSET] = vector; -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) { - uint32_t *vectors = (uint32_t*)SCB->VTOR; - return vectors[IRQn + NVIC_USER_IRQ_OFFSET]; -} diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F410xB/device/cmsis_nvic.h b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F410xB/device/cmsis_nvic.h index 513dbf6795e..c39900fb9b0 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F410xB/device/cmsis_nvic.h +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F410xB/device/cmsis_nvic.h @@ -1,5 +1,4 @@ /* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors ******************************************************************************* * Copyright (c) 2014, STMicroelectronics * All rights reserved. @@ -27,7 +26,7 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ******************************************************************************* - */ + */ #ifndef MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H @@ -36,20 +35,7 @@ // CORE: 16 vectors = 64 bytes from 0x00 to 0x3F // MCU Peripherals: 98 vectors = 392 bytes from 0x40 to 0x1C8 // Total: 114 vectors = 456 bytes (0x1C8) to be reserved in RAM -#define NVIC_NUM_VECTORS 114 -#define NVIC_USER_IRQ_OFFSET 16 - -#include "cmsis.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +#define NVIC_NUM_VECTORS 114 +#define NVIC_RAM_VECTOR_ADDRESS 0x20000000 // Vectors positioned at start of RAM #endif diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F411xE/device/cmsis_nvic.c b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F411xE/device/cmsis_nvic.c deleted file mode 100644 index 2da63fc9af8..00000000000 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F411xE/device/cmsis_nvic.c +++ /dev/null @@ -1,55 +0,0 @@ -/* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors - ******************************************************************************* - * Copyright (c) 2014, STMicroelectronics - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "cmsis_nvic.h" - -#define NVIC_RAM_VECTOR_ADDRESS (0x20000000) // Vectors positioned at start of RAM -#define NVIC_FLASH_VECTOR_ADDRESS (0x08000000) // Initial vector position in flash - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { - uint32_t *vectors = (uint32_t *)SCB->VTOR; - uint32_t i; - - // Copy and switch to dynamic vectors if the first time called - if (SCB->VTOR == NVIC_FLASH_VECTOR_ADDRESS) { - uint32_t *old_vectors = vectors; - vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS; - for (i=0; iVTOR = (uint32_t)NVIC_RAM_VECTOR_ADDRESS; - } - vectors[IRQn + NVIC_USER_IRQ_OFFSET] = vector; -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) { - uint32_t *vectors = (uint32_t*)SCB->VTOR; - return vectors[IRQn + NVIC_USER_IRQ_OFFSET]; -} diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F411xE/device/cmsis_nvic.h b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F411xE/device/cmsis_nvic.h index a98d56f154a..e44a1ce9f61 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F411xE/device/cmsis_nvic.h +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F411xE/device/cmsis_nvic.h @@ -1,5 +1,4 @@ /* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors ******************************************************************************* * Copyright (c) 2014, STMicroelectronics * All rights reserved. @@ -27,7 +26,7 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ******************************************************************************* - */ + */ #ifndef MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H @@ -36,20 +35,7 @@ // CORE: 16 vectors = 64 bytes from 0x00 to 0x3F // MCU Peripherals: 86 vectors = 344 bytes from 0x40 to 0x197 // Total: 102 vectors = 408 bytes (0x198) to be reserved in RAM -#define NVIC_NUM_VECTORS 102 -#define NVIC_USER_IRQ_OFFSET 16 - -#include "cmsis.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +#define NVIC_NUM_VECTORS 102 +#define NVIC_RAM_VECTOR_ADDRESS 0x20000000 // Vectors positioned at start of RAM #endif diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F412xG/device/cmsis_nvic.c b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F412xG/device/cmsis_nvic.c deleted file mode 100644 index 2da63fc9af8..00000000000 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F412xG/device/cmsis_nvic.c +++ /dev/null @@ -1,55 +0,0 @@ -/* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors - ******************************************************************************* - * Copyright (c) 2014, STMicroelectronics - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "cmsis_nvic.h" - -#define NVIC_RAM_VECTOR_ADDRESS (0x20000000) // Vectors positioned at start of RAM -#define NVIC_FLASH_VECTOR_ADDRESS (0x08000000) // Initial vector position in flash - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { - uint32_t *vectors = (uint32_t *)SCB->VTOR; - uint32_t i; - - // Copy and switch to dynamic vectors if the first time called - if (SCB->VTOR == NVIC_FLASH_VECTOR_ADDRESS) { - uint32_t *old_vectors = vectors; - vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS; - for (i=0; iVTOR = (uint32_t)NVIC_RAM_VECTOR_ADDRESS; - } - vectors[IRQn + NVIC_USER_IRQ_OFFSET] = vector; -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) { - uint32_t *vectors = (uint32_t*)SCB->VTOR; - return vectors[IRQn + NVIC_USER_IRQ_OFFSET]; -} diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F412xG/device/cmsis_nvic.h b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F412xG/device/cmsis_nvic.h index 0c7ed202f34..900f42a5168 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F412xG/device/cmsis_nvic.h +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F412xG/device/cmsis_nvic.h @@ -36,20 +36,8 @@ // CORE: 16 vectors = 64 bytes from 0x00 to 0x3F // MCU Peripherals: 97 vectors = 388 bytes from 0x40 to 0x1C3 // Total: 113 vectors = 452 bytes (0x1C4) to be reserved in RAM -#define NVIC_NUM_VECTORS 113 -#define NVIC_USER_IRQ_OFFSET 16 +#define NVIC_NUM_VECTORS 113 +#define NVIC_RAM_VECTOR_ADDRESS (0x20000000) // Vectors positioned at start of RAM -#include "cmsis.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif #endif diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F429xI/device/cmsis_nvic.c b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F429xI/device/cmsis_nvic.c deleted file mode 100644 index 64aa174e4d5..00000000000 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F429xI/device/cmsis_nvic.c +++ /dev/null @@ -1,55 +0,0 @@ -/* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors - ******************************************************************************* - * Copyright (c) 2014, STMicroelectronics - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "cmsis_nvic.h" -#include "nvic_addr.h" - -#define NVIC_RAM_VECTOR_ADDRESS (0x20000000) // Vectors positioned at start of RAM - -void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { - uint32_t *vectors = (uint32_t *)SCB->VTOR; - uint32_t i; - - // Copy and switch to dynamic vectors if the first time called - if (SCB->VTOR == NVIC_FLASH_VECTOR_ADDRESS) { - uint32_t *old_vectors = vectors; - vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS; - for (i=0; iVTOR = (uint32_t)NVIC_RAM_VECTOR_ADDRESS; - } - vectors[IRQn + NVIC_USER_IRQ_OFFSET] = vector; -} - -uint32_t __NVIC_GetVector(IRQn_Type IRQn) { - uint32_t *vectors = (uint32_t*)SCB->VTOR; - return vectors[IRQn + NVIC_USER_IRQ_OFFSET]; -} diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F429xI/device/cmsis_nvic.h b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F429xI/device/cmsis_nvic.h index 7b9f0dd9162..3087fbdee75 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F429xI/device/cmsis_nvic.h +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F429xI/device/cmsis_nvic.h @@ -1,5 +1,4 @@ /* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors ******************************************************************************* * Copyright (c) 2015, STMicroelectronics * All rights reserved. @@ -27,7 +26,7 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ******************************************************************************* - */ + */ #ifndef MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H @@ -36,20 +35,7 @@ // CORE: 16 vectors = 64 bytes from 0x00 to 0x3F // MCU Peripherals: 91 vectors = 364 bytes from 0x40 to 0x1AB // Total: 107 vectors = 428 bytes (0x1AC) to be reserved in RAM -#define NVIC_NUM_VECTORS 107 -#define NVIC_USER_IRQ_OFFSET 16 - -#include "cmsis.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t __NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +#define NVIC_NUM_VECTORS 107 +#define NVIC_RAM_VECTOR_ADDRESS 0x20000000 // Vectors positioned at start of RAM #endif diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F437xG/device/cmsis_nvic.c b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F437xG/device/cmsis_nvic.c deleted file mode 100644 index 2da63fc9af8..00000000000 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F437xG/device/cmsis_nvic.c +++ /dev/null @@ -1,55 +0,0 @@ -/* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors - ******************************************************************************* - * Copyright (c) 2014, STMicroelectronics - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "cmsis_nvic.h" - -#define NVIC_RAM_VECTOR_ADDRESS (0x20000000) // Vectors positioned at start of RAM -#define NVIC_FLASH_VECTOR_ADDRESS (0x08000000) // Initial vector position in flash - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { - uint32_t *vectors = (uint32_t *)SCB->VTOR; - uint32_t i; - - // Copy and switch to dynamic vectors if the first time called - if (SCB->VTOR == NVIC_FLASH_VECTOR_ADDRESS) { - uint32_t *old_vectors = vectors; - vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS; - for (i=0; iVTOR = (uint32_t)NVIC_RAM_VECTOR_ADDRESS; - } - vectors[IRQn + NVIC_USER_IRQ_OFFSET] = vector; -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) { - uint32_t *vectors = (uint32_t*)SCB->VTOR; - return vectors[IRQn + NVIC_USER_IRQ_OFFSET]; -} diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F437xG/device/cmsis_nvic.h b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F437xG/device/cmsis_nvic.h index f924f58fe74..8cbf47ad849 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F437xG/device/cmsis_nvic.h +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F437xG/device/cmsis_nvic.h @@ -36,20 +36,7 @@ // CORE: 16 vectors = 64 bytes from 0x00 to 0x3F // MCU Peripherals: 91 vectors = 364 bytes from 0x40 to 0x1AB // Total: 107 vectors = 428 bytes (0x1AC) to be reserved in RAM -#define NVIC_NUM_VECTORS 107 -#define NVIC_USER_IRQ_OFFSET 16 - -#include "cmsis.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +#define NVIC_NUM_VECTORS 107 +#define NVIC_RAM_VECTOR_ADDRESS 0x20000000 // Vectors positioned at start of RAM #endif diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F439xI/device/cmsis_nvic.c b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F439xI/device/cmsis_nvic.c deleted file mode 100644 index a1e0351aa1a..00000000000 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F439xI/device/cmsis_nvic.c +++ /dev/null @@ -1,55 +0,0 @@ -/* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors - ******************************************************************************* - * Copyright (c) 2014, STMicroelectronics - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "cmsis_nvic.h" -#include "nvic_addr.h" - -#define NVIC_RAM_VECTOR_ADDRESS (0x20000000) // Vectors positioned at start of RAM - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { - uint32_t *vectors = (uint32_t *)SCB->VTOR; - uint32_t i; - - // Copy and switch to dynamic vectors if the first time called - if (SCB->VTOR == NVIC_FLASH_VECTOR_ADDRESS) { - uint32_t *old_vectors = vectors; - vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS; - for (i=0; iVTOR = (uint32_t)NVIC_RAM_VECTOR_ADDRESS; - } - vectors[IRQn + NVIC_USER_IRQ_OFFSET] = vector; -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) { - uint32_t *vectors = (uint32_t*)SCB->VTOR; - return vectors[IRQn + NVIC_USER_IRQ_OFFSET]; -} diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F439xI/device/cmsis_nvic.h b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F439xI/device/cmsis_nvic.h index f8403dae25d..3087fbdee75 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F439xI/device/cmsis_nvic.h +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F439xI/device/cmsis_nvic.h @@ -1,5 +1,4 @@ /* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors ******************************************************************************* * Copyright (c) 2015, STMicroelectronics * All rights reserved. @@ -27,7 +26,7 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ******************************************************************************* - */ + */ #ifndef MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H @@ -36,20 +35,7 @@ // CORE: 16 vectors = 64 bytes from 0x00 to 0x3F // MCU Peripherals: 91 vectors = 364 bytes from 0x40 to 0x1AB // Total: 107 vectors = 428 bytes (0x1AC) to be reserved in RAM -#define NVIC_NUM_VECTORS 107 -#define NVIC_USER_IRQ_OFFSET 16 - -#include "cmsis.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +#define NVIC_NUM_VECTORS 107 +#define NVIC_RAM_VECTOR_ADDRESS 0x20000000 // Vectors positioned at start of RAM #endif diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F446xE/device/cmsis_nvic.c b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F446xE/device/cmsis_nvic.c deleted file mode 100644 index 9263c748e78..00000000000 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F446xE/device/cmsis_nvic.c +++ /dev/null @@ -1,55 +0,0 @@ -/* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors - ******************************************************************************* - * Copyright (c) 2015, STMicroelectronics - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "cmsis_nvic.h" - -#define NVIC_RAM_VECTOR_ADDRESS (0x20000000) // Vectors positioned at start of RAM -#define NVIC_FLASH_VECTOR_ADDRESS (0x08000000) // Initial vector position in flash - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { - uint32_t *vectors = (uint32_t *)SCB->VTOR; - uint32_t i; - - // Copy and switch to dynamic vectors if the first time called - if (SCB->VTOR == NVIC_FLASH_VECTOR_ADDRESS) { - uint32_t *old_vectors = vectors; - vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS; - for (i=0; iVTOR = (uint32_t)NVIC_RAM_VECTOR_ADDRESS; - } - vectors[IRQn + NVIC_USER_IRQ_OFFSET] = vector; -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) { - uint32_t *vectors = (uint32_t*)SCB->VTOR; - return vectors[IRQn + NVIC_USER_IRQ_OFFSET]; -} diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F446xE/device/cmsis_nvic.h b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F446xE/device/cmsis_nvic.h index 67f05a519f9..eb90e367e88 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F446xE/device/cmsis_nvic.h +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F446xE/device/cmsis_nvic.h @@ -1,5 +1,4 @@ /* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors ******************************************************************************* * Copyright (c) 2015, STMicroelectronics * All rights reserved. @@ -27,7 +26,7 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ******************************************************************************* - */ + */ #ifndef MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H @@ -35,20 +34,7 @@ // CORE: 16 vectors = 64 bytes from 0x00 to 0x3F // MCU Peripherals: 97 vectors = 388 bytes from 0x40 to 0x1C3 // Total: 113 vectors = 452 bytes (0x1C4) to be reserved in RAM -#define NVIC_NUM_VECTORS 113 -#define NVIC_USER_IRQ_OFFSET 16 - -#include "cmsis.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +#define NVIC_NUM_VECTORS 113 +#define NVIC_RAM_VECTOR_ADDRESS 0x20000000 // Vectors positioned at start of RAM #endif diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F469xI/device/cmsis_nvic.c b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F469xI/device/cmsis_nvic.c deleted file mode 100644 index 2da63fc9af8..00000000000 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F469xI/device/cmsis_nvic.c +++ /dev/null @@ -1,55 +0,0 @@ -/* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors - ******************************************************************************* - * Copyright (c) 2014, STMicroelectronics - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "cmsis_nvic.h" - -#define NVIC_RAM_VECTOR_ADDRESS (0x20000000) // Vectors positioned at start of RAM -#define NVIC_FLASH_VECTOR_ADDRESS (0x08000000) // Initial vector position in flash - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { - uint32_t *vectors = (uint32_t *)SCB->VTOR; - uint32_t i; - - // Copy and switch to dynamic vectors if the first time called - if (SCB->VTOR == NVIC_FLASH_VECTOR_ADDRESS) { - uint32_t *old_vectors = vectors; - vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS; - for (i=0; iVTOR = (uint32_t)NVIC_RAM_VECTOR_ADDRESS; - } - vectors[IRQn + NVIC_USER_IRQ_OFFSET] = vector; -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) { - uint32_t *vectors = (uint32_t*)SCB->VTOR; - return vectors[IRQn + NVIC_USER_IRQ_OFFSET]; -} diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F469xI/device/cmsis_nvic.h b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F469xI/device/cmsis_nvic.h index 4f2fbf9b5d5..724bfe356d6 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F469xI/device/cmsis_nvic.h +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F469xI/device/cmsis_nvic.h @@ -1,5 +1,4 @@ /* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors ******************************************************************************* * Copyright (c) 2014, STMicroelectronics * All rights reserved. @@ -27,7 +26,7 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ******************************************************************************* - */ + */ #ifndef MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H @@ -36,20 +35,7 @@ // CORE: 16 vectors = 64 bytes from 0x00 to 0x3F // MCU Peripherals: 93 vectors = 372 bytes from 0x40 to 0x1B3 // Total: 109 vectors = 436 bytes (0x1B4) to be reserved in RAM -#define NVIC_NUM_VECTORS 109 -#define NVIC_USER_IRQ_OFFSET 16 - -#include "cmsis.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +#define NVIC_NUM_VECTORS 109 +#define NVIC_RAM_VECTOR_ADDRESS 0x20000000 // Vectors positioned at start of RAM #endif diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_UBLOX_EVK_ODIN_W2/device/cmsis_nvic.c b/targets/TARGET_STM/TARGET_STM32F4/TARGET_UBLOX_EVK_ODIN_W2/device/cmsis_nvic.c deleted file mode 100644 index a1e0351aa1a..00000000000 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_UBLOX_EVK_ODIN_W2/device/cmsis_nvic.c +++ /dev/null @@ -1,55 +0,0 @@ -/* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors - ******************************************************************************* - * Copyright (c) 2014, STMicroelectronics - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "cmsis_nvic.h" -#include "nvic_addr.h" - -#define NVIC_RAM_VECTOR_ADDRESS (0x20000000) // Vectors positioned at start of RAM - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { - uint32_t *vectors = (uint32_t *)SCB->VTOR; - uint32_t i; - - // Copy and switch to dynamic vectors if the first time called - if (SCB->VTOR == NVIC_FLASH_VECTOR_ADDRESS) { - uint32_t *old_vectors = vectors; - vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS; - for (i=0; iVTOR = (uint32_t)NVIC_RAM_VECTOR_ADDRESS; - } - vectors[IRQn + NVIC_USER_IRQ_OFFSET] = vector; -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) { - uint32_t *vectors = (uint32_t*)SCB->VTOR; - return vectors[IRQn + NVIC_USER_IRQ_OFFSET]; -} diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_UBLOX_EVK_ODIN_W2/device/cmsis_nvic.h b/targets/TARGET_STM/TARGET_STM32F4/TARGET_UBLOX_EVK_ODIN_W2/device/cmsis_nvic.h index cf9d4e711b5..a96b9da4110 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_UBLOX_EVK_ODIN_W2/device/cmsis_nvic.h +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_UBLOX_EVK_ODIN_W2/device/cmsis_nvic.h @@ -1,5 +1,4 @@ /* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors ******************************************************************************* * Copyright (c) 2014, STMicroelectronics * All rights reserved. @@ -27,7 +26,7 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ******************************************************************************* - */ + */ #ifndef MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H @@ -36,20 +35,7 @@ // CORE: 16 vectors = 64 bytes from 0x00 to 0x3F // MCU Peripherals: 91 vectors = 364 bytes from 0x40 to 0x1AB // Total: 107 vectors = 428 bytes (0x1AC) to be reserved in RAM -#define NVIC_NUM_VECTORS 107 -#define NVIC_USER_IRQ_OFFSET 16 - -#include "cmsis.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +#define NVIC_NUM_VECTORS 107 +#define NVIC_RAM_VECTOR_ADDRESS 0x20000000 // Vectors positioned at start of RAM #endif diff --git a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F746xG/device/cmsis_nvic.c b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F746xG/device/cmsis_nvic.c deleted file mode 100644 index 69a0fa58323..00000000000 --- a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F746xG/device/cmsis_nvic.c +++ /dev/null @@ -1,55 +0,0 @@ -/* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors - ******************************************************************************* - * Copyright (c) 2016, STMicroelectronics - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "cmsis_nvic.h" - -#define NVIC_RAM_VECTOR_ADDRESS (0x20000000) // Vectors positioned at start of RAM -#define NVIC_FLASH_VECTOR_ADDRESS (0x08000000) // Initial vector position in flash - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { - uint32_t *vectors = (uint32_t *)SCB->VTOR; - uint32_t i; - - // Copy and switch to dynamic vectors if the first time called - if (SCB->VTOR == NVIC_FLASH_VECTOR_ADDRESS) { - uint32_t *old_vectors = vectors; - vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS; - for (i=0; iVTOR = (uint32_t)NVIC_RAM_VECTOR_ADDRESS; - } - vectors[IRQn + NVIC_USER_IRQ_OFFSET] = vector; -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) { - uint32_t *vectors = (uint32_t*)SCB->VTOR; - return vectors[IRQn + NVIC_USER_IRQ_OFFSET]; -} diff --git a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F746xG/device/cmsis_nvic.h b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F746xG/device/cmsis_nvic.h index 0a26d73682f..878cea72be4 100644 --- a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F746xG/device/cmsis_nvic.h +++ b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F746xG/device/cmsis_nvic.h @@ -1,5 +1,4 @@ /* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors ******************************************************************************* * Copyright (c) 2016, STMicroelectronics * All rights reserved. @@ -27,7 +26,7 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ******************************************************************************* - */ + */ #ifndef MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H @@ -36,19 +35,6 @@ // MCU Peripherals: 98 vectors = 392 bytes from 0x40 to 0x1C7 // Total: 114 vectors = 456 bytes (0x1C8) to be reserved in RAM #define NVIC_NUM_VECTORS 114 -#define NVIC_USER_IRQ_OFFSET 16 - -#include "cmsis.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +#define NVIC_RAM_VECTOR_ADDRESS 0x20000000 // Vectors positioned at start of RAM #endif diff --git a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F756xG/device/cmsis_nvic.c b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F756xG/device/cmsis_nvic.c deleted file mode 100644 index 69a0fa58323..00000000000 --- a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F756xG/device/cmsis_nvic.c +++ /dev/null @@ -1,55 +0,0 @@ -/* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors - ******************************************************************************* - * Copyright (c) 2016, STMicroelectronics - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "cmsis_nvic.h" - -#define NVIC_RAM_VECTOR_ADDRESS (0x20000000) // Vectors positioned at start of RAM -#define NVIC_FLASH_VECTOR_ADDRESS (0x08000000) // Initial vector position in flash - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { - uint32_t *vectors = (uint32_t *)SCB->VTOR; - uint32_t i; - - // Copy and switch to dynamic vectors if the first time called - if (SCB->VTOR == NVIC_FLASH_VECTOR_ADDRESS) { - uint32_t *old_vectors = vectors; - vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS; - for (i=0; iVTOR = (uint32_t)NVIC_RAM_VECTOR_ADDRESS; - } - vectors[IRQn + NVIC_USER_IRQ_OFFSET] = vector; -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) { - uint32_t *vectors = (uint32_t*)SCB->VTOR; - return vectors[IRQn + NVIC_USER_IRQ_OFFSET]; -} diff --git a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F756xG/device/cmsis_nvic.h b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F756xG/device/cmsis_nvic.h index 0a26d73682f..de4c30ea1fd 100644 --- a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F756xG/device/cmsis_nvic.h +++ b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F756xG/device/cmsis_nvic.h @@ -1,5 +1,4 @@ /* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors ******************************************************************************* * Copyright (c) 2016, STMicroelectronics * All rights reserved. @@ -27,7 +26,7 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ******************************************************************************* - */ + */ #ifndef MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H @@ -35,20 +34,7 @@ // CORE: 16 vectors = 64 bytes from 0x00 to 0x3F // MCU Peripherals: 98 vectors = 392 bytes from 0x40 to 0x1C7 // Total: 114 vectors = 456 bytes (0x1C8) to be reserved in RAM -#define NVIC_NUM_VECTORS 114 -#define NVIC_USER_IRQ_OFFSET 16 - -#include "cmsis.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +#define NVIC_NUM_VECTORS 114 +#define NVIC_RAM_VECTOR_ADDRESS 0x20000000 // Vectors positioned at start of RAM #endif diff --git a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F767xI/device/cmsis_nvic.c b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F767xI/device/cmsis_nvic.c deleted file mode 100644 index 69a0fa58323..00000000000 --- a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F767xI/device/cmsis_nvic.c +++ /dev/null @@ -1,55 +0,0 @@ -/* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors - ******************************************************************************* - * Copyright (c) 2016, STMicroelectronics - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "cmsis_nvic.h" - -#define NVIC_RAM_VECTOR_ADDRESS (0x20000000) // Vectors positioned at start of RAM -#define NVIC_FLASH_VECTOR_ADDRESS (0x08000000) // Initial vector position in flash - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { - uint32_t *vectors = (uint32_t *)SCB->VTOR; - uint32_t i; - - // Copy and switch to dynamic vectors if the first time called - if (SCB->VTOR == NVIC_FLASH_VECTOR_ADDRESS) { - uint32_t *old_vectors = vectors; - vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS; - for (i=0; iVTOR = (uint32_t)NVIC_RAM_VECTOR_ADDRESS; - } - vectors[IRQn + NVIC_USER_IRQ_OFFSET] = vector; -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) { - uint32_t *vectors = (uint32_t*)SCB->VTOR; - return vectors[IRQn + NVIC_USER_IRQ_OFFSET]; -} diff --git a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F767xI/device/cmsis_nvic.h b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F767xI/device/cmsis_nvic.h index 0a26d73682f..de4c30ea1fd 100644 --- a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F767xI/device/cmsis_nvic.h +++ b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F767xI/device/cmsis_nvic.h @@ -1,5 +1,4 @@ /* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors ******************************************************************************* * Copyright (c) 2016, STMicroelectronics * All rights reserved. @@ -27,7 +26,7 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ******************************************************************************* - */ + */ #ifndef MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H @@ -35,20 +34,7 @@ // CORE: 16 vectors = 64 bytes from 0x00 to 0x3F // MCU Peripherals: 98 vectors = 392 bytes from 0x40 to 0x1C7 // Total: 114 vectors = 456 bytes (0x1C8) to be reserved in RAM -#define NVIC_NUM_VECTORS 114 -#define NVIC_USER_IRQ_OFFSET 16 - -#include "cmsis.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +#define NVIC_NUM_VECTORS 114 +#define NVIC_RAM_VECTOR_ADDRESS 0x20000000 // Vectors positioned at start of RAM #endif diff --git a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F769xI/device/cmsis_nvic.c b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F769xI/device/cmsis_nvic.c deleted file mode 100644 index 69a0fa58323..00000000000 --- a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F769xI/device/cmsis_nvic.c +++ /dev/null @@ -1,55 +0,0 @@ -/* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors - ******************************************************************************* - * Copyright (c) 2016, STMicroelectronics - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "cmsis_nvic.h" - -#define NVIC_RAM_VECTOR_ADDRESS (0x20000000) // Vectors positioned at start of RAM -#define NVIC_FLASH_VECTOR_ADDRESS (0x08000000) // Initial vector position in flash - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { - uint32_t *vectors = (uint32_t *)SCB->VTOR; - uint32_t i; - - // Copy and switch to dynamic vectors if the first time called - if (SCB->VTOR == NVIC_FLASH_VECTOR_ADDRESS) { - uint32_t *old_vectors = vectors; - vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS; - for (i=0; iVTOR = (uint32_t)NVIC_RAM_VECTOR_ADDRESS; - } - vectors[IRQn + NVIC_USER_IRQ_OFFSET] = vector; -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) { - uint32_t *vectors = (uint32_t*)SCB->VTOR; - return vectors[IRQn + NVIC_USER_IRQ_OFFSET]; -} diff --git a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F769xI/device/cmsis_nvic.h b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F769xI/device/cmsis_nvic.h index 0a26d73682f..de4c30ea1fd 100644 --- a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F769xI/device/cmsis_nvic.h +++ b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F769xI/device/cmsis_nvic.h @@ -1,5 +1,4 @@ /* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors ******************************************************************************* * Copyright (c) 2016, STMicroelectronics * All rights reserved. @@ -27,7 +26,7 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ******************************************************************************* - */ + */ #ifndef MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H @@ -35,20 +34,7 @@ // CORE: 16 vectors = 64 bytes from 0x00 to 0x3F // MCU Peripherals: 98 vectors = 392 bytes from 0x40 to 0x1C7 // Total: 114 vectors = 456 bytes (0x1C8) to be reserved in RAM -#define NVIC_NUM_VECTORS 114 -#define NVIC_USER_IRQ_OFFSET 16 - -#include "cmsis.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +#define NVIC_NUM_VECTORS 114 +#define NVIC_RAM_VECTOR_ADDRESS 0x20000000 // Vectors positioned at start of RAM #endif diff --git a/targets/TARGET_STM/TARGET_STM32L0/TARGET_DISCO_L053C8/device/cmsis_nvic.c b/targets/TARGET_STM/TARGET_STM32L0/TARGET_DISCO_L053C8/device/cmsis_nvic.c deleted file mode 100644 index 2da63fc9af8..00000000000 --- a/targets/TARGET_STM/TARGET_STM32L0/TARGET_DISCO_L053C8/device/cmsis_nvic.c +++ /dev/null @@ -1,55 +0,0 @@ -/* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors - ******************************************************************************* - * Copyright (c) 2014, STMicroelectronics - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "cmsis_nvic.h" - -#define NVIC_RAM_VECTOR_ADDRESS (0x20000000) // Vectors positioned at start of RAM -#define NVIC_FLASH_VECTOR_ADDRESS (0x08000000) // Initial vector position in flash - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { - uint32_t *vectors = (uint32_t *)SCB->VTOR; - uint32_t i; - - // Copy and switch to dynamic vectors if the first time called - if (SCB->VTOR == NVIC_FLASH_VECTOR_ADDRESS) { - uint32_t *old_vectors = vectors; - vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS; - for (i=0; iVTOR = (uint32_t)NVIC_RAM_VECTOR_ADDRESS; - } - vectors[IRQn + NVIC_USER_IRQ_OFFSET] = vector; -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) { - uint32_t *vectors = (uint32_t*)SCB->VTOR; - return vectors[IRQn + NVIC_USER_IRQ_OFFSET]; -} diff --git a/targets/TARGET_STM/TARGET_STM32L0/TARGET_DISCO_L053C8/device/cmsis_nvic.h b/targets/TARGET_STM/TARGET_STM32L0/TARGET_DISCO_L053C8/device/cmsis_nvic.h index 027dd9f78a6..5f586069889 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/TARGET_DISCO_L053C8/device/cmsis_nvic.h +++ b/targets/TARGET_STM/TARGET_STM32L0/TARGET_DISCO_L053C8/device/cmsis_nvic.h @@ -1,5 +1,4 @@ /* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors ******************************************************************************* * Copyright (c) 2014, STMicroelectronics * All rights reserved. @@ -27,7 +26,7 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ******************************************************************************* - */ + */ #ifndef MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H @@ -35,20 +34,7 @@ // CORE: 16 vectors = 64 bytes from 0x00 to 0x3F // MCU Peripherals: 32 vectors = 128 bytes from 0x40 to 0xBF // Total: 48 vectors = 192 bytes (0xC0) to be reserved in RAM -#define NVIC_NUM_VECTORS 48 -#define NVIC_USER_IRQ_OFFSET 16 - -#include "cmsis.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +#define NVIC_NUM_VECTORS 48 +#define NVIC_RAM_VECTOR_ADDRESS 0x20000000 // Vectors positioned at start of RAM #endif diff --git a/targets/TARGET_STM/TARGET_STM32L0/TARGET_DISCO_L072CZ_LRWAN1/device/cmsis_nvic.c b/targets/TARGET_STM/TARGET_STM32L0/TARGET_DISCO_L072CZ_LRWAN1/device/cmsis_nvic.c deleted file mode 100644 index 41a742b4aa1..00000000000 --- a/targets/TARGET_STM/TARGET_STM32L0/TARGET_DISCO_L072CZ_LRWAN1/device/cmsis_nvic.c +++ /dev/null @@ -1,55 +0,0 @@ -/* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors - ******************************************************************************* - * Copyright (c) 2017, STMicroelectronics - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "cmsis_nvic.h" - -#define NVIC_RAM_VECTOR_ADDRESS (0x20000000) // Vectors positioned at start of RAM -#define NVIC_FLASH_VECTOR_ADDRESS (0x08000000) // Initial vector position in flash - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { - uint32_t *vectors = (uint32_t *)SCB->VTOR; - uint32_t i; - - // Copy and switch to dynamic vectors if the first time called - if (SCB->VTOR == NVIC_FLASH_VECTOR_ADDRESS) { - uint32_t *old_vectors = vectors; - vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS; - for (i=0; iVTOR = (uint32_t)NVIC_RAM_VECTOR_ADDRESS; - } - vectors[IRQn + NVIC_USER_IRQ_OFFSET] = vector; -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) { - uint32_t *vectors = (uint32_t*)SCB->VTOR; - return vectors[IRQn + NVIC_USER_IRQ_OFFSET]; -} diff --git a/targets/TARGET_STM/TARGET_STM32L0/TARGET_DISCO_L072CZ_LRWAN1/device/cmsis_nvic.h b/targets/TARGET_STM/TARGET_STM32L0/TARGET_DISCO_L072CZ_LRWAN1/device/cmsis_nvic.h index baba2251b18..b50440aede6 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/TARGET_DISCO_L072CZ_LRWAN1/device/cmsis_nvic.h +++ b/targets/TARGET_STM/TARGET_STM32L0/TARGET_DISCO_L072CZ_LRWAN1/device/cmsis_nvic.h @@ -36,19 +36,6 @@ // MCU Peripherals: 32 vectors = 128 bytes from 0x40 to 0xBF // Total: 48 vectors = 192 bytes (0xC0) to be reserved in RAM #define NVIC_NUM_VECTORS 48 -#define NVIC_USER_IRQ_OFFSET 16 - -#include "cmsis.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +#define NVIC_RAM_VECTOR_ADDRESS (0x20000000) // Vectors positioned at start of RAM #endif diff --git a/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L011K4/device/cmsis_nvic.c b/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L011K4/device/cmsis_nvic.c deleted file mode 100644 index 2da63fc9af8..00000000000 --- a/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L011K4/device/cmsis_nvic.c +++ /dev/null @@ -1,55 +0,0 @@ -/* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors - ******************************************************************************* - * Copyright (c) 2014, STMicroelectronics - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "cmsis_nvic.h" - -#define NVIC_RAM_VECTOR_ADDRESS (0x20000000) // Vectors positioned at start of RAM -#define NVIC_FLASH_VECTOR_ADDRESS (0x08000000) // Initial vector position in flash - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { - uint32_t *vectors = (uint32_t *)SCB->VTOR; - uint32_t i; - - // Copy and switch to dynamic vectors if the first time called - if (SCB->VTOR == NVIC_FLASH_VECTOR_ADDRESS) { - uint32_t *old_vectors = vectors; - vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS; - for (i=0; iVTOR = (uint32_t)NVIC_RAM_VECTOR_ADDRESS; - } - vectors[IRQn + NVIC_USER_IRQ_OFFSET] = vector; -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) { - uint32_t *vectors = (uint32_t*)SCB->VTOR; - return vectors[IRQn + NVIC_USER_IRQ_OFFSET]; -} diff --git a/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L011K4/device/cmsis_nvic.h b/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L011K4/device/cmsis_nvic.h index 027dd9f78a6..5f586069889 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L011K4/device/cmsis_nvic.h +++ b/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L011K4/device/cmsis_nvic.h @@ -1,5 +1,4 @@ /* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors ******************************************************************************* * Copyright (c) 2014, STMicroelectronics * All rights reserved. @@ -27,7 +26,7 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ******************************************************************************* - */ + */ #ifndef MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H @@ -35,20 +34,7 @@ // CORE: 16 vectors = 64 bytes from 0x00 to 0x3F // MCU Peripherals: 32 vectors = 128 bytes from 0x40 to 0xBF // Total: 48 vectors = 192 bytes (0xC0) to be reserved in RAM -#define NVIC_NUM_VECTORS 48 -#define NVIC_USER_IRQ_OFFSET 16 - -#include "cmsis.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +#define NVIC_NUM_VECTORS 48 +#define NVIC_RAM_VECTOR_ADDRESS 0x20000000 // Vectors positioned at start of RAM #endif diff --git a/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L031K6/device/cmsis_nvic.c b/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L031K6/device/cmsis_nvic.c deleted file mode 100644 index 2da63fc9af8..00000000000 --- a/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L031K6/device/cmsis_nvic.c +++ /dev/null @@ -1,55 +0,0 @@ -/* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors - ******************************************************************************* - * Copyright (c) 2014, STMicroelectronics - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "cmsis_nvic.h" - -#define NVIC_RAM_VECTOR_ADDRESS (0x20000000) // Vectors positioned at start of RAM -#define NVIC_FLASH_VECTOR_ADDRESS (0x08000000) // Initial vector position in flash - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { - uint32_t *vectors = (uint32_t *)SCB->VTOR; - uint32_t i; - - // Copy and switch to dynamic vectors if the first time called - if (SCB->VTOR == NVIC_FLASH_VECTOR_ADDRESS) { - uint32_t *old_vectors = vectors; - vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS; - for (i=0; iVTOR = (uint32_t)NVIC_RAM_VECTOR_ADDRESS; - } - vectors[IRQn + NVIC_USER_IRQ_OFFSET] = vector; -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) { - uint32_t *vectors = (uint32_t*)SCB->VTOR; - return vectors[IRQn + NVIC_USER_IRQ_OFFSET]; -} diff --git a/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L031K6/device/cmsis_nvic.h b/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L031K6/device/cmsis_nvic.h index 64c689a3b08..5f586069889 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L031K6/device/cmsis_nvic.h +++ b/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L031K6/device/cmsis_nvic.h @@ -1,5 +1,4 @@ /* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors ******************************************************************************* * Copyright (c) 2014, STMicroelectronics * All rights reserved. @@ -35,20 +34,7 @@ // CORE: 16 vectors = 64 bytes from 0x00 to 0x3F // MCU Peripherals: 32 vectors = 128 bytes from 0x40 to 0xBF // Total: 48 vectors = 192 bytes (0xC0) to be reserved in RAM -#define NVIC_NUM_VECTORS 48 -#define NVIC_USER_IRQ_OFFSET 16 - -#include "cmsis.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +#define NVIC_NUM_VECTORS 48 +#define NVIC_RAM_VECTOR_ADDRESS 0x20000000 // Vectors positioned at start of RAM #endif diff --git a/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L053R8/device/cmsis_nvic.c b/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L053R8/device/cmsis_nvic.c deleted file mode 100644 index 2da63fc9af8..00000000000 --- a/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L053R8/device/cmsis_nvic.c +++ /dev/null @@ -1,55 +0,0 @@ -/* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors - ******************************************************************************* - * Copyright (c) 2014, STMicroelectronics - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "cmsis_nvic.h" - -#define NVIC_RAM_VECTOR_ADDRESS (0x20000000) // Vectors positioned at start of RAM -#define NVIC_FLASH_VECTOR_ADDRESS (0x08000000) // Initial vector position in flash - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { - uint32_t *vectors = (uint32_t *)SCB->VTOR; - uint32_t i; - - // Copy and switch to dynamic vectors if the first time called - if (SCB->VTOR == NVIC_FLASH_VECTOR_ADDRESS) { - uint32_t *old_vectors = vectors; - vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS; - for (i=0; iVTOR = (uint32_t)NVIC_RAM_VECTOR_ADDRESS; - } - vectors[IRQn + NVIC_USER_IRQ_OFFSET] = vector; -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) { - uint32_t *vectors = (uint32_t*)SCB->VTOR; - return vectors[IRQn + NVIC_USER_IRQ_OFFSET]; -} diff --git a/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L053R8/device/cmsis_nvic.h b/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L053R8/device/cmsis_nvic.h index 027dd9f78a6..5f586069889 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L053R8/device/cmsis_nvic.h +++ b/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L053R8/device/cmsis_nvic.h @@ -1,5 +1,4 @@ /* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors ******************************************************************************* * Copyright (c) 2014, STMicroelectronics * All rights reserved. @@ -27,7 +26,7 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ******************************************************************************* - */ + */ #ifndef MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H @@ -35,20 +34,7 @@ // CORE: 16 vectors = 64 bytes from 0x00 to 0x3F // MCU Peripherals: 32 vectors = 128 bytes from 0x40 to 0xBF // Total: 48 vectors = 192 bytes (0xC0) to be reserved in RAM -#define NVIC_NUM_VECTORS 48 -#define NVIC_USER_IRQ_OFFSET 16 - -#include "cmsis.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +#define NVIC_NUM_VECTORS 48 +#define NVIC_RAM_VECTOR_ADDRESS 0x20000000 // Vectors positioned at start of RAM #endif diff --git a/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L073RZ/device/cmsis_nvic.c b/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L073RZ/device/cmsis_nvic.c deleted file mode 100644 index 2da63fc9af8..00000000000 --- a/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L073RZ/device/cmsis_nvic.c +++ /dev/null @@ -1,55 +0,0 @@ -/* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors - ******************************************************************************* - * Copyright (c) 2014, STMicroelectronics - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "cmsis_nvic.h" - -#define NVIC_RAM_VECTOR_ADDRESS (0x20000000) // Vectors positioned at start of RAM -#define NVIC_FLASH_VECTOR_ADDRESS (0x08000000) // Initial vector position in flash - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { - uint32_t *vectors = (uint32_t *)SCB->VTOR; - uint32_t i; - - // Copy and switch to dynamic vectors if the first time called - if (SCB->VTOR == NVIC_FLASH_VECTOR_ADDRESS) { - uint32_t *old_vectors = vectors; - vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS; - for (i=0; iVTOR = (uint32_t)NVIC_RAM_VECTOR_ADDRESS; - } - vectors[IRQn + NVIC_USER_IRQ_OFFSET] = vector; -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) { - uint32_t *vectors = (uint32_t*)SCB->VTOR; - return vectors[IRQn + NVIC_USER_IRQ_OFFSET]; -} diff --git a/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L073RZ/device/cmsis_nvic.h b/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L073RZ/device/cmsis_nvic.h index 027dd9f78a6..5f586069889 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L073RZ/device/cmsis_nvic.h +++ b/targets/TARGET_STM/TARGET_STM32L0/TARGET_NUCLEO_L073RZ/device/cmsis_nvic.h @@ -1,5 +1,4 @@ /* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors ******************************************************************************* * Copyright (c) 2014, STMicroelectronics * All rights reserved. @@ -27,7 +26,7 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ******************************************************************************* - */ + */ #ifndef MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H @@ -35,20 +34,7 @@ // CORE: 16 vectors = 64 bytes from 0x00 to 0x3F // MCU Peripherals: 32 vectors = 128 bytes from 0x40 to 0xBF // Total: 48 vectors = 192 bytes (0xC0) to be reserved in RAM -#define NVIC_NUM_VECTORS 48 -#define NVIC_USER_IRQ_OFFSET 16 - -#include "cmsis.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +#define NVIC_NUM_VECTORS 48 +#define NVIC_RAM_VECTOR_ADDRESS 0x20000000 // Vectors positioned at start of RAM #endif diff --git a/targets/TARGET_STM/TARGET_STM32L1/TARGET_MOTE_L152RC/device/cmsis_nvic.c b/targets/TARGET_STM/TARGET_STM32L1/TARGET_MOTE_L152RC/device/cmsis_nvic.c deleted file mode 100644 index 2da63fc9af8..00000000000 --- a/targets/TARGET_STM/TARGET_STM32L1/TARGET_MOTE_L152RC/device/cmsis_nvic.c +++ /dev/null @@ -1,55 +0,0 @@ -/* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors - ******************************************************************************* - * Copyright (c) 2014, STMicroelectronics - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "cmsis_nvic.h" - -#define NVIC_RAM_VECTOR_ADDRESS (0x20000000) // Vectors positioned at start of RAM -#define NVIC_FLASH_VECTOR_ADDRESS (0x08000000) // Initial vector position in flash - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { - uint32_t *vectors = (uint32_t *)SCB->VTOR; - uint32_t i; - - // Copy and switch to dynamic vectors if the first time called - if (SCB->VTOR == NVIC_FLASH_VECTOR_ADDRESS) { - uint32_t *old_vectors = vectors; - vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS; - for (i=0; iVTOR = (uint32_t)NVIC_RAM_VECTOR_ADDRESS; - } - vectors[IRQn + NVIC_USER_IRQ_OFFSET] = vector; -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) { - uint32_t *vectors = (uint32_t*)SCB->VTOR; - return vectors[IRQn + NVIC_USER_IRQ_OFFSET]; -} diff --git a/targets/TARGET_STM/TARGET_STM32L1/TARGET_MOTE_L152RC/device/cmsis_nvic.h b/targets/TARGET_STM/TARGET_STM32L1/TARGET_MOTE_L152RC/device/cmsis_nvic.h index 29fbb15f408..8fe85757e8e 100644 --- a/targets/TARGET_STM/TARGET_STM32L1/TARGET_MOTE_L152RC/device/cmsis_nvic.h +++ b/targets/TARGET_STM/TARGET_STM32L1/TARGET_MOTE_L152RC/device/cmsis_nvic.h @@ -1,5 +1,4 @@ /* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors ******************************************************************************* * Copyright (c) 2014, STMicroelectronics * All rights reserved. @@ -27,7 +26,7 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ******************************************************************************* - */ + */ #ifndef MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H @@ -36,20 +35,7 @@ // CORE: 16 vectors = 64 bytes from 0x00 to 0x3F // MCU Peripherals: 57 vectors = 228 bytes from 0x40 to 0x123 // Total: 73 vectors = 292 bytes (0x124) to be reserved in RAM -#define NVIC_NUM_VECTORS 73 -#define NVIC_USER_IRQ_OFFSET 16 - -#include "cmsis.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +#define NVIC_NUM_VECTORS 73 +#define NVIC_RAM_VECTOR_ADDRESS 0x20000000 // Vectors positioned at start of RAM #endif diff --git a/targets/TARGET_STM/TARGET_STM32L1/TARGET_NUCLEO_L152RE/device/cmsis_nvic.c b/targets/TARGET_STM/TARGET_STM32L1/TARGET_NUCLEO_L152RE/device/cmsis_nvic.c deleted file mode 100644 index 2da63fc9af8..00000000000 --- a/targets/TARGET_STM/TARGET_STM32L1/TARGET_NUCLEO_L152RE/device/cmsis_nvic.c +++ /dev/null @@ -1,55 +0,0 @@ -/* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors - ******************************************************************************* - * Copyright (c) 2014, STMicroelectronics - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "cmsis_nvic.h" - -#define NVIC_RAM_VECTOR_ADDRESS (0x20000000) // Vectors positioned at start of RAM -#define NVIC_FLASH_VECTOR_ADDRESS (0x08000000) // Initial vector position in flash - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { - uint32_t *vectors = (uint32_t *)SCB->VTOR; - uint32_t i; - - // Copy and switch to dynamic vectors if the first time called - if (SCB->VTOR == NVIC_FLASH_VECTOR_ADDRESS) { - uint32_t *old_vectors = vectors; - vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS; - for (i=0; iVTOR = (uint32_t)NVIC_RAM_VECTOR_ADDRESS; - } - vectors[IRQn + NVIC_USER_IRQ_OFFSET] = vector; -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) { - uint32_t *vectors = (uint32_t*)SCB->VTOR; - return vectors[IRQn + NVIC_USER_IRQ_OFFSET]; -} diff --git a/targets/TARGET_STM/TARGET_STM32L1/TARGET_NUCLEO_L152RE/device/cmsis_nvic.h b/targets/TARGET_STM/TARGET_STM32L1/TARGET_NUCLEO_L152RE/device/cmsis_nvic.h index 2911892ec3b..c2b939c5dc8 100644 --- a/targets/TARGET_STM/TARGET_STM32L1/TARGET_NUCLEO_L152RE/device/cmsis_nvic.h +++ b/targets/TARGET_STM/TARGET_STM32L1/TARGET_NUCLEO_L152RE/device/cmsis_nvic.h @@ -1,5 +1,4 @@ /* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors ******************************************************************************* * Copyright (c) 2014, STMicroelectronics * All rights reserved. @@ -27,7 +26,7 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ******************************************************************************* - */ + */ #ifndef MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H @@ -36,20 +35,7 @@ // CORE: 16 vectors = 64 bytes from 0x00 to 0x3F // MCU Peripherals: 57 vectors = 228 bytes from 0x40 to 0x123 // Total: 73 vectors = 292 bytes (0x124) to be reserved in RAM -#define NVIC_NUM_VECTORS 73 -#define NVIC_USER_IRQ_OFFSET 16 - -#include "cmsis.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +#define NVIC_NUM_VECTORS 73 +#define NVIC_RAM_VECTOR_ADDRESS 0x20000000 // Vectors positioned at start of RAM #endif diff --git a/targets/TARGET_STM/TARGET_STM32L1/TARGET_NZ32_SC151/device/cmsis_nvic.c b/targets/TARGET_STM/TARGET_STM32L1/TARGET_NZ32_SC151/device/cmsis_nvic.c deleted file mode 100644 index 9263c748e78..00000000000 --- a/targets/TARGET_STM/TARGET_STM32L1/TARGET_NZ32_SC151/device/cmsis_nvic.c +++ /dev/null @@ -1,55 +0,0 @@ -/* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors - ******************************************************************************* - * Copyright (c) 2015, STMicroelectronics - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "cmsis_nvic.h" - -#define NVIC_RAM_VECTOR_ADDRESS (0x20000000) // Vectors positioned at start of RAM -#define NVIC_FLASH_VECTOR_ADDRESS (0x08000000) // Initial vector position in flash - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { - uint32_t *vectors = (uint32_t *)SCB->VTOR; - uint32_t i; - - // Copy and switch to dynamic vectors if the first time called - if (SCB->VTOR == NVIC_FLASH_VECTOR_ADDRESS) { - uint32_t *old_vectors = vectors; - vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS; - for (i=0; iVTOR = (uint32_t)NVIC_RAM_VECTOR_ADDRESS; - } - vectors[IRQn + NVIC_USER_IRQ_OFFSET] = vector; -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) { - uint32_t *vectors = (uint32_t*)SCB->VTOR; - return vectors[IRQn + NVIC_USER_IRQ_OFFSET]; -} diff --git a/targets/TARGET_STM/TARGET_STM32L1/TARGET_NZ32_SC151/device/cmsis_nvic.h b/targets/TARGET_STM/TARGET_STM32L1/TARGET_NZ32_SC151/device/cmsis_nvic.h index 214b55e373c..2f5de616487 100644 --- a/targets/TARGET_STM/TARGET_STM32L1/TARGET_NZ32_SC151/device/cmsis_nvic.h +++ b/targets/TARGET_STM/TARGET_STM32L1/TARGET_NZ32_SC151/device/cmsis_nvic.h @@ -1,5 +1,4 @@ /* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors ******************************************************************************* * Copyright (c) 2015, STMicroelectronics * All rights reserved. @@ -27,7 +26,7 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ******************************************************************************* - */ + */ #ifndef MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H @@ -36,20 +35,7 @@ // CORE: 16 vectors = 64 bytes from 0x00 to 0x3F // MCU Peripherals: 57 vectors = 228 bytes from 0x40 to 0x123 // Total: 73 vectors = 292 bytes (0x124) to be reserved in RAM -#define NVIC_NUM_VECTORS 73 -#define NVIC_USER_IRQ_OFFSET 16 - -#include "cmsis.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +#define NVIC_NUM_VECTORS 73 +#define NVIC_RAM_VECTOR_ADDRESS 0x20000000 // Vectors positioned at start of RAM #endif diff --git a/targets/TARGET_STM/TARGET_STM32L1/TARGET_XDOT_L151CC/device/cmsis_nvic.c b/targets/TARGET_STM/TARGET_STM32L1/TARGET_XDOT_L151CC/device/cmsis_nvic.c deleted file mode 100644 index 9263c748e78..00000000000 --- a/targets/TARGET_STM/TARGET_STM32L1/TARGET_XDOT_L151CC/device/cmsis_nvic.c +++ /dev/null @@ -1,55 +0,0 @@ -/* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors - ******************************************************************************* - * Copyright (c) 2015, STMicroelectronics - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "cmsis_nvic.h" - -#define NVIC_RAM_VECTOR_ADDRESS (0x20000000) // Vectors positioned at start of RAM -#define NVIC_FLASH_VECTOR_ADDRESS (0x08000000) // Initial vector position in flash - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { - uint32_t *vectors = (uint32_t *)SCB->VTOR; - uint32_t i; - - // Copy and switch to dynamic vectors if the first time called - if (SCB->VTOR == NVIC_FLASH_VECTOR_ADDRESS) { - uint32_t *old_vectors = vectors; - vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS; - for (i=0; iVTOR = (uint32_t)NVIC_RAM_VECTOR_ADDRESS; - } - vectors[IRQn + NVIC_USER_IRQ_OFFSET] = vector; -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) { - uint32_t *vectors = (uint32_t*)SCB->VTOR; - return vectors[IRQn + NVIC_USER_IRQ_OFFSET]; -} diff --git a/targets/TARGET_STM/TARGET_STM32L1/TARGET_XDOT_L151CC/device/cmsis_nvic.h b/targets/TARGET_STM/TARGET_STM32L1/TARGET_XDOT_L151CC/device/cmsis_nvic.h index 94aba6e7f41..6f8097c63bd 100644 --- a/targets/TARGET_STM/TARGET_STM32L1/TARGET_XDOT_L151CC/device/cmsis_nvic.h +++ b/targets/TARGET_STM/TARGET_STM32L1/TARGET_XDOT_L151CC/device/cmsis_nvic.h @@ -1,5 +1,4 @@ /* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors ******************************************************************************* * Copyright (c) 2015, STMicroelectronics * All rights reserved. @@ -27,7 +26,7 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ******************************************************************************* - */ + */ #ifndef MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H @@ -36,20 +35,7 @@ // CORE: 16 vectors = 64 bytes from 0x00 to 0x3F // MCU Peripherals: 57 vectors = 228 bytes from 0x40 to 0x123 // Total: 73 vectors = 292 bytes (0x124) to be reserved in RAM -#define NVIC_NUM_VECTORS 73 -#define NVIC_USER_IRQ_OFFSET 16 - -#include "cmsis.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +#define NVIC_NUM_VECTORS 73 +#define NVIC_RAM_VECTOR_ADDRESS 0x20000000 // Vectors positioned at start of RAM #endif diff --git a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L432xC/device/cmsis_nvic.c b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L432xC/device/cmsis_nvic.c deleted file mode 100644 index a8a6a487a54..00000000000 --- a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L432xC/device/cmsis_nvic.c +++ /dev/null @@ -1,55 +0,0 @@ -/* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors - ******************************************************************************* - * Copyright (c) 2015, STMicroelectronics - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "cmsis_nvic.h" - -#define NVIC_RAM_VECTOR_ADDRESS (0x10000000) // Vectors positioned at start of SRAM2 -#define NVIC_FLASH_VECTOR_ADDRESS (0x08000000) // Initial vector position in flash - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { - uint32_t *vectors = (uint32_t *)SCB->VTOR; - uint32_t i; - - // Copy and switch to dynamic vectors if the first time called - if (SCB->VTOR == NVIC_FLASH_VECTOR_ADDRESS) { - uint32_t *old_vectors = vectors; - vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS; - for (i=0; iVTOR = (uint32_t)NVIC_RAM_VECTOR_ADDRESS; - } - vectors[IRQn + NVIC_USER_IRQ_OFFSET] = vector; -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) { - uint32_t *vectors = (uint32_t*)SCB->VTOR; - return vectors[IRQn + NVIC_USER_IRQ_OFFSET]; -} diff --git a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L432xC/device/cmsis_nvic.h b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L432xC/device/cmsis_nvic.h index 2af8d33e214..abb7956a000 100644 --- a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L432xC/device/cmsis_nvic.h +++ b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L432xC/device/cmsis_nvic.h @@ -1,5 +1,4 @@ /* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors ******************************************************************************* * Copyright (c) 2015, STMicroelectronics * All rights reserved. @@ -27,7 +26,7 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ******************************************************************************* - */ + */ #ifndef MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H @@ -35,20 +34,7 @@ // CORE: 16 vectors = 64 bytes from 0x00 to 0x3F // MCU Peripherals: 82 vectors = 328 bytes from 0x40 to 0x187 // Total: 98 vectors = 392 bytes (0x188) to be reserved in RAM -#define NVIC_NUM_VECTORS 98 -#define NVIC_USER_IRQ_OFFSET 16 - -#include "cmsis.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +#define NVIC_NUM_VECTORS 98 +#define NVIC_RAM_VECTOR_ADDRESS 0x10000000 // Vectors positioned at start of SRAM2 #endif diff --git a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/device/cmsis_nvic.c b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/device/cmsis_nvic.c deleted file mode 100644 index a8a6a487a54..00000000000 --- a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/device/cmsis_nvic.c +++ /dev/null @@ -1,55 +0,0 @@ -/* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors - ******************************************************************************* - * Copyright (c) 2015, STMicroelectronics - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "cmsis_nvic.h" - -#define NVIC_RAM_VECTOR_ADDRESS (0x10000000) // Vectors positioned at start of SRAM2 -#define NVIC_FLASH_VECTOR_ADDRESS (0x08000000) // Initial vector position in flash - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { - uint32_t *vectors = (uint32_t *)SCB->VTOR; - uint32_t i; - - // Copy and switch to dynamic vectors if the first time called - if (SCB->VTOR == NVIC_FLASH_VECTOR_ADDRESS) { - uint32_t *old_vectors = vectors; - vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS; - for (i=0; iVTOR = (uint32_t)NVIC_RAM_VECTOR_ADDRESS; - } - vectors[IRQn + NVIC_USER_IRQ_OFFSET] = vector; -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) { - uint32_t *vectors = (uint32_t*)SCB->VTOR; - return vectors[IRQn + NVIC_USER_IRQ_OFFSET]; -} diff --git a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/device/cmsis_nvic.h b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/device/cmsis_nvic.h index 2af8d33e214..abb7956a000 100644 --- a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/device/cmsis_nvic.h +++ b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/device/cmsis_nvic.h @@ -1,5 +1,4 @@ /* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors ******************************************************************************* * Copyright (c) 2015, STMicroelectronics * All rights reserved. @@ -27,7 +26,7 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ******************************************************************************* - */ + */ #ifndef MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H @@ -35,20 +34,7 @@ // CORE: 16 vectors = 64 bytes from 0x00 to 0x3F // MCU Peripherals: 82 vectors = 328 bytes from 0x40 to 0x187 // Total: 98 vectors = 392 bytes (0x188) to be reserved in RAM -#define NVIC_NUM_VECTORS 98 -#define NVIC_USER_IRQ_OFFSET 16 - -#include "cmsis.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +#define NVIC_NUM_VECTORS 98 +#define NVIC_RAM_VECTOR_ADDRESS 0x10000000 // Vectors positioned at start of SRAM2 #endif diff --git a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L486xG/device/cmsis_nvic.c b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L486xG/device/cmsis_nvic.c deleted file mode 100644 index a8a6a487a54..00000000000 --- a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L486xG/device/cmsis_nvic.c +++ /dev/null @@ -1,55 +0,0 @@ -/* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors - ******************************************************************************* - * Copyright (c) 2015, STMicroelectronics - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "cmsis_nvic.h" - -#define NVIC_RAM_VECTOR_ADDRESS (0x10000000) // Vectors positioned at start of SRAM2 -#define NVIC_FLASH_VECTOR_ADDRESS (0x08000000) // Initial vector position in flash - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { - uint32_t *vectors = (uint32_t *)SCB->VTOR; - uint32_t i; - - // Copy and switch to dynamic vectors if the first time called - if (SCB->VTOR == NVIC_FLASH_VECTOR_ADDRESS) { - uint32_t *old_vectors = vectors; - vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS; - for (i=0; iVTOR = (uint32_t)NVIC_RAM_VECTOR_ADDRESS; - } - vectors[IRQn + NVIC_USER_IRQ_OFFSET] = vector; -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) { - uint32_t *vectors = (uint32_t*)SCB->VTOR; - return vectors[IRQn + NVIC_USER_IRQ_OFFSET]; -} diff --git a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L486xG/device/cmsis_nvic.h b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L486xG/device/cmsis_nvic.h index 2af8d33e214..abb7956a000 100644 --- a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L486xG/device/cmsis_nvic.h +++ b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L486xG/device/cmsis_nvic.h @@ -1,5 +1,4 @@ /* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors ******************************************************************************* * Copyright (c) 2015, STMicroelectronics * All rights reserved. @@ -27,7 +26,7 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ******************************************************************************* - */ + */ #ifndef MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H @@ -35,20 +34,7 @@ // CORE: 16 vectors = 64 bytes from 0x00 to 0x3F // MCU Peripherals: 82 vectors = 328 bytes from 0x40 to 0x187 // Total: 98 vectors = 392 bytes (0x188) to be reserved in RAM -#define NVIC_NUM_VECTORS 98 -#define NVIC_USER_IRQ_OFFSET 16 - -#include "cmsis.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +#define NVIC_NUM_VECTORS 98 +#define NVIC_RAM_VECTOR_ADDRESS 0x10000000 // Vectors positioned at start of SRAM2 #endif diff --git a/targets/TARGET_Silicon_Labs/TARGET_EFM32/common/cmsis_nvic.c b/targets/TARGET_Silicon_Labs/TARGET_EFM32/common/cmsis_nvic.c deleted file mode 100644 index b238daa7437..00000000000 --- a/targets/TARGET_Silicon_Labs/TARGET_EFM32/common/cmsis_nvic.c +++ /dev/null @@ -1,47 +0,0 @@ -/* mbed Microcontroller Library - cmsis_nvic for EFM32 - * Copyright (c) 2011 ARM Limited. All rights reserved. - * - * CMSIS-style functionality to support dynamic vectors - */ -#include "cmsis_nvic.h" - -#if (defined (__GNUC__) && (!defined(__CC_ARM))) -extern uint32_t __start_vector_table__; // Dynamic vector positioning in GCC -#endif - -#define NVIC_RAM_VECTOR_ADDRESS (0x20000000) // Vectors positioned at start of RAM -#define NVIC_FLASH_VECTOR_ADDRESS (0x0) // Initial vector position in flash - -void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { - uint32_t *vectors = (uint32_t*)SCB->VTOR; - uint32_t i; - - // Copy and switch to dynamic vectors if the first time called - // For GCC, use dynamic vector table placement since otherwise we run into an alignment conflict -#if (defined (__GNUC__) && (!defined(__CC_ARM))) - if (SCB->VTOR == NVIC_FLASH_VECTOR_ADDRESS) { - uint32_t *old_vectors = vectors; - vectors = (uint32_t*)(&__start_vector_table__); - for (i=0; iVTOR = (uint32_t)(&__start_vector_table__); - } - // Other compilers don't matter as much... -#else - if (SCB->VTOR == NVIC_FLASH_VECTOR_ADDRESS) { - uint32_t *old_vectors = vectors; - vectors = (uint32_t*)(NVIC_RAM_VECTOR_ADDRESS); - for (i=0; iVTOR = (uint32_t)(NVIC_RAM_VECTOR_ADDRESS); - } -#endif - vectors[IRQn + 16] = vector; -} - -uint32_t __NVIC_GetVector(IRQn_Type IRQn) { - uint32_t *vectors = (uint32_t*)SCB->VTOR; - return vectors[IRQn + 16]; -} diff --git a/targets/TARGET_Silicon_Labs/TARGET_EFM32/common/cmsis_nvic.h b/targets/TARGET_Silicon_Labs/TARGET_EFM32/common/cmsis_nvic.h index e2fc226fdc5..bb4841e9006 100644 --- a/targets/TARGET_Silicon_Labs/TARGET_EFM32/common/cmsis_nvic.h +++ b/targets/TARGET_Silicon_Labs/TARGET_EFM32/common/cmsis_nvic.h @@ -1,31 +1,18 @@ /* mbed Microcontroller Library - cmsis_nvic * Copyright (c) 2009-2011 ARM Limited. All rights reserved. - * - * CMSIS-style functionality to support dynamic vectors - */ + */ #ifndef MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H -#include "cmsis.h" +#define NVIC_NUM_VECTORS (16 + EXT_IRQ_COUNT) // CORE + MCU Peripherals -#define NVIC_NUM_VECTORS (16 + EXT_IRQ_COUNT) // CORE + MCU Peripherals -#define NVIC_USER_IRQ_OFFSET 16 - -#if __CORTEX_M == 0 -#define __NVIC_SetVector NVIC_SetVector -#define __NVIC_GetVector NVIC_GetVector -#endif - -#ifdef __cplusplus -extern "C" { +/* For GCC, use dynamic vector table placement since otherwise we run into an alignment conflict */ +#if (defined (__GNUC__) && (!defined(__CC_ARM))) +extern uint32_t __start_vector_table__; // Dynamic vector positioning in GCC +#define NVIC_RAM_VECTOR_ADDRESS (&__start_vector_table__) +#else +#define NVIC_RAM_VECTOR_ADDRESS 0x20000000 // Vectors positioned at start of RAM #endif -void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t __NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif - -#endif +#endif /* MBED_CMSIS_NVIC_H */ diff --git a/targets/TARGET_WIZNET/TARGET_W7500x/device/cmsis_nvic.c b/targets/TARGET_WIZNET/TARGET_W7500x/device/cmsis_nvic.c deleted file mode 100644 index 71da98cf15b..00000000000 --- a/targets/TARGET_WIZNET/TARGET_W7500x/device/cmsis_nvic.c +++ /dev/null @@ -1,47 +0,0 @@ -/* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors - ******************************************************************************* - * Copyright (c) 2014, STMicroelectronics - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "cmsis_nvic.h" - -#define NVIC_RAM_VECTOR_ADDRESS (0x20000000) // Vectors positioned at start of RAM -#define NVIC_FLASH_VECTOR_ADDRESS (0x00000000) // Initial vector position in flash - - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { - static volatile uint32_t *vectors = (uint32_t *)NVIC_RAM_VECTOR_ADDRESS; - - vectors[IRQn + 16] = vector; -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) { - uint32_t *vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS; - // Return the vector - return vectors[IRQn + 16]; -} diff --git a/targets/TARGET_WIZNET/TARGET_W7500x/device/cmsis_nvic.h b/targets/TARGET_WIZNET/TARGET_W7500x/device/cmsis_nvic.h index 3d1e0ed80f1..a3b2a5606a7 100644 --- a/targets/TARGET_WIZNET/TARGET_W7500x/device/cmsis_nvic.h +++ b/targets/TARGET_WIZNET/TARGET_W7500x/device/cmsis_nvic.h @@ -32,20 +32,7 @@ #ifndef MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H -#define NVIC_NUM_VECTORS 41 -#define NVIC_USER_IRQ_OFFSET 16 - -#include "cmsis.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +#define NVIC_NUM_VECTORS 41 +#define NVIC_RAM_VECTOR_ADDRESS (0x20000000) // Vectors positioned at start of RAM #endif diff --git a/targets/TARGET_ublox/TARGET_HI2110/device/cmsis_nvic.c b/targets/TARGET_ublox/TARGET_HI2110/device/cmsis_nvic.c deleted file mode 100644 index 86531fc09d1..00000000000 --- a/targets/TARGET_ublox/TARGET_HI2110/device/cmsis_nvic.c +++ /dev/null @@ -1,50 +0,0 @@ -/* mbed Microcontroller Library - * CMSIS-style functionality to support dynamic vectors - ******************************************************************************* - * Copyright (c) 2011 ARM Limited. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of ARM Limited nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include "cmsis_nvic.h" - -#define NVIC_RAM_VECTOR_ADDRESS (0x01000000) // Location of vectors in RAM -#define NVIC_FLASH_VECTOR_ADDRESS (0x0) // Initial vector position in flash - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { - // Space for dynamic vectors, initialised to allocate in R/W - static volatile uint32_t* vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS; - - // Set the vector - vectors[IRQn + 16] = vector; -} - -uint32_t NVIC_GetVector(IRQn_Type IRQn) { - // We can always read vectors at 0x0, as the addresses are remapped - uint32_t *vectors = (uint32_t*)0; - - // Return the vector - return vectors[IRQn + 16]; -} diff --git a/targets/TARGET_ublox/TARGET_HI2110/device/cmsis_nvic.h b/targets/TARGET_ublox/TARGET_HI2110/device/cmsis_nvic.h index 46ee73e063d..76ae74e1ecc 100644 --- a/targets/TARGET_ublox/TARGET_HI2110/device/cmsis_nvic.h +++ b/targets/TARGET_ublox/TARGET_HI2110/device/cmsis_nvic.h @@ -18,21 +18,7 @@ #ifndef MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H -#define NVIC_NUM_VECTORS (16 + 32) // CORE + MCU Peripherals -#define NVIC_USER_IRQ_OFFSET 16 - -#include "cmsis.h" - - -#ifdef __cplusplus -extern "C" { -#endif - -void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); -uint32_t NVIC_GetVector(IRQn_Type IRQn); - -#ifdef __cplusplus -} -#endif +#define NVIC_NUM_VECTORS (16 + 32) // CORE + MCU Peripherals +#define NVIC_RAM_VECTOR_ADDRESS (0x01000000) // Location of vectors in RAM #endif From b793a3fb89cd45def09826c8f89a9c729029dd2d Mon Sep 17 00:00:00 2001 From: Bartek Szatkowski Date: Mon, 15 May 2017 09:55:45 -0500 Subject: [PATCH 09/24] Update codebase for CMSIS5/RTX5 Update all of mbed-os to use RTX5. --- TESTS/mbedmicro-rtos-mbed/mutex/main.cpp | 2 +- TESTS/mbedmicro-rtos-mbed/threads/main.cpp | 4 +- events/equeue/equeue_platform.h | 2 +- features/FEATURE_BLE/ble/services/iBeacon.h | 2 +- .../arm_hal_interrupt.c | 20 +- .../arm_hal_timer.cpp | 28 +- .../ns_event_loop.c | 60 +- .../arch/TARGET_Freescale/k64f_emac.c | 13 +- .../lwip-eth/arch/TARGET_NXP/lpc17_emac.c | 28 +- .../lwip-eth/arch/TARGET_STM/stm32xx_emac.c | 2 +- .../lwip-sys/arch/lwip_sys_arch.c | 154 +++-- .../lwip-interface/lwip-sys/arch/sys_arch.h | 49 +- .../FEATURE_LWIP/lwip-interface/lwipopts.h | 2 +- .../source/greentea_metrics.cpp | 55 +- .../NanostackRfPhyNcs36510.cpp | 41 +- features/netsocket/TCPSocket.cpp | 10 +- features/netsocket/UDPSocket.cpp | 10 +- platform/SingletonPtr.h | 6 +- platform/mbed_retarget.cpp | 92 +-- platform/mbed_sdk_boot.c | 89 +++ platform/mbed_stats.c | 61 +- rtos/Mail.h | 52 +- rtos/MemoryPool.h | 47 +- rtos/Mutex.cpp | 26 +- rtos/Mutex.h | 22 +- rtos/Queue.h | 65 +- rtos/RtosTimer.cpp | 20 +- rtos/RtosTimer.h | 18 +- rtos/Semaphore.cpp | 36 +- rtos/Semaphore.h | 27 +- rtos/Thread.cpp | 280 ++++---- rtos/Thread.h | 121 ++-- rtos/mbed_boot.c | 637 ++++++++++++++++++ rtos/mbed_rtos1_types.h | 27 + rtos/mbed_rtos_storage.h | 52 ++ rtos/rtos.h | 3 + .../TESTS/memory/heap_and_stack/main.cpp | 0 rtos/rtx2/mbed_rtx_conf.h | 54 ++ rtos/rtx2/mbed_rtx_handlers.c | 38 ++ targets/TARGET_ARM_SSG/mbed_rtx.h | 3 - targets/TARGET_Freescale/mbed_rtx.h | 42 -- targets/TARGET_Maxim/mbed_rtx.h | 18 - targets/TARGET_NORDIC/TARGET_NRF5/us_ticker.c | 277 +++----- targets/TARGET_NORDIC/mbed_rtx.h | 6 - targets/TARGET_NUVOTON/mbed_rtx.h | 8 +- targets/TARGET_NXP/mbed_rtx.h | 28 - targets/TARGET_ONSEMI/mbed_rtx.h | 3 - targets/TARGET_STM/mbed_rtx.h | 129 ---- targets/TARGET_Silicon_Labs/mbed_rtx.h | 16 +- targets/TARGET_ublox/mbed_rtx.h | 3 - 50 files changed, 1678 insertions(+), 1110 deletions(-) create mode 100644 platform/mbed_sdk_boot.c create mode 100644 rtos/mbed_boot.c create mode 100644 rtos/mbed_rtos1_types.h create mode 100644 rtos/mbed_rtos_storage.h rename rtos/{rtx => rtx2}/TARGET_CORTEX_M/TESTS/memory/heap_and_stack/main.cpp (100%) create mode 100644 rtos/rtx2/mbed_rtx_conf.h create mode 100644 rtos/rtx2/mbed_rtx_handlers.c diff --git a/TESTS/mbedmicro-rtos-mbed/mutex/main.cpp b/TESTS/mbedmicro-rtos-mbed/mutex/main.cpp index 507197499e9..a53c45527c0 100644 --- a/TESTS/mbedmicro-rtos-mbed/mutex/main.cpp +++ b/TESTS/mbedmicro-rtos-mbed/mutex/main.cpp @@ -142,7 +142,7 @@ void test_dual_thread_lock_lock_thread(Mutex *mutex) uint32_t start = us_ticker_read(); osStatus stat = mutex->lock(TEST_HALF_SEC_MS); - TEST_ASSERT_EQUAL(stat, osEventTimeout); + TEST_ASSERT_EQUAL(stat, osErrorTimeout); TEST_ASSERT_UINT32_WITHIN(TEST_ONE_MS_US, TEST_HALF_SEC_US, us_ticker_read() - start); } diff --git a/TESTS/mbedmicro-rtos-mbed/threads/main.cpp b/TESTS/mbedmicro-rtos-mbed/threads/main.cpp index 0f98d6621f7..c6d52084e62 100644 --- a/TESTS/mbedmicro-rtos-mbed/threads/main.cpp +++ b/TESTS/mbedmicro-rtos-mbed/threads/main.cpp @@ -61,11 +61,13 @@ void self_terminate(Thread *self) { // Tests that spawn tasks in different configurations template void test_single_thread() { + const char tname[] = "Single Thread"; counter_t counter(0); - Thread thread(osPriorityNormal, THREAD_STACK_SIZE, NULL); + Thread thread(osPriorityNormal, THREAD_STACK_SIZE, NULL, tname); thread.start(callback(F, &counter)); thread.join(); TEST_ASSERT_EQUAL(counter, 1); + TEST_ASSERT_EQUAL(strcmp(tname, thread.get_name()), 0); } template diff --git a/events/equeue/equeue_platform.h b/events/equeue/equeue_platform.h index 8b7c4f735d5..7bb058cd560 100644 --- a/events/equeue/equeue_platform.h +++ b/events/equeue/equeue_platform.h @@ -112,7 +112,7 @@ typedef struct equeue_sema { bool signal; } equeue_sema_t; #elif defined(EQUEUE_PLATFORM_MBED) && defined(MBED_CONF_RTOS_PRESENT) -typedef unsigned equeue_sema_t[8]; +typedef unsigned equeue_sema_t[9]; #elif defined(EQUEUE_PLATFORM_MBED) typedef volatile int equeue_sema_t; #endif diff --git a/features/FEATURE_BLE/ble/services/iBeacon.h b/features/FEATURE_BLE/ble/services/iBeacon.h index 95f8d12af72..0bdaf4dc657 100644 --- a/features/FEATURE_BLE/ble/services/iBeacon.h +++ b/features/FEATURE_BLE/ble/services/iBeacon.h @@ -16,7 +16,7 @@ #ifndef __BLE_IBEACON_H__ #define __BLE_IBEACON_H__ -#include "core_cmInstr.h" +#include "cmsis_compiler.h" #include "ble/BLE.h" /** diff --git a/features/FEATURE_COMMON_PAL/nanostack-hal-mbed-cmsis-rtos/arm_hal_interrupt.c b/features/FEATURE_COMMON_PAL/nanostack-hal-mbed-cmsis-rtos/arm_hal_interrupt.c index ff4a509c3fe..21ce05a2939 100644 --- a/features/FEATURE_COMMON_PAL/nanostack-hal-mbed-cmsis-rtos/arm_hal_interrupt.c +++ b/features/FEATURE_COMMON_PAL/nanostack-hal-mbed-cmsis-rtos/arm_hal_interrupt.c @@ -4,22 +4,30 @@ #include "arm_hal_interrupt.h" #include "arm_hal_interrupt_private.h" -#include "cmsis_os.h" - +#include "cmsis_os2.h" +#include "mbed_rtos_storage.h" +#include static uint8_t sys_irq_disable_counter; -static osMutexDef(critical); -static osMutexId critical_mutex_id; +static mbed_rtos_storage_mutex_t critical_mutex; +static const osMutexAttr_t critical_mutex_attr = { + .name = "critical_mutex", + .attr_bits = osMutexRecursive, + .cb_mem = &critical_mutex, + .cb_size = sizeof critical_mutex, +}; +static osMutexId_t critical_mutex_id; void platform_critical_init(void) { - critical_mutex_id = osMutexCreate(osMutex(critical)); + critical_mutex_id = osMutexNew(&critical_mutex_attr); + MBED_ASSERT(critical_mutex_id); } void platform_enter_critical(void) { - osMutexWait(critical_mutex_id, osWaitForever); + osMutexAcquire(critical_mutex_id, osWaitForever); sys_irq_disable_counter++; } diff --git a/features/FEATURE_COMMON_PAL/nanostack-hal-mbed-cmsis-rtos/arm_hal_timer.cpp b/features/FEATURE_COMMON_PAL/nanostack-hal-mbed-cmsis-rtos/arm_hal_timer.cpp index bac1b5430a8..4ab6f718f39 100644 --- a/features/FEATURE_COMMON_PAL/nanostack-hal-mbed-cmsis-rtos/arm_hal_timer.cpp +++ b/features/FEATURE_COMMON_PAL/nanostack-hal-mbed-cmsis-rtos/arm_hal_timer.cpp @@ -4,24 +4,27 @@ // Include before mbed.h to properly get UINT*_C() #include "ns_types.h" - -#include "cmsis_os.h" #include "mbed.h" - +#include "cmsis_os2.h" +#include "rtx_os.h" #include "platform/arm_hal_timer.h" #include "platform/arm_hal_interrupt.h" +#include -static osThreadId timer_thread_id; +static osThreadId_t timer_thread_id; +static uint64_t timer_thread_stk[2048]; +static osRtxThread_t timer_thread_tcb; static Timer timer; static Timeout timeout; static uint32_t due; static void (*arm_hal_callback)(void); -static void timer_thread(const void *) +static void timer_thread(void *arg) { + (void)arg; for (;;) { - osSignalWait(1, osWaitForever); + osThreadFlagsWait(1, osFlagsWaitAny, osWaitForever); // !!! We don't do our own enter/exit critical - we rely on callback // doing it (ns_timer_interrupt_handler does) //platform_enter_critical(); @@ -33,8 +36,14 @@ static void timer_thread(const void *) // Called once at boot void platform_timer_enable(void) { - static osThreadDef(timer_thread, osPriorityRealtime, /*1,*/ 2*1024); - timer_thread_id = osThreadCreate(osThread(timer_thread), NULL); + static osThreadAttr_t timer_thread_attr = {0}; + timer_thread_attr.stack_mem = &timer_thread_stk[0]; + timer_thread_attr.cb_mem = &timer_thread_tcb; + timer_thread_attr.stack_size = sizeof(timer_thread_stk); + timer_thread_attr.cb_size = sizeof(timer_thread_tcb); + timer_thread_attr.priority = osPriorityRealtime; + timer_thread_id = osThreadNew(timer_thread, NULL, &timer_thread_attr); + MBED_ASSERT(timer_thread_id != NULL); timer.start(); } @@ -53,8 +62,7 @@ void platform_timer_set_cb(void (*new_fp)(void)) static void timer_callback(void) { due = 0; - osSignalSet(timer_thread_id, 1); - //callback(); + osThreadFlagsSet(timer_thread_id, 1); } // This is called from inside platform_enter_critical - IRQs can't happen diff --git a/features/FEATURE_COMMON_PAL/nanostack-hal-mbed-cmsis-rtos/ns_event_loop.c b/features/FEATURE_COMMON_PAL/nanostack-hal-mbed-cmsis-rtos/ns_event_loop.c index a2267e5230c..01d5675e0ed 100644 --- a/features/FEATURE_COMMON_PAL/nanostack-hal-mbed-cmsis-rtos/ns_event_loop.c +++ b/features/FEATURE_COMMON_PAL/nanostack-hal-mbed-cmsis-rtos/ns_event_loop.c @@ -2,8 +2,10 @@ * Copyright (c) 2016 ARM Limited, All Rights Reserved */ +#include #include "cmsis.h" -#include "cmsis_os.h" +#include "cmsis_os2.h" +#include "mbed_rtos_storage.h" #include "ns_trace.h" #include "eventOS_scheduler.h" @@ -12,21 +14,32 @@ #define TRACE_GROUP "evlp" -static void event_loop_thread(const void *arg); - -// 1K should be enough - it's what the SAM4E port uses... -// What happened to the instances parameter? -static osThreadDef(event_loop_thread, osPriorityNormal, /*1,*/ MBED_CONF_NANOSTACK_HAL_EVENT_LOOP_THREAD_STACK_SIZE); -static osMutexDef(event); - -static osThreadId event_thread_id; -static osMutexId event_mutex_id; -static osThreadId event_mutex_owner_id = NULL; +static void event_loop_thread(void *arg); + +static uint64_t event_thread_stk[MBED_CONF_NANOSTACK_HAL_EVENT_LOOP_THREAD_STACK_SIZE/8]; +static mbed_rtos_storage_thread_t event_thread_tcb; +static const osThreadAttr_t event_thread_attr = { + .priority = osPriorityNormal, + .stack_mem = &event_thread_stk[0], + .stack_size = sizeof event_thread_stk, + .cb_mem = &event_thread_tcb, + .cb_size = sizeof event_thread_tcb, +}; +static osThreadId_t event_thread_id; +static mbed_rtos_storage_mutex_t event_mutex; +static const osMutexAttr_t event_mutex_attr = { + .name = "event_mutex", + .attr_bits = osMutexRecursive, + .cb_mem = &event_mutex, + .cb_size = sizeof event_mutex, +}; +static osMutexId_t event_mutex_id; +static osThreadId_t event_mutex_owner_id = NULL; static uint32_t owner_count = 0; void eventOS_scheduler_mutex_wait(void) { - osMutexWait(event_mutex_id, osWaitForever); + osMutexAcquire(event_mutex_id, osWaitForever); if (0 == owner_count) { event_mutex_owner_id = osThreadGetId(); } @@ -52,7 +65,7 @@ void eventOS_scheduler_signal(void) // XXX why does signal set lock if called with irqs disabled? //__enable_irq(); //tr_debug("signal %p", (void*)event_thread_id); - osSignalSet(event_thread_id, 1); + osThreadFlagsSet(event_thread_id, 1); //tr_debug("signalled %p", (void*)event_thread_id); } @@ -60,29 +73,26 @@ void eventOS_scheduler_idle(void) { //tr_debug("idle"); eventOS_scheduler_mutex_release(); - osSignalWait(1, osWaitForever); + osThreadFlagsWait(1, 0, osWaitForever); eventOS_scheduler_mutex_wait(); } -static void event_loop_thread(const void *arg) +static void event_loop_thread(void *arg) { - //tr_debug("event_loop_thread create"); - osSignalWait(2, osWaitForever); - + (void)arg; eventOS_scheduler_mutex_wait(); - tr_debug("event_loop_thread"); - - // Run does not return - it calls eventOS_scheduler_idle when it's, er, idle - eventOS_scheduler_run(); + eventOS_scheduler_run(); //Does not return } void ns_event_loop_thread_create(void) { - event_mutex_id = osMutexCreate(osMutex(event)); - event_thread_id = osThreadCreate(osThread(event_loop_thread), NULL); + event_mutex_id = osMutexNew(&event_mutex_attr); + MBED_ASSERT(event_mutex_id != NULL); + + event_thread_id = osThreadNew(event_loop_thread, NULL, &event_thread_attr); + MBED_ASSERT(event_thread_id != NULL); } void ns_event_loop_thread_start(void) { - osSignalSet(event_thread_id, 2); } diff --git a/features/FEATURE_LWIP/lwip-interface/lwip-eth/arch/TARGET_Freescale/k64f_emac.c b/features/FEATURE_LWIP/lwip-interface/lwip-eth/arch/TARGET_Freescale/k64f_emac.c index 3afa22d1a6b..9291363852b 100644 --- a/features/FEATURE_LWIP/lwip-interface/lwip-eth/arch/TARGET_Freescale/k64f_emac.c +++ b/features/FEATURE_LWIP/lwip-interface/lwip-eth/arch/TARGET_Freescale/k64f_emac.c @@ -532,8 +532,8 @@ static err_t k64f_low_level_output(struct netif *netif, struct pbuf *p) } /* Check if a descriptor is available for the transfer. */ - int32_t count = osSemaphoreWait(k64f_enet->xTXDCountSem.id, 0); - if (count < 1) + osStatus_t stat = osSemaphoreAcquire(k64f_enet->xTXDCountSem.id, 0); + if (stat != osOK) return ERR_BUF; /* Get exclusive access */ @@ -697,11 +697,10 @@ err_t eth_arch_enetif_init(struct netif *netif) netif->linkoutput = k64f_low_level_output; /* CMSIS-RTOS, start tasks */ -#ifdef CMSIS_OS_RTX - memset(k64f_enetdata.xTXDCountSem.data, 0, sizeof(k64f_enetdata.xTXDCountSem.data)); - k64f_enetdata.xTXDCountSem.def.semaphore = k64f_enetdata.xTXDCountSem.data; -#endif - k64f_enetdata.xTXDCountSem.id = osSemaphoreCreate(&k64f_enetdata.xTXDCountSem.def, ENET_TX_RING_LEN); + memset(&k64f_enetdata.xTXDCountSem.data, 0, sizeof(k64f_enetdata.xTXDCountSem.data)); + k64f_enetdata.xTXDCountSem.attr.cb_mem = &k64f_enetdata.xTXDCountSem.data; + k64f_enetdata.xTXDCountSem.attr.cb_size = sizeof(k64f_enetdata.xTXDCountSem.data); + k64f_enetdata.xTXDCountSem.id = osSemaphoreNew(ENET_TX_RING_LEN, ENET_TX_RING_LEN, &k64f_enetdata.xTXDCountSem.attr); LWIP_ASSERT("xTXDCountSem creation error", (k64f_enetdata.xTXDCountSem.id != NULL)); diff --git a/features/FEATURE_LWIP/lwip-interface/lwip-eth/arch/TARGET_NXP/lpc17_emac.c b/features/FEATURE_LWIP/lwip-interface/lwip-eth/arch/TARGET_NXP/lpc17_emac.c index 9fa203df68f..91515c43cc9 100644 --- a/features/FEATURE_LWIP/lwip-interface/lwip-eth/arch/TARGET_NXP/lpc17_emac.c +++ b/features/FEATURE_LWIP/lwip-interface/lwip-eth/arch/TARGET_NXP/lpc17_emac.c @@ -70,6 +70,7 @@ * the same. */ #define RX_PRIORITY (osPriorityNormal) #define TX_PRIORITY (osPriorityNormal) +#define PHY_PRIORITY (osPriorityNormal) /** \brief Debug output formatter lock define * @@ -603,7 +604,7 @@ static err_t lpc_low_level_output(struct netif *netif, struct pbuf *p) /* THIS WILL BLOCK UNTIL THERE ARE ENOUGH DESCRIPTORS AVAILABLE */ while (dn > lpc_tx_ready(netif)) #if NO_SYS == 0 - osSemaphoreWait(lpc_enetif->xTXDCountSem.id, osWaitForever); + osSemaphoreAcquire(lpc_enetif->xTXDCountSem.id, osWaitForever); #else osDelay(1); #endif @@ -685,7 +686,7 @@ void LPC17xxEthernetHandler(void) if (ints & RXINTGROUP) { /* RX group interrupt(s): Give signal to wakeup RX receive task.*/ - osSignalSet(lpc_enetdata.RxThread->id, RX_SIGNAL); + osThreadFlagsSet(lpc_enetdata.RxThread->id, RX_SIGNAL); } if (ints & TXINTGROUP) { @@ -711,7 +712,7 @@ static void packet_rx(void* pvParameters) { while (1) { /* Wait for receive task to wakeup */ - osSignalWait(RX_SIGNAL, osWaitForever); + osThreadFlagsWait(RX_SIGNAL, 0, osWaitForever); /* Process packets until all empty */ while (LPC_EMAC->RxConsumeIndex != LPC_EMAC->RxProduceIndex) @@ -942,10 +943,13 @@ err_t lpc_etharp_output_ipv6(struct netif *netif, struct pbuf *q, #if NO_SYS == 0 /* periodic PHY status update */ -void phy_update(void const *nif) { - lpc_phy_sts_sm((struct netif*)nif); +void phy_update(void *nif) { + while (true) { + lpc_phy_sts_sm((struct netif*)nif); + osDelay(250); + } } -osTimerDef(phy_update, phy_update); + #endif /** @@ -1017,11 +1021,10 @@ err_t eth_arch_enetif_init(struct netif *netif) /* CMSIS-RTOS, start tasks */ #if NO_SYS == 0 -#ifdef CMSIS_OS_RTX - memset(lpc_enetdata.xTXDCountSem.data, 0, sizeof(lpc_enetdata.xTXDCountSem.data)); - lpc_enetdata.xTXDCountSem.def.semaphore = lpc_enetdata.xTXDCountSem.data; -#endif - lpc_enetdata.xTXDCountSem.id = osSemaphoreCreate(&lpc_enetdata.xTXDCountSem.def, LPC_NUM_BUFF_TXDESCS); + memset(&lpc_enetdata.xTXDCountSem.data, 0, sizeof(lpc_enetdata.xTXDCountSem.data)); + lpc_enetdata.xTXDCountSem.attr.cb_mem = &lpc_enetdata.xTXDCountSem.data; + lpc_enetdata.xTXDCountSem.attr.cb_size = sizeof(lpc_enetdata.xTXDCountSem.data); + lpc_enetdata.xTXDCountSem.id = osSemaphoreNew(LPC_NUM_BUFF_TXDESCS, LPC_NUM_BUFF_TXDESCS, &lpc_enetdata.xTXDCountSem.attr); LWIP_ASSERT("xTXDCountSem creation error", (lpc_enetdata.xTXDCountSem.id != NULL)); err = sys_mutex_new(&lpc_enetdata.TXLockMutex); @@ -1037,8 +1040,7 @@ err_t eth_arch_enetif_init(struct netif *netif) sys_thread_new("txclean_thread", packet_tx, netif->state, DEFAULT_THREAD_STACKSIZE, TX_PRIORITY); /* periodic PHY status update */ - osTimerId phy_timer = osTimerCreate(osTimer(phy_update), osTimerPeriodic, (void *)netif); - osTimerStart(phy_timer, 250); + sys_thread_new("phy_thread", phy_update, netif, DEFAULT_THREAD_STACKSIZE, TX_PRIORITY); #endif return ERR_OK; diff --git a/features/FEATURE_LWIP/lwip-interface/lwip-eth/arch/TARGET_STM/stm32xx_emac.c b/features/FEATURE_LWIP/lwip-interface/lwip-eth/arch/TARGET_STM/stm32xx_emac.c index 4e230228aae..de1bd17f695 100644 --- a/features/FEATURE_LWIP/lwip-interface/lwip-eth/arch/TARGET_STM/stm32xx_emac.c +++ b/features/FEATURE_LWIP/lwip-interface/lwip-eth/arch/TARGET_STM/stm32xx_emac.c @@ -4,7 +4,7 @@ #include "lwip/tcpip.h" #include "lwip/ethip6.h" #include -#include "cmsis_os.h" +#include "cmsis_os2.h" #include "mbed_interface.h" #define RECV_TASK_PRI (osPriorityHigh) diff --git a/features/FEATURE_LWIP/lwip-interface/lwip-sys/arch/lwip_sys_arch.c b/features/FEATURE_LWIP/lwip-interface/lwip-sys/arch/lwip_sys_arch.c index 4ec57613d3c..d02fe9321f5 100644 --- a/features/FEATURE_LWIP/lwip-interface/lwip-sys/arch/lwip_sys_arch.c +++ b/features/FEATURE_LWIP/lwip-interface/lwip-sys/arch/lwip_sys_arch.c @@ -21,6 +21,7 @@ #include "mbed_error.h" #include "mbed_interface.h" #include "us_ticker_api.h" +#include "mbed_rtos_storage.h" /* lwIP includes. */ #include "lwip/opt.h" @@ -124,14 +125,21 @@ u32_t sys_now(void) { err_t sys_mbox_new(sys_mbox_t *mbox, int queue_sz) { if (queue_sz > MB_SIZE) error("sys_mbox_new size error\n"); - -#ifdef CMSIS_OS_RTX + + mbox->post_idx = 0; + mbox->fetch_idx = 0; memset(mbox->queue, 0, sizeof(mbox->queue)); - mbox->def.pool = mbox->queue; - mbox->def.queue_sz = queue_sz; -#endif - mbox->id = osMessageCreate(&mbox->def, NULL); - return (mbox->id == NULL) ? (ERR_MEM) : (ERR_OK); + + memset(&mbox->data, 0, sizeof(mbox->data)); + mbox->attr.cb_mem = &mbox->data; + mbox->attr.cb_size = sizeof(mbox->data); + mbox->id = osEventFlagsNew(&mbox->attr); + if (mbox->id == NULL) + error("sys_mbox_new create error\n"); + + osEventFlagsSet(mbox->id, SYS_MBOX_POST_EVENT); + + return ERR_OK; } /*---------------------------------------------------------------------------* @@ -145,8 +153,7 @@ err_t sys_mbox_new(sys_mbox_t *mbox, int queue_sz) { * sys_mbox_t *mbox -- Handle of mailbox *---------------------------------------------------------------------------*/ void sys_mbox_free(sys_mbox_t *mbox) { - osEvent event = osMessageGet(mbox->id, 0); - if (event.status == osEventMessage) + if (mbox->post_idx != mbox->fetch_idx) error("sys_mbox_free error\n"); } @@ -160,8 +167,19 @@ void sys_mbox_free(sys_mbox_t *mbox) { * void *msg -- Pointer to data to post *---------------------------------------------------------------------------*/ void sys_mbox_post(sys_mbox_t *mbox, void *msg) { - if (osMessagePut(mbox->id, (uint32_t)msg, osWaitForever) != osOK) - error("sys_mbox_post error\n"); + osEventFlagsWait(mbox->id, SYS_MBOX_POST_EVENT, + osFlagsWaitAny | osFlagsNoClear, osWaitForever); + + int state = osKernelLock(); + + mbox->queue[mbox->post_idx % MB_SIZE] = msg; + mbox->post_idx += 1; + + osEventFlagsSet(mbox->id, SYS_MBOX_FETCH_EVENT); + if (mbox->post_idx - mbox->fetch_idx == MB_SIZE-1) + osEventFlagsClear(mbox->id, SYS_MBOX_POST_EVENT); + + osKernelRestoreLock(state); } /*---------------------------------------------------------------------------* @@ -178,8 +196,22 @@ void sys_mbox_post(sys_mbox_t *mbox, void *msg) { * if not. *---------------------------------------------------------------------------*/ err_t sys_mbox_trypost(sys_mbox_t *mbox, void *msg) { - osStatus status = osMessagePut(mbox->id, (uint32_t)msg, 0); - return (status == osOK) ? (ERR_OK) : (ERR_MEM); + uint32_t flags = osEventFlagsWait(mbox->id, SYS_MBOX_POST_EVENT, + osFlagsWaitAny | osFlagsNoClear, 0); + if ((flags & osFlagsError) || !(flags & SYS_MBOX_POST_EVENT)) + return ERR_MEM; + + int state = osKernelLock(); + + mbox->queue[mbox->post_idx % MB_SIZE] = msg; + mbox->post_idx += 1; + + osEventFlagsSet(mbox->id, SYS_MBOX_FETCH_EVENT); + if (mbox->post_idx - mbox->fetch_idx == MB_SIZE-1) + osEventFlagsClear(mbox->id, SYS_MBOX_POST_EVENT); + + osKernelRestoreLock(state); + return ERR_OK; } /*---------------------------------------------------------------------------* @@ -208,14 +240,23 @@ err_t sys_mbox_trypost(sys_mbox_t *mbox, void *msg) { * of milliseconds until received. *---------------------------------------------------------------------------*/ u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout) { - u32_t start = us_ticker_read(); - - osEvent event = osMessageGet(mbox->id, (timeout != 0)?(timeout):(osWaitForever)); - if (event.status != osEventMessage) + uint32_t start = us_ticker_read(); + uint32_t flags = osEventFlagsWait(mbox->id, SYS_MBOX_FETCH_EVENT, + osFlagsWaitAny | osFlagsNoClear, (timeout ? timeout : osWaitForever)); + if ((flags & osFlagsError) || !(flags & SYS_MBOX_FETCH_EVENT)) return SYS_ARCH_TIMEOUT; - - *msg = (void *)event.value.v; - + + int state = osKernelLock(); + + if (msg) + *msg = mbox->queue[mbox->fetch_idx % MB_SIZE]; + mbox->fetch_idx += 1; + + osEventFlagsSet(mbox->id, SYS_MBOX_POST_EVENT); + if (mbox->post_idx == mbox->fetch_idx) + osEventFlagsClear(mbox->id, SYS_MBOX_FETCH_EVENT); + + osKernelRestoreLock(state); return (us_ticker_read() - start) / 1000; } @@ -234,12 +275,22 @@ u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout) { * return ERR_OK. *---------------------------------------------------------------------------*/ u32_t sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg) { - osEvent event = osMessageGet(mbox->id, 0); - if (event.status != osEventMessage) + uint32_t flags = osEventFlagsWait(mbox->id, SYS_MBOX_FETCH_EVENT, + osFlagsWaitAny | osFlagsNoClear, 0); + if ((flags & osFlagsError) || !(flags & SYS_MBOX_FETCH_EVENT)) return SYS_MBOX_EMPTY; - - *msg = (void *)event.value.v; - + + int state = osKernelLock(); + + if (msg) + *msg = mbox->queue[mbox->fetch_idx % MB_SIZE]; + mbox->fetch_idx += 1; + + osEventFlagsSet(mbox->id, SYS_MBOX_POST_EVENT); + if (mbox->post_idx == mbox->fetch_idx) + osEventFlagsClear(mbox->id, SYS_MBOX_FETCH_EVENT); + + osKernelRestoreLock(state); return ERR_OK; } @@ -257,11 +308,10 @@ u32_t sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg) { * err_t -- ERR_OK if semaphore created *---------------------------------------------------------------------------*/ err_t sys_sem_new(sys_sem_t *sem, u8_t count) { -#ifdef CMSIS_OS_RTX - memset(sem->data, 0, sizeof(uint32_t)*2); - sem->def.semaphore = sem->data; -#endif - sem->id = osSemaphoreCreate(&sem->def, count); + memset(&sem->data, 0, sizeof(sem->data)); + sem->attr.cb_mem = &sem->data; + sem->attr.cb_size = sizeof(sem->data); + sem->id = osSemaphoreNew(UINT16_MAX, count, &sem->attr); if (sem->id == NULL) error("sys_sem_new create error\n"); @@ -294,7 +344,7 @@ err_t sys_sem_new(sys_sem_t *sem, u8_t count) { u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout) { u32_t start = us_ticker_read(); - if (osSemaphoreWait(sem->id, (timeout != 0)?(timeout):(osWaitForever)) < 1) + if (osSemaphoreAcquire(sem->id, (timeout != 0)?(timeout):(osWaitForever)) != osOK) return SYS_ARCH_TIMEOUT; return (us_ticker_read() - start) / 1000; @@ -327,15 +377,10 @@ void sys_sem_free(sys_sem_t *sem) {} * @param mutex pointer to the mutex to create * @return a new mutex */ err_t sys_mutex_new(sys_mutex_t *mutex) { -#ifdef CMSIS_OS_RTX -#if defined(__MBED_CMSIS_RTOS_CA9) || defined(__MBED_CMSIS_RTOS_CM) - memset(mutex->data, 0, sizeof(int32_t)*4); -#else - memset(mutex->data, 0, sizeof(int32_t)*3); -#endif - mutex->def.mutex = mutex->data; -#endif - mutex->id = osMutexCreate(&mutex->def); + memset(&mutex->data, 0, sizeof(mutex->data)); + mutex->attr.cb_mem = &mutex->data; + mutex->attr.cb_size = sizeof(mutex->data); + mutex->id = osMutexNew(&mutex->attr); if (mutex->id == NULL) return ERR_MEM; @@ -345,7 +390,7 @@ err_t sys_mutex_new(sys_mutex_t *mutex) { /** Lock a mutex * @param mutex the mutex to lock */ void sys_mutex_lock(sys_mutex_t *mutex) { - if (osMutexWait(mutex->id, osWaitForever) != osOK) + if (osMutexAcquire(mutex->id, osWaitForever) != osOK) error("sys_mutex_lock error\n"); } @@ -366,12 +411,15 @@ void sys_mutex_free(sys_mutex_t *mutex) {} * Description: * Initialize sys arch *---------------------------------------------------------------------------*/ -osMutexId lwip_sys_mutex; -osMutexDef(lwip_sys_mutex); +osMutexId_t lwip_sys_mutex; +osMutexAttr_t lwip_sys_mutex_attr; +mbed_rtos_storage_mutex_t lwip_sys_mutex_data; void sys_init(void) { us_ticker_read(); // Init sys tick - lwip_sys_mutex = osMutexCreate(osMutex(lwip_sys_mutex)); + lwip_sys_mutex_attr.cb_mem = &lwip_sys_mutex_data; + lwip_sys_mutex_attr.cb_size = sizeof(lwip_sys_mutex_data); + lwip_sys_mutex = osMutexNew(&lwip_sys_mutex_attr); if (lwip_sys_mutex == NULL) error("sys_init error\n"); } @@ -408,7 +456,7 @@ u32_t sys_jiffies(void) { * sys_prot_t -- Previous protection level (not used here) *---------------------------------------------------------------------------*/ sys_prot_t sys_arch_protect(void) { - if (osMutexWait(lwip_sys_mutex, osWaitForever) != osOK) + if (osMutexAcquire(lwip_sys_mutex, osWaitForever) != osOK) error("sys_arch_protect error\n"); return (sys_prot_t) 1; } @@ -469,16 +517,16 @@ sys_thread_t sys_thread_new(const char *pcName, sys_thread_t t = (sys_thread_t)&thread_pool[thread_pool_index]; thread_pool_index++; -#ifdef CMSIS_OS_RTX - t->def.pthread = (os_pthread)thread; - t->def.tpriority = (osPriority)priority; - t->def.stacksize = stacksize; - t->def.stack_pointer = (uint32_t*)malloc(stacksize); - if (t->def.stack_pointer == NULL) { + t->attr.name = pcName; + t->attr.priority = (osPriority_t)priority; + t->attr.cb_size = sizeof(t->data); + t->attr.cb_mem = &t->data; + t->attr.stack_size = stacksize; + t->attr.stack_mem = malloc(stacksize); + if (t->attr.stack_mem == NULL) { error("Error allocating the stack memory"); } -#endif - t->id = osThreadCreate(&t->def, arg); + t->id = osThreadNew((osThreadFunc_t)thread, arg, &t->attr); if (t->id == NULL) error("sys_thread_new create error\n"); diff --git a/features/FEATURE_LWIP/lwip-interface/lwip-sys/arch/sys_arch.h b/features/FEATURE_LWIP/lwip-interface/lwip-sys/arch/sys_arch.h index 57766ac2494..57fb5cf60cf 100644 --- a/features/FEATURE_LWIP/lwip-interface/lwip-sys/arch/sys_arch.h +++ b/features/FEATURE_LWIP/lwip-interface/lwip-sys/arch/sys_arch.h @@ -19,19 +19,18 @@ #define __ARCH_SYS_ARCH_H__ #include "lwip/opt.h" +#include "mbed_rtos_storage.h" extern u8_t lwip_ram_heap[]; #if NO_SYS == 0 -#include "cmsis_os.h" +#include "cmsis_os2.h" // === SEMAPHORE === typedef struct { - osSemaphoreId id; - osSemaphoreDef_t def; -#ifdef CMSIS_OS_RTX - uint32_t data[2]; -#endif + osSemaphoreId_t id; + osSemaphoreAttr_t attr; + mbed_rtos_storage_semaphore_t data; } sys_sem_t; #define sys_sem_valid(x) (((*x).id == NULL) ? 0 : 1) @@ -39,31 +38,30 @@ typedef struct { // === MUTEX === typedef struct { - osMutexId id; - osMutexDef_t def; -#ifdef CMSIS_OS_RTX -#if defined(__MBED_CMSIS_RTOS_CA9) || defined(__MBED_CMSIS_RTOS_CM) - int32_t data[4]; -#else - int32_t data[3]; -#endif -#endif + osMutexId_t id; + osMutexAttr_t attr; + mbed_rtos_storage_mutex_t data; } sys_mutex_t; // === MAIL BOX === #define MB_SIZE 8 typedef struct { - osMessageQId id; - osMessageQDef_t def; -#ifdef CMSIS_OS_RTX - uint32_t queue[4+MB_SIZE]; /* The +4 is required for RTX OS_MCB overhead. */ -#endif + osEventFlagsId_t id; + osEventFlagsAttr_t attr; + mbed_rtos_storage_event_flags_t data; + + uint8_t post_idx; + uint8_t fetch_idx; + void* queue[MB_SIZE]; } sys_mbox_t; +#define SYS_MBOX_FETCH_EVENT 0x1 +#define SYS_MBOX_POST_EVENT 0x2 + #define SYS_MBOX_NULL ((uint32_t) NULL) -#define sys_mbox_valid(x) (((*x).id == NULL) ? 0 : 1 ) -#define sys_mbox_set_invalid(x) ( (*x).id = NULL ) +#define sys_mbox_valid(x) (((*x).id == NULL) ? 0 : 1) +#define sys_mbox_set_invalid(x) ( (*x).id = NULL) #if ((DEFAULT_RAW_RECVMBOX_SIZE) > (MB_SIZE)) || \ ((DEFAULT_UDP_RECVMBOX_SIZE) > (MB_SIZE)) || \ @@ -75,13 +73,14 @@ typedef struct { // === THREAD === typedef struct { - osThreadId id; - osThreadDef_t def; + osThreadId_t id; + osThreadAttr_t attr; + mbed_rtos_storage_thread_t data; } sys_thread_data_t; typedef sys_thread_data_t* sys_thread_t; #define SYS_THREAD_POOL_N 6 -#define SYS_DEFAULT_THREAD_STACK_DEPTH DEFAULT_STACK_SIZE +#define SYS_DEFAULT_THREAD_STACK_DEPTH OS_STACK_SIZE // === PROTECTION === typedef int sys_prot_t; diff --git a/features/FEATURE_LWIP/lwip-interface/lwipopts.h b/features/FEATURE_LWIP/lwip-interface/lwipopts.h index e28b008e33b..2a9c574aa18 100644 --- a/features/FEATURE_LWIP/lwip-interface/lwipopts.h +++ b/features/FEATURE_LWIP/lwip-interface/lwipopts.h @@ -68,7 +68,7 @@ //#define LWIP_DEBUG #if NO_SYS == 0 -#include "cmsis_os.h" +#include "cmsis_os2.h" #define SYS_LIGHTWEIGHT_PROT 1 diff --git a/features/frameworks/greentea-client/source/greentea_metrics.cpp b/features/frameworks/greentea-client/source/greentea_metrics.cpp index 31e9ec3592d..faa943fe338 100644 --- a/features/frameworks/greentea-client/source/greentea_metrics.cpp +++ b/features/frameworks/greentea-client/source/greentea_metrics.cpp @@ -18,7 +18,7 @@ #include "mbed.h" #include "rtos.h" #include "mbed_stats.h" -#include "cmsis_os.h" +#include "cmsis_os2.h" #include "greentea-client/test_env.h" #include "greentea-client/greentea_metrics.h" #include "SingletonPtr.h" @@ -28,7 +28,6 @@ typedef struct { uint32_t entry; - uint32_t arg; uint32_t stack_size; uint32_t max_stack; } thread_info_t; @@ -43,8 +42,8 @@ static SingletonPtr > queue; static void send_heap_info(void); #if defined(MBED_STACK_STATS_ENABLED) && MBED_STACK_STATS_ENABLED static void send_stack_info(void); -static void on_thread_terminate(osThreadId id); -static void enqeue_thread_info(osThreadId id); +static void on_thread_terminate(osThreadId_t id); +static void enqeue_thread_info(osThreadId_t id); static void deque_and_print_thread_info(void); // sprintf uses a lot of stack so use these instead @@ -86,22 +85,21 @@ MBED_UNUSED static void send_stack_info() } // Print info for all other threads - osThreadEnumId enum_id = _osThreadsEnumStart(); - while (true) { - osThreadId thread_id = _osThreadEnumNext(enum_id); - if (NULL == thread_id) { - // End of enumeration - break; - } - enqeue_thread_info(thread_id); + uint32_t thread_n = osThreadGetCount(); + osThreadId_t *threads = new osThreadId_t[thread_n]; + thread_n = osThreadEnumerate(threads, thread_n); + + for(size_t i = 0; i < thread_n; i++) { + enqeue_thread_info(threads[i]); deque_and_print_thread_info(); } - _osThreadEnumFree(enum_id); + + delete[] threads; mutex->unlock(); } -MBED_UNUSED static void on_thread_terminate(osThreadId id) +MBED_UNUSED static void on_thread_terminate(osThreadId_t id) { mutex->lock(); @@ -116,30 +114,13 @@ MBED_UNUSED static void on_thread_terminate(osThreadId id) mutex->unlock(); } -static void enqeue_thread_info(osThreadId id) +static void enqeue_thread_info(osThreadId_t id) { - osEvent info; thread_info_t thread_info = {}; - info = _osThreadGetInfo(id, osThreadInfoEntry); - if (info.status != osOK) { - return; - } - thread_info.entry = (uint32_t)info.value.p; - info = _osThreadGetInfo(id, osThreadInfoArg); - if (info.status != osOK) { - return; - } - thread_info.arg = (uint32_t)info.value.p; - info = _osThreadGetInfo(id, osThreadInfoStackSize); - if (info.status != osOK) { - return; - } - thread_info.stack_size = (uint32_t)info.value.v; - info = _osThreadGetInfo(id, osThreadInfoStackMax); - if (info.status != osOK) { - return; - } - thread_info.max_stack = (uint32_t)info.value.v; + + thread_info.entry = (uint32_t)id; + thread_info.stack_size = osThreadGetStackSize(id); + thread_info.max_stack = thread_info.stack_size - osThreadGetStackSpace(id); queue->push(thread_info); } @@ -151,8 +132,6 @@ static void deque_and_print_thread_info() uint32_t pos = 0; buf[pos++] = '\"'; pos += print_hex(buf + pos, thread_info.entry); - buf[pos++] = '-'; - pos += print_hex(buf + pos, thread_info.arg); buf[pos++] = '\"'; buf[pos++] = ','; pos += print_dec(buf + pos, thread_info.max_stack); diff --git a/features/nanostack/FEATURE_NANOSTACK/targets/TARGET_NCS36510/NanostackRfPhyNcs36510.cpp b/features/nanostack/FEATURE_NANOSTACK/targets/TARGET_NCS36510/NanostackRfPhyNcs36510.cpp index 596756b5a12..027895c9efa 100644 --- a/features/nanostack/FEATURE_NANOSTACK/targets/TARGET_NCS36510/NanostackRfPhyNcs36510.cpp +++ b/features/nanostack/FEATURE_NANOSTACK/targets/TARGET_NCS36510/NanostackRfPhyNcs36510.cpp @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - +#include "mbed.h" #include "ns_types.h" #include #include "common_functions.h" @@ -29,24 +29,12 @@ extern "C" { #include "TARGET_NCS36510/rfAna.h" } -#include "cmsis_os.h" - -#ifdef MBED_CONF_RTOS_PRESENT - -#include "cmsis.h" -#include "cmsis_os.h" - #define RF_THREAD_STACK_SIZE 1024 #define SIGNAL_COUNT_RADIO 1 -static void rf_thread_loop(const void *arg); - -static osThreadDef(rf_thread_loop, osPriorityRealtime, /*1,*/ RF_THREAD_STACK_SIZE); - -static osThreadId rf_thread_id; - -#endif +static void rf_thread_loop(); +Thread rf_thread(osPriorityRealtime, RF_THREAD_STACK_SIZE); #define PHY_MTU_SIZE 127 #define CRC_LENGTH 0 @@ -166,16 +154,13 @@ static phy_device_driver_s device_driver = { NULL }; -#ifdef MBED_CONF_RTOS_PRESENT -static void rf_thread_loop(const void *arg) +static void rf_thread_loop() { for (;;) { - osEvent event = osSignalWait(0, osWaitForever); - if (event.status != osEventSignal) { - continue; - } + int32_t event = rf_thread.signal_wait(0); + platform_enter_critical(); - if (event.value.signals & SIGNAL_COUNT_RADIO) { + if (event & SIGNAL_COUNT_RADIO) { handle_IRQ_events(); } platform_exit_critical(); @@ -183,7 +168,6 @@ static void rf_thread_loop(const void *arg) NVIC_EnableIRQ(MacHw_IRQn); } } -#endif static int8_t rf_device_register(void) { @@ -467,9 +451,8 @@ static void rf_mac_hw_init(void) { for (lutIndex=0;lutIndex<96;lutIndex++) { *(pMatchReg + lutIndex) = 0xFF; } -#ifdef MBED_CONF_RTOS_PRESENT - rf_thread_id = osThreadCreate(osThread(rf_thread_loop), NULL); -#endif + osStatus_t status = rf_thread.start(mbed::callback(rf_thread_loop)); + MBED_ASSERT(status == osOK); /** Clear and enable MAC IRQ at task level, when scheduler is on. */ NVIC_ClearPendingIRQ(MacHw_IRQn); @@ -819,12 +802,8 @@ static void rf_mac_tx_interrupt(void) */ extern "C" void fIrqMacHwHandler(void) { -#ifdef MBED_CONF_RTOS_PRESENT NVIC_DisableIRQ(MacHw_IRQn); - osSignalSet(rf_thread_id, SIGNAL_COUNT_RADIO); -#else - handle_IRQ_events(); -#endif + rf_thread.signal_set(SIGNAL_COUNT_RADIO); } static void handle_IRQ_events(void) diff --git a/features/netsocket/TCPSocket.cpp b/features/netsocket/TCPSocket.cpp index 52c9519a0d0..da88eb2460d 100644 --- a/features/netsocket/TCPSocket.cpp +++ b/features/netsocket/TCPSocket.cpp @@ -188,14 +188,8 @@ nsapi_size_or_error_t TCPSocket::recv(void *data, nsapi_size_t size) void TCPSocket::event() { - int32_t wcount = _write_sem.wait(0); - if (wcount <= 1) { - _write_sem.release(); - } - int32_t rcount = _read_sem.wait(0); - if (rcount <= 1) { - _read_sem.release(); - } + _write_sem.release(); + _read_sem.release(); _pending += 1; if (_callback && _pending == 1) { diff --git a/features/netsocket/UDPSocket.cpp b/features/netsocket/UDPSocket.cpp index 08f270cdd8c..8baae204ba5 100644 --- a/features/netsocket/UDPSocket.cpp +++ b/features/netsocket/UDPSocket.cpp @@ -123,14 +123,8 @@ nsapi_size_or_error_t UDPSocket::recvfrom(SocketAddress *address, void *buffer, void UDPSocket::event() { - int32_t wcount = _write_sem.wait(0); - if (wcount <= 1) { - _write_sem.release(); - } - int32_t rcount = _read_sem.wait(0); - if (rcount <= 1) { - _read_sem.release(); - } + _write_sem.release(); + _read_sem.release(); _pending += 1; if (_callback && _pending == 1) { diff --git a/platform/SingletonPtr.h b/platform/SingletonPtr.h index e576b2632d0..369d6dbe2f1 100644 --- a/platform/SingletonPtr.h +++ b/platform/SingletonPtr.h @@ -23,11 +23,11 @@ #include #include "platform/mbed_assert.h" #ifdef MBED_CONF_RTOS_PRESENT -#include "cmsis_os.h" +#include "cmsis_os2.h" #endif #ifdef MBED_CONF_RTOS_PRESENT -extern osMutexId singleton_mutex_id; +extern osMutexId_t singleton_mutex_id; #endif /** Lock the singleton mutex @@ -39,7 +39,7 @@ extern osMutexId singleton_mutex_id; inline static void singleton_lock(void) { #ifdef MBED_CONF_RTOS_PRESENT - osMutexWait(singleton_mutex_id, osWaitForever); + osMutexAcquire(singleton_mutex_id, osWaitForever); #endif } diff --git a/platform/mbed_retarget.cpp b/platform/mbed_retarget.cpp index 33e02cbd6d3..51789776fe5 100644 --- a/platform/mbed_retarget.cpp +++ b/platform/mbed_retarget.cpp @@ -36,7 +36,6 @@ #include #include "platform/mbed_retarget.h" - #if defined(__ARMCC_VERSION) # include # define PREFIX(x) _sys##x @@ -76,7 +75,6 @@ extern const char __stdout_name[] = "/stdout"; extern const char __stderr_name[] = "/stderr"; #endif -// Heap limits - only used if set unsigned char *mbed_heap_start = 0; uint32_t mbed_heap_size = 0; @@ -157,10 +155,6 @@ static inline int openmode_to_posix(int openmode) { } #endif -extern "C" WEAK void mbed_sdk_init(void); -extern "C" WEAK void mbed_sdk_init(void) { -} - #if MBED_CONF_FILESYSTEM_PRESENT // Internally used file objects with managed memory on close class ManagedFile : public File { @@ -198,11 +192,6 @@ extern "C" FILEHANDLE PREFIX(_open)(const char* name, int openmode) { // Before version 5.03, we were using a patched version of microlib with proper names // This is the workaround that the microlib author suggested us static int n = 0; - static int mbed_sdk_inited = 0; - if (!mbed_sdk_inited) { - mbed_sdk_inited = 1; - mbed_sdk_init(); - } if (!std::strcmp(name, ":tt")) return n++; #else /* Use the posix convention that stdin,out,err are filehandles 0,1,2. @@ -684,79 +673,10 @@ extern "C" WEAK void __cxa_pure_virtual(void) { #endif -#if defined(TOOLCHAIN_GCC) - -#ifdef FEATURE_UVISOR -#include "uvisor-lib/uvisor-lib.h" -#endif/* FEATURE_UVISOR */ - - -extern "C" WEAK void software_init_hook_rtos(void) -{ - // Do nothing by default. -} - -extern "C" void software_init_hook(void) -{ -#ifdef FEATURE_UVISOR - int return_code; - - return_code = uvisor_lib_init(); - if (return_code) { - mbed_die(); - } -#endif/* FEATURE_UVISOR */ - mbed_sdk_init(); - software_init_hook_rtos(); -} -#endif - -// **************************************************************************** -// mbed_main is a function that is called before main() -// mbed_sdk_init() is also a function that is called before main(), but unlike -// mbed_main(), it is not meant for user code, but for the SDK itself to perform -// initializations before main() is called. - -extern "C" WEAK void mbed_main(void); -extern "C" WEAK void mbed_main(void) { -} - -#if defined(TOOLCHAIN_ARM) -extern "C" int $Super$$main(void); - -extern "C" int $Sub$$main(void) { - mbed_main(); - return $Super$$main(); -} - -extern "C" void _platform_post_stackheap_init (void) { - mbed_sdk_init(); -} - -#elif defined(TOOLCHAIN_GCC) -extern "C" int __real_main(void); - -extern "C" int __wrap_main(void) { - mbed_main(); - return __real_main(); -} -#elif defined(TOOLCHAIN_IAR) -// IAR doesn't have the $Super/$Sub mechanism of armcc, nor something equivalent -// to ld's --wrap. It does have a --redirect, but that doesn't help, since redirecting -// 'main' to another symbol looses the original 'main' symbol. However, its startup -// code will call a function to setup argc and argv (__iar_argc_argv) if it is defined. -// Since mbed doesn't use argc/argv, we use this function to call our mbed_main. -extern "C" void __iar_argc_argv() { - mbed_main(); -} -#endif - // Provide implementation of _sbrk (low-level dynamic memory allocation // routine) for GCC_ARM which compares new heap pointer with MSP instead of // SP. This make it compatible with RTX RTOS thread stacks. #if defined(TOOLCHAIN_GCC_ARM) || defined(TOOLCHAIN_GCC_CR) -// Linker defined symbol used by _sbrk to indicate where heap should start. -extern "C" int __end__; #if defined(TARGET_CORTEX_A) extern "C" uint32_t __HeapLimit; @@ -777,6 +697,8 @@ extern "C" caddr_t _sbrk(int incr) { return (caddr_t) __wrap__sbrk(incr); } #else +// Linker defined symbol used by _sbrk to indicate where heap should start. +extern "C" uint32_t __end__; extern "C" caddr_t _sbrk(int incr) { static unsigned char* heap = (unsigned char*)&__end__; unsigned char* prev_heap = heap; @@ -897,7 +819,7 @@ namespace mbed { void mbed_set_unbuffered_stream(FILE *_file) { #if defined (__ICCARM__) char buf[2]; - std::setvbuf(_file,buf,_IONBF,NULL); + std::setvbuf(_file,buf,_IONBF,NULL); #else setbuf(_file, NULL); #endif @@ -911,11 +833,11 @@ int mbed_getc(FILE *_file){ _file->_Mode = (unsigned short)(_file->_Mode & ~ 0x1000);/* Unset read mode */ _file->_Rend = _file->_Wend; _file->_Next = _file->_Wend; - } + } return res; -#else +#else return std::fgetc(_file); -#endif +#endif } char* mbed_gets(char*s, int size, FILE *_file){ @@ -928,7 +850,7 @@ char* mbed_gets(char*s, int size, FILE *_file){ _file->_Next = _file->_Wend; } return str; -#else +#else return std::fgets(s,size,_file); #endif } diff --git a/platform/mbed_sdk_boot.c b/platform/mbed_sdk_boot.c new file mode 100644 index 00000000000..353be86354e --- /dev/null +++ b/platform/mbed_sdk_boot.c @@ -0,0 +1,89 @@ +/* mbed Microcontroller Library + * Copyright (c) 2017 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "mbed_toolchain.h" +#include +#include + +/* This startup is for mbed 2 baremetal. There is no config for RTOS for mbed 2, + * therefore we protect this file with MBED_CONF_RTOS_PRESENT + * Note: The new consolidated started for mbed OS is in rtos/mbed_boot code file. + */ +#if !defined(MBED_CONF_RTOS_PRESENT) + +/* mbed_main is a function that is called before main() + * mbed_sdk_init() is also a function that is called before main(), but unlike + * mbed_main(), it is not meant for user code, but for the SDK itself to perform + * initializations before main() is called. + */ +MBED_WEAK void mbed_main(void) +{ + +} + +/* This function can be implemented by the target to perform higher level target initialization + */ +MBED_WEAK void mbed_sdk_init(void) +{ + +} + +MBED_WEAK void software_init_hook_rtos() +{ + // Nothing by default +} + +/* Toolchain specific main code */ + +#if defined (__CC_ARM) + +int $Super$$main(void); + +int $Sub$$main(void) +{ + mbed_main(); + return $Super$$main(); +} + +void _platform_post_stackheap_init(void) +{ + mbed_sdk_init(); +} + +#elif defined (__GNUC__) + +extern int __real_main(void); + +__attribute__((naked)) void software_init_hook(void) +{ + mbed_sdk_init(); + software_init_hook_rtos(); +} + + +int __wrap_main(void) +{ + mbed_main(); + return __real_main(); +} + +#elif defined (__ICCARM__) + +// cmsis.S file implements the mbed SDK boot for IAR + +#endif + +#endif diff --git a/platform/mbed_stats.c b/platform/mbed_stats.c index 9c05b5a05dc..106394be42c 100644 --- a/platform/mbed_stats.c +++ b/platform/mbed_stats.c @@ -1,8 +1,10 @@ #include "mbed_stats.h" #include +#include +#include "mbed_assert.h" #if MBED_CONF_RTOS_PRESENT -#include "cmsis_os.h" +#include "cmsis_os2.h" #endif // note: mbed_stats_heap_get defined in mbed_alloc_wrappers.cpp @@ -12,24 +14,25 @@ void mbed_stats_stack_get(mbed_stats_stack_t *stats) memset(stats, 0, sizeof(mbed_stats_stack_t)); #if MBED_STACK_STATS_ENABLED && MBED_CONF_RTOS_PRESENT - osThreadEnumId enumid = _osThreadsEnumStart(); - osThreadId threadid; + uint32_t thread_n = osThreadGetCount(); + unsigned i; + osThreadId_t *threads; - while ((threadid = _osThreadEnumNext(enumid))) { - osEvent e; + threads = malloc(sizeof(osThreadId_t) * thread_n); + MBED_ASSERT(threads != NULL); - e = _osThreadGetInfo(threadid, osThreadInfoStackMax); - if (e.status == osOK) { - stats->max_size += (uint32_t)e.value.p; - } + osKernelLock(); + thread_n = osThreadEnumerate(threads, thread_n); - e = _osThreadGetInfo(threadid, osThreadInfoStackSize); - if (e.status == osOK) { - stats->reserved_size += (uint32_t)e.value.p; - } - - stats->stack_cnt += 1; + for(i = 0; i < thread_n; i++) { + uint32_t stack_size = osThreadGetStackSize(threads[i]); + stats->max_size += stack_size - osThreadGetStackSpace(threads[i]); + stats->reserved_size += stack_size; + stats->stack_cnt++; } + osKernelUnlock(); + + free(threads); #endif } @@ -39,26 +42,24 @@ size_t mbed_stats_stack_get_each(mbed_stats_stack_t *stats, size_t count) size_t i = 0; #if MBED_STACK_STATS_ENABLED && MBED_CONF_RTOS_PRESENT - osThreadEnumId enumid = _osThreadsEnumStart(); - osThreadId threadid; + osThreadId_t *threads; - while ((threadid = _osThreadEnumNext(enumid)) && i < count) { - osEvent e; + threads = malloc(sizeof(osThreadId_t) * count); + MBED_ASSERT(threads != NULL); - e = _osThreadGetInfo(threadid, osThreadInfoStackMax); - if (e.status == osOK) { - stats[i].max_size = (uint32_t)e.value.p; - } + osKernelLock(); + count = osThreadEnumerate(threads, count); - e = _osThreadGetInfo(threadid, osThreadInfoStackSize); - if (e.status == osOK) { - stats[i].reserved_size = (uint32_t)e.value.p; - } - - stats[i].thread_id = (uint32_t)threadid; + for(i = 0; i < count; i++) { + uint32_t stack_size = osThreadGetStackSize(threads[i]); + stats[i].max_size = stack_size - osThreadGetStackSpace(threads[i]); + stats[i].reserved_size = stack_size; + stats[i].thread_id = (uint32_t)threads[i]; stats[i].stack_cnt = 1; - i += 1; } + osKernelUnlock(); + + free(threads); #endif return i; diff --git a/rtos/Mail.h b/rtos/Mail.h index 6cbb7f4dcaa..5ac0469a052 100644 --- a/rtos/Mail.h +++ b/rtos/Mail.h @@ -1,5 +1,5 @@ /* mbed Microcontroller Library - * Copyright (c) 2006-2012 ARM Limited + * Copyright (c) 2006-2017 ARM Limited * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -25,7 +25,13 @@ #include #include -#include "cmsis_os.h" +#include "Queue.h" +#include "MemoryPool.h" +#include "cmsis_os2.h" +#include "rtx_lib.h" +#include "mbed_rtos1_types.h" + +using namespace rtos; namespace rtos { /** \addtogroup rtos */ @@ -35,32 +41,23 @@ namespace rtos { A mail is a memory block that is send to a thread or interrupt service routine. @tparam T data type of a single message element. @tparam queue_sz maximum number of messages in queue. + + @note + Memory considerations: The mail data store and control structures will be created on current thread's stack, + both for the mbed OS and underlying RTOS objects (static or dynamic RTOS memory pools are not being used). */ template class Mail { public: /** Create and Initialise Mail queue. */ - Mail() { - #ifdef CMSIS_OS_RTX - memset(_mail_q, 0, sizeof(_mail_q)); - _mail_p[0] = _mail_q; - - memset(_mail_m, 0, sizeof(_mail_m)); - _mail_p[1] = _mail_m; - - _mail_def.pool = _mail_p; - _mail_def.queue_sz = queue_sz; - _mail_def.item_sz = sizeof(T); - #endif - _mail_id = osMailCreate(&_mail_def, NULL); - } + Mail() { }; /** Allocate a memory block of type T @param millisec timeout value or 0 in case of no time-out. (default: 0). @return pointer to memory block that can be filled with mail or NULL in case error. */ T* alloc(uint32_t millisec=0) { - return (T*)osMailAlloc(_mail_id, millisec); + return _pool.alloc(); } /** Allocate a memory block of type T and set memory block to zero. @@ -68,7 +65,7 @@ class Mail { @return pointer to memory block that can be filled with mail or NULL in case error. */ T* calloc(uint32_t millisec=0) { - return (T*)osMailCAlloc(_mail_id, millisec); + return _pool.calloc(); } /** Put a mail in the queue. @@ -76,7 +73,7 @@ class Mail { @return status code that indicates the execution status of the function. */ osStatus put(T *mptr) { - return osMailPut(_mail_id, (void*)mptr); + return _queue.put(mptr); } /** Get a mail from a queue. @@ -84,7 +81,11 @@ class Mail { @return event that contains mail information or error code. */ osEvent get(uint32_t millisec=osWaitForever) { - return osMailGet(_mail_id, millisec); + osEvent evt = _queue.get(millisec); + if (evt.status == osEventMessage) { + evt.status = osEventMail; + } + return evt; } /** Free a memory block from a mail. @@ -92,17 +93,12 @@ class Mail { @return status code that indicates the execution status of the function. */ osStatus free(T *mptr) { - return osMailFree(_mail_id, (void*)mptr); + return _pool.free(mptr); } private: - osMailQId _mail_id; - osMailQDef_t _mail_def; -#ifdef CMSIS_OS_RTX - uint32_t _mail_q[4+(queue_sz)]; - uint32_t _mail_m[3+((sizeof(T)+3)/4)*(queue_sz)]; - void *_mail_p[2]; -#endif + Queue _queue; + MemoryPool _pool; }; } diff --git a/rtos/MemoryPool.h b/rtos/MemoryPool.h index aed4569f4c3..be8c2a3dbe4 100644 --- a/rtos/MemoryPool.h +++ b/rtos/MemoryPool.h @@ -25,7 +25,9 @@ #include #include -#include "cmsis_os.h" +#include "cmsis_os2.h" +#include "mbed_rtos1_types.h" +#include "mbed_rtos_storage.h" namespace rtos { /** \addtogroup rtos */ @@ -34,50 +36,57 @@ namespace rtos { /** Define and manage fixed-size memory pools of objects of a given type. @tparam T data type of a single object (element). @tparam queue_sz maximum number of objects (elements) in the memory pool. + + @note + Memory considerations: The memory pool data store and control structures will be created on current thread's stack, + both for the mbed OS and underlying RTOS objects (static or dynamic RTOS memory pools are not being used). */ template class MemoryPool { public: /** Create and Initialize a memory pool. */ MemoryPool() { - #ifdef CMSIS_OS_RTX - memset(_pool_m, 0, sizeof(_pool_m)); - _pool_def.pool = _pool_m; - - _pool_def.pool_sz = pool_sz; - _pool_def.item_sz = sizeof(T); - #endif - _pool_id = osPoolCreate(&_pool_def); + memset(_pool_mem, 0, sizeof(_pool_mem)); + memset(&_obj_mem, 0, sizeof(_obj_mem)); + _attr.mp_mem = _pool_mem; + _attr.mp_size = sizeof(_pool_mem); + _attr.cb_mem = &_obj_mem; + _attr.cb_size = sizeof(_obj_mem); + _id = osMemoryPoolNew(pool_sz, sizeof(T), &_attr); + MBED_ASSERT(_id); } /** Allocate a memory block of type T from a memory pool. @return address of the allocated memory block or NULL in case of no memory available. */ T* alloc(void) { - return (T*)osPoolAlloc(_pool_id); + return (T*)osMemoryPoolAlloc(_id, 0); } /** Allocate a memory block of type T from a memory pool and set memory block to zero. @return address of the allocated memory block or NULL in case of no memory available. */ T* calloc(void) { - return (T*)osPoolCAlloc(_pool_id); + T *item = (T*)osMemoryPoolAlloc(_id, 0); + if (item != NULL) { + memset(item, 0, sizeof(T)); + } + return item; } - /** Return an allocated memory block back to a specific memory pool. - @param address of the allocated memory block that is returned to the memory pool. + /** Free a memory block. + @param address of the allocated memory block to be freed. @return status code that indicates the execution status of the function. */ osStatus free(T *block) { - return osPoolFree(_pool_id, (void*)block); + return osMemoryPoolFree(_id, (void*)block); } private: - osPoolId _pool_id; - osPoolDef_t _pool_def; -#ifdef CMSIS_OS_RTX - uint32_t _pool_m[3+((sizeof(T)+3)/4)*(pool_sz)]; -#endif + osMemoryPoolId_t _id; + osMemoryPoolAttr_t _attr; + char _pool_mem[sizeof(T) * pool_sz]; + mbed_rtos_storage_mem_pool_t _obj_mem; }; } diff --git a/rtos/Mutex.cpp b/rtos/Mutex.cpp index 432e0a7ba22..b194d9a75ac 100644 --- a/rtos/Mutex.cpp +++ b/rtos/Mutex.cpp @@ -22,35 +22,35 @@ #include "rtos/Mutex.h" #include -#include "platform/mbed_error.h" +#include "mbed_error.h" +#include "mbed_assert.h" namespace rtos { Mutex::Mutex() { -#ifdef CMSIS_OS_RTX - memset(_mutex_data, 0, sizeof(_mutex_data)); - _osMutexDef.mutex = _mutex_data; -#endif - _osMutexId = osMutexCreate(&_osMutexDef); - if (_osMutexId == NULL) { - error("Error initializing the mutex object\n"); - } + memset(&_obj_mem, 0, sizeof(_obj_mem)); + memset(&_attr, 0, sizeof(_attr)); + _attr.cb_mem = &_obj_mem; + _attr.cb_size = sizeof(_obj_mem); + _attr.attr_bits = osMutexRecursive; + _id = osMutexNew(&_attr); + MBED_ASSERT(_id); } osStatus Mutex::lock(uint32_t millisec) { - return osMutexWait(_osMutexId, millisec); + return osMutexAcquire(_id, millisec); } bool Mutex::trylock() { - return (osMutexWait(_osMutexId, 0) == osOK); + return (osMutexAcquire(_id, 0) == osOK); } osStatus Mutex::unlock() { - return osMutexRelease(_osMutexId); + return osMutexRelease(_id); } Mutex::~Mutex() { - osMutexDelete(_osMutexId); + osMutexDelete(_id); } } diff --git a/rtos/Mutex.h b/rtos/Mutex.h index acddddf8b39..6cc78abd502 100644 --- a/rtos/Mutex.h +++ b/rtos/Mutex.h @@ -23,14 +23,20 @@ #define MUTEX_H #include -#include "cmsis_os.h" +#include "cmsis_os2.h" +#include "mbed_rtos1_types.h" +#include "mbed_rtos_storage.h" namespace rtos { /** \addtogroup rtos */ /** @{*/ -/** The Mutex class is used to synchronise the execution of threads. +/** The Mutex class is used to synchronize the execution of threads. This is for example used to protect access to a shared resource. + + @note + Memory considerations: The mutex control structures will be created on current thread's stack, both for the mbed OS + and underlying RTOS objects (static or dynamic RTOS memory pools are not being used). */ class Mutex { public: @@ -56,15 +62,9 @@ class Mutex { ~Mutex(); private: - osMutexId _osMutexId; - osMutexDef_t _osMutexDef; -#ifdef CMSIS_OS_RTX -#if defined(__MBED_CMSIS_RTOS_CA9) || defined(__MBED_CMSIS_RTOS_CM) - int32_t _mutex_data[4]; -#else - int32_t _mutex_data[3]; -#endif -#endif + osMutexId_t _id; + osMutexAttr_t _attr; + mbed_rtos_storage_mutex_t _obj_mem; }; } diff --git a/rtos/Queue.h b/rtos/Queue.h index 48e1c2d4b9e..f03caeb92b5 100644 --- a/rtos/Queue.h +++ b/rtos/Queue.h @@ -25,8 +25,10 @@ #include #include -#include "cmsis_os.h" +#include "cmsis_os2.h" +#include "mbed_rtos_storage.h" #include "platform/mbed_error.h" +#include "mbed_rtos1_types.h" namespace rtos { /** \addtogroup rtos */ @@ -37,30 +39,34 @@ namespace rtos { to a thread or interrupt service routine. @tparam T data type of a single message element. @tparam queue_sz maximum number of messages in queue. + + @note + Memory considerations: The queue control structures will be created on current thread's stack, both for the mbed OS + and underlying RTOS objects (static or dynamic RTOS memory pools are not being used). */ template class Queue { public: - /** Create and initialise a message Queue. */ + /** Create and initialize a message Queue. */ Queue() { - #ifdef CMSIS_OS_RTX - memset(_queue_q, 0, sizeof(_queue_q)); - _queue_def.pool = _queue_q; - _queue_def.queue_sz = queue_sz; - #endif - _queue_id = osMessageCreate(&_queue_def, NULL); - if (_queue_id == NULL) { - error("Error initialising the queue object\n"); - } + memset(&_obj_mem, 0, sizeof(_obj_mem)); + memset(&_attr, 0, sizeof(_attr)); + _attr.mq_mem = _queue_mem; + _attr.mq_size = sizeof(_queue_mem); + _attr.cb_mem = &_obj_mem; + _attr.cb_size = sizeof(_obj_mem); + _id = osMessageQueueNew(queue_sz, sizeof(T*), &_attr); + MBED_ASSERT(_id); } /** Put a message in a Queue. @param data message pointer. @param millisec timeout value or 0 in case of no time-out. (default: 0) + @param prio priority value or 0 in case of default. (default: 0) @return status code that indicates the execution status of the function. */ - osStatus put(T* data, uint32_t millisec=0) { - return osMessagePut(_queue_id, (uint32_t)data, millisec); + osStatus put(T* data, uint32_t millisec=0, uint8_t prio=0) { + return osMessageQueuePut(_id, &data, prio, millisec); } /** Get a message or Wait for a message from a Queue. @@ -68,15 +74,36 @@ class Queue { @return event information that includes the message and the status code. */ osEvent get(uint32_t millisec=osWaitForever) { - return osMessageGet(_queue_id, millisec); + osEvent event; + T *data = NULL; + osStatus_t res = osMessageQueueGet(_id, &data, NULL, millisec); + + switch (res) { + case osOK: + event.status = (osStatus)osEventMessage; + event.value.p = data; + break; + case osErrorResource: + event.status = osOK; + break; + case osErrorTimeout: + event.status = (osStatus)osEventTimeout; + break; + case osErrorParameter: + default: + event.status = osErrorParameter; + break; + } + event.def.message_id = _id; + + return event; } private: - osMessageQId _queue_id; - osMessageQDef_t _queue_def; -#ifdef CMSIS_OS_RTX - uint32_t _queue_q[4+(queue_sz)]; -#endif + osMessageQueueId_t _id; + osMessageQueueAttr_t _attr; + char _queue_mem[queue_sz * (sizeof(T*) + sizeof(mbed_rtos_storage_message_t))]; + mbed_rtos_storage_msg_queue_t _obj_mem; }; } diff --git a/rtos/RtosTimer.cpp b/rtos/RtosTimer.cpp index 6bfe36ea05a..acec84ed98c 100644 --- a/rtos/RtosTimer.cpp +++ b/rtos/RtosTimer.cpp @@ -24,32 +24,30 @@ #include #include "mbed.h" -#include "cmsis_os.h" #include "platform/mbed_error.h" namespace rtos { void RtosTimer::constructor(mbed::Callback func, os_timer_type type) { -#ifdef CMSIS_OS_RTX - _timer.ptimer = (void (*)(const void *))Callback::thunk; - - memset(_timer_data, 0, sizeof(_timer_data)); - _timer.timer = _timer_data; -#endif _function = func; - _timer_id = osTimerCreate(&_timer, type, &_function); + memset(&_obj_mem, 0, sizeof(_obj_mem)); + memset(&_attr, 0, sizeof(_attr)); + _attr.cb_mem = &_obj_mem; + _attr.cb_size = sizeof(_obj_mem); + _id = osTimerNew((void (*)(void *))Callback::thunk, type, &_function, &_attr); + MBED_ASSERT(_id); } osStatus RtosTimer::start(uint32_t millisec) { - return osTimerStart(_timer_id, millisec); + return osTimerStart(_id, millisec); } osStatus RtosTimer::stop(void) { - return osTimerStop(_timer_id); + return osTimerStop(_id); } RtosTimer::~RtosTimer() { - osTimerDelete(_timer_id); + osTimerDelete(_id); } } diff --git a/rtos/RtosTimer.h b/rtos/RtosTimer.h index 0e39661e7d7..901ebcab5c0 100644 --- a/rtos/RtosTimer.h +++ b/rtos/RtosTimer.h @@ -23,9 +23,11 @@ #define RTOS_TIMER_H #include -#include "cmsis_os.h" +#include "cmsis_os2.h" +#include "rtx_lib.h" #include "platform/Callback.h" #include "platform/mbed_toolchain.h" +#include "mbed_rtos1_types.h" namespace rtos { /** \addtogroup rtos */ @@ -72,6 +74,10 @@ namespace rtos { queue.cancel(blink_id); // stop after 5s } @endcode + + @note + Memory considerations: The timer control structures will be created on current thread's stack, both for the mbed OS + and underlying RTOS objects (static or dynamic RTOS memory pools are not being used). */ class RtosTimer { public: @@ -140,13 +146,11 @@ class RtosTimer { // Required to share definitions without // delegated constructors void constructor(mbed::Callback func, os_timer_type type); - + + osTimerId_t _id; + osTimerAttr_t _attr; + os_timer_t _obj_mem; mbed::Callback _function; - osTimerId _timer_id; - osTimerDef_t _timer; -#ifdef CMSIS_OS_RTX - uint32_t _timer_data[6]; -#endif }; } diff --git a/rtos/Semaphore.cpp b/rtos/Semaphore.cpp index a97a6705b22..4e2aa8b2ac0 100644 --- a/rtos/Semaphore.cpp +++ b/rtos/Semaphore.cpp @@ -20,29 +20,49 @@ * SOFTWARE. */ #include "rtos/Semaphore.h" +#include "platform/mbed_assert.h" #include namespace rtos { Semaphore::Semaphore(int32_t count) { -#ifdef CMSIS_OS_RTX - memset(_semaphore_data, 0, sizeof(_semaphore_data)); - _osSemaphoreDef.semaphore = _semaphore_data; -#endif - _osSemaphoreId = osSemaphoreCreate(&_osSemaphoreDef, count); + constructor(count, 1024); +} + +Semaphore::Semaphore(int32_t count, uint16_t max_count) { + constructor(count, max_count); +} + +void Semaphore::constructor(int32_t count, uint16_t max_count) { + memset(&_obj_mem, 0, sizeof(_obj_mem)); + memset(&_attr, 0, sizeof(_attr)); + _attr.cb_mem = &_obj_mem; + _attr.cb_size = sizeof(_obj_mem); + _id = osSemaphoreNew(max_count, count, &_attr); + MBED_ASSERT(_id != NULL); } int32_t Semaphore::wait(uint32_t millisec) { - return osSemaphoreWait(_osSemaphoreId, millisec); + osStatus_t stat = osSemaphoreAcquire(_id, millisec); + switch (stat) { + case osOK: + return osSemaphoreGetCount(_id) + 1; + case osErrorTimeout: + case osErrorResource: + return 0; + case osErrorParameter: + default: + return -1; + } } osStatus Semaphore::release(void) { - return osSemaphoreRelease(_osSemaphoreId); + return osSemaphoreRelease(_id); } Semaphore::~Semaphore() { - osSemaphoreDelete(_osSemaphoreId); + osSemaphoreDelete(_id); } } diff --git a/rtos/Semaphore.h b/rtos/Semaphore.h index d1709334429..03b4f411cfc 100644 --- a/rtos/Semaphore.h +++ b/rtos/Semaphore.h @@ -23,13 +23,20 @@ #define SEMAPHORE_H #include -#include "cmsis_os.h" +#include "cmsis_os2.h" +#include "mbed_rtos1_types.h" +#include "mbed_rtos_storage.h" namespace rtos { /** \addtogroup rtos */ /** @{*/ -/** The Semaphore class is used to manage and protect access to a set of shared resources. */ +/** The Semaphore class is used to manage and protect access to a set of shared resources. + * + * @note + * Memory considerations: The semaphore control structures will be created on current thread's stack, both for the mbed OS + * and underlying RTOS objects (static or dynamic RTOS memory pools are not being used). + */ class Semaphore { public: /** Create and Initialize a Semaphore object used for managing resources. @@ -37,6 +44,12 @@ class Semaphore { */ Semaphore(int32_t count=0); + /** Create and Initialize a Semaphore object used for managing resources. + @param count number of available resources + @param max_count maximum number of available resources + */ + Semaphore(int32_t count, uint16_t max_count); + /** Wait until a Semaphore resource becomes available. @param millisec timeout value or 0 in case of no time-out. (default: osWaitForever). @return number of available tokens, or -1 in case of incorrect parameters @@ -51,11 +64,11 @@ class Semaphore { ~Semaphore(); private: - osSemaphoreId _osSemaphoreId; - osSemaphoreDef_t _osSemaphoreDef; -#ifdef CMSIS_OS_RTX - uint32_t _semaphore_data[2]; -#endif + void constructor(int32_t count, uint16_t max_count); + + osSemaphoreId_t _id; + osSemaphoreAttr_t _attr; + mbed_rtos_storage_semaphore_t _obj_mem; }; } diff --git a/rtos/Thread.cpp b/rtos/Thread.cpp index 9969e096704..cb602c2e586 100644 --- a/rtos/Thread.cpp +++ b/rtos/Thread.cpp @@ -24,17 +24,10 @@ #include "mbed.h" #include "rtos/rtos_idle.h" -// rt_tid2ptcb is an internal function which we exposed to get TCB for thread id -#undef NULL //Workaround for conflicting macros in rt_TypeDef.h and stdio.h -#include "rt_TypeDef.h" - -extern "C" P_TCB rt_tid2ptcb(osThreadId thread_id); - - -static void (*terminate_hook)(osThreadId id) = 0; -extern "C" void thread_terminate_hook(osThreadId id) +static void (*terminate_hook)(osThreadId_t id) = 0; +extern "C" void thread_terminate_hook(osThreadId_t id) { - if (terminate_hook != (void (*)(osThreadId))NULL) { + if (terminate_hook != (void (*)(osThreadId_t))NULL) { terminate_hook(id); } } @@ -42,21 +35,21 @@ extern "C" void thread_terminate_hook(osThreadId id) namespace rtos { void Thread::constructor(osPriority priority, - uint32_t stack_size, unsigned char *stack_pointer) { + uint32_t stack_size, unsigned char *stack_mem, const char *name) { _tid = 0; + _dynamic_stack = (stack_mem == NULL); _finished = false; - _dynamic_stack = (stack_pointer == NULL); - -#if defined(__MBED_CMSIS_RTOS_CA9) || defined(__MBED_CMSIS_RTOS_CM) - _thread_def.tpriority = priority; - _thread_def.stacksize = stack_size; - _thread_def.stack_pointer = (uint32_t*)stack_pointer; -#endif + memset(&_obj_mem, 0, sizeof(_obj_mem)); + memset(&_attr, 0, sizeof(_attr)); + _attr.priority = priority; + _attr.stack_size = stack_size; + _attr.name = name; + _attr.stack_mem = (uint32_t*)stack_mem; } void Thread::constructor(Callback task, - osPriority priority, uint32_t stack_size, unsigned char *stack_pointer) { - constructor(priority, stack_size, stack_pointer); + osPriority priority, uint32_t stack_size, unsigned char *stack_mem, const char *name) { + constructor(priority, stack_size, stack_mem, name); switch (start(task)) { case osErrorResource: @@ -80,24 +73,25 @@ osStatus Thread::start(Callback task) { return osErrorParameter; } -#if defined(__MBED_CMSIS_RTOS_CA9) || defined(__MBED_CMSIS_RTOS_CM) - _thread_def.pthread = Thread::_thunk; - if (_thread_def.stack_pointer == NULL) { - _thread_def.stack_pointer = new uint32_t[_thread_def.stacksize/sizeof(uint32_t)]; - MBED_ASSERT(_thread_def.stack_pointer != NULL); + if (_attr.stack_mem == NULL) { + _attr.stack_mem = new uint32_t[_attr.stack_size/sizeof(uint32_t)]; + MBED_ASSERT(_attr.stack_mem != NULL); } //Fill the stack with a magic word for maximum usage checking - for (uint32_t i = 0; i < (_thread_def.stacksize / sizeof(uint32_t)); i++) { - _thread_def.stack_pointer[i] = 0xE25A2EA5; + for (uint32_t i = 0; i < (_attr.stack_size / sizeof(uint32_t)); i++) { + ((uint32_t *)_attr.stack_mem)[i] = 0xE25A2EA5; } -#endif + + memset(&_obj_mem, 0, sizeof(_obj_mem)); + _attr.cb_size = sizeof(_obj_mem); + _attr.cb_mem = &_obj_mem; _task = task; - _tid = osThreadCreate(&_thread_def, this); + _tid = osThreadNew(Thread::_thunk, this, &_attr); if (_tid == NULL) { if (_dynamic_stack) { - delete[] (_thread_def.stack_pointer); - _thread_def.stack_pointer = (uint32_t*)NULL; + delete[] (uint32_t *)(_attr.stack_mem); + _attr.stack_mem = (uint32_t*)NULL; } _mutex.unlock(); _join_sem.release(); @@ -109,27 +103,27 @@ osStatus Thread::start(Callback task) { } osStatus Thread::terminate() { - osStatus ret; + osStatus_t ret; _mutex.lock(); // Set the Thread's tid to NULL and // release the semaphore before terminating // since this thread could be terminating itself - osThreadId local_id = _tid; + osThreadId_t local_id = _tid; _join_sem.release(); - _tid = (osThreadId)NULL; + _tid = (osThreadId_t)NULL; _finished = true; + _mutex.unlock(); ret = osThreadTerminate(local_id); - _mutex.unlock(); return ret; } osStatus Thread::join() { int32_t ret = _join_sem.wait(); if (ret < 0) { - return osErrorOS; + return osError; } // The semaphore has been released so this thread is being @@ -145,7 +139,7 @@ osStatus Thread::join() { } osStatus Thread::set_priority(osPriority priority) { - osStatus ret; + osStatus_t ret; _mutex.lock(); ret = osThreadSetPriority(_tid, priority); @@ -155,7 +149,7 @@ osStatus Thread::set_priority(osPriority priority) { } osPriority Thread::get_priority() { - osPriority ret; + osPriority_t ret; _mutex.lock(); ret = osThreadGetPriority(_tid); @@ -164,176 +158,162 @@ osPriority Thread::get_priority() { return ret; } -int32_t Thread::signal_set(int32_t signals) { - // osSignalSet is thread safe as long as the underlying - // thread does not get terminated or return from main - return osSignalSet(_tid, signals); +int32_t Thread::signal_set(int32_t flags) { + return osThreadFlagsSet(_tid, flags); } -int32_t Thread::signal_clr(int32_t signals) { - // osSignalClear is thread safe as long as the underlying - // thread does not get terminated or return from main - return osSignalClear(_tid, signals); +int32_t Thread::signal_clr(int32_t flags) { + return osThreadFlagsClear(flags); } Thread::State Thread::get_state() { -#if !defined(__MBED_CMSIS_RTOS_CA9) && !defined(__MBED_CMSIS_RTOS_CM) -#ifdef CMSIS_OS_RTX - State status; + uint8_t state = osThreadTerminated; + _mutex.lock(); if (_tid != NULL) { - status = (State)_thread_def.tcb.state; - } else if (_finished) { - status = Deleted; - } else { - status = Inactive; + state = _obj_mem.state; } _mutex.unlock(); - return status; -#endif -#else - State status = Deleted; - _mutex.lock(); - if (_tid != NULL) { - status = (State)osThreadGetState(_tid); + State user_state; + + switch(state) { + case osThreadInactive: + user_state = Inactive; + break; + case osThreadReady: + user_state = Ready; + break; + case osThreadRunning: + user_state = Running; + break; + case osRtxThreadWaitingDelay: + user_state = WaitingDelay; + break; + case osRtxThreadWaitingJoin: + user_state = WaitingJoin; + break; + case osRtxThreadWaitingThreadFlags: + user_state = WaitingThreadFlag; + break; + case osRtxThreadWaitingEventFlags: + user_state = WaitingEventFlag; + break; + case osRtxThreadWaitingMutex: + user_state = WaitingMutex; + break; + case osRtxThreadWaitingSemaphore: + user_state = WaitingSemaphore; + break; + case osRtxThreadWaitingMemoryPool: + user_state = WaitingMemoryPool; + break; + case osRtxThreadWaitingMessageGet: + user_state = WaitingMessageGet; + break; + case osRtxThreadWaitingMessagePut: + user_state = WaitingMessagePut; + break; + case osThreadTerminated: + default: + user_state = Deleted; + break; } - _mutex.unlock(); - return status; -#endif + return user_state; } uint32_t Thread::stack_size() { -#ifndef __MBED_CMSIS_RTOS_CA9 -#if defined(CMSIS_OS_RTX) && !defined(__MBED_CMSIS_RTOS_CM) - uint32_t size = 0; - _mutex.lock(); - - if (_tid != NULL) { - size = _thread_def.tcb.priv_stack; - } - - _mutex.unlock(); - return size; -#else uint32_t size = 0; _mutex.lock(); if (_tid != NULL) { - P_TCB tcb = rt_tid2ptcb(_tid); - size = tcb->priv_stack; + os_thread_t *thread = (os_thread_t *)_tid; + size = thread->stack_size; } _mutex.unlock(); return size; -#endif -#else - return 0; -#endif } uint32_t Thread::free_stack() { -#ifndef __MBED_CMSIS_RTOS_CA9 -#if defined(CMSIS_OS_RTX) && !defined(__MBED_CMSIS_RTOS_CM) - uint32_t size = 0; - _mutex.lock(); - - if (_tid != NULL) { - uint32_t bottom = (uint32_t)_thread_def.tcb.stack; - size = _thread_def.tcb.tsk_stack - bottom; - } - - _mutex.unlock(); - return size; -#else uint32_t size = 0; _mutex.lock(); if (_tid != NULL) { - P_TCB tcb = rt_tid2ptcb(_tid); - uint32_t bottom = (uint32_t)tcb->stack; - size = tcb->tsk_stack - bottom; + os_thread_t *thread = (os_thread_t *)_tid; + size = (uint32_t)thread->stack_mem - thread->sp; } _mutex.unlock(); return size; -#endif -#else - return 0; -#endif } uint32_t Thread::used_stack() { -#ifndef __MBED_CMSIS_RTOS_CA9 -#if defined(CMSIS_OS_RTX) && !defined(__MBED_CMSIS_RTOS_CM) - uint32_t size = 0; - _mutex.lock(); - - if (_tid != NULL) { - uint32_t top = (uint32_t)_thread_def.tcb.stack + _thread_def.tcb.priv_stack; - size = top - _thread_def.tcb.tsk_stack; - } - - _mutex.unlock(); - return size; -#else uint32_t size = 0; _mutex.lock(); if (_tid != NULL) { - P_TCB tcb = rt_tid2ptcb(_tid); - uint32_t top = (uint32_t)tcb->stack + tcb->priv_stack; - size = top - tcb->tsk_stack; + os_thread_t *thread = (os_thread_t *)_tid; + size = ((uint32_t)thread->stack_mem + thread->stack_size) - thread->sp; } _mutex.unlock(); return size; -#endif -#else - return 0; -#endif } uint32_t Thread::max_stack() { -#ifndef __MBED_CMSIS_RTOS_CA9 -#if defined(CMSIS_OS_RTX) && !defined(__MBED_CMSIS_RTOS_CM) uint32_t size = 0; _mutex.lock(); if (_tid != NULL) { + os_thread_t *thread = (os_thread_t *)_tid; uint32_t high_mark = 0; - while (_thread_def.tcb.stack[high_mark] == 0xE25A2EA5) + while (((uint32_t *)(thread->stack_mem))[high_mark] == 0xE25A2EA5) high_mark++; - size = _thread_def.tcb.priv_stack - (high_mark * 4); + size = thread->stack_size - (high_mark * sizeof(uint32_t)); } _mutex.unlock(); return size; -#else - uint32_t size = 0; - _mutex.lock(); - - if (_tid != NULL) { - P_TCB tcb = rt_tid2ptcb(_tid); - uint32_t high_mark = 0; - while (tcb->stack[high_mark] == 0xE25A2EA5) - high_mark++; - size = tcb->priv_stack - (high_mark * 4); - } +} - _mutex.unlock(); - return size; -#endif -#else - return 0; -#endif +const char *Thread::get_name() { + return _attr.name; } osEvent Thread::signal_wait(int32_t signals, uint32_t millisec) { - return osSignalWait(signals, millisec); + uint32_t res; + osEvent evt; + uint32_t options = osFlagsWaitAll; + if (signals == 0) { + options = osFlagsWaitAny; + signals = 0x7FFFFFFF; + } + res = osThreadFlagsWait(signals, options, millisec); + if (res & osFlagsError) { + switch (res) { + case osFlagsErrorISR: + evt.status = osErrorISR; + break; + case osFlagsErrorResource: + evt.status = osOK; + break; + case osFlagsErrorTimeout: + evt.status = (osStatus)osEventTimeout; + break; + case osFlagsErrorParameter: + default: + evt.status = (osStatus)osErrorValue; + break; + } + } + evt.status = (osStatus)osEventSignal; + evt.value.signals = res; + + return evt; } osStatus Thread::wait(uint32_t millisec) { @@ -352,30 +332,28 @@ void Thread::attach_idle_hook(void (*fptr)(void)) { rtos_attach_idle_hook(fptr); } -void Thread::attach_terminate_hook(void (*fptr)(osThreadId id)) { +void Thread::attach_terminate_hook(void (*fptr)(osThreadId_t id)) { terminate_hook = fptr; } Thread::~Thread() { // terminate is thread safe terminate(); -#ifdef __MBED_CMSIS_RTOS_CM if (_dynamic_stack) { - delete[] (_thread_def.stack_pointer); - _thread_def.stack_pointer = (uint32_t*)NULL; + delete[] (uint32_t*)(_attr.stack_mem); + _attr.stack_mem = (uint32_t*)NULL; } -#endif } -void Thread::_thunk(const void * thread_ptr) +void Thread::_thunk(void * thread_ptr) { Thread *t = (Thread*)thread_ptr; t->_task(); t->_mutex.lock(); t->_tid = (osThreadId)NULL; t->_finished = true; + t->_mutex.unlock(); t->_join_sem.release(); - // rtos will release the mutex automatically } } diff --git a/rtos/Thread.h b/rtos/Thread.h index d2bae4fb012..9cf0db2eab6 100644 --- a/rtos/Thread.h +++ b/rtos/Thread.h @@ -23,7 +23,10 @@ #define THREAD_H #include -#include "cmsis_os.h" +#include "cmsis_os2.h" +#include "mbed_rtos1_types.h" +#include "mbed_rtos_storage.h" +#include "mbed_rtx_conf.h" #include "platform/Callback.h" #include "platform/mbed_toolchain.h" #include "rtos/Semaphore.h" @@ -60,31 +63,37 @@ namespace rtos { * thread.join(); * } * @endcode + * + * @note + * Memory considerations: The thread control structures will be created on current thread's stack, both for the mbed OS + * and underlying RTOS objects (static or dynamic RTOS memory pools are not being used). + * Additionally the stack memory for this thread will be allocated on the heap, if it wasn't supplied to the constructor. */ class Thread { public: /** Allocate a new thread without starting execution @param priority initial priority of the thread function. (default: osPriorityNormal). - @param stack_size stack size (in bytes) requirements for the thread function. (default: DEFAULT_STACK_SIZE). - @param stack_pointer pointer to the stack area to be used by this thread (default: NULL). + @param stack_size stack size (in bytes) requirements for the thread function. (default: OS_STACK_SIZE). + @param stack_mem pointer to the stack area to be used by this thread (default: NULL). + @param name name to be used for this thread. It has to stay allocated for the lifetime of the thread (default: NULL) */ Thread(osPriority priority=osPriorityNormal, - uint32_t stack_size=DEFAULT_STACK_SIZE, - unsigned char *stack_pointer=NULL) { - constructor(priority, stack_size, stack_pointer); + uint32_t stack_size=OS_STACK_SIZE, + unsigned char *stack_mem=NULL, const char *name=NULL) { + constructor(priority, stack_size, stack_mem, name); } /** Create a new thread, and start it executing the specified function. @param task function to be executed by this thread. @param argument pointer that is passed to the thread function as start argument. (default: NULL). @param priority initial priority of the thread function. (default: osPriorityNormal). - @param stack_size stack size (in bytes) requirements for the thread function. (default: DEFAULT_STACK_SIZE). - @param stack_pointer pointer to the stack area to be used by this thread (default: NULL). + @param stack_size stack size (in bytes) requirements for the thread function. (default: OS_STACK_SIZE). + @param stack_mem pointer to the stack area to be used by this thread (default: NULL). @deprecated Thread-spawning constructors hide errors. Replaced by thread.start(task). @code - Thread thread(priority, stack_size, stack_pointer); + Thread thread(priority, stack_size, stack_mem); osStatus status = thread.start(task); if (status != osOK) { @@ -97,9 +106,9 @@ class Thread { "Replaced by thread.start(task).") Thread(mbed::Callback task, osPriority priority=osPriorityNormal, - uint32_t stack_size=DEFAULT_STACK_SIZE, - unsigned char *stack_pointer=NULL) { - constructor(task, priority, stack_size, stack_pointer); + uint32_t stack_size=OS_STACK_SIZE, + unsigned char *stack_mem=NULL) { + constructor(task, priority, stack_size, stack_mem); } /** Create a new thread, and start it executing the specified function. @@ -107,13 +116,13 @@ class Thread { @param method function to be executed by this thread. @param argument pointer that is passed to the thread function as start argument. (default: NULL). @param priority initial priority of the thread function. (default: osPriorityNormal). - @param stack_size stack size (in bytes) requirements for the thread function. (default: DEFAULT_STACK_SIZE). - @param stack_pointer pointer to the stack area to be used by this thread (default: NULL). + @param stack_size stack size (in bytes) requirements for the thread function. (default: OS_STACK_SIZE). + @param stack_mem pointer to the stack area to be used by this thread (default: NULL). @deprecated Thread-spawning constructors hide errors. Replaced by thread.start(callback(task, argument)). @code - Thread thread(priority, stack_size, stack_pointer); + Thread thread(priority, stack_size, stack_mem); osStatus status = thread.start(callback(task, argument)); if (status != osOK) { @@ -127,10 +136,10 @@ class Thread { "Replaced by thread.start(callback(task, argument)).") Thread(T *argument, void (T::*task)(), osPriority priority=osPriorityNormal, - uint32_t stack_size=DEFAULT_STACK_SIZE, - unsigned char *stack_pointer=NULL) { + uint32_t stack_size=OS_STACK_SIZE, + unsigned char *stack_mem=NULL) { constructor(mbed::callback(task, argument), - priority, stack_size, stack_pointer); + priority, stack_size, stack_mem); } /** Create a new thread, and start it executing the specified function. @@ -138,13 +147,13 @@ class Thread { @param method function to be executed by this thread. @param argument pointer that is passed to the thread function as start argument. (default: NULL). @param priority initial priority of the thread function. (default: osPriorityNormal). - @param stack_size stack size (in bytes) requirements for the thread function. (default: DEFAULT_STACK_SIZE). - @param stack_pointer pointer to the stack area to be used by this thread (default: NULL). + @param stack_size stack size (in bytes) requirements for the thread function. (default: OS_STACK_SIZE). + @param stack_mem pointer to the stack area to be used by this thread (default: NULL). @deprecated Thread-spawning constructors hide errors. Replaced by thread.start(callback(task, argument)). @code - Thread thread(priority, stack_size, stack_pointer); + Thread thread(priority, stack_size, stack_mem); osStatus status = thread.start(callback(task, argument)); if (status != osOK) { @@ -158,10 +167,10 @@ class Thread { "Replaced by thread.start(callback(task, argument)).") Thread(T *argument, void (*task)(T *), osPriority priority=osPriorityNormal, - uint32_t stack_size=DEFAULT_STACK_SIZE, - unsigned char *stack_pointer=NULL) { + uint32_t stack_size=OS_STACK_SIZE, + unsigned char *stack_mem=NULL) { constructor(mbed::callback(task, argument), - priority, stack_size, stack_pointer); + priority, stack_size, stack_mem); } /** Create a new thread, and start it executing the specified function. @@ -169,13 +178,13 @@ class Thread { @param task function to be executed by this thread. @param argument pointer that is passed to the thread function as start argument. (default: NULL). @param priority initial priority of the thread function. (default: osPriorityNormal). - @param stack_size stack size (in bytes) requirements for the thread function. (default: DEFAULT_STACK_SIZE). - @param stack_pointer pointer to the stack area to be used by this thread (default: NULL). + @param stack_size stack size (in bytes) requirements for the thread function. (default: OS_STACK_SIZE). + @param stack_mem pointer to the stack area to be used by this thread (default: NULL). @deprecated Thread-spawning constructors hide errors. Replaced by thread.start(callback(task, argument)). @code - Thread thread(priority, stack_size, stack_pointer); + Thread thread(priority, stack_size, stack_mem); osStatus status = thread.start(callback(task, argument)); if (status != osOK) { @@ -188,10 +197,10 @@ class Thread { "Replaced by thread.start(callback(task, argument)).") Thread(void (*task)(void const *argument), void *argument=NULL, osPriority priority=osPriorityNormal, - uint32_t stack_size=DEFAULT_STACK_SIZE, - unsigned char *stack_pointer=NULL) { + uint32_t stack_size=OS_STACK_SIZE, + unsigned char *stack_mem=NULL) { constructor(mbed::callback((void (*)(void *))task, argument), - priority, stack_size, stack_pointer); + priority, stack_size, stack_mem); } /** Starts a thread executing the specified function. @@ -240,13 +249,13 @@ class Thread { /** Set the specified Signal Flags of an active thread. @param signals specifies the signal flags of the thread that should be set. - @return previous signal flags of the specified thread or 0x80000000 in case of incorrect parameters. + @return previous signal flags of the specified thread or osFlagsError in case of incorrect parameters. */ int32_t signal_set(int32_t signals); /** Clears the specified Signal Flags of an active thread. @param signals specifies the signal flags of the thread that should be cleared. - @return resultant signal flags of the specified thread or 0x80000000 in case of incorrect parameters. + @return resultant signal flags of the specified thread or osFlagsError in case of incorrect parameters. */ int32_t signal_clr(int32_t signals); @@ -256,12 +265,18 @@ class Thread { Ready, /**< Ready to run */ Running, /**< Running */ WaitingDelay, /**< Waiting for a delay to occur */ + WaitingJoin, /**< Waiting for thread to join */ + WaitingThreadFlag, /**< Waiting for a thread flag to be set */ + WaitingEventFlag, /**< Waiting for a event flag to be set */ + WaitingMutex, /**< Waiting for a mutex event to occur */ + WaitingSemaphore, /**< Waiting for a semaphore event to occur */ + WaitingMemoryPool, /**< Waiting for a memory pool */ + WaitingMessageGet, /**< Waiting for message to arrive */ + WaitingMessagePut, /**< Waiting for message to be send */ WaitingInterval, /**< Waiting for an interval to occur */ WaitingOr, /**< Waiting for one event in a set to occur */ WaitingAnd, /**< Waiting for multiple events in a set to occur */ - WaitingSemaphore, /**< Waiting for a semaphore event to occur */ WaitingMailbox, /**< Waiting for a mailbox event to occur */ - WaitingMutex, /**< Waiting for a mutex event to occur */ /* Not in sync with RTX below here */ Deleted, /**< The task has been deleted */ @@ -292,8 +307,13 @@ class Thread { */ uint32_t max_stack(); + /** Get thread name + @return thread name or NULL if the name was not set. + */ + const char *get_name(); + /** Wait for one or more Signal Flags to become signaled for the current RUNNING thread. - @param signals wait until all specified signal flags set or 0 for any single signal flag. + @param signals wait until all specified signal flags are set or 0 for any single signal flag. @param millisec timeout value or 0 in case of no time-out. (default: osWaitForever). @return event flag information or error code. @note not callable from interrupt @@ -317,7 +337,7 @@ class Thread { @return thread ID for reference by other functions or NULL in case of error. */ static osThreadId gettid(); - + /** Attach a function to be called by the RTOS idle task @param fptr pointer to the function to be called */ @@ -338,21 +358,24 @@ class Thread { // Required to share definitions without // delegated constructors void constructor(osPriority priority=osPriorityNormal, - uint32_t stack_size=DEFAULT_STACK_SIZE, - unsigned char *stack_pointer=NULL); + uint32_t stack_size=OS_STACK_SIZE, + unsigned char *stack_mem=NULL, + const char *name=NULL); void constructor(mbed::Callback task, osPriority priority=osPriorityNormal, - uint32_t stack_size=DEFAULT_STACK_SIZE, - unsigned char *stack_pointer=NULL); - static void _thunk(const void * thread_ptr); - - mbed::Callback _task; - osThreadId _tid; - osThreadDef_t _thread_def; - Semaphore _join_sem; - Mutex _mutex; - bool _dynamic_stack; - bool _finished; + uint32_t stack_size=OS_STACK_SIZE, + unsigned char *stack_mem=NULL, + const char *name=NULL); + static void _thunk(void * thread_ptr); + + mbed::Callback _task; + osThreadId_t _tid; + osThreadAttr_t _attr; + bool _dynamic_stack; + Semaphore _join_sem; + Mutex _mutex; + mbed_rtos_storage_thread_t _obj_mem; + bool _finished; }; } diff --git a/rtos/mbed_boot.c b/rtos/mbed_boot.c new file mode 100644 index 00000000000..ab7200d8115 --- /dev/null +++ b/rtos/mbed_boot.c @@ -0,0 +1,637 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2016 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* mbed OS boot sequence + * + * Most of mbed supported targets use default ARM Cortex M boot approach, where the core starts executing reset vector + * after power up. Reset ISR is defined for each target by the vendor (basing on CMSIS template). Reset vector is + * responsible for low level platform init and then calling in libc (__main). Depending on compiler and version of C + * library, predefined function will be called which is implemented by mbed OS. + * + * There's number of functions, vendor and users can provide to setup the platform and/or inject a code to be executed + * before main(): + * * Reset vector and SystemInit: Reset vector should do low level core and board initialization. + * * mbed_sdk_init: Higher level board init and making sure the board is ready for the mbed OS. + * * mbed_main: User's code to be executed before main(). + * * main: Standard application code. + * + * Detailed boot procedures: + * + * For ARMCC: + * ========== + * + * Reset (TARGET) + * -> SystemInit (TARGET) + * -> __main (LIBC) + * -> __rt_entry (MBED: rtos/mbed_boot.c) + * -> __user_setup_stackheap (LIBC) + * -> mbed_set_stack_heap (MBED: rtos/mbed_boot.c) + * -> mbed_cpy_nvic (MBED: rtos/mbed_boot.c) + * -> mbed_sdk_init (TARGET) + * -> _platform_post_stackheap_init (RTX) + * -> osKernelInitialize (RTX) + * -> mbed_start_main (MBED: rtos/mbed_boot.c) + * -> osThreadNew (RTX) + * -> pre_main(MBED: rtos/mbed_boot.c) + * -> __rt_lib_init (LIBC) + * -> $Sub$$main (MBED: rtos/mbed_boot.c) + * -> mbed_main (MBED: rtos/mbed_boot.c) + * -> main (APP) + * -> osKernelStart (RTX) + * + * In addition to the above, libc will use functions defined by RTX: __user_perthread_libspace, _mutex_initialize, + * _mutex_acquire, _mutex_release, _mutex_free for details consult: ARM C and C++ Libraries and Floating-Point + * Support User Guide. + * + * For MICROLIB: + * ========== + * + * Reset (TARGET) + * -> SystemInit (TARGET) + * -> __main (LIBC) + * -> _main_init (MBED: rtos/mbed_boot.c) + * -> mbed_set_stack_heap (MBED: rtos/mbed_boot.c) + * -> mbed_cpy_nvic (MBED: rtos/mbed_boot.c) + * -> mbed_sdk_init (TARGET) + * -> osKernelInitialize (RTX) + * -> mbed_start_main (MBED: rtos/mbed_boot.c) + * -> osThreadNew (RTX) + * -> pre_main(MBED: rtos/mbed_boot.c) + * -> __cpp_initialize__aeabi_ (LIBC) + * -> $Sub$$main (MBED: rtos/mbed_boot.c) + * -> mbed_main (MBED: rtos/mbed_boot.c) + * -> main (APP) + * -> osKernelStart (RTX) + * + * For GCC: + * ======== + * + * Reset (TARGET) + * -> SystemInit (TARGET) + * -> __main (LIBC) + * -> software_init_hook (MBED: rtos/mbed_boot.c) + * -> mbed_set_stack_heap (MBED: rtos/mbed_boot.c) + * -> mbed_cpy_nvic (MBED: rtos/mbed_boot.c) + * -> mbed_sdk_init (TARGET) + * -> osKernelInitialize (RTX) + * -> mbed_start_main (MBED: rtos/mbed_boot.c) + * -> osThreadNew (RTX) + * -> pre_main(MBED: rtos/mbed_boot.c) + * -> __libc_init_array (LIBC) + * -> __wrap_main (MBED: rtos/mbed_boot.c) + * -> mbed_main (MBED: rtos/mbed_boot.c) + * -> __real_main (APP) + * -> osKernelStart (RTX) + * + * For IAR: + * ======== + * + * Reset (TARGET) + * -> SystemInit (TARGET) + * -> __iar_program_start + * -> __iar_init_core + * -> __iar_init_core + * -> __iar_init_vfp + * -> __low_level_init + * -> __iar_data_init3 + * -> mbed_cpy_nvic (MBED: rtos/mbed_boot.c) + * -> mbed_sdk_init (TARGET) + * -> mbed_set_stack_heap (MBED: rtos/mbed_boot.c) + * -> osKernelInitialize (RTX) + * -> mbed_start_main (MBED: rtos/mbed_boot.c) + * -> osThreadNew (RTX) + * -> pre_main(MBED: rtos/mbed_boot.c) + * -> __iar_dynamic_initialization +* -> main + * -> osKernelStart (RTX) + * + * Other notes: + * + * * In addition to the above, libc will use functions defined in mbed_boot.c: __rtos_malloc_lock/unlock, + * __rtos_env_lock/unlock. + * + * * First step after the execution is passed to mbed, software_init_hook for GCC and __rt_entry for ARMC is to + * initialize heap. + * + * Memory layout notes: + * ==================== + * + * IAR Default Memory layout notes: + * -Heap defined by "HEAP" region in .icf file + * -Interrupt stack defined by "CSTACK" region in .icf file + * -Value INITIAL_SP is ignored + * + * IAR Custom Memory layout notes: + * -There is no custom layout available for IAR - everything must be defined in + * the .icf file and use the default layout + * + * + * GCC Default Memory layout notes: + * -Block of memory from symbol __end__ to define INITIAL_SP used to setup interrupt + * stack and heap in the function set_stack_heap() + * -ISR_STACK_SIZE can be overridden to be larger or smaller + * + * GCC Custom Memory layout notes: + * -Heap can be explicitly placed by defining both HEAP_START and HEAP_SIZE + * -Interrupt stack can be explicitly placed by defining both ISR_STACK_START and ISR_STACK_SIZE + * + * + * ARM Memory layout + * -Block of memory from end of region "RW_IRAM1" to define INITIAL_SP used to setup interrupt + * stack and heap in the function set_stack_heap() + * -ISR_STACK_SIZE can be overridden to be larger or smaller + * + * ARM Custom Memory layout notes: + * -Heap can be explicitly placed by defining both HEAP_START and HEAP_SIZE + * -Interrupt stack can be explicitly placed by defining both ISR_STACK_START and ISR_STACK_SIZE + * + */ + +#include "cmsis.h" +#include "mbed_rtx.h" +#include "mbed_rtos_storage.h" +#include "cmsis_os2.h" +#include "mbed_toolchain.h" +#include "mbed_error.h" + +/* Heap limits - only used if set */ +extern unsigned char *mbed_heap_start; +extern uint32_t mbed_heap_size; + +unsigned char *mbed_stack_isr_start = 0; +uint32_t mbed_stack_isr_size = 0; + +WEAK void mbed_main(void); +void pre_main (void); + +osThreadAttr_t _main_thread_attr; +/* The main stack size is hardcoded on purpose, so it's less tempting to change it per platform. As usually it's not + * the correct solution to the problem and it makes mbed OS behave differently on different targets. + */ +MBED_ALIGN(8) char _main_stack[4096]; +mbed_rtos_storage_thread_t _main_obj; + +osMutexId_t singleton_mutex_id; +mbed_rtos_storage_mutex_t singleton_mutex_obj; +osMutexAttr_t singleton_mutex_attr; + +/* + * Sanity check values + */ +#if defined(__ICCARM__) && \ + (defined(HEAP_START) || defined(HEAP_SIZE) || \ + defined(ISR_STACK_START) && defined(ISR_STACK_SIZE)) + #error "No custom layout allowed for IAR. Use .icf file instead" +#endif +#if defined(HEAP_START) && !defined(HEAP_SIZE) + #error "HEAP_SIZE must be defined if HEAP_START is defined" +#endif +#if defined(ISR_STACK_START) && !defined(ISR_STACK_SIZE) + #error "ISR_STACK_SIZE must be defined if ISR_STACK_START is defined" +#endif +#if defined(HEAP_SIZE) && !defined(HEAP_START) + #error "HEAP_START must be defined if HEAP_SIZE is defined" +#endif + +/* IAR - INITIAL_SP and HEAP_START ignored as described in Memory layout notes above + */ +#if !defined(__ICCARM__) && !defined(INITIAL_SP) && !defined(HEAP_START) + #error "no target defined" +#endif + +/* Interrupt stack and heap always defined for IAR + * Main thread defined here + */ +#if defined(__ICCARM__) + #pragma section="CSTACK" + #pragma section="HEAP" + #define HEAP_START ((unsigned char*)__section_begin("HEAP")) + #define HEAP_SIZE ((uint32_t)__section_size("HEAP")) + #define ISR_STACK_START ((unsigned char*)__section_begin("CSTACK")) + #define ISR_STACK_SIZE ((uint32_t)__section_size("CSTACK")) +#endif + +/* Define heap region if it has not been defined already */ +#if !defined(HEAP_START) + #if defined(__ICCARM__) + #error "Heap should already be defined for IAR" + #elif defined(__CC_ARM) + extern uint32_t Image$$RW_IRAM1$$ZI$$Limit[]; + #define HEAP_START ((unsigned char*)Image$$RW_IRAM1$$ZI$$Limit) + #define HEAP_SIZE ((uint32_t)((uint32_t)INITIAL_SP - (uint32_t)HEAP_START)) + #elif defined(__GNUC__) + extern uint32_t __end__[]; + #define HEAP_START ((unsigned char*)__end__) + #define HEAP_SIZE ((uint32_t)((uint32_t)INITIAL_SP - (uint32_t)HEAP_START)) + #endif +#endif + +/* Define stack sizes if they haven't been set already */ +#if !defined(ISR_STACK_SIZE) + #define ISR_STACK_SIZE ((uint32_t)1024) +#endif + +/* + * mbed_set_stack_heap purpose is to set the following variables: + * -mbed_heap_start + * -mbed_heap_size + * -mbed_stack_isr_start + * -mbed_stack_isr_size + */ +void mbed_set_stack_heap(void) { + + unsigned char *free_start = HEAP_START; + uint32_t free_size = HEAP_SIZE; + +#ifdef ISR_STACK_START + /* Interrupt stack explicitly specified */ + mbed_stack_isr_size = ISR_STACK_SIZE; + mbed_stack_isr_start = ISR_STACK_START; +#else + /* Interrupt stack - reserve space at the end of the free block */ + mbed_stack_isr_size = ISR_STACK_SIZE < free_size ? ISR_STACK_SIZE : free_size; + mbed_stack_isr_start = free_start + free_size - mbed_stack_isr_size; + free_size -= mbed_stack_isr_size; +#endif + + /* Heap - everything else */ + mbed_heap_size = free_size; + mbed_heap_start = free_start; +} + +static void mbed_cpy_nvic(void) +{ + /* If vector address in RAM is defined, copy and switch to dynamic vectors. Exceptions for M0 which doesn't have + VTOR register and for A9 for which CMSIS doesn't define NVIC_SetVector; in both cases target code is + responsible for correctly handling the vectors. + */ +#if !defined(__CORTEX_M0) && !defined(__CORTEX_A9) +#ifdef NVIC_RAM_VECTOR_ADDRESS + uint32_t *old_vectors = (uint32_t *)SCB->VTOR; + uint32_t *vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS; + for (int i = 0; i < NVIC_NUM_VECTORS; i++) { + vectors[i] = old_vectors[i]; + } + SCB->VTOR = (uint32_t)NVIC_RAM_VECTOR_ADDRESS; +#endif /* NVIC_RAM_VECTOR_ADDRESS */ +#endif /* !defined(__CORTEX_M0) && !defined(__CORTEX_A9) */ +} + +/* mbed_main is a function that is called before main() + * mbed_sdk_init() is also a function that is called before main(), but unlike + * mbed_main(), it is not meant for user code, but for the SDK itself to perform + * initializations before main() is called. + */ +WEAK void mbed_main(void) { + +} + +/* This function can be implemented by the target to perform higher level target initialization, before the mbed OS or + * RTX is started. + */ +void mbed_sdk_init(void); +WEAK void mbed_sdk_init(void) { +} + +void mbed_start_main(void) +{ + _main_thread_attr.stack_mem = _main_stack; + _main_thread_attr.stack_size = sizeof(_main_stack); + _main_thread_attr.cb_size = sizeof(_main_obj); + _main_thread_attr.cb_mem = &_main_obj; + _main_thread_attr.priority = osPriorityNormal; + _main_thread_attr.name = "MAIN"; + osThreadId_t result = osThreadNew((osThreadFunc_t)pre_main, NULL, &_main_thread_attr); + if ((void *)result == NULL) { + error("Pre main thread not created"); + } + + osKernelStart(); +} + +/******************** Toolchain specific code ********************/ + +#if defined (__CC_ARM) + +/* Common for both ARMC and MICROLIB */ +int $Super$$main(void); +int $Sub$$main(void) { + mbed_main(); + return $Super$$main(); +} + +#if defined (__MICROLIB) /******************** MICROLIB ********************/ + +int main(void); +void _main_init (void) __attribute__((section(".ARM.Collect$$$$000000FF"))); +void $Super$$__cpp_initialize__aeabi_(void); + +void _main_init (void) { + mbed_set_stack_heap(); + /* Copy the vector table to RAM only if uVisor is not in use. */ +#if !(defined(FEATURE_UVISOR) && defined(TARGET_UVISOR_SUPPORTED)) + mbed_cpy_nvic(); +#endif + mbed_sdk_init(); + osKernelInitialize(); + mbed_start_main(); + for (;;); +} + +void $Sub$$__cpp_initialize__aeabi_(void) +{ + /* This should invoke C++ initializers prior _main_init, we keep this empty and + * invoke them after _main_init, when the RTX is already initilized. + */ +} + +void pre_main() +{ + singleton_mutex_attr.attr_bits = osMutexRecursive; + singleton_mutex_attr.cb_size = sizeof(singleton_mutex_obj); + singleton_mutex_attr.cb_mem = &singleton_mutex_obj; + singleton_mutex_id = osMutexNew(&singleton_mutex_attr); + + $Super$$__cpp_initialize__aeabi_(); + main(); +} + +#else /******************** ARMC ********************/ + +#include +extern __value_in_regs struct __argc_argv __rt_lib_init(unsigned heapbase, unsigned heaptop); +extern __value_in_regs struct __initial_stackheap __user_setup_stackheap(void); +extern void _platform_post_stackheap_init (void); +extern int main(int argc, char* argv[]); + +void pre_main (void) +{ + singleton_mutex_attr.attr_bits = osMutexRecursive; + singleton_mutex_attr.cb_size = sizeof(singleton_mutex_obj); + singleton_mutex_attr.cb_mem = &singleton_mutex_obj; + singleton_mutex_id = osMutexNew(&singleton_mutex_attr); + + __rt_lib_init((unsigned)mbed_heap_start, (unsigned)(mbed_heap_start + mbed_heap_size)); + + main(0, NULL); +} + +/* The single memory model is checking for stack collision at run time, verifing + that the heap pointer is underneath the stack pointer. + With the RTOS there is not only one stack above the heap, there are multiple + stacks and some of them are underneath the heap pointer. +*/ +#pragma import(__use_two_region_memory) + +/* Called by the C library */ +void __rt_entry (void) { + __user_setup_stackheap(); + mbed_set_stack_heap(); + /* Copy the vector table to RAM only if uVisor is not in use. */ +#if !(defined(FEATURE_UVISOR) && defined(TARGET_UVISOR_SUPPORTED)) + mbed_cpy_nvic(); +#endif + mbed_sdk_init(); + _platform_post_stackheap_init(); + mbed_start_main(); +} + +#endif /* ARMC */ +#elif defined (__GNUC__) /******************** GCC ********************/ + +extern int main(int argc, char* argv[]); +extern void __libc_init_array (void); +extern int __real_main(void); + +osMutexId_t malloc_mutex_id; +mbed_rtos_storage_mutex_t malloc_mutex_obj; +osMutexAttr_t malloc_mutex_attr; + +osMutexId_t env_mutex_id; +mbed_rtos_storage_mutex_t env_mutex_obj; +osMutexAttr_t env_mutex_attr; + +#ifdef FEATURE_UVISOR +#include "uvisor-lib/uvisor-lib.h" +#endif/* FEATURE_UVISOR */ + +int __wrap_main(void) { + mbed_main(); + return __real_main(); +} + +void pre_main(void) +{ + singleton_mutex_attr.attr_bits = osMutexRecursive; + singleton_mutex_attr.cb_size = sizeof(singleton_mutex_obj); + singleton_mutex_attr.cb_mem = &singleton_mutex_obj; + singleton_mutex_id = osMutexNew(&singleton_mutex_attr); + + malloc_mutex_attr.attr_bits = osMutexRecursive; + malloc_mutex_attr.cb_size = sizeof(malloc_mutex_obj); + malloc_mutex_attr.cb_mem = &malloc_mutex_obj; + malloc_mutex_id = osMutexNew(&malloc_mutex_attr); + + env_mutex_attr.attr_bits = osMutexRecursive; + env_mutex_attr.cb_size = sizeof(env_mutex_obj); + env_mutex_attr.cb_mem = &env_mutex_obj; + env_mutex_id = osMutexNew(&env_mutex_attr); + + __libc_init_array(); + + main(0, NULL); +} + +void software_init_hook(void) +{ + mbed_set_stack_heap(); + /* Copy the vector table to RAM only if uVisor is not in use. */ +#if !(defined(FEATURE_UVISOR) && defined(TARGET_UVISOR_SUPPORTED)) + mbed_cpy_nvic(); +#endif + mbed_sdk_init(); + osKernelInitialize(); + /* uvisor_lib_init calls RTOS functions, so must be called after the RTOS has + * been initialized. */ +#ifdef FEATURE_UVISOR + int return_code; + + return_code = uvisor_lib_init(); + if (return_code) { + mbed_die(); + } +#endif/* FEATURE_UVISOR */ + mbed_start_main(); +} + +/* Opaque declaration of _reent structure */ +struct _reent; + +void __rtos_malloc_lock( struct _reent *_r ) +{ + osMutexAcquire(malloc_mutex_id, osWaitForever); +} + +void __rtos_malloc_unlock( struct _reent *_r ) +{ + osMutexRelease(malloc_mutex_id); +} + +void __rtos_env_lock( struct _reent *_r ) +{ + osMutexAcquire(env_mutex_id, osWaitForever); +} + +void __rtos_env_unlock( struct _reent *_r ) +{ + osMutexRelease(env_mutex_id); +} + +#endif + +#if defined(TOOLCHAIN_IAR) /******************** IAR ********************/ + +extern void* __vector_table; +extern int __low_level_init(void); +extern void __iar_data_init3(void); +extern __weak void __iar_init_core( void ); +extern __weak void __iar_init_vfp( void ); +extern void __iar_dynamic_initialization(void); +extern void mbed_sdk_init(void); +extern int main(void); +extern void exit(int arg); + +static uint8_t low_level_init_needed; + +void pre_main(void) +{ + singleton_mutex_attr.attr_bits = osMutexRecursive; + singleton_mutex_attr.cb_size = sizeof(singleton_mutex_obj); + singleton_mutex_attr.cb_mem = &singleton_mutex_obj; + singleton_mutex_id = osMutexNew(&singleton_mutex_attr); + + if (low_level_init_needed) { + __iar_dynamic_initialization(); + } + mbed_main(); + main(); +} + +#pragma required=__vector_table +void __iar_program_start( void ) +{ + __iar_init_core(); + __iar_init_vfp(); + + uint8_t low_level_init_needed_local; + + low_level_init_needed_local = __low_level_init(); + if (low_level_init_needed_local) { + __iar_data_init3(); + /* Copy the vector table to RAM only if uVisor is not in use. */ +#if !(defined(FEATURE_UVISOR) && defined(TARGET_UVISOR_SUPPORTED)) + mbed_cpy_nvic(); +#endif + mbed_sdk_init(); + } + + mbed_set_stack_heap(); + + /* Store in a global variable after RAM has been initialized */ + low_level_init_needed = low_level_init_needed_local; + + osKernelInitialize(); + + mbed_start_main(); +} + +/* Thread safety */ +static osMutexId_t std_mutex_id_sys[_MAX_LOCK] = {0}; +static mbed_rtos_storage_mutex_t std_mutex_sys[_MAX_LOCK] = {0}; +#define _FOPEN_MAX 10 +static osMutexId_t std_mutex_id_file[_FOPEN_MAX] = {0}; +static mbed_rtos_storage_mutex_t std_mutex_file[_FOPEN_MAX] = {0}; + +void __iar_system_Mtxinit(__iar_Rmtx *mutex) /* Initialize a system lock */ +{ + osMutexAttr_t attr; + uint32_t index; + for (index = 0; index < _MAX_LOCK; index++) { + if (0 == std_mutex_id_sys[index]) { + attr.cb_mem = &std_mutex_sys[index]; + attr.cb_size = sizeof(std_mutex_sys[index]); + attr.attr_bits = osMutexRecursive; + std_mutex_id_sys[index] = osMutexNew(&attr); + *mutex = (__iar_Rmtx*)&std_mutex_id_sys[index]; + return; + } + } + + /* This should never happen */ + error("Not enough mutexes\n"); +} + +void __iar_system_Mtxdst(__iar_Rmtx *mutex) /* Destroy a system lock */ +{ + osMutexDelete(*(osMutexId_t*)*mutex); + *mutex = 0; +} + +void __iar_system_Mtxlock(__iar_Rmtx *mutex) /* Lock a system lock */ +{ + osMutexAcquire(*(osMutexId_t*)*mutex, osWaitForever); +} + +void __iar_system_Mtxunlock(__iar_Rmtx *mutex) /* Unlock a system lock */ +{ + osMutexRelease(*(osMutexId_t*)*mutex); +} + +void __iar_file_Mtxinit(__iar_Rmtx *mutex) /* Initialize a file lock */ +{ + osMutexAttr_t attr; + uint32_t index; + for (index = 0; index < _FOPEN_MAX; index++) { + if (0 == std_mutex_id_file[index]) { + attr.cb_mem = &std_mutex_file[index]; + attr.cb_size = sizeof(std_mutex_file[index]); + attr.attr_bits = osMutexRecursive; + std_mutex_id_file[index] = osMutexNew(&attr); + *mutex = (__iar_Rmtx*)&std_mutex_id_file[index]; + return; + } + } + /* The variable _FOPEN_MAX needs to be increased */ + error("Not enough mutexes\n"); +} + +void __iar_file_Mtxdst(__iar_Rmtx *mutex) /* Destroy a file lock */ +{ + osMutexDelete(*(osMutexId_t*)*mutex); + *mutex = 0; +} + +void __iar_file_Mtxlock(__iar_Rmtx *mutex) /* Lock a file lock */ +{ + osMutexAcquire(*(osMutexId_t*)*mutex, osWaitForever); +} + +void __iar_file_Mtxunlock(__iar_Rmtx *mutex) /* Unlock a file lock */ +{ + osMutexRelease(*(osMutexId_t*)*mutex); +} + +#endif diff --git a/rtos/mbed_rtos1_types.h b/rtos/mbed_rtos1_types.h new file mode 100644 index 00000000000..10530ac7cbf --- /dev/null +++ b/rtos/mbed_rtos1_types.h @@ -0,0 +1,27 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2017 ARM Limited + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef MBED_RTOS_RTX1_TYPES_H +#define MBED_RTOS_RTX1_TYPES_H + +#include "rtx/cmsis_os.h" + +#endif diff --git a/rtos/mbed_rtos_storage.h b/rtos/mbed_rtos_storage.h new file mode 100644 index 00000000000..270e57d4de9 --- /dev/null +++ b/rtos/mbed_rtos_storage.h @@ -0,0 +1,52 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2017 ARM Limited + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef MBED_RTOS_STORAGE_H +#define MBED_RTOS_STORAGE_H + +/** \addtogroup rtos */ +/** @{*/ + +/** @brief RTOS primitives storage types for RTX + + Types defined in this file should be utilized, when the direct RTOS C API usage is required, to provide backing memory + for internal RTX data. Allocated object should be wrapped in attribute struct and passed to os*New call, for details + see CMSIS-RTOS2 documentation. + + @note + This file breaks abstraction layers and uses RTX internal types, but it limits the contamination to single, RTOS + implementation specific, header file, therefore limiting scope of possible changes. + */ + +#include "rtx_lib.h" + +typedef os_mutex_t mbed_rtos_storage_mutex_t; +typedef os_semaphore_t mbed_rtos_storage_semaphore_t; +typedef os_thread_t mbed_rtos_storage_thread_t; +typedef os_memory_pool_t mbed_rtos_storage_mem_pool_t; +typedef os_message_queue_t mbed_rtos_storage_msg_queue_t; +typedef os_event_flags_t mbed_rtos_storage_event_flags_t; +typedef os_message_t mbed_rtos_storage_message_t; +typedef os_timer_t mbed_rtos_storage_timer_t; + +#endif + +/** @}*/ diff --git a/rtos/rtos.h b/rtos/rtos.h index c3da7997cdd..968ca78dd40 100644 --- a/rtos/rtos.h +++ b/rtos/rtos.h @@ -25,6 +25,9 @@ #ifndef RTOS_H #define RTOS_H +#include "mbed_rtx.h" +#include "mbed_rtx_conf.h" +#include "mbed_rtos_storage.h" #include "rtos/Thread.h" #include "rtos/Mutex.h" #include "rtos/RtosTimer.h" diff --git a/rtos/rtx/TARGET_CORTEX_M/TESTS/memory/heap_and_stack/main.cpp b/rtos/rtx2/TARGET_CORTEX_M/TESTS/memory/heap_and_stack/main.cpp similarity index 100% rename from rtos/rtx/TARGET_CORTEX_M/TESTS/memory/heap_and_stack/main.cpp rename to rtos/rtx2/TARGET_CORTEX_M/TESTS/memory/heap_and_stack/main.cpp diff --git a/rtos/rtx2/mbed_rtx_conf.h b/rtos/rtx2/mbed_rtx_conf.h new file mode 100644 index 00000000000..04af69df2e5 --- /dev/null +++ b/rtos/rtx2/mbed_rtx_conf.h @@ -0,0 +1,54 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2012 ARM Limited + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef MBED_RTX_CONF_H +#define MBED_RTX_CONF_H + +#include "mbed_rtx.h" + +#ifndef OS_STACK_SIZE +#ifndef MBED_SMALL_TARGET +#define OS_STACK_SIZE 4096 +#else +#define OS_STACK_SIZE 2048 +#endif +#endif + +#define OS_TIMER_THREAD_STACK_SIZE 768 +#define OS_IDLE_THREAD_STACK_SIZE 256 + +#define OS_DYNAMIC_MEM_SIZE 0 + +#if defined(__CC_ARM) +#define OS_MUTEX_OBJ_MEM 1 +#define OS_MUTEX_NUM 6 +#endif + +#if !defined(OS_STACK_WATERMARK) && (defined(MBED_STACK_STATS_ENABLED) && MBED_STACK_STATS_ENABLED) +#define OS_STACK_WATERMARK 1 +#endif + +/* Run threads unprivileged when uVisor is enabled. */ +#if defined(FEATURE_UVISOR) && defined(TARGET_UVISOR_SUPPORTED) +# define OS_PRIVILEGE_MODE 0 +#endif + +#endif /* MBED_RTX_CONF_H */ diff --git a/rtos/rtx2/mbed_rtx_handlers.c b/rtos/rtx2/mbed_rtx_handlers.c new file mode 100644 index 00000000000..738fa13c86c --- /dev/null +++ b/rtos/rtx2/mbed_rtx_handlers.c @@ -0,0 +1,38 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2016 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "cmsis_compiler.h" +#include "rtx_os.h" +#include "mbed_rtx.h" +#include "mbed_error.h" + +extern void rtos_idle_loop(void); + +__NO_RETURN void osRtxIdleThread (void *argument) +{ + for (;;) { + rtos_idle_loop(); + } +} + +__NO_RETURN uint32_t osRtxErrorNotify (uint32_t code, void *object_id) +{ + osThreadId_t tid = osThreadGetId(); + error("CMSIS-RTOS error status: 0x%X, task ID: 0x%X\n\r", code, tid); + + /* That shouldn't be reached */ + for (;;) {} +} diff --git a/targets/TARGET_ARM_SSG/mbed_rtx.h b/targets/TARGET_ARM_SSG/mbed_rtx.h index 31c789d9265..ed472b81e58 100644 --- a/targets/TARGET_ARM_SSG/mbed_rtx.h +++ b/targets/TARGET_ARM_SSG/mbed_rtx.h @@ -22,9 +22,6 @@ #ifndef INITIAL_SP #define INITIAL_SP (0x20020000UL) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 7 -#endif #ifndef OS_MAINSTKSIZE #define OS_MAINSTKSIZE 112 #endif diff --git a/targets/TARGET_Freescale/mbed_rtx.h b/targets/TARGET_Freescale/mbed_rtx.h index 43a913e652f..497007c94e2 100644 --- a/targets/TARGET_Freescale/mbed_rtx.h +++ b/targets/TARGET_Freescale/mbed_rtx.h @@ -22,9 +22,6 @@ #ifndef INITIAL_SP #define INITIAL_SP (0x10008000UL) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 14 -#endif #ifndef OS_MAINSTKSIZE #define OS_MAINSTKSIZE 256 #endif @@ -37,9 +34,6 @@ #ifndef INITIAL_SP #define INITIAL_SP (0x20008000UL) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 14 -#endif #ifndef OS_MAINSTKSIZE #define OS_MAINSTKSIZE 256 #endif @@ -52,9 +46,6 @@ #ifndef INITIAL_SP #define INITIAL_SP (0x20010000UL) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 14 -#endif #ifndef OS_MAINSTKSIZE #define OS_MAINSTKSIZE 256 #endif @@ -67,9 +58,6 @@ #ifndef INITIAL_SP #define INITIAL_SP (0x20030000UL) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 14 -#endif #ifndef OS_MAINSTKSIZE #define OS_MAINSTKSIZE 256 #endif @@ -82,9 +70,6 @@ #ifndef INITIAL_SP #define INITIAL_SP (0x20003000UL) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 6 -#endif #ifndef OS_MAINSTKSIZE #define OS_MAINSTKSIZE 128 #endif @@ -97,9 +82,6 @@ #ifndef INITIAL_SP #define INITIAL_SP (0x20006000UL) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 14 -#endif #ifndef OS_MAINSTKSIZE #define OS_MAINSTKSIZE 256 #endif @@ -112,9 +94,6 @@ #ifndef INITIAL_SP #define INITIAL_SP (0x20000C00UL) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 6 -#endif #ifndef OS_MAINSTKSIZE #define OS_MAINSTKSIZE 128 #endif @@ -127,9 +106,6 @@ #ifndef INITIAL_SP #define INITIAL_SP (0x20003000UL) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 6 -#endif #ifndef OS_MAINSTKSIZE #define OS_MAINSTKSIZE 128 #endif @@ -142,9 +118,6 @@ #ifndef INITIAL_SP #define INITIAL_SP (0x20003000UL) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 6 -#endif #ifndef OS_MAINSTKSIZE #define OS_MAINSTKSIZE 128 #endif @@ -157,9 +130,6 @@ #ifndef INITIAL_SP #define INITIAL_SP (0x20006000UL) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 14 -#endif #ifndef OS_MAINSTKSIZE #define OS_MAINSTKSIZE 256 #endif @@ -172,9 +142,6 @@ #ifndef INITIAL_SP #define INITIAL_SP (0x20012000UL) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 14 -#endif #ifndef OS_MAINSTKSIZE #define OS_MAINSTKSIZE 256 #endif @@ -192,9 +159,6 @@ #define ISR_STACK_SIZE (0x1000) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 14 -#endif #ifndef OS_MAINSTKSIZE #define OS_MAINSTKSIZE 256 #endif @@ -207,9 +171,6 @@ #ifndef INITIAL_SP #define INITIAL_SP (0x20008000UL) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 14 -#endif #ifndef OS_MAINSTKSIZE #define OS_MAINSTKSIZE 256 #endif @@ -237,9 +198,6 @@ #ifndef INITIAL_SP #define INITIAL_SP (0x20030000UL) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 14 -#endif #ifndef OS_MAINSTKSIZE #define OS_MAINSTKSIZE 256 #endif diff --git a/targets/TARGET_Maxim/mbed_rtx.h b/targets/TARGET_Maxim/mbed_rtx.h index 07e635d40b4..17058aa8ab9 100644 --- a/targets/TARGET_Maxim/mbed_rtx.h +++ b/targets/TARGET_Maxim/mbed_rtx.h @@ -22,9 +22,6 @@ #ifndef INITIAL_SP #define INITIAL_SP (0x20008000UL) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 14 -#endif #ifndef OS_MAINSTKSIZE #define OS_MAINSTKSIZE 256 #endif @@ -37,9 +34,6 @@ #ifndef INITIAL_SP #define INITIAL_SP (0x20008000UL) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 14 -#endif #ifndef OS_MAINSTKSIZE #define OS_MAINSTKSIZE 256 #endif @@ -52,12 +46,6 @@ #ifndef INITIAL_SP #define INITIAL_SP (0x20040000UL) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 14 -#endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 256 -#endif #ifndef OS_CLOCK #define OS_CLOCK 48000000 #endif @@ -67,12 +55,6 @@ #ifndef INITIAL_SP #define INITIAL_SP (0x20028000UL) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 14 -#endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 256 -#endif #ifndef OS_CLOCK #define OS_CLOCK 96000000 #endif diff --git a/targets/TARGET_NORDIC/TARGET_NRF5/us_ticker.c b/targets/TARGET_NORDIC/TARGET_NRF5/us_ticker.c index bde1be74734..d03b55c9cc9 100644 --- a/targets/TARGET_NORDIC/TARGET_NRF5/us_ticker.c +++ b/targets/TARGET_NORDIC/TARGET_NRF5/us_ticker.c @@ -103,9 +103,6 @@ __STATIC_INLINE void errata_20(void) #endif } -#if (defined (__ICCARM__)) && defined(TARGET_MCU_NRF51822)//IAR -__stackless __task -#endif void RTC1_IRQHandler(void); void common_rtc_init(void) @@ -299,169 +296,70 @@ void us_ticker_clear_interrupt(void) */ static uint32_t previous_tick_cc_value = 0; +/* The Period of RTC oscillator, unit [1/RTC1_CONFIG_FREQUENCY] */ +static uint32_t os_rtc_period; + +/* Variable for frozen RTC1 counter value. It is used when system timer is disabled. */ +static uint32_t frozen_sub_tick = 0; + + /* RTX provide the following definitions which are used by the tick code: - * os_trv: The number (minus 1) of clock cycle between two tick. - * os_clockrate: Time duration between two ticks (in us). - * OS_Tick_Handler: The function which handle a tick event. + * osRtxConfig.tick_freq: The RTX tick frequency. + * osRtxInfo.kernel.tick: Count of RTX ticks. + + * SysTick_Handler: The function which handle a tick event. This function is special because it never returns. Those definitions are used by the code which handle the os tick. To allow compilation of us_ticker programs without RTOS, those symbols are exported from this module as weak ones. */ -MBED_WEAK uint32_t const os_trv; -MBED_WEAK uint32_t const os_clockrate; -MBED_WEAK void OS_Tick_Handler(void) +MBED_WEAK void SysTick_Handler(void) { } -#if defined (__CC_ARM) /* ARMCC Compiler */ - -__asm void COMMON_RTC_IRQ_HANDLER(void) -{ - IMPORT OS_Tick_Handler - IMPORT common_rtc_irq_handler - - /** - * Chanel 1 of RTC1 is used by RTX as a systick. - * If the compare event on channel 1 is set, then branch to OS_Tick_Handler. - * Otherwise, just execute common_rtc_irq_handler. - * This function has to be written in assembly and tagged as naked because OS_Tick_Handler - * will never return. - * A c function would put lr on the stack before calling OS_Tick_Handler and this value - * would never been dequeued. - * - * \code - * void COMMON_RTC_IRQ_HANDLER(void) { - if(NRF_RTC1->EVENTS_COMPARE[1]) { - // never return... - OS_Tick_Handler(); - } else { - common_rtc_irq_handler(); - } - } - * \endcode - */ - ldr r0,=0x40011144 - ldr r1, [r0, #0] - cmp r1, #0 - beq US_TICKER_HANDLER - bl OS_Tick_Handler -US_TICKER_HANDLER - push {r3, lr} - bl common_rtc_irq_handler - pop {r3, pc} - ; ALIGN ; -} +#ifdef MBED_CONF_RTOS_PRESENT + #include "rtx_os.h" //import osRtxInfo, SysTick_Handler() + + static inline void clear_tick_interrupt(); +#endif -#elif defined (__GNUC__) /* GNU Compiler */ +#ifndef RTC1_CONFIG_FREQUENCY + #define RTC1_CONFIG_FREQUENCY 32678 // [Hz] +#endif -__attribute__((naked)) void COMMON_RTC_IRQ_HANDLER(void) -{ - /** - * Chanel 1 of RTC1 is used by RTX as a systick. - * If the compare event on channel 1 is set, then branch to OS_Tick_Handler. - * Otherwise, just execute common_rtc_irq_handler. - * This function has to be written in assembly and tagged as naked because OS_Tick_Handler - * will never return. - * A c function would put lr on the stack before calling OS_Tick_Handler and this value - * would never been dequeued. - * - * \code - * void COMMON_RTC_IRQ_HANDLER(void) { - if(NRF_RTC1->EVENTS_COMPARE[1]) { - // never return... - OS_Tick_Handler(); - } else { - common_rtc_irq_handler(); - } - } - * \endcode - */ - __asm__ ( - "ldr r0,=0x40011144\n" - "ldr r1, [r0, #0]\n" - "cmp r1, #0\n" - "beq US_TICKER_HANDLER\n" - "bl OS_Tick_Handler\n" - "US_TICKER_HANDLER:\n" - "push {r3, lr}\n" - "bl common_rtc_irq_handler\n" - "pop {r3, pc}\n" - "nop" - ); -} -#elif defined (__ICCARM__)//IAR -void common_rtc_irq_handler(void); -__stackless __task void COMMON_RTC_IRQ_HANDLER(void) +void COMMON_RTC_IRQ_HANDLER(void) { - uint32_t temp; - - __asm volatile( - " ldr %[temp], [%[reg2check]] \n" - " cmp %[temp], #0 \n" - " beq 1f \n" - " bl.w OS_Tick_Handler \n" - "1: \n" - " push {r3, lr}\n" - " blx %[rtc_irq] \n" - " pop {r3, pc}\n" - - : /* Outputs */ - [temp] "=&r"(temp) - : /* Inputs */ - [reg2check] "r"(0x40011144), - [rtc_irq] "r"(common_rtc_irq_handler) - : /* Clobbers */ - "cc" - ); - (void)temp; -} - - -#else - -#error Compiler not supported. -#error Provide a definition of COMMON_RTC_IRQ_HANDLER. - -/* - * Chanel 1 of RTC1 is used by RTX as a systick. - * If the compare event on channel 1 is set, then branch to OS_Tick_Handler. - * Otherwise, just execute common_rtc_irq_handler. - * This function has to be written in assembly and tagged as naked because OS_Tick_Handler - * will never return. - * A c function would put lr on the stack before calling OS_Tick_Handler and this value - * will never been dequeued. After a certain time a stack overflow will happen. - * - * \code - * void COMMON_RTC_IRQ_HANDLER(void) { - if(NRF_RTC1->EVENTS_COMPARE[1]) { - // never return... - OS_Tick_Handler(); - } else { - common_rtc_irq_handler(); - } - } - * \endcode - */ + if(nrf_rtc_event_pending(COMMON_RTC_INSTANCE, OS_TICK_EVENT)) { +#ifdef MBED_CONF_RTOS_PRESENT + clear_tick_interrupt(); + // Trigger the SysTick_Handler just after exit form RTC Handler. + NVIC_SetPendingIRQ(SWI3_IRQn); + nrf_gpio_pin_set(11); #endif + } else { + common_rtc_irq_handler(); + } +} + +#ifdef MBED_CONF_RTOS_PRESENT /** * Return the next number of clock cycle needed for the next tick. - * @note This function has been carrefuly optimized for a systick occuring every 1000us. + * @note This function has been carefully optimized for a systick occurring every 1000us. */ static uint32_t get_next_tick_cc_delta() { uint32_t delta = 0; - if (os_clockrate != 1000) { + if (osRtxConfig.tick_freq != 1000) { // In RTX, by default SYSTICK is is used. // A tick event is generated every os_trv + 1 clock cycles of the system timer. - delta = os_trv + 1; + delta = os_rtc_period; } else { // If the clockrate is set to 1000us then 1000 tick should happen every second. // Unfortunatelly, when clockrate is set to 1000, os_trv is equal to 31. @@ -556,82 +454,89 @@ static void register_next_tick() __enable_irq(); } + /** * Initialize alternative hardware timer as RTX kernel timer * This function is directly called by RTX. * @note this function shouldn't be called directly. * @return IRQ number of the alternative hardware timer */ -int os_tick_init (void) +int32_t osRtxSysTimerSetup(void) { common_rtc_init(); + + os_rtc_period = (RTC1_CONFIG_FREQUENCY) / osRtxConfig.tick_freq; + + return nrf_drv_get_IRQn(COMMON_RTC_INSTANCE); +} + +// Start SysTickt timer emulation +void osRtxSysTimerEnable(void) +{ nrf_rtc_int_enable(COMMON_RTC_INSTANCE, OS_TICK_INT_MASK); - nrf_rtc_cc_set(COMMON_RTC_INSTANCE, OS_TICK_CC_CHANNEL, 0); + uint32_t current_cnt = nrf_rtc_counter_get(COMMON_RTC_INSTANCE); + nrf_rtc_cc_set(COMMON_RTC_INSTANCE, OS_TICK_CC_CHANNEL, current_cnt); register_next_tick(); - return nrf_drv_get_IRQn(COMMON_RTC_INSTANCE); + NVIC_SetVector(SWI3_IRQn, (uint32_t)SysTick_Handler); + NVIC_SetPriority(SWI3_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Emulated Systick Interrupt */ + NVIC_EnableIRQ(SWI3_IRQn); +} + +// Stop SysTickt timer emulation +void osRtxSysTimerDisable(void) +{ + nrf_rtc_int_disable(COMMON_RTC_INSTANCE, OS_TICK_INT_MASK); + + // RTC1 is free runing. osRtxSysTimerGetCount will return proper frozen value + // thanks to geting frozen value instead of RTC1 counter value + frozen_sub_tick = nrf_rtc_counter_get(COMMON_RTC_INSTANCE); } + + /** * Acknowledge the tick interrupt. * This function is called by the function OS_Tick_Handler of RTX. * @note this function shouldn't be called directly. */ -void os_tick_irqack(void) +void osRtxSysTimerAckIRQ(void) { - clear_tick_interrupt(); register_next_tick(); } -/** - * Returns the overflow flag of the alternative hardware timer. - * @note This function is exposed by RTX kernel. - * @return 1 if the timer has overflowed and 0 otherwise. - */ -uint32_t os_tick_ovf(void) +// provide a free running incremental value over the entire 32-bit range +uint32_t osRtxSysTimerGetCount(void) { - uint32_t current_counter = nrf_rtc_counter_get(COMMON_RTC_INSTANCE); - uint32_t next_tick_cc_value = nrf_rtc_cc_get(COMMON_RTC_INSTANCE, OS_TICK_CC_CHANNEL); - - return is_in_wrapped_range(previous_tick_cc_value, next_tick_cc_value, current_counter) ? 0 : 1; -} - -/** - * Return the value of the alternative hardware timer. - * @note The documentation is not very clear about what is expected as a result, - * is it an ascending counter, a descending one ? - * None of this is specified. - * The default systick is a descending counter and this function return values in - * descending order, even if the internal counter used is an ascending one. - * @return the value of the alternative hardware timer. - */ -uint32_t os_tick_val(void) -{ - uint32_t current_counter = nrf_rtc_counter_get(COMMON_RTC_INSTANCE); - uint32_t next_tick_cc_value = nrf_rtc_cc_get(COMMON_RTC_INSTANCE, OS_TICK_CC_CHANNEL); - - // do not use os_tick_ovf because its counter value can be different - if(is_in_wrapped_range(previous_tick_cc_value, next_tick_cc_value, current_counter)) { - if (next_tick_cc_value > previous_tick_cc_value) { - return next_tick_cc_value - current_counter; - } else if(current_counter <= next_tick_cc_value) { - return next_tick_cc_value - current_counter; + uint32_t current_cnt; + uint32_t sub_tick; + + if (nrf_rtc_int_is_enabled(COMMON_RTC_INSTANCE, OS_TICK_INT_MASK)) { + // system timer is enabled + current_cnt = nrf_rtc_counter_get(COMMON_RTC_INSTANCE); + + if (current_cnt >= previous_tick_cc_value) { + //0 prev current MAX + //|------|---------|------------|----> + sub_tick = current_cnt - previous_tick_cc_value; } else { - return next_tick_cc_value + (MAX_RTC_COUNTER_VAL - current_counter); + //0 current prev MAX + //|------|---------|------------|----> + sub_tick = MAX_RTC_COUNTER_VAL - previous_tick_cc_value + current_cnt; } - } else { - // use (os_trv + 1) has the base step, can be totally inacurate ... - uint32_t clock_cycles_by_tick = os_trv + 1; - - // if current counter has wrap arround, add the limit to it. - if (current_counter < next_tick_cc_value) { - current_counter = current_counter + MAX_RTC_COUNTER_VAL; - } - - return clock_cycles_by_tick - ((current_counter - next_tick_cc_value) % clock_cycles_by_tick); + } else { // system timer is disabled + sub_tick = frozen_sub_tick; } + + return (os_rtc_period * osRtxInfo.kernel.tick) + sub_tick; +} +// Timer Tick frequency +uint32_t osRtxSysTimerGetFreq (void) { + return RTC1_CONFIG_FREQUENCY; } +#endif // #ifdef MBED_CONF_RTOS_PRESENT + #endif // defined(TARGET_MCU_NRF51822) diff --git a/targets/TARGET_NORDIC/mbed_rtx.h b/targets/TARGET_NORDIC/mbed_rtx.h index 4318915f37e..5c0fa624ffb 100644 --- a/targets/TARGET_NORDIC/mbed_rtx.h +++ b/targets/TARGET_NORDIC/mbed_rtx.h @@ -27,9 +27,6 @@ # endif #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 7 -#endif #ifndef OS_MAINSTKSIZE #define OS_MAINSTKSIZE 512 #endif @@ -45,9 +42,6 @@ #ifndef INITIAL_SP #define INITIAL_SP (0x20010000UL) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 7 -#endif #ifndef OS_MAINSTKSIZE #define OS_MAINSTKSIZE 512 #endif diff --git a/targets/TARGET_NUVOTON/mbed_rtx.h b/targets/TARGET_NUVOTON/mbed_rtx.h index e948d3117cf..a8b9c13d3ea 100644 --- a/targets/TARGET_NUVOTON/mbed_rtx.h +++ b/targets/TARGET_NUVOTON/mbed_rtx.h @@ -17,11 +17,10 @@ #ifndef MBED_MBED_RTX_H #define MBED_MBED_RTX_H +#include + #if defined(TARGET_NUMAKER_PFM_NUC472) -#ifndef OS_TASKCNT -#define OS_TASKCNT 14 -#endif #ifndef OS_MAINSTKSIZE #define OS_MAINSTKSIZE 256 #endif @@ -55,9 +54,6 @@ #elif defined(TARGET_NUMAKER_PFM_M453) -#ifndef OS_TASKCNT -#define OS_TASKCNT 14 -#endif #ifndef OS_MAINSTKSIZE #define OS_MAINSTKSIZE 256 #endif diff --git a/targets/TARGET_NXP/mbed_rtx.h b/targets/TARGET_NXP/mbed_rtx.h index f7f2d97539c..c4b9ad33da3 100644 --- a/targets/TARGET_NXP/mbed_rtx.h +++ b/targets/TARGET_NXP/mbed_rtx.h @@ -22,9 +22,6 @@ #ifndef INITIAL_SP #define INITIAL_SP (0x10008000UL) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 14 -#endif #ifndef OS_MAINSTKSIZE #define OS_MAINSTKSIZE 256 #endif @@ -40,9 +37,6 @@ #ifndef INITIAL_SP #define INITIAL_SP (0x10002000UL) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 6 -#endif #ifndef OS_MAINSTKSIZE #define OS_MAINSTKSIZE 128 #endif @@ -55,9 +49,6 @@ #ifndef INITIAL_SP #define INITIAL_SP (0x10001000UL) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 6 -#endif #ifndef OS_MAINSTKSIZE #define OS_MAINSTKSIZE 128 #endif @@ -70,9 +61,6 @@ #ifndef INITIAL_SP #define INITIAL_SP (0x10002000UL) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 14 -#endif #ifndef OS_MAINSTKSIZE #define OS_MAINSTKSIZE 256 #endif @@ -85,9 +73,6 @@ #ifndef INITIAL_SP #define INITIAL_SP (0x02009000UL) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 14 -#endif #ifndef OS_MAINSTKSIZE #define OS_MAINSTKSIZE 256 #endif @@ -100,9 +85,6 @@ #ifndef INITIAL_SP #define INITIAL_SP (0x10008000UL) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 14 -#endif #ifndef OS_MAINSTKSIZE #define OS_MAINSTKSIZE 256 #endif @@ -115,9 +97,6 @@ #ifndef INITIAL_SP #define INITIAL_SP (0x10010000UL) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 14 -#endif #ifndef OS_MAINSTKSIZE #define OS_MAINSTKSIZE 256 #endif @@ -130,7 +109,6 @@ #ifndef INITIAL_SP #define INITIAL_SP (0x10008000UL) #endif -#define OS_TASKCNT 14 #ifndef OS_MAINSTKSIZE #define OS_MAINSTKSIZE 256 #endif @@ -143,9 +121,6 @@ #ifndef INITIAL_SP #define INITIAL_SP (0x10001000UL) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 6 -#endif #ifndef OS_MAINSTKSIZE #define OS_MAINSTKSIZE 128 #endif @@ -158,9 +133,6 @@ #ifndef INITIAL_SP #define INITIAL_SP (0x10002000UL) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 6 -#endif #ifndef OS_MAINSTKSIZE #define OS_MAINSTKSIZE 128 #endif diff --git a/targets/TARGET_ONSEMI/mbed_rtx.h b/targets/TARGET_ONSEMI/mbed_rtx.h index 897f3136789..c8fa8ad6d3a 100644 --- a/targets/TARGET_ONSEMI/mbed_rtx.h +++ b/targets/TARGET_ONSEMI/mbed_rtx.h @@ -22,9 +22,6 @@ #ifndef INITIAL_SP #define INITIAL_SP (0x40000000UL) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 14 -#endif #ifndef OS_MAINSTKSIZE #define OS_MAINSTKSIZE 256 #endif diff --git a/targets/TARGET_STM/mbed_rtx.h b/targets/TARGET_STM/mbed_rtx.h index f0d09701bf8..c2b0a2255bc 100644 --- a/targets/TARGET_STM/mbed_rtx.h +++ b/targets/TARGET_STM/mbed_rtx.h @@ -22,9 +22,6 @@ #ifndef INITIAL_SP #define INITIAL_SP (0x20002000UL) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 6 -#endif #ifndef OS_MAINSTKSIZE #define OS_MAINSTKSIZE 128 #endif @@ -37,9 +34,6 @@ #ifndef INITIAL_SP #define INITIAL_SP (0x20002000UL) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 6 -#endif #ifndef OS_MAINSTKSIZE #define OS_MAINSTKSIZE 112 #endif @@ -52,9 +46,6 @@ #ifndef INITIAL_SP #define INITIAL_SP (0x20004000UL) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 6 -#endif #ifndef OS_MAINSTKSIZE #define OS_MAINSTKSIZE 128 #endif @@ -67,9 +58,6 @@ #ifndef INITIAL_SP #define INITIAL_SP (0x20004000UL) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 6 -#endif #ifndef OS_MAINSTKSIZE #define OS_MAINSTKSIZE 128 #endif @@ -82,9 +70,6 @@ #ifndef INITIAL_SP #define INITIAL_SP (0x20008000UL) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 6 -#endif #ifndef OS_MAINSTKSIZE #define OS_MAINSTKSIZE 128 #endif @@ -97,9 +82,6 @@ #ifndef INITIAL_SP #define INITIAL_SP (0x20002000UL) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 6 -#endif #ifndef OS_MAINSTKSIZE #define OS_MAINSTKSIZE 128 #endif @@ -112,9 +94,6 @@ #ifndef INITIAL_SP #define INITIAL_SP (0x20005000UL) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 6 -#endif #ifndef OS_MAINSTKSIZE #define OS_MAINSTKSIZE 128 #endif @@ -127,9 +106,6 @@ #ifndef INITIAL_SP #define INITIAL_SP (0x20020000UL) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 14 -#endif #ifndef OS_MAINSTKSIZE #define OS_MAINSTKSIZE 256 #endif @@ -142,9 +118,6 @@ #ifndef INITIAL_SP #define INITIAL_SP (0x2000A000UL) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 14 -#endif #ifndef OS_MAINSTKSIZE #define OS_MAINSTKSIZE 256 #endif @@ -157,9 +130,6 @@ #ifndef INITIAL_SP #define INITIAL_SP (0x20003000UL) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 6 -#endif #ifndef OS_MAINSTKSIZE #define OS_MAINSTKSIZE 112 #endif @@ -172,9 +142,6 @@ #ifndef INITIAL_SP #define INITIAL_SP (0x20004000UL) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 6 -#endif #ifndef OS_MAINSTKSIZE #define OS_MAINSTKSIZE 128 #endif @@ -187,9 +154,6 @@ #ifndef INITIAL_SP #define INITIAL_SP (0x20003000UL) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 6 -#endif #ifndef OS_MAINSTKSIZE #define OS_MAINSTKSIZE 112 #endif @@ -202,9 +166,6 @@ #ifndef INITIAL_SP #define INITIAL_SP (0x20010000UL) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 6 -#endif #ifndef OS_MAINSTKSIZE #define OS_MAINSTKSIZE 112 #endif @@ -217,9 +178,6 @@ #ifndef INITIAL_SP #define INITIAL_SP (0x20010000UL) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 6 -#endif #ifndef OS_MAINSTKSIZE #define OS_MAINSTKSIZE 112 #endif @@ -232,9 +190,6 @@ #ifndef INITIAL_SP #define INITIAL_SP (0x20003000UL) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 6 -#endif #ifndef OS_MAINSTKSIZE #define OS_MAINSTKSIZE 112 #endif @@ -247,9 +202,6 @@ #ifndef INITIAL_SP #define INITIAL_SP (0x20020000UL) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 14 -#endif #ifndef OS_MAINSTKSIZE #define OS_MAINSTKSIZE 256 #endif @@ -262,9 +214,6 @@ #ifndef INITIAL_SP #define INITIAL_SP (0x20010000UL) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 14 -#endif #ifndef OS_MAINSTKSIZE #define OS_MAINSTKSIZE 256 #endif @@ -277,9 +226,6 @@ #ifndef INITIAL_SP #define INITIAL_SP (0x20030000UL) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 14 -#endif #ifndef OS_MAINSTKSIZE #define OS_MAINSTKSIZE 256 #endif @@ -292,9 +238,6 @@ #ifndef INITIAL_SP #define INITIAL_SP (0x20030000UL) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 14 -#endif #ifndef OS_MAINSTKSIZE #define OS_MAINSTKSIZE 512 #endif @@ -322,9 +265,6 @@ #ifndef INITIAL_SP #define INITIAL_SP (0x20050000UL) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 14 -#endif #ifndef OS_MAINSTKSIZE #define OS_MAINSTKSIZE 256 #endif @@ -337,9 +277,6 @@ #ifndef INITIAL_SP #define INITIAL_SP (0x20020000UL) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 14 -#endif #ifndef OS_MAINSTKSIZE #define OS_MAINSTKSIZE 256 #endif @@ -352,9 +289,6 @@ #ifndef INITIAL_SP #define INITIAL_SP (0x20018000UL) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 14 -#endif #ifndef OS_MAINSTKSIZE #define OS_MAINSTKSIZE 256 #endif @@ -367,9 +301,6 @@ #ifndef INITIAL_SP #define INITIAL_SP (0x20008000UL) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 14 -#endif #ifndef OS_MAINSTKSIZE #define OS_MAINSTKSIZE 256 #endif @@ -382,9 +313,6 @@ #ifndef INITIAL_SP #define INITIAL_SP (0x20020000UL) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 14 -#endif #ifndef OS_MAINSTKSIZE #define OS_MAINSTKSIZE 1024 #endif @@ -397,9 +325,6 @@ #ifndef INITIAL_SP #define INITIAL_SP (0x20020000UL) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 14 -#endif #ifndef OS_MAINSTKSIZE #define OS_MAINSTKSIZE 256 #endif @@ -427,9 +352,6 @@ #ifndef INITIAL_SP #define INITIAL_SP (0x20020000UL) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 14 -#endif #ifndef OS_MAINSTKSIZE #define OS_MAINSTKSIZE 256 #endif @@ -442,9 +364,6 @@ #ifndef INITIAL_SP #define INITIAL_SP (0x20020000UL) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 14 -#endif #ifndef OS_MAINSTKSIZE #define OS_MAINSTKSIZE 256 #endif @@ -457,9 +376,6 @@ #ifndef INITIAL_SP #define INITIAL_SP (0x20020000UL) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 14 -#endif #ifndef OS_MAINSTKSIZE #define OS_MAINSTKSIZE 256 #endif @@ -472,9 +388,6 @@ #ifndef INITIAL_SP #define INITIAL_SP (0x20050000UL) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 14 -#endif #ifndef OS_MAINSTKSIZE #define OS_MAINSTKSIZE 256 #endif @@ -487,9 +400,6 @@ #ifndef INITIAL_SP #define INITIAL_SP (0x20050000UL) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 14 -#endif #ifndef OS_MAINSTKSIZE #define OS_MAINSTKSIZE 256 #endif @@ -502,9 +412,6 @@ #ifndef INITIAL_SP #define INITIAL_SP (0x20080000UL) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 14 -#endif #ifndef OS_MAINSTKSIZE #define OS_MAINSTKSIZE 256 #endif @@ -517,9 +424,6 @@ #ifndef INITIAL_SP #define INITIAL_SP (0x20080000UL) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 14 -#endif #ifndef OS_MAINSTKSIZE #define OS_MAINSTKSIZE 256 #endif @@ -532,9 +436,6 @@ #ifndef INITIAL_SP #define INITIAL_SP (0x20002000UL) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 6 -#endif #ifndef OS_MAINSTKSIZE #define OS_MAINSTKSIZE 112 #endif @@ -547,9 +448,6 @@ #ifndef INITIAL_SP #define INITIAL_SP (0x20002000UL) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 6 -#endif #ifndef OS_MAINSTKSIZE #define OS_MAINSTKSIZE 112 #endif @@ -562,9 +460,6 @@ #ifndef INITIAL_SP #define INITIAL_SP (0x20002000UL) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 6 -#endif #ifndef OS_MAINSTKSIZE #define OS_MAINSTKSIZE 112 #endif @@ -592,9 +487,6 @@ #ifndef INITIAL_SP #define INITIAL_SP (0x20005000UL) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 6 -#endif #ifndef OS_MAINSTKSIZE #define OS_MAINSTKSIZE 112 #endif @@ -607,9 +499,6 @@ #ifndef INITIAL_SP #define INITIAL_SP (0x20008000UL) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 14 -#endif #ifndef OS_MAINSTKSIZE #define OS_MAINSTKSIZE 256 #endif @@ -622,9 +511,6 @@ #ifndef INITIAL_SP #define INITIAL_SP (0x20014000UL) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 14 -#endif #ifndef OS_MAINSTKSIZE #define OS_MAINSTKSIZE 256 #endif @@ -637,9 +523,6 @@ #ifndef INITIAL_SP #define INITIAL_SP (0x20008000UL) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 6 -#endif #ifndef OS_MAINSTKSIZE #define OS_MAINSTKSIZE 128 #endif @@ -652,9 +535,6 @@ #ifndef INITIAL_SP #define INITIAL_SP (0x20008000UL) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 6 -#endif #ifndef OS_MAINSTKSIZE #define OS_MAINSTKSIZE 128 #endif @@ -667,9 +547,6 @@ #ifndef INITIAL_SP #define INITIAL_SP (0x20018000UL) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 14 -#endif #ifndef OS_MAINSTKSIZE #define OS_MAINSTKSIZE 256 #endif @@ -682,9 +559,6 @@ #ifndef INITIAL_SP #define INITIAL_SP (0x2000C000UL) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 14 -#endif #ifndef OS_MAINSTKSIZE #define OS_MAINSTKSIZE 256 #endif @@ -697,9 +571,6 @@ #ifndef INITIAL_SP #define INITIAL_SP (0x20018000UL) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 14 -#endif #ifndef OS_MAINSTKSIZE #define OS_MAINSTKSIZE 256 #endif diff --git a/targets/TARGET_Silicon_Labs/mbed_rtx.h b/targets/TARGET_Silicon_Labs/mbed_rtx.h index 51dfdbb16db..00ff64e28b3 100644 --- a/targets/TARGET_Silicon_Labs/mbed_rtx.h +++ b/targets/TARGET_Silicon_Labs/mbed_rtx.h @@ -17,6 +17,7 @@ #ifndef MBED_MBED_RTX_H #define MBED_MBED_RTX_H +#include #include "clocking.h" #ifndef OS_CLOCK @@ -43,9 +44,6 @@ extern uint32_t STACK$$Base; #define INITIAL_SP (0x20020000UL) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 14 -#endif #ifndef OS_MAINSTKSIZE #define OS_MAINSTKSIZE 256 #endif @@ -56,9 +54,6 @@ extern uint32_t STACK$$Base; #define INITIAL_SP (0x20002000UL) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 6 -#endif #ifndef OS_MAINSTKSIZE #define OS_MAINSTKSIZE 112 #endif @@ -69,9 +64,6 @@ extern uint32_t STACK$$Base; #define INITIAL_SP (0x20008000UL) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 14 -#endif #ifndef OS_MAINSTKSIZE #define OS_MAINSTKSIZE 128 #endif @@ -82,9 +74,6 @@ extern uint32_t STACK$$Base; #define INITIAL_SP (0x20008000UL) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 14 -#endif #ifndef OS_MAINSTKSIZE #define OS_MAINSTKSIZE 128 #endif @@ -95,9 +84,6 @@ extern uint32_t STACK$$Base; #define INITIAL_SP (0x20008000UL) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 14 -#endif #ifndef OS_MAINSTKSIZE #define OS_MAINSTKSIZE 128 #endif diff --git a/targets/TARGET_ublox/mbed_rtx.h b/targets/TARGET_ublox/mbed_rtx.h index 98cf1d6d75f..2e5e2e7870c 100644 --- a/targets/TARGET_ublox/mbed_rtx.h +++ b/targets/TARGET_ublox/mbed_rtx.h @@ -23,9 +23,6 @@ #define INITIAL_SP (0x01000000 + 0x05000 - 256) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 6 -#endif #ifndef OS_MAINSTKSIZE #define OS_MAINSTKSIZE 128 #endif From 6be9e47a079956f41a5b9c9cb24aaa860935ef8d Mon Sep 17 00:00:00 2001 From: Jaeden Amero Date: Thu, 6 Apr 2017 17:57:39 +0100 Subject: [PATCH 10/24] uVisor: Import RTX5-capable uVisor Imported from 20170407_v7-M tag, commit e33f2739e961 "Make function in transition macro match target". --- features/FEATURE_UVISOR/AUTHORS.txt | 15 +- features/FEATURE_UVISOR/README.md | 191 +++++++----------- features/FEATURE_UVISOR/VERSION.txt | 2 +- .../includes/uvisor-lib/rtx/rtx_box_index.h | 15 +- .../includes/uvisor/api/inc/box_config.h | 14 +- .../uvisor/api/inc/lib_hook_exports.h | 2 +- .../uvisor/api/inc/uvisor_semaphore.h | 4 +- .../uvisor/api/inc/uvisor_semaphore_exports.h | 2 +- features/FEATURE_UVISOR/source/rtx/box_init.c | 60 +++--- .../source/rtx/rtx_malloc_wrapper.c | 17 +- .../source/rtx/secure_allocator.c | 74 +++++-- .../source/rtx/unsupported_page_allocator.c | 15 +- .../source/rtx/uvisor_semaphore.c | 31 +-- ...ration_beetle_cortex_m3_0x20000000_0x140.a | Bin 504854 -> 509950 bytes ...ration_beetle_cortex_m3_0x20000000_0x140.a | Bin 476954 -> 483114 bytes .../libconfiguration_efm32_cortex_m3_p1.a | Bin 504470 -> 510078 bytes .../libconfiguration_efm32_cortex_m4_p1.a | Bin 508878 -> 514486 bytes .../libconfiguration_efm32_cortex_m3_p1.a | Bin 476570 -> 482734 bytes .../libconfiguration_efm32_cortex_m4_p1.a | Bin 480978 -> 487142 bytes ...nfiguration_kinetis_cortex_m4_0x1fff0000.a | Bin 553910 -> 559522 bytes ...nfiguration_kinetis_cortex_m4_0x1fff0000.a | Bin 527546 -> 533710 bytes ...iguration_stm32_cortex_m4_0x10000000_0x0.a | Bin 510030 -> 515126 bytes ...iguration_stm32_cortex_m4_0x10000000_0x0.a | Bin 482126 -> 488290 bytes 23 files changed, 230 insertions(+), 212 deletions(-) diff --git a/features/FEATURE_UVISOR/AUTHORS.txt b/features/FEATURE_UVISOR/AUTHORS.txt index da80522e604..53ea7bb3257 100644 --- a/features/FEATURE_UVISOR/AUTHORS.txt +++ b/features/FEATURE_UVISOR/AUTHORS.txt @@ -1,15 +1,16 @@ 592 Milosch Meriac - 544 Alessandro Angelino - 98 Jaeden Amero - 64 Niklas Hauser - 4 Irit Arkin + 547 Alessandro Angelino + 105 Jaeden Amero + 65 Niklas Hauser + 5 Irit Arkin 3 Hugo Vincent - 3 JaredCJR 3 Jim Huang + 3 JaredCJR + 2 tonyyanxuan 2 Jan Jongboom 2 Nathan Chong 2 Vincenzo Frascino - 2 tonyyanxuan - 1 Aksel Skauge Mellbye 1 Amanda Butler + 1 Aksel Skauge Mellbye + 1 AnotherButler 1 ccli8 diff --git a/features/FEATURE_UVISOR/README.md b/features/FEATURE_UVISOR/README.md index 9160cdb5fe7..ae5cb2b31da 100644 --- a/features/FEATURE_UVISOR/README.md +++ b/features/FEATURE_UVISOR/README.md @@ -1,28 +1,28 @@ -# Quick-Start Guide for uVisor on mbed OS +# Getting started guide for uVisor on mbed OS -This guide will help you get started with uVisor on mbed OS by showing you how to create a sample application for the NXP FRDM-K64F board. +This guide will help you start uVisor on mbed OS by showing you how to create a sample application for the NXP FRDM-K64F board. -The uVisor provides sandboxed environments and resources protection for applications built for ARM Cortex-M3 and Cortex-M4 devices. We will show you how to enable the uVisor and configure a secure box to get hold of some exclusive resources (memory, peripherals, interrupts). For more information on the uVisor design philosophy, please check out our the uVisor [introductory document](../../README.md). +The uVisor provides sandboxed environments and resources protection for applications built for ARM Cortex-M3 and Cortex-M4 devices. This guide will show you how to enable the uVisor and configure a secure box to access some exclusive resources (memory, peripherals, interrupts). For more information about the uVisor design philosophy, please see the uVisor [introductory document](../../README.md). -## Overview +## Requirements -To get a basic `blinky` application running on mbed OS with uVisor enabled, you will need the following: +To run the `blinky` application on mbed OS with uVisor enabled, you need: -* A platform and a toolchain supported by uVisor on mbed OS. You can verify this on [the official list](../../README.md#supported-platforms). Please note that uVisor might support some platform internally, but not on mbed OS. Generally this means that the porting process is only partly complete. If you want to port your platform to uVisor and enable it on mbed OS, please follow the [uVisor Porting Guide for mbed OS](../core/PORTING.md). -* git. It will be used to download the mbed codebase. -* mbed-cli. You can run `pip install mbed-cli` to install it. +- A platform and a toolchain that uVisor on mbed OS supports. You can verify this on [the official list](../README.md#supported-platforms). If uVisor supports your platform internally but not on mbed OS, the porting process is incomplete. To port your platform to uVisor and enable it on mbed OS, please follow the [uVisor porting guide for mbed OS](../core/PORTING.md). +- Git. +- mbed CLI. Run `pip install mbed-cli` to install it. -For the remainder of this guide we will assume the following: +The remainder of this guide assumes: -* You are developing on a \*nix machine, in the `~/code` folder. -* You are building the app for the [NXP FRDM-K64F](http://developer.mbed.org/platforms/FRDM-K64F/) target, with the [GNU ARM Embedded Toolchain](https://launchpad.net/gcc-arm-embedded) toolchain. +- You are developing on a \*nix machine in the `~/code` folder. +- You are building the app for the [NXP FRDM-K64F](http://developer.mbed.org/platforms/FRDM-K64F/) target with the [GNU ARM Embedded Toolchain](https://launchpad.net/gcc-arm-embedded). You can use these instructions as guidelines in the case of other targets on other host OSs. ## Start with the `blinky` app [Go to top](#overview) -To create a new mbed application called `uvisor-example`, just run the following commands: +Create a new mbed application called `uvisor-example` by running the following commands: ```bash $ cd ~/code @@ -30,13 +30,13 @@ $ mbed new uvisor-example $ cd uvisor-example ``` -The mbed-cli tools will automatically fetch the mbed codebase for you. By default, git will be used to track your code changes, so your application will be ready to be pushed to a git server, if you want to. +The mbed CLI tools automatically fetch the mbed codebase. By default, Git tracks your code changes, so you can push your application to a Git server if you want to. -Once the import process is finished, create a `source` folder: +Once the import process finishes, create a `source` folder: ```bash $ mkdir ~/code/uvisor-example/source ``` -and place a new file `main.cpp` in it: +Place a new file `main.cpp` in it: ```C /* ~/code/uvisor-example/source/main.cpp */ @@ -66,25 +66,18 @@ Compile the application: $ mbed compile -m K64F -t GCC_ARM ``` -The resulting binary will be located at: +The resulting binary is located at: ```bash ~/code/uvisor-example/BUILD/K64F/GCC_ARM/uvisor-example.bin ``` -Drag and drop it onto the USB device mounted on your computer in order to flash the device. When the flashing process is completed, press the reset button on the device. You should see the device LED blinking. - ---- - -In the next sections you will see: - -* How to [enable uVisor](#enable-uvisor) on the `uvisor-example` app. -* How to [add a secure box](#add-a-secure-box) to the `uvisor-example` app with exclusive access to a timer, to a push-button interrupt, and to static and dynamic memories. +Drag and drop it onto the USB device mounted on your computer to flash the device. When the flashing process is complete, press the reset button on the device. The device's LED blinks. ## Enable uVisor [Go to top](#overview) -To enable the uVisor on the app, add the following lines at the beginning of the `main.cpp` file: +To enable the uVisor on the app, add these lines to the beginning of the `main.cpp` file: ```C /* ~/code/uvisor-example/source/main.cpp */ @@ -114,12 +107,12 @@ UVISOR_SET_MODE_ACL(UVISOR_ENABLED, g_public_box_acls); ... ``` -In the code above we specified 2 elements: +In the code above, we specified two elements: -1. Public box Access Control Lists (ACLs). Since with uVisor enabled everything runs in unprivileged mode, we need to make sure that peripherals that are accessed by the OS and the public box are allowed. These peripherals are specified using a list like the one in the snippet above. For the purpose of this example we provide you the list of all the ACLs that we know you will need. For other platforms or other applications you need to determine those ACLs following a process that is described in a [section](#the-main-box-acls) below. -1. App-specific uVisor configurations: `UVISOR_SET_MODE_ACL`. This macro sets the uVisor mode (enabled) and associates the list of ACLs we just created with the public box. +1. Public box Access Control Lists (ACLs). With uVisor enabled, everything runs in unprivileged mode, so make sure the public box and peripherals the OS accesses are allowed. These peripherals are specified using a list like the one in the snippet above. This example provides the list of all the ACLs you need. For other platforms or other applications, you need to determine those ACLs following the process in [The main box ACLs](#the-main-box-acls). +1. App-specific uVisor configurations: `UVISOR_SET_MODE_ACL`. This macro sets the uVisor mode (enabled) and associates the list of ACLs you just created with the public box. -Before compiling, we need to override the original `K64F` target to enable the uVisor feature. To do so, add the file `~/code/uvisor-example/mbed_app.json` with the following content: +Before compiling, you need to override the original `K64F` target to enable the uVisor feature. To do so, add the file `~/code/uvisor-example/mbed_app.json` with the following content: ```JSON { @@ -136,57 +129,57 @@ Before compiling, we need to override the original `K64F` target to enable the u } ``` -The macros `FEATURE_UVISOR` and `TARGET_UVISOR_SUPPORTED` in the configuration file above are automatically defined for C and C++ files, but not for assembly files. Because the uVisor relies on those symbols in some assembly code, we need to define them manually. +The macros `FEATURE_UVISOR` and `TARGET_UVISOR_SUPPORTED` in the configuration file above are automatically defined for C and C++ files but not for assembly files. Because the uVisor relies on those symbols in some assembly code, you need to define them manually. --- **Checkpoint** -Compile the application again. This time the `K64F` target will include the new features and labels we provided in `mbed_app.json`; +Compile the application again. This time, the `K64F` target includes the new features and labels you provided in `mbed_app.json`; ```bash $ mbed compile -m K64F -t GCC_ARM ``` -The binary will be located at: +The binary is located at: ```bash ~/code/uvisor-example/BUILD/K64F/GCC_ARM/uvisor-example.bin ``` -Reflash the device and press the reset button. The device LED should be blinking as in the previous case. +Reflash the device, and press the reset button. The device LED blinks as in the previous case. --- -If you enable uVisor in the `blinky` app as it was written above, you will not get any particular security feature. All code and resources share the same security context, which we call the *public box*. +If you enable uVisor in the `blinky` app as it was written above, you do not get any particular security feature. All code and resources share the same security context, which we call the *public box*. -A lot happens unseen, though. All the user code now runs in unprivileged mode, and the systems services such as the `NVIC` APIs and the OS SVCalls are routed through the uVisor. +A lot happens unseen, though. All the user code now runs in unprivileged mode, and the systems services, such as the `NVIC` APIs and the OS SVCalls, are routed through the uVisor. ## Add a secure box [Go to top](#overview) -Now that uVisor is enabled, we can finally add a *secure box*. +Now that uVisor is enabled, you can finally add a *secure box*. -A secure box is a special compartment that is granted exclusive access to peripherals, memories and interrupts. Private resources are only accessible when the *context* of the secure box is active. The uVisor is the only one that can enable a secure box context, for example upon thread switching or interrupt handling. +A secure box is a special compartment with exclusive access to peripherals, memories and interrupts. Private resources are only accessible when the *context* of the secure box is active. The uVisor is the only one that can enable a secure box context, for example upon thread switching or interrupt handling. uVisor does not obfuscate code that belongs to a box, so it is still readable and executable from outside of the box. In addition, declaring an object in the same file that configures a secure box does not protect that object automatically. -Instead, we provide specific APIs to instruct the uVisor to protect a private resource. We will show how to use these APIs in the `uvisor-example` app. +Instead, we provide specific APIs to instruct the uVisor to protect a private resource. The `uvisor-example` app will show how to use these APIs. ### Configure the secure box For this example, we want to create a secure box called `private_button`. The `private_button` box has exclusive access to the push-button on the NXP FRDM-K64F board, which means that other boxes cannot access its corresponding peripheral. -Each secure box must have at least one thread, which we call the box's main thread. In our `private_button` box we only use this thread throughout the whole program. The thread runs every second and counts the number of times it has been called between 2 button presses. The thread count is saved in a variable private to the box. Whenever we press the `SW2` button on the board the current thread count is stored into a private buffer and is restarted. For debug purposes, the program prints the content of the buffer every time it is filled up. +Each secure box must have at least one thread, which we call the box's main thread. In our `private_button` box, we only use this thread throughout the whole program. The thread runs every second and counts the number of times it has been called between two button presses. The thread count is saved in a variable private to the box. Whenever we press the `SW2` button on the board, the current thread count is stored into a private buffer and restarts. For debug purposes, the program prints the content of the buffer every time it fills up. -We want the box to have exclusive access to the following resources: +You want the box to have exclusive access to the following resources: -* The push-button peripheral (as specified by a peripheral ACL). Nobody else should be able to access the push-button port. -* The push-button interrupt (as specified by an IRQ ACL). We want the button IRQ to be rerouted to our box-specific ISR. -* The private dynamically allocated buffer (as specified by a dynamic memory ACL). -* The private variables (as specified by a static memory ACL). +- The push-button peripheral (as specified by a peripheral ACL). Nobody else should be able to access the push-button port. +- The push-button interrupt (as specified by an IRQ ACL). You want the button IRQ to reroute to our box-specific ISR. +- The private dynamically allocated buffer (as specified by a dynamic memory ACL). +- The private variables (as specified by a static memory ACL). -Create a new source file, `~/code/uvisor-example/source/secure_box.cpp`. We will configure the secure box inside this file. The secure box name for this example is `private_button`. +Create a new source file, `~/code/uvisor-example/source/secure_box.cpp`. You will configure the secure box inside this file. The secure box name for this example is `private_button`. ```C /* ~/code/uvisor-example/source/secure_box.cpp */ @@ -223,9 +216,9 @@ UVISOR_BOX_CONFIG(private_button, /* Name of the secure box */ ### Create the secure box's main thread function -In general, you can decide what to do in your box's main thread. You can run it once and then stop it, or use it to configure memories or peripherals or to create other threads. In this app, the box's main thread is the only thread for the `private_button` box, and it runs throughout the whole program. +In general, you can decide what to do in your box's main thread. You can run it once and then stop it or use it to configure memories or peripherals or to create other threads. In this app, the box's main thread is the only thread for the `private_button` box, and it runs throughout the program. -The `private_button_main_thread` function configures the push-button to trigger an interrupt when pressed, allocates the dynamic buffer to hold the thread count values and initializes its private static memory, `PrivateButtonStaticMemory`. A spinning loop is used to update the counter value every second. +The `private_button_main_thread` function configures the push-button to trigger an interrupt when pressed, allocates the dynamic buffer to hold the thread count values and initializes its private static memory, `PrivateButtonStaticMemory`. A spinning loop updates the counter value every second. ```C /* ~/code/uvisor-example/source/secure_box.cpp */ @@ -291,12 +284,12 @@ static void private_button_main_thread(const void *) A few things to note in the code above: -* If code is running in the context of `private_button`, then any object instantiated inside that code will belong to the `private_button` heap and stack. This means that in the example above, the `InterruptIn` object is private to the `private_button` box. The same applies to the dynamically allocated buffer `uvisor_ctx->buffer`. -* You can access the content of the private memory `PrivateButtonStaticMemory` using the `void * const __uvisor_ctx` pointer, which uVisor maintains. You need to cast this pointer to your own context type. In this example we used a pre-processor symbol to improve readability. -* The `InterruptIn` object triggers the registration of an interrupt slot. Because that code is run in the context of the `private_button` box, then the push-button IRQ belongs to that box. If you want to use the IRQ APIs directly, read the [section](#the-nvic-apis) below. -* Even if the `private_button_on_press` function runs in the context of `private_button`, we can still use the `printf` function, which accesses the `UART0` peripheral, owned by the public box. This is because all ACLs declared in the public box are by default shared with all the other secure boxes. This also means that the messages we are printing on the serial port are not secure, because other boxes have access to that peripheral. +- If code runs in the context of `private_button`, then any object instantiated inside that code belongs to the `private_button` heap and stack. This means that in the example above, the `InterruptIn` object is private to the `private_button` box. The same applies to the dynamically allocated buffer `uvisor_ctx->buffer`. +- You can access the content of the private memory `PrivateButtonStaticMemory` using the `void * const __uvisor_ctx` pointer, which uVisor maintains. You need to cast this pointer to your own context type. In this example we used a pre-processor symbol to improve readability. +- The `InterruptIn` object triggers the registration of an interrupt slot. Because that code runs in the context of the `private_button` box, the push-button IRQ belongs to that box. If you want to use the IRQ APIs directly, read the [NVIC APIs section](#the-nvic-apis) below. +- Even if the `private_button_on_press` function runs in the context of `private_button`, you can still use the `printf` function, which accesses the `UART0` peripheral, owned by the public box. This is because all ACLs declared in the public box are by default shared with all the other secure boxes. This also means that the messages we are printing on the serial port are not secure because other boxes have access to that peripheral. -> **Warning**: Instantiating an object in the `secure_box.cpp` global scope will automatically map it to the public box context, not the `private_button` one. If you want an object to be private to a box, you need to instantiate it inside the code that runs in the context of that box (such as the `InterruptIn` object), or alternatively statically initialize it in the box private static memory (such as the `buffer`, `index` and `counter` variables in `PrivateButtonStaticMemory`). +> **Warning**: Instantiating an object in the `secure_box.cpp` global scope automatically maps it to the public box context, not the `private_button` one. If you want an object to be private to a box, you need to instantiate it inside the code that runs in the context of that box (such as the `InterruptIn` object), or alternatively statically initialize it in the box private static memory (such as the `buffer`, `index` and `counter` variables in `PrivateButtonStaticMemory`). --- @@ -308,13 +301,14 @@ Compile the application again: $ mbed compile -m K64F -t GCC_ARM ``` -Reflash the device, and press the reset button. The device LED should be blinking as in the previous case. +Reflash the device, and press the reset button. The device LED blinks. -If you don't see the LED blinking, it means that the application halted somewhere, probably because uVisor captured a fault. You can set up the uVisor debug messages to see if there is any problem. Follow the [Debugging uVisor on mbed OS](DEBUGGING.md) document for a step-by-step guide. +If the LED doens't blink, it means the application halted somewhere, probably because uVisor captured a fault. You can set up the uVisor debug messages to see if there is a problem. See [Debugging uVisor on mbed OS](DEBUGGING.md) for a step-by-step guide. -If the LED is blinking, it means that the app is running fine. If you now press the `SW2` button on the NXP FRDM-K64F board, the `private_button_on_press` function will be executed, printing the values in the timer buffer after `PRIVATE_BUTTON_BUFFER_COUNT` presses. You can observe these values by opening a serial port connection to the device, with a baud rate of 9600. +If the LED is blinking, the app is running correctly. If you press the `SW2` button on the NXP FRDM-K64F board, the `private_button_on_press` function executes, printing the values in the timer buffer after `PRIVATE_BUTTON_BUFFER_COUNT` presses. You can observe these values by opening a serial port connection to the device, with a baud rate of 9600. ## Expose public secure entry points to the secure box +[Go to top](#overview) So far the code in the secure box cannot communicate to other boxes. To let other boxes call functions in our secure box you can define public secure entry points. These entry points can map to private functions within the context of a secure box, and the arguments and return values are automatically serialized using an RPC protocol to ensure no private memory can be leaked to external boxes. @@ -352,7 +346,7 @@ static int get_index() { UVISOR_BOX_RPC_GATEWAY_SYNC (private_button, secure_get_index, get_index, int, void); -#define PRIVATE_BUTTON_BUFFER_COUNT 8 + #define PRIVATE_BUTTON_BUFFER_COUNT 8 ``` ### Listening for RPC messages @@ -395,7 +389,7 @@ static void private_button_main_thread(const void *) ### Calling the public secure entry point -To call the public secure entry point from any other box, you can use the `secure_get_index` function. It will automatically do an RPC call into the secure box and serialize the return value. You can try this out from the main box. In `~/code/uvisor-example/source/main.cpp`, first include the header file for the secure box: +To call the public secure entry point from any other box, you can use the `secure_get_index` function. It will automatically do an RPC call into the secure box and serialize the return value. You can try this out from the public box. In `~/code/uvisor-example/source/main.cpp`, first include the header file for the secure box: ```cpp /* ~/code/uvisor-example/source/main.cpp */ @@ -420,44 +414,18 @@ int main(void) You can observe the secure index by opening a serial port connection to the device, with a baud rate of 9600. When you press the `SW2` button the index will be increased. -## Wrap-up -[Go to top](#overview) - -In this guide we showed you how to: - -* Enable uVisor on an existing application. -* Add a secure box to your application. - * Protect static and dynamic memories in a secure box. - * Gain exclusive access to a peripheral and an IRQ in a secure box. - * Expose public secure entry points to a secure box. - -You can now modify the example or create a new one to protect your resources into a secure box. You may find the following resources useful: - -* [uVisor API documentation](API.md). -* [Debugging uVisor on mbed OS](DEBUGGING.md). - -If you found any bug or inconsistency in this guide, please [raise an issue](https://github.com/ARMmbed/uvisor/issues/new). - -## Appendix -[Go to top](#overview) - -This section contains additional information that you may find useful when setting up a secure box. +## The NVIC APIs -### The NVIC APIs - -The ARM CMSIS header files provide APIs to configure, enable and disable IRQs in the NVIC module. These APIs are all prefixed with `NVIC_` and can be found in the `core_cm*.h` files in your CMSIS module. - -In addition, the CMSIS header files also provide APIs to set and get an interrupt vector at runtime. This requires the interrupt vector table, which is usually located in flash, to be relocated to SRAM. +The ARM CMSIS header files provide APIs to configure, enable and disable IRQs in the NVIC module. These APIs all begin with `NVIC_`, and you can find them in the `core_cm*.h` files in your CMSIS module. The CMSIS header files also provide APIs to set and get an interrupt vector at runtime. This requires the relocation of the interrupt vector table, which is usually located in flash, to SRAM. When the uVisor is enabled, all NVIC APIs are rerouted to the corresponding uVisor vIRQ APIs, which virtualize the interrupt module. The uVisor interrupt model has the following features: -* The uVisor owns the interrupt vector table. -* All ISRs are relocated to SRAM. -* The first call to any NVIC API will register the IRQ for exclusive use with the active box. IRQs cannot be unregistered. -* Code in a box can only change the state of an IRQ (enable it, change its priority, etc.) if the box registered that IRQ with uVisor at runtime first. -* An IRQ that belongs to a box can only be modified when that box context is active. +- The uVisor owns the interrupt vector table. +- All ISRs are relocated to SRAM. +- Code in a box can only change the state of an IRQ (enable it, change its priority, etc.) if the box registered that IRQ with uVisor at runtime, using the `NVIC_SetVector` API. +- An IRQ that belongs to a box can only be modified when that box context is active. -Although this behaviour is different from the original NVIC one, it is backward compatible. This means that legacy code (like a device HAL) will still work after uVisor is enabled. The general use case is the following: +Although this behavior is different from that of the original NVIC, it is backward compatible. Legacy code (such as a device HAL) still works after uVisor is enabled. The general use case is the following: ```C #define MY_IRQ 42 @@ -473,34 +441,22 @@ NVIC_SetPriority(MY_IRQ, 3); NVIC_EnableIRQ(MY_IRQ); ``` -> **Note**: When enabling the IRQ before setting the vector, uVisor uses the handler specified in the original vector table. This mirrors the NVIC hardware behavior. - -For more information on the uVisor APIs, see the [uVisor API documentation](API.md) document. - -### The *public box* ACLs +> **Note**: In this model, a call to `NVIC_SetVector` must happen before an IRQ state changes. In platforms that don't relocate the interrupt vector table, such a call might be absent and must be added to work with uVisor. -The code samples that we provide in this guide give you a ready-made list of ACLs for the public box. The list includes peripherals that we already know will be necessary to make the example app work, and it is specific to the NXP FRDM-K64F target. +## The *public box* ACLs -This section shows how to discover the needed ACLs for the public box. You might need to follow these instructions in case you want to generate the ACLs list for a different target or a different app. +The code samples in this guide provide a list of ACLs for the public box. The list includes peripherals necessary to make the example app work, and they are specific to the NXP FRDM-K64F target. -At the moment the uVisor does not provide a way to detect and list all the faulting ACLs for a given platform automatically. This is a planned feature that will be released in the future. - -In order to generate the list of ACLs, use the code provided in the [Enable uVisor](#enable-uvisor) section. In this case, though, start with an empty ACLs list: +To generate the ACLs list for a different target or a different app, use the code provided in the [Enable uVisor](#enable-uvisor) section, but start with an empty ACLs list: ```C static const UvisorBoxAclItem g_public_box_acls[] = { } ``` -You now need to compile your application using uVisor in debug mode. This operation requires some more advanced steps, which are described in detail in the [Debugging uVisor on mbed OS](DEBUGGING.md) document. The main idea is that you compile the application in debug mode: - -```bash -$ mbed compile -m K64F -t GCC_ARM --profile mbed-os/tools/profiles/debug.json -``` +Compile your application using uVisor in debug mode. This operation requires some more advanced steps. Please read [Debugging uVisor on mbed OS](DEBUGGING.md) for the detailed instructions. -and then use a GDB-compatible interface to flash the device, enable semihosting and access the uVisor debug messages. Please read the [Debugging uVisor on mbed OS](DEBUGGING.md) document for the detailed instructions. - -Once the uVisor debug messages are enabled, you will see your application fail. The failure is due to the first missing ACL being hit by the public box code. The message will look like: +Once the uVisor debug messages are enabled, your application fails. The failure is due to the first missing ACL being hit by the public box code. The message will look like: ``` *********************************************************** @@ -509,7 +465,7 @@ Once the uVisor debug messages are enabled, you will see your application fail. ... -* MEMORY MAP +/* MEMORY MAP Address: 0x4004800C Region/Peripheral: SIM Base address: 0x40047000 @@ -518,8 +474,7 @@ Once the uVisor debug messages are enabled, you will see your application fail. ... ``` -Now that you know which peripheral is causing the fault (the `SIM` peripheral, in this example), you can add its entry to the ACLs list: - +Once you know which peripheral is causing the fault (the `SIM` peripheral, in this example), add its entry to the ACLs list: ```C static const UvisorBoxAclItem g_public_box_acls[] = { @@ -527,8 +482,16 @@ static const UvisorBoxAclItem g_public_box_acls[] = { }; ``` -> **Note**: If the fault debug screen does not show the name of the peripheral, you need to look it up in the target device reference manual. +> **Note**: If the fault debug screen does not show the name of the peripheral, look it up in the target device reference manual. -For readability, do not use the hard-coded addresses of your peripherals, but rather use the symbols that the target CMSIS module provides. +For readability, do not use the hard-coded addresses of your peripherals. Instead, use the symbols that the target CMSIS module provides. -Repeat the process multiple times until all ACLs have been added to the list. When no other ACL is needed any more, the system will run without hitting a uVisor fault. +Repeat the process multiple times until all ACLs have been added to the list. When no other ACL is needed, the system runs without hitting a uVisor fault. + +## Additional resources +[Go to top](#overview) + +- [uVisor API documentation](API.md). +- [Debugging uVisor on mbed OS](DEBUGGING.md). + +If you found any bug or inconsistency in this guide, please [raise an issue](https://github.com/ARMmbed/uvisor/issues/new). diff --git a/features/FEATURE_UVISOR/VERSION.txt b/features/FEATURE_UVISOR/VERSION.txt index 0a8bf80d69f..899f060ab16 100644 --- a/features/FEATURE_UVISOR/VERSION.txt +++ b/features/FEATURE_UVISOR/VERSION.txt @@ -1 +1 @@ -v0.27.0 +20170407_v7-M diff --git a/features/FEATURE_UVISOR/includes/uvisor-lib/rtx/rtx_box_index.h b/features/FEATURE_UVISOR/includes/uvisor-lib/rtx/rtx_box_index.h index ebdf45087a9..3275e8de3d9 100644 --- a/features/FEATURE_UVISOR/includes/uvisor-lib/rtx/rtx_box_index.h +++ b/features/FEATURE_UVISOR/includes/uvisor-lib/rtx/rtx_box_index.h @@ -17,7 +17,8 @@ #ifndef __RTX_BOX_INDEX_H__ #define __RTX_BOX_INDEX_H__ -#include "cmsis_os.h" +#include "cmsis_os2.h" +#include "rtx_os.h" #ifdef __cplusplus extern "C" { @@ -28,12 +29,14 @@ typedef struct /* The uvisor box index must be placed at the beginning */ UvisorBoxIndex index; - /* Id of the mutex */ - osMutexId mutex_id; - /* Pointer to the data of the mutex */ - osMutexDef_t mutex; + /* ID of the mutex */ + osMutexId_t mutex_id; + + /* Attribute of the mutex */ + osMutexAttr_t mutex_attr; + /* Internal data of the mutex */ - int32_t mutex_data[4]; + osRtxMutex_t mutex_data; } RtxBoxIndex; #ifdef __cplusplus diff --git a/features/FEATURE_UVISOR/includes/uvisor/api/inc/box_config.h b/features/FEATURE_UVISOR/includes/uvisor/api/inc/box_config.h index def616db778..b4cbbf34f40 100644 --- a/features/FEATURE_UVISOR/includes/uvisor/api/inc/box_config.h +++ b/features/FEATURE_UVISOR/includes/uvisor/api/inc/box_config.h @@ -26,6 +26,12 @@ UVISOR_EXTERN const uint32_t __uvisor_mode; UVISOR_EXTERN void const * const public_box_cfg_ptr; +typedef struct { + void (*function)(void *); + size_t priority; + size_t stack_size; +} uvisor_box_main_t; + #define UVISOR_DISABLED 0 #define UVISOR_PERMISSIVE 1 #define UVISOR_ENABLED 2 @@ -145,8 +151,12 @@ UVISOR_EXTERN void const * const public_box_cfg_ptr; * thread of your box will use for its body. If you don't want a main thread, * too bad: you have to have one. */ #define UVISOR_BOX_MAIN(function, priority, stack_size) \ - static osThreadDef(function, priority, stack_size); \ - static const void * const __uvisor_box_lib_config = osThread(function); + static const uvisor_box_main_t __uvisor_box_main = { \ + function, \ + priority, \ + stack_size, \ + }; \ + static const void * const __uvisor_box_lib_config = &__uvisor_box_main; #define UVISOR_BOX_HEAPSIZE(heap_size) \ static const uint32_t __uvisor_box_heapsize = heap_size; diff --git a/features/FEATURE_UVISOR/includes/uvisor/api/inc/lib_hook_exports.h b/features/FEATURE_UVISOR/includes/uvisor/api/inc/lib_hook_exports.h index 4d8300ab2cf..74c790d43e2 100644 --- a/features/FEATURE_UVISOR/includes/uvisor/api/inc/lib_hook_exports.h +++ b/features/FEATURE_UVISOR/includes/uvisor/api/inc/lib_hook_exports.h @@ -29,7 +29,7 @@ typedef struct uvisor_semaphore UvisorSemaphore; * These functions will be run by unprivileged code only. */ typedef struct { void (*box_init)(void * lib_config); - int (*semaphore_init)(UvisorSemaphore * semaphore, int32_t count); + int (*semaphore_init)(UvisorSemaphore * semaphore, uint32_t initial_count, uint32_t max_count); int (*semaphore_pend)(UvisorSemaphore * semaphore, uint32_t timeout_ms); } UvisorLibHooks; diff --git a/features/FEATURE_UVISOR/includes/uvisor/api/inc/uvisor_semaphore.h b/features/FEATURE_UVISOR/includes/uvisor/api/inc/uvisor_semaphore.h index 5dbb6f6968b..a5ce6801ec6 100644 --- a/features/FEATURE_UVISOR/includes/uvisor/api/inc/uvisor_semaphore.h +++ b/features/FEATURE_UVISOR/includes/uvisor/api/inc/uvisor_semaphore.h @@ -19,7 +19,9 @@ #include "api/inc/uvisor_semaphore_exports.h" -UVISOR_EXTERN int __uvisor_semaphore_init(UvisorSemaphore * semaphore, int32_t count); +/* Initialize a semaphore with the specified initial count. This function is + * not safe to call from interrupt context. */ +UVISOR_EXTERN int __uvisor_semaphore_init(UvisorSemaphore * semaphore, uint32_t initial_count, uint32_t max_count); /* This function is not safe to call from interrupt context, even if the * timeout is zero. */ diff --git a/features/FEATURE_UVISOR/includes/uvisor/api/inc/uvisor_semaphore_exports.h b/features/FEATURE_UVISOR/includes/uvisor/api/inc/uvisor_semaphore_exports.h index 9839802aaba..b67efbff16e 100644 --- a/features/FEATURE_UVISOR/includes/uvisor/api/inc/uvisor_semaphore_exports.h +++ b/features/FEATURE_UVISOR/includes/uvisor/api/inc/uvisor_semaphore_exports.h @@ -20,7 +20,7 @@ #include "api/inc/uvisor_exports.h" /* This must be big enough for all operating systems uVisor runs on. */ -#define UVISOR_SEMAPHORE_INTERNAL_SIZE (16) +#define UVISOR_SEMAPHORE_INTERNAL_SIZE (36) /* An opaque structure, that one knows the size of so that they can allocate * memory. */ diff --git a/features/FEATURE_UVISOR/source/rtx/box_init.c b/features/FEATURE_UVISOR/source/rtx/box_init.c index b62255bcf6b..ba9715a8d99 100644 --- a/features/FEATURE_UVISOR/source/rtx/box_init.c +++ b/features/FEATURE_UVISOR/source/rtx/box_init.c @@ -18,8 +18,9 @@ #include "api/inc/pool_queue_exports.h" #include "api/inc/rpc_exports.h" #include "api/inc/uvisor_semaphore.h" +#include "api/inc/box_config.h" #include "mbed_interface.h" -#include "cmsis_os.h" +#include "cmsis_os2.h" #include #include @@ -27,9 +28,9 @@ extern void SVC_Handler(void); extern void PendSV_Handler(void); extern void SysTick_Handler(void); -extern uint32_t rt_suspend(void); +extern uint32_t svcRtxKernelLock(void); -UVISOR_SET_PRIV_SYS_HOOKS(SVC_Handler, PendSV_Handler, SysTick_Handler, rt_suspend, __uvisor_semaphore_post); +UVISOR_SET_PRIV_SYS_HOOKS(SVC_Handler, PendSV_Handler, SysTick_Handler, svcRtxKernelLock, __uvisor_semaphore_post); extern RtxBoxIndex * const __uvisor_ps; @@ -56,15 +57,7 @@ void __uvisor_initialize_rpc_queues(void) /* Initialize all the result semaphores. */ for (i = 0; i < UVISOR_RPC_OUTGOING_MESSAGE_SLOTS; i++) { UvisorSemaphore * semaphore = &rpc_outgoing_msg_queue->messages[i].semaphore; - if (__uvisor_semaphore_init(semaphore, 1)) { - uvisor_error(USER_NOT_ALLOWED); - } - - /* Semaphores are created with their value initialized to count. We - * want the semaphore to start at zero. Decrement the semaphore, so it - * starts with a value of zero. This will allow the first pend to - * block. */ - if (__uvisor_semaphore_pend(semaphore, 0)) { + if (__uvisor_semaphore_init(semaphore, 1, 0)) { uvisor_error(USER_NOT_ALLOWED); } } @@ -102,15 +95,7 @@ void __uvisor_initialize_rpc_queues(void) /* Initialize all the function group semaphores. */ for (i = 0; i < UVISOR_RPC_FN_GROUP_SLOTS; i++) { UvisorSemaphore * semaphore = &rpc_fn_group_queue->fn_groups[i].semaphore; - if (__uvisor_semaphore_init(semaphore, 1)) { - uvisor_error(USER_NOT_ALLOWED); - } - - /* Semaphores are created with their value initialized to count. We - * want the semaphore to start at zero. Decrement the semaphore, so it - * starts with a value of zero. This will allow the first pend to - * block. */ - if (__uvisor_semaphore_pend(semaphore, 0)) { + if (__uvisor_semaphore_init(semaphore, 1, 0)) { uvisor_error(USER_NOT_ALLOWED); } } @@ -120,16 +105,14 @@ void __uvisor_initialize_rpc_queues(void) * create box main threads for the box. */ void __uvisor_lib_box_init(void * lib_config) { - osThreadId thread_id; - osThreadDef_t * flash_thread_def = lib_config; - osThreadDef_t thread_def; + osThreadId_t thread_id; + uvisor_box_main_t * box_main = lib_config; + osThreadAttr_t thread_attr = { 0 }; __uvisor_initialize_rpc_queues(); - /* Copy thread definition from flash to RAM. The thread definition is most - * likely in flash, so we need to copy it to box-local RAM before we can - * modify it. */ - memcpy(&thread_def, flash_thread_def, sizeof(thread_def)); + thread_attr.priority = box_main->priority; + thread_attr.stack_size = box_main->stack_size; /* Note that the box main thread stack is separate from the box stack. This * is because the thread must be created to use a different stack than the @@ -138,17 +121,26 @@ void __uvisor_lib_box_init(void * lib_config) /* Allocate memory for the main thread from the process heap (which is * private to the process). This memory is never freed, even if the box's * main thread exits. */ - thread_def.stack_pointer = malloc_p(thread_def.stacksize); + thread_attr.stack_mem = malloc_p(thread_attr.stack_size); + if (thread_attr.stack_mem == NULL) { + /* No process heap memory available for thread stack */ + uvisor_error(USER_NOT_ALLOWED); + } - if (thread_def.stack_pointer == NULL) { - /* No process heap memory available */ - mbed_die(); + /* Allocate memory for the main thread control block from the process heap + * (which is private to the process). This memory is never freed, even if + * the box's main thread exits. */ + thread_attr.cb_size = sizeof(osRtxThread_t); + thread_attr.cb_mem = malloc_p(thread_attr.cb_size); + if (thread_attr.cb_mem == NULL) { + /* No process heap memory available for thread control block. */ + uvisor_error(USER_NOT_ALLOWED); } - thread_id = osThreadCreate(&thread_def, NULL); + thread_id = osThreadNew(box_main->function, NULL, &thread_attr); if (thread_id == NULL) { /* Failed to create thread */ - mbed_die(); + uvisor_error(USER_NOT_ALLOWED); } } diff --git a/features/FEATURE_UVISOR/source/rtx/rtx_malloc_wrapper.c b/features/FEATURE_UVISOR/source/rtx/rtx_malloc_wrapper.c index ab6676c5cfc..ce143829845 100644 --- a/features/FEATURE_UVISOR/source/rtx/rtx_malloc_wrapper.c +++ b/features/FEATURE_UVISOR/source/rtx/rtx_malloc_wrapper.c @@ -15,7 +15,7 @@ * limitations under the License. */ -#include "cmsis_os.h" +#include "cmsis_os2.h" #include "uvisor-lib/uvisor-lib.h" #include @@ -44,7 +44,7 @@ static int is_kernel_initialized() if (kernel_running) { return 1; } - if (osKernelRunning()) { + if (osKernelGetState() == osKernelRunning) { kernel_running = 1; return 1; } @@ -64,10 +64,13 @@ static int init_allocator() } if ((__uvisor_ps->mutex_id == NULL) && is_kernel_initialized()) { - /* Point the mutex pointer to the data. */ - __uvisor_ps->mutex.mutex = &(__uvisor_ps->mutex_data); + /* Point the mutex attr to the data. */ + __uvisor_ps->mutex_attr.attr_bits = 0; /* Non-recursive */ + __uvisor_ps->mutex_attr.cb_mem = &__uvisor_ps->mutex_data; + __uvisor_ps->mutex_attr.cb_size = sizeof(__uvisor_ps->mutex_data); + /* Create mutex if not already done. */ - __uvisor_ps->mutex_id = osMutexCreate(&(__uvisor_ps->mutex)); + __uvisor_ps->mutex_id = osMutexNew(&__uvisor_ps->mutex_attr); /* Mutex failed to be created. */ if (__uvisor_ps->mutex_id == NULL) { return -1; @@ -80,7 +83,7 @@ static int init_allocator() /* Lock the mutex during initialization. */ int kernel_initialized = is_kernel_initialized(); if (kernel_initialized) { - osMutexWait(__uvisor_ps->mutex_id, osWaitForever); + osMutexAcquire(__uvisor_ps->mutex_id, osWaitForever); } /* Initialize the process heap. */ SecureAllocator allocator = secure_allocator_create_with_pool( @@ -123,7 +126,7 @@ static void * memory(void * ptr, size_t size, int heap, int operation) * the `rt_alloc_mem` and `rt_free_mem` functions in `uvisor_allocator.c`. * However, it is simpler to do it here for now. */ if (mutexed) { - osMutexWait(__uvisor_ps->mutex_id, osWaitForever); + osMutexAcquire(__uvisor_ps->mutex_id, osWaitForever); } /* Perform the required operation. */ switch(operation) diff --git a/features/FEATURE_UVISOR/source/rtx/secure_allocator.c b/features/FEATURE_UVISOR/source/rtx/secure_allocator.c index c40e3890a28..dccbdbfcf53 100644 --- a/features/FEATURE_UVISOR/source/rtx/secure_allocator.c +++ b/features/FEATURE_UVISOR/source/rtx/secure_allocator.c @@ -15,8 +15,28 @@ * limitations under the License. */ -#include "rt_TypeDef.h" -#include "rt_Memory.h" +#include "rtx_lib.h" + +/* uVisor uses rtx_memory instead of implementing its own dynamic, + * non-fixed-size memory allocator. To do this, uVisor creates multiple + * non-fixed-size allocator pools (one per page) and allocates memory from + * these pools. uVisor must manage the memory for these pools' control blocks, + * so it must know the size of these control blocks. */ + +/* The following memory pool control block structs are copied from + * rtx_memory.c, so that uVisor can manage the memory for these control blocks + * within pages. */ +typedef struct mem_head_s { + uint32_t size; // Memory Pool size + uint32_t used; // Used Memory +} mem_head_t; + +// Memory Block Header structure +typedef struct mem_block_s { + struct mem_block_s *next; // Next Memory Block in list + uint32_t info; // Info: length = <31:2>:'00', type = <1:0> +} mem_block_t; +/* End copy */ #include "secure_allocator.h" #include "uvisor-lib/uvisor-lib.h" @@ -49,17 +69,29 @@ SecureAllocator secure_allocator_create_with_pool( /* Signal that this is non-page allocated memory. */ allocator->table.page_size = bytes; allocator->table.page_count = 0; - /* The internal rt_Memory MEMP structure must be placed AFTER table.page_origins[0] !!! */ + /* The internal rtx_Memory memory pool structure must be placed AFTER + * table.page_origins[0] !!! */ size_t offset = OFFSETOF(SecureAllocatorInternal, table.page_origins) + sizeof(((UvisorPageTable) {0}).page_origins); - /* Create MEMP structure inside the memory. */ - if (rt_init_mem(mem + offset, bytes - offset)) { + uintptr_t page_origin = (uintptr_t) mem + offset; + + /* Align page_origin to a multiple of 8 (because RTX requries 8-byte + * alignment of the origin). */ + page_origin = (page_origin + (0x8 - 1)) & -0x8; + offset = page_origin - (uintptr_t) mem; + size_t size = bytes - offset; + /* Align size to a multiple of 8 (because RTX requires 8-byte alignment of + * the size) */ + size &= -0x8; + + /* Create pool allocator structure inside the memory. */ + if (!osRtxMemoryInit((void *) page_origin, size)) { /* Abort if failed. */ - DPRINTF("secure_allocator_create_with_pool: MEMP allocator creation failed\n\n"); + DPRINTF("secure_allocator_create_with_pool: pool allocator %p with offset %d creation failed (size %u bytes)\n\n", page_origin, offset, bytes - offset); return NULL; } - /* Remember the MEMP pointer though. */ - allocator->table.page_origins[0] = mem + offset; - DPRINTF("secure_allocator_create_with_pool: Created MEMP allocator %p with offset %d\n\n", mem + offset, offset); + /* Remember the pool allocator pointer though. */ + allocator->table.page_origins[0] = (void *) page_origin; + DPRINTF("secure_allocator_create_with_pool: Created pool allocator %p with offset %d\n\n", page_origin, offset); return allocator; } @@ -68,9 +100,9 @@ SecureAllocator secure_allocator_create_with_pages( size_t maximum_malloc_size) { const uint32_t page_size = uvisor_get_page_size(); - /* The rt_Memory allocator puts one MEMP structure at both the + /* The rtx_Memory allocator puts one pool allocator structure at both the * beginning and end of the memory pool. */ - const size_t block_overhead = 2 * sizeof(MEMP); + const size_t block_overhead = 2 * sizeof(mem_block_t); const size_t page_size_with_overhead = page_size + block_overhead; /* Calculate the integer part of required the page count. */ size_t page_count = size / page_size_with_overhead; @@ -110,11 +142,15 @@ SecureAllocator secure_allocator_create_with_pages( return NULL; } - /* Initialize a MEMP structure in all pages. */ + /* Initialize a memory pool structure in all pages. */ for(size_t ii = 0; ii < page_count; ii++) { /* Add each page as a pool. */ - rt_init_mem(allocator->table.page_origins[ii], page_size); - DPRINTF("secure_allocator_create_with_pages: Created MEMP allocator %p with offset %d\n", allocator->table.page_origins[ii], 0); + osStatus_t status = osRtxMemoryInit(allocator->table.page_origins[ii], page_size); + if (status == osOK) { + DPRINTF("secure_allocator_create_with_pages: Created memory pool allocator %p with offset %d page %u\n", allocator->table.page_origins[ii], 0, ii); + } else { + DPRINTF("secure_allocator_create_with_pages: Failed creating memory pool allocator %p with offset %d page %u\n", allocator->table.page_origins[ii], 0, ii); + } } DPRINTF("\n"); /* Aaaand across the line. */ @@ -124,7 +160,7 @@ SecureAllocator secure_allocator_create_with_pages( int secure_allocator_destroy( SecureAllocator allocator) { - DPRINTF("secure_allocator_destroy: Destroying MEMP allocator at %p\n", table(allocator)->page_origins[0]); + DPRINTF("secure_allocator_destroy: Destroying memory pool allocator at %p\n", table(allocator)->page_origins[0]); /* Check if we are working on statically allocated memory. */ SecureAllocatorInternal * alloc = (SecureAllocatorInternal * const) allocator; @@ -153,7 +189,7 @@ void * secure_malloc( size_t index = 0; do { /* Search in this page. */ - void * mem = rt_alloc_mem(table(allocator)->page_origins[index], size); + void * mem = osRtxMemoryAlloc(table(allocator)->page_origins[index], size, 0); /* Return if we found something. */ if (mem) { DPRINTF("secure_malloc: Found %4uB in page %u at %p\n", size, index, mem); @@ -187,7 +223,7 @@ void * secure_realloc( /* Passing NULL as ptr is legal, realloc acts as malloc then. */ if (ptr) { /* Get the size of the ptr memory. */ - size_t size = ((MEMP *) ((uint32_t) ptr - sizeof(MEMP)))->len; + size_t size = ((mem_block_t *) ((uint32_t) ptr - sizeof(mem_block_t)))->info & ~0x3; /* Copy the memory to the new location, min(new_size, size). */ memcpy(new_ptr, ptr, new_size < size ? new_size : size); /* Free the previous memory. */ @@ -203,9 +239,9 @@ void secure_free( size_t index = 0; do { /* Search in this page. */ - int ret = rt_free_mem(table(allocator)->page_origins[index], ptr); + int ret = osRtxMemoryFree(table(allocator)->page_origins[index], ptr); /* Return if free was successful. */ - if (ret == 0) { + if (ret == 1) { DPRINTF("secure_free: Freed %p in page %u.\n", ptr, index); return; } diff --git a/features/FEATURE_UVISOR/source/rtx/unsupported_page_allocator.c b/features/FEATURE_UVISOR/source/rtx/unsupported_page_allocator.c index 8bd0e66909a..7bb3a575356 100644 --- a/features/FEATURE_UVISOR/source/rtx/unsupported_page_allocator.c +++ b/features/FEATURE_UVISOR/source/rtx/unsupported_page_allocator.c @@ -51,22 +51,27 @@ int uvisor_page_free(const UvisorPageTable *const table) } /* Implement mutex for page allocator. */ -static osMutexId g_page_allocator_mutex_id = NULL; -static int32_t g_page_allocator_mutex_data[4]; -static const osMutexDef_t g_page_allocator_mutex = { g_page_allocator_mutex_data }; +static osMutexId_t g_page_allocator_mutex_id = NULL; +static osRtxMutex_t g_page_allocator_mutex_data; +static osMutexDef_t g_page_allocator_mutex_attr = { + .name = "", + .attr_bits = 0, /* Non-recursive */ + .cb_mem = &g_page_allocator_mutex_data, + .cb_size = sizeof(g_page_allocator_mutex_data) +}; static void page_allocator_mutex_aquire() { if (g_page_allocator_mutex_id == NULL) { /* Create mutex if not already done. */ - g_page_allocator_mutex_id = osMutexCreate(&g_page_allocator_mutex); + g_page_allocator_mutex_id = osMutexNew(&g_page_allocator_mutex_attr); if (g_page_allocator_mutex_id == NULL) { /* Mutex failed to be created. */ return; } } - osMutexWait(g_page_allocator_mutex_id, osWaitForever); + osMutexAcquire(g_page_allocator_mutex_id, osWaitForever); } /* Alignment of MPU regions is not required anymore, however we still require diff --git a/features/FEATURE_UVISOR/source/rtx/uvisor_semaphore.c b/features/FEATURE_UVISOR/source/rtx/uvisor_semaphore.c index 97cd09ea957..4372b2fd07a 100644 --- a/features/FEATURE_UVISOR/source/rtx/uvisor_semaphore.c +++ b/features/FEATURE_UVISOR/source/rtx/uvisor_semaphore.c @@ -1,24 +1,27 @@ #include "api/inc/uvisor_semaphore_exports.h" #include "api/inc/uvisor_exports.h" #include "api/inc/halt_exports.h" -#include "cmsis_os.h" +#include "cmsis_os2.h" +#include "rtx_lib.h" #include typedef struct uvisor_semaphore_internal { - osSemaphoreId id; - osSemaphoreDef_t def; - uint32_t data[2]; /* RTX expects this is 4-byte aligned */ + osSemaphoreId_t id; + osSemaphoreAttr_t attr; + osRtxSemaphore_t data; } UVISOR_ALIGN(4) uvisor_semaphore_internal_t; UVISOR_STATIC_ASSERT(UVISOR_SEMAPHORE_INTERNAL_SIZE >= sizeof(UvisorSemaphore), semaphore_size_too_small); -int __uvisor_semaphore_init(UvisorSemaphore * s, int32_t count) +int __uvisor_semaphore_init(UvisorSemaphore * s, uint32_t max_count, uint32_t initial_count) { uvisor_semaphore_internal_t * semaphore = (uvisor_semaphore_internal_t *) s; - memset(semaphore->data, 0, sizeof(semaphore->data)); - semaphore->def.semaphore = semaphore->data; - semaphore->id = osSemaphoreCreate(&semaphore->def, count); + memset(&semaphore->data, 0, sizeof(semaphore->data)); + memset(&semaphore->attr, 0, sizeof(semaphore->attr)); + semaphore->attr.cb_size = sizeof(semaphore->data); + semaphore->attr.cb_mem = &semaphore->data; + semaphore->id = osSemaphoreNew(max_count, initial_count, &semaphore->attr); /* Error when semaphore->id is NULL */ return semaphore->id == NULL ? UVISOR_ERROR_OUT_OF_STRUCTURES : 0; @@ -28,14 +31,14 @@ int __uvisor_semaphore_pend(UvisorSemaphore * s, uint32_t timeout_ms) { uvisor_semaphore_internal_t * semaphore = (uvisor_semaphore_internal_t *) s; - int32_t num_available_tokens = osSemaphoreWait(semaphore->id, timeout_ms); + osStatus_t status = osSemaphoreAcquire(semaphore->id, timeout_ms); - if (num_available_tokens == -1) { - return UVISOR_ERROR_INVALID_PARAMETERS; - } - - if (num_available_tokens == 0) { + if (status == osErrorTimeout) { return UVISOR_ERROR_TIMEOUT; + } else if (status == osErrorParameter) { + return UVISOR_ERROR_INVALID_PARAMETERS; + } else if (status != osOK) { + return -1; /* Other error */ } return 0; diff --git a/features/FEATURE_UVISOR/targets/TARGET_UVISOR_SUPPORTED/TARGET_ARM_BEETLE_SOC/TARGET_DEBUG/TARGET_M3/libconfiguration_beetle_cortex_m3_0x20000000_0x140.a b/features/FEATURE_UVISOR/targets/TARGET_UVISOR_SUPPORTED/TARGET_ARM_BEETLE_SOC/TARGET_DEBUG/TARGET_M3/libconfiguration_beetle_cortex_m3_0x20000000_0x140.a index 1c41e39c05449ab35d0909073c5f7db150a9c8ee..9b5478ea18497f74261a13d1afd245c2b01c1ddf 100644 GIT binary patch delta 113410 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'd>Ux|6BL97^C_Rx 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

rZ+qPX)XysbuZKrw^ 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

rGIz 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 TwP)ra4Y?T?+Ca70)!q|VCcPr6a$1N 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

Snh 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�=%Jl|S3 zt1YjfM-#njR!!UlQZlWM0G;$RNY!*9A28Vs0pw&F9}haEIcQhYnC|>I*Rq@b?T)gv zU69pq%^|s`26L}9T41IZmbK)0H5b<#o->`Gq@=u?MMC+I@_G@ZlkUF~v}r!hc6z{C zkdo<#m^vptN`5h`E=doF?43ld2kWAB9xj1QQ54Bu?Qww>?i6@~T0b9MH%|AniC3rK zRExJDK-?+#bC5c7_Dx0SrWhY&H}xYDJu&$xeveU}jzyV&2+EXT$Tq2eb&4-Mq>O~| zUBc!-T$f#X)>Fs4gPU+Tj|sb*c`h-M^^u$_KNa!4dPB-Z15yGx2gqM7Uxc>=ON zv+!lWCBBr%D;UKkl{%KZPQt>nOT>9FzT2rpQd(fHF6q?B%NO>|acMOi0ctu9Nf+Za zD)dB`OEwj&rp=uPfoWd=c_+WBiDM*}d>Y!-^sEKtT_&MRPt%(%L3gKev&j+xx(CtC zOs{2w?rjF`XBq?Bx%6!fx{ZmR%ySu3g#p^~oJTaj0TW66!Ix3#wG#`?)n&-bx0N#9 zp>hz)x|CDDs_7uLuOwPCEyRj<8A;+!lCwGuSouan(WrSue&)>&Jfeklo{Cs@4O<6o zbywGj6f95E3`BryWH-2s)l< zKU1?%&4k1lyghEXhTJ`=}9bhw`A%x&Sas1Q>a0r z=}Rh4rSeo$1Y*lA%?ph)O{WlBZt0<*+nBzB%iJ>CgU&Io+gC~rh*=A8j=9I<8si|rb2{+Tj5^NHKyk}^G)lu z6LPNEUa>)oWmz8Bw%oe(gj3wR(ImPaf?QxYjK=~f9O>hSgRTDo6+wfs`LIwaIMmyI z`cXV&AJYn}Q!%Sr*p@U95$=k!ht}j7_)2k=H61BfCB?~8^LfjgAKs)T$yb{3A2(_7 z@>gCwc(dkjI!7B`vu1V2Jp*kiE}(sy+?6WN$YS?6rm0EU!33Xx9-6e*i{J=R{wQ`> zB!+^|kkQUl)WU$sb=863Iha(FR;LqOiNHbTA{Y?4fe>h#G$fp00@Oehyyi|!6NI`Z zt-{`;NiT|F#G`i76;ZM)-KU@35=pix%h_-^1Hbbq!pz} zA7S%HnjJI25TW83p>!fao3wk29iO+FG&6+U;#|8Nxw!Dv|yQP(&J*@ z(>oHqQK+?C%*-D?)uc8;trZ9gO?s{gL3#-oas!DWXTihhK`8f}=*`wPiHdF@(2=9Z zLNF4$hbGZK5jE+6(E4Z&(QgVEgp~(7`4apIfe!fuf?LHbr-*@_g>qN0&X71v82mhf z30dJp&u0ZZg*b=pZAF9Cd8uLpsQjiFcvwEsJ*@=y2`{!4N?a3m z`Zu*1?|B3dh{glOY%0X;e-;aDqcHVV(dlp5Bso=B zYq{`fsh}&wVC6!xI8G=ee4i~Qri-?Fh5crSqt+&!!4{%PEpfg?%nP9bVu8Ic7E-K* z%I6B@#t50eg?W34i1|gh<3VA+OG4&#F@ZW^n~#NBuL`@G6RDq%#grzBKt3rfVG9t( zd{F2ZCW`1fNkblVf;nQbJtEAzM1)LV5nRK%QEgK(%LjC#{}#i{6Ly*-)XEeJ^%DJu zT1mz%>@iRnzh4t7`O_x0lug2mRzWXw_(qt0i60`YD zxU6d@Dt}18E~5M`F^z*FoUfC?r9TP@?#Brcso3bnYnt?d==5C?ZeNLQAy?1`MMoD! zSj~th$s*z7kz!`&MFe~z=FzGH)#_s2mxStlgz;yIiTxyGkP`wj=|YK1qBkFZ5&wS9 zRB^C?V1<~|F5!a1!pBQR=y0qRVP7+lj=C^dE#ycRYOMePl6Fb2-qH($iJ*y}w7ts(WX73~1 z_of)QS{V5Q(dT$k{)JGkA0kYb_CXb0>IHY`(lAV0my#)gA`;t)MY3L4;Zq zKBBwl1ntz4N^&|99AhO|A!@he5iRnBNzq~&!9wyJX!;7Psb7-abT@LX=~;4>Q*(mO zM_~s?0t>4~3nZG6Nov`Lv_NODuP_L**qx;bJj{F$0mx$K*&W`5^>M{Yy*S|(4U5m(B~$>)#AJr$rQ*CJkqPFo z`w@dkS3)nWLKeFU8?C#IYy-4H7P|_PKfwGDK*(Yz6h6d+#ÞuhD3Nxq%Mj?_gK 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

4rMj>c$A@SF< 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ⅇ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 Q64Mna;}qjfdN1hz1d8uYu>b%7 diff --git a/features/FEATURE_UVISOR/targets/TARGET_UVISOR_SUPPORTED/TARGET_EFM32/TARGET_RELEASE/TARGET_M3/libconfiguration_efm32_cortex_m3_p1.a b/features/FEATURE_UVISOR/targets/TARGET_UVISOR_SUPPORTED/TARGET_EFM32/TARGET_RELEASE/TARGET_M3/libconfiguration_efm32_cortex_m3_p1.a index f7a322ec3a2ff7ac0919bc1aab48ee0bfe5f6cd4..21010fab25fd6699b8b8f688e2ee4dd96bd5faee 100644 GIT binary patch delta 112240 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 %LD8;#v7mX4etvIjz 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 LkDL-E!QKA>DV+tP delta 108383 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 diff --git a/features/FEATURE_UVISOR/targets/TARGET_UVISOR_SUPPORTED/TARGET_EFM32/TARGET_RELEASE/TARGET_M4/libconfiguration_efm32_cortex_m4_p1.a b/features/FEATURE_UVISOR/targets/TARGET_UVISOR_SUPPORTED/TARGET_EFM32/TARGET_RELEASE/TARGET_M4/libconfiguration_efm32_cortex_m4_p1.a index 7bfe271e87499bda4558af69c9700b558f83981b..fc8197054e92d5a5a35da3061496e0a4a1f61111 100644 GIT binary patch delta 112682 zcmbrn2YeMp_cy+?yL0c7o{&oFO-O_E9ui0(0YVSG6Vm7(@g%qg?8d+*)n^R52(uKSm_>f_#A zV*iIfCHD_WZQ1I7{p0+c^v^%T@TU^}8NF}+_n&1@tEzK9JEzb3%;2pzS|i(A{N!bp z#jL00h&)J5k4p>EySuWms{P(b^p7VA6d?_g$}0LRMrOaDp(HsxS}#exJuGI`!|V|# zNs67PB*`^1per+NXfTk>H_jqt3|$JO^5fo6Ti610iy~4}jp^Ay8XuQW$oO!$B&jOz zJzyxct?CMG6OHU02W_RsB7nH|AbC0Qk3ygwO=O0_U5$MV!dPQ0WO1uNO2**kpyQu_ zRE>Ym159valB5||bOW6j0NTO0eX*rE&vFY4fGGI`sPgKNJC!c6tmM9FlgC2hGJJ+4 zF_#|hFi}!Yd5}(hD7jXS#ApVe`JjzM6iG5vTMSY%_UNd)RPb;lK zx1$@{!;ez$L2D(cy5{?edcVS=G(RFGsp=#EM_H2G351X%zC?r4$rU>OcR(6g6|W?; z8MP=$s^U!~250j9P^iUphRi1rGUXt2?OI%Zk6JZ#N*Rd|4*L+A!64g*PozN}zz+M! z4m61I<~q<(L^D!|S^t+poK?Ylm2TS2t9IJ+E)=7S(d@Z!FvuhtN^-peFU$6!UxV?Y zzL@bBm~EeO0*q^pza(Yb*XjvZ8E-(-K9gc68S5p3&LXjD++is*dNpj714)y2(CA`J zD+S$xrgt~4ZU(v)(H_Q|lR>w22kmX_X$IXP19YZwV>IZl6pz}LPmTVaHj=5`Zlle0 z`C^3JzWceq3@EZ1@C=68m(sAR@jP|!MKm|I8UeZwscTXdbv&>#-w~p|vxxlGQeUfX zHsoW>5Tv(caBv7sQ?VYWo)CpuhkiL9bU4wfF}4hJ1gU6JReJ;{52T1PMr)UX#z=ce zIEf829jkxIZH{sbwGKv$atylzv1*(>5p={8EF2kqY9*K&&(Yvutkx8CO`=_lN*3rS zssMN6oP5yHM0*>LQ~@1hZ;&KEWBZPvV`^uo{?cJc88m}N4j&)9g&NuePhTxb*Mz=A_)j`*N2zdwNOvJ~rUa(PW zCUr4-tpk&jX_Tby#wTk*=e7b}VjOA#UB4gbUdB$@pc_mE-Ot#u7<9v>pv#N{ksXeC z`#}#iHd<^+v^yd94X^m!E{>&UEnCF7JqmhKK-k^6c;wD=Y}a8hw?f~s_JTHcw|57ed+tq~2eta9**j>Ycdw3;Li zk}@2dt<#zSXnMFf?V1Ga8H1#As+dmXN;}IPhw!#kK2BRG>#SRz(^jHY@1h|?B&R*p zNi+6UFc;diHFRgeNf#zEMSosPSMu5SFn(%msQly!&X#1f3a zeISMnpXC924n}mHE(mfRLeGFgFN%X+Zji z_)Bb=Z%r0i(bj1-OE`sSDt?aKt)deMca?|uz!)XeRjJ~}?fS0*?I3f*(Y_$Gs@ziw zvqZSW%T;PvI=e*s?+d0*UI-N2r+8{M!mA2*+qlTG-X%!>#akcLSaEl9=57{yD0}*F zw}2LwA6+67N5N863H0M`4LT4NtSY-Xxr3gB*CkbbHX9LU|;2N4w##NB3E>bnM+ zJ^e#3SE?ERTq!Yc|L~uA_#iimD9j z6E{m&5ezOZ5Yxm88=dV)V(d(?jab2~YD7m0`7s2aOQvvw=a5pEej>s4Vi`kmZROH1 zY#T6C^c^UAWg%Q#8ZnAsH=0-)CtA%L;RG%{UqEn*uxpK&tickJoJaa_$!7z>=BN)Y zxrzyTh$(wDBuRatKW+rk=Xwy_B+R;*L-eaf1X~Fo_(c${qgJ@|fq?zZb%+TU&dH1+ zS}P_vO{`KD6B~qat;!{!j( zB#mG^t_ED%SdKlLOL4gb?}#XRMH8JVCLSpgXL|-oj;9j5E{wP=41K(YB;z^}^c8_K z*C+b4@ZtzDO`LH1ERkEE&7#%?V!<87f~yUe%n-E{Zv1jSHQ((?@NfvhkG%;_^B`E@ zNwCKxf&r}v))$gGB4O=Cy!(q#-Y=lmjX^5OPxd#y%H<%7A9_4Px7tP2-d--&!s-X=z*eAW{Lc#Ydyvn zVe<1Kx>Bq@Ul{QrdD<+6il}H)sQHzcX1Ivx9YOyh5-N*SrP3}05e>lAEeO6dlVDaJ z!AcRndLm)-u<>x|saSo9sIMoHB-vb#;C*4-WT9i;B-~p^p@z$%2xo}|%oWqW5yov6 zzPTsNnlBtXs+9Cch&62zrf-{0k_W<<+k}a|rjg_$k%p_SSt0_Y2=Cs(Mvi1Ri{zTS zmY63s35JM>o)ps@3nWQ>Vb(ffb(nCnhe+5+;g8BP(%I=na8O5r-!~^Xvjf5VqV>L! z=UY`f5z9!K&GVoe7Mh<+}H{z3$F=X{bh9Z9f}Ot4Qm!C@lv%_4g~eOKgvrdU(r z1Zrl&v2LP+uLzA4MDpRG1UHCjMvL_g7Ar6aBQD?sg3=vNu=6s4H`WqtBz6TRGUvtkI27e?T;0s4tp0Ne*UQ227Qs4R0?IEfaDm3=#l=xZX|n~GSr7TK^!c%pY8 zwQdsm{G9{QYenA@5vIG&`GC2bhs@vjYvI%^r4ve8|WCMHv>ukY#G7!s|fxEO@mZ_4be(3 zg0<=poF>BYsgRs*VJ6XXk!~GD&U-B+$=Y!QGsSQp3;AW?SbuD~1}P7w7^GSVghBe! zm!NAD!P=dvm$Ptq4!@1V@S0FA~!? z5N_{|EmoXq)F$LULnm67@iPjQmPD}180->4!_?Iad_*AmWh`rougGu zW_67iih<%Uv-)-!C_qXS2ikDGgLD`CUL$CrXT1BTZlX%2>eG1{%1(S%LrfOcqLR z*}$5R*ABA5R1=@FSsh{5GnRm9#LDbO!EWyI6~;BxC`K6?Y92!93{icNGluB*;V(Ic z9+((nL)SqPXCV*9r;(Wn>l*snr^OPnzU{YOH0cO{z1K9Ax<$x`| zrX26&OQw`gqj(KSL-hHur}F{dYe+7b#HKX`DrXaE@cAr17HB1VM0NB&t3m1&>?_P; z*u#Xqdzmn}k_n4HWbd2F=6y^Uy`Pc2h9iuOw=Vd{`WV9F1B#)KOo`w-KN`?(mem7HFQeS9-2$=YS#*=eb5F$qHmX4*G(Sa2(%R09ED=+A z{k9SU|A(X!($EALnNOt10b3jWXN-TaT^|IF|KD0UF2Vl>&`tw<(T`nCuR; zm<@6QTEb?~m}}TFvT7~6M?3R6W}X1FjoqYF+HPjw(DiNyYe}B}kUgZV*vB+Sp#ALJ zNT3tUp4v{b;25A&?2~+;OUyS3=u4)>1AWD=P64{dKBu*P&n6=m`47xOCG{&aQyhL{ zzmq3kFix2~SsqvbG(|Q$&|;>_%SpOWK1d~?%Skl-BDn(%xX`-^qCw(Lw_x|8U=J+4x^CWkn2$Q+wuZ(&^`H# z8JWxP%Nwc3ud+(DJyto}5@?bVg3$1p%DEh%S<3gcm_^Db6oSRdBOPd+l1&z_SCYB` z?Nk5_GK@c z1XwqdrmT07y5)R96_DG01YrFzO8N#z$jOc4Y4d9BK_hesrj>R))(o&q!fe2T(xreU z+bBi)?4l9+E*THlzgHe$S(o;-{|ucv1I%b2nsORDL1+&9g*;i#R9e_v)-nKS9vd_O z$im8&04-nz_CQOS1#97(S@nfLd)cOrZ&%xeyzl*j4DAv}BJQ74h&;wpNIbLQeeP9<>c;!WG(ex9BLJ&Sq@jF&Ax*#6w3fiJ6uY2Kw8r4( zu-7``ruyKk*;6E|=kx>&olB#HO&3)1FX@HoIQ;lqIssX_bD(lSe;^^nJk5ZHH&qr1~i+UaRr*g zdRR9sr+(n(viWA50t~B}C#~}U>rJW$*)&SdLu|wYQL(DI-p@uigPV#WI6|PP1Yxm7igU$!}*_0j=&Fb0>d)&ivfa(eRKh zrCOdLH>GTuDPJLDX36JCI9r}X5u76@j0Gx}Teb(9EB`{CpC=zDms;dP+OFoy2T5~* zyq!F}P!6PY)8$ecWs&^;P@u)~8R&SXts16pX1ZwEk=@7sv_q>+i$d^!U9Zlh}Qt3qb_ zA0WE|j*$NX&tgz({Qav^90M*wMF`w>4F~W0HC$okLz0Of6ir&gD3MI=R9e9`Y0)9S z&^A=vfdNKtT?<&_i}iptk4^!MTDl4_?)%PwN!_VX(>gB(Og~O>t~DCDW9Av0yq?*X zCa67$Hsw0!Nhx;$F0j1uj8MSlEAj#J-RA?gUpWl0>lcB5-M%L87KBs2bsrc9Somlx zU~xS!z>;#DlX%}!@@LsA8F1(aD*%TDkXgg4Pzsr+vXwOFOlBSoG>groOkU64knkQ0 zK$;3S_|8)x@ViB=0hx3WH-%_`Aw>lH+^6vNJ8TCyU=6vXtZ^>jh}ks9I5rX<6T^gz zTnRz-qbO4zT7fh-^YF8ji#5*Dn9(OF^Be3WS2e304%ni66yV@)H35hDl50mybO#(A z)f{jvlNtd{U`2jFQ`se2>MYhe2FSu5bOBn-T*H7?vq*B`I+nP|W{TV00T7r2e5r!d zR?xPdzKv3;R)^_;8PV$iGYumEYd10jHrrtj*m@_f*t|_6%Jue7C})HHvgypCy3x+ROyZ z$s%HbL|c|DkdIqC0kG(Xd5f+ z40Mof4g&gw{h14NgWYumddQw5!K|xwBX7mtZUxwFD<#i6)3Jl{_bRD|#631$kw9hMgX^gTPX9O!4} zIt=JB^Y#V$m0hA_{hghnki20zSwQ3E<(h4sO*+tq(!wtau+1nq-Mac13XXT!U$MW@ z0({N8*=V1y;>aoWC&*svUk)<($MzdoT-Yx*r?g+c!ojhHgZoDh7&xFby0oyUcXZF< z;@Fhvgt++B=t1$(!^%nuhnDJ31{tdVUw3NRUGdkQ&-1{T|I68G4>tH@C&t9b_8w5& zZ&*pG6gzCl;Qv3jgn~8& zx%G3J)@@ZkH%NaoSPr$^j2`b+@ITrr3S;Iu>SI4peJx&@nav8?)o<0hQH$mU1wp|n zF|am>d={4wpBxl1xU^qs;gHhEpw4w$HH$6nUsPIBQd$z75?wU7a6oadpuwfXdk^V7 za6nK(QgU*9Lf2qR%gp(f{Mo90ZHH{HcYnZCz5h}r&T=cor^2Q7E;%r^?U2&JLt^_B zmKOFejf;=XA3U&6Y4Ok@vBNOZz`>SdS#=!Rv??7^I2vm|K{}hR_~_TaW)2lj^?S>% ziZ^dCmcUiz+`%uQcaC_7q|;>9Az;#2-( z{)<0zPyNPhLyYCy;%{}+Wae)9x#W|IPf88Ea^hO$E~_}+ueMwfG;pz8+OT=spq%*l zp#RtG3ySVvTsEwB@xZ}DOGiZaPXu2$xVTqs>g;=`R=%WX3Q@ZNA_o-DY%)^e!mNg@~7>3~nH!(q<`;4bnv>G{Gb}c}jH7jUP zziykht?C!#w$9fF{K~^CvPZ90^^d;e@XD|JqUA=W(ei3sm}P!FZ~fMOWuI>Rkvr-a zzT;d!x?72=_+@+))9+m80eY*IhW9H@Ph2NkLdJXP)km;uy5DNUD&6HK*DA87wpA@l zXTGjd(7H`-4stSHcU^1fR$({0s;v7cyt*Z-{GeX7LJikPo>iJu44M18tXI)^p#G|f zoUflftT^dg*2`7&fb&XKeUZkCD*K#Q7Rq`NGYqXfctKgfEG|p#1?IPE(XdtBzqW#) zV6g=x#ibSuPmOLCT=9HKh0F^I>UYT3zujywRXkk&hoV35;(Znx4JLj2Rb{`WU~M96 ztH&>ut6FAubf*Lf(O+&gB+}LB7-{ey41;7(e)3pV(b)qz49ZAAR|DgHiuIQg*jwZ0VtA zdvZIyi<=?Hw`D=2dX3t^S8-B70a7dHuYyjrtS$?!jJc;QQY~Y4?$N70Py#IRyLyWf z|Bw8I5!EU#>^j5s)(v=|l9&>yAFCyM=ri366ZHE}mD+k*RYP5i$L8vlD}GVlFj0d4 zwL$6I<9VF^@pEOPe)}#9v;++_>RS@|Lf!i}Wm!eY;R4wiYyaoYqQ@OFjI4NZv=!5X z{!}6>x*T7m>6hGP94_AOO}4!n0g6eEi3_f<`?wRs&Q-Tfi)M{-3hL&xENE4~X;6}W zRgCa6D5P4p4Eicuh?rAKN}aau}zX+lwaLP|=H8Zj%U8d-SlYduS~2-)xt89>riSyWP%pCK-Zorj!|&Me zdp10&qQ%QMvfaCMB;%4aL#^oWx)0;HKak=qkKXv|-BMMJ4Y1sQ6E1`aLby!`7i2K2 zFi8ksTZJ=h!W1EFo<`jlT(t?)gm8rr>NS~7T1!YDTBW1jN;8GDPC5;sfBaTjM@VN| zrM|Llglr+bVU_lME3GG_F}1`92i{6^h4ekE)LyZT&_GB(wMsj`mF5X)K!zCMgSXPg zLOQ@Iefd_}R9_jc`09r<)G~d*bAzVuS6M`rsn_u(5O{NdeqUt+tCWLX1ZNM>i#gbc z+xU8hXuZl=!z$Teg9KaC0Jb|=`p{#5K8jfF4p`h;z#GKwc!ci+31wd+*vnuS3AV41 zg~%->J>S5B9m^i$`#2=VU!ra{FkeF!W_)C8zJO+LngY$q*5()=N$O*3{^5xvO||t- z70vP@AAM|=>gm4`;wt#d#vlDFdkS-8>qzNV)pvaL3;(9N=owUPlV(^|i~aPV?0*^c z=yRJ#Fhgyts@YF3`#05_P(`7LrDR!E=lJPI|4sEVRD0P}>snQB`ROio|HXg~zoHUs zsySBGD*pd&z*MNdHK4v#)yH3dT>D=}T?ADTJB-}Ws+!@yu-?CD9)+gJ0cbX|YHkns zcT;=4_}kPbR@JWq^i}^h>LRG7*;dues){4Wzq<7TRNtoHXGZ7I-NcXnif`t2Om{eNUt_8<73na$9)Vo1ZFAW52T%g;q<-ehZTZ=LaF zkUlo|UuMjHDM{rv)s9xxz9#*`zo}k;>KU7AXR9g?{`X8;^ylB@)zzxnK3FfS|1So- zfU0I&a)DK~c8GrT-&Cd7wrv4M6k1hVhx~hZyrKFwJjGVkVymjpe^+S4TUC9AGYd2f z38Ae>-{H)HtEBzabd{Ryk(>S-7rL-u9`TtZjn%_lu%&GJOmFJK!m8v!If&e&k8)vw z^5xGKWE(vfyk~TAbhsc%j}4ME5Uu_6z&eVr;m@ydRWazRFqWYgI;u?fc4fJ8Vv^p? zl|@w5T(M{10YMT$)Wlioj6Nn$-E4-Z=n;)Xc$^L6!H3`{+3*w_#&Z!NpJBsz9wqoW zHaypc@%&227uYbKSP32v9R*%$!*~{A7J`*F!D<^`Ys2epm|RQ-ZnohMYGuz_2*Tx9d zx8E?o*bGMpnTMn?`iA)xtX#SL3hm80qaVI(9`g|-MR*pbw&*V;#;{9h(D=My^w5l3 z&3J_T_qWYC+^NjQF@=k7n_ItPz9TjmZ@(F)-U$1D=7+7FZU)zz41!{6};)UnBUG`nb0 zG}>E`3GP~KQ^;Ep?V(lVfo@v|w6}JpDs(!Og3i<;iXiX09OKp2Usq%Po%cqev6}+~ zZuFH02gmNu{<5LSYQui4-?5a&RkdrlLOAv!nrq8kAnzm8B|CKsx+(cF5cRDjvhkn# za9IFeV_+M~jp<4GQ& zwSEM70*x7^b*KS4k>qjO^83^wi5il$E0aMdXM;}D+WrDMr6uT0tsXMdIc*T=Y^^rj z;ha7fbgs6$6m-UM(0SVOlb~zg0NqqOO8RvkfzH=Fai(+5BBR@AXW?n*y53k`2W@@> z(Dj;%@2G3{oM35A4>WYw8vTrh+|i&*wA19S`U^q#(z0N#V|gx%?a^!?9XB6b4qRN8i|>y+rGZ{y4Qk!9`o%!z z8T|#)&}B8r@J00@kx*EZhkl+eF1xk^d+nbKQN?Z|!R?y`q^X>EJD=tTLq_3awzRR&h>>@#0F^=vo$LoNuuHEXV&kbUx z9_cE~IdKAG7;?~Hr#1(4u55=*vKo!%tfe!_)t3e{y1NDKMypo8JJxBUXh~X=JD`J! zR<$kIGu%Rm*0h1ROuJR5-P1w)HbwU~u`qL!cqX}p4a5)z`f9q;C>P(Z4*m(Go%$Hi zuP?S$g}p!;M|H;F$_{MD?t_W+kD7pyO4&5fo~rwX6g&85#33|qvL~|USdg1ZD!FF> zGyo+^PQg!n+}HL5tC@%6%H+O&Jeno^?1xG2?|VV6VpH`+!w1wy34{6W+rK6A=B>dP zp8cWiHtGia>JfXDhG{n&;&>t@pMt)UM*2K)+G>=$ zM<&q@+IVNswTX7od`m#rA=+K*LpoXGQNu`%Y-G4cHZ}NZd8l`fx@q z)65>-h?cZ(T%c7z)2do?MBAhAHR)(%fkzQ7eJb2TW4Ti@IXV0_s9Qs9ESkr#M2Ix| zOvr~5DQOXHLBAu0L|4iHw+6pqL-5#B>_~AclRWmCg{n`%V9BFWX!;bqBYAvCq^3>B z$6+4(>VbC9GJXZUpJ*qaf}$Rh#{n|IMVlW3`9ae6)~c3+{)n~$KdmcD#N*^)C#tax z$X1Wjw?S9e+My;r&Kcmc2rc;=oJu`D4gwS9Q!uPZ^7xbnjROtaJ|ol8K*P2RG(o1e z=m|Q15eEHi?H3==mr_9I_!RU*-><1}u2!FPu8@9H?cyHLSDzzs^R+)xK;IaLmABD; zzYO~JU<4zygZAwzFn6dLx@cE$g!7;;pGqZ?Jt5L}7^h#X&OFRBK^sUA6px~fP(9LR zTA!(CDh9}qNnJA4=nE!Wo&~#9(~|>#F`6l|@n4LC=@Nyzp6KIZ@;(hFM;_>k;F^|r zz=Q^(CC;>bK3W>e6VZ}nHVyDXQzOxoW@>`Vj7JlB0h%&R@icaGnF=u5RE?MxLM_)6 zE2B@oXvs7Ewi7Ka<)!G;)b!jFOdFw=Z%P;irmeig0QZ?KkCM`f`-V6nP`s9>_>QN;=_F zN(2YtSV|R#XoSZ>IL}U{?+n;Wn2{3XA37v5zg7Byl&AwG&fiLy!T|!Y)lpiAnv-o? z-&-EL=I&T{B#@;eTS6XvgAqJJ*c7yz#3mLhXvy@3d=SQH8rAeGC9OG}QB*a|Lo2jX z8vus9L>Qbrve+3K!Sw^^WeZv|wdet+u3!wN3t?dDu|^oqL2@T_869jUR=?oUQKk*R z)TkkZo#kn0mrVJaz;qEYQBCX+{O{3KsA;D2!@+cuX_KsO`UqzLj{*_MJX8C#Xz4B^ zoKn7N5FG4LDANYj!PILZT8d;!^j@Z#wZRk%rp%Od0!)cuMwr%PH}NQye}p+>O>O6Z z=^_6PW~$lL^+#|$#YC%2*Kic@=p{O>GtEFCJ$egfiz$(I_dbHzZ90wbKzQ^O%t6zq zN5J$G%n6hKOECS#XrD;#dy#oGr*Mgnm8WS1ZzLY;uYz0>0xzlhV~@ddGij zwFl<+mi*$7<8~^EoT&6f`av)qw4F-zXQy6*Gu$aTDy<#qhA4d3V~qM*rnC=#>5kdn z$WuT&(~r{zl)|I797|Giho#pvEb&ob@F;??Z$%3n}Pe&+D{Iy zNBv&012mZ&*(hJ~dd;qakrZ=qQ)+v|Zi0QR1dl;ccuDe6v`J2qJ7F@|7BEf=ao+(U z4P^_O;6HxLr%LWi(N3d__D2$@Hlg$cL=CzxoFGg7WvD_gW|ptOpVeo2xy#<}@Jlwl z=;bMJSP#NEqF7^9lXvGaI&3q~`oS`5ZVFb*|a=d_Z%stLxWW)3mFf^o0eIuA?r zlOr&)x9P%M^zj!h)lD6c^<0TH=#Pw71qa19S?}ep*5n^izor($1RGz|=0;0>b-(x|S z5d_TNAa_E6~d%Mh+B~iZ<|@F6cbVmg@~Gv*c50bUEV4Xf{9M@6S za1V6cN%0B(JW|bAOSly6^fB7He|u&HDPP9;_=PJa!tu;da%iP*#5T9VcedJ*8UXo-ED zHq;OKpZ%7*2iq2GYCfzW3sn4>*+w&Z)q2ZkbVs9YMJ^zOUpH@ridaz@ z`X?evZ&xH%9`jaj&u4G-CXyb4|5h(E6LhApBz*@B#6=#8t5*Za%)dZ@g;S2z>0$@7 zv8h27e{30bNQt4PmD5@lVNelpB$Cyz`NAmrA#)-wRBtDf>U{nj-A6(q(N}ueGJ7m4 zPWWgf`RFNxF~Ucq%rr3TkVP64Df-98-^0Y&MAr3!yegbiHyFe?BBDWj1|o}sj{k{I z##yg3=pw99P~C|mAh)GoJscXO`A`I}%xz;xVl7!*5^F^+!1~34u;*GAG))ZQMME_G zdk87#Rdbltf~8}aT#vM=U>LmF8kAfRv$?9IIAtQ`@zX!Wsg`{Pr(bmjRAq{jJqK&gzy>;6+w2=vP2;%m{ng5; z)nsc$&op~U3jPNR^oxE1pK~U$P=fHXUr7|k~Doh{Ovur9)?NQyQeT8bIRY- z(GaQs9D=4u^T!~6kC`3=kJF6dJ|xWcURckE)N0vd0yl#sWh6l#rDdHmzA81=1|zw$ z1@(NWsZI>b@_9Rm{vw4rHp!w{Td}rYWH|N6wg-bUpuxzjdT)orBb&c12ok!vf3E=f zsOP6LkGKYZD>bTWRcjby^HsP{5S)|ux9jN31PfBxe%4sePhsfm4j=sK$eg=0U7RxH+1}10m9wD zLlS(Lq=fn_RRXwO^WPwJP`Tmgk07)_?wKU%A7!w3dG{p!*9;czf7}_`?jc4DF5xX8 zb~eJxp1V2a>e-nrsJf*u`g%I3)+U>Rzbki3JWdUGeaD7_`ov5YnH02%1_{KQIv(H< zg13T1a<{3wh%(9Ctp@JR@K%r-7}>S^7bKCpeSb;MuFZVScd$t)o+(`GgGm*;RPNX*4uo@> zZAh1NE_-f=M6Ja$4{t&D|5%f~2e(hu;19=CRdI4q6=!$u9*Ik&;+??_CHS;eReY-c zql>bVIsAh)+lEsdGI?aP%jg&VA6`>jZQ6=^ZLa!{AoGv1I#{$%7I$lY1sy!Ht>dYR zUtKGu1bPZWNvmfQG_}67MR~)+5is7>CSKAxh!E%BCds68*NxzOTo&=8ef-Czr7#XKfZ(?{t>Cxw$Q3S~ppUk>l!m7z zTuS+qL|@>V#ihloiPm=zjE3v+A{AVQ@V*KmSs|wUsV7MgIKcH62u>B_^g2QGbCffe zW}^=AZUE71-$kNd;G;PF#``?cEdr60utHe9elXGdekS-X?jX1{v?kHL;s|~yrmV!} zpG&tF5v+@kO7X@E+;!p21)(JI6GI2rBFSEVg58DA@uSrGN_a>^S;05cNOCQO;T~A3 z?N7{A)I44+u!3N_Ac9XG5j-=VU>ZsU?_>}Y9}z~E;Rrtml#$^@N|$Un6*H zB*C_g2sZeLU;?&byzv6{#HG~N1br|UUNI8ihZtY%4tSBuOMcM1!^e-{k~IWd3(xh(!4G*L zV!u}SY!5yQ=F-u*B-d*bTop_b13t`#&%WzLqFk}c--S!JiL}~WpXArXiXVu{ri#os zEFA7H;`+ET>11WnK&f~LjOq|M|GF8;+chNUok4IUPV{&eL@v?4wIX=Kj^J#wD1-KU zh*|N3;9lWOCWf|b@+#kxq)3$U7%^qz9FmL{g*vu3 z(Kkez|Ja9UKe77EYa*3u;D($_p(3KQvCnd8k?_F@Q3aWKBstiZVAn|m2Z&W3+)H$Q zoSV7SUwG)Z_enBQ6mY2Ur7Tt%FZ#B}wF^bwmUIe5pg*vr@%sVN$rdY~Ifm%{B8ZEI5k0t^;FNv@J(H-HaURj{32$YJ)NZ(n zB%_yz{C~F&F%7;V*hRPtTAl*4l^lDK~FGS&u5-C=_3(4{+72neRyQ-a7=(tS4CID8aSw z6RcTAaC>cn<4+MBwvgbvVzhTnG|n#~9N}WY{hm?l@n1#$?-6-ERVYmq5i*HbI`$@| zH^RhPc0~6VowwH_dWx9r`hKE)vk106NiaZ+`SC`g4}3&09k-EOsv&A5(4QnrPY^T> zre~m%_cmf$ULg4MK7utv3C4&-TiuxGGdM4D>2oo3N6~71bJJz9%8!sG25A}25x6vq zE9dA%cZ?U-^z%=w&fvfvw z0UBT{Uc!=F4yY|D1gx^AA4H^K+WiG!gpQfbcnix`a=GZu|W#mekX(-Fj_9`=mSvwq z5@$A3zQ;eGgy9m3XkSn4Spt|e@k795ODzdCRodsIS1}H%9v;9pep(|KOD4e~A34`}C zVR0oBCV$9;&40awh0MiESjc$mf_GCPd)U#uK09dN@g0gVbJKgj0*20}vcu%)Gt@TEfik zltgRTI+|-O^QFpI$97Syw=w%XpzX|K0niTiC9cwv>Q;Ryq=QeL-{2Y>?wIH`S-Luk~(}QuZ_o7?(i0t@h`w$m%HG@9=wGGU;d=G zusnVO;XT= zxK2rN09voSs0p-F`NIilm-0(5pkqq&6SV&xSMpFIBAeWHp`N(cD+-a%_W>9uur&oY zdh86qn4T2K#I0Kav)lIptSeKZ)N`VB=M35oI(O7k!1~E_g=kPpJ7VK!)zR8oyu7Hx z&~uP<>~j*Zi+Cf3xnMV*m-3RKbOh_OkB07hk|NdLs|jFP5)D0cOE&1yvHJk0vG!|$ z=CC44>T(uG4w=jPIYDn8qhBfEyuSDbw0Ae$hjX8abY-ZP zN7p&uw z;z17H%ZS}f@cw69z?*teA_p_d|By>GM$-B_HjQx81n?2jv`yFOMmaK#xwQkD&OY`8 zn!!{`(U~mdH0?il3k&7;Y*vp}F^8?8TeoudJK*!lbn&Bh%<4&LxY};_4lk5&zeTwxAr2IS0 zo@9YN!@e5^be46ac${PSHI{_8urz6e=^rwUoHawPVgZ^dhtQRNmb|eZ&}{iBrRyAd z33Vu!Thk)u%CXBJoG1Ig0+ML_fAo-)t^d1gp-bX+|yoLEGjcc@!1uVmWR; zCfp$Jgxz=x%gCRB<|_IK>Y?-|;W8zEJ-F3M7eX79#yF&j!1#J+L*RE2U3kDbx+@Ay zpsWdUp!rPc^hp@yr_W>3sMdluE3l=A@>>4+KF@$01Tdf5HREwm16ZRwCzWxPX}G2A@ZKrY)!L7 zncq7ECT=fnIZ1c^0G&3XFJStY$WvZx0c{i+(OUsCOK4NBJ&>xoj!J{(rcVZJ+=o`$ z{4%xXPw5WWe#2tGu1VDZyJ?pI3tmy$b>BqQU)Y>-pqSoS%u9OFk0^NG$dO>mF7E{# zdL$5VSQ$Nd8Gf418&laCI+@O7>*zE*i*1jC!g{vqYoL3~F7U1Q(@sL*SNB)IfFG&R zG?6y&kf(I|>~nA)B>jxEk^y5*0G1`-qRY)AA{@btWAEbDQMfZ?_$~;lyL$nKUU&)^ z9#R2VgT9c&qbtt?HZU&$Y*t3QL5n^?pa=J&3&OA$r$LW+hwceS??$|F5gbOM32a3! z&{WoKCD1IELSeG7!|AmDFJ=;LwX501O^~i*iUU!((Ix^r>CMCd9Btj z05i-~Q<>pw0c)3C0BlCD$L6gY(;VV;8@#e>*MV@;)MR7&Y%Y2&Cx?s>*a@SJ0`59Gc_1J`#9 z0BkUcJl61=qkwsi2LPKl!N$c~Y^QPZeZ~N`q&MXAcKH(k%^hNDV~DO_e+Q;}7VQg# zGyDLHy3txnpCR{!X?|&BT3{kg9{1Hcz?8AH12z*cryRAt1L&13mbR{K>>C5PgKSD& zpikJ7vp_f4tkFOZnQ!9T#eRqSF!R_J36OVN{w?4;-+c`D-n<_H$Ff&Us<~>px@a$9KtuO<8R=`%bwUOh3A@-tb(A$i0=X0+`VIyy8W;lyti4wb+w;*Dt0A z7SgM*gY|}$)y9AC=1`ZLP`8(a$oZ0J)4*yvNL%BB;@@ufP|k@+f3If2#k z12d7`K(dJ?$;FWngaqsY3_Uy;Fnr#hfHgKzo<{vN7BD7)vLeo%jwA_RhCz~aF&Xz? zJjIhbr`g8=W<&-6)>eP9uG%o>DQ%DCtZ!?0Y@WC=;47F9b}X9Lc2%}r9c>pYepCLG z+P;@fvw{AXOP4U+T*(YnEc;m#3g00%Z6CO!Z1)E19NaagEd(BqkWD;qehOg8;m3e| zp3{M87aKsAkq>1v`DdS;MfV~5<@TGw9gu6T20AG3+XHk+9z-J_miv(AIe9>BppRwq zBRaHxBKy--``ChL2W&&T@^e&*ymizCa)IJLI)bctAU#^SopU z(5Kvz4s?N^q}X5N?kj;l=bdPjFL<53K$m#qWPMA(gx@{7w2`VJ#QX6Jq&08)4BjHWag?A zGM%lW%391uQyMH`{_YA zDfP(Sa%E>Z&_bmb+55h7ge?46>0FiK|A}IuP3#NhUR*#Uorl=Fn0!>pblqL(*KdA=Ss+UrMHmM!o1=^~P z{{?7=>VE`iw>mM5_P@RAGYZK!>OuMNuK>tJw#ji&nlx8K2a0M zUC-4EnLv|yaxu^pzO@i&F&|DU%lXLtK&$vHdV0Nv*Q4-m;B)99$tM2o=V;r)cjI_q z=G*x|TJ}zUoRVe_H`Ab%yfbCXK7Kp`=n$Vsd3BUGe*$!jzqHskC+GP;K;ZJu-T!4n z{NJ}g^1qvzt_gk{;{i?dB{v>y*B>zA8AUL1$RxlT!IbeeFH!bqjYUR@-P1FI0vGfx zWmruQIvFP%!VV_d+`4Xp)c-*Yq@f$hr;$B70LBFk0!%uJ+JGMX@78Y{1Rhr(0(vf| zT8UmU1~6vmHNeRzmXa|3k1GK{6Lp$0@!yD>%)~L({x@V_8SZ;j?=!u*~8^kZN`8d!sxtRgzSNU5? z;NRrSw0Zq5|3stxA*am*_oqDe7|<)ZlEV2$-baN#R!Jux&sDtJ0?kuWt^jRSYSbYA zZ&QBW3U-I$R0n9Ml6VoQLK#{Fv|D+HVzyTqKpv=68gv8Nr<75S?pHRs0UZ=?;pB&u z;~C(NDD9$vjw)`4fsQLO9h^T>@DdStM=7Euol*j>1D#PG;s9jkXO&UZcuo0u6{Odd z?AAcvDmQ57y{Sy-1MapmjH>uMWjdjW>I15@N$QD%K-<)hsBE{ZU&=r`)z8lX?Naq` zfOe~!D}eT>C3k=-)pW#>f2bbp3bbE6J^{#lK)pzpiNoq)x}qIXU%!I%n0lDDz~kx* z`efjQ+LAh+RL6V)bXpChj69=G@d9^FUAqP7V|6{H!FhGsD4 zfcru%bq2bmb|&k;QWw+4^0iq_ppyDVZA^_<)Fm%~uB%_rFgMgqCxLFMcPXiEtHWrU zyQALHfbOck=@|Qa^)}i2gL;rs=O;D4DbRg&4&^^~t6kt8s-M&Jk5xM=p(pAsY!>_% zbqSgFOf|QqV)#uR@CVQfbuLBb50(C(nD|TeI$bMXsbA_quhsj=Wj>C-qOr&G!WeK9 zxts+wiFX+ZG=-m|GMdVBdjd`84W|Lk;2%=v&*Fcc0-DYH39O?P>TStTYmj50N?k2zO4emCdMu)%e_`)+lce#mX zxX0=H%Vz!qAAJDqkGwbSBKP_FrQja$=5)b($Yol^BmVnipr^dnETCWbb=r%b^X>P6 ze&u{T&M29U)t@xhHR!Z$ z+%!ad4DPmJ)Hgui8DhT$x@%}k^>@$UNUr?RV7BAHKN*s#a(*^E-4FE8KtDC*PYn5# z0#6OvS)gZzS?7SB8v;q?H^ajtKraldD3P}qgDJhX8takuJB)UuveQ_dHkt}!z+|A^ z#&r#V_8Lp0fGUlh=(b~@af+GhaKG^-h3lYkB3u0rpmcy+54vGJ4UORp*8mfnx%QJ z0h+Bvr(wc!?FKDvuJ$AC9v0258o2pd`z=5VwHq~obnPb9=3?#VsX$A#@A?8Q)1H~A z{+4U$MPOHIV;q21X>%zQYqZZOKx;LPo@K4q4p4Dy(0Ws}HfhgXfi`Pl%Yi=7+ENB> z(c1O^+NS+Ur`PS8eK&ABwQNeAUD^kfPrJ2)K0tdkb{?owTiAi>??Y`l74Ck`L>~kk z&yXy%d*~e2+R*0${~vqr9UoQE{g2JdqM%9d$jui%r88;a)9GYkHsX-*^N)MC@CSI4b+5$5Og(e&-QF1N(zV0qNpLkL)18&mMbc z0B(6K*a!HJ039~0+yIJB?Fc^%&Xr9t}t6D>q_%_S_RgaTa^I3W!^zny4HM} z40)aTRkFYh<~wwYxY0ax2w;=>heE(+^O3&*+sqSY1Ku@Hq`vGh-+mR~GS{dB*lo_o z?S{U`e2$(#_L=9c0dv3E!DxUEnEfjO4w{G1+m}P;`mGQqx7Qg zn7K(5m>-)fQWc+=uT}$mYCcC6bkdwl*W^>?W@II2%vF{F&YCrPeR zd~dE!!~BDJAzhk(HjnuMaLcT01KcrRdL8hq`HzZ#`{r8h01wPzH0ZyXFAf4cGOtRc z`S*u8bPM25^V;=*$L3x>XyO>lJ$kSGhQ*iW<~YkCT68B^jy3~Kw3H!RpJM4si@{V& zsosbcSVlDhOt%apd)jCzRR!>lWg8W}+43vh&TX-rrU|>vvY%F+cP&A}#gNO=nx@Q7 z%kUqOb+_d%jm#d)LK=g;memWy=BIbqpPw`?aZL&(-nTc*&&`OMPgeVTt~E#Gbe_j8LH3pj6S zM~eEw;!VB3V0mc=VqaM%k@7EE;^}&D$#Uf=Vpl91siv!z^r3+3mebUjZ!GVSx^Gxg zXx`qm^q|Y<_m=730DiEXY6_TWy+I0^WUW9m%`wFqM3;xDRu>stfi;wtyXn>>vX4UR z;a-55)>LZYY-`1@08Xos(&k#HQGe%IZ_~A6zV!oIZ5LS2Yyd2>E~ic`wnE#OYSzni zIa+ERL;@?U7fJzETCdY!uW?wDs{`M%{#qWe*4m9mW}Wr!5X3fE*OJ;cTF1VG*e2`# zKLMMq>=0m^b#G_DyVh=0%ns|CF#wmctoO;RPguv~ z0!~^7kzJj(-lxax&#V(LqWW3uI$G>Mw^mI8{A|5Jv+o%A0sgdJp9%QOy5beU7+VjzCXcnP4Tr!u zTfzjy#@h;La!s`T>I;};EB6R6#rBvc&Qx1%8s!38QxceN3pNrvERthyH*&wlSo{Uv2Nw74NRC8$A)+vprk{=6#!u7R}#m(Q^Th zZ1ZRg{_V5R3(x|*)?>_wAnwdW5D0c$-i%K+;<$Ik<7^gKih#d}_#V0^^$e?&$z@T*NL zDdWL!zlFFxNc^B$f!#tRd?n59=<%aLW8R~1Y(80K{5zP%dSdB(g!`PMs{0#0MtD$Z zf6$>zXt5qK42!L(D7JkcaFg$ld<`e5q;c+V2xnYw3)?;{*TDQdd;dWLdpWPHEX$9*!fJ|x=AS!C-PyE#kgMgZtb)d` zF+GqUU%~ucvtMUx^?yAJ+*NZNOEkEqOk#6Xo;H=`xSCC40gPWBq?Xt0ac%jPj}89b z?bBMc!8y&1GFrE3&?>uOMvDv{eUd%ApP zu+EHkyvP#x8>Q4Tt_g)~w#uWc>t%zovxnvn&l%b)e>my2A7bLv{s@Xx=03AoJs!W; z=*0t_Y!9zjTlaPSLHe=P3C_f&R<%=+Bt&{nw(yvs_+BL zS!tfp9KHy&mC)SmFtv`W&Pv90-m0N)7YBQP_BKm#)mh6_)#&a8Kd_ROcC}p3N~yf% zE*9yUwUNEd_$P0wiTva{20vHGCU($h%66NQ>zD1UyH+}z4&g6;n73WwKTlA7_@-T~ zb;;Ig>FI5o7adHV?7W;(&gH+Gg)!%f!C@RHl8<(E+rvUsm&ZPK!Nd=I%X~F^LR)_I zFx$>=-8GcuYmcxvQ+A8C&6?R`c;FFbQXy!lbqn;TCsKj-^P zY;-JnZRR?6l)b8nBgFYHC-l;;w~w=xI`j|~p@+CWJk9ztp0|-j^5e%1fxOj9)tg^C z!{+iVKVvW-`wIl7on?I(4{oG4=AP%+cy~9SIV#=GhrF+ayIkj3sFBA$#7V4wea$-m zjoS%c@(}aolN+jjuJo@b1BPU13{=Ba3HFgSYdMSJ~Sor4x$= zEur)ljqE&i42nv;#!lsCyN3aDs7*v}|D0jNstK#N=Z_qoKXjmd*zlnva>?HUaV2Ei zLqjp`bNkh@3kka%Nx`$%vBUF%m>EUcoLSxMJo-9o#qaDeOyyN`RZrJzJ=B4WS6E{R z^v-VEtYNFP^fuWI-N(+yRd+4F&T6Rq`*mu0TXyS?twkHtnl<3J)))g_rEjoZj5j~c z>bZWt$@VkXm*2Br)KV`E>Yp>bPyc*-QNZ=Z&+G@rm)6nCg*~-#chmX|>@yrQHFw0& zVSQf8kElfLb-jO^MH{q%`7iU5_gF`McZ#tzUv!Vv<%Or2pX;Z4I5yRl^^nCG_~>0M zz?9u{@StJY!+H5pY8u~s0F&^eKUgmB`zO1_&mPu-ojKbpxkmp*MmFvb7QttqfnV;- zRybUK&?HvQwf-@yr}C|p^%UMnRl6En)NfF)Z6h8yO7(XgRMo}o$s)hepnhKDH{pqo z4lHuV?y?}h)THim_Cp}0{ovPgm=2;`yYp(CgsQJvNO-6Gp-Opb~`1{LQ z8CO+bwI1Vl7Hj2POa0UgBUe|bf!rrpjo|%*)scKkq8iIj2N=U#?}w=C81Mdx>d$R& z!iU4GP&LS>Rf9HZtr~&UYt}$mW(F)imNySm8}JihYPi4KTw66rZwtRI?HXjaDKcP} zS4H)p@!z>v;XhYZeVt#AH}M*(Zsmh-Xfb?rHPzowTpKg$|7)*O0`(xiwVK+rOh%jL z*=^EWW!G!lx}*C_8`sv=IZ8dlj5zgv(1_vOu^uZ)MvS_d7Yu{bgR2R_F27jynt^*J zs$+P{Y*yCwS)$rs=Vi7Sy`9xpm*#ao!|Hdnwz|>4uk1ILaqUS{m%`!0S8#-J@+dR8 zdS$4$G+o%et8H_2iqWTW8hTALo-Unm$I&XSqdivPzieiKJC+%|3@%FtHIVU=x}g_O z>Zpz_^Ed8e6n?8CR-$Vi)st!&v3Nh{zQMJ%i+WP?q8?|oZv_tv?Qn6f-<;Roii^~~ zdxkjvNq6-(?u^2<_^({Gv;h|)Ov9Z1`Iu8)z18FVP?R22{OVLE7&iAsZ*_|)8{TvB z;*ytUq}tg3p0^bqy3-iwES%-ZZx2>ibH6yf zg5N(Z*ZBAhUS(VxhNzm#^IXi=d2*}Gb!(XVJ(iJSeO@J#;<88Y~-SJjw*=iY>0O3=exV@Ihz zI-j1VJ~L=D(oi@XtR?V|$EZK>_^HNHu8U*Ul}ub`vUB?n8um~3PQ}vrtnFC&7miZ{ zRoBr8>S~od?_hk>BXTR-bCvY0wi)&Lp5?}>{OoDHjB`eU2Vd7;OX2}j)W!Vx6t%W5 z?pFur=l1E@CqJ*q%=!%MIfy)(I5&5AnXj9w*7+MhP_A#Ls%LSjU8vdlt}VE;a(t!x zyS|yOss?A?#!8rwYK8v^S4FPwv(@)>SB?4V4%JEyb6PZjhpC2Hd`wf!y3j@HI@POyVu8Bk3R(yKq z$GdMc`0zK@tNol;j+b^tZBS#FXEt3!XtAXy5ZB<1>YJ)7WV70s@v&Qse$J@XM(3FY zzI?$J^=m%+l;%y2gQ9uvc&!xNPHq0g5a3W6rKi`lNBmzocfpTB3Xd(1=U3x4b?;Nx zEg}MXdOT6%X_x-j1bzCaDYeA$EKfPLln_LYlYscERTL1YDRrL9 zUq|GRc#^BmlMn?oCB^ZaK#Kd!8YJSu9Suqm1vIAI;xDBrAW&1%o|8`#`MW&HmG&e= z0ZmDNE z^j!SS=i*DBi!bL@ZH6G6KC_w!hZuw4?t1NWIq<@<*q(C^11xkGXHDHUqMN;E3Zlh6+!~jWIRk{NauSGs7wE!53c_SA6y$)tAw7_W2?vK zCgmr^R_~FYn9wshu1Ag7o;{Njb7FeHZJF>Dh8v%reR{#WSoPQ%QHcpT2?=pIJra84 z!*yA5^`0?#Ny+dR7Lykj7ZaP1&;L5A)@>OZpBS5ma(X6L&+FMUKe?ab*aZ$O|tHTRfVtg)qsm1oJo}b&JMh^L8i^)xh&xxs#Eb17VpYL{zmK0Sz zu18EljfB|5xOnulXF^Voo;fkGXjfcPjfA8acbjta@_SN~;*+BC;*+ZPNJ>uZnUj~) z6OPXElS?GPw^~ACjh=CEnU)aa3O=S5Fne-NLQ;HgVp498>PdNVi9K_3V&Zxx#l_ah zBdihQ`uJnDpXy5ZR6WQlpLO3jsO1&qBrIOVZzX34LvZ{r;W-?eOn9E#PpZD=FBIiR zihjvc5pDUUqTq)cMGa7tctXsPWI|*kw470t#uP`sW`tiUN){n%!A}E9`3r72%h!t1 zMdagepHzeWFDW=0*PT63uocBF;;zdl)i(?^e!+^SqT>4!8I~rB+a%g0R+X43u`^$E z7E8<&8J#O}gT$Q@4@tZuk@f~t@fIvaggz20NQ{zLQ({Ajtt57n*w2j)Wu#<`mpD`6 zn-cd(JSvgaM5_3*#2+P=#L`6k0Eu)G0mW-d>?LuSL|V$!7zge^C1a(;O%nG={7~Wp ziJGUZNMg9eIEg6|n@Vgiak|7s65l3tpoQBd3iQOd*koc;^ITDvkq`hY(w@2bt ziMJ&FQ4+t9QUC@T>qu-OvAx7Ri9;lgmN-q~e2J?iZk4!S;&CsGKQ*8< zezhmGOKdMOSK=6nJ0%{Hcv9jw67NWSEYareF4tdTxWojB>2yjoRoqfyw!~K@PL_B_ zqN%hye;J7(5~C#ckT^)=7$dQk#D;EkC@m$Ui^N_Mhf16vahAk4C9ajYUE%?WpGf>d;x`h1k@%-X zGk&KQ^S`VJC`yRLNQpHhHjvm-VpoZMB#w|cR^oJt3nZ?VxJBY#i60Tt{68xhS0w%< z@i&ROuUn<@66;IMl-Nt+Fp1M7u9tX3;wg#O32|BZ4k+gTU77G$qQ%c$p${Q0UjZ^6 zPKb+RZ5eM&h|6488Sg`g%ilm5f0Ypb9Wp+RFa*c#%J>#Pn*VqUuun3MNjxXNwR zalO?1fzX&IA;vLK#w!t4Rg`GSuPfu}GM+^Uxpst@Np!jw#RvJ*{D zri`b^c!rF(kns*OPTzx3!Gk4^m&j%MVj15c(Xn499FmNa60b|VONa(OBD7+u#`sda zG$9%sNCsOQ}Xvp{znpjkoZWZKbCRYyFv}~6WCc%LM0ZKVF^+0dBSYWwCj>_OX5Ak?zor43{-P4 zw1f~SMc4xxBFx1_kuXnDst_WbHggl!mDp5bYeHyI%cMJ*x6Yk5sSi^|aoMTLLvNu9`JJevoO6=hoBgt`&c&9?a#fX{kon zP_x#!v}1@76`>bn31M`;Onc@+Ikk68F z(IJ%6TgLknqPzkbpGoMgn3N5I;YtnCdZ_FO|2S9+77mg1BS`4OPXueBBG{LL0i4_- zi+DdCY?n#>-AUveStJeMgNl*{x|7I7vPc@l_ZKA%b|;aeWRWz4mkf~w4s|Dyw`7qt zjAs`m4Rf^RBHddZzcev?Jg%lvUs(nxm_IZqZzukg$YvaVO%N#sFUB#q)r zi;`Y*Cy^Uvk@PyhRg^T^okYHrMUsQ3gvtWPxRc1CvPc@s3yYH8a3_&hWsx+FUn)u( z?@rpcRCgy$;L%~Sz=`gp63b-LBlhC8)?vD8AozbJL4JN30C zT)wF&b)GwQL$OrO9~Y(0cc;ErEOi0T443sTbf+FKmb!>WGtgFyvsk#WW?%9BwG6)e zbhwu6nY^DV?;{JTFNym`Xim?Eh+};etXkX^p{09f9e{@?$*RLmmBAWWjFrOM6Kfe* z$ud_Oe~Vb>!Sa%|nCJ>ei}CNt-=fOg>o=nh-(6Mns@(mvr_IPjmLj2b&k0@Q zzoL%F`N+Nu*{F_|#j=y4i`UV#ilX%7jjCy(Rg&qog=|*qzZ1dAPk&n?`7*eN=AEi( zUR9FMG2z~u>cQpdNwc2RBZY<~3ZK$$q03jFDjwIae-xUV$W!aenmj$OG2tqlYU;>c zky@|{cj1kzX%(WDA*nmqltk-&k#3%E#DFA)e25DfP4fDnd*gmPaXG^-XT59Ds4 z+c%kFM`jYre}T}(TEZ){TgdCXr?!l%&Ohp5Z!O_V+AU;<5M76;Cc2>hlfp~Z7EZt2 zLX#mBBZd0CKq#qpvF7b8*1Q2P5NcGrn0+0EP|?I5^a7ziwaI(AR32pBmKq=O0-3Mt z6zkIbAD(t;*b9X8y27KmyQZTMDq2uRyg(?fZZSR3OT(fihi+N^N#p6og}jOhz48K~ z)^&xyb2+vU%94s0^#Y*|Df}{=qzj>_!9P7+U0;8J(9#s#n#$R96f$okFBuV@sQ$4_ zl~aXpba(3p|I8G+(;=a;FA!RgD!in-g_K)NxJDxODksMM7nj&s91>3KM(4-d#^{Xd*sJn$?e!)^CYnt)`p|SOf8AM|U6&b{|7YNNNF4Uoz z(DWAwEl2Yn;>tryd{l1;4VKL-e1Xt!^%NyRuCC`HQ)J__ULX^dt|*J8J$T)DI!ewL z$Q(;A*0}Q!Dr(%^7YJ3TuPDK?agBd{x=!*J$fQ9gUCQ)^Ok?CFYgq6CnemXZOPS5Z z>RI#xnN^UP#Ka{g@+4$%ry}Zk^93?h8{&nA`?@{z9xjZUTV&}AM3OU}nom^3Z%@r< z`3r;^XFMI$WXKc^>dF_$ybhU~a!?0DrbutAUm)YkD0U&+2_ZW&ld|7>fzW3ePuJq8 z^AL)WLTg_j^!wA+MR`1W+Pd{GkV$BQdk#6OS&%8RxQ#E6nE{zBDf2#LI>@$ddV$PE z$XqTdZ#I6167ZZzO4#xOnSGs}4r`TUPxZ;Fu9o?}*FGUBP> zL-5b=;JR9XapqR0tg-QBUaW%gHi|5(;#OEo*OL?D679TuDORa;-tVFyJzhYB(ogBj z57gD}Ir^YJsuq-`H^Ps45j7Qs-rX1dsmypd7|p4VcMq&;9M~%JNDc+4`ej@fRMpgG z5x{^m5s@t_71=WJ@(3K$q7;CK-Ytv3bl@daV$k~x98PIfaU-pra-e9{F9O-M_VW>p zp~n?{GQ~%i1o2&opm8l|m?7XjgiYhyqm;nc#G`_TO)LK$G0%r1Z}5Et71PHv5w-_F zg$C21N(hJGn`Effd>5$}B8t^uGmxC;AO|Qu*j6lpP`wr+ip_x5fc^pMIS7Qxc$x_* zAz)}NpcJhFwM)mBkBYV}453IW!J~{Gy$CE*wJ~7DG(}J`{m~rZ*u@ANOx1AN!U+&N z5b-bt;BA^7NA0(n+F|L_<0LF}Uys2|G1LZLjN3;kGa?Pnx0j59`f_h^RcikRgLl7?Y z8=f*)shSv6RncO-P*ZpZ)UTALTfhS3C_^NaOyeRNPVltD$ZI(d%Yua&xF);4C5-WDj%mZOm`_}DnV8y6n6jf_QdO_(+1)+Xl z^v#+`LdJ(d3Y;F*ynwLjkJ(_?7RF_IGalg-V#A5eBsAJuZ#Rnb@EbT{fMRVxRohJ4 z>Ve;s2HeXuA`jtA;+HW^gb`U=QMjyW$3%qNlBxQcIzhG84x7NQZCVkDaMv5C0J{+l z-vV{2&A&7?^gjNVD?mO)+vlKeb!!KX@!SH`YVBUvP}Ep*V~y}!SeP}R>NA**Qn|e; zjHB5{BHWjLZL&& z!)B|v0m-I{J;AEvuDUGl(rn=rHke976SfG-;-QqL`S2cs!e&t0mINeLc7UT3+oQlU zEW;@K;aSmL7+JJur4C>lOnKuGj=)58z~JvKMWjj}B-l)snj&14!d|BQx(HXJ*;>Zb zU>?Ge6!tUiY>03aPTp4nP2Xc`ct%s9c9RcA+cSpvVWzbM5RN5&gz4Oy2v?^vtC@nv zAsk2i7}NeG7=O=rN{Ba=TZx2(sR$>VwqOPDOk9L;ZPTCmoNAhdk@u`|0pa>4 zIv2yUmdT_jjZLu=5UxXBrJ9)vF)yA~&Orb`%F&zm*IIS!A9ZYL60-p6| zA>74bid}_B`g%mVo2(SBe*ob;(<+RLXM+m}_ckq|1~t5gaDUU09tbzGc;ND68UgF^ zY+M=P;im6kKAuh9LuDfsPtrJbvS=~QK-f$jEn;*d22|y6bBfr5!1gASw;3i-4$^_; z50nYUOoW9MZ6+qUhX#{ITPKFiu)HY!B&C1uPXCb7iD5GwC`zZ7>+Xg05&4j|(9}aZ z-iFhqtx*I;t{{)u4;)K*5HRSs6?|4pK~GRKY1l#w8yJ-l7A+(7T4+WH`xXVe33Uk> zYZhgkMj44XUX;B)O0pSpNr)y5jgdP$sTV19j<=acOB5w07PwoA^3&M4^OH1EJ}gS1 zk#x&AWYU$QBpO(eg#5o3F=>R|`7?_;hh#5swVZ`$UDM-Wm%NaRVDo5jOI~WEC?(3# zye?UO6@md*F!=)7K-(qDHpFncJ$2%G;7V+)wP(Q_apBO)cxmQRx@GY)gl$YWuIh_` zhqvzY8Q+khRgaib1yk3cd6(6_)6yxwkM8Y(I<-Jg-Me8Y;^=zluwmTTM5`9`dMGhy z#2}^l6gdm?HS6AI=JU)Znw`zzgPUl6R@(EZ`ILi;vliUhM5`RXsRoGzm)E`N=U_Ni z3)a1Jv1A*x5WDVOfNsILSBUOy3ZYPF1>HLmpRhE+OUAY}c&VmZ*~<4PQjwOTO2gr! z%}TA;BH*L#{RI?CfM>S+20XK=R^Aah2P#qY+C)p1BH9qG*Oe2f3cg=bh)x|RICi3M zVyOpb2GM0W32@g;h#dXp;oI0E!A~iz4ACz|U#ALHCyEY4 z_auI_(CgMI6fQfMXq0GljF>4O3;S>Cm`MrxBBFamZ~TSY>tKGv4UJzQw~RyfU8Xjw}a3N(#^oq!IRj9YKMx6Cx5?&I@oGS8!iVk!Xy0Ho!92JV)nMe8Slp{KN647l_iEb9U zd`C2Kz!YKs$AzuN3p05=g)+StLG)KIqCbf#^pP;7AFC24wNa5QoSCc^Y~ zih>M6?Nz#wzhUmw0h&t-NLO^#DP?Q+U#=`PD3iJ8qRpP%SiZ+j<@asacHAVi8HHouX3_;CG z6b=>DoDu!I)s;9KqKW>DClIW&ZxEfjnCQcmM0-2Lvd~EMZ?~wpy->ARMM{1{BkJlw z)JHTZM^vl{oz)exqeQc=i;=z{R6Rv>Y2Fx;I#!wJd9fa>7MzX3!up6wyL+XBlEwMY z%68EMSOz%FM2}D9i?A@p(xPX6Gl)|VO!PG|mK}sOd@eNMFEp`5m~&@g0bPV_12IhN z0!Zphq2r~EDg2FH*ncmvdLN4;*6Hy?Yl*%-6s`7+C(f^8acwTzekGhZnH`AU6OCw) zi-#!XTamwvxL*8-QHK{TQLz~#ZB(uer2NYU5uLbv$Pf=Wu2v0+AbmgSb%EnjK^AAGMqXrQsmdnn3S^*)BqSdAVnjFDrZuOcU2 zDd-uTc=aU}#?Gd8R_~bs8aHP$X#7_zK@(szc%`$U9%xd^GSJilvXDkM-UQ9eBpdHE zxd&+eAsViM{mOujuu*vQ15)|~HV~GGbNCxj*>jj44Oq$|XdbO&UCU7ax3S#=(3b5? zGEzqU2KdeU^hGY3g8f{LurTE zU)1g+Y+)AQ3|krpILivC!Jo4&bb0!g^&`#SV5PbOZZemn5O|+$rFtK*`P8QTU|!W#}2h?Uw})! zPZqgT-9uCOhr{1aSN%aU@xRmaj2`h(iu z4!EygYylXfO{b-9f)452)btYiGc7cXqfhNu(Tc!C>3s-AfsJ~mZ&u9W~ z)o#53IG{DHOXGh~YY6KXL+pKqM#Fa;O)m5WGE01;o+l1)ia<1jpDx?Hpz46+T9L z-6b|?fViXFi7Y@^Ct6D@iWB!M4aBOWhv#8dx-(9jh`8@(P_>8$ZKw4*BrOTFf;g== zbQ~2OzhJS<5&r#j#3RlO0QhQN_vsIl2#;GP%0L)Q8BO{!v zI!VFv)Eclha^m$a3C>qPK}X@lt8F$aT%-PuR=_XH40IH30Ddn`5}I#K#1?BDpfA@x z#067dqjiBjih&7u_zD<-O{mK9b*a!`f9j}xMSIYYlR+|{|9)y>xuqRI9RX2Q0D;Yt zK!cW2!^&SI1qOeF-0tyyAh_i0O~kz?yoB@sW6@}PkEW$1pnoLE7LXlx5R5)E|C95S9-@ryuf zXHf-pMw8C#KI{To|EJZUO)@Kiw&-M=3u~B_9j#& z)EoNtQZT~mbOWuJf#KJ~|0n}mxk26n@89XZhgfG+9s1mx&0?JXdS}H5;`86 z4%+De3|sH~Ck;!N{X?k!uJqZC+qC{9GpX@y3TVy0Xg<`sF2;T`rixzYI2KGjt?ok5 zdeaL))2opt>yIFNZqStSG@LXZv{6N}kH+uOgl@4+XepPPpOs5ZZaI%uzII6~K^+~g zP+z)Y=Dahk^F^g6uQ@#7Nn+z`CT=VESH1j~PB2G;ts`w)yC6&{11sK$kM% z-}fE%XD7toW5cN1$Jv7VfQxKu3Bb=RY-v$vEzlO6c=aI@>~@T-=jC0PRQl*oX%dZL z!)VbM$67W4;7*vVuYjHE1(?kumjf2Cs|kQ*Y%b;|?p{hq1J<&$Qve&-qH%z&ETAD^ zJM$yCJ*;k1z&=*KHsBERNg(~hiB|^T6Q<7soMCTP0bF2rY4C9r8fCf8SY^Ns_TWvx zPwYBb^KJHZ0N_4rNw)eMdrU*}n60i0ctgG5A^X|%xSQ8t~Q{t3=MFU~O9=+vc({0~*#;d(qkyQw$N{_i}{%-OPbHlIJrXm@7KFz~N7 z<7mU~KQaR!utUP<(KdewQAN55uFa>b0$s;U3(G%)9Zl)APyt@4NE4{w#9Gi=a6 z=U*xHT-RRK)-!P!=5wcFIe$r;@2dE!HbwKKQ+=Ks=jOWXFh(+7xZPmqY^vtZzdpxo z+e$PDQ+eaDT0$v09r2li{dn+K`Z}Kch8E_Xjl+T3H_ND(-8`d3W~=OMdjfy;4Q;QG zdFDh#&MxZvd71HAcbtGTYM-GZFI=ygoXeU-^ONJX<2-aC^LGAH5Wv&V8p=3VHjUsH zCuoPb_W{GJuHZ>pb?txTq@%2uy2(=ktb!Joknk z;Ho%ZOVIdD9G%6tZeiYhS&r)I)N&X6-SJ^3d#S;ESt1U)TCiB#!<@(SZ@MyK3(5oA$qVc$ih54mDs< zUcPJRI<2*a)4f8S-K+HFcM5Q@VeC6v3;ymdoEbR#9qn_~xnksEXRB9sJ2!4LxoU0G zhOvJ=oRtr}uZM3-eQmjce{fBQw(jevaP*|f`RCaC-1MC;4vN+3n58J*<$=NKdTWnX zjq&SW;{d@{ON}477VgzvQ%$WiIyJzlO*~{IPAv>vZd}H_F6$oKQYY77u8IdWo90|p z(B3uUu(n>~rMKZ!zgIre^0%#@)j;F(J@g)~zMp9GRNjLbhr8Z8sSQ;B-RWe`*wtlR zI3%wE4#CTA&>@RoT5Ak(t^QnlS>5*I(rt`KZ!mHm;HTG`XEKKHO&7G?{H=|~Fz);c zUplnqv5VBw&Vr6*$V5W%VY=7zQ_`8!x)LAUNge0hv(}q`WHwH54sBPO zG{nbW!+C10u4@nY`0i?k(|bc9Pxa9)yon*C7Q&1`M!KkW#Q-D@1V?cw`n8E=8JP+j+a*J|tAGC%x|(ZP)sT+KAY1}4r` z^;3#gFS*FuD^!n4h>EG;Dxn+VaF8EP4$N$xk)EBF-V$g2HpB6m7Y`aET>FiNuBzkz z>gX;dtvasuIXt4NUi#_5UCzxXtGkYw4egBo?@*Zki9=!DWIV^m@R0*|h>D6^Q#=d^ z>?$!&B0ca>I^8l8j+ThKP7%lBo4{2PH%mM$@sz}`CDz7m9hK9}jSeMSGWtn;S>iZ} zg%bBlq|KUC!1ofdw_e2WOQeSiO7~FRSVp2MlF?pbuEaqSM@e)_Tq<$BM3=-5B%YA? zK%z=_)~Kh1#BvfV0UeZ3T{0R-%#t`l;$(^979IJQ$@pH0XC+>d_>;unB@Y8G(4X64*duGyZXeA&IXDG)(4SRyJgrugQe(d964@p=)Rr!%UAFZ6vd^#2ym+ zNE|HjWr;;|dV&juXa*eJoswh-2lR47p&MLoxa0;?vd9wchW2i7xZy1~oN&VfHw4!Z z0*%}-$PL^L``vKE4JB)eoJnrTcEcn$Y;wanH#~Mjcr782>4ulxu(Xz8zxm{s*vN-& zqA#@#p=X&nz4-~^PUE+T>-VD~zBKENUEAPpKH1R&m*b3NZL25=Bz-Pw0TCw`2;EhWm;S4@FYe&x-i)us6>}61&J9 zDX8W=xDi-_dh<=h-OEo9SNR28QOslFuI0h0;6~h06uYQ5GZoy!d=POPgX<-@ONo1y z?Lj#m?PZ8f3KI}H_Ia_bOpSXkhCE}7>;|`)PCF?`iuJYouG@)zd0h%b1vXR8n zxT8J^fICxgHxYLWKSA8&hp;ZeeGIPJ)Xv{0l_014Ft)FxC?nSJ zuMpOcA6M{Qg4W0osy6#%ZmP+LJ~J?n`2-6()}ub$(FkSQ&+ui9@Bv@lMg}i+*(07s zk#?EJSUoW|KBnj+gVpFB-rwN09{wWm*=slF>)I^dF3ULF+O-0@ zNqB4c^Z0X z{n|cs*buY~IW0{0y$v*Fp~bo%1yLPS|0s=Y@u)@jzW|OF2r=V%u~K>%ZlL3uKbmg} zoq$A(Y6?$9y2*)JO_kxi25^bO)hNs;LsSl2*vT9*?i`L5V8pp|SXEP{G01DXS`*C3 zU<$5JKro&PR*dT!qE)7fPDDI&h=b24aQ!ePl8~`AUN)whYKCIko5mrhsWvGAt@8&- zA-2Kfm4I72Q#}>=Jxb8_b5jGV+Gbi|2fyjd$nRy!jzKt+_+?BZDf;#+iE2CfMGt~TUOCV${z^$dt)P3xeM$wN~NWG25 zn)0b!gXsdv_olFJI+l!ZU&`*Glr+=;YCcp|zxoucP=>c|ZLHXUPN(vSq>?OUJfi8G z5mN+SZ+gVgZ@P-<1RCuTYXRF}ItWd8R1ZVg!}LugXj}rqHq(-(d~a*K>R5s|pB@Q^ zAg9+tf^Y30Zfj!N zsF+@^!n4~L!yS}v37iO?{vn7TBcr#5-A35|S}c`04ZT8{Loj~U@N?k%UZ{k2g)Txy z3wFoH;kLgvxZ!-mlAzYQhUZ&kx20g1$ zo-(HSjS-Hdu%Br%sArTBoe4DchAKUysZ596R1O2|8AAzSrgL!!$5KLsX-RX0t5c!X zO#A8}97p^Z(>dbD6F=VMk6GiHPztiirde4CCsshXwrNBR!pZdzPBo3Ih;WS_2-i1# z7J_iC83;EveM_Bj)LDl}Gt>9fh`O|$KFf475#bbSbsJL}?8h_hI`|z-S7CRa^=RjC z7t?yGIK4W;-A(f;T)#2Gd8P``y=Q|S2=_LP#e(G7@HK?{o4&*Ncs8P~^@B|XFnZ6% zn-LyvQu{XLIm=f5x6hG9#Sg(=D6-T*p!45*}mGUf0`;|dO0sBirCWs^Nz*<$1V&sbFWfQ^8ZZvX$G>&Gy{*g^B3j2f#|c920z3k zVX%^-3ZpSY+!cmVg>*?ng_MUHRvG_`3hw7OHm!=sEz{4FT~4{_(qD-iU)@vh<-{@FD#*~9IbiyZdBjt9t1zn9b7MmqS#o3}D zm(amWSgx=wRy2#w(A1R&n2gv!E_&YqlLxzB^(>L_fy5 zjSa}6SqJR2jX)_c3i?>6y=+-Z?wm$+kf32g%;ig*Qi86HqVQFrk2F#7WieRqV?D>V zTcP}OuyUwZlsr!4rw{v}QOqOka29#$g5!V^#F&*AefqUNC08s*^ron|VnYg-3L$F7 zY6->SLW_QjihsizgK7lrE^Md{rU`bmi-v}ak|)9Puuo77Tr*M5>q3jIs1}EEL#Uk| zw{@kOsGj!h>EawfZ1xuF^%rW~Bzk#36#A#Im@F&hERFR-S1t?sOI-?o8&33y;J8GU zR$(P`#85hgKIlX?nCH)x2>uY(`<57jo?`4L3iaL-W|Ao?yI+!W&KEjJ6T?)-k2qaL zUwxWUxRdCBe{~9%6B;s#zV;DXxhBflE$X7r=dj=1(STr<5MC~NGf?zCUNq&1Q1wbt zs56yvt`*vPO^oYI5xyHs`~s2l12H4$EmSfr|@q=e_w@B*djDq8H<~)M1%|b zSH%Pqd%=`4c1n0xw62%PR9&c1e9NT73a#7`3iK4!zb-luEGpYAnsrGic0~-86Cy0X zbQ*>8geLNZ4qg#WJdh^rKa^4OTUCkH6C)({EhwLxh%-lfJ!& z{d>m4tc_iZ$R`@F~+Zm5&a#vBf3(vHqmur`MfF=J51ys zD~8}}F$6cnLS9!?vq$uAm*~Je(TEYE-(5us*F>HPVnCaUJub>I(Z5u&+;XAnX`;AS z#h{#Vw_P+ycs*98h@2r}NeL7)exXpim+0%4qDzZJqoX(5*r?)y(Ly1CRH4j0Vroqg{3y|g+Vv^*Td@*&3k7Zv)?gAH7$!79_ba;6PFMh) zLyOJUVwn1gT51YS%nv2LcPU~2R&iaU`4OJH0^#S2X_Dz9T8jLH)9+o*K( zA(}3R>AcVc9gPk9r$b3~<&qd1IGBDE@G*lic~dQ5Ck4e@We# z$V#Ap*hYSxN}0^wDuLJ{7D?(^%s#FPxWi&eK@ZtgYRVWjlWcN=dW@Je)wNXP9Q7or zd!ag*y8UDuc|PhD?I`)MD%oGTJ~Ych&QtfIqp12i$Ed@tD^bYnk+SSY-vKp|R@k7&>FMF|Zk9qy_nkwvq2b&#;aB zS5jfDLWWZPHd$p{YqIG0K1eRwM!v|7aMH_UC#hFR1&xGn`phO|Z1 z8Fa*PGRo0isfiQVJ2WR}vJ+JH95$Ke-BQ+!=FvK~-c0@9#%|&Qgl*)a!8@2}v5Sc& z?_{FQPqvX$bFqz_8ZT66nM(#zwhVRK-$sTIumYB*hg750yJA_o=7gtWGU$QN1R6+qj_t5I`PN?}y=`n71bWxPy9wAe;g()wi4X!&*{1q5YMj?kgBURT~k zl_Y!>4Vto!#yDfO3AFVdTD`_FCztZEwITQ-C=e}i41*4|{L#Qg_;@1m|gV4qOi9gQ|_(OLI7CFLfl2QwLH* zQ$W*plfLUElT`XKqV-QCgEpud2HLQUgWA<3g^FvPK}B@Pq#`>0MYPK*GT&^mjWX{n zSyA7%G|l>XQ~L*0peZ%@wFuDR=PBoFtLW-6g=JFBg={`mG?O)@DrT`>G#zKNanv8D zd#m(Z=7akm+G$>!*5bA7Eh>End#6fKZ&Opj@Qp+d#cT`mAf<+!r?IS1l0-uXP_yD` zyRFC(UV{1?(G?oitMsl2I)xo1rA}ohsK?XT(I`LxdyN`5ojG(*;0#uc2Ca}~mjKLU z!>Ez7SSw5{?BJe*>ahdSn{vL#aK)k>+-pde``B#@U_aYLvG%1JadeVQg zK{K6)ZpMzhiRbi(|FB83hHJ-p-JAW>Ce0B3dU@5xqaES~woWpviaqNGr$ggg}_Q~4U3{AFay|IO_aJJDO-g^VF*Ua{_{swP&!{F<@KA?}Q zuWCVZUNo-pT@J=m$3#%J5CM zjYj@PceN=tEC%pPKk0t_GmEk3|Ie+9IUAd~KH6gRz%EX?bx|xc&zhC1TS*v`>+}xe z)PLHkScfN`Ua>mso;VD}&kiFB_-ruCBX{ zpR3P%H+9AAH6GTSnIBsCz$De5Cmt|feeniG9(B;z>2LNYy0Aa7J^R1gn&|#@gSR_m zEap?x)#b3U|Nq;Tn8#kO*bU*oikz8lc-ak0-SD9sZn?qtuE?3jzM&ch^G98s4`tqZi;9jMQnqS22K-HGUY5p_H=hSDMIbAC65dMw0<2=0kT#$bIT?lo`mm5+>J zlt9~>y71uNk+2wd$bI>^Kaj9U5u2L2@IgpW;m~*H@5XSC#i&fQdq24B8-D3`V}!?& zq860=16fVMJmwE%C9Wtr8(j7)cl?2@OWnUAcHx^SD;!Xtq^#h&yYQH}746*qC%DVp zyOFx^%s)}U0zT+Z6tLWFwNM-}5AgkxX&1e_Ma-{x$-mq=aT|@ErThivPduBLEAacV zU>1U@rc~gY|3XdR;>m_IN?HFu-rfVes$zQ|-m}X&A&meB2!wJ{fCNHFFVv8bKp>Dn zXwpI|0ck=&1msYaCIq5vkQSdmDt52!+AAt}QSX)SeP>S~dVk;l|NOu2 zd%p8zuXoLwH8X40teL&D&pxwf*jJRQQ@+O)S4Y>)5t??JVUN55XF@$ws{5GZkAHE_ z7ux%;xFW0%=VRpT7ont2z7a23cj{hBb(G}_%CH5GK-yUMNcik zJ8(>AThRsk_-L)Yf1sIdCF7%>_z4^jm*P4f*Y@~C^A-I$j^Jt#DdEBhXRL$ zRoz*YAE{r;n`8W;d9}#FRkc~-HO(9Um^n45>a(g*mm>=gWQlVk>E|y6q^zg=*B1uf znHxT2X>NzArn$$fnrz!zwJGCi}8$so(Y~lOszyUG&Y3ykHms+5aqyEY~B?UiPb5d3iwm*~@`-tSw@? z|8~vWcJgCiUAVR2!j*WU)BZ30jjCz6T5WdK>ReIl9TJ|`zUokwcB#i~mJ_*$s?J?L z8_|5x+AQN8&8r`K%=guWWewSGCp$50(aEd}@8)-2lC53Jo4vA4#MF?yqN>P?OOw`R zefHWTKWR<%b7fPXyR5~Bw}1U|;L@en1wa2d9>c0Dr;&%MGIF&`iB5ywm%pT8{9O3g zlXs;*6fnfhZC`ay)%Ggm+f1YOvgm6c8EnQ(Hgkh=Tjg%eMR(F}Jr?wn$3J-c%a;+m zwZhKMP0WqS^-4!-(LcYIAGPzcr!Zj1^z05*$Er{w!8@Qjo*mSpe|_zERdjB<0p~C8 z&!ohg>plketg=&wm{GoG9;nHk_026K@}pV}nf1-)5gn_lvrkrWKq3chO)C0ID_)gl zzLx!!7IzxG{Pnd%Svap_cx{cH-)4Z&d2S?<4ulyGmoGE4%;M(Br0h;y({v%#0CkIuW zk1kw%sikq8xAq#IdK-@Uil^S1ZX~$Z?+2LHTKt=Aj2R8JhNs@P=OM$-dIB=NkDq($ zLbP`EvA6q+q5cGx1ef#JTRxU0SEI+?zPgtW-SDwD%{|Qa4mI02554j1Xb9W~aJR2R zp1<&O9(oJGnb_~zLvR1V3EKD-D}!H~_n~I|TgS6S4G+EjFb9&&u-=dly;&Y~+Fv)i zeKYe8ZD(KHZ3`ysDv|e0$(-Xk2~r&FH)e3V|nm5O$9un~UYlNM^;F z>vU5%!sxUWi6B;loaVS6Vx+Q=>&Fhf1n9|ggS!%^AVWR*_5^OH82unF#Zyl1gGe-b z^370BzWo#TYz+0}+hrlFpE8@(L7dh)F=zGgBeCZpXx_O@YW z`|(F;{-k|0Dhz9ApfP#fRio6CZ?|}%qMm$n6@XVyzRg?=ej3&J1sDCFgyA7W8wDrcM8N%y0_NB_v+~|cH3V)9hM2t_(#{kNq+7((L4Vb@`3InIL-KX zB_E<0J^Lcj?J3l4u`=Tm3~WFxGyMYt?ik7XBO)N$@&r^gchz$6c8&c|f!Vz4>ZwR< z>jE8%imn!uP-Vc*JuI|j3-Wfc9?iWr%KoXqY}LI-IAnXI5t{KzPbBu1LpLBK;DHx` zfp1}S1CE~~J0RFjE;PH0Vt)ee#bp4hX|)3U5%Okm>D;+mz(XwM=N@W8evc$Y5mxc|dmeQ={}{%{ERkA6h4cBpnf zYkU;(6Y%k2vaRgu;bzj1uQ9Q7IbK#WuEtu*hXVDqS>Rjc!-ZO_Xv}lbYC0x{-s*kW zX0#fzlBIOX7X8()|eXY@VeV`lX@ep@R1b7+79yh~PA9hY!b^wco zUc~l#yT@XF>f^{~x;gvw32b|So6nQ$li0&Su)Z}LzI-!8#S7V>fqQjmb&uKu zaT!_7onL}0ZoQn3KbcOGQ`jVk|!8lg*oUX66+$h|Ih1WV29Y?%7e4tb5T2>nB zRJxXxj&&+s%Sx*>ssj|Ki};(f6w%@4^jWjZeE^VN?&q2KDIV zhh{lzg5uvquIAo23VcFmh)wqj%&efqOz?j0*CvBc;_p)e-7RhVwvlF^=1syOOZgb( ztTD)FH!a8hV5AwAb{zF-tx6(kKrCh(3o-m7x?bvL*3~?;N$py>UQpj#)I#{I=yau_oOw8r##BN>jv-%Z~Ksl zcIVxNL?SDVbuY{SpTq+3?vg{`lPOPj-;VXASxOUJ7o@u%I0inoE%@H<-=~02=S!|L z-PsteW*Ota50GnFvtB;%gWMffL*8dQ_CGY26i258p(0zS>eEs4iLV}AI zXr81qDC$9%D}jF8hmh~wRzd2j3x@HYv_Sy(DG*PFWAAre!S{5UI=&x#FYpl5gi8e*}Dg@?I_USZmZLJcC!W z>EG@}&JePi`}0`v`Q(?ji5&}m7>(9Mn>H9f&u}J8Y?#mKwiQaUCmprWkZJg-i||Z* zD;QtDI$oOu9u@wHF!B_$S<~H&m6v<~xu2UBcuLvz)o>5%@?)HS2S!!u`W=(q&oi$X zE&|*iBGNqb$!hMYVc>6+RiY>(z%^hn!qoFn{}A{;xOlead046j7thf=^-?n!Hh3N( z>*vm?LIo$Xzz4d^Xvd@EgM*7pD>ctanh@fCjdq`+eyDqSCith==XP#>Me2Ea2Nqhd zdnKsn*~dYn+!yD8f8jGe{uAx~i5-3MPh`Xf7h{WH&nv7n9z0BYm8PYGhi&KBKyUZ7 z3h2LKHs>UN7@D5*9`M=0#nVytZI&J2j-UtLqkg`-egOFQ-w5O+pUe>buoykZFXqWTBAoQY`MCY<;K) z5Pqo(Xs*nO58qvf#6Z0iImzMq7)(!|%t;SV#nqB$h&~rNy~DrTgTyeM^D#3#kzr6E z)dqy`%tWG)IX-Prc-~D&4cBi%q5SZ!aFb`G)GG}ClAar-v%e$5Q)%e}y&KfVMlggu zi*-irAQ6$tW^dLRm-!;%H^hf$neKz)2YN(v#HHsJJsy4kSdVy!^Z!6W>4}S3X9GoGrRq36b`x z)um&H6)>!$XpLx#oC+fYJ&}TsYKF^2t&`-n@Jded&Vucj;eB$D=ps0(yjo)qo0?Ie zk>4%G1o89}2U)?J)lkcnycWI~5>J1baE1TA5B~RLi9A#nsQD2dM!vE!>YV2~y&e~3 z;rS6LG+yTluZ90>DH0Rpn3&-%j@Cq}EnhK*$k(eSIstaG-7KtiZW`FpD%aE8V6ZeMCJ%q$GnRqaKMmZAKGvU)tg&#oJ zc&5v&v*BI4BQZl(_mbwv|1a34bV(a0&1PlV?WFnOrA)WhqAqym=mChW@Q1hn&y&0s zzT-M1=Idd|SfKfFK_M&4_}XiJ^edxU3fgO(E_lYsS=X5}+A~wu{aHp{FE_Q%{B;1XbXhnw)=4&42iz9D{?;5y+Nwt;?HjxlH}3bN%R&KNI{F zy#jo@zL-Ly?P*#55`19sIZD^M!>B|2=PU5?UkLH1`WFHY6j$Vb5L(9_Sc-)vo`OcqWvyNecmBcbV#Ys~cF|Wl8#nlw@YrwC> z(Y4}UqzlE5$Unxks}AYmvZ+^?E`q29J8{v`(EMFV1#_zIW4vF-R1tJZ9> z8FJIXbZ2&47o>V@?C2C2!~z%IhJO4X5TRSRE`g|bLVy>jC9Z(99T?UwenwLXDBcx` zDwZ54cEQBhe8~7)zgRwo|}BVnB-f%PH_yFCf?zdRDumr>|T&# z&`OC%#(hYnqQBsiX=x&4(yaGZqJXsYs;GA?Ej^2(%355JIm#cU`PPCz;RVssCxDy< z`v_`C6@_}WA6n3%oL-5XOOU?aki)k1`LJcP%8~jFQiK~IsNmhHJ~;99oH2I_E^Y)1i;=z7MgiIi zhNHe|a_`ESn#dM-SXHZpZnxv`N(kDT&GzuS@Yc#Ls9Qt6Cc1L~ec<{~HKIZ66;Cy& zUX^v19$dv@j&^2)c8vI`LHnxA(cUVx`))_wh0vCR6EFJQh4jjX(s{zy4SkWrbyb+C z0xR7MwO2s~K?VMHUcZqlM(8)=+qS;Qd=HuZu+(c9q?8)q2?#hcj`z9oLB_M|&{h4a z_tT*zcKm@FWAuYyeY*56_r=JR{?r98F~sm*-LOmvQ&3e5?=3xVNzcE8{N7VF;gXZ} z8>ITPlR)_qmXQ5n8U|=0P4x%yz@f_8ItIdTIp!jvjSm-2axM6lOG&m|1-|7XFaRxl z&w$1Q?Ob|!^^=taCQ$I&`=R8Z~$hF~37RZ&$#@pMaWdlDdLq*5w9Db(b z5WXExtipbzsGzB$47 zL0aDrRSe!=4)!E#^FhBydoPwvXn%zRZ<0qf2^`zl?jXLM(9n9k2nS-pLq7ga^@57@ zA$;$|YNYaE^2<2K_J-7-x=*cRU0*?z@DGq=*1}A>Ud&n6P|Hb#+EDLRQA54yu~4Gde}&4mb$=fC5r_=9 z9m^5DZfwGD_u+OdN7C;LF`Xu$Y(o^y1MeI93(l;9to-^^>|p-~$$2%8{-}m+J>Eu; z(yY}u#KMvE5YNS&RMOfG4b$VFkaE&6M=V+l#n>Mq;+`_YypX|M{x6iw3Ype@AmZi& z4K+#`MGZ9;Ook`|k~&InPMD2k>>`l6QDtEqgr6gUMQZh($mdSqnxJp8We;Yv2ibBp zna!cshI{uwVIbA`sp0uY?6?`$$gmqorBkR`hMi1(B~u7HnergI%_V77wq*t8Kd=K63#9m4Y|cfWDg(0mz&^bk~}H$}nO z4$9?Rr2gXa9=Cd(^K3eDL;<(1zjnFO3YDf{NolxTF*cc~Q+l6LRD|*F z-j}hS1qk@Cdc70sa9_FhNP9|mhwW=5eI5AD+TA zEt6IFoIEY-({RWSNIhO#I(i4B9z)7FAmew`JE)Y0v3S&|X`05vSUxI!17tUUa~<82{~-~fwBfn<2l)x31v8Hi|b%RO_(;*GYq8@v~`}(>(xET<0ev%?pETdI799zP+8CDw_MSO1Fmwn?x1p zViF6m>SPvakh4h2n&ko>Wp$}*mkUh~-INuID2G^c#OVzhRL_WmC+V91>QYbi!OwBH zPe%>defw$`k?egfn|AbRWQXix-$n*w5c)ao*V2~EM$SUAf1_SQGfP<%K#RQ64Qbh` zL;weWfNEJLa+Fmvk$WxC4o(_qe>B0>dIY;U=voD|HV;Ym4W*bIe61XlIJ3&0G8gvc zH_AnFXq>Pwq>7d?!yG?qT0x@@pxHvFt9N9z;UEl$`V+Iw){{n{nnrEn=bug^PB(Es z>sr5^UXO~?7X3N&{ET{2%AC)=A$=q`zw(5z1 zRA?gzlnQM$VLuL2!`0DlFjqfV4WPhp50viMI6Q`N3MK zmEwTCJ9uJadGIn1q!I^~3yKJ{aTwZcv3oO^t&SX2et4Ft!yz=MM__66@T-PUp^^o!_ZBBjg}DPb@GaLg_FL54->>KT>4>g4|~5N>rn;&hC7Z*~PbCB?&qXHt&yv z6S?8z0@EO8d&~=I$W%NBg)xXLE*Y^5*M<*!G62UQ9Qh4GAnJ(FIAAOs+9-pDm^j$5 zzrE`wvzIRwEW5x^?2Dt}L%V1b?O`|*t_t>MEyHuR;z1g;^paYTa>Q0e8$ zPB$nvwv~l4aa7}2i=**}2J`b*pNswW5guY(h{%8s5{|%xb=QA|*jqN6%%3)S!}lRdAeBUFoce2JT9V5(_|E2mz@gIc{!vTFtC76ADPrM3SapU@dJDW(xM^k}wuhqOok)MgWrU@j#GMqpPf#}bXa;!?h7Iq%TSxjOJY;F58%RI6i8KbGfY;Jt zB=F8zc;C`y%MQGamE6)EmGX!2p8>Ylk@W;OBR}d^{L^J=yH_z$f%OG@gmffz-t_8` z{XQ>gtNSQFC>!1>t9A{hWbiK1n<7ZRla0NYfLG7iGz099j2L7n%KUMGE4$!{jH1<_E_ zj_XOMFC%?gx;+!K5bq1!MC$A-^q}l<2RZ6Xq#I}8zcp-zw1o5y8G7=Ur}%*=C5v!X zYia#glNQNRc~TN7%f>l-&O9aK`6bzp;ghL)|7g;;WIw{Cyr+~mkyg*~GWWO~np7zn zD;+z%E9E^iNS}~>y&^-eTKeqssg!>t{n|+ea&5JY|Gv`d3^`R=1X5}27ScZZNx$1m zs>>=4?;u~0KzinO(!Og*x63|#AT{Sn&pj?1yH^fMK{0in$EtwZq*)K#M*bi00pdTp zh>0K>vCsAi8W zdQtYQtCYmHpyU@hiqp4|PnCm}EJt+reoB_zOX_Uv@-Ta;)gLDPp(*L>(%-&1^3^^p zy_S}4lRkBfbfxsf3vyMMvzC%+vN3*d4&TTyY&nbkKm+c{S-AVeU?A`&{fw$8r>9G2CSH^SCvqrn zB0ceyPJWw=fSs~zDu>CZg|%nKbut113dp}M3p^_e9F_i%@14{9rSrR8N1YfM4Lftm z50$2Omz4&Or{o*ya8CuV=X9xmT53*2=-~$iGCnS^A@9qUr-u*aWQdVb`UX^8S`Qh+ zv!=1SRq|vL7fe3?deRxvlo#dDJhq>bL$cvNSCZc+>%1i8+&}=UOKaBoEgbIBx?vz( zS|kGBrL}S1^lD9_(j++-#)Of-ES=w12II$)ABEmn+H*TeJ8mbP*NgPiJ4p3%(x=9e zj*^Cc5kdZ;YAkyuIP)SS#WjH4azDBm)Gs-lDt3`lS`jr`g z8vP(z#QqD<-3Yi-zZ1RoVJn_i46aA@9%xsZ+VoM@)OP$5(D0R8KzmH(5cgTh<-BMN zJ2~Sr>sT*((JKc6)|rD?7Ap^hKj7v|Asw~hqUMnao1C*%GK>4Rti^a z1^4`Mb${zt{3jAOb!N5Z>hbw~ki`Ga5lk4^3^cJN$1&+CIyia65zv(OT)|R5pi9yY z-wm2Mj}bEPy1PINZexs(yN;5IQyi|DD-VIrd)5YBQbrf768|0ns1d__jQHC{5WI}7 zc!D`Dheg}gfaBsQrXF_Ukp@33q{a1u&$_!F5z^$VJMqw5?8HOcoes}seJ!7_18sA9 zIA~b61kmucnV_Bi#hKdWG<)Ieey0UU_=7Q$^h8_GjG2s)K7TM8`!!{O0pb8?-a}kp zhHYn%6m4o4tky%pS?vRRf=0f=k}-$-gQnav1+-r(SD?HYjI>oWD+UyS)d#RlEMi}m z`$Rn3*(%0%0c;a7borgak6zs?Zs*|d6B}Cr_KWkY0QU*cOu$jGygA^Q*g-!(BKk4h zPKfu}<447T>i}oPM=JqOi(lFGXGGW-zw&HYNO zw`bWOrz-RRLXyUW_^PID<>Y2jC<)R=+w1v~NFuL0H@-!VRKGk)dzu+?b6G2dn+ zvfcg0Xj*u{m@*mhkF9vJa{vz*iFEK2#*?i3N#ovz>C^TedM;`YYwz@aU(n7gT7Y(G z;YCXfoaS{jytUjMvCRfH-%+zcyYm4lEAFXfph-#WK<4xNLHoaTJ7`w!-8}zgNAE&n zz+6UG&PlpFH*hlO;IsjtMW3gGj@`5r^tyj+2c58JJ!tVSBSFhYSAkCZoYU<3mpSS) zb}%kx&+G?U{R}l1e{d`48gZ@{V58WW3aAllGXR@}?`$Y=vv@WWP%DfOz#Za|u7K@g zRv6%J@jmT)Skz!uaeDjhY6x1V!m%>l{!Io*crZN^(Y7gQ%@q1z%;FikM#RnnY!Z0jLc>lx zowgu#QryrEa7x@vcuXum3^*-%F!Iib>5PEK@q%c;6XG7W{-jtv8t{~OhhuV9_)ZrC zpB6gd8F6JF;91d>qwt*gVg}%O(X9^ff_SVI;C1n&56%A|!syL)`UHl?di_z3_HFu5 z3ODF-C$){bNr%+vq2mCX^l%2(W<9VUpjLm9F1uZS$%opo70)j>0Ji8qFkEc?68pPV zKe_<0O)tZw!cIKR5xLljrx}J9JMrw{2yHP&WFxi1SWheV7`ej$2aUThJaS;d+Ae{h z-9#GRVE`-b_!}p&cM(krf3^e8KhB8i6o)N2pb9o`$r%{-A_hf-UDN4MGOoF zjr^T+I7%D=jj1H><__|M(=(N)XymJ;(=Kp)roXlnbmmUFWOh=S*{0C$U`b%1+C+gkt+h`mDr4~d=A04JdiI4z#b0h|>co^zfR0fm5<#W@>r zUX;Y~`s00Zwm*^|idoA6pNa9YfG@@Jy8z#dS&X0yqOv{USMkeaz;A-Tr@%WhM~(n2 z*INakDSEE?rLLf!b0wfH7jhA8^*l$rbp{up(Cm(&Z7#F=wofzz4Rh^c|JzkD>N|Ql zw%&l2pb^W^j#K5lE=Y$?Sqj>I{$S89|A9qL-u;wzoPs7~y3J|U({|c;(6C>+gSN}< z3)=n)Cs&949?*`7bPSDcAHJVb--8%jDe!AXzqdRZ3L2V0mqfpm0GgP*9yGNdgE3<~ zgRb||IiUSM<)~)mbI@}3M1c-UARS`Jfc+IyOxF9pScegDeIlkZJUzapMtKUe84q-3eqv)F3vKn`a2YzBE;7H3pqcTSU}GXp@ApIrr-vTY@3>LFT| zcC-jIeY3RHy#st^WI1U6Q&_95EI;-qdpLccvo{kocaYrkdZ3F{$c0vcDs;g0Wj7&P(j zn?RH04#KH(IOWpIX-cm=K6GpK`6SAz*md)7RII@kK=9aRdC6z(5+e?&Y-iC|i?3P> zt&jB&5K^u$bpwI$zgiikU+YEdu4v*>aS#3SnDDJw0eoDXxKs75*?V+V%N4so2fYU= zRuoRUX(u;eD&ac&hP7Y@;JhWbGknu}nk(U3)(7aN^|m#f&Aww5 z9pL^b`I<0`s%)Gw?=&T>s zfzI~ubTW4sO`N})bL{4DF1|}%pnH8W&IAdg=hlkKRe%j5h#lD|GAzJmv1Je74lz#v zwus}5dt3aI!L&{6*vEmmQ+$~V*da`sxJ%gd*-`NdTRSEOa^1RL?7bK8fLK`#I4(*u z01t_a9FB*@Sq?|ND47cQQS9vj__y%R2mD98u?_I2=<5Ys5kE3-sUFAhS*Cx_A3b3O zPo`5==^6CaT3zlx{!e|^E~LKGZ)Tu>ueYIlF6vLr1N^R6b_Xmq-aiCbW}LnOu-bT$ z@xI0w&0wlAA~OM7jL-7{hmBN5!;8k5XuwOxPbGjijGqw=KI^=(t{IYV8;QpNpBNeK z0iPPPISs!vX4C?fo9*b5mFCbLfLqL#2LQL4huEhz=G z<|59zVyT;>|JkNW>lT94$x7LS+8(>AGgXj0-mreq~w%n+MHS;D~390 zbrt;A1@V8m1a5KhJI6oZ4)soI``sH{9{c1SX4C)Uy#fE9zK<~0q&-)jnEuP+YlhY;w-e6mt{x6eBqf@ie1pz;{n$%`}6;=&W#M?yM^ zY9=m-yy=NiZj~8>1Lx=x9B1%vVFL*(A(LlS>iQ*7G7h+61H*yZ3$z! zAphr*vEWw-?>M8Y*O<^7qDxY=UU-X*TbINczlpdg`}u8VOdI1J&1)R;vDg(^#YC@Z z!v1R8y3_1bXarRnbK{I4uj39$j~HcfP=5r41iWLsiW=@`4a_xuXDyN&B?}o*m8PCz zijE!nCg?7E)}8pNJ1tr&i?4DuA3eeA%U z<`_RGV2Z2jC+{@3iBN7Amy}pMvUosFc7Fd6IRm^}F<*tt*Ozy(>j}H(o+pP*~)x z^~PoW5Bp=*@7oP6d)L45V(s4()0?8A-2S8TM-~?qj2e-hQ=5>~yZ*iXW*@zFS8|HI z?k@8W`^N>YHuX;(GOLAMc;51}yR~smv>)qjx$T(UX3yG*>Fw+(hs`tAjdP}A*Uop= z>3!{Yzqh=$zQ~pF|Lta*^&Rdtr;6Id{jKegmRLHrA2BbrkZ=F}>#lvZpKOS-kKbn= z_}^{5X^%N-Uf*bI$t(TxO?doz`^Qaso2JEZZFR| zOHQ3RwK}@9EN4$XZfIE{SPP2DSG|&r%fHZC%tL5@GlxUAgiDtpQb$#XLd82cRM|vH}Nc)w~ zM4{c{DRYoL{fybe9{-ft$L{~M5o$m4l=)_>Y*`L(^+v^0r_8J<_tNe4!=J%V?`to< z&>DM|-dF$SbLJY;{!cqAys>HjM!J5+%jOZ&Q(RJAJ!fj^yy}YL870%Hib3{E}{619JS?`%A?fjqdy7wnWVWY>)4X!Ts;4 z2(2wxw#NSE19S2Junp?wf0(;GWBOxv&k;ET^NL31j3~~{8EU2!SGt)b_dd|GEYJ?D@N&7yS|rK*4r>{Qs(XB?d)h@RnzSL zr;V2NyFNGf8Ft)3y>k#u%jsV1%VEu=`%HGVPG>5yh9kG57!f_VW64 zyZbDiD|cXR!Q4}|b1K8^^WT~${)f$Tmo?EB*L%M=>qT&J@yrTD^NpD5#nqZE)?ypn zAAT?&6L_`#czfJWX0N~*rPZ@;EOXX{`n!HI7waL#obS0g{YQ=(kyAXNsIdOKi{@vd z)rg#t{YMN0$--3UVB`%Oh#|h;ADbV4_A9myo^{gb_J6lQY*Tya>msZE#J^0T+ZT4b z0&AaL*~H@yG$$yBRV{fghsd7?IQdF%Rsf1ABT?U$>&*d=YO7WLErV}7Owj?5d1 ziB~LV&_ly4e_`Kw)-1HMy?R8w|I_9mQ9o8#JM`LRcebeanpUcL$5~g4dTbpVX4roO zSPAvl1zMN>x7)_n4{Zu9yT)+E*mtzBYHP!Hb*%5>vD_kFE>ynyy;1d}L#;gB-gC1EvtLZp zBhzKW)pKqt{!8`$)%bsD*h~Fft?RF}weAu2XLlN{?b0Knhy8XttCPLEi7VLd-QH?% zKY7$_RexQ3YmBfTJYlv7l}lFM0DAhbi`K~wRvKto-7f;l%)NLhUCh9qpYl)@b|n^JWLT zV2a+r*biJLuHP)JE7v)+Vjil5V zyLhG1QY6$TbjQtg`~FWvOWW#UJ!s`}s@Ikjb*|s}i!nslyIa6dL-4}Xi0Ud{?-ZAT z;_N9;{(n0YbBo>Oc9X9~iT!Y*mDqy;JL13ms9~FkN}fEm;{GFZ#^&J)C~sVjH!0EX z|EtlezC6i_)LqVL!%p~AcEz_)I`(l>W+kWZ-UXJ(iNmqz) z@r*uiuDvWBw-OL6CDSYH78zD#Gc2eh(;Hv3+40-;nEFW>xWjH=S**9UFZZ&F1Fnv9 zw|Kkw5Vq-jx3~2)FExhtAN!Zm>+Ti(>Ro-UA542=e?6@6>1qSg^>Nww-(Btw+(&CT zJCDx6DYIahHzF}EB`!Wfn>`CFQN^6OTII~*DRX9Fj}2P+x1E;@A9H!?+vZs5!rs}( zYS;bRDO)b?I4Mu9#??*Pyg75H&aY4xD%#YU^Gl{rEw_g^afR7ibFImC$AQ*FdvaU7 zk3HjNBdWe`pcSqAw1L^#J-yKgPVdNBv!>7WR?eE^#d_z>nNeC%UXGJ=;hb4z6?5m# znlsn?_ub)Rys2?XaS2}T86TgRkm8M27g;gh@u;Img{q@_YWLDPB{R#aymKn%Pn|n; z)=Y0=a!N`<;zWD+Sy%h^xaXqv4-Q;utkO3K@Ln7ZpBg)9uoWrl>@kC}t=Yif^eOhq z!Bznt=nNQQ#hXc*%ir!d#LBT>I-@80+zrJfcG7U4Nn?#{LDxEIxV4}q<8VHm8W@R& z)xN79%UT{i+Ub@HF}u zTDQNI@226tP@@iXljU(MN`1ODFcJ+7FYx%Q0o`Q*+?P=w+_q`-F|;0k)5qPRMjt~< z_*;I0tgq^-4sK>O`WRj<>2C#+WP!Q{rP_~POR!@f)I;p&{LOfK@gsWkrW})y1_kYw z`mg=XaA7a0*Z&l^)L$yVt*;TkT37SIw9}$-7vtKey~d5yu6;UaYyXn&s6G0Zv{(Dq zWxvz}XK2p|E5yF{5k2Ji(l?((n`iV)U;9QLq**b4OZWX-dhFlQ^Zu6J__uW3-_rLW z%@Ctgn`_-OwUd8Scta_)lL|ew&s2K4Oebg;ReHZnC)sa~w2Hmusg-G^W$CF26^W$@ ziK(fTDW!=?$*H9k8A+)b$rW{BCwo0O84m=T|zl95)L7GIv4mRO#Uo={nqR#}!3 zpHP;NQTxf;`M$*Dw2G9na!m4yvXZ3aKYGP?=N=imjNk)8XT19$tf^6h!iNvJ1@|2|bU7 znou@tX64i=Fgh_IBQ7%ihbJVb zCX}O|%JjtY%F2rL(#rDkvP5X4Ri?s0m5%?aZ<<{(m(EB`iAyP~OfN~!NU2PyOsl9& zN=-{kD=AM;O)p8PNJ@-Pwbwtdr~8VpmPk*ED@#no7UikQWf-D_%EXGY(u@)gb$nS$ za!Gtfx@==kMTO(A$K7Duiq$$m33qQb zZbO?(#EsdpMBMJ@GN*4WbXF58Wc^KnQ;ZeHQVzppK~zx6bW=^cg$P6N<$z4r0ridb z3np5+%lB#^5?!!0wZe}SexvYDg-wDSz3vJ#6y_=%u5g0FDGKK*T&r-4!o3dqv~x=E zfx@p8UR0l|6QqZJ zQ)t1Z^jN6E9EHObPE|Nh;WCAMevIY#tR(RO(Ff*DCHO?)ZwjptN3og0_6lPZrYO8# z;Y|u}QCO?6PT>)Sk1Bi?=#yiw1fMAULE#??{hB$3v{V?Ou!q9l3iA|>R#>i(FLGl$ zOBHTV*r_?br(s4yb4Q`C!XXOBDx9Oxr*OT(Z3-V(__D(H6n?4jqC);~l7FX><956(!0&Ncpg^U^sdTYQ zPgChxD!ovpR}j(gt;8rz<9pdyPo2U8N`9OOy?T{?#!36M4^+nY3V%`x0_!X*@>kfD zhz8oLbT=X@%vR|^Dm_8rEQL!{{u-6OT_JzxsJF-XpHPA~6#hztM?`BN7NHO#(qTjx z5Sg*+kSMf3lAbtW@bci9Tf9rv#4?(ZF*m{ei-7mHbzgc7-|> zwpAFbun*CV-$JYO2!-Pm-atf0787ylxeh4j{}u|+FdqS>!rcm=RPu8Q`O;h#{09*| z`C6rQd^yN+%@wv+n5ZyI;ZTKR6_#;xE*6}r1d9}|BDTe;Q>AwiVcN^L`GMY&Qv&2;cSJ=71k)+r|=<# zFA-tLTSR#22O`?}w?h9gCmrfjOnV{vYZgFfwFO5lgN%!Y%BI6<^m=`KW65U=FPL>Q8-($^`RPK4eKD!okM?FtVo zPwQkbN$zrtK1>M2y|Q7T=m(&Z{W zlgQuj&sBn(mBM<3o0Oc}7_;I1L|A@YrJq;$vXXy7M15Z<`M(wNsZW;gq%ekvdeVVD zW(=eN1xF}_3YDIzuv*Di645h0KTX`B@Q}g>6+W);C57)O{7m5mh5zn|i)mIA=yfXW zpfJupIm7DcD^bZC6fRb{TH#iO`xG8kcwFJ53QsG1TH*5w&nY~w@O_0JIq0u_p#Qqk%SgcnCEzw^RM?}Cn}Tu4s#kbg;gbrvO&IgvQTUO2{kXvC<|2u`hDEybgKNae@^QH5}*4!CM3cD(dQ<$l6fWjdP zxs4^uk5{e+rsEWHuPmnfE9910OpmmW&$G_>24SKx znXhoH!U+l|D=b$yn~3$VTHykPixsXWA`;dstWkKo!a9Zf9rS63l;B>4j}Q@~rxZS} z@T|gf3ePKiN8twwzanB;`cB~mg%=g_E+zBv#19Z5<);LJ3PTif<18wAi8u*FDU4Pa zt1w<+vcjt;4V50GFkfMz!jVL57Oag`f(Z(%6i!z-TVb`rr9@1Ol?qoAF@)1F&z)DZd(X_{i zx!6{j*ahc2;y_#t6A@q^67#TIroH`k>&yCS3#~^2>?b$lxtivSKso7msnWQEkX-DFjX@FET*^5FsJVnQMQ<(BETcI{@X zz=pE7{?pA?o#pd0kpuO9L^$d}A{-O}86DHG{5{Du{2*5+^go_+5B>JA=D}EWh|q~w z>0~168>!M`iKti31?Vqjx|x=y)scZQKRRr1efl=brHeK8 zl- zEM3;=W8Tb$ydo!Wmy`D@^G-M9jdJpSaPm6tL|*VkRp%HduWyE|a~AU^HRN6AB z&M@!3hP?4k-iJ%#Y0GBGFKKs*@dD zXE}p4O{RmA8>w7x@9tuR;fbCzz059v;ySB~-Ww0cU2=6M*6p!c*~5C9A>AKoi?=?& za=N4w4pa4FC=eBD2vzy1Mxw?x_E=G|D8Yzj2~3x(C8mOJTmlb4Vsok@l!!)&XjLMn zQHfjsR${-sdyf?z9d@mLeuLLw(Z0WFe_;Qpw7tloHQjMEXg>zNu{8tietVs|8+zNL zk@h=()1GW^gmz3LOA;Ds|NJ-Ymkhg*4*hkn)hrfeIFD&hQlm0WVGQkQ_{@f(KiNt9 z;7^voYQYjII2w8Y@n1@mV0bp!EB0BD*3a-_nSBq~phsebR^xU`r`zxEv%>UIc#!I{ ztCbzR-wFvDgs>QdT3LHfyW4&%%sPU;JZBHtkJ2^Bt;0Amx3|5Bx$|K4C3`z_eEu}x;}VZ?DQe4Ss>0xhwwcDvooFS*uM4!W`B4P*#oYPdX|$ttgoHf z7uj)lIoVrLlBEa8Z0pUwnuZnRUMngPFM*q^GIM37t8+h1`%$xZ?6)F<9!GYlGHj6D z?QW}`m8oIJI4Ad=Tp_oAWzB<~hJBg#(tc=o$-QWJAna0o&UdmWWjSWwcQ>;0u9-c| z$zGaepJVCZ`&71Sy3om@Z3rw_zrXbV~2a z-jdZ&IAjPsswyAtWH-;TL;53s!#yaSe=WAgI@vvQoVI1<$PQ6X8)x5h5KZUUHQ6XE zM+>=ys_qH)ANL?P*Z!Efli00c&dzW&dy-T2mRx&w4zlG~BAX`02zJ2B9HoSmL| z1ceKP{C<|XrB2~j2HM`MJ_$j)UgR;q+{yoDU?ZQ!Bfr7$N+s760SX%Zr_y zSBE)%k|R9!nv<6}*&hwFx88?>$Z7B|-X?n=et769(6l>U_ILN8LF8sCYnR($N0EEq zDC|IZzuo(&6=6lWg|^f#JBmk<_Pg!XN1f`HssgvzCsDw7$xqzT-`(<#CGLUMU#$<@S^k3Wy^MS`p*OsP^8}VxUAOMeCb)a# z15E3RKh&0W1Yb~!3U$+sU!`k!2j?@L3GRQVVlBS<3eNMf(7wW&omX)Fh~YG@y@J#D z9bXNZ@_lT*TpqK>1=Q$%r59xJbzn93V_3b-grC5g?nGSEnu$ReML+jhoV3iO4&Vdb z`wD7@S^b*-fG-HmlzX6x9}(k5=KJkxcUxiU;k_XV8I*;yLdYCHn23GX&`B!_i=o!6 zJ_EJ6+T0G_y++4*yX`ixn!8_DJLEV{{`DEPVXn5m`?2kX0Z-sLw+ZNiU@$!`Orx{Mvs8)+L&>=KC<+E%1FulTfm# zTHDci^f*yrb~*P&@oVtHt=*o>1&whU`|8aRv=YW>s3Vws5l^(1~}*TC*%#%f4? zPhT~mw1!r?55cs63f617`AU$0D)N@whgljhjp}|{6Z2-E@wElf^{dJL-oh?^$cpT~ zuQO_uZ`yMO26jrq<%Ihm81=x;PURy8g6~4!bPrFqk3M9D`G(+ojKCNdRIO|f*ZQES zbEsJQC8(2AjzJaF`6Gx;cUzpOgQ6MCe(pL!ob5!?>H0d5f2ezf1D(GaWCyA^%qXyU+#-NHU}(n=8T+3%gS;v)D0E5qYK`>5Y& z<)@g|O|0foh;5@~%i6;sVZL}=BpR*!|FT)5+DP#~@DuhXYe#w*#Vzew)M;stNqG(y zWJ~)5gKlZ(LP(Ec1h7@&08)M{Z)s~WN|tsnA`e?}!C-8)#L1$48%8=T3b(f{?N)%L zEytRTo#%o{{V`=w4BoP|cV&}*O1T?8#V&OHNpFcE4M8kodpOz5*V4p$WZ945GE19< zvBAz|a5gsOlk!*7$oH1@@HQg$uto>}6TF9mW_9NIDwBV`(|E zVGpJ|_AHY=czq!GU!++ECJJ_VLws0Tyfo`ML>M+v!wC%?llA{B+q!~i!5(f0rFHko z>b50N^dHO`WOzvzVx%n1mOgkvTHQ=G(@9c(s|8JbWeh*HB3%$C^<^*bmkm#p#?4En z{8j1vw-FGQmMu+eBL%=>e=CmiBNC>8sMv zcjO>;kwygIWN2wyW!%h_^opcEOCzpGoi)R#GfwU{qCG7~&Oe-@q%6|5xD$izAEn!Q zgWA$w%O?F+_V|9;<6+XhU&&IjvX_z4+~;NJ`2|q_MVyOa3Qxt_U2>rB>q35sl*|jq z*BjUpPCBi-9LrM4&y(@_aA#RXBSI>J!O7iA4*0yGak-Dvgu7)M(#G_l}ei^MxFa7p4C`mO2r#1Gh@w#7G~klYYf3 zWl-C@vP-__rR{CysPhpa>_{qYyb;c^y@rJJN#>Czy+V$aeZ^paLef4tqmlMP># zJsTkXF;F&8BS*1KFY0_HCvdhjI!g}Oo;=E5k#x80WRz_3L5uQ8*~*YS9}@@VqOl{F zeA7bG@8lRiBP$&%c|SR>d*sl((VaT^a*U_Ro^_KAyeGS{A)C3sOVe+arr#sW9+pjh zCv~2cfjKcs#($#h**mi8mQ7gLPfn*Cxmw*LC^;#|c!iAo{xUM|#TgPiGRmqa%N4Co zI<{KsH$1+9q}xA=WIYFEm(qKa@5_ksX`jdiVW1SX zmJxnIPMEu;5zFMzyeFH40L6C59Y68FV*G$$DwZQrYh^IdG9(S@x{-mbAKH`NsctVRQCReY(7eQ zF%v%KtvkyMqRFl@cFTQ)L*?^pPH1vJ+#yxMbxx4zQS{4F5toO=GQo}iu#qC)MT3nL zry&Bckz#HEQmaLAFjCvaOC07MVi%XHpT!l1$7OMtrYzM>#^fq}E4@~u-@pcM*H>}i z@ATqIvn>2(21buJIK+LXu){@sdyO@tKb^H+WcC0Y z6ny_Qwi9~;24N$`N{j_IQaswwcmK=mOUO}F>+0GWJ#lrb%f|e7#g6qL(fte@*07Oc z7`o<)KSUQMJVZMa&oC&HnlPf1U!?m|X42r)>%5?8-_Y@yOBo>p{mB=!XN-?q7YACg zn!`2oh9;o%^2jggL>H_QH_P>>M(kqcw~In9O1s5R45-7RjQYpLPF&$(BSmTO!vYp- zu6iLYend!SOFT$uNOlTbo*XfVp3{?Dc39fVPIF;0pMX1i3$fFoTRQMHH zhJvgkx2qtjCwU?y4P*r(eU@A$kUU3HkRQ*Jm!?AU3b`F0zDm@Hvx&TboPUG7nF`5a zQi{BPlbiw*gYa1uSayPRAl>hhkI(=2KMVDTaYw`gyBT|2>a&@NFHUQa4=ihgZOYCyBkf6vbETK9lHT>{+7ibV;5dv zx1w$yV87)cd7b?LEuoE-OK|;pgAG7tyvsg^B)-Q=XtN)(g^2q<*-Vtf1@?WE*{AIM z2uMC-C1mcO*(X48A&}x0Z16362_;#>?Hdir7ETYMfk29tT1a+sfhfT`?tWxfJ@*=_ z#PeJQP-ufliVJZt&D?8f!7ZGO41SyYIU3tBuJSwc3ALd#qNZRaAQ!F)I}vHd8nn>c zb|RTsGm$*QIh?5TmmvF$2eFkY9WAEd;T*UYx_~l4zKT39***p4KVfbJqL`1)nXq6n zj$-jbBV3oP#mRH|bEqOKn~UJOsvC`e^`H)}RRuT&-1j)v{Evm$#w${U=Bc7!pKDY%oKzmt00!HIi%iTlNr*jhg|<>tqwm89s#$y%)K!`4|a{ zbD=?uE{1!5*+~KN315I}`}3cphJ;^6Rg`%<~XCazVFX13Y{}QayU+-HSa8x(2 z+Lw=8j*?B>kNTwh42P(njF_`O0Z#gAj6P(7d`c*YRTwiV8TIcmvJLy$Mt+?H$#z0< z(%M1BArp5J{Gob?i{wR<+(q)RN-ar2GIoT6mOi$}e1nrw?2FiCd>{6oFb~J6E$31p zN&I~Ht%@VHNMrOD_%z0bN)vk!r5Set>530k!8KtIRQAhz0xnVU_X1jGGzaS!Uwcr z+v^_+6G-SkMtGqe_lv*yiBK-Iv`aAhBDw5?;C=Ms*AScK)5pc2w%RV?1@8ZD6eKs+J&|R&3B7HEP4WeUh+-N%M zyzur<$2hqh`j62`=mWpv+J7Qe1NjvEzHxNpTYNH&-XdnxSr>(kH1uu$0h;hAx3BGd zpYVOKkPNDROmx!mmxNhA6+M7L+WIdEBM9wskw|)dyEyfyzUI!{Azr0H z=lGPiW&J`m`B69;Zdt}pg!t&Zi%p>WCkjb)=4Ihon)nEOoE~>YXtdw^i+o!4G?z?2 zYi6V9l+XDRJ7@j0ZTVNi7?#TYe3bpt>Pi~CS3E#(`yCfd9e)*e{Er3A$Za$26C(-L zzrro{ML3{Oyuux&`|HG6^y^o-HFQe7m<_Qoo^1Q$HQ{y=vg98^U#$67;E4UxDUy9? z(@y${Qz-qZ2p4TH9O2R-&cX#Dp3Zq%JV{er!bJ(c?T1JTG_jh*wLxH(BGUG&n?f76 zcaE4Fuw+TaJ*y!y!Z`ZOBV0J$`CBn=?=dlgLd=R(TJ{Gniw=81RJSc9qUztqt)MGk z6w8GrOA6PAKSlr`p(x6itiE{qY)-+?J_)9yfAyNpWi$g{2zl``$ z@$$^Jlg*-vqhVih@%C{omA-lAZ=)u)-5D%G$c^tqGrXM#0Wx-kihrTI!^9ck|18u( zCOv(f8_|{?E?#7Vf&L!{I%vym7iH2`su69hz3jb!wrkOFILa59K=aQc6VTg^i3`DQ z^XHY#DmE?2H_e7nHZ!%^^wVQvJKYc`{@V8cDrA7~wZGR(bK*tw51;?HeGo6+#4uW4<@Yd~0@*%aHfjcz+TZ{vc>bmIF3dJ< z!~fZ1whgnrkgfA&rD9Rf&Sq$AiKq|S4*y5PrvRxmW`+pIk-$IuD@`jFldupE{a|65 zzi>J1=2p^yB2hp5%N>mG&<~bo_)6I`k^VzJx0Q$?K|7&)*gatJSby=$8vm)Dhp>1T z6yL%<&R<+V(tm>G3>Mek8Y#5S@)x&`^dGH=H;Wuyi-$J1&N$x&G4WbgcnOJw^Uf^{uv({iw^L{ilh1R6}DQPoc_G zfAP9#-)SNr(NKzqi4gU4f9V%7{=-D2GXS^!ho1BOJrAc(8=+?(YAA)xiLbHA-*|GY zf5g*@#Sj$~`v{|Lv&00^3?6wJNB=lW)c;T-l|sq=;P~g2)AUkNCp4{P;Hb#lQjm9M zmH!ChA_n9Bca&+K@feQ7Ym& zku|Wpd@W?p;_D#X4X{~R2kN>Spb`K-L8$=vIluyd+W}?+%mOF|CU^*-PqLrrNhKH9yv@OVx`C+US0(lc`f7k>kYaeo@9T1BdqUd3O}~CP}_TT zB|o{r7~4D9y7@2*bf;Ahtg-NNPlK_)H{AF1)D3!tmEsq_dE?W5rUMQsYcc4! z1yYkFezevB!7EGVuGBkfxVcNKikPpNzCdkN(M5$nYJnZwmMDh#?tb= zs-;r;rXZDQwlqaoZ~ji}d8y?|V_FY0dcMp!9#XQZiM;HH-mI};*^|ci zyBU3URYK_;Inzq)$14+M#vW^C9J$J>HJjw8jk=yIEBQQXjPGT%Cl#j3Y?H@Zp_1b+ zrA~o^>iu(+B=v`t%-9dRNcN?cll@$yrkZg~Q(&TV*p(0Z38bf$HedRl^2h!}m>6zK zj25}4g?r>A7=v~_XoJ!kCkN>lm`0c*<;C-*hIg*kNYbE+dwyUuPvj>Ut;{;u6)sw< zmhwbSW(Kt^?Nm$gdCaR3)iv@?W4#>I8KjSxnIdy;VhW$R$a?8+y`{b)q>4D^dfymi zgQI$bXX>rNY3w-^_X35cgh=CU=^~?j2?)x#teChI=2b!Vb2Uo|pBZk}S>vng{F;$<^P@7AjU zTeWigm&#`B3kQ$=RRI74Y>e0WLA$3PthbeygGz>*nMAuWyQ4dr(FM+69ivvhaC3OcNGtQ|ZewCsqt)FUV;yJ?nYrKUbuRD{N3olxhe>j=WR9sGSwQqBTS@|m zBLTv^lEHFCmpRO2fNNFJV&I7CpVZM`A)LP!)3KN?k)+W9^O1o7GwCi#O0apIpLwP= zPckoDyAOudxR#&%Ya>e6>-^X=rFk4Y-*fBvleeCq^8EJJ-3d>Mwds1zT2nXHf6J3< z&6J7bJ&z=-LE2ttD?CXoJ!MKXQ{y;Gf<-%v?R`M=tTFQ(qZ?C|QmsxA=AKjQ)H%e> zRE??9SW>D-mc&@qRglk&nt2ikC64_boizd^sn$aTE1MTAy0Un10K@Aj}ISny$jx>JB}(5<~(bRl}TjXVwOfGcGh8_6#-I4GE(QG z3RD=WK`N0lq*!DK1M!aGl=7hfsY0~?dg2@jFvSH*w~71&l9g3O%i-RJ2(Td{Lz_TE zh@=1j5g;NK0KynE5UiIGeOhv|#T-zs=o!?d_YI5#j+GXHc0d~*$~PN-)xqdEvq{my zB+PUm{^bCIuWVBXUouD0W|AzUqD=th`=LU{Wk-IU9Bz(~N64|&UZ>tezv89XI~i>> zFpM9V6aF(LDU)?*$Z12jDhuQdE6pZh#t+vY58*qKVM-}uMoIEx@&q{&#A9i)!@3n= zj;)rm-?{o8Pk$juNw!6bj^P{}cb?I@xT|3fFC%o4317EFHN)?6rhL{(CSK@A>^K-? zQf8~Lpu-!@SMph|%bQ5n<*y6sd(jx$Ieu^ovssx8bL|zkwsLFp z7&%qu;VeV@mpLH0Q%87T&$g+VK&f`5+}B^`@Mh+;GaU}+J1 z!@p~Xo$YgrePHa+*>dRYQ|Jsk_on6mdBf%S&Km0!DBI}PZGd@ljHYAh24T<^%f)su z14fY7)N*FPL{uHg>$a`)>foMRxNgO|DVctTS&!s=k1FmKssbSG$H@LQt|^%-)-jF( zH>1sI_w!n5YhBE%v3m{o|ZgH8fW6F)__ORZfwW_N5PI%BV;~K1I?$ zxMDq-tY6PKV%+*lChhA^lrA`1t}pw&$$#z#lQ07r)?Yo1BgE-fVv3-G8~loz_k~2e<1dJ3rQ1t z_xqTB%7voPZ}6sZo#SM!>~-Gh*>9a7Pl12+H+ckTeTi>S(?)~c+MB%|_R@DYvAA7Gx=78W5Ao$hJbILnxzE#-mb*>)b zWXuWm%*HxnSTEe`LN_)TpX$w(aTvcFs_SPOHydrwc8!Dw0l3pB^E#gfJDM3p8iL&1 z%{hvSAp=1p@|7T_(#kfRQF!%>R<7=hqEcVB3idNfkUF*Uj1sOrqo~!Xcb`!VYA*3{ zr9iy};Di$1G!iAErp zqgrYT9AJknRM@^@gDP@f;bBiC_Fy&kmim0rf2We7deShbE>$tlO z)(=_&+&pioBn>r%7rOQ+1q_#Ru1i~Z_a@`VUCno^TDa3zW?_ZVEyMv`sBW9$*_8H#9oCc^WqOS!?+91Xe z=3$CzF4kOxCkJAsB%UqEu+q+0X}-$qTrmVA@zBgTDV_H?k9(*kP8ww!or3!X_8hPE zIQ3r9tj?aRB!Q#TVB|Y}djohL)uC?30CfSd+r-*l=OwRdMu3?ac!x1=h^cNcN}b*@ zKh*cWWm*R8@m&EIA_YnPv(s9+>4cz2|Mz$M8aAL^P!lVd; zEE#rwLNzmJF`NKT{6)jb7Up_|p@uGql;Simb#Q|glgg|rIoQEnuQ2hBU>>ZDqmM^Q zIjVVz9+ntz%Fjef_Y}=lGOM_OqwH4sjtyRCh$reWb~9XJ#9r7 zPk*g%SqvW&WO8&YGhJh{PFq5&M-(3eondti21eiALTfeBcr|*%v2w0ikQc5AmTQf4 zUz~J|)!d{D%UVMa($R9JYE82SODrXEHGp@_$yMVp1Q?7;J3c+)?(UDV z@)H`Ru1?G!a{s~SbNWkPayRue9du%X6ff>$gVc^c~*#OJO<)`T>+7g1ku9jY9D=n(8`{cJevqJ3IvOk^%N z&?&NTka4iCwf$kuShv+hwTV(n_xgR%M&p@29BoKgcAzx z@yY?v+C*(&K{wOlb~qSEnM;-OMu$pE^g1j20F1*FA7)JGFd4%PF&e$iqHYKGsjR{H zXwxQnn;ap>%jzdXyGE6e(Y12765AvmG%0+0n=$l)(D>ZIFz!hsII+4GW9)@kIbdLm zstBC7yJK4+FX4KoK^77kVm-|i9h_krvl`G7M5OZi*!>Vc3iSoBCS)dUw-(*sHJJHm~+<-S%Mb2T+5Nr_outufU>^5kYcSXaGK=s_{_H%K3!dZQQK=ebtO@7{Kj6$gH>>LkF!?c8t*hU7vhT=kMl8wRwqj(!AxTGte5p; zRx!I(K*#g6D_Kg70v@{pu9C^;TNt}h?$GDLq{cWNrXi!Gu$=L4_*{U^ei5iz8Ass_ z+#|Msse);H#bH?bb?VlwO}xw<*k%kpk3K2UF?PCml%!z;6?*?DsoX{qkHM?N?v}an z=UeIxTaB8IFj+{;=@9f9xvB{CuSk&9@)L3pXkVFwzgFxIkYqK+EE+Z z#cGF~zxRG41fC5T^iJZ(qB#yZ4|%bL$|WhPL2s7chz2|4Jm5VfWqlOs;Dbennih_h zGNOl^+q|jRVgDknF`fH0r( z33JF<=A~bamUN>QS?4Je%7p=SL-CB6N5)2l;(9&QzXBl4nN9!k+l9iWC#%q1LlBF@$<5wlU z$~XTEIY02c=6d*AOuFBVKs?9aQn%N_i*S4yF6fAPp{1$_^XgWT@(74S@QtF$jsRnsZQR~}zFY!$c6yvnp}`>M^$POmz?%#djqXUIF>ojHEkKj2bl zs>iAGu675F7kXyHG++SW^KNwW<5ivA^x_yPF1fi=4X<=w={!EjbKTMBrPz)Tg-m7u zp6?l_u#>d_Pt(LSX|6a*<_6U)eIQL*UW(pj7wn-im}4P8JHT%s-wsd@hpN5+C;+~BsNL(Qhhfsn;aUvu*1c$c3;x2&&F7D9c5+Jy{TcJ2D z)>4WTip%%R+0efK@AnDsn|WsD_{^L+_uk#ReR#{~;yRzwCS5C47TEvGpH!=fAlKRU zfBY#MI|}rtYxwQ|=bv6UEBxR7rtQ9EZYg#$FJ{}#+r>drbX1%cnJtAn<$M(ApAyF* zOz182EbAfZnYG+N5Nt}93&O}A+Jz>vi^;=J5Ty4mf*|_TKxL7s#Q^|OX*!8OKWh#^ zR<^mL+Ke>t>4j8H*8h_VP?duX3G_Jw1VNUSE*N6eZkx4jkC=S zlvGD6U#Q~OpsErCz1@}B=0%EE(hc+`I0Q@(1m-Z(8B-LbZ@;5D*{D=06RfK9m;qkz zDGP$ma}HQRf3&4G|2thM%QSoHyi6V)sdXUgqIDZbl!xx8)@PTXYt`!$wVsbfsoum2 zg41XaTTu|4iP)1NI)IVhR6-q}`>3O12Ddn<^o~^o!Qf6TI%nd|U{veb8afX@YVi$- zmFbtERI19qmO#}R?ywG|5p<$;=qT!B@=~b6TY?qz!71E zdM63vE<;u86!N5?zl~_KP9?Rhw=(zAyVdc?gr?p=6gucf6@hO^6L8jdfq$)=5bvU2 zj5S#|cLwjSFNdY9Th;&{rr%T*e7nBrE!=!o@6+0r=Gy)@lvT2ujR3IDKl$$j3M~`3 zgNa!eQ@67IDmCv+yrRF28CZ9v>Z)LnM*yWTJE*!%CRQ|Ot3jqZh+~_;d6=rs#wIuk zL7~rv|7}7nUC%Uw4<%mKkB2{O!l;TWI9bE3IbgZZ(c9^G6oy+vqmWuR$u{U`rNU6Q z!IsV_UXH|W*5#VD%jMt`Lcyo#=N5rasslbvZ-N7DlRJUW(!ZA z;A?IHpQ}FtZ`js40=|*{P=D~LH0fsgmx18ZpF-bKp9}}sW(4Sk`a)a%_N5RqQ}lw6 zub)nQRuk|=`k?9Hv%7=utanWVUwaJr?)rI!;Ooo--%EcNyVN#kC-{E)3z|9B>aaK^ zr0ktl6iZx(XtAx=5;nJc+yQL;{ir2fh7;|~x0M>HdMDV(ZWrm@^|O%5 z?DqA5#+%#S?tsBS4zG{&Y1@-k4ben=tAi#nu#@V~(3d&RS`vgUS6Sfbhi zoqF3UjxSq*ah8?9rkIQrTuCxGDpt3#Gb9^P(Ov8cMs-qLUj&2kcGirk%-Njo;4V6a zo7*^43s@Zhy|Wu!2181&Y6atFP#hyQ6uG!-e>Rf5f*!$SlB<<$DX*yIW3M=d+E9Uq z;`p$>`45NiSVMK{$j@7G{1#1Q$>^gvzK3&V$=_FTv_WvnQh=Z0*v3d)piyxgX3nl; zG%dsWB{wTsmV$#Sx(^9f9Pf_)-*KhT5XG@1j9P|;DvrH}5f>k(IBv`)u10u8%hbvi zMwSHxvLYA~fXs^fW;*DMIlGQUzjOiolRI6v1&a(KCTWH)2mJ z!ucGcxl4(5r)Uu(>JiQ0v<;`(IKCBOia${+q#Q+P2IDKjXg=iqNaF27h&~@jv}Q|C zlkgW@r3laXFu8n=%Xs5D*hGr382(m-5>KLgxSm2o5wdtk?GbQ_&~zlxntT}ocDN$s zBdI7t5K@sMNY+FzaeDiE;y<<^dWQFG>Hs4s!qgc=W5*NC%5>JT5wCuhs`tRrbs__Th^Bz`oaNf9!+4MIYRZ!wl=H%`M%$k{L#H%{$p z#Ag)}y@x9$_>T{~*i8I7q#_K@jsGXMo+9+-Q;gu$S0c^t$lQuBjPu<^;%6-*+JaBf ze+uyj5{drB$8A0p8C?qJ%21>&zjIg9p*ReD$Smi9bk|HVGH_W;>4kt_ah(xjt*e58`}fK3H9OM0;frHSx)Pa*hY! zFTBz^zJkTvHZ6Fd1yrY+$BKxy=4@Np+3>d zoX_T^CY3b79f&^W7Tu9de8F-a|4Y6nq0S(p?f9%$%^|*M7SU;(*5a#l7)F{WwnU9Q zR&>17fd^m&Ppj4|sB|{BL@@8On1`MdckA?6D*dA!(Hhn~{tNlaR`Uqx=}rYLxL@ya zU!LP3vyC^t%7&)cg`8#*koA%V|5%2mCcW6B`X@23uzveD*pGul@+{LSS^u%G= zi2rHa1|B1*_&7K0KHlIkcY$mqeWzfezwu#w`1;oK75ouF`kA;sQG_eQiJqQI)U=dn zM<=2)`SQ{S5`Ugsx@HjZHZrJ5m{dqYM?Ry6eBcGV>c@qoA25RGVD9Nl-w+@39nrt} zq`i1lPv`l7ao6b6s8r(#>JE>pKfOrv8(+Xpf%qS}E$gWS9edCha!>pH=aA5P;@M<=u@q56S5+K+R~ zmGPQ0`GlJCtooX3e5|RaZ)c*f8gMh#<>7Xc$NZ)lRB(zLa~AJ3g?n@nH>|BI4K^Ng z*9k`vTsmPt%&QZ;st_I0n%chS1|Pz0);W$oS(=S6Uj$8l*Qx!052Xsg{nF& zAnL(a|2H508*cWs9R*zJpiJ&h=F{z>SkNCOSE<$7ff}wNOYj>0_1z$cor42)!`L4) zAq;2DYC{^$#-u?S!}=ovbYt0=WidJE^g}%QEm+F$_6`;vo;5l9O zDIuUWWH?_;p=T?)nn#yHQ|m7>VCr<5W!gQ8$@GR4&lwD*O6EtJuPMth6OcWeVy3~v znxM_Y=YzKEMj_t09ZjomAh~OB7@V(+WRuK*Nvsyxz|0!g11w|*sr#iYHUhAY&7+O9 zoq1A&11zd1CUc1K86ReR%10QV^HFBvvp&Z7w2w2IvF;3`>06e6Asbz|EF|lB+2n%y zCuV?#ro#xlhFfQvxzF23(7<|>Xv5DWgU0_u_D!8czNtIj5wvL!N;_tDGafL5-7W&m zG_f-ju4|Z|Ghi)K>;dc8M+(EOtgZyu#;#CGEoW^gLJzRTBH$nkr9KZa+ggBAY!ZdZ zX*QpXc7~fAq@7d9|fDbH{ zMj9`cko_iz_Yt1TL@{pwV2-$^Jz%c*DG)GEd_&4r;vfp$)#7m)evRl(eeMvqxdC>H z?Un&{iPOUXC&W<{d?&@m6jrCi?j{P3YoY^9@w!-z_S$cv9~tVgxcz&;bMaUb;Dwk& z?f((O$w2SKKM``uXK@WR7%!c!4=_tsl+$KQn<%grNz*a`i=~;gmNn8JWUjT+z*&HD zNuU{SmwL4`0S`-!Y5GT`FO=dgODo8vKT9E)8h5dyE4kS1X?0K!^d=~NRi}bhdrkWx zV$x91*l?O&TFX(O>Az0~&B&lunLQ|Uv+fN9&3;NrqxKiF@i!x=x29uE)J4m2w9;1N zDZbj?o&=hAWe#Z3dy0{+xzt6s72ksPSV`Afy*?1%FKzI5#1}bG~ z?EuqQjxS(3JJkbVX1~q`%w#XE0rOaY55OuD+e^J~V`{6ftF2GgcW+Nq@|neh{Q@Rw zu>`Y&)-MIqvdD8?Av@mA9>#3WN`#nKJ=OPv@_4<#7>=w4PLiX_^&-(XE z1PypXOAMS&J;&XcTTvsl9a%Q41=5sKIgV^So_#jaI1^YO$|4ilutLBjR!T;k%xZZ8 zrZ88EoT;oj?SfKf>;{;|+IB#qSi%m|I(M;pRC71;q1fER{vgNiWp~^F``F(k?Prlr zfCFqJjed~1Gz1)CONR3JV}DUd9AQy3?on1P0C0>opaGAw(PX$2>>ZsWCz(tJzsR~` zPP(UTe*;Jp#XWNXlf-cpl#|6MIwPitpJ+=>701#DrQ&mnm}%mfp@8XP5?RzNUWlag zXNDL+zMd%>N&vIO9cF+gmc#;Pi*i4}9ML%s1FjUmg^_hPL_G~ZP1;L&X_nNxI;8oM zNGI+RiBW{ElxmNvFuPX=M33U_N1^Duk!It!cmSwzXA4l1zwWC?J(iN8Jr~m^_S#O{ z$=j3&>f=K5^1Vq0^lQPs`nw0$*1<|F@nA!pdgaXhD!asy{6kf0dxYZ1e?R#@Ad+%) zph9j8n#*WD;Z_JDrEI6g)KskkwQ2 zXn>kOcLA+cYc^U%o9|@r# zl7{IJ;|5yviEPl#jttssxdhtJdjV+wsT4~CI#3LaW6x;JNo+@Nz+`rY0(k|iPR@VG zqOd$}7OxN)3hw~w(Dx&)&A(g)4SY?sYqp6d)xC)|XwNOwwpXPr&_Ty(jNvR8nT+@2 z^Oz>!`>`FUUmbf;{~fNNLF4H}4{b@Bv}?44I{6`>bzf6Vb?;mmv}E@(&^}9?K?l4d z+kIav2Xsh%Z(9EdR!R#U%i2-IPG(hUGniQ%`A=hA$%1p)E(D&% CLeDBo*P1;2f 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 diff --git a/features/FEATURE_UVISOR/targets/TARGET_UVISOR_SUPPORTED/TARGET_MCU_K64F/TARGET_DEBUG/TARGET_M4/libconfiguration_kinetis_cortex_m4_0x1fff0000.a b/features/FEATURE_UVISOR/targets/TARGET_UVISOR_SUPPORTED/TARGET_MCU_K64F/TARGET_DEBUG/TARGET_M4/libconfiguration_kinetis_cortex_m4_0x1fff0000.a index 451252f018b69c56521914715c6b8f11b0e626a8..681db20cc77e5481357e5c3c42782f5b8d08704a 100644 GIT binary patch delta 118456 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 delta 119096 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�QLzQgwoay?~UcF>rbvJw7^wQnkPnc>y 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 From 0016bd46394fdbaf4b506f7a45e3e74f036cfa39 Mon Sep 17 00:00:00 2001 From: Jaeden Amero Date: Thu, 11 May 2017 14:59:57 +0100 Subject: [PATCH 11/24] uVisor: Re-import RTX5-capable uVisor Use a newer version of uVisor that doesn't change the box main thread function type. Previously, we required all box main thread definitions to change from taking a `const void *` to a `void *` when moving to RTX5. We now are backwards compatibile. --- features/FEATURE_UVISOR/AUTHORS.txt | 10 +++++----- features/FEATURE_UVISOR/README.md | 14 +++++++------- features/FEATURE_UVISOR/VERSION.txt | 2 +- .../includes/uvisor/api/inc/box_config.h | 2 +- features/FEATURE_UVISOR/source/rtx/box_init.c | 2 +- ...ration_beetle_cortex_m3_0x20000000_0x140.a | Bin 509950 -> 509954 bytes ...ration_beetle_cortex_m3_0x20000000_0x140.a | Bin 483114 -> 483130 bytes .../libconfiguration_efm32_cortex_m3_p1.a | Bin 510078 -> 510098 bytes .../libconfiguration_efm32_cortex_m4_p1.a | Bin 514486 -> 514506 bytes .../libconfiguration_efm32_cortex_m3_p1.a | Bin 482734 -> 482750 bytes .../libconfiguration_efm32_cortex_m4_p1.a | Bin 487142 -> 487158 bytes ...nfiguration_kinetis_cortex_m4_0x1fff0000.a | Bin 559522 -> 559530 bytes ...nfiguration_kinetis_cortex_m4_0x1fff0000.a | Bin 533710 -> 533722 bytes ...iguration_stm32_cortex_m4_0x10000000_0x0.a | Bin 515126 -> 515142 bytes ...iguration_stm32_cortex_m4_0x10000000_0x0.a | Bin 488290 -> 488310 bytes 15 files changed, 15 insertions(+), 15 deletions(-) diff --git a/features/FEATURE_UVISOR/AUTHORS.txt b/features/FEATURE_UVISOR/AUTHORS.txt index 53ea7bb3257..fcf7f1b0307 100644 --- a/features/FEATURE_UVISOR/AUTHORS.txt +++ b/features/FEATURE_UVISOR/AUTHORS.txt @@ -1,16 +1,16 @@ 592 Milosch Meriac - 547 Alessandro Angelino + 554 Alessandro Angelino 105 Jaeden Amero 65 Niklas Hauser 5 Irit Arkin + 3 JaredCJR + 3 AnotherButler 3 Hugo Vincent 3 Jim Huang - 3 JaredCJR 2 tonyyanxuan + 2 Amanda Butler 2 Jan Jongboom 2 Nathan Chong 2 Vincenzo Frascino - 1 Amanda Butler - 1 Aksel Skauge Mellbye - 1 AnotherButler 1 ccli8 + 1 Aksel Skauge Mellbye diff --git a/features/FEATURE_UVISOR/README.md b/features/FEATURE_UVISOR/README.md index ae5cb2b31da..dff98c49473 100644 --- a/features/FEATURE_UVISOR/README.md +++ b/features/FEATURE_UVISOR/README.md @@ -310,13 +310,13 @@ If the LED is blinking, the app is running correctly. If you press the `SW2` but ## Expose public secure entry points to the secure box [Go to top](#overview) -So far the code in the secure box cannot communicate to other boxes. To let other boxes call functions in our secure box you can define public secure entry points. These entry points can map to private functions within the context of a secure box, and the arguments and return values are automatically serialized using an RPC protocol to ensure no private memory can be leaked to external boxes. +So far, the code in the secure box cannot communicate to other boxes. To let other boxes call functions in our secure box, you can define public secure entry points. These entry points can map to private functions within the context of a secure box, and an RPC protocol automatically serializes the arguments and return values to ensure no private memory can leak to external boxes. -You can define a public secure entry point to retrieve the index value from the secure box. This index value is increased every time the `SW2` button is pressed. +You can define a public secure entry point to retrieve the index value from the secure box. This index value increases every time you press the `SW2` button. ### Defining a secure entry point -Create a new source file, `~/code/uvisor-example/source/secure_box.h`. In here we will define the functions that can be called through RPC. +Create a new source file, `~/code/uvisor-example/source/secure_box.h`, where you will define the functions that you can call through RPC. ```cpp /* ~/code/uvisor-example/source/secure_box.h */ @@ -333,7 +333,7 @@ UVISOR_EXTERN int (*secure_get_index)(void); ### Implementing a secure entry point -Now that you have defined the secure entry point, you can map the entry point to a function running in the secure box. This is done through the `UVISOR_BOX_RPC_GATEWAY_SYNC` macro. Open `~/code/uvisor-example/source/secure_box.cpp`, and replace the line with `#define PRIVATE_BUTTON_BUFFER_COUNT 8` by: +Now that you have defined the secure entry point, you can map the entry point to a function running in the secure box. You can do this through the `UVISOR_BOX_RPC_GATEWAY_SYNC` macro. Open `~/code/uvisor-example/source/secure_box.cpp`, and replace the line with `#define PRIVATE_BUTTON_BUFFER_COUNT 8` by: ```cpp /* ~/code/uvisor-example/source/secure_box.cpp */ @@ -351,7 +351,7 @@ UVISOR_BOX_RPC_GATEWAY_SYNC (private_button, secure_get_index, get_index, int, v ### Listening for RPC messages -To receive RPC messages you will need to spin up a new thread, running in the secure box context. You can do this in the main thread of the secure box. In `~/code/uvisor-example/source/secure_box.cpp`, replace the first five lines of `private_button_main_thread` with: +To receive RPC messages, you need to spin up a new thread, running in the secure box context. You can do this in the main thread of the secure box. In `~/code/uvisor-example/source/secure_box.cpp`, replace the first five lines of `private_button_main_thread` with: ```cpp /* ~/code/uvisor-example/source/secure_box.cpp */ @@ -397,7 +397,7 @@ To call the public secure entry point from any other box, you can use the `secur #include "secure-box.h" ``` -And then replace the `main` function with: +Then replace the `main` function with: ```cpp /* ~/code/uvisor-example/source/main.cpp */ @@ -412,7 +412,7 @@ int main(void) } ``` -You can observe the secure index by opening a serial port connection to the device, with a baud rate of 9600. When you press the `SW2` button the index will be increased. +You can observe the secure index by opening a serial port connection to the device with a baud rate of 9600. When you press the `SW2` button, the index will increase. ## The NVIC APIs diff --git a/features/FEATURE_UVISOR/VERSION.txt b/features/FEATURE_UVISOR/VERSION.txt index 899f060ab16..a57af0501c4 100644 --- a/features/FEATURE_UVISOR/VERSION.txt +++ b/features/FEATURE_UVISOR/VERSION.txt @@ -1 +1 @@ -20170407_v7-M +v0.27.0-23-g8231ae897dadbb1c3eeb79ae2103d308d28c7e14 diff --git a/features/FEATURE_UVISOR/includes/uvisor/api/inc/box_config.h b/features/FEATURE_UVISOR/includes/uvisor/api/inc/box_config.h index b4cbbf34f40..1c7e5e7b2d6 100644 --- a/features/FEATURE_UVISOR/includes/uvisor/api/inc/box_config.h +++ b/features/FEATURE_UVISOR/includes/uvisor/api/inc/box_config.h @@ -27,7 +27,7 @@ UVISOR_EXTERN const uint32_t __uvisor_mode; UVISOR_EXTERN void const * const public_box_cfg_ptr; typedef struct { - void (*function)(void *); + void (*function)(const void *); size_t priority; size_t stack_size; } uvisor_box_main_t; diff --git a/features/FEATURE_UVISOR/source/rtx/box_init.c b/features/FEATURE_UVISOR/source/rtx/box_init.c index ba9715a8d99..e63a8468e4a 100644 --- a/features/FEATURE_UVISOR/source/rtx/box_init.c +++ b/features/FEATURE_UVISOR/source/rtx/box_init.c @@ -137,7 +137,7 @@ void __uvisor_lib_box_init(void * lib_config) uvisor_error(USER_NOT_ALLOWED); } - thread_id = osThreadNew(box_main->function, NULL, &thread_attr); + thread_id = osThreadNew((osThreadFunc_t) box_main->function, NULL, &thread_attr); if (thread_id == NULL) { /* Failed to create thread */ diff --git a/features/FEATURE_UVISOR/targets/TARGET_UVISOR_SUPPORTED/TARGET_ARM_BEETLE_SOC/TARGET_DEBUG/TARGET_M3/libconfiguration_beetle_cortex_m3_0x20000000_0x140.a b/features/FEATURE_UVISOR/targets/TARGET_UVISOR_SUPPORTED/TARGET_ARM_BEETLE_SOC/TARGET_DEBUG/TARGET_M3/libconfiguration_beetle_cortex_m3_0x20000000_0x140.a index 9b5478ea18497f74261a13d1afd245c2b01c1ddf..244b33917d9ad176cc09e41056335709c73a3e5a 100644 GIT binary patch delta 43078 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 delta 43274 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 QinPu=O!ruC7KHg zpzY?O7C^hr@m@y8UNf7A`^;ac^n>P5%3Eq~qN}}T_HGAs%$!7no-}vTFHf1Tz}qF^ z1RtZbg*1M`cU*R3`#*Es|B}@ZW>YLYk!ueOE({DWt)FIkn>x>}vnrL29%(j;Tz258 zxMe>LpY3#9X+@Xbm}gFjTz0F(c5YlVf@Cq^vI9;;>Bh|n@Bi~9%~?B5JfQxv-&L{n z;rC`{#s6p(pzkHk``s|R=X9}R^~48U09bmdi7n~@-m+DGgPmzlTQTW;CDxU;9-7na?nn);^k1n(duL0)Izfm> zKRW}C?5bNGbf7)O`QT}5WYp(qriGl$#%x*07(Xh{kPVS*v_!26i=4jQtSq(2S>Fv` zkLv7P?q(Huzp0D9>qEkT*x6`oVTZ_BI(mJt1Bw#6gVgMZj-ZoCiQ~F)&pvuL4_(E;jsZJ14tf)G6FKlSF2ErA?N{d+&VIJi|(B2ZdJt`{TJP> zP^{a#*WGHORylQgSdGK7+5VZUs8^vBAs86Y@2mk~7CN(fSh1=bK7(TA2VH>gK3?Ou z(y7wZ%7|Nt4j!-Zn~2tr*Z3794Fqu`U+AufGpZ+;jBu9qv}!l|pbpNIt?@gGpntr^ z@5iQ~%hveaWqH{ezYOT+@ftt8x(XJ`?bPmt5sY_Q_p)N+uCYSd8ov)nm#y*R3Ynmm z{cXM%bjDeX7C~-|^6`4Vw@MH6vi_-X7rV8Om8z0TKkQ?Ds;U&!gNfqG8|8vc|8vl^ zEWK;$ob8KWC;tv5{}1U1!E+))D;cljJUh^85_Mc;Ym&;-?+e4#!f-|~OKv(R2U?-w*t1(W*AdIH7(-6p;AcE$J(;N}S_m3kl-&|O4IongTGf;YcRfgI+l68jq z?2fp^T$ni4>(aGL>>J*O<*fvUO8N3yEZHP_KQ6;Mos`F-4MBu%QTBCVdPY3)fG|xH z`n2;9@+0UC?4F!PRMBG1k zE3MUY6HXOrdx$0u`qt@jAsHs7ojrrC#9A+lcB%`f7ILD3$Z}k=+egB6Mi?6$bo3!s z?G~*?ce7w@OPep^b&=pNfx#^8wy^7kI+iv>LcOuL$i64YVhC#D!_v;UAy#aI-^GdJ zL~F~$vzm$?w@9<;Qoc>boL7#`#-cMzi+0`{VkLTGrRtP$a=idqunA{t!rC6fI&!u^ zT>p|}$veVyxeRA5B$E3o*LGUks!CbR!l?)-a|l#HY6DwV!+PwiyQ z-_$HWpx@O^X45(P(M+N~-e zJRLB~qy|!C54_Yi)J)wPl>xIlHwVoA2%cf)3}mYo-+760ds9s&8rl}hmg8!lF-kq_nHpmL z&K_fT)dtMqL#Wh`Y8$R3{Wx2g!5D_y4`80BoUX3Cx(*MbfzgRCO&n5b0T41R@f=9*r zK;Ew`({*ZVx&Ab*xk3+P1}M>gVxo5RiZtI!J&-zBrJqQ___pc+a7O$%wgdyigQHHb zFEKuK3P)S+YMC&o=qYj!Gg8$Z?4$Zxb{LiH92sq;gw|jW)fJ;8Y8qJi6hEc(;b?2@ v|L2Onw~f+cyR9I6f28!SGuAfqKYCv5pM<-t+jsD!*mjgWDW=}FE?@dDnK;Tf diff --git a/features/FEATURE_UVISOR/targets/TARGET_UVISOR_SUPPORTED/TARGET_ARM_BEETLE_SOC/TARGET_RELEASE/TARGET_M3/libconfiguration_beetle_cortex_m3_0x20000000_0x140.a b/features/FEATURE_UVISOR/targets/TARGET_UVISOR_SUPPORTED/TARGET_ARM_BEETLE_SOC/TARGET_RELEASE/TARGET_M3/libconfiguration_beetle_cortex_m3_0x20000000_0x140.a index d68186bf6cec991e07327c16a9175cc14a98ac30..0a9c228580278caf659aad6972d726c514a650db 100644 GIT binary patch delta 44366 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

^8Z(3-vM4l)vY~y=FCh;AqkxHgmBVH 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 delta 44868 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 diff --git a/features/FEATURE_UVISOR/targets/TARGET_UVISOR_SUPPORTED/TARGET_EFM32/TARGET_RELEASE/TARGET_M3/libconfiguration_efm32_cortex_m3_p1.a b/features/FEATURE_UVISOR/targets/TARGET_UVISOR_SUPPORTED/TARGET_EFM32/TARGET_RELEASE/TARGET_M3/libconfiguration_efm32_cortex_m3_p1.a index 21010fab25fd6699b8b8f688e2ee4dd96bd5faee..5074eee338702703431fe15323cd16c804a18ec1 100644 GIT binary patch delta 44180 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 JjuY|J{{SBa*2n+= delta 44239 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 M@vqoy+Yz1q4~|gku>b%7 diff --git a/features/FEATURE_UVISOR/targets/TARGET_UVISOR_SUPPORTED/TARGET_EFM32/TARGET_RELEASE/TARGET_M4/libconfiguration_efm32_cortex_m4_p1.a b/features/FEATURE_UVISOR/targets/TARGET_UVISOR_SUPPORTED/TARGET_EFM32/TARGET_RELEASE/TARGET_M4/libconfiguration_efm32_cortex_m4_p1.a index fc8197054e92d5a5a35da3061496e0a4a1f61111..17b0845abf512269e8b7b7e504b4cb1cfd01c6d7 100644 GIT binary patch delta 44770 zcma&P2UJv7^gepeow+juGbkXvS1E#kfQo=(LB)!__ufnFMhANXMMu3B>@6BwG>W~q zXqt(=B^skiH1?jT@B0qsxBl;~x8D0@Ex&J{ea}5*?|t?;Gk3VTcQf$S&A`HDeVQu5 z%#G%LYFgp(sY9)@R@_MKziabx;&TXfVJhQ31v| z-WkJ0oFh>4_WdvqH7mFXMX{I~GJj@J6qDa#h>Cf#If>ieYQqXA}s#z zd9QzKM>|taW`lN$;^Z5wVpIp9cD^zmjj0yn#=+1W!j!DxQ=l=a)~Ly-WPXGutTC-2 zD&{+m+a`}RsYxu+_^rg%WXeMERIO!CK=LXc17&>*JrDD$hLD?5_B7v_3b};`WFK=M#~yRC&qj9A z@eVX@D;C3k*3M_qj`>%I!4fW-JEANteB)phTiKGX-p_{|McHU>;#gowiR3_BB1^8) zt}bQoYP?!F8FKVf)U=q-I38Kjy9{pwO#-imn41JZPPCd}SM&XWkdvs7Hg8%6xx!1x zaps&!kdvuTG|yWOIfeQZ^WD{uQ@wC+WpnfOkSj((&M^0P%ybGD9UNPoyhT69DW~up z-?g|}GsCPXoz2hJK(5ska(D9x2juMjkb9fkW@*`$ZnA9EQLJSJOqYusk;yI zFmwH#6`Ws-idC0DRll`SQA!=?4zb}8Ts0I8M%h6Fm~5pMl(N8j6Nf;x&?@6=hNF|s z$L(@YXcpf_eT_BT`Z%WBCb`gdr8Y0ct%^C$;p5WRH@Gu2Czha!=IaEHxt98&F4$|B zW2s9Omr2uc^&-1+HMe!#amf;Yb|kpR*lW+E<{(C)DewCcby+h(_EOrJnnf|E%leZ>QT_v7*OV{huzsyc`QsvDQ)#$>Xv&MH z+eusCT1^>Hl^B&s%qUMR+l@F&&eAA5w#dN^N7QMG69Yx*fI!m}RSxkm7O|!b!Fq-V zuxK>ps+4cZI-&TRQc}DiJ@*F0aU8 zJzGu9inc_5=_Y$NnzvYYIynyfjgVtZbOC4s9N6G!J0tJNhIHz3xMp;Z^_Pg9=B$xL({_KdM#lV$V zcio8=>2k*!%1<4=yu3vnhuzEDUPsR2>R{@>@+Qt{L%iRJxT!VKMH=*hnX-@zYL7HT zIXS{(()5{f)g6=zq@o;8m8GnIOD9_80?Cu(KbS{NYZrm`TqhIaB zIxl5AKYLQ%IiJ{QG%-gmuKv;`BS%tWmk$1M4CShF0;!JM-r@EWvYqjAw1sj!rbO2H z33~vHIFZ<)i1@2CeU4mJLXP=Q*>ZnrxCRld)5AdQEk~FkdrXrf$(9x(#F60QFTb#?3P>tsUg%%lVMp~TKa>`s9ogD z<~SPr2HNkpW}VZr=}?50Nf{@HekYT9Gor(!?33+ZM;((ADg*U_#5OBg=QV1Ylsc;^ zhxR5`sY;w7ZTwJbPRkxw$cShs!_s#l>#VCdfz(kp_no|OMOrHm$;qVj#86C12CQpR zF8UMQ;)v}Wp?==>2zl?dN^GHnTot;^;VoC{7V)Ip(S2@gkI_ ziTjQp{XFcywT14PXvBs3M*PdZ^VBztxGCzNeL;n)gI&y5ooU`B>Z5j`O)7GsqU}@b zB7SAZrCq7_t271}+P)B&U}krjH}ZhZBG~W%1B|2Pi<-2;dQsn3QS90QQOG#{UVPaG z!+If7(2Z=-c^t;6xxT;vO|d<&a!ln8!!xG1eh55M{I@WWTAm*jObJnIp-J3DlOC^Wuo1GY`$PWssK|@)5z8Oa{cF|y91kj9s$e~Ju8AHi0uy7K>w@)-o08B zF@3BN_n6_CV0IuPLr49=qq;^#52%SYRR z$-x{(){-f}>Q&iejh}f}&5L#hPOUbhfZ1gm0Bhf*G3q6AkvH>Z6Rji00^1yI2yCA+ z8`!DWQegLQdjR`>%@+CQv z4WJ`}OZ9M^3Jwujj{CuZc7;X@&I<;HjN*91`lIub>R)7|>}PEPjOfw}7&*5xu0k7zM%2y%l%s=(D0W4Ql?Q;Gaj zE(e&?fI%JDQ*hmpz>u`oz)=7H+~V7k-TPHSWN7|d8Q%d;975ntM?#pVJ#{eTp!3j_ zIPvQdtalZ&Dk+DjvOFZ7wH$PQs24*!tQ^N5?n&E6*aR?U+Ztf(#dW}P$G9-#maPOP zYD`oqUAa&ycUTNeJ4WYJ`J4;Io^GZAGg`2N%r(qQRexZmS~~Uxt=_CiV58-^z+A8S zz*eh<13Uc8NbPu;hU%2f80kDH5!mG^4biQJH?aHGroetZ(t(5DGYt;gvK%-(gu@z9 zj((qR7YEsAzL+o+R3P#hed|OZ^Uyt!h3SpF5LV>2%58%9;^Ikp*pf~wj(X{v^q zQNYIY#sY_SEC(DO==eLlyxp0RxmdWB1+5Y>w9HzOy6966?q)_(kUwo(c{!71+PAHN zRoc!3rYA7lW>`i6GwU45MUce0kEw@2eww&AX`nS?Kmur^_-O`cvp78ov_p)q4ca9#dEb69 zuD-)s)-UVNLX<9uz*x|AQGsr{C8p2^cSYT3(0y@s8R&0OW;p1H@bL$|63-YcZ^ao$ zkFw!n+|C(g*R|CBFB!b_AzidGdh9^8+|KUfCi#ZuHf>y|Y4wJkT4pzGmeaUVNLXU| z3YE$y##cy=?^U@%a#C1v;w8g=qvP<>dpl1S1yBN{L;1R!r&AJ*h{J3O&1b-P!-zl6aA?n=N9bn6KMOar$eEXe?^! zb(}!mb)96>?~}gPD>;L1=+j8U^vk3RdXyFPP#;Merk^Gi>E1Tb3B4ETu3k)fp_^Sm z?e$iqe0>9{NPkT_q1Pz|>aXjhBKG?#Oig*h$yjHA4F=P>!cg{VUnwU zAEYXmbyp8jR`f5f07fBR1rrth}sNBo3$mB`A1-<2=j zf^YElzelV#Y=^3r%R470F9D*bf{V1mG z0F7We0x&$d2`Qdsvxh0c4-3VzN+04c64bx*_0|5OT9v@9sF8XRHB60gx%90#p_nT6 zf#_^(19TPXygOtzWVazdLUv2T`Vel5bpHS`EcoOc3`jBDh!%=d)L*FNzWph_{&n_; zITXtzeQSUSLcn|%AiU#$IE!zkeLCU-?h$HZCyX#1BeeSR1GnK6HXqv+tR+m%n5w%4 z3hzcu(}m&^Gm*Dg{CptCQ5K3>bt(S?B#W$&SW>~U8(-fhmsIdlUCKT}1@G_9Lm6K{ zafUu3Py|JctcZ3h@}m3B!HSaQQe`f3f#oFDpGyX9rC7S@djds*Q1w3o;rbi8El4Db zJ$hD<@Tw{6buFp43`240!5)p4!)I`RZ_1iwxhwR2U$9x&aWmM^v^-S(iYdnHi-SZ> zm(qxeQc-NkXsM$A86*PyX5+q6F{ws)V<^C!UpnHWCdZ}+2a6H*HWh?YI;oTiU#eRw zK8Cw01VfIqv_@VjolJeACGP>`6zWqf*QP>F&4OInQu#ULicKJASZcu3r7I7CoMrh? z3^{EstdG*<#tP+rmY#%hhsSN}>Z?H}98@S_Ol+ZlP@S?fThg zitDaz?7(6>g*yAG_knE-!-cn~t$z_N%43aR4i_Q9S$`8Qf_%&0MHGbjBW{hBIfxYZ zaLN`-qMi@|mp9bAMTkiC?rVK!goqYt`pyVZMU>VbMF{WO(WvUN?H5LIv(@-k--~P1 zz2hzP>6vid8O?ZO>-S8esQ7m3r+8MF$bnkk{s6Ur~Qk(i_NKK0t4=%+l>; zMVPSYt8s^j(Z4GzDvKc96eYrwE@07m9#6$g11z1=@NnwnA)GxzEbH4rfBFvO2#Yr? z=y}#unxW>Sw~fMb7^~03-I;v+<9UreHn7aw1^N0**dW*Pt|H`H6I}3l#d6~cFBs;9n>?p5bB|W)&)p7%62X^y3tCR8~kch8F8CvBJ0XEi9N)p4G$|*8XXe zo*F9}ly>_972B)Zu@a1-#}4R)vBD?%BvyiFCpogZp;Zvjo}JaPm_TmmXE3s77uA6# zT8GByKcd~}m&Z||yGnzM3hjwy;n_p|6JE><^_qi1PxUPd(?hd#w{jxce>%=op8aI) z1EF&cqtIU#PJ}9Yr*fjUSfH;jCu+i^f0aXsmeI?^iApXDo}l6fmClHIueXX5@#3~V zB~Fwrt(b-4{YI?Ep-T~A27OO8=HrQNtoN-0)uP$F&eO zCMQ?%{vfXNZbMiCFMSlhqV&WNR#o?p7vn_@9VdmdqKkesUL=>AI~Q#Qsz*>iA~aoB z%Zsx9XOMusL!~Yy^aJvucbF_x4y~@&EHASB{a_UDXmtdRdYwaW8&M%f9gD)S(3$%3 z@*>aW=pU$1PJNG#qYCwM2_jfH>Gcytlc+K4u>8W-pt8xy6G^MqJFGo#CW6wI84!J> zcvC-~Aey&eCh?8gj*HkAkx6`GDH|;j^`I~3hR+ce%lu=I%Tu;lek%hxfwHTmJW`!+ z1Ea_N2eXyQA#DnvsL4D1)k ztYvD1vf1JnJQHlGjoscageva&rV65|sHkKAi1$u?56=g3rlmguMG(dK2KurJVwgCp zyC;iCKLa*4k-owQn;CX2HY;jfLdmj6Z;~vM-JhPtjdgGT&-H{bePOb&ySieHiX(-% z1M^oZ?$IMt#IoQ?2549O?T3+KoE7s0iYr+up2cGQc8XZ%)zKMRmOK zt6n|}d3?3rCQD>SoyAm)hV&F{v=pkjmk36Kd#dJs8mBpfS4GWIPCu9>{G2auMcG(I z%dqRWvxKLAss+P!sbn;ivKbAfJv5KMkkbr4>6)ph?p7U{B2lkaT_lPmeQIeGz z>exE!>c3PMAy(%nsO#yYxxd?}JJ%2y_WE$CrYy%1R#V=@AzqYqn4+fiN~dPD)X%9# z`A1|jO)FwDw47vh{X_XzIh0FFDVw?zFN`NXsZ1P!pYdqQBdi!rSt)1#N1)OG zg#)tCs}d_!jwdF2u+l%Wp+3@pt!7ex5L+{@UTew(WK4uZCUG@#2Of^Q3Rnu^s(3H|LKtD93zGWSvPdag|zA9S;+I@DhFySe2w{)68-qu{& zx04U`*JIdFr<;_^eMd~JMSL#x5ARX#F4xvL*>pW5B!qxmJ$Zd7AC=K4ALb}Q_}GS@ zXh@I7*|DqOQMNRE0>H7mBDrkh+&KZR5Cs$D8o?WFb3VE@sSKjrAo$+i8vG-*LOR`ryY z*tef`!u6-Mu{@ItS(w(J=##=qXQaEvOXCE~fU~UR)l8XA##E&obBP!zjf2)8?;K7{ zeoNf&hWIJ=MRFoHa2nH;SZS_{I5lCKvV+oj z)K8Q_kt%N zkn~RKHpyiaDVNmg)2y{dhVB~~=j6SX|%vMh3Eki6-U9*T+&Jv?#e24X= z?6a0w-;LN+CX4&8C|^nB0M^U;U;akT_>sgJ>xgF$6T5FBmK#jmCRa{P9NOXjg~Txx zWpkg0vZ3crR7Kf{jb9Mg$!>~e^v#rYrb+{c>p3|h#=d+XEBRL=dYmK%$t;yGP4W40 zY61*w+C_$Cuv}5?Pf#B!bMe(Jlv92rZrw{PCliF5boQ!x)Xczcjpy>RxFE(2(> zT~6U7Txe2?O0$wt?jV_qaHLW;ouOv6M%k+om|>N_ZZv>80xnPqY3r3ejWqa`lD3y&KM(c+~v$CFrJ$gGf83r6QA!6p1(v z=b7k3zr7Lleh1~LrQd_5sJ|wG3e{ki=BxQC2v43lmrd$iZbbW30WZoyl&+T!gz`=M49GUS-2Pl2iFoM^S`p8<0ojsP|bW#-HiXa7ZEg7_Vw zqD>TA7+;ITjEkVf;@vIK5^?buXtkKeuGWYf%(ZL9j&AIKtFST+ZxfezG}0wXs4@}Pl6Vzqqx{~^?emwTcplC zhthgAgI#P;FXN*Po@_ryWZ}v7X?IYux{g7zN4=%bZ6rKetmCG6S?%!#%A0CO{IFEJ zr8eYQ=Z^X_t$9y%?Ere9`tkVpO6_b!DbH|$$EPWVMvTgQ!zQd3t-!F78|os1zy7Wf zQfg@?$72R3M7InL_s_5tH1A(&Z(n@Vh$kq`=&AU;S-|r3ZUU1BZUJVs>I8^)Wh@0|r&a;h?!i1&?^Oh@Hsh}?wAQW80^5|MUD_WQ(;3uB$EQ54`v{&z z`i^1K{l1{t2YA;94z9?ihi%S+{P`2kWQOor1DYecGD7iSmy?|<2I8v~JboF&l0*1B z0WA=1bTti#X?vf}__U+>W;5mbmE)}ZQ~Lk| zuI&Z}U(;vgiqJCO?Lr~)0%NS~AckR7fqpPoMB4AtGT|2(;VIMaezIm%=p>Y*U76@& zgG&bQ-V&;r;+z*~mblNZ^Tpj$paKy{nk{N^By+@Cp7#sIg-1}%729D-Jh*mar~AdU zt)K&9JR{?vSa<_D3Qw-jEdw1Emy$q7#EJ8uqv8O=?U;DP4ehwt^cCoY*vch$Qk>Qo zH4$On%XvWjNz~6l7mtJ`2G?e(XXokXn}{-j7a0q4)N!m+sJ7tP=BiKVPq@h8i>&(eQx zDx&Q5vF~c(?-`5{TbadT(q=-At&_=mWzaog3;xfvZ%;rG5b+8a^er#iL#Hwyg;7jrm4Q`Rb#Mwc5p7ho z3*-snb9{)9rVp>Q1BwU_Z(!ukXTYet)Wq@&PAz`Pcfi_N3xExWaxpdT8v=P~U#7R= z*H1$pHJYCeKHqJJH<8m@Q#VO0uLYVef>(eFM8yn{LmWv%mBm73u307KeF5cK(FTDm zhvMGB3Pn&fqoA^LJmj=WSO{8`if@4FS&Zh4KUM=Xn=!vN$95JYzKiQfu{q zJ4)-UF~ByxU4d<{(6sFwJWjO#XaRPJMRb>R`2GUQY2CPFtMDg-cpA=yo8iHOMdoxy zPxaNMfHjtKi>Y~>OR&~>wwvt|1gzbg7OS)52(WG4@ArWk)#v(bJeUpT`i=uOY3l}T znaljpIx!PXblCSB7m{uM1t+?9P~&8CjU3JwFjU`Xj}oC-^Fgg-5|UwC+c4v8}#Kqthq z@}Scqxft}Fu(SeQ5ce2v*M*lG=$6R72jyLHd=corIK~zEw|LHz!V^)`-X6tQqGdJE zThUg7_M^ynjnYK*^1M&cQ9p7e6ph>62R1)*_mkFrfiQLfp*PuDG1 zm~=fKurZ%FA7JzdVuil6NyQ~x#%cCQdOBmmMqssejO-fIm;tkU@FQy7yBucydW?Wp z?Gc2sqw8YIc4WZYB9qbcyXe~omtTlw+!o)6B(8;zV%8&+rl<#kI=RnMveGePInr#wl0s|IsNd|@=`E8B=l_Q)l; z_Pypv1O2F-q^r(r7ng&6(%OCo`dRzPMlWdf8iFor&F6wHX_cmfE^EohL07cBA3;~O z7KcICw0JJQ>)Mu8DBaMOGzZ<(0^&fov>RC6+ArE>rodmdrgk1mZ)-1iqj*RAFdFom zR*$RvuGYm5^t)D!Wue{EBKY;uea*~>d!PmM2R+v&7lHoKW-*3lnHICr*``$-(|nW9 ze_@{R&q*i}m;DG#I*aF4TFO@5S1I?X;)R$z$snqd#g&`xCRfpO{Xtt17@5ah*w}~G zYjJ)%u>DX*PKQC*Lfc9#~qCp3> z$xPHow4|q?quK$-r=?zc@{CxheKjV<8I-&}N-11+1>!1J=09tuy<3eq8H2mODznYEIDfFUKS9fT^6# zzz5fXgR1=v9P)T7Kiv*}z*smV?jp=&3iNADlTFeFGBr%r;3^!|wIYW7Vl4;RS6ioz z;VRy)J+28_Zn`!Xbkg*Z_kCkN!GODBK8{{xdo$ISoL;dyg|V|&?a1@yK6N-lUZ36x zUvYRGg!ojg#{BkN%{m5pp*Dn(@v(Cy)75MB3K#fW^&#(lr&i8K>0h<_QP6v}I0^Jo z-OrVkXLz>-rMU(l=IMC`-)o>PhFF+Q+iKX#YugQ_s)D{Uc%29BGz`;&I*Y1VKXVYr z3`QQwjvF3v?VU7)Q+diDZi3Dj&T|X?#?X-m-y4Sfl~CR^WHkf*V)#`r>MX*_O*w$l zR^xF-^fu!~74(&H*ICdGn z=7D3zcl^@wgs}-+pq(^!{uy-I7|NJ9W1QxV(ph779=y*P*U=H*8E1?IeQ$jJ5cH$5 zy56~q@Q?VM3+b}4LUYhnV?7?XuNlX^0o^qI%o}bQ`{*lB(;moU^L^t<4&o2vfj*$W zjJXX!4~%meR(~6heTC8^<4?0dPmIoPpr^(YSR&eUV^K7!yf9W~=)N{Kc?Wu997fZ< zGnRe|`p0;L+3US=p$__Be862}g7%S3Pt>~TXVHT23{ zZ6i%SUn}McTA&%(pRRREhjNj2aX)B@wrV+Osh0j7Xqon)KWI79A8M}DN-scZm3ECG zwMM(aPcdt?mq{qC*9w^OH)u=s+g*i6xoj@WEt)&MxlIe31KO@_C6!~wPx`s{i6NDFD8D~?l2?W(dz96{icmR1NvPH9RRwgMbq(rXqlYupISdIhzDBF zr6@hra+xe2X}|x2(qrw$6VNm5pM21BZMmK6>ZLZ1+sP|Un+STN>2pDEHTeez|7d%; z)Bme&9|z?JttYpkk6N-TXoBeu7TmgyMR zalYxY5j4lNzY?g>RCc7ky}Qt|dfr0OVd_gSFECXI0WCB|YyvGZ?XZFtn}#vsmYRmW z0u`A$GjevCt~3RGZEB&v>@LFWIqd0>X&O`g5z``P&{0z#=J?~LBaHVGrdC|!H%xDt zb8ng&bA-Q`7IQ`YYO5i!*7vygy_g_H2n-Uns_e|f@Tz{IJHPBzC)H0yIO*^^Y zJThg_XirVKX`R8(Ob_Uo7pB2n-Y-qRGJ;;4wlTWin7S~6Hk-q^P_~$B3;}I7pWCbd z&_jfJwdW~suXzTedY}0{t$x5fRX6n%VRaVsQ~61A02k;f^MZ8H8M8Yb`;B=&ckge_ zg%6?p&K$|~_oMmBDA0NHXXil|%>9>uE}E<9gL)z?7wfaoX2j)HP|mg_RL1RvmRq$^ znrnH$<>Rop`=K-+zp^@yn)X-heVHY#E0ilN<7}Xnmbo;-YD-}OXpP00AH&yK4l?rA zTl&yWUsztafi_z17lFRCwBWw8+0vpXXshJ|j}_Z2){ZEBWeKOxc38e-e*W5Wz!$X3 za`#(Mv1MVk*5Eys6mX`cZ@2F*KLzIqLj&Y@&wEUU? zI%T<}f7J`$5-np+{oe8=cbM~*kx8JRECu{1anW)x9CXRzeH_ZGmLMjgYnD6Q8*f-n zeGR&4DLe@J#nO{m=2uG!v(p_*&PFJIv)ttx{@tR`JNGQfZ2Aw&DkkqgEq4~9^uUte zkh6bi=@bZhWEnpj^w`q&5a_9;A!F^CXPnORn}V}W^~&SgIj4KH!FNt~;y~X!U1l8o z=+uK7!+EC$^z{X&2P;4qoiu)ba>dDoEBUIE3md!c^woBhZa6g`1-j+5ndAJ$X*thl zx1GMYi_#sZvTH$ioo?F$z`r|frR(lH9X$#9!>Kw4`j=A$y6%C~5^fNWoVqb(J$5>} z1N6-4mvNxyPX9)NUOA<=1ig0peIe+r)2%_EcTQ_7g8p^7%fY;N>iZ?=qf;L*j3UqZ zHNRJz=M2;=|TWQ(*&egfl{&3FbmiCwP;NL+HoX^(>O|_n-fu>o1I{=ztRrJCA z5KnJ7iaFMky+DOl!O}ddnu)iq4f##=pyT6Ca}fU1)D)jt*bcfA}h>` zrD46pOufQ7h&QaZUUvhnv96;h*IO%B0Bx{74+3qpcBUsbSzp+Ppt#xkCGE7uI$;D# z+pMeKgSK0bak=lb9&88t+8WGec3aoyfr_mY_<3=!HS8El`>gHR=mBdBZgU5%8)kzJ zTWdcC9kD)T8a-yM+M32MrQTRi(iZQm;|7ENu~r!idT(7< z2>M`MJsOl}%l-y5!S*E|KTWcwPC;q1ts(Q-RNHf&5vJMRzXi>(eH;mzX$$Ui6`XHt z$U6#b=F2F}v2|vU721mF3Wu%QHPC!p2W|}uZFd;Cx~&thEwMGSftK3tJqInb^=EEg zZu6x{R@&S-v{kl;jE*(7_4#gm{e9$}FLfZAc&4cI254I~_C@poF@)1awXI+kNr~CcHc?Ecs}+7>W>BqbG2*#K=d*D0e#!k1%CfDhaAXP z3zXav%4Fm9>>#uibqnNLE`NQx=CiUmWw2;FzxX?&IEO`=uc`-Mxk=>E9%VOVUZd_{OKh#KCjd<46L;>0Y-T}G7ZpapMbVta^Y}ICNtv{+`$Q1YWxVnY_ z^90iMLcqB!|{!TS{a*-lYe%;9^zbdJH>o;L{cYgpPEjw69$!F#dZpq|-+ z1BNx`Ti#-RMLCYLV1@F&9EPlrSW+QpB`PGBRN!l}Dx-qe_hX=pzl^)Qo?%z9rm$Vb zWP}M+Yh-;?@%A<7>v9YMcD^&rnn4RH=9wvwt6j%sqj@6+XRWah_gQ=f4j-Ucv)PBu zyt)ST^>GpJTbkG%a%1W}%)?=7Yg5Xe<~>s(w}9L6O0Bl=wzc&(=rhc7;vsjqkM=Va zoADl4)3fT~2eC&u-i|GyFkM}YUaXy~8Zn*^`ha={ZQSs`F-k(+r>g`QBAEt!w^0?1L6jpkJSV?9iFc`8&fcGT1k04(_~5jiGy z1v9urmfS{HyOeDWwb9&jGURARkj4BO$;>6T5A-(k_t+_1%29STH%0nziDMlPa~)(l zmw3uP<_)zWm$#!%fcbT6$O)}k2r+vFqL4^A!hCK3vyQ>afd2dsgdIumkb^UigUD=vkcVP4c7a^?Myv&?z$g-hCX$hFMp5PvS|X0xKy zH7E0LCS5YaQD|VE69l;`e*~Rtu8IZhQjMc-Zr&LIxq1iaTbnn+<}NknLT+zPUJJSA zmykP~T`1Q&3c0&^J;KgAh;a``!F&5;?Vde*V zQ3JzCky6~Xp#gtd(QOH?)&JJ0D5d}C2C-oRZYlkJ9YrbSN6(fHL1(4>Z^J46EsOUz zGV~FV+pzEq9r_Xu)}zGzm)9q zM|oj$6gBl{5-T8#@vCQ88t;gb-87OzY~f7J23Qh5*6T)W>Q5|rwU|6;D1XUzYg{*pF`#7e_2n&q&1$<78K zlJIN8VZ?EWMEr=@i>S#Cs>&|4I@CDJ`ol+2e$<25uoMw5Lcur6N*sKGcW+4>$nV&d z<;V=0vP0s5Ov?Kbh+28#M1(qCgd+#nQ+6DN%!BuE4I-9BJpcDXvM4#k_p<%jD)nD1 zC%%&MeJnsb-uEP%s3OO>bPg|%twhYLN_3U;URsm#9_hu8ag_Vz5!a>@uT>$Q$sk^m zgIFa88oP#?Q0b;v={RdPHQ!4se!*Vs%1mkY^)9^NEW_%qobkg1Y90?KKB`T8Dns=O z)+anIL$ALt<>O_D^E`-Erx15EA&!!oS@K@38#UXdD~ETYJT;AI|GhCOt{$=ErEu3; zQC6jSm&h=gCS6k$O#RnLcIX}p3cpO|ky|+}=bA4~U0F^bqbK!A(ym|6pj>G%(O(Wa zSgw?FGX5Ldamc`L`Iiz8%GsEt*)v0_Ss72PKZp41RAK{ZtsT;%$x`-~okhu-e(hNY zJ^>Dp6Wftb`LPVcS<-#WKcl8Fg}5%)PU_j0*fEy)x;in*nfSe|bVr)Eoq?JyauGh1 z0XS3EiIfv)BW>d%ZLmuk_GEX~&-5dfyi07?Ov=loEw{=c4w@n3|69Z%ezGsaq;ECK z8>5NOU5Pj3*w3w@e6<|0TWR7w+077{l>Fqd?nskfmL25PWSv{>h}#Dd?|Ks5+DJ_! zVlc7`;{UF^Y>~^RLN{JGBu&~{c91Q-7(15wZE^*tOON)EE-QIgTIEH&+HxB4ft!^vmnkl`W-HG!4`a~DGF20*j*`76;#4{vD85jIfq+(H>YMgG)XwS60gzATn@6BRS(+Jt(KiU<{En^P5dgelT&o zgV)@`hs)r>~^!g{mfH z`fAEfy@)g9&A&?HUyvGy9Lg0LTr*{a|0O$~I)U|T$kzUq`m$Nn^hb!9lp7d|Nhv?t zPFjLMHz{wiQccQDxfm|U&@bo58^S6POUve*rMw8U!EgPgReIH;T=M?8w{s}}yqs7{ z4q~qC{*^TT+P?6U5!Z|!9I|N{r)4+WdC_t=2@%rU@F`3|cD`D?1o(|OP|Tha41>0Yy4isx4}qWh}oZgYS4MpB3yPIfo4sy8><1!y@9h#aVdyAQ~VlONG)$K zc_CYMOvaR$PopKxM*~^~`G;f43#UU)xwQuP>4j`dYe244eI+n!G-IO9pUZ%a8#9Zw zUCL)9vJ$#GBENuS6`G* zLtuQ70hn}0<(`s!h}&4&Fgq~Q$bnYd%j8z8Dsy6vJDX_qmSNE>15L}WyrXG=z^1Gb z9vB9U>7NEneNN9*6YYUH^<06?;v<21VrwdBg1FHgG*N6|m@g8c?(B52@G1>jA`Ywo ztrmM#&>9g!d#n|$CV{pJe=4_$_pG^Htfb}lhzSg^z4*In&_40gXwV4}%WEga1CINY zn2`&*Ao7zz7sY4}_>$N;4RlWon61>u_jw|y1B!o$y>mdX#18iRS}bx0y%F+_rc>3o z9Z{O59*h7@SBEm97ph%&sL<78?0%7&sF&+#@VAe}YQrxQ-Z1#~s9&UjPN_d|FsIe4 zbjlCvFKp$qT74|&rrMI;xuu?u0o_qmn(>}GklFEp+A0L}O8pL*7Qa9EoM~(d55HIh z2EUr10)tB-Xp!MMjlI|qB>%o|t-*&gTxZ}b$?*@daFqRoB58tO`5%>%?*^+y4-uVKry zYqeXk(|SS7Tg?L5L~A$Bw9U+h!1i-y0Xr>R3he%d(a`rXmq@>H9NYjOX8*xYS^|e1 zXU)%_P6o~pMeKQw@L)%UVm7;&D+KL1PmCM@a)?z+K=uVWx8`T>FQv46cGk5&SfEgT4p z>W=kSQm^E&$?mqX?A!aTTWS8^r=SF!vd7;(XR%9VzX%M8DcO) zW~La=#4}6m=?cmh@^zU7BGezH+2Ubo&>Z1clAApGp)^4x00N@Q@J`$c)yJRr)m z=0UM>CFqc-=mk0~cCd6rgt~!_ipKWA;A3KCW6*ICOLLqM*>u-Q@#RR+De-q0=(O-* zsyQRp^#Oe&=5l&x#T3^3No2XA`$wV^TbZSfW3c3_?>LwO^)+vptsX%3#P9qo=79>; z-x)D;)joE1I8S{>GdWZn-8)~s$RJ#x?xKYks_6_jUER$a7pd1UQM`_>YbSKLUVV>I z;OAGfF;UZ8!#`zs1OCJur6R**khaROyEbUOp(El^I>!IqXea_IF&2Wd@|b6W{W;N) zZLNTzKL&oP==&|l=(o8w(BD567?8$c1|HRibTxR|eFvcsB+yPt08AUfikAP}>)wy4 z#J^2EYb|Ergf^ZH4EsA282*-N=hHju{7XTOUCUXQTf{^VcWWguv8Wv|r6Ct)WqmO) zZ5kb0C6}>cPp?QbXJoR2%vm&YRgK=L^>`hyUPf79qjtH#+{F37R>Ot^J4^}zc8uoW zI;~=Sb-qL!bh(iS>^9sJ*gc{tuwNk!I2f;Bz}mjC95}o&hc!ZF$l#rIyV+;HxIP3_ zAgVEP*9pOS-4hWA%Mx>M^cbVzQa=O)H>?sMiq~nFDug_Nae7K(Rlv&G@wp?%MNds)nX$U}O7O;Lxv;G_~Pv z*xIN=+#x=HN#o^-?R7zuL=?P@Q_)9GwLk=v2O%+WJ6tTz(}JtSO9u5?(RII{-9on`{lbJhYgax#ILl^Na*qiw)uzd3--o6yUx_R(prBNz#7 zzAXT@J&s7$+Wkehv_DFVc1VXSN+RpMKsoK_YQQR1CXw`eOL-E=n8~G)xt9sDde#zP zjXC+in)T>}S`!(+*$r8z_KeBEIu$svx?ggYH7bx+>c-*c_TZ44Okt*LnYISl`ZrFc z16B&+qX(_hB{c%r^*Y0|$N5p%IONy@s?w;z@+IntBj!Q=^cuWbSfJY26^XzVqBcjk zRX8)A4~Wk=?Qg~OTA*8ECWHTxC=36V%+{IKN*KWq?8yIHgf?I@eI1=o|)` zB(m)Fz&O^@R{7#qFVH-ZunM$T{E!M-DJE71tr1EBXrs711GHHzn*`b+oNI%2iAdhJ zU&Pl39TL_I&CrY9KR*|=!p}w;l;CO8-j!N{N1J@#Q|FlUZwRimkhyp?_P{);VNS<$ID3@^!CMC zfL?mFF{*gW3BxE?ee)KBkG^iP8tHId=&AR-XxQ?BmVI z^fC>kvKuKw-$`nq8ybSz>&-};^))1;{=B4Avk^)ex`SlYeyt>6^`A-e z_3&I{Gci&hnQIIe-|I_rjZtc&@AM;OL|N2%fTAhlf}(6U=|^fA!o=F*^d`m=!eTIqf@aMrY)LU~)-#$L zV|=GzEtq+90EPPks)egqjOGgZ_~yoRF+ktf+*rlu65Hsw95!7bF4i5jv9{o;BV@f2)```Z*W;(iZ zDf^4Y%RQ??j%J4zbAq1U3d35WcWPx!$b5?}&LxSpqRlHCLay)xa-8`Hvb0Mw^@--I z)TdCNV)ln!T~ggl3LXtP^mAy!_YXFnxe2NU=D(1$T&nU3QLgzfy-aIkxbGI;QL}=X z&vcehu2mOucXNc^7?)jU!+0)rw?j3|+`rh~+W1U(KZX@u>Nhju5#sp-hz)n+vi~G~ zdRyaR(NVA4&KMB0zY%Oy;%ry|nNbl%k6^KYZ;{(X3_WlP%7Bh~0ji64`lfc6bw~aC zcE(ir#Ms_gLHwgvYHy4}sZ)Dnps1jaYj13vvc4wn_Z*3P`JXHPiK3E5J=th3{sk}= zgl92CeuoxNVRr}P4$XNPh9v)gFJ1KmU5y>YS>3OjF;@JhXLmDJ8!)jB!dR)pZB==O z`QU9TZp0c=zd4w4JWQ!6|Dsb(xd|iU3vTWOpZ-@Lmn%wrIB^&(iFbsccYG@!L9|QU zBQaWk+RYeKrd$nPI21!1$Fq#$rN?(S#@GXx|CR1MCMXSLKmBCSKXPwY_NEc1z?GWv z0`|w76O6=H5;vq%9w!^^BHJmJV;@zQ`f9Sv`Yx2;a_>;a$x*k>rTo#E*wQ3BsH$Jb zSbRfdt#i^Ap2+rij8UC9L=Ws?4D5B6CrhQKy#0f{?|tA6W-~DGB+NG+2-v*vnefMEVi`2qH%5t9lr{Bge^Z-Ud)r@B>90;m z4ft}_n;4_tMAc0BqZOs8Y~#K(%qlDpJo=Jt^UEZ>RYl&gR2slHjGC|H436tbJrQuv z^~ODob;NXC?`cf1`!ryM_VRY$3X}unXe`pAv*ZYVFT+%y-hL%|N6g5`|j{6s;&LmbI!~ONgxS1S2Q_E^d|eGjphjYc)^I?G|XA2 z#W4})kaV|F{O6fAJls#F=9glC*`l`&h<14Ui?~6qOvKf?%5Z1=fO1KA<#5fGEVM?n z5G)40DiZxo`kX8CEh1U^mz=ROm*x3+qrG%>c7C)-#kbH9U3hS`t?3(F{J8$ar2ikvePy%A1#{17xF%?8~`MSf&4PO6so6AGJNkBzms zp#4TVlYE_$q4IDVyPXcIv;OL%VJ%?2Q+$pxnb3t{lN&?D{o0 z+zgW@$^3~{ZP1PLFRPeCeRyZN7WhV!Xr7#FG-TVo)O_axi~ih8?sp8XN8OG(1T$C@ z-qxo_I=w?X(V=#zoy^;>{9!ZPJ{F-4Dv_!}iCB2e3g!Ci_AzC`?PCg9Ij9x1SdB0a zEh3PXiP{(j^wwp7O7!SXqnt76w-`fO)T8TVhtf;)n$aiQKf|J(_R~Ct??2S5r@vk^ z%2^n8n*-UXepVoxR0$>BtnO&XXlEVMXsYXtb|$B$Q6b-`aU9JJb%j&!rV6Dke#5mW z$nWZ+AIKfmUr!tDbcfwxL|ADacYlJ((8_cdUT01sxX4nAn8Q42YRYr zjVAK!j0VE%fw6zEgEZN)SnmWC)Iiq&<|JkVTOH+)a+|VN>kGuZ_w=VFPS3~=^tT?5 zu|iM29MbB&l`+4cNp%%{SRXjNI}Kj!rd%WA=s6`*l7ZttVaX|58K>r|$JoyzwT8aF zSasl#mZ%{?AWPL2UcoF=X?nmIr@LS~n>(oXq&yr~N{Mj#nki%sRC|mYd(xI4jJSH2zBS9vxnrM_6x_c?#piO~aCU=x?jpq(I*t z>r9Rbg%w0aQOT?ueU0tae3DgSH|Xqf&Zw$M>?x)>dr0!>A>*7Gp~vYv;ip(OVlcfX za-`ll&YA5gV9zysQA4rI(Q>7IHdd(d&dUw|_g~!_zq+$3E}XT)O~0bSV%Mqfe#IYWoKO9qUYDP(Do(xUypoyt5#rv%KTK@= zVl<3H08+S&{C!bz%4s!Is&VCGt-%#Zw)LdbKY)p!IX);epoTXQ7C{9%y~1A4;E$gBilvrK8gZu>bMX_q$zu zkT2>Gj=4tk0z{L=@3}I-S^QTytDh@$`sv&NtFGzpt4ji`u$16&Xlgmca>y@bi$8t+ zO-E8bsH@u^%kA?1NuE=1s?OER2p_t7=i8dKLe~sB8IL;&VwJt z!!Vs4*~un`;;N#v11(QRInG*+4$nZOV3#=*d}sFRc3pfNd{^={T;X%UcY7CQ!treE z>_DqQbMCTs^u;|X!;aa6&K&*A(W*;28@L!H4cDw%C^DEWI9+=>gC9!Xa+T=c0%z^9N8HXPRxi~Lhh zp?iysIULYpfP87xKQLg$<7__;mI_#T5=9Kx@af?7V$3ANS#7|e5%`u~G|KoHj;+IR zWOWh}7HioVebIiv-!`y?Qhl?kRo{HNnU1W67no4UfCrx>4c8;8S#8y9eW03EFTxmv zBX4}cMv8HU2nY^%XANjzUwyBd)wJqU^N{!8+oXv)H^@o}{1}=J_+keN;TG4#Aggog zaCB^hrNHBGn{GSYFYF51bA&xQ6EYi)4+bEsWgdd0{ht0g$ZFIgVl8so@@?|Lt~wa2 zDF$_m;ml6&qP1|>DY&dzn1x!+UA^E-W-szNt^@k1VB7`1I~7^|o@Jwa>tS7UKzlUj z>b?QlgUA}Lj);L~ktqhHOPE90vY!#;3_vxkrQ2I1%WM}P1Q9s?if^616Ytxjh3Hu{U|R#c-`P~8X{5YPVV zBFv+|py%-PY{Ep8wr{}denAm$fp;y05rZNxfHho`bY>{dwLBaYy%Aa1Cx|;IM-dBy z1?x>ix*oV^_idGdTk8&4CW`hI=l!zlWlgd z>xyfNL<1hE?;5lXd=?L6xmF^;hdfdxfH&3->;>O25`1%4_)zeTn}W}A4S=;mn)Cvn z=Q@XY6Vl8FzMZRuv*|-kPmjR$ot~teDk2I> zb3ev}6MHM@wX0B6yf)SduQ%K<7Atq3k62yC*Ox3}#9EyaVKu3GAO7#>o)8j*yf1V~ z1a$g?UKC-~RfF`=2n*k!hE3gkgbq@sw9>aCtT^?X4vxg7${gJ>(u!}90E@amVTq2e ze)-_9d;lePaSfz8KkFCF$MIVsY`Cv?fs{R5pAP~5RX+IMt_^xuq{YY6e~PqfM}0gP zM{>;K>QI|^YYGy%d|uWF_Ll05C@aFZVLkHNngiYNXYcI-B-%@X#@@$qMsjyB$KgnG z?~e#(?oK8xnd8ljLZY)2%k$>9LZXWtY3J=Q35mzdNvPA&n*y2Lk4v#G-bEZnH**qv z|8ei*lxm`x>c;Pm9&yyDdx}Xdwo`F^+3i%5D(|S`Ho#xq(@Y;4ylTd|p<4GWvpz=i zg&FsOwxX?-S+!;$Ggf(^@A%npra*VR;(aTx7$;G9!#k4}uB|wBr}u09PP7$~{Noh3 zr8`?b$>6;_9tCnLKhNNug8J@OlCZt^b#RQ;K>bVS#aOj-=OOsJ`^l)cBo27XwX3Gpzgh*ob%GfH4H@3UdO}TW zQ@i1#koTuK7>*MC4d#@JJdVRb&R?B~wXcG;7wq69`1eila&}jL{P)>i{V8X6BldaS zKh{cA-Sw z&U9qFFWJvZHXKpCPhng0N<_U+S@Zd|Z*_@RmiZ#qhpf;>B)-fOm0`5~xBfZaN>ar- zGQo<8^IMM!uh1Lv(^r5!$kn9$;5}d~vMs|Xc)g-$g4Gn?vO#sVnHN>&5~Dz>ZDqAa zP-Vy0^}a-_9X=d;H___ST#A;m=v^GFEIXZLBiW#P9vYfK?WG~v@%17kXY%69T+%x~ zy<%2vtEy7zdU=wyH+dc+geqZGbvp(l6%k7~yw)-3 z5^Y&x6_e6YyQ#5;@dlCwWA%5*Rt%N{{pwghCyrT(F0w_tg}h!-O&yrDs&Ev}oa&L` zFpnynq+?Sok6gj1+Na^0s_@7hptthy3EdfoV|JBdVnv?g1xjvcM~rH%rxwl&gw~~c zMvCPPAKM+-nG~!w?PX?iKt}FeeKf_2^6i_C;x9AHF`Je6n5*MuiX){f4;i`Fy~y4o z#rFJFY>O1*z#UseHQhdjV)^fw(rp~V3;!L{yEVn6*yPbsD9sXXc>W;o(g5szk!|4c)w@f}q?{Fqq%`1i>tMb5u z!vSt9;L1Q8uIj}HC92?q5}}s+7NVacJkhe3=^D+f{=W8uF`JE;HpGRP3%K75LGdIr zBB5o>C?E#RBKC%hTSn#0@~ma#_a_lwY)f=@A)dfV-ZCEXC)!0-`4^^;|7Q>455dHrJMfVe zBV{8K>7s-5y5twZ-gvLPVE=aH#_AkMp^k$j09ZALT6)%Pl@s`!R@e; zCn7cz?16BC%_0c?Se>zmUn9qdQR1`#%ZZF3V&hiX%#mk3j6_ZTBqk#^1i_hLtop>t zJsV4L(Tp{>d}5mTK?^ZZbR*`R+(qmuI(rHy2|V`=--kZt6Gu%0`V4tTmyv^sfc+** zh;wAby=BC;#Ok$0jUzE@vCjA$afP^^+@8V{jm(+sA-0}F>?XC^OV0UD%&8~kiwnqq zC&L)spS~KuSw#_uZUJ!RthbH2@PbKUX^dS&)&?$j~j_QWc0h%k?)*AJh_~hGncql#`Kw# zoFESS*)Zns5~GalNB%5=1HMioVjWmOzD&AoBa<*l9CmaI<}c|k{y%jT6AkMT{}dG! z$!N-?xdc&fPjQ)U&$7(+BI1WqrgFpBQ87)iINHwEJlb(6Q6Ba(u8Zh?V)ai%m%~M% z>+_6w6l&>U(dT70CrbBWb(w=JJ7BeZ9h75*`L0T{T3ju+4v%yd6}m;KnH`yvAp-Nu z()jQJ&N~nHH&uwyewInyP>j>gpGT_?CbpBDx}oHM6{C$>O}_C;VnZ?D2A`N{#x7=6 zE|R?}qdK&MIX?ywe-Z^xTTgy`O=43`JT1{-ri}c8M1k@1m_I@~+uMx%AL4b5Mw4$V znvIk88$~jw>q0S9nb@v%duFW^A6O$Jn=_L+qq2!@B;Y(9yh8-4C4xpmX9!f!O6B{~Xr5Sl zk4)Q-WK0)C>gY5!QN1VersQ-hAfMZixHN&dy9III7@|uNeWJ_J!^jVp^TvQ^^2So) z4fb2jxFch_D3;r<_vBhJzQ$q?e$g2pRS{F~?@a!EQPEo_`R+3CI%1V%8B}|b?mfxR zZ_6^jibd0;=ekca=Lb=2=3rc98?~hTQ&N)OMX`+&((hg0TqXuf*f++rTB>*>-_v6o z8RDx8hBH4+f=WFJ7{iO1Q!b)h6dRn_%$zr+V?)$?TH5?w@;?^^Rz={kjVchuHqxMQ z+lc3~Gce@RT+g3xQQgy-~iD{~F zC#1^MdmP3r6$w*gX>}*3-W+u=7OAz$(FUn?>h(S#KdUIJ4Br=^K1$8+CWDljF%SdG zEnC^)a`W6XAZvW)s~q+Y6Ym4T?hP{o{fekTd{*9y?DHJZJ8LB{J%ru2n8`3*IDvy4 zd6#X>S3Rkft%{#i!%EZpJb%5dmi2~Qx7BSFkp}(8Z9sl-C_;#xQiP`L)NKnfC+)g} z;WT#I$Fp%M{NVc-H})W>el&w%M%xfzriXTHaE%JidVDwVk!Flk4QF-$Hrllvm=i+} zY5U}hz|ISTfV~uR1|O%nM$Os=oN!hHpBqFKl&Q!<#)QR69k}eOns3Q1$_rsv#|rn5L%sIN0f`KKogvdL)6Y zu6!Tv8s$%|Zd5C2{7q_67|3SzQ5nb{l{pIJB{jV|$X=C4J-@2@(A^HHPdVbl>QqmV zH`KM6Ag9%D9QvE8Nq3M-s%|ro57paEG5@d=s1Jj|H|i{fxuLdG+?#41jr5yZ4FATe zb5R1w9X0(~kXh!g0U)!@(qxc1W>@<6N;5eTM4QV8f~+!25Lv9PrX2zDqFI-dWt(}C zvGt(2l+st2zipuXUo~g9K=MuV6N>njd6skb9rNa6AeYTSH9$T!|DXvzGqYL$x_OEg z{Kn*y2iP9emZ9=Dvjr7Y>L~94Qs&rafXsI+r++SR++loJz$LnnSb;q8E((%0EJtw@IN` z1)t{u3l}s2_E=U5?D_dxVDG8(f&D_d0gJ{D1rEQ#X;%C_tv+%c{h}l+2RQx=OHTO= z(;I8#6Ptr9QjHpcELNFKtAQ?2Z-j#^Rij(!j_s{T-=~xX%j3N<2pQR}Imqxdh7u(m z^I-zg-h=evxJb_Q_+W~VwGd%NN+d-sLOOZycwmb2ao}9lirzU-J=PGUT$L1o%vV)8 z;04OfA`8_h>TZ!wjp1o`vFbD$WQpoE3=?~UO5!{?qQ*pn992_Ej;WbDK#r?)df5r( zrnO(I+(UR$U1aaCtF2FfoKl}q|8JjiI^`Pg} zF*?-y>J1;d|52Udlqol#r5nsQkJ7RW%wL(g&`d)Stf%jyLKd418Jm}wTs6gd`hjea zW#;Qt*>b#(8f1l8V=Tx@^GAAyHh<@ESDE`b3s;-de3(F3P=eL3b;(^z6?LD~ z71(E7Jh1Pd)N;SnI>7#8ITHp%&IAs6pPdyArN9?r)PLOX@UyQC&ee(EBw6E1T=W170R?4de;VQ=XTGl6|?S-@w~wgR7%M=eX$phP5QsNg{$v({8LQKwee_wEipV$Z(J&C=PO5 zm9znQL&-Zp-ctL!Aazl_uR$)U0rfzxs1dm!pQ$m^LB3K?)&;qtX7aRsOO1g8ndaU^oOeqb=uw4eRgS8ge-3>9M-79K4^lx8N!#v3UT6xhS zJ|A&(2xI#lHJowrPxU6pS!O06CABMSa6#-ivM`X5g{WzZ1kA(p93ot@#LTyK#we@2Y?Z-KR z9m{J02e(}Y^tIy|V}@$XP&!ksoclmHb2nW!zFIOcaa?;~Qa~OsWmzP!?%TV8^#;TO z>$lng%-lH%m?h5(HJ7>K>3C~;QwD<+9HIH4i zp4|iTwsnifeb>6(6y!Z?E=}{kH6Q}y18e0-kV{rlbC3_M(~NZ=SywSke1oEp9er$d z+XC`;>!o6lPps?NoCH^_g!)KcwZb{-PpyUw5uaH<_5=Cc%9;Z5g*9&~$Te#bJ?y%5 zowMvqtNt{QudJshgM4l6-~|1~y1x|UhE;nJ$oKg89mp?MxIf4}>&4|D_yz_0TWI&k z$b9$+g~I_E>3!*EYXj@Idlr}x*#wxiZ6>hMJ5)vElXU*3eH#Ls9p`jv{!=2b#dj-# zIos&VtxAJ{x&3ZyGix>QY$CLDb}8+hL(XWR6(@SBGtqKS*lji8&;?Z3S_0) zFTSq6rZcTp&vOiG)S|W^>y$l>`g~rkrp{hcZ?m_(s;wJjpW3_&>z$_cX}A)rUHy&~p3g(_yBWx2l0mH?LxTA;L7Fdght; z<3YYO*VE;HFn#pwTjt4@Ah*p^6F}~oPo;sBIzGir#Fs6;7y~lL@hu&Eu46piXR+ga z4#-N!0xETf<1?E7yyHYN$OT6buTt=33pb^|+IGYHNYC}-R^Yvts1NuD4RUI`7~NZSXhE5qeixi|80edTGpy(6psgLkP0>(0;Em#i+B%RBYE zU7caN)D?69L6h`B>>c_2!9oT*SMWa?bke z;l76J7~->&-*qvZt}OleMB8I->Ab9ym8~01veRPYo8w4u0ZuzAc&s1Y*5OwL-k-o{ zNJ9?k8I$ZB^H7szQFf&Me3BiGjfHn6*`s{Nv(V{l5G_C+J+<-T(U~T?`yG=epiU34 zhO2dF@O8=KJE?f_=$5|<)UPbS$L#|eR2JZiN8dn!uoak;0cnHC4txY`7TYyKqH#*Z zi%0oFQqLAsfBmc-9T|qafCrDNevh+yK=u%XAgAj_*0M3KFr6{kPEhgsiOF`;@Y!s& zFJ2^Lg#2EBCqDxEpGHv>+BO-so2D;Jwg*(@MwN$KF30JnQ|v4irbkb)JyoL-n5!mJ zi+-++df61z`At_$vC~`bX@DaSc39p=Sb4a^^63`fAMCJv1mk?T!*VJV^l*oz(M2ar zwd+MZ&(HdDZl zaJ^g)d|SS9v&7X4<9@jRvP#9}srJtbyCl!~?0Tw1|I25m)L4qJ$A4$z*b?{+|5cn$ zZ={-4j4MU#^Q?ju9EsH&Re~)4V015gAUzFq>U4W1yngR=ySe&P-SD z3LJ=ik5SoZ?k2`cgI=C4jakysX#FV~@%7-@#>ki2VGQ<07m?-?Op9Cat%#1Q#GyP{ z8kr);IcN{>74s(sLKoN&CXN2-CBHS0xK~gyne3A%JReQ^9Pof*P#d4rzmBY4J ztV|`IhVx*-#!Gxe_hHcwFxl}cJQ>bD8BQ0`-AySZ8*Q+Tyt)jQ+^#Fi?6#_f{@t4iaG`koVY%j=ws9R27l+vDmea+=&5WmXRP0&JH4aZ@K4dEy2?Ib_yw?Nv*iGs34m$#+)yiC?_8%10y1Bnu!`%e6W&$wAe9s&WD_S+NR z72KfH=GdOpMlkOmSqJKXxptiv@zV9GG#=yh*9boHM88&Zie;uv3}j%~D-31&!@yE2g;g*V%X!k?q9*y+;AU>SCN z3cGz%RX#MJ8IWbe5G5xEbHpB7anl-VrZuD;*82!~A!o zr349yzru~=YSUSj_OS<3(XQPbqF;4lmHiN1N_b70Ke;;xQL5_0g}9lJD>PW~8b>Y8 zQX^nkta!E4cOl-RHqBCIuA-}A_Yj*~ZqDYw*O-O0;tsP98pn_5JD4Vw7rlJTvlZEh zZsPTE@}z%2A8Rp8m&~{8`Szi<6!gDK9}a#A#qE^Z=-p1;2+i4bd$@sV*D%J1i&Qb4 zkyHO1N1ai@-ZM|c0~-Wzl4Qxt!X6n#IU4q?1#I*Kb(K>JqgZVN$#;&ifW6A=Vc&)| zcplw+)R-#32_1CW0^8f=7usxx8pOQ)>I6;~Scwv$4l0qVLWx+fDv|52l_<)Dl_&~W zIjBNt)2cC6KfeHOc#-lY1tkL0R&XX|L=zjVrmmYD<8*J~sRqp6tiM2ofLxeH+VOm# z&4qSh*bqv;QT?JoHmPKaw^{Ac#S0NC(m-aLo=}iE=5A)LG?zF*w7HmiT4hewp^NM|ctJywOx<&lo$m{z zF;_XB<|JM1IM^O!vttl@-{R=SHupIWM1#ESXvZ0R($R-@f8A01(BjpnaWtOhECi1S z#x7!;Y4RqvdW)!!1|4evbFQ=mwi>`u^z2QA_wLR3+;0r0VbP}gz~TF8_u@+|Kk}b(z>>UV;P}NXIi)wdoQp3kfGkp- z+0SB?!f`E8>G1s4xE;`o*AdIqI-ZGEsBfvWwd!^N$aZD5139RsVaAIItB<3C!#}2A zF?VV4qz?M?#dZcB$_`nA0F$QEm)H&3zs)w2o`D-wR=Yz1JeM$ZNyj`zMSIsXM8sWZ zkMYeonyjlBnUqM9H$Ek2>77e#uWFz#F0rG01#ESRN==7T;e{e(+U{3iV} z$i-iU4T3=e^^9QGGf3U5OmzrBW?j9OBv5}(azHn$4sunOlZ@9_NG|ErP>>(=WRmgv zJjps8nBO(>zyR)^gWU{bcZmI5qd4jI{iHfes_96zS89$ zS1NwMS9o0U>ScY!<4Ur!N(`g1-td$wR7Zxpg3)+txGTvVQBwK(p7nY%lJ?#S*n8uw P{E6zWI3Mncdg8wT+ulwS delta 44250 zcma&P2Xqui*Dc!B(>*g9jR-z1wu9+S+Z*K%XxDhzDUYA;m@c7^V zZ>snoMXOWyfBaw9Pb&ZG|K|R$6#j4Vx%>b9-#P7ekxjq0Rn_ElV@e$@N_5}S%oHTV zbLV$jiuK1yilVBP2ny#pLFW`lthFR=D?4MJa0a|HP|5H8Ki+ zXAX1@Fvn*mHd7QA-(VG!+k-mWEL0aC0 zrtpF}Fr#bhljz5C(`mAXi@MGzYXjc`ouH5WGSr6|kfSJTmL%s)Yia~1;ui6xmgaSf zyr;8v@<_q2gC>Fb1CsXOG(mZsT|E02cU-O{8TkaJ<)ht&TW@DVK>^_Be zc7$fm9kkckqHuNRSo;V!+OELbdAL-u#5#T4y84RN&>WtNCc3W+JXWZ{uT{ZbeVp^$ zO1TXii`okus*t6z^R8RA(6)pZI47cyV&bL%H{E?pQwScK9`4&0LPTMci@R>?u^6&l z)y)T-L4`(Hew>Y>r;qVG*W~X!QmBz<<;HNBDI`#Lw<3}>Q)rOx-rQNNaCH&l99%d+ zjCRf~99`QFOV*Y9Wr#`<;_xuyA{bLwMr9MX!ezP=96}senAmYL@p?G1A@;bgOwS>n zau#+E6nmXX?lF#v$674}MEIG>UlA zjp!UnY$RvW7yDUP`UMg%%WHedtFm0F88C?0(jf;PCaZsx%Xl-B6=USImdL>>!}Ypy z8b;L>U&NfQ)bb$~mIHK@Lw2r0O(ofW*Z|5W;dNbEDW`S20_9J$iFKvn0-`A!V;!V5 zaILQNC`*h=CYDJgTH6uF$yKUyV6&WDJw%AiImLccC|6HcY@lLUEd1!aRm9s-Mh-JjI(kEC>JOD9-jG9HmeYE%gqmSZ ziT=_}j!Kk|Nt+Ewr<^Q}JV^$_ugHjSt6W|axjaAV;yTi17m!sDTAhgdoc%n!b2^Tq z98{NB$%|N4hLfvwWe@44$E~PuQi|xCOZ>hXaY`uhX$xY4^MXeS$0s?ukL-W#a_ZNO zBbLQJ)s?O?ID5&koP^B=2TUbilm-p(rJOHko-6y@kw8s^G@o@0Fng?Eh;%3Ufzxvxr+Qe>Nj~4dp99ItVNvInD|)MKDJQ)UCw!~Gnmk@Md@l$yqF61&$Vb(f7I0w@oWiKnZK)*s~}=g3a` zO8-xg9gR(8%XKY@KT7lcB0c=)XllOmA+C|m7$+T2MDBw`=P+;YoE35byJeKUk^P+W zWcy7sh&2WhbL8ggD&wW!x70YKgMaysav8aR6z3i9aK{SS&-Ze+edK)1$!v25_W;EH zaALFh#GBIeIdWGCIp>G6=dRLlHHxxL2NSWHoM9O`VuqYa1!;i^i&?vT1hI^Co2x@c z*$O%71#()2V_1#D9&oMHRL`b7NpA4rauSL(^vek9;bvg)9O5b&-g!}!XUT=#nnd}! zjLI6)G4-TxXUk~n66{ocy-K#1Hoou2rhBB#ZptlCB7~YTGAt`gOMjFZwT)a^Z)a`a zK*x#3Y;#0*ZEBC3t1Wi zIG&j44E6JNgvo2KmShiEm^u=n%;A5@#mtel=cZ7@8YHbc zCunZUMOc2NwXLZ{m%+#rvPEbMZb3K z0j5kD3rtK2|akO zfnRiAmCp5_kpK+cp8<^6kFpDQkz2ebiU`{Ms);dZD*R#RFvPbW~ z7oi;Zj4i^egaTu-N&!o(qLH&|aR29&b_dq`z9?|0=$Hl?CZ;=qc~xW;__K>Wt}Jrtu6 z8u}l?$&h|495mVA;yqXMPUsA*(Q2<&pfReQ6B?^7pmLVFrwqtYQ`z%uwK4l#pxER)uDbs$fP`RWPA#}2i%vq+FXKCC1KRdPJ!ptDUsbG>s+&kfKrQ#QL= zZc1$l+GLu^VK$q5xyFO0M_kn*)01z$n$vwb4dPv?G!Wql3?4!kBur&sCq_DeDZ!jZ z_Uuu>a%DJT`Ln#L!Z`;6r(&Z4z)F!dfR*>t7}bh#lh^ZP7mdRP0h=7G32a_`GO$&L zdBFDTI{>?GW)I!w4hQz=Tosttyb-YP*a^VzeL3VfahNnk{FMlrDm1QZny3?`DE0N} zqBnw5cZ$5ZpqZi-Phs)kG#NbZ&FKN3cbr(@ujPSJts#G@>p@2Z zzi96~8XO|ZIv)lHI{x9jf`PQ=Z~b^jLWi7$^2} zobh5cjXXh=<+hzD(rEZeqPZVvvN+DTogzB2$y8CGJ7}7ifm@gP2jNAZ?iO9xa*r5S z0JK*OSPa@HOg^CfVi-#YgnJRtLD8@`$mftaUmN_BD9t!HEY{JxN5n;^U#P#M6&G?+ zcrf6969EW8^D{9o6{QJk4Z3)udX>XYQcqJkSsg{QPf?2x1x;1!(9hGLJ?B zskY&Uo}unx%bDs1nsSyJ%os7$4(w&Nx|;cJj(XYB3IncCe{t>(jj28w5hBg&|7swr z11uT9pk^E?xbnBa5dX%&Q2&43;+xLl{d^G_y8n8{cYq705V+f!6z1tDk_S2HEHq!7 zxVb;uUBarql*3D~+&h7-`qBBJ9t`cUIL<%(FYec(b^(l8w-gwAZaFaS05@j*yv4xe zhs}Vgt+`Rso6P}c9HMhdeb0^JD6P|gWg2jR%u&osWlytF#hJJ-=+!1f0BbGG1?GCp z05)3G57^=yBemrv8md(kW2AMjWMG@;G(@}d-oW-#>jJxVC=JZ}qyqb{SqSVG#A)?+ zq2I?k#3GJ4Q8@a5CW(oRzUAUGl@CM^LhFmMr<Kl&?I@)Dgp;g<`~1oKv+z66FzVe6h#kUYv~bN7@P4?Cm2<+C)j7gVX7)`qN!?T zMgeP29R%#tG7i|!-}y8=(eZ?Ne~u^|3Hm|A&@#(J%IvQrxZm#yMUX#jo4%0AGGjgC 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 F|37MMqnZE! delta 55512 zcmaHU2UHZ<^X}a4zCDdIC?W_5hyx;G093>Pn6qonYj(|9*SPLFm=h{8>X^lVIp>^n z&N=6t)*RpWwf=tZ|K2<2?K#$0Rkv=gs(ZU>*d?yexvtQZZq>XkQYrrb|F`mnMgEU} zR{zNs^WWwd7VH1{Z}qklsvgtZVzFOwrD%n!)fjKFD2jFU41gxX+gmK^otoflw6aiR zZBYhb$m6vL))oCM7EO~Ky7pq((`K+<69VEN18X&_%S(n9{4oeNF=FYp?y zX5Bv#w4kT3SPbjc=HLru2XD7lnC@Pc&05lXRd(nKFNLkliGqwLr@BR;H87;{V5q#Z zkF{8Y*E}B#!=kELX;dConUh^FrJq>svg)}-vMWXp4FA-QmYoNfmc_j>iilmbY%aJID_HSabcm#wf82UD7Gh7;oo)km-)&rW>SQuN_Flcne7BLh?){AJt z7TFN2#d>r;_81Cw7^%MDB!>wWAt=pos2CMs6pH~N8o4l`e^(h5Y|!o6YV( zlR0)e7Sz__h>8IYcLf+>!rPT-)C-8hw%T*0peKtpZ8G=>@|rc>wbY13x3>&G&$!_h zi)U_bm0^A2(mdkDTvsU%zsmQ!L0{mWv{-UmLuP?5_zrwN>&v0w3sE0qwax|~OMR^M z_+0RXv+5R0QETD?@Np5~6Rdx^(mcWf)Dh4mu7l<`YaeX5XNmpbYg!{+*F3^1D_B&| zvI$m;rG@nx7TdF2ZSbwFiIc#W?+m`Zbx;}b6^4WFY@OU1e8uVDyIad)89Xa(0pH8| zYHg(qA4K!BSPsvs4K+B^kv3qf?Lw*g3cH)p#Rbsq87E~luqOL@LN(b2AHc?vcbn_u z-|~;nmW)#_pq61#PqjnA)Y}jwD`lSSnq?o7aX7p><1%!Fsy_y~qCGnVlxPXnzG<+L z0Up>huZ$-v0kbxBt@bSL895rI=h?oO)!+5evy^zbwphlqBJvR?qXv0O@9&Ml_-Hch zGQw01&#ZcQ%M1@`$WcWv=X7U8annX6_$G!kW5GiVqZc2$kYCA}Bq zA(uNsdcSt9%AC993ap^C*h`Y;&qBI4jP!R?zYJ?CElq}zE_IOh&rF&T!<3fbaMG*@ zeQ7CCm2?C4Mp`a$DJ(auk+yOb^Nw^r8$62j3%8}inM(J(tn~!%VT>n4|A5!)5$MIBudL+xTCaq&|54`;epcP zHiuZ(q&*aBULfwI<+91&Fl}zlrzW#GrQiwV8x*&M0veX4P$Sh;nInxs_JBT$G{Pl( z{KD(Q#ib=6hV<%O(qoNDE1BDLup;?xu0&Y&MG};jZRTXAnUlHFmzt^O3jJkHK)U+- z1Y0wXpuVGPrcbcQ?b-@Ws<|7_T{nFS2c(kNGrmGBg<@fb-o-`-WY6eR; z1(4n_dz{{k{3mnd$4ysU1y7fjZ|2qqn+tT$9vK%|(yd(Cvnedg*8nraTtX+kb@ z)G33hYG}Ild~67N93(YkK*7#F;zfm6d$`$)t_}q?OH3 z@J=OPxIgJpbA{&pO+K?ZrK_%|eqqkLW;^Z739K}SSkdgIpEXZ#v*nWJT8<5;O&gVTggL^IW{<_pk*MaP^hslBwPB`>xsz>U%8S*F0EYZca-QO?o0dr|~nMr4LZkC=kr!m3|qb{Z|`kI;hi|dDfWRaZa zx(*7YWovU$Mpq%f+d(?Q^uH12F3lfK&2n?-+g;5Af}K9UQccvawlwRGG8gfMsmW4{`tqh1+&5iu zo0*!c#tmV?8ne*`=05x|mt!dQT(?ZbP;^TsET3-a0f*ErweypXbQQ?v=e%Ps--BXo zp_A!T#mz>;DpFJ0YE%GXdY}RC8JtefpAl=MMDen(M|)vrdW;9Ry}(BfvtX@CRRM*Hj0TMz zKM%BUSB^NYXL-;fv1y>CYLx=57(ENL#zi~m?+qC|ZKAkQU1wvHWpB63GsscXP2XN3 zCQ!9jyzhqY)(dk?8-zKijlvw&CSeY1voOcCMQ}*^PQmg0oKt~HXu-FpYhaLHr`Als z5h>L{^E*}00{a!vLhf>)#mWx?O?(;*S~5Nrw4AjdXyrzKfmYAY#8u}kcHL~(FOU-o zj;2M}$WYM8stKTl&vT_qx>JJ##12=s;J{KVXG1Yp%wSLRL>MPDUqlQ8tPmF7idKrt z^ubl4A6I9SD28p3n}xv~yhY4*^$w174q;oh!vBIl*7zN8&rYYPpS%H6)rnI9^VLTq0qJUw=781eHg>Z{-8~er zTlFdp*rWRN{Izo4hq)krofAPZWYCaYsi67W(37LSB!L!c!C{mtH3GEsy%f+g?^vsB zKPNq7$lPlvvo4=j`+WJac(2fn*LZ>nu zTo<1zpxqZW1nm_w7WD7k%!s2zXZAc^#Kr(pL}_+0LEOo1vDA^NVnR2FF7b6bV3KHV z156ju*#L{hVYa?O{EIy_{lt4FcfkKRhZOvteil&}{Liv3+=!4M*U1ovc;I>+5}aiL zhZSOHqRug#!wntda^&!>_Xo2@_{`#z&*5H%Hd)M+DfzGHd5GIHO_^>`l?BG^!6_P1r zn;4Z5uwDF-2G}7w(rb2#&XjhEl34(|#Wd`(+#_<-0_+uDjHi9#V>7^hF_|uSK>QO1 zI4FKF$_|P9T#&;;!8By6A-M|f_baqB zClr>2Ta?o-KqIFx&F0yW4w|<;qdDL3G|-rWO+jOgA)rMSdTFs{+{5CBnEB!-a6uC$ zv;D;MPM{@P)23X~0?;an$8rIxKj9wM+&l@iLG!+#O`FpxoB4Ba&0EuHTC6Gn+HxgV z=8wgGpslaDBEy26A)Mhzv6F2li@kpW#)?a|0qG)yiRFPPfmxW-4@^~|2+CgvH2Xcy z!4YPFhP5K?xRg88c}E7&u6tOudyfjB{m#(S1_?*XuV%t#GCkz{Mh7YwzLu^U5yK(n z=`k8K|2}FeG~$X>8<-okMw@>?d(O@W+FN&h2#azSp`%U}wIcv?L~ky@d~pS?`E#G7 zxtr~{ghh|SLuIi~^n>D-WYBp3`Jf30=pTvM>G;)FG4$$m<_gx$PA6^)07gyI2meR_RKh^`FcIZ8($z=gEMryw0Ju z+@BM))l%+4n>By^8b?qQAIKs7{Xt{CyFlZ*a%9!2w*(!~tsv-Zae--Wg;?eq5FS_| z0Gsi14&GdZ=%~7&&6abg`(6wI9eA-lXp(rvwHP9vRt1a@cewz`;$sIus<`O779NIngXH;Hrq>_S_H+x%T(Os7Sy=QF0dGxj0QP zdL`B|2;Pg#EdZZHS68=OVWRC?SFSe=-0|sJ;kB0rHVkm56xFQmfUcVV+B#GA%8;71 zYgDXVx?1!4sa`wQAWiCa!gn!m)9M3$$)iBsR8Cu|ly0H-2lRI`p;aw}urIhC6Q-5hk*4 ztdT_|2od8>_7S;6+Qzj$Vz%C}Q)^+d4;>;b^Gad0|F8cPp)beV0X3yQ);VuHN)=(O zxdKq+dAu&gE8K3aP+r_Xd9}tY*JNyGXx#24fg)SZxJxMb@0(j~14>4<5ICq}U@I9_ zYP9=NpolCtU?GxY{#DReee~#T7>lvN1FD!KP+5%d)p+4qAP{QJ_^5*~ScE1<@i(w3 zR0+J@IOMJuBuX`0jy=~4pGPgdI`o-VPJnq_2e28mMxb7T6S3wP2R`%3ze)EF#S7KU zZxOb5&D-cMN^^FD-n(sIfj$CufH#i1p9hK9!lo){Dm3~Pke`it6K(Q zQ{@9*^F};jGkx6kgGHXAf0xAcAEMg~!5Lw06*j+SK;txA+vZOe6@?Nw1*;N){B8^2 z1E;#oy(w7ajB+88JtGIx%9vhGSUmHQ7Z$7H8FdnzVH(8zG??qokX?j0uRKGY*cGhf zJ)#9#_Y4<^4u9ICCQmq*i5$2v{ zy0fo?_+exxfnui3ckjc(%|cr0PkKg*I$WGyX=ndbTGojsBIv zcQnnh!^==jefv9F>$H(<=GE@%AtEe4-}7V)+loP2?HR*cX_!RkaAC=q>u2Mowxc+L zyk_{VanA}7f#Ii+e=$wLFSTs?Jk5omcuCEZjw_(wJG=&_4e&UJ-saS8MNx4 znZDp~$()VenW=pSfj6wIZ}sucu@0ri#5uy^?V#saj4e$un^5waF$brwcNlrYXw?aP zPQLWB8*AJzbBc&2d`$Ar)eSA^CqYzug0N%>eF8Rv_6jt}AGu$>vKP*ouQA$I%NzsS zlWg#BYY~KP#3=AtHJ=4>88FX&r%=4eM)sJyXSfKfxCBRmPx@dOS&ZlBz%TJbsb*0J z<5cijS^CA)Df^5ugq`Pgo zM1JSKmiXbBZ;_5RSoL3l;$lDhdXL2ATb#URjG72Op1fiB;;P}B@Uw|Fb)ior?`5Q6 zoW3Q<`xt(=z?UTNZ`_y-n^NS1jO1d_mnNUXl6_DGG$)+CRhF>p0k{VHRwZjO8czoQ z8~LOVOH1(8|G^wABE+u+gjy6dOqlMu1xCI_6pJOqlD%3PizP+)HvP!<_!7#u8Ci?5 zHVoC8vs=wbhgbNv{7w^tBXGw>h>(D|{y2nudl#}pJr3>q_91IQ=Ik0FO17NQ9+ftu zd8VGxDBeOoV?gs(Z7sfAGs4u%c;6Z}+t`V}@gf-fUXCxwNa+B6{|;PQa~N%q4Sf&Z z0iV-&hlASph@J^QeKQ)lGv*f2tz2B@v$>!uW#ko?F@>XYT(1Y~c!f<`94|v5lv2i`U(L}P&izX;9EXelx5VyP!4)lI*70&|=jxPI zx@E@JJM0uHm?bfe+wgneipo%w#5$%SXZlt~Ne*OF$H>)?sw$IEl;D^v(Oh+fo?6Nw z3%GkmitrYd;KaUl&6a99W{!bHJ!KU#XkCYUEK2$*)lj!#D0kiWZ-qNuNrc8%h4ha? zxA;wj=E5!1caSm%hS!wPDdQmxS88K!x0KKY?hlb-a_p-cP=<(NSlloJK4bR{6C+^Z zFdZn|=avFfmHs$5328jjy1QPNC#jg`phSce?#+uU4%N{;F3idaEuB zKmV*HLMI(W*_WTyL}t%CUYo}m1|o3zKg36ENbXt6xsZKh+7a} zsiB?SC-aLAiLEhbKcQT~oO34o`6&KA810g3P-a#3qn^d#ffVQGr|bf+Ii_zxiN7fr zj;ik7QKC?d*N34CHg!22$%q8M?52?0(FW`87h($e9JhKy$YBaGjwW+Z$6*Swj%V-# zzfe;s>KN|+5G6_lo__{iZlw=~)57sPR^KmD833V|Bg|bpS|oY;;=1UUSNVq7M6__< zj26+JZIK=Pb9{o8W(;x%#)$IH4LCRbL)Sv32l!%h9>rQL0e)LCmrQ$lfb}=ok#P8c z0F!Og2HKy;@B|DvAZQhBONW3BHd*5q3_?tH)=aQDOtx%07&zF1b!b3thaZB4cW7ro zB#VDO$OPmeuNkY|u+3}Q7=_Z%L=<_uF$OPqfP&SR7PAMS#oEf80T!pG~Mn*V5KvnXUjJ1zpT0H{%Z^qrfz}KR_CV1G?CSTV` z_!s(mWRN=|00Bjt57SjScw6!! z92SwE-z@#ogs+526wilWio)&#g+#bWb3ZF2{5?CexIE`+F;=)U$BKx&h00(Um2UsH z(dfl3p?JU{^1q_^CuWohfGgSDf5eJhIV0gQVh77;BW7GO%kW$%c2J>AXdSb{y*yR~ zW-@!*#om+&eWRMYFUE>LirHvs-pG{+y`on1K@-2E)=|w%L7F`gE~89nA2kn$yGZ+4 zy<5~c_n(DD*Q^iv!(<$qv^2y&G2;S^qprF?6voJ&aVjWB$~DV!1Y*=?oBe;b**R*S zyL6n$Rj_RhG+l$1`%KGzu#7T?TkAi=Eo_BJZ5AjKx!iD$MHRPK*~7gYLl*RG%<}5PTQk z<@{p&Y|=Z#ofa<~VgKAl<*fE!AME@p56&#TC*?%dtl`qTk^5e}$WzGE$tFT_OK&}s z0GA_DdON+yITYz_bY*F19(?5Ufm~Q#>3!2(Izi+pd1DBA@Uv^08Xo&v$@;_rT29t6-_N%NP7S2PD>C$&5o|(XyT+X8mG9Lp@{VSRvPs)75&ws zS23yFS_h3*TqfLkf!aR{eihq%r7Z$UOZ6n#o7{e83Gy^^ceOKkjUaBEJ~q zu9PTpWUi0oqp7<@35+Os;|HF4jcjtO|2U!y$7Cx&Zn@Z`eu_^=AWcNmH#d(EyR!NI^O{ z(h>@fk(O0?$&aW&nhzd^pM@iz;KPnFap}eyvJ9gI!ws;4F3G zYnUz+<|6%I(R^u|8)pQ5{N9vw8m^xB&Za!|&TZsRWH4=l$)6rb+6vJmEu%h>Z(W4^ zOWa5CkxV;kdgE4uFUZW*{k)W#WkX3F(V$LCZgafO7^>dlEWrM)Bn_y{YVoZ|2P2N8 z#lH|~ffg)1Yw{hYQ*)|0HT8qYi|yoPI{A#R$Y;mfO=$@?_q(3yAD3|6OUwQRq)zb{ zVU{_FzNTun*+B?SER6a&=|ZyuPjh$YzMW@+Znnyw=%$KR_ou4#n${R@Tp5WY6Iz>QPdylL@E%2_=Lk;@UmtT zLAX0g%aC5A8Mv61@8+Plnl8B;XQs52!ov$bS-D1j?U>{kiT=YINKh@qr_r zXr$#cvIAyzgY=Xj-Qr1l-@($0)k!m%PMsU)xU}ptqpUfSDExmi@}$Idgw$Bb;_0Sy zy^A2fFqHaGb3Im>LG=wU#HD5Ycb2|hPnxYZH8JMOE$BkcHq(VO1@RcbQ%GG(&Eo+0ey!>VvP4hO}TqdvKS#GmGp-ZA5TjXA&JxH3q~B$M_u-SA)`YHmy>)hBZ( z^GcAfQHOk-xvfi^QPU(54_OEv`k`e;LDCC%NROI}6Nje*BvHH~M&%x)!_7UDnaO`O zvtBB0AJX!t8PmOIkbh}9;J}fznQU%ikhx}F2U*(X0cpWOq&=pBIxXXW@aEUmJgx0b zS@0R>n{GL0E@@vx1imHvOns7>D~*52m)u4DzvenMG7p&X=A3fnVaI(;%Z#Sa8{KJN z%{*{(G$8*7J>u-IKF2xb;Pq_M1xrZt^#2u(u#8h*sRBH)1HA>Z9;wl1@@moF^a-Q*tvvQk3?XIzGn8!*nxEnQ|VmL~;HG|=>pwY|Qf+iwe<45UD{b1hZH@Zr)xX&|lfoPEzuub&kDx44* zR%4WJ#d~;=#mTv6Slb8XUIXS~ym?w32hF<%%dF?SH3&5S&MNp(>8~%^+O9xpOpCuz ztH7vq(1Kfdtt#}Exg&O_Cp3ls%ncehj~BTju^6>1btVXW#RG*wYuK1Sf6tQ%`Zo3d za00rf`#{xuK9k45Wy_%%CR!f?q=?*fs)=G6gMYR-%T-8g}(Z2TGm;a`Bztdb9q7qhwT9k z3t?N4^;y60B2KAfsQLAM<;P6zb^cn5;v~_B$#syZ^e3dj!k6QkBDym`=}XU)kzBq0(pPi|Y*D6`}?93?Iu~X$NVQSi`{DB(6*bY!=V30&kAX-LZ$2th>Mh6{(uci z0R!5N3g6D-le*uSY7Z#OxU>hAElU6=m5aPRTvW2J09;qi~ z08f>oQ&IL_8Dl_7QjeuT8m9i<6_Bj<>;1qTKJHS+R_n#=7uinfENLOD> zhH|yq=pJB=+9MjUTlM9V>{0vlNBA&$yboLl^_zmcAOkLXfrfPSLiPNM_k)j0N&_wQ zdopOLHuSsF4H)xf&YuD;>#W5l%3WY+l=o@^T45pAtV)4g;Oi{=2ee`RR-ldS@t{rm zGvJ%|T?*P-Z4KJ-cwx{^r@nx8xv&N{-J8dO_Ik%<`aAnl&{5(uqjbDz#59~DvLT`3 z1GWV}c>bk|dORUqqFgj!lJG#v$Cr8^c_&^hN-To3K{Udi{hV!gCO7~74BX((FF+$& zJpE5uTZT`_wAcTU+cP|T^791nT}6M+8Yp1l_Ybp$|C0q~{5|CCvZc%e4V-%fMnT;^ zf`$y(0h*&QuNR?*{=3+1hd|CY_a11@u02sFyd|&axqO%`BSvFye-1OT8)U!u#9wl7 zCi;M5b5q!c?x5#|)kV6K&e*2dYO_kjuIEtXe#OL|$FCSnMu}5XA&eFQod9FR1RiwB zqFoZCvEnLwA1B75I#%{5*Dysq$pvYG7>3Bir-3KeLE0*w+yQJ8g0tQ(rZdm&5LwvR zPN%3d3Ajsq=A3tnk`DoU#OGuv_llFNA?*`NDM4qBxeCtCeMK4#gPj$05Kv{?n( z^u8x(GxKBo<_XM6E%q{XwCsh$O8yZ@+WH@6%uYQMP`7)S2l#$PR)X(eRD%Asn(2I` z$XXhZEVeLE$BLQs>U8ml7D(qIzm_S`8FUo|L9H`^X8(dyOFE3aunF6h7ktN_bh6GR zOMrH5*#@+G6E0Q1;NL+9iO$o1Eoa!94lvJIhJA)N;jt9);BT1ZiL4BoKhy*Km#i?OAcJ1oZCf?om?&ID^hW7%6JiN0qVScqAm3s5l5PRaCqWm?L~20Okuf zLicBwC(%W-=UoPM(fzDnEGNUOc>4*U@opX_3GdrLpO{3OYHj!$q)zh#;OoAj3pYq+ z9&VWR22)|9$f_v*-TYXu@#sImH|gt*;-*`XjemCdhRFQiOuUiG@mxeyh zr!Z)-6+J)`#&Ae#4;1cZvxozw84VHIM#Ta5E3DLaUhlV?Qu+ z6wY!MG_E6~y2$h8;EQ(Y&8uLsrEQ@qwXrNzrPJ1cmgyY|P1(uZz4966LQ~-dr&Vz{ zP8eDF6&~2+Z{_4Q0MGX&^$%zMuss_kvOEIl6va?Wv$e-SmWbPkLlxX{-*xszPxeeH&oaeP> ztJ1R)V4G5{4Zyiw$zw;29ZIbg5RWKpszW-ed|`q*rgW(Sc&mBQ^+!w3Fu)e+R~jaV zpGPG;Fe5s18&Q9T*5nY5IyFuY&RLwJ*iiKbYD6Pg#aJOiZOtPa!fzKQ<=ON z@UNW0aet9>keTEdy`BOXr}s*Oa-x0&K4k7hv||wTFH=Phl^okwvGEn)n;7X_jf&qz znIwomM32dUB&FpzCOqt3YK3W+N1nI6)umz-NiWmlXu2g*i1TJw^Syno5BEt)QNP`k*XL7X_UH?E|;Rt*#_lg^~gy2#}akO8;D2MkGv`!Q;RXn zoK^e9LwQd9z?;)W^;~BtZ>vk_k9X8zjUhc#&EE+dtPSSo4%K3L0~xN#wJ;f>-8>H% zrFAgZSKH_ZX`aTf8ss7^S9ZX1Ewn!`0jsn%^!#<&QZCd6twvG6WoPqhW|F4CVSp{G#{wL}}sr zrNNg>8xLBx(e7V0bF3MJvQk$|ftIe;8njH#d7$N=(Dgc&U|4rb;VIX7H9e(E2p$=n zvg;;pN;e}3w8vV8TF)5^Ko5x{2u5@8*`7L}7$Qdw1`L%AzXQh0(;U!Ld4o%oE^{9O ztdjMaRA%XIiU9WOyVs$g!`7pf0hg@7C4P-`v~r;y$~P+I8ajcSm3<86ElOTG{&wZV zBuG1y+iplZl`nH3y;3f-{nttWe!L3UU_!~@IiSn9u+<*Pg+3wteob( z_^VR;H%Q-U}QwX7#`+NL$oMUr5{3F1(3uSHrvjJJqRt2HvHvcngy~ zYBaOWUbPmTdcQgz?_Qkpfco$q3J<9_xHX5>TRIA_snIteU00KL0dA@RobN4lLpzk+ zQU8gBbXV=N6EIXeR}0EvTEmr)R%mtj7G$LsvJ}#4tx!0mHCiASVV#zT@w#5SvKX*Y zJIMfdZqhz+y|!p~o&&aOi*5pTXueEkJGIUXxZPU5!hk*62Hu_aX$RT%e$D(P_=8#= zde7I7N2XJ32!<6t)>&Eo> zNNYF{@I*_E13cAge*!$$aBIS4Uwgvq>nkmgmajGEg2upqweo)f-fGeB0Uxx}eAN7? zRqO@$ti^4F@{6{ek0Rf+icH<#wN11fB$qNx43^KbLmDdA_W=x(tvvuEWH=Io94X`C zVKQ1as0|n+UuT4Jti0j|jFVZNg`rK6Z?8d|Aia5ynkZA}0w&4S)d06#9|)Kt<9QrR zlM!^N>9STKNHb-tzJOVBby+CWWKV9>9C?HfT=Qg=e*p942+nMQY|C918I#WI>n zVu|!C#`s$%Yn}%zm+e9TE9F3D@KrKzHrT9@{c{7>%4t%Pw-v)V$m#j^4CrviX z{0*SoD!&c`Y?GIHL)|Ge{DrbzQm+STj~u~O-z%rk6ZXqb@O*hd9t&pt9hS$cKzl@f z*aA2vbFt!axtwuuQr>(B;F(ICntN8G7UUuTjUXV+B11`z-^8uG-het5E zCR6)Ex-M5Qfpk+Q@X6qoyv0N5j&#fe+?C4_6;52l`Y}2l$Rl+5N78pXq{s5WP)JYZ zy#PqhWbrG27qUziz)R^919&5sXNJkY(t87>ck+H3r1$btFyNys$w>bslld(2MOFz0 ze3gwEso&-I*^qw7vaIeLr2AzA4%VyjXc(p+vIB(obd0j|@xv2dfFM*rBPcjr}Li{675gROd#%aFF~Z+Ru$p}QG)yYzhdA??y~7$vxAewK0C#k)DwKEizb^sq>(2FEpnae(-wg4w zJ~A2bM1PGVTt3&63ISf|Zy0#5^~R$BZ}izbbl>WGS^u5hpFMrh;qh2?JtxPz%zB0g z=5p&Zy1*)Hwd0UhTWd3EuC*5H2<1BKQ+B(-I^Q`2+KtvJ8pO@kV_exS)>DI^+-5B? z1k!fvg-F0o>#B4pcUi0OuC>Q{m$ALq`mqFHzx9$Aln1PxnnF5ceU%At*t(9H>6o=l zd%$sPOYYAp>x$Wc)7JRLP@c2?m5cYk^VZEgYc5%>snA}wKE4RJYR#D&aLwALE#QXr zFh_XP>fn89v~hYIV2n|&8I)s9zrlIh%ag6EmiqYvN zwAT#$p(J>)aVH4Mo5m=n_gh9FA0O`+6z+{vvT&cBvJ+~IMkKg69L+34iEJpz|NxyK`!nRuUv`Ik=i zdqfn2bkL(-W|$oENXP@}h)3X8NJl-!(@TzfG%5(`good6kWP6tXb9=F$HG8J=RB%# zpyxd{wgX)9XvI`^*<-15Ch)4qpNW8L9xdn}H$3vJ2i)|CD2R%;JyJUX?szO40!MH z+=;Re9(Ou1{yurUh=Tap1&qq@JCE(r83yGABxfiw1}0-OJmsbjxBaaFM%XT|f^w9t*Hv2Dj`U;v zCEMzcfH>AR)*mq5wwG@SQf&5akWy`+oEKYO}4F`2$*7f%%GfVJ39%| zblc!IkY?DH{0o?6yZiw#+m`PjV6JWMVwlXcJ@5xCusI}Pp=}`I-6Pd5}O~l zYnkl>6WnrJR*qt&ZQ33vSJ`si1+29NL;%*=KGPpJ*yb@=Z?xT62FuO1oAV%TvAul^ z*k*h860qHNb3b6Gt;apUE}Qua-+OGU=&O5e*Rr9WbHDA>0f+}|lTslbvW=yC9kyN0 z1?iY=?f}4XTX%MN()OKkbjtRuBjAiJ+a)N^+6H!pbl$c$64C|Rh~|J7wz6vhFKw^r z7q4wkS_0nK4$|}A+Rk@`^v-763Hac&nSZM2qiy3Zh@WjGE5PQ9?HR-Po2?F$?swa+ z?~s!0)A9iZ*%Q+ML+oWnqHL(W>k3H2?GO3_M%Y7n)Qz$)i-R=Uu6_a}+o#gy$J+aI z^yBT%80abXc?>w0-FY<|aH8Fn1np$|u0(*_KEw`~W>oV< zX?DLJfI0RXNq~9wEH?r3?fJO)3+y=_0v6gobDbC4J29~>vD@h-%j}y=0+!pS(PX7v z^0)ZpD*K~85ZBnxECj5z8$|)@?fbbx8|*EX!eo7K>u7c)GAd8W?vbXP*zEYGMIz--SGpBR5>o=us;=XeJ4>1wX$?r6X~ z&p){%^F6zkL&bE@LB4>+p3yy^T;j>U{VA7wp5Pg`&1>c)%g^WJnc_M_X_lD6keDrM zY=o31+A?v@5&VTlIag>^Aj{1%W@;ipM-LqA{dPVpDtO-^(JH zm(MF=T4iXjiuCo6u8Dc$_LT>?hBJwbOKNZa@@O$WIq8bt*euR>bUAz#Dxw$XJ zDTeDSG1U+7T72VHzY%{iYX22w0-<~>zA{eUiAL#w_u?S0iyy@ISinb7fXB`!(U#u- zS)}uU=ZiR=3({8+%fsNCXn`eh;^pHH#?lY*wKKFyO3o^PK}vOQ^I)Y0r6I~O_B2#U zXHp)fyjTJlt~@Ib7@3>vBM<@)rl=QU=ciOj7DB2256Fl|h+XSR%7scJf50MT3s2(3%GMHqCCd9yz*1$02g;TyOBqMYmCvQ1T%qh| z{H;{Vy8)||Z#$gE>*QP1!dEuw5B_9k4@LMrkMhoDfWQDVd8y+Ks>P0NA7Wy$9@7 zx^uq!l;=Fb4=CGtLL5|<@geMxlHkk??O|m;r*=fSI0MpA!|QMr)_xTJ*f zl5klmOGmn*gpOhST~&(U`AJ?=&M-)>EBvFq_`+yE-Q=c{ll|UO&ILibt#m#QxT9Eo zpuDRTvq8G2lx9}FuQX>)c%bar2~xVW94Z@D4!@>=}%9U_rXv;Q%aiO zqdr##r9k^a$;PAbrLu^r>6OxyFFIZ;*&6}gC@x+Q|5Yw~Lwc)h;Q{O+TWC(odDmJJx>5Xlz-zHe@W^HZpk3EI(r(d zzGnapQSnmp+#rWQ&AOji%kfoG^IxiK@<=hdN{r53b9nytn&MAOuQA0W+9 zJ01bdRr8F5a-MpL5k4Q^gE5PwtHYRd7pULq){E4>^B^r&SA;@ZqTXPFTdHmrfMx29 zUMO3x#?=L^P@ixzE7i5R0jux}P=M8{&X+}N)DuieYt`tvfOYEKf>5qkA2LI1P~WTt zY*d|(xh9*`61=NyR*UhLy+uv80Jf@a%RsqJy~V`1T^+)$+@UJWs5@1^7l2)ATL$%R z_3=M|J*u6laIcy`7ucuPV@&T?w|4{_P?vGO2UQPVH4dqrWkCSEu(y z*#&hg{pq6GgXjHawL>Pr6}5X4m|RsiW&&JO@0#!5uB+?V{SCDn6V*-iMHfi7)MXaH zZS^ek#vSz&GsInWCGS@E)LlH9@2e%bcMsH*m5?5)Z7TpCsk50O9;S zXgrk9)X6;Co~u!u^$WFFA>Mypssj^Y^GY4VBkQ#~n!f%iltlA8L+W zC`-}`V)2}Ekk%<2;$UrH0Td3=?2NIYT806DVcM}rfZ%@U8I#82Ux6S?~lSI z+WcC8rP}tKfMwd*5rE~|SFY>|Z5FfEO0DBVNUOAaJYrXCJs7ELw5ZL1wVHbZlVBQjaqkx_9o5wnOnJ88$kcqss(X_wrRyUnC;q~Ie;D7nDv02+OnP~ z+oiRr3Te0IVi@nyt}(;x)k^cqzEArq0Qy0YA?C>hqS#7P(Dp_V|4)1fKRU z6YEV4e})Btr-k!&cU!wy2+BL!)QOPpYODBEaZlT3hw{F*m(KD)YcvbeLv3>`;F0#C zIpDF@t~}t0R+EYGnWlOIo@6;ex!eD0?-)mK zwbmTWJI#oP^j`aSAmD?xmKoxsrd9%c(n4ATK5Iwvq3nwmxdGBw?J~Fdo0h*X;Jc>t z!ums7kP&4`(vLY|kZgPq%E9t2ES>nV-T_t|Dy#5V878051Bc6pn*bwZ8YeSSKIG{z zO3r6u9W5&q0gREo8C=P-C%0*=yvvOlCrj`#V>~{~2c*cZbchLZ2XkPm?8L*xB~vN_ zCd#Gx0nSNs#~t8gIeaI;E&HAXOpz7FqsCNOd>Eu@GJXl9>9QA3%9*kXkCj<+I)i$) zbkU*GWHDYI=ExBo?_Bv{A7Gvwz+^CAmSD0^m(N(XKxXR&SSY*yfqILaavx{0SdQT+ zmPoHz&@PorCjpkp_P+s^O?v-O(0rttg%uM@bB6~U@7j*_4ltWtq4$0Er0EgvB zDv!t^TL4F;y#^{AlQ*2pfhXj7c7IY9VA?t*NAV(eTE1)x>5Tl?4RBVL7l3neT?4>* znK2M17o=wdq>J(eSLTwOT@un|+446?S7ZUM^HsUp0k|edtwq^&i5Vf_Qf?qQIC`_hw>c_2G*gb(GN*N`5`6SW~d#vfIL^h7@1 z3wSF3JPUXx$3+01%LCJ3@7IJD3_?%WC0#{(B>zM??GdSvL46uO(wG6A9892m?Y`x zc1VNt9IQ83pTzhZqH7$?P`xo+z=$|;BI6_}j8PZ7oD0h35zJYr%TIc^_ z1U~>e#Zx$0Z$*=_`j8+<+jA17U&U-t%dqK2FD^jtUh3|Q*Xz# zvqaC{7_d~IlLYNDJu(E+a{a(GNGtRPjRC9l@679~_4DNcYxK+cVX{{D%nfOs-hi#G z*O&K$a)Z8-Gu)`>qmysaOGN@U>(es@F!g8zrM>D`S-RZ?Nuw8$`6tP49%2nT~ zUu3@7rTZ~tcI)TLL)xQzwS%-*pB@a@r?1Km<$k^IcSr~H=QAK3)NdVxbVy%(9dKBG z)B?&Q`frSbqk57rq+|LU=KAA$TqD2!RC~HlLz)`z0p)iXY|_K^t1Yk zp-`UF6+X0|q=R$d3ugfkT=r`yd5B0PVls(dG@b2_j zf5#Aiq7QBd>8bviTlh@Br2(Gn4yM8v`jQKPm-=+3yH~pBI>2i^oN42Yey$AQUtKTD z^Y5)bsSd<zt-A(rxWX-_c8f?{=vxiuBmVgI z&)H|6bCN)SkRFndgoHqP=!Ascn}8r99YLf@SLB4=A=E_`P&!BzLT>^hh#(?JQ4mE? zET||bBHwjQ@c!=i`{R9{FF%-T*6dYg&CHs;&#uoIfOYnAT5`SplkasDH`u+?QQT-3 zZ;sL?dxH(wZ2$2*gzwtk5r8dr)nyQFwX1FiY_s3wGTLsxp9k1skLQ})X)k;Tc+Vb5 zop#x+Istauc_kq%w99aRyT@L{B(T?x<9gj^@2thJ+Hbe-hpGqcgN*Tm_JG=eL-x#y z5FWNS76Ojgow(;XYCqx(-?#e=1RS^H{sNq^8&<%!lXh!1|G?gv3pi!J%UtlGUG@#Y zY1_Xc;Eeq(k3v7Pzhz1|Yv=T1cK_J!!ei-k_NP1+IBzdw`%i2K^Wz0OCKd3h{gkWt zqP;m0@R@z+Cg75NWf$PGU61bl+`iNwaK+C41aQ@k<8Jqw{d6Yax?Q^pgkRYHw*X(- z3GYI9!)}B9p3k~zuch=Wd-czNTlT17*!Z>mLVLhB_67#&ZF?(2{agD2GwB`s@dm(M z`~I(h@9dU5>i*tN+=|jYyE7Nn5BA*^5dLTnptpar(>b%B?cXi{?%O}61Aehf-v#)7 zwX@?<^@06YITU}lzo`oN!>$zq;Y0h$bd(<1!@2zav}=C@_{(0h5!)WypHTR>9d#1$ z#Qu@7`j35tYvZYXs5@Yad(u=0r@5CiqfK|;{s_XE?v&Xm&36CEAKe8$_x$$2x$Z5D zo%!xT%q4HT=W>a@<9>MtV72=kr?$o&{uHp*y(SB=&b^67T<^|hAZ~E?N$Wd?)Pbnt?nE;dz(85yH;Fp_O)fFJKPD_YVC9{;t91~?ic+5 zyWPtVLRjeT#Wk|WeK-%W*FEF|z&>{n^WuK@ST2AA?v2c=2i?C+1{`u97>_E4-DVTO z5%;-bfTL~)SJN@~?TRS9@2*5=A9qjpeF{9`KCl3A(!Dkmb^dlYc9 zJu!^cC7$g}OiMji3VkRp^ZdmFljR=QCP?4%%o+n&=@~(ftnv&S33%IcXEB7UJ$qsS zYdkgR`?a1{4Ec4QD+Pe{9w$Az!4u4Q+~}#m;Wv4XbcS%VC%qfsT~8YW!Y!WLjPb3W zr)|0Zwt2qVg5q}1Z8~VD=S%K6-t+8w2f|&R{EaB>_GJ2@ROoT6LTQg@Vlqm5J!6=U z_j$@j0`_~J42JN4XE(#^py%}nz#&gAL+7xkJeSxJ&!2w-j(WbNwU2oU@f*o!z3=H- z4ponPhRg??@TgXRlb%+L=MOyB7oqAY&w-BtA9@}$vz_*g;fguqxzrT!k!Kd;@vNuh z7l4mFIrjnQJa4{t7bR&!N+>RC(eFM4M4z|HrW$5;ux+U|;-2To z32ghpvtT9QN6%3@?#KMg@?xpx@% zhHrW8aa?~ZymkDsai!O@3#C=wol$^|-pV~8-0YQaguLr*#I&>3Tc;g_+r42+0f)U? z+W?Mu9}Wc^^}fcOeaxHo6KcNi9lHQ<+&irpgeSbOamRJi+prSg18)=$5l?w@qqzP) z^maJ}>1po(_I<{C(I2Icyd#(?&UzQpl^=WaA^_*SZ__{Ly^onbKJk896T%DL6HQS1 z)O(sideM86dw|cpxm+BVyvg*|WpATlfX}@dDcE+!Tlf~>s`saM-2Ywk9;Gp^d#hJQ zoiDskd2IQmcSBde4eycCfScah%&1>^8~z5k-*Yk@y`9ZXa|dsm$Y-1q*| z5%7z5?KV{X)!T?#{N`Q4obbT=N_oKV-aoSde|W#=j^v^DVo5Z314>W4hYzCkkJmpPrKdjc2L3R}_gnHjq+|VZxHlc=x2g(+3+?iw%m!G^zv(vS8R+mBjxD%(@~Du zdCV|eWiPwICw{yTG%bv&CEYh?34TE@ZL^-Vu*& zA;tNtr+R2~4M14CWuW0JhG9cg3xurbUUDXPI>D_2v90niCBfGV=^13p?yrUmYmyFw!h|#nGTuJ3UyLrCklO(%UsFU+B4I4(UDb>V?3z5;aBlL=GwWx^4icnfe|kGSO+p-$j zgsyrkp^tt_$k#1@02JsIgq8YdLZHt55zt7_CIspmgnXU$6JVwG5$@`91h34?U;`+)Vj3*o-rN(j_X33uqYnb1n-{tAfEvk5Ep4Z=2^_L~TO z1k8`HNJl>a?9l@Wr}W_mjtc6gzW2ZphZzm?_$nYn@nc4BS&4< zjsA2*R`~?2jS_p1a#V?9$cXs*LeA^ZH2w=TblG4r-HOoBE^vT^XHZ@Hs$Tl1BPoiT z?MNFUs}V?`%ECr>{9y1UuIihAIx72qtY8?P(DiI(;L8e&@tei*c1Os<=0WB-fl<7l zBU{3(&VBHe6lxdw)5~`>MfIel=-T!`_+=KKB|L zIqkqD;Op!|Rd*;qx8PTw{rcMlbs=vGZSg7B=X-*0NqLan8|L?Wj(lmG*B|`aAr$bv zUcNuquftZzYuYnXz`t|{{pT3|&ToO1?)2DEx@I6%?EE|gu2hWc@7J}K6Z(j5-HUWn z(Wugk{X6X)?57WT%U-76ee8%*%k-JYj`)hlTcULwri7^SPuR>(TrWdZuBek1|M?S4JMSKSXj&wdS-52$txd_DUV zLN1_&Z5u`-d%#5SIdR~d*^kSBua)gXp_M%!F&B_a9oyR5;=$K`3Gxp11{gG;4xb+C zWJj(BUw0GuuJ#}AfUn1A9edj5eDL+Jf$wAU1wsK0eh1&rUe_IbL$BK~2H78AX#_MX z4}Pef2X_WEIe@W78Ua)Ei6@RdDx+}BKaPqjWe>MC{m5w;#SioV+dK_TipMlEjAG$* zVQ~+XC>HS*!XjdA;pL}}S5$O3`gQ~bIy@yTZ|{}h{gvhFgu`-&yQCF-P^p+ zOlMtnMb|f-$p@N(0TCFCmMm8NyHayX-XLttdQX{{z{%@U;PP!jL1 z6ZxJz@*j*R4UHvTjx`1evWI0%izgim7vqDxjY+q?LrOQ{#cce!YE;M4#B2AkqAY`- zc)&Z~%8}NQQEK{R!-hnPCQT!Cbs!x9GvoDo()AmnRy!{xZ*(Lb+k;e|?s@i|;vcZ9 zz=uYqpMk~5ubn{JS5*IW6#0b+Ow0H~+Mbl&7W?@qDnv@aYaX$qz+2r$l3ta055WS% zcS}XB_unCZ4Cb?pM?* z<#Y}5dvZumh!Ss!qQAXO$?q?awin0!S)aTIyFR?MR7RQRM}BPpsPEY~OE1cdOQdr{ zeewErF=MXG@~G(BFP>Y^g^?OTq`wOtHIe+J)}+^pB+~YZ*leY^vT+w~9bTREa!b;b zCZxWWWeHov_Z`H%E(ysAag@7bNY^6kSw=rBBCHWn@wm+OD>3qrS(FF9Oezln7(Y)X z|BF~9RFodvn36Ld(kTU`otBcu_`(T)$m}N-EwB_yCW%ubCX;U_<}zfkEaC6pdr9TqZVN&F_2qQ#6a zIw*IDRgQ=;r%9czGJ_Lhr|zQGn(C~%xF_jKnbLky{r)scmWVC4h>9D=)8CyG8ANl7*%&u6$L6$Fdf{W^2QA7bPnp-(1J zGDc!Pb|(2_LrI^@CEX-#Ps@-yrB0%RXPS6DtPATLXiAzR4vmo2v}qJ2JbL6yMa7pZ z#mChpe5%O2PfFJf#9Fo$J+=Xn79>}8S_WZn+x;j3ko zfBg>W0&#IenO;eGlY+59hWtyG$~XrrEs}71C_d{Z1HULndsQ0mkxoy%$eI> z?&eeSUU|~Jk`Eq=WLh32ZBj`miV_*(nib__HW&pPmdT8F$kM7T!T3Pj(QX#EK9Xp^ zDsx&O(XdlD_d26|4W#OF@k($ctA@-Wz1fH~Rn~N&*!_AICB-L_MvAGgh>mi9zHwes zX|iZ~CXsd0JCN3&Pg<@Aj#rHjr2a2b^DKPqGQRf7z%QT@UV%A)RkurUw_Zu!g~Z}A zTE9*H3yJVil4@>>_1E{Ne4?mQN`mXgQc4cVz(>cDPc7u-W=k;Mk~Qj& zDZ!S3q@@PILr!o`7nOCr%n8}|=n|j16~VI}=|HN){#F|0q<7&dynFK;7vfm;Z3C1h zswcGWB-Iz5c1>2_tVU^y+EWIlrRo%SYs-qh75uA8qOl&S`m{v889Nd%(OmNipupV9 z0q2|hh5(l6m;If^eXHg^8@>3;oPPMs*Fj_Vb2@1aIA~7s6wo#UIJN%S43in^Ia*<@ z8bTu-P!SBpkCl1>+B{I-pmUjy_t7HA1Dl{*SMp+X<*JYcSGg)?Ansf#Z^Auhs;}r9 z(#e>RD}5wAmhnBc%UstOH0zTopxNsf_|HBeJ+&_QDs@+a=Dos*Xjtnl(3UL&Ks&y| z#n&r{?inBti4W_<03OqW6Q8JBGP@M0N$h*R`WdUrhbK1p4QV`TaU=+^Q@z$7s_ast z@NOj<7b;PCj}o2#^Tti8i#Kjk_o4~+fUm65BjG_C__(gnzj961~kq zQ7T>i&W>59CWb?E)H0t z4y^#Zt@fILcT_9dW3`$)9gFR7on^Z8b-pJg<~nO*g3Clv3h2eScxsM1^o57lRK_En{i zKxvYBwliR|xi20t#XLnJ-qOcI3T+b&cZAvc3jPhI`DjT$U%zkEq25W_^0& zoOzwiFPn4T0DNIKpj*B)KQ0frW&X<2x8|z|PTZ`%k`4Ya54Qm1I|eX&O?1S;`nb*8 zT@NtR(Wn5h$l)#lSnTM>U|;QMBkz1$V~+6y(T@{s z$Lew(84)3RHKFF-P@}2Fz6f{Q>jTA4>oW)Ly#7w^Z#92X0WS+52u4 z`2r>;v-L6(LnkZHsDQeliF=@A(YD9*VRSL5RaDMn5CrXWgO=t;OReCaV0|lO1?>~+ zp|8RUXqoV1bwDEmtAj?C7|#V2Jt_u;n30@g+09V6sLQfko#ESBfyUQhl1$iM6|`JA z?t2o?W8oFmJ2eUAkU$J1UGA>aTP{)oluJ7o>bqL z1$>|;V5)fT>u(zFLv=#~POBGK^MdLhh~a-yt=Y?T^8$lqhFNJ2V5Yh66~HWWZz^E6 zIVm4dVD4qa%rWFF_EJvDeCcFVyU^b9L>P^N&| zL=PTeR5YxZ@$FHFt@*D#s`Mzz;tOF2vXtbr($`2`~Bx8xVY zS@ETR-CMGNsU+h06xQm`z=@qkhnKw<3mP|@etY&2?ucUGlOIs83ZF8^Rb00cG=0#E zpxIM6@v65MgI4=30;7aFPx19*2r89TC-X$(3~lZ>*h)Rplvef zgtn{b<@SYiT8I8L=LgcuTf(e zGgi&d7od={n+dY^f+e7JPR{_X8$e6ed!F%Ie<|xUI6eWip^Fo1w74#4i)mt|0;=Dt z1yyc6qygyja_?Y=GR);Kje-VN*Y31Rx6F9Z?!i+)d)34SpXe6(2KTqo>w`hlx8tDj z-%opY!2-43IGzr=Le-^)Thx~w0SDAhn*Jj-yguMdHLV!nCzS;M7R}a6Yo#@L4z%-W z2G5AV<)CA>at-CHmzX2QtJ=OMz{%<}+G>W{(Hk&VJz5D^tPWQOtW>XYjlZLwQ2!08 zB)zj)eLfzrLp|bTcd0+w>3)^k6mUpAt_e7D2i)wN*;F{V@=YOd# z%SU0pQTJ%YJF3N7fFD)OVSxLpaU|dmmC0cJQ`MXac&f(fLm|%KL{$-`wqxG@ceefL zjL-w6|1B?Lv{i^Jd>rCDUT)rR&1)9kt>s)1v$OJ`cvbjrS7)yPUA4J2N^frCYPxfo zZ>X!V&oJlyzq4-ng88K$O|`|ckWHc#kwBKiZeHTq+69z!TK#_1*!^qtHSe)nK4D5B)?g>)Wox} zDpAjNT2fRMs?ekb1X)ED z{7jo~Gco+nREIDnnrs(j{D0q-w8IT~-^FtH-%;{rVsq zc76*LTzv4w-|jlrgrvQ`h;M$Wz50>MYOhM@R<;!qwh+C!Gvgh+^f3m>z@1eIyubaL z&bO^sqx&Ne@hQAI&^+v+8v`2-6TN%lJE4~AXYF-cdFp4~)NMT%umL+b|3uoxY5VJq zZYvvl-EdnW0acNM0+PHk$Rmx%+2T|`o#?UBavCD#2V~r^3|uOaOB|W^!B@2B=0KiB zdAhx+IrwbKv+ZwSsDMf(Tm~+cjMnqeMc6)ep0g36W_Io3;A`=UNh|xZzJ`Iq7Q*%c zbu(>V;}}oAUL){5?LTyg*NO`mhS>x(;zy*1+O-NBdhxt;$Wa(AplKVYVTANe1KWHz zHb=D6t^BRI4bq{FN~NpJIYW$y2~bECxfv73A~e*p)i6}#UhI!mc^V$yn~RiIQjM*m zKGI16R#}yGCla%T+rr!YHCf0Q8o0#?MQs_K!pEJb>p*~~Z|N16ju;uIIAhZEn-$i`p#>k?M^ zQcr5L(7rtBnM_iLjxK4HkM_VIIK9OEx6w@c&VlD}dQisPuX~rYq8iWQ{?7=O)-9w# zaZ#*EBg#u44lSdV41I=~(&#HH)on$-xgTi<=2|0ApT(GAzcM!)Ph~!hk=ih4QLnBp zUdoE{eS!s#ua-&c_rwh8Sk1T=Ak(@G>srQo87DH8{0H#*zu$mLlRCI#1(F-0QNIAG zBL*8APChT1wCFVa{8;j5#Z-&9moi?Cmw{W0M=A>4BXpZ6@oESw{i@HEvO->LEi>OD zz20$h!z!!?{FBjEmmyz2lyr(%WLa7A<7G~pMY{}f;ag&(RvvCm^^%^@wS%mNYM7pi z>+QbpWwxo(>y8X=w?xUSVz%p|ScvqrO2U9wbMeWw`lP*@k^U?roD_}vh~fW|*^ZDt zd*`vv2AM%C8LL3}nKIT9U8S@YQcBK|7&m1KE92SVPu;DwRikB$_-nfOB0$=;mXW_s zV5M2oUls22j2h{r1Gxt`?#P%`#e$0^Eg|Uvj6W`Wt5FoNo9>vJU5#egW@E03lW8Lv*+}LaI1XnTJ+OIvj;PHfoZVQ`Q~99hT!cP z^6`<4=1VmAKC>D+l|hQnVLXRF$GC~ztbYo(vV7A~z)98b&`|1l2Qh8~hoPn`c_zZi zRpA`W<*LXR&$&|iU`qdf#b`A=>`L!JqhTvpb z)tGo1j>AscYT3kMsB~Rl-jLC zt3oAe?NOrFe@>iIC!9E?f<==GWvVKDmu3y?K~qIs3I>fGOm8K8r}HAMsI-gB3poZO zEcZ5DT2C`!H-1V>w@_TLZC3wl%aHPVMkJ2t4(gkcR**Wae@Cg^(>zrAR@G;4-%&%k zaPF$xEd8NcaApscmy>y`A3paocDYP~!Pha!jc z5kepRb(B@VS~cpo$Z?Nxw%AdTK3nbZar8BKivVD|qkj}&hoff>;Hcvf&3?==KzA!+ zMYQP+Q(B2UD=YRXd717Aaj*rJ7HIT&4v?~zp_00mhRHg^<(~Jj7HI8RoKhVJ9a?t* zX}v@GTp26Gm&pbls}~Gzva^D?_tCY%1Z(rx|uac zkK_PTRa`D$wwg@a7pQM&$vNr}6vl72-x%}r)Kf0n1uB?kTB@e`1Db76Z?N~>s$ufK za|_CYAVgt4GS{fy0A#aN zMH+mz+FcA#puVOebJRV=FHWiTp~?2EuB>@L@rEOuQX5R`98$FyJ%`onEFDo9ZopCX zfJ^6?T2Kz~zS>W79al>^)e}li2cA^l>DDn;kZ(72KCP~C+XZzBO5hw?Teh2S?r#Q| zVOB(B;vCvYsx-@-#Dz8645N_?%u2NH9P>ktFxPy$6C3ei#T$b$utS?ta;|8`&oq#Vyz~X=RLP5 ztMF!DJHq@Qf1AGB(Ta=Ir#HC*3vUg_lTZJv-=?{$aO7cETUGeRSPQSJxUTIrR!jAb zZcq3@uOmFr4*}-i`MS|sBm$?_Ya#X5cL+hc$~r)#p1jT)p)TsDMWvSOAzY?c5GLrK z36VN?1E8LsO}MUa5NhhQjexe=N4T!f5u7@D6QH6VNNB4M6ME|6n*lR)7ecn)O6aMd z5+>-D?*iuQ6#(<^rTYH6P&8ZTZh;g7Zm}w;!+QS~{I2^{-`HX$qEmY-V1iBqm@|gy zZ3;hPj%Xi>uJq9c4grhqS#=hk+iJCO`{jgt*F0GBFAJZ+!z}X80oqsirUuZa`e!8+=QS8f3rJ7W{MMOWP%;f^T;obwcf4 zI&q(sRr3JH>5Qk94A<_rF_`K)9lhEzSofmATE?JCFZSTH(^`V>L*BCA)C>1n^?W-= zVi<3NzXQ#(R$`*%ikh(t@3Y_dw@QLfqTFr&gI$ETJb8b+3zDignS7w(_yPL|Z-w_U zyv5EOYhXpcdEDsr_gm1G{eKn<(ZZvsV%Q_bf!75{42H8;O9+-ZhOE=4dV@r ze#dXJlUK19^b7Pmw*=_FM=w2KRS)Pg4YJQfb30StI$$OH_kpGTZf-;+M}iJLXtk^m z)EWH-S3#_);J?-*@Pc_Sts}U>1n6uyUhf7`t$N7(t`&OjL90s6M@t}SXuIgd>zJ!4 z4h<5=nJvzvw@|w;g4Jx3jaD`7_Yg~FNAh`go^~C=DPDUFL|tBIr`yZp{D|4DF}kzw zuY|Y1)@)Os2R z=up&p+G_B93`e~IXg}>R+aFNo^d@XCDop<`6{i1}3e(w1GrJ}Nzo>dA!`%|1j%exO z3bhSKrzzOjczPg2p-*1m-LdA(we0z|h1f9rJybWsVmE-FON9@ZVNX_~uz-C`u);v%jEO@ba_(x!IrcqxwVkP;wxp?H;5aG?fIOWs~ zX)rL3aqsmHOsL>N&83)0;Ip;+#xn5F)@~In!@wj~aT{(fy&7P}rkG|otl7Zw|FB<* zy)#P0pYozJuB#FWoW7{z!wsdEA$QtePQr#HPTXyOxE_4+UC90Iv#r2aARlPI*9d$? z)(Ntc-vXaPKGd#;{Yn||>6FLY{)541P@ZJRt^=RRKHFEc zD^^1xiyPAIY8*J58?x>Do4{A{;HapoU2Gfp%HiN^+WUHguUZ{^p8ZQ(@YOnkuV;@& z!YNV12fmRVrduAv0o@GU`tpY#PZc_N^F}%GI4~85*Zk0|s0AG|WdkUM1J3j_3 zQ@0Kb|Kx4MD8!*)Cb?mZls%?vg(?BTIe~atb~Zydtp`RtzK-SJQP~VmPWB1MxoH!9ECQ`Vk}&AV!v(d zAN1u&vqF$j)96r^77ZG0(u$2#*`GMjhYqisWj{dD37TZ4V>UO< zvTy1&A6g5uQ;^$&qE!eC9+!b&@(+qry-*`ooRc8D5u4fpwaO{Z-5J|P4?Jy!B|RRE zunfvoYgxO`P*lhh-iYlDNl0 z+A4PR1QfcNgVDA_tZx60)42tceo1L-3>O9{PvX{-vr3_x+*zw)^y9YZr-drOFy@>N$wxP#*h-DTZy;QFNM5A}pT#wR*Y&cqR#>!b z40*P(ZTWTZr6WX*l)9~wZ|RF?t=bV=r$cIrN6@Fy8UNL??!ksp{-I9)7)ShFb^gaz zD8^s>v6U3w9LdIUf#dOy7FWvxLJTAIzP|Rc6_LizEjljp=+c}sB3(52tVp{->7x5( z?y)QfTN@dxb;3ETocXw|Zhp=RudoV-AC6rN4s%YQ^jq^$+RZCs?5gj(C>7>fEDcKU zr{|utx>e-CmSZ&!w#+$3x-?%~)O=_JF@L{yh`g*xNcPJ$mM#XTk{We*vdMdHmxjHx=&suLkc;fiU*})8IAT^@0^s zY;Qi+Y4~Xy)vL{Ks%Krmt};unyA$a7UAx^w4v05cMNyNZr?I0dr1qPBVDEsUd087e$`kwmMj#j*fO>v zDOyG*a-L<}!#)5HM+_nT73mL8B)|f=+}DeAB?1FypGCP7Z;*c|{X7&ETTP~9$wbnj zZ<2nG<1<_yoIv`rvQkWU%4ykpF5V>E~NX z2O#iqnNJ4TE%rFnf|5TFB9^gvH0e_8Ff8LUQENz3^6#%A{UQN-XFvtgVbe&b3Oy#K zOQ}l9CmE#g^&o93vpgyTZ$kpdWscWKdwWTHBFOMifv9-#ZSozQq$Q+gX^Z@Ak(8Dm zrbO~i7~?on6uPcOdaDuX=UAwC>Z%!O7X%8fsic#(Pa+-Piu7qc(xnYZzZM6Tt4uy( zGpWDW%#B?FZly=0TZWBggh#T*l3HT*8;FTS+}}NiqVHwKFUyQm#Ov$Cj4`p?+Dt#W zZbjAOB2TbX_9zhsKo55q*QZlJD|7=|Iu<+iv8acF~=`up)i(xg;Yz znX(^b&>^CIYYB@nVgO%fQta{6kn~04iGs(;S?8YToK9M6S z8C8?C2C^8g)AlEodw`9iOKrUZD5)sDoh(iM1&M*~a;u`zrYA*-GW`3ph6jqVof1Gt z>u~E&y-Dj!m|hdze-cYf5gXhS>z|U4t>s|NMzTERYK?JR!ul)@N^qfDqQyuhKP^qd z?h_n!VpYp9mt^yO2`~OYK}L`Pb~YvdIg%SLD@u^H3?&~>o3x?C`!ZR!pNst(%Q|>Z zCicBZJ}$|cEyanki^<=^RDH-}GLQMIDf(g)>62j6?J~+lMM~q}rPF)j=@qTm_-mQd3DH_!y=oljK>1f9xzw2a zgG!_s@uY>a7M=_uZ!6MJv1N%@gs(taIg<4795KjL8Mx@NsGSnScf}Ix%d%3PWg`3F$=`%4M9E1{WJp;)eiq86U~OzfC1?zef35SrH32kpB)fUB+|?Y9e zI9vhee4B=It>ldCfpmuZP7J7LCDOmth<(f~n)D)q6<3Ilcu^Ru_BKapqI!<{Pf|M( z&bUBqarsYC$D>hNss`7m{g9O*A|1Z_|4-)Z?CjwaQn5 z_Bx=>OaXkXaymh=2XfE2%*^W#y{*8b2@ogWMqjQ9!;vXm6-yxmT`8YT#vx~F(PKQd zw?LA9h_1^xN5f|>Y6+Uve;R1^7VeBIt$Pl%vegu{N>xTnp3leNXqd4MwB=bwcSm`Q zrB{1;YCxy;pu?0mke3@hW_)N^wH8`aMU6I_js8Vpr-DbaVg z5`_zuXuL;>%Ky0B?hB65y1>~iAjenv4+C-HH%~ykS^rG9i%DIp>cw055Ki^RqoZ@PAj#+Ap8pr6^s`{4%Y*TA# z%RS0|5wKSc=N$H_{x1NItE&?LC)D~3z)AJ>^MH%0a&^FG>T@b}spv6}Z`J6zDBV%5 zx&ZFtw^`M1ag}rS>nKe!+jIj=HdC2SrdF9opMyhU{j&DpB}d(1gC0VmBFROthAG?U#q^9ob$Wz#AR_`+1Q`j_U9zKXzG z=1CU6HK!r?@SM)KZ1IPAgH`h#l{x?>I<~{!cuuD@V{E2l6BqX)$1d)t7CX+;BC8#( zso@$&#jb$uju+|!b~sXK(4&q)?E08vBodmqEqq9O2;zOOu=j+SwLr@yu(!nPSi@4K zWE<)cGOZqH7#0VvmF}XiQbw^}>V>hOSzmDid52bm)}B5ew9ZAkweI^2^LpbLG4&^) zN2|dnw0jf2mBDJGtAch|na?!w!dxz@PCaITc3IUHv}bT1(7yTX;?)IobN}^qK?jB9 zf)3rnnxijI2A!(L)d0*^wJQS(R82a3j#^9~%~h}E0p_V~?*JC4my-cYRlNwn1~vRG zz;5O1fW%NV+i#~p5^@i7kaARaMsDnp9MH0Sm5CK6w{d3|N8*zjiM;>cO7a^DnmoS^ z=u~x&sc4#VP@U;2yeD9W3a1rjs@1GAOT9}A%vKK>4+TE8WB_oE`WsWm_57>!>weWB z5^zAtJ(ma7&&()?lrs!)SS?`UJ))k{2}e~ej($v4X57E8?$9U4)p(lvg!+IpIH{I! z{vW8%%K%QPwhYw|)yWlr)5_N+7ZpRt z`@3n70`n%_GRKT$bj>vn)dI{jyTt?Mo7Y%#f!S>^V4+z+MYVZv$XP5wk~>9|J+;Q?8COZP;tH zo9i{EE^QxMfN4s-k|kb8Ibz6~f6H5F@rZ(S&@y*u%h(Q$scG52VnE~i&=K)3Z3ZoW zj5N79*G7fjjIfG@>@0m^XVC0pA)r+|y$xEe6g#SZn69nSZ8d1kp&THm49#5Y8`i1U zWE*IcBQrr;?4qMu{k{aW{fn&`|1Xt{L!q;W!*scl1ln~pmq)i!6F_^c<6u2Y(%i4! zW_}s;Tp;Mkt#sU|crNnSx6{&7R1?PI3^j8YV5WLP^Q}=coPclDM$E3rd~%CV443u^d!Izb*4FBm#W(ruwP+pu7oc+>*MNVO~40o%N3r4n5a>@s7j>*uBmag0bi;y z;{e|%xjF5Q>d3wEk7^79=)Ove;$hk!YEM@b|5O9~0Z-MJtpVfA5I+n>)0KQD88m1? zH_*~a%%Z^~+Jc5;GXaJAM}vl~tq2;v8BuIStYX@V^fKzB50?dvc{d2OYy%8a)MH#C z%Av#aL48pxngA005r{<_k5C+48be4qtSdVT&wLRyVoeHY zvQfdSDLq^3S=qgsb}v046g2dkJkX>ubXaEO4A9CywqyKP^KidhvmPTNw=RRLP6>Lg zeqKCiqw@^UrhH?M)&5Y&XB}Tt8SsefD^-i(d0V~D#t&5I-hfBSAIS`+9Ljl4G*3b( z+J&^|s1?Z8sd zyn8)BYY$!kT4x{ETU~isPW|SbVuSBXf;Lp_q45wWXtTC4puPT@3+j`XABIzdD2Q$uo((?K`@`9Ka6s zkQUx!#!ms@Yhj%L`^@fJ0sGBm%K!(=fvW%q%};6hLuO}M;I#Pz!|#l_Rp;Yd(w)Zj zLTR7%@@&8Yh9#GKelQytj}BjR0DisJx9k} zuqrdLerml*uV1t>^nHxr>q;|!ZZ%p1xMEddHo0o?-Y|Tg;Zhplx|Pa>|An=>KHy7h zK^MRctM+KXO-sKC_{xgrY;RdJxTe0ga>fF_vBtjvxNTKv3i#IA%22su-DZxvXT=Nw z{D$jqUf^S^<9xt$S5pSwEEnGmhEEbW9M6oMHliE^>FwzCjCf}9>{SfKDvQg4R_*u> zX!Stmx*GGicxt|t0GhLWA!uHcQlPbu6bG&2?FicJcdFO&RmNjG-wf*0sa|u?moCzx zuTBf9S3WS?veUmzxl1+Q z@ydFX#yTnv2H@joTr*Q0e={o;I6lq=EOZp3i8ngBFdEJ{`X>QCa_sKj4fv@;UNv#i zF}wsymmRaV0={yXQGi>H1g^9n9A)PL#yP*Bxh6R8GHFe6de;CZI|p-4Q=J1Q0~R)-g#Aj^(*4sxg4e4&P&WiSDY)W1HN$9UI+NfndJ|-?VQ#d@SXE1*T;{} zFKF~%oE5nb{M~tTGhmW6pMIHay*?AL*jh^WEVnY5gI8KhxV+xBk{SZmT2c9c_0}5! zfX&v&KCXa=y(0B7jDHjBawuk~>`UH{|#n_mua{ZLb%A8wT_yt>Ji zTk`+M{hNQaR~Ph<5IfFHcr4Er7H$c#lT6ny*|@6h(AUH4EO&EQ5VtD+s6)bSybM^^ z3b&)wTHPt!E~|EHU$`9-_OL!ol!-Ue;;xC;Qov`G0q<{*)LX;t{?VSAFk#>iwQ(UV zaI2d(ah#>i<9UZ+iG8|8gq>&Zt2Qsg6|QxJ9f~Vk+al}%zF27C=#Jt2YD#lNH40e4*v7YDymT0^ecB96@uSDH2S6VAbS^s z_+_(Sqr?r&!}Lqw%O*qCn0k4n9T~O2-JU{BfO-4jk2>7*n7aUJCCNK zbwIfr7JEO0H6M`l3zTx>j*+Hi(8(q}u#BCSQz8pno;_H&ry2NX4;F^9#j^(sf1&)@ zgN5lZ*1r!HeyXpbi?BT8+kYP{yjBeSvj+=T>9}Y+uJJ9lc=ll7Ir7gQENqWV8Bo8w z%{zmR!0Z7HMuYEXcTEM~a1QuEb{_2T?^A~-3TH>#zbX~3$Hm&I>iNR$vG!FJyrdGm zno!K)DQ`D|+VfFT@C5YbW!(j2ObzB^mj$baV=<4wp+1Be+B=b#g^g zL3(fnP+qehX@zjof4ECFIwDeWl`fWayVx!#nEY??GW}n8#AAFUv_lm6*Rim0YBz+m zmflv*4tepi*rJ26YYk0PPlKPo#v}6vwcT;U68?A^4<)itBk)^6gwe36`hZdb+FD)GUr3mcB+i< zvS?IB48KBV`-AlPBX_XIXqmw>v1t$C2gz8ybZC+tQtF>Nth7z0Fd?4&`?^k&U8Cjq zGPhA!HI{KxMm{Mc%Mp`tNBa9Pf?Lb*(8usdEc6$bACeg~6x~OOXCw4SNp|@c`-^!> ziju=6QvZ@JcFD4MQ-C`P(#Tbh!6iKJ;F86-KwB?EVsVfKlo?(=Bc zfB>|O?pgtnHBn~%TXBjS%4A)7S_Qj&z!fn@CuuiOAE|&H^;i1K3U->Bq>ELwqY|Pe z4wj&e%UCN(;$`vuyUp3xTC7_ao@#DY(T=MUFN4I&v_FwR=p%Z5EzOEv0(o0>p5$S( z?U;)Te%e^kF7In8RriIlS9cm|Q%Q#MJ`SU^Y+WKjA1GaSlUXF&ta%C=$pM)2+XR$d zp)`j5EobX)O6u8#SxAl8OvY?dIOmhEZZ|?C9qnAli-F2%0y+ldyk(YuwQ z8u${bxRUwiSyzR6Fr2I6fFRJ6Ow8rqYcTgQ4_A5$?VYigBWA9P1I>Cj4>UWUv#c}# z-CC7*#DG>=L7(JZVJ>Yb&s?^QvcPw&mWsy@tX{b^=zvwQy*13xi&E{_J`3owjcOic zJ5^aY3Kv>LsohGnDpaD@9wmDH=Rym0!gUrZSTw22Ob(?JIkm7bCXk3Xm{?*nnNku4 z>ew_pD(xMnf}B>xKyw>#rPQm<1>5*EP26HBJ=4a5XQa!JNxFZU-3G@3N7L}R>Q?#^ zO6?}*p%PwYL%r{)K3pqzRY%6fAL=e=@lYM(VtS-PxXdP*^HTtm&6HArDdtuR7n*aN z0Bsh~I*ZIGJtiGTrcd-LLa08TZrAs1VV{c}?=Zj?J6`3)Ry!j@?Ws#~f8*8PUIFHoXzDAQBW&4H})nIj20&ut*(7TV!=F4Vw36EzsHyj##HF zTh;x_MW{DL&&sevd{3ALI^1Qu7b+!ycKW9_XqOZ&wVth+^85Cob6*`!UHV_)9%N8d z66nxO?o&qp!_+cWZQww&RcqS2Kz&Z@%~5?A(sR{82KYSHp($X2`i>S_s^a|t$SB@bR6QQy&_N7W%Ns$=T4a)9^MG&CC;e%|mQnV3wr8=a`Fh ziEKNl!Z_Myf%!Zwu+U7Q0kv6+{#j%;Ndqi4pQJ$fwPq9DD%&m}^(verMu@mde@EU4 z2Q71oeMfiD3$yK%knZfPOfCcbzaHS*S9mqs-d^ed-}8HC9J=oU=itJ-opIZ+9<7}r xh54`9WrOwT#*UJOJEqtRt^d`p!ZnVt{n}VP@`RAi}3mX|D*oUEz+(1|NGC* zmlpYd{IN!7v6z3(0{`zn>vsIDD0#zN6MRG#(SJh&HAIN-DSfp#BXXR@qA1o)DVww` zp&fczESe_Ub?#wNG;5B=7K=J46eMGe1$0}=S1nvDNePzz0n<}p8S5b|7Q>pY3HZ1W z@OEpFluELy_>eMN23gfXc*^Tt%3j##?F&miU^0xX-BpW451aS=TN+p_ZULbR zCbt7^?pFq&PsPwWbb}^8R%VMB292)RvJQoj^$Ys3Wv>g?VttWvSNF+pYGQtC8qY;* z9C=~!Rcu)ffb)y(2W9RSWHWRJo0lC~(hp9FvStrx058~*CO~1a=8Xqmqz%@lSqGhoG(%?BUvhi4P5O%{Vs$O=BmdL?DFTZFihvf9mGJWM&{7Evy8AzDi$SuK{P)}IT& zm#hxHrPX^f_);Cgx3&5g17CVL_>R{5Ex?zV0lusCIby-1>^AT{tXDV0x_=T0C*UEE z3UxJ$C0({wU@PrGtJ)Y_o-TzB(Cz7_q%+{YA5^8<5EvG#meRzYF@1?P&`i4vdr6D* z7gI*shj`F;=~m8wnZ>#!C8J0CfH6&>IWQe2GQbU6=9TVrS)iXYWrjxqkDnvadXYnU zSudvC^C&9PZ-_{DUSzA<5)%pXkluwFfbr2}L~0K(nbWIo-qOAAT<~^9>XlPMyoQN< zDGR-N`<|(bT~fn>rT5po<`o+9RAa z8XlCE;_#ic__l~9}J7Pjw z+I1xLMh!qe<|v--NSk?0wP9Q-t-~87);t6 z`y?%0%%_Uj$bUe@OUq*?mM<+fv$>_YjA5zNXk$o~Or)2v-_laPCutT0nzXFWNIK3O z;J&%+%w?%rWKQmEz?F>M9oEW zif_l0H}YHD0WZygBU5f?@OPFoheWJoQb4s%ps4N)A})=8k@N(WzB6$DossE z(`WJd$;X&ZK4u0(MKcVlo1;`Pm*+BrA)V>7R_2nrwB=K4Q+oRNXTEQ4;?nBWEb=2Q zY=%<@b1QS0yVNsfolmf}7Y+z%S)OvyC*IlD9A&=g^{wVobC{uZ-JE$tGYE5)r~O!D zlC&&D{zyyf8KnIKNPCzwyw-^P^4z5JO*ai2LH>ssJi6)P2PXfIIaVIi@>N1Z8WluN zN{dHT()Y=v-_1ovR3g6{$tW!a;z=7W_*`4yY6pJ&MlNSf15*A zL)X$GTa#Wfr<-{s`JATHZ<#^0+8q5~Gn)3Bd!EzWq$@>f`5`N5dUL}Ln!U|lK+XM> zHh%tMUy9Su-?_nD#VFHd>CGVjR*yC{s*w7b{7$p=nU$JO=A0wV&3jycnvp2Zu;(`Y8Z|NX=#>1+RKc}Y33sR%uZW7 zsLwQwv@Z%5lA;Oe64QOB%pGoH4sgv}Mz*nR)y*6}WA5{=ltKRfM`k}3 zGvbPwQF+uHtDKockIXH3Yi`vu(;XGeMQ$C)XV<3O^^b7InEi}0XZziZ&Ck(ntz@pE zxmlK;&7|g;>H5FT%@F3CTlO~RVD?!!l6)(b^g;{LrRIqF&6(^mEvL?Y$ zIV)0#=t~-C`c=(N{<@h;*-ed6j2fqz$m7jPG&LQ4KQr}}Eu?Eqx5l+0-#ja6n7Ocq zW{M@5QTfzd(iwAaYbDWUacGJX;Fs^N8RVrhQI&rp>5Ouue}$2b5TuEwr~8*jj5c=~(QHZh2x(eNJI&x+6MtOT4*x@?suhrh8d78O@C~JrEaM{ z-|WE*%TMOBqf8&yZAX2anVx}WL_9IWa*0{zkkBpXFcsaB zhLFG{;4|H#<{~|u;t2G2&KbmKU5TVe&7jI`b~?mdjGx(aRWpQQ=g>x)OARtx-=(J} z7fwHm22M+(OY}Begf*JpHYSIFx_$lokA-8WKjdsXu?PAb z;va0HK0>@rITPsPtkM9ww_+Q&^s{Kou?H&M8ArpES{(orly@9rvNEg(V7gMjAz-L+b4D8vT9R;puh&e8EInf7-f)=X7<=2={7qn9g?tQXYLoX~AD*`MQr`#dF zGmcLQ|N5BLd$9(?n2U9{VV=^fDf-oObVcUqISXKC^jwV)czW*s*bF6#?*n>t>_TW_ zdU1R5Y~nOyo0kWTvoi?uu46FAcjkl>jFO=FYR?5N`Uv~)kY&owhEV0Q9kl);PNh`< z_owqz?5*rMI7JO|wC%|FUM@ycwL!G(g5fp^b55IuIjJ;Z&T5M=r?pj>^V%jjC4INx z{C=-#acT76TW~69Kyz+jrs26k9sOA%Gv`l94hnAj!U?|6nqbf(UK2q}ZixXc7evd- zSu%pwSc(lcd-N~FwFKXxMMQoFX!h^yD?Y9jXpu|Yt#WO>L2Go51RW?M@&N{kpw=nr zg9D46Wz5YNGZnxBk%0?bD83H?tQPIL|7*n6^nkS@T@k<*(VHQ%RTv(CZK6y{hv4ka zx;$_miUXYBBjME;@K|^;2tJD2?DCVS#~}JF2D3^ISH3g>j8J|?07fc-y#c98pF#ka zl9xSCRW6PIELI9|xl5Fz@St3(^vw>~tf)u`nWofZfNW8!r(_7pgm;nXkW$W;9CWJs zg$tghI;R2_syo@$B6Sz%wN9e1e2H?b?307 zdbv?hWy3X$t0o_2fVNC*4cfjqd+6ZL$#u$H4z%mTI-osdGHCx)7RFJc7)Ks2{*3}m z5aT$+M6nJYt|2FhU!5VQ2n#!%BAVC$GsHWrMJ^K?+52V@i&QhC$Gb9PB4bZZDLAasw_PkZ!#@{%YRbXB+#|>KM9}cMoNUAy_MG?Y%s&=cqv)h;r@L8F zhJ$BG?+fN|moLv*}2N0(0!GZ`KeMF?i0&l7y}lH0{mTJ8{|(gAjg zVRHeyM2n1o-C`W2J)%ekz+UmL8(^O(S{1NgY~hX{5c%ljgQ7-Cpd*v>73!)yCWj!Q+)R0|671>)g?aN>_SwlH#PBQj{9Z z-N{ORT24_4(QB#78eTSBN*(qxRmsW&Zkp2E+7tsWRvM>lcVw@iA{I&>VLbf#xj43XyB+T+o;tSqx~ijvS`Ne1FiEfi+UXB7&S_xx$emJNr%+-~R%P z6`$GTA~A}}hhim`@!P4BR49TvR0j>&%0)OL4A6+?r0v^sM>_7}6{2$`+H|#+0_|;M zr-Q^tc*g7|VmGTwWcenbv6(k82D4`8oN|;N1)BQ+HKn6?7pN4S6|{;+f6%|G<^=7T zE#*Z-l=JUK;HL>S3t*m@QWdaJ?4SB)1n=%Rlw`;V`Y`dhH)#Gu?r?#Nqd^N6VEs%Q z(i^nUAx3niwKmWi#puGChZs3^?$hOU*U^#n(s57gJJ7pq&?Eu0p}3baBQjH)3aua% zEQN58NjDjtg}$efpM&g@@kApPB{exE-}465h@IrOiLpfTqsfhKfjpjDdD6trJh z9?&^r1gEoFJWJ`8Ig_&>-2OX^y}8`zjx|6Vui~Ee3Y-NxpjcbbfnuHmFhqRkwPAz^ z>JCU2&D#Mci7#^j(?rR9fVsl60APV=5)D`;D$%NUz$sT>v_6BU~;DkgVqT<$iBv2l6A zH*|Hal^crAS{?7Q50c&+ex9pu4U1{kEHQt+ym^|nXpuiYKDK%5xR%ZHCAQ3)7@Mb6 zi&lABr_DX9IrI(F?)1qjrn)j1qL-NK8be5Qscxc*sOqXg=;~TP$mn`U*yAeU4tVTJ zAq;fgC){zx*#MtiLkI(1=Lt()5q7{CS9ii|*M5Lv`RMZT5S2w+R|^klr@A%}mb%n* zrfCgAZ`T6CQrA1e9ajlYz-w0uK(TyrJ@CZyRb6pjrp*vSRo8jK9altpQ`wzhxb_pg zTp7Fp*<39MiLMQVvMx1)$SHETqBDpHCH}N)ts(tf?K223vBlLdgUBlCx)uP`$EPi> ziBZuw9eKJ3v##H9AlPMqb8X|NCd~o14%wr>VdZ z&XME<5cP%YNTA4G(!KgCnV^CR)`)h?o&yxvi&6ui#kIhFD zVbL*F2ou(4t)9|{Yg6@ zA4K|@Lok1f`t=@KBfCKF{o!wcF#>jhH*UF3W)gYhO;r$oa@Vhc{O-&xQpJTd{qZ8~ zrt(0uo2MV~i+a|l>}HfJAxPxNzoZD3UkAgw2d9I%RoMI+1C8`?_{};aSv)9|$u4;1 zF4E5yz!!G)d6H{dkcfzSi5lmTeK5_8LnVd9BNusLu__)>r@MtZG7D6bjI>ABISQkjgqIM!!+QuzQI7%>(Q2H<3_Oy!7Zzg$9OqGl zYR#yKv)iM1SB@3Xxo0Q*OCeOJ;A?y>2EJBd z@EMJM1MooIR^XG2imsKxB5VBt*cy+&<A@cxGWq zm*scgJ9eNsD|yXGas3k_f-<*3wN95k9+vuFAl78h$Y1i0cRVxye(aWOSBUU0x1^k~ zc;*Pz>5K-b`kpz-!x4k38dxf=@I&ePNSO4SbTZraJVA-M|+$ zoDtyjPXu4m5CO0$xDR|;V>O2?bPIe%!)+t@!mq$rHQbOio<%aX#vE%JRpAlOVi_^h zy2f*8Jd0NZ-_YRSoOqUK4Zf-Io)4Go55A?bfcB+Q!M8P9#9*+}Yr%Ik);@*4%t7#7 z4eJ%~Wgmd=VPtg$hKYlsYTBJJkw-Wq7Ne=cU^v<{${$ZxdI~GGMsH#9N};c*w8pYCyV1z? zEK=llo@$1_Q1i{#9=9PQ-)c1H|2>uih0C`9dCf5JSE0TI$s5K=lm*|U-(B>p34I~* zUPdv@)3-2rA7jgH@I}aHG&;?K5m_~Zn%Pb<{}Bww`vU*dVt2HpLyMcw zcsUN!IVF@Xh&CUGABECpON^rt;@-E6G88R&9Sc!4eaoRG6!p}ht%FoSnS!PyM{$Yn zDk}`sqK@XSYS~1Vro|D$zBSE`syaNzz@V107A3T%qsmyc^j0e2(YoQ>bKm|7_qnVH zZ&d-(KMI4Qq6iPeo!xhkG7p9~l<;?`Fuuc;>R8$xC48;xayF5gcj7H5Lq&eLHewJ` z-R>J9M!>>hhEHabw>Ub?#qe1KU8Fg7x#ndT0oe`}Ljd>|5l3jqk-OeYujfFqd} zi0)b`PcYCx#|XN=wekhRNXOs<5Zagn&2?PEWz@H=*~3Cd|Ep+eX9_DFSw=u;Zweb7 z+oK_LFohkCT`UzHP2qq;af8sw?CpfbXEV0!iI+>yDdId6xK}-u+}IC`<9<6=*_WGUquol^vf8?GfeMZT!@xK#T7R2b4(dk%-yFJ%OH&nqY>e$f-qNj5E= z|67sjjqWD6?72jMGbOh`673(91`?_)S0CL9p7mbPC*zy_P_vfD5SHCcbWj|YUA>^0n&0vznYIy4}g z!ynngE3`8pJDY#M$OPmduNg5e*yc2CjFofHMHG3vu?mM@Ks0$T<3=IyvE+S>fm>h` zM?RwwS`GRH@uN^k2FLL*c2q6E!IeQfQG^pavAk;KMN>AKE{|? z0Y=5i=QYM4jRH!L$4$xAH3s+3;Ak|Lr>dk8i3kX&K)$Te{RvDfX9Zu;*x46+HR`Jx zHTuG)I{BK$`?t{7B45{-)eC%W@(s<)c0fJyO^v#lpl?XNrO~w^_(tU08bf2jH+CdI z=xBH#s{)#^p{w!o4)|8&dl*;Bf^SW}xA6iunt*n3;QJfpTuFIEl(WMiGyq9WvegI-oenefC>AJG{$KJ7p@;g5N;x3cJqzymaL{jpPym64yCc zJwjm;zk^B-6&CS3sAji@HiY4kds;rQ;W!~Jzn_R&iuX{Fne+LrFz*!=@RO1`x@L*m zfvbtgRuGy$PaLQx!Ym^90z~~E&3#;)1b?jiABAgitjH|lTqj~hMvrW3&|He^v=}2@ zZ(>E(oZV3jMcKRm(`odEW>7rj6!~8y{)m}X0uV|LSBW?gmpKs;BX+T^zuETDY{P4z z*u{s6;!n&-*Niw3>}3wOhr=zypM;*SBXOc@AqQ>EOZj7JNB)fwOwkHoB+MxaaSp$j z!L{6yP!A`(n9D9uQ7s8uT|M)PMSgqwzzF9kFY}yV5~3{OjVmS|^YbeK4caZ117@2o z2oo}U?ZaN*qMN9Cu95L#xwB6dbY4Z|heb(quGKhD$&2{WK~y)j2`|uD4Za5BB3%QU zT&hVMXv#yjP$_1X?t_}5_UF>oj_l~YAGiUOEoC~uP%WsISyKWwF=~l~`gkl*oeaCO zMKYwVOAuSE`DV6&QIMzf-qQqDKDvzPbqJcw!Kzz`bRYK$yj_!e)$Cx5Q0dox0L+5I zT-6NC$F;GrC?kftz84mOV!X@0h;T%N+=Zc^U9)luf2bOqUV2xE#DjjBrS}(CgCZhF z+@k?#S3|Q&@5Q(l;Df5{(mT|PoI{b`N@uo)=aAkLKaq>bDZT5uwiFRz&f!Bag1=qU z)XdSpM^UrHNbmhfnHsOp*c$J#5uRNNbGgi0$Qlcu|x6&1dj3ZZbR9{Dsion2Es zeWZ^I>rpcnl=>3a#G)d%aJhCD6=CU{Hsr{AL}AQ4posK#bG{_z-!y)T zk}_=OI!^qTC?&&$t5h)&F1EYc787CNT@YHTZ${}oW-u%?wPq&it)79-Ctg#117(Kn zuI0t>b4=v~-JX&6>qnZ1D+azP z=}4L#Kfd4twoBBf;h2z?cVFjj3;r*F|aRJcfJ-ele1k zmbk>AA9ImLFKUWra#HmIl@wpmp)5_X&A%bk^^txzGQ<%l`V*_LdLGoR8c zQqSzh_dluBr|U#M1Vsl6@TI0YP6lZ?gBN5BhFdnKZm#)lwH%Li_46(+%{c3W(74hhmy`Tr?u6b?u{5~R;LQ^zhNQuhmhU)3K2hQO3OiW?@yU- zY=mQ8T52yQy^e^(SBtAi4O6oW14zqda|_&2q42$u*?)w&x%F`@OQ+>)9X6cDEm&IW z;WrX|5QY3iSRq*uR^7<2?Mb@VL7D~ejGay*-|0DNO>-~L;^huLYs}VpxygsrB$b;< zV@FZntb^I=K^kQG+o_se%sWD(e|nHEH1~URGWmYbNE>OS0eESF184-2U52g?5B(w4d-x@OUve1YLrOQ zGrP=4o`uUI*3pP`u0bQ?7U>y5+9n<8YzJGPRwm8=JE{j!Kfp}0MAT38fLe$+H^X+C z83BjP*jkf~mQBOiS_wBBR20+4ohF*`AN`Zfoi>riRA=)U({*z@QIoiaG^qgfwyvZ( zGm`#vr@pH>QSSoe2jkepH(i-YFXtldV-7hBKXc;KEwdkgGj4WWWovv>!T7&Y&FuOy zRih$E+n53JE1djHGZk0ia*uS%N;=&|eO5EJ_uwjpfpOu1lXsE#HKVf(G zwWp15HqwHo500=(IxVL=)ATA%V|<0xm(9`7$k&-eTEq0jeY^zVGu#KHuguj?HV0^o z^8?d01JGf5=+S=KY&Iu4&dmOyW<7{pM18!A_GgNce~)tnAFF*gSJvq=1&@ZL<9CoY z#V6bv#hi1~+%~EDF zQ@xGZgO76|9|);OI;A@4y$qz8-1%4=KhpMQ&Fb?v^+zU9bJE<=Q1e7s5KsMzG}2+W zNtdo9U1ct#m#L{amYOG~rkWWO|CkxNk^JtXf+R*I;qqTo5F$b z7bf4T26<0&UpF$ZIv1S)p6xO z@o7Q&at7(L2$LT{qb%nBEj06Z$|360JtPe`NS{t6jsArf2+O-Om(t-7?sR zn)IlKx@CHDc~8BEPI)Ba-}^7pEuT4`w0KCu4j&tpNY?^=Qy z*YAM36^Guma6I&doNY5=z=?1C?tO+dNKAr@@rhq~UVQM0Umi#!L~w0LBgJCusXjwY zPl7a4bmUgO6-kV$&temc^gzY;6r^FwomYSfNi zX8B%hT=i$|?p2qe+3Wp$OgG1)6QDWE!P$DQs)ImtpDT~QApP^j-@R36jd2#}i;nUH zvOL6|0S3t&QI}3$F3Q~H`ZtIGO;~S5;%tiWwX1%!>n%u`o z^YrEZ#I;)oeg1ZvnSX_1Nvd4t7+Iue7rAG@90E0|Gw*^V_O^ z)gc`cf3sLz5ch{ex`-d0AYBp#S!o}NkRZS#!Jq5#g<%(GNi=>GeOaMCiG92PeHNY@ z0K=81EaoGWfH`OzseIyzld2?eGA?B!i~dw)`**-%r8{q6OOyvUAuUz<1OPTGXRT1C zDVG@@Ta>d$0Ed*zd7(V4^j;1)txVa#xm{LnAb#adq(Zq) z{fdf&FBb)CD!yD?fM0s?>Ec7gs~Jt+ZMXve`8*r~hVg6D zJDV6Q04+UOr`mfYfOhE0b#$7%9!6b9v%4M}Hh}iOL8pxp9%TUIg*S`w1hHZnj3;tRIy_hS3j=KVio4d!5QnR5b%Sm3oN_@Xp(nKMUnfL~>!bV8j#h8159pY*hnCuieSm<_%A)^7i z#kt9VJz_f7yjT2s2-qjuCqubkR9FY;fXH1G(m`>*8KgrZ-4@2*Vd2uCJtFeZ#YaW% zk&upw%98-+#Df(m+%Lt@DQFv`oUj6tl~Y{PSmg$9RpXQ+d_^0t1Sx2npx_5IOk2r2 z9nvIam@lLhWdM)M$%+Sy{S;;5M?k7_7Rl#CE?;N5PgTk>>Zd7Z{>Ffdl_H2*{krl9 zlhG%tJ$UA)s#}IanyLO>6w*9(CZ;AAt9{G;iIGfOc?JYE% zBeMV5o`8uw90Rv;vz?iiaAiT!yo3k0i31IBuK^mmGUktY@XJfE2pPQpzfg?EfHG6e zu>a)B93)dFRlp+ypfHX{K(D)wIv~h9R5FIp_o+CXsa^ z@9Ev3iE9{c`Ac)q0<}0)!F+Q-lloC#C_ATE_~HoAk_U%@mOr`$`pO?z)~oKj4ZhCZ zHK2_q@dRyLsSIe7_wPZQ_T%u)UT+3%;UaAr;=BduFpJm3u1DR#_x`XNe4i@}iN4!e z&qs>d#Q@1-vJ)^?6k=E}5+fxnP|rjExGB@lYtRQtFVK)>-k=VD-W4M1vkJ8LW``Zy z<5ytW`EyIqt{vzqXYaWBfI;G4#EY3;5zpJfK5{U}%zR}pXx7^OVUi=M9BA$tlb|WR zej;e4OKU-^ov^RhKmi@QupaaDP55N#H?<`=XXj2=Vj1?ntKuQs> z%>0`s9;Ki=RossV7?c)!t!4*p8=X=X$^g$^eaIt zy`2S3jRyz8*X+!Mt&^Umxo#TEdcC9yXsy3H7JP%bywWtxoPjQFl!9zF*X})zTabV6 zY|sJ)nAHVa;vy}RI&c>Yja&p;%*z+FcrRvhiBT@llEaojQ>r8jQt7@7-ZG(`p(%S} zIQYuP5xBC7#T$Ip;sZgeRp235`!VgEb$j4uCL7KA2&1OuIjd%UXMt}%?l@?xvzz|- zBB*9F$f3g+NHKohV3#oYF!)N}E#Uh__X9si^gjw%Eq0Ct>=5VL0#1m-%!XT{V;;au zk%~h2d$DVfkWLwWejz$&T(vSG$zlPsdy;6& zVlz$DV3nUMj^=@Kfq2PWS|)08cUFove?eL=+D-s$5*Ic@xm~Y)jD+&KXqgGpEz$2Uzyr}5^$7Qt5%tjaLd-n?cr83^P<|Ar>8dXx zEdcOK4Dp9@u(AkSW3ID8EH5cldaw}J>@fAe)hkT!jLuHDm;81|BIld)8nVljjna=H z`}Xw1V;SGg1I?Dx9W?eqG3XO&#)IZx+6^?R1UIF~BBpZjHA6s4wMh?J_R|>93YBVu z);WN1H2b|SYWG7Gy(`)lhu-hXjBHqXY7U!;N!0IK*&3lGl-wcL`j&!OwTu975KyqJ;CQM-Ws&%-4f6g3tA6a zJSv>`-x7fVgQ|2?0%)0%E1@Yjf$!ZFLwiBfs>MQ3r{^eWhKR(g5Qd5&HUBJ0 z$-+rTEaJeK&+~GVwfS!FIlgo0xwKf&s6j9{yCNZoQ{7ED|ttmhWytbDa(-V z|F5IV^s6&Xv}4WMCOYscx>NLJzV8v@l>x^U=Rg*y6N;-m z;JvmItCpkX;RwJsS-co*j>u!2!BM%DHRYHLr)Q7LZ``62@?}22Nm*kK;FO$3SDukY z_rc_>d^Q)-Ia%NWr1SC)bL@hw#ra;8PcuNeB-=STjmy&iFKDmGrv~7v4EYGSCUaj0 zT$fb?U~)sAvIB0)coy1Qatd$dx1}edTHcXgQUQ16f(8dR};CsGLB#j&nzK~H0e9?;>u-NS+(Bk))EENM7 zr&VgNX$z=zBO_?TG5YtLn%-3Nz*{{3+-=s&iZ zpab3v19cX02OT2%xL(v3nViEfL7F1IGDTCx8(u42;^m)mJ6&Wg445hASpl;} z^b-L7cQGc+TG4G6V4aAbf#=o>=O#!S#N!@-O(Km&W3%Ww5s)U_YXV-0Y@Eq=(d9MZ zhbZk_hX;R(AiC|Bcsd0zP&tcBt{kLnP5}&75_yCSQ`}gwM=N=QA>CKXHih(D={6Mb zLQ!8r`Cj?Tx4ExM%VB_lYG(%VAaxu=a-`brA4sFr=w!eIHFyVV>8Q=x_(Z@} zErIcNQ~S)lysK^X1N^If=5Ga0vc2cZ;468^A2ic{vts zv0IVYzk9t(ZRmv+&}L4}20nWh8>lnpFhe14N96o(!wd`}-#U$<_3Owy$emCLG|J~R zXmnkk^zo@owj$rgftI+q=g*U2;e*gtRA)gf)}ke7@on=#OVww|X@8MP+`-N%c69Kv z+G#U<>y(}EaZ|e7W0mRlt`O*7xfg>T5q17MSOXU^m50cf!GNLi^AEsyS(_7@CcDr@ zi{vV1$yyoH8!%g6ln-!FcW%TuN3FNY0j^jZ75+2R(aN1#Xirlr*X5{N6)g_1O*ziM z->GzE7Vc7-;&LK)D?R2xdaX2O>3XB=*Z_E^*ir%Sm0~{uAC=T=fKN*8@p#~i^1dmg zuZoK=-QSgl6(Rjl0uBLwDGfUU2C5g&0Vb;ND>42jsrd|utJKq+=4$+(Pk^;*d2hfv z^+OfF1~rmz02|e8EUBAS*F8X*T8j?fs#Z7yX`6bKS+qm7bOY>E_j>|%tKB$@J!wt{y(J7`GCeFYJG0aQFWk>#vAIHn~-j*26k88RwvOVchpL4 z&~{JVnHSQ1^~o;4Q0-|oD2HhmRzq5?rQZN)jkb0PIgV7pfCHei>wiBY&)i)6y>)jGxl_Gx99p$D|OD*y+zNFTsq zZ8{6v5iK7#=9sp&2;jKp#v8&(ty5RDozj+NfOJO7Z~$;t>vsomUhBiscfqMWVkx_% z)nQ&;*2b}RUe*5P5ZAO}JiBgc(R}chW}~0(VhEVr(r z7uX>ARa?)gebdhK#p8#ze>Fy2~ArGQ3$dR&H zL70q|op?hTBPV%6Iabzi0mjK<&Uk1i$SF479=0kBFs!T@XJQdaP_@^}Dj*2}Kh02^d~2E-=$oZGxv+7cmckxc>t zTV=jFP;QqSdA#qCeeVNy%f5Zkwnuu^g0xR&rPue%(u{?K*PC*X?oTL`!+vp>j3ep|fa4n>JaytEcU#1}|oVa!kW_CQ3?G4yGmgA;FdLk28+n>o< zfsmfd>%7gsl&?AcS2BfV?X9eo9`H_%+XUqY`PW=XALT^m*k}2Jnf^r%=e6dWR6_vY zWjAK(PuXh@q+jyB7bNE(J zje|5^x6;oO^h#`-q|fXHNYU>xAg1X3dA6kLuLeRnRe$*m(lmW4H*JO<-W)Jf|3PnW zaO#6P0XOQ8*qEkgJ_Tuu{$v7Ro1UH}ZM**C3Z$L-WCp}8{W248k6ti0q`i9Y1%Ul} z??!+FdTmzA8+xazfSY={p|HHIXI&5JjvlZaa8Hk_0Ofr>n0@}MJ1g=k@lemsTh0@` zXfoibu2qEcg}x#V@KQHg0^aDyM*`mJo~#h>^_G18gPzQhKIw>fcwIk`0n$qAjY^PK zSsOA0)>_YNi!+GicYnzG-T$Z~hk+M8Q>$lBAjr56k#n{X}ss`R~wn;u%xUp_ACIbGp4)-tT!CR02_^{8UXw>O_MYurad0qV$@>7 zZZif5Q|+bUPZ)8S@(fE*hU5fJ=t=bhKSHl6Y`kGwipaykWQs0B#zCgP^=^ z6c2@T$5_gozGqZx3hBP_nw|Y?ROEs6&`6*Y9vg3b08fnZ?od86jzzPiJU5Q34!5ClTb|V**Yu$_}NE_U8Tmv{ay4kuwyV5r}DS_y8Ub zcC&ITx4R{-g0#zRejiA?-Bv6F>~*`k49b0O-J90LTZJ5u zj=63B2I;t4IHTmG+p<_lr`&QdU(dKTs|)F@)2&PaW-?%^t9OCF0c*H2v}^}%VM&`7Q!=inJvddm@KzBxLqr4n^@6S*`~15H8#I}P_DHd zc1>uHQq~|DQkreD_hUgfH$`H%>Zw0ml*2rZKvBq`d}Nu3-Tvh7pB-} zTihPNS6lVcF!^R%*HvNCWM8a{~t1H_rhKv9BM&!Z_6abQQ$m_C37- zBkXt9K{?9)JOR>Z`-0DaWcvcf_*lCar$64_kf}Yv{tr_u#XdO`V6t5u2xY4MSs{SS zj{id)h1lMvHDHE4rZr4v*%P>y+4kA)fVuYc-FQ2iXP+?;;sX1|TY!c3=d6~C?R&X} zOYB-@z%u)FUiFsS$1qA(+8-1Ftg_dCgtj&I@7W=(weREAbiKXB62Jy~*+jr5d$HYs z&GwKLFxg@+9|LKtz4|;z+wD!=_;#|xzBe1hU3Q&Yx!Zn-r}tU=ZIO#z*BpX!cac5TY1zxw|D9a>4m*w3BW6RB8$Ll`${*!8+$t* zV{h&AxUzS4?LNS0j9-Y5HIoG2*YxX>k^>p`qk2BGL1s?agy$e02mW0V7j{<&xWgh!j*p_>I zV$7^^dW>Y>JG}g+Sbo2r&k_ST_H0p`DKSSJ-wbK4n8;E&Pdpq1X}<8U0BM2fQwP#Q z;TZsFk$BD8yjZN{{w)#x`1n#0kp^j*$ipO9E^MqdE5zhxkXDMr*SY_z#5W#Et3_Md z>=s9Y0ei#<2Vk$L-xE*l6B#oC_KRj$0SClAmgs{b{Sm++@tGNUSRD4k14qPJmdc~z zE)TC`!kcqCE^_AqoDkJmz)p%WZy}u$V`lRxJ1wH~K|CW~nj0_r@IHM`4B^%Hyr{Ph z68_PNV}Oey-zLB%{Cf>(yDZFqH1mq6!j!lw%JO=7O&ll(lj~x@CP+6#8OGF2af#RI zTOy7bd0XV*cH9xWhd}APE3&3SyeBfx1w0VRI|2WS;ZFb$MW+I=c_jWh4C%30#DzW) zUQGc{MJ*QWXW}nr`*ZPv;rBvZ^FiB7QHz`VO0?nBUW@$xfHxwIJN;JFWYWG9_c*op zPLY%!;s^1R$K*$mkCXZ&vd05Hi>EwizK9S;|5uU7cbacvL{>=O#TgCoL)_R1_$lTf zm+>;8sph&bUAthLYSCFjMhj4$o5FvV_c5+VM&^ zN4Z)HmUERGtR3@|xr~eXO0V9K7AW3%AT3mu(s_%NO2Yw*l}pUlC5m?dV5w4#NAEJ_ zVPU{>Wepv>LTTylMB_?j6Z2@5lDQbPtCiNwzctD(#>HA?oO#VuK8`}$dS%!+zy{?f z%i%`lXB(JoQmQhmHY)?N0n(J6jG!&bEMJ&xRkkhwY*YT357@2@%8a%hN+H&{CvE0PI(ubG-+Y#XPeQDgF4qb6DBe9B@Q=njXrd z%4sg`m{N5nq~pqf8-NqaRYvDYrNU}RrT6n+t$@$`ZaxIqxgCZ4e(QHCa{vRj!~Y;CrJPX^9rD{70NeC z-gWMyp6g4-~XtH{@AYh8Rn-fh{xAM$)spEKDO;!DdLz<>0wSzQW-Q%1CoS}AR z1kY6SUIffiEmfeLtzNN1nxo$B32Cl+?jxjm>MQQ(e0BN=C>N-$W&swe!&pQXsf{-Q z7OQh^!eptMnUTLtZ5sh;x!PqBV1>F>09L9)xxiIw#hN@ISF1m`m^JG1Y=E`uK^{lz z)Ws|j>(!-yNd^|e;dPsenHJx1aMK!(F-=0)U)*fm(`&>@2{$Eo`7p=--a-` zuD0Sydqa(2y|}5?x(m3a-e#S;tv>Dq>5jV60=TOt2LbM>k-WCuR}VG>JW!imgVOo0 z+Mb*DP_?gt_(+{l8t_=HGY0TPtvVNNPt{>u_A|BDI4Ga16S@IjsLQtjUaEcK0I$?# zg<$ept;c%)M$N&)?X4Qco9sI^nq~dHI-7U74{8kGTtBK2Jn%j_)wZk+pVdkUfG?_p zOZ%#h;tl?r`k3keT}|Y{`9uAOz5P^uxLd!}nY>vJ)c9|T%0XJ@EP%n<*gR+(qHXhm zG*o-QoF1knKL!lfZe>E-2+jLDq>bb+cFa{Nju1jn4*p4ooTZ6j%WH5?XVxDRP7V{bZHM*A*O1bT~JQb z;+QzoHJvw#8Cn!irI}iqb2`LXnp_5PwpQEzRLRv>cBhuGPNQg0xOE{~7J|+HzK?4VrZ#lpD2^-2t1lbrWE>R^%_V?a@Y8fV5Y`KVXOa+oz3Y z(CpVblz{et_FVuDY7d%1c}Tm>)gRVYaqo|4CwWjG)!yZWbWF=hcOBQF&5YAr-1L*$ z#~8pVZ4smUw06HJ;EYz#1vslU4+Wgl4zRAC*E%4qobrO!rvbDVwYw}Wm$Z3)kS=Qn zSYfVcJ6VLTY6IONUDL{PE3a$s4nw-3RcAKd)C?AyTiOa1*4x@5`uUD_kO^>C^Un+A zJuTy8NcXk8~}n8-O?35N_;SZ7z5Fo%V}q^j-_(WIkwRc^-V!P7VNk(js_X zf7bkX-hOdv@hyR0wU)Wj_)SwbL;9}W=QjV)ti1p~wL855zqHcn&^Aym@2r%Q_5Rt7LxmWl#QkxlLaQl-M0;F8}@ z0jA2$GBJ24Kw5eo|Lm>Bu|yua<%#8#T>bd0X0{?4TN@{T*nE|mmLlO z7Ra6~1`B1{Ou!=PR~oQb`t$%Sk;7Zyxuxj}L$i@@*PmqpZe&*d!ag0Bn{|_5#x6VESo` zJlqqoRh~&g-`nJlPJr$5JZs4gS-vFNcFN97*j+N01=4Q0hDCmlyu_H-_ucLW@k40?tTf4ouF<;jJN^ljFMp&dYz9Di`FjI)IDva3<#8CHZd_h?iyi^?2fn zJjO%ns_ak^(lwcre!ea{gadBKG8@o#Q({TTIH@t#Z_6;A*LP&z07!S`5-$6mTtUa) zmu`q1eErf<0{)f$T+2gwl{0)Kr@w*Zd@LVShxkMuW$Aw^TkQutlb_E4p3Ab?054=^ zdiJI4&6@H`)?EO2EgQ4?ypd{Vz+3q}8t_g=bB6C_gF-O*Aj@@t^ii(hdOyiJi=h0B z-^u`AdL-a*g zAq~}sGX#d|?u_T*dNaO*kI-+FgEUef!q6F|SK=Ow)~_=U#^`MrEXjH@O~&fZh#-jL zbpEgL_#2;0QSnxZeO2}sqqvaq`J!A$?D zdT>_2G<}W%n66K`i?$iMvn*hy9-R>|OCL*L%+_BohcrjOaVXU6Q+A2I*->49w^ z?bmDa)#ZTRE`<4aQ1|}{@sQqgCTtGtt$4Z|(aW>W9o2s}h4PqQnt5t)GZk<{- zfQoRRX9xVgKko0o@BJgsT6@i&z1LoCCTCg;kUwp^d5-za7R1nbZu^Q+^1^0&2J)Bf zEDig&ZQKlW`Nwv%KUyzcwki|Q{MXimCu^^4-A01EwmoMJ&65`rv2B7p5`xx5IpZYA zB>8g=gp*};fz}kcmB+EE@+8ksrpepXX}bJ|g<^)RNH@=vQ>$UyELn~9ZMNL#1u{pz zQb#)Ja*)oGNY~1r zcxYcIr*Y$YnYs;RgKVyWd??dcH#W+X@1eCxj^uxnn`J;Fv_6te>>yjDJ9B%h+%pnn zo7}k!!tL_Y9UwcTJCkase3S|DvFyYY{X|xJ&Y<~J`ctW0@|}(#yXB)&5EjX`M?m&S zuazKsWg_$UGx>W>kk92K7S?^TGeiChxvdt+e!09Hga_oLB9Mb}8jmA~kTcSgk#JV3_e*~%FLT~= z@;n!FUVh0lgA4KocfTknuv%V{N##Mlk{`T+@Unb|mF0@;atGvV*=iTaRXL~u$T#xB zKpy|D$-T_qZ)H^;g|ExOb3ks$2|OjZDYvqQ-jd&Kf$+BUD1+7=S?36E#2$-MSgb$^jA58 zzJDkO(c6z?0+;q!j=lu)MAlCM`AuHA5Asz09EqNP$WLR@`cp<#1$icK`9k|A>Go%=Y%}d1B(v=O z&O$iHzJe!m^X$L(Lo46DvJJ=rd*kOIi|qASTGrV2(M@aZp|e5O*&Fa!zTW;BeXzm) zLn_FJ_P$%ubEEy-D3DEdlZW5Uc2@vx@{zsbZjdeZ8RJ2=+TTkD*=9!oB7*H(>Fpi% z3?6BB+W+97AKOs{n6#6{XCBx|Jr?cG<#+DDT!^b?H?4NmFKu)1DWqwJrZPr<2U%%Sm;>F zq+H~9XDRns?9jNez>&yViH(Jh10_I~IO;Q4mpUR?rN0^vHx&D;}%D?ZXjD7zrP0A=9tAG-|p~f1+v5O!8VYcjvwfsPaF?;Ao{U*o-$Eda-7agzY z=1Y!k%!;oZyQuzUN6b4QR~&Pgsb4!@^00E%QIm(GZyX6P(DRx@W}x-0qg^Gmt~u5r9&ymM7xbGb1RFLl-4J)JT4~|1M zKz?*A;UV(AW9c^_4;;Sq)=!REaUefCc5#Pa9J$QxUmYcA^@omb8ibD=^E;yT*m0Sj zeBwyj4&hVB0p{QD4p+_qNdIum`vv4rM0TT zR)K#Uhj@bU(y_}2+x~U*Z->?^hX+I8wZq9XzdYw}JY-C8{!8IR=g(b0COOrIgeE(; zcSdW9GtkANFxA<70LV0FK@*Va&OKeR;|%9NYe8l@^BfS)a(>LxKie5d=go1>*vK*{5hNcRm=7)(Yp}C`QIg=k^I8A2{!^-mG#?`4p|y&HLJk|o_pmW8$Acvf#{CNI(*m?gUx*l=< zy$Ix}Gob`F9&?uCk?Xi~T1Ai(&brwUo^;+0207)t&N_G6IhkXhalYq))>-Fj7K$&O zt?9{g&cA{{&O5Vw(dB}(|0Ix$&eG`+UUGg@AFZ#PPDB@ee{oLWdapQ}GdsR^enWR% zbv~ks-#E{(_+4`*uLSwl`Jxrbb!Y9PAUB-7Dxu3w=VG2}-f|x33Ub@ol>u?b`O`#n zx$At*n7QX1#Dx9Md6a4Ry)$7x$Pdm$)-czP&H@|geP`VvAP=1X^52`EoT*&e&rZ7s z$S=;tV?lm(^5x0KL+5wvK^{3hSf?I4V=jO^aoRh8{O0Vr13jNQA9#cO?ySaR+#k-a z@gRRXqtZa0Iei#9&z%!XV}}o4>AbxWt$&@>Y3^6f zpk%aOJ5yNf^W4_8hH!%0VP@P!x3iTYoa9!PCYkJ(J`%zyZr6B5G2N~7uV~G1yYw%} zOt-*I5YBSDcwWi+PshO^KPPdcn=wld=!;A86)0F!cRV$bCM zn>KAqd-=J@Z(n~W+Ev5~8+OpdC_Mzwe9Pfhn?@}EYaBdkeFn0vxA&=lC zrFyCEKJ5M46If|}DQwG$Z2M-LfAZ&$27MTf@z>#uTGvLwokh223$sE|!2xmqbF=FY zdRWo8_x11k{?FefC>s9*p2A=F=u&XerG}Q>CI6S-Bq%!7-QuxC>@~0cV~Mn^s;rwk z?S@ZLsh5_ny6rJeIo&UrqhDE~TKXZ2@iKkhi-nize~;DT4f;m{G|lo&rlyG|?Xe7e zKsFZ*-EQn{N+N5Hf*t<*xa_)4=$#UdE&j-5&2ry-^2!oeZ8yqVlr?A{MDpJ@*dchV z4qmgnTS9-Lum~r1mau1($-4Nj!4i%mqh^(B&79YkK{*SeV8_Ji+{4@8V=^+BgO48O7E=X1eCxdrY2sDv<~tDC<(9^QHQOq4 zm9WOQ8UwSq)u076IW`S^#&zsumF=LATh?djYWL@B^xbkfuDk4#4S9pX=W^#tF9 za&LLJ5%}ihePpT`s>31^%u2d7wnlZ%-?=qLwe?<#A>6vwv|=(farfeh{|rT!UfkI# zKSY&v>qFjwePF$3V^Em6LnUmCcR_+n1L!f^BdQ+KPif@A?>vIfhq@jyZ6UVGyOY7k zEk}7k=u}^YMnYd~aF^9^vgc8jyr(Rg0lpkV&0Ah60G~+SU-m>Ed6dUXb+lmF1I5WB ziGzmAk*F;m$&^RQ%7ehCP#!0HuLNI#W0sRkCxK6;JXtpRfCHs*Lz;|T3%=q^@Kxk~ zM1@DCW#DT_YcKFs_?UI3{1p!IsCpfIj{E|V=uurtO{*)nnc-HepKC7y&m)66wv_9m zz}M=8&28l-*vKPmKKPEZ<~s1%AA#>G{mJJX0^d_+Edrl=9ef}85vQ;HC-?y}qX+mp zPP>LL`98(}9UgV#!M`iV!0jIO_hGKlng{LM)@JUuT0apnMg0tGIg$7qJ2W_J)wGf= zdxCA0g#Aj+s;g-w0_pFPWifk+pu2EN(8Z!7HfvuImVgN?-kuhRm*Lz5r&!#DVXM#| zjJ=fM`?1-;Zmkg8Cjkz``x$+VQV+A)-`6NL0a~ih_8w?YiD5)OG1u9xiNPHs+2+Rt zu#?62?F%UV97d_0=0m$RTeL7!9M*)ecGcJ+4BzhUfg*_4Plg$#vXDD?{baaND#3iu zVNKItS2cGytUhtWr(slI=iAX@@zTnl{#0_w)p}nq0e7crM=ip^bs{c}iEZ(iB z@V!FvCBle&g+E^B8&<|ra(pInWm{q+*cdM!RMWh#RBYv>q%=w!-iZhQ z8QRA|#NsaidyOW4Lya@I1oD02FxHPDjZXj{FWr*bCfE)psPFa8V+}ODI>B0FDFDL!VAk# zLGiLKMDpA32JccT&QdrRd4^Z=eL#Gs`1{BYynN1A4Y5?|=$p^YRjLrvGl(nIy4&WE zk3xpy!^`D}Kjsm;skkw#lb@1KoT`*qSe|@E6%BLRlW(IOcQTiJJ!QpSoTZ93Q<;5( z2RBTaOI)p1d`qpkpYr-g%8V|x%J0^(PdD>`JB!K`HbR>dzwsv4Rb7YnAU{xf?rs27*T3O&S@}Ibrz8jTG zYbY}&skr@E8Nnlpoz&$B?TiZdllhdWZ=-1;f#i>M!z*a^l5UTZ>3oI~7#I)-3TIT!FQ`H5*nuV%zc{fJEyh@WN=Q=G(u zs!vH}#SRuq;*?d|DqGG}efWA|*g)B4*-{m~!<1oDdU1n#oJTAE@^7+o@;qhCZA!(T zRXm?X)Zx{5?TN9^Sx?I;OWwwa|oy-01ft0Y;eR+iA4eSFjeO_dYZzfVbm%H!Qi>F3Jd z#UD04UdXK%=^&TZrUM&4s^~3jM82HbTpveU6i6IP4DGxcw7yc*t_F=)p;uSs{dcMC zv$iwwnKH7s!gLh@?*~xcO}X{Ha%ETsCF+xVnkz@e=ML5Bk0fr`q`bbf3;9^ZS1b0Y zN}kWv^u?bLcbm^X$CQshRTk>5)@@r#IbU3ix4_ho$rAiAGZvM+DY2A(} zCK9b`w3$l&9qsDUIwy0`y3oa@Z9;I_w7;=#oAwKG*QV9$z}?g{{o1TR^0zA!XDZj6 zP`tG#C0z@MQMtt8&qu$TPrlm+#P`(d8>-d&c~aupAD*+iz*_UDvuz{SC2!ML_8g+) zOOy%qk8#8kAGG5hA}H~y#gc_+Oc1+jqcugG<}#*=&4>WoG+|>TPZwK4(OM=J*FbBz zxY!=#sW`~+cp+|5l{~%nXpku`y>UO#e0?ovT%_L~4zg7L*8%e1*Ol)sc%w(jR~#vD z592lBA1*JcG^bC`qB&aFIP$bnge1TUj@|OU$FsG{u z^fo;2VO(3nI~dDWb~t=zD;I-6v?aC}f`9eiylb%`63~|17!o6;BnB`ll&TL*^h*y0-ut)}uDKm&y2ut#LcGQjxwYQTzJdIB>Bb_CY*8RZGm zA}ku1C;C?cnSgH)w)e5(t=`;!jo3>C)`~`4`Z{rG638|YMB#SvZ%L3Hf)DQFt%?un z|GgrQX8uexVw4;e_nF?u#7(MrT>RM-H;!N-yQ`rU4KYnf!@sx#MBRS`a=C99(^|G18I~G z^@a??jruB9irxBs#(a@Jm9e)+Uz!GTTt7q&Pv}*{LC)(JqiE}^`aYKTn|f(_=azmX z9^{^WfUO_(u82|G$-IbrJkzT(i}NfGnt@EQL~0eGz=2ol0*7>L1AMn8yN(^eDQ5`3sUY*jJWiA^{^lI> zMYk}J1>(DbAPey#7LdhaFMYL4?4esWiSIf1Zt-b5tV=ESH5?me_)im%hup{l#(oDa zi#Ps52ZwDiOZr=VTt9R`!}mLw+wi+hEBk+41sE`eo(i1DU4w4YUBS(0*|34(z;I8l zsZ0(mUp(Y*xo8I_&~;H?u}nsf=O{5Rk?2P3Q6yY(KRaFK*A(-pc1W)Jw0FcWJPwrk zm}`oB*%O!+zv4}o*xrolxD7*q30r908R7=#nJIpzCuWJL9w4)Y`q=#(F(C-8x#CwQ z);uwlUGha9juo)v74*dWnu@s0&&6E!bnO%6+4T$Y=_-)@qJZ&!Kzza0LDAR?q&IyZ zWU(GG7^FZy#R_cdDGbO$y*6#QL_gOB6K>FFK?}T?YA)7^x3k2t4i#7qRYPmJ#Z{|1 znyW3t>ws*qTtgfx&jgKNPzV3PDMLS}Hem&<65&B@ff31XJsMDjDhB!^@{Ayl1Yqzp zIx{4ZdWE{N>V%!bpvC^auB7`hs%n?gT^uy10Etp8=)_tQ)F6>N8@+)Mr|JJPwF8?v7(3OEE(6v`;`r&$ z`)XP%*26&Nh>sYz>%~9{e-!yxj9PTib_)c-m$``0 zdBliJJ228k>{p!{4Deub4AMBqkYPE%(Y=NOCy2m#Z-$9{^Z^7>yOETJE4p4ukl2pY zETO>+V4~FzSi9szV51kYz$Smwc*Bz31&+AP5Fh;u{WZ2*V_=>bSPx{9m=*#uUF@q4 zGDnnPfG!jsG};nzg!Wo3y3t_k#1jNsu^U}&20;?qfi|!5E#ls&x|M-b?c15a>Mhp+ zYuIW6(?4NwH;Quywirs2w>-7LmjO+liPlVP7IV*B=L2ikeB|sht zzQeqDwN6?q>0WbS=hFJkH!WnC8+yCmS*w2;3 zM0}mwh!oe%?RF#9((cRRFH;x2!nHBo?v;Zz>GDf6$jyjJYKiLlf39(rLXue8B0w$v z2qVq13Ldv4w*jj@B5lhyhqxJoTru#LB?jZjNCdg&)MacY5=O3S0*J@OT99AKmm`l4 zG3&BCE(E{nkX+nhc4G)qi#xdKGA0il+#gqiFfokm9!w(BIIdi=7baR2bQ61j~Kj&^#^S{dhJFmo!Hb$Jg>^cFxWWE{h z0SjF^Q?!_U(UyF zTEGWp%@T$mK55>%gpmnimN1%o+^d6ru~g0~ubavj;YNEP<^&>hg2K z@5)g{3qA2as^8x*nn!~c$OFGeNnji8#^#{8=JHZFtLbZYENukGABQJJvD>j=)DlfB ze}tq9zKR30h^N7iLm1rGT#fF+F!z_nBKw;6N*fj70)KC#g0Ptlyp7l}wMQWLz?~#o zF#Re5i_kpBX1Y1w+h`(ons@P?sp7u)wx^~w#b0q>ANJ+1QNig&-adE;z_}61S=@EQ z<}xn?8lA)yvwV<|ARd|Rf{ctNbLt?p@!~zA74iTVEZ`3Oo{HeZhdNXr+|2-9s1ej1_L`QfwgwUnrMvoPTPq(yNlY|x z5RYQobo0v)!_T81GTzW?`4Q91-yrHRQ?0Y38sk2K5WnRk)bX_*<$=DT=A0z5evIW*V)O)hE(#p!~%5kV1rT-bV?hklS)t)KqpH$H`+MJIeT-DWrN2st-Ox5a0@*sWlE#L*G^I7^;SQS&x0xiL_QwoBVDyW`a^XM1^C4iom^UobUYE$4dp& z7&9@#a0{ELhHj#~^-S5VxmwwM<>`)Qn+PK*rBJzdxf*Y?;23`@yIoiIEKt_7t98`j z*@aeQ7DX8G=_i#kUnf$uO2y1XrDQ*qcA9d-0u?i(RV7eoLRur0d+W@QGDc*#0@Y}& zHpi=+EmBrURBpYmG}@@@F` z95zaO62sJD_nK!gf7wK3j6$_v9i{v(6;{E@s{X1p9933bWClc{{&z9!MH(T|!_|KL zr_82(q!PQe3W)`n7HN#~XVd;NXGI#3VGoqmh05&FDpvNYynmo}>tucziQ~yk^M^?o<&3Rq?CqZ{~(5=P!?0WuH7UG2M2q{}xTy@1Sq%+}1TViEQ_VyRj<5-L>xdNw8QD4ERpf2F0c4c0r zjpS0_{6e}X9DL=;^hV|@9*pXIP6srpZ!lciUt@~&QeP+=^doE7h->DxXd}Yaj)AgS zd_&nMA{H*f&!9@F-9l+qB$QfvgwpH3pFyb;eg>t2#f$ow9`lLd(gLc|`axTKff1GH ztLQSUKCzvc0aB=6Fb~8UWyEvy9?5Leh%<71htbi6mR}fz zODw&(?sb+uX4g2w+oi6R9I|}Dl5^N{2&Pgt3hW#UK~y&$9im6@h!j(aIT8D7i8nn; z1<-+hCxd~=31FCm=14rv;3|KbW=dV{1I$d$0Mwl7*s5Ly*P7m-bpF`nrQO+$7Z3aCVC`32#@|C=(m}s=;!~ z9w9!oTEsnOf0>fpH*zM`N*e?fRgc&pt}kw;`Bgk(bp|zhvPgeMk1f_aFeVCg8+~Ky$GKmjeg_M~ z4`_2_c}%!L&oMp98u7WIaE&rlP%8Hg{)OX(zQbL@wlKcK+r|SU+QLYxU#azsbN>pQ zKBOI|jh$(}U)D$|eTpXY|B?d)3}%D{jy4aJH8MnR^L1InM;s{fDQEmq>3{w&bm0&) zt*Ay1!=@K??`3Qb!Y!GeMWGXncjW*4&u7<*wuO38IKeipr3r7rZ4<&l@ zuk0Q3H;CL*^Uy01_tt9e`%SN-M#X?zOCWjkKWca6sU;&$hu+dH3+Ur7&zT<{HBxItbDqw)v0Jk(T#LypU1wob zsV3`=6@XtDjxN18f>oA+ku8158}dif_n4963Lb-LoYC$UboE?~g~k-`#vz<<{%s9J ztU2Q-hqa-oGoHM=Y+Mz50(no(avep+S@sB~H#nGO8?5NIkQ<%uZi`!T{3N)=t>6&4 zX!6cP@Mb=;L9>?V)?PW%e76;=Il?p3e%wgb2Uj<% z9XE14sHEGLWf((~bIsYuaTfoJdHJ|eKA=?(Y&m*|gY?HSz|GU`Jb%G)?`sB~Fsgan zm^V%V`L05E3E!og5Np1?o7CcaWHNNt zEOFf-s+ogwXRBkDI%!l+p9f9!IucdNQ}W*rT{+ZSIZkhU0i*d#|E`d?NW)$=WG}>$ z-kyA>ykky1X@t6ljEAVpdmQv7GQOPNtsaJxU&1qb53-t^fEu9p)RjXS5_)frY}ZO! z-LRWw;dY4n_@k@eK3$)&h`V3QgKWlpW%wV*lFtV3E;nr?&n^w+j#c2z$Wum~&w_~* zx91Qib$zCR+9*FTyPh)qTx#!`+}po+@0r}YZSmeS*MaY&SsD$-{xc77|9wKARiFDS z6=wZkD$M%7RG3w)!sFi9Pj&C8*_&YZ_Sn;Lii<`Cn2wEgXL&;8UxdWXk@}ns9J!*2 z4f8%lcP-!$-L!xT@6!XmrO_61jLAm8gN|qv(&L#JtjMf++VJhjAJK(xAx@cb6LgCa zFiGrAbhliO#qS%5?CkXRNQ$;&mbsH4O1^@vn)E_3@<`#$a8~&bLeQfEe^s~3oNnM# zn}K(ibIcv5jmG-O+68Bfpvq+tGMaDuNKR+-QPWL22*;Z3IaJtG`-&oh!y?{xQ!F6%%~-YVevCUe`a0RJX)Gm(Uz zaqME(>`c7sV3kF&%BD53G5!_DrPw*!E9#^ZgE6bT-uyfTbzGWP%vH#(k~fZd#c|zs z*>@B8ga?qj%gpBB%aZq$WoH6rVMk5u%^j&$emVZ+Gh zR0ZEtE?f#ew*~k#hd>u8b{e@g?3}Clbw!^M+62 z68NH2nUmO5(s~XUS~VMn|8}jWl`hv54zyUw4kH^j*_?3R2o)citIp#BO+QRfdOZ&a zntX`3DZTkm?2od;OMaz4ih?;USCOZsw|@b-B@D6d?b{u_ZEah?-rh-j(L=7A0&xmi ztwfjpns)^bXq8vdrI@$Nml&^@cb8#VZ+SE8f>F0e+4X2w=RS5>t`~T|v>Xl}84f<3 zyr&#wg6H!Qa5x`$@y;OcFYh7ryfeuM%RXDd*CHRT`G4Vu;e>bn=_R0`&3t&l@XOuS z79AS%Mkh@K%!kpuo3UZVvjL3SLUdJ88>abB>ZfV>!n@Pg++D4&Gg(cJH0xbNX&;8Y z?cO82NP;J%J1!b!#UAsiGx-vJD!yqB zxMW18FNH_Fzh#exa#1e$>tDghP31Q<=dCWDywAKRs)qNyrqHsjOhdeRf1eA!BMwn# zFB#c-gC?feS4MPD;yc)ssq;#Wdjx-R@y^mYuxG^gX0xx10GA&0HE1-}>B`KAj36|csBSqCHEW^KRBfpnacB%0&Ga$Yr(r|_ zl=g0^x;2eB%5}8T#~}DyMr@)pN9$$1@p_83WoT0Gu{zCISCl!-X~*fbc|%cVD+1Pg zg3h~fZs=urf0p-DJsGRHqnD{{Mqf4xDi%zFFiiNt;*q}~n%uo3MKAP-P~M4FycWS% zPI<=&uH70@ueSN*vf&@sa~uNGJ40+>_eLnd_`oQ6E#d>9cP-VhMGP~OuNbLfu-Ws9 z5tIE0)!(~|T2|eN0-C<7J_P$Tjra>?*1MZN6#KS~h@FQn`?`p76Vd3a8e1ZMLHY6Sry8F| z+%aRnHoBHbTnX6--3>O2aQ({D{xI|^Mc`hO@QPhGEczt`5klD7j3v@cnDl``SiB2BTnP2L%6H>BLr(z zN)F)yv(>7Ga2Tywp*j1G(X_mpSDpI}z}$6Jk2>s8$fla8?zk{bJBnuguTAG&Tpf7N zjJs<*jlN%iDKeCOTkxDkRI?y)MT_qdR-$4*I7qaJGBfVsCt#k%h?rxDPSGM|1~8&{ zb47D7Hiz)GRBPaAo}^@rYKT=W^9#qpfsp;oTzk)m@c+6E#1*JmHa(_S;DWTQA?A&H zMvyCZ4!VC#k!2cpibr-?KBhXVckw1I>v06c>s7aH|8-lhx^dx_^~yA@zJX!+XBpe- zBuWhbEE8Mpn2Tt|pHFbBsnCFbmJeFZNYu0$ZUD>tR-YgO>NM;o>WX2su)uCA2`Dnpx4o4B(Cu`N``{jaExhIYR`al%yM zC4@bm9zeA+w9N~NTVjcBb%}kN68GTPkEb1+#D2|*;}uTFA>7c$tR~ivCO$@G$6fcX zc#?i<$_~}Ydz2+MNA??9-wwoYVSYnv`5y7vyTmJ~lDN4UR>D&(Y60H|lYgw_<;RlG zQsbnkADF+KMv1zsOuLC9j_;`>xN&8OCquZ@q}KghVdOSS;?%^R?~pImfOr_;jeEh% z5dTt>wOB{KJ`Q1qHe&~I1L_TK(NzJgWj#OOvub;pm^FPZ$BIO4Nr z#Nw+M^XrgTpG4DqDw99Eh4_xLStbq~c<81v(Nxa;egb%x_CT4vY7{p_E+GD@R@_Rh zxL^z=GnE;OpAFeHo|3sL^d6zK;7)2E;&eaa-s!|MYOmHxlBD*HRsGMaaOSgexLnzl z=t^xva!;*eQFroN)dpXswJV&GEy^|7O7bl#hN1OJAYNB0c2{dnQ_ILxHf!6DTYpt{ zU7?&RJ8Y0 ziS(@+?v*lcI~6i#R1&`G$(~L%{ZzGpQz)@WC#6EGudDd_&e>dUsUA;ku1x5mj9So;lBr7J zC8|bD!;uJ&YGe_ER5r9$Nj*#1tFDvs-l}%2P!d~dN_b{sXx}d(Zc|I!q8#YwT2GPs zOq*6wIidVaN{((OdU+CCwj@4ZMVt^y++h+gs6of6m1n6c@Uz-?l!}l|)!C;-H{$HU z#5&6Qg)_+Ks1QFnR~hmj<+~46gt#kXzf$4&YBIa_&LD191$T`Kr)QI$RFaoCA2|mt=TFZZkgx)#--~&FD)2}J{Gs;9Kbn;Er!sjSWXRAeR zRob0a@=bNvr(JzwjG8&W1NrXDh|_xE%v+mW++X#)jU2XV6~}Pv5Er7zrg;u$&`Vr@=lG;OM?1BE2JXWe?D<4!`Pf0>Y;z;GQA!^KlN}k<-@<7DA zO&bVRY}#4`kxfeuMNHbXQpv<=Dtr5@pjTgM)|S-dZo8KgCn)|TR%2+HD~YCBpKlHF z?F)z_dJ=Qh>Yvmif1ni66DfgT67YD-NUCgW#%0M03xO_stq2f@164_NiAeQFJ1!KS z!ll*&PBbQn<&DvrA}VqjQ$;>pjVrCYnR?TOJshoNqIYeymW!CqAWy{*n(T$xNmcUn zt~AjUeb^w7eEkznxJb{Wqx}${H5>8?$ zTiMWg$Vpqd&IlS?Vq+Zk-d??Zx($-#6ZBw8Kb~h)n6nO;T8R^-b=eB6s9uv-=>bhr z`I}9^%n6K;Iu}0#HrY`U*uEDfz0&BeK`%D~M`RQN#}AhG;sv|lHN&SCmmP4L z$rBXCgJDG3TEOUwOvzYRW=oL7r3NtNAI3=Pxjq~*`5F2UdJ>n3< zZLes-6@MmT86rnTn<*g2#A7b~xLDB!`pNe}3iOC*5L5q&+Y0p`8HOA5(g7eJ z>Xn%+8};L?t$65#+85~q*3kcZ^gLG6|(StwgR}i>(=p~b-@|o^O1LavBw*{GE*$LO+p_dno&pDPsOrS!`!_pv2ESqVd zb(V9`(1oX7zU_+UPD>MJ@W+7iFuJ0G%%``h(yj@U_eV!WQUi@d28*p1z(2$=8?C1@rYK zQ$QBzTQfiw>YvkOi}V}}hAZX$hJoNqCX5VIA2=DLP>&r0vPA#d)g2RV&}Sk_@vKQ2 zQXJ2kEKT4Z7F!Nl%Pl1sjH@lpn}BSvguy+^>_H30Ll9hN)eYs z-}Ec>9@9AJ8NyKQS1N+Z7Ic+|me4R)AUjuwFO4!SBY=_W5sau3TfxTKqRoUy2++XR6O{u{i_1I<Yc~MLtG5W`iH^}| zOcK3%fJ_rtsncvxa{vgQP20?xh=&RUnyW-+Hpp6`p7h-$&dfqvPB)Oh1TO*Mp@M;xKql(GZg1E5C;q=wr}Qd->hxtmQt#u14bbReb_P~hzZRIf zJQtXjK{r?QngXn}nwnKkfia9K-prG#uI0eYf}X%yX$8P6!S!Un>jlis#tL0V?J~4k zo$-@__0$&{8y1Fx@Abt(plkmM;3SdDQaV|<&wQhtzLg;xDdT|ASL*>|{c?Z_t5_Jy zU1I?#KPU{C+;B6nLIkTx+A3dQrJtF-RXR}>^DAldat-Cid@-~xth7L#z~K${r#BYQ z^`@-9DX(v;9lq~#1wm=MuTQ~x|G#RVvSpF*Ou!VMiO^mkUxVC_M{QJ8qHJ2*oh#g4IldB zjPaNrKWpq=1@fgaWgEyjLp`T>!FX5=t&2thU31A86aey-@ykGv%SLz&kSoRm*1E5a z8(1dZd4Gy_|He489^{%~9RTvJaXo|Uzixyiqj|%K;;L^NOIadr8QEPyZX27&g51Gx zD-!)-7$q8l{Adhg?A$k&Ge3SY;*nr@TfM&%iB1JvNoEFOPuKar$V3o@2fYsVm0#-l6 zbgJ=FG%&rZ3Cx_xSgy6UBrxk}dtk%PG-ng_Y+b7~s?#x+C9zX8+P80f2C$#&3A1a^ z{!rlHcbIiU3V6U6UWYo4oWQ&qcepZeeEJ}uYjtr_?Bm`u#Vx8gS4_c5aN1PW09hbP ztN~dp@WwzKlEoGk>!JgLX^HUW8kUOR>wqj5V<)r#T`5Y^X4}OH&bC8Dc!TT|+qZyx zEP{FT_(bUR_%1PE9LR1_gYGC2m-~V|7R!=AUW&qzApeR6W{R85+f|(bGeP&HK_=>% z^+2ZR9od?x|H*3mo$mVq$gldJjO>T{XEj0o(5rHkzjbvVV4lUX39Sj1is~?Fso4vy z8J1H#q~u$UW`Y!0e&a!Ivn7k}KV#Vw2XfZZlV>UT*3bd^|FUHptIkzR#tx9Xmf9g8 z_bd+>4Zm7`;NmA*7tuhIt;d#wOtsEg4>HZVD;#8o^_OWNi>-fiNo%d8SyeV#S1bkD zYHh_d+hOgAAi~#U?$SNGtr2mI_iNU9)j@7r?|uk!*IL0HgihAWK243AaDC1%?iBeX8a24iX-$VNlGnskdX zor$sCXqLmo+G(ty!n=&FRKLhr!cg05?4+T-Fb3112aW3t%tOY8s#CIj<~gr% zar^(Z0{(y2yaF5kQP=({s^wu5>E^Tf)+lr37MpG1kp8Zs?E1EP!RGM4^iXr~5NnyD z*1c^*g8o-`J_djIdZNu%6gIo(#!~xO~eIr9?1jq zHi@U16b=$+x=8Ap=SiBHVG$sG%)umu=79(~3cFV>gH~H}8p$g2DoLgp8wp}JN0IC> zPmp|L`bB{ZF?*9-FpEeYm@--k+mIBRACeq2pOZW=>%@TI;WUzP^F9gYi&esDBzE&E zNn0~E4rGTpie!&@f+XDZiwDUxdy_OZi%6!MG6AH}Y(ruFD+?EFJwLEBUM&?J2>U4BQtGwS+@2yc z@hsbu6q$;v&rucRAlJz>D6j`=x~ZE`ZFq;~WF1rMO(2SI3l?{MkuOJHXy{OW{eK;j zi#zbndbiZ#4nDeD%u#gkor6SlOYA|meMPWo92d7yVI8_#^i?$c*6XHMstgt-%<`$y zPrseEaH#Y(JEh7f5oAtGmDT)R9HcYffa0a&L>2GBJcfcKOPH5aWuzEmzDSkbJi4Ij zzkT#^ocT_gOp7joS>8VSI0JjXee}^A#n>Z`7PZT*=7BUBsUt(aPm|@-_oQOen`a*- z7WDSn$3f}f-#q)6N%@;+AE%>~ynXi3&1_OpCW!*mRZ;p0(=;o}$ml?r?d`LVlKh)z zAGcDs-0qV1dc81jV-Jt!SmxX3Aiaw$mE==_rxl-7mgNzq(N$!E=S&nb{#mPp^+AO6 zDe6*1-W7iNu&gDz1U@WhID?>&dhReH)ofEuP8KQVjcT$+6DQ1LXitKPS1~Jo@#bMe zI}JSytw|WM_(4GRoV&KeMoCf*@wZaM$vijEc1IHLn!T&b5HZi3QeDQEzE+E}{CHvw z7!YrRGY?@y*eRAM z1dGyifwJ540QON|xYTy!lD`&Cycb1G@g*8&qjdP*9WKP1`TU3l=1_<_BxbP@6-fNd zN_^KKo5l&HsHv}C2rSITb{-6(&7N`Q;PECkwW^Sg9eM^rS+ z)|5%<3)HIqQltKs!tFEE-n*5NswlphutZ5VtMXyM-3RP2K=-nC6&xh8F1VYHK4b$gZdh{ zHb!}4s5vJ?#*1TSQ3m{1{E%4{HOL61=YD17AtsKl$yj7|NH|1{6R5Tt`gLYTEkGU*UhJ;0{fu!=;bY;Cil#cV2j(g0jnKCKGM}=we z(~=(vj`z6=#BnN=8^lnu0o4SFpklwhS-F;sPcN^gUX#cTeN^OVN+my)Ip3&N{ek*{ zxK`1!LfN$V8Qm;%MJ*ZGt@w?aHnsVz+HI0r^G}i7ZIw#I3OE4a;p%v|;0_zF(v1yHz?_Vf1)P!x2H8!n->6R@c!`@Sq3{lHYRH3n7={ZyF zaMo;;jWV8S_R5y=u90fXRF%*@lQ{co<%8c?Ao6&J0uRBu7Q{rAY>6C{=zwxs&aJ}`-a5itrX!hw~a(>j?mS-k4_k#7>hY-zu^JRa*XdM&0=2d#7fN3=HE<;n=x zFZ9x8kx$tt;uH=qxFn^N+AWk;MM9~yM<~7iyCg-Oa7l^^7B8w3>}U9lgEfr+51ers zL4z5J5wBQbqmNPH*Z?MN;$kLKN-#0C;#%6f>Mj<6^qdmF4D}09j)y<^dg|?*jSK0o z79HR(HI?5jvwUsY!gm-KxJLXgK-P*@T){fA!8B{bV@J(HAimc#A^cHzGIZ{Xqs*lT zVn;z8>0Q=?$vjn8A5NR5M=(jI>+2~j(C4$rntDEMSEvs+GwR4Ph=uMX3FeeKGS}Bi z2Nzn_GWeEQ4sqG*EFH`{7}}M|%spi3P46GJ^myy{QnRVBU+rKZA{`hujiV&?VaSx9 zMjNEI_5o&oRTEfCJqMb#hkIpLrLS|;`?7MaEcLbjFm$i&pN~ zG7H#cEYq*&)?{G6{q%nSv)p0eKV^VJ8pi?Ooz9+PTXM=7;x)-UQHP~7U!*01%oplk z?**bKPd*lk4|zmeEPkSqmWc>=kWIp~F34^%D*@T0yi{r&P3nJvI)zxnfw9@9TRoYA z^Y-+5C@j%thk7zK;u{VcyAG}|-t9>S+J0x@G1U$kYHqJ5{k-mDAxaR-yO@o*a^}@~ zG6HwU{#8!~b!^E&=8K9+2+GwWl~(;+Jf~*+L~|R+7b1oR+%K*$mJWy{whoG)=)Oau zDO2mPSj)NI8y@*G%xq1|f{XG2w z_siF_Y1H}pX0{gSg91So>c26}7wL;=jm7%ERJTB%M2DDqQ+lLO-vH%tjig<9tYL$` z%Jga=<3kR?9ctM@zq0rTf5PEHzvb9rjm^zBr4S5GIIKnMv@qJ*F!5E3jvfZ*;d?ryud?GP+Tf(n_{r~^Z z&Zidnzx}Zm2(p-e&iGrb|L31|JNhaj+Bw%nMvDF$ny5iSe02=eVvMly7K@@-H#jzF zIfFa(vsg4ucIw{SqG(oIbBjey3I_3wwt#MNeAU9lB1d-V<2T&_%R=tLVlk|)Ex^YF zfwx&pI;zWB;+&(wv(f=UZv#BCKii}U$BBj?SR(x^52+C zF|^8mLQ@1gatj{`jjp&wj)0N%6J~JB-3YA3`pj`h_sV2yqJL?craSKxvS#&-9t5lW zZD5rxOE0j6`K%?&P)C$Cx8EPwuv`2@C@j{(vEWO0z&12%OGi&@c*MeX(A4B~URL)S z;Omh0wl+xyU*8M7ul25Di#5hKj4x?^7n&@2XToD{EstRy>mLr)2p1CVyk>pV(=pA6iQr1yBYq9jmF_w3OAfnW%kH_}z!V{IyfjL*+W!YM1vnaF zT^9&G+D(Tmtp$64FGzhZYup_0g+74KXWcg(d<^x`)}XoI3sYa%`eHu#*lc*VsI}Q* z@Ntpg=VEv?@dfKRLgzOB_`3i$F}!FRO! zlmTC16!@;zgKfZ9OatH3`V@h8ue1$(Z|kKEg?JL-WH?6KhP%^unO3I3%wk>S z@OAI(*R3Tq2WG-V`ne!v9+^&60%jZHNOLdl{(Uq?FYr|!)^m=#?g=9EhVV@1M6N<@ zv5-J_=^2bvRJ}AAKBYI9h%Bm$r*!R~4&J6nJ)a}UW2A_6EcEE_y}l8mq=sado?i=- z3k{N2mt$s@Ts22wVriLQk~Du-(%xYv4-ZO9S@=#`3XC9a8bUfC z3+Wx?ytJGQCq2`bv}P63i;gUw*+o@H0ngm_-D9b7LrzFb#jd0tD0j?bz9q9O`CizK zwCpk0@WP*bZc`uMpM2Ix(qrzVnMRVHMaD?Ws{y1JvXdqvPSVoDe5$k?`FF^8JY~oB zrR9Y=bz5^A!>3WBj5BEf>3PIkS}OG+&4EOdmeszbDdr3AnA?u1M9m^|ao^2l#Ua$v zveaDG>_qb8W{@VDj?0vbyyqA@A?FyrA0HRb2nc+1%)Rq-pDIy zabb2?njyQSWxTn>swVvtRV*zMl_D)yO#Y^6V_8Ja1#^k7Cy+OaSzG}x%@>C`Ze{hc zS2SM}X9l`!JdNx{NmI>N9y6EqZ9X+G8k1Hs!xUeEd|A_HvBk(on@&DvCPNi74eFS0 zscLR-s+kO#OrNzew^X|$pIYnaDv_2@8%}MtCQb}Vw9HR zv82swlb&|$_RejuYi9fxGunyf)C0}MxdhXuxB1H2m|9vMnR$HKTyFSiYI2)SziB4b zYV+;)%xv0k#@xLLZ7wH}euyN^Vg~G>IoqrS)ZBA)$mS#VIPBSc>{HEMbTD0(#Z2-W zf6%6GP14VeNYl*GXIAnx&BD>m;5{x*&2iK9n+K7P8$i0oT+g92@|~xXI!*e;bZcA^ zHI2+NIndQ~(^n@|BXKlHOA7~SA2Tawn49!6Cv6`}z26MdfoNRdTaYd>-FMQAa69t_ zSIuqYOy#I%*6`_Hadss6_*C{ZHxSv9qmRsaEM~@)HnZ}u`L4=l5j`+N^4bj5Gt(WF z%}r(u<+H0DcYMO_p5{Es=4x-6x%s&ON2{8%-(?|x4coA2;Is_7L~qAUSPRhG#*`pXm(P8F zTZHcPft+hQVxSKdH&8ErGD+mF2yvuH=9))|K?tIrEM7ZK`+M07Hi7P~n8lEO7FFox zp~|1kqmfFHE`W*3JHBFyGQ2lnrV`&2uv|eew8(AB-pRjToVhtC@?Xmo3*`+&7C4Xq zTCzU3U-vI=s#_bzK1EET7Z!^Zein;e?hrSb$0x-Xyjy=SR^c_~W?fydPU%q=^XhrJ zqjL1TMG+Z2Uo#}0p1(1iqD1lPuNR132u*Z-M!Vn!F0)YUDxfj0Ov1uzn9Q-=x!^b> z5wu9XbkKxHh<~W8SYZx?nwM;#jgz^Qc0P@(D%28MR*%=}(1#!|IGljy2Zo&2a+SB3+n8CZ)bWp$63}C>h{Gg$O*&-u~ zI8p+$cYJ0CUvdr4w9=U-fhKN=2CW=O%NjX-LF+C?fXx|wN^mdPZ_^^YSSV=j@0=^v zn+HPaEsR#>j-H@(yXOEMD#D8ZlEja8jx5>z6HYPb=8IVhV1dZW4K5U4hXYoNYK;FH zaU~02t;kdwfDJN5whF@?uuYVAbjhCE-hcD9Hm@q0Z3MUgabw^zD&1i%7Bspr&5?RPgl+*0~RaAx!onoVR%q3RR-n;Y*rp{ zVHrw8Cdd}0jw5SO06vQp2r6%H&6iGBzi`7d)FJfqLUlW*TBN2o2dq=;@HOkzDcs{; zbuo9fPwntu)_FdmLwuBYP(S$CB7?th&irnJK%?f_L1VIT83|cOftJab09w|YQ7G5S zJ`Ip~mis9`nLW2cUcR)-O0x(ivN#&e=0tzwM?;lOS23?zyh{UZ>)#%M6R^GHL`-f9Zy;3;g3V?=4bd4hNl1(+y$@)eWBI(WFQoGfm1hv*PLW&);)7H)tv z@eX^D%fx!lzL}rle`Swn4d#SzFD@y2N;%NTYgnY2S)Sb(h~TD zD|lxxXviVvSJ*bZ`$gQ@J~}Dasy{7`;UT{Es z3$R~oX2cH&KRWrKsO|6%4Y0pJUzNv18K(AGQ5ngmzZ9v3A&pb6GMFh!{YijSWjB@M z6$>3aL0L5vFj3jbh)zkOJKf|^>aupHC`D*FRSD<`n5L}aWy7g7BFMOJwc24Gs4BsjRh@Hl>IY4sXu7R1I*~^Ygub`OVfq*4lr{X-lNMKt)nCV zura2MgE6~o(jpGDskrS(%Ms8aKZ~T;Qicc8$O1_DpHLjSuOyWXo)#Ku7Z>|8^z?DhUsG%c!gip!8>F;)p2K?S) zU^Oqu!GHOJMxU7s8rPkPR((iI&_N*uLFbBOE@w54gFhnz?8V^rUuo>g?G~s}7qs~* z#+;aLSw4Ma%yvUpfa7_$mm~M(6jKO_TJQv`RXfOxx zLZmR8UW@*$hL0kF$?`>%akR@BE=Fw_lQT=h4O@n6^>e1j=!RqFkZjH~J4L{T)y^q0 zxK^E-73-9#-l9SII&~}8tPv7cD7s*g=)%!OTJ$ZFzk1k)GPBpjZg_jPvo)kmbi1NO zTDNTzTdYW{)@@t0E?l%wblaju+qRF5Y1bZu8wOvUnO{tC`WT|0nB|;6DD1Slh?=6B zvmv3Ya|yxA`H8T@S*>_^a?hY2>Pk0&69vjd^9GlP)mv}P4~MJ{JdRuQhooU%B@ch%e3 zJ*)5#8=dy7B2v_IE+O1^o+9`Np(5Z7J zVgVu{%Ozx|9(w_E=ry3voZUG#Km_J3IT%8gaY$s5Wyf%=$fEk+!`F^EdO+{_uCKss ze!IXMx147JMB!Ld709o}^{XHrg8OvIq2eZ)w9wE>Md})uV z^OnLiaW5fwhV&Me1oz^TFlxNP3f$w@(!^NS2_~hf){L$=bluDLhw%`>cdtpkm*Jmd8H73%ybb@d;OmzH?`sVB8xJ&U2R`1Y;#`|uL^dA$ z2UN{%c#r4ZhQeZVZ~6XzmeTsyQi^xS4DC3ZX4D%8z9V^Q?5_;IvuSQ|)mGv$)o6m* zx@3@Dl zp055BR%-43!s6keudOzZsYTHz48M3da#}2wgugK9h+!v(HNRGEx>`J@TWDfY$E?D@ z3^xcmAM(^1;USONBRM*3HTXGv$YKnx0=v23<1xcuJ=<73(m7xlH~ld%kG##IZon;azi6KC}maW?yC(S7FH#zz3{eo*^4yYy{5}7SB++-D2FweaAD5yk-=i z20om;VGPFY!ZQcI#k3jUo#(+1CYW1&bR6toWV0I^P-E@H81UINuf=h$*je_|7+&f|Hd_^E!yF>4Vi$C8uSLUP zWick72fy40!gN0Gwxd)TE zPsoGOLY&NIG^iV?dS!^M8RD-4avyEu8x(DB!i-X+Kz#tW3a zcl@s@2GoPTBzX^`71rrpioBO``4;%n;}tNS$nRZc zIbR)!tGjnqvKHg=RPfcv4-NKe1-`}*?7<>}^E!`2i0uBW%33TFg?F>he6T*M(7QQV zi_zKnGeY=?<4&KPBFt|gQrYnC6Jx{3Hl(k2U$PdXnX^t#QQG}bM?AO{Q^6Mj&N(@S zPstG6F}-(ieZIyLd~o#M&#VtLwsiu3a2IMn#0W&o@;-bQd=BHE&ESvenb|Qsoo{oB z0`4Ak)w!HdB^WcDQIVLnDz3NQS2=4nqZ00;-q$`LQnidiIIFyGCb_fJGjn}+|H3vK z8I5*Bf4>9xrp9XLut*VW?}m1iOY<(Ka1Ehv>chB%!Wk{0%fcWeD5-d(7CIjJ_**bS zKNSC;5nE`xa0q41XFNh5aqH!j9!LhS!y_tT=AHM=5o%wcASAY3H?E zVw!#3O(=s!F@!RF9;(yk9WIh#5o#tvgvnb%JEi0GIR#y$h2HFmM9XwOU6!g$<^&ylMl`)(1b#5F?K~DEP!q48O2K3F8 zD;}6Qv`%h3-duSDm*fbokB;iy!t_O@(DvV8)>0XS$7_YQF9e~L;=mglg?7w<&{|=v zJBGeF2ceBA^bGyn143I<=pTBhC}wM?Ji&X0hAv?o+ACi?EOjiSL+9fF^X_22C_VHt z?tb1K&4(6-&boq;PNuLjv_dk3&Ze+2^jZN3T})v|=x)||S5r6;syaXA5fw5wV2JuC z`4I+7sM^_CEw6}mXAXLIS1x1WIomnM=Y<L^(KRFc7G zzKGJ#R$w9~$)#oTc`K%QV!E|Xk9@+f)s+0g;`31~hH7YN-|P@Ri4_pi!(Kf{_xo&) zSVY(fWT(#;b0|cFy+_0G`TFZA5mx*##=iY}OoUy22kHB-=ajHS=h%G0KXVP5{1mq_ z^J_J1nsY-w(W%q{MBPUySFybuDL!6`FYXJW=c_}RO*x3wT0*m<>-hL6d%$aVZYpzxejN+*AXCT{ItdQ-2{wg%p(FZ02r-4|&=2W&Ce#!P zhw42cgqcFo(Dlx1`9*@5<_wGyez@w#MTw#Axp5!!$*cT}wMPo){wQ>p5EQ#_$QP_v zGp0I!Mv3zFGB~+>!!|&r`+39Zm16PLyU%v4JoEKG!TOqPzTU#(=V!7L(B%An9fYx1 zonPQu+I|ZHo84rO-hx4}$riy!Rlg9Ez1$uKp`5`w!Y@~-4^p1@GUxsR!pk1z#9&@i zY5X%6&qR^88LM&L_!S`UVcaMQz7TmYBYg{OV#xa%*=s`|M?TP~yd3%>%gW2`CLYW`_PvnpU)VGE0AC5P&y&UwJo#+96J!^nfOGH~N{@Hm$(VIiI z8vemEfrg5YI{qP4Sq$Go&NT%^Hj&eLsGtZI-<=N&iioPqkf;Fxytm{#g;EfH5;r1D zZpDn^S5{bqg+=_zie2rY4Pq+f-&zE07)~t9uP34wI~x=dA%%D13>Udd@M{utrl@_$ zV3B_Ta`U(14lWoXie33Xg>!i!5g`gXPZtut?m5?Bxco$}!dUA3P)J02I?#$lr91yK zXMuChs2JfZf}Is(L`+06#8B+w1B3BL%=+kuObEt@A+d`~O~9Y%rOvrABD;q<`5sQb z41eN!Isb_fJxiLl=H2u$wM+YA7E`ohdvUuHAkO6vJa9X;#5KktD$+Rxx|bzxn{z;6 zu_)W^0Wca5CGNCbLwo?nUO5ZLVtsMtpuxDsa=;vO3&euVSqE^|x0oiXu`?xBEUz%I zCMK^bioqh$Tx)Hg-S82LOdDUb+l-9)cz!yXq1oT_?N(Z_}h+ zD>oP;SZ3?!oKs4)5+kRT7XBjD8Bkh;ic-#!rG>9+HGG|*W{bd&bet_pi##z_JDQRj zoJ)G*OA~M*xus`_2f0v1dWLo9XjmTUIr$U0@VwHqzjH@v5t6WYI9}#s(=;`rfR$U( z)SS`M^ByWi&1Tbnt0D_Z&$LaPE>|JxIp+z@Vq>JI?;&Skf(U4yjPD`TY;n>Enh(ac zh;(m;%uzEJ{r$X0F{upR2#r=;#;3i+&WbalQ@5V0X?33x6> z{bi`BKSZJonYoU8`6%t2>zgdp zr+y&6?KSDK+0^Vp$>8sM;TLJyj{_LLlyXqBCogGQ1=0pc9%;GSgS?x49ECmjI4CXU zo{^6mWKx{a_*Fw!(nx%ZAT47qQojYw8Ot>%dRv&9SturH$ybDQ2%3qsENo7FOMEWE z&xg$U1M$^|w2Z(V0P~oe)caAB5P)pMuUb+`-=P`ecPq$f>;u&!EtXZJBXP} zJDnx#8q)muP6Iz^X-yiQnKUtmv`I_;{k7$%DZH9V)z=n$;FB5k+2$J8Eu{W1N?KY9 z;d?k~Ib_EErRl~YI9#Qr?_$z#$T+;l^jR)ba}+PYY-R}DUXVXy&L3(9w+YTZX}9<{ z;=p+qPTdfn{_$%Fl&rL5pp2yD`Jd!Z_aWUIN}2=tjHt(x?{2189W$11MpBd7oTGd5 zlP^_|G-5Mp^cd<}bRnJZP8x6e+pd{Y>^(xG*}X{*nDM@tLVoZw(qPB>U-EBp z-omC3HEIsh*SpM2PQ#rH`)Ed*ZqO*#P14giR-~mvCepc~9DP=U^p9Uzokaa$v&`bq zQZWO1rnHnX({`(w0f)`pT9b>Gt-?531NRAZ6w}9DCYkvk{e#1)n@FS38<8fa>-Kb` zrqLSGlEtZa=}DT;m-L4#^%Kp77Aj7D7*0ZDQUvLze53=-SI#L<`*P+yMa;apd4;1f zEd}%cVr>rF9#b_YoV25vAV0&%&o)bO1#Tc{JCUT@oYYq|b9)aiJkl~87Z&(w7x`E- z+dH_CUuN>zP2VV;X_GA%X}sx!qwJD)%d74*y^@Xe&w(6{en!6ET+(``C)D=jpWY{Z zZSH=G`GOWWS@3HrGXcX)4_Ob;Cc|9l>eb{In*AVg5&0M=?O!L5e~)tnnfKM)S?VPU z`J0li*+JSI-+I99B}oV6q~`8;(xzs&pD>I17G{zbH?!eiGXcY9)23!VjuvY``qiKG zzFD;HW-GIqrQXh*p|E`+A1L()>83iQce9cPy7IA(*+{#XJ!?i^>JLq%=A;?X(&mY< zKbHFA8KjGDkset|dcxd>)711%rN(6^X&o~sX161seALYUuIBz~-~xeKH|Z!d4I|A1 zrr$K`hfn2;)zakK)Ftn3#`QvTYIc+)ZEU8Y^DcRB(<`lU2S=56AiZrS?|ZZ07kf~% zWtEx#b#V(pqM65Hrdi~dnQ8bunMM`N_{}%#c+(+{Mm;1AGe})$kVgN+wcV1{JhJ1= z{;>gVJX*GzyNS!g7uPUNmzdce zX7)9!c?MQ#Nc%B(rL+W9B<;6^^t&0?-AGB@(yJ2b_IrHs*tw()my_=7#hJU9wa}8= zuv;FOb-(!vr`R`-!#Co{$Mh%lHDlJTH}$v7Ysj|!)VIq{jnlM$-;n&5JQm!VFs6NE z|I=+Tpw_I6v+?aVs7pEMO^eWn-jH)$#F!nwGQ0N~Qj(Ym7vo1}o$19<;_rfxl10e| zkVcC`h^d|?w#7r5B~lowx1uSt>a*C)COuS%Jqc-~a_1FbqB0l`z^@_3mVh)%$OAMg@@*1(UUi+ z9l~Qi3{HweYq84rV*M&~YVO^|hcrCzk^H@)S=B)^4>-lOVf#yF~1%G$<`!{C_ zx`Q5VZ#)o>6)ev7Q0OGDRWZ-mJPMb~1Wjyy+~8$gMjL2~yuh+$LNA_k72n2!)(l1i zm5q;QhQ8fU`lNdWFKGG{WbgR9*(zv83YQ~*iJ}fOYl>p1 z#Z1kh-iCMKXCkDJqCZ>GCvlfIp3kBH z*E>paodZZ#eCA?owDO5Z%rvDz2Y^#K&we&t+3_8)SoxDzt|f|g6Vg&;fFEG9a@GoE zhH{Ddutj;pxF1q37l!h%(sw!Fl;W`Sx^PLkiiDLnlxMtn+*B@KhUs1961&nv<>xuT zGiB3sjD1uJxnYc(zo(APQ z)&D+Vy&B3Ux>r54fcdshy^jPn)5kOU1{6N~*d_c%@-Po}V{6V|;~@AbzjV-;Lc9tl z+@Aq`neV76S$5!Q&~h(WafwPC^yPCj1+7rs22GX6_-bF)^&bM-sB>%3KZ=$BZR$XQ z+hvPfD`3<%e_PPb`Qt#l{KJJA?GW_}0H%ul`JhY_wib|*}#H)_w7X|WRG|W8X5ZR zzro2YnBcl^{*#BX9=s~D@p~U*24~x0frU>4wg=xd=D*)J?#@4c0cb$QW6%V8u$Kn= z>;esG(G)Z+Zoq%OjvCJW`?q08a{T-g4@G?J44QN6d1xYoyZ>j{um@zH4!C=m>(0K( zfE;?F8EnI`A_u&HoNE$~xIE>G!D5W)Gy}p|5z_@QPW&7TWr}EJ z9||#5bo~qBc#(?d;n~`}i%b*?BOy%^p(sWC?5@j3NZZAVyMP_yYEGE!6uH>hc8Mg; zwp*N@0@x$cxaYmX@(8d`bWDMAzv!|K(g6{b0O_DmTSGb|qPEcWhsAUa+9RSiU3^sJ z9S!N2s5TjJR@_~IPW@6WoQkn=%0E^>igJp3N>#4%8Z}-y#Lr|Clt2Yz6O|JT+$5#m zOh}WJQQnXoik;`<6eT~q`&4D}N5C}Yl%4&~seEI(PggoI>t`q@`{IR*l>}t1eoc9R z#psjNDLmw-shdYYnx#%lfHY5?iKWTK>deZ&b0pvjn|@$39&14zw}KD;SsQ%F%LwqH zqjUcbkKbgThW=X+Y`Y9N%$)`1r(yPvF?`gh3mUvC`oDN*x&(`$`TPG%#hQ4b45&5o zKe<{R*arl%lLb|b0u8Mg1&gp!%%kvc>7Y4EwgAojilv)pCGGQOVL90I&HD!s-RK@@ z;a9ssi=JY-6>EPHw0IxBszk%Npz&$cm(0T@mO7UVnz(-?Xq6{hps(?feZ1D)Ti_dt zwV=%=X98{Bts-cP5AQ)+rt$TyJTgGrWNZd)YcIu?*<}vzg*}hDfbaiqHTVHnm=Xi8 zv4M{keaiq+#6~+HRg_{{FA`%UEFOyB;NNZvxN#NwKL0n!nhldd|GI}Vk$o-|2kp-^%b*E!s7}B&i}f4(Z;t5fp0R0cbKLT_N)+^O+hvPYKh|+f?{{( zfEF*xsxHws0DSy7MzQ45MWAIoyg|$MXC;?Qc7i4@Vk(s{%Z5~;Ka;m&>F&@}IyMS? zjb}()SyOm|uaz(qw01Qff(;(R-Yy&cg{zosHisqIvJzL-YUXV4tydohZTDu=Z(juV zZUs4b6cZ`hi`_DA<6-dC|FwW0RC5scxnkB)z-ncQHSwZDU$z!v|fy!2-qafZiaHZc#S$nkL=J6a6qKz#n@qybsVG=3=X?Mf~3tH^RpP=!H3`6OIEZ(xGhJ%*xkOj1o4=cQCw+5gM?;`=tiLZ%z zgU~nch|!$qfp}0C@LoJ;^?VjLsl+$7ye5rQ3}mqRkk6|TP~>~sgGHbJXCKh0EX>G4 z=emH8xy~b?@D{Ehb_+`*ZW?R5$edN+i)QHqzE}e9Qwbswnlkb0LCY54r`>Xk8NBif z=0Q`TMjU9xvMZsfJc*yItCj8tO}pU>LGA8icti{rjjli%Ar{p8y(OgrR~>$kFOE20 z0*^%w+YLTXU_;P+ISPSB%_|KW-8>s;q2j$^Q@AV-thiIW$`!56Oei67DBvH5;9kyM z>qBndg?6HtmIDr(Y+n8Ca*pVe|JQqepTob;!{5h~ysd0Kh-V)u%TeI}zr)IOY=#)a zCbdm;;zf9;7{~(OBRr=5c6^qFJRZDX^A=y}T`OLZ+KyuL>O6!8^LnwL-C>LJm2G^h zlJgE=oAQ&Fo9)VuN`M_ozjlC~%5f&^E~PwgYR8mAH2}wzbateFl#D8X_u5MAT8@>6 z!vWi5xiT<0B9CwdN97eZkz;mQmYzK>zc5Ds$X7)GCuD8j%1=rseR*28+y|30@<}?R zv$FAdNay5D7TI~(hwHr{pJjz~QFi7kF3BQ)L3vp|H2_y+@JGN^S^XN|nyl>ylk4)7 z4RAx+>$A1ql$*{0Zpi}3YI$4wIRSU%g}-5QR}Nyz+>`g=LwR4;ssQPMd=U(IC=Wyf z9?6mY0ncQ~Wq^0mX9g_4$>K91jnnHZfbsfIZfT1C9@S$;s=$w-(A%Sj)q}pEAM>T~ zk#e9#j?mjhFQAfT@eW>~CEoHAMEufG;7huc2cPhPFD&yj9<=N|7E3jM=4s7U9YO2g z@C9vpiSsne&1iLUI|bT#lMS@{%QB!nayJ6)nR6t)XzKfo(0so3b`#L=M zL&Vc>KZWZwz)q5xzb|<;Dw^Sgz~-e zji2AXDy>HXhN}3r8)i{gGbcx@J%&IUqvlTmOjJwmfO48zbTlh!xf=f#;&HV-PrrZE ztC;}j)XOEHJg+*o0xqeYxpsgt~#R$q~~gz#*l_-rB*{4q0Juz7^Tfy4`s48 z;sRidmgf>+s@BsNus}Ps2C!7S6$DtN1rA`XuGQ*#;lYhsA|16^TT>KpMJvpNyP^3m zhjd5Vnho$k`^c{Yo@i&g0bXc}g8*-|5m6ZXpgm+)A0@N1Oq1nezG;T+77v&$cXP6I z*|t2S`Eti3NQ-5;1b&=ZDksK4yHXxxA6_FpUIErgqcUKVjPC){3>h>7(pEY79bl*Q zZ3EaNhwKFGl|dE6uk6n}|0Wb3{n69R*7)lq$p6{;{_kdI|KG3XW(|4r*F7@uuljg# z=xSDS*yBy$b1h=Xb5Gt3O`fMb#fu$g^y6=Rviy2~wjcC-$lt8uyq61Mtk4w{_ODs5 zP#b)91+)>t^Cc_^+vhA0q{=AI}Pw&Df~k2L`s z)G*%pH>$bvz;d&iaTk!G)}_O@s$EV)+NK_3741-e^aSiw4`c@HR{!EE_NX1+!(^ZO zY%Qey>cj4UgK9`G`u~uc{sDtW)PW4mQ8h`&;C1!&4M;cCT!^l`rLLz-ZmU&0VC=4X zqcEg^P`2<>rgC`W4VS3_E@W!?a3jdq%4yH0zGTY+4!m8TOnYWK54+N4ce2FTEA zuqN$Wv~c=so0j$huwCnP3$RPu%q-lkMX=!ZYALaReOd=r=mD+&3cx`v2al1%+H^Ly zBU(cS=9p&w1N!5d3$F+#v@Z0;No`qHNT;=!1AsGH+HJr&tsh(8dAs(2t?Z)Kk9BoP zOJVQ4qDdyzRc#T^t{YlSK6q2J(NA}@b){i)S6g2U(tR!28}LBu+8Xdk^JaT|tkwA& z@Kk#n2Y9Bv`wV!Y^9-Ssp@TkfUYm5-=Gn zyYPxKPEO7YWvcAu1dNwu?Xl2Kl$)+YoFp@tNmFFr`GBc1Y8}8Sy9WZM%QPMbGx3-C zcpy!#i-9y-Hth$PBX5+0GF_f!nC8iwbs;T~TUg`^WfFI`SWavSSR$9OaV?Wg5-_%0 z_AAEvTPZ)B2dt8zA%HdV2wU%3`HvrL*2_P00XE1XOo&a=wh?2SrL8EWEwZIQV5@A{ z5X$ZH{7AqKIrAQ1x9mRvV|!$DeMtLcE_!{xtiVh-D96&Vhvdj0*56T?ttzy~q+=W4 zA322&o{%+I2d8BEBPdVHcHH4v`Thx{b25>A?SgdDvlnH}K7h;8Ya!r@%<~u~*YQvP zA>ELzSqHb|@-dKZ%fV|Q-Id$u-+S^Bs=|(I*L+sTL)pcE&11QGCZs2_FnjwmIolu7 zbNP+8`IquFm;XvmVq1GFYh(euldCsD`9bzfhxAcSW{rK8-&pBiQ*GKUA4|*!!^hrm?!|VFNtdLe(zgLH}%G#JI zu-5waA4u!0>)A9nSWk9>a-(%9U%T1b)jk~B3~MnB;#O;Mwuo)k=}A!Tu&(51ubtMD zxdFSatrkJK$Ex$Lwa+?&J!QYOQE9+I>i~xGkacP^NJp%5JOD?n-Mj(+Si5!voUp!R zd`?@7@y33}+Kyf4ytQslHo*(l#yo2-ThrCqA2Cv_N$ zvE?qUczImuGK8^T=C&VKz)$%|* z=Cb1(q~k6j%!?B)M+-qZ>5`WPd)g(b5u`INl>#80cR9#~UT`u0jre7kZ_^-MaY>vF zxaM-MB;dM>9~0uH%b|^cTP{Tk;ki35kzD|HUG}gA-gn8DUMIYHA$F1OAC9=lvQ z33%!s~x1DE^D}@p{`STNgL++au{o5xNAxx#F4HKE?{t!YbGDS7}t060ApQC zfEtF&2Vz1HC?LdE8xb6*gclG1@lZ@=2qn)OqRQqVYF7dZD2=R<>ug=Yuw`YLAloL z(Otj>w{wvI`$o5oVZhC9gHiw)ZgW<`bgSD$7WFo_O+1r#xUGH#*y%RnAYiv!q5FV6 zZjI^z_PJeUuI_gm!t268w?16qAvbk0q$6%6m|aKR*5`!ukDJFJzzMfJeBUWIM@LAf z?QTh(foI*Wu`!-=%i0yv1-EXzi(hnG*8=d;?bdq0E4Qhq0B_v9S_9s?U1H|HcYD6&*X_Lu>4#e@ey$j5tCt^;WV2tK3mk4+ zn~cE`HrLgVM%ixn10>sSu7h%n%~k}`SlhzSfE3&Q4uDi!CN6)1tuae`qHQ)S&S9Gp z0GMJEL!q2zdtMUYwDCVokTY%V+5^&Twc5jEwygp8GRHQ@&g*2ltsvJu&$gWnZh`Im zO~69i3wF!JwmXdI5?hWMfMvETy!kD+jbYBLv_0T`d6linBaE%F{hJ%oTH9UTRM*>v zF9B?@bu0?lWNWn>u-O*40w!B*oueUbwbh!(^I*HJl?z~pZC@_HE}NC1+--Zv!~Bfx z2HW!$+XDvXp)K(Rl#gurrvo0_n)7Dx#P-A$@YL3#6qL_w29KKOw$z@GUf8;p1H7^| zVo!K&Tj>ILV;jR`?5%C@L)PCrTh=H%@!s}r8MGg48`!Kr+DbPB{A;^c3-H6%h|TM}Wi z$h~+rz%uteXmfVC+}-Cdh^yR3bM74;aZ@e7KFQ7&bLjawq8>|Pu6VW?Qo5MT&N)x$ z!ywHUzEwHDn9&f@LgC>DX_4??Ls%?UF@8(L06xA{l*@p$OcY=dEEjqC_zE%E-U{MM z@rX~X65n|wtrqQRvs)a^4%j0`hXVGBfqh`IPx$%*_KTz|fCJ**H^4zr@Ce|L@U0Ix zERJ~Kfg|D!8|P6WwgZldLOeZ=i|Pdd|A?AwXD39;TRX&)V#OT5DN&P&ep+Oz1~?;T z@Oph#jNnc9oEWeU(s@zf7~q0vxCwAkWOHKdl33RS(q&PdC2>Vm=56z;xL+Ac{Fexu zAYB)gm{T{z`Hg^^BE}nIw?vgh#{ah1IUL$MqT)1Y?~3y2fcs+QPQU|^`~>h&bT1B* zM`HG2NRP!qww@;9?Xciq${k?}8siEZ6i&d=bIS{;wjAA922kri~#*u4rMNoma}4^w7P8m{Eyi$*A6JR0mHmF3HUqZA95 zpR7E+hr!W`TVKE!k zt5yLfD*;@LLkY?Qn5z6-3YexmE{idz(wwtQw=0GY?F^+yU%*Tyj;CIlva%y!mJ-bx zo~?Lt!E=-`xYNnG%BA|SOjoYX1I$zQFfZmSefmRMpcE$yo-<)ygQ=-x}p6^J1;CdI4aa z@_r1))+@uu12!n%*$y`wtfhs|@c6r3(+3lgc1Aic?C^IM(0kU;q2s z8Kq(#NN1JU@_=(naR&XovVn)m1!c`ANEeltYzCJUSH9x1QoS9NSCl8^G(B4=T9hytHW4oBh(T_ zA&pem(fOm)s%%2`WHoUMaI~6H4B9d3o(+)3s_t0<sz5nOUC5(wvU+R)z@b)W8BI|I*EChV#f45&ukg%wsuOrzO;_VaL7HJ# zi+6%JQ{6Qekfx4j2G3IKT>#8hMNKH@sF!V!=Bl^)KuTB7eS|bm&3p_nU!Bg2%L28{ zY`{WwRC&N6wdp3nVs$sOdZ`-D%wMK<42QH_ov;Y7Lft9=D^>e2?r@b_r5<3l`h%NU zqprvWSgRi5akNfd!Va-sJ;Ii>K|R8)ZB#SIK)Fd3e?r=LIqB9qQMvfSu|IMskmrOtpuY7y@Du)3Ug-y^Cv8_J_^1Q#I zx@HDkRcAJZ$u+edPulBhIrfViYM(oRo9YersavYi9nx)er3G+DO$h|tRU=Ac?4G*6 zDgQqCzM90d`GMMn!F#CYTLbBly0!w~vD$AO;E7rz9b-?`;oSB!)j1x@=jvKI|Al&N z8{nlnBL?tFU0xClF&z_=X9SD=D+L3IKrfHuzr&D{t z4l!Np>V$HJR+p`Cre@`hBF(Nv@mQLrZJG&jwidAr(j2Xv71CU7dn-ukT7{92=4q{1 zBlES&^Pyazh2;e-)SmM~y-3@i23V}seh%dltt-oSskS>6uuMzokFn+2mfC<7TJIcy zm0B6r?JCWllb&6zHD=pdqvd@BX|49TKBRS87)y1%c8m>bgU0{#4qx;i?*-VTJ!=o; zW^Ho{AVbT;+TNnAU?jI{ADJH8wXvzN+@ak(4{4`1h;_S5i`)d*t(E)>V|%pa_Nox~ zYO8qA@6$#zY4&U5%0W7yeHVa(+TE5=9@1`b_lLC=jQtVq1rO?@+WW$gj%oSmuH#xw zv*I)-gMLEGRuFJfJILfdrKx2Ar?nPdiWxa9?Zf&hzhq*478&L+vfQ$Ro`!7Vuc}Z3%dytt$_Bsy& z@i*X;7K-!Qj=zfV;eq=_i)jn^s*PZW`leYnL;9|%9U%RyMfL;y&@2N0KedXPFg8@q z=aG?wf1Lp3Fd0P4;c_;g8zFD8j7G|K%!E;LI5Q|&KIL9U%UwJj#>ms`tM;+-uOh&4 zGMts3BF`oOQe|!4;Ks|Jmmy7%L%55HvO5!El03^EI9cYq0m&h+Rs>9u?VQ3KjynKYAg8h!ER>gK0T#(P_Q%DtaBsj8Iid}oTPpwJCYH%+T*Y#k#%{Sn=9&sv zDF;^rtitCxjIEZ})&bT?yAQj;T6vgvm~}F^C}6$p^8v6ydeUth<)6%*O|t0=z-H;P z50D|}(@$IEqdtJG@=QGD-X^zo18kRP*h_ZE&WRY?DZ8>@cgcJfNW0})Hu*jB5_4v+ zd}#jTwtaHv-_Y)t^LURuAYT;&9F$k~!sd|N*A;MBu5JxDBJZ+m9+mT{JSKzL`j5*H z-V^?jGgkpl$|meZr{vrbfYUN;E=jdCx+<&E&(~y^Fu-+LegnpCNNfoeCl%)UEt$ac`nHVqgLFqO z;Fg=5Wd8+#*Rln>&l{;l0N%=f3jp59{9NICIjAH|KFEq)Abpg} z8UjAaev6>|jIYitmPq_X&ed3Gzse6cq5URZo&mngOkC5y@>3+>r!4MFAA&DyL(*Y6 zTt9dP$`N`pgFaHv!vr3sx8|qrWc_<(NTc-;OqMZvReF7_{%r)Lae6zZM~c3ZCaHRk zKuF{Dka$QF^s_u0C+bmNP)^b}uoq0$m(K$@^cnQQ6n&uiWx-T^Nj+$%=~viFo%&D~ z{B%7i5->wgHvlvBO?NPsrq8Ven57r+1K|JI()EsQ0Q2U5TmNajI#1{``rGM{&gyyC?#}6fEW`79+I&bC^y%dwUDVg` z(tk;x>j&j!ecMUE6+JJDD-%#zQ#^&{Ym{+youst+0ilW+RJT_AnePI3{IAa51G`J~ zd-u-0Hwg*pm2{Gjgj9MUp@cvviS#DDix3qA6}j|YLS1?dRk}z}P?=1r&{kTEapbtNi1$K~)(#hQ3 zBzL|GvRR&61mPBWVJpa1>10-IlMi!1w#yHhq94m@e}e3gLDcCJ*|QVKPWga`&r*5t zAjmG6wiM)3$t5gtIz#d6`-n_nLfj8pw6Iq8fxZ^n?{5cv`AIlwaDE=WE)Bt%RZ~8;{ zr@Y8H;V-$I+4xlIcR`-XHk=ComVZKaNf51!WP?IU$h0CWiMdt%(3TjYFTN&PCu=(*O>}ZVt<22@74C* z^uZdtkqNTa-e(hPuCt#S3bNilpU2w`_F$UiBYW$eARF!LM}TayFXa5T*^U520NX#J zv$xuFc%a>8|HH*bx7+t00QuOyu_2_N*q^(B?6lWl{+8OiybrR=9?r1*)E;;gZ(;)Mu{Yr~`?J9?%BlfPGmqga_>p7{`a~ zsb4Yw4%=JL1vz5R3q+mg_R~Cc{A2gwvGIl7&lB5T+Lz2jX{6(}4P>Tc*}EXK9Oan@ zvmKu?Dd#wPa@v{ec)=O2PBcLdTSD;$G{fvj}&UI1Z<@PaVT)na>>8LP2&rrnBEYj+hxBpF2WA zK)!HXV^-{S{KUlD=UDh0WWQr5t$o08vJtAd4mxVkL5Cc_&IUQ`@Z;~eBaYuV_a1c& z;c@qvquZAt#~q6~vz>5Mi2*t3_^AoVDaV5hY&-4vinGs`jwcU6&N$ZH06FV0+ku>O zRN&dpdB>N`imx0ysr>~LtfNJgi)HWb<%z#gX_Is$O;2IqQAxc#r9S z%@H{S>TBQaEfy)rheRlubIL8o93Lt zgX(l=RcboJS2{N^_i_v*ui931@+M&LJF==`3Ze z&Uao81X>n19Qh-*UcL?p(bC(iP4D z6+kvP^LYT;=&Tow(kAEqBOqIxZICj?Hs>;C`d;V3mLU6_iw1-2clrc?9B}?{A2km; zgBj$9oQdTiJnT&3f$NBKZ55EC&c^j2Jm$O=%KSU-{G0RK3Fm0GebV{92TG@$`#Dpb zcDAJ}zjQtg0XgHW?~f{Ho&CmuoO5PyVm~&Poig3(gfB??q=zCdVb`C3@?! z^A~D(#rbnGwq11=E(Q788Q2EIbqT|sU-yD=bcIUSr) zZ#%W$LGCyQF=4-T9%dTeb;i#G`OaCHbJ+LJc{Y%H&b~z;KREyHhHXDO(>Su9oDL6= zpPjRZgZ$#;Lchj+m(#Ka^no*(6V*d!!?Pg2I^#Qn{O0Vw6;&TOfAj_U-C2vrxW~?J z2_SzsV>3aXIQz9|V28h)(>c*Rb#7*IJae94{{8KYsfW^Y=Z$qJ{p0LNYrk-Y zrlR!H=}O^bKho_GjWNpY4l{1F+v#c$j&Vz(NyfUp{w{>$+%EH!VxpVxFDOlN`|2N% z$!>w`A)Mm&+Zjz$&q~LSd>is43vx!4!v{=3IilczrrDxCbbycRGY^=OTL(L)PH~Mu zA?*v!ota6T5~}uM^7YH%adkjtJ8)2MCc@jdIQ0*yKlfF`Y01os>PyCATMZ|V4vp&2 zzKz2+L6SeO6Zj_m!d|K6{RwU0H;j{we?K}dAc3h6Si@BdBFOD|y6S>D*zAhO-7ZGnZQXQqme(*L)W>`ULNc&Brn!G-4u4^Zaq&v2 zt{WYvlgK+53RY)77^G>IpK~-#6m)~bI%=myU`rq} zRkM6IA8cv?SYsl~BXFp*1grvU+X0NRazQIi{@NCeB!mvvQPAw}mI^;odIG0%7QS%= zzTr&p5jYrXR=Lw`^wKi0!Ri>an#^YHzDCL-Y?5n7LX?V>1>d(h_%uW%_Bb{heELrC zb~%9wlEGHpWjFKLOG|B0I=8wtwAwT5td)O)I1}Z!dqZ!{lI#mbV{TwSn;*`e>@p|` zD#~IDAUKWM%3gD)SmVRERfbAPj79)2frF`LkKu<0%lDdl)>_r|N1~=V0@raL4NJVQ zsEF|-BRd^Ivmvt_Mjy^AND$c68c_sE5!~Pw{UO`I=TZMcC0V`%qJ&dyL%t-RL>{XQ z>u!~UsFSLYT2^7oa#YADtKg@HyH%`?8vc17K$?6RyZOI?40Fq5!iv-0FRXs`fxG`|g&@cHL!BeaM>(LUk{ByC?Vp%6;XdX5d?p z_mgQ8z_&&m;M1xd;C{DuTOiMpb1;dzy?zhv*Vf#v--8-vQ{C#9Rf8&aZUcd>*FyB- z*0qim`Y7GHm+AIL1yt$9_O0?Ww$qoqA@`a~bZZ#Cn6O*7#v~OWLfxY=B!rZEEMK6L zGkZf+v8<6*II_6Mk+;f=rklkY8Z@vfL3zcom8x%2Q>tW#BU@&y=yNz*m_JzPjAA8hq77;IrhPJ;7J!Thux7 zA6VX_#x?K_xtdeoZ?+P3(5SsdjJ=UVu~;w}uE*BfB$-iH5Sv%qdm zkNcn!9Bj3C`x)LZ>a)JT;myy8s;|Os??8!RL_aXs*{#W;gQ8gu#3-CM$&F)37}-L1MYdaKpPbG6u^{Mi}1l<_L#1Gus=LECEjR z9$WEMlNI9(@3$sE?C<=y@i?qm`A-6OjmMgm%@>lZf|V+x%->o$M3@|l461HEP%5@|QewmW2DRW$L)#ug zEc@Q9=P>dQRXc;qk-w`3uxbR9^=rd)5 zZAdn(TQ`NMF4}8PVM;>_8A2S7@I=%8#1X24Qq|>Gd6e{5$~{o6HS0}DGo@CLdJ0S1 zwSXeKvVpoPs|8G=BvIkiI^_4J5S^8Yx4RQBb4N8e&@Zc?3Cm`z-)#@(+0`6|eMtbU0Z5hfi; z9IWDILoM?2YZH57F2|=Sm7*Cc8b)@Yq^)w?)m-v<%8J9-i%XlV%)Z8h8^%m0?ocEC zO^vv(^70iGz_)SPd?fcuI{ma1r@!Y5O(5o+E3utrpj7% zlt(iZ|E}sRN!5I>6YIbmz@G|;iPMOmW1d5VH6sQLCeFUsm$2XLP{#`IlBmqyF^T*i z%HL%l);%iX&Br-DR)WQ`25SJSHeaWrF3qMI%~GM)Z~-?z z$so?_taxQ)Uxl?)2Ok7c-bMNKJLSvtY)XDq`?gl$xmDHSO4nEyQcb-jUC38gd`;!h z_9~lPpT5TpWuLHC?<#S!i$9ZaeRfbV?UUjL*k{@j$M)y#>QmC8ic!a9? zhT8XuYP3*!x}P$&^?lYaKZ>{~f!ILJ2N6orUqx6)m9&S|!dqIb^37T`0@x2be65UG zTcuVV6^t%5vf0zQ^_OsB;2h#tDjH@hOSDmz*rvj{ql$p$YTtdzP0mo(S06CcIyELA z6{+I?59NtH%InR>al=|Q)}BghMc${iVfDfcQQzNW&>e=+&S z?TIgyG4H5GCo1_9rQBNxI-6Dts@Sx(h%KA;4CA(GFOa%6EvqBGR zQ8o8`Ma|^@Tey;wI-RAs|%=Fmu2MNRHM(w$S|XM5w~Mx>i4j9Caq^%!(qvr zbd|jU(Qy*9gsKtws~^hoKO-o)(4q&UW|TP65E_mXH#m&(VjUs?3oTk1$`i%L3MefS z>#|TE>KQk9WPANRdE>y;j! zzjbh7L-0-pY~<5oU`j=HUpt59X!*1)@XdJG534TSpjEKYBCWPZ{9O~|OEDF`z(R|1 z@T(S`RiU=wbrA~MD!qrMY>98db+)7$2t-?Q8f^6MLW}uGKrFPF1d);Efd-89=zL&? zCnGxZ-YQ^~foRvL+OIya+L-0QoW_ihJhhfbK>=gD!{hG2UM=XZfhT=|Ll!ciN3^90 z#)+>v=M)Q_ZO;*ZGVhj&Rm`Ie;&We)|6@@R{a~R*rSMLnG%giN=ruSj-D>XbKY_EY_5HmACE{YLU?UG2E2=cx7o;JQG)DuKM zh;((P@kDqt^#2rxy+QsGEjibZ*V}agnV=tt0hy@(OyNAe8&5Ax{Q$e4udnC9XN~?Q zZL(Hx8Vs^dU+x6isUPnTQmT(-?CsJwWr7^hFHpmydJX#IjD9zUp1!Pq_5sKZy&}Ey zjeaQscvM%n;K!vlNT_ z>|>_r77j8??0*wvHkN1snJYe}uNH}2bjx~ihmG$PYujU7YOvn1JktrpeK!Q~{d&N- z+t9LX5h(CW530KeL<%3<~C z*~k~wfKl5y#OQ}m)5wfl@~TFhddx0MK1W{L>t0Wwv*HOzbz zX!UWKlopH5Z-C4c$FLD=Ieo&B?H1ERK=z2rOv2B__T?a7hMrP`F7@f291GM36J%K&V(VH{i z@Tv(-I!{-t8JcwLmgBz z%xw^`g3FEbPWW-OTIS(TmG~U0sIs@lMnmSn6lLWiP9`CpIhR!Ui;)v~Y&tONW+X7W zKHd20v&bRkz*h>R6%xyH228rQ9GLodM_}d=8lrl%dg!mly$}>?o@ThzILjhVhI(}9K*r_Hh z`uZXaudKg+1j?=&t8zeU_Gd!WdYc)S<260_)kQ0qf7FB^%ss1I)cT z7uZloHW+y`I{_QLS0C7XmaPDqy=#Q-H6(2Mvs_{b`kMu9`6* z-CIor_R8lLE4a`%Xw>l4oN7`Z&H}#r0`pH@z<;2Y%3mg$P{YllUq_HVA|)T>lxUL+ z@{O2W4&;I83-^|d)=6unTxOf!L-#>QM)h5 zEKz+0$O5sfD#&ttoCjo;Fj7F)i$Z#5qwpUKvRz!^U_TLK`+)2g8=8Q8A+BYC91>sA z3rEF6=E!L=lC#WcyebHqI$ge`Zs{KTK&RBga z-lt1mitgDUqxEa{SL19_QXYZ=M-s5r7c2iAeN#Fo@YDZ%AIIoRwA9r~pH{G*s5pB; z)2z~8a;-xnKHfhtMwCwKWA!R$7QZXsD@}dZ`hLLdf%EE`Ge$|LX`60c_5b-W^dDAp z`4~Ctf4iqPTMP*>i+k&`bn+Z)tE#2fPgvL4{@43x_)v7Dt@Q9^>+w`E65ok7qAizC zz4~tQ3A^E?w>@p1^$`_Ib%)`n+dUiLj9!-~&2TrPVoHl@aQ}aI%lO8Pr5$3^5||3h zSeC-smQ>8oIFtZvb&66qy`Ob|*TKnQRv)`iL4`#$t-lJh}<9o4XMz zrkf+&jQ|m1&T}_viFeKO?ncePo7}(iQq;4Vh%I;7b(9XtbTh`oh!z*kMjlw>Hp5)* zVFU!7Mx*xh7=*fA>c};FMiubxa=m%h!+0Zn27*!xT2c=K2)c*p!QD6B=5@q$LM_`9 zvqL#7Q2E4MRL*GOaSO*j_c)r!DnB)!l`}G-UW%s?;4ujEkw?5!byD4I=?N`XnL|B| zl-iFm{d=U{G&J07;bk9>^k2az$>X)bXHcFh?@*ped8UkkK|QLJw`sW9ve^6dy-(7KdImpQ$RPfqr=4-?;{nV{z9F+w10qVB>Xs&^A59sDuxZ zzaC;_iz()k5F?;klRN~ic08O|6?VeKejki>vS*ZjG4JLXEJ-TX}HP z7OK7bs~s*VZALYsypd{qmOL|)-ipW1Dr=}`eytEsm8sp0&tb|_JHsT#$qpQ$07G8OSCSbjK+{#nEzD_AFi#T|@K@4UX@*MTCMx*z8c^cnMGRAe zEj7=e|HMRPjQJ|~bCvR+sNe`yHuP`A9S#K&XPIHqMv8ddY!;0#6TGGNdkan3G_{U~ zmZ=BPQS-^E!HowwK@7V z4s)SCjb8fiDrOPdRDF2*Q64-P2OuNzTPm8;giY7JXhy^uajs3+fNPWntf%Tb*D|=h zo+d(EX%oW9mS}^kY)O;hJX^9KI{Wt;ds)7)tNbPvWzMrS5W=3tKd)g{VZ z5#XzhrYCYyS#RokD3yXq5*CDB3*`T)5TYlkY^NI+`2u>Gqug3zD=WrTGQy2I$ z!l-49C(Nqa)fkf5p=L35aJ%-eF$4OU+biNrEqu@d7YiQ=kX2#{)hiLg42i>><1lkU zT34kJz8Awef_vgGI^hQqO8Y+%$#nal;+Y-fFVPR-fUA5lG{OYEHII`MbwN+h)4#BS znEK}i$b9`v^I)72CH^qKCz)(I;*DHa5!;+^`B{Q2u=Jq!N-R5bKvrAkb0XMgNvFxT zTNZH=*l+oq^UMLuUf4((C%AJQ1TozhRIx*NpsDD~M2P#P+^ZVi0rXtJu}~lq0T?b} z5+nIoP2M7@e2gZ`Sm6iEshkb0dziznSD(ApzesHGH3yX2CKfJQ;wr?Q336Fe1eS^J#(+(y5p|%oKxC5P2)aGCE~9KJ*T@vYM%RCgv{P-29_p`mNxx=`(am_HdYo`N_X}(ItAhhNpJJPVViqt)}2C|UfF8V5Lzf5&mN^FbrCLWj-}23>>1@?3}b z$_TJ{tZ>0Qkl4+w2XO_r^Jeg`eml0`0{*|>j+V-JpdY{LSmD)g$8Xky|L?b>rQ$eL za8DZvVKN?p)!g@(eus=I-L5ZyB&!&mX_8+&vt-Akd#n6#4fuLGYTC>3=|M{_e}=lt zJRI08O@^Ynm#onjd;#UY(x)}}7Uccp)Jfo5pGBQOdCL6gkdcuUJrbhMcpw|sMpvO7 zOV=srMylSsm-Rk70#$mk1*_~2_gMOpH{@M2_^{ESL-2d(#u@8w!EWVN;1_kpvfbE( z^VRRlU_`Jpo^m|v2SuF;~7=H!rs{3qjrcnBhl_njT+IhU}tJP%bcg zA2lkuSAap?Zf!s%Xt?;OQINP59c%te5r4veKD?{@^FdFG|NgPiS+h91LsX}M0Tpvi z|6@iqe0;h2G5lPhJM`vfv2&p0H(&LZnW&T{dmvi$4&-y>H|FGHMuotEh&sK?`)uQR z0)A=h-5O&K#D$Q3XsD@bs1F;mYo1m&)UwP(80vikQ7K@Lu1}i7+LuQ{HfbgdtjW8> z$=3((F4wLj&nivjW;6P@k<_9XM%O2G;O@tCeX@arp z&<0YUwuWkCn2^udfo8R!y|nf$YPUxZx`N=-=XOA0tPymg6AJU`xE!fj*nqyE7dH6` zOrx56%n9)Ryc!Lc;Y1i0NM0KPdE7S0E!X0(n@2MDcKUjx#9|(mQ^(+vLh40q*5vO9 z0gp63dS;bR5n3MUygqH06}y4Ycn!R}oMP@cVKmSBG8dw%Z$sp1?G7yKzg&a~-ai2W zqWO1-rWQ6orNtOHx?Bu@OxQY_bxz{Ed9T^#q!FLh5gR;1S7HN}4aGGJ9kZTSG(+0y z?iHKpfLgp6@AWGC+AIP8D*Gy!pPe*9gVy1A@0IX^E!0AF=hX5s$DG*hy7>_OH0Bdm z<>NUhyX*tImap^!wz|vtuYpe_?zS39*KAC)=td8Sy`O5qlY^V$}3r-mU zuHWB+DD5&t@pA84@ab$KNxoA9dqoouVp0+L1~tIsCfSfoGeBNmAMRK$Ye4`cM2g}&fwx_WG zT=&Eh$eJ{P5kuoJ6_#(d7Mm?5Ozs_Z46LX1OJIeW^&q{nO4EFj3gIVa)fd_H$43$L4iEVo&$gX2}^NI@qVXN|%h39BKiRkpocFYtUB0senC0(@=qUUGm5z7Ba`S?6sazgh$T?|TP)4*5{o zdlUG&#LfZ zeqR}}!qcqvl@ZkM2u@yn>+5_L!Z-2(<{00GI@?c;^rPqU^zPV_8M!qdg~n=2^~i;- zP-vpRgDqK+-B+T}T&GuaBC|Qh0#&U+cu_8l}5X@wy(xXPtb<>#5$Fc1w>6G7~Ns z^IUVrKo~A~)i(MxBFWu1TJ%DVNadke#cPo#=;n$-IU#Zdb%_(a^TR_F+w-)>0HeEq zhzZX(TdZLNO)v-h<|tl^Tn346T~)9}79r()>xsrNms#f`eipuI_PuCStbZ0WyKfg| zg+`IX=z^|#5h@i%{)x%ex10VJT4@&S5+^Gtb}y)?WYPGBY#|nLVs1*5qZE&ykvAOm$($N zA-Wsvr$uV!f=kA#Mk@wF_EP8aU7`8)5ca`eV6&(74=d*4U0`kVHZV{A`2oBf zczoC7C^$vDn1UPd&XG&fu}QX;ouG8D~4F{)vtTBV|mC>M%{m_@d-JiPST zWqb`sB$zX=8bPAS{0Lth601s2Ud6S4QQLIC2I(-f;x*&l^3U61-=DdwNDI=m`X|jz z*NpJ|9T==Quf*>wF*Q3+&FU+~&Qr16VQV10z;nV}rNc$;&`_y&8CizEyiC*oI!^Mp znRTukVbQ~vV~0-|7`c3HMC{}}liZ-qU`w+NP0N4UvvkCDqlO5dhW$l}M2GrJEnn@o zhWk~6;hH|}XQ_)ELC?T>psKQvdW`bIhajOoQ#&n&{)YRVqX-;@)S#- z*(rBb>4t9%4}rTIyKWj=<6q#gAd0xFcpQeYDkY0J!1`)bMQlcUZJt?t%P6d@`psj% z1MuHS)yQLw`7ElA8hse9X@^kE-({A&jVq_a%%t0R&HlT2=ptL$w#d8!-Lw-!i)O=INTof4|Vy zW6>l3Ez4R@O4c;~TV}T2hQ#2%Ws*6dx@=JT<+sKIkNCtkkoZ~*?->=z1Q_0>&Bz2= z96^S2YYcdI18=XGcYnh@mUy$?BO@>L?s`^nrv)^;j#A$6euBx%;)}a$1?K8UMs{m{ zHs0clG(3Lo48}9+RaLKOL!W?o#$t^zvL5uq-entJZFciD+`M~Wvqz-WQqEzuc={N= z-IhQQ7;D&0m^FSky4pwfLaJ+5bIldM8~(2Be3o3}iD!`lhE^Z0GPHHGi5ugHJ@SbA zFfHL5m>OjxVvlPrNXgc+rEHfx+X3fKvEwDEWsJb|d5+tRLK9>-l2 zgc@$jj3qWMNBmP^iZ~pwf2;FDz!E@A-{AbF<#jqK8d_#3Nc`cdJH+V5etLy0~F6TrxP1s zPQZh;9}tUF$ITHj_{upl5I3xp@q-a~P;?b>i^6tR#p6f-OJF`RwC|MU5Dp=D*k7qQ zPPuqi9ZJF)^WijY0n!vVKAI9Ab|MPNn)|B+BM9io`{7j8CQ;p+_(!FMX%70RZU8H>J7(z)krNk1IDL(F$d^wN! zaS5@za#L^BLIkoBvE@o5siM46_I|@UHKrD-Do=zk0@c~-RPtr76CB690q-ic;-{0Z ztGb-3l5os0O7>+DFRRh-7)U;)GI6)EP*0Udd-zysbTm$*^2&}K6E;mYe@DO*-l3bj$Tsbk?*_3WK?8$pNcNFo}(S`#0sP&)dprex|yVio0rBsHc38z?F7@*=6)iulKJ;;0J5 z%_i|nm7^c3f#;}6;0Lwy5Y-uf=cCbX#QuYbdCL0pCXsKTBK*j7@=ulLUaA0bDpTK5 z1A9JJS$VHYTfGIVj#Z)jwHi|!e@coM6F*knr>exySIR9_)5z2|+}dFzanTs!fpNsI zm0h1I50%}?T@X$ApDT#N7ZPu6RrA!dt}L9bM*Kt>aFS}`oC=n!H7OsYCV``Bd+XO3~@6W-GOC(RkMRKsma<%G&%9YM#m&%ME_X#CGk8os^_} zKKWWziBn>TFI4E?eT%#l#NSsE*YqRyNF=JyP-%nJe6(M6JV1@Lu8M}LxvZlrOZ=dN zcWHY(DVnEt-l+T(A4bU;W#mBx^Bp0Sz|_fEvYCL>s}`cqr~H8D2)@- zIE?XPIwAmfTX!%cCklH6N{htaT$C0II|uPdw4llU60@nwNWC*nG)`|d5Tsaleas%` z=ymA%h58Hbu|fA|aDAq)Uhql}&kB?WpBn*;e8%CWoTiIwe+Xk4Eq8YSzB!OhOclkn z${Nu)1Z0nBI0@uSaTUJ6E!)1RqQ>sLw*qo6_ln4WTcrpL#g-U41DMnqL1Rm9IuYl_ zmHQ1Gtl3h2-3&?UYI-oOe|cc~loDV@AUn!@eG{79X_X|SNc-mz-Q}#Lu$`w{*Nf43C4-8Y@=9gXT;ADZ^6oVuVgF}X@iJEwBUBG z6`_gSxk}%iLMdD-l*YS+Qu)8zxl|XobE$jTfG@K>zibXWD5?c8Bqj~$iX4*z5_^uR z8W+_Hn7q&crv1$r$@nrDSmQm0NNsyKFx$@h4b-}qjT1R3HebgeX(&U>jJA>>jTW5!WpRXG&;0p-vrnnkKOKKY>yJZaj>IB?Fu0C#cOdO3q(_z ze4)ssRaXipXN6UwpFc>6$mg7fCrBAfTf}N_5Ukw7X?~Yj#c=ynyv7lKCL9crL!$LK zki+63hkiu3+T!;+9^(9vs$LY~B$vcF#?kkp_H2-Q;+FaTOC!Yf)&<*nV`QH z4>D0d@&U*^Ju()=)K7K?nXlhv#I4bNf=+!0nzoYxk4Y7svI@b;btUV8V;|-ER2HiBv z0A|H}%Y7e^1(tOjb&2H^by;oM(-j1Zujhhnx2&TL_FHx%&~Z;Y>fe+I_GGg$1|}qY zdAiQrMYdqql?EsTO=m~p@6z(g+t_~P8l!<3>J{Cb?A74wHk}Ks_conWe-I z++&QHhTW(@{s6Yt@|)_wc5)Q3eapqbPQOhBc4^Baa?g+Y0{eGl3vZ-l(P?i!sShmb zlMNi4H4Qkt#YEsFal97D3^B1PNU<1G17xN+7YH&-?8`BW1V-@MG8A`;$H;#boZj7N zl7Nj+SCzxQj6pe4)&WM9A0$3Nilpi({)WRjS`*qSWz+4B^! zwkOC`F^U78COWXnbn!O_J0n1RHwLs=j2Z+oQ_Sp#v|J$;nGw3p*EMYegkOj(hRR-X z7Cqwbb~Rs+{X#AJbwK>m2Bm|dISqbD_|T4rMcXbQN5qg4kfS1$CO#%=F}9A270W?R z2-6?ryr@1B{XG!AwA2)RUt5r=dg^?TX?jDo1kZGRg$uAS=v0J|P!=y#h=gY~!>z`4KY=JqJOv2P`?XsQ=**gcN_y|;6L z@6V^DCyHO$!&Fi9F32>ofa`H1iNHhE3;>xWZf^itAf^hCO=a4NNNajNO&+5kBUKsAg4t`hU*2RxQu4)6U(TYKrmB@g|ZbzrqTfxERE{p*-s-#|EZ1SFp*bY!bb#zVK z>W?hFE#74=d?z+=@5kczJ|KUI6`UGhioG1?IK3lEYNvqj*lW^a>}e!tF~}>g=?qL? z#Wcxy+yIzan~tyIISyEL1vRVYQs4Nf{zNJJArA#P!+HYirq2V`6C6AKCsgA z7|s<*mpLa?9!Phm=5GL|hjV_(T<#C7`h$5|+Ct(7QB*9B=fO6!)QJ}se?PXatP4)) z(3tbA>1D^f-UnX(KTmtF^ePozmC)#CLhA+cxp+DTWS>ZZKa^3+7t#uTPZ@QM3hAYu zZJ1E~(`Es;i%sYRClSjgf_$p4?F90fUY;|OYqvg>w%DWRuLSvA?@FtFp+8>_azc;s z139U8-U4z;uNVpP*t(dJG}#E~4f2^0QVep;h+P44+<1R9$O*%Tc0XyHqi0VUrOQE1 z8)G(ud}(BG_B(6j)&x0+4-wJ_=Z%3uAYU1$-vqf}466ll(fEP0+$G~WhKU8@k1`3b z7{^zGTs6Lb1LSKXBOBzJ5ta&a-5AdBzF|Dd1^LE^?Fw?!ST`Kxmhs|4klV(^mLPYG zcpBkbBd25(=w0Kd4?w;%dN%?2-Y8;_+%pz35q>uKf;pCU4|Ib3ZG_APnPQv84yW5L zn717^|DZkedDnVp0Tn(c$a`I6zZje#o~RM zXQ}X@LAHpa>}{)v^aa@_Hf;piE}qdmABzq(Kt2)uY2}@w<_M5dv9lk@Lzh^T0{UFc zdl%#%(Rd-q3(+J3)tfaW4#*Ne5QBdv^dft8MmV>KAadQS|WOZOtQE>VyqNfLUTaoSsK&E8!QXy>ywsU z@gS!x4ZDMUWm&?(T(E5BOmf*$dn?FoOT#dbJC^V1`ClyG(iWqwvuLid)`N>d##^VX z2AN>}ghQHS{c!@wTIIaEy!(ax;w~s*6_X{KUxd z82cD4%Z>9v%$t?QyO@xSHOAPHAnOdZgy%-1Kht1~v7WQsHe(SL{>11^^-GQ47*(Gd zj;0`=8%OEiea6)pAp4CMh)Ol}c)GEc*FD&j<^M6iA%$O^)&>8cC%DpD9yYhy=A(v2 z$n3-pT}t~lv7HT>eJ7)$x%?BWF}vsum)Wz(8c{l|kF6-=|NS!B+SoBRTWn#Ag1i=W zn{{cE+oEOTg60uX>8WYeQZrMlb$Pd1a;rvwY5B>v zleJ9mQATL#v%|LLZvU50F0MUqThti)5pDhU9`79s@GK97J-;+)HxT z^o&))E+lizEhKx)mn3)1f{GxI&1EE^=0g(n7pH_XNUY{fl2&F)Jjh1VMY6*@LlSC+ zCxB#`gGid1dr8Kco|Qo6m|aM$<`$AH^JQ77AQ7d(<}#8w=0lR}W_FS+(4V(3i<4w? zsCE-Yc9;y(({zz6HqRu>L@~P#2`wGM~o)@iY&Q6sT zVU*8OWtezoUP+Zv=|>Qp*3{*QSxp{|1)ugC<5xCm2u$bVqIUUZGWd)N;N9isg4xZD zZ1asYnJj~{P}M8PT$UyS#1^wOP3GuZYRnF?1)DzUG7z_olhWnDhHEl$%Wo%ia8qv< z+OW{%SRLJI1rQ~)1FOlVff#k*i5#B z=cY{e44Dw@4yD~*JsbK5j?He_eK5CJ<>#5R-;(}juM8O@g3QSovSuK!UbuC>gT2dZ znEtT-<6%^l?&kFjIAZ9$Oxexjb<7k0z5&?L9GEFHW7&g8Y%%)O#yDkJW~$*t9JtDn#-!l=*EFC-oNhz8suNS6ZjF8&FwDnY=?Y8dBfr0 z2gp5@!RK++#UfbK0$A4?}@ZJcP-lcu2 z%iAJgI?Qj0EoX6f8qOf7tX|%GnQnHeDaRs^@79!A!fr;^k^$9@K@USK2q%_ZgjH{P zYg=uUBsU=b=1m-3mAEsSc+(tI3voKloK{OF_*||_Suqd0S}-h%_u|as*bsh{v#!?A zml&=Z4B+8V8xHg0#+g|@ONP0cLvd)J_IBrKgw{c6a|0eWw4YVmsUGCt;;~SRS9W^wci6EA1Srn=tcJ zXw+whQhSf;p|8@yg*3qhd<50M@9;HOy2L0vhU~-JZ-^5^OI3BUm86?$!J>38R+juT zh;_D9AZ|8m*OmdbEl5;DTNz6HP@yA?{7F4>(Qq6|v9zCgrVe7Dg=*xyvi>JA+)!$|Wy@Lx z-zZfsBCK(H$U+QO4eszHpQ$vM8$$klo-1lL<+}Z<2k&~6s1IeodZ%xYIX7D-h=behD^9IQw^KTISuS_#IM}{UYQe!Bu!s?a^fm&)j&3KBSsSgZkR~wTz&2Bj|pidiB z_)7W7TjfJ=AvZr!5%PsQq-9w8C2MyB%j zPV;7tOiA-m0af-^;YWg-cdL;3Km}csijMcCW4 z_NGsL8C`9d>U*HFMsg)KxJRkqSM6{@$>*t|jB#+cI~XDwHQ%f+6I^90WsX-V+B1ba zFH^qyJ%app)zAYK|Aoyc8K9;tzAA5Ml_aq`MySp=tpW6-Z6Gz2U(*!!Y@%a5#-eIO zrZ`cKAIMRS6g3cmLAYl1W+aN^1RuS^ov0xQ0Njas&8*x&CNz7_02!yROb02}m$JDz z`iHdXLcOI0BO|r@a?BWdtWPoFa$NPadrv=3FJ=hlSmq^;xXM5@YgFwK z0j%~1ZIv^blT)4_`GPP5*kNvEygy;|noScATncX(Lt2^La%E)SAL+ymqL{Le#abLt zaEC}KwNogqN`+Eumr#2BcZY~N;SLcMEF0A8u%_Yn0c>joc`(RA1~GsmUjzeV51K#a z%CMA=IZxDXP!5>AkS1#2!5D1ZfK{8%rq?M?#;NVJdOs+XyXUW zIadc*SG|#0ZzuPvU(H32HyF;jCD$4QZ1@kynm>m5($a%XwEK(LzIQCJQwz@NUEXIZ z_S}>T?5~!Ned7e{zxj6*ut=@RICwm34sXFOCy9SZW{6z&Q!Fw$u9<>Ayd!X>pdL>; zW{cH4n9LPF(q@Z9q&vuZQO^9ek@WZYk}8B*BY<&rO`paxExbJk88|l>7^E&C1(!1K zLQ+D2q0wfK#xkSvPBtA^g78oQ;Qb&Q<$x3Lqbi3DqP-(GaMFmn!;YhKIjGFdCl%f!TG&877csQ!7vdrVaIZ*a zX`lF!PTnsnGw%+FRh(oFiiLF0A@Oq($YF7vfpbJm;qmIIXa~h{D`h4pjpL#*l|3O6 zT{Pc$F%qre8lQSad5Yc*8slEdZ7MTOFXbN7^%x#%X6RqCi( zgnrESDqLaX;Z4mhO=NPwJ=&>4HuL0vyc3vRx~hrH{QvV#;GmGwmCNKjGhU zok23#yh&1Grknw}Zn{W*G0&XAPu5)X?=$$NwA&0nE93O6A~PZ!Ke0NWm0tSu*=EsM iSy3Ncq}Her>&(5VW7{=E(`s4Eez=B~dY+RfTmC<#&xQd2 diff --git a/features/FEATURE_UVISOR/targets/TARGET_UVISOR_SUPPORTED/TARGET_STM32F4/TARGET_DEBUG/TARGET_M4/libconfiguration_stm32_cortex_m4_0x10000000_0x0.a b/features/FEATURE_UVISOR/targets/TARGET_UVISOR_SUPPORTED/TARGET_STM32F4/TARGET_DEBUG/TARGET_M4/libconfiguration_stm32_cortex_m4_0x10000000_0x0.a index 06b70de73c2f4cd77c86ff5b21977c8ca3a65c94..a001ff6b2284b1faaa737b2934b87e2fcce056c0 100644 GIT binary patch delta 44468 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%0A8)lg>i0Az{hqpm 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 delta 44080 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

m8H(SIow;annYSVi$uw#eLz;0LBL-*%n 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 diff --git a/features/FEATURE_UVISOR/targets/TARGET_UVISOR_SUPPORTED/TARGET_STM32F4/TARGET_RELEASE/TARGET_M4/libconfiguration_stm32_cortex_m4_0x10000000_0x0.a b/features/FEATURE_UVISOR/targets/TARGET_UVISOR_SUPPORTED/TARGET_STM32F4/TARGET_RELEASE/TARGET_M4/libconfiguration_stm32_cortex_m4_0x10000000_0x0.a index 9d58b09f8a50787a8fdab6c970637a376de32231..2a27c33d901c22895cfdd4655269d130e34a390d 100644 GIT binary patch delta 45069 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Đ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 From f194ea7be9260225721e8ab5b7c52d28693037a4 Mon Sep 17 00:00:00 2001 From: Bartek Szatkowski Date: Tue, 16 May 2017 10:09:54 +0100 Subject: [PATCH 12/24] Remove redefinitions of register macros from target code --- .../TARGET_MOTE_L152RC/device/stm32l152xc.h | 34 ------------------- .../TARGET_NUCLEO_L152RE/device/stm32l152xe.h | 34 ------------------- .../TARGET_NZ32_SC151/device/stm32l151xc.h | 34 ------------------- .../TARGET_XDOT_L151CC/device/stm32l151xc.h | 34 ------------------- 4 files changed, 136 deletions(-) diff --git a/targets/TARGET_STM/TARGET_STM32L1/TARGET_MOTE_L152RC/device/stm32l152xc.h b/targets/TARGET_STM/TARGET_STM32L1/TARGET_MOTE_L152RC/device/stm32l152xc.h index 418d6b6efe7..e654544acd6 100644 --- a/targets/TARGET_STM/TARGET_STM32L1/TARGET_MOTE_L152RC/device/stm32l152xc.h +++ b/targets/TARGET_STM/TARGET_STM32L1/TARGET_MOTE_L152RC/device/stm32l152xc.h @@ -8631,58 +8631,24 @@ typedef struct /******************* Bit definition for SCB_CFSR register *******************/ /*!< MFSR */ -#define SCB_CFSR_IACCVIOL_Pos (0U) -#define SCB_CFSR_IACCVIOL_Msk (0x1U << SCB_CFSR_IACCVIOL_Pos) /*!< 0x00000001 */ #define SCB_CFSR_IACCVIOL SCB_CFSR_IACCVIOL_Msk /*!< Instruction access violation */ -#define SCB_CFSR_DACCVIOL_Pos (1U) -#define SCB_CFSR_DACCVIOL_Msk (0x1U << SCB_CFSR_DACCVIOL_Pos) /*!< 0x00000002 */ #define SCB_CFSR_DACCVIOL SCB_CFSR_DACCVIOL_Msk /*!< Data access violation */ -#define SCB_CFSR_MUNSTKERR_Pos (3U) -#define SCB_CFSR_MUNSTKERR_Msk (0x1U << SCB_CFSR_MUNSTKERR_Pos) /*!< 0x00000008 */ #define SCB_CFSR_MUNSTKERR SCB_CFSR_MUNSTKERR_Msk /*!< Unstacking error */ -#define SCB_CFSR_MSTKERR_Pos (4U) -#define SCB_CFSR_MSTKERR_Msk (0x1U << SCB_CFSR_MSTKERR_Pos) /*!< 0x00000010 */ #define SCB_CFSR_MSTKERR SCB_CFSR_MSTKERR_Msk /*!< Stacking error */ -#define SCB_CFSR_MMARVALID_Pos (7U) -#define SCB_CFSR_MMARVALID_Msk (0x1U << SCB_CFSR_MMARVALID_Pos) /*!< 0x00000080 */ #define SCB_CFSR_MMARVALID SCB_CFSR_MMARVALID_Msk /*!< Memory Manage Address Register address valid flag */ /*!< BFSR */ -#define SCB_CFSR_IBUSERR_Pos (8U) -#define SCB_CFSR_IBUSERR_Msk (0x1U << SCB_CFSR_IBUSERR_Pos) /*!< 0x00000100 */ #define SCB_CFSR_IBUSERR SCB_CFSR_IBUSERR_Msk /*!< Instruction bus error flag */ -#define SCB_CFSR_PRECISERR_Pos (9U) -#define SCB_CFSR_PRECISERR_Msk (0x1U << SCB_CFSR_PRECISERR_Pos) /*!< 0x00000200 */ #define SCB_CFSR_PRECISERR SCB_CFSR_PRECISERR_Msk /*!< Precise data bus error */ -#define SCB_CFSR_IMPRECISERR_Pos (10U) -#define SCB_CFSR_IMPRECISERR_Msk (0x1U << SCB_CFSR_IMPRECISERR_Pos) /*!< 0x00000400 */ #define SCB_CFSR_IMPRECISERR SCB_CFSR_IMPRECISERR_Msk /*!< Imprecise data bus error */ -#define SCB_CFSR_UNSTKERR_Pos (11U) -#define SCB_CFSR_UNSTKERR_Msk (0x1U << SCB_CFSR_UNSTKERR_Pos) /*!< 0x00000800 */ #define SCB_CFSR_UNSTKERR SCB_CFSR_UNSTKERR_Msk /*!< Unstacking error */ -#define SCB_CFSR_STKERR_Pos (12U) -#define SCB_CFSR_STKERR_Msk (0x1U << SCB_CFSR_STKERR_Pos) /*!< 0x00001000 */ #define SCB_CFSR_STKERR SCB_CFSR_STKERR_Msk /*!< Stacking error */ -#define SCB_CFSR_BFARVALID_Pos (15U) -#define SCB_CFSR_BFARVALID_Msk (0x1U << SCB_CFSR_BFARVALID_Pos) /*!< 0x00008000 */ #define SCB_CFSR_BFARVALID SCB_CFSR_BFARVALID_Msk /*!< Bus Fault Address Register address valid flag */ /*!< UFSR */ -#define SCB_CFSR_UNDEFINSTR_Pos (16U) -#define SCB_CFSR_UNDEFINSTR_Msk (0x1U << SCB_CFSR_UNDEFINSTR_Pos) /*!< 0x00010000 */ #define SCB_CFSR_UNDEFINSTR SCB_CFSR_UNDEFINSTR_Msk /*!< The processor attempt to excecute an undefined instruction */ -#define SCB_CFSR_INVSTATE_Pos (17U) -#define SCB_CFSR_INVSTATE_Msk (0x1U << SCB_CFSR_INVSTATE_Pos) /*!< 0x00020000 */ #define SCB_CFSR_INVSTATE SCB_CFSR_INVSTATE_Msk /*!< Invalid combination of EPSR and instruction */ -#define SCB_CFSR_INVPC_Pos (18U) -#define SCB_CFSR_INVPC_Msk (0x1U << SCB_CFSR_INVPC_Pos) /*!< 0x00040000 */ #define SCB_CFSR_INVPC SCB_CFSR_INVPC_Msk /*!< Attempt to load EXC_RETURN into pc illegally */ -#define SCB_CFSR_NOCP_Pos (19U) -#define SCB_CFSR_NOCP_Msk (0x1U << SCB_CFSR_NOCP_Pos) /*!< 0x00080000 */ #define SCB_CFSR_NOCP SCB_CFSR_NOCP_Msk /*!< Attempt to use a coprocessor instruction */ -#define SCB_CFSR_UNALIGNED_Pos (24U) -#define SCB_CFSR_UNALIGNED_Msk (0x1U << SCB_CFSR_UNALIGNED_Pos) /*!< 0x01000000 */ #define SCB_CFSR_UNALIGNED SCB_CFSR_UNALIGNED_Msk /*!< Fault occurs when there is an attempt to make an unaligned memory access */ -#define SCB_CFSR_DIVBYZERO_Pos (25U) -#define SCB_CFSR_DIVBYZERO_Msk (0x1U << SCB_CFSR_DIVBYZERO_Pos) /*!< 0x02000000 */ #define SCB_CFSR_DIVBYZERO SCB_CFSR_DIVBYZERO_Msk /*!< Fault occurs when SDIV or DIV instruction is used with a divisor of 0 */ /******************* Bit definition for SCB_HFSR register *******************/ diff --git a/targets/TARGET_STM/TARGET_STM32L1/TARGET_NUCLEO_L152RE/device/stm32l152xe.h b/targets/TARGET_STM/TARGET_STM32L1/TARGET_NUCLEO_L152RE/device/stm32l152xe.h index daaf042e5b7..1d45ead417c 100644 --- a/targets/TARGET_STM/TARGET_STM32L1/TARGET_NUCLEO_L152RE/device/stm32l152xe.h +++ b/targets/TARGET_STM/TARGET_STM32L1/TARGET_NUCLEO_L152RE/device/stm32l152xe.h @@ -8933,58 +8933,24 @@ typedef struct /******************* Bit definition for SCB_CFSR register *******************/ /*!< MFSR */ -#define SCB_CFSR_IACCVIOL_Pos (0U) -#define SCB_CFSR_IACCVIOL_Msk (0x1U << SCB_CFSR_IACCVIOL_Pos) /*!< 0x00000001 */ #define SCB_CFSR_IACCVIOL SCB_CFSR_IACCVIOL_Msk /*!< Instruction access violation */ -#define SCB_CFSR_DACCVIOL_Pos (1U) -#define SCB_CFSR_DACCVIOL_Msk (0x1U << SCB_CFSR_DACCVIOL_Pos) /*!< 0x00000002 */ #define SCB_CFSR_DACCVIOL SCB_CFSR_DACCVIOL_Msk /*!< Data access violation */ -#define SCB_CFSR_MUNSTKERR_Pos (3U) -#define SCB_CFSR_MUNSTKERR_Msk (0x1U << SCB_CFSR_MUNSTKERR_Pos) /*!< 0x00000008 */ #define SCB_CFSR_MUNSTKERR SCB_CFSR_MUNSTKERR_Msk /*!< Unstacking error */ -#define SCB_CFSR_MSTKERR_Pos (4U) -#define SCB_CFSR_MSTKERR_Msk (0x1U << SCB_CFSR_MSTKERR_Pos) /*!< 0x00000010 */ #define SCB_CFSR_MSTKERR SCB_CFSR_MSTKERR_Msk /*!< Stacking error */ -#define SCB_CFSR_MMARVALID_Pos (7U) -#define SCB_CFSR_MMARVALID_Msk (0x1U << SCB_CFSR_MMARVALID_Pos) /*!< 0x00000080 */ #define SCB_CFSR_MMARVALID SCB_CFSR_MMARVALID_Msk /*!< Memory Manage Address Register address valid flag */ /*!< BFSR */ -#define SCB_CFSR_IBUSERR_Pos (8U) -#define SCB_CFSR_IBUSERR_Msk (0x1U << SCB_CFSR_IBUSERR_Pos) /*!< 0x00000100 */ #define SCB_CFSR_IBUSERR SCB_CFSR_IBUSERR_Msk /*!< Instruction bus error flag */ -#define SCB_CFSR_PRECISERR_Pos (9U) -#define SCB_CFSR_PRECISERR_Msk (0x1U << SCB_CFSR_PRECISERR_Pos) /*!< 0x00000200 */ #define SCB_CFSR_PRECISERR SCB_CFSR_PRECISERR_Msk /*!< Precise data bus error */ -#define SCB_CFSR_IMPRECISERR_Pos (10U) -#define SCB_CFSR_IMPRECISERR_Msk (0x1U << SCB_CFSR_IMPRECISERR_Pos) /*!< 0x00000400 */ #define SCB_CFSR_IMPRECISERR SCB_CFSR_IMPRECISERR_Msk /*!< Imprecise data bus error */ -#define SCB_CFSR_UNSTKERR_Pos (11U) -#define SCB_CFSR_UNSTKERR_Msk (0x1U << SCB_CFSR_UNSTKERR_Pos) /*!< 0x00000800 */ #define SCB_CFSR_UNSTKERR SCB_CFSR_UNSTKERR_Msk /*!< Unstacking error */ -#define SCB_CFSR_STKERR_Pos (12U) -#define SCB_CFSR_STKERR_Msk (0x1U << SCB_CFSR_STKERR_Pos) /*!< 0x00001000 */ #define SCB_CFSR_STKERR SCB_CFSR_STKERR_Msk /*!< Stacking error */ -#define SCB_CFSR_BFARVALID_Pos (15U) -#define SCB_CFSR_BFARVALID_Msk (0x1U << SCB_CFSR_BFARVALID_Pos) /*!< 0x00008000 */ #define SCB_CFSR_BFARVALID SCB_CFSR_BFARVALID_Msk /*!< Bus Fault Address Register address valid flag */ /*!< UFSR */ -#define SCB_CFSR_UNDEFINSTR_Pos (16U) -#define SCB_CFSR_UNDEFINSTR_Msk (0x1U << SCB_CFSR_UNDEFINSTR_Pos) /*!< 0x00010000 */ #define SCB_CFSR_UNDEFINSTR SCB_CFSR_UNDEFINSTR_Msk /*!< The processor attempt to excecute an undefined instruction */ -#define SCB_CFSR_INVSTATE_Pos (17U) -#define SCB_CFSR_INVSTATE_Msk (0x1U << SCB_CFSR_INVSTATE_Pos) /*!< 0x00020000 */ #define SCB_CFSR_INVSTATE SCB_CFSR_INVSTATE_Msk /*!< Invalid combination of EPSR and instruction */ -#define SCB_CFSR_INVPC_Pos (18U) -#define SCB_CFSR_INVPC_Msk (0x1U << SCB_CFSR_INVPC_Pos) /*!< 0x00040000 */ #define SCB_CFSR_INVPC SCB_CFSR_INVPC_Msk /*!< Attempt to load EXC_RETURN into pc illegally */ -#define SCB_CFSR_NOCP_Pos (19U) -#define SCB_CFSR_NOCP_Msk (0x1U << SCB_CFSR_NOCP_Pos) /*!< 0x00080000 */ #define SCB_CFSR_NOCP SCB_CFSR_NOCP_Msk /*!< Attempt to use a coprocessor instruction */ -#define SCB_CFSR_UNALIGNED_Pos (24U) -#define SCB_CFSR_UNALIGNED_Msk (0x1U << SCB_CFSR_UNALIGNED_Pos) /*!< 0x01000000 */ #define SCB_CFSR_UNALIGNED SCB_CFSR_UNALIGNED_Msk /*!< Fault occurs when there is an attempt to make an unaligned memory access */ -#define SCB_CFSR_DIVBYZERO_Pos (25U) -#define SCB_CFSR_DIVBYZERO_Msk (0x1U << SCB_CFSR_DIVBYZERO_Pos) /*!< 0x02000000 */ #define SCB_CFSR_DIVBYZERO SCB_CFSR_DIVBYZERO_Msk /*!< Fault occurs when SDIV or DIV instruction is used with a divisor of 0 */ /******************* Bit definition for SCB_HFSR register *******************/ diff --git a/targets/TARGET_STM/TARGET_STM32L1/TARGET_NZ32_SC151/device/stm32l151xc.h b/targets/TARGET_STM/TARGET_STM32L1/TARGET_NZ32_SC151/device/stm32l151xc.h index 482e9427546..b59f0ebd32f 100644 --- a/targets/TARGET_STM/TARGET_STM32L1/TARGET_NZ32_SC151/device/stm32l151xc.h +++ b/targets/TARGET_STM/TARGET_STM32L1/TARGET_NZ32_SC151/device/stm32l151xc.h @@ -8481,58 +8481,24 @@ typedef struct /******************* Bit definition for SCB_CFSR register *******************/ /*!< MFSR */ -#define SCB_CFSR_IACCVIOL_Pos (0U) -#define SCB_CFSR_IACCVIOL_Msk (0x1U << SCB_CFSR_IACCVIOL_Pos) /*!< 0x00000001 */ #define SCB_CFSR_IACCVIOL SCB_CFSR_IACCVIOL_Msk /*!< Instruction access violation */ -#define SCB_CFSR_DACCVIOL_Pos (1U) -#define SCB_CFSR_DACCVIOL_Msk (0x1U << SCB_CFSR_DACCVIOL_Pos) /*!< 0x00000002 */ #define SCB_CFSR_DACCVIOL SCB_CFSR_DACCVIOL_Msk /*!< Data access violation */ -#define SCB_CFSR_MUNSTKERR_Pos (3U) -#define SCB_CFSR_MUNSTKERR_Msk (0x1U << SCB_CFSR_MUNSTKERR_Pos) /*!< 0x00000008 */ #define SCB_CFSR_MUNSTKERR SCB_CFSR_MUNSTKERR_Msk /*!< Unstacking error */ -#define SCB_CFSR_MSTKERR_Pos (4U) -#define SCB_CFSR_MSTKERR_Msk (0x1U << SCB_CFSR_MSTKERR_Pos) /*!< 0x00000010 */ #define SCB_CFSR_MSTKERR SCB_CFSR_MSTKERR_Msk /*!< Stacking error */ -#define SCB_CFSR_MMARVALID_Pos (7U) -#define SCB_CFSR_MMARVALID_Msk (0x1U << SCB_CFSR_MMARVALID_Pos) /*!< 0x00000080 */ #define SCB_CFSR_MMARVALID SCB_CFSR_MMARVALID_Msk /*!< Memory Manage Address Register address valid flag */ /*!< BFSR */ -#define SCB_CFSR_IBUSERR_Pos (8U) -#define SCB_CFSR_IBUSERR_Msk (0x1U << SCB_CFSR_IBUSERR_Pos) /*!< 0x00000100 */ #define SCB_CFSR_IBUSERR SCB_CFSR_IBUSERR_Msk /*!< Instruction bus error flag */ -#define SCB_CFSR_PRECISERR_Pos (9U) -#define SCB_CFSR_PRECISERR_Msk (0x1U << SCB_CFSR_PRECISERR_Pos) /*!< 0x00000200 */ #define SCB_CFSR_PRECISERR SCB_CFSR_PRECISERR_Msk /*!< Precise data bus error */ -#define SCB_CFSR_IMPRECISERR_Pos (10U) -#define SCB_CFSR_IMPRECISERR_Msk (0x1U << SCB_CFSR_IMPRECISERR_Pos) /*!< 0x00000400 */ #define SCB_CFSR_IMPRECISERR SCB_CFSR_IMPRECISERR_Msk /*!< Imprecise data bus error */ -#define SCB_CFSR_UNSTKERR_Pos (11U) -#define SCB_CFSR_UNSTKERR_Msk (0x1U << SCB_CFSR_UNSTKERR_Pos) /*!< 0x00000800 */ #define SCB_CFSR_UNSTKERR SCB_CFSR_UNSTKERR_Msk /*!< Unstacking error */ -#define SCB_CFSR_STKERR_Pos (12U) -#define SCB_CFSR_STKERR_Msk (0x1U << SCB_CFSR_STKERR_Pos) /*!< 0x00001000 */ #define SCB_CFSR_STKERR SCB_CFSR_STKERR_Msk /*!< Stacking error */ -#define SCB_CFSR_BFARVALID_Pos (15U) -#define SCB_CFSR_BFARVALID_Msk (0x1U << SCB_CFSR_BFARVALID_Pos) /*!< 0x00008000 */ #define SCB_CFSR_BFARVALID SCB_CFSR_BFARVALID_Msk /*!< Bus Fault Address Register address valid flag */ /*!< UFSR */ -#define SCB_CFSR_UNDEFINSTR_Pos (16U) -#define SCB_CFSR_UNDEFINSTR_Msk (0x1U << SCB_CFSR_UNDEFINSTR_Pos) /*!< 0x00010000 */ #define SCB_CFSR_UNDEFINSTR SCB_CFSR_UNDEFINSTR_Msk /*!< The processor attempt to excecute an undefined instruction */ -#define SCB_CFSR_INVSTATE_Pos (17U) -#define SCB_CFSR_INVSTATE_Msk (0x1U << SCB_CFSR_INVSTATE_Pos) /*!< 0x00020000 */ #define SCB_CFSR_INVSTATE SCB_CFSR_INVSTATE_Msk /*!< Invalid combination of EPSR and instruction */ -#define SCB_CFSR_INVPC_Pos (18U) -#define SCB_CFSR_INVPC_Msk (0x1U << SCB_CFSR_INVPC_Pos) /*!< 0x00040000 */ #define SCB_CFSR_INVPC SCB_CFSR_INVPC_Msk /*!< Attempt to load EXC_RETURN into pc illegally */ -#define SCB_CFSR_NOCP_Pos (19U) -#define SCB_CFSR_NOCP_Msk (0x1U << SCB_CFSR_NOCP_Pos) /*!< 0x00080000 */ #define SCB_CFSR_NOCP SCB_CFSR_NOCP_Msk /*!< Attempt to use a coprocessor instruction */ -#define SCB_CFSR_UNALIGNED_Pos (24U) -#define SCB_CFSR_UNALIGNED_Msk (0x1U << SCB_CFSR_UNALIGNED_Pos) /*!< 0x01000000 */ #define SCB_CFSR_UNALIGNED SCB_CFSR_UNALIGNED_Msk /*!< Fault occurs when there is an attempt to make an unaligned memory access */ -#define SCB_CFSR_DIVBYZERO_Pos (25U) -#define SCB_CFSR_DIVBYZERO_Msk (0x1U << SCB_CFSR_DIVBYZERO_Pos) /*!< 0x02000000 */ #define SCB_CFSR_DIVBYZERO SCB_CFSR_DIVBYZERO_Msk /*!< Fault occurs when SDIV or DIV instruction is used with a divisor of 0 */ /******************* Bit definition for SCB_HFSR register *******************/ diff --git a/targets/TARGET_STM/TARGET_STM32L1/TARGET_XDOT_L151CC/device/stm32l151xc.h b/targets/TARGET_STM/TARGET_STM32L1/TARGET_XDOT_L151CC/device/stm32l151xc.h index 482e9427546..b59f0ebd32f 100644 --- a/targets/TARGET_STM/TARGET_STM32L1/TARGET_XDOT_L151CC/device/stm32l151xc.h +++ b/targets/TARGET_STM/TARGET_STM32L1/TARGET_XDOT_L151CC/device/stm32l151xc.h @@ -8481,58 +8481,24 @@ typedef struct /******************* Bit definition for SCB_CFSR register *******************/ /*!< MFSR */ -#define SCB_CFSR_IACCVIOL_Pos (0U) -#define SCB_CFSR_IACCVIOL_Msk (0x1U << SCB_CFSR_IACCVIOL_Pos) /*!< 0x00000001 */ #define SCB_CFSR_IACCVIOL SCB_CFSR_IACCVIOL_Msk /*!< Instruction access violation */ -#define SCB_CFSR_DACCVIOL_Pos (1U) -#define SCB_CFSR_DACCVIOL_Msk (0x1U << SCB_CFSR_DACCVIOL_Pos) /*!< 0x00000002 */ #define SCB_CFSR_DACCVIOL SCB_CFSR_DACCVIOL_Msk /*!< Data access violation */ -#define SCB_CFSR_MUNSTKERR_Pos (3U) -#define SCB_CFSR_MUNSTKERR_Msk (0x1U << SCB_CFSR_MUNSTKERR_Pos) /*!< 0x00000008 */ #define SCB_CFSR_MUNSTKERR SCB_CFSR_MUNSTKERR_Msk /*!< Unstacking error */ -#define SCB_CFSR_MSTKERR_Pos (4U) -#define SCB_CFSR_MSTKERR_Msk (0x1U << SCB_CFSR_MSTKERR_Pos) /*!< 0x00000010 */ #define SCB_CFSR_MSTKERR SCB_CFSR_MSTKERR_Msk /*!< Stacking error */ -#define SCB_CFSR_MMARVALID_Pos (7U) -#define SCB_CFSR_MMARVALID_Msk (0x1U << SCB_CFSR_MMARVALID_Pos) /*!< 0x00000080 */ #define SCB_CFSR_MMARVALID SCB_CFSR_MMARVALID_Msk /*!< Memory Manage Address Register address valid flag */ /*!< BFSR */ -#define SCB_CFSR_IBUSERR_Pos (8U) -#define SCB_CFSR_IBUSERR_Msk (0x1U << SCB_CFSR_IBUSERR_Pos) /*!< 0x00000100 */ #define SCB_CFSR_IBUSERR SCB_CFSR_IBUSERR_Msk /*!< Instruction bus error flag */ -#define SCB_CFSR_PRECISERR_Pos (9U) -#define SCB_CFSR_PRECISERR_Msk (0x1U << SCB_CFSR_PRECISERR_Pos) /*!< 0x00000200 */ #define SCB_CFSR_PRECISERR SCB_CFSR_PRECISERR_Msk /*!< Precise data bus error */ -#define SCB_CFSR_IMPRECISERR_Pos (10U) -#define SCB_CFSR_IMPRECISERR_Msk (0x1U << SCB_CFSR_IMPRECISERR_Pos) /*!< 0x00000400 */ #define SCB_CFSR_IMPRECISERR SCB_CFSR_IMPRECISERR_Msk /*!< Imprecise data bus error */ -#define SCB_CFSR_UNSTKERR_Pos (11U) -#define SCB_CFSR_UNSTKERR_Msk (0x1U << SCB_CFSR_UNSTKERR_Pos) /*!< 0x00000800 */ #define SCB_CFSR_UNSTKERR SCB_CFSR_UNSTKERR_Msk /*!< Unstacking error */ -#define SCB_CFSR_STKERR_Pos (12U) -#define SCB_CFSR_STKERR_Msk (0x1U << SCB_CFSR_STKERR_Pos) /*!< 0x00001000 */ #define SCB_CFSR_STKERR SCB_CFSR_STKERR_Msk /*!< Stacking error */ -#define SCB_CFSR_BFARVALID_Pos (15U) -#define SCB_CFSR_BFARVALID_Msk (0x1U << SCB_CFSR_BFARVALID_Pos) /*!< 0x00008000 */ #define SCB_CFSR_BFARVALID SCB_CFSR_BFARVALID_Msk /*!< Bus Fault Address Register address valid flag */ /*!< UFSR */ -#define SCB_CFSR_UNDEFINSTR_Pos (16U) -#define SCB_CFSR_UNDEFINSTR_Msk (0x1U << SCB_CFSR_UNDEFINSTR_Pos) /*!< 0x00010000 */ #define SCB_CFSR_UNDEFINSTR SCB_CFSR_UNDEFINSTR_Msk /*!< The processor attempt to excecute an undefined instruction */ -#define SCB_CFSR_INVSTATE_Pos (17U) -#define SCB_CFSR_INVSTATE_Msk (0x1U << SCB_CFSR_INVSTATE_Pos) /*!< 0x00020000 */ #define SCB_CFSR_INVSTATE SCB_CFSR_INVSTATE_Msk /*!< Invalid combination of EPSR and instruction */ -#define SCB_CFSR_INVPC_Pos (18U) -#define SCB_CFSR_INVPC_Msk (0x1U << SCB_CFSR_INVPC_Pos) /*!< 0x00040000 */ #define SCB_CFSR_INVPC SCB_CFSR_INVPC_Msk /*!< Attempt to load EXC_RETURN into pc illegally */ -#define SCB_CFSR_NOCP_Pos (19U) -#define SCB_CFSR_NOCP_Msk (0x1U << SCB_CFSR_NOCP_Pos) /*!< 0x00080000 */ #define SCB_CFSR_NOCP SCB_CFSR_NOCP_Msk /*!< Attempt to use a coprocessor instruction */ -#define SCB_CFSR_UNALIGNED_Pos (24U) -#define SCB_CFSR_UNALIGNED_Msk (0x1U << SCB_CFSR_UNALIGNED_Pos) /*!< 0x01000000 */ #define SCB_CFSR_UNALIGNED SCB_CFSR_UNALIGNED_Msk /*!< Fault occurs when there is an attempt to make an unaligned memory access */ -#define SCB_CFSR_DIVBYZERO_Pos (25U) -#define SCB_CFSR_DIVBYZERO_Msk (0x1U << SCB_CFSR_DIVBYZERO_Pos) /*!< 0x02000000 */ #define SCB_CFSR_DIVBYZERO SCB_CFSR_DIVBYZERO_Msk /*!< Fault occurs when SDIV or DIV instruction is used with a divisor of 0 */ /******************* Bit definition for SCB_HFSR register *******************/ From abcae6f01e6e0877b87ded366c2323ede1ddb6de Mon Sep 17 00:00:00 2001 From: "andreas.larsson" Date: Fri, 19 May 2017 13:38:15 +0200 Subject: [PATCH 13/24] Updated driver binaries for feature_cmsis5 as v2.0 rc1 --- .../TOOLCHAIN_ARM/libublox-odin-w2-driver.ar | Bin 5406998 -> 5456646 bytes .../libublox-odin-w2-driver.a | Bin 1902246 -> 1902990 bytes .../TOOLCHAIN_IAR/libublox-odin-w2-driver.a | Bin 5141062 -> 5166670 bytes 3 files changed, 0 insertions(+), 0 deletions(-) diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_UBLOX_EVK_ODIN_W2/sdk/TOOLCHAIN_ARM/libublox-odin-w2-driver.ar b/targets/TARGET_STM/TARGET_STM32F4/TARGET_UBLOX_EVK_ODIN_W2/sdk/TOOLCHAIN_ARM/libublox-odin-w2-driver.ar index 02bb74ed9862cdfe332e9f46583c30f6f46ca024..64088728cfc13671e1d8778f76cfd5a3d14331cb 100644 GIT binary patch delta 519303 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 Ku%mzI!2bt6Elbe= delta 501611 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�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 ap}jatXnMHDV7P0dR{nbOL9{<-ivM34AgEpd diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_UBLOX_EVK_ODIN_W2/sdk/TOOLCHAIN_GCC_ARM/libublox-odin-w2-driver.a b/targets/TARGET_STM/TARGET_STM32F4/TARGET_UBLOX_EVK_ODIN_W2/sdk/TOOLCHAIN_GCC_ARM/libublox-odin-w2-driver.a index bfac450c73288a59c163c533dd4d4054a5396c7b..888c10f8cf0c265324df3c2c275f1d3beaf61c05 100644 GIT binary patch delta 19785 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 X5@rgCH;xD98+j7dDSruEl=lAtPx9F_ delta 19471 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%0AjT^}$h8l0YaQkC=*jS>3f_M` zrSsT`xG-uxbF*25OY13<$4ds@m%yGI#3UXNc^JXC4b<|?21?+un1Qz>u;WHb;Bl9M z{WsFYe%?sAJ6aw=@cKsT-adzNccd_|4_4SM{Fp;&J1#KriUfAZrL-Lljw0AEms+08 zrL-MZ240iEPG3>lj$;fQ@D;T@^%dposB#R!8xq)M6XolOW8f#7sO6bWl&@nK18;4j z(+07dDPMicA)0{~80eEv z;G}%W+Ua4220tS>R{|Y(LkR<|3^ebimQ!{^_$~yGF%Trsc@LyAu*xZ%K>0oL1g7qR zB8JByF3j6QBe?8EpCW?080fc`z-fCSk%6A45nLdFZr?!x1A8*C;&;??#&-~qkKjfI zW=Np>_Ylv(mkg}*J+(~!9`YC%c?Q8u3H00tEtBr-rlkLxU81?m9cI`e8gaoP@JzFJUUP^#S33+nWw7C4v8DUs!yISC2tSrg z3X|o$<5f}Ecvx)jUh{||!hAPO)bt36a#f-%66GHe&keaZJF4_r0(_poKYtWTPa1;^ zD#0@9^W9Mz?u}zgpA{r(drbVjaNna6ts>D6$7t#;3zS}KNEBH>qOVn=btF1eARaAp zkHk1a`wed(QO`n=6~q0sN|ZyQn}syP-p7?*Uy*3|aT48Di8hny*>M)AWpSVMgVGCs z|JVx7{eeW4F)q6PM`(gcR2fGN=SQsLyr`Xv9BU?lmy<(B9`85;gi!d!sC=5!pUu`dmrktd!JyD6i zCz0#VBpUm((rZ77X8uf%QaGiE4wA_06p5y&M2ATPr^Er_=;AN~zCq&RRX9xxF&RS@ z?NcitQMx1&&M2be(nZd&kVlLAQkCcgi8h^~SzFF3y?!E5M16{>*GZM= zHi@nkQ?GUy(`bJtcSzLxA{1W5H(DhrA<0#|hifRgr1ZH*l7W}#t^GwMdO)J*m*~Zu zd|By**|FGKq+g~<2v-!*BNBOCp5RzHnFQQVp&uot{yrmRISODNu=CK*TrL z>8jYtqYnl=+HV&liHgTrD)QGz^hhPb=%9p|P89^_>m-|TUFn7)K75K(MgF=tL5~_Y z6cNVlh}|09fW*4^J6<9fP3|f=#@>kX!#8NyC=7kH&&E}f#oQFv#N)6^W{_lOC0VOm zNf~UR!PEZ`d$2qzRe%14r2&O?5x-EURm%7rk$@ z%yNI>teN>WGrwl$*UbEynO`&WYhgk1JD`OHX<>>;wJX~MfV5(d{dQ4|8f`6q_2P6h2_u6t-yOj(F-)kKkfpt zhXT;PHL;4(kqOH?iuQco1f?%L%Rxyy443hZC7V8eGUgz?Z!E{Tu``p^gn(Y6IxEcW z#Zq{i=LVqlZFw&o1|r_CU5!WcVHf!x^3u3CjOoML`6^t>8~>J zM_>Z-lV~p7++Q*A3w!%h&t}Mi>Wj_*X5SayA3$6*c>`3&{Q?PmZ=hn_7dm2v8SD29 zR4n_#4-(k&6O~y%@)NrH?oU)^{o|hyyH3;~m03S#5VibakjkuoX^@yxdu}{VZ`5Fw zX@AOKYW)OrGqAMWqG{iC2u*9`5S3|vvIO26qB89ZL)mc}w89Qmnf7N5W#?Bcf+v6JrgDmgCQ;+=%@J@~V2_&eg-{g}5oZ{m@1mU4P~fZ~9%W*%THA0>JEJAv zNm0|FAWU$8OQr_Z9gF)Q3#%)b;;L5_B5+&JQZ&C4N15C3lVxsmd?$|Mf^@Lq)0$O< z!NXX1fRuyz9B#fbM>GEmyxiasB=jB2{D6||%vdo$vv3Q+$C&RqW*jAGjvpu1(R+1w zBlh`~s=_B$rjc2M(N@(MB^V>cKuiEFj`3+CQ^qX9B&@Rw#YDVr!bq-=UM(zwTN0yS zl`cLhiRoe%VXhkV9M5zyi%?}e9ktI3$KK0 z7G@E)sz7MatAzn7_G#fSG@q!t^5%(52eSx!Co&ohi}3m+rhZw34<|_%Wx1;lO=9Yo zML07_)$`-YO#QM5eJ870UYg9*FN<&=h4S4EnZndBi!gQyErW4ueG{h0K<&#S=%%XH z?{lm$@XM*H-nuWD_GJ;gzoZ$?_>w7J79oS`u=7K+0j6#B@E0&XPrQfBX-wg=2pguU z#;%SOyaNynn@%gY8mV|$eLL3Wm!QE67DHtbTF#)6w#{JSQx;+W4C?ecavQPwhcl_Z z8;N;Y{W#X;L0ToVpef{LO%?}%xBXXVMr7XgTR26s=D-3*+s#^Ka(pZ?3MVOjK!#z)95mHFKixj==!H%EBf}8tKh`{K^MI;C%t99VWD(+#=NA*V zLxrC12B@8nuitG#giaYO;t8*mAzm5wxA!x^LDu4z3^C=S@a7^g?)I?gKgnj?Um^!o z7G`l5)?`D>ZV$U-mKgvX8a8g&lz1GRCfN3SI3evr%XzLoHrKr#P0P4wTSHJj`Dx{MK=adTep>s>pqT<>4gJ-b0utbSMb9!Pu@YdU zzh@aMK(ag!=FhU>Cbm}1GHki?yON7`LsyOq2EJA8YQl!DP~}}ui%_{g9j>a{pB%CH zDW-72&s|JD0bQM#wgg%?u55roldAYT8U}J)k&cqM+#XE+xlThUiOT@VuXthzC2_et zgj}kfhf)%kf#^+SNnFmOtC1yjxige$5*DFP9A$AC5l7<{#ZeZQ5~kI`4dRDWbjk%px=%LzJ&WBGDKB?ih+_T{s4P^p0Wz5>)Pv zMtTPEzrn*u&$m`VpN5YzhHk0To-rQgt9Oe1KV1K`C_dzRwT z*Jl38vtJuNO7V>fpJS*gW2H#$1<~G^t3r%l#fnHumxXbvj>#B!+NKJ{ubzg8m$-4p z6Ob=4j5QIdC+Ocn`twN~_e6|d<$s1^Y$UXsCZ&@ph}tSFunul=5jVp08q|*f?K2fGIRxps-Nztsu4?F_iEH zkmiD^J&Pb$LWGVB6&4DiKYH2lTrb{eh%39%g%sjDBtu0$F*XAV58~ZBEmDzBlv_k^ z#4P+Agv-XrCxj&uSSgd3C&U=tdYPnfj?d({01rrT!FPViI=K60RWVMNKMp2?Q6gIx zwa!Kj!-A#Lle>1mhNpA?MMlxYzcOQ3(U>da)_ zWR~g?qc<^N(|%@>zX*v3@d|xXR7WO9q|oJFq^Pt|k5nkVP&J=QNcn zS{^IR=`}M=rHU>}W0?XiLc>`qUG%M4)N^e`;Lxn-}$kBOgo}z@}lMN`q zOO2kd@E{7)=0gHIzu9PkqJ;|YEPy2T)b=e<)KC5-7@66j(?XT@Ibb2gGJmT}hD!VN z%ODRWWGLFFurh;G(%?lZ4#e<95RI&2!Vim7+UKQ3^n^NPst6DVWRg~YB2%S%W-+AwfMfb*DLN=$0|Glr%aoR-B0$W}5?PUi&}Djee zq9Q=-h81RO*uO*}Kt#)qsgrcAj!P8|L>`Y4OE`2-#?ag`LojApBtk4%N@EXNrXoTd zvy8xp%Tz>&j?2l}I~H?o%0!4Wm$NrDh)0>72T|}?K?a+o6)FPB7W~>{Mj0X4Usn}q^h5-RR|IJsS5sJEsGE)PDI{8;ZKcUr=mqn zTnGGR{C!zZtcZ&lRif8=vP|?}&vElyMau;LGW{&R`H|b8)>*qzqG(i2KcQJ8h=}s6 zB~1Iomb0r;Ro<3&&X}Q>|FqbDzKyVAOidr#flJ0qj+${oGfrs63C%d687J(zh~^yE zoa35vTyu`g+a}F8Auq)%HclAeday|e9=2N{3}6j0DG|g9Tp`q?ILz7Z)`k|2kv`~J z{YDjcXdR9kXADRB?RtL)LfS+PU2PVg`VU`CD;~J(dMbWsj~Ll>Vd7(C99B=qak~2AIATJF zB{8Hm2F9uk7$LEw_3nsOEEvdgo*gPNQ#HoGg5GEeVA&k_cOjyogn!jbWyjdvi=_;ViV@vHL0^?U zqX;XE5UX83l|7?(KamZY@24_nTm@5PAkl7p)SpZmqQkcrs=sG&09${!-PUB$uf!HoJ@I zC+$S07IxfI)2uYjO4F<~%}R6o%I|>Y_SM|J_Lo7^to|pO72A`-@-@HLtPl=XuFw3# zV#AYbf2UN5uh?S8)V+wx-~T zOx93Lga;$&Ud*2=N|Rvulmdy@e5%rzb`S`QKB|E{I(^VtC-UXC#bn{k=eJ{|N@qGa zl9u(YQ7WCO-6#SNR4Pz7!u;4$26y`Z&R4(9U66pVh$^~5a3+lf73&jO2 zY(bD+z2R7u5BROI1m=%b`G5<@l3VbDaVj5h*Kq{?I8NmQz9NA=ttuaI9I|||$zQjs ze87*e!hGt(5>-Cn@gnb+MR<0yJl#>{2`UG0{RyN2XCvbmOLq6hHIq@uoj}e)M+}Y#cAzlk##14?SskJq?lTqk zUo+JvbvCAJEkB2_W)j&jKhBo+j&C*I*5iihuwegPu!Y<<_0nrjLd{92sj`|XtEsZ~ zovY>~)SQHxlTdRK+V@G?3EBqoQoJH3VM2jd9Hch$a)VP%yc8#)0*`L$r8o%{xJolG z#Yu?U*>1MQ&Ae{7@bM}q;d>vED%1!uF(?NrkCFWmkct|9MRVem`dSXk91R=vZMI$E^#6m^#5`=$_+j(0~68 z$GuJAhMjYqjbeQng(Hp~tv3qae?!i*)hHAWe#5exnBfSM*ej1&w}UuL29$2cy?JVT z%tzU8F9hcMV49A-ER~5FUW+vt9dGT$P)A>gjx|&j+)jgOH#QiBEI2#@qL3JzzODq@DAOyYA!B}qHOloB)SWRmPNkZ>6X3OdU)6Ek>>L$JwNh%G{J z`&p)*n4t#)51dtv@$NaMsF+~`O7tDhaa<-TBI2bVoMT#x8D6k%4(B28G>$d(JgF{i ztq9JOK>rJjAk_?+46J(r5?ITP7l1F1;2j3;xCyN+asu_|Q zcnv|eX5ESzW2za>GjMP*@Ou!vRLp2o&2aGEheqLkF%+Iau+K%tohpGNE~;*?6f3fX zzeH<2bVt`nGc9rzgg7}*l&egm@R>7;=x-N0jc*nQp&D3QTc2(mXW_~Tk8^!2g6xynz29v}l);g=spX^FP#}ZO zzYsX>7YJBr@4ny{T3ydO5HEvO?l9%vBFw%6c`~^44z($6K(1hSY4MEo|GN+HTF6aq_Ck0-MfvSi7IQd+Uv_n<@u zo8MD4x7~yAO#2-7-4iFSYjK~0v`n2Zz1eN zbQchfSZbf=-KVN~4t|CY#4gf*@r>hks#c`=b9^v%snGhls^dNsg)Fl#<;mw9hqPKV zb>8C7xh~-aJ|MePNP3~V(Z?t%ltnHt>2}7y#3!@dKE+utl@5X{2l30L7fDxv<01B} z$(R0WEaD(f7OiI@Yl9j>bsmf>>>a{*9sp>ja5* zp{|1ypPuL-t-=K-D3B$0op8iNyw?HF5U|ERyU(0?2pQ7W!aGB}9n`;c=D9T0U8cG~ zo-E9A;nm+Up@}OP*V>1B&sBZ1yImnh79B@XL<+tS;*V0a8|28MSU0t($Sr-HeY_Hs zh)ded08uhJ*r0yaHw};_i=HqMd!nPCY-Fu$WtTuT<@CN%pdk{@vmu_l=L_4Z)Wi0!&el|jZ zEWD1weX6T$G(o^dX*~Td6JKUm)7=Z=?LyrUFZDuS_kuiG^aw@DLXYwWV~%}_Q@qu^ z1RsczMP5F*49WHvF5L%mWYG#HVqe2bzUjI4q3ZccYcSszqGWWn9rZOsmW1N~hawrRQ(pQCFD(zjo9x4ELbUh` zoU+9a5@ocppL8SZ{h&ZbzeQAR8(aYbHrq!CuOOkDDnPu9?m<*sisls|Pexl;RDW3y zRRrS}`!HuvqgO-r&vAdqVd#$g9~yNR5sgS{P{XlFC7v@@fF6DQs_Nfs z!gJ~Lo&NU{NPY!=uA5JxBdr1wlv@6+s|?3Vb{OPdtF%yQXJ% zXZQI$-{&uWf6cxKHSemP?w;P6*{-gxs(=_v=d`pmJ#gU6NLR?q4OTVr=p)(^`qmy% z;jW)*8ob}cTtYXO(9I=ua|zvCLU*s2ncHs6Z8zq&8*|%@XU1eMp?ikn)-9pWp`W@% z`E0G3Lu=EUSE66ih7iO|gm%~Nf>x{n|!SXn8{o_byj8K0;k5>pW z!Y0GiUqN85C?wr|PTOju{Dyd35^7E*SB5mSD%TK;D=Hb$)3S0JCac?DVxJLb&})c{ zb*(Nf8`{vJzWAdSt6rNc-uGq!8X9|2~}hqC1I52d?E1vA&{%o`s{cad6V z*4-~lF4-^LMN&tCxmIWXv0u82lrb~tBUy6JN77xSnwiUW=FcBVcM zkz!^p`Bq>7n;=*)?5&7X>Ew~hvL&H-8S^a1HElE=)S574#`aH|}Y-Xgo1 zH|?M-_~k*(TV%r+@V-At86TqDC(>6WlX(*Xc>VjxC(>7BD>F}jLT9-kg5?*Xdfj8h& zDv>-bUVRz!KKfLi-1dm{6RBoq&m$E1F-|@r-9+r;!Fvxp?sto$(oLk8nO%=kB^Nv@ zy+o>*_r_7Uj(}G!qXb$ffY-K~vJPlGWCKUqdgi@cEh}tP!`Z-NXg4!k)X-HfSfj-T z+>i~{vo)|SfrTLX9Plrbc@6;X%!8lF$beg!`Q&GGmJ5C^BLiMxUZc-t!BwBj$bjiN zU~c#v9$hGSOa=z5U|#)Wvf#2~GB98*Gaoz#=PRus5`n|KkPBYe7qZ}jFJxT6GG?y& zg7$I2FJxH2YUZh5A|NMtU&@ex_B`;Gfroxm`1|1z)U~Q^1Qj#;?=R&mWad{g9AFhQ z@BT_Qbm=P@3(%Sm=3hFq;J6F~n8(cd2*SvtarU^30=OGY7*`gnYgIa)Qnef9@!1yL8)(m|H4uGK0Yg}@cir8+n_N=rYSykYA3KgCLTl`1XqXqd&;<5kJxn z#&JK&@{j&Ve=&aMN7I*-~v5)zgE^!Ix&lJh_ z-1mN_E}(e5J|C5e@=_eLVR9Ab?8+( z$l_cWu5h#A6&iaE;*%1peSe{%a}baIMfT-`U+68ypX>OJUn%rF@X%j1IgPJD?h|0rE!_8AG)fxlCKHe8SYU9$u!XKCZN5MTXWHkbVeU1IUf zKQtq$@*{Qr4&s0RkYhLdPg=va)6ze+vBebRIEzEBk@7v*4_u?>OrL<6i62DkU$mI9 z9R?<*qyMIZOsD=W`}R4-Ucl++B~*w0Lq!)L&izM<57C<}KKYNlB?tXWp%)>Z@UIjf zpfMLAKK`#1_rFd%SUmQ+6z`{NEdJuUyiEq&p#GO29(RLEK!bMOz&t5JTc}i@3#WZ7 z8yrEGE=9F;uTWOM(>_*h-Pe7u#p+EMz5<{`BEX1x&0>S01Ole+=fQBZl2YEV>5q!>G#@>eE0Eh)o= zSVY?zBP!{Zm5Ek$D;x{mNgz{3NFTz^BecYfRJ9-_g1SY=#;FHK$k-pgY6PZ6 z;GO`OTNTW$3g%V?bE|@9c4}$_o}sv<8o>ttssB40qW!iiOrU7rtqO7``z1wFsByo7 z(wgim5|h9lj)-NFWundi73B)3KL9?K?uo2m$37A(p-)gc$6d z{i~0RkfA!nNICVljuhg!Vd{Tzq&BIiX;&?=bQ#J3t;Z2-3-mU#?pOu=;14~1$V5GU z$ehtKp#ML5{E+Z5vXO;){E*dSWK#E#u`+&0tR5d^g&sfTk+Cw{fMuMF9}+!Io?mW= zAEK@sr)d(F?-4g-w;^uG1_TPJr(K~IGyfStg!AOMA?43{bqZ@~7h7Qa_FdXarK0KM zuG(j#6Y6W;+k&Y{n3{yCNtm_;&plw;7EIfM`(`jT z3D4y57HJYm&1~~%N}U*|w;|>P*Nti6%XzVGjGz0SHj_=M7xO|pp9q5;i=;_mV38JK zFlZox+>Z&-c0Q|5mq-obxe}>CfNC1Vb0tFbr~EtXH_!qNs#g$Up5xxno~LOLYUw=6 z>lK5L9Ct}`z~;N8!Qh3vWE!ocr84MX+EOXszEqkEURz2T-yzNL-E1vzs-5nZbN;9A zmN5rk)p6o7sWY@$Cd2DjE|W0__brn;MbA>HGYmr4JzZ9 z9oW58ChI={JTBg;9tUOl&~lE{fz3~#97nynoP%^Y)!K4de$aA`&w=w16J5({y_`dH z;QZw>;QruyI4Xxz&DJBKSKq_2IB@m1ba_k%{&Vl&qDjAb;#%hkS;Z&Ed zmS-a}L@vZPB~<6!%P}>u=Mq_LAWjXuUv|6revX>q zRLgYyRtOF4p_&rFmUbbWRVr? z5C+4kKB7a*dX9YIRH8ROFiigQM9Jl?}hc&fS z`JHly$0S>NZx*7HM;ld_Zl>MCV_N9ZE6)s%X&BHcwY}6q3+K|5;_kgDkHR+5nTU>= zRQ5wul&fH5Oy?la^X=A4LtTH5k69UP>ZPV$YU-t?UTW&4?rErL;W8~;riIJ2aCv4- zre5k9id(0bE}{>1#CWY&&{P-Eq!(hEd7EZV@XnY7563%`UA{Bscw_fYH!VGO-!WPg zOM3F-m=Mc^F+!xsAeHv{DIsA&dT7fPW2pLL%(z$NN;_EH12I0_ zDmH?K9E?E(ruJ$eeg1cFl&k}Jp|v2EPeP_5FLcIV`gxojS_@+NGfR*hdYwly5=o&s zh~@2{KvFP;@;R`k)}!-NWF*T6S@J82aojhp7u}vpji9??(2LV7dtfTup4`_FP$&ah zwmt+&gF;F_ge%=#C<9q8W9AEm-m290MKYS@5tj5SVhu}ges_@!X_;^slByy~J&cM* zOp_rkXEAf~H1Ei$Cn4d$l<%?RhiQf$m|vMLBV6XNM9eTWK4XRq zbNMn$md=nd-?UNrZHA0>d4nZ^GYvhsYo?5KIphc=_syiFe=w3QPlaQ^XVU!(y2ATu z7VSQQtJpe+>=};e2I3-apiuoLV)Evk4M#mXnU+zYU0T}?U8GjFv&3I3yZq#!DA()N zF)9C3E34zW{i~RHrdDR|J2dwln)?nbOs&k+%1mpa=N>Svg{HO8eKVL^nMV=2bz0d{ z`n##ko0JS%*;a3>&1_4lm(%9wdIUpZ9Xg*F58ojq7@#M2#td<_Ot!t>P+4S%nAFjz zpAGcY&+5AMv$^1R52BhDogC_}9IuY1yh_TzBpb1c=00W(&GKrF5P`Js9c zLV}!=MIqgLS*slMEWcGn3fh7^CTG>g$sX`dI7922JgD0FOTA znrzV2KAvpQ)VdcKG_^qm22Jgg0)wV@0>#{#nmT!kOgy0JY4fJAfk;=cE=)1#X@5?U zdfKw720iV;sfLPT3%z=pl0r%+)h4yXN3f-lGY@EL+V(=q;sEKIrqrp(psV#QGK|Z6 zka%>pBSi*Xt=BYzt_Ee#s~>+p&7iBDpJve2hE6x=YPnG9IC8nxgRiC=bhQg8=GLRt zoEZjPZPpC0u4egQ2C}QuLkqe#3Hk?z7X#?c1zjEL`QraYW&5WXDq9Tg=x2-eW`c_i z?AX4e9>sQGKG}b2HGq~RblpV7UDR~SPV5@xx?_MXB+&B=@DhaUu_3mXf=oM_X-6~d zXr>*_)Y#k;G}De|+R;oqnrTP#OqNWI%`+6YNMq9?MLapg7D^92W>DL_?B)AH{Q^iF zdEDmR4XRnxFrBs1&K^+>T+^Shy%FJ)9IpLHHmf<+{v&Dj3pRx68%>q9n6|$JO^kM| zY86XtL!-a=h_y3$r0Hg_BQyhyMx4<^)6Ejb7<8nE$9Q!!_31IRYbPrIL384gI)O5Q zYNKLpQYD))&Y%#T8D~(*E(5q#GNq8pqH&65J6kl~t3@c6shS0v>FlOauz>6_5NMXO zRTI2tsMjYL^szeGGHVg*D#}`_;#1gcrfjC9R9(MPg2-wEpDkxf3`M57`D-YT`D`~+ zHhKB9%N83;o3de1jDynZF+r8&QsOR*#anq~k8K)FOHPGHB0%7*UAEi2YD>d_)Q);= zi>yhmp!11{ZGoMCv95$l+jhU$7DH#mhPo18x4mV?wlHl>rj5z8F_|_d&#$tnv6vc* zsj-+Ei|2)4YAl|ixOE!KY~nd7#VN7g?SIf%boRSStalHfmz}4^`fUW%D#66o;;L0+ zn^=vz0hL-U-UU2rG8@Du2mOvn7li@RM=g7_=A)+MQ~B$yZB)kb?DS)Az`J~?E-x8E zUep~UJ$A}9tpy%KP-UXv5w;0YCO&~@QRDH_VXftO+IFS|5;~8U4r_bIOHZTD6Euf4 zr61+HTFbzB?@W+RYlkLK7CVjg&X!JVBeSUzUR6{a6Pt`+?5tmCf%b;xNT;>j9IZ;a zn2HUCjcu`UWKF}~!Vgo`D6QNGY;A%aft? zD)T4{7`YH`?r&@3AQ9IbR z5l#K@M#b>XX-~|Et%~&7%l6_383SVecRW ztJU(|M2^v&_5`l8RRNX2)S-phyS;!zhG#v79eGc#h>dbvH}c|bmJXddbxPHg4drjw zKPzHwQJ&jH+kiD?Q*5s&a|4#S0n6NgWp2PSH(;3?uuPX3&plwe%$P1S?wi3>Gd%Og zTd8Jz_p84uQTkh~PpIzM6#u)y+M!Ki*Z&^dc8oH@;3KoVMAIuQgm`&_Na@$2Nf00I zj+Um2zN@8rF>tk1FF@0(pl*O>J{W*p&PXjDGPcMq~(*|EaOTyI?KG*pY$dfhlaS0c|Erna*Pk#!a7|HabxP? zE#5@q$~TlY3Z=8Qdh?9KhE>D7FSmNrj3aHa#v8xQkY#-OHaU1-ZS!UsSCH&?G)~TW z%9~}}GV3WJ9*{OLtq1=+<;^x8{?YhhJ531 zZKpK$eA4R8ea4VoXlu@ z|8wNcJ^uJ}wC;0vi&@Vb5|HOVPun<|^SS4}8OW7iC~Z6%Te!oJfPD21EoZQ*zTnM3 zuGFWJ2`ISi1#bp&@*}GU$s+Kh;&-}kd>S>kSmc?$>r{T z(VKx>L3Bgr{q>?D0eR?4@>`t$k|6{6N}YN2B|`>soN`b>epqTgWiy7$Yb7+J$v8{nTGs{H{_7SxMUh~ zr%R68dY4Q?{*=pbyC%LVbCI`s)9~ExcvB`Mf6K^h_m<2`e&<`V`gh-=dYpsYUVvNR zFr^isi%D8x z9(=h$jtmIdWoM@-*NmwR{ZpP*ztJ$r)p~lvsphs&(_CwsYfW>lX|DC?3Z}W%G}oHu zTGL$Xc_EnVD4wCXMe8W}Z!~<=(+0qN^6^~LIBg4p{X&mulh`$HHp~cuyO`3jX#>(? zK@K18jRmO|>N(F42r`fkzL^}M&KM3|rlHd^1KUEaG6CAMz0k3jj*t;Y9<(7rSs9WQ zbA-hsEOCR=w!{#+vA1CebF@rq2~`lUK-uX-qRBp{t%U|uHH=W-2d4(g$M+B`cT#zJ z4;yXZqQghh^Ho@T2^b}{6E2|MGfH~2)!hg1@F=;)ph?2D^k^}Z!;;3MrJvX;2F0Uk z<33chXf#wF&|=t}7k7!K>-!o;s>{ZZ^?k3lkQX1TrnRSS`;(iiD>Gf2=M0Qj=#GtH zQS|x;4KI3z{pu05C#72(MY{g{u;H8l)4pojS55n>X4<({Tn$bN65Kv%2Ajmk}zD{~Fs zT*Eil@Xa-R&+m~rS2ySC=3L#Jt9xDu=3Lz~6t{S;E+?jhiD@j|ocdp8?ZyH-3;)af z-B@6Jk>5<7)d6pTIM??@jYc$3uuYFA_IbUMA{804E~v*yA?D` zgD4QYkG%;hbVPVC>yPgAk0DUZ@7c1OD8JbBK=Jl;8pe6~6+!QMZ{<@vIX zyo?@^*bkUA3B2%$-s@4zC-R0#gs+$=cUx+W)tkgSCY@^HBts82P2w$+PIZSC3*D(Y zCi8Ylr`lGFbM921LwE_s2!iezE_Uux3c&19Kv%zs(g$f*0c90ni=d_p?S;#iQ5T9q zIP(=4R_9d8UyG=MTUkNsI+ZF`H1ce9Vr8gp`wkst?1|@xYg?T*d>(q*u(4Gng8YXY%;}hep)s|Dg;u zqW@hFYDE9L3Y0*j?ot}Ko;lX&ivZ;jgKc9@rshhftftCOQ*2aw17Ys;?$ zmFP@qAK%tQ*~>+el@CZcf|6Q5JncAH{UDQOKingRsu3hl{U(!B`8d^nSyWRM74xXw zYE{Q%QR)fI-#2Da(iaF?SJj}6jY&k{vH41S^2si8BVbYoG-@f&& zYQ%6Egf4$L6`w?9i-*(Yx8kDdX1Fy{EgMc%CymO0&C(^UOIxW81iYN5Q1JQ0J1LLC zf?V)?XcX-EN;Q3;Dy^}@74U7N2h0SkriH|`keC({(?a5TL7Em4(?VieNK6Zf=Y?SE z1D>I{mHGhYq&>Y2@%|>BrP4!f8~bf!(%9+k8vAZ!(n_yB(5|uTK)bk$A<9<6tbeH? z$tnk_&Oc<2p$#7+-RXKAbng)d7lScW@pWVjrQWO;LOF0}2znT1ki5TW#@>dGfM2r| zTDP}hvw%Nwu+5ez5ArE6n&AInwSX;7NR!EJx5rrnYKAFPlYn9ahbxq|t8O$c1zR0I zoF2SA&KdB*NQELBL!3TJp|pyCXo{J9n>8R4=xjXL2XRpDW?Q}lc!iXQ(e0pl=yp0#zCE#-`sjGNk%7xQm8($k z!#$#@d(Swl@&^s>8Q0Pn%C23zwAA*LpVuS>Ap{eSruEWH7vJ6)cYl!QCUC1NVRU_C zTw~Yi0de1%`iiNqnEHyTubBFZ=PhaKE2h3;>MN$c;&~yM`if^LZn3_iO-#FaTho=6 zFnVcI+#Uag&C^&~x;gHDYA*T|H~6u*ZHWkc<#onrHCD#H>p9jP`%djSmJ;5HbE;b= z%D8t=Pn2=*Ksl_o3i=-8$^km-jzQfX`;=BDI)i#mhCUNO8FxlI6oez|sE4Sw7HZ+O zE%ri=ZFaVI{U+*5g)+kSodm=BT}kWR&fZMZ9y%seW1{qimllqRKB}0vRz) zM%kV`P0GKSCZlZsI88?7&YdoE^~|0w@ww?T#P%=K>FjFMH+hB@Vq2XzLz+}-XK3-Y z)hjb7?HKAWpQ#1cR@cpx^6N7>vbIyLGmFyx4wijfGmEmAw`mq-9KktJvuPW!rRi(| zJxRN?cV^R7E^-JW&Pp`2m@*~+=N41>_rT|hX&vKViYciYRg{#_S;plhG7|XTC6ty8 z95zRGV*zM(d<IxD>2@y_IT#B zggI@X>q27u;SN3_zcY~ba|Kj_QQ4%7!t{Mqwh$X-Oe)^9rST6~B|jZ}rGd7Wi}~A7 zK8VYg#nQgq2#4||T^SXR5YY1}3#TyEvJst_FV!YcR+}s*<_oce_PrC=L>;kE&g`oe zN+bM z)l|YbdbJ#~wX10#BcRKQFH%v8Wk1^ zfAt?OV+9NzE@K6NYOw+aBVO>GhFAd=a9lwYF!f(h#1ybZj1b~DrAIYtqJBF<1_*=C zOnQ%GHE*Qmxlg;B42qy{(tE@~gDBbC#HPg&K)8aW3=}FDCC{m$5{74WIGFZjAbRlD zG(;T89xaO;q-{+H+2{)Mz8=j+CZtPZum3SJQow{UlBYTN9~~nTEomP3XRy)F;DK-H z2yZKG++!jwqM8jT-0s6_+H+8ghVOjgotP%K^E(W#{xTkP7sH~zHO z-39~Q&vokK_{YtiYo^{{>J6seVCoH?-$qk!F!csgZ!q-+&kMoS8$3gC>-2_cv@1Fx z$#P+f!42xCT8}_E%Jw_U7*oo$27-QCB5^XTXXgJki zv_ZKu`j-QxNvui%;0(?Tbg7(gY||@G@zPE<}+Av&PvUKeeIQ3Xuly9^zu7QmML5Jg0J?TOlj=#&d1W%~JBJqU zFOd0KbD8-#0GEuLA``amV&-iCY%1D0MJ8;$$;@}aWP4KTR4rpG4Lytwqy3*SLXCvB7>l|q@g^^Q-$euuVYCdtqP-HK%L)`!4X2NuZ& ztBPbqvNO!A##TSJ84bf$J`PjX<_MS*aicKv+i5awYbi5-ngs(!C&IVO#@Gu#dY$By07?|A4HgVX7M-rTti7>+~ zl3El36Ij&~$l|ycx#Ld{m&y{TrYxO?8K$pSSyG#gkebhq5uU(gRJ8!f9(z8T&{SOq z>k6wGL8CZ0bBq?9OpVcUEIO43+45qemrq7o)h9>Ef(>9EaVt=26XainI-@)!jWDb{ zsaqtEHoX@gLE+JDB8YV-wec9aS8O9}FVSd7Q=Fb3BfWE)j5R1u?EqLu+A>xuPMRjM zYpmSY6*!Kp8xx%BkK;Cc)Ha6wXq0~`cVmKkOBb790z0I3YAf{y>oV7|jR})OJl_pe z*#542wR4Ae#}8-8X}&H+bfaw@z=EMwc!p zI6Mt$c9^AC5}dxA23HdjJsfQkyZmZGYBL|@fnvs=$~EMH*GjxKO)3#bV$tG3m<&9ULDQuNO+rIRCcxjHv%hQSoSH86iCHZ9X}Y1d z61e@drtuz2%4ZnPQQ`25@+oYhW_$E~i;?s)W}4C5PtnemlL1Uh||CCm{in5%Xl~8*MN@n!zSv@3Ev94pp4=M?2>~@Ty`--9$+KHcI9#ptPxw{8+8DfVd4&WbLPiusrQ%e@ny>^U6=-pJa zJ|UXA^^A+Oq}(mUMXJn#mFZ`DqOX;yQ(BjHRC#$&iZao)tXoTmLc6=DQLg2V#A^ZW zN6v*u?km&OWSW{xQO3#;gL+CYulWhF4eTqR_I)>8hQ`ia0afrj zDrTNCS~E8(7Ak+ewVnq@KTaRfJcM>5Shi{zO_7K%r{1UAh5n?xm5Iqg!Pw)s6~Uzu zZccq}tQN!#ife6DY_i&K9F?3vYMj*Q*kt8H%3PJ0tn{ZcMq??`)mq!ArtGI`aMUlx zYXJe2L1d3XfeDna7f_E*(4s6TXFM!r7*(N=IuUycIjG#RY#C?aTZxrXlxIU7Q@mRV zKg-b~Ehy(GGELuII1=ec$HhC90?K$xc11mon&hzh#;*q{cqWo@F{hlqE+ z1++y5pIpR-Q%1UOtW7-aQA4PFlA|5fJDC{lihn5aV>64VsgRfoiK&p73W?`u&{RlF zg~U`yOohbrLNFB)&rsYVg{0(_q%lZMnHWeBCkzUSm;KNQgF@nE$DA}OB%X=wypxHS z1C?u(-$-eq<{)z>$A6ofMU}OfGtbQuBF?)B4ja$3eR5Zjvr~DP%6ZS6mZ4KW_Gl)S zhp~Gu*|00_?O`(3SX-z%tg-aO?m3P<_C9vgU4qw6^a#p02W%Nh_SmL+woTheT6Zqd zz156o>MADc#UHh8p`378&L`e9_^0so>~3$b;~ID|@g380U{2J{iMlyaHz(?zA0u<3 zZcfzAiMlya_q-6yiMnSfZskNhy@NfB+PAlREeG0+Tx0KPZ}(ab-0Wmex3tA)p3^?} zatC`I#p*R2sEGBotxL;BwDr+J5$b!o`QS~C(9D2?0=x&e6hW1b4r-zuUNKDKU#6P( znj|Z)P!h-d(&q2lakBc#NG;+ovDd%aRrf&IHHu2uRb}?}mR5D|D7wFw9Z6dd#fv>r z4pDwplVtUzglb>-l0+jH&SY&*%u@Ur+EjCU~%$6=M zk0W?>EK0nXEqz#&9OQ^WpR;nQ1lyL_iN!Jzp$isKR?oNwG_jvuZcyq>mBW%^m5v*h zw`rk1S?;RpXTMufvgq~!_BM!7Fl&H4H@Y)MwHSYj2p8#!5Ft2DrE>%9 zR*?VaNeDVPEmGHLY94C&k~DU zCPaN4KIwu_8`ot8n~dLk)le2WH=y$md_dISx=6rM=m9FDV=-sdNK z)(^kphxhy8ul(>Yepn6mc8A-pm?^TV&xU)f2Cr5F9!zx!eB8PG3;uOghE3H`%3#t$d^;ZA=Z9zb z;l+MWc=V5o%_vRUjh8ARWu|8;i|8xS=?t;|Q%jn}`ed*4M1Qh!&YT!>SdC7i)p} z!zV2#88gsG6T&yt{YdkLmbFs!V6t{A*#`S{T8;?<2 zkmST=yyQmONhW=JI%e<|A3|yUZVkwF1TuL&eweaUIv{_*)%c1P$*e#1)C@2Uw)4RgSUu4Tyr~y> zm+4j^-eNK>`YNl z3yq@ZxAVbMLi7O*&qQu%&?$2e@SkxnTq(<;Cr)8HSBPm$H$t^!I!}mYI{#j#ci~EP z{$|i{80#MgO~83ub^H`#oX1N-rL3Sn&jK{`A`2GFbtM&AFs~=6Q15u%NQGL*>qROQ zQeG!gv7Ex|Ln^%bcv(n&TP_Ew&~teiNNpgOf7EB>vJcnC%RNk4LsZ|we?qwKIADKQ zQR_rd<$b{pOKd|7hj&fWGHS9A59wP5TC0IrXH1IV-O!)dlhvOlQ|5yKF&v;r7yLz4 zEWlP_O>pxQyEUjzfe?j()Z>udVVPe9eI1LQ$WS-*klm`zFXBDcPNvEMcu%^Sl{yoP zrj4{FwGxL>vb=~M+TYZvu0()NV9Pqx7$WmB+;JE+ZbCY4=0D@df2oMBGXE{`BMjyD z7g5HisJEs_`U!I-%I8$^DK6uTk$0AAnfFr>-I35Lh7ymU+;wE^vnMMGWsPWVquI=| zkiy4gINpn6)iRB0j-Z_-aQm&cJC$F^eiYTIGpPSju>Uiglp4@cx_j)dqc~>@yl7eY zU9t3xy$PoBJ6Wr7;!NEqc4##U-VN7TRH`bvJM0!_Mk4t(Ggr)!?y#4c`3OpIJ3{w_ zy`u(9D;#E-xn{0(f_;dYn^1z8Hr@aA3^SAACJQD#n~)ewZ9W6%MTkE`v1HxlwUn8i z=F3)|o-e&!k23RBotd~mI=Uu)4rZGLvXf6OkUp-nnfb~Bd3wS^>E61RnXMN}=H`V| z!alF{j)D1tWRmso&VlqnVfQG?WwvvXEW3UYMHZp#E@nQZGwUvz}&1egO-po4a_afi~->BSiXd^n0c9*>viUhCA5v1cYFzE-MeJTC3n$PWGQQdO z4TJ;lQLS7VodrL31M~4($9qpqz#o6`77%1V?z4)nrnRS}q{QZG=nU7gqivNvxDyn^H!-ZC+1F5WrrPkkKl z%hCP8t4KUeO9$H$l{ctM%Rz~yCk;|Aec2EH1B@#bvH0Ufwd_FeqF8;bdhOIP2;}v| zDIKG4z=`5^yfyiJiQ~onKDcqI*rPM}6 zj+<)oV9^N+vn-b#Y9dza7;kl)-%RZDk>@uTzvv9v!Y%wgXs!-=)zB@WQy<>_n_=q!7?e7oZd+rKX&XL?@TL;LisE{YH0_T8b37nv zai><4-Z#`+7M#|!``bWo1K_l!D}H508mnkc)gM~CF?6&lYS-0E^DUFtKeW9sr)o&u zjvmgw!xjN{5ZkjjlN);z8-nA=jy)bWLYzyBq zskx!v)hv|BHHtF`!Ck$Nu&lyicnfHpE7t?Pc3zEBe9Gc|s5MSiNT~N!q;XQ~8){y6 zE_jTm;S%d@qdcH|e3ywHuK!kayjIUAgTslG*u!^7KnIJa_j@M7B}Z$sKz zAUO5tpS?}JZ%U0F(mv@nPmg$s(1m$#3-u1U1Q@I>0e04w06XUgUzJOM!G24CVvaqj zb01zD6tyDx=8#T##jejgCS43ucGKA}x;Icy;`m?kvCfi||SUUp^?~AoF#-p&2 zg(?0U2ijo(R+Jb|6=D|CEUcL^9WBIzOvebZfhh`a2IWP)CmAE{;&#UUv2etAyqw&t zBc;Bk24bGiikdo2DrhR!JgR8yok@q(L7{S)=RRm&Q@qPO%2g`qm6WU&Wz*(fNm!4` zrk5KjhLs(4Q#Snv5@j1z_C~>%vZ-rtz}F?*mrZLK9@HQInOvnT zCV$al5Q`;;RbHi6{RX71+r;P4Cw)*ubK2J*^{3@fqrOQ_OAiz?F4y$Wp=rz?>BrB{ zp|`WruB%7>qb`FL01Me;a@9rEL$GkNL-hDar0`o{Vy(NeKX1J3g2cRdra%ez* z49Pn=a^c6j*ma0Dp{vSQ+G%jQzr^SV?JVUob-~HXKio{RdOb%jZ*3irWVKvJ*AK`w zumiyA{#+T1?h1p0xiT1C>_7uZcZ0)NA}eH&n*sAh>$)u5`w;A%=4Eb$_{B}q9H8=K{ zs=KMWo2t8KvZQIprs~eKgj=V&Po@E{B>6aC-Rt=Rps-J-Yw_Lv_SIni+Q4<>)uc-) z3UtSYO&d@Jdsn@i58b4@^t-YIPsC0XQu?)M62ynKdREm7Q)Qx{AEwGgL7-ZqpdX-o zze)SviEE-hjjaP5{h;wQEgC{lOU&x+78$T@AcA0XhM=n1oN3jmR%_9&ooe@DN@Lfm zLB%rn=w7HxjE@$}oIV3eVAcg5SE6}lsUIP(bqw&Az+XqjJX(yTKm+DzVcXPkb2J`V z!>y69dU^f1fUYtQUMPF9WFcit0A9OL z26=-LxsGupOzZ3gwi!w#;};gm`ePPTS~jqAu{?j%Vpd9>>JC`j52L(e2`i*dwe1pF z{>de*j5^hqb=>GKRz#g@i@T(J!(FU|I@M=&Tz@G=<^nsGYGLTqhnKSI=~SOyD%*>> zo7GOVf4988$L^LY=g^BStm;mkX>jFm42r3i397?AT7-_Ed+)*8PaxIwigs8! z-z!8rPfl5N`n?qWLy|jA$G&rkv4QQ{b(ZR(T0Y9P_J^cpelhj%e1*6MTuxeV#?&+I zyQY2DwC|esUGJ2{wC{dwuw~UuPw?8Q&PF6p_6$`1uOW9*-T{j@QwungjN;y8{Vl{h z^MklI)|Eq(JY_O2*rs{_Y|A|<{r52M{%(y^{X?Ml1dWsVy4u9|tg;bx4c52AmOgal zU>zT;^+3w|#FsPMQw3DQEXq?9?+K=oXex=G+rv~6JwtKpl*DYpbTooqU1;^bFQ6Ri z>;-Z4e2lz0yF)j}|5O}9xF##DiLcjywtk!v;@aEI(I`l{&8tT$H|R!&BUw$&k_Nf0 zh^NP3XitYzy+2Fpj}=)`e*|UyQ3bus@~SL3>%VQ7raW4@4`W3^GYM^3i9i}J4wJL~ zL?o4J%Jk#!#M5oifbl9b?_jbsb+gg|n zo266R4xOZm5c%h?Fd++JX)o*`DdIXso(}IoM@pIoyPoUg_(Cm>5%+Nk&nHHl^c)Kj zAZ+5i4^9`q7_fl+cVN}Svxys?V?O^*Q3o4WdE>17*hCC(WYs?brJ}cJ21bmVg9=+4 z3y8j=2QY6HmLHqw<0J2{1q|5e7UTRJANfEr6FAPpvxxo^^&GQ2OS}$T>*3kNd!A#K4;P;TU-R&6;!DplJVye=NbwyQs%H#s z;%9FG$VZFoz_A87d;7RQ0b;E76|#qp{MfXwXsrQ90{ z&&LV>G2mtH3bgYli3fmxF~~Rg$P2`?z<(R$yL36Xj}A-~d%?h_3;kmg2Yf0h632n3 z8RTbuVV7z81aGR&M+`$sj9rz=Iytj{h zt{4e?+91#Ik&mRp8&C1PXQ9m zfmeikJJ8lgzDe{1zG#s1kQ?zp$bU4*NBEronD&(!<)xFk0J~vmADes=8t_cWV-0wL zPlZot6&mHMAa8Fd&mA=4hak`N%1gyYp9;5V6&ebN=OM55o**iH%5M|KEG;ma1H^(Lt zeB?VsYvAQ>c`16_$)~_h(HFSZT>$b-ANfln5BQ=%UgRU+B^Co;G02zu$ScKqV0Osl z5AJ`Pc+983t70c`f?j~-uldMd7asyU4f0QY9hhG z&!)YWC-4b6e#xi&KCuUQl|lZIkNgAiC2)m7enyvT*B>DEi_2itHt;sULu$m=_=G60 zT)}HP)_}u+I~#BmaHat#08cjH6ySTKJnw&-XbZ+hLxJwVuNiP3;A#Wr*j?Wk@HpV# z40tkdM6|cVvw)i#@FL*u(c1NMA)8nZhWir$r@6I0_+$B%xC=nO8FKF=r=fV=r+j0v z#|IzuJ0GF4AP@4iFB*$aeNKoMU-;ldeig*a3OpT(7vK4mPZU4-;7|R|PZZZ7_p~1% zl7z+c)5wq6QNI(CM6{2*iHP^XHGburh*m!GW}<@+{+!Eu+Q)S?6TN*3B#Xg5_zS-V zl0~+Uytydw!C(26Z!YHh$XklLLk;Z*h_C%lXsP`gdVYIEOYwkD1+B!RKKP{H`K|oU zZzZ1bDc?rCRO-VxP$ohbdur$7hsyAM9^ zcR~kY@yuTM9_b|N_~7sS%6Ag+KJqT2nGe2D>UTmH(ZQ!cS2-c^+~r-xL?3xKKY2Gn zKJxB<^6p}XkG!;pc-Mz*C!P20%r{;95Zx~+r8+AulwQK!nG>3|G4~}ez?$p>HJ6CqDnUzIDEz% ze)yChZsvU^v>&N#KRnkDul2**e6d5k?aL6K`r-4`>CxE4(z>2$m;Cii^25XZaG4)| z+z;>e!yo(MO9qTzZ-)?`X%+h|3(?#UcPHD1*u<><1~!l97(ZO-hZp+c)qZ$0&E651 zh^%^LJHrx_F8E3R_QUnag-(=a)I-bqhdYt$ho}4DazFfl0rRzPG+?gpML+zWFP

    $emKB0MU>xWeLvjL54ZHg-Kpxuur{T|e(dFbc#R)k=Z81?;jMo78DM_=`IS&# zbP=a~aEDUS9HZkc&`B%-=ED3JiIu%4f%jmhutclCCO!b>5CHu1Tp!Q>CE#BTxE@CL zV^r8kmv;aTKxKtGo&$AGiow3NM*)13v)=qmje9yd~y& zyx8FGzzE<@!14-hVj1ujG?1c~-vj(Rg#4c2`YrD;NbvHcGe9D|`kx(on%yz#V|y9Sp^#MB}-grI+sx{1e`? z?gnQA-vfD$F5eFP6)xaq9bW-niSm92oU!b9An77BJs%Xj7|j4KThD980_%I35L->v%6PzBNzz6Z-jlQT0W< z=pL`tSE@fojm28Y(5{%HZoI2w*$1l9zHltO!dKS#5!R9aD$NuL;j4NksF7K zJ$4Oh?QztO8peEs@pl%9KqZ%$fzJs1MT%gdBxz8uFj`FZ!41T#J~;A!g!QNlnw&o` zzinH(Io2L+>DXR0okx)+^<$`RYbBIYzK*F!FT27*sb5L`dUQMU#xU>nx1ph~Cnh@% zt2Ch?sXkqQH87ldZ0{OIm);DkM-NPOgi+yBU9I%*mUf}k@GbCKy%QEjC#O1IrT3p~ z7fpv}tD&U49@voTy^H!?AGB;pH<&l-?Jz6-T!;!bJ>9ilc*l04^}K>b^Kv_Orqt$E z8{J%3Ka}p>(#}dx@`*G{wYp{&If4~>`ls+obk_qB5%l98NJe(;i1w#B?w}Swhd)@q zZ3oeMa>2y;Q*)=x$)8z})};$wy+0yJZQF^mo^BUI=chX&m3CyE;eefOh9e{r4I9e0 zP3=VKESn9P(uuC}ISXbuB54aV(x}aLFrH<`Q84J@IeT5Yu>^hna)!f7H^5WdccE=u zDrhE3wVC-p+dyAZXQGWE|^k~TUd}k zxnNGmRFRw8Yf%55xtYC(jp#S5cSf&{X_WDS5~Fr(`*8Z)xvr;XIsQ`qTl5weB06_d z=|6KE6{Rz0&sm%~d-jZs88c>260_$HE^u@D%qb}FVGJo)sNuPD^QRVM%`cc=(6?Zo zALoCT$(%n=6wfJ|HE)WT>!$PO%qW;8=FXcl%XNCLV?d;9cfS3+YC55rPH3hRn(2gQ zI-!|PXp_>&j31-zwl?<{n)?eqo9fK{g`T0fMf(fWjyP6(+5nhJ&Z7?RhQh3)jujp; z0>%uakbOW;kf%L=Fa0|i;sp_ghL zwm@FaqnbXBC<`;8y>(F=ASf;qYO*3RisC+VbS!i^k^RKHF%@8j;of<2wl3E2gabnIG{S}F?p>Zc_sc}a`a z<{{Mq&8;heNv1?d=Kq)zbJX&%DxN7FP z$3weTU>=87m#$<4YS&+-34~lh{Wj@#zKVR`0x3d41=G zZBpjqD=I07b$7FlPd5X#Zl=s~cgEepltMSBDlQ-;;`o`1*kz@L2c_FXYK1+h)@oM} zpL?TPq1Mj65+Ia{ltOh=Km~VYaG@NVls=Z-SN0%wx1p1=dsEOo<5+Q*-3=Q@=Ks;O z)^eh3nos#}ji=H}#~cl@kivJ+3d1nTUKDDB#DlXc@0JXY9Gy77;d#I_Jb}B5$@Ycg ztWrdOec{+rdSxhoo6X{P{Sp|4zi|A8;4c(c85C1{?Ai*Ek?_d1*8)Dgw!&(y?5E#6 z?pvfyrMwTicyF}dmdthEjy%LXoOSeXG9ozLF7Qn%6&CqjZd6Mvu-kJ3pAb-?Y*e>c zQ_`=zUB=HF?$|W>w0ABPDKo2;l-bp4%AD$el*QG7DdI|5nFar^E(=PTUmc92`^rM_ z|NUj5`2T^ju#|1plT(&f7o0*Ret4Y99@j!k}=(LGzIa79kx8_QrR*uo+vVpc9X)C>abDcKRY0?GltBKRTn#TBUxRKah z>3tepNKYyKEpeBusL=(gI_`+3%Hxg>16S-0?8A3F$L^2C(=Qw;h4O9if8Fz*r|n7p zmaHi)>7V0{!KKd1v_5!>wU-j^t3B6n%NNAg?US;|k`lPLa8YC11p=@Bq^OI+iurXM*h`j?{|DJqim&d$5EsjP&GWX&$m^>= z(SqM!d#z}G`R=^MRf$SU$Z@{;+<#&AypjfcjHhdFgC-Pm!qKAheY?vsE}<25`ZP@n zz51{0kTdk^m0&bl7F7Glt4izbd*Aq3gt_Y*&?lo05+_VM;b=N$d*#>Kt59~Uh~F|z zL{dhcaNulfIeJ*s=WDzy_}uW_doEtNhhOV?i-S@UYVwMdl*T9dlHKp({G#%n^-thi zZ9?ZxIOdcZ`#c?W_wih@aNM{cuXyX?Iw>JF?!GatYv1a3y)(3aagWfm3gO__m;CM< zXuowUcJrN7r%!Ap9)4{EobjoPRQmj+WAs@0J@7ZYdr@RcgPL&r?qd0iB)@xExpvV$ zRr48qv0Syc;%4zFivm*O@DL|a={IRo%Go{32^gK#lCg^Tlb}UYH8) zxr*DX_jYe_Um+$<96cywNbc|v86!px&+R>I*wA5NY;@&O^6i4X&z_6c^cxqnb13|j zqj4$UxyyH_EDB1g+efVq!7F0!9`Dq^_w>TM0V6$q%YAK&zTVK@ z6DgH@F1Am1Uv=7l8D74#g78KRsSZsEt`19STAj8>j$PUws(;$y^cipYqs{LG;jq>E zUM6?df+xp#De}27e$_WF@RTkD?wJHSFZ@Auqdy*a0ezuEAG7ZGh&`) z#{aMuMbER^c{<|w*I+OXT^=Tmed(M$CfV(qykMHQs)!xr_ z`pCyEMxV6>_pv&9`i9>!on3Ke(_zS5FEmZP~wQ@~Vx zxy`Q{S&LP#Gk+CreWRHb$%>7>kT^=(ekvgS4#pt7~8 z7OGlYH<)UFbj+sgr1s&|>bBd$Xxa6MIve8EKsx$SzX`OvcR)1F=w=Vcq#Ykv`+1PW zV~Pl3x=DfY5g!=IHQjZy0&68c8x^^M2R3C^Ud7{z+|v4lqFH)H7ezW+!P3jm3_C@^ zCM(zhik}4rcBZHw_q7leN~yLd9j2!1WK~1N3k-(>970mQ}P> z;FW|=J4NI%#g$EBIzrLHwF)GaEn+-Y5!0A96=FKmS&Ei~THL0H62?xMdsa+Q;30z# z_=}jP2zbQcQ(CBKn=DwMeHSgH0iI7-$pu;|Vii;HS2IQV`JY- z5vI2xdoI&Q6!92S4C~`eA6CRRrnr#pAf@d6_8c>CMK3VL742l&7Nf~@k|HXZ;)K_j zqP&YK%D>GN<=?FonVTF`0d0Eoo0$J{0!3>iujf(mI3(57U@EK&$K`hKQPTw#E(pSVrK}` z$%@=7IaCq9GRBSan>OZC74a7{@D=>aG+PnZnf5^zDW>>N0~AmUZ6H(dElhDOa}lppWg5Tmrw73}edZ$qnS3{zAzo+)aXz;ui@XxRFph>3bRd<$AR+^<@> zBBtZu1IKik!cA~}$b7{IsBk{hfr|95oSvEwn6AZB z!E}WpUSf*Yb~7zg#H&m(v~MuQ1-!)+-_N^D@%`*&iV=FBDTaJMQ(WKyrh^r6h-oRt z^#~u}F0WxaP7$9mEfC^!rWlsvOmRggnc|90GsTtg9yad4w@lH23rx|#f0&|ypO~Wl zD@;-URi@M6QpObZ{Rvts<|^WEX5b6D&Xn&sOnvxf;_XGE8-5d*;;{^7Is?B6OfhnG zn4$ytvC=xwfGMsthAGP1n9h>>=tPMk;u)j7ohdrpMCIoXJ$5n!Jx*p?j6P^o5$ra~ zC!{jP3GJBTJJ;Mt`{TEOah@W&F-3#7GsSx%gJ}-#cBXUiEilDBfL~^ z3XzN-17@^P#0aLig3(OzRg7Ue4|OudkmoR+u84f5XmBFa1$ap^U95;grs(i=rf6Um zQ``e3Oi_LgQ~UtTWm<~gf>J&}k2#ML3zjfNMQ(nX&M#+*n{X9VlwZws32tDftMOaF z6!%I6(*Mk!dNu(iV9Mh zqJlK0oAC?H6fY#+ddlZ(4%9fm2V*={=}d7UcQVEKoY|1i@5>aEfqtN++|$82V+d1J zIGpK|IEN|jg|SR=(~Q&k;>`to|(<= zhR63$et%8;$hqg7nc3OdcFvr}5aUfW=#vckWQG`*Lx_2tnG84LN$03tmfaRG;aSbG zm|+`8L=3|O<1!W@u4K)lPJVgi=x}aiA!MI1tA|J92OnGrS36JwuGoG0`kI zrZ8NB=RcEw%)+~zA+BjRhPb9TGQ=gxVTcLd#PAI~7!1qsE@y}X_hpE7{TS}U4bO0q z<`~Ejmu8SbAIuQ_h8y$|46AYdNAeF$fP<$UF`8on!%WEc3~`3j8R9^t3~`3+RO=Xo zS2jbe6bDtahQ63#C2m@VkYMj%xKVT5%MiNve;96nV8ZYm?t6yIpN3?@KQ7?i!Eh_& zb%qdWMfCMk5KI{V5;rWvEf7o?Ld4z1a5DrGhTp@tnc*e~CJZkd*#Mrw&B^#LSapWm zaC0(*#9IZpoK>c`nSe7r#1I1BI}9NTA7=QR<~VNf-!u5{GyDf3qYUxber)j1FwBRz z&QQlInqi^l_>|!iyrLO8A+9qlf}rBfTPe6E-!Q=!@;bu;yrUVSSmr>lDOBFo%a4}j zv}jUsbB9sn@@p4LGyaDEsC!SyM5)JKx&o_hO&>3R%JuEsg1&QSO{DS*o&2?xR2$tg zgo3a7NWOLlO}ZMjpduGd|NJK^j2bX+W-DmK)f%qn)*6-4lUU#9|?@fUV z76vY*y1=HW_B+8DOs{%He=X|%hT#2;c1u=z-{p0;Y^nDSTtcNioYSbh2u=U%jQ&*q znp71rk#f&v#nA1IqQ$8NP`5_WEvV)JU;Fg`IF~h>MqO^yf|4I?Hj%1)qg&B$t9>U{ zbi?@;z8B!4Z+j#f^m|%2MOU8EM~yM&`T0S?bdirEdijMnolP}<(aq@HTb%~2aa;7L z^2h4@`XokQvCPL`57VhOF0dsMm8Q;WA`2SR9f`eLcu;L+=^5kX*N8Nea(rwWZ%O zaLM_~l21l_bJ}o&moHVsU|M3-JrDGgqwXk0apiOCoB8{;z#?Ofbz0lL=?u!f$;&_T zh5uRi0f9?$0vAjX{|>{Xa%Q2sxSgsVPw=5h6Mg(CX=}44G-E`!NmSSew_}I0potY- zZwRHOLD7xr*GF*~#I&BvO@tqHX`C-Td}q)^irB3AQ=4~sH4Paa=y>bxV|=~EeQ~Qm zd(wsp-gD%kKD*Gd1+9J@1Fh*47)~d)yC%wWE`A=r#QF7pJwl$}>VApF1l_rbEhuz& z#zg8-fNR{Y*gJq)-isq!Xht$$XjGb}V=bdwQ_u)B77s@o`Eb142A5xqpFF=+Ani`^ zvZEENaH9OUl(deDJ6ly|Gj4pnC*%ST64RB>nvaeHIFG^ONM~XE1!JBsO}~@)sZ?a=Rxr;lHmx0Y!=N>2lLdpC&iU^a&b= z!8r8snj?bYL`Z@RE1>-|duV!B)Ih3Nz>pXoCo@i8oxdtl4;hw+hQ z!a95$8LpL^U-~3g^MH58eg;D*v|^&qUqjzv&^sA)eA`5Oe6mD)e2T<4_{Ir3K3#&2 zPZIu?J9K>P1OwkN!N9kP|B4@lxWN#rIMW+rh4@Kr+XZ3;(}DAfbXq3%$sCQ7u+PEm z@TuZ6ZH!M6_Fx3WR)?e0T8CpS;~AO=P~!H>Sh8%Kg0C+#5+EWngs2IzRtyZ$MhyH4 zLkwKS5Cb1JAa6zSz@IaYfiE${!1%0*as3%$+#rS+Hv*6+j3y}V1Wj={|A71f$pY1! zFe8R(a=)T6&h&o9(;=%eOok}QFi~^71y~#?wSLCWGLEDCXz^zIBHH}yC80|7hjgtW@|^0v4M z_y-1_1(eSHA2B2ySbwq3vw zC$NMePHY839A_0^C+ya8hLYutS7?sMm;s%3Bg5Nq0EXzejUmotJ41A=VpxKEg(38s zj~JreDTY{~vkcLWGm&)KjoclK-;0}&;XQc4!Cb&65XA5SXakM#{56J>oMqbkN-&&^GiM0Za4$pLEN?OFfK52SPA?+85#zY)zXfa?jJuj~ z96*P2A1}2JLmVKCA=*U&@{+p&i$gGBrek6$oSA?-W-!FevKXS{D2BLciUB*lgnNSV zF*tLEXupzSZ@j1&qWx}$IM9ATUiuow`7ve~kDItL?x8m!J_GV4XvQ!W&wmU4fdNAp zV&<(FV!%R%Q=yFm@)<8;90ynpSR9JSk8$+d$Pm|l3q$mKg(2Ei0rEsd9w(e}4bw59 zi-4JL%kX+kWVz!i6As{I)dU^zShN9bJQ80whS5+B8Af8M7!Jg>WH=WeQHD6s5{4Lf zHDKmJ+|`WZ47W1G1h)frdKtOT8NU@Gw0l%+3I2zT|=zK!BNt5z`6C6LT|u1Ur*}+`cD6 zOso$ew=V?jgfCbzLs(^|F~p@=0JxlIRE{5+M_~m5RDJZ zgMO7EZc^W7=>IP48i3rt1z>S&eC?Qi4C=B$&tM!@oGb(H*NmTkEYTPy;6PIV`SB=W z94j-2A#Sb(46!oz17_CXreYiidW>;Qe7%9czz`GP%@F-xVTh+{4@30-fFX_}5<_8v z=bPdAXLHNf%)m{=-nRS-4P%HiOEF-+0jC*o9z(nzRx<30_Xk7hxDPVKfhz!;;AVb; z@o?OX3^Cq+8RC_{pZT~c-&)RuUYg@5!!~$K81g;94PM1P!0C1g7GuKr}$5wB1e zAkIVwbl_$ZiKOsY#xWfylFbkkxs_obyg?0opn(r#h~q3DgC9-sd@o=EW_Slfe1`93 zI12XyLkzT@VNX2g4AJoghG_pPL$v=dL$o`}@J1{(!)z=u!&~r8V2FM{0%q1a9KSNo z&;J$t;0Xi;fPewp7%;|w@eDDMP7LuF4P=M|4P%&tr8oEw8T>~K{<91*k=+b2k-ZFW z!mFGiCUO|C$&0xDoYG3~2T_XQ96bLF3-NAeScDy4h6S+tG2D%NqXh=Q(#Hexn=p%U z+%wq>XJN@1;t~x6%zO`99gO2 zJwtSG1Oj5Ia~a~yhB1tRIe{VgD;T2v6AaP+kU__5#G$`v=odHvyl_Q342$O<9a5Mu ztRdsy=qz@d^n8{u@d8?6z%m0)k&xe@;=s=v3d{?JqSDDwOhC`Z2A@L*BNqcPJzBAXtW@vxfoXI0UxSlw0C&3rIAQ ziX<6632C$|GrHaK8)Z~A&jcNX6_`)b(NhMcvjTyEgweJo!#*-no;4-xNeLS(>mYmr z;S2|2K^VeB+Kyqq!x6!77|bmUM_^Z!;V77009vt0GKL8d^V&0nnCE6VfgauyG;ujT zKN*bPg8p{>-S)| z9=os%H)5NK;U=*JVsraupv!r;8fzgon{Q$GtT1egJ>T0He?hDbzOKks!T2t*Mh?er z*cKRnQRXsWr-0iT$2+e-!&e;0c#A)Lj`-qp5!yV4c-3JI#oq5AK0fc|Vll;@?GT35 zVo_lsg0YhEx5eTjX(_gG8HWUbMMg$VY}qozcNB|_T}tf2GQ@WhYc8^M6fneRtB~O_ z>@_kxF118Q4a{{y@2usELhIj(LBY_DdLpgKijMQk#ntyh>o!#ONVnELgK_b{h?Mnm zyJ2CAtyIx^w6hm}4we;O&1$htp8(MpgX{SJ z1uE{0v|BccGaCJKIKr1x*NVRk zgLq%}XqQhmIt>n{vM$k4O&_Ynx}gcLOC@dW5#0tghS$6u<8Hde#@R?U-J@GOcY@?= zRt*mDx3$H4V1PA-?5Nz?yEhkKtvRM>XZgB(*9!cjG_%rBq1dW_mFoPedvR6`Ii_74NBZ^kAv25d9 z>>r0=y&?S;Lv?v)sA z?_S%|#P1{56ZL(%?&E~|Vg&-UeN<>N-q=S)ztx{kw<_9ca{5-;2J=)^JXt^1K|3S8 znsQCf&DFLpJF01;$=O$Jn{(Iwbcs1rhhjPR+b+#p`zd>U{b4@XZ!M=+-!~n!c0IPM z#d(f=)4FP2HDJ}5tn+VjJurExz4G32Q0j*IUPW)2YvA(w0IV{Tb@44*uOV+E_|Rlc zc-uNBuUfDoH`WhWXJ_4hz(J)ZYxDuzfXBe9Hd$xwtN{ld6i`_|V8KCKuNtt5OxF2> zw$&JV$U(bI*2F`k)!&g`-+-lUsvq#LL)O*xTKJBG@|Y!V<9B3@biTd3^urFSG&{98 zY~7Py_kwlVWIb}&wuDWNI4Eax{h?YPvCU!wSZhtzjw80q6>}7q%VcGs7P)!3UH~g~ zOZ|X*kJ_e@@h&cx$?EwoT|NWvUorVtz^XM_2j1mkdj@O3Fv>IW=1W}C(bV3nGz zi^psiIrlg&m&qzTZoP=SPJ$J%wSK@akJ~0cwg#8WWX-CfJaZb(T3jxZ6D)Cag$CM)d&8*3|AbtdZ-)R(V+Rd{85h->vs{eV3`w5`Nmu*#Tq z-w>SBhqej!{0NtdISF~-d}QMs1}E~_`r%G}WW6oChMd5aGFcN&(27K-aeco9tJ-8; zIYFft>+gy?PU1>ES3lr`CvEfd{}@-wWVQL&_8>eA)-GoC?Slz^Y`gN|r*NUR8{;`U zo`Rc?C?+T`${uj@nA>C+-qwdt+3u!Jr*XYZ)~%;)tleN;Hd*`atfVuzUeDJLc;gvc zuV=wpYqIv(S?*78y-Zf8Pi(z5ftC6~{eZh|EIRTw%=xQcfGtzZKIyEj+hb>O#msKc z+F2pzaLIPmkLW&U>-8X5r6y~Woz?6-E}6+{d*1dwSqoOc&iVl>?W~|WTr!gtQ)j!g z9|dcd$$F;FHjUs5xMsWR2W)@A###$jp2@1TvzmU23no~jaV^6?rO3Y;g#@QxBh1YD z6dI(gATyHNwYW$*Cn7?K5oi2G=+Lsfjlgdbc-@UCDI@R^0#EHxkIxc#8RLD&M7x@< z0-n`GN=l)WJqEJ<{vTMjuYA0pY~nmD@XIFt9`G>Ad7_^GwZPY!xPFQGb@h1DR>12O zu1tA|C?-+alg1ED<84j4(24@gA`PT0ip-4jakBD9+zo{#W1 zu4#7;tS~QmZhuikVRVEuwM%-2QDG-7GYtvP0@`S?+8NJ(3Zs{Mn>hw@=EU4UqjyI) z@eG|1J;bSUWT_lkDo2*ek)?8EsT^4GleqOi2m$c3VR*rRFu=Din%dS(IJeuvZraetI%5CM{ zfMU%C>>MhYsx=rQovJ=`#+t{(py_mJxLDLaEd%~G$HVJq=t{YWV z>()#_=}zavZFO1&<skm(`H7|$1+yJ$9#iGWGMC~y<;Yt5 zcHCe(|3dpFESNT;vpb`$LY&v|rtXTiZnJB6S9V2PB{^Bn^)b>--eatpQo@lg~Pk zTYn{A)Zx?)P&L=c{B@`#j~ynsF2vK=ce`*A!91RJfjk+s98)+-Q*?T1II_+{h*TYOzLp42v zqxBi1sd8bLVEU(tE5Nw~=Bh#xr8kG|j}B^}7^J6Xr3%GBACm9c`+8EiMqz^^gFIin z8SSf^*I6hD9b3fsdAc8nMvkgq-|=nf3;iO!OG;8_Pr#Js`!xD_YV+=9hrDRN+=#5P zowG7iQ&UolGK*6>O-N74>XMp~o|c(al$p^vwQ~wpNBddDlOyko%Bkk2q#Q4A^PM87=R0fWqb&%R;+xqIl}Nd6 zzXaP{GHB<=wl{O+GfkC}pp*oqBq$}p6c9J~Oj0oYD!Zo55c?2GRP&ZidK5#PU)wyj zVVlCI5=bctEE5RDuB1s5OR>A| zO2YH57*n1jO9#jbh_Uoxi+nI3#uOt-Xax{#xBDQ;k=8N>v6ojN=Z~kd$bPZT9l3DA zlWr2h## zYl;t#aW&8lQafd2N~6Ja&!e;Yw$(h9ZDaar=C?sCUTQ>4sh3g+ltQ2s0;Lcrg+M6; z%4%TV1IlWktOoTrgR&Z!a^rPZ2;Q9>V{MdJlK;>tF>&T3Eb?blVj@klkZJo&jhXAE z1z8G#zPmrw1wdv#*q-=Q^yZU4YwTjj|=1RvuA*4T-%X&ZvEoqbP(qGRNlDgA{K$dJekH+4)_(^4Z z;L5aNeq4Za2vGPP^^OmugwmMc24Z_!28s&`U!Q}trlsF4o@1pk)6Bhm562uDI&$svaf;iAMzJSvnTG*#Gp+c-HbhyEj;1Xe_L>3fE`4ThJ_27_-xa@e zX~iC!=^7HbW$0z`oKn8FY(Jy~b|tXaf1i27UhUx5KT1?PwQYfk)cMDbH<6;Bd~c@0 zL(X<~iuII%4R?y4ZBMtLl-%xT`^bI~I??P6>%mQw{Yzu(wIV1r-`HF@1SR)n-FmGE z%8J3wtc^cVZlz1_G&NrhT;Q)S6&`L#nQ0yvh41pHP_r3!RVh5>=40L-N?_>w$>L2Qh;2U?apn#0afNAb&j5Ly<_7 zAzfbHv4Hcxg;2LQW6HEb&l_*XjMB7aHcet|F7-g5vA!jjCNkWaD`HgjmvYI&cvUXP z@VcG*VMpjEv`1fV2oQ!V9P@&i3T)~%?%-R7aC|!Q)yH`$P+vHj>_Y#fav?~^sGD-^L-=pPGa?no^RLQ&$F*4=H^Dq zZlLT2%5I?45T%AFHALAB%zHrD4V2xW{$@~Wh$%c?cQvGA+xFIef~A4H+P3|_ITGF0 zuD!KqA?yYaY{w_s9f|aiVN}^Ap%ra>xSzk?bC?w2HxBCH^65DY3GthYNCVw_64mVs za_hd6sPYgz{sAushPj=-laQ{Hs$XvttuLD_V+p>VEJFYscmEGyDDX#TQRO)dA3mFk81FcnB9DN- zX*TU*eD`e0?=**YjR<$^x6YB{zcYulk-$HmBl)A}QXb>e=hE7D(EsbXRLS_Cb2)j3 zTc0|QE;GJ(p2$=n&RCyMIio;pF<*{RF`w2lz7>$ih+aT-jHfT4T}Od$UqGp&f&X^_ zm0rM{Z(2xYj1L6lbNpZ-)iQo@p&W10B8nUXe8D0)-Y<(}F!q((TDWxQVi9$rk629Y zhO~D(@3;er*M#O(;g75F^c^&FNc)D0QCg>r6sZ_x&+%Lw(*BsQd2b8FXuyv4jXZyk zY5%;hQjC;hq!c5i7%9c5UJg?BnTUfPpNvk+P9p#+rx-pQ!o5-*Qx9N`>1yrD2o*%Lt2Rbn^N3|7)6QM&n*c`(HmR zYoUZr1etboE6ruIfaH&$>M`97ov3mIWgl+u_Nhdw-Jaf5UEm)DSE)6Jq1${mhSepv zfJcx6>JZc>Mp#us47Jub(um47erFHv;7dFIY3>W=@+0kI5x~7GRS%`}UWk`2l$MXg z-tjKy$U=^j{-;+!w4N|dgk0|h*PFfPBDnbnYd`09P_(r zw3dnOj)VC3G)@oa*5^*AIwsC!;$73_fi6#{)QKSO1Cg4wZWkujblD7A@d~U~&1=wf z^$d!v!CljICe?D&0w#vfluG34nIeZO?O@`1D8wAK-?)TIkyw?^zTe)Zw=&)a&Zg`S+Pn2$vuV-??c*&|SD1Hdm&{I5p&LBVbLNBg!*%m16*vFF6YcL- z!7<9$PWjp?U%PUp%PCz>8M(}RKpDA|k*oe@5bBcB<#@;UIvcr~Qevdr(s%2PTuo_D zq}$S)Epopox8-yzj1-V*{XP4l+&#Rt7@JndkueB{asGm$ELGBPO$5ojYy`=?W(3Iq ziXa)lh@7Zk+BY{YK(8Gj!`W}hl|k~i=dxE>2)R-azy3h3jG)n}BrrLaecy5rP@~_M z$D#5@#LVM)RQXkW2&%)zxt!mdVKaKtK)Tekd9Vzc$v|?i2ukgPpqV`#-1T{|;IkIy zotAEdy6Z)Q=a66?(^4`rfJ zCK?q&qe5uR7lIP&&84`mV*LVl5KWrzzScy;-1{aG$hf{>tO-UexG_7Ua2grTYsd^DCKO$^1&@S2Dl(T~ji@ zlKGX)uVjAng`i}9b1AN?%+J*^&K`F+qJm@pBlw%VZ;$FlaSRc>m zv+gvN6iZ3>O1f9ly^`+D7o?Kzm2|J9dnMhQF9apsn@e&1r27dhlQ!_t5fmR9)*-gR zX1+oGzC*0FnQzIoBjaPeeYFg0GhdrPb#vm{(fWfSzRq>ngpYuqPI~L6KAgJ>e=ovs z29eUO(gW%FXG2|j!XO#1-t16_OHUpoQ%?QOoO)yoIL>5jv3HUwr*3}^%n5^dyFY|x zyqV_GYca-M?Lz2DaGZ5$xlwNXUp*8Opbch)!D#sVU>Tv&{~a)f*ci))P|iCTZv8tU zE^Q4J{?;f|3{At|2p4tp{OQrrI8u1NOiPvUNfVdPET{txjdDI|66KsV)Zy@x^IHs_ zb20ENX%bkM85;~I{`3rrXwoGNnX9^VGIWK?J3K#T#vW^8UT&=GEgt`yVs|!CvDqp% zTg7Ip*lgv`U+=!F)C8p_C^bQ;38t{5)C6-WuBV#t-MU!IIUhdz6KKgpu~v+Mz%)wz zvysedb!3{1%s!3CVXlUqKiw9YT|AxgI62h$>9)x1OGdEps2R4%>}g1pg;*`c#UaEO5khRnWdCds z3z0F)jL9xR8ZB;lrqmXb{jEV9Hp>>1J!zI~`N1q(O!h^Cm^<4RlU+Dlwmdr97L$F( zAofCDEi)#2*c=&YePoU;Cj0ap8K|8**A|mqIG5_~fs5CBNW*2uWM43dgXh^|vd7Pp zN3WS@#boQ}4Pw9fwvg;m^X1Wx&$oqSpF_?rj`JS6z!s7{5ed8a=pQ3N7l&m3!*SYQ z8QHtWE~IKE4yXlj7E*L^_pcXHz+@0NF!4|1@!~};UPMJq{DFz{7D?iTMYM~FJ>CQH zM@gh9*;)S7WD277*D!g;VtG4!wV3jzpzS#({;^mds&oleGBNpm5X+XxQNLS4mzntP zTd{~;M~koG-9EWXQE=UhBDbVO={r|Y^4qbTups~K*hEv=Z0VhrnPNDgIR}f76OZda z>>e|K+=FMeuQEv~law+^DU*~kNtyDL(lwQ?sdP=HYnm?vrE8i?aXod-?}OqR)6l>; zOPLhvr67M77~6)r70HUBhs>HCZTlLXXAL4b+gEsvJB>*&_kA)o~6gyy8n z$KYlbjNla37VnmEC0u)5;EiCgGJ{G&;i`7p<#tYkt!kJRRN{OKxU?dPxRQ5)8b+k| z+r(K$q?X?48EHn6-~SHvl(+OlU`cssa!Y#boA?CJy0&pyrif2$tMdd$#yzCud?n{A zIbX^7O3pXGWlGLha=w!Dm7H(B5R{y6F2(hf^G{8^R+gVKEzZhDEQJ26)8edRu0n{N zJUwnuBQ4Pq?Dc45Wa4~Kd2lM*#!h9?+8;86|2>e4A{rIbdl;=ye138CzmegRZE4>G-T2yf1#XR_`>I7w~x4G1S0!X-)!S~H5wxgnGy zP9(eZw!%fs?K2zRVZIt{PpzVaH<;lawvm%ZtrXs2WgJLyXntIfwPCNLsNvf8{5t3n zL#XY^WRW3CO7?Gm8`;;hePP@-D{fpY%KF7|u}ZR6lD(4bm1M6Zd-Ln1Bzq;Tf29uD+fJ4#wT%vlU@anSmq{KYcmaO#Gx>qPpX8 z_2u_+{9UL^o|%=BLPdqqaoU}p{F=B5KXVm?xZdeh+;&xXPl@YFTvy_{64%XlqY~GZ zxUR%?C9az<1SPJUOL6_g^$8T%p~E#!HJdwhxMm~1b9{$uHsUwMcX%w$F0<=dBdrXs z&f<{{$0X8v#Yg+_Pj8njKt5%v6xU~jw-vLFC$EE%)UCvok9gcQfjXaRb z2cs0<+G!N9AB|A4trm@)O{cTROipj?oR<%1i8ydXN}Lj<`f`SJh}HiPb;O8 zwBBxg2?~q@*M6WnX8(i02p(-J!XCKDUQI5BSUk(v@5gxBFI1L~hR)fv_9PmvK-2>l z-YdyN!*Wy|$6z!%uRUVI$HJe#ipjxHr!`6zDfN6H(HHaa32c&xh?$N-M)!D#dF0;;}%sud;q9Rjq4GKiy`8958((!EVN zBhdLnpuBW_7Rm69JwM&<(nlg(3k&5sN7&df?R;@qDr@Z^^IMQOC6HZI6>W>g2?YtmztZ%0){8W9lW=~LL@ zZe`9;`jOI)lzyc2BU1)Y`jOI)lzyc2BlCrz^doaAuBUzk!PJ|a&vm#aAVH8He(qY` zNsv2i@6aG1;bsrWYnnAsmp&4HOGb5a?|~vB!N(i+iSFJ~SIW+px>C=4p(`Pp;Zk5& ztPZs7Fr1D=K*E81+EojCMNcZct6i+mVE7cRKsKtIgQN5hhH*Q@u@9G~jpE@{dLbUc z=EFs?3;oJ)(N$kGf`by=`l=C7E-;jXYJzbX*GS1;J(40rz+P|QZAMWkJhGwHVVnI~2zO{hbz31n44k}=cEg%OP-MW1p>WgDYV@c=EMi_&3 z$a8sLhkXr=CA70uyf1||?iJ(-Io#otGMgy1K&b^vEl_HK`RP+?fl>>UTA(}_{z`utUR zJDnU!+51|C5W7P8F!N}0sVi(T>?+#~y9yw?K{>a8)!=Bg6&~mMD@~yIiP$x_bp(&BHwvayR{x6D5ix>b>r!{sZId zEkjc8%j(i4Q`SWsd7o$h!1!g?D1HN;k9Shl^LWT6f7Lz6^Yp0rJU^8YS!G048Ie^+ zWR($FWkepAO4Uc5-AHMFO8ZmVpQ-XF?ay3_>#6+-=`?Bkwc4K`@7sQ@_6Ks5IW3L> zA#Uh_beoWZs^ePA7`U>rg7-PBEh`~$|7BD3w7;nEY<#S~bh5Mul}(nubATe$1yDN& zfxGuqDeUisFCCIo`5c4pSK^e$pc_l6lH2SrmByg=N@d&IW=UhvP$TW{n}BQ#dViKw zW%|!X)C=%2vt|DaaDQX#&yTYue>z;;7+;DMzpN--nM2i#`_Gm6lJA~N0inPvpu({+ zDgs_@jHf_RV`J1S^Jo`v?EqC>z$uQMPrF8hyY*R6$hdhJoY+PJk6R%0J34hEvgnQ+ z8Qw;JZGoIX2Ga9#i=N2H%RLS(q|1zd1TQyMyLvC8oKe7s19Dd94;Il{#xFu0;{}=IvV(220jC7730gGYjMKhOG~JhamP~GeMN@bs8ywGJ- z%6KePCm!#yWmL`hvj!f%oB|4fcU&&V+pwI97~ip6>ZQpmXcyx>R!Dr`3epP0k&F1t zc$a>Bg%)m$8LD`Q2pLU1Pm1*y8h|R6|GmcIc1wuwmD^+Ge7mpHm9^RrJX75%zPmz?aW+?>#3cc%S^b& z{x-8y!ZjgHUY!%J32A~P+f=t34vmDbfRZjw}fUs=7I^m@%z;YKAtl<2?KnTEkxNulr2QrLX<5; z*+P^p#JmR{4=**pn5BrDTD{hecaO1mD7GWLXrr&*!KCC}2per8rNd*g$Tg^uHKp1n-3#q( z+qlDHx=__=e@oJ-{M-j8G^&}^yE-f_n{r!uH=tOv0Xv6ErfLm_NT;d~omO!_44O`t zhWjO(vk;Wrf@Vn#C>7JM9VYjLGtq1k@OoS~s;btlnSj!r&WC$jQkbAz8rI0VM4(t# z5Xdd$+S=T@7J^cKqNzo}+=iORRMNJ&6xUPQW|@@6w$iWhgabL=Jie^q!3|ffNoeQ< zM?$9kZB4@V7WN|YdJ!`2c1bV-WY(Zk`=$i94tS0e_$F^oa50jzIl=9-W{AVl%ZQpe zfp8Zj1VaX|)MP!BRv<}O{qO9-h%n#zPjg@W^l&QT#JwCtLu>wM6egUxE{~v6_I{hW z1!HR?scZ`lcv;4|=rcx3OUbg)GVZ12s*a*4d>g&V7|VO?o-xv1LStmb58nb|FVVti zSE^Bqa%F)qnP?ADQ9Y??p|qNW7gFAPFdFPElvb0fLTRPRERt4}TZ%|y{;?uqHPO!k z=Q<+;#!9nE!B{H$*zinyf2=f}d^%Q+F>D;=v0-EqAPf^&lk#l|$Z$4JdTnKor@C!8 z-A9V4D7kkq{nNx1pzkQA)MpavtpNcwaiPx4wA3zH(rs(6$FudBgtr3gud%1}jf5ou zN-a@piBe0HTB6hvQzYHsH*ww0pDh`Stpb$Nr&(J4o0CA9QgPVdl8r!k(B!86+Gm!D zL@w;yk+N^|v)Y0J!S%uuWlazl?^Is{YM7 znG{IW@i-6LR6yxURR^5b4~5e*oVj=mrJu$PB}!B?JXcEm;Uxnu=napC7(F0hg!6$^7XS`MS_yj!Zz~S3yp@E zLzKD_^G&2|WS6lfBDBJqFZ``-cBWLgy;B-CDQVKgQYEjaTCy`F(Mf}LHorzK5#*PG z6Rp>!&`kuncSxe8n?RiH=Xot8abceZE?U1$x2YxVXV8kGM7Iv8U&kJvwG=GA7U3XW4v%6=DZ(#h@H(0&ZdWKa|nKz-OfVDJu5Lld)PME6A!ch znbBqY!|cyxoKRE+d!iYfvJJ^>oBb6N=9T8yKRt;e&(UTQ{< zJtPxMh)df25%yOzIQ<@xIq3xFFc6b->XC|v8XFUv@F=^m8C~W+%27=Qr|wbd%=XG; z9N*3u{TS6u#T_{PF>AH73)F5}Vyyn7jiyh0oJyvl;rz#~VYN?bA2 zocV;U;b|(Ej)vdZX!_76X(u&;z+UFjxxru9Z^Am)Z`fZ-`^An#? z-ipdwQF$vWZ$;&;XuTWNM#Vv!QdT>)t)+0)`Nxho7pmwd-b#XM zz0m z5Y%)|51~a->WSn~+S$bAa?VGo)@)ljB@c=Z$Q9V{ox~t#YM1nk zEMn(K4V&5(jpOx&gX!!kx2TKiIeIwJ-;(Zyi{z!Sj!iwu?@Tp{8oHqqTcI;r2?Y%o^W_1>Rg;XAr>GGWP>J_BX zKTo9udGYI`*L6U7k^m9s}=Zo1L z-7T~%YsVfDQ4uTK#X5TrLNYg5PnCbdR*-jpqbPmuFu7m9aG2b$2ju;F?}fu04yt`5 zI7sf;pFu4k-jVNxxF@8B(}xYG9nXb^(1yFqC{V$|Gp|$Q6nf$H&MPC>SL2!{rwUTzi*xf~|c*Ij5-A1s{1=W^KVMXi{%|Rs#>MW&YX=OnL51N6Qb~173l&^N%c- zo-6FUfbtNb(TK;oMQca{$2knR4K4Z_DcHUV3d2@E#-mMN zcMPM5zq119$k(u^^nC}x`^?bK=gUxcG4PueF<%HuOEH(?I%z3&8O+l``6oDj9vXh^iSqM5%i)VDGUMFdice zA4{bd>(B4pSSlLNcAh;+F6{@ZMMIyS;~b7l(qy7%OrVIIs9@SKKQ6%8Z-T?IlP=#5 zdr9Hz4Kxw2^z;mJwbA1AxX(FY5$y2D0U$Ui%fMRJPf?d)$`QMBtCmJVT^l6}k_~c5XNo%A{ zLVf$5$j@9A+0Uh|{Ki1 zXr<@oQ6xO5U@!2?pvBNTkSQ6zSOd{6aj!ju>|Zr$2%93@`WvX!!}w=IXvH&~-Ovjz1t%vq zi0R4HF1Ba`$)N~^* zWY0iPc}u@=jmkrlThe3S#3#@LcP9UC-pQ5&*723eOO@F}sX5={%>j!L6Y^QdoH&P^u*RAKj7U!Av)S$ zSV6Qp(msS~VI~Squou?s0n!T#P~stLMY+{MEiCFg#p7k2k|QrbROa9`a|IN zY;HI(JtpX7ec-@Ubppl-QHvszs#dlN^GfZMCPOLy^n{;Gey>3h3Ynpndbm>>d9qI@ zZ&BjB66cjTuf%yJ&YPbsCC)2xUWxNcoHt(xN}M;B;(ChnER#~3_9>PtlQ3-v@{aZ? z*H}D2wkYNnwGeCxf~_}Q35pB!9C4?#_O@rO)t3#R$dyPmyKaCC`0kUC;&QG-y}3sa zC9Vb1{ehV-B$^ctPmh78B}<2=GfX#re+{~xj2d&vy@P4TA6WtVt)j4;5qrH`RG$+O z;?Dih1A5Wgpv-8!v8Y*Lv{_nTfsRAEAIOvC+eLh~&p>Gd5h2wf17!jz4ykrdhRmPK z#p$A*ui>Ykj8GSm)%$^GQ5j0pwHi0JVD_9@lV?m!nwcDdztoH_nTB>yzQ0+hcS>ej z7wPciH-p+9Pwhk9JH?)q1ue!Tr`+4n|H*@b7F(6;lTs3tlAx3Xr6iaiLZu`qB|#|( zN=YzZ2uevXm*RRV2`QOS60VkAt0V~W9o2r8N+5IxL5{mK<$uE;T6-S5Gi5?p1JxiO zIbO#gthh3tZhs=htw$pC`5@w~xo90Db^GA2(;mJ;Tz?vn>sdJ4k9IhowNOj;S?%t^o48J+cWcX6j}^<(haj>~;)r zgo*8_EJGI+G-w+WTZe|V(H}>GEUuXmG(ncQh?yYg@#q9j?u1$z6WECf@!`d?z(uEG zimU?Ok-qnZ)i(Zar_3#P?64 zoKe8vn86Q5GwD-{d!epvr{Kv_ZcQ>@Q`BNx$H1K<-Q0awux88Irm5qiw z6c_T=!>3Zpo5(fAmAv&CQz?8)ireX)?r^jg*QdfC0P}&FZ`V1=i5Lv zden#ve*xx<^CF$Dwwh8Av#mWyWhlK(A|71)j&(i=V?Rh$!K&F^5?FW5fu5MT)G7h5J!9vdIp7IPdp zg4>I!@*Io@yNgB9Z+$=P8C)a0^F)sPcI&snh`|NC_e>P_5bZD(b&^ICy%X#d+~n3t z6%RFb>$N~fgu6LZq_ffDc33Xh!Z8{a3m&8fkn!`A4Y?%oJ%6`4%`Y z$CRnkBC=?zG|K!mRa!*6rpZF-Gp9+5$Z`Y!W}38!{54HlRHjX5i-=oaGF=|;@^q>- zEhO3u+I1QS$)7=-j0vRjtMK*uLq>o*n;|R&g}ON`Bmz<1w5lY1 z3F!yYf<(}_a}n5N*f}@_Za}WIZ$#!&<726?bL7e-v|EuH7fER8{6`2&S$QlqMt?7t zL%$I_ek`>rq(HogA%lrpsfULC1{)P zMkQz~L0bvhO3*f62ujd4m*V;f+Oz1n*t7;#g;~@qF3rk93;BB%eHE8xW})>!h~1K? zAqlD}XeW;p5f?s-P#F4>i?qE>TG0c~hWhGLu$z4dp%>3T8|u<$O_OmL%?^dQ^m)@b z4O0mH&768<3^>kt(;SYwsQUFbfpq(GVE#2-=1raPW|~W%JwsIOrYFJixpM~OdT+|v z*Ca|mJxkW@7Oe)(W}`z0^?wIP8arE7%@&*!vt?BFdggpFn>4QVEjUx>$gW`Y%*yXVTX-K&{XF;^D!7MuY1IdQJqv&@N{C+qhK&NK65 z-R`6#;Jjw%IMNcVuO3_n_p7}yhik`U?*GbX4JUM+b9eLiS=m|=}3pPbhP=0&CQuGLl zo*~H=??`*8h1T6t`LsQB`NkV!eVm99Ip5gQ__WU`;1>9f35D{=9-jw!cT8wrpMW!GEUWoI%5w(98%4M*o=iHCz{6kdPIz5oCvi7)YjHRV&#iP{iJ9#%SkI!Gk&L--hn-1DgE>WrlSRXHV4hxI}B_bq$rON5;5{18Ht2 zS2Qo7>TD>vH^LBAuXAwTUoD+#SB7=ae)T+lAnnhe6rBEt`QYp+Af>J5WrMR9d#hSo$%XTCbi0Ghn%XTCvuLq@@wj)!eXhZpnwLs4; z!Rf7?4fKjdbUpypI@S!J?8EI*M1!kxJZ-C6{+z9DdHruVZ8@JqM0=v)#DzZk31ry) z6G7?&^Mo^(b8H?9+}T`!<2@AWU_GFUoxO$*l+`>Y4rCR;t$jmPfytpV=KL?Cct`Fa zhhv2dH?Kiyb1vR7;HDc|c!L~4sa(6GO?bM^0W3^UOQF&OX&v-q13gb1NGsClbldbV z%`0N*RRIy{E0j2|#CavoD{)?l^X3auiStUFSK_=9=gk*_66ejOxPIdNbUHja-HJPh z@V?eODv;^)>y-2cF&Bn$plE9P%ieY&UVp#8^apE;$O?ar%4YVB(&BAGe3DIwum8=$ zcv3C}>}?rL`{u?4=)H2K2b2)gYh_G^vrg3E5Mq3XJegQ(J(UDPV|XEtU5MN`jw!%9 zyTUp#R4N6z^W$93wZLT+KJQ)lNo9Mm|Gr^EqGkOaythl4$2g{?-Szv_nuDUDCC-W*b3C3HEk3q}05ox3^QWD7&~}uP#(x67YIlH>#@Et(kz*oz91Q+cs>Oa%os2>k^@jbp?UkLawdNt!p7DB>B`U>Ejz_kP;N1E4HnAP|D1CSVHWdSJD?es)bo@KKhHRY$>Cz z(!Pp}Sf8t_;7%VYQ%3!|U6#}MbGt030m$VveE!@HdD@ru{?j~4Ye9MATFSZ-_q{BV zMCp&eT=7VTTYv6dS&<^{m`oCtb&Nwj-1^RAvXVyCF_~Pc^KpuNDj`-oF44WmWrC<< z27XJ8Ob|7sM)Hr=$OKVmYUFT(Yh{9{@wHU;aZm`?($G)V$|O-=+GwNRlZ7*;y(h={ z6p*t-{q&xkX36`qaK;M2kC1-pxA$d^s74>q+LOSSejsy1J@A3#dw(c%L0oL)JN=Ot@%e?sPn>Uu)ryH3a)QPn48PO6NPGDlR; zld=HGzLT6I3aPkG${bSJA5-KQ;JF{m_HTYnrHsFC;J2Q_#RZ;!O3vrlDGDe6e)g11 zyfykX6)`^jw9G+u;WX`H{KwNW5!bXcq!l6@W5Ad3E`7-vBT>~E+W3fUgv2Aa- z-Mu~~*Atjh;HT!4HhoHkAnCh5rLxbFV=VI`?PUCxi}Db!T&#E!=z)v!q`Q4axs3Py zOyX6a(MHB=KC|w)o}betrVakwq8<92ve$!l5;T;Q@#^`7gVwJ1YOfFeLLA5IZ4m01 z@ZlHYT)lF?bWrLB5DLE(hw}Omgfb?4_N5q?3Y)kB^sgLL%f!iF$#G7B5V_H-z4Pm@ z*bc_a?lt0T2bF@RPx)HhA6}n;P|bwzzLveleB+>iN)TpzBU{vgP{f4G-%#B>?c84D zzID(pCd~d;5MfOY#(!B=bjeNuC0&lxZ(pwDvz?RY21-e-g!NXk={@e`>YWtBro-Cvk&$ z-Sjh-Wh>gmZw1&^NUDY=XC*uJSO~T5a#`gWnseIzsh^z zM-VPELH|wMre5X0VOh3;u<+SggPcv8ib~QU|F64A^Z>7;y)mi zG2ziaqQ|7uJLc9sd%qL9b^)sAj^RzhsxxE4WRb z10m;%B)kej5fctwk!RcQZ>$FsM*S^Yybpr59fVK+mJ=Ir73;x-f~z8d9*uc9!=Ikr z?$yTm-BpL6nQ$Jz5cp`%9(Jao^Y#1=b4bN zX_T`DT|d+)#_jcSI;~*BY+a+GGZ^Dnoobli;|0QMv{>au5j#M5%uB0S z;oV-3_NEfX)4eqcSceABc~cb=UI!s>MOb^io0D8SLFns5i~pd-+fFKE!iOM~@=^Qv z&`u_d@X=@&ALN8j#V+7q02gBxG@@K4%xq)~@l_+*$b>)Y3A26a5)m1%zbF35lVq8o~`<6Dmo{``b)ny3@ zOv1d=(^HHsueL+!>?wCoy0LeQW;Bf&zfZ@WO$eeN{+s0Q8U9Ab(T4u1guSp}&z!1^ z4^`ZovT7@3PT#DAuh z46@5V)7ogQCtH;It+8Nwzfsoho-s``H#xNwYkv&kZU}>G*I0MRzm$R0KQI$J4=9zi z4=$$n2WGl-_>7ABvyUaDxbzPO$uPJx%&AAdHaHPEQNgt1kE{Uw+d-@rg;4IFSuTCp zU=a#e!M`UBrqw|>!nVP-20=q)zLP6`l3ZGhtgs|{mJgBfZ`(I^3!u?`lhWzFV8qF_ z>7V3sw#he*OJAhk+99ShEMJMRQNP#Vq8Grc08+Jn?{m*N2+#95IC6=;9$P&9!I=u*9ArA~kn^guq-CrLX* zFF18n<0)lB)D*Y&YuG0vs%77XlFIm2{S*oMa((c7Xf6dMAyD~0gL-kIt`gf45g_wwLvu8yKT6iBSEd-Tank}`ZQUTWbyqSAZ8h9ND|tJs zpi0)JKz(p`6WN$TO?!5X2^H{Hh43aTc_8>*d`9c++7V6wsz8RQREG!#Jp>%^keiG6Oub zu;~U;AJneQfIQkP;Y}$Ms%X;z%BglqCOAyM<_6w;kO`Tz*%BiBi5Iksb-*t?A+!To zIi6-|G?7Q+LCOv_5&JC0x+6tc9V$CiF7;ZL#qzBi?qZIN1DtlZX95olX0f`5C+KvQ zP#cfDyO`wxmRhgXG*;I?z}Mf8C+wTF$h>cPz+T&iclE$e0d381Z48KQDWHjfCIXrW zXdeVS9u0RtgeXFwLA>W`WMiIS_#brO%ksJ{J?k zCMW4QJ(VF9at({CB7!0bIUK5FK>0{-7oN!DL=ML*mo&1-X$-WGlxYz00Kb0qG=^G8 z?KD14+;j$8$e8K8eSA8@E#$&<{uSe~&MM*PNH&9N&o@qXmPql!%e)Ac)vtBnJpD+pCR_!_)eqW&EZYe{WCUIE^ zEA9Hp0cpjaNWt{;_Y3B*uCSx|pf!o&sk#FE*#Y9kjI17a-A0ANRm7nJ)AkDL*59>n(|KfKnzB!;>EDqzYypk zRY7$nhP?fY3h6G`_XzYNm#ZnU5bG?xi2Cn&t=wJwGeSyd*wzCFx%557jm~Y>KQq}M z-%}=++-cko6h}7hH1h|FN#st~keAt1r#o_|e|_;XPE)+uc%TKy;Zz2?g+$J#Iz2hf zDR%6-XPu#-wDCyG&hR>5tkYv`G}Y<3v%J6<>$L7Hg|3Z9+J<~k<(iD=D3)#9$pgut zCoRjg^&ADbjXUjQj8SLE>5D6Ho`POy*u+1pH)8jBihdiP{NZ`cjqtiaA#vkQfs9is z--vw|C{A{UpXn5`VqGYHzR28sjc#?=MT#8dlRrc@DxTb^)6t8Xbsg{{#np{F4f~OY zMQ-bdv;9c1wljReKdUngyhQPK!|u2yfi!+e@XJZJpszZ=B#V#pU=l z`DYfe$!_SG%M_S9!>%yaNmV3Xq2RpnpqW=RGoM5n?BpgoUB;7Xku)|%%1;!=Hy&v+ za%7cfruHX_?HhNh|B3%@*+?^LDBy40DZfT@Q|{J4W>cLEwVDghL%wZOoeF9-&+)xl zx?A83gMx8wuJR`|VsZ#vy;{QUlb ztXm#-gDn18eXWLFhbmMwTF;ML6Dp|uHoe-LnkT9Vw*+T4F>0B%lMC{Wo9g8CyJn=FzeCyQP5c3Q?{~ft*?k~R z{Rh-x9~i+uv$BSZf|xw~a1-aA{sa6@<9GXa0QUJ4ikj*(=TBa=klo?>KcS|nPSP#S zk9P4b@U3iOw)MAoITJQgtG{4rQ=K~gr5Wk9zu;6;o%U)wJzobNRZUFSw@&kW+*=2^ zO?CPNiPW?JWqbN^tH(4UO$?M?uNkPi9tLbQG=7$9>os34>u)H;POu#R6k8$3dcEc$ zfBHB4)YJg2Z}YuUwmL<(p?6^uvy|QD+2U9y?>q2vQ=NkEXqNE9JMdjoosQnoOgH2% zbSk3P8-lBFmsg2lQ(U+UGf~m#mviGTe}6EO=N=rUCo_}hp5}?YbPrk=H*xYG_cT_) z)cY{5sZI-#4t^YO%z^X(2kcMYTmO6|APBq?3nQ{ z|H|*+8o{)|*zJ-mVJj8+2tK3TQXa`GgFid4AA;RZKhiutQIBEF5IQXq!Y$W=)9$Ao zFKc8Z@d-Sp9W$Ts6CnQ%_qRhGnzb#d@ht!M7wnD<>|tS3WVpNOg9Cl}-nP#e z@a-594H=p4Kfu!89X-sWq662f3~S3)cN_TRwLm*Snzb8bWV>gZ561;A7KCfD=`A+B z#iqB|^j0=@#HP2{^cI`mV$)lBA&5M6?skBsGzpR3bhpv)mG^21mT zEoOmq0mJxL&f?a83C7cxS%K#h-!76ItNzJ6Zu}pg2jw(&J$61f{?q4kFiWVU3wZnC0!F|lwhMXxjd-N=hMfzkv%*B27IAt**G0U&eGz9i>|dmzJ9J*m z=nbULVvX?a#f;xTK1LyhFg=%WZbR4--hO`x=QbQ!0tG)iI+tQqBPpNL8%F0t-ZgaZ zFtR~SKIb^p<@58hU*;T#IWKegQui{A-SCo@@-MVxDJM8=SjxMT0#0yfQ^4s0`30Qd zuu*P5EZ_tO+htrocNyn4tXjrB-Rv6fFXIFUo8{b5%!Ds5XDkO&xLngyw}Mj~j4QZT zi1l2tf>RteuTV~RkXCY2U%r#>)tV&_$y>(FNv_p>qKfmNLFP`QfV zvcaoqr~~HdUd_KjB_3(})M`HRi)%RDVbmIi7olUEvpu9uMS?^PdXMg7fCd|O>?<@> z!9-@f!eQlauh6Ij6S@BicQ3L|^ViZS1ca??`P}yFXvBeubXdnvDp|*Z3wSx&J?l7@ ze7KH1wv;+SwidzDh|bPHc@t1$Wwe5h(Lvp~cZo75`UVGBGWnX`GZ#e%Rog4C0Q{K^ zhx~VgT2SVM6ZIsug-*8|?V$JHJu4u13UPv`om^X*eRf-Sk-&ad8++I}m9#X!P!{ry z1p7a*vV-l}om-lJObdET(CLNuNqC=x_epr4l-H|3p8|af^eND%@_nq4v7R0ktR znh~=((i}3IBTYOa((DMK(Y;y_Yz*kw(;3n+3ol8U4O<@snaHsDJmk>BCfGrmujKK? zNO*^bL0%+eB}W4+TkoNjY8qei%}NRZtACmR?b1WHF)_ z7wkQ4cYg;|AV!w2u=QG6J4+s>(^?7^WzFWbw2GFj*)3~|{>AHD2a>Br;f=`0atahq z47CTlGIUkf@Ec6ql??-Kc7i#!~SVSLG^pP8R3T#eitoA|`?2#~S;**9O@R8g^OM1zQ|Hz6Ws@TkH zdxicNhuW-J%nvrx`d;!GUu@RQ9#TRpeaV{W67?JmGp*9&mpfCUS+nR;TJ%fqJ-SrY zV3oH_EA0JKsb=hCpe4ZM-V;InY7*8UGhpvOK+`*G3oQsH_kL-Mvc|O3O*!rTXp8)- zXo=tSHCi1EpN-I8szUKmq2NZZse zLpE-sg~Oa7_Dvjpn>spi+Kv^(FhlqblyBF_w{NGV#N;XVZ`Tavxq}uJlQn)jG(U#>v87juS7^e*mH$I@5qWQE3@_!CjJQ$0r?^g1g!##K@z_$9l! zusr1Y&rpN4$K;bvzOJsTerOr1LME${%TyKK&O}>!JImu~Kzp0fu-)n^q3==IpcpucZBQ6CU=Sq# z%P!0b+!;P&0*`dPIe|OFA5PHtR2O7(kN7Lu8o#FPMD7-EH<1>BmOY|dCvxBTzKQA_ zkiIn*p}rGl1ROYtdz=qX;x6*<X;E5^n+H~%{?134<7eB`{g1-%kG+nj_=8l&3gG4{)A{J0Squj86s!o>^4;!8tyh2VP?LLR&gr0LWxL`l#m8O-8KAl4yK_(J7m*a#N=W2o^ zzr+UCD$~NafmQ>9&ew+uv{8G`x}Pi(nNABXmZ?q4iIL}=dL^^yfL2#(muc= zO>e@4ix%)e+I4btZi|IHhSqfUCAL}Zg`l3gmJetFxH2;wM}H#DxN<413c2) zSnN*rL^n3=6t-F;G-E_A6&_oyiIWb)uw2Z?#o=Py8XhwH#u}Y2(uQXnzgei$`Dh@c zV-bAn9%89)TXnUQt5u)i;6B{nl$&J6lq_y~}mR|Ierz)=84 z0UVVVqyUZrI11n>fTQw45WrDcisl23i@<7Hhzbf3CN6?Er-d}|FKtn-Lp5TLPY>B+ zkY;PVN(Bi}>(JX|C`~}%sAd(14f|YLNNwQhrj9P~?mibI8J(y}D?T=n`kI{KG1XWa zm{#0qH8v5QQ{`Lww}seuTpUP#B9B6w@kJjaxs5}tL|C`u9T%fPKO8FpL3w-sw(tZ` zl(L|DPB#~z9WjQi{#*PUe;nmMY2+~w@g2%{qMW3S;Q1xl$j7ijV_l3qx)Q$SnzdTxkO3WD&9CKspc=w;I;atu$> z>3n(qmUi<(c>b1P$UD--MIY3sFI2B^^(MhrUpe@ z7@r_V>7s^KH$yI(!>;)TY7~at17sjpTh?shk1DIqu=Ynxtpg6_{kxEMSWTCnvHc^w zF1b1m8>;jYr_`|}dlNZW3Te&fvW8O^f{a5&^Vww$r|u*+ly5ok3e+lWyWv;lY&DcI zc|}94yDk^WVHYs+Cn!)TcN4Hd@4p9SKO#O<6g9Gfof2CEo-%FDNYZOGkIYv!oM^|s z&G{PYz;cFMI)AOgv@?=Sxz-IE>|`yc+D+SvE2C9JUDZ(SQm<+rjMG;&T)S&mHS;I@ z%*l3a{*0fw=9Gl<|16X3D6vbHv*{zRX}ESNa?Kj1IeHDk6<*zGttR{z4dX817e32U zYn7D+;J4H2&2P)TVVKePUO*Pf9nLhkSbCUN1yi|AXK7vHDKY zPkDm3>TSzZ3!Z46&Bv%JrYiQRKjnW_>YfH+)tvKoc5w4;%agS0spj|FNe8}r<(HJc zH`az>rC(|&UtI@F70vsoDgWBpiT~(BB{-$1VzDwz#M^MIF6_F2X|k1Ed}v1kna zR%8T$Tt$^dw5lrvDizhO2C6A~Fur3MaDiUFKsMkXddN^zk5J`X=_SuK!wL>C6-|rxw#K^!4-QmrT`}5$8V5k^Q zQGjzf80YG@_@}K?it=7 zSYyyczQ?+8BJQ!a;(M&obNC)>{2ac=ibs|WJARH%cUu$LAHgz{VSxU8&Hz49ni1+n zrpZy^=L>jD|8>mwtVG^tEaNf#xyv}%W1-nUFXMszw`E~nmskgA{Xr``$ZX$oc#!|16{--+=K7Au%XzYb*BE9qt;eYG@fh#DeIWSR7(tE*+eBPf^YH#|7&J~d7}y}&R`c-wcQ9z2cJf%mBl~^VXd=t^ zVJ7DZIMYECDrfe5g-7;>VJ2tH+zQV@}UdzM!qwuJl_UT$4+kZkU z9I%cD_zzpB>3IaRK4VnB;d@N*T*M>P*(Hx(&!hckVeT`_uyoIEA}-KfmI4jaOmE=9 z{`oA6nTg!rz!PWNY}DMpmpAfI|3af=8M_`?%Z=c$EkI4|$dAD_-RR|5b9k z=O#JUA9ItPN2bBvO+3v1lTDh$;69sK=4>eh>W5)|DmL+(n_2d3>AxCT=MtJh+eG@5 zu)!c~m6bj8pN7}`UWsP7PNlT?w#m@DRH;eKhCEbC3vZjGZ=g28GEFGZqT41zEGR{~ zS>I0qu*$YcIspZVmcBt-Xn}1LiQJ-D$0J*4L2VQHUKSc7kOhI|x~VMvHI>VNx#kYc zz=YMT%1B9? z^>Q*r%wC3MBm`T@K}l(HP*R#4l$6E+voqFgy(YsjnlkGl_MaI%@4+D4E~ogIBs5^A=A4vIAm^}sY#Djn8~^DucMHn+jiqQR`waM8EN-; zj+H+g&so+zvp5$%43G4rPcVNMg~-R{_K*o2A}8Sy^>Ag5pFMQXLikf7C-q9t<{)`m zHXq@7Hpj>R$nDt^IX+%7k?VDnI5aj+(tPVRlQ=ZqGKpV%TTG;$jZmlyNP)zQ6i(*2 z`1Q#gCp%7|keG9{rRSkO!4oqKQ{b{-3S?YE;8L5T)46Ma%M5n6o}JlICBabrXry_92wmHUC6!>9OAq;f29515Jjlsq`y(#`v^_ z`2)i&oNI?u-CV2#eftIl`@w-Dl1abmGh6uSqG^!IyM|$QtsKp*2Zvpklw0fI-Nzp? zMnyWolj5*ev5WWuK>kz&U;p-5-4iPq}JOd(ZP=pOy9tMFB6f?4! z5JL4aza(y*#utV8D6=&X+d{({BHB}Ip-;Ar8bGKRyQ|UI#eXm0zXA9!9REe&zk&E~ z5dIsC|Ayedq2?#WF9y$$QdD3ewSxlBSTCDw%nWs6iY+91nLPD=2W`ROy;fcI0r(*k ztejX%Vb=0o6zt9_qq0`{Mr2~8WBpP?@IhP4=Kg^PNH0vrGpkq2%p&~}Y!zUulrj&$ z$Hvl5J)IZJO3Bu^9 z>ki(;G|Bw6KJu1Yk6@dkCUi7p&gW! z#M&G5=nHrrq)4AG*7W02JtVHT=}eZVLhWHkle8NAdJ`8Yi+6M2pTb9aw}1mrTel#q zQ^AkstvL0xwUKllO=%h?vS~EU{baJtvGNhbmvy^w==r0uWe z_8^Su8trZ(Bk+iNnCwrGLX_s-0gC*I6?|~Q_&oI3f)x?d(%do4$%}1_Bs&W#el(g4 z2eWj#ufT6dY!|W&t1GVUgeiKF^;HDr+hW^7o4f|NMBmRh5R4t9Zlr3QIX5rzij{I( zEx^Rdyklb1f!50yTbP}pR@8Ts@gXiHcF0hn}*k>&D3I{5mW4sf^4*`gDC@>k4N`t9POl4D7WL%IX)SaPBQ@_Ed)zDQao}&ZVy4g#FEHT zq>(g+Qpin)x3Oeo5u6(A)P)2g1p3#;xzyfhG(?Tl=`dBqRzw?FXCs|tGKQyJu&b5I z#aNqaK5{nle`>uv4mU1FxtcFtjQmiLFN6z3xIlypM7ThdKdAz42)H5OhJYK&3qimQ zWht5oZWJ$wo({*lMyVw%m?Yg4)m53AN$#4WIw}&?lFjyt`ly8zu7MHjq5g%i_RQ}= z&dGK0D3*}UL7{Jy7x`iYb9xXgOIQ9C+TnQgt8`>XR`Q}Q-py$B4dM<+T-d@9ibi@H zN$ZhNd)3iP!g_VI>$;I}$}h?!^@ltPLp+kb9iTcq%mr$OxfzK$38XL3tI`WRBT(j> zfU*~oLHZuuDB;*aItF=Ev6L##AwsFa&Z$sEWv8fY$|$J4jIygx{(P(p9K0Q8B!7>B zyc;<6izyIs70dMHW@E>|RLHFA;{=`3ydB8E)Y86Dmh8;6^SZeb{{X1p8|Y2$jDjl{ zO@m8+Xn6%HFB@IW?*&ASR5{toV#47SQ8wnZps3XX8whM5uz|n^0vjlQas)OI*g#+d zfen-wg1`pKQZy$vXumv4rCKv2@XJ?zUdq%=61O5sjh<4>Su>im^K7I@4L0bf!3G5y zY+xwB%Gk3teulf?M+;upQQUx)d+2B8Y>+=I@ll2cNbHW{>;&d{7&wCO{(m%rc^(X3 zB9J)GD`~&JvXjxU1DV|Gp>{}{F2p;DIUo$dSiE`{7hOu?K8Qb(cyQFDWVsq1^$E;N zX3-=TEtPE6^UxecE1!gTEgvmH4{@z9OXlF#2UVFEl6n` zcrK1Mk*#qw2NQ0~_l!2uMxHDzzJ~>%i)3Nd;%FCGdquITX_yW1?aRo<(i3h~|6vvB z2XQqCL%1YlKzpxmRqciw$+Lp)NMmm6x^HP!}8OVnbbQs4Fi7VO1+j(VSNG zcJJtJ%0$eDMo9};R@G8Xa;l0OCoW<(?da~&XkTmj#-p|N^&Z*2-mA5*vBB(XJgW9J zHasz^9X{?EZP~SEVeJ3UyVh>zqTbPu#jdrmuZ4Xr>}z3PE3bB8Ukm$M*w@0oR$d6g zzE+l^`RwbL;KclBH5dgA>6c*Qg6IaOb&+x%mJMq+KqI!LdC9`)>mAAC8q=h9dENNj$D=!3L zNh?dyOqR66SJAWJ<}r;WjgnGjR;Kni9{o&;8D_-3dOSK^k`gqbA49cU)5Y@EbcuFr z8XIhD8jtGMG&b1Q^xxk+yEXlPv!vb4-=2&Xk<=pQ!&g|+!jcx2wDR5-mb9>>g(WR4 zY2}3=ENNvan$MEX1>zE;iIV;*Iv2LN#F&(+(VWhOAlH~qs)W{KMRVHS{GMwJMtb~z zG^g#`$5zHdMP-f1iXCfVXA3)9*xAbKTiDsc&K7pIu(OpHg0QodrD!HQ+w*Wt4g^n* zQInN0$+weZ)MO=0GHFVT8XsZ_0C6&(of4C3&?Yh@DZ?mZ(PY>)Os87`(%?32q0%$f zD0xA}Nz6y$(VG~h?jU`OpL6GQQ$M5J&>ic-_U36xDp5y9CxG8W8xuL302TLbOom@k zzXie_+jSxNiA*Iugxt2hy(C-6>m2JPt%OQ!k&@vcT`-wQn-Ng=pH|M`ajv(~&>3@@ zjN*eQ%4IvESg$#Zjnff2!L83@?BPIVj1|27O^l;?=$x2Y!qykIzOeO$tuJhSnlsqe762vc=)--jz`OWt2*o9n7I&C8S_kZ3f-_~Hmww*ppA< znXPXfg|>bx2?}P$be2YG?EEy1op1S!c0Nf<0Ef@roZ#@BZVqHl0xhxX43$)KN4E5> zFtcF-xAaFQLN%@BO7+rdYVNzh;tu{s!!_)qHR$_eQo{sp(61W~5v5^RjR_5XQaGHW zfR~OnwC4Nz1@__A{HLkr?~lbSXk2s12?n^vwlbq3Um=o<3mab8@WO@{HoWo|L)h@b zh8H%xu;G;#g0SJ0rD#4IJ_m}NW7T|uYb+_Xt=M#I*ATI{@_EWmXS^|0^?2RsZf8StMcSyQq{-|s002}2_GH1tuC9%)L{iAM< z=7~LH=e7{p#znSqk!@UL8yDHeEy;xi77$oKU;%*z6thWS0c9zg2@7DBmZ>oFMyxG# zSRC7+5~(cycyVlla-_02Wl3zqnxtm5ZV$Lf=^FAW!OEUvL)-Csq;aY6UP-LUIu5Pp zGAl@2Z_}ClIfmCGtsledk>atwt*eRPF)_HiGqAEkm&QWHSu9pMVjL?gM6$-gtoY6(eiLWDnYDakb&Nt-NQOQ>@e)UL*IL7TH^Eg=)xodurX;81Q8pqjS5 zCqTssY`-x9Je{%q{sc(;9@|5*A&<6`vT5m36S4D;ku zUY-bCLb5S`PS)ad(DCw5ZaZ99C2b>PC87f$xsk=M4{L=ydHF(kZpaWptbg`8#5@byf9# ze!fumaer@f{f^j!&*ag;2cQ#lxEb5RY+n}JQ-muCSBG$Q2v>)2btr$r1-udPM!*{Z zZ3a#VtW|;g8lmjLuQ({EAjUSPtQ)?WX~vbky}f53C45^aWvc2 z#|Aw^C}5YraX_36I2~=_3JL$~;$}X5JGPGqMiLgfu+W8tE-ZBAkAtw#g@rCGbYY<@ zF9czsD@)PL7P=i24v4dcxEJD7im=5fmvw)=5ZBmXXF8R6YzegK1kBNa;+@IP}%Q}9`Hd- zTo2{$vURH|iE}f5m@o2oikhvxME*`c0SyE+P+pJ%8VG10pn-q}$_qh217#_i6B=Zc zJZto$#0nlXEpA-1mD#kLk4N{BpzoHrZVl25_0eX>Um|D6FVJSk#|F!ek4H5-J~mi( z{EXM)EYbhW*7on)huhj@)+jht*i+rEGXr#B1B;r2&5$yCCl83Rg;UwzchI$%&Q#8!YNao;n z`)NlLBu2%#LJgJN8ws8l9Zk|gaF~ZlLwyrawl)d!PzI@=xx2!_+i^zXo(y?6aJ*T# z)&3Py1OnPZZZ`HrDsjX`6Q%%7^EMg=;%2)qRMXU+qwmByTCZN0s;yMD4^I*0tzTg(VS4AEGFIx=0?Xq6OO~gb}{kKMB<>hDNumc?ZHl3P(TK! zsH9*+A!gax4N{~}7gCr4;nU(xr1b<22-;5IfB=sS5a3Y(1jJu+dJQK>#VaG3Lg2M#tm_UVRX7aOBb0L!o8O)iI%U}-qJQr&6;!TF3 Vb9K6o99~g`Lnh1x-&yg_{|A5}tlad0_AxXaFtwABdKJ;H?DM4`PEC|P1lqljG7lr?-?E6>{|3R_-okpZ#fbg1& z^>ugnH~X``o-4A;H46WzSpPvo`$dn1*Hx^)?Z~jeL-U}ZxrLQJA$TIwUz(+ zyMyaT!oMylZwU@5R{Gy>%8Lxa;a?QToKeDWi&Oa^K`GIX1Sh#z>6g>J|GyRMpAB9r zC0qDEDAqq6r1YgV!XFjqe#ye?E7sT9*+1yZ`dY8%?@z$``j+zV4~}D7|MXtE%v>tG z?&9inMkraVzXkq}>(<}R=xM?$_6kwR~PrCiH;f|dTKlyy^ua<92~d~i_s({jqgDtMgo_`~AadZX}{W!tBM=U)^r zuN}gFEYqzk1h47;`%->Dj_`-YN(uWctW+rXj_{Am^mRf7ZMpEBP~pEQR?6hvqW|A7 z`)di_|DjZj+#&pjVihXx?f93aQph9WKbFPggi3!>D*HST{=8WKgg84*sQg#u>Ssdb z-xQzLeTBbWtbf+%tdHRH8jEko#ljyI>mPxCh~2Fv`2I!lYxzp}2gUkN8okCg)_*kX z*Ea#{-&nRPk+p>1m3>`>Dt}R`Ru0-ejT1zbIDPxMs)x|E$~z5Z-L!^T%aFYvIlRT&({M)BlX8))?zL zq1G5IN80{jsqJeK{!y9RSE&7;%DsI;Z7conKa@J{vxL7@c1H?z{-D(La1?%9tiJ_* zSC2m_)TQP79Hj)*J}SJHvSzwf2v{@ycO_8xLipQdQi>3GGUq>*px%uIr5v<26M_yl z6M`#xt7X(_A^88QSpN?Os<-PJ-=m)JugkQyLj6B3);}Zs&+!JOQ-ubl zt@OYDeF3a__V|DeMrJF*0Ac`Mpc_($d1LE)`GC{0^T5aeQ|Us~G@`)4JljL`bODc|)M zTK}fBsplbJvC{vP^8Opnf>K7kCA@!V%paDv)w&A*sw__y+CH3&#h3m!S!lN;l9!*l z3++ml?TahM#gIPT7e*&kH?$lruy4Lj4O+H*JFw-rmZRb1!YbXiN6*h|Xit^85PG$u z*Y=)=7Za-E4Ge*>9*w;00_ulAT#BK(SZ90FV+Eo^V4dJTqxuCwMA!OFp?!JLdHe7a zL+orn2aCJKh2Q0scf_^<4I0)7hT;aU%@y{-{r2HL^@Br#>P0o`8{9vnUjLxrpaB6P z_%X15R8UAjaL9oA5OKi1iri$O@5L&R(Lk)E0jfgL=f)k*-6=ItC%63MymsJy@U3e<<9%l670V}Q?MHwA$B zkQ&{U4q}qL+i5FxA>*NAgOW&eW#=Fn!R~57bRREe2^iq>v#6{s1BzNWmgGpwGde=x zW3f(&ju;xY&MEZwX#OL|_A&}F_q~F_r?ci(Akqv>RWvU$BJE1Pl86k1xGp7I&Czx` z9DKHtT3Tcf_?&c5Zw_`b2*OLdy{YAC4|%2Clpi-pTIE(7BGcW}_YILc;4{dp1Wz5v z`$b(P+6s|DUg~{8Edu73)c#v2V!q;dfko&TBSEWI5 zD?jy}3_N8BTNJ8!br5I);X^gQ%?$CWv@=%~Q^h$PSL`+su%h2lnbUGbEs^ zlluH3(*HM|j_^_!n>C0oQvb35L-M|NP`ij|)Iy)`uZJQBJkBt%4!3 zo1^-`a-J-wnhK9^WqbUqTA&$NEOb%lm4Bjb82H>Ws@I9g0B!5HAg+?;X~X{1$Fn%J zT9m>Y-!q^QM32-gA|mQ@ZSG)f0tLTl{(c~Wzqw5`e+@Ga`KVKidAF8&yP~X3)gOIq zs8%u?lxhS%J2X>71b^N4Y5u$*@;2l&(~i`jl-haz+HzqjeKj`|0rh7(w_1ZH5PpQH zk3T~Kij3+iGbD1iTd=Yk4Dl%=25J%Y)x>2ChJf*|>bf%|`jC@43`6p!dev3BD6U?i zhf>LX?AHt;?`hr_MAUo3T89qOytVjn)PjPEuIdPx;g(iPf9b=6I?EOOU9Sq^Id00I z8YuJ-V`VB7Zx8MaS)Q7UlMyrY@DepoF=f2yrT!&gJ5(F)P{)WQ@;&hB+t`mxXa~7F z94#cF9hlw_EhMuY zh=Tgh5q^C`^f$P+7X%+D{@LIT&Ai33Y$IJC%(px|4fTTRHwuRM6oWrGve=gDEyg;_ zS84ODA#N+B@1gZQw7!RycGdbG8uUH1zK7QL(EPMX-$S!QH+>I{Cy)9bnx4P@jXiWk zj8lK;IZ1Q@ziviVNR?q#ZjccdFiaLJ%DYp*-RTFm$&q?x`)J6U5m>f8sO>e5bK$9<4SS10$zavyhxI;JX7m$QvUF z4I#d#M-|Z#qIV!i{3I|>x3`d_Nw`n{;D6EUsz_b&|nUf)tl5-K>iR6Y;K>P&j zt*1aHtsk5M=}vzBBEq|{`avwDQ*ysp&VD`?im@)e*|$ElI=d> z*An*$WKweCClHm5>^`4@I2-E$pF&}##UF|(^JWD1BC+`lNTBS5Of*?|rCb-~m2)u4V{aiT(W4hjmLLBOxC-#At|mUdLa& z2>D1A@39)`8U^O#^)2FH$fU$G5R-<)Yph1X`$8rqMndLFFHd#>;CiUFGkB+0@Wzf9 znsyimj7rA=yY}PPaR4%D^^8;v1#uNt!}~KTcwO~yhMub`cti9aS9@4}xnfn+v8Gd& z)&qD4UqJDy3ZBq=K|>Qcz%ddq5YqQLdcal+hGGR*jBFl=(i4KOD3~RI)dxXX4ub6$ zBG_;c=Ug)gk|?->f?r6W&tNE|-~$Q<4Cb7vgCQ^%!Dh(_Zk9l=ArMc&w<-jfNcAC* zRIRPWU>za|ham}?Rxz~tND$s&_dMmatI5z8tB0X@jEg%|XiQ{9RM^#up2om{fcgOq zAiOcLkgFfsCNw6ls&xu|`fPc9$z+QzAn5{L~elQCCO(eRb3Tz%6Dect7vA0uqDYZtkhtbuj^n!IScds*_?;62h*wqI{B*P2wae z=}Zb!Op)6u5Z0l(#dteK5H1Enpo@ba`T8)^OpzmpA)acg@RO>h3`Y(NLQ6=$XLe6n zWHb@iJg$vN$YUxhvOEu(EwHl~T3#1~Pau9-sjA|2uA(}B9daG~ETrQNrlKN!Z*XPE zN&KWbs>?SZ>^#b6-EMLn)sUNDraG#hZ$boBN*QiJ=z4BVW+I8VxTY%Y7VpIQHq%rQ z@7ugS^EOviExygC=XnQ`sB+5x4iqFd^nijCqZ!p&RAFV53VG))*I9jd zmv@tM7viZ7EAKATc#-$+K|ZZ_zsKkL?LDrtx_%D|Q3od8=NhZg_qh(L=sx694VLf# z!m73PNLh-5KHyrb#0Pw0ZVw@fs;MeJQpD9(t%~@JwiiJJ)l}`5 z>UE2`=Bjxyr*A5TVoKj#oRTgtR+mRyc{S(}=lSLlS6=-f)jRwMg;bf<=SNOI_9NF` zU6AUneu8+auIlm=r|dk)!U#hR_@H40H{+a8qj!E^9$B>J3L#xMv@GW0x z?`|*3TvbaNWE0k+Db2fUB{Nmv_K`blXeUCB(yBGq zSZ8107tg@<831S^brGk(cXn6t2!v{@dxfk8~UEcf%SL4>F@nY0^g z;R@{-)*{kn+J{CF(qx*Uzflyn@TD|6i0Ep89oAY}%1p4rW{`kiLa)$yrIa$;JBUI8 z=dS4}LL$Z4!Z*fRev-WKUt+C5rWw9=6ou`OKeJ|4;)FM(KyEV=YiwGH_zOZx;Z30= zHaJ#_*U1xJiM2dRYTF4{1}o}7HA~}-DU>^GjJ2?OO{E*N3v1B|?I_lK7L1 zoGXaimUt&1}*(nr?!y zFJw|OlGuC&GbAaf$tCeWbWvHzRnWDFDz}#SlmoL(?k1p|)F8DS zL@DTI8TImjOa-m(p%tkF9_Qy&-aX%b{X50ha`p6tvoK{{?^sV(ehA8(YA|AnZ@#&iFK&} zfxG0M233%*{F@38FQep#3XmxO&XAsOK)y_|8}^3wIWKwxe0NJ-5y4wC-SOTKqflme zYlgS42)UHf^LYg`sfe%WCh0{ai50<|g_K|Dql*;wdlOFo5?6vKN?@-?wMv?om#nS? znF?t;l9V4QQoS;Wd*oIPD{DzxDnkS%9bbuSQ(1GZ4SXP7ZbRPn(NOlH`8%a}FT)4Y zNBgL@@`bQ$X&lnUSF;EweIZGv*j@J3J~t75P^gfi{IsMqeh|1Zr}6?}7~e(c6pmF{z4RfwVJJ$x((g6vu8TMcp*)=||& zNLPM;Zd3zvF7o$GMSi3({y`Rqq9D5=<1JeLyB5flN#uov&pr?ECi;W858L!`buigY z_1C@+Fa2Tb4m*pTOLgt5FrzxWLX<#tbqVm-t=&#Le^RN2=80NX16J(B=9_BZJzgt4 zO`(LbF}SnO#$};9?*o>_X14H`Q^-jyK^l~3T|iKr<5RUx6Z;UuCYytby-L$#q&7P5X{Te=%>*MSif_@Isi?5zXY6gVXT zViR!LLx-%ZeeX`yh2DFR>k6XEeuVT5fUOiA6@b$lT3*^@6$ij8ii&~ilAH0G+h-#< z7eThyC|ZPfC=gaq&@D)s%%mWAK!G_j@FWPD?M1*LSmGER4D%>3O$HtY!(|HmiU4~R zi&kRC^`K4;g463s&5G(lECmGI9kJm9p5s$oA5J1jrq$QHcE8kzO1a4C+yFW8Z$QdZ zWNZKwdMsY|vG-4Ft<`>@ZQA?jTa1EAMF&UFWK z-N9UUFsCl(x`VmyV6JQ*bO&?hEu%Y_|Am7&(=QyTWv?1wF{D#%O{f)y+^MaJjls-h zI@htk^Z^+rX&yEV;hKkRG}J-=7h^Ws=A0?ZH4h77x#l4ymTMmHlW87OVyXK~6dGzV z&BNAs$rS_LMyUHptErHS3JMZ32MU*=NXWM8o9A%lL)IL2ypA$Mng=W(rrI3L0{$*1j8=5y6U zf(AtYp2Saa-13RMVR9l@5w+MD@+kSe1^lr5 z*aEI~xUhhqP;^Vd!ejx)!YFdWRw{IA9G| zK8#%hX~}rGtoiLVOanolt>G6Ky%ut*h9Yh)uRmD}=7m^ySjXq^@j8g2_1WuE*2z!x zFY6$aV$SP%n`!IuTovmJ*YjmCLU=MRgU4r_obVZ*_8@urXZ)^~gCa_uu!Z%^RVRlCw6ln<`d^fD|M*+{EX%X%kAoNZ!4Pll>u&l0!E0 zvA1ppUqEv9W=^gN(SYQ}TX^d&TOgN`_iRzFPOJ;2#mLfpt7g$NwnEfmw9*}|bVn=Q(Mor;(jBe%3HCn>4acPN?T!XD z4kANZIvLbxc?`MWWKaXqv5jf#QU=>-5-myYw?;D0D)Mq9w2L*Mg%-0N^nl1@qhl!| z#dt$7;+&HQblB-=B2g*0FUL4?15&6w?*S_*h?PtP4Fgb`M3JbQ*`4|;*~6<@ZJdd5 z8F!A#n_I&K&7#XY!}(6_y^Zsi2|{%jh@9QVkJvtgfHUnea>E8l--VrbK#Af!j!2u3 zqZ=S^Sa}OMzkzP~C9vH_6yT7v*G4KPNZ^@`kVL_28#SC=HlZ~if`gd6A#tAHgkdHS zyt9eQC=%FrGsIJH)MhFpSjf%IkWcGRHmesvqEYbJgJ9ei4fqTz6m;6E0jF+-Tna9b z3rZl``)78dpNg1Tr~$h%)?R({VH)I|%;^1je4z`I{UJ_S2}Nn?6Q z-JSgsuMxpp^iu|Vd<8KS9Qu_8y!;j9Qt$y1sdF8h;vgH!Y6y(@W;geAy>#U4{1B=Yze zBq!DMle_Xc!5b_(0r3jB_5?jllP<<`67m&F z1H2ODCu!A5@SRTwnTfYsOQ>`TVkm(kgp01E{iX(BqNn@kph7 zP=7BT=^(n3?(AuNbsAt4J8~vCHU*xh7t~-Ep6CI_fm@Q=e>@o{C2E_{!1Q? z=rWdcvHTlQ^pn9E4Fg{OWT38$2w@PJ0uPf|j6R5UJYi%HPvv`Pp@+#(`~gPA;almw zNF!}Nqz4Zc*jT-eGraiP)0>JLv}FNulRKR_b@i@tUJ!8A!vx3Zw?w4DkMvs{V&rjW zh#%~45ywF8WgI_`V$-`o%wbQ9ScHCw*qhG}I41#ohxvH2));app5oDnlgVAFyy3wK z#b_*mgd9o`yFn684mJ0kSp_%bxqDnaA#|CSN$iD6PW+ycY*fA{B5vq4 zQV>R>d1|RD;&CvysO-s2TEj3=0?mjJF-j1MSVjaAHj%3GFz&`gZt{J2BGn99(AQN= z!RYz#f6S^R`(qw%=H$oR*1Fv!Zu8x163j0^d*r*5n9aB0#Uw#M17I2zX31o3_Pt>; zRWw+{au`Gsd#pBvn@(??!VSK&r%(+ICRd2%v1Ynr_5_+MpfHvjdl$!o+hwHBu<{@? zfaw&_Bv>p1zDtb$2ERB#n9m2yjN@Tua^qBcRLq2!i)^F?n!VFp4O#Kb=-Y5SUNOgx zKnr*pZYByX;_=GKnW@a=+i-2FAlP`%%P^M$4L7rC8aIcg_Q7Huh@i<3noZ{>)BC3L zkTa*Jt30IBC*1mbz$b!`%=>!w3Ag@s`c%U=_fu{Ho~i-S8NM(Tudwb68fld+>E#(b z1kHmPTv}sx%Kc_?Q}EF<`TTFppFN8=V(!JWxIMVrY)wbgG2|;X z`c9tB)(ZW*%`|~Rr8z891W7|@07}l7qgh^G43CODftY)NW|zo7mjD`oCI>(9sS-mV zA`Qu{5_lI!&{Kd0l{v?AFp%(h)G8dK45XJbk;r*mGNjJE#_gDi;j9D8#9)|%#twm8 zDr646St+m}-6%WwVg~8*c0saxZ|Nc6>Jjt~6nKl5VdVOtvbMKY8@n2m(T;nj7wU4ME*ElZXi z4)wu^pFLF>fPC4LhbH~HCpFl#kY>HOtk@nuX)w-Ry|}D+v==pxvyc|OxqooS-WuWK zP;V|Re&3r*Etv6vCefoAADG~V(lE=S_j4bOi{_9>E;CMy)J*42Bo`c?M`}1nL^0`6 zj76Eo%b(nd;;zEaqqxj8ye}6Wr(iA!Dh|M3;6h>e7xb?dZ~uF74>jjxO!!(vB|eC`ZD&7VLFs!R+C^p$>k^ zqRKiid$>H*p@jD&Q-#^XxM2>J6>iyN%ieZ>f5nHI`)!B|G6 zX}qHKD`y6C!RFdv9>iwA5H8q^9l~XlXG54^gJFuqX0nQH?nhj> zN&SfL`aOnnxyCY-*VFKm$~757A#$x8CdM+13pWjhai)x6T&~HH>WznUk>N_+o%S8cWtveVIsaY!q%zD4sXiu}%QVxYIsIic z4}Ihk!)2aNVz@lBNUFPx;_^(zQM`W`#T8)drMmBEo^v5^G>_r4c{EpiWsTg)3d+g`mNSudC;S-WBF}4FqZ4P&Pespaa7eM>5Ib0F}caOb{wXmvuCOzGJFyg z9c=6YOlnF%T_om#ScXzl{Bl`p0@N3wuTrBxDIRRAKDL784$pq$riA)ids~gw4zqL* zC0%g3rVCEG;G_#qy5OV>PP*Wv3r@OOppC(4=4(5Y9XX2OY%+1^yKw`GY-Sde3 z9{ei{vk^lbo#Dg~$KM1uVDO-i9DieB#$dxx#}e*Gooum)v?Gaq zwGJlQ{B?(;NwfpgPDg*kAxtAt9>gR(OlRRK55=NV1$mFLbQ4l|O02N(l*f=+U^yo= z;VF;B^Z0-rrb1pPj6vCFDn!tDfiq@P8!8^vOhntMU5=R2VGifrG>3JgbO60S* zFbxF_G}#u@P$;ngkIdyEDbLN-M9bTdz(Z2*M86Z66EoHYWZ@9+&Qme6e;$uW`3H7+=zWf~BJ^XKfrVd^Ep$g6Sy zx+_UMDCNT>s^5?Tx%F7UgHjG%fRQBSbudCkHn#Rys9~Ini7GI(q+!8A>P(~rj>Bww z;d_y{K{8LL!KUi>N|O0uL`@0V)k=7YPDp#y|@|9)|Iw z6dt4UW6XAr;V9wPS@zCwHwObF{+dD+Oj7e$;87~)vE&sNd|cvkaWd|Unekl;4V$@` zN2i3v>Zs^juPfgH*huoSKo$jf+mDUVHgb}5@0X@^-Y zXave$%Xs}XX0@R8t1P>PG|~2{EG#AIovJP~d6vqfQaUZ?^N6H@50|s3lq7LE>kT7& z6dk}Bltc4KWziO{;Nd7&ui!iwkK=3PslJj=U^#x$7?fLhUG#&1gGdg->=w#xUy;V6 zPi{?Pk2*T4$l;sGbGVGax>`scvaJmBQG z)tUvqj};n)^5tsoX~hEkg|C533P!GhbM!M0BcC2|r0#mvk2op;{?d(J_CXEmH{t>Q zMt^8qam4X9QGU;<0yo9W$pq`|8hY7Y9CviJ*QH-w`qiahUHa9fUtRjurC(k8)umr$ zx1=l1{-xqdqBn>RFb^|=KjI{Vrz)%AI#Ne?5n?_bvPzg;1Uy4nnj1x-9HMCdtJ?t zUpC0!@H2A6LFS^SRmj)~>S^QwrnCxXF@ovJ;KGM>>%ry$!Ol>G`ZRd66IM$-3GpUH z9eGboWi{Xf$ah9<+1L+wSZ=DWG91Mif`c)j2KF5EA@~mQ_h7oJCLanyL&zL~x~lzt zPLiV# zDl{GjAAM8ZvnP#mN><3y(K6qc!iS&N_OvY??X=on*|TH5CET+c&U6rjVO&AQw(X&O z+y0KaZD(Ko4e#KlysBo~J~$jA&~i<@&Gzi%SvaIqL$)CikbW7>%f98Cb#k58aqpf! zAQ&TjQwzALj-2O2N2;dsfY2=nUh1gs)A3Zl;A1C$GW7#xk51-%0D+U7UxV{;JQBq((lZ@ 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�c4AHwpeG2b>idoLDns`ZIY8-tQU|D*%m=o& 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 O`z(W@8mclHx&9yFG$M2W From 535ee8ba2593032447434a670f9a0334971e7b35 Mon Sep 17 00:00:00 2001 From: Bartek Szatkowski Date: Mon, 22 May 2017 16:21:35 +0100 Subject: [PATCH 14/24] Make stack sizes configurable by the app Application can overwrite stack sizes by defining main-stack-size and thread-stack-size in mbed_app.json --- rtos/mbed_boot.c | 10 ++++++---- rtos/rtx2/mbed_rtx_conf.h | 11 +++++------ 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/rtos/mbed_boot.c b/rtos/mbed_boot.c index ab7200d8115..efe6cc39d4c 100644 --- a/rtos/mbed_boot.c +++ b/rtos/mbed_boot.c @@ -178,10 +178,12 @@ WEAK void mbed_main(void); void pre_main (void); osThreadAttr_t _main_thread_attr; -/* The main stack size is hardcoded on purpose, so it's less tempting to change it per platform. As usually it's not - * the correct solution to the problem and it makes mbed OS behave differently on different targets. - */ -MBED_ALIGN(8) char _main_stack[4096]; + +/** The main thread's stack size can be configured by the application, if not explicitly specified it'll default to 4K */ +#ifndef MBED_CONF_APP_MAIN_STACK_SIZE +#define MBED_CONF_APP_MAIN_STACK_SIZE 4096 +#endif +MBED_ALIGN(8) char _main_stack[MBED_CONF_APP_MAIN_STACK_SIZE]; mbed_rtos_storage_thread_t _main_obj; osMutexId_t singleton_mutex_id; diff --git a/rtos/rtx2/mbed_rtx_conf.h b/rtos/rtx2/mbed_rtx_conf.h index 04af69df2e5..c8a93f97a1d 100644 --- a/rtos/rtx2/mbed_rtx_conf.h +++ b/rtos/rtx2/mbed_rtx_conf.h @@ -24,14 +24,13 @@ #include "mbed_rtx.h" -#ifndef OS_STACK_SIZE -#ifndef MBED_SMALL_TARGET -#define OS_STACK_SIZE 4096 -#else -#define OS_STACK_SIZE 2048 -#endif +/** The thread's stack size can be configured by the application, if not explicitly specified it'll default to 4K */ +#ifndef MBED_CONF_APP_THREAD_STACK_SIZE +#define MBED_CONF_APP_THREAD_STACK_SIZE 4096 #endif +#define OS_STACK_SIZE MBED_CONF_APP_THREAD_STACK_SIZE + #define OS_TIMER_THREAD_STACK_SIZE 768 #define OS_IDLE_THREAD_STACK_SIZE 256 From 05548e786d1c5e588be2c2a839750b087eb90bb6 Mon Sep 17 00:00:00 2001 From: Bartek Szatkowski Date: Tue, 23 May 2017 09:44:20 +0100 Subject: [PATCH 15/24] Rename directories rtx->rtx4 rtx2->rtx5 --- rtos/mbed_rtos1_types.h | 2 +- rtos/{rtx => rtx4}/cmsis_os.h | 0 rtos/{rtx => rtx4}/cmsis_os1.c | 0 rtos/{rtx2 => rtx5}/TARGET_CORTEX_M/RTX_Config.c | 0 rtos/{rtx2 => rtx5}/TARGET_CORTEX_M/RTX_Config.h | 2 +- .../TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_ARM/irq_cm0.s | 0 .../TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_GCC/irq_cm0.S | 0 .../TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_IAR/irq_cm0.s | 0 .../TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_ARM/irq_cm0.s | 0 .../TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_GCC/irq_cm0.S | 0 .../TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_IAR/irq_cm0.s | 0 .../TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_ARM/irq_cm3.s | 0 .../TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_GCC/irq_cm3.S | 0 .../TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_IAR/irq_cm3.s | 0 .../TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_ARM/irq_cm4f.s | 0 .../TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_GCC/irq_cm4f.S | 0 .../TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_IAR/irq_cm4f.s | 0 .../TARGET_CORTEX_M/TESTS/memory/heap_and_stack/main.cpp | 0 rtos/{rtx2 => rtx5}/TARGET_CORTEX_M/cmsis_os2.h | 0 rtos/{rtx2 => rtx5}/TARGET_CORTEX_M/core_cm.h | 0 rtos/{rtx2 => rtx5}/TARGET_CORTEX_M/rt_OsEventObserver.c | 0 rtos/{rtx2 => rtx5}/TARGET_CORTEX_M/rt_OsEventObserver.h | 0 rtos/{rtx2 => rtx5}/TARGET_CORTEX_M/rtx_delay.c | 0 rtos/{rtx2 => rtx5}/TARGET_CORTEX_M/rtx_evflags.c | 0 rtos/{rtx2 => rtx5}/TARGET_CORTEX_M/rtx_evr.c | 0 rtos/{rtx2 => rtx5}/TARGET_CORTEX_M/rtx_evr.h | 0 rtos/{rtx2 => rtx5}/TARGET_CORTEX_M/rtx_kernel.c | 0 rtos/{rtx2 => rtx5}/TARGET_CORTEX_M/rtx_lib.c | 0 rtos/{rtx2 => rtx5}/TARGET_CORTEX_M/rtx_lib.h | 0 rtos/{rtx2 => rtx5}/TARGET_CORTEX_M/rtx_memory.c | 0 rtos/{rtx2 => rtx5}/TARGET_CORTEX_M/rtx_mempool.c | 0 rtos/{rtx2 => rtx5}/TARGET_CORTEX_M/rtx_msgqueue.c | 0 rtos/{rtx2 => rtx5}/TARGET_CORTEX_M/rtx_mutex.c | 0 rtos/{rtx2 => rtx5}/TARGET_CORTEX_M/rtx_os.h | 0 rtos/{rtx2 => rtx5}/TARGET_CORTEX_M/rtx_semaphore.c | 0 rtos/{rtx2 => rtx5}/TARGET_CORTEX_M/rtx_system.c | 0 rtos/{rtx2 => rtx5}/TARGET_CORTEX_M/rtx_thread.c | 0 rtos/{rtx2 => rtx5}/TARGET_CORTEX_M/rtx_timer.c | 0 rtos/{rtx2 => rtx5}/mbed_rtx_conf.h | 0 rtos/{rtx2 => rtx5}/mbed_rtx_handlers.c | 0 40 files changed, 2 insertions(+), 2 deletions(-) rename rtos/{rtx => rtx4}/cmsis_os.h (100%) rename rtos/{rtx => rtx4}/cmsis_os1.c (100%) rename rtos/{rtx2 => rtx5}/TARGET_CORTEX_M/RTX_Config.c (100%) rename rtos/{rtx2 => rtx5}/TARGET_CORTEX_M/RTX_Config.h (99%) rename rtos/{rtx2 => rtx5}/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_ARM/irq_cm0.s (100%) rename rtos/{rtx2 => rtx5}/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_GCC/irq_cm0.S (100%) rename rtos/{rtx2 => rtx5}/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_IAR/irq_cm0.s (100%) rename rtos/{rtx2 => rtx5}/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_ARM/irq_cm0.s (100%) rename rtos/{rtx2 => rtx5}/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_GCC/irq_cm0.S (100%) rename rtos/{rtx2 => rtx5}/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_IAR/irq_cm0.s (100%) rename rtos/{rtx2 => rtx5}/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_ARM/irq_cm3.s (100%) rename rtos/{rtx2 => rtx5}/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_GCC/irq_cm3.S (100%) rename rtos/{rtx2 => rtx5}/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_IAR/irq_cm3.s (100%) rename rtos/{rtx2 => rtx5}/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_ARM/irq_cm4f.s (100%) rename rtos/{rtx2 => rtx5}/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_GCC/irq_cm4f.S (100%) rename rtos/{rtx2 => rtx5}/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_IAR/irq_cm4f.s (100%) rename rtos/{rtx2 => rtx5}/TARGET_CORTEX_M/TESTS/memory/heap_and_stack/main.cpp (100%) rename rtos/{rtx2 => rtx5}/TARGET_CORTEX_M/cmsis_os2.h (100%) rename rtos/{rtx2 => rtx5}/TARGET_CORTEX_M/core_cm.h (100%) rename rtos/{rtx2 => rtx5}/TARGET_CORTEX_M/rt_OsEventObserver.c (100%) rename rtos/{rtx2 => rtx5}/TARGET_CORTEX_M/rt_OsEventObserver.h (100%) rename rtos/{rtx2 => rtx5}/TARGET_CORTEX_M/rtx_delay.c (100%) rename rtos/{rtx2 => rtx5}/TARGET_CORTEX_M/rtx_evflags.c (100%) rename rtos/{rtx2 => rtx5}/TARGET_CORTEX_M/rtx_evr.c (100%) rename rtos/{rtx2 => rtx5}/TARGET_CORTEX_M/rtx_evr.h (100%) rename rtos/{rtx2 => rtx5}/TARGET_CORTEX_M/rtx_kernel.c (100%) rename rtos/{rtx2 => rtx5}/TARGET_CORTEX_M/rtx_lib.c (100%) rename rtos/{rtx2 => rtx5}/TARGET_CORTEX_M/rtx_lib.h (100%) rename rtos/{rtx2 => rtx5}/TARGET_CORTEX_M/rtx_memory.c (100%) rename rtos/{rtx2 => rtx5}/TARGET_CORTEX_M/rtx_mempool.c (100%) rename rtos/{rtx2 => rtx5}/TARGET_CORTEX_M/rtx_msgqueue.c (100%) rename rtos/{rtx2 => rtx5}/TARGET_CORTEX_M/rtx_mutex.c (100%) rename rtos/{rtx2 => rtx5}/TARGET_CORTEX_M/rtx_os.h (100%) rename rtos/{rtx2 => rtx5}/TARGET_CORTEX_M/rtx_semaphore.c (100%) rename rtos/{rtx2 => rtx5}/TARGET_CORTEX_M/rtx_system.c (100%) rename rtos/{rtx2 => rtx5}/TARGET_CORTEX_M/rtx_thread.c (100%) rename rtos/{rtx2 => rtx5}/TARGET_CORTEX_M/rtx_timer.c (100%) rename rtos/{rtx2 => rtx5}/mbed_rtx_conf.h (100%) rename rtos/{rtx2 => rtx5}/mbed_rtx_handlers.c (100%) diff --git a/rtos/mbed_rtos1_types.h b/rtos/mbed_rtos1_types.h index 10530ac7cbf..73df37f061f 100644 --- a/rtos/mbed_rtos1_types.h +++ b/rtos/mbed_rtos1_types.h @@ -22,6 +22,6 @@ #ifndef MBED_RTOS_RTX1_TYPES_H #define MBED_RTOS_RTX1_TYPES_H -#include "rtx/cmsis_os.h" +#include "rtx4/cmsis_os.h" #endif diff --git a/rtos/rtx/cmsis_os.h b/rtos/rtx4/cmsis_os.h similarity index 100% rename from rtos/rtx/cmsis_os.h rename to rtos/rtx4/cmsis_os.h diff --git a/rtos/rtx/cmsis_os1.c b/rtos/rtx4/cmsis_os1.c similarity index 100% rename from rtos/rtx/cmsis_os1.c rename to rtos/rtx4/cmsis_os1.c diff --git a/rtos/rtx2/TARGET_CORTEX_M/RTX_Config.c b/rtos/rtx5/TARGET_CORTEX_M/RTX_Config.c similarity index 100% rename from rtos/rtx2/TARGET_CORTEX_M/RTX_Config.c rename to rtos/rtx5/TARGET_CORTEX_M/RTX_Config.c diff --git a/rtos/rtx2/TARGET_CORTEX_M/RTX_Config.h b/rtos/rtx5/TARGET_CORTEX_M/RTX_Config.h similarity index 99% rename from rtos/rtx2/TARGET_CORTEX_M/RTX_Config.h rename to rtos/rtx5/TARGET_CORTEX_M/RTX_Config.h index 6d95b78099d..e161b529e6d 100644 --- a/rtos/rtx2/TARGET_CORTEX_M/RTX_Config.h +++ b/rtos/rtx5/TARGET_CORTEX_M/RTX_Config.h @@ -30,7 +30,7 @@ #ifndef RTX_CONFIG_H_ #define RTX_CONFIG_H_ -#include "rtx2/mbed_rtx_conf.h" +#include "rtx5/mbed_rtx_conf.h" //-------- <<< Use Configuration Wizard in Context Menu >>> -------------------- diff --git a/rtos/rtx2/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_ARM/irq_cm0.s b/rtos/rtx5/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_ARM/irq_cm0.s similarity index 100% rename from rtos/rtx2/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_ARM/irq_cm0.s rename to rtos/rtx5/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_ARM/irq_cm0.s diff --git a/rtos/rtx2/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_GCC/irq_cm0.S b/rtos/rtx5/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_GCC/irq_cm0.S similarity index 100% rename from rtos/rtx2/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_GCC/irq_cm0.S rename to rtos/rtx5/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_GCC/irq_cm0.S diff --git a/rtos/rtx2/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_IAR/irq_cm0.s b/rtos/rtx5/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_IAR/irq_cm0.s similarity index 100% rename from rtos/rtx2/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_IAR/irq_cm0.s rename to rtos/rtx5/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_IAR/irq_cm0.s diff --git a/rtos/rtx2/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_ARM/irq_cm0.s b/rtos/rtx5/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_ARM/irq_cm0.s similarity index 100% rename from rtos/rtx2/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_ARM/irq_cm0.s rename to rtos/rtx5/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_ARM/irq_cm0.s diff --git a/rtos/rtx2/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_GCC/irq_cm0.S b/rtos/rtx5/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_GCC/irq_cm0.S similarity index 100% rename from rtos/rtx2/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_GCC/irq_cm0.S rename to rtos/rtx5/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_GCC/irq_cm0.S diff --git a/rtos/rtx2/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_IAR/irq_cm0.s b/rtos/rtx5/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_IAR/irq_cm0.s similarity index 100% rename from rtos/rtx2/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_IAR/irq_cm0.s rename to rtos/rtx5/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_IAR/irq_cm0.s diff --git a/rtos/rtx2/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_ARM/irq_cm3.s b/rtos/rtx5/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_ARM/irq_cm3.s similarity index 100% rename from rtos/rtx2/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_ARM/irq_cm3.s rename to rtos/rtx5/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_ARM/irq_cm3.s diff --git a/rtos/rtx2/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_GCC/irq_cm3.S b/rtos/rtx5/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_GCC/irq_cm3.S similarity index 100% rename from rtos/rtx2/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_GCC/irq_cm3.S rename to rtos/rtx5/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_GCC/irq_cm3.S diff --git a/rtos/rtx2/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_IAR/irq_cm3.s b/rtos/rtx5/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_IAR/irq_cm3.s similarity index 100% rename from rtos/rtx2/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_IAR/irq_cm3.s rename to rtos/rtx5/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_IAR/irq_cm3.s diff --git a/rtos/rtx2/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_ARM/irq_cm4f.s b/rtos/rtx5/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_ARM/irq_cm4f.s similarity index 100% rename from rtos/rtx2/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_ARM/irq_cm4f.s rename to rtos/rtx5/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_ARM/irq_cm4f.s diff --git a/rtos/rtx2/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_GCC/irq_cm4f.S b/rtos/rtx5/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_GCC/irq_cm4f.S similarity index 100% rename from rtos/rtx2/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_GCC/irq_cm4f.S rename to rtos/rtx5/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_GCC/irq_cm4f.S diff --git a/rtos/rtx2/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_IAR/irq_cm4f.s b/rtos/rtx5/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_IAR/irq_cm4f.s similarity index 100% rename from rtos/rtx2/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_IAR/irq_cm4f.s rename to rtos/rtx5/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_IAR/irq_cm4f.s diff --git a/rtos/rtx2/TARGET_CORTEX_M/TESTS/memory/heap_and_stack/main.cpp b/rtos/rtx5/TARGET_CORTEX_M/TESTS/memory/heap_and_stack/main.cpp similarity index 100% rename from rtos/rtx2/TARGET_CORTEX_M/TESTS/memory/heap_and_stack/main.cpp rename to rtos/rtx5/TARGET_CORTEX_M/TESTS/memory/heap_and_stack/main.cpp diff --git a/rtos/rtx2/TARGET_CORTEX_M/cmsis_os2.h b/rtos/rtx5/TARGET_CORTEX_M/cmsis_os2.h similarity index 100% rename from rtos/rtx2/TARGET_CORTEX_M/cmsis_os2.h rename to rtos/rtx5/TARGET_CORTEX_M/cmsis_os2.h diff --git a/rtos/rtx2/TARGET_CORTEX_M/core_cm.h b/rtos/rtx5/TARGET_CORTEX_M/core_cm.h similarity index 100% rename from rtos/rtx2/TARGET_CORTEX_M/core_cm.h rename to rtos/rtx5/TARGET_CORTEX_M/core_cm.h diff --git a/rtos/rtx2/TARGET_CORTEX_M/rt_OsEventObserver.c b/rtos/rtx5/TARGET_CORTEX_M/rt_OsEventObserver.c similarity index 100% rename from rtos/rtx2/TARGET_CORTEX_M/rt_OsEventObserver.c rename to rtos/rtx5/TARGET_CORTEX_M/rt_OsEventObserver.c diff --git a/rtos/rtx2/TARGET_CORTEX_M/rt_OsEventObserver.h b/rtos/rtx5/TARGET_CORTEX_M/rt_OsEventObserver.h similarity index 100% rename from rtos/rtx2/TARGET_CORTEX_M/rt_OsEventObserver.h rename to rtos/rtx5/TARGET_CORTEX_M/rt_OsEventObserver.h diff --git a/rtos/rtx2/TARGET_CORTEX_M/rtx_delay.c b/rtos/rtx5/TARGET_CORTEX_M/rtx_delay.c similarity index 100% rename from rtos/rtx2/TARGET_CORTEX_M/rtx_delay.c rename to rtos/rtx5/TARGET_CORTEX_M/rtx_delay.c diff --git a/rtos/rtx2/TARGET_CORTEX_M/rtx_evflags.c b/rtos/rtx5/TARGET_CORTEX_M/rtx_evflags.c similarity index 100% rename from rtos/rtx2/TARGET_CORTEX_M/rtx_evflags.c rename to rtos/rtx5/TARGET_CORTEX_M/rtx_evflags.c diff --git a/rtos/rtx2/TARGET_CORTEX_M/rtx_evr.c b/rtos/rtx5/TARGET_CORTEX_M/rtx_evr.c similarity index 100% rename from rtos/rtx2/TARGET_CORTEX_M/rtx_evr.c rename to rtos/rtx5/TARGET_CORTEX_M/rtx_evr.c diff --git a/rtos/rtx2/TARGET_CORTEX_M/rtx_evr.h b/rtos/rtx5/TARGET_CORTEX_M/rtx_evr.h similarity index 100% rename from rtos/rtx2/TARGET_CORTEX_M/rtx_evr.h rename to rtos/rtx5/TARGET_CORTEX_M/rtx_evr.h diff --git a/rtos/rtx2/TARGET_CORTEX_M/rtx_kernel.c b/rtos/rtx5/TARGET_CORTEX_M/rtx_kernel.c similarity index 100% rename from rtos/rtx2/TARGET_CORTEX_M/rtx_kernel.c rename to rtos/rtx5/TARGET_CORTEX_M/rtx_kernel.c diff --git a/rtos/rtx2/TARGET_CORTEX_M/rtx_lib.c b/rtos/rtx5/TARGET_CORTEX_M/rtx_lib.c similarity index 100% rename from rtos/rtx2/TARGET_CORTEX_M/rtx_lib.c rename to rtos/rtx5/TARGET_CORTEX_M/rtx_lib.c diff --git a/rtos/rtx2/TARGET_CORTEX_M/rtx_lib.h b/rtos/rtx5/TARGET_CORTEX_M/rtx_lib.h similarity index 100% rename from rtos/rtx2/TARGET_CORTEX_M/rtx_lib.h rename to rtos/rtx5/TARGET_CORTEX_M/rtx_lib.h diff --git a/rtos/rtx2/TARGET_CORTEX_M/rtx_memory.c b/rtos/rtx5/TARGET_CORTEX_M/rtx_memory.c similarity index 100% rename from rtos/rtx2/TARGET_CORTEX_M/rtx_memory.c rename to rtos/rtx5/TARGET_CORTEX_M/rtx_memory.c diff --git a/rtos/rtx2/TARGET_CORTEX_M/rtx_mempool.c b/rtos/rtx5/TARGET_CORTEX_M/rtx_mempool.c similarity index 100% rename from rtos/rtx2/TARGET_CORTEX_M/rtx_mempool.c rename to rtos/rtx5/TARGET_CORTEX_M/rtx_mempool.c diff --git a/rtos/rtx2/TARGET_CORTEX_M/rtx_msgqueue.c b/rtos/rtx5/TARGET_CORTEX_M/rtx_msgqueue.c similarity index 100% rename from rtos/rtx2/TARGET_CORTEX_M/rtx_msgqueue.c rename to rtos/rtx5/TARGET_CORTEX_M/rtx_msgqueue.c diff --git a/rtos/rtx2/TARGET_CORTEX_M/rtx_mutex.c b/rtos/rtx5/TARGET_CORTEX_M/rtx_mutex.c similarity index 100% rename from rtos/rtx2/TARGET_CORTEX_M/rtx_mutex.c rename to rtos/rtx5/TARGET_CORTEX_M/rtx_mutex.c diff --git a/rtos/rtx2/TARGET_CORTEX_M/rtx_os.h b/rtos/rtx5/TARGET_CORTEX_M/rtx_os.h similarity index 100% rename from rtos/rtx2/TARGET_CORTEX_M/rtx_os.h rename to rtos/rtx5/TARGET_CORTEX_M/rtx_os.h diff --git a/rtos/rtx2/TARGET_CORTEX_M/rtx_semaphore.c b/rtos/rtx5/TARGET_CORTEX_M/rtx_semaphore.c similarity index 100% rename from rtos/rtx2/TARGET_CORTEX_M/rtx_semaphore.c rename to rtos/rtx5/TARGET_CORTEX_M/rtx_semaphore.c diff --git a/rtos/rtx2/TARGET_CORTEX_M/rtx_system.c b/rtos/rtx5/TARGET_CORTEX_M/rtx_system.c similarity index 100% rename from rtos/rtx2/TARGET_CORTEX_M/rtx_system.c rename to rtos/rtx5/TARGET_CORTEX_M/rtx_system.c diff --git a/rtos/rtx2/TARGET_CORTEX_M/rtx_thread.c b/rtos/rtx5/TARGET_CORTEX_M/rtx_thread.c similarity index 100% rename from rtos/rtx2/TARGET_CORTEX_M/rtx_thread.c rename to rtos/rtx5/TARGET_CORTEX_M/rtx_thread.c diff --git a/rtos/rtx2/TARGET_CORTEX_M/rtx_timer.c b/rtos/rtx5/TARGET_CORTEX_M/rtx_timer.c similarity index 100% rename from rtos/rtx2/TARGET_CORTEX_M/rtx_timer.c rename to rtos/rtx5/TARGET_CORTEX_M/rtx_timer.c diff --git a/rtos/rtx2/mbed_rtx_conf.h b/rtos/rtx5/mbed_rtx_conf.h similarity index 100% rename from rtos/rtx2/mbed_rtx_conf.h rename to rtos/rtx5/mbed_rtx_conf.h diff --git a/rtos/rtx2/mbed_rtx_handlers.c b/rtos/rtx5/mbed_rtx_handlers.c similarity index 100% rename from rtos/rtx2/mbed_rtx_handlers.c rename to rtos/rtx5/mbed_rtx_handlers.c From b01f13d1a0b38920f827461950c388686cd55e88 Mon Sep 17 00:00:00 2001 From: Bartek Szatkowski Date: Tue, 23 May 2017 11:26:30 +0100 Subject: [PATCH 16/24] Make sure all system threads and mutexes have clear names --- .../nanostack-hal-mbed-cmsis-rtos/arm_hal_interrupt.c | 2 +- .../nanostack-hal-mbed-cmsis-rtos/arm_hal_timer.cpp | 1 + .../nanostack-hal-mbed-cmsis-rtos/ns_event_loop.c | 3 ++- .../lwip-eth/arch/TARGET_Freescale/k64f_emac.c | 8 ++++---- .../arch/TARGET_NUVOTON/TARGET_NUC472/nuc472_netif.c | 8 ++++---- .../lwip-interface/lwip-eth/arch/TARGET_NXP/lpc17_emac.c | 6 +++--- .../lwip-eth/arch/TARGET_RZ_A1H/rza1_emac.c | 4 ++-- .../lwip-eth/arch/TARGET_STM/stm32xx_emac.c | 4 ++-- .../lwip-eth/arch/TARGET_VK_RZ_A1H/rza1_emac.c | 4 ++-- .../lwip-interface/lwip-sys/arch/lwip_sys_arch.c | 4 +++- features/FEATURE_UVISOR/source/rtx/box_init.c | 1 + features/FEATURE_UVISOR/source/rtx/rtx_malloc_wrapper.c | 1 + .../source/rtx/unsupported_page_allocator.c | 2 +- rtos/Thread.cpp | 2 +- rtos/mbed_boot.c | 7 ++++++- 15 files changed, 34 insertions(+), 23 deletions(-) diff --git a/features/FEATURE_COMMON_PAL/nanostack-hal-mbed-cmsis-rtos/arm_hal_interrupt.c b/features/FEATURE_COMMON_PAL/nanostack-hal-mbed-cmsis-rtos/arm_hal_interrupt.c index 21ce05a2939..2110f8efa66 100644 --- a/features/FEATURE_COMMON_PAL/nanostack-hal-mbed-cmsis-rtos/arm_hal_interrupt.c +++ b/features/FEATURE_COMMON_PAL/nanostack-hal-mbed-cmsis-rtos/arm_hal_interrupt.c @@ -12,7 +12,7 @@ static uint8_t sys_irq_disable_counter; static mbed_rtos_storage_mutex_t critical_mutex; static const osMutexAttr_t critical_mutex_attr = { - .name = "critical_mutex", + .name = "nanostack_critical_mutex", .attr_bits = osMutexRecursive, .cb_mem = &critical_mutex, .cb_size = sizeof critical_mutex, diff --git a/features/FEATURE_COMMON_PAL/nanostack-hal-mbed-cmsis-rtos/arm_hal_timer.cpp b/features/FEATURE_COMMON_PAL/nanostack-hal-mbed-cmsis-rtos/arm_hal_timer.cpp index 4ab6f718f39..662eddae866 100644 --- a/features/FEATURE_COMMON_PAL/nanostack-hal-mbed-cmsis-rtos/arm_hal_timer.cpp +++ b/features/FEATURE_COMMON_PAL/nanostack-hal-mbed-cmsis-rtos/arm_hal_timer.cpp @@ -37,6 +37,7 @@ static void timer_thread(void *arg) void platform_timer_enable(void) { static osThreadAttr_t timer_thread_attr = {0}; + timer_thread_attr.name = "pal_timer_thread"; timer_thread_attr.stack_mem = &timer_thread_stk[0]; timer_thread_attr.cb_mem = &timer_thread_tcb; timer_thread_attr.stack_size = sizeof(timer_thread_stk); diff --git a/features/FEATURE_COMMON_PAL/nanostack-hal-mbed-cmsis-rtos/ns_event_loop.c b/features/FEATURE_COMMON_PAL/nanostack-hal-mbed-cmsis-rtos/ns_event_loop.c index 01d5675e0ed..27c02b5a815 100644 --- a/features/FEATURE_COMMON_PAL/nanostack-hal-mbed-cmsis-rtos/ns_event_loop.c +++ b/features/FEATURE_COMMON_PAL/nanostack-hal-mbed-cmsis-rtos/ns_event_loop.c @@ -19,6 +19,7 @@ static void event_loop_thread(void *arg); static uint64_t event_thread_stk[MBED_CONF_NANOSTACK_HAL_EVENT_LOOP_THREAD_STACK_SIZE/8]; static mbed_rtos_storage_thread_t event_thread_tcb; static const osThreadAttr_t event_thread_attr = { + .name = "nanostack_event_thread", .priority = osPriorityNormal, .stack_mem = &event_thread_stk[0], .stack_size = sizeof event_thread_stk, @@ -28,7 +29,7 @@ static const osThreadAttr_t event_thread_attr = { static osThreadId_t event_thread_id; static mbed_rtos_storage_mutex_t event_mutex; static const osMutexAttr_t event_mutex_attr = { - .name = "event_mutex", + .name = "nanostack_event_mutex", .attr_bits = osMutexRecursive, .cb_mem = &event_mutex, .cb_size = sizeof event_mutex, diff --git a/features/FEATURE_LWIP/lwip-interface/lwip-eth/arch/TARGET_Freescale/k64f_emac.c b/features/FEATURE_LWIP/lwip-interface/lwip-eth/arch/TARGET_Freescale/k64f_emac.c index 9291363852b..b4c9d1e8221 100644 --- a/features/FEATURE_LWIP/lwip-interface/lwip-eth/arch/TARGET_Freescale/k64f_emac.c +++ b/features/FEATURE_LWIP/lwip-interface/lwip-eth/arch/TARGET_Freescale/k64f_emac.c @@ -712,18 +712,18 @@ err_t eth_arch_enetif_init(struct netif *netif) LWIP_ASSERT("RxReadySem creation error", (err == ERR_OK)); #ifdef LWIP_DEBUG - sys_thread_new("receive_thread", packet_rx, netif->state, DEFAULT_THREAD_STACKSIZE*5, RX_PRIORITY); + sys_thread_new("k64f_emac_rx_thread", packet_rx, netif->state, DEFAULT_THREAD_STACKSIZE*5, RX_PRIORITY); #else - sys_thread_new("receive_thread", packet_rx, netif->state, DEFAULT_THREAD_STACKSIZE, RX_PRIORITY); + sys_thread_new("k64f_emac_thread", packet_rx, netif->state, DEFAULT_THREAD_STACKSIZE, RX_PRIORITY); #endif /* Transmit cleanup task */ err = sys_sem_new(&k64f_enetdata.TxCleanSem, 0); LWIP_ASSERT("TxCleanSem creation error", (err == ERR_OK)); - sys_thread_new("txclean_thread", packet_tx, netif->state, DEFAULT_THREAD_STACKSIZE, TX_PRIORITY); + sys_thread_new("k64f_emac_txclean_thread", packet_tx, netif->state, DEFAULT_THREAD_STACKSIZE, TX_PRIORITY); /* PHY monitoring task */ - sys_thread_new("phy_thread", k64f_phy_task, netif, DEFAULT_THREAD_STACKSIZE, PHY_PRIORITY); + sys_thread_new("k64f_emac_phy_thread", k64f_phy_task, netif, DEFAULT_THREAD_STACKSIZE, PHY_PRIORITY); /* Allow the PHY task to detect the initial link state and set up the proper flags */ osDelay(10); diff --git a/features/FEATURE_LWIP/lwip-interface/lwip-eth/arch/TARGET_NUVOTON/TARGET_NUC472/nuc472_netif.c b/features/FEATURE_LWIP/lwip-interface/lwip-eth/arch/TARGET_NUVOTON/TARGET_NUC472/nuc472_netif.c index 7cdb7a9a604..cd954a6a436 100644 --- a/features/FEATURE_LWIP/lwip-interface/lwip-eth/arch/TARGET_NUVOTON/TARGET_NUC472/nuc472_netif.c +++ b/features/FEATURE_LWIP/lwip-interface/lwip-eth/arch/TARGET_NUVOTON/TARGET_NUC472/nuc472_netif.c @@ -435,17 +435,17 @@ err_t #if defined (__GNUC__) // mbed OS 2.0, DEFAULT_THREAD_STACKSIZE*3 // mbed OS 5.0, DEFAULT_THREAD_STACKSIZE*5 - sys_thread_new("receive_thread", __packet_rx_task, &RxReadySem, DEFAULT_THREAD_STACKSIZE*5, osPriorityNormal); + sys_thread_new("nuc472_emac_rx_thread", __packet_rx_task, &RxReadySem, DEFAULT_THREAD_STACKSIZE*5, osPriorityNormal); #else - sys_thread_new("receive_thread", __packet_rx_task, &RxReadySem, DEFAULT_THREAD_STACKSIZE, osPriorityNormal); + sys_thread_new("nuc472_emac_rx_thread", __packet_rx_task, &RxReadySem, DEFAULT_THREAD_STACKSIZE, osPriorityNormal); #endif /* PHY monitoring task */ #if defined (__GNUC__) // mbed OS 2.0, DEFAULT_THREAD_STACKSIZE // mbed OS 5.0, DEFAULT_THREAD_STACKSIZE*2 - sys_thread_new("phy_thread", __phy_task, netif, DEFAULT_THREAD_STACKSIZE*2, osPriorityNormal); + sys_thread_new("nuc472_emac_phy_thread", __phy_task, netif, DEFAULT_THREAD_STACKSIZE*2, osPriorityNormal); #else - sys_thread_new("phy_thread", __phy_task, netif, DEFAULT_THREAD_STACKSIZE, osPriorityNormal); + sys_thread_new("nuc472_emac_phy_thread", __phy_task, netif, DEFAULT_THREAD_STACKSIZE, osPriorityNormal); #endif /* Allow the PHY task to detect the initial link state and set up the proper flags */ osDelay(10); diff --git a/features/FEATURE_LWIP/lwip-interface/lwip-eth/arch/TARGET_NXP/lpc17_emac.c b/features/FEATURE_LWIP/lwip-interface/lwip-eth/arch/TARGET_NXP/lpc17_emac.c index 91515c43cc9..d62fa90bf07 100644 --- a/features/FEATURE_LWIP/lwip-interface/lwip-eth/arch/TARGET_NXP/lpc17_emac.c +++ b/features/FEATURE_LWIP/lwip-interface/lwip-eth/arch/TARGET_NXP/lpc17_emac.c @@ -1031,16 +1031,16 @@ err_t eth_arch_enetif_init(struct netif *netif) LWIP_ASSERT("TXLockMutex creation error", (err == ERR_OK)); /* Packet receive task */ - lpc_enetdata.RxThread = sys_thread_new("receive_thread", packet_rx, netif->state, DEFAULT_THREAD_STACKSIZE, RX_PRIORITY); + lpc_enetdata.RxThread = sys_thread_new("lpc17_emac_rx_thread", packet_rx, netif->state, DEFAULT_THREAD_STACKSIZE, RX_PRIORITY); LWIP_ASSERT("RxThread creation error", (lpc_enetdata.RxThread)); /* Transmit cleanup task */ err = sys_sem_new(&lpc_enetdata.TxCleanSem, 0); LWIP_ASSERT("TxCleanSem creation error", (err == ERR_OK)); - sys_thread_new("txclean_thread", packet_tx, netif->state, DEFAULT_THREAD_STACKSIZE, TX_PRIORITY); + sys_thread_new("lpc17_emac_txclean_thread", packet_tx, netif->state, DEFAULT_THREAD_STACKSIZE, TX_PRIORITY); /* periodic PHY status update */ - sys_thread_new("phy_thread", phy_update, netif, DEFAULT_THREAD_STACKSIZE, TX_PRIORITY); + sys_thread_new("lpc17_emac_phy_thread", phy_update, netif, DEFAULT_THREAD_STACKSIZE, TX_PRIORITY); #endif return ERR_OK; diff --git a/features/FEATURE_LWIP/lwip-interface/lwip-eth/arch/TARGET_RZ_A1H/rza1_emac.c b/features/FEATURE_LWIP/lwip-interface/lwip-eth/arch/TARGET_RZ_A1H/rza1_emac.c index 0953de1da42..65515507a05 100644 --- a/features/FEATURE_LWIP/lwip-interface/lwip-eth/arch/TARGET_RZ_A1H/rza1_emac.c +++ b/features/FEATURE_LWIP/lwip-interface/lwip-eth/arch/TARGET_RZ_A1H/rza1_emac.c @@ -195,8 +195,8 @@ err_t eth_arch_enetif_init(struct netif *netif) sys_sem_new(&recv_ready_sem, 0); /* task */ - sys_thread_new("rza1_recv_task", rza1_recv_task, netif, DEFAULT_THREAD_STACKSIZE, RECV_TASK_PRI); - sys_thread_new("rza1_phy_task", rza1_phy_task, netif, DEFAULT_THREAD_STACKSIZE, PHY_TASK_PRI); + sys_thread_new("rza1_emac_rx_thread", rza1_recv_task, netif, DEFAULT_THREAD_STACKSIZE, RECV_TASK_PRI); + sys_thread_new("rza1_emac_phy_thread", rza1_phy_task, netif, DEFAULT_THREAD_STACKSIZE, PHY_TASK_PRI); return ERR_OK; } diff --git a/features/FEATURE_LWIP/lwip-interface/lwip-eth/arch/TARGET_STM/stm32xx_emac.c b/features/FEATURE_LWIP/lwip-interface/lwip-eth/arch/TARGET_STM/stm32xx_emac.c index de1bd17f695..c834912a2ff 100644 --- a/features/FEATURE_LWIP/lwip-interface/lwip-eth/arch/TARGET_STM/stm32xx_emac.c +++ b/features/FEATURE_LWIP/lwip-interface/lwip-eth/arch/TARGET_STM/stm32xx_emac.c @@ -451,8 +451,8 @@ err_t eth_arch_enetif_init(struct netif *netif) sys_mutex_new(&tx_lock_mutex); /* task */ - sys_thread_new("_eth_arch_rx_task", _eth_arch_rx_task, netif, DEFAULT_THREAD_STACKSIZE, RECV_TASK_PRI); - sys_thread_new("_eth_arch_phy_task", _eth_arch_phy_task, netif, DEFAULT_THREAD_STACKSIZE, PHY_TASK_PRI); + sys_thread_new("stm32_emac_rx_thread", _eth_arch_rx_task, netif, DEFAULT_THREAD_STACKSIZE, RECV_TASK_PRI); + sys_thread_new("stm32_emac_phy_thread", _eth_arch_phy_task, netif, DEFAULT_THREAD_STACKSIZE, PHY_TASK_PRI); /* initialize the hardware */ _eth_arch_low_level_init(netif); diff --git a/features/FEATURE_LWIP/lwip-interface/lwip-eth/arch/TARGET_VK_RZ_A1H/rza1_emac.c b/features/FEATURE_LWIP/lwip-interface/lwip-eth/arch/TARGET_VK_RZ_A1H/rza1_emac.c index 0953de1da42..65515507a05 100644 --- a/features/FEATURE_LWIP/lwip-interface/lwip-eth/arch/TARGET_VK_RZ_A1H/rza1_emac.c +++ b/features/FEATURE_LWIP/lwip-interface/lwip-eth/arch/TARGET_VK_RZ_A1H/rza1_emac.c @@ -195,8 +195,8 @@ err_t eth_arch_enetif_init(struct netif *netif) sys_sem_new(&recv_ready_sem, 0); /* task */ - sys_thread_new("rza1_recv_task", rza1_recv_task, netif, DEFAULT_THREAD_STACKSIZE, RECV_TASK_PRI); - sys_thread_new("rza1_phy_task", rza1_phy_task, netif, DEFAULT_THREAD_STACKSIZE, PHY_TASK_PRI); + sys_thread_new("rza1_emac_rx_thread", rza1_recv_task, netif, DEFAULT_THREAD_STACKSIZE, RECV_TASK_PRI); + sys_thread_new("rza1_emac_phy_thread", rza1_phy_task, netif, DEFAULT_THREAD_STACKSIZE, PHY_TASK_PRI); return ERR_OK; } diff --git a/features/FEATURE_LWIP/lwip-interface/lwip-sys/arch/lwip_sys_arch.c b/features/FEATURE_LWIP/lwip-interface/lwip-sys/arch/lwip_sys_arch.c index d02fe9321f5..7c6ecbc0e02 100644 --- a/features/FEATURE_LWIP/lwip-interface/lwip-sys/arch/lwip_sys_arch.c +++ b/features/FEATURE_LWIP/lwip-interface/lwip-sys/arch/lwip_sys_arch.c @@ -378,6 +378,7 @@ void sys_sem_free(sys_sem_t *sem) {} * @return a new mutex */ err_t sys_mutex_new(sys_mutex_t *mutex) { memset(&mutex->data, 0, sizeof(mutex->data)); + mutex->attr.name = "lwip_mutex"; mutex->attr.cb_mem = &mutex->data; mutex->attr.cb_size = sizeof(mutex->data); mutex->id = osMutexNew(&mutex->attr); @@ -417,6 +418,7 @@ mbed_rtos_storage_mutex_t lwip_sys_mutex_data; void sys_init(void) { us_ticker_read(); // Init sys tick + lwip_sys_mutex_attr.name = "lwip_sys_mutex"; lwip_sys_mutex_attr.cb_mem = &lwip_sys_mutex_data; lwip_sys_mutex_attr.cb_size = sizeof(lwip_sys_mutex_data); lwip_sys_mutex = osMutexNew(&lwip_sys_mutex_attr); @@ -517,7 +519,7 @@ sys_thread_t sys_thread_new(const char *pcName, sys_thread_t t = (sys_thread_t)&thread_pool[thread_pool_index]; thread_pool_index++; - t->attr.name = pcName; + t->attr.name = pcName ? pcName : "lwip_unnamed_thread"; t->attr.priority = (osPriority_t)priority; t->attr.cb_size = sizeof(t->data); t->attr.cb_mem = &t->data; diff --git a/features/FEATURE_UVISOR/source/rtx/box_init.c b/features/FEATURE_UVISOR/source/rtx/box_init.c index e63a8468e4a..63f257243f5 100644 --- a/features/FEATURE_UVISOR/source/rtx/box_init.c +++ b/features/FEATURE_UVISOR/source/rtx/box_init.c @@ -111,6 +111,7 @@ void __uvisor_lib_box_init(void * lib_config) __uvisor_initialize_rpc_queues(); + thread_attr.name = "uvisor_box_main_thread"; thread_attr.priority = box_main->priority; thread_attr.stack_size = box_main->stack_size; diff --git a/features/FEATURE_UVISOR/source/rtx/rtx_malloc_wrapper.c b/features/FEATURE_UVISOR/source/rtx/rtx_malloc_wrapper.c index ce143829845..ddb90ba9312 100644 --- a/features/FEATURE_UVISOR/source/rtx/rtx_malloc_wrapper.c +++ b/features/FEATURE_UVISOR/source/rtx/rtx_malloc_wrapper.c @@ -65,6 +65,7 @@ static int init_allocator() if ((__uvisor_ps->mutex_id == NULL) && is_kernel_initialized()) { /* Point the mutex attr to the data. */ + __uvisor_ps->mutex_attr.name = "uvisor_malloc_mutex"; __uvisor_ps->mutex_attr.attr_bits = 0; /* Non-recursive */ __uvisor_ps->mutex_attr.cb_mem = &__uvisor_ps->mutex_data; __uvisor_ps->mutex_attr.cb_size = sizeof(__uvisor_ps->mutex_data); diff --git a/features/FEATURE_UVISOR/source/rtx/unsupported_page_allocator.c b/features/FEATURE_UVISOR/source/rtx/unsupported_page_allocator.c index 7bb3a575356..c0423a97ab3 100644 --- a/features/FEATURE_UVISOR/source/rtx/unsupported_page_allocator.c +++ b/features/FEATURE_UVISOR/source/rtx/unsupported_page_allocator.c @@ -54,7 +54,7 @@ int uvisor_page_free(const UvisorPageTable *const table) static osMutexId_t g_page_allocator_mutex_id = NULL; static osRtxMutex_t g_page_allocator_mutex_data; static osMutexDef_t g_page_allocator_mutex_attr = { - .name = "", + .name = "uvisor_page_alloc_mutex", .attr_bits = 0, /* Non-recursive */ .cb_mem = &g_page_allocator_mutex_data, .cb_size = sizeof(g_page_allocator_mutex_data) diff --git a/rtos/Thread.cpp b/rtos/Thread.cpp index cb602c2e586..990a1260628 100644 --- a/rtos/Thread.cpp +++ b/rtos/Thread.cpp @@ -43,7 +43,7 @@ void Thread::constructor(osPriority priority, memset(&_attr, 0, sizeof(_attr)); _attr.priority = priority; _attr.stack_size = stack_size; - _attr.name = name; + _attr.name = name ? name : "application_unnamed_thread"; _attr.stack_mem = (uint32_t*)stack_mem; } diff --git a/rtos/mbed_boot.c b/rtos/mbed_boot.c index efe6cc39d4c..ee443c1de9c 100644 --- a/rtos/mbed_boot.c +++ b/rtos/mbed_boot.c @@ -315,7 +315,7 @@ void mbed_start_main(void) _main_thread_attr.cb_size = sizeof(_main_obj); _main_thread_attr.cb_mem = &_main_obj; _main_thread_attr.priority = osPriorityNormal; - _main_thread_attr.name = "MAIN"; + _main_thread_attr.name = "main_thread"; osThreadId_t result = osThreadNew((osThreadFunc_t)pre_main, NULL, &_main_thread_attr); if ((void *)result == NULL) { error("Pre main thread not created"); @@ -381,6 +381,7 @@ extern int main(int argc, char* argv[]); void pre_main (void) { + singleton_mutex_attr.name = "singleton_mutex"; singleton_mutex_attr.attr_bits = osMutexRecursive; singleton_mutex_attr.cb_size = sizeof(singleton_mutex_obj); singleton_mutex_attr.cb_mem = &singleton_mutex_obj; @@ -437,16 +438,19 @@ int __wrap_main(void) { void pre_main(void) { + singleton_mutex_attr.name = "singleton_mutex"; singleton_mutex_attr.attr_bits = osMutexRecursive; singleton_mutex_attr.cb_size = sizeof(singleton_mutex_obj); singleton_mutex_attr.cb_mem = &singleton_mutex_obj; singleton_mutex_id = osMutexNew(&singleton_mutex_attr); + malloc_mutex_attr.name = "malloc_mutex"; malloc_mutex_attr.attr_bits = osMutexRecursive; malloc_mutex_attr.cb_size = sizeof(malloc_mutex_obj); malloc_mutex_attr.cb_mem = &malloc_mutex_obj; malloc_mutex_id = osMutexNew(&malloc_mutex_attr); + env_mutex_attr.name = "env_mutex"; env_mutex_attr.attr_bits = osMutexRecursive; env_mutex_attr.cb_size = sizeof(env_mutex_obj); env_mutex_attr.cb_mem = &env_mutex_obj; @@ -520,6 +524,7 @@ static uint8_t low_level_init_needed; void pre_main(void) { + singleton_mutex_attr.name = "singleton_mutex"; singleton_mutex_attr.attr_bits = osMutexRecursive; singleton_mutex_attr.cb_size = sizeof(singleton_mutex_obj); singleton_mutex_attr.cb_mem = &singleton_mutex_obj; From e66f9ee81846c6b91034b1f25c5cae42bf2a21cd Mon Sep 17 00:00:00 2001 From: Bartek Szatkowski Date: Tue, 23 May 2017 11:27:10 +0100 Subject: [PATCH 17/24] Fix IAR coding style and thread/mutex namingin mbed_boot.c --- rtos/mbed_boot.c | 100 ++++++++++++++++++++++++----------------------- 1 file changed, 52 insertions(+), 48 deletions(-) diff --git a/rtos/mbed_boot.c b/rtos/mbed_boot.c index ee443c1de9c..f2620497d8d 100644 --- a/rtos/mbed_boot.c +++ b/rtos/mbed_boot.c @@ -342,15 +342,15 @@ void _main_init (void) __attribute__((section(".ARM.Collect$$$$000000FF"))); void $Super$$__cpp_initialize__aeabi_(void); void _main_init (void) { - mbed_set_stack_heap(); - /* Copy the vector table to RAM only if uVisor is not in use. */ + mbed_set_stack_heap(); + /* Copy the vector table to RAM only if uVisor is not in use. */ #if !(defined(FEATURE_UVISOR) && defined(TARGET_UVISOR_SUPPORTED)) - mbed_cpy_nvic(); + mbed_cpy_nvic(); #endif - mbed_sdk_init(); - osKernelInitialize(); - mbed_start_main(); - for (;;); + mbed_sdk_init(); + osKernelInitialize(); + mbed_start_main(); + for (;;); } void $Sub$$__cpp_initialize__aeabi_(void) @@ -362,13 +362,14 @@ void $Sub$$__cpp_initialize__aeabi_(void) void pre_main() { - singleton_mutex_attr.attr_bits = osMutexRecursive; - singleton_mutex_attr.cb_size = sizeof(singleton_mutex_obj); - singleton_mutex_attr.cb_mem = &singleton_mutex_obj; - singleton_mutex_id = osMutexNew(&singleton_mutex_attr); + singleton_mutex_attr.name = "singleton_mutex"; + singleton_mutex_attr.attr_bits = osMutexRecursive; + singleton_mutex_attr.cb_size = sizeof(singleton_mutex_obj); + singleton_mutex_attr.cb_mem = &singleton_mutex_obj; + singleton_mutex_id = osMutexNew(&singleton_mutex_attr); - $Super$$__cpp_initialize__aeabi_(); - main(); + $Super$$__cpp_initialize__aeabi_(); + main(); } #else /******************** ARMC ********************/ @@ -540,14 +541,15 @@ void pre_main(void) #pragma required=__vector_table void __iar_program_start( void ) { - __iar_init_core(); - __iar_init_vfp(); + __iar_init_core(); + __iar_init_vfp(); - uint8_t low_level_init_needed_local; + uint8_t low_level_init_needed_local; + + low_level_init_needed_local = __low_level_init(); + if (low_level_init_needed_local) { + __iar_data_init3(); - low_level_init_needed_local = __low_level_init(); - if (low_level_init_needed_local) { - __iar_data_init3(); /* Copy the vector table to RAM only if uVisor is not in use. */ #if !(defined(FEATURE_UVISOR) && defined(TARGET_UVISOR_SUPPORTED)) mbed_cpy_nvic(); @@ -574,37 +576,38 @@ static mbed_rtos_storage_mutex_t std_mutex_file[_FOPEN_MAX] = {0}; void __iar_system_Mtxinit(__iar_Rmtx *mutex) /* Initialize a system lock */ { - osMutexAttr_t attr; - uint32_t index; - for (index = 0; index < _MAX_LOCK; index++) { - if (0 == std_mutex_id_sys[index]) { - attr.cb_mem = &std_mutex_sys[index]; - attr.cb_size = sizeof(std_mutex_sys[index]); - attr.attr_bits = osMutexRecursive; - std_mutex_id_sys[index] = osMutexNew(&attr); - *mutex = (__iar_Rmtx*)&std_mutex_id_sys[index]; - return; + osMutexAttr_t attr; + uint32_t index; + for (index = 0; index < _MAX_LOCK; index++) { + if (0 == std_mutex_id_sys[index]) { + attr.name = "system_mutex"; + attr.cb_mem = &std_mutex_sys[index]; + attr.cb_size = sizeof(std_mutex_sys[index]); + attr.attr_bits = osMutexRecursive; + std_mutex_id_sys[index] = osMutexNew(&attr); + *mutex = (__iar_Rmtx*)&std_mutex_id_sys[index]; + return; + } } - } - /* This should never happen */ - error("Not enough mutexes\n"); + /* This should never happen */ + error("Not enough mutexes\n"); } void __iar_system_Mtxdst(__iar_Rmtx *mutex) /* Destroy a system lock */ { - osMutexDelete(*(osMutexId_t*)*mutex); - *mutex = 0; + osMutexDelete(*(osMutexId_t*)*mutex); + *mutex = 0; } void __iar_system_Mtxlock(__iar_Rmtx *mutex) /* Lock a system lock */ { - osMutexAcquire(*(osMutexId_t*)*mutex, osWaitForever); + osMutexAcquire(*(osMutexId_t*)*mutex, osWaitForever); } void __iar_system_Mtxunlock(__iar_Rmtx *mutex) /* Unlock a system lock */ { - osMutexRelease(*(osMutexId_t*)*mutex); + osMutexRelease(*(osMutexId_t*)*mutex); } void __iar_file_Mtxinit(__iar_Rmtx *mutex) /* Initialize a file lock */ @@ -612,14 +615,15 @@ void __iar_file_Mtxinit(__iar_Rmtx *mutex) /* Initialize a file lock */ osMutexAttr_t attr; uint32_t index; for (index = 0; index < _FOPEN_MAX; index++) { - if (0 == std_mutex_id_file[index]) { - attr.cb_mem = &std_mutex_file[index]; - attr.cb_size = sizeof(std_mutex_file[index]); - attr.attr_bits = osMutexRecursive; - std_mutex_id_file[index] = osMutexNew(&attr); - *mutex = (__iar_Rmtx*)&std_mutex_id_file[index]; - return; - } + if (0 == std_mutex_id_file[index]) { + attr.name = "file_mutex"; + attr.cb_mem = &std_mutex_file[index]; + attr.cb_size = sizeof(std_mutex_file[index]); + attr.attr_bits = osMutexRecursive; + std_mutex_id_file[index] = osMutexNew(&attr); + *mutex = (__iar_Rmtx*)&std_mutex_id_file[index]; + return; + } } /* The variable _FOPEN_MAX needs to be increased */ error("Not enough mutexes\n"); @@ -627,18 +631,18 @@ void __iar_file_Mtxinit(__iar_Rmtx *mutex) /* Initialize a file lock */ void __iar_file_Mtxdst(__iar_Rmtx *mutex) /* Destroy a file lock */ { - osMutexDelete(*(osMutexId_t*)*mutex); - *mutex = 0; + osMutexDelete(*(osMutexId_t*)*mutex); + *mutex = 0; } void __iar_file_Mtxlock(__iar_Rmtx *mutex) /* Lock a file lock */ { - osMutexAcquire(*(osMutexId_t*)*mutex, osWaitForever); + osMutexAcquire(*(osMutexId_t*)*mutex, osWaitForever); } void __iar_file_Mtxunlock(__iar_Rmtx *mutex) /* Unlock a file lock */ { - osMutexRelease(*(osMutexId_t*)*mutex); + osMutexRelease(*(osMutexId_t*)*mutex); } #endif From 0064df1ce6ef1a5b4e81487ee079dc732bef8581 Mon Sep 17 00:00:00 2001 From: Bartek Szatkowski Date: Tue, 23 May 2017 11:28:07 +0100 Subject: [PATCH 18/24] Add name parameter for C++ mutex wrapper --- rtos/Mutex.cpp | 14 +++++++++++++- rtos/Mutex.h | 8 ++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/rtos/Mutex.cpp b/rtos/Mutex.cpp index b194d9a75ac..ade6ebb4a87 100644 --- a/rtos/Mutex.cpp +++ b/rtos/Mutex.cpp @@ -27,9 +27,21 @@ namespace rtos { -Mutex::Mutex() { +Mutex::Mutex() +{ + constructor(); +} + +Mutex::Mutex(const char *name) +{ + constructor(name); +} + +void Mutex::constructor(const char *name) +{ memset(&_obj_mem, 0, sizeof(_obj_mem)); memset(&_attr, 0, sizeof(_attr)); + _attr.name = name ? name : "aplication_unnamed_mutex"; _attr.cb_mem = &_obj_mem; _attr.cb_size = sizeof(_obj_mem); _attr.attr_bits = osMutexRecursive; diff --git a/rtos/Mutex.h b/rtos/Mutex.h index 6cc78abd502..2224c459808 100644 --- a/rtos/Mutex.h +++ b/rtos/Mutex.h @@ -43,6 +43,12 @@ class Mutex { /** Create and Initialize a Mutex object */ Mutex(); + /** Create and Initialize a Mutex object + + @param name name to be used for this mutex. It has to stay allocated for the lifetime of the thread. + */ + Mutex(const char *name); + /** Wait until a Mutex becomes available. @param millisec timeout value or 0 in case of no time-out. (default: osWaitForever) @return status code that indicates the execution status of the function. @@ -62,6 +68,8 @@ class Mutex { ~Mutex(); private: + void constructor(const char *name = NULL); + osMutexId_t _id; osMutexAttr_t _attr; mbed_rtos_storage_mutex_t _obj_mem; From 85cc9c838130edad568f4f83ab90eb4554db9ed7 Mon Sep 17 00:00:00 2001 From: Bartek Szatkowski Date: Tue, 23 May 2017 14:52:38 +0100 Subject: [PATCH 19/24] Remove deprecated RTX4 config options --- targets/TARGET_ARM_SSG/mbed_rtx.h | 6 - targets/TARGET_Freescale/mbed_rtx.h | 112 ---------- targets/TARGET_Maxim/mbed_rtx.h | 27 --- targets/TARGET_NORDIC/mbed_rtx.h | 21 -- targets/TARGET_NUVOTON/mbed_rtx.h | 14 -- targets/TARGET_NXP/mbed_rtx.h | 60 ------ targets/TARGET_ONSEMI/mbed_rtx.h | 6 - targets/TARGET_RENESAS/mbed_rtx.h | 25 --- targets/TARGET_STM/mbed_rtx.h | 285 ------------------------- targets/TARGET_Silicon_Labs/mbed_rtx.h | 38 ---- targets/TARGET_WIZNET/mbed_rtx.h | 28 +-- targets/TARGET_ublox/mbed_rtx.h | 6 - 12 files changed, 1 insertion(+), 627 deletions(-) delete mode 100644 targets/TARGET_RENESAS/mbed_rtx.h diff --git a/targets/TARGET_ARM_SSG/mbed_rtx.h b/targets/TARGET_ARM_SSG/mbed_rtx.h index ed472b81e58..d535d608635 100644 --- a/targets/TARGET_ARM_SSG/mbed_rtx.h +++ b/targets/TARGET_ARM_SSG/mbed_rtx.h @@ -22,12 +22,6 @@ #ifndef INITIAL_SP #define INITIAL_SP (0x20020000UL) #endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 112 -#endif -#ifndef OS_CLOCK -#define OS_CLOCK 24000000 -#endif #endif diff --git a/targets/TARGET_Freescale/mbed_rtx.h b/targets/TARGET_Freescale/mbed_rtx.h index 497007c94e2..3602d0436f5 100644 --- a/targets/TARGET_Freescale/mbed_rtx.h +++ b/targets/TARGET_Freescale/mbed_rtx.h @@ -22,132 +22,66 @@ #ifndef INITIAL_SP #define INITIAL_SP (0x10008000UL) #endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 256 -#endif -#ifndef OS_CLOCK -#define OS_CLOCK 96000000 -#endif #elif defined(TARGET_TEENSY3_1) #ifndef INITIAL_SP #define INITIAL_SP (0x20008000UL) #endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 256 -#endif -#ifndef OS_CLOCK -#define OS_CLOCK 96000000 -#endif #elif defined(TARGET_MCU_K22F) #ifndef INITIAL_SP #define INITIAL_SP (0x20010000UL) #endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 256 -#endif -#ifndef OS_CLOCK -#define OS_CLOCK 80000000 -#endif #elif defined(TARGET_K66F) #ifndef INITIAL_SP #define INITIAL_SP (0x20030000UL) #endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 256 -#endif -#ifndef OS_CLOCK -#define OS_CLOCK 120000000 -#endif #elif defined(TARGET_KL27Z) #ifndef INITIAL_SP #define INITIAL_SP (0x20003000UL) #endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 128 -#endif -#ifndef OS_CLOCK -#define OS_CLOCK 48000000 -#endif #elif defined(TARGET_KL43Z) #ifndef INITIAL_SP #define INITIAL_SP (0x20006000UL) #endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 256 -#endif -#ifndef OS_CLOCK -#define OS_CLOCK 48000000 -#endif #elif defined(TARGET_KL05Z) #ifndef INITIAL_SP #define INITIAL_SP (0x20000C00UL) #endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 128 -#endif -#ifndef OS_CLOCK -#define OS_CLOCK 48000000 -#endif #elif defined(TARGET_KL25Z) #ifndef INITIAL_SP #define INITIAL_SP (0x20003000UL) #endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 128 -#endif -#ifndef OS_CLOCK -#define OS_CLOCK 48000000 -#endif #elif defined(TARGET_KL26Z) #ifndef INITIAL_SP #define INITIAL_SP (0x20003000UL) #endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 128 -#endif -#ifndef OS_CLOCK -#define OS_CLOCK 48000000 -#endif #elif defined(TARGET_KL46Z) #ifndef INITIAL_SP #define INITIAL_SP (0x20006000UL) #endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 256 -#endif -#ifndef OS_CLOCK -#define OS_CLOCK 48000000 -#endif #elif defined(TARGET_KL82Z) #ifndef INITIAL_SP #define INITIAL_SP (0x20012000UL) #endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 256 -#endif -#ifndef OS_CLOCK -#define OS_CLOCK 72000000 -#endif #elif defined(TARGET_K64F) @@ -155,55 +89,23 @@ #define INITIAL_SP (0x20030000UL) #endif -#if defined(__CC_ARM) || defined(__GNUC__) -#define ISR_STACK_SIZE (0x1000) -#endif - -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 256 -#endif -#ifndef OS_CLOCK -#define OS_CLOCK 120000000 -#endif - #elif defined(TARGET_KW24D) #ifndef INITIAL_SP #define INITIAL_SP (0x20008000UL) #endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 256 -#endif -#ifndef OS_CLOCK -#define OS_CLOCK 48000000 -#endif #elif defined(TARGET_KW41Z) #ifndef INITIAL_SP #define INITIAL_SP (0x20018000UL) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 14 -#endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 256 -#endif -#ifndef OS_CLOCK -#define OS_CLOCK 40000000 -#endif #elif defined(TARGET_K82F) #ifndef INITIAL_SP #define INITIAL_SP (0x20030000UL) #endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 256 -#endif -#ifndef OS_CLOCK -#define OS_CLOCK 120000000 -#endif #elif defined(TARGET_RO359B) @@ -211,20 +113,6 @@ #define INITIAL_SP (0x20030000UL) #endif -#if defined(__CC_ARM) || defined(__GNUC__) -#define ISR_STACK_SIZE (0x1000) -#endif - -#ifndef OS_TASKCNT -#define OS_TASKCNT 14 -#endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 256 -#endif -#ifndef OS_CLOCK -#define OS_CLOCK 96000000 -#endif - #endif #endif // MBED_MBED_RTX_H diff --git a/targets/TARGET_Maxim/mbed_rtx.h b/targets/TARGET_Maxim/mbed_rtx.h index 17058aa8ab9..7229a5586f9 100644 --- a/targets/TARGET_Maxim/mbed_rtx.h +++ b/targets/TARGET_Maxim/mbed_rtx.h @@ -22,57 +22,30 @@ #ifndef INITIAL_SP #define INITIAL_SP (0x20008000UL) #endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 256 -#endif -#ifndef OS_CLOCK -#define OS_CLOCK 24000000 -#endif #elif defined(TARGET_MAX32610) #ifndef INITIAL_SP #define INITIAL_SP (0x20008000UL) #endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 256 -#endif -#ifndef OS_CLOCK -#define OS_CLOCK 24000000 -#endif #elif defined(TARGET_MAX32620) #ifndef INITIAL_SP #define INITIAL_SP (0x20040000UL) #endif -#ifndef OS_CLOCK -#define OS_CLOCK 48000000 -#endif #elif defined(TARGET_MAX32625) #ifndef INITIAL_SP #define INITIAL_SP (0x20028000UL) #endif -#ifndef OS_CLOCK -#define OS_CLOCK 96000000 -#endif #elif defined(TARGET_MAX32630) #ifndef INITIAL_SP #define INITIAL_SP (0x20080000UL) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 14 -#endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 256 -#endif -#ifndef OS_CLOCK -#define OS_CLOCK 96000000 -#endif #endif diff --git a/targets/TARGET_NORDIC/mbed_rtx.h b/targets/TARGET_NORDIC/mbed_rtx.h index 5c0fa624ffb..06a73ad5312 100644 --- a/targets/TARGET_NORDIC/mbed_rtx.h +++ b/targets/TARGET_NORDIC/mbed_rtx.h @@ -27,12 +27,6 @@ # endif #endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 512 -#endif -#ifndef OS_CLOCK -#define OS_CLOCK 32768 -#endif #ifndef OS_SYSTICK #define OS_SYSTICK 0 #endif @@ -42,27 +36,12 @@ #ifndef INITIAL_SP #define INITIAL_SP (0x20010000UL) #endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 512 -#endif -#ifndef OS_CLOCK -#define OS_CLOCK 64000000 -#endif #elif defined(TARGET_MCU_NRF52840) #ifndef INITIAL_SP #define INITIAL_SP (0x20040000UL) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 24 -#endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 2048 -#endif -#ifndef OS_CLOCK -#define OS_CLOCK 64000000 -#endif #endif // defined(TARGET_MCU_NRF51822)... diff --git a/targets/TARGET_NUVOTON/mbed_rtx.h b/targets/TARGET_NUVOTON/mbed_rtx.h index a8b9c13d3ea..74596d71cda 100644 --- a/targets/TARGET_NUVOTON/mbed_rtx.h +++ b/targets/TARGET_NUVOTON/mbed_rtx.h @@ -21,13 +21,6 @@ #if defined(TARGET_NUMAKER_PFM_NUC472) -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 256 -#endif -#ifndef OS_CLOCK -#define OS_CLOCK 84000000 -#endif - #if defined(__CC_ARM) extern uint32_t Image$$ARM_LIB_HEAP$$ZI$$Base[]; extern uint32_t Image$$ARM_LIB_HEAP$$ZI$$Length[]; @@ -54,13 +47,6 @@ #elif defined(TARGET_NUMAKER_PFM_M453) -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 256 -#endif -#ifndef OS_CLOCK -#define OS_CLOCK 72000000 -#endif - #if defined(__CC_ARM) extern uint32_t Image$$ARM_LIB_HEAP$$ZI$$Base[]; extern uint32_t Image$$ARM_LIB_HEAP$$ZI$$Length[]; diff --git a/targets/TARGET_NXP/mbed_rtx.h b/targets/TARGET_NXP/mbed_rtx.h index c4b9ad33da3..436c8acc329 100644 --- a/targets/TARGET_NXP/mbed_rtx.h +++ b/targets/TARGET_NXP/mbed_rtx.h @@ -22,12 +22,6 @@ #ifndef INITIAL_SP #define INITIAL_SP (0x10008000UL) #endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 256 -#endif -#ifndef OS_CLOCK -#define OS_CLOCK 48000000 -#endif #elif defined(TARGET_LPC11U24) \ || defined(TARGET_LPC11U35_401) \ @@ -37,108 +31,54 @@ #ifndef INITIAL_SP #define INITIAL_SP (0x10002000UL) #endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 128 -#endif -#ifndef OS_CLOCK -#define OS_CLOCK 48000000 -#endif #elif defined(TARGET_LPC1114) #ifndef INITIAL_SP #define INITIAL_SP (0x10001000UL) #endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 128 -#endif -#ifndef OS_CLOCK -#define OS_CLOCK 48000000 -#endif #elif defined(TARGET_LPC1347) #ifndef INITIAL_SP #define INITIAL_SP (0x10002000UL) #endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 256 -#endif -#ifndef OS_CLOCK -#define OS_CLOCK 72000000 -#endif #elif defined(TARGET_LPC1549) #ifndef INITIAL_SP #define INITIAL_SP (0x02009000UL) #endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 256 -#endif -#ifndef OS_CLOCK -#define OS_CLOCK 72000000 -#endif #elif defined(TARGET_LPC1768) #ifndef INITIAL_SP #define INITIAL_SP (0x10008000UL) #endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 256 -#endif -#ifndef OS_CLOCK -#define OS_CLOCK 96000000 -#endif #elif defined(TARGET_LPC4088) || defined(TARGET_LPC4088_DM) #ifndef INITIAL_SP #define INITIAL_SP (0x10010000UL) #endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 256 -#endif -#ifndef OS_CLOCK -#define OS_CLOCK 120000000 -#endif #elif defined(TARGET_LPC4330) || defined(TARGET_LPC4337) #ifndef INITIAL_SP #define INITIAL_SP (0x10008000UL) #endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 256 -#endif -#ifndef OS_CLOCK -#define OS_CLOCK 204000000 -#endif #elif defined(TARGET_LPC812) #ifndef INITIAL_SP #define INITIAL_SP (0x10001000UL) #endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 128 -#endif -#ifndef OS_CLOCK -#define OS_CLOCK 36000000 -#endif #elif defined(TARGET_LPC824) || defined(TARGET_SSCI824) #ifndef INITIAL_SP #define INITIAL_SP (0x10002000UL) #endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 128 -#endif -#ifndef OS_CLOCK -#define OS_CLOCK 30000000 -#endif #endif diff --git a/targets/TARGET_ONSEMI/mbed_rtx.h b/targets/TARGET_ONSEMI/mbed_rtx.h index c8fa8ad6d3a..58677a495ef 100644 --- a/targets/TARGET_ONSEMI/mbed_rtx.h +++ b/targets/TARGET_ONSEMI/mbed_rtx.h @@ -22,12 +22,6 @@ #ifndef INITIAL_SP #define INITIAL_SP (0x40000000UL) #endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 256 -#endif -#ifndef OS_CLOCK -#define OS_CLOCK 32000000 -#endif #endif diff --git a/targets/TARGET_RENESAS/mbed_rtx.h b/targets/TARGET_RENESAS/mbed_rtx.h deleted file mode 100644 index 61886067b10..00000000000 --- a/targets/TARGET_RENESAS/mbed_rtx.h +++ /dev/null @@ -1,25 +0,0 @@ -/* mbed Microcontroller Library - * Copyright (c) 2016 ARM Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#ifndef MBED_MBED_RTX_H -#define MBED_MBED_RTX_H - -#if defined(TARGET_RZ_A1H) || defined(TARGET_VK_RZ_A1H) -#ifndef OS_CLOCK -#define OS_CLOCK 12000000 -#endif -#endif - -#endif // MBED_MBED_RTX_H diff --git a/targets/TARGET_STM/mbed_rtx.h b/targets/TARGET_STM/mbed_rtx.h index c2b0a2255bc..444691fb89b 100644 --- a/targets/TARGET_STM/mbed_rtx.h +++ b/targets/TARGET_STM/mbed_rtx.h @@ -22,561 +22,276 @@ #ifndef INITIAL_SP #define INITIAL_SP (0x20002000UL) #endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 128 -#endif -#ifndef OS_CLOCK -#define OS_CLOCK 48000000 -#endif #elif defined(TARGET_STM32L031K6) #ifndef INITIAL_SP #define INITIAL_SP (0x20002000UL) #endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 112 -#endif -#ifndef OS_CLOCK -#define OS_CLOCK 32000000 -#endif #elif defined(TARGET_STM32F070RB) #ifndef INITIAL_SP #define INITIAL_SP (0x20004000UL) #endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 128 -#endif -#ifndef OS_CLOCK -#define OS_CLOCK 48000000 -#endif #elif defined(TARGET_STM32F072RB) #ifndef INITIAL_SP #define INITIAL_SP (0x20004000UL) #endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 128 -#endif -#ifndef OS_CLOCK -#define OS_CLOCK 48000000 -#endif #elif defined(TARGET_STM32F091RC) #ifndef INITIAL_SP #define INITIAL_SP (0x20008000UL) #endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 128 -#endif -#ifndef OS_CLOCK -#define OS_CLOCK 48000000 -#endif #elif defined(TARGET_STM32F100RB) #ifndef INITIAL_SP #define INITIAL_SP (0x20002000UL) #endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 128 -#endif -#ifndef OS_CLOCK -#define OS_CLOCK 24000000 -#endif #elif defined(TARGET_STM32F103RB) #ifndef INITIAL_SP #define INITIAL_SP (0x20005000UL) #endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 128 -#endif -#ifndef OS_CLOCK -#define OS_CLOCK 72000000 -#endif #elif defined(TARGET_STM32F207ZG) #ifndef INITIAL_SP #define INITIAL_SP (0x20020000UL) #endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 256 -#endif -#ifndef OS_CLOCK -#define OS_CLOCK 120000000 -#endif #elif defined(TARGET_STM32F303VC) #ifndef INITIAL_SP #define INITIAL_SP (0x2000A000UL) #endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 256 -#endif -#ifndef OS_CLOCK -#define OS_CLOCK 72000000 -#endif #elif defined(TARGET_STM32F334C8) #ifndef INITIAL_SP #define INITIAL_SP (0x20003000UL) #endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 112 -#endif -#ifndef OS_CLOCK -#define OS_CLOCK 72000000 -#endif #elif defined(TARGET_STM32F302R8) #ifndef INITIAL_SP #define INITIAL_SP (0x20004000UL) #endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 128 -#endif -#ifndef OS_CLOCK -#define OS_CLOCK 72000000 -#endif #elif defined(TARGET_STM32F303K8) #ifndef INITIAL_SP #define INITIAL_SP (0x20003000UL) #endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 112 -#endif -#ifndef OS_CLOCK -#define OS_CLOCK 64000000 -#endif #elif defined(TARGET_STM32F303RE) #ifndef INITIAL_SP #define INITIAL_SP (0x20010000UL) #endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 112 -#endif -#ifndef OS_CLOCK -#define OS_CLOCK 72000000 -#endif #elif defined(TARGET_STM32F303ZE) #ifndef INITIAL_SP #define INITIAL_SP (0x20010000UL) #endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 112 -#endif -#ifndef OS_CLOCK -#define OS_CLOCK 72000000 -#endif #elif defined(TARGET_STM32F334R8) #ifndef INITIAL_SP #define INITIAL_SP (0x20003000UL) #endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 112 -#endif -#ifndef OS_CLOCK -#define OS_CLOCK 72000000 -#endif #elif defined(TARGET_STM32F446VE) #ifndef INITIAL_SP #define INITIAL_SP (0x20020000UL) #endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 256 -#endif -#ifndef OS_CLOCK -#define OS_CLOCK 180000000 -#endif #elif defined(TARGET_STM32F401VC) #ifndef INITIAL_SP #define INITIAL_SP (0x20010000UL) #endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 256 -#endif -#ifndef OS_CLOCK -#define OS_CLOCK 84000000 -#endif #elif (defined(TARGET_STM32F429ZI) || defined(TARGET_STM32F439ZI)) #ifndef INITIAL_SP #define INITIAL_SP (0x20030000UL) #endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 256 -#endif -#ifndef OS_CLOCK -#define OS_CLOCK 168000000 -#endif #elif defined(TARGET_UBLOX_EVK_ODIN_W2) #ifndef INITIAL_SP #define INITIAL_SP (0x20030000UL) #endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 512 -#endif -#ifndef OS_CLOCK -#define OS_CLOCK 168000000 -#endif #elif defined(TARGET_UBLOX_C030) #ifndef INITIAL_SP #define INITIAL_SP (0x20030000UL) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 14 -#endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 512 -#endif -#ifndef OS_CLOCK -#define OS_CLOCK 168000000 -#endif #elif defined(TARGET_STM32F469NI) #ifndef INITIAL_SP #define INITIAL_SP (0x20050000UL) #endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 256 -#endif -#ifndef OS_CLOCK -#define OS_CLOCK 168000000 -#endif #elif defined(TARGET_STM32F405RG) #ifndef INITIAL_SP #define INITIAL_SP (0x20020000UL) #endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 256 -#endif -#ifndef OS_CLOCK -#define OS_CLOCK 48000000 -#endif #elif defined(TARGET_STM32F401RE) #ifndef INITIAL_SP #define INITIAL_SP (0x20018000UL) #endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 256 -#endif -#ifndef OS_CLOCK -#define OS_CLOCK 84000000 -#endif #elif defined(TARGET_STM32F410RB) #ifndef INITIAL_SP #define INITIAL_SP (0x20008000UL) #endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 256 -#endif -#ifndef OS_CLOCK -#define OS_CLOCK 100000000 -#endif #elif defined(TARGET_MTS_MDOT_F411RE) || defined (TARGET_MTS_DRAGONFLY_F411RE) #ifndef INITIAL_SP #define INITIAL_SP (0x20020000UL) #endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 1024 -#endif -#ifndef OS_CLOCK -#define OS_CLOCK 96000000 -#endif #elif defined(TARGET_STM32F411RE) #ifndef INITIAL_SP #define INITIAL_SP (0x20020000UL) #endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 256 -#endif -#ifndef OS_CLOCK -#define OS_CLOCK 100000000 -#endif #elif defined(TARGET_STM32F412ZG) #ifndef INITIAL_SP #define INITIAL_SP (0x20040000UL) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 14 -#endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 256 -#endif -#ifndef OS_CLOCK -#define OS_CLOCK 100000000 -#endif #elif defined(TARGET_STM32F446RE) #ifndef INITIAL_SP #define INITIAL_SP (0x20020000UL) #endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 256 -#endif -#ifndef OS_CLOCK -#define OS_CLOCK 180000000 -#endif #elif defined(TARGET_STM32F446ZE) #ifndef INITIAL_SP #define INITIAL_SP (0x20020000UL) #endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 256 -#endif -#ifndef OS_CLOCK -#define OS_CLOCK 180000000 -#endif #elif defined(TARGET_STM32F407VG) #ifndef INITIAL_SP #define INITIAL_SP (0x20020000UL) #endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 256 -#endif -#ifndef OS_CLOCK -#define OS_CLOCK 168000000 -#endif #elif defined(TARGET_STM32F746NG) #ifndef INITIAL_SP #define INITIAL_SP (0x20050000UL) #endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 256 -#endif -#ifndef OS_CLOCK -#define OS_CLOCK 216000000 -#endif #elif (defined(TARGET_STM32F746ZG) || defined(TARGET_STM32F756ZG)) #ifndef INITIAL_SP #define INITIAL_SP (0x20050000UL) #endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 256 -#endif -#ifndef OS_CLOCK -#define OS_CLOCK 216000000 -#endif #elif defined(TARGET_STM32F767ZI) #ifndef INITIAL_SP #define INITIAL_SP (0x20080000UL) #endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 256 -#endif -#ifndef OS_CLOCK -#define OS_CLOCK 216000000 -#endif #elif defined(TARGET_STM32F769NI) #ifndef INITIAL_SP #define INITIAL_SP (0x20080000UL) #endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 256 -#endif -#ifndef OS_CLOCK -#define OS_CLOCK 216000000 -#endif #elif defined(TARGET_STM32L053C8) #ifndef INITIAL_SP #define INITIAL_SP (0x20002000UL) #endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 112 -#endif -#ifndef OS_CLOCK -#define OS_CLOCK 32000000 -#endif #elif defined(TARGET_STM32L031K6) #ifndef INITIAL_SP #define INITIAL_SP (0x20002000UL) #endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 112 -#endif -#ifndef OS_CLOCK -#define OS_CLOCK 32000000 -#endif #elif defined(TARGET_STM32L053R8) #ifndef INITIAL_SP #define INITIAL_SP (0x20002000UL) #endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 112 -#endif -#ifndef OS_CLOCK -#define OS_CLOCK 32000000 -#endif #elif defined(TARGET_STM32L072CZ) #ifndef INITIAL_SP #define INITIAL_SP (0x20005000UL) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 6 -#endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 112 -#endif -#ifndef OS_CLOCK -#define OS_CLOCK 32000000 -#endif #elif defined(TARGET_STM32L073RZ) #ifndef INITIAL_SP #define INITIAL_SP (0x20005000UL) #endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 112 -#endif -#ifndef OS_CLOCK -#define OS_CLOCK 32000000 -#endif #elif defined(TARGET_STM32L152RC) #ifndef INITIAL_SP #define INITIAL_SP (0x20008000UL) #endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 256 -#endif -#ifndef OS_CLOCK -#define OS_CLOCK 24000000 -#endif #elif defined(TARGET_STM32L152RE) #ifndef INITIAL_SP #define INITIAL_SP (0x20014000UL) #endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 256 -#endif -#ifndef OS_CLOCK -#define OS_CLOCK 32000000 -#endif #elif defined(TARGET_NZ32_SC151) #ifndef INITIAL_SP #define INITIAL_SP (0x20008000UL) #endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 128 -#endif -#ifndef OS_CLOCK -#define OS_CLOCK 32000000 -#endif #elif defined(TARGET_XDOT_L151CC) #ifndef INITIAL_SP #define INITIAL_SP (0x20008000UL) #endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 128 -#endif -#ifndef OS_CLOCK -#define OS_CLOCK 32000000 -#endif #elif defined(TARGET_STM32L476VG) #ifndef INITIAL_SP #define INITIAL_SP (0x20018000UL) #endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 256 -#endif -#ifndef OS_CLOCK -#define OS_CLOCK 80000000 -#endif #elif defined(TARGET_STM32L432KC) #ifndef INITIAL_SP #define INITIAL_SP (0x2000C000UL) #endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 256 -#endif -#ifndef OS_CLOCK -#define OS_CLOCK 80000000 -#endif #elif (defined(TARGET_STM32L476RG) || defined(TARGET_STM32L486RG)) #ifndef INITIAL_SP #define INITIAL_SP (0x20018000UL) #endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 256 -#endif -#ifndef OS_CLOCK -#define OS_CLOCK 80000000 -#endif #endif diff --git a/targets/TARGET_Silicon_Labs/mbed_rtx.h b/targets/TARGET_Silicon_Labs/mbed_rtx.h index 00ff64e28b3..bd804b3e659 100644 --- a/targets/TARGET_Silicon_Labs/mbed_rtx.h +++ b/targets/TARGET_Silicon_Labs/mbed_rtx.h @@ -20,10 +20,6 @@ #include #include "clocking.h" -#ifndef OS_CLOCK -#define OS_CLOCK REFERENCE_FREQUENCY -#endif - #if defined(__CC_ARM) extern uint32_t HEAP$$Base; extern uint32_t HEAP$$Limit; @@ -44,76 +40,42 @@ extern uint32_t STACK$$Base; #define INITIAL_SP (0x20020000UL) #endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 256 -#endif - #elif defined(TARGET_EFM32HG_STK3400) #ifndef INITIAL_SP #define INITIAL_SP (0x20002000UL) #endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 112 -#endif - #elif defined(TARGET_EFM32LG_STK3600) #ifndef INITIAL_SP #define INITIAL_SP (0x20008000UL) #endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 128 -#endif - #elif defined(TARGET_EFM32PG_STK3401) #ifndef INITIAL_SP #define INITIAL_SP (0x20008000UL) #endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 128 -#endif - #elif defined(TARGET_EFM32WG_STK3800) #ifndef INITIAL_SP #define INITIAL_SP (0x20008000UL) #endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 128 -#endif - #elif defined(TARGET_EFR32MG1) #ifndef INITIAL_SP #define INITIAL_SP (0x20007C00UL) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 5 -#endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 256 -#endif - #elif defined(TARGET_EFR32MG12) || defined(TARGET_EFM32PG12) #ifndef INITIAL_SP #define INITIAL_SP (0x20040000UL) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 14 -#endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 256 -#endif - #endif #endif // MBED_MBED_RTX_H diff --git a/targets/TARGET_WIZNET/mbed_rtx.h b/targets/TARGET_WIZNET/mbed_rtx.h index c475509da13..bf8630cbab7 100644 --- a/targets/TARGET_WIZNET/mbed_rtx.h +++ b/targets/TARGET_WIZNET/mbed_rtx.h @@ -22,45 +22,19 @@ #ifndef INITIAL_SP #define INITIAL_SP (0x20004000UL) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 6 -#endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 128 -#endif -#ifndef OS_CLOCK -#define OS_CLOCK 20000000 -#endif #elif defined(TARGET_WIZWIKI_W7500P) #ifndef INITIAL_SP #define INITIAL_SP (0x20004000UL) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 6 -#endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 128 -#endif -#ifndef OS_CLOCK -#define OS_CLOCK 20000000 -#endif + #elif defined(TARGET_WIZWIKI_W7500ECO) #ifndef INITIAL_SP #define INITIAL_SP (0x20004000UL) #endif -#ifndef OS_TASKCNT -#define OS_TASKCNT 6 -#endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 128 -#endif -#ifndef OS_CLOCK -#define OS_CLOCK 20000000 -#endif #endif // diff --git a/targets/TARGET_ublox/mbed_rtx.h b/targets/TARGET_ublox/mbed_rtx.h index 2e5e2e7870c..11d4591e277 100644 --- a/targets/TARGET_ublox/mbed_rtx.h +++ b/targets/TARGET_ublox/mbed_rtx.h @@ -23,12 +23,6 @@ #define INITIAL_SP (0x01000000 + 0x05000 - 256) #endif -#ifndef OS_MAINSTKSIZE -#define OS_MAINSTKSIZE 128 -#endif -#ifndef OS_CLOCK -#define OS_CLOCK 48000000 -#endif #endif #endif // MBED_MBED_RTX_H From a8229b5351205a69396b0c3b22336683e6cf4515 Mon Sep 17 00:00:00 2001 From: Bartek Szatkowski Date: Wed, 24 May 2017 09:32:48 +0100 Subject: [PATCH 20/24] Make sure all RTOS attribute structures are 0-ed before use --- .../lwip-interface/lwip-sys/arch/lwip_sys_arch.c | 14 ++++++-------- rtos/MemoryPool.h | 1 + 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/features/FEATURE_LWIP/lwip-interface/lwip-sys/arch/lwip_sys_arch.c b/features/FEATURE_LWIP/lwip-interface/lwip-sys/arch/lwip_sys_arch.c index 7c6ecbc0e02..5e8496544ed 100644 --- a/features/FEATURE_LWIP/lwip-interface/lwip-sys/arch/lwip_sys_arch.c +++ b/features/FEATURE_LWIP/lwip-interface/lwip-sys/arch/lwip_sys_arch.c @@ -126,11 +126,8 @@ err_t sys_mbox_new(sys_mbox_t *mbox, int queue_sz) { if (queue_sz > MB_SIZE) error("sys_mbox_new size error\n"); - mbox->post_idx = 0; - mbox->fetch_idx = 0; - memset(mbox->queue, 0, sizeof(mbox->queue)); + memset(mbox, 0, sizeof(*mbox)); - memset(&mbox->data, 0, sizeof(mbox->data)); mbox->attr.cb_mem = &mbox->data; mbox->attr.cb_size = sizeof(mbox->data); mbox->id = osEventFlagsNew(&mbox->attr); @@ -308,7 +305,7 @@ u32_t sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg) { * err_t -- ERR_OK if semaphore created *---------------------------------------------------------------------------*/ err_t sys_sem_new(sys_sem_t *sem, u8_t count) { - memset(&sem->data, 0, sizeof(sem->data)); + memset(sem, 0, sizeof(*sem)); sem->attr.cb_mem = &sem->data; sem->attr.cb_size = sizeof(sem->data); sem->id = osSemaphoreNew(UINT16_MAX, count, &sem->attr); @@ -377,7 +374,7 @@ void sys_sem_free(sys_sem_t *sem) {} * @param mutex pointer to the mutex to create * @return a new mutex */ err_t sys_mutex_new(sys_mutex_t *mutex) { - memset(&mutex->data, 0, sizeof(mutex->data)); + memset(mutex, 0, sizeof(*mutex)); mutex->attr.name = "lwip_mutex"; mutex->attr.cb_mem = &mutex->data; mutex->attr.cb_size = sizeof(mutex->data); @@ -513,12 +510,13 @@ sys_thread_t sys_thread_new(const char *pcName, void (*thread)(void *arg), void *arg, int stacksize, int priority) { LWIP_DEBUGF(SYS_DEBUG, ("New Thread: %s\n", pcName)); - + if (thread_pool_index >= SYS_THREAD_POOL_N) error("sys_thread_new number error\n"); sys_thread_t t = (sys_thread_t)&thread_pool[thread_pool_index]; thread_pool_index++; - + + memset(t, 0, sizeof(*t)); t->attr.name = pcName ? pcName : "lwip_unnamed_thread"; t->attr.priority = (osPriority_t)priority; t->attr.cb_size = sizeof(t->data); diff --git a/rtos/MemoryPool.h b/rtos/MemoryPool.h index be8c2a3dbe4..127639147bb 100644 --- a/rtos/MemoryPool.h +++ b/rtos/MemoryPool.h @@ -48,6 +48,7 @@ class MemoryPool { MemoryPool() { memset(_pool_mem, 0, sizeof(_pool_mem)); memset(&_obj_mem, 0, sizeof(_obj_mem)); + memset(&_attr, 0, sizeof(_attr)); _attr.mp_mem = _pool_mem; _attr.mp_size = sizeof(_pool_mem); _attr.cb_mem = &_obj_mem; From 80cb65e094cdca5b74d864a32d51b160954b4c1f Mon Sep 17 00:00:00 2001 From: Bartek Szatkowski Date: Wed, 24 May 2017 09:39:47 +0100 Subject: [PATCH 21/24] Add more verbose RTOS error messages --- rtos/rtx5/mbed_rtx_handlers.c | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/rtos/rtx5/mbed_rtx_handlers.c b/rtos/rtx5/mbed_rtx_handlers.c index 738fa13c86c..ddc20f79d00 100644 --- a/rtos/rtx5/mbed_rtx_handlers.c +++ b/rtos/rtx5/mbed_rtx_handlers.c @@ -31,7 +31,37 @@ __NO_RETURN void osRtxIdleThread (void *argument) __NO_RETURN uint32_t osRtxErrorNotify (uint32_t code, void *object_id) { osThreadId_t tid = osThreadGetId(); - error("CMSIS-RTOS error status: 0x%X, task ID: 0x%X\n\r", code, tid); + + switch (code) { + case osRtxErrorStackUnderflow: + // Stack underflow detected for thread (thread_id=object_id) + error("CMSIS-RTOS error: Stack underflow (status: 0x%X, task ID: 0x%X, task name: %s)\n\r", + code, object_id, osThreadGetName(object_id)); + break; + case osRtxErrorISRQueueOverflow: + // ISR Queue overflow detected when inserting object (object_id) + error("CMSIS-RTOS error: ISR Queue overflow (status: 0x%X, task ID: 0x%X, object ID: 0x%X)\n\r", + code, tid, object_id); + break; + case osRtxErrorTimerQueueOverflow: + // User Timer Callback Queue overflow detected for timer (timer_id=object_id) + error("CMSIS-RTOS error: User Timer Callback Queue overflow (status: 0x%X, task ID: 0x%X, timer ID: 0x%X)\n\r", + code, tid, object_id); + break; + case osRtxErrorClibSpace: + // Standard C/C++ library libspace not available: increase OS_THREAD_LIBSPACE_NUM + error("CMSIS-RTOS error: STD C/C++ library libspace not available (status: 0x%X, task ID: 0x%X)\n\r", + code, tid); + break; + case osRtxErrorClibMutex: + // Standard C/C++ library mutex initialization failed + error("CMSIS-RTOS error: STD C/C++ library mutex initialization failed (status: 0x%X, task ID: 0x%X)\n\r", + code, tid); + break; + default: + error("CMSIS-RTOS error: Unknown (status: 0x%X, task ID: 0x%X)\n\r", code, tid); + break; + } /* That shouldn't be reached */ for (;;) {} From f03509c6cb0c07c0c4381ae0af35335388e87536 Mon Sep 17 00:00:00 2001 From: Yuguo Zou Date: Mon, 15 May 2017 17:55:11 +0800 Subject: [PATCH 22/24] Add up OS_MUTEX_NUM for ARMCC compiler CI shield test (SPI test) may need 7 mutexes --- rtos/rtx5/mbed_rtx_conf.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtos/rtx5/mbed_rtx_conf.h b/rtos/rtx5/mbed_rtx_conf.h index c8a93f97a1d..7558cddf0b3 100644 --- a/rtos/rtx5/mbed_rtx_conf.h +++ b/rtos/rtx5/mbed_rtx_conf.h @@ -38,7 +38,7 @@ #if defined(__CC_ARM) #define OS_MUTEX_OBJ_MEM 1 -#define OS_MUTEX_NUM 6 +#define OS_MUTEX_NUM 7 #endif #if !defined(OS_STACK_WATERMARK) && (defined(MBED_STACK_STATS_ENABLED) && MBED_STACK_STATS_ENABLED) From 39a1b39ce144f7af3bd25851b9ade309532f52c5 Mon Sep 17 00:00:00 2001 From: Bartosz Szatkowski Date: Fri, 26 May 2017 10:53:35 +0100 Subject: [PATCH 23/24] Bump number of ARMC mutexes to fix PAL test failure --- rtos/rtx5/mbed_rtx_conf.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtos/rtx5/mbed_rtx_conf.h b/rtos/rtx5/mbed_rtx_conf.h index 7558cddf0b3..f5477007209 100644 --- a/rtos/rtx5/mbed_rtx_conf.h +++ b/rtos/rtx5/mbed_rtx_conf.h @@ -38,7 +38,7 @@ #if defined(__CC_ARM) #define OS_MUTEX_OBJ_MEM 1 -#define OS_MUTEX_NUM 7 +#define OS_MUTEX_NUM 8 #endif #if !defined(OS_STACK_WATERMARK) && (defined(MBED_STACK_STATS_ENABLED) && MBED_STACK_STATS_ENABLED) From c674ee2290af66a174a8dbb9c374fec69648225f Mon Sep 17 00:00:00 2001 From: Martin Kojtal <0xc0170@gmail.com> Date: Thu, 1 Jun 2017 12:11:54 +0100 Subject: [PATCH 24/24] Jenkinsfile: remove client app test temporarily This should be fixed as soon as client and its dependencies are updated to resolve conflicts there. We expect this to be reverted asap. --- Jenkinsfile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 8cb9d5c33b9..846827c2a09 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -24,8 +24,7 @@ def parallelSteps = mbed.createParalleSteps("mbed-os", targets, toolchains) mbed.compile(parallelSteps) def testApps = [ - "mbed-os-cliapp", - "mbed-client-testapp" + "mbed-os-cliapp" ] // buildTestApps accepts array of test application names and a mbed-os branch or PR reference as parameters