+
+
+/************************* Miscellaneous Configuration ************************/
+#define VECT_TAB_OFFSET 0x00 /*!< Vector Table base offset field.
+ This value must be a multiple of 0x200. */
+/******************************************************************************/
+
+/************************* PLL Parameters *************************************/
+/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */
+#define PLL_M ((HSE_VALUE) / 1000000UL)
+#define PLL_N 336
+
+/* SYSCLK = PLL_VCO / PLL_P */
+#define PLL_P 2
+
+/* USB OTG FS, SDIO and RNG Clock = PLL_VCO / PLLQ */
+#define PLL_Q 7
+
+/******************************************************************************/
+
+
+ uint32_t SystemCoreClock = 168000000;
+
+ __I uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
+
+
+static void SetSysClock(void);
+
+extern uint32_t __Vectors[];
+
+/**
+ * @brief Setup the microcontroller system
+ * Initialize the Embedded Flash Interface, the PLL and update the
+ * SystemFrequency variable.
+ * @param None
+ * @retval None
+ */
+void SystemInit(void)
+{
+ /* FPU settings ------------------------------------------------------------*/
+ #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
+ SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); /* set CP10 and CP11 Full Access */
+ #endif
+
+ /* Reset the RCC clock configuration to the default reset state ------------*/
+ /* Set HSION bit */
+ RCC->CR |= (uint32_t)0x00000001;
+
+ /* Reset CFGR register */
+ RCC->CFGR = 0x00000000;
+
+ /* Reset HSEON, CSSON and PLLON bits */
+ RCC->CR &= (uint32_t)0xFEF6FFFF;
+
+ /* Reset PLLCFGR register */
+ RCC->PLLCFGR = 0x24003010;
+
+ /* Reset HSEBYP bit */
+ RCC->CR &= (uint32_t)0xFFFBFFFF;
+
+ /* Disable all interrupts */
+ RCC->CIR = 0x00000000;
+
+ /* Configure the System clock source, PLL Multiplier and Divider factors,
+ AHB/APBx prescalers and Flash settings ----------------------------------*/
+ SetSysClock();
+
+ /* Configure the Vector Table location add offset address ------------------*/
+ SCB->VTOR = (uint32_t)(&__Vectors[0]);
+}
+
+/**
+ * @brief Update SystemCoreClock variable according to Clock Register Values.
+ * The SystemCoreClock variable contains the core clock (HCLK), it can
+ * be used by the user application to setup the SysTick timer or configure
+ * other parameters.
+ *
+ * @note Each time the core clock (HCLK) changes, this function must be called
+ * to update SystemCoreClock variable value. Otherwise, any configuration
+ * based on this variable will be incorrect.
+ *
+ * @note - The system frequency computed by this function is not the real
+ * frequency in the chip. It is calculated based on the predefined
+ * constant and the selected clock source:
+ *
+ * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*)
+ *
+ * - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**)
+ *
+ * - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**)
+ * or HSI_VALUE(*) multiplied/divided by the PLL factors.
+ *
+ * (*) HSI_VALUE is a constant defined in stm32f4xx.h file (default value
+ * 16 MHz) but the real value may vary depending on the variations
+ * in voltage and temperature.
+ *
+ * (**) HSE_VALUE is a constant defined in stm32f4xx.h file (default value
+ * 25 MHz), user has to ensure that HSE_VALUE is same as the real
+ * frequency of the crystal used. Otherwise, this function may
+ * have wrong result.
+ *
+ * - The result of this function could be not correct when using fractional
+ * value for HSE crystal.
+ *
+ * @param None
+ * @retval None
+ */
+void SystemCoreClockUpdate(void)
+{
+ uint32_t tmp = 0, pllvco = 0, pllp = 2, pllsource = 0, pllm = 2;
+
+ /* Get SYSCLK source -------------------------------------------------------*/
+ tmp = RCC->CFGR & RCC_CFGR_SWS;
+
+ switch (tmp)
+ {
+ case 0x00: /* HSI used as system clock source */
+ SystemCoreClock = HSI_VALUE;
+ break;
+ case 0x04: /* HSE used as system clock source */
+ SystemCoreClock = HSE_VALUE;
+ break;
+ case 0x08: /* PLL used as system clock source */
+
+ /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N
+ SYSCLK = PLL_VCO / PLL_P
+ */
+ pllsource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) >> 22;
+ pllm = RCC->PLLCFGR & RCC_PLLCFGR_PLLM;
+
+ if (pllsource != 0)
+ {
+ /* HSE used as PLL clock source */
+ pllvco = (HSE_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6);
+ }
+ else
+ {
+ /* HSI used as PLL clock source */
+ pllvco = (HSI_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6);
+ }
+
+ pllp = (((RCC->PLLCFGR & RCC_PLLCFGR_PLLP) >>16) + 1 ) *2;
+ SystemCoreClock = pllvco/pllp;
+ break;
+ default:
+ SystemCoreClock = HSI_VALUE;
+ break;
+ }
+ /* Compute HCLK frequency --------------------------------------------------*/
+ /* Get HCLK prescaler */
+ tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)];
+ /* HCLK frequency */
+ SystemCoreClock >>= tmp;
+}
+
+/**
+ * @brief Configures the System clock source, PLL Multiplier and Divider factors,
+ * AHB/APBx prescalers and Flash settings
+ * @Note This function should be called only once the RCC clock configuration
+ * is reset to the default reset state (done in SystemInit() function).
+ * @param None
+ * @retval None
+ */
+static void SetSysClock(void)
+{
+/******************************************************************************/
+/* PLL (clocked by HSE) used as System clock source */
+/******************************************************************************/
+ __IO uint32_t StartUpCounter = 0, HSEStatus = 0;
+
+ /* Enable HSE */
+ RCC->CR |= ((uint32_t)RCC_CR_HSEON);
+
+ /* Wait till HSE is ready and if Time out is reached exit */
+ do
+ {
+ HSEStatus = RCC->CR & RCC_CR_HSERDY;
+ StartUpCounter++;
+ } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
+
+ if ((RCC->CR & RCC_CR_HSERDY) != RESET)
+ {
+ HSEStatus = (uint32_t)0x01;
+ }
+ else
+ {
+ HSEStatus = (uint32_t)0x00;
+ }
+
+ if (HSEStatus == (uint32_t)0x01)
+ {
+ /* Select regulator voltage output Scale 1 mode, System frequency up to 168 MHz */
+ RCC->APB1ENR |= RCC_APB1ENR_PWREN;
+ PWR->CR |= PWR_CR_VOS;
+
+ /* HCLK = SYSCLK / 1*/
+ RCC->CFGR |= RCC_CFGR_HPRE_DIV1;
+
+ /* PCLK2 = HCLK / 2*/
+ RCC->CFGR |= RCC_CFGR_PPRE2_DIV2;
+
+ /* PCLK1 = HCLK / 4*/
+ RCC->CFGR |= RCC_CFGR_PPRE1_DIV4;
+
+ /* Configure the main PLL */
+ RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) |
+ (RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24);
+
+ /* Enable the main PLL */
+ RCC->CR |= RCC_CR_PLLON;
+
+ /* Wait till the main PLL is ready */
+ while((RCC->CR & RCC_CR_PLLRDY) == 0)
+ {
+ }
+
+ /* Configure Flash prefetch, Instruction cache, Data cache and wait state */
+ FLASH->ACR = FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_5WS;
+
+ /* Select the main PLL as system clock source */
+ RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
+ RCC->CFGR |= RCC_CFGR_SW_PLL;
+
+ /* Wait till the main PLL is used as system clock source */
+ while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL);
+ {
+ }
+ }
+ else
+ { /* If HSE fails to start-up, the application will have wrong clock
+ configuration. User can add here some code to deal with this error */
+ }
+
+}
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
diff --git a/platform/mcu/CMSIS/Include/arm_common_tables.h b/platform/mcu/CMSIS/Include/arm_common_tables.h
new file mode 100644
index 00000000..34f910f9
--- /dev/null
+++ b/platform/mcu/CMSIS/Include/arm_common_tables.h
@@ -0,0 +1,35 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010 ARM Limited. All rights reserved.
+*
+* $Date: 11. November 2010
+* $Revision: V1.0.2
+*
+* Project: CMSIS DSP Library
+* Title: arm_common_tables.h
+*
+* Description: This file has extern declaration for common tables like Bitreverse, reciprocal etc which are used across different functions
+*
+* Target Processor: Cortex-M4/Cortex-M3
+*
+* Version 1.0.2 2010/11/11
+* Documentation updated.
+*
+* Version 1.0.1 2010/10/05
+* Production release and review comments incorporated.
+*
+* Version 1.0.0 2010/09/20
+* Production release and review comments incorporated.
+* -------------------------------------------------------------------- */
+
+#ifndef _ARM_COMMON_TABLES_H
+#define _ARM_COMMON_TABLES_H
+
+#include "arm_math.h"
+
+extern uint16_t armBitRevTable[256];
+extern q15_t armRecipTableQ15[64];
+extern q31_t armRecipTableQ31[64];
+extern const q31_t realCoefAQ31[1024];
+extern const q31_t realCoefBQ31[1024];
+
+#endif /* ARM_COMMON_TABLES_H */
diff --git a/platform/mcu/CMSIS/Include/arm_math.h b/platform/mcu/CMSIS/Include/arm_math.h
new file mode 100644
index 00000000..d8901db1
--- /dev/null
+++ b/platform/mcu/CMSIS/Include/arm_math.h
@@ -0,0 +1,7051 @@
+/* ----------------------------------------------------------------------
+ * Copyright (C) 2010 ARM Limited. All rights reserved.
+ *
+ * $Date: 15. July 2011
+ * $Revision: V1.0.10
+ *
+ * Project: CMSIS DSP Library
+ * Title: arm_math.h
+ *
+ * Description: Public header file for CMSIS DSP Library
+ *
+ * Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
+ *
+ * Version 1.0.10 2011/7/15
+ * Big Endian support added and Merged M0 and M3/M4 Source code.
+ *
+ * Version 1.0.3 2010/11/29
+ * Re-organized the CMSIS folders and updated documentation.
+ *
+ * Version 1.0.2 2010/11/11
+ * Documentation updated.
+ *
+ * Version 1.0.1 2010/10/05
+ * Production release and review comments incorporated.
+ *
+ * Version 1.0.0 2010/09/20
+ * Production release and review comments incorporated.
+ * -------------------------------------------------------------------- */
+
+/**
+ \mainpage CMSIS DSP Software Library
+ *
+ * Introduction
+ *
+ * This user manual describes the CMSIS DSP software library,
+ * a suite of common signal processing functions for use on Cortex-M processor based devices.
+ *
+ * The library is divided into a number of modules each covering a specific category:
+ * - Basic math functions
+ * - Fast math functions
+ * - Complex math functions
+ * - Filters
+ * - Matrix functions
+ * - Transforms
+ * - Motor control functions
+ * - Statistical functions
+ * - Support functions
+ * - Interpolation functions
+ *
+ * The library has separate functions for operating on 8-bit integers, 16-bit integers,
+ * 32-bit integer and 32-bit floating-point values.
+ *
+ * Processor Support
+ *
+ * The library is completely written in C and is fully CMSIS compliant.
+ * High performance is achieved through maximum use of Cortex-M4 intrinsics.
+ *
+ * The supplied library source code also builds and runs on the Cortex-M3 and Cortex-M0 processor,
+ * with the DSP intrinsics being emulated through software.
+ *
+ *
+ * Toolchain Support
+ *
+ * The library has been developed and tested with MDK-ARM version 4.21.
+ * The library is being tested in GCC and IAR toolchains and updates on this activity will be made available shortly.
+ *
+ * Using the Library
+ *
+ * The library installer contains prebuilt versions of the libraries in the Lib folder.
+ * - arm_cortexM4lf_math.lib (Little endian and Floating Point Unit on Cortex-M4)
+ * - arm_cortexM4bf_math.lib (Big endian and Floating Point Unit on Cortex-M4)
+ * - arm_cortexM4l_math.lib (Little endian on Cortex-M4)
+ * - arm_cortexM4b_math.lib (Big endian on Cortex-M4)
+ * - arm_cortexM3l_math.lib (Little endian on Cortex-M3)
+ * - arm_cortexM3b_math.lib (Big endian on Cortex-M3)
+ * - arm_cortexM0l_math.lib (Little endian on Cortex-M0)
+ * - arm_cortexM0b_math.lib (Big endian on Cortex-M3)
+ *
+ * The library functions are declared in the public file arm_math.h which is placed in the Include folder.
+ * Simply include this file and link the appropriate library in the application and begin calling the library functions. The Library supports single
+ * public header file arm_math.h for Cortex-M4/M3/M0 with little endian and big endian. Same header file will be used for floating point unit(FPU) variants.
+ * Define the appropriate pre processor MACRO ARM_MATH_CM4 or ARM_MATH_CM3 or
+ * ARM_MATH_CM0 depending on the target processor in the application.
+ *
+ * Examples
+ *
+ * The library ships with a number of examples which demonstrate how to use the library functions.
+ *
+ * Building the Library
+ *
+ * The library installer contains project files to re build libraries on MDK Tool chain in the CMSIS\DSP_Lib\Source\ARM folder.
+ * - arm_cortexM0b_math.uvproj
+ * - arm_cortexM0l_math.uvproj
+ * - arm_cortexM3b_math.uvproj
+ * - arm_cortexM3l_math.uvproj
+ * - arm_cortexM4b_math.uvproj
+ * - arm_cortexM4l_math.uvproj
+ * - arm_cortexM4bf_math.uvproj
+ * - arm_cortexM4lf_math.uvproj
+ *
+ * Each library project have differant pre-processor macros.
+ *
+ * ARM_MATH_CMx:
+ * Define macro ARM_MATH_CM4 for building the library on Cortex-M4 target, ARM_MATH_CM3 for building library on Cortex-M3 target
+ * and ARM_MATH_CM0 for building library on cortex-M0 target.
+ *
+ * ARM_MATH_BIG_ENDIAN:
+ * Define macro ARM_MATH_BIG_ENDIAN to build the library for big endian targets. By default library builds for little endian targets.
+ *
+ * ARM_MATH_MATRIX_CHECK:
+ * Define macro for checking on the input and output sizes of matrices
+ *
+ * ARM_MATH_ROUNDING:
+ * Define macro for rounding on support functions
+ *
+ * __FPU_PRESENT:
+ * Initialize macro __FPU_PRESENT = 1 when building on FPU supported Targets. Enable this macro for M4bf and M4lf libraries
+ *
+ *
+ * The project can be built by opening the appropriate project in MDK-ARM 4.21 chain and defining the optional pre processor MACROs detailed above.
+ *
+ * Copyright Notice
+ *
+ * Copyright (C) 2010 ARM Limited. All rights reserved.
+ */
+
+
+/**
+ * @defgroup groupMath Basic Math Functions
+ */
+
+/**
+ * @defgroup groupFastMath Fast Math Functions
+ * This set of functions provides a fast approximation to sine, cosine, and square root.
+ * As compared to most of the other functions in the CMSIS math library, the fast math functions
+ * operate on individual values and not arrays.
+ * There are separate functions for Q15, Q31, and floating-point data.
+ *
+ */
+
+/**
+ * @defgroup groupCmplxMath Complex Math Functions
+ * This set of functions operates on complex data vectors.
+ * The data in the complex arrays is stored in an interleaved fashion
+ * (real, imag, real, imag, ...).
+ * In the API functions, the number of samples in a complex array refers
+ * to the number of complex values; the array contains twice this number of
+ * real values.
+ */
+
+/**
+ * @defgroup groupFilters Filtering Functions
+ */
+
+/**
+ * @defgroup groupMatrix Matrix Functions
+ *
+ * This set of functions provides basic matrix math operations.
+ * The functions operate on matrix data structures. For example,
+ * the type
+ * definition for the floating-point matrix structure is shown
+ * below:
+ *
+ * typedef struct
+ * {
+ * uint16_t numRows; // number of rows of the matrix.
+ * uint16_t numCols; // number of columns of the matrix.
+ * float32_t *pData; // points to the data of the matrix.
+ * } arm_matrix_instance_f32;
+ *
+ * There are similar definitions for Q15 and Q31 data types.
+ *
+ * The structure specifies the size of the matrix and then points to
+ * an array of data. The array is of size numRows X numCols
+ * and the values are arranged in row order. That is, the
+ * matrix element (i, j) is stored at:
+ *
+ * pData[i*numCols + j]
+ *
+ *
+ * \par Init Functions
+ * There is an associated initialization function for each type of matrix
+ * data structure.
+ * The initialization function sets the values of the internal structure fields.
+ * Refer to the function arm_mat_init_f32(), arm_mat_init_q31()
+ * and arm_mat_init_q15() for floating-point, Q31 and Q15 types, respectively.
+ *
+ * \par
+ * Use of the initialization function is optional. However, if initialization function is used
+ * then the instance structure cannot be placed into a const data section.
+ * To place the instance structure in a const data
+ * section, manually initialize the data structure. For example:
+ *
+ * arm_matrix_instance_f32 S = {nRows, nColumns, pData};
+ * arm_matrix_instance_q31 S = {nRows, nColumns, pData};
+ * arm_matrix_instance_q15 S = {nRows, nColumns, pData};
+ *
+ * where nRows specifies the number of rows, nColumns
+ * specifies the number of columns, and pData points to the
+ * data array.
+ *
+ * \par Size Checking
+ * By default all of the matrix functions perform size checking on the input and
+ * output matrices. For example, the matrix addition function verifies that the
+ * two input matrices and the output matrix all have the same number of rows and
+ * columns. If the size check fails the functions return:
+ *
+ * ARM_MATH_SIZE_MISMATCH
+ *
+ * Otherwise the functions return
+ *
+ * ARM_MATH_SUCCESS
+ *
+ * There is some overhead associated with this matrix size checking.
+ * The matrix size checking is enabled via the #define
+ *
+ * ARM_MATH_MATRIX_CHECK
+ *
+ * within the library project settings. By default this macro is defined
+ * and size checking is enabled. By changing the project settings and
+ * undefining this macro size checking is eliminated and the functions
+ * run a bit faster. With size checking disabled the functions always
+ * return ARM_MATH_SUCCESS.
+ */
+
+/**
+ * @defgroup groupTransforms Transform Functions
+ */
+
+/**
+ * @defgroup groupController Controller Functions
+ */
+
+/**
+ * @defgroup groupStats Statistics Functions
+ */
+/**
+ * @defgroup groupSupport Support Functions
+ */
+
+/**
+ * @defgroup groupInterpolation Interpolation Functions
+ * These functions perform 1- and 2-dimensional interpolation of data.
+ * Linear interpolation is used for 1-dimensional data and
+ * bilinear interpolation is used for 2-dimensional data.
+ */
+
+/**
+ * @defgroup groupExamples Examples
+ */
+#ifndef _ARM_MATH_H
+#define _ARM_MATH_H
+
+#define __CMSIS_GENERIC /* disable NVIC and Systick functions */
+
+#if defined (ARM_MATH_CM4)
+ #include "core_cm4.h"
+#elif defined (ARM_MATH_CM3)
+ #include "core_cm3.h"
+#elif defined (ARM_MATH_CM0)
+ #include "core_cm0.h"
+#else
+#include "ARMCM4.h"
+#warning "Define either ARM_MATH_CM4 OR ARM_MATH_CM3...By Default building on ARM_MATH_CM4....."
+#endif
+
+#undef __CMSIS_GENERIC /* enable NVIC and Systick functions */
+#include "string.h"
+ #include "math.h"
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+ /**
+ * @brief Macros required for reciprocal calculation in Normalized LMS
+ */
+
+#define DELTA_Q31 (0x100)
+#define DELTA_Q15 0x5
+#define INDEX_MASK 0x0000003F
+#define PI 3.14159265358979f
+
+ /**
+ * @brief Macros required for SINE and COSINE Fast math approximations
+ */
+
+#define TABLE_SIZE 256
+#define TABLE_SPACING_Q31 0x800000
+#define TABLE_SPACING_Q15 0x80
+
+ /**
+ * @brief Macros required for SINE and COSINE Controller functions
+ */
+ /* 1.31(q31) Fixed value of 2/360 */
+ /* -1 to +1 is divided into 360 values so total spacing is (2/360) */
+#define INPUT_SPACING 0xB60B61
+
+
+ /**
+ * @brief Error status returned by some functions in the library.
+ */
+
+ typedef enum
+ {
+ ARM_MATH_SUCCESS = 0, /**< No error */
+ ARM_MATH_ARGUMENT_ERROR = -1, /**< One or more arguments are incorrect */
+ ARM_MATH_LENGTH_ERROR = -2, /**< Length of data buffer is incorrect */
+ ARM_MATH_SIZE_MISMATCH = -3, /**< Size of matrices is not compatible with the operation. */
+ ARM_MATH_NANINF = -4, /**< Not-a-number (NaN) or infinity is generated */
+ ARM_MATH_SINGULAR = -5, /**< Generated by matrix inversion if the input matrix is singular and cannot be inverted. */
+ ARM_MATH_TEST_FAILURE = -6 /**< Test Failed */
+ } arm_status;
+
+ /**
+ * @brief 8-bit fractional data type in 1.7 format.
+ */
+ typedef int8_t q7_t;
+
+ /**
+ * @brief 16-bit fractional data type in 1.15 format.
+ */
+ typedef int16_t q15_t;
+
+ /**
+ * @brief 32-bit fractional data type in 1.31 format.
+ */
+ typedef int32_t q31_t;
+
+ /**
+ * @brief 64-bit fractional data type in 1.63 format.
+ */
+ typedef int64_t q63_t;
+
+ /**
+ * @brief 32-bit floating-point type definition.
+ */
+ typedef float float32_t;
+
+ /**
+ * @brief 64-bit floating-point type definition.
+ */
+ typedef double float64_t;
+
+ /**
+ * @brief definition to read/write two 16 bit values.
+ */
+#define __SIMD32(addr) (*(int32_t **) & (addr))
+
+#if defined (ARM_MATH_CM3) || defined (ARM_MATH_CM0)
+ /**
+ * @brief definition to pack two 16 bit values.
+ */
+#define __PKHBT(ARG1, ARG2, ARG3) ( (((int32_t)(ARG1) << 0) & (int32_t)0x0000FFFF) | \
+ (((int32_t)(ARG2) << ARG3) & (int32_t)0xFFFF0000) )
+
+#endif
+
+
+ /**
+ * @brief definition to pack four 8 bit values.
+ */
+#ifndef ARM_MATH_BIG_ENDIAN
+
+#define __PACKq7(v0,v1,v2,v3) ( (((int32_t)(v0) << 0) & (int32_t)0x000000FF) | \
+ (((int32_t)(v1) << 8) & (int32_t)0x0000FF00) | \
+ (((int32_t)(v2) << 16) & (int32_t)0x00FF0000) | \
+ (((int32_t)(v3) << 24) & (int32_t)0xFF000000) )
+#else
+
+#define __PACKq7(v0,v1,v2,v3) ( (((int32_t)(v3) << 0) & (int32_t)0x000000FF) | \
+ (((int32_t)(v2) << 8) & (int32_t)0x0000FF00) | \
+ (((int32_t)(v1) << 16) & (int32_t)0x00FF0000) | \
+ (((int32_t)(v0) << 24) & (int32_t)0xFF000000) )
+
+#endif
+
+
+ /**
+ * @brief Clips Q63 to Q31 values.
+ */
+ static __INLINE q31_t clip_q63_to_q31(
+ q63_t x)
+ {
+ return ((q31_t) (x >> 32) != ((q31_t) x >> 31)) ?
+ ((0x7FFFFFFF ^ ((q31_t) (x >> 63)))) : (q31_t) x;
+ }
+
+ /**
+ * @brief Clips Q63 to Q15 values.
+ */
+ static __INLINE q15_t clip_q63_to_q15(
+ q63_t x)
+ {
+ return ((q31_t) (x >> 32) != ((q31_t) x >> 31)) ?
+ ((0x7FFF ^ ((q15_t) (x >> 63)))) : (q15_t) (x >> 15);
+ }
+
+ /**
+ * @brief Clips Q31 to Q7 values.
+ */
+ static __INLINE q7_t clip_q31_to_q7(
+ q31_t x)
+ {
+ return ((q31_t) (x >> 24) != ((q31_t) x >> 23)) ?
+ ((0x7F ^ ((q7_t) (x >> 31)))) : (q7_t) x;
+ }
+
+ /**
+ * @brief Clips Q31 to Q15 values.
+ */
+ static __INLINE q15_t clip_q31_to_q15(
+ q31_t x)
+ {
+ return ((q31_t) (x >> 16) != ((q31_t) x >> 15)) ?
+ ((0x7FFF ^ ((q15_t) (x >> 31)))) : (q15_t) x;
+ }
+
+ /**
+ * @brief Multiplies 32 X 64 and returns 32 bit result in 2.30 format.
+ */
+
+ static __INLINE q63_t mult32x64(
+ q63_t x,
+ q31_t y)
+ {
+ return ((((q63_t) (x & 0x00000000FFFFFFFF) * y) >> 32) +
+ (((q63_t) (x >> 32) * y)));
+ }
+
+
+#if defined (ARM_MATH_CM0) && defined ( __CC_ARM )
+#define __CLZ __clz
+#endif
+
+#if defined (ARM_MATH_CM0) && ((defined (__ICCARM__)) ||(defined (__GNUC__)) || defined (__TASKING__) )
+
+ static __INLINE uint32_t __CLZ(q31_t data);
+
+
+ static __INLINE uint32_t __CLZ(q31_t data)
+ {
+ uint32_t count = 0;
+ uint32_t mask = 0x80000000;
+
+ while((data & mask) == 0)
+ {
+ count += 1u;
+ mask = mask >> 1u;
+ }
+
+ return(count);
+
+ }
+
+#endif
+
+ /**
+ * @brief Function to Calculates 1/in(reciprocal) value of Q31 Data type.
+ */
+
+ static __INLINE uint32_t arm_recip_q31(
+ q31_t in,
+ q31_t * dst,
+ q31_t * pRecipTable)
+ {
+
+ uint32_t out, tempVal;
+ uint32_t index, i;
+ uint32_t signBits;
+
+ if(in > 0)
+ {
+ signBits = __CLZ(in) - 1;
+ }
+ else
+ {
+ signBits = __CLZ(-in) - 1;
+ }
+
+ /* Convert input sample to 1.31 format */
+ in = in << signBits;
+
+ /* calculation of index for initial approximated Val */
+ index = (uint32_t) (in >> 24u);
+ index = (index & INDEX_MASK);
+
+ /* 1.31 with exp 1 */
+ out = pRecipTable[index];
+
+ /* calculation of reciprocal value */
+ /* running approximation for two iterations */
+ for (i = 0u; i < 2u; i++)
+ {
+ tempVal = (q31_t) (((q63_t) in * out) >> 31u);
+ tempVal = 0x7FFFFFFF - tempVal;
+ /* 1.31 with exp 1 */
+ //out = (q31_t) (((q63_t) out * tempVal) >> 30u);
+ out = (q31_t) clip_q63_to_q31(((q63_t) out * tempVal) >> 30u);
+ }
+
+ /* write output */
+ *dst = out;
+
+ /* return num of signbits of out = 1/in value */
+ return (signBits + 1u);
+
+ }
+
+ /**
+ * @brief Function to Calculates 1/in(reciprocal) value of Q15 Data type.
+ */
+ static __INLINE uint32_t arm_recip_q15(
+ q15_t in,
+ q15_t * dst,
+ q15_t * pRecipTable)
+ {
+
+ uint32_t out = 0, tempVal = 0;
+ uint32_t index = 0, i = 0;
+ uint32_t signBits = 0;
+
+ if(in > 0)
+ {
+ signBits = __CLZ(in) - 17;
+ }
+ else
+ {
+ signBits = __CLZ(-in) - 17;
+ }
+
+ /* Convert input sample to 1.15 format */
+ in = in << signBits;
+
+ /* calculation of index for initial approximated Val */
+ index = in >> 8;
+ index = (index & INDEX_MASK);
+
+ /* 1.15 with exp 1 */
+ out = pRecipTable[index];
+
+ /* calculation of reciprocal value */
+ /* running approximation for two iterations */
+ for (i = 0; i < 2; i++)
+ {
+ tempVal = (q15_t) (((q31_t) in * out) >> 15);
+ tempVal = 0x7FFF - tempVal;
+ /* 1.15 with exp 1 */
+ out = (q15_t) (((q31_t) out * tempVal) >> 14);
+ }
+
+ /* write output */
+ *dst = out;
+
+ /* return num of signbits of out = 1/in value */
+ return (signBits + 1);
+
+ }
+
+
+ /*
+ * @brief C custom defined intrinisic function for only M0 processors
+ */
+#if defined(ARM_MATH_CM0)
+
+ static __INLINE q31_t __SSAT(
+ q31_t x,
+ uint32_t y)
+ {
+ int32_t posMax, negMin;
+ uint32_t i;
+
+ posMax = 1;
+ for (i = 0; i < (y - 1); i++)
+ {
+ posMax = posMax * 2;
+ }
+
+ if(x > 0)
+ {
+ posMax = (posMax - 1);
+
+ if(x > posMax)
+ {
+ x = posMax;
+ }
+ }
+ else
+ {
+ negMin = -posMax;
+
+ if(x < negMin)
+ {
+ x = negMin;
+ }
+ }
+ return (x);
+
+
+ }
+
+#endif /* end of ARM_MATH_CM0 */
+
+
+
+ /*
+ * @brief C custom defined intrinsic function for M3 and M0 processors
+ */
+#if defined (ARM_MATH_CM3) || defined (ARM_MATH_CM0)
+
+ /*
+ * @brief C custom defined QADD8 for M3 and M0 processors
+ */
+ static __INLINE q31_t __QADD8(
+ q31_t x,
+ q31_t y)
+ {
+
+ q31_t sum;
+ q7_t r, s, t, u;
+
+ r = (char) x;
+ s = (char) y;
+
+ r = __SSAT((q31_t) (r + s), 8);
+ s = __SSAT(((q31_t) (((x << 16) >> 24) + ((y << 16) >> 24))), 8);
+ t = __SSAT(((q31_t) (((x << 8) >> 24) + ((y << 8) >> 24))), 8);
+ u = __SSAT(((q31_t) ((x >> 24) + (y >> 24))), 8);
+
+ sum = (((q31_t) u << 24) & 0xFF000000) | (((q31_t) t << 16) & 0x00FF0000) |
+ (((q31_t) s << 8) & 0x0000FF00) | (r & 0x000000FF);
+
+ return sum;
+
+ }
+
+ /*
+ * @brief C custom defined QSUB8 for M3 and M0 processors
+ */
+ static __INLINE q31_t __QSUB8(
+ q31_t x,
+ q31_t y)
+ {
+
+ q31_t sum;
+ q31_t r, s, t, u;
+
+ r = (char) x;
+ s = (char) y;
+
+ r = __SSAT((r - s), 8);
+ s = __SSAT(((q31_t) (((x << 16) >> 24) - ((y << 16) >> 24))), 8) << 8;
+ t = __SSAT(((q31_t) (((x << 8) >> 24) - ((y << 8) >> 24))), 8) << 16;
+ u = __SSAT(((q31_t) ((x >> 24) - (y >> 24))), 8) << 24;
+
+ sum =
+ (u & 0xFF000000) | (t & 0x00FF0000) | (s & 0x0000FF00) | (r & 0x000000FF);
+
+ return sum;
+ }
+
+ /*
+ * @brief C custom defined QADD16 for M3 and M0 processors
+ */
+
+ /*
+ * @brief C custom defined QADD16 for M3 and M0 processors
+ */
+ static __INLINE q31_t __QADD16(
+ q31_t x,
+ q31_t y)
+ {
+
+ q31_t sum;
+ q31_t r, s;
+
+ r = (short) x;
+ s = (short) y;
+
+ r = __SSAT(r + s, 16);
+ s = __SSAT(((q31_t) ((x >> 16) + (y >> 16))), 16) << 16;
+
+ sum = (s & 0xFFFF0000) | (r & 0x0000FFFF);
+
+ return sum;
+
+ }
+
+ /*
+ * @brief C custom defined SHADD16 for M3 and M0 processors
+ */
+ static __INLINE q31_t __SHADD16(
+ q31_t x,
+ q31_t y)
+ {
+
+ q31_t sum;
+ q31_t r, s;
+
+ r = (short) x;
+ s = (short) y;
+
+ r = ((r >> 1) + (s >> 1));
+ s = ((q31_t) ((x >> 17) + (y >> 17))) << 16;
+
+ sum = (s & 0xFFFF0000) | (r & 0x0000FFFF);
+
+ return sum;
+
+ }
+
+ /*
+ * @brief C custom defined QSUB16 for M3 and M0 processors
+ */
+ static __INLINE q31_t __QSUB16(
+ q31_t x,
+ q31_t y)
+ {
+
+ q31_t sum;
+ q31_t r, s;
+
+ r = (short) x;
+ s = (short) y;
+
+ r = __SSAT(r - s, 16);
+ s = __SSAT(((q31_t) ((x >> 16) - (y >> 16))), 16) << 16;
+
+ sum = (s & 0xFFFF0000) | (r & 0x0000FFFF);
+
+ return sum;
+ }
+
+ /*
+ * @brief C custom defined SHSUB16 for M3 and M0 processors
+ */
+ static __INLINE q31_t __SHSUB16(
+ q31_t x,
+ q31_t y)
+ {
+
+ q31_t diff;
+ q31_t r, s;
+
+ r = (short) x;
+ s = (short) y;
+
+ r = ((r >> 1) - (s >> 1));
+ s = (((x >> 17) - (y >> 17)) << 16);
+
+ diff = (s & 0xFFFF0000) | (r & 0x0000FFFF);
+
+ return diff;
+ }
+
+ /*
+ * @brief C custom defined QASX for M3 and M0 processors
+ */
+ static __INLINE q31_t __QASX(
+ q31_t x,
+ q31_t y)
+ {
+
+ q31_t sum = 0;
+
+ sum = ((sum + clip_q31_to_q15((q31_t) ((short) (x >> 16) + (short) y))) << 16) +
+ clip_q31_to_q15((q31_t) ((short) x - (short) (y >> 16)));
+
+ return sum;
+ }
+
+ /*
+ * @brief C custom defined SHASX for M3 and M0 processors
+ */
+ static __INLINE q31_t __SHASX(
+ q31_t x,
+ q31_t y)
+ {
+
+ q31_t sum;
+ q31_t r, s;
+
+ r = (short) x;
+ s = (short) y;
+
+ r = ((r >> 1) - (y >> 17));
+ s = (((x >> 17) + (s >> 1)) << 16);
+
+ sum = (s & 0xFFFF0000) | (r & 0x0000FFFF);
+
+ return sum;
+ }
+
+
+ /*
+ * @brief C custom defined QSAX for M3 and M0 processors
+ */
+ static __INLINE q31_t __QSAX(
+ q31_t x,
+ q31_t y)
+ {
+
+ q31_t sum = 0;
+
+ sum = ((sum + clip_q31_to_q15((q31_t) ((short) (x >> 16) - (short) y))) << 16) +
+ clip_q31_to_q15((q31_t) ((short) x + (short) (y >> 16)));
+
+ return sum;
+ }
+
+ /*
+ * @brief C custom defined SHSAX for M3 and M0 processors
+ */
+ static __INLINE q31_t __SHSAX(
+ q31_t x,
+ q31_t y)
+ {
+
+ q31_t sum;
+ q31_t r, s;
+
+ r = (short) x;
+ s = (short) y;
+
+ r = ((r >> 1) + (y >> 17));
+ s = (((x >> 17) - (s >> 1)) << 16);
+
+ sum = (s & 0xFFFF0000) | (r & 0x0000FFFF);
+
+ return sum;
+ }
+
+ /*
+ * @brief C custom defined SMUSDX for M3 and M0 processors
+ */
+ static __INLINE q31_t __SMUSDX(
+ q31_t x,
+ q31_t y)
+ {
+
+ return ((q31_t)(((short) x * (short) (y >> 16)) -
+ ((short) (x >> 16) * (short) y)));
+ }
+
+ /*
+ * @brief C custom defined SMUADX for M3 and M0 processors
+ */
+ static __INLINE q31_t __SMUADX(
+ q31_t x,
+ q31_t y)
+ {
+
+ return ((q31_t)(((short) x * (short) (y >> 16)) +
+ ((short) (x >> 16) * (short) y)));
+ }
+
+ /*
+ * @brief C custom defined QADD for M3 and M0 processors
+ */
+ static __INLINE q31_t __QADD(
+ q31_t x,
+ q31_t y)
+ {
+ return clip_q63_to_q31((q63_t) x + y);
+ }
+
+ /*
+ * @brief C custom defined QSUB for M3 and M0 processors
+ */
+ static __INLINE q31_t __QSUB(
+ q31_t x,
+ q31_t y)
+ {
+ return clip_q63_to_q31((q63_t) x - y);
+ }
+
+ /*
+ * @brief C custom defined SMLAD for M3 and M0 processors
+ */
+ static __INLINE q31_t __SMLAD(
+ q31_t x,
+ q31_t y,
+ q31_t sum)
+ {
+
+ return (sum + ((short) (x >> 16) * (short) (y >> 16)) +
+ ((short) x * (short) y));
+ }
+
+ /*
+ * @brief C custom defined SMLADX for M3 and M0 processors
+ */
+ static __INLINE q31_t __SMLADX(
+ q31_t x,
+ q31_t y,
+ q31_t sum)
+ {
+
+ return (sum + ((short) (x >> 16) * (short) (y)) +
+ ((short) x * (short) (y >> 16)));
+ }
+
+ /*
+ * @brief C custom defined SMLSDX for M3 and M0 processors
+ */
+ static __INLINE q31_t __SMLSDX(
+ q31_t x,
+ q31_t y,
+ q31_t sum)
+ {
+
+ return (sum - ((short) (x >> 16) * (short) (y)) +
+ ((short) x * (short) (y >> 16)));
+ }
+
+ /*
+ * @brief C custom defined SMLALD for M3 and M0 processors
+ */
+ static __INLINE q63_t __SMLALD(
+ q31_t x,
+ q31_t y,
+ q63_t sum)
+ {
+
+ return (sum + ((short) (x >> 16) * (short) (y >> 16)) +
+ ((short) x * (short) y));
+ }
+
+ /*
+ * @brief C custom defined SMLALDX for M3 and M0 processors
+ */
+ static __INLINE q63_t __SMLALDX(
+ q31_t x,
+ q31_t y,
+ q63_t sum)
+ {
+
+ return (sum + ((short) (x >> 16) * (short) y)) +
+ ((short) x * (short) (y >> 16));
+ }
+
+ /*
+ * @brief C custom defined SMUAD for M3 and M0 processors
+ */
+ static __INLINE q31_t __SMUAD(
+ q31_t x,
+ q31_t y)
+ {
+
+ return (((x >> 16) * (y >> 16)) +
+ (((x << 16) >> 16) * ((y << 16) >> 16)));
+ }
+
+ /*
+ * @brief C custom defined SMUSD for M3 and M0 processors
+ */
+ static __INLINE q31_t __SMUSD(
+ q31_t x,
+ q31_t y)
+ {
+
+ return (-((x >> 16) * (y >> 16)) +
+ (((x << 16) >> 16) * ((y << 16) >> 16)));
+ }
+
+
+
+
+#endif /* (ARM_MATH_CM3) || defined (ARM_MATH_CM0) */
+
+
+ /**
+ * @brief Instance structure for the Q7 FIR filter.
+ */
+ typedef struct
+ {
+ uint16_t numTaps; /**< number of filter coefficients in the filter. */
+ q7_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+ q7_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/
+ } arm_fir_instance_q7;
+
+ /**
+ * @brief Instance structure for the Q15 FIR filter.
+ */
+ typedef struct
+ {
+ uint16_t numTaps; /**< number of filter coefficients in the filter. */
+ q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+ q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/
+ } arm_fir_instance_q15;
+
+ /**
+ * @brief Instance structure for the Q31 FIR filter.
+ */
+ typedef struct
+ {
+ uint16_t numTaps; /**< number of filter coefficients in the filter. */
+ q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+ q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */
+ } arm_fir_instance_q31;
+
+ /**
+ * @brief Instance structure for the floating-point FIR filter.
+ */
+ typedef struct
+ {
+ uint16_t numTaps; /**< number of filter coefficients in the filter. */
+ float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+ float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */
+ } arm_fir_instance_f32;
+
+
+ /**
+ * @brief Processing function for the Q7 FIR filter.
+ * @param[in] *S points to an instance of the Q7 FIR filter structure.
+ * @param[in] *pSrc points to the block of input data.
+ * @param[out] *pDst points to the block of output data.
+ * @param[in] blockSize number of samples to process.
+ * @return none.
+ */
+ void arm_fir_q7(
+ const arm_fir_instance_q7 * S,
+ q7_t * pSrc,
+ q7_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Initialization function for the Q7 FIR filter.
+ * @param[in,out] *S points to an instance of the Q7 FIR structure.
+ * @param[in] numTaps Number of filter coefficients in the filter.
+ * @param[in] *pCoeffs points to the filter coefficients.
+ * @param[in] *pState points to the state buffer.
+ * @param[in] blockSize number of samples that are processed.
+ * @return none
+ */
+ void arm_fir_init_q7(
+ arm_fir_instance_q7 * S,
+ uint16_t numTaps,
+ q7_t * pCoeffs,
+ q7_t * pState,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Processing function for the Q15 FIR filter.
+ * @param[in] *S points to an instance of the Q15 FIR structure.
+ * @param[in] *pSrc points to the block of input data.
+ * @param[out] *pDst points to the block of output data.
+ * @param[in] blockSize number of samples to process.
+ * @return none.
+ */
+ void arm_fir_q15(
+ const arm_fir_instance_q15 * S,
+ q15_t * pSrc,
+ q15_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Processing function for the fast Q15 FIR filter for Cortex-M3 and Cortex-M4.
+ * @param[in] *S points to an instance of the Q15 FIR filter structure.
+ * @param[in] *pSrc points to the block of input data.
+ * @param[out] *pDst points to the block of output data.
+ * @param[in] blockSize number of samples to process.
+ * @return none.
+ */
+ void arm_fir_fast_q15(
+ const arm_fir_instance_q15 * S,
+ q15_t * pSrc,
+ q15_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Initialization function for the Q15 FIR filter.
+ * @param[in,out] *S points to an instance of the Q15 FIR filter structure.
+ * @param[in] numTaps Number of filter coefficients in the filter. Must be even and greater than or equal to 4.
+ * @param[in] *pCoeffs points to the filter coefficients.
+ * @param[in] *pState points to the state buffer.
+ * @param[in] blockSize number of samples that are processed at a time.
+ * @return The function returns ARM_MATH_SUCCESS if initialization was successful or ARM_MATH_ARGUMENT_ERROR if
+ * numTaps is not a supported value.
+ */
+
+ arm_status arm_fir_init_q15(
+ arm_fir_instance_q15 * S,
+ uint16_t numTaps,
+ q15_t * pCoeffs,
+ q15_t * pState,
+ uint32_t blockSize);
+
+ /**
+ * @brief Processing function for the Q31 FIR filter.
+ * @param[in] *S points to an instance of the Q31 FIR filter structure.
+ * @param[in] *pSrc points to the block of input data.
+ * @param[out] *pDst points to the block of output data.
+ * @param[in] blockSize number of samples to process.
+ * @return none.
+ */
+ void arm_fir_q31(
+ const arm_fir_instance_q31 * S,
+ q31_t * pSrc,
+ q31_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Processing function for the fast Q31 FIR filter for Cortex-M3 and Cortex-M4.
+ * @param[in] *S points to an instance of the Q31 FIR structure.
+ * @param[in] *pSrc points to the block of input data.
+ * @param[out] *pDst points to the block of output data.
+ * @param[in] blockSize number of samples to process.
+ * @return none.
+ */
+ void arm_fir_fast_q31(
+ const arm_fir_instance_q31 * S,
+ q31_t * pSrc,
+ q31_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Initialization function for the Q31 FIR filter.
+ * @param[in,out] *S points to an instance of the Q31 FIR structure.
+ * @param[in] numTaps Number of filter coefficients in the filter.
+ * @param[in] *pCoeffs points to the filter coefficients.
+ * @param[in] *pState points to the state buffer.
+ * @param[in] blockSize number of samples that are processed at a time.
+ * @return none.
+ */
+ void arm_fir_init_q31(
+ arm_fir_instance_q31 * S,
+ uint16_t numTaps,
+ q31_t * pCoeffs,
+ q31_t * pState,
+ uint32_t blockSize);
+
+ /**
+ * @brief Processing function for the floating-point FIR filter.
+ * @param[in] *S points to an instance of the floating-point FIR structure.
+ * @param[in] *pSrc points to the block of input data.
+ * @param[out] *pDst points to the block of output data.
+ * @param[in] blockSize number of samples to process.
+ * @return none.
+ */
+ void arm_fir_f32(
+ const arm_fir_instance_f32 * S,
+ float32_t * pSrc,
+ float32_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Initialization function for the floating-point FIR filter.
+ * @param[in,out] *S points to an instance of the floating-point FIR filter structure.
+ * @param[in] numTaps Number of filter coefficients in the filter.
+ * @param[in] *pCoeffs points to the filter coefficients.
+ * @param[in] *pState points to the state buffer.
+ * @param[in] blockSize number of samples that are processed at a time.
+ * @return none.
+ */
+ void arm_fir_init_f32(
+ arm_fir_instance_f32 * S,
+ uint16_t numTaps,
+ float32_t * pCoeffs,
+ float32_t * pState,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Instance structure for the Q15 Biquad cascade filter.
+ */
+ typedef struct
+ {
+ int8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */
+ q15_t *pState; /**< Points to the array of state coefficients. The array is of length 4*numStages. */
+ q15_t *pCoeffs; /**< Points to the array of coefficients. The array is of length 5*numStages. */
+ int8_t postShift; /**< Additional shift, in bits, applied to each output sample. */
+
+ } arm_biquad_casd_df1_inst_q15;
+
+
+ /**
+ * @brief Instance structure for the Q31 Biquad cascade filter.
+ */
+ typedef struct
+ {
+ uint32_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */
+ q31_t *pState; /**< Points to the array of state coefficients. The array is of length 4*numStages. */
+ q31_t *pCoeffs; /**< Points to the array of coefficients. The array is of length 5*numStages. */
+ uint8_t postShift; /**< Additional shift, in bits, applied to each output sample. */
+
+ } arm_biquad_casd_df1_inst_q31;
+
+ /**
+ * @brief Instance structure for the floating-point Biquad cascade filter.
+ */
+ typedef struct
+ {
+ uint32_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */
+ float32_t *pState; /**< Points to the array of state coefficients. The array is of length 4*numStages. */
+ float32_t *pCoeffs; /**< Points to the array of coefficients. The array is of length 5*numStages. */
+
+
+ } arm_biquad_casd_df1_inst_f32;
+
+
+
+ /**
+ * @brief Processing function for the Q15 Biquad cascade filter.
+ * @param[in] *S points to an instance of the Q15 Biquad cascade structure.
+ * @param[in] *pSrc points to the block of input data.
+ * @param[out] *pDst points to the block of output data.
+ * @param[in] blockSize number of samples to process.
+ * @return none.
+ */
+
+ void arm_biquad_cascade_df1_q15(
+ const arm_biquad_casd_df1_inst_q15 * S,
+ q15_t * pSrc,
+ q15_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Initialization function for the Q15 Biquad cascade filter.
+ * @param[in,out] *S points to an instance of the Q15 Biquad cascade structure.
+ * @param[in] numStages number of 2nd order stages in the filter.
+ * @param[in] *pCoeffs points to the filter coefficients.
+ * @param[in] *pState points to the state buffer.
+ * @param[in] postShift Shift to be applied to the output. Varies according to the coefficients format
+ * @return none
+ */
+
+ void arm_biquad_cascade_df1_init_q15(
+ arm_biquad_casd_df1_inst_q15 * S,
+ uint8_t numStages,
+ q15_t * pCoeffs,
+ q15_t * pState,
+ int8_t postShift);
+
+
+ /**
+ * @brief Fast but less precise processing function for the Q15 Biquad cascade filter for Cortex-M3 and Cortex-M4.
+ * @param[in] *S points to an instance of the Q15 Biquad cascade structure.
+ * @param[in] *pSrc points to the block of input data.
+ * @param[out] *pDst points to the block of output data.
+ * @param[in] blockSize number of samples to process.
+ * @return none.
+ */
+
+ void arm_biquad_cascade_df1_fast_q15(
+ const arm_biquad_casd_df1_inst_q15 * S,
+ q15_t * pSrc,
+ q15_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Processing function for the Q31 Biquad cascade filter
+ * @param[in] *S points to an instance of the Q31 Biquad cascade structure.
+ * @param[in] *pSrc points to the block of input data.
+ * @param[out] *pDst points to the block of output data.
+ * @param[in] blockSize number of samples to process.
+ * @return none.
+ */
+
+ void arm_biquad_cascade_df1_q31(
+ const arm_biquad_casd_df1_inst_q31 * S,
+ q31_t * pSrc,
+ q31_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Fast but less precise processing function for the Q31 Biquad cascade filter for Cortex-M3 and Cortex-M4.
+ * @param[in] *S points to an instance of the Q31 Biquad cascade structure.
+ * @param[in] *pSrc points to the block of input data.
+ * @param[out] *pDst points to the block of output data.
+ * @param[in] blockSize number of samples to process.
+ * @return none.
+ */
+
+ void arm_biquad_cascade_df1_fast_q31(
+ const arm_biquad_casd_df1_inst_q31 * S,
+ q31_t * pSrc,
+ q31_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Initialization function for the Q31 Biquad cascade filter.
+ * @param[in,out] *S points to an instance of the Q31 Biquad cascade structure.
+ * @param[in] numStages number of 2nd order stages in the filter.
+ * @param[in] *pCoeffs points to the filter coefficients.
+ * @param[in] *pState points to the state buffer.
+ * @param[in] postShift Shift to be applied to the output. Varies according to the coefficients format
+ * @return none
+ */
+
+ void arm_biquad_cascade_df1_init_q31(
+ arm_biquad_casd_df1_inst_q31 * S,
+ uint8_t numStages,
+ q31_t * pCoeffs,
+ q31_t * pState,
+ int8_t postShift);
+
+ /**
+ * @brief Processing function for the floating-point Biquad cascade filter.
+ * @param[in] *S points to an instance of the floating-point Biquad cascade structure.
+ * @param[in] *pSrc points to the block of input data.
+ * @param[out] *pDst points to the block of output data.
+ * @param[in] blockSize number of samples to process.
+ * @return none.
+ */
+
+ void arm_biquad_cascade_df1_f32(
+ const arm_biquad_casd_df1_inst_f32 * S,
+ float32_t * pSrc,
+ float32_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Initialization function for the floating-point Biquad cascade filter.
+ * @param[in,out] *S points to an instance of the floating-point Biquad cascade structure.
+ * @param[in] numStages number of 2nd order stages in the filter.
+ * @param[in] *pCoeffs points to the filter coefficients.
+ * @param[in] *pState points to the state buffer.
+ * @return none
+ */
+
+ void arm_biquad_cascade_df1_init_f32(
+ arm_biquad_casd_df1_inst_f32 * S,
+ uint8_t numStages,
+ float32_t * pCoeffs,
+ float32_t * pState);
+
+
+ /**
+ * @brief Instance structure for the floating-point matrix structure.
+ */
+
+ typedef struct
+ {
+ uint16_t numRows; /**< number of rows of the matrix. */
+ uint16_t numCols; /**< number of columns of the matrix. */
+ float32_t *pData; /**< points to the data of the matrix. */
+ } arm_matrix_instance_f32;
+
+ /**
+ * @brief Instance structure for the Q15 matrix structure.
+ */
+
+ typedef struct
+ {
+ uint16_t numRows; /**< number of rows of the matrix. */
+ uint16_t numCols; /**< number of columns of the matrix. */
+ q15_t *pData; /**< points to the data of the matrix. */
+
+ } arm_matrix_instance_q15;
+
+ /**
+ * @brief Instance structure for the Q31 matrix structure.
+ */
+
+ typedef struct
+ {
+ uint16_t numRows; /**< number of rows of the matrix. */
+ uint16_t numCols; /**< number of columns of the matrix. */
+ q31_t *pData; /**< points to the data of the matrix. */
+
+ } arm_matrix_instance_q31;
+
+
+
+ /**
+ * @brief Floating-point matrix addition.
+ * @param[in] *pSrcA points to the first input matrix structure
+ * @param[in] *pSrcB points to the second input matrix structure
+ * @param[out] *pDst points to output matrix structure
+ * @return The function returns either
+ * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking.
+ */
+
+ arm_status arm_mat_add_f32(
+ const arm_matrix_instance_f32 * pSrcA,
+ const arm_matrix_instance_f32 * pSrcB,
+ arm_matrix_instance_f32 * pDst);
+
+ /**
+ * @brief Q15 matrix addition.
+ * @param[in] *pSrcA points to the first input matrix structure
+ * @param[in] *pSrcB points to the second input matrix structure
+ * @param[out] *pDst points to output matrix structure
+ * @return The function returns either
+ * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking.
+ */
+
+ arm_status arm_mat_add_q15(
+ const arm_matrix_instance_q15 * pSrcA,
+ const arm_matrix_instance_q15 * pSrcB,
+ arm_matrix_instance_q15 * pDst);
+
+ /**
+ * @brief Q31 matrix addition.
+ * @param[in] *pSrcA points to the first input matrix structure
+ * @param[in] *pSrcB points to the second input matrix structure
+ * @param[out] *pDst points to output matrix structure
+ * @return The function returns either
+ * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking.
+ */
+
+ arm_status arm_mat_add_q31(
+ const arm_matrix_instance_q31 * pSrcA,
+ const arm_matrix_instance_q31 * pSrcB,
+ arm_matrix_instance_q31 * pDst);
+
+
+ /**
+ * @brief Floating-point matrix transpose.
+ * @param[in] *pSrc points to the input matrix
+ * @param[out] *pDst points to the output matrix
+ * @return The function returns either ARM_MATH_SIZE_MISMATCH
+ * or ARM_MATH_SUCCESS based on the outcome of size checking.
+ */
+
+ arm_status arm_mat_trans_f32(
+ const arm_matrix_instance_f32 * pSrc,
+ arm_matrix_instance_f32 * pDst);
+
+
+ /**
+ * @brief Q15 matrix transpose.
+ * @param[in] *pSrc points to the input matrix
+ * @param[out] *pDst points to the output matrix
+ * @return The function returns either ARM_MATH_SIZE_MISMATCH
+ * or ARM_MATH_SUCCESS based on the outcome of size checking.
+ */
+
+ arm_status arm_mat_trans_q15(
+ const arm_matrix_instance_q15 * pSrc,
+ arm_matrix_instance_q15 * pDst);
+
+ /**
+ * @brief Q31 matrix transpose.
+ * @param[in] *pSrc points to the input matrix
+ * @param[out] *pDst points to the output matrix
+ * @return The function returns either ARM_MATH_SIZE_MISMATCH
+ * or ARM_MATH_SUCCESS based on the outcome of size checking.
+ */
+
+ arm_status arm_mat_trans_q31(
+ const arm_matrix_instance_q31 * pSrc,
+ arm_matrix_instance_q31 * pDst);
+
+
+ /**
+ * @brief Floating-point matrix multiplication
+ * @param[in] *pSrcA points to the first input matrix structure
+ * @param[in] *pSrcB points to the second input matrix structure
+ * @param[out] *pDst points to output matrix structure
+ * @return The function returns either
+ * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking.
+ */
+
+ arm_status arm_mat_mult_f32(
+ const arm_matrix_instance_f32 * pSrcA,
+ const arm_matrix_instance_f32 * pSrcB,
+ arm_matrix_instance_f32 * pDst);
+
+ /**
+ * @brief Q15 matrix multiplication
+ * @param[in] *pSrcA points to the first input matrix structure
+ * @param[in] *pSrcB points to the second input matrix structure
+ * @param[out] *pDst points to output matrix structure
+ * @return The function returns either
+ * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking.
+ */
+
+ arm_status arm_mat_mult_q15(
+ const arm_matrix_instance_q15 * pSrcA,
+ const arm_matrix_instance_q15 * pSrcB,
+ arm_matrix_instance_q15 * pDst,
+ q15_t * pState);
+
+ /**
+ * @brief Q15 matrix multiplication (fast variant) for Cortex-M3 and Cortex-M4
+ * @param[in] *pSrcA points to the first input matrix structure
+ * @param[in] *pSrcB points to the second input matrix structure
+ * @param[out] *pDst points to output matrix structure
+ * @param[in] *pState points to the array for storing intermediate results
+ * @return The function returns either
+ * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking.
+ */
+
+ arm_status arm_mat_mult_fast_q15(
+ const arm_matrix_instance_q15 * pSrcA,
+ const arm_matrix_instance_q15 * pSrcB,
+ arm_matrix_instance_q15 * pDst,
+ q15_t * pState);
+
+ /**
+ * @brief Q31 matrix multiplication
+ * @param[in] *pSrcA points to the first input matrix structure
+ * @param[in] *pSrcB points to the second input matrix structure
+ * @param[out] *pDst points to output matrix structure
+ * @return The function returns either
+ * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking.
+ */
+
+ arm_status arm_mat_mult_q31(
+ const arm_matrix_instance_q31 * pSrcA,
+ const arm_matrix_instance_q31 * pSrcB,
+ arm_matrix_instance_q31 * pDst);
+
+ /**
+ * @brief Q31 matrix multiplication (fast variant) for Cortex-M3 and Cortex-M4
+ * @param[in] *pSrcA points to the first input matrix structure
+ * @param[in] *pSrcB points to the second input matrix structure
+ * @param[out] *pDst points to output matrix structure
+ * @return The function returns either
+ * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking.
+ */
+
+ arm_status arm_mat_mult_fast_q31(
+ const arm_matrix_instance_q31 * pSrcA,
+ const arm_matrix_instance_q31 * pSrcB,
+ arm_matrix_instance_q31 * pDst);
+
+
+ /**
+ * @brief Floating-point matrix subtraction
+ * @param[in] *pSrcA points to the first input matrix structure
+ * @param[in] *pSrcB points to the second input matrix structure
+ * @param[out] *pDst points to output matrix structure
+ * @return The function returns either
+ * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking.
+ */
+
+ arm_status arm_mat_sub_f32(
+ const arm_matrix_instance_f32 * pSrcA,
+ const arm_matrix_instance_f32 * pSrcB,
+ arm_matrix_instance_f32 * pDst);
+
+ /**
+ * @brief Q15 matrix subtraction
+ * @param[in] *pSrcA points to the first input matrix structure
+ * @param[in] *pSrcB points to the second input matrix structure
+ * @param[out] *pDst points to output matrix structure
+ * @return The function returns either
+ * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking.
+ */
+
+ arm_status arm_mat_sub_q15(
+ const arm_matrix_instance_q15 * pSrcA,
+ const arm_matrix_instance_q15 * pSrcB,
+ arm_matrix_instance_q15 * pDst);
+
+ /**
+ * @brief Q31 matrix subtraction
+ * @param[in] *pSrcA points to the first input matrix structure
+ * @param[in] *pSrcB points to the second input matrix structure
+ * @param[out] *pDst points to output matrix structure
+ * @return The function returns either
+ * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking.
+ */
+
+ arm_status arm_mat_sub_q31(
+ const arm_matrix_instance_q31 * pSrcA,
+ const arm_matrix_instance_q31 * pSrcB,
+ arm_matrix_instance_q31 * pDst);
+
+ /**
+ * @brief Floating-point matrix scaling.
+ * @param[in] *pSrc points to the input matrix
+ * @param[in] scale scale factor
+ * @param[out] *pDst points to the output matrix
+ * @return The function returns either
+ * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking.
+ */
+
+ arm_status arm_mat_scale_f32(
+ const arm_matrix_instance_f32 * pSrc,
+ float32_t scale,
+ arm_matrix_instance_f32 * pDst);
+
+ /**
+ * @brief Q15 matrix scaling.
+ * @param[in] *pSrc points to input matrix
+ * @param[in] scaleFract fractional portion of the scale factor
+ * @param[in] shift number of bits to shift the result by
+ * @param[out] *pDst points to output matrix
+ * @return The function returns either
+ * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking.
+ */
+
+ arm_status arm_mat_scale_q15(
+ const arm_matrix_instance_q15 * pSrc,
+ q15_t scaleFract,
+ int32_t shift,
+ arm_matrix_instance_q15 * pDst);
+
+ /**
+ * @brief Q31 matrix scaling.
+ * @param[in] *pSrc points to input matrix
+ * @param[in] scaleFract fractional portion of the scale factor
+ * @param[in] shift number of bits to shift the result by
+ * @param[out] *pDst points to output matrix structure
+ * @return The function returns either
+ * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking.
+ */
+
+ arm_status arm_mat_scale_q31(
+ const arm_matrix_instance_q31 * pSrc,
+ q31_t scaleFract,
+ int32_t shift,
+ arm_matrix_instance_q31 * pDst);
+
+
+ /**
+ * @brief Q31 matrix initialization.
+ * @param[in,out] *S points to an instance of the floating-point matrix structure.
+ * @param[in] nRows number of rows in the matrix.
+ * @param[in] nColumns number of columns in the matrix.
+ * @param[in] *pData points to the matrix data array.
+ * @return none
+ */
+
+ void arm_mat_init_q31(
+ arm_matrix_instance_q31 * S,
+ uint16_t nRows,
+ uint16_t nColumns,
+ q31_t *pData);
+
+ /**
+ * @brief Q15 matrix initialization.
+ * @param[in,out] *S points to an instance of the floating-point matrix structure.
+ * @param[in] nRows number of rows in the matrix.
+ * @param[in] nColumns number of columns in the matrix.
+ * @param[in] *pData points to the matrix data array.
+ * @return none
+ */
+
+ void arm_mat_init_q15(
+ arm_matrix_instance_q15 * S,
+ uint16_t nRows,
+ uint16_t nColumns,
+ q15_t *pData);
+
+ /**
+ * @brief Floating-point matrix initialization.
+ * @param[in,out] *S points to an instance of the floating-point matrix structure.
+ * @param[in] nRows number of rows in the matrix.
+ * @param[in] nColumns number of columns in the matrix.
+ * @param[in] *pData points to the matrix data array.
+ * @return none
+ */
+
+ void arm_mat_init_f32(
+ arm_matrix_instance_f32 * S,
+ uint16_t nRows,
+ uint16_t nColumns,
+ float32_t *pData);
+
+
+
+ /**
+ * @brief Instance structure for the Q15 PID Control.
+ */
+ typedef struct
+ {
+ q15_t A0; /**< The derived gain, A0 = Kp + Ki + Kd . */
+ #ifdef ARM_MATH_CM0
+ q15_t A1;
+ q15_t A2;
+ #else
+ q31_t A1; /**< The derived gain A1 = -Kp - 2Kd | Kd.*/
+ #endif
+ q15_t state[3]; /**< The state array of length 3. */
+ q15_t Kp; /**< The proportional gain. */
+ q15_t Ki; /**< The integral gain. */
+ q15_t Kd; /**< The derivative gain. */
+ } arm_pid_instance_q15;
+
+ /**
+ * @brief Instance structure for the Q31 PID Control.
+ */
+ typedef struct
+ {
+ q31_t A0; /**< The derived gain, A0 = Kp + Ki + Kd . */
+ q31_t A1; /**< The derived gain, A1 = -Kp - 2Kd. */
+ q31_t A2; /**< The derived gain, A2 = Kd . */
+ q31_t state[3]; /**< The state array of length 3. */
+ q31_t Kp; /**< The proportional gain. */
+ q31_t Ki; /**< The integral gain. */
+ q31_t Kd; /**< The derivative gain. */
+
+ } arm_pid_instance_q31;
+
+ /**
+ * @brief Instance structure for the floating-point PID Control.
+ */
+ typedef struct
+ {
+ float32_t A0; /**< The derived gain, A0 = Kp + Ki + Kd . */
+ float32_t A1; /**< The derived gain, A1 = -Kp - 2Kd. */
+ float32_t A2; /**< The derived gain, A2 = Kd . */
+ float32_t state[3]; /**< The state array of length 3. */
+ float32_t Kp; /**< The proportional gain. */
+ float32_t Ki; /**< The integral gain. */
+ float32_t Kd; /**< The derivative gain. */
+ } arm_pid_instance_f32;
+
+
+
+ /**
+ * @brief Initialization function for the floating-point PID Control.
+ * @param[in,out] *S points to an instance of the PID structure.
+ * @param[in] resetStateFlag flag to reset the state. 0 = no change in state 1 = reset the state.
+ * @return none.
+ */
+ void arm_pid_init_f32(
+ arm_pid_instance_f32 * S,
+ int32_t resetStateFlag);
+
+ /**
+ * @brief Reset function for the floating-point PID Control.
+ * @param[in,out] *S is an instance of the floating-point PID Control structure
+ * @return none
+ */
+ void arm_pid_reset_f32(
+ arm_pid_instance_f32 * S);
+
+
+ /**
+ * @brief Initialization function for the Q31 PID Control.
+ * @param[in,out] *S points to an instance of the Q15 PID structure.
+ * @param[in] resetStateFlag flag to reset the state. 0 = no change in state 1 = reset the state.
+ * @return none.
+ */
+ void arm_pid_init_q31(
+ arm_pid_instance_q31 * S,
+ int32_t resetStateFlag);
+
+
+ /**
+ * @brief Reset function for the Q31 PID Control.
+ * @param[in,out] *S points to an instance of the Q31 PID Control structure
+ * @return none
+ */
+
+ void arm_pid_reset_q31(
+ arm_pid_instance_q31 * S);
+
+ /**
+ * @brief Initialization function for the Q15 PID Control.
+ * @param[in,out] *S points to an instance of the Q15 PID structure.
+ * @param[in] resetStateFlag flag to reset the state. 0 = no change in state 1 = reset the state.
+ * @return none.
+ */
+ void arm_pid_init_q15(
+ arm_pid_instance_q15 * S,
+ int32_t resetStateFlag);
+
+ /**
+ * @brief Reset function for the Q15 PID Control.
+ * @param[in,out] *S points to an instance of the q15 PID Control structure
+ * @return none
+ */
+ void arm_pid_reset_q15(
+ arm_pid_instance_q15 * S);
+
+
+ /**
+ * @brief Instance structure for the floating-point Linear Interpolate function.
+ */
+ typedef struct
+ {
+ uint32_t nValues;
+ float32_t x1;
+ float32_t xSpacing;
+ float32_t *pYData; /**< pointer to the table of Y values */
+ } arm_linear_interp_instance_f32;
+
+ /**
+ * @brief Instance structure for the floating-point bilinear interpolation function.
+ */
+
+ typedef struct
+ {
+ uint16_t numRows; /**< number of rows in the data table. */
+ uint16_t numCols; /**< number of columns in the data table. */
+ float32_t *pData; /**< points to the data table. */
+ } arm_bilinear_interp_instance_f32;
+
+ /**
+ * @brief Instance structure for the Q31 bilinear interpolation function.
+ */
+
+ typedef struct
+ {
+ uint16_t numRows; /**< number of rows in the data table. */
+ uint16_t numCols; /**< number of columns in the data table. */
+ q31_t *pData; /**< points to the data table. */
+ } arm_bilinear_interp_instance_q31;
+
+ /**
+ * @brief Instance structure for the Q15 bilinear interpolation function.
+ */
+
+ typedef struct
+ {
+ uint16_t numRows; /**< number of rows in the data table. */
+ uint16_t numCols; /**< number of columns in the data table. */
+ q15_t *pData; /**< points to the data table. */
+ } arm_bilinear_interp_instance_q15;
+
+ /**
+ * @brief Instance structure for the Q15 bilinear interpolation function.
+ */
+
+ typedef struct
+ {
+ uint16_t numRows; /**< number of rows in the data table. */
+ uint16_t numCols; /**< number of columns in the data table. */
+ q7_t *pData; /**< points to the data table. */
+ } arm_bilinear_interp_instance_q7;
+
+
+ /**
+ * @brief Q7 vector multiplication.
+ * @param[in] *pSrcA points to the first input vector
+ * @param[in] *pSrcB points to the second input vector
+ * @param[out] *pDst points to the output vector
+ * @param[in] blockSize number of samples in each vector
+ * @return none.
+ */
+
+ void arm_mult_q7(
+ q7_t * pSrcA,
+ q7_t * pSrcB,
+ q7_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Q15 vector multiplication.
+ * @param[in] *pSrcA points to the first input vector
+ * @param[in] *pSrcB points to the second input vector
+ * @param[out] *pDst points to the output vector
+ * @param[in] blockSize number of samples in each vector
+ * @return none.
+ */
+
+ void arm_mult_q15(
+ q15_t * pSrcA,
+ q15_t * pSrcB,
+ q15_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Q31 vector multiplication.
+ * @param[in] *pSrcA points to the first input vector
+ * @param[in] *pSrcB points to the second input vector
+ * @param[out] *pDst points to the output vector
+ * @param[in] blockSize number of samples in each vector
+ * @return none.
+ */
+
+ void arm_mult_q31(
+ q31_t * pSrcA,
+ q31_t * pSrcB,
+ q31_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Floating-point vector multiplication.
+ * @param[in] *pSrcA points to the first input vector
+ * @param[in] *pSrcB points to the second input vector
+ * @param[out] *pDst points to the output vector
+ * @param[in] blockSize number of samples in each vector
+ * @return none.
+ */
+
+ void arm_mult_f32(
+ float32_t * pSrcA,
+ float32_t * pSrcB,
+ float32_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Instance structure for the Q15 CFFT/CIFFT function.
+ */
+
+ typedef struct
+ {
+ uint16_t fftLen; /**< length of the FFT. */
+ uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */
+ uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */
+ q15_t *pTwiddle; /**< points to the twiddle factor table. */
+ uint16_t *pBitRevTable; /**< points to the bit reversal table. */
+ uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */
+ uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */
+ } arm_cfft_radix4_instance_q15;
+
+ /**
+ * @brief Instance structure for the Q31 CFFT/CIFFT function.
+ */
+
+ typedef struct
+ {
+ uint16_t fftLen; /**< length of the FFT. */
+ uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */
+ uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */
+ q31_t *pTwiddle; /**< points to the twiddle factor table. */
+ uint16_t *pBitRevTable; /**< points to the bit reversal table. */
+ uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */
+ uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */
+ } arm_cfft_radix4_instance_q31;
+
+ /**
+ * @brief Instance structure for the floating-point CFFT/CIFFT function.
+ */
+
+ typedef struct
+ {
+ uint16_t fftLen; /**< length of the FFT. */
+ uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */
+ uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */
+ float32_t *pTwiddle; /**< points to the twiddle factor table. */
+ uint16_t *pBitRevTable; /**< points to the bit reversal table. */
+ uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */
+ uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */
+ float32_t onebyfftLen; /**< value of 1/fftLen. */
+ } arm_cfft_radix4_instance_f32;
+
+ /**
+ * @brief Processing function for the Q15 CFFT/CIFFT.
+ * @param[in] *S points to an instance of the Q15 CFFT/CIFFT structure.
+ * @param[in, out] *pSrc points to the complex data buffer. Processing occurs in-place.
+ * @return none.
+ */
+
+ void arm_cfft_radix4_q15(
+ const arm_cfft_radix4_instance_q15 * S,
+ q15_t * pSrc);
+
+ /**
+ * @brief Initialization function for the Q15 CFFT/CIFFT.
+ * @param[in,out] *S points to an instance of the Q15 CFFT/CIFFT structure.
+ * @param[in] fftLen length of the FFT.
+ * @param[in] ifftFlag flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform.
+ * @param[in] bitReverseFlag flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output.
+ * @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if fftLen is not a supported value.
+ */
+
+ arm_status arm_cfft_radix4_init_q15(
+ arm_cfft_radix4_instance_q15 * S,
+ uint16_t fftLen,
+ uint8_t ifftFlag,
+ uint8_t bitReverseFlag);
+
+ /**
+ * @brief Processing function for the Q31 CFFT/CIFFT.
+ * @param[in] *S points to an instance of the Q31 CFFT/CIFFT structure.
+ * @param[in, out] *pSrc points to the complex data buffer. Processing occurs in-place.
+ * @return none.
+ */
+
+ void arm_cfft_radix4_q31(
+ const arm_cfft_radix4_instance_q31 * S,
+ q31_t * pSrc);
+
+ /**
+ * @brief Initialization function for the Q31 CFFT/CIFFT.
+ * @param[in,out] *S points to an instance of the Q31 CFFT/CIFFT structure.
+ * @param[in] fftLen length of the FFT.
+ * @param[in] ifftFlag flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform.
+ * @param[in] bitReverseFlag flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output.
+ * @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if fftLen is not a supported value.
+ */
+
+ arm_status arm_cfft_radix4_init_q31(
+ arm_cfft_radix4_instance_q31 * S,
+ uint16_t fftLen,
+ uint8_t ifftFlag,
+ uint8_t bitReverseFlag);
+
+ /**
+ * @brief Processing function for the floating-point CFFT/CIFFT.
+ * @param[in] *S points to an instance of the floating-point CFFT/CIFFT structure.
+ * @param[in, out] *pSrc points to the complex data buffer. Processing occurs in-place.
+ * @return none.
+ */
+
+ void arm_cfft_radix4_f32(
+ const arm_cfft_radix4_instance_f32 * S,
+ float32_t * pSrc);
+
+ /**
+ * @brief Initialization function for the floating-point CFFT/CIFFT.
+ * @param[in,out] *S points to an instance of the floating-point CFFT/CIFFT structure.
+ * @param[in] fftLen length of the FFT.
+ * @param[in] ifftFlag flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform.
+ * @param[in] bitReverseFlag flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output.
+ * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if fftLen is not a supported value.
+ */
+
+ arm_status arm_cfft_radix4_init_f32(
+ arm_cfft_radix4_instance_f32 * S,
+ uint16_t fftLen,
+ uint8_t ifftFlag,
+ uint8_t bitReverseFlag);
+
+
+
+ /*----------------------------------------------------------------------
+ * Internal functions prototypes FFT function
+ ----------------------------------------------------------------------*/
+
+ /**
+ * @brief Core function for the floating-point CFFT butterfly process.
+ * @param[in, out] *pSrc points to the in-place buffer of floating-point data type.
+ * @param[in] fftLen length of the FFT.
+ * @param[in] *pCoef points to the twiddle coefficient buffer.
+ * @param[in] twidCoefModifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table.
+ * @return none.
+ */
+
+ void arm_radix4_butterfly_f32(
+ float32_t * pSrc,
+ uint16_t fftLen,
+ float32_t * pCoef,
+ uint16_t twidCoefModifier);
+
+ /**
+ * @brief Core function for the floating-point CIFFT butterfly process.
+ * @param[in, out] *pSrc points to the in-place buffer of floating-point data type.
+ * @param[in] fftLen length of the FFT.
+ * @param[in] *pCoef points to twiddle coefficient buffer.
+ * @param[in] twidCoefModifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table.
+ * @param[in] onebyfftLen value of 1/fftLen.
+ * @return none.
+ */
+
+ void arm_radix4_butterfly_inverse_f32(
+ float32_t * pSrc,
+ uint16_t fftLen,
+ float32_t * pCoef,
+ uint16_t twidCoefModifier,
+ float32_t onebyfftLen);
+
+ /**
+ * @brief In-place bit reversal function.
+ * @param[in, out] *pSrc points to the in-place buffer of floating-point data type.
+ * @param[in] fftSize length of the FFT.
+ * @param[in] bitRevFactor bit reversal modifier that supports different size FFTs with the same bit reversal table.
+ * @param[in] *pBitRevTab points to the bit reversal table.
+ * @return none.
+ */
+
+ void arm_bitreversal_f32(
+ float32_t *pSrc,
+ uint16_t fftSize,
+ uint16_t bitRevFactor,
+ uint16_t *pBitRevTab);
+
+ /**
+ * @brief Core function for the Q31 CFFT butterfly process.
+ * @param[in, out] *pSrc points to the in-place buffer of Q31 data type.
+ * @param[in] fftLen length of the FFT.
+ * @param[in] *pCoef points to twiddle coefficient buffer.
+ * @param[in] twidCoefModifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table.
+ * @return none.
+ */
+
+ void arm_radix4_butterfly_q31(
+ q31_t *pSrc,
+ uint32_t fftLen,
+ q31_t *pCoef,
+ uint32_t twidCoefModifier);
+
+ /**
+ * @brief Core function for the Q31 CIFFT butterfly process.
+ * @param[in, out] *pSrc points to the in-place buffer of Q31 data type.
+ * @param[in] fftLen length of the FFT.
+ * @param[in] *pCoef points to twiddle coefficient buffer.
+ * @param[in] twidCoefModifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table.
+ * @return none.
+ */
+
+ void arm_radix4_butterfly_inverse_q31(
+ q31_t * pSrc,
+ uint32_t fftLen,
+ q31_t * pCoef,
+ uint32_t twidCoefModifier);
+
+ /**
+ * @brief In-place bit reversal function.
+ * @param[in, out] *pSrc points to the in-place buffer of Q31 data type.
+ * @param[in] fftLen length of the FFT.
+ * @param[in] bitRevFactor bit reversal modifier that supports different size FFTs with the same bit reversal table
+ * @param[in] *pBitRevTab points to bit reversal table.
+ * @return none.
+ */
+
+ void arm_bitreversal_q31(
+ q31_t * pSrc,
+ uint32_t fftLen,
+ uint16_t bitRevFactor,
+ uint16_t *pBitRevTab);
+
+ /**
+ * @brief Core function for the Q15 CFFT butterfly process.
+ * @param[in, out] *pSrc16 points to the in-place buffer of Q15 data type.
+ * @param[in] fftLen length of the FFT.
+ * @param[in] *pCoef16 points to twiddle coefficient buffer.
+ * @param[in] twidCoefModifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table.
+ * @return none.
+ */
+
+ void arm_radix4_butterfly_q15(
+ q15_t *pSrc16,
+ uint32_t fftLen,
+ q15_t *pCoef16,
+ uint32_t twidCoefModifier);
+
+ /**
+ * @brief Core function for the Q15 CIFFT butterfly process.
+ * @param[in, out] *pSrc16 points to the in-place buffer of Q15 data type.
+ * @param[in] fftLen length of the FFT.
+ * @param[in] *pCoef16 points to twiddle coefficient buffer.
+ * @param[in] twidCoefModifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table.
+ * @return none.
+ */
+
+ void arm_radix4_butterfly_inverse_q15(
+ q15_t *pSrc16,
+ uint32_t fftLen,
+ q15_t *pCoef16,
+ uint32_t twidCoefModifier);
+
+ /**
+ * @brief In-place bit reversal function.
+ * @param[in, out] *pSrc points to the in-place buffer of Q15 data type.
+ * @param[in] fftLen length of the FFT.
+ * @param[in] bitRevFactor bit reversal modifier that supports different size FFTs with the same bit reversal table
+ * @param[in] *pBitRevTab points to bit reversal table.
+ * @return none.
+ */
+
+ void arm_bitreversal_q15(
+ q15_t * pSrc,
+ uint32_t fftLen,
+ uint16_t bitRevFactor,
+ uint16_t *pBitRevTab);
+
+ /**
+ * @brief Instance structure for the Q15 RFFT/RIFFT function.
+ */
+
+ typedef struct
+ {
+ uint32_t fftLenReal; /**< length of the real FFT. */
+ uint32_t fftLenBy2; /**< length of the complex FFT. */
+ uint8_t ifftFlagR; /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */
+ uint8_t bitReverseFlagR; /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */
+ uint32_t twidCoefRModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */
+ q15_t *pTwiddleAReal; /**< points to the real twiddle factor table. */
+ q15_t *pTwiddleBReal; /**< points to the imag twiddle factor table. */
+ arm_cfft_radix4_instance_q15 *pCfft; /**< points to the complex FFT instance. */
+ } arm_rfft_instance_q15;
+
+ /**
+ * @brief Instance structure for the Q31 RFFT/RIFFT function.
+ */
+
+ typedef struct
+ {
+ uint32_t fftLenReal; /**< length of the real FFT. */
+ uint32_t fftLenBy2; /**< length of the complex FFT. */
+ uint8_t ifftFlagR; /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */
+ uint8_t bitReverseFlagR; /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */
+ uint32_t twidCoefRModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */
+ q31_t *pTwiddleAReal; /**< points to the real twiddle factor table. */
+ q31_t *pTwiddleBReal; /**< points to the imag twiddle factor table. */
+ arm_cfft_radix4_instance_q31 *pCfft; /**< points to the complex FFT instance. */
+ } arm_rfft_instance_q31;
+
+ /**
+ * @brief Instance structure for the floating-point RFFT/RIFFT function.
+ */
+
+ typedef struct
+ {
+ uint32_t fftLenReal; /**< length of the real FFT. */
+ uint16_t fftLenBy2; /**< length of the complex FFT. */
+ uint8_t ifftFlagR; /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */
+ uint8_t bitReverseFlagR; /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */
+ uint32_t twidCoefRModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */
+ float32_t *pTwiddleAReal; /**< points to the real twiddle factor table. */
+ float32_t *pTwiddleBReal; /**< points to the imag twiddle factor table. */
+ arm_cfft_radix4_instance_f32 *pCfft; /**< points to the complex FFT instance. */
+ } arm_rfft_instance_f32;
+
+ /**
+ * @brief Processing function for the Q15 RFFT/RIFFT.
+ * @param[in] *S points to an instance of the Q15 RFFT/RIFFT structure.
+ * @param[in] *pSrc points to the input buffer.
+ * @param[out] *pDst points to the output buffer.
+ * @return none.
+ */
+
+ void arm_rfft_q15(
+ const arm_rfft_instance_q15 * S,
+ q15_t * pSrc,
+ q15_t * pDst);
+
+ /**
+ * @brief Initialization function for the Q15 RFFT/RIFFT.
+ * @param[in, out] *S points to an instance of the Q15 RFFT/RIFFT structure.
+ * @param[in] *S_CFFT points to an instance of the Q15 CFFT/CIFFT structure.
+ * @param[in] fftLenReal length of the FFT.
+ * @param[in] ifftFlagR flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform.
+ * @param[in] bitReverseFlag flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output.
+ * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if fftLenReal is not a supported value.
+ */
+
+ arm_status arm_rfft_init_q15(
+ arm_rfft_instance_q15 * S,
+ arm_cfft_radix4_instance_q15 * S_CFFT,
+ uint32_t fftLenReal,
+ uint32_t ifftFlagR,
+ uint32_t bitReverseFlag);
+
+ /**
+ * @brief Processing function for the Q31 RFFT/RIFFT.
+ * @param[in] *S points to an instance of the Q31 RFFT/RIFFT structure.
+ * @param[in] *pSrc points to the input buffer.
+ * @param[out] *pDst points to the output buffer.
+ * @return none.
+ */
+
+ void arm_rfft_q31(
+ const arm_rfft_instance_q31 * S,
+ q31_t * pSrc,
+ q31_t * pDst);
+
+ /**
+ * @brief Initialization function for the Q31 RFFT/RIFFT.
+ * @param[in, out] *S points to an instance of the Q31 RFFT/RIFFT structure.
+ * @param[in, out] *S_CFFT points to an instance of the Q31 CFFT/CIFFT structure.
+ * @param[in] fftLenReal length of the FFT.
+ * @param[in] ifftFlagR flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform.
+ * @param[in] bitReverseFlag flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output.
+ * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if fftLenReal is not a supported value.
+ */
+
+ arm_status arm_rfft_init_q31(
+ arm_rfft_instance_q31 * S,
+ arm_cfft_radix4_instance_q31 * S_CFFT,
+ uint32_t fftLenReal,
+ uint32_t ifftFlagR,
+ uint32_t bitReverseFlag);
+
+ /**
+ * @brief Initialization function for the floating-point RFFT/RIFFT.
+ * @param[in,out] *S points to an instance of the floating-point RFFT/RIFFT structure.
+ * @param[in,out] *S_CFFT points to an instance of the floating-point CFFT/CIFFT structure.
+ * @param[in] fftLenReal length of the FFT.
+ * @param[in] ifftFlagR flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform.
+ * @param[in] bitReverseFlag flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output.
+ * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if fftLenReal is not a supported value.
+ */
+
+ arm_status arm_rfft_init_f32(
+ arm_rfft_instance_f32 * S,
+ arm_cfft_radix4_instance_f32 * S_CFFT,
+ uint32_t fftLenReal,
+ uint32_t ifftFlagR,
+ uint32_t bitReverseFlag);
+
+ /**
+ * @brief Processing function for the floating-point RFFT/RIFFT.
+ * @param[in] *S points to an instance of the floating-point RFFT/RIFFT structure.
+ * @param[in] *pSrc points to the input buffer.
+ * @param[out] *pDst points to the output buffer.
+ * @return none.
+ */
+
+ void arm_rfft_f32(
+ const arm_rfft_instance_f32 * S,
+ float32_t * pSrc,
+ float32_t * pDst);
+
+ /**
+ * @brief Instance structure for the floating-point DCT4/IDCT4 function.
+ */
+
+ typedef struct
+ {
+ uint16_t N; /**< length of the DCT4. */
+ uint16_t Nby2; /**< half of the length of the DCT4. */
+ float32_t normalize; /**< normalizing factor. */
+ float32_t *pTwiddle; /**< points to the twiddle factor table. */
+ float32_t *pCosFactor; /**< points to the cosFactor table. */
+ arm_rfft_instance_f32 *pRfft; /**< points to the real FFT instance. */
+ arm_cfft_radix4_instance_f32 *pCfft; /**< points to the complex FFT instance. */
+ } arm_dct4_instance_f32;
+
+ /**
+ * @brief Initialization function for the floating-point DCT4/IDCT4.
+ * @param[in,out] *S points to an instance of floating-point DCT4/IDCT4 structure.
+ * @param[in] *S_RFFT points to an instance of floating-point RFFT/RIFFT structure.
+ * @param[in] *S_CFFT points to an instance of floating-point CFFT/CIFFT structure.
+ * @param[in] N length of the DCT4.
+ * @param[in] Nby2 half of the length of the DCT4.
+ * @param[in] normalize normalizing factor.
+ * @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if fftLenReal is not a supported transform length.
+ */
+
+ arm_status arm_dct4_init_f32(
+ arm_dct4_instance_f32 * S,
+ arm_rfft_instance_f32 * S_RFFT,
+ arm_cfft_radix4_instance_f32 * S_CFFT,
+ uint16_t N,
+ uint16_t Nby2,
+ float32_t normalize);
+
+ /**
+ * @brief Processing function for the floating-point DCT4/IDCT4.
+ * @param[in] *S points to an instance of the floating-point DCT4/IDCT4 structure.
+ * @param[in] *pState points to state buffer.
+ * @param[in,out] *pInlineBuffer points to the in-place input and output buffer.
+ * @return none.
+ */
+
+ void arm_dct4_f32(
+ const arm_dct4_instance_f32 * S,
+ float32_t * pState,
+ float32_t * pInlineBuffer);
+
+ /**
+ * @brief Instance structure for the Q31 DCT4/IDCT4 function.
+ */
+
+ typedef struct
+ {
+ uint16_t N; /**< length of the DCT4. */
+ uint16_t Nby2; /**< half of the length of the DCT4. */
+ q31_t normalize; /**< normalizing factor. */
+ q31_t *pTwiddle; /**< points to the twiddle factor table. */
+ q31_t *pCosFactor; /**< points to the cosFactor table. */
+ arm_rfft_instance_q31 *pRfft; /**< points to the real FFT instance. */
+ arm_cfft_radix4_instance_q31 *pCfft; /**< points to the complex FFT instance. */
+ } arm_dct4_instance_q31;
+
+ /**
+ * @brief Initialization function for the Q31 DCT4/IDCT4.
+ * @param[in,out] *S points to an instance of Q31 DCT4/IDCT4 structure.
+ * @param[in] *S_RFFT points to an instance of Q31 RFFT/RIFFT structure
+ * @param[in] *S_CFFT points to an instance of Q31 CFFT/CIFFT structure
+ * @param[in] N length of the DCT4.
+ * @param[in] Nby2 half of the length of the DCT4.
+ * @param[in] normalize normalizing factor.
+ * @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if N is not a supported transform length.
+ */
+
+ arm_status arm_dct4_init_q31(
+ arm_dct4_instance_q31 * S,
+ arm_rfft_instance_q31 * S_RFFT,
+ arm_cfft_radix4_instance_q31 * S_CFFT,
+ uint16_t N,
+ uint16_t Nby2,
+ q31_t normalize);
+
+ /**
+ * @brief Processing function for the Q31 DCT4/IDCT4.
+ * @param[in] *S points to an instance of the Q31 DCT4 structure.
+ * @param[in] *pState points to state buffer.
+ * @param[in,out] *pInlineBuffer points to the in-place input and output buffer.
+ * @return none.
+ */
+
+ void arm_dct4_q31(
+ const arm_dct4_instance_q31 * S,
+ q31_t * pState,
+ q31_t * pInlineBuffer);
+
+ /**
+ * @brief Instance structure for the Q15 DCT4/IDCT4 function.
+ */
+
+ typedef struct
+ {
+ uint16_t N; /**< length of the DCT4. */
+ uint16_t Nby2; /**< half of the length of the DCT4. */
+ q15_t normalize; /**< normalizing factor. */
+ q15_t *pTwiddle; /**< points to the twiddle factor table. */
+ q15_t *pCosFactor; /**< points to the cosFactor table. */
+ arm_rfft_instance_q15 *pRfft; /**< points to the real FFT instance. */
+ arm_cfft_radix4_instance_q15 *pCfft; /**< points to the complex FFT instance. */
+ } arm_dct4_instance_q15;
+
+ /**
+ * @brief Initialization function for the Q15 DCT4/IDCT4.
+ * @param[in,out] *S points to an instance of Q15 DCT4/IDCT4 structure.
+ * @param[in] *S_RFFT points to an instance of Q15 RFFT/RIFFT structure.
+ * @param[in] *S_CFFT points to an instance of Q15 CFFT/CIFFT structure.
+ * @param[in] N length of the DCT4.
+ * @param[in] Nby2 half of the length of the DCT4.
+ * @param[in] normalize normalizing factor.
+ * @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if N is not a supported transform length.
+ */
+
+ arm_status arm_dct4_init_q15(
+ arm_dct4_instance_q15 * S,
+ arm_rfft_instance_q15 * S_RFFT,
+ arm_cfft_radix4_instance_q15 * S_CFFT,
+ uint16_t N,
+ uint16_t Nby2,
+ q15_t normalize);
+
+ /**
+ * @brief Processing function for the Q15 DCT4/IDCT4.
+ * @param[in] *S points to an instance of the Q15 DCT4 structure.
+ * @param[in] *pState points to state buffer.
+ * @param[in,out] *pInlineBuffer points to the in-place input and output buffer.
+ * @return none.
+ */
+
+ void arm_dct4_q15(
+ const arm_dct4_instance_q15 * S,
+ q15_t * pState,
+ q15_t * pInlineBuffer);
+
+ /**
+ * @brief Floating-point vector addition.
+ * @param[in] *pSrcA points to the first input vector
+ * @param[in] *pSrcB points to the second input vector
+ * @param[out] *pDst points to the output vector
+ * @param[in] blockSize number of samples in each vector
+ * @return none.
+ */
+
+ void arm_add_f32(
+ float32_t * pSrcA,
+ float32_t * pSrcB,
+ float32_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Q7 vector addition.
+ * @param[in] *pSrcA points to the first input vector
+ * @param[in] *pSrcB points to the second input vector
+ * @param[out] *pDst points to the output vector
+ * @param[in] blockSize number of samples in each vector
+ * @return none.
+ */
+
+ void arm_add_q7(
+ q7_t * pSrcA,
+ q7_t * pSrcB,
+ q7_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Q15 vector addition.
+ * @param[in] *pSrcA points to the first input vector
+ * @param[in] *pSrcB points to the second input vector
+ * @param[out] *pDst points to the output vector
+ * @param[in] blockSize number of samples in each vector
+ * @return none.
+ */
+
+ void arm_add_q15(
+ q15_t * pSrcA,
+ q15_t * pSrcB,
+ q15_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Q31 vector addition.
+ * @param[in] *pSrcA points to the first input vector
+ * @param[in] *pSrcB points to the second input vector
+ * @param[out] *pDst points to the output vector
+ * @param[in] blockSize number of samples in each vector
+ * @return none.
+ */
+
+ void arm_add_q31(
+ q31_t * pSrcA,
+ q31_t * pSrcB,
+ q31_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Floating-point vector subtraction.
+ * @param[in] *pSrcA points to the first input vector
+ * @param[in] *pSrcB points to the second input vector
+ * @param[out] *pDst points to the output vector
+ * @param[in] blockSize number of samples in each vector
+ * @return none.
+ */
+
+ void arm_sub_f32(
+ float32_t * pSrcA,
+ float32_t * pSrcB,
+ float32_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Q7 vector subtraction.
+ * @param[in] *pSrcA points to the first input vector
+ * @param[in] *pSrcB points to the second input vector
+ * @param[out] *pDst points to the output vector
+ * @param[in] blockSize number of samples in each vector
+ * @return none.
+ */
+
+ void arm_sub_q7(
+ q7_t * pSrcA,
+ q7_t * pSrcB,
+ q7_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Q15 vector subtraction.
+ * @param[in] *pSrcA points to the first input vector
+ * @param[in] *pSrcB points to the second input vector
+ * @param[out] *pDst points to the output vector
+ * @param[in] blockSize number of samples in each vector
+ * @return none.
+ */
+
+ void arm_sub_q15(
+ q15_t * pSrcA,
+ q15_t * pSrcB,
+ q15_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Q31 vector subtraction.
+ * @param[in] *pSrcA points to the first input vector
+ * @param[in] *pSrcB points to the second input vector
+ * @param[out] *pDst points to the output vector
+ * @param[in] blockSize number of samples in each vector
+ * @return none.
+ */
+
+ void arm_sub_q31(
+ q31_t * pSrcA,
+ q31_t * pSrcB,
+ q31_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Multiplies a floating-point vector by a scalar.
+ * @param[in] *pSrc points to the input vector
+ * @param[in] scale scale factor to be applied
+ * @param[out] *pDst points to the output vector
+ * @param[in] blockSize number of samples in the vector
+ * @return none.
+ */
+
+ void arm_scale_f32(
+ float32_t * pSrc,
+ float32_t scale,
+ float32_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Multiplies a Q7 vector by a scalar.
+ * @param[in] *pSrc points to the input vector
+ * @param[in] scaleFract fractional portion of the scale value
+ * @param[in] shift number of bits to shift the result by
+ * @param[out] *pDst points to the output vector
+ * @param[in] blockSize number of samples in the vector
+ * @return none.
+ */
+
+ void arm_scale_q7(
+ q7_t * pSrc,
+ q7_t scaleFract,
+ int8_t shift,
+ q7_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Multiplies a Q15 vector by a scalar.
+ * @param[in] *pSrc points to the input vector
+ * @param[in] scaleFract fractional portion of the scale value
+ * @param[in] shift number of bits to shift the result by
+ * @param[out] *pDst points to the output vector
+ * @param[in] blockSize number of samples in the vector
+ * @return none.
+ */
+
+ void arm_scale_q15(
+ q15_t * pSrc,
+ q15_t scaleFract,
+ int8_t shift,
+ q15_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Multiplies a Q31 vector by a scalar.
+ * @param[in] *pSrc points to the input vector
+ * @param[in] scaleFract fractional portion of the scale value
+ * @param[in] shift number of bits to shift the result by
+ * @param[out] *pDst points to the output vector
+ * @param[in] blockSize number of samples in the vector
+ * @return none.
+ */
+
+ void arm_scale_q31(
+ q31_t * pSrc,
+ q31_t scaleFract,
+ int8_t shift,
+ q31_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Q7 vector absolute value.
+ * @param[in] *pSrc points to the input buffer
+ * @param[out] *pDst points to the output buffer
+ * @param[in] blockSize number of samples in each vector
+ * @return none.
+ */
+
+ void arm_abs_q7(
+ q7_t * pSrc,
+ q7_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Floating-point vector absolute value.
+ * @param[in] *pSrc points to the input buffer
+ * @param[out] *pDst points to the output buffer
+ * @param[in] blockSize number of samples in each vector
+ * @return none.
+ */
+
+ void arm_abs_f32(
+ float32_t * pSrc,
+ float32_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Q15 vector absolute value.
+ * @param[in] *pSrc points to the input buffer
+ * @param[out] *pDst points to the output buffer
+ * @param[in] blockSize number of samples in each vector
+ * @return none.
+ */
+
+ void arm_abs_q15(
+ q15_t * pSrc,
+ q15_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Q31 vector absolute value.
+ * @param[in] *pSrc points to the input buffer
+ * @param[out] *pDst points to the output buffer
+ * @param[in] blockSize number of samples in each vector
+ * @return none.
+ */
+
+ void arm_abs_q31(
+ q31_t * pSrc,
+ q31_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Dot product of floating-point vectors.
+ * @param[in] *pSrcA points to the first input vector
+ * @param[in] *pSrcB points to the second input vector
+ * @param[in] blockSize number of samples in each vector
+ * @param[out] *result output result returned here
+ * @return none.
+ */
+
+ void arm_dot_prod_f32(
+ float32_t * pSrcA,
+ float32_t * pSrcB,
+ uint32_t blockSize,
+ float32_t * result);
+
+ /**
+ * @brief Dot product of Q7 vectors.
+ * @param[in] *pSrcA points to the first input vector
+ * @param[in] *pSrcB points to the second input vector
+ * @param[in] blockSize number of samples in each vector
+ * @param[out] *result output result returned here
+ * @return none.
+ */
+
+ void arm_dot_prod_q7(
+ q7_t * pSrcA,
+ q7_t * pSrcB,
+ uint32_t blockSize,
+ q31_t * result);
+
+ /**
+ * @brief Dot product of Q15 vectors.
+ * @param[in] *pSrcA points to the first input vector
+ * @param[in] *pSrcB points to the second input vector
+ * @param[in] blockSize number of samples in each vector
+ * @param[out] *result output result returned here
+ * @return none.
+ */
+
+ void arm_dot_prod_q15(
+ q15_t * pSrcA,
+ q15_t * pSrcB,
+ uint32_t blockSize,
+ q63_t * result);
+
+ /**
+ * @brief Dot product of Q31 vectors.
+ * @param[in] *pSrcA points to the first input vector
+ * @param[in] *pSrcB points to the second input vector
+ * @param[in] blockSize number of samples in each vector
+ * @param[out] *result output result returned here
+ * @return none.
+ */
+
+ void arm_dot_prod_q31(
+ q31_t * pSrcA,
+ q31_t * pSrcB,
+ uint32_t blockSize,
+ q63_t * result);
+
+ /**
+ * @brief Shifts the elements of a Q7 vector a specified number of bits.
+ * @param[in] *pSrc points to the input vector
+ * @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right.
+ * @param[out] *pDst points to the output vector
+ * @param[in] blockSize number of samples in the vector
+ * @return none.
+ */
+
+ void arm_shift_q7(
+ q7_t * pSrc,
+ int8_t shiftBits,
+ q7_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Shifts the elements of a Q15 vector a specified number of bits.
+ * @param[in] *pSrc points to the input vector
+ * @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right.
+ * @param[out] *pDst points to the output vector
+ * @param[in] blockSize number of samples in the vector
+ * @return none.
+ */
+
+ void arm_shift_q15(
+ q15_t * pSrc,
+ int8_t shiftBits,
+ q15_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Shifts the elements of a Q31 vector a specified number of bits.
+ * @param[in] *pSrc points to the input vector
+ * @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right.
+ * @param[out] *pDst points to the output vector
+ * @param[in] blockSize number of samples in the vector
+ * @return none.
+ */
+
+ void arm_shift_q31(
+ q31_t * pSrc,
+ int8_t shiftBits,
+ q31_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Adds a constant offset to a floating-point vector.
+ * @param[in] *pSrc points to the input vector
+ * @param[in] offset is the offset to be added
+ * @param[out] *pDst points to the output vector
+ * @param[in] blockSize number of samples in the vector
+ * @return none.
+ */
+
+ void arm_offset_f32(
+ float32_t * pSrc,
+ float32_t offset,
+ float32_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Adds a constant offset to a Q7 vector.
+ * @param[in] *pSrc points to the input vector
+ * @param[in] offset is the offset to be added
+ * @param[out] *pDst points to the output vector
+ * @param[in] blockSize number of samples in the vector
+ * @return none.
+ */
+
+ void arm_offset_q7(
+ q7_t * pSrc,
+ q7_t offset,
+ q7_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Adds a constant offset to a Q15 vector.
+ * @param[in] *pSrc points to the input vector
+ * @param[in] offset is the offset to be added
+ * @param[out] *pDst points to the output vector
+ * @param[in] blockSize number of samples in the vector
+ * @return none.
+ */
+
+ void arm_offset_q15(
+ q15_t * pSrc,
+ q15_t offset,
+ q15_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Adds a constant offset to a Q31 vector.
+ * @param[in] *pSrc points to the input vector
+ * @param[in] offset is the offset to be added
+ * @param[out] *pDst points to the output vector
+ * @param[in] blockSize number of samples in the vector
+ * @return none.
+ */
+
+ void arm_offset_q31(
+ q31_t * pSrc,
+ q31_t offset,
+ q31_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Negates the elements of a floating-point vector.
+ * @param[in] *pSrc points to the input vector
+ * @param[out] *pDst points to the output vector
+ * @param[in] blockSize number of samples in the vector
+ * @return none.
+ */
+
+ void arm_negate_f32(
+ float32_t * pSrc,
+ float32_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Negates the elements of a Q7 vector.
+ * @param[in] *pSrc points to the input vector
+ * @param[out] *pDst points to the output vector
+ * @param[in] blockSize number of samples in the vector
+ * @return none.
+ */
+
+ void arm_negate_q7(
+ q7_t * pSrc,
+ q7_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Negates the elements of a Q15 vector.
+ * @param[in] *pSrc points to the input vector
+ * @param[out] *pDst points to the output vector
+ * @param[in] blockSize number of samples in the vector
+ * @return none.
+ */
+
+ void arm_negate_q15(
+ q15_t * pSrc,
+ q15_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Negates the elements of a Q31 vector.
+ * @param[in] *pSrc points to the input vector
+ * @param[out] *pDst points to the output vector
+ * @param[in] blockSize number of samples in the vector
+ * @return none.
+ */
+
+ void arm_negate_q31(
+ q31_t * pSrc,
+ q31_t * pDst,
+ uint32_t blockSize);
+ /**
+ * @brief Copies the elements of a floating-point vector.
+ * @param[in] *pSrc input pointer
+ * @param[out] *pDst output pointer
+ * @param[in] blockSize number of samples to process
+ * @return none.
+ */
+ void arm_copy_f32(
+ float32_t * pSrc,
+ float32_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Copies the elements of a Q7 vector.
+ * @param[in] *pSrc input pointer
+ * @param[out] *pDst output pointer
+ * @param[in] blockSize number of samples to process
+ * @return none.
+ */
+ void arm_copy_q7(
+ q7_t * pSrc,
+ q7_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Copies the elements of a Q15 vector.
+ * @param[in] *pSrc input pointer
+ * @param[out] *pDst output pointer
+ * @param[in] blockSize number of samples to process
+ * @return none.
+ */
+ void arm_copy_q15(
+ q15_t * pSrc,
+ q15_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Copies the elements of a Q31 vector.
+ * @param[in] *pSrc input pointer
+ * @param[out] *pDst output pointer
+ * @param[in] blockSize number of samples to process
+ * @return none.
+ */
+ void arm_copy_q31(
+ q31_t * pSrc,
+ q31_t * pDst,
+ uint32_t blockSize);
+ /**
+ * @brief Fills a constant value into a floating-point vector.
+ * @param[in] value input value to be filled
+ * @param[out] *pDst output pointer
+ * @param[in] blockSize number of samples to process
+ * @return none.
+ */
+ void arm_fill_f32(
+ float32_t value,
+ float32_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Fills a constant value into a Q7 vector.
+ * @param[in] value input value to be filled
+ * @param[out] *pDst output pointer
+ * @param[in] blockSize number of samples to process
+ * @return none.
+ */
+ void arm_fill_q7(
+ q7_t value,
+ q7_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Fills a constant value into a Q15 vector.
+ * @param[in] value input value to be filled
+ * @param[out] *pDst output pointer
+ * @param[in] blockSize number of samples to process
+ * @return none.
+ */
+ void arm_fill_q15(
+ q15_t value,
+ q15_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Fills a constant value into a Q31 vector.
+ * @param[in] value input value to be filled
+ * @param[out] *pDst output pointer
+ * @param[in] blockSize number of samples to process
+ * @return none.
+ */
+ void arm_fill_q31(
+ q31_t value,
+ q31_t * pDst,
+ uint32_t blockSize);
+
+/**
+ * @brief Convolution of floating-point sequences.
+ * @param[in] *pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] *pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] *pDst points to the location where the output result is written. Length srcALen+srcBLen-1.
+ * @return none.
+ */
+
+ void arm_conv_f32(
+ float32_t * pSrcA,
+ uint32_t srcALen,
+ float32_t * pSrcB,
+ uint32_t srcBLen,
+ float32_t * pDst);
+
+/**
+ * @brief Convolution of Q15 sequences.
+ * @param[in] *pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] *pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] *pDst points to the location where the output result is written. Length srcALen+srcBLen-1.
+ * @return none.
+ */
+
+ void arm_conv_q15(
+ q15_t * pSrcA,
+ uint32_t srcALen,
+ q15_t * pSrcB,
+ uint32_t srcBLen,
+ q15_t * pDst);
+
+ /**
+ * @brief Convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4
+ * @param[in] *pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] *pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] *pDst points to the block of output data Length srcALen+srcBLen-1.
+ * @return none.
+ */
+
+ void arm_conv_fast_q15(
+ q15_t * pSrcA,
+ uint32_t srcALen,
+ q15_t * pSrcB,
+ uint32_t srcBLen,
+ q15_t * pDst);
+
+ /**
+ * @brief Convolution of Q31 sequences.
+ * @param[in] *pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] *pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] *pDst points to the block of output data Length srcALen+srcBLen-1.
+ * @return none.
+ */
+
+ void arm_conv_q31(
+ q31_t * pSrcA,
+ uint32_t srcALen,
+ q31_t * pSrcB,
+ uint32_t srcBLen,
+ q31_t * pDst);
+
+ /**
+ * @brief Convolution of Q31 sequences (fast version) for Cortex-M3 and Cortex-M4
+ * @param[in] *pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] *pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] *pDst points to the block of output data Length srcALen+srcBLen-1.
+ * @return none.
+ */
+
+ void arm_conv_fast_q31(
+ q31_t * pSrcA,
+ uint32_t srcALen,
+ q31_t * pSrcB,
+ uint32_t srcBLen,
+ q31_t * pDst);
+
+ /**
+ * @brief Convolution of Q7 sequences.
+ * @param[in] *pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] *pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] *pDst points to the block of output data Length srcALen+srcBLen-1.
+ * @return none.
+ */
+
+ void arm_conv_q7(
+ q7_t * pSrcA,
+ uint32_t srcALen,
+ q7_t * pSrcB,
+ uint32_t srcBLen,
+ q7_t * pDst);
+
+ /**
+ * @brief Partial convolution of floating-point sequences.
+ * @param[in] *pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] *pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] *pDst points to the block of output data
+ * @param[in] firstIndex is the first output sample to start with.
+ * @param[in] numPoints is the number of output points to be computed.
+ * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2].
+ */
+
+ arm_status arm_conv_partial_f32(
+ float32_t * pSrcA,
+ uint32_t srcALen,
+ float32_t * pSrcB,
+ uint32_t srcBLen,
+ float32_t * pDst,
+ uint32_t firstIndex,
+ uint32_t numPoints);
+
+ /**
+ * @brief Partial convolution of Q15 sequences.
+ * @param[in] *pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] *pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] *pDst points to the block of output data
+ * @param[in] firstIndex is the first output sample to start with.
+ * @param[in] numPoints is the number of output points to be computed.
+ * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2].
+ */
+
+ arm_status arm_conv_partial_q15(
+ q15_t * pSrcA,
+ uint32_t srcALen,
+ q15_t * pSrcB,
+ uint32_t srcBLen,
+ q15_t * pDst,
+ uint32_t firstIndex,
+ uint32_t numPoints);
+
+ /**
+ * @brief Partial convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4
+ * @param[in] *pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] *pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] *pDst points to the block of output data
+ * @param[in] firstIndex is the first output sample to start with.
+ * @param[in] numPoints is the number of output points to be computed.
+ * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2].
+ */
+
+ arm_status arm_conv_partial_fast_q15(
+ q15_t * pSrcA,
+ uint32_t srcALen,
+ q15_t * pSrcB,
+ uint32_t srcBLen,
+ q15_t * pDst,
+ uint32_t firstIndex,
+ uint32_t numPoints);
+
+ /**
+ * @brief Partial convolution of Q31 sequences.
+ * @param[in] *pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] *pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] *pDst points to the block of output data
+ * @param[in] firstIndex is the first output sample to start with.
+ * @param[in] numPoints is the number of output points to be computed.
+ * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2].
+ */
+
+ arm_status arm_conv_partial_q31(
+ q31_t * pSrcA,
+ uint32_t srcALen,
+ q31_t * pSrcB,
+ uint32_t srcBLen,
+ q31_t * pDst,
+ uint32_t firstIndex,
+ uint32_t numPoints);
+
+
+ /**
+ * @brief Partial convolution of Q31 sequences (fast version) for Cortex-M3 and Cortex-M4
+ * @param[in] *pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] *pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] *pDst points to the block of output data
+ * @param[in] firstIndex is the first output sample to start with.
+ * @param[in] numPoints is the number of output points to be computed.
+ * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2].
+ */
+
+ arm_status arm_conv_partial_fast_q31(
+ q31_t * pSrcA,
+ uint32_t srcALen,
+ q31_t * pSrcB,
+ uint32_t srcBLen,
+ q31_t * pDst,
+ uint32_t firstIndex,
+ uint32_t numPoints);
+
+ /**
+ * @brief Partial convolution of Q7 sequences.
+ * @param[in] *pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] *pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] *pDst points to the block of output data
+ * @param[in] firstIndex is the first output sample to start with.
+ * @param[in] numPoints is the number of output points to be computed.
+ * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2].
+ */
+
+ arm_status arm_conv_partial_q7(
+ q7_t * pSrcA,
+ uint32_t srcALen,
+ q7_t * pSrcB,
+ uint32_t srcBLen,
+ q7_t * pDst,
+ uint32_t firstIndex,
+ uint32_t numPoints);
+
+
+ /**
+ * @brief Instance structure for the Q15 FIR decimator.
+ */
+
+ typedef struct
+ {
+ uint8_t M; /**< decimation factor. */
+ uint16_t numTaps; /**< number of coefficients in the filter. */
+ q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/
+ q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+ } arm_fir_decimate_instance_q15;
+
+ /**
+ * @brief Instance structure for the Q31 FIR decimator.
+ */
+
+ typedef struct
+ {
+ uint8_t M; /**< decimation factor. */
+ uint16_t numTaps; /**< number of coefficients in the filter. */
+ q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/
+ q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+
+ } arm_fir_decimate_instance_q31;
+
+ /**
+ * @brief Instance structure for the floating-point FIR decimator.
+ */
+
+ typedef struct
+ {
+ uint8_t M; /**< decimation factor. */
+ uint16_t numTaps; /**< number of coefficients in the filter. */
+ float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/
+ float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+
+ } arm_fir_decimate_instance_f32;
+
+
+
+ /**
+ * @brief Processing function for the floating-point FIR decimator.
+ * @param[in] *S points to an instance of the floating-point FIR decimator structure.
+ * @param[in] *pSrc points to the block of input data.
+ * @param[out] *pDst points to the block of output data
+ * @param[in] blockSize number of input samples to process per call.
+ * @return none
+ */
+
+ void arm_fir_decimate_f32(
+ const arm_fir_decimate_instance_f32 * S,
+ float32_t * pSrc,
+ float32_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Initialization function for the floating-point FIR decimator.
+ * @param[in,out] *S points to an instance of the floating-point FIR decimator structure.
+ * @param[in] numTaps number of coefficients in the filter.
+ * @param[in] M decimation factor.
+ * @param[in] *pCoeffs points to the filter coefficients.
+ * @param[in] *pState points to the state buffer.
+ * @param[in] blockSize number of input samples to process per call.
+ * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if
+ * blockSize is not a multiple of M.
+ */
+
+ arm_status arm_fir_decimate_init_f32(
+ arm_fir_decimate_instance_f32 * S,
+ uint16_t numTaps,
+ uint8_t M,
+ float32_t * pCoeffs,
+ float32_t * pState,
+ uint32_t blockSize);
+
+ /**
+ * @brief Processing function for the Q15 FIR decimator.
+ * @param[in] *S points to an instance of the Q15 FIR decimator structure.
+ * @param[in] *pSrc points to the block of input data.
+ * @param[out] *pDst points to the block of output data
+ * @param[in] blockSize number of input samples to process per call.
+ * @return none
+ */
+
+ void arm_fir_decimate_q15(
+ const arm_fir_decimate_instance_q15 * S,
+ q15_t * pSrc,
+ q15_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Processing function for the Q15 FIR decimator (fast variant) for Cortex-M3 and Cortex-M4.
+ * @param[in] *S points to an instance of the Q15 FIR decimator structure.
+ * @param[in] *pSrc points to the block of input data.
+ * @param[out] *pDst points to the block of output data
+ * @param[in] blockSize number of input samples to process per call.
+ * @return none
+ */
+
+ void arm_fir_decimate_fast_q15(
+ const arm_fir_decimate_instance_q15 * S,
+ q15_t * pSrc,
+ q15_t * pDst,
+ uint32_t blockSize);
+
+
+
+ /**
+ * @brief Initialization function for the Q15 FIR decimator.
+ * @param[in,out] *S points to an instance of the Q15 FIR decimator structure.
+ * @param[in] numTaps number of coefficients in the filter.
+ * @param[in] M decimation factor.
+ * @param[in] *pCoeffs points to the filter coefficients.
+ * @param[in] *pState points to the state buffer.
+ * @param[in] blockSize number of input samples to process per call.
+ * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if
+ * blockSize is not a multiple of M.
+ */
+
+ arm_status arm_fir_decimate_init_q15(
+ arm_fir_decimate_instance_q15 * S,
+ uint16_t numTaps,
+ uint8_t M,
+ q15_t * pCoeffs,
+ q15_t * pState,
+ uint32_t blockSize);
+
+ /**
+ * @brief Processing function for the Q31 FIR decimator.
+ * @param[in] *S points to an instance of the Q31 FIR decimator structure.
+ * @param[in] *pSrc points to the block of input data.
+ * @param[out] *pDst points to the block of output data
+ * @param[in] blockSize number of input samples to process per call.
+ * @return none
+ */
+
+ void arm_fir_decimate_q31(
+ const arm_fir_decimate_instance_q31 * S,
+ q31_t * pSrc,
+ q31_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Processing function for the Q31 FIR decimator (fast variant) for Cortex-M3 and Cortex-M4.
+ * @param[in] *S points to an instance of the Q31 FIR decimator structure.
+ * @param[in] *pSrc points to the block of input data.
+ * @param[out] *pDst points to the block of output data
+ * @param[in] blockSize number of input samples to process per call.
+ * @return none
+ */
+
+ void arm_fir_decimate_fast_q31(
+ arm_fir_decimate_instance_q31 * S,
+ q31_t * pSrc,
+ q31_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Initialization function for the Q31 FIR decimator.
+ * @param[in,out] *S points to an instance of the Q31 FIR decimator structure.
+ * @param[in] numTaps number of coefficients in the filter.
+ * @param[in] M decimation factor.
+ * @param[in] *pCoeffs points to the filter coefficients.
+ * @param[in] *pState points to the state buffer.
+ * @param[in] blockSize number of input samples to process per call.
+ * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if
+ * blockSize is not a multiple of M.
+ */
+
+ arm_status arm_fir_decimate_init_q31(
+ arm_fir_decimate_instance_q31 * S,
+ uint16_t numTaps,
+ uint8_t M,
+ q31_t * pCoeffs,
+ q31_t * pState,
+ uint32_t blockSize);
+
+
+
+ /**
+ * @brief Instance structure for the Q15 FIR interpolator.
+ */
+
+ typedef struct
+ {
+ uint8_t L; /**< upsample factor. */
+ uint16_t phaseLength; /**< length of each polyphase filter component. */
+ q15_t *pCoeffs; /**< points to the coefficient array. The array is of length L*phaseLength. */
+ q15_t *pState; /**< points to the state variable array. The array is of length blockSize+phaseLength-1. */
+ } arm_fir_interpolate_instance_q15;
+
+ /**
+ * @brief Instance structure for the Q31 FIR interpolator.
+ */
+
+ typedef struct
+ {
+ uint8_t L; /**< upsample factor. */
+ uint16_t phaseLength; /**< length of each polyphase filter component. */
+ q31_t *pCoeffs; /**< points to the coefficient array. The array is of length L*phaseLength. */
+ q31_t *pState; /**< points to the state variable array. The array is of length blockSize+phaseLength-1. */
+ } arm_fir_interpolate_instance_q31;
+
+ /**
+ * @brief Instance structure for the floating-point FIR interpolator.
+ */
+
+ typedef struct
+ {
+ uint8_t L; /**< upsample factor. */
+ uint16_t phaseLength; /**< length of each polyphase filter component. */
+ float32_t *pCoeffs; /**< points to the coefficient array. The array is of length L*phaseLength. */
+ float32_t *pState; /**< points to the state variable array. The array is of length phaseLength+numTaps-1. */
+ } arm_fir_interpolate_instance_f32;
+
+
+ /**
+ * @brief Processing function for the Q15 FIR interpolator.
+ * @param[in] *S points to an instance of the Q15 FIR interpolator structure.
+ * @param[in] *pSrc points to the block of input data.
+ * @param[out] *pDst points to the block of output data.
+ * @param[in] blockSize number of input samples to process per call.
+ * @return none.
+ */
+
+ void arm_fir_interpolate_q15(
+ const arm_fir_interpolate_instance_q15 * S,
+ q15_t * pSrc,
+ q15_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Initialization function for the Q15 FIR interpolator.
+ * @param[in,out] *S points to an instance of the Q15 FIR interpolator structure.
+ * @param[in] L upsample factor.
+ * @param[in] numTaps number of filter coefficients in the filter.
+ * @param[in] *pCoeffs points to the filter coefficient buffer.
+ * @param[in] *pState points to the state buffer.
+ * @param[in] blockSize number of input samples to process per call.
+ * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if
+ * the filter length numTaps is not a multiple of the interpolation factor L.
+ */
+
+ arm_status arm_fir_interpolate_init_q15(
+ arm_fir_interpolate_instance_q15 * S,
+ uint8_t L,
+ uint16_t numTaps,
+ q15_t * pCoeffs,
+ q15_t * pState,
+ uint32_t blockSize);
+
+ /**
+ * @brief Processing function for the Q31 FIR interpolator.
+ * @param[in] *S points to an instance of the Q15 FIR interpolator structure.
+ * @param[in] *pSrc points to the block of input data.
+ * @param[out] *pDst points to the block of output data.
+ * @param[in] blockSize number of input samples to process per call.
+ * @return none.
+ */
+
+ void arm_fir_interpolate_q31(
+ const arm_fir_interpolate_instance_q31 * S,
+ q31_t * pSrc,
+ q31_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Initialization function for the Q31 FIR interpolator.
+ * @param[in,out] *S points to an instance of the Q31 FIR interpolator structure.
+ * @param[in] L upsample factor.
+ * @param[in] numTaps number of filter coefficients in the filter.
+ * @param[in] *pCoeffs points to the filter coefficient buffer.
+ * @param[in] *pState points to the state buffer.
+ * @param[in] blockSize number of input samples to process per call.
+ * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if
+ * the filter length numTaps is not a multiple of the interpolation factor L.
+ */
+
+ arm_status arm_fir_interpolate_init_q31(
+ arm_fir_interpolate_instance_q31 * S,
+ uint8_t L,
+ uint16_t numTaps,
+ q31_t * pCoeffs,
+ q31_t * pState,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Processing function for the floating-point FIR interpolator.
+ * @param[in] *S points to an instance of the floating-point FIR interpolator structure.
+ * @param[in] *pSrc points to the block of input data.
+ * @param[out] *pDst points to the block of output data.
+ * @param[in] blockSize number of input samples to process per call.
+ * @return none.
+ */
+
+ void arm_fir_interpolate_f32(
+ const arm_fir_interpolate_instance_f32 * S,
+ float32_t * pSrc,
+ float32_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Initialization function for the floating-point FIR interpolator.
+ * @param[in,out] *S points to an instance of the floating-point FIR interpolator structure.
+ * @param[in] L upsample factor.
+ * @param[in] numTaps number of filter coefficients in the filter.
+ * @param[in] *pCoeffs points to the filter coefficient buffer.
+ * @param[in] *pState points to the state buffer.
+ * @param[in] blockSize number of input samples to process per call.
+ * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if
+ * the filter length numTaps is not a multiple of the interpolation factor L.
+ */
+
+ arm_status arm_fir_interpolate_init_f32(
+ arm_fir_interpolate_instance_f32 * S,
+ uint8_t L,
+ uint16_t numTaps,
+ float32_t * pCoeffs,
+ float32_t * pState,
+ uint32_t blockSize);
+
+ /**
+ * @brief Instance structure for the high precision Q31 Biquad cascade filter.
+ */
+
+ typedef struct
+ {
+ uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */
+ q63_t *pState; /**< points to the array of state coefficients. The array is of length 4*numStages. */
+ q31_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */
+ uint8_t postShift; /**< additional shift, in bits, applied to each output sample. */
+
+ } arm_biquad_cas_df1_32x64_ins_q31;
+
+
+ /**
+ * @param[in] *S points to an instance of the high precision Q31 Biquad cascade filter structure.
+ * @param[in] *pSrc points to the block of input data.
+ * @param[out] *pDst points to the block of output data
+ * @param[in] blockSize number of samples to process.
+ * @return none.
+ */
+
+ void arm_biquad_cas_df1_32x64_q31(
+ const arm_biquad_cas_df1_32x64_ins_q31 * S,
+ q31_t * pSrc,
+ q31_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @param[in,out] *S points to an instance of the high precision Q31 Biquad cascade filter structure.
+ * @param[in] numStages number of 2nd order stages in the filter.
+ * @param[in] *pCoeffs points to the filter coefficients.
+ * @param[in] *pState points to the state buffer.
+ * @param[in] postShift shift to be applied to the output. Varies according to the coefficients format
+ * @return none
+ */
+
+ void arm_biquad_cas_df1_32x64_init_q31(
+ arm_biquad_cas_df1_32x64_ins_q31 * S,
+ uint8_t numStages,
+ q31_t * pCoeffs,
+ q63_t * pState,
+ uint8_t postShift);
+
+
+
+ /**
+ * @brief Instance structure for the floating-point transposed direct form II Biquad cascade filter.
+ */
+
+ typedef struct
+ {
+ uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */
+ float32_t *pState; /**< points to the array of state coefficients. The array is of length 2*numStages. */
+ float32_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */
+ } arm_biquad_cascade_df2T_instance_f32;
+
+
+ /**
+ * @brief Processing function for the floating-point transposed direct form II Biquad cascade filter.
+ * @param[in] *S points to an instance of the filter data structure.
+ * @param[in] *pSrc points to the block of input data.
+ * @param[out] *pDst points to the block of output data
+ * @param[in] blockSize number of samples to process.
+ * @return none.
+ */
+
+ void arm_biquad_cascade_df2T_f32(
+ const arm_biquad_cascade_df2T_instance_f32 * S,
+ float32_t * pSrc,
+ float32_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Initialization function for the floating-point transposed direct form II Biquad cascade filter.
+ * @param[in,out] *S points to an instance of the filter data structure.
+ * @param[in] numStages number of 2nd order stages in the filter.
+ * @param[in] *pCoeffs points to the filter coefficients.
+ * @param[in] *pState points to the state buffer.
+ * @return none
+ */
+
+ void arm_biquad_cascade_df2T_init_f32(
+ arm_biquad_cascade_df2T_instance_f32 * S,
+ uint8_t numStages,
+ float32_t * pCoeffs,
+ float32_t * pState);
+
+
+
+ /**
+ * @brief Instance structure for the Q15 FIR lattice filter.
+ */
+
+ typedef struct
+ {
+ uint16_t numStages; /**< number of filter stages. */
+ q15_t *pState; /**< points to the state variable array. The array is of length numStages. */
+ q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numStages. */
+ } arm_fir_lattice_instance_q15;
+
+ /**
+ * @brief Instance structure for the Q31 FIR lattice filter.
+ */
+
+ typedef struct
+ {
+ uint16_t numStages; /**< number of filter stages. */
+ q31_t *pState; /**< points to the state variable array. The array is of length numStages. */
+ q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numStages. */
+ } arm_fir_lattice_instance_q31;
+
+ /**
+ * @brief Instance structure for the floating-point FIR lattice filter.
+ */
+
+ typedef struct
+ {
+ uint16_t numStages; /**< number of filter stages. */
+ float32_t *pState; /**< points to the state variable array. The array is of length numStages. */
+ float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numStages. */
+ } arm_fir_lattice_instance_f32;
+
+ /**
+ * @brief Initialization function for the Q15 FIR lattice filter.
+ * @param[in] *S points to an instance of the Q15 FIR lattice structure.
+ * @param[in] numStages number of filter stages.
+ * @param[in] *pCoeffs points to the coefficient buffer. The array is of length numStages.
+ * @param[in] *pState points to the state buffer. The array is of length numStages.
+ * @return none.
+ */
+
+ void arm_fir_lattice_init_q15(
+ arm_fir_lattice_instance_q15 * S,
+ uint16_t numStages,
+ q15_t * pCoeffs,
+ q15_t * pState);
+
+
+ /**
+ * @brief Processing function for the Q15 FIR lattice filter.
+ * @param[in] *S points to an instance of the Q15 FIR lattice structure.
+ * @param[in] *pSrc points to the block of input data.
+ * @param[out] *pDst points to the block of output data.
+ * @param[in] blockSize number of samples to process.
+ * @return none.
+ */
+ void arm_fir_lattice_q15(
+ const arm_fir_lattice_instance_q15 * S,
+ q15_t * pSrc,
+ q15_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Initialization function for the Q31 FIR lattice filter.
+ * @param[in] *S points to an instance of the Q31 FIR lattice structure.
+ * @param[in] numStages number of filter stages.
+ * @param[in] *pCoeffs points to the coefficient buffer. The array is of length numStages.
+ * @param[in] *pState points to the state buffer. The array is of length numStages.
+ * @return none.
+ */
+
+ void arm_fir_lattice_init_q31(
+ arm_fir_lattice_instance_q31 * S,
+ uint16_t numStages,
+ q31_t * pCoeffs,
+ q31_t * pState);
+
+
+ /**
+ * @brief Processing function for the Q31 FIR lattice filter.
+ * @param[in] *S points to an instance of the Q31 FIR lattice structure.
+ * @param[in] *pSrc points to the block of input data.
+ * @param[out] *pDst points to the block of output data
+ * @param[in] blockSize number of samples to process.
+ * @return none.
+ */
+
+ void arm_fir_lattice_q31(
+ const arm_fir_lattice_instance_q31 * S,
+ q31_t * pSrc,
+ q31_t * pDst,
+ uint32_t blockSize);
+
+/**
+ * @brief Initialization function for the floating-point FIR lattice filter.
+ * @param[in] *S points to an instance of the floating-point FIR lattice structure.
+ * @param[in] numStages number of filter stages.
+ * @param[in] *pCoeffs points to the coefficient buffer. The array is of length numStages.
+ * @param[in] *pState points to the state buffer. The array is of length numStages.
+ * @return none.
+ */
+
+ void arm_fir_lattice_init_f32(
+ arm_fir_lattice_instance_f32 * S,
+ uint16_t numStages,
+ float32_t * pCoeffs,
+ float32_t * pState);
+
+ /**
+ * @brief Processing function for the floating-point FIR lattice filter.
+ * @param[in] *S points to an instance of the floating-point FIR lattice structure.
+ * @param[in] *pSrc points to the block of input data.
+ * @param[out] *pDst points to the block of output data
+ * @param[in] blockSize number of samples to process.
+ * @return none.
+ */
+
+ void arm_fir_lattice_f32(
+ const arm_fir_lattice_instance_f32 * S,
+ float32_t * pSrc,
+ float32_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Instance structure for the Q15 IIR lattice filter.
+ */
+ typedef struct
+ {
+ uint16_t numStages; /**< number of stages in the filter. */
+ q15_t *pState; /**< points to the state variable array. The array is of length numStages+blockSize. */
+ q15_t *pkCoeffs; /**< points to the reflection coefficient array. The array is of length numStages. */
+ q15_t *pvCoeffs; /**< points to the ladder coefficient array. The array is of length numStages+1. */
+ } arm_iir_lattice_instance_q15;
+
+ /**
+ * @brief Instance structure for the Q31 IIR lattice filter.
+ */
+ typedef struct
+ {
+ uint16_t numStages; /**< number of stages in the filter. */
+ q31_t *pState; /**< points to the state variable array. The array is of length numStages+blockSize. */
+ q31_t *pkCoeffs; /**< points to the reflection coefficient array. The array is of length numStages. */
+ q31_t *pvCoeffs; /**< points to the ladder coefficient array. The array is of length numStages+1. */
+ } arm_iir_lattice_instance_q31;
+
+ /**
+ * @brief Instance structure for the floating-point IIR lattice filter.
+ */
+ typedef struct
+ {
+ uint16_t numStages; /**< number of stages in the filter. */
+ float32_t *pState; /**< points to the state variable array. The array is of length numStages+blockSize. */
+ float32_t *pkCoeffs; /**< points to the reflection coefficient array. The array is of length numStages. */
+ float32_t *pvCoeffs; /**< points to the ladder coefficient array. The array is of length numStages+1. */
+ } arm_iir_lattice_instance_f32;
+
+ /**
+ * @brief Processing function for the floating-point IIR lattice filter.
+ * @param[in] *S points to an instance of the floating-point IIR lattice structure.
+ * @param[in] *pSrc points to the block of input data.
+ * @param[out] *pDst points to the block of output data.
+ * @param[in] blockSize number of samples to process.
+ * @return none.
+ */
+
+ void arm_iir_lattice_f32(
+ const arm_iir_lattice_instance_f32 * S,
+ float32_t * pSrc,
+ float32_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Initialization function for the floating-point IIR lattice filter.
+ * @param[in] *S points to an instance of the floating-point IIR lattice structure.
+ * @param[in] numStages number of stages in the filter.
+ * @param[in] *pkCoeffs points to the reflection coefficient buffer. The array is of length numStages.
+ * @param[in] *pvCoeffs points to the ladder coefficient buffer. The array is of length numStages+1.
+ * @param[in] *pState points to the state buffer. The array is of length numStages+blockSize-1.
+ * @param[in] blockSize number of samples to process.
+ * @return none.
+ */
+
+ void arm_iir_lattice_init_f32(
+ arm_iir_lattice_instance_f32 * S,
+ uint16_t numStages,
+ float32_t *pkCoeffs,
+ float32_t *pvCoeffs,
+ float32_t *pState,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Processing function for the Q31 IIR lattice filter.
+ * @param[in] *S points to an instance of the Q31 IIR lattice structure.
+ * @param[in] *pSrc points to the block of input data.
+ * @param[out] *pDst points to the block of output data.
+ * @param[in] blockSize number of samples to process.
+ * @return none.
+ */
+
+ void arm_iir_lattice_q31(
+ const arm_iir_lattice_instance_q31 * S,
+ q31_t * pSrc,
+ q31_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Initialization function for the Q31 IIR lattice filter.
+ * @param[in] *S points to an instance of the Q31 IIR lattice structure.
+ * @param[in] numStages number of stages in the filter.
+ * @param[in] *pkCoeffs points to the reflection coefficient buffer. The array is of length numStages.
+ * @param[in] *pvCoeffs points to the ladder coefficient buffer. The array is of length numStages+1.
+ * @param[in] *pState points to the state buffer. The array is of length numStages+blockSize.
+ * @param[in] blockSize number of samples to process.
+ * @return none.
+ */
+
+ void arm_iir_lattice_init_q31(
+ arm_iir_lattice_instance_q31 * S,
+ uint16_t numStages,
+ q31_t *pkCoeffs,
+ q31_t *pvCoeffs,
+ q31_t *pState,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Processing function for the Q15 IIR lattice filter.
+ * @param[in] *S points to an instance of the Q15 IIR lattice structure.
+ * @param[in] *pSrc points to the block of input data.
+ * @param[out] *pDst points to the block of output data.
+ * @param[in] blockSize number of samples to process.
+ * @return none.
+ */
+
+ void arm_iir_lattice_q15(
+ const arm_iir_lattice_instance_q15 * S,
+ q15_t * pSrc,
+ q15_t * pDst,
+ uint32_t blockSize);
+
+
+/**
+ * @brief Initialization function for the Q15 IIR lattice filter.
+ * @param[in] *S points to an instance of the fixed-point Q15 IIR lattice structure.
+ * @param[in] numStages number of stages in the filter.
+ * @param[in] *pkCoeffs points to reflection coefficient buffer. The array is of length numStages.
+ * @param[in] *pvCoeffs points to ladder coefficient buffer. The array is of length numStages+1.
+ * @param[in] *pState points to state buffer. The array is of length numStages+blockSize.
+ * @param[in] blockSize number of samples to process per call.
+ * @return none.
+ */
+
+ void arm_iir_lattice_init_q15(
+ arm_iir_lattice_instance_q15 * S,
+ uint16_t numStages,
+ q15_t *pkCoeffs,
+ q15_t *pvCoeffs,
+ q15_t *pState,
+ uint32_t blockSize);
+
+ /**
+ * @brief Instance structure for the floating-point LMS filter.
+ */
+
+ typedef struct
+ {
+ uint16_t numTaps; /**< number of coefficients in the filter. */
+ float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+ float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */
+ float32_t mu; /**< step size that controls filter coefficient updates. */
+ } arm_lms_instance_f32;
+
+ /**
+ * @brief Processing function for floating-point LMS filter.
+ * @param[in] *S points to an instance of the floating-point LMS filter structure.
+ * @param[in] *pSrc points to the block of input data.
+ * @param[in] *pRef points to the block of reference data.
+ * @param[out] *pOut points to the block of output data.
+ * @param[out] *pErr points to the block of error data.
+ * @param[in] blockSize number of samples to process.
+ * @return none.
+ */
+
+ void arm_lms_f32(
+ const arm_lms_instance_f32 * S,
+ float32_t * pSrc,
+ float32_t * pRef,
+ float32_t * pOut,
+ float32_t * pErr,
+ uint32_t blockSize);
+
+ /**
+ * @brief Initialization function for floating-point LMS filter.
+ * @param[in] *S points to an instance of the floating-point LMS filter structure.
+ * @param[in] numTaps number of filter coefficients.
+ * @param[in] *pCoeffs points to the coefficient buffer.
+ * @param[in] *pState points to state buffer.
+ * @param[in] mu step size that controls filter coefficient updates.
+ * @param[in] blockSize number of samples to process.
+ * @return none.
+ */
+
+ void arm_lms_init_f32(
+ arm_lms_instance_f32 * S,
+ uint16_t numTaps,
+ float32_t * pCoeffs,
+ float32_t * pState,
+ float32_t mu,
+ uint32_t blockSize);
+
+ /**
+ * @brief Instance structure for the Q15 LMS filter.
+ */
+
+ typedef struct
+ {
+ uint16_t numTaps; /**< number of coefficients in the filter. */
+ q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+ q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */
+ q15_t mu; /**< step size that controls filter coefficient updates. */
+ uint32_t postShift; /**< bit shift applied to coefficients. */
+ } arm_lms_instance_q15;
+
+
+ /**
+ * @brief Initialization function for the Q15 LMS filter.
+ * @param[in] *S points to an instance of the Q15 LMS filter structure.
+ * @param[in] numTaps number of filter coefficients.
+ * @param[in] *pCoeffs points to the coefficient buffer.
+ * @param[in] *pState points to the state buffer.
+ * @param[in] mu step size that controls filter coefficient updates.
+ * @param[in] blockSize number of samples to process.
+ * @param[in] postShift bit shift applied to coefficients.
+ * @return none.
+ */
+
+ void arm_lms_init_q15(
+ arm_lms_instance_q15 * S,
+ uint16_t numTaps,
+ q15_t * pCoeffs,
+ q15_t * pState,
+ q15_t mu,
+ uint32_t blockSize,
+ uint32_t postShift);
+
+ /**
+ * @brief Processing function for Q15 LMS filter.
+ * @param[in] *S points to an instance of the Q15 LMS filter structure.
+ * @param[in] *pSrc points to the block of input data.
+ * @param[in] *pRef points to the block of reference data.
+ * @param[out] *pOut points to the block of output data.
+ * @param[out] *pErr points to the block of error data.
+ * @param[in] blockSize number of samples to process.
+ * @return none.
+ */
+
+ void arm_lms_q15(
+ const arm_lms_instance_q15 * S,
+ q15_t * pSrc,
+ q15_t * pRef,
+ q15_t * pOut,
+ q15_t * pErr,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Instance structure for the Q31 LMS filter.
+ */
+
+ typedef struct
+ {
+ uint16_t numTaps; /**< number of coefficients in the filter. */
+ q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+ q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */
+ q31_t mu; /**< step size that controls filter coefficient updates. */
+ uint32_t postShift; /**< bit shift applied to coefficients. */
+
+ } arm_lms_instance_q31;
+
+ /**
+ * @brief Processing function for Q31 LMS filter.
+ * @param[in] *S points to an instance of the Q15 LMS filter structure.
+ * @param[in] *pSrc points to the block of input data.
+ * @param[in] *pRef points to the block of reference data.
+ * @param[out] *pOut points to the block of output data.
+ * @param[out] *pErr points to the block of error data.
+ * @param[in] blockSize number of samples to process.
+ * @return none.
+ */
+
+ void arm_lms_q31(
+ const arm_lms_instance_q31 * S,
+ q31_t * pSrc,
+ q31_t * pRef,
+ q31_t * pOut,
+ q31_t * pErr,
+ uint32_t blockSize);
+
+ /**
+ * @brief Initialization function for Q31 LMS filter.
+ * @param[in] *S points to an instance of the Q31 LMS filter structure.
+ * @param[in] numTaps number of filter coefficients.
+ * @param[in] *pCoeffs points to coefficient buffer.
+ * @param[in] *pState points to state buffer.
+ * @param[in] mu step size that controls filter coefficient updates.
+ * @param[in] blockSize number of samples to process.
+ * @param[in] postShift bit shift applied to coefficients.
+ * @return none.
+ */
+
+ void arm_lms_init_q31(
+ arm_lms_instance_q31 * S,
+ uint16_t numTaps,
+ q31_t *pCoeffs,
+ q31_t *pState,
+ q31_t mu,
+ uint32_t blockSize,
+ uint32_t postShift);
+
+ /**
+ * @brief Instance structure for the floating-point normalized LMS filter.
+ */
+
+ typedef struct
+ {
+ uint16_t numTaps; /**< number of coefficients in the filter. */
+ float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+ float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */
+ float32_t mu; /**< step size that control filter coefficient updates. */
+ float32_t energy; /**< saves previous frame energy. */
+ float32_t x0; /**< saves previous input sample. */
+ } arm_lms_norm_instance_f32;
+
+ /**
+ * @brief Processing function for floating-point normalized LMS filter.
+ * @param[in] *S points to an instance of the floating-point normalized LMS filter structure.
+ * @param[in] *pSrc points to the block of input data.
+ * @param[in] *pRef points to the block of reference data.
+ * @param[out] *pOut points to the block of output data.
+ * @param[out] *pErr points to the block of error data.
+ * @param[in] blockSize number of samples to process.
+ * @return none.
+ */
+
+ void arm_lms_norm_f32(
+ arm_lms_norm_instance_f32 * S,
+ float32_t * pSrc,
+ float32_t * pRef,
+ float32_t * pOut,
+ float32_t * pErr,
+ uint32_t blockSize);
+
+ /**
+ * @brief Initialization function for floating-point normalized LMS filter.
+ * @param[in] *S points to an instance of the floating-point LMS filter structure.
+ * @param[in] numTaps number of filter coefficients.
+ * @param[in] *pCoeffs points to coefficient buffer.
+ * @param[in] *pState points to state buffer.
+ * @param[in] mu step size that controls filter coefficient updates.
+ * @param[in] blockSize number of samples to process.
+ * @return none.
+ */
+
+ void arm_lms_norm_init_f32(
+ arm_lms_norm_instance_f32 * S,
+ uint16_t numTaps,
+ float32_t * pCoeffs,
+ float32_t * pState,
+ float32_t mu,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Instance structure for the Q31 normalized LMS filter.
+ */
+ typedef struct
+ {
+ uint16_t numTaps; /**< number of coefficients in the filter. */
+ q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+ q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */
+ q31_t mu; /**< step size that controls filter coefficient updates. */
+ uint8_t postShift; /**< bit shift applied to coefficients. */
+ q31_t *recipTable; /**< points to the reciprocal initial value table. */
+ q31_t energy; /**< saves previous frame energy. */
+ q31_t x0; /**< saves previous input sample. */
+ } arm_lms_norm_instance_q31;
+
+ /**
+ * @brief Processing function for Q31 normalized LMS filter.
+ * @param[in] *S points to an instance of the Q31 normalized LMS filter structure.
+ * @param[in] *pSrc points to the block of input data.
+ * @param[in] *pRef points to the block of reference data.
+ * @param[out] *pOut points to the block of output data.
+ * @param[out] *pErr points to the block of error data.
+ * @param[in] blockSize number of samples to process.
+ * @return none.
+ */
+
+ void arm_lms_norm_q31(
+ arm_lms_norm_instance_q31 * S,
+ q31_t * pSrc,
+ q31_t * pRef,
+ q31_t * pOut,
+ q31_t * pErr,
+ uint32_t blockSize);
+
+ /**
+ * @brief Initialization function for Q31 normalized LMS filter.
+ * @param[in] *S points to an instance of the Q31 normalized LMS filter structure.
+ * @param[in] numTaps number of filter coefficients.
+ * @param[in] *pCoeffs points to coefficient buffer.
+ * @param[in] *pState points to state buffer.
+ * @param[in] mu step size that controls filter coefficient updates.
+ * @param[in] blockSize number of samples to process.
+ * @param[in] postShift bit shift applied to coefficients.
+ * @return none.
+ */
+
+ void arm_lms_norm_init_q31(
+ arm_lms_norm_instance_q31 * S,
+ uint16_t numTaps,
+ q31_t * pCoeffs,
+ q31_t * pState,
+ q31_t mu,
+ uint32_t blockSize,
+ uint8_t postShift);
+
+ /**
+ * @brief Instance structure for the Q15 normalized LMS filter.
+ */
+
+ typedef struct
+ {
+ uint16_t numTaps; /**< Number of coefficients in the filter. */
+ q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */
+ q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */
+ q15_t mu; /**< step size that controls filter coefficient updates. */
+ uint8_t postShift; /**< bit shift applied to coefficients. */
+ q15_t *recipTable; /**< Points to the reciprocal initial value table. */
+ q15_t energy; /**< saves previous frame energy. */
+ q15_t x0; /**< saves previous input sample. */
+ } arm_lms_norm_instance_q15;
+
+ /**
+ * @brief Processing function for Q15 normalized LMS filter.
+ * @param[in] *S points to an instance of the Q15 normalized LMS filter structure.
+ * @param[in] *pSrc points to the block of input data.
+ * @param[in] *pRef points to the block of reference data.
+ * @param[out] *pOut points to the block of output data.
+ * @param[out] *pErr points to the block of error data.
+ * @param[in] blockSize number of samples to process.
+ * @return none.
+ */
+
+ void arm_lms_norm_q15(
+ arm_lms_norm_instance_q15 * S,
+ q15_t * pSrc,
+ q15_t * pRef,
+ q15_t * pOut,
+ q15_t * pErr,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Initialization function for Q15 normalized LMS filter.
+ * @param[in] *S points to an instance of the Q15 normalized LMS filter structure.
+ * @param[in] numTaps number of filter coefficients.
+ * @param[in] *pCoeffs points to coefficient buffer.
+ * @param[in] *pState points to state buffer.
+ * @param[in] mu step size that controls filter coefficient updates.
+ * @param[in] blockSize number of samples to process.
+ * @param[in] postShift bit shift applied to coefficients.
+ * @return none.
+ */
+
+ void arm_lms_norm_init_q15(
+ arm_lms_norm_instance_q15 * S,
+ uint16_t numTaps,
+ q15_t * pCoeffs,
+ q15_t * pState,
+ q15_t mu,
+ uint32_t blockSize,
+ uint8_t postShift);
+
+ /**
+ * @brief Correlation of floating-point sequences.
+ * @param[in] *pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] *pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] *pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1.
+ * @return none.
+ */
+
+ void arm_correlate_f32(
+ float32_t * pSrcA,
+ uint32_t srcALen,
+ float32_t * pSrcB,
+ uint32_t srcBLen,
+ float32_t * pDst);
+
+ /**
+ * @brief Correlation of Q15 sequences.
+ * @param[in] *pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] *pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] *pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1.
+ * @return none.
+ */
+
+ void arm_correlate_q15(
+ q15_t * pSrcA,
+ uint32_t srcALen,
+ q15_t * pSrcB,
+ uint32_t srcBLen,
+ q15_t * pDst);
+
+ /**
+ * @brief Correlation of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4.
+ * @param[in] *pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] *pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] *pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1.
+ * @return none.
+ */
+
+ void arm_correlate_fast_q15(
+ q15_t * pSrcA,
+ uint32_t srcALen,
+ q15_t * pSrcB,
+ uint32_t srcBLen,
+ q15_t * pDst);
+
+ /**
+ * @brief Correlation of Q31 sequences.
+ * @param[in] *pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] *pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] *pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1.
+ * @return none.
+ */
+
+ void arm_correlate_q31(
+ q31_t * pSrcA,
+ uint32_t srcALen,
+ q31_t * pSrcB,
+ uint32_t srcBLen,
+ q31_t * pDst);
+
+ /**
+ * @brief Correlation of Q31 sequences (fast version) for Cortex-M3 and Cortex-M4
+ * @param[in] *pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] *pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] *pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1.
+ * @return none.
+ */
+
+ void arm_correlate_fast_q31(
+ q31_t * pSrcA,
+ uint32_t srcALen,
+ q31_t * pSrcB,
+ uint32_t srcBLen,
+ q31_t * pDst);
+
+ /**
+ * @brief Correlation of Q7 sequences.
+ * @param[in] *pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] *pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] *pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1.
+ * @return none.
+ */
+
+ void arm_correlate_q7(
+ q7_t * pSrcA,
+ uint32_t srcALen,
+ q7_t * pSrcB,
+ uint32_t srcBLen,
+ q7_t * pDst);
+
+ /**
+ * @brief Instance structure for the floating-point sparse FIR filter.
+ */
+ typedef struct
+ {
+ uint16_t numTaps; /**< number of coefficients in the filter. */
+ uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */
+ float32_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */
+ float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/
+ uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */
+ int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */
+ } arm_fir_sparse_instance_f32;
+
+ /**
+ * @brief Instance structure for the Q31 sparse FIR filter.
+ */
+
+ typedef struct
+ {
+ uint16_t numTaps; /**< number of coefficients in the filter. */
+ uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */
+ q31_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */
+ q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/
+ uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */
+ int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */
+ } arm_fir_sparse_instance_q31;
+
+ /**
+ * @brief Instance structure for the Q15 sparse FIR filter.
+ */
+
+ typedef struct
+ {
+ uint16_t numTaps; /**< number of coefficients in the filter. */
+ uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */
+ q15_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */
+ q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/
+ uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */
+ int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */
+ } arm_fir_sparse_instance_q15;
+
+ /**
+ * @brief Instance structure for the Q7 sparse FIR filter.
+ */
+
+ typedef struct
+ {
+ uint16_t numTaps; /**< number of coefficients in the filter. */
+ uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */
+ q7_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */
+ q7_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/
+ uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */
+ int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */
+ } arm_fir_sparse_instance_q7;
+
+ /**
+ * @brief Processing function for the floating-point sparse FIR filter.
+ * @param[in] *S points to an instance of the floating-point sparse FIR structure.
+ * @param[in] *pSrc points to the block of input data.
+ * @param[out] *pDst points to the block of output data
+ * @param[in] *pScratchIn points to a temporary buffer of size blockSize.
+ * @param[in] blockSize number of input samples to process per call.
+ * @return none.
+ */
+
+ void arm_fir_sparse_f32(
+ arm_fir_sparse_instance_f32 * S,
+ float32_t * pSrc,
+ float32_t * pDst,
+ float32_t * pScratchIn,
+ uint32_t blockSize);
+
+ /**
+ * @brief Initialization function for the floating-point sparse FIR filter.
+ * @param[in,out] *S points to an instance of the floating-point sparse FIR structure.
+ * @param[in] numTaps number of nonzero coefficients in the filter.
+ * @param[in] *pCoeffs points to the array of filter coefficients.
+ * @param[in] *pState points to the state buffer.
+ * @param[in] *pTapDelay points to the array of offset times.
+ * @param[in] maxDelay maximum offset time supported.
+ * @param[in] blockSize number of samples that will be processed per block.
+ * @return none
+ */
+
+ void arm_fir_sparse_init_f32(
+ arm_fir_sparse_instance_f32 * S,
+ uint16_t numTaps,
+ float32_t * pCoeffs,
+ float32_t * pState,
+ int32_t * pTapDelay,
+ uint16_t maxDelay,
+ uint32_t blockSize);
+
+ /**
+ * @brief Processing function for the Q31 sparse FIR filter.
+ * @param[in] *S points to an instance of the Q31 sparse FIR structure.
+ * @param[in] *pSrc points to the block of input data.
+ * @param[out] *pDst points to the block of output data
+ * @param[in] *pScratchIn points to a temporary buffer of size blockSize.
+ * @param[in] blockSize number of input samples to process per call.
+ * @return none.
+ */
+
+ void arm_fir_sparse_q31(
+ arm_fir_sparse_instance_q31 * S,
+ q31_t * pSrc,
+ q31_t * pDst,
+ q31_t * pScratchIn,
+ uint32_t blockSize);
+
+ /**
+ * @brief Initialization function for the Q31 sparse FIR filter.
+ * @param[in,out] *S points to an instance of the Q31 sparse FIR structure.
+ * @param[in] numTaps number of nonzero coefficients in the filter.
+ * @param[in] *pCoeffs points to the array of filter coefficients.
+ * @param[in] *pState points to the state buffer.
+ * @param[in] *pTapDelay points to the array of offset times.
+ * @param[in] maxDelay maximum offset time supported.
+ * @param[in] blockSize number of samples that will be processed per block.
+ * @return none
+ */
+
+ void arm_fir_sparse_init_q31(
+ arm_fir_sparse_instance_q31 * S,
+ uint16_t numTaps,
+ q31_t * pCoeffs,
+ q31_t * pState,
+ int32_t * pTapDelay,
+ uint16_t maxDelay,
+ uint32_t blockSize);
+
+ /**
+ * @brief Processing function for the Q15 sparse FIR filter.
+ * @param[in] *S points to an instance of the Q15 sparse FIR structure.
+ * @param[in] *pSrc points to the block of input data.
+ * @param[out] *pDst points to the block of output data
+ * @param[in] *pScratchIn points to a temporary buffer of size blockSize.
+ * @param[in] *pScratchOut points to a temporary buffer of size blockSize.
+ * @param[in] blockSize number of input samples to process per call.
+ * @return none.
+ */
+
+ void arm_fir_sparse_q15(
+ arm_fir_sparse_instance_q15 * S,
+ q15_t * pSrc,
+ q15_t * pDst,
+ q15_t * pScratchIn,
+ q31_t * pScratchOut,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Initialization function for the Q15 sparse FIR filter.
+ * @param[in,out] *S points to an instance of the Q15 sparse FIR structure.
+ * @param[in] numTaps number of nonzero coefficients in the filter.
+ * @param[in] *pCoeffs points to the array of filter coefficients.
+ * @param[in] *pState points to the state buffer.
+ * @param[in] *pTapDelay points to the array of offset times.
+ * @param[in] maxDelay maximum offset time supported.
+ * @param[in] blockSize number of samples that will be processed per block.
+ * @return none
+ */
+
+ void arm_fir_sparse_init_q15(
+ arm_fir_sparse_instance_q15 * S,
+ uint16_t numTaps,
+ q15_t * pCoeffs,
+ q15_t * pState,
+ int32_t * pTapDelay,
+ uint16_t maxDelay,
+ uint32_t blockSize);
+
+ /**
+ * @brief Processing function for the Q7 sparse FIR filter.
+ * @param[in] *S points to an instance of the Q7 sparse FIR structure.
+ * @param[in] *pSrc points to the block of input data.
+ * @param[out] *pDst points to the block of output data
+ * @param[in] *pScratchIn points to a temporary buffer of size blockSize.
+ * @param[in] *pScratchOut points to a temporary buffer of size blockSize.
+ * @param[in] blockSize number of input samples to process per call.
+ * @return none.
+ */
+
+ void arm_fir_sparse_q7(
+ arm_fir_sparse_instance_q7 * S,
+ q7_t * pSrc,
+ q7_t * pDst,
+ q7_t * pScratchIn,
+ q31_t * pScratchOut,
+ uint32_t blockSize);
+
+ /**
+ * @brief Initialization function for the Q7 sparse FIR filter.
+ * @param[in,out] *S points to an instance of the Q7 sparse FIR structure.
+ * @param[in] numTaps number of nonzero coefficients in the filter.
+ * @param[in] *pCoeffs points to the array of filter coefficients.
+ * @param[in] *pState points to the state buffer.
+ * @param[in] *pTapDelay points to the array of offset times.
+ * @param[in] maxDelay maximum offset time supported.
+ * @param[in] blockSize number of samples that will be processed per block.
+ * @return none
+ */
+
+ void arm_fir_sparse_init_q7(
+ arm_fir_sparse_instance_q7 * S,
+ uint16_t numTaps,
+ q7_t * pCoeffs,
+ q7_t * pState,
+ int32_t *pTapDelay,
+ uint16_t maxDelay,
+ uint32_t blockSize);
+
+
+ /*
+ * @brief Floating-point sin_cos function.
+ * @param[in] theta input value in degrees
+ * @param[out] *pSinVal points to the processed sine output.
+ * @param[out] *pCosVal points to the processed cos output.
+ * @return none.
+ */
+
+ void arm_sin_cos_f32(
+ float32_t theta,
+ float32_t *pSinVal,
+ float32_t *pCcosVal);
+
+ /*
+ * @brief Q31 sin_cos function.
+ * @param[in] theta scaled input value in degrees
+ * @param[out] *pSinVal points to the processed sine output.
+ * @param[out] *pCosVal points to the processed cosine output.
+ * @return none.
+ */
+
+ void arm_sin_cos_q31(
+ q31_t theta,
+ q31_t *pSinVal,
+ q31_t *pCosVal);
+
+
+ /**
+ * @brief Floating-point complex conjugate.
+ * @param[in] *pSrc points to the input vector
+ * @param[out] *pDst points to the output vector
+ * @param[in] numSamples number of complex samples in each vector
+ * @return none.
+ */
+
+ void arm_cmplx_conj_f32(
+ float32_t * pSrc,
+ float32_t * pDst,
+ uint32_t numSamples);
+
+ /**
+ * @brief Q31 complex conjugate.
+ * @param[in] *pSrc points to the input vector
+ * @param[out] *pDst points to the output vector
+ * @param[in] numSamples number of complex samples in each vector
+ * @return none.
+ */
+
+ void arm_cmplx_conj_q31(
+ q31_t * pSrc,
+ q31_t * pDst,
+ uint32_t numSamples);
+
+ /**
+ * @brief Q15 complex conjugate.
+ * @param[in] *pSrc points to the input vector
+ * @param[out] *pDst points to the output vector
+ * @param[in] numSamples number of complex samples in each vector
+ * @return none.
+ */
+
+ void arm_cmplx_conj_q15(
+ q15_t * pSrc,
+ q15_t * pDst,
+ uint32_t numSamples);
+
+
+
+ /**
+ * @brief Floating-point complex magnitude squared
+ * @param[in] *pSrc points to the complex input vector
+ * @param[out] *pDst points to the real output vector
+ * @param[in] numSamples number of complex samples in the input vector
+ * @return none.
+ */
+
+ void arm_cmplx_mag_squared_f32(
+ float32_t * pSrc,
+ float32_t * pDst,
+ uint32_t numSamples);
+
+ /**
+ * @brief Q31 complex magnitude squared
+ * @param[in] *pSrc points to the complex input vector
+ * @param[out] *pDst points to the real output vector
+ * @param[in] numSamples number of complex samples in the input vector
+ * @return none.
+ */
+
+ void arm_cmplx_mag_squared_q31(
+ q31_t * pSrc,
+ q31_t * pDst,
+ uint32_t numSamples);
+
+ /**
+ * @brief Q15 complex magnitude squared
+ * @param[in] *pSrc points to the complex input vector
+ * @param[out] *pDst points to the real output vector
+ * @param[in] numSamples number of complex samples in the input vector
+ * @return none.
+ */
+
+ void arm_cmplx_mag_squared_q15(
+ q15_t * pSrc,
+ q15_t * pDst,
+ uint32_t numSamples);
+
+
+ /**
+ * @ingroup groupController
+ */
+
+ /**
+ * @defgroup PID PID Motor Control
+ *
+ * A Proportional Integral Derivative (PID) controller is a generic feedback control
+ * loop mechanism widely used in industrial control systems.
+ * A PID controller is the most commonly used type of feedback controller.
+ *
+ * This set of functions implements (PID) controllers
+ * for Q15, Q31, and floating-point data types. The functions operate on a single sample
+ * of data and each call to the function returns a single processed value.
+ * S points to an instance of the PID control data structure. in
+ * is the input sample value. The functions return the output value.
+ *
+ * \par Algorithm:
+ *
+ * y[n] = y[n-1] + A0 * x[n] + A1 * x[n-1] + A2 * x[n-2]
+ * A0 = Kp + Ki + Kd
+ * A1 = (-Kp ) - (2 * Kd )
+ * A2 = Kd
+ *
+ * \par
+ * where \c Kp is proportional constant, \c Ki is Integral constant and \c Kd is Derivative constant
+ *
+ * \par
+ * \image html PID.gif "Proportional Integral Derivative Controller"
+ *
+ * \par
+ * The PID controller calculates an "error" value as the difference between
+ * the measured output and the reference input.
+ * The controller attempts to minimize the error by adjusting the process control inputs.
+ * The proportional value determines the reaction to the current error,
+ * the integral value determines the reaction based on the sum of recent errors,
+ * and the derivative value determines the reaction based on the rate at which the error has been changing.
+ *
+ * \par Instance Structure
+ * The Gains A0, A1, A2 and state variables for a PID controller are stored together in an instance data structure.
+ * A separate instance structure must be defined for each PID Controller.
+ * There are separate instance structure declarations for each of the 3 supported data types.
+ *
+ * \par Reset Functions
+ * There is also an associated reset function for each data type which clears the state array.
+ *
+ * \par Initialization Functions
+ * There is also an associated initialization function for each data type.
+ * The initialization function performs the following operations:
+ * - Initializes the Gains A0, A1, A2 from Kp,Ki, Kd gains.
+ * - Zeros out the values in the state buffer.
+ *
+ * \par
+ * Instance structure cannot be placed into a const data section and it is recommended to use the initialization function.
+ *
+ * \par Fixed-Point Behavior
+ * Care must be taken when using the fixed-point versions of the PID Controller functions.
+ * In particular, the overflow and saturation behavior of the accumulator used in each function must be considered.
+ * Refer to the function specific documentation below for usage guidelines.
+ */
+
+ /**
+ * @addtogroup PID
+ * @{
+ */
+
+ /**
+ * @brief Process function for the floating-point PID Control.
+ * @param[in,out] *S is an instance of the floating-point PID Control structure
+ * @param[in] in input sample to process
+ * @return out processed output sample.
+ */
+
+
+ static __INLINE float32_t arm_pid_f32(
+ arm_pid_instance_f32 * S,
+ float32_t in)
+ {
+ float32_t out;
+
+ /* y[n] = y[n-1] + A0 * x[n] + A1 * x[n-1] + A2 * x[n-2] */
+ out = (S->A0 * in) +
+ (S->A1 * S->state[0]) + (S->A2 * S->state[1]) + (S->state[2]);
+
+ /* Update state */
+ S->state[1] = S->state[0];
+ S->state[0] = in;
+ S->state[2] = out;
+
+ /* return to application */
+ return (out);
+
+ }
+
+ /**
+ * @brief Process function for the Q31 PID Control.
+ * @param[in,out] *S points to an instance of the Q31 PID Control structure
+ * @param[in] in input sample to process
+ * @return out processed output sample.
+ *
+ * Scaling and Overflow Behavior:
+ * \par
+ * The function is implemented using an internal 64-bit accumulator.
+ * The accumulator has a 2.62 format and maintains full precision of the intermediate multiplication results but provides only a single guard bit.
+ * Thus, if the accumulator result overflows it wraps around rather than clip.
+ * In order to avoid overflows completely the input signal must be scaled down by 2 bits as there are four additions.
+ * After all multiply-accumulates are performed, the 2.62 accumulator is truncated to 1.32 format and then saturated to 1.31 format.
+ */
+
+ static __INLINE q31_t arm_pid_q31(
+ arm_pid_instance_q31 * S,
+ q31_t in)
+ {
+ q63_t acc;
+ q31_t out;
+
+ /* acc = A0 * x[n] */
+ acc = (q63_t) S->A0 * in;
+
+ /* acc += A1 * x[n-1] */
+ acc += (q63_t) S->A1 * S->state[0];
+
+ /* acc += A2 * x[n-2] */
+ acc += (q63_t) S->A2 * S->state[1];
+
+ /* convert output to 1.31 format to add y[n-1] */
+ out = (q31_t) (acc >> 31u);
+
+ /* out += y[n-1] */
+ out += S->state[2];
+
+ /* Update state */
+ S->state[1] = S->state[0];
+ S->state[0] = in;
+ S->state[2] = out;
+
+ /* return to application */
+ return (out);
+
+ }
+
+ /**
+ * @brief Process function for the Q15 PID Control.
+ * @param[in,out] *S points to an instance of the Q15 PID Control structure
+ * @param[in] in input sample to process
+ * @return out processed output sample.
+ *
+ * Scaling and Overflow Behavior:
+ * \par
+ * The function is implemented using a 64-bit internal accumulator.
+ * Both Gains and state variables are represented in 1.15 format and multiplications yield a 2.30 result.
+ * The 2.30 intermediate results are accumulated in a 64-bit accumulator in 34.30 format.
+ * There is no risk of internal overflow with this approach and the full precision of intermediate multiplications is preserved.
+ * After all additions have been performed, the accumulator is truncated to 34.15 format by discarding low 15 bits.
+ * Lastly, the accumulator is saturated to yield a result in 1.15 format.
+ */
+
+ static __INLINE q15_t arm_pid_q15(
+ arm_pid_instance_q15 * S,
+ q15_t in)
+ {
+ q63_t acc;
+ q15_t out;
+
+ /* Implementation of PID controller */
+
+ #ifdef ARM_MATH_CM0
+
+ /* acc = A0 * x[n] */
+ acc = ((q31_t) S->A0 )* in ;
+
+ #else
+
+ /* acc = A0 * x[n] */
+ acc = (q31_t) __SMUAD(S->A0, in);
+
+ #endif
+
+ #ifdef ARM_MATH_CM0
+
+ /* acc += A1 * x[n-1] + A2 * x[n-2] */
+ acc += (q31_t) S->A1 * S->state[0] ;
+ acc += (q31_t) S->A2 * S->state[1] ;
+
+ #else
+
+ /* acc += A1 * x[n-1] + A2 * x[n-2] */
+ acc = __SMLALD(S->A1, (q31_t)__SIMD32(S->state), acc);
+
+ #endif
+
+ /* acc += y[n-1] */
+ acc += (q31_t) S->state[2] << 15;
+
+ /* saturate the output */
+ out = (q15_t) (__SSAT((acc >> 15), 16));
+
+ /* Update state */
+ S->state[1] = S->state[0];
+ S->state[0] = in;
+ S->state[2] = out;
+
+ /* return to application */
+ return (out);
+
+ }
+
+ /**
+ * @} end of PID group
+ */
+
+
+ /**
+ * @brief Floating-point matrix inverse.
+ * @param[in] *src points to the instance of the input floating-point matrix structure.
+ * @param[out] *dst points to the instance of the output floating-point matrix structure.
+ * @return The function returns ARM_MATH_SIZE_MISMATCH, if the dimensions do not match.
+ * If the input matrix is singular (does not have an inverse), then the algorithm terminates and returns error status ARM_MATH_SINGULAR.
+ */
+
+ arm_status arm_mat_inverse_f32(
+ const arm_matrix_instance_f32 * src,
+ arm_matrix_instance_f32 * dst);
+
+
+
+ /**
+ * @ingroup groupController
+ */
+
+
+ /**
+ * @defgroup clarke Vector Clarke Transform
+ * Forward Clarke transform converts the instantaneous stator phases into a two-coordinate time invariant vector.
+ * Generally the Clarke transform uses three-phase currents Ia, Ib and Ic to calculate currents
+ * in the two-phase orthogonal stator axis Ialpha and Ibeta.
+ * When Ialpha is superposed with Ia as shown in the figure below
+ * \image html clarke.gif Stator current space vector and its components in (a,b).
+ * and Ia + Ib + Ic = 0, in this condition Ialpha and Ibeta
+ * can be calculated using only Ia and Ib.
+ *
+ * The function operates on a single sample of data and each call to the function returns the processed output.
+ * The library provides separate functions for Q31 and floating-point data types.
+ * \par Algorithm
+ * \image html clarkeFormula.gif
+ * where Ia and Ib are the instantaneous stator phases and
+ * pIalpha and pIbeta are the two coordinates of time invariant vector.
+ * \par Fixed-Point Behavior
+ * Care must be taken when using the Q31 version of the Clarke transform.
+ * In particular, the overflow and saturation behavior of the accumulator used must be considered.
+ * Refer to the function specific documentation below for usage guidelines.
+ */
+
+ /**
+ * @addtogroup clarke
+ * @{
+ */
+
+ /**
+ *
+ * @brief Floating-point Clarke transform
+ * @param[in] Ia input three-phase coordinate a
+ * @param[in] Ib input three-phase coordinate b
+ * @param[out] *pIalpha points to output two-phase orthogonal vector axis alpha
+ * @param[out] *pIbeta points to output two-phase orthogonal vector axis beta
+ * @return none.
+ */
+
+ static __INLINE void arm_clarke_f32(
+ float32_t Ia,
+ float32_t Ib,
+ float32_t * pIalpha,
+ float32_t * pIbeta)
+ {
+ /* Calculate pIalpha using the equation, pIalpha = Ia */
+ *pIalpha = Ia;
+
+ /* Calculate pIbeta using the equation, pIbeta = (1/sqrt(3)) * Ia + (2/sqrt(3)) * Ib */
+ *pIbeta = ((float32_t) 0.57735026919 * Ia + (float32_t) 1.15470053838 * Ib);
+
+ }
+
+ /**
+ * @brief Clarke transform for Q31 version
+ * @param[in] Ia input three-phase coordinate a
+ * @param[in] Ib input three-phase coordinate b
+ * @param[out] *pIalpha points to output two-phase orthogonal vector axis alpha
+ * @param[out] *pIbeta points to output two-phase orthogonal vector axis beta
+ * @return none.
+ *
+ * Scaling and Overflow Behavior:
+ * \par
+ * The function is implemented using an internal 32-bit accumulator.
+ * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format.
+ * There is saturation on the addition, hence there is no risk of overflow.
+ */
+
+ static __INLINE void arm_clarke_q31(
+ q31_t Ia,
+ q31_t Ib,
+ q31_t * pIalpha,
+ q31_t * pIbeta)
+ {
+ q31_t product1, product2; /* Temporary variables used to store intermediate results */
+
+ /* Calculating pIalpha from Ia by equation pIalpha = Ia */
+ *pIalpha = Ia;
+
+ /* Intermediate product is calculated by (1/(sqrt(3)) * Ia) */
+ product1 = (q31_t) (((q63_t) Ia * 0x24F34E8B) >> 30);
+
+ /* Intermediate product is calculated by (2/sqrt(3) * Ib) */
+ product2 = (q31_t) (((q63_t) Ib * 0x49E69D16) >> 30);
+
+ /* pIbeta is calculated by adding the intermediate products */
+ *pIbeta = __QADD(product1, product2);
+ }
+
+ /**
+ * @} end of clarke group
+ */
+
+ /**
+ * @brief Converts the elements of the Q7 vector to Q31 vector.
+ * @param[in] *pSrc input pointer
+ * @param[out] *pDst output pointer
+ * @param[in] blockSize number of samples to process
+ * @return none.
+ */
+ void arm_q7_to_q31(
+ q7_t * pSrc,
+ q31_t * pDst,
+ uint32_t blockSize);
+
+
+
+
+ /**
+ * @ingroup groupController
+ */
+
+ /**
+ * @defgroup inv_clarke Vector Inverse Clarke Transform
+ * Inverse Clarke transform converts the two-coordinate time invariant vector into instantaneous stator phases.
+ *
+ * The function operates on a single sample of data and each call to the function returns the processed output.
+ * The library provides separate functions for Q31 and floating-point data types.
+ * \par Algorithm
+ * \image html clarkeInvFormula.gif
+ * where pIa and pIb are the instantaneous stator phases and
+ * Ialpha and Ibeta are the two coordinates of time invariant vector.
+ * \par Fixed-Point Behavior
+ * Care must be taken when using the Q31 version of the Clarke transform.
+ * In particular, the overflow and saturation behavior of the accumulator used must be considered.
+ * Refer to the function specific documentation below for usage guidelines.
+ */
+
+ /**
+ * @addtogroup inv_clarke
+ * @{
+ */
+
+ /**
+ * @brief Floating-point Inverse Clarke transform
+ * @param[in] Ialpha input two-phase orthogonal vector axis alpha
+ * @param[in] Ibeta input two-phase orthogonal vector axis beta
+ * @param[out] *pIa points to output three-phase coordinate a
+ * @param[out] *pIb points to output three-phase coordinate b
+ * @return none.
+ */
+
+
+ static __INLINE void arm_inv_clarke_f32(
+ float32_t Ialpha,
+ float32_t Ibeta,
+ float32_t * pIa,
+ float32_t * pIb)
+ {
+ /* Calculating pIa from Ialpha by equation pIa = Ialpha */
+ *pIa = Ialpha;
+
+ /* Calculating pIb from Ialpha and Ibeta by equation pIb = -(1/2) * Ialpha + (sqrt(3)/2) * Ibeta */
+ *pIb = -0.5 * Ialpha + (float32_t) 0.8660254039 *Ibeta;
+
+ }
+
+ /**
+ * @brief Inverse Clarke transform for Q31 version
+ * @param[in] Ialpha input two-phase orthogonal vector axis alpha
+ * @param[in] Ibeta input two-phase orthogonal vector axis beta
+ * @param[out] *pIa points to output three-phase coordinate a
+ * @param[out] *pIb points to output three-phase coordinate b
+ * @return none.
+ *
+ * Scaling and Overflow Behavior:
+ * \par
+ * The function is implemented using an internal 32-bit accumulator.
+ * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format.
+ * There is saturation on the subtraction, hence there is no risk of overflow.
+ */
+
+ static __INLINE void arm_inv_clarke_q31(
+ q31_t Ialpha,
+ q31_t Ibeta,
+ q31_t * pIa,
+ q31_t * pIb)
+ {
+ q31_t product1, product2; /* Temporary variables used to store intermediate results */
+
+ /* Calculating pIa from Ialpha by equation pIa = Ialpha */
+ *pIa = Ialpha;
+
+ /* Intermediate product is calculated by (1/(2*sqrt(3)) * Ia) */
+ product1 = (q31_t) (((q63_t) (Ialpha) * (0x40000000)) >> 31);
+
+ /* Intermediate product is calculated by (1/sqrt(3) * pIb) */
+ product2 = (q31_t) (((q63_t) (Ibeta) * (0x6ED9EBA1)) >> 31);
+
+ /* pIb is calculated by subtracting the products */
+ *pIb = __QSUB(product2, product1);
+
+ }
+
+ /**
+ * @} end of inv_clarke group
+ */
+
+ /**
+ * @brief Converts the elements of the Q7 vector to Q15 vector.
+ * @param[in] *pSrc input pointer
+ * @param[out] *pDst output pointer
+ * @param[in] blockSize number of samples to process
+ * @return none.
+ */
+ void arm_q7_to_q15(
+ q7_t * pSrc,
+ q15_t * pDst,
+ uint32_t blockSize);
+
+
+
+ /**
+ * @ingroup groupController
+ */
+
+ /**
+ * @defgroup park Vector Park Transform
+ *
+ * Forward Park transform converts the input two-coordinate vector to flux and torque components.
+ * The Park transform can be used to realize the transformation of the Ialpha and the Ibeta currents
+ * from the stationary to the moving reference frame and control the spatial relationship between
+ * the stator vector current and rotor flux vector.
+ * If we consider the d axis aligned with the rotor flux, the diagram below shows the
+ * current vector and the relationship from the two reference frames:
+ * \image html park.gif "Stator current space vector and its component in (a,b) and in the d,q rotating reference frame"
+ *
+ * The function operates on a single sample of data and each call to the function returns the processed output.
+ * The library provides separate functions for Q31 and floating-point data types.
+ * \par Algorithm
+ * \image html parkFormula.gif
+ * where Ialpha and Ibeta are the stator vector components,
+ * pId and pIq are rotor vector components and cosVal and sinVal are the
+ * cosine and sine values of theta (rotor flux position).
+ * \par Fixed-Point Behavior
+ * Care must be taken when using the Q31 version of the Park transform.
+ * In particular, the overflow and saturation behavior of the accumulator used must be considered.
+ * Refer to the function specific documentation below for usage guidelines.
+ */
+
+ /**
+ * @addtogroup park
+ * @{
+ */
+
+ /**
+ * @brief Floating-point Park transform
+ * @param[in] Ialpha input two-phase vector coordinate alpha
+ * @param[in] Ibeta input two-phase vector coordinate beta
+ * @param[out] *pId points to output rotor reference frame d
+ * @param[out] *pIq points to output rotor reference frame q
+ * @param[in] sinVal sine value of rotation angle theta
+ * @param[in] cosVal cosine value of rotation angle theta
+ * @return none.
+ *
+ * The function implements the forward Park transform.
+ *
+ */
+
+ static __INLINE void arm_park_f32(
+ float32_t Ialpha,
+ float32_t Ibeta,
+ float32_t * pId,
+ float32_t * pIq,
+ float32_t sinVal,
+ float32_t cosVal)
+ {
+ /* Calculate pId using the equation, pId = Ialpha * cosVal + Ibeta * sinVal */
+ *pId = Ialpha * cosVal + Ibeta * sinVal;
+
+ /* Calculate pIq using the equation, pIq = - Ialpha * sinVal + Ibeta * cosVal */
+ *pIq = -Ialpha * sinVal + Ibeta * cosVal;
+
+ }
+
+ /**
+ * @brief Park transform for Q31 version
+ * @param[in] Ialpha input two-phase vector coordinate alpha
+ * @param[in] Ibeta input two-phase vector coordinate beta
+ * @param[out] *pId points to output rotor reference frame d
+ * @param[out] *pIq points to output rotor reference frame q
+ * @param[in] sinVal sine value of rotation angle theta
+ * @param[in] cosVal cosine value of rotation angle theta
+ * @return none.
+ *
+ * Scaling and Overflow Behavior:
+ * \par
+ * The function is implemented using an internal 32-bit accumulator.
+ * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format.
+ * There is saturation on the addition and subtraction, hence there is no risk of overflow.
+ */
+
+
+ static __INLINE void arm_park_q31(
+ q31_t Ialpha,
+ q31_t Ibeta,
+ q31_t * pId,
+ q31_t * pIq,
+ q31_t sinVal,
+ q31_t cosVal)
+ {
+ q31_t product1, product2; /* Temporary variables used to store intermediate results */
+ q31_t product3, product4; /* Temporary variables used to store intermediate results */
+
+ /* Intermediate product is calculated by (Ialpha * cosVal) */
+ product1 = (q31_t) (((q63_t) (Ialpha) * (cosVal)) >> 31);
+
+ /* Intermediate product is calculated by (Ibeta * sinVal) */
+ product2 = (q31_t) (((q63_t) (Ibeta) * (sinVal)) >> 31);
+
+
+ /* Intermediate product is calculated by (Ialpha * sinVal) */
+ product3 = (q31_t) (((q63_t) (Ialpha) * (sinVal)) >> 31);
+
+ /* Intermediate product is calculated by (Ibeta * cosVal) */
+ product4 = (q31_t) (((q63_t) (Ibeta) * (cosVal)) >> 31);
+
+ /* Calculate pId by adding the two intermediate products 1 and 2 */
+ *pId = __QADD(product1, product2);
+
+ /* Calculate pIq by subtracting the two intermediate products 3 from 4 */
+ *pIq = __QSUB(product4, product3);
+ }
+
+ /**
+ * @} end of park group
+ */
+
+ /**
+ * @brief Converts the elements of the Q7 vector to floating-point vector.
+ * @param[in] *pSrc is input pointer
+ * @param[out] *pDst is output pointer
+ * @param[in] blockSize is the number of samples to process
+ * @return none.
+ */
+ void arm_q7_to_float(
+ q7_t * pSrc,
+ float32_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @ingroup groupController
+ */
+
+ /**
+ * @defgroup inv_park Vector Inverse Park transform
+ * Inverse Park transform converts the input flux and torque components to two-coordinate vector.
+ *
+ * The function operates on a single sample of data and each call to the function returns the processed output.
+ * The library provides separate functions for Q31 and floating-point data types.
+ * \par Algorithm
+ * \image html parkInvFormula.gif
+ * where pIalpha and pIbeta are the stator vector components,
+ * Id and Iq are rotor vector components and cosVal and sinVal are the
+ * cosine and sine values of theta (rotor flux position).
+ * \par Fixed-Point Behavior
+ * Care must be taken when using the Q31 version of the Park transform.
+ * In particular, the overflow and saturation behavior of the accumulator used must be considered.
+ * Refer to the function specific documentation below for usage guidelines.
+ */
+
+ /**
+ * @addtogroup inv_park
+ * @{
+ */
+
+ /**
+ * @brief Floating-point Inverse Park transform
+ * @param[in] Id input coordinate of rotor reference frame d
+ * @param[in] Iq input coordinate of rotor reference frame q
+ * @param[out] *pIalpha points to output two-phase orthogonal vector axis alpha
+ * @param[out] *pIbeta points to output two-phase orthogonal vector axis beta
+ * @param[in] sinVal sine value of rotation angle theta
+ * @param[in] cosVal cosine value of rotation angle theta
+ * @return none.
+ */
+
+ static __INLINE void arm_inv_park_f32(
+ float32_t Id,
+ float32_t Iq,
+ float32_t * pIalpha,
+ float32_t * pIbeta,
+ float32_t sinVal,
+ float32_t cosVal)
+ {
+ /* Calculate pIalpha using the equation, pIalpha = Id * cosVal - Iq * sinVal */
+ *pIalpha = Id * cosVal - Iq * sinVal;
+
+ /* Calculate pIbeta using the equation, pIbeta = Id * sinVal + Iq * cosVal */
+ *pIbeta = Id * sinVal + Iq * cosVal;
+
+ }
+
+
+ /**
+ * @brief Inverse Park transform for Q31 version
+ * @param[in] Id input coordinate of rotor reference frame d
+ * @param[in] Iq input coordinate of rotor reference frame q
+ * @param[out] *pIalpha points to output two-phase orthogonal vector axis alpha
+ * @param[out] *pIbeta points to output two-phase orthogonal vector axis beta
+ * @param[in] sinVal sine value of rotation angle theta
+ * @param[in] cosVal cosine value of rotation angle theta
+ * @return none.
+ *
+ * Scaling and Overflow Behavior:
+ * \par
+ * The function is implemented using an internal 32-bit accumulator.
+ * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format.
+ * There is saturation on the addition, hence there is no risk of overflow.
+ */
+
+
+ static __INLINE void arm_inv_park_q31(
+ q31_t Id,
+ q31_t Iq,
+ q31_t * pIalpha,
+ q31_t * pIbeta,
+ q31_t sinVal,
+ q31_t cosVal)
+ {
+ q31_t product1, product2; /* Temporary variables used to store intermediate results */
+ q31_t product3, product4; /* Temporary variables used to store intermediate results */
+
+ /* Intermediate product is calculated by (Id * cosVal) */
+ product1 = (q31_t) (((q63_t) (Id) * (cosVal)) >> 31);
+
+ /* Intermediate product is calculated by (Iq * sinVal) */
+ product2 = (q31_t) (((q63_t) (Iq) * (sinVal)) >> 31);
+
+
+ /* Intermediate product is calculated by (Id * sinVal) */
+ product3 = (q31_t) (((q63_t) (Id) * (sinVal)) >> 31);
+
+ /* Intermediate product is calculated by (Iq * cosVal) */
+ product4 = (q31_t) (((q63_t) (Iq) * (cosVal)) >> 31);
+
+ /* Calculate pIalpha by using the two intermediate products 1 and 2 */
+ *pIalpha = __QSUB(product1, product2);
+
+ /* Calculate pIbeta by using the two intermediate products 3 and 4 */
+ *pIbeta = __QADD(product4, product3);
+
+ }
+
+ /**
+ * @} end of Inverse park group
+ */
+
+
+ /**
+ * @brief Converts the elements of the Q31 vector to floating-point vector.
+ * @param[in] *pSrc is input pointer
+ * @param[out] *pDst is output pointer
+ * @param[in] blockSize is the number of samples to process
+ * @return none.
+ */
+ void arm_q31_to_float(
+ q31_t * pSrc,
+ float32_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @ingroup groupInterpolation
+ */
+
+ /**
+ * @defgroup LinearInterpolate Linear Interpolation
+ *
+ * Linear interpolation is a method of curve fitting using linear polynomials.
+ * Linear interpolation works by effectively drawing a straight line between two neighboring samples and returning the appropriate point along that line
+ *
+ * \par
+ * \image html LinearInterp.gif "Linear interpolation"
+ *
+ * \par
+ * A Linear Interpolate function calculates an output value(y), for the input(x)
+ * using linear interpolation of the input values x0, x1( nearest input values) and the output values y0 and y1(nearest output values)
+ *
+ * \par Algorithm:
+ *
+ * y = y0 + (x - x0) * ((y1 - y0)/(x1-x0))
+ * where x0, x1 are nearest values of input x
+ * y0, y1 are nearest values to output y
+ *
+ *
+ * \par
+ * This set of functions implements Linear interpolation process
+ * for Q7, Q15, Q31, and floating-point data types. The functions operate on a single
+ * sample of data and each call to the function returns a single processed value.
+ * S points to an instance of the Linear Interpolate function data structure.
+ * x is the input sample value. The functions returns the output value.
+ *
+ * \par
+ * if x is outside of the table boundary, Linear interpolation returns first value of the table
+ * if x is below input range and returns last value of table if x is above range.
+ */
+
+ /**
+ * @addtogroup LinearInterpolate
+ * @{
+ */
+
+ /**
+ * @brief Process function for the floating-point Linear Interpolation Function.
+ * @param[in,out] *S is an instance of the floating-point Linear Interpolation structure
+ * @param[in] x input sample to process
+ * @return y processed output sample.
+ *
+ */
+
+ static __INLINE float32_t arm_linear_interp_f32(
+ arm_linear_interp_instance_f32 * S,
+ float32_t x)
+ {
+
+ float32_t y;
+ float32_t x0, x1; /* Nearest input values */
+ float32_t y0, y1; /* Nearest output values */
+ float32_t xSpacing = S->xSpacing; /* spacing between input values */
+ int32_t i; /* Index variable */
+ float32_t *pYData = S->pYData; /* pointer to output table */
+
+ /* Calculation of index */
+ i = (x - S->x1) / xSpacing;
+
+ if(i < 0)
+ {
+ /* Iniatilize output for below specified range as least output value of table */
+ y = pYData[0];
+ }
+ else if(i >= S->nValues)
+ {
+ /* Iniatilize output for above specified range as last output value of table */
+ y = pYData[S->nValues-1];
+ }
+ else
+ {
+ /* Calculation of nearest input values */
+ x0 = S->x1 + i * xSpacing;
+ x1 = S->x1 + (i +1) * xSpacing;
+
+ /* Read of nearest output values */
+ y0 = pYData[i];
+ y1 = pYData[i + 1];
+
+ /* Calculation of output */
+ y = y0 + (x - x0) * ((y1 - y0)/(x1-x0));
+
+ }
+
+ /* returns output value */
+ return (y);
+ }
+
+ /**
+ *
+ * @brief Process function for the Q31 Linear Interpolation Function.
+ * @param[in] *pYData pointer to Q31 Linear Interpolation table
+ * @param[in] x input sample to process
+ * @param[in] nValues number of table values
+ * @return y processed output sample.
+ *
+ * \par
+ * Input sample x is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part.
+ * This function can support maximum of table size 2^12.
+ *
+ */
+
+
+ static __INLINE q31_t arm_linear_interp_q31(q31_t *pYData,
+ q31_t x, uint32_t nValues)
+ {
+ q31_t y; /* output */
+ q31_t y0, y1; /* Nearest output values */
+ q31_t fract; /* fractional part */
+ int32_t index; /* Index to read nearest output values */
+
+ /* Input is in 12.20 format */
+ /* 12 bits for the table index */
+ /* Index value calculation */
+ index = ((x & 0xFFF00000) >> 20);
+
+ if(index >= (nValues - 1))
+ {
+ return(pYData[nValues - 1]);
+ }
+ else if(index < 0)
+ {
+ return(pYData[0]);
+ }
+ else
+ {
+
+ /* 20 bits for the fractional part */
+ /* shift left by 11 to keep fract in 1.31 format */
+ fract = (x & 0x000FFFFF) << 11;
+
+ /* Read two nearest output values from the index in 1.31(q31) format */
+ y0 = pYData[index];
+ y1 = pYData[index + 1u];
+
+ /* Calculation of y0 * (1-fract) and y is in 2.30 format */
+ y = ((q31_t) ((q63_t) y0 * (0x7FFFFFFF - fract) >> 32));
+
+ /* Calculation of y0 * (1-fract) + y1 *fract and y is in 2.30 format */
+ y += ((q31_t) (((q63_t) y1 * fract) >> 32));
+
+ /* Convert y to 1.31 format */
+ return (y << 1u);
+
+ }
+
+ }
+
+ /**
+ *
+ * @brief Process function for the Q15 Linear Interpolation Function.
+ * @param[in] *pYData pointer to Q15 Linear Interpolation table
+ * @param[in] x input sample to process
+ * @param[in] nValues number of table values
+ * @return y processed output sample.
+ *
+ * \par
+ * Input sample x is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part.
+ * This function can support maximum of table size 2^12.
+ *
+ */
+
+
+ static __INLINE q15_t arm_linear_interp_q15(q15_t *pYData, q31_t x, uint32_t nValues)
+ {
+ q63_t y; /* output */
+ q15_t y0, y1; /* Nearest output values */
+ q31_t fract; /* fractional part */
+ int32_t index; /* Index to read nearest output values */
+
+ /* Input is in 12.20 format */
+ /* 12 bits for the table index */
+ /* Index value calculation */
+ index = ((x & 0xFFF00000) >> 20u);
+
+ if(index >= (nValues - 1))
+ {
+ return(pYData[nValues - 1]);
+ }
+ else if(index < 0)
+ {
+ return(pYData[0]);
+ }
+ else
+ {
+ /* 20 bits for the fractional part */
+ /* fract is in 12.20 format */
+ fract = (x & 0x000FFFFF);
+
+ /* Read two nearest output values from the index */
+ y0 = pYData[index];
+ y1 = pYData[index + 1u];
+
+ /* Calculation of y0 * (1-fract) and y is in 13.35 format */
+ y = ((q63_t) y0 * (0xFFFFF - fract));
+
+ /* Calculation of (y0 * (1-fract) + y1 * fract) and y is in 13.35 format */
+ y += ((q63_t) y1 * (fract));
+
+ /* convert y to 1.15 format */
+ return (y >> 20);
+ }
+
+
+ }
+
+ /**
+ *
+ * @brief Process function for the Q7 Linear Interpolation Function.
+ * @param[in] *pYData pointer to Q7 Linear Interpolation table
+ * @param[in] x input sample to process
+ * @param[in] nValues number of table values
+ * @return y processed output sample.
+ *
+ * \par
+ * Input sample x is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part.
+ * This function can support maximum of table size 2^12.
+ */
+
+
+ static __INLINE q7_t arm_linear_interp_q7(q7_t *pYData, q31_t x, uint32_t nValues)
+ {
+ q31_t y; /* output */
+ q7_t y0, y1; /* Nearest output values */
+ q31_t fract; /* fractional part */
+ int32_t index; /* Index to read nearest output values */
+
+ /* Input is in 12.20 format */
+ /* 12 bits for the table index */
+ /* Index value calculation */
+ index = ((x & 0xFFF00000) >> 20u);
+
+
+ if(index >= (nValues - 1))
+ {
+ return(pYData[nValues - 1]);
+ }
+ else if(index < 0)
+ {
+ return(pYData[0]);
+ }
+ else
+ {
+
+ /* 20 bits for the fractional part */
+ /* fract is in 12.20 format */
+ fract = (x & 0x000FFFFF);
+
+ /* Read two nearest output values from the index and are in 1.7(q7) format */
+ y0 = pYData[index];
+ y1 = pYData[index + 1u];
+
+ /* Calculation of y0 * (1-fract ) and y is in 13.27(q27) format */
+ y = ((y0 * (0xFFFFF - fract)));
+
+ /* Calculation of y1 * fract + y0 * (1-fract) and y is in 13.27(q27) format */
+ y += (y1 * fract);
+
+ /* convert y to 1.7(q7) format */
+ return (y >> 20u);
+
+ }
+
+ }
+ /**
+ * @} end of LinearInterpolate group
+ */
+
+ /**
+ * @brief Fast approximation to the trigonometric sine function for floating-point data.
+ * @param[in] x input value in radians.
+ * @return sin(x).
+ */
+
+ float32_t arm_sin_f32(
+ float32_t x);
+
+ /**
+ * @brief Fast approximation to the trigonometric sine function for Q31 data.
+ * @param[in] x Scaled input value in radians.
+ * @return sin(x).
+ */
+
+ q31_t arm_sin_q31(
+ q31_t x);
+
+ /**
+ * @brief Fast approximation to the trigonometric sine function for Q15 data.
+ * @param[in] x Scaled input value in radians.
+ * @return sin(x).
+ */
+
+ q15_t arm_sin_q15(
+ q15_t x);
+
+ /**
+ * @brief Fast approximation to the trigonometric cosine function for floating-point data.
+ * @param[in] x input value in radians.
+ * @return cos(x).
+ */
+
+ float32_t arm_cos_f32(
+ float32_t x);
+
+ /**
+ * @brief Fast approximation to the trigonometric cosine function for Q31 data.
+ * @param[in] x Scaled input value in radians.
+ * @return cos(x).
+ */
+
+ q31_t arm_cos_q31(
+ q31_t x);
+
+ /**
+ * @brief Fast approximation to the trigonometric cosine function for Q15 data.
+ * @param[in] x Scaled input value in radians.
+ * @return cos(x).
+ */
+
+ q15_t arm_cos_q15(
+ q15_t x);
+
+
+ /**
+ * @ingroup groupFastMath
+ */
+
+
+ /**
+ * @defgroup SQRT Square Root
+ *
+ * Computes the square root of a number.
+ * There are separate functions for Q15, Q31, and floating-point data types.
+ * The square root function is computed using the Newton-Raphson algorithm.
+ * This is an iterative algorithm of the form:
+ *
+ * x1 = x0 - f(x0)/f'(x0)
+ *
+ * where x1 is the current estimate,
+ * x0 is the previous estimate and
+ * f'(x0) is the derivative of f() evaluated at x0.
+ * For the square root function, the algorithm reduces to:
+ *
+ * x0 = in/2 [initial guess]
+ * x1 = 1/2 * ( x0 + in / x0) [each iteration]
+ *
+ */
+
+
+ /**
+ * @addtogroup SQRT
+ * @{
+ */
+
+ /**
+ * @brief Floating-point square root function.
+ * @param[in] in input value.
+ * @param[out] *pOut square root of input value.
+ * @return The function returns ARM_MATH_SUCCESS if input value is positive value or ARM_MATH_ARGUMENT_ERROR if
+ * in is negative value and returns zero output for negative values.
+ */
+
+ static __INLINE arm_status arm_sqrt_f32(
+ float32_t in, float32_t *pOut)
+ {
+ if(in > 0)
+ {
+
+// #if __FPU_USED
+ #if (__FPU_USED == 1) && defined ( __CC_ARM )
+ *pOut = __sqrtf(in);
+ #else
+ *pOut = sqrtf(in);
+ #endif
+
+ return (ARM_MATH_SUCCESS);
+ }
+ else
+ {
+ *pOut = 0.0f;
+ return (ARM_MATH_ARGUMENT_ERROR);
+ }
+
+ }
+
+
+ /**
+ * @brief Q31 square root function.
+ * @param[in] in input value. The range of the input value is [0 +1) or 0x00000000 to 0x7FFFFFFF.
+ * @param[out] *pOut square root of input value.
+ * @return The function returns ARM_MATH_SUCCESS if input value is positive value or ARM_MATH_ARGUMENT_ERROR if
+ * in is negative value and returns zero output for negative values.
+ */
+ arm_status arm_sqrt_q31(
+ q31_t in, q31_t *pOut);
+
+ /**
+ * @brief Q15 square root function.
+ * @param[in] in input value. The range of the input value is [0 +1) or 0x0000 to 0x7FFF.
+ * @param[out] *pOut square root of input value.
+ * @return The function returns ARM_MATH_SUCCESS if input value is positive value or ARM_MATH_ARGUMENT_ERROR if
+ * in is negative value and returns zero output for negative values.
+ */
+ arm_status arm_sqrt_q15(
+ q15_t in, q15_t *pOut);
+
+ /**
+ * @} end of SQRT group
+ */
+
+
+
+
+
+
+ /**
+ * @brief floating-point Circular write function.
+ */
+
+ static __INLINE void arm_circularWrite_f32(
+ int32_t * circBuffer,
+ int32_t L,
+ uint16_t * writeOffset,
+ int32_t bufferInc,
+ const int32_t * src,
+ int32_t srcInc,
+ uint32_t blockSize)
+ {
+ uint32_t i = 0u;
+ int32_t wOffset;
+
+ /* Copy the value of Index pointer that points
+ * to the current location where the input samples to be copied */
+ wOffset = *writeOffset;
+
+ /* Loop over the blockSize */
+ i = blockSize;
+
+ while(i > 0u)
+ {
+ /* copy the input sample to the circular buffer */
+ circBuffer[wOffset] = *src;
+
+ /* Update the input pointer */
+ src += srcInc;
+
+ /* Circularly update wOffset. Watch out for positive and negative value */
+ wOffset += bufferInc;
+ if(wOffset >= L)
+ wOffset -= L;
+
+ /* Decrement the loop counter */
+ i--;
+ }
+
+ /* Update the index pointer */
+ *writeOffset = wOffset;
+ }
+
+
+
+ /**
+ * @brief floating-point Circular Read function.
+ */
+ static __INLINE void arm_circularRead_f32(
+ int32_t * circBuffer,
+ int32_t L,
+ int32_t * readOffset,
+ int32_t bufferInc,
+ int32_t * dst,
+ int32_t * dst_base,
+ int32_t dst_length,
+ int32_t dstInc,
+ uint32_t blockSize)
+ {
+ uint32_t i = 0u;
+ int32_t rOffset, dst_end;
+
+ /* Copy the value of Index pointer that points
+ * to the current location from where the input samples to be read */
+ rOffset = *readOffset;
+ dst_end = (int32_t) (dst_base + dst_length);
+
+ /* Loop over the blockSize */
+ i = blockSize;
+
+ while(i > 0u)
+ {
+ /* copy the sample from the circular buffer to the destination buffer */
+ *dst = circBuffer[rOffset];
+
+ /* Update the input pointer */
+ dst += dstInc;
+
+ if(dst == (int32_t *) dst_end)
+ {
+ dst = dst_base;
+ }
+
+ /* Circularly update rOffset. Watch out for positive and negative value */
+ rOffset += bufferInc;
+
+ if(rOffset >= L)
+ {
+ rOffset -= L;
+ }
+
+ /* Decrement the loop counter */
+ i--;
+ }
+
+ /* Update the index pointer */
+ *readOffset = rOffset;
+ }
+
+ /**
+ * @brief Q15 Circular write function.
+ */
+
+ static __INLINE void arm_circularWrite_q15(
+ q15_t * circBuffer,
+ int32_t L,
+ uint16_t * writeOffset,
+ int32_t bufferInc,
+ const q15_t * src,
+ int32_t srcInc,
+ uint32_t blockSize)
+ {
+ uint32_t i = 0u;
+ int32_t wOffset;
+
+ /* Copy the value of Index pointer that points
+ * to the current location where the input samples to be copied */
+ wOffset = *writeOffset;
+
+ /* Loop over the blockSize */
+ i = blockSize;
+
+ while(i > 0u)
+ {
+ /* copy the input sample to the circular buffer */
+ circBuffer[wOffset] = *src;
+
+ /* Update the input pointer */
+ src += srcInc;
+
+ /* Circularly update wOffset. Watch out for positive and negative value */
+ wOffset += bufferInc;
+ if(wOffset >= L)
+ wOffset -= L;
+
+ /* Decrement the loop counter */
+ i--;
+ }
+
+ /* Update the index pointer */
+ *writeOffset = wOffset;
+ }
+
+
+
+ /**
+ * @brief Q15 Circular Read function.
+ */
+ static __INLINE void arm_circularRead_q15(
+ q15_t * circBuffer,
+ int32_t L,
+ int32_t * readOffset,
+ int32_t bufferInc,
+ q15_t * dst,
+ q15_t * dst_base,
+ int32_t dst_length,
+ int32_t dstInc,
+ uint32_t blockSize)
+ {
+ uint32_t i = 0;
+ int32_t rOffset, dst_end;
+
+ /* Copy the value of Index pointer that points
+ * to the current location from where the input samples to be read */
+ rOffset = *readOffset;
+
+ dst_end = (int32_t) (dst_base + dst_length);
+
+ /* Loop over the blockSize */
+ i = blockSize;
+
+ while(i > 0u)
+ {
+ /* copy the sample from the circular buffer to the destination buffer */
+ *dst = circBuffer[rOffset];
+
+ /* Update the input pointer */
+ dst += dstInc;
+
+ if(dst == (q15_t *) dst_end)
+ {
+ dst = dst_base;
+ }
+
+ /* Circularly update wOffset. Watch out for positive and negative value */
+ rOffset += bufferInc;
+
+ if(rOffset >= L)
+ {
+ rOffset -= L;
+ }
+
+ /* Decrement the loop counter */
+ i--;
+ }
+
+ /* Update the index pointer */
+ *readOffset = rOffset;
+ }
+
+
+ /**
+ * @brief Q7 Circular write function.
+ */
+
+ static __INLINE void arm_circularWrite_q7(
+ q7_t * circBuffer,
+ int32_t L,
+ uint16_t * writeOffset,
+ int32_t bufferInc,
+ const q7_t * src,
+ int32_t srcInc,
+ uint32_t blockSize)
+ {
+ uint32_t i = 0u;
+ int32_t wOffset;
+
+ /* Copy the value of Index pointer that points
+ * to the current location where the input samples to be copied */
+ wOffset = *writeOffset;
+
+ /* Loop over the blockSize */
+ i = blockSize;
+
+ while(i > 0u)
+ {
+ /* copy the input sample to the circular buffer */
+ circBuffer[wOffset] = *src;
+
+ /* Update the input pointer */
+ src += srcInc;
+
+ /* Circularly update wOffset. Watch out for positive and negative value */
+ wOffset += bufferInc;
+ if(wOffset >= L)
+ wOffset -= L;
+
+ /* Decrement the loop counter */
+ i--;
+ }
+
+ /* Update the index pointer */
+ *writeOffset = wOffset;
+ }
+
+
+
+ /**
+ * @brief Q7 Circular Read function.
+ */
+ static __INLINE void arm_circularRead_q7(
+ q7_t * circBuffer,
+ int32_t L,
+ int32_t * readOffset,
+ int32_t bufferInc,
+ q7_t * dst,
+ q7_t * dst_base,
+ int32_t dst_length,
+ int32_t dstInc,
+ uint32_t blockSize)
+ {
+ uint32_t i = 0;
+ int32_t rOffset, dst_end;
+
+ /* Copy the value of Index pointer that points
+ * to the current location from where the input samples to be read */
+ rOffset = *readOffset;
+
+ dst_end = (int32_t) (dst_base + dst_length);
+
+ /* Loop over the blockSize */
+ i = blockSize;
+
+ while(i > 0u)
+ {
+ /* copy the sample from the circular buffer to the destination buffer */
+ *dst = circBuffer[rOffset];
+
+ /* Update the input pointer */
+ dst += dstInc;
+
+ if(dst == (q7_t *) dst_end)
+ {
+ dst = dst_base;
+ }
+
+ /* Circularly update rOffset. Watch out for positive and negative value */
+ rOffset += bufferInc;
+
+ if(rOffset >= L)
+ {
+ rOffset -= L;
+ }
+
+ /* Decrement the loop counter */
+ i--;
+ }
+
+ /* Update the index pointer */
+ *readOffset = rOffset;
+ }
+
+
+ /**
+ * @brief Sum of the squares of the elements of a Q31 vector.
+ * @param[in] *pSrc is input pointer
+ * @param[in] blockSize is the number of samples to process
+ * @param[out] *pResult is output value.
+ * @return none.
+ */
+
+ void arm_power_q31(
+ q31_t * pSrc,
+ uint32_t blockSize,
+ q63_t * pResult);
+
+ /**
+ * @brief Sum of the squares of the elements of a floating-point vector.
+ * @param[in] *pSrc is input pointer
+ * @param[in] blockSize is the number of samples to process
+ * @param[out] *pResult is output value.
+ * @return none.
+ */
+
+ void arm_power_f32(
+ float32_t * pSrc,
+ uint32_t blockSize,
+ float32_t * pResult);
+
+ /**
+ * @brief Sum of the squares of the elements of a Q15 vector.
+ * @param[in] *pSrc is input pointer
+ * @param[in] blockSize is the number of samples to process
+ * @param[out] *pResult is output value.
+ * @return none.
+ */
+
+ void arm_power_q15(
+ q15_t * pSrc,
+ uint32_t blockSize,
+ q63_t * pResult);
+
+ /**
+ * @brief Sum of the squares of the elements of a Q7 vector.
+ * @param[in] *pSrc is input pointer
+ * @param[in] blockSize is the number of samples to process
+ * @param[out] *pResult is output value.
+ * @return none.
+ */
+
+ void arm_power_q7(
+ q7_t * pSrc,
+ uint32_t blockSize,
+ q31_t * pResult);
+
+ /**
+ * @brief Mean value of a Q7 vector.
+ * @param[in] *pSrc is input pointer
+ * @param[in] blockSize is the number of samples to process
+ * @param[out] *pResult is output value.
+ * @return none.
+ */
+
+ void arm_mean_q7(
+ q7_t * pSrc,
+ uint32_t blockSize,
+ q7_t * pResult);
+
+ /**
+ * @brief Mean value of a Q15 vector.
+ * @param[in] *pSrc is input pointer
+ * @param[in] blockSize is the number of samples to process
+ * @param[out] *pResult is output value.
+ * @return none.
+ */
+ void arm_mean_q15(
+ q15_t * pSrc,
+ uint32_t blockSize,
+ q15_t * pResult);
+
+ /**
+ * @brief Mean value of a Q31 vector.
+ * @param[in] *pSrc is input pointer
+ * @param[in] blockSize is the number of samples to process
+ * @param[out] *pResult is output value.
+ * @return none.
+ */
+ void arm_mean_q31(
+ q31_t * pSrc,
+ uint32_t blockSize,
+ q31_t * pResult);
+
+ /**
+ * @brief Mean value of a floating-point vector.
+ * @param[in] *pSrc is input pointer
+ * @param[in] blockSize is the number of samples to process
+ * @param[out] *pResult is output value.
+ * @return none.
+ */
+ void arm_mean_f32(
+ float32_t * pSrc,
+ uint32_t blockSize,
+ float32_t * pResult);
+
+ /**
+ * @brief Variance of the elements of a floating-point vector.
+ * @param[in] *pSrc is input pointer
+ * @param[in] blockSize is the number of samples to process
+ * @param[out] *pResult is output value.
+ * @return none.
+ */
+
+ void arm_var_f32(
+ float32_t * pSrc,
+ uint32_t blockSize,
+ float32_t * pResult);
+
+ /**
+ * @brief Variance of the elements of a Q31 vector.
+ * @param[in] *pSrc is input pointer
+ * @param[in] blockSize is the number of samples to process
+ * @param[out] *pResult is output value.
+ * @return none.
+ */
+
+ void arm_var_q31(
+ q31_t * pSrc,
+ uint32_t blockSize,
+ q63_t * pResult);
+
+ /**
+ * @brief Variance of the elements of a Q15 vector.
+ * @param[in] *pSrc is input pointer
+ * @param[in] blockSize is the number of samples to process
+ * @param[out] *pResult is output value.
+ * @return none.
+ */
+
+ void arm_var_q15(
+ q15_t * pSrc,
+ uint32_t blockSize,
+ q31_t * pResult);
+
+ /**
+ * @brief Root Mean Square of the elements of a floating-point vector.
+ * @param[in] *pSrc is input pointer
+ * @param[in] blockSize is the number of samples to process
+ * @param[out] *pResult is output value.
+ * @return none.
+ */
+
+ void arm_rms_f32(
+ float32_t * pSrc,
+ uint32_t blockSize,
+ float32_t * pResult);
+
+ /**
+ * @brief Root Mean Square of the elements of a Q31 vector.
+ * @param[in] *pSrc is input pointer
+ * @param[in] blockSize is the number of samples to process
+ * @param[out] *pResult is output value.
+ * @return none.
+ */
+
+ void arm_rms_q31(
+ q31_t * pSrc,
+ uint32_t blockSize,
+ q31_t * pResult);
+
+ /**
+ * @brief Root Mean Square of the elements of a Q15 vector.
+ * @param[in] *pSrc is input pointer
+ * @param[in] blockSize is the number of samples to process
+ * @param[out] *pResult is output value.
+ * @return none.
+ */
+
+ void arm_rms_q15(
+ q15_t * pSrc,
+ uint32_t blockSize,
+ q15_t * pResult);
+
+ /**
+ * @brief Standard deviation of the elements of a floating-point vector.
+ * @param[in] *pSrc is input pointer
+ * @param[in] blockSize is the number of samples to process
+ * @param[out] *pResult is output value.
+ * @return none.
+ */
+
+ void arm_std_f32(
+ float32_t * pSrc,
+ uint32_t blockSize,
+ float32_t * pResult);
+
+ /**
+ * @brief Standard deviation of the elements of a Q31 vector.
+ * @param[in] *pSrc is input pointer
+ * @param[in] blockSize is the number of samples to process
+ * @param[out] *pResult is output value.
+ * @return none.
+ */
+
+ void arm_std_q31(
+ q31_t * pSrc,
+ uint32_t blockSize,
+ q31_t * pResult);
+
+ /**
+ * @brief Standard deviation of the elements of a Q15 vector.
+ * @param[in] *pSrc is input pointer
+ * @param[in] blockSize is the number of samples to process
+ * @param[out] *pResult is output value.
+ * @return none.
+ */
+
+ void arm_std_q15(
+ q15_t * pSrc,
+ uint32_t blockSize,
+ q15_t * pResult);
+
+ /**
+ * @brief Floating-point complex magnitude
+ * @param[in] *pSrc points to the complex input vector
+ * @param[out] *pDst points to the real output vector
+ * @param[in] numSamples number of complex samples in the input vector
+ * @return none.
+ */
+
+ void arm_cmplx_mag_f32(
+ float32_t * pSrc,
+ float32_t * pDst,
+ uint32_t numSamples);
+
+ /**
+ * @brief Q31 complex magnitude
+ * @param[in] *pSrc points to the complex input vector
+ * @param[out] *pDst points to the real output vector
+ * @param[in] numSamples number of complex samples in the input vector
+ * @return none.
+ */
+
+ void arm_cmplx_mag_q31(
+ q31_t * pSrc,
+ q31_t * pDst,
+ uint32_t numSamples);
+
+ /**
+ * @brief Q15 complex magnitude
+ * @param[in] *pSrc points to the complex input vector
+ * @param[out] *pDst points to the real output vector
+ * @param[in] numSamples number of complex samples in the input vector
+ * @return none.
+ */
+
+ void arm_cmplx_mag_q15(
+ q15_t * pSrc,
+ q15_t * pDst,
+ uint32_t numSamples);
+
+ /**
+ * @brief Q15 complex dot product
+ * @param[in] *pSrcA points to the first input vector
+ * @param[in] *pSrcB points to the second input vector
+ * @param[in] numSamples number of complex samples in each vector
+ * @param[out] *realResult real part of the result returned here
+ * @param[out] *imagResult imaginary part of the result returned here
+ * @return none.
+ */
+
+ void arm_cmplx_dot_prod_q15(
+ q15_t * pSrcA,
+ q15_t * pSrcB,
+ uint32_t numSamples,
+ q31_t * realResult,
+ q31_t * imagResult);
+
+ /**
+ * @brief Q31 complex dot product
+ * @param[in] *pSrcA points to the first input vector
+ * @param[in] *pSrcB points to the second input vector
+ * @param[in] numSamples number of complex samples in each vector
+ * @param[out] *realResult real part of the result returned here
+ * @param[out] *imagResult imaginary part of the result returned here
+ * @return none.
+ */
+
+ void arm_cmplx_dot_prod_q31(
+ q31_t * pSrcA,
+ q31_t * pSrcB,
+ uint32_t numSamples,
+ q63_t * realResult,
+ q63_t * imagResult);
+
+ /**
+ * @brief Floating-point complex dot product
+ * @param[in] *pSrcA points to the first input vector
+ * @param[in] *pSrcB points to the second input vector
+ * @param[in] numSamples number of complex samples in each vector
+ * @param[out] *realResult real part of the result returned here
+ * @param[out] *imagResult imaginary part of the result returned here
+ * @return none.
+ */
+
+ void arm_cmplx_dot_prod_f32(
+ float32_t * pSrcA,
+ float32_t * pSrcB,
+ uint32_t numSamples,
+ float32_t * realResult,
+ float32_t * imagResult);
+
+ /**
+ * @brief Q15 complex-by-real multiplication
+ * @param[in] *pSrcCmplx points to the complex input vector
+ * @param[in] *pSrcReal points to the real input vector
+ * @param[out] *pCmplxDst points to the complex output vector
+ * @param[in] numSamples number of samples in each vector
+ * @return none.
+ */
+
+ void arm_cmplx_mult_real_q15(
+ q15_t * pSrcCmplx,
+ q15_t * pSrcReal,
+ q15_t * pCmplxDst,
+ uint32_t numSamples);
+
+ /**
+ * @brief Q31 complex-by-real multiplication
+ * @param[in] *pSrcCmplx points to the complex input vector
+ * @param[in] *pSrcReal points to the real input vector
+ * @param[out] *pCmplxDst points to the complex output vector
+ * @param[in] numSamples number of samples in each vector
+ * @return none.
+ */
+
+ void arm_cmplx_mult_real_q31(
+ q31_t * pSrcCmplx,
+ q31_t * pSrcReal,
+ q31_t * pCmplxDst,
+ uint32_t numSamples);
+
+ /**
+ * @brief Floating-point complex-by-real multiplication
+ * @param[in] *pSrcCmplx points to the complex input vector
+ * @param[in] *pSrcReal points to the real input vector
+ * @param[out] *pCmplxDst points to the complex output vector
+ * @param[in] numSamples number of samples in each vector
+ * @return none.
+ */
+
+ void arm_cmplx_mult_real_f32(
+ float32_t * pSrcCmplx,
+ float32_t * pSrcReal,
+ float32_t * pCmplxDst,
+ uint32_t numSamples);
+
+ /**
+ * @brief Minimum value of a Q7 vector.
+ * @param[in] *pSrc is input pointer
+ * @param[in] blockSize is the number of samples to process
+ * @param[out] *result is output pointer
+ * @param[in] index is the array index of the minimum value in the input buffer.
+ * @return none.
+ */
+
+ void arm_min_q7(
+ q7_t * pSrc,
+ uint32_t blockSize,
+ q7_t * result,
+ uint32_t * index);
+
+ /**
+ * @brief Minimum value of a Q15 vector.
+ * @param[in] *pSrc is input pointer
+ * @param[in] blockSize is the number of samples to process
+ * @param[out] *pResult is output pointer
+ * @param[in] *pIndex is the array index of the minimum value in the input buffer.
+ * @return none.
+ */
+
+ void arm_min_q15(
+ q15_t * pSrc,
+ uint32_t blockSize,
+ q15_t * pResult,
+ uint32_t * pIndex);
+
+ /**
+ * @brief Minimum value of a Q31 vector.
+ * @param[in] *pSrc is input pointer
+ * @param[in] blockSize is the number of samples to process
+ * @param[out] *pResult is output pointer
+ * @param[out] *pIndex is the array index of the minimum value in the input buffer.
+ * @return none.
+ */
+ void arm_min_q31(
+ q31_t * pSrc,
+ uint32_t blockSize,
+ q31_t * pResult,
+ uint32_t * pIndex);
+
+ /**
+ * @brief Minimum value of a floating-point vector.
+ * @param[in] *pSrc is input pointer
+ * @param[in] blockSize is the number of samples to process
+ * @param[out] *pResult is output pointer
+ * @param[out] *pIndex is the array index of the minimum value in the input buffer.
+ * @return none.
+ */
+
+ void arm_min_f32(
+ float32_t * pSrc,
+ uint32_t blockSize,
+ float32_t * pResult,
+ uint32_t * pIndex);
+
+/**
+ * @brief Maximum value of a Q7 vector.
+ * @param[in] *pSrc points to the input buffer
+ * @param[in] blockSize length of the input vector
+ * @param[out] *pResult maximum value returned here
+ * @param[out] *pIndex index of maximum value returned here
+ * @return none.
+ */
+
+ void arm_max_q7(
+ q7_t * pSrc,
+ uint32_t blockSize,
+ q7_t * pResult,
+ uint32_t * pIndex);
+
+/**
+ * @brief Maximum value of a Q15 vector.
+ * @param[in] *pSrc points to the input buffer
+ * @param[in] blockSize length of the input vector
+ * @param[out] *pResult maximum value returned here
+ * @param[out] *pIndex index of maximum value returned here
+ * @return none.
+ */
+
+ void arm_max_q15(
+ q15_t * pSrc,
+ uint32_t blockSize,
+ q15_t * pResult,
+ uint32_t * pIndex);
+
+/**
+ * @brief Maximum value of a Q31 vector.
+ * @param[in] *pSrc points to the input buffer
+ * @param[in] blockSize length of the input vector
+ * @param[out] *pResult maximum value returned here
+ * @param[out] *pIndex index of maximum value returned here
+ * @return none.
+ */
+
+ void arm_max_q31(
+ q31_t * pSrc,
+ uint32_t blockSize,
+ q31_t * pResult,
+ uint32_t * pIndex);
+
+/**
+ * @brief Maximum value of a floating-point vector.
+ * @param[in] *pSrc points to the input buffer
+ * @param[in] blockSize length of the input vector
+ * @param[out] *pResult maximum value returned here
+ * @param[out] *pIndex index of maximum value returned here
+ * @return none.
+ */
+
+ void arm_max_f32(
+ float32_t * pSrc,
+ uint32_t blockSize,
+ float32_t * pResult,
+ uint32_t * pIndex);
+
+ /**
+ * @brief Q15 complex-by-complex multiplication
+ * @param[in] *pSrcA points to the first input vector
+ * @param[in] *pSrcB points to the second input vector
+ * @param[out] *pDst points to the output vector
+ * @param[in] numSamples number of complex samples in each vector
+ * @return none.
+ */
+
+ void arm_cmplx_mult_cmplx_q15(
+ q15_t * pSrcA,
+ q15_t * pSrcB,
+ q15_t * pDst,
+ uint32_t numSamples);
+
+ /**
+ * @brief Q31 complex-by-complex multiplication
+ * @param[in] *pSrcA points to the first input vector
+ * @param[in] *pSrcB points to the second input vector
+ * @param[out] *pDst points to the output vector
+ * @param[in] numSamples number of complex samples in each vector
+ * @return none.
+ */
+
+ void arm_cmplx_mult_cmplx_q31(
+ q31_t * pSrcA,
+ q31_t * pSrcB,
+ q31_t * pDst,
+ uint32_t numSamples);
+
+ /**
+ * @brief Floating-point complex-by-complex multiplication
+ * @param[in] *pSrcA points to the first input vector
+ * @param[in] *pSrcB points to the second input vector
+ * @param[out] *pDst points to the output vector
+ * @param[in] numSamples number of complex samples in each vector
+ * @return none.
+ */
+
+ void arm_cmplx_mult_cmplx_f32(
+ float32_t * pSrcA,
+ float32_t * pSrcB,
+ float32_t * pDst,
+ uint32_t numSamples);
+
+ /**
+ * @brief Converts the elements of the floating-point vector to Q31 vector.
+ * @param[in] *pSrc points to the floating-point input vector
+ * @param[out] *pDst points to the Q31 output vector
+ * @param[in] blockSize length of the input vector
+ * @return none.
+ */
+ void arm_float_to_q31(
+ float32_t * pSrc,
+ q31_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Converts the elements of the floating-point vector to Q15 vector.
+ * @param[in] *pSrc points to the floating-point input vector
+ * @param[out] *pDst points to the Q15 output vector
+ * @param[in] blockSize length of the input vector
+ * @return none
+ */
+ void arm_float_to_q15(
+ float32_t * pSrc,
+ q15_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Converts the elements of the floating-point vector to Q7 vector.
+ * @param[in] *pSrc points to the floating-point input vector
+ * @param[out] *pDst points to the Q7 output vector
+ * @param[in] blockSize length of the input vector
+ * @return none
+ */
+ void arm_float_to_q7(
+ float32_t * pSrc,
+ q7_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Converts the elements of the Q31 vector to Q15 vector.
+ * @param[in] *pSrc is input pointer
+ * @param[out] *pDst is output pointer
+ * @param[in] blockSize is the number of samples to process
+ * @return none.
+ */
+ void arm_q31_to_q15(
+ q31_t * pSrc,
+ q15_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Converts the elements of the Q31 vector to Q7 vector.
+ * @param[in] *pSrc is input pointer
+ * @param[out] *pDst is output pointer
+ * @param[in] blockSize is the number of samples to process
+ * @return none.
+ */
+ void arm_q31_to_q7(
+ q31_t * pSrc,
+ q7_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Converts the elements of the Q15 vector to floating-point vector.
+ * @param[in] *pSrc is input pointer
+ * @param[out] *pDst is output pointer
+ * @param[in] blockSize is the number of samples to process
+ * @return none.
+ */
+ void arm_q15_to_float(
+ q15_t * pSrc,
+ float32_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Converts the elements of the Q15 vector to Q31 vector.
+ * @param[in] *pSrc is input pointer
+ * @param[out] *pDst is output pointer
+ * @param[in] blockSize is the number of samples to process
+ * @return none.
+ */
+ void arm_q15_to_q31(
+ q15_t * pSrc,
+ q31_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Converts the elements of the Q15 vector to Q7 vector.
+ * @param[in] *pSrc is input pointer
+ * @param[out] *pDst is output pointer
+ * @param[in] blockSize is the number of samples to process
+ * @return none.
+ */
+ void arm_q15_to_q7(
+ q15_t * pSrc,
+ q7_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @ingroup groupInterpolation
+ */
+
+ /**
+ * @defgroup BilinearInterpolate Bilinear Interpolation
+ *
+ * Bilinear interpolation is an extension of linear interpolation applied to a two dimensional grid.
+ * The underlying function f(x, y) is sampled on a regular grid and the interpolation process
+ * determines values between the grid points.
+ * Bilinear interpolation is equivalent to two step linear interpolation, first in the x-dimension and then in the y-dimension.
+ * Bilinear interpolation is often used in image processing to rescale images.
+ * The CMSIS DSP library provides bilinear interpolation functions for Q7, Q15, Q31, and floating-point data types.
+ *
+ * Algorithm
+ * \par
+ * The instance structure used by the bilinear interpolation functions describes a two dimensional data table.
+ * For floating-point, the instance structure is defined as:
+ *
+ * typedef struct
+ * {
+ * uint16_t numRows;
+ * uint16_t numCols;
+ * float32_t *pData;
+ * } arm_bilinear_interp_instance_f32;
+ *
+ *
+ * \par
+ * where numRows specifies the number of rows in the table;
+ * numCols specifies the number of columns in the table;
+ * and pData points to an array of size numRows*numCols values.
+ * The data table pTable is organized in row order and the supplied data values fall on integer indexes.
+ * That is, table element (x,y) is located at pTable[x + y*numCols] where x and y are integers.
+ *
+ * \par
+ * Let (x, y) specify the desired interpolation point. Then define:
+ *
+ * XF = floor(x)
+ * YF = floor(y)
+ *
+ * \par
+ * The interpolated output point is computed as:
+ *
+ * f(x, y) = f(XF, YF) * (1-(x-XF)) * (1-(y-YF))
+ * + f(XF+1, YF) * (x-XF)*(1-(y-YF))
+ * + f(XF, YF+1) * (1-(x-XF))*(y-YF)
+ * + f(XF+1, YF+1) * (x-XF)*(y-YF)
+ *
+ * Note that the coordinates (x, y) contain integer and fractional components.
+ * The integer components specify which portion of the table to use while the
+ * fractional components control the interpolation processor.
+ *
+ * \par
+ * if (x,y) are outside of the table boundary, Bilinear interpolation returns zero output.
+ */
+
+ /**
+ * @addtogroup BilinearInterpolate
+ * @{
+ */
+
+ /**
+ *
+ * @brief Floating-point bilinear interpolation.
+ * @param[in,out] *S points to an instance of the interpolation structure.
+ * @param[in] X interpolation coordinate.
+ * @param[in] Y interpolation coordinate.
+ * @return out interpolated value.
+ */
+
+
+ static __INLINE float32_t arm_bilinear_interp_f32(
+ const arm_bilinear_interp_instance_f32 * S,
+ float32_t X,
+ float32_t Y)
+ {
+ float32_t out;
+ float32_t f00, f01, f10, f11;
+ float32_t *pData = S->pData;
+ int32_t xIndex, yIndex, index;
+ float32_t xdiff, ydiff;
+ float32_t b1, b2, b3, b4;
+
+ xIndex = (int32_t) X;
+ yIndex = (int32_t) Y;
+
+ /* Care taken for table outside boundary */
+ /* Returns zero output when values are outside table boundary */
+ if(xIndex < 0 || xIndex > (S->numRows-1) || yIndex < 0 || yIndex > ( S->numCols-1))
+ {
+ return(0);
+ }
+
+ /* Calculation of index for two nearest points in X-direction */
+ index = (xIndex - 1) + (yIndex-1) * S->numCols ;
+
+
+ /* Read two nearest points in X-direction */
+ f00 = pData[index];
+ f01 = pData[index + 1];
+
+ /* Calculation of index for two nearest points in Y-direction */
+ index = (xIndex-1) + (yIndex) * S->numCols;
+
+
+ /* Read two nearest points in Y-direction */
+ f10 = pData[index];
+ f11 = pData[index + 1];
+
+ /* Calculation of intermediate values */
+ b1 = f00;
+ b2 = f01 - f00;
+ b3 = f10 - f00;
+ b4 = f00 - f01 - f10 + f11;
+
+ /* Calculation of fractional part in X */
+ xdiff = X - xIndex;
+
+ /* Calculation of fractional part in Y */
+ ydiff = Y - yIndex;
+
+ /* Calculation of bi-linear interpolated output */
+ out = b1 + b2 * xdiff + b3 * ydiff + b4 * xdiff * ydiff;
+
+ /* return to application */
+ return (out);
+
+ }
+
+ /**
+ *
+ * @brief Q31 bilinear interpolation.
+ * @param[in,out] *S points to an instance of the interpolation structure.
+ * @param[in] X interpolation coordinate in 12.20 format.
+ * @param[in] Y interpolation coordinate in 12.20 format.
+ * @return out interpolated value.
+ */
+
+ static __INLINE q31_t arm_bilinear_interp_q31(
+ arm_bilinear_interp_instance_q31 * S,
+ q31_t X,
+ q31_t Y)
+ {
+ q31_t out; /* Temporary output */
+ q31_t acc = 0; /* output */
+ q31_t xfract, yfract; /* X, Y fractional parts */
+ q31_t x1, x2, y1, y2; /* Nearest output values */
+ int32_t rI, cI; /* Row and column indices */
+ q31_t *pYData = S->pData; /* pointer to output table values */
+ uint32_t nCols = S->numCols; /* num of rows */
+
+
+ /* Input is in 12.20 format */
+ /* 12 bits for the table index */
+ /* Index value calculation */
+ rI = ((X & 0xFFF00000) >> 20u);
+
+ /* Input is in 12.20 format */
+ /* 12 bits for the table index */
+ /* Index value calculation */
+ cI = ((Y & 0xFFF00000) >> 20u);
+
+ /* Care taken for table outside boundary */
+ /* Returns zero output when values are outside table boundary */
+ if(rI < 0 || rI > (S->numRows-1) || cI < 0 || cI > ( S->numCols-1))
+ {
+ return(0);
+ }
+
+ /* 20 bits for the fractional part */
+ /* shift left xfract by 11 to keep 1.31 format */
+ xfract = (X & 0x000FFFFF) << 11u;
+
+ /* Read two nearest output values from the index */
+ x1 = pYData[(rI) + nCols * (cI)];
+ x2 = pYData[(rI) + nCols * (cI) + 1u];
+
+ /* 20 bits for the fractional part */
+ /* shift left yfract by 11 to keep 1.31 format */
+ yfract = (Y & 0x000FFFFF) << 11u;
+
+ /* Read two nearest output values from the index */
+ y1 = pYData[(rI) + nCols * (cI + 1)];
+ y2 = pYData[(rI) + nCols * (cI + 1) + 1u];
+
+ /* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 3.29(q29) format */
+ out = ((q31_t) (((q63_t) x1 * (0x7FFFFFFF - xfract)) >> 32));
+ acc = ((q31_t) (((q63_t) out * (0x7FFFFFFF - yfract)) >> 32));
+
+ /* x2 * (xfract) * (1-yfract) in 3.29(q29) and adding to acc */
+ out = ((q31_t) ((q63_t) x2 * (0x7FFFFFFF - yfract) >> 32));
+ acc += ((q31_t) ((q63_t) out * (xfract) >> 32));
+
+ /* y1 * (1 - xfract) * (yfract) in 3.29(q29) and adding to acc */
+ out = ((q31_t) ((q63_t) y1 * (0x7FFFFFFF - xfract) >> 32));
+ acc += ((q31_t) ((q63_t) out * (yfract) >> 32));
+
+ /* y2 * (xfract) * (yfract) in 3.29(q29) and adding to acc */
+ out = ((q31_t) ((q63_t) y2 * (xfract) >> 32));
+ acc += ((q31_t) ((q63_t) out * (yfract) >> 32));
+
+ /* Convert acc to 1.31(q31) format */
+ return (acc << 2u);
+
+ }
+
+ /**
+ * @brief Q15 bilinear interpolation.
+ * @param[in,out] *S points to an instance of the interpolation structure.
+ * @param[in] X interpolation coordinate in 12.20 format.
+ * @param[in] Y interpolation coordinate in 12.20 format.
+ * @return out interpolated value.
+ */
+
+ static __INLINE q15_t arm_bilinear_interp_q15(
+ arm_bilinear_interp_instance_q15 * S,
+ q31_t X,
+ q31_t Y)
+ {
+ q63_t acc = 0; /* output */
+ q31_t out; /* Temporary output */
+ q15_t x1, x2, y1, y2; /* Nearest output values */
+ q31_t xfract, yfract; /* X, Y fractional parts */
+ int32_t rI, cI; /* Row and column indices */
+ q15_t *pYData = S->pData; /* pointer to output table values */
+ uint32_t nCols = S->numCols; /* num of rows */
+
+ /* Input is in 12.20 format */
+ /* 12 bits for the table index */
+ /* Index value calculation */
+ rI = ((X & 0xFFF00000) >> 20);
+
+ /* Input is in 12.20 format */
+ /* 12 bits for the table index */
+ /* Index value calculation */
+ cI = ((Y & 0xFFF00000) >> 20);
+
+ /* Care taken for table outside boundary */
+ /* Returns zero output when values are outside table boundary */
+ if(rI < 0 || rI > (S->numRows-1) || cI < 0 || cI > ( S->numCols-1))
+ {
+ return(0);
+ }
+
+ /* 20 bits for the fractional part */
+ /* xfract should be in 12.20 format */
+ xfract = (X & 0x000FFFFF);
+
+ /* Read two nearest output values from the index */
+ x1 = pYData[(rI) + nCols * (cI)];
+ x2 = pYData[(rI) + nCols * (cI) + 1u];
+
+
+ /* 20 bits for the fractional part */
+ /* yfract should be in 12.20 format */
+ yfract = (Y & 0x000FFFFF);
+
+ /* Read two nearest output values from the index */
+ y1 = pYData[(rI) + nCols * (cI + 1)];
+ y2 = pYData[(rI) + nCols * (cI + 1) + 1u];
+
+ /* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 13.51 format */
+
+ /* x1 is in 1.15(q15), xfract in 12.20 format and out is in 13.35 format */
+ /* convert 13.35 to 13.31 by right shifting and out is in 1.31 */
+ out = (q31_t) (((q63_t) x1 * (0xFFFFF - xfract)) >> 4u);
+ acc = ((q63_t) out * (0xFFFFF - yfract));
+
+ /* x2 * (xfract) * (1-yfract) in 1.51 and adding to acc */
+ out = (q31_t) (((q63_t) x2 * (0xFFFFF - yfract)) >> 4u);
+ acc += ((q63_t) out * (xfract));
+
+ /* y1 * (1 - xfract) * (yfract) in 1.51 and adding to acc */
+ out = (q31_t) (((q63_t) y1 * (0xFFFFF - xfract)) >> 4u);
+ acc += ((q63_t) out * (yfract));
+
+ /* y2 * (xfract) * (yfract) in 1.51 and adding to acc */
+ out = (q31_t) (((q63_t) y2 * (xfract)) >> 4u);
+ acc += ((q63_t) out * (yfract));
+
+ /* acc is in 13.51 format and down shift acc by 36 times */
+ /* Convert out to 1.15 format */
+ return (acc >> 36);
+
+ }
+
+ /**
+ * @brief Q7 bilinear interpolation.
+ * @param[in,out] *S points to an instance of the interpolation structure.
+ * @param[in] X interpolation coordinate in 12.20 format.
+ * @param[in] Y interpolation coordinate in 12.20 format.
+ * @return out interpolated value.
+ */
+
+ static __INLINE q7_t arm_bilinear_interp_q7(
+ arm_bilinear_interp_instance_q7 * S,
+ q31_t X,
+ q31_t Y)
+ {
+ q63_t acc = 0; /* output */
+ q31_t out; /* Temporary output */
+ q31_t xfract, yfract; /* X, Y fractional parts */
+ q7_t x1, x2, y1, y2; /* Nearest output values */
+ int32_t rI, cI; /* Row and column indices */
+ q7_t *pYData = S->pData; /* pointer to output table values */
+ uint32_t nCols = S->numCols; /* num of rows */
+
+ /* Input is in 12.20 format */
+ /* 12 bits for the table index */
+ /* Index value calculation */
+ rI = ((X & 0xFFF00000) >> 20);
+
+ /* Input is in 12.20 format */
+ /* 12 bits for the table index */
+ /* Index value calculation */
+ cI = ((Y & 0xFFF00000) >> 20);
+
+ /* Care taken for table outside boundary */
+ /* Returns zero output when values are outside table boundary */
+ if(rI < 0 || rI > (S->numRows-1) || cI < 0 || cI > ( S->numCols-1))
+ {
+ return(0);
+ }
+
+ /* 20 bits for the fractional part */
+ /* xfract should be in 12.20 format */
+ xfract = (X & 0x000FFFFF);
+
+ /* Read two nearest output values from the index */
+ x1 = pYData[(rI) + nCols * (cI)];
+ x2 = pYData[(rI) + nCols * (cI) + 1u];
+
+
+ /* 20 bits for the fractional part */
+ /* yfract should be in 12.20 format */
+ yfract = (Y & 0x000FFFFF);
+
+ /* Read two nearest output values from the index */
+ y1 = pYData[(rI) + nCols * (cI + 1)];
+ y2 = pYData[(rI) + nCols * (cI + 1) + 1u];
+
+ /* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 16.47 format */
+ out = ((x1 * (0xFFFFF - xfract)));
+ acc = (((q63_t) out * (0xFFFFF - yfract)));
+
+ /* x2 * (xfract) * (1-yfract) in 2.22 and adding to acc */
+ out = ((x2 * (0xFFFFF - yfract)));
+ acc += (((q63_t) out * (xfract)));
+
+ /* y1 * (1 - xfract) * (yfract) in 2.22 and adding to acc */
+ out = ((y1 * (0xFFFFF - xfract)));
+ acc += (((q63_t) out * (yfract)));
+
+ /* y2 * (xfract) * (yfract) in 2.22 and adding to acc */
+ out = ((y2 * (yfract)));
+ acc += (((q63_t) out * (xfract)));
+
+ /* acc in 16.47 format and down shift by 40 to convert to 1.7 format */
+ return (acc >> 40);
+
+ }
+
+ /**
+ * @} end of BilinearInterpolate group
+ */
+
+
+
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* _ARM_MATH_H */
+
+
+/**
+ *
+ * End of file.
+ */
diff --git a/platform/mcu/CMSIS/Include/core_cm0.h b/platform/mcu/CMSIS/Include/core_cm0.h
new file mode 100644
index 00000000..edd52217
--- /dev/null
+++ b/platform/mcu/CMSIS/Include/core_cm0.h
@@ -0,0 +1,665 @@
+/**************************************************************************//**
+ * @file core_cm0.h
+ * @brief CMSIS Cortex-M0 Core Peripheral Access Layer Header File
+ * @version V2.10
+ * @date 19. July 2011
+ *
+ * @note
+ * Copyright (C) 2009-2011 ARM Limited. All rights reserved.
+ *
+ * @par
+ * ARM Limited (ARM) is supplying this software for use with Cortex-M
+ * processor based microcontrollers. This file can be freely distributed
+ * within development tools that are supporting such ARM based processors.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
+ * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
+ * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
+ * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
+ *
+ ******************************************************************************/
+#if defined ( __ICCARM__ )
+ #pragma system_include /* treat file as system include file for MISRA check */
+#endif
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#ifndef __CORE_CM0_H_GENERIC
+#define __CORE_CM0_H_GENERIC
+
+
+/** \mainpage CMSIS Cortex-M0
+
+ This documentation describes the CMSIS Cortex-M Core Peripheral Access Layer.
+ It consists of:
+
+ - Cortex-M Core Register Definitions
+ - Cortex-M functions
+ - Cortex-M instructions
+
+ The CMSIS Cortex-M0 Core Peripheral Access Layer contains C and assembly functions that ease
+ access to the Cortex-M Core
+ */
+
+/** \defgroup CMSIS_MISRA_Exceptions CMSIS MISRA-C:2004 Compliance Exceptions
+ CMSIS violates following MISRA-C2004 Rules:
+
+ - Violates MISRA 2004 Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'.
+
+ - Violates MISRA 2004 Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers.
+
+ - Violates MISRA 2004 Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code.
+
+ */
+
+
+/*******************************************************************************
+ * CMSIS definitions
+ ******************************************************************************/
+/** \defgroup CMSIS_core_definitions CMSIS Core Definitions
+ This file defines all structures and symbols for CMSIS core:
+ - CMSIS version number
+ - Cortex-M core
+ - Cortex-M core Revision Number
+ @{
+ */
+
+/* CMSIS CM0 definitions */
+#define __CM0_CMSIS_VERSION_MAIN (0x02) /*!< [31:16] CMSIS HAL main version */
+#define __CM0_CMSIS_VERSION_SUB (0x10) /*!< [15:0] CMSIS HAL sub version */
+#define __CM0_CMSIS_VERSION ((__CM0_CMSIS_VERSION_MAIN << 16) | __CM0_CMSIS_VERSION_SUB) /*!< CMSIS HAL version number */
+
+#define __CORTEX_M (0x00) /*!< Cortex core */
+
+
+#if defined ( __CC_ARM )
+ #define __ASM __asm /*!< asm keyword for ARM Compiler */
+ #define __INLINE __inline /*!< inline keyword for ARM Compiler */
+
+#elif defined ( __ICCARM__ )
+ #define __ASM __asm /*!< asm keyword for IAR Compiler */
+ #define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */
+
+#elif defined ( __GNUC__ )
+ #define __ASM __asm /*!< asm keyword for GNU Compiler */
+ #define __INLINE inline /*!< inline keyword for GNU Compiler */
+
+#elif defined ( __TASKING__ )
+ #define __ASM __asm /*!< asm keyword for TASKING Compiler */
+ #define __INLINE inline /*!< inline keyword for TASKING Compiler */
+
+#endif
+
+/*!< __FPU_USED to be checked prior to making use of FPU specific registers and functions */
+#define __FPU_USED 0
+
+#if defined ( __CC_ARM )
+ #if defined __TARGET_FPU_VFP
+ #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #endif
+#elif defined ( __ICCARM__ )
+ #if defined __ARMVFP__
+ #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #endif
+
+#elif defined ( __GNUC__ )
+ #if defined (__VFP_FP__) && !defined(__SOFTFP__)
+ #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #endif
+
+#elif defined ( __TASKING__ )
+ /* add preprocessor checks */
+#endif
+
+#include /*!< standard types definitions */
+#include "core_cmInstr.h" /*!< Core Instruction Access */
+#include "core_cmFunc.h" /*!< Core Function Access */
+
+#endif /* __CORE_CM0_H_GENERIC */
+
+#ifndef __CMSIS_GENERIC
+
+#ifndef __CORE_CM0_H_DEPENDANT
+#define __CORE_CM0_H_DEPENDANT
+
+/* check device defines and use defaults */
+#if defined __CHECK_DEVICE_DEFINES
+ #ifndef __CM0_REV
+ #define __CM0_REV 0x0000
+ #warning "__CM0_REV not defined in device header file; using default!"
+ #endif
+
+ #ifndef __NVIC_PRIO_BITS
+ #define __NVIC_PRIO_BITS 2
+ #warning "__NVIC_PRIO_BITS not defined in device header file; using default!"
+ #endif
+
+ #ifndef __Vendor_SysTickConfig
+ #define __Vendor_SysTickConfig 0
+ #warning "__Vendor_SysTickConfig not defined in device header file; using default!"
+ #endif
+#endif
+
+/* IO definitions (access restrictions to peripheral registers) */
+#ifdef __cplusplus
+ #define __I volatile /*!< defines 'read only' permissions */
+#else
+ #define __I volatile const /*!< defines 'read only' permissions */
+#endif
+#define __O volatile /*!< defines 'write only' permissions */
+#define __IO volatile /*!< defines 'read / write' permissions */
+
+/*@} end of group CMSIS_core_definitions */
+
+
+
+/*******************************************************************************
+ * Register Abstraction
+ ******************************************************************************/
+/** \defgroup CMSIS_core_register CMSIS Core Register
+ Core Register contain:
+ - Core Register
+ - Core NVIC Register
+ - Core SCB Register
+ - Core SysTick Register
+*/
+
+/** \ingroup CMSIS_core_register
+ \defgroup CMSIS_CORE CMSIS Core
+ Type definitions for the Cortex-M Core Registers
+ @{
+ */
+
+/** \brief Union type to access the Application Program Status Register (APSR).
+ */
+typedef union
+{
+ struct
+ {
+#if (__CORTEX_M != 0x04)
+ uint32_t _reserved0:27; /*!< bit: 0..26 Reserved */
+#else
+ uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */
+ uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */
+ uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */
+#endif
+ uint32_t Q:1; /*!< bit: 27 Saturation condition flag */
+ uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
+ uint32_t C:1; /*!< bit: 29 Carry condition code flag */
+ uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
+ uint32_t N:1; /*!< bit: 31 Negative condition code flag */
+ } b; /*!< Structure used for bit access */
+ uint32_t w; /*!< Type used for word access */
+} APSR_Type;
+
+
+/** \brief Union type to access the Interrupt Program Status Register (IPSR).
+ */
+typedef union
+{
+ struct
+ {
+ uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
+ uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */
+ } b; /*!< Structure used for bit access */
+ uint32_t w; /*!< Type used for word access */
+} IPSR_Type;
+
+
+/** \brief Union type to access the Special-Purpose Program Status Registers (xPSR).
+ */
+typedef union
+{
+ struct
+ {
+ uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
+#if (__CORTEX_M != 0x04)
+ uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */
+#else
+ uint32_t _reserved0:7; /*!< bit: 9..15 Reserved */
+ uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */
+ uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */
+#endif
+ uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */
+ uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */
+ uint32_t Q:1; /*!< bit: 27 Saturation condition flag */
+ uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
+ uint32_t C:1; /*!< bit: 29 Carry condition code flag */
+ uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
+ uint32_t N:1; /*!< bit: 31 Negative condition code flag */
+ } b; /*!< Structure used for bit access */
+ uint32_t w; /*!< Type used for word access */
+} xPSR_Type;
+
+
+/** \brief Union type to access the Control Registers (CONTROL).
+ */
+typedef union
+{
+ struct
+ {
+ uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */
+ uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */
+ uint32_t FPCA:1; /*!< bit: 2 FP extension active flag */
+ uint32_t _reserved0:29; /*!< bit: 3..31 Reserved */
+ } b; /*!< Structure used for bit access */
+ uint32_t w; /*!< Type used for word access */
+} CONTROL_Type;
+
+/*@} end of group CMSIS_CORE */
+
+
+/** \ingroup CMSIS_core_register
+ \defgroup CMSIS_NVIC CMSIS NVIC
+ Type definitions for the Cortex-M NVIC Registers
+ @{
+ */
+
+/** \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC).
+ */
+typedef struct
+{
+ __IO uint32_t ISER[1]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */
+ uint32_t RESERVED0[31];
+ __IO uint32_t ICER[1]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */
+ uint32_t RSERVED1[31];
+ __IO uint32_t ISPR[1]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */
+ uint32_t RESERVED2[31];
+ __IO uint32_t ICPR[1]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */
+ uint32_t RESERVED3[31];
+ uint32_t RESERVED4[64];
+ __IO uint32_t IP[8]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */
+} NVIC_Type;
+
+/*@} end of group CMSIS_NVIC */
+
+
+/** \ingroup CMSIS_core_register
+ \defgroup CMSIS_SCB CMSIS SCB
+ Type definitions for the Cortex-M System Control Block Registers
+ @{
+ */
+
+/** \brief Structure type to access the System Control Block (SCB).
+ */
+typedef struct
+{
+ __I uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */
+ __IO uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */
+ uint32_t RESERVED0;
+ __IO uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */
+ __IO uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */
+ __IO uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */
+ uint32_t RESERVED1;
+ __IO uint32_t SHP[2]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */
+ __IO uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */
+} SCB_Type;
+
+/* SCB CPUID Register Definitions */
+#define SCB_CPUID_IMPLEMENTER_Pos 24 /*!< SCB CPUID: IMPLEMENTER Position */
+#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */
+
+#define SCB_CPUID_VARIANT_Pos 20 /*!< SCB CPUID: VARIANT Position */
+#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */
+
+#define SCB_CPUID_ARCHITECTURE_Pos 16 /*!< SCB CPUID: ARCHITECTURE Position */
+#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */
+
+#define SCB_CPUID_PARTNO_Pos 4 /*!< SCB CPUID: PARTNO Position */
+#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */
+
+#define SCB_CPUID_REVISION_Pos 0 /*!< SCB CPUID: REVISION Position */
+#define SCB_CPUID_REVISION_Msk (0xFUL << SCB_CPUID_REVISION_Pos) /*!< SCB CPUID: REVISION Mask */
+
+/* SCB Interrupt Control State Register Definitions */
+#define SCB_ICSR_NMIPENDSET_Pos 31 /*!< SCB ICSR: NMIPENDSET Position */
+#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */
+
+#define SCB_ICSR_PENDSVSET_Pos 28 /*!< SCB ICSR: PENDSVSET Position */
+#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */
+
+#define SCB_ICSR_PENDSVCLR_Pos 27 /*!< SCB ICSR: PENDSVCLR Position */
+#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */
+
+#define SCB_ICSR_PENDSTSET_Pos 26 /*!< SCB ICSR: PENDSTSET Position */
+#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */
+
+#define SCB_ICSR_PENDSTCLR_Pos 25 /*!< SCB ICSR: PENDSTCLR Position */
+#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */
+
+#define SCB_ICSR_ISRPREEMPT_Pos 23 /*!< SCB ICSR: ISRPREEMPT Position */
+#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */
+
+#define SCB_ICSR_ISRPENDING_Pos 22 /*!< SCB ICSR: ISRPENDING Position */
+#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */
+
+#define SCB_ICSR_VECTPENDING_Pos 12 /*!< SCB ICSR: VECTPENDING Position */
+#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */
+
+#define SCB_ICSR_VECTACTIVE_Pos 0 /*!< SCB ICSR: VECTACTIVE Position */
+#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL << SCB_ICSR_VECTACTIVE_Pos) /*!< SCB ICSR: VECTACTIVE Mask */
+
+/* SCB Application Interrupt and Reset Control Register Definitions */
+#define SCB_AIRCR_VECTKEY_Pos 16 /*!< SCB AIRCR: VECTKEY Position */
+#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */
+
+#define SCB_AIRCR_VECTKEYSTAT_Pos 16 /*!< SCB AIRCR: VECTKEYSTAT Position */
+#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */
+
+#define SCB_AIRCR_ENDIANESS_Pos 15 /*!< SCB AIRCR: ENDIANESS Position */
+#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */
+
+#define SCB_AIRCR_SYSRESETREQ_Pos 2 /*!< SCB AIRCR: SYSRESETREQ Position */
+#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */
+
+#define SCB_AIRCR_VECTCLRACTIVE_Pos 1 /*!< SCB AIRCR: VECTCLRACTIVE Position */
+#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */
+
+/* SCB System Control Register Definitions */
+#define SCB_SCR_SEVONPEND_Pos 4 /*!< SCB SCR: SEVONPEND Position */
+#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */
+
+#define SCB_SCR_SLEEPDEEP_Pos 2 /*!< SCB SCR: SLEEPDEEP Position */
+#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */
+
+#define SCB_SCR_SLEEPONEXIT_Pos 1 /*!< SCB SCR: SLEEPONEXIT Position */
+#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */
+
+/* SCB Configuration Control Register Definitions */
+#define SCB_CCR_STKALIGN_Pos 9 /*!< SCB CCR: STKALIGN Position */
+#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */
+
+#define SCB_CCR_UNALIGN_TRP_Pos 3 /*!< SCB CCR: UNALIGN_TRP Position */
+#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */
+
+/* SCB System Handler Control and State Register Definitions */
+#define SCB_SHCSR_SVCALLPENDED_Pos 15 /*!< SCB SHCSR: SVCALLPENDED Position */
+#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */
+
+/*@} end of group CMSIS_SCB */
+
+
+/** \ingroup CMSIS_core_register
+ \defgroup CMSIS_SysTick CMSIS SysTick
+ Type definitions for the Cortex-M System Timer Registers
+ @{
+ */
+
+/** \brief Structure type to access the System Timer (SysTick).
+ */
+typedef struct
+{
+ __IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */
+ __IO uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */
+ __IO uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */
+ __I uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */
+} SysTick_Type;
+
+/* SysTick Control / Status Register Definitions */
+#define SysTick_CTRL_COUNTFLAG_Pos 16 /*!< SysTick CTRL: COUNTFLAG Position */
+#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */
+
+#define SysTick_CTRL_CLKSOURCE_Pos 2 /*!< SysTick CTRL: CLKSOURCE Position */
+#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */
+
+#define SysTick_CTRL_TICKINT_Pos 1 /*!< SysTick CTRL: TICKINT Position */
+#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */
+
+#define SysTick_CTRL_ENABLE_Pos 0 /*!< SysTick CTRL: ENABLE Position */
+#define SysTick_CTRL_ENABLE_Msk (1UL << SysTick_CTRL_ENABLE_Pos) /*!< SysTick CTRL: ENABLE Mask */
+
+/* SysTick Reload Register Definitions */
+#define SysTick_LOAD_RELOAD_Pos 0 /*!< SysTick LOAD: RELOAD Position */
+#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL << SysTick_LOAD_RELOAD_Pos) /*!< SysTick LOAD: RELOAD Mask */
+
+/* SysTick Current Register Definitions */
+#define SysTick_VAL_CURRENT_Pos 0 /*!< SysTick VAL: CURRENT Position */
+#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL << SysTick_VAL_CURRENT_Pos) /*!< SysTick VAL: CURRENT Mask */
+
+/* SysTick Calibration Register Definitions */
+#define SysTick_CALIB_NOREF_Pos 31 /*!< SysTick CALIB: NOREF Position */
+#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */
+
+#define SysTick_CALIB_SKEW_Pos 30 /*!< SysTick CALIB: SKEW Position */
+#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */
+
+#define SysTick_CALIB_TENMS_Pos 0 /*!< SysTick CALIB: TENMS Position */
+#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL << SysTick_VAL_CURRENT_Pos) /*!< SysTick CALIB: TENMS Mask */
+
+/*@} end of group CMSIS_SysTick */
+
+
+/** \ingroup CMSIS_core_register
+ \defgroup CMSIS_CoreDebug CMSIS Core Debug
+ Cortex-M0 Core Debug Registers (DCB registers, SHCSR, and DFSR) are only accessible over DAP
+ and not via processor. Therefore they are not covered by the Cortex-M0 header file.
+ @{
+ */
+/*@} end of group CMSIS_CoreDebug */
+
+
+/** \ingroup CMSIS_core_register
+ @{
+ */
+
+/* Memory mapping of Cortex-M0 Hardware */
+#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */
+#define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */
+#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */
+#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */
+#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */
+
+#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */
+#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */
+#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */
+
+
+/*@} */
+
+
+
+/*******************************************************************************
+ * Hardware Abstraction Layer
+ ******************************************************************************/
+/** \defgroup CMSIS_Core_FunctionInterface CMSIS Core Function Interface
+ Core Function Interface contains:
+ - Core NVIC Functions
+ - Core SysTick Functions
+ - Core Register Access Functions
+*/
+
+
+
+/* ########################## NVIC functions #################################### */
+/** \ingroup CMSIS_Core_FunctionInterface
+ \defgroup CMSIS_Core_NVICFunctions CMSIS Core NVIC Functions
+ @{
+ */
+
+/* Interrupt Priorities are WORD accessible only under ARMv6M */
+/* The following MACROS handle generation of the register offset and byte masks */
+#define _BIT_SHIFT(IRQn) ( (((uint32_t)(IRQn) ) & 0x03) * 8 )
+#define _SHP_IDX(IRQn) ( ((((uint32_t)(IRQn) & 0x0F)-8) >> 2) )
+#define _IP_IDX(IRQn) ( ((uint32_t)(IRQn) >> 2) )
+
+
+/** \brief Enable External Interrupt
+
+ This function enables a device specific interrupt in the NVIC interrupt controller.
+ The interrupt number cannot be a negative value.
+
+ \param [in] IRQn Number of the external interrupt to enable
+ */
+static __INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
+{
+ NVIC->ISER[0] = (1 << ((uint32_t)(IRQn) & 0x1F));
+}
+
+
+/** \brief Disable External Interrupt
+
+ This function disables a device specific interrupt in the NVIC interrupt controller.
+ The interrupt number cannot be a negative value.
+
+ \param [in] IRQn Number of the external interrupt to disable
+ */
+static __INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)
+{
+ NVIC->ICER[0] = (1 << ((uint32_t)(IRQn) & 0x1F));
+}
+
+
+/** \brief Get Pending Interrupt
+
+ This function reads the pending register in the NVIC and returns the pending bit
+ for the specified interrupt.
+
+ \param [in] IRQn Number of the interrupt for get pending
+ \return 0 Interrupt status is not pending
+ \return 1 Interrupt status is pending
+ */
+static __INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)
+{
+ return((uint32_t) ((NVIC->ISPR[0] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0));
+}
+
+
+/** \brief Set Pending Interrupt
+
+ This function sets the pending bit for the specified interrupt.
+ The interrupt number cannot be a negative value.
+
+ \param [in] IRQn Number of the interrupt for set pending
+ */
+static __INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn)
+{
+ NVIC->ISPR[0] = (1 << ((uint32_t)(IRQn) & 0x1F));
+}
+
+
+/** \brief Clear Pending Interrupt
+
+ This function clears the pending bit for the specified interrupt.
+ The interrupt number cannot be a negative value.
+
+ \param [in] IRQn Number of the interrupt for clear pending
+ */
+static __INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
+{
+ NVIC->ICPR[0] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* Clear pending interrupt */
+}
+
+
+/** \brief Set Interrupt Priority
+
+ This function sets the priority for the specified interrupt. The interrupt
+ number can be positive to specify an external (device specific)
+ interrupt, or negative to specify an internal (core) interrupt.
+
+ Note: The priority cannot be set for every core interrupt.
+
+ \param [in] IRQn Number of the interrupt for set priority
+ \param [in] priority Priority to set
+ */
+static __INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
+{
+ if(IRQn < 0) {
+ SCB->SHP[_SHP_IDX(IRQn)] = (SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFF << _BIT_SHIFT(IRQn))) |
+ (((priority << (8 - __NVIC_PRIO_BITS)) & 0xFF) << _BIT_SHIFT(IRQn)); }
+ else {
+ NVIC->IP[_IP_IDX(IRQn)] = (NVIC->IP[_IP_IDX(IRQn)] & ~(0xFF << _BIT_SHIFT(IRQn))) |
+ (((priority << (8 - __NVIC_PRIO_BITS)) & 0xFF) << _BIT_SHIFT(IRQn)); }
+}
+
+
+/** \brief Get Interrupt Priority
+
+ This function reads the priority for the specified interrupt. The interrupt
+ number can be positive to specify an external (device specific)
+ interrupt, or negative to specify an internal (core) interrupt.
+
+ The returned priority value is automatically aligned to the implemented
+ priority bits of the microcontroller.
+
+ \param [in] IRQn Number of the interrupt for get priority
+ \return Interrupt Priority
+ */
+static __INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn)
+{
+
+ if(IRQn < 0) {
+ return((uint32_t)((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) >> (8 - __NVIC_PRIO_BITS))); } /* get priority for Cortex-M0 system interrupts */
+ else {
+ return((uint32_t)((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) >> (8 - __NVIC_PRIO_BITS))); } /* get priority for device specific interrupts */
+}
+
+
+/** \brief System Reset
+
+ This function initiate a system reset request to reset the MCU.
+ */
+static __INLINE void NVIC_SystemReset(void)
+{
+ __DSB(); /* Ensure all outstanding memory accesses included
+ buffered write are completed before reset */
+ SCB->AIRCR = ((0x5FA << SCB_AIRCR_VECTKEY_Pos) |
+ SCB_AIRCR_SYSRESETREQ_Msk);
+ __DSB(); /* Ensure completion of memory access */
+ while(1); /* wait until reset */
+}
+
+/*@} end of CMSIS_Core_NVICFunctions */
+
+
+
+/* ################################## SysTick function ############################################ */
+/** \ingroup CMSIS_Core_FunctionInterface
+ \defgroup CMSIS_Core_SysTickFunctions CMSIS Core SysTick Functions
+ @{
+ */
+
+#if (__Vendor_SysTickConfig == 0)
+
+/** \brief System Tick Configuration
+
+ This function initialises the system tick timer and its interrupt and start the system tick timer.
+ Counter is in free running mode to generate periodical interrupts.
+
+ \param [in] ticks Number of ticks between two interrupts
+ \return 0 Function succeeded
+ \return 1 Function failed
+ */
+static __INLINE uint32_t SysTick_Config(uint32_t ticks)
+{
+ if (ticks > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */
+
+ SysTick->LOAD = (ticks & SysTick_LOAD_RELOAD_Msk) - 1; /* set reload register */
+ NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Cortex-M0 System Interrupts */
+ SysTick->VAL = 0; /* Load the SysTick Counter Value */
+ SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
+ SysTick_CTRL_TICKINT_Msk |
+ SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */
+ return (0); /* Function successful */
+}
+
+#endif
+
+/*@} end of CMSIS_Core_SysTickFunctions */
+
+
+
+
+#endif /* __CORE_CM0_H_DEPENDANT */
+
+#endif /* __CMSIS_GENERIC */
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/platform/mcu/CMSIS/Include/core_cm3.h b/platform/mcu/CMSIS/Include/core_cm3.h
new file mode 100644
index 00000000..c15e10ae
--- /dev/null
+++ b/platform/mcu/CMSIS/Include/core_cm3.h
@@ -0,0 +1,1236 @@
+/**************************************************************************//**
+ * @file core_cm3.h
+ * @brief CMSIS Cortex-M3 Core Peripheral Access Layer Header File
+ * @version V2.10
+ * @date 19. July 2011
+ *
+ * @note
+ * Copyright (C) 2009-2011 ARM Limited. All rights reserved.
+ *
+ * @par
+ * ARM Limited (ARM) is supplying this software for use with Cortex-M
+ * processor based microcontrollers. This file can be freely distributed
+ * within development tools that are supporting such ARM based processors.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
+ * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
+ * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
+ * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
+ *
+ ******************************************************************************/
+#if defined ( __ICCARM__ )
+ #pragma system_include /* treat file as system include file for MISRA check */
+#endif
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#ifndef __CORE_CM3_H_GENERIC
+#define __CORE_CM3_H_GENERIC
+
+
+/** \mainpage CMSIS Cortex-M3
+
+ This documentation describes the CMSIS Cortex-M Core Peripheral Access Layer.
+ It consists of:
+
+ - Cortex-M Core Register Definitions
+ - Cortex-M functions
+ - Cortex-M instructions
+
+ The CMSIS Cortex-M3 Core Peripheral Access Layer contains C and assembly functions that ease
+ access to the Cortex-M Core
+ */
+
+/** \defgroup CMSIS_MISRA_Exceptions CMSIS MISRA-C:2004 Compliance Exceptions
+ CMSIS violates following MISRA-C2004 Rules:
+
+ - Violates MISRA 2004 Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'.
+
+ - Violates MISRA 2004 Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers.
+
+ - Violates MISRA 2004 Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code.
+
+ */
+
+
+/*******************************************************************************
+ * CMSIS definitions
+ ******************************************************************************/
+/** \defgroup CMSIS_core_definitions CMSIS Core Definitions
+ This file defines all structures and symbols for CMSIS core:
+ - CMSIS version number
+ - Cortex-M core
+ - Cortex-M core Revision Number
+ @{
+ */
+
+/* CMSIS CM3 definitions */
+#define __CM3_CMSIS_VERSION_MAIN (0x02) /*!< [31:16] CMSIS HAL main version */
+#define __CM3_CMSIS_VERSION_SUB (0x10) /*!< [15:0] CMSIS HAL sub version */
+#define __CM3_CMSIS_VERSION ((__CM3_CMSIS_VERSION_MAIN << 16) | __CM3_CMSIS_VERSION_SUB) /*!< CMSIS HAL version number */
+
+#define __CORTEX_M (0x03) /*!< Cortex core */
+
+
+#if defined ( __CC_ARM )
+ #define __ASM __asm /*!< asm keyword for ARM Compiler */
+ #define __INLINE __inline /*!< inline keyword for ARM Compiler */
+
+#elif defined ( __ICCARM__ )
+ #define __ASM __asm /*!< asm keyword for IAR Compiler */
+ #define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */
+
+#elif defined ( __GNUC__ )
+ #define __ASM __asm /*!< asm keyword for GNU Compiler */
+ #define __INLINE inline /*!< inline keyword for GNU Compiler */
+
+#elif defined ( __TASKING__ )
+ #define __ASM __asm /*!< asm keyword for TASKING Compiler */
+ #define __INLINE inline /*!< inline keyword for TASKING Compiler */
+
+#endif
+
+/*!< __FPU_USED to be checked prior to making use of FPU specific registers and functions */
+#define __FPU_USED 0
+
+#if defined ( __CC_ARM )
+ #if defined __TARGET_FPU_VFP
+ #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #endif
+#elif defined ( __ICCARM__ )
+ #if defined __ARMVFP__
+ #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #endif
+
+#elif defined ( __GNUC__ )
+ #if defined (__VFP_FP__) && !defined(__SOFTFP__)
+ #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #endif
+
+#elif defined ( __TASKING__ )
+ /* add preprocessor checks */
+#endif
+
+#include /*!< standard types definitions */
+#include "core_cmInstr.h" /*!< Core Instruction Access */
+#include "core_cmFunc.h" /*!< Core Function Access */
+
+#endif /* __CORE_CM3_H_GENERIC */
+
+#ifndef __CMSIS_GENERIC
+
+#ifndef __CORE_CM3_H_DEPENDANT
+#define __CORE_CM3_H_DEPENDANT
+
+/* check device defines and use defaults */
+#if defined __CHECK_DEVICE_DEFINES
+ #ifndef __CM3_REV
+ #define __CM3_REV 0x0200
+ #warning "__CM3_REV not defined in device header file; using default!"
+ #endif
+
+ #ifndef __MPU_PRESENT
+ #define __MPU_PRESENT 0
+ #warning "__MPU_PRESENT not defined in device header file; using default!"
+ #endif
+
+ #ifndef __NVIC_PRIO_BITS
+ #define __NVIC_PRIO_BITS 4
+ #warning "__NVIC_PRIO_BITS not defined in device header file; using default!"
+ #endif
+
+ #ifndef __Vendor_SysTickConfig
+ #define __Vendor_SysTickConfig 0
+ #warning "__Vendor_SysTickConfig not defined in device header file; using default!"
+ #endif
+#endif
+
+/* IO definitions (access restrictions to peripheral registers) */
+#ifdef __cplusplus
+ #define __I volatile /*!< defines 'read only' permissions */
+#else
+ #define __I volatile const /*!< defines 'read only' permissions */
+#endif
+#define __O volatile /*!< defines 'write only' permissions */
+#define __IO volatile /*!< defines 'read / write' permissions */
+
+/*@} end of group CMSIS_core_definitions */
+
+
+
+/*******************************************************************************
+ * Register Abstraction
+ ******************************************************************************/
+/** \defgroup CMSIS_core_register CMSIS Core Register
+ Core Register contain:
+ - Core Register
+ - Core NVIC Register
+ - Core SCB Register
+ - Core SysTick Register
+ - Core Debug Register
+ - Core MPU Register
+*/
+
+/** \ingroup CMSIS_core_register
+ \defgroup CMSIS_CORE CMSIS Core
+ Type definitions for the Cortex-M Core Registers
+ @{
+ */
+
+/** \brief Union type to access the Application Program Status Register (APSR).
+ */
+typedef union
+{
+ struct
+ {
+#if (__CORTEX_M != 0x04)
+ uint32_t _reserved0:27; /*!< bit: 0..26 Reserved */
+#else
+ uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */
+ uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */
+ uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */
+#endif
+ uint32_t Q:1; /*!< bit: 27 Saturation condition flag */
+ uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
+ uint32_t C:1; /*!< bit: 29 Carry condition code flag */
+ uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
+ uint32_t N:1; /*!< bit: 31 Negative condition code flag */
+ } b; /*!< Structure used for bit access */
+ uint32_t w; /*!< Type used for word access */
+} APSR_Type;
+
+
+/** \brief Union type to access the Interrupt Program Status Register (IPSR).
+ */
+typedef union
+{
+ struct
+ {
+ uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
+ uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */
+ } b; /*!< Structure used for bit access */
+ uint32_t w; /*!< Type used for word access */
+} IPSR_Type;
+
+
+/** \brief Union type to access the Special-Purpose Program Status Registers (xPSR).
+ */
+typedef union
+{
+ struct
+ {
+ uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
+#if (__CORTEX_M != 0x04)
+ uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */
+#else
+ uint32_t _reserved0:7; /*!< bit: 9..15 Reserved */
+ uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */
+ uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */
+#endif
+ uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */
+ uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */
+ uint32_t Q:1; /*!< bit: 27 Saturation condition flag */
+ uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
+ uint32_t C:1; /*!< bit: 29 Carry condition code flag */
+ uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
+ uint32_t N:1; /*!< bit: 31 Negative condition code flag */
+ } b; /*!< Structure used for bit access */
+ uint32_t w; /*!< Type used for word access */
+} xPSR_Type;
+
+
+/** \brief Union type to access the Control Registers (CONTROL).
+ */
+typedef union
+{
+ struct
+ {
+ uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */
+ uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */
+ uint32_t FPCA:1; /*!< bit: 2 FP extension active flag */
+ uint32_t _reserved0:29; /*!< bit: 3..31 Reserved */
+ } b; /*!< Structure used for bit access */
+ uint32_t w; /*!< Type used for word access */
+} CONTROL_Type;
+
+/*@} end of group CMSIS_CORE */
+
+
+/** \ingroup CMSIS_core_register
+ \defgroup CMSIS_NVIC CMSIS NVIC
+ Type definitions for the Cortex-M NVIC Registers
+ @{
+ */
+
+/** \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC).
+ */
+typedef struct
+{
+ __IO uint32_t ISER[8]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */
+ uint32_t RESERVED0[24];
+ __IO uint32_t ICER[8]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */
+ uint32_t RSERVED1[24];
+ __IO uint32_t ISPR[8]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */
+ uint32_t RESERVED2[24];
+ __IO uint32_t ICPR[8]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */
+ uint32_t RESERVED3[24];
+ __IO uint32_t IABR[8]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */
+ uint32_t RESERVED4[56];
+ __IO uint8_t IP[240]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */
+ uint32_t RESERVED5[644];
+ __O uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */
+} NVIC_Type;
+
+/* Software Triggered Interrupt Register Definitions */
+#define NVIC_STIR_INTID_Pos 0 /*!< STIR: INTLINESNUM Position */
+#define NVIC_STIR_INTID_Msk (0x1FFUL << NVIC_STIR_INTID_Pos) /*!< STIR: INTLINESNUM Mask */
+
+/*@} end of group CMSIS_NVIC */
+
+
+/** \ingroup CMSIS_core_register
+ \defgroup CMSIS_SCB CMSIS SCB
+ Type definitions for the Cortex-M System Control Block Registers
+ @{
+ */
+
+/** \brief Structure type to access the System Control Block (SCB).
+ */
+typedef struct
+{
+ __I uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */
+ __IO uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */
+ __IO uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */
+ __IO uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */
+ __IO uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */
+ __IO uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */
+ __IO uint8_t SHP[12]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */
+ __IO uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */
+ __IO uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */
+ __IO uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */
+ __IO uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */
+ __IO uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */
+ __IO uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */
+ __IO uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */
+ __I uint32_t PFR[2]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */
+ __I uint32_t DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */
+ __I uint32_t ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */
+ __I uint32_t MMFR[4]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */
+ __I uint32_t ISAR[5]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */
+ uint32_t RESERVED0[5];
+ __IO uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */
+} SCB_Type;
+
+/* SCB CPUID Register Definitions */
+#define SCB_CPUID_IMPLEMENTER_Pos 24 /*!< SCB CPUID: IMPLEMENTER Position */
+#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */
+
+#define SCB_CPUID_VARIANT_Pos 20 /*!< SCB CPUID: VARIANT Position */
+#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */
+
+#define SCB_CPUID_ARCHITECTURE_Pos 16 /*!< SCB CPUID: ARCHITECTURE Position */
+#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */
+
+#define SCB_CPUID_PARTNO_Pos 4 /*!< SCB CPUID: PARTNO Position */
+#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */
+
+#define SCB_CPUID_REVISION_Pos 0 /*!< SCB CPUID: REVISION Position */
+#define SCB_CPUID_REVISION_Msk (0xFUL << SCB_CPUID_REVISION_Pos) /*!< SCB CPUID: REVISION Mask */
+
+/* SCB Interrupt Control State Register Definitions */
+#define SCB_ICSR_NMIPENDSET_Pos 31 /*!< SCB ICSR: NMIPENDSET Position */
+#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */
+
+#define SCB_ICSR_PENDSVSET_Pos 28 /*!< SCB ICSR: PENDSVSET Position */
+#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */
+
+#define SCB_ICSR_PENDSVCLR_Pos 27 /*!< SCB ICSR: PENDSVCLR Position */
+#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */
+
+#define SCB_ICSR_PENDSTSET_Pos 26 /*!< SCB ICSR: PENDSTSET Position */
+#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */
+
+#define SCB_ICSR_PENDSTCLR_Pos 25 /*!< SCB ICSR: PENDSTCLR Position */
+#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */
+
+#define SCB_ICSR_ISRPREEMPT_Pos 23 /*!< SCB ICSR: ISRPREEMPT Position */
+#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */
+
+#define SCB_ICSR_ISRPENDING_Pos 22 /*!< SCB ICSR: ISRPENDING Position */
+#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */
+
+#define SCB_ICSR_VECTPENDING_Pos 12 /*!< SCB ICSR: VECTPENDING Position */
+#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */
+
+#define SCB_ICSR_RETTOBASE_Pos 11 /*!< SCB ICSR: RETTOBASE Position */
+#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */
+
+#define SCB_ICSR_VECTACTIVE_Pos 0 /*!< SCB ICSR: VECTACTIVE Position */
+#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL << SCB_ICSR_VECTACTIVE_Pos) /*!< SCB ICSR: VECTACTIVE Mask */
+
+/* SCB Vector Table Offset Register Definitions */
+#define SCB_VTOR_TBLOFF_Pos 7 /*!< SCB VTOR: TBLOFF Position */
+#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */
+
+/* SCB Application Interrupt and Reset Control Register Definitions */
+#define SCB_AIRCR_VECTKEY_Pos 16 /*!< SCB AIRCR: VECTKEY Position */
+#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */
+
+#define SCB_AIRCR_VECTKEYSTAT_Pos 16 /*!< SCB AIRCR: VECTKEYSTAT Position */
+#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */
+
+#define SCB_AIRCR_ENDIANESS_Pos 15 /*!< SCB AIRCR: ENDIANESS Position */
+#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */
+
+#define SCB_AIRCR_PRIGROUP_Pos 8 /*!< SCB AIRCR: PRIGROUP Position */
+#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */
+
+#define SCB_AIRCR_SYSRESETREQ_Pos 2 /*!< SCB AIRCR: SYSRESETREQ Position */
+#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */
+
+#define SCB_AIRCR_VECTCLRACTIVE_Pos 1 /*!< SCB AIRCR: VECTCLRACTIVE Position */
+#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */
+
+#define SCB_AIRCR_VECTRESET_Pos 0 /*!< SCB AIRCR: VECTRESET Position */
+#define SCB_AIRCR_VECTRESET_Msk (1UL << SCB_AIRCR_VECTRESET_Pos) /*!< SCB AIRCR: VECTRESET Mask */
+
+/* SCB System Control Register Definitions */
+#define SCB_SCR_SEVONPEND_Pos 4 /*!< SCB SCR: SEVONPEND Position */
+#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */
+
+#define SCB_SCR_SLEEPDEEP_Pos 2 /*!< SCB SCR: SLEEPDEEP Position */
+#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */
+
+#define SCB_SCR_SLEEPONEXIT_Pos 1 /*!< SCB SCR: SLEEPONEXIT Position */
+#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */
+
+/* SCB Configuration Control Register Definitions */
+#define SCB_CCR_STKALIGN_Pos 9 /*!< SCB CCR: STKALIGN Position */
+#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */
+
+#define SCB_CCR_BFHFNMIGN_Pos 8 /*!< SCB CCR: BFHFNMIGN Position */
+#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */
+
+#define SCB_CCR_DIV_0_TRP_Pos 4 /*!< SCB CCR: DIV_0_TRP Position */
+#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */
+
+#define SCB_CCR_UNALIGN_TRP_Pos 3 /*!< SCB CCR: UNALIGN_TRP Position */
+#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */
+
+#define SCB_CCR_USERSETMPEND_Pos 1 /*!< SCB CCR: USERSETMPEND Position */
+#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */
+
+#define SCB_CCR_NONBASETHRDENA_Pos 0 /*!< SCB CCR: NONBASETHRDENA Position */
+#define SCB_CCR_NONBASETHRDENA_Msk (1UL << SCB_CCR_NONBASETHRDENA_Pos) /*!< SCB CCR: NONBASETHRDENA Mask */
+
+/* SCB System Handler Control and State Register Definitions */
+#define SCB_SHCSR_USGFAULTENA_Pos 18 /*!< SCB SHCSR: USGFAULTENA Position */
+#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */
+
+#define SCB_SHCSR_BUSFAULTENA_Pos 17 /*!< SCB SHCSR: BUSFAULTENA Position */
+#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */
+
+#define SCB_SHCSR_MEMFAULTENA_Pos 16 /*!< SCB SHCSR: MEMFAULTENA Position */
+#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */
+
+#define SCB_SHCSR_SVCALLPENDED_Pos 15 /*!< SCB SHCSR: SVCALLPENDED Position */
+#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */
+
+#define SCB_SHCSR_BUSFAULTPENDED_Pos 14 /*!< SCB SHCSR: BUSFAULTPENDED Position */
+#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */
+
+#define SCB_SHCSR_MEMFAULTPENDED_Pos 13 /*!< SCB SHCSR: MEMFAULTPENDED Position */
+#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */
+
+#define SCB_SHCSR_USGFAULTPENDED_Pos 12 /*!< SCB SHCSR: USGFAULTPENDED Position */
+#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */
+
+#define SCB_SHCSR_SYSTICKACT_Pos 11 /*!< SCB SHCSR: SYSTICKACT Position */
+#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */
+
+#define SCB_SHCSR_PENDSVACT_Pos 10 /*!< SCB SHCSR: PENDSVACT Position */
+#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */
+
+#define SCB_SHCSR_MONITORACT_Pos 8 /*!< SCB SHCSR: MONITORACT Position */
+#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */
+
+#define SCB_SHCSR_SVCALLACT_Pos 7 /*!< SCB SHCSR: SVCALLACT Position */
+#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */
+
+#define SCB_SHCSR_USGFAULTACT_Pos 3 /*!< SCB SHCSR: USGFAULTACT Position */
+#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */
+
+#define SCB_SHCSR_BUSFAULTACT_Pos 1 /*!< SCB SHCSR: BUSFAULTACT Position */
+#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */
+
+#define SCB_SHCSR_MEMFAULTACT_Pos 0 /*!< SCB SHCSR: MEMFAULTACT Position */
+#define SCB_SHCSR_MEMFAULTACT_Msk (1UL << SCB_SHCSR_MEMFAULTACT_Pos) /*!< SCB SHCSR: MEMFAULTACT Mask */
+
+/* SCB Configurable Fault Status Registers Definitions */
+#define SCB_CFSR_USGFAULTSR_Pos 16 /*!< SCB CFSR: Usage Fault Status Register Position */
+#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */
+
+#define SCB_CFSR_BUSFAULTSR_Pos 8 /*!< SCB CFSR: Bus Fault Status Register Position */
+#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */
+
+#define SCB_CFSR_MEMFAULTSR_Pos 0 /*!< SCB CFSR: Memory Manage Fault Status Register Position */
+#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL << SCB_CFSR_MEMFAULTSR_Pos) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */
+
+/* SCB Hard Fault Status Registers Definitions */
+#define SCB_HFSR_DEBUGEVT_Pos 31 /*!< SCB HFSR: DEBUGEVT Position */
+#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */
+
+#define SCB_HFSR_FORCED_Pos 30 /*!< SCB HFSR: FORCED Position */
+#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */
+
+#define SCB_HFSR_VECTTBL_Pos 1 /*!< SCB HFSR: VECTTBL Position */
+#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */
+
+/* SCB Debug Fault Status Register Definitions */
+#define SCB_DFSR_EXTERNAL_Pos 4 /*!< SCB DFSR: EXTERNAL Position */
+#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */
+
+#define SCB_DFSR_VCATCH_Pos 3 /*!< SCB DFSR: VCATCH Position */
+#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */
+
+#define SCB_DFSR_DWTTRAP_Pos 2 /*!< SCB DFSR: DWTTRAP Position */
+#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */
+
+#define SCB_DFSR_BKPT_Pos 1 /*!< SCB DFSR: BKPT Position */
+#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */
+
+#define SCB_DFSR_HALTED_Pos 0 /*!< SCB DFSR: HALTED Position */
+#define SCB_DFSR_HALTED_Msk (1UL << SCB_DFSR_HALTED_Pos) /*!< SCB DFSR: HALTED Mask */
+
+/*@} end of group CMSIS_SCB */
+
+
+/** \ingroup CMSIS_core_register
+ \defgroup CMSIS_SCnSCB CMSIS System Control and ID Register not in the SCB
+ Type definitions for the Cortex-M System Control and ID Register not in the SCB
+ @{
+ */
+
+/** \brief Structure type to access the System Control and ID Register not in the SCB.
+ */
+typedef struct
+{
+ uint32_t RESERVED0[1];
+ __I uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */
+#if ((defined __CM3_REV) && (__CM3_REV >= 0x200))
+ __IO uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */
+#else
+ uint32_t RESERVED1[1];
+#endif
+} SCnSCB_Type;
+
+/* Interrupt Controller Type Register Definitions */
+#define SCnSCB_ICTR_INTLINESNUM_Pos 0 /*!< ICTR: INTLINESNUM Position */
+#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL << SCnSCB_ICTR_INTLINESNUM_Pos) /*!< ICTR: INTLINESNUM Mask */
+
+/* Auxiliary Control Register Definitions */
+
+#define SCnSCB_ACTLR_DISFOLD_Pos 2 /*!< ACTLR: DISFOLD Position */
+#define SCnSCB_ACTLR_DISFOLD_Msk (1UL << SCnSCB_ACTLR_DISFOLD_Pos) /*!< ACTLR: DISFOLD Mask */
+
+#define SCnSCB_ACTLR_DISDEFWBUF_Pos 1 /*!< ACTLR: DISDEFWBUF Position */
+#define SCnSCB_ACTLR_DISDEFWBUF_Msk (1UL << SCnSCB_ACTLR_DISDEFWBUF_Pos) /*!< ACTLR: DISDEFWBUF Mask */
+
+#define SCnSCB_ACTLR_DISMCYCINT_Pos 0 /*!< ACTLR: DISMCYCINT Position */
+#define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL << SCnSCB_ACTLR_DISMCYCINT_Pos) /*!< ACTLR: DISMCYCINT Mask */
+
+/*@} end of group CMSIS_SCnotSCB */
+
+
+/** \ingroup CMSIS_core_register
+ \defgroup CMSIS_SysTick CMSIS SysTick
+ Type definitions for the Cortex-M System Timer Registers
+ @{
+ */
+
+/** \brief Structure type to access the System Timer (SysTick).
+ */
+typedef struct
+{
+ __IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */
+ __IO uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */
+ __IO uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */
+ __I uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */
+} SysTick_Type;
+
+/* SysTick Control / Status Register Definitions */
+#define SysTick_CTRL_COUNTFLAG_Pos 16 /*!< SysTick CTRL: COUNTFLAG Position */
+#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */
+
+#define SysTick_CTRL_CLKSOURCE_Pos 2 /*!< SysTick CTRL: CLKSOURCE Position */
+#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */
+
+#define SysTick_CTRL_TICKINT_Pos 1 /*!< SysTick CTRL: TICKINT Position */
+#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */
+
+#define SysTick_CTRL_ENABLE_Pos 0 /*!< SysTick CTRL: ENABLE Position */
+#define SysTick_CTRL_ENABLE_Msk (1UL << SysTick_CTRL_ENABLE_Pos) /*!< SysTick CTRL: ENABLE Mask */
+
+/* SysTick Reload Register Definitions */
+#define SysTick_LOAD_RELOAD_Pos 0 /*!< SysTick LOAD: RELOAD Position */
+#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL << SysTick_LOAD_RELOAD_Pos) /*!< SysTick LOAD: RELOAD Mask */
+
+/* SysTick Current Register Definitions */
+#define SysTick_VAL_CURRENT_Pos 0 /*!< SysTick VAL: CURRENT Position */
+#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL << SysTick_VAL_CURRENT_Pos) /*!< SysTick VAL: CURRENT Mask */
+
+/* SysTick Calibration Register Definitions */
+#define SysTick_CALIB_NOREF_Pos 31 /*!< SysTick CALIB: NOREF Position */
+#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */
+
+#define SysTick_CALIB_SKEW_Pos 30 /*!< SysTick CALIB: SKEW Position */
+#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */
+
+#define SysTick_CALIB_TENMS_Pos 0 /*!< SysTick CALIB: TENMS Position */
+#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL << SysTick_VAL_CURRENT_Pos) /*!< SysTick CALIB: TENMS Mask */
+
+/*@} end of group CMSIS_SysTick */
+
+
+/** \ingroup CMSIS_core_register
+ \defgroup CMSIS_ITM CMSIS ITM
+ Type definitions for the Cortex-M Instrumentation Trace Macrocell (ITM)
+ @{
+ */
+
+/** \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM).
+ */
+typedef struct
+{
+ __O union
+ {
+ __O uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */
+ __O uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */
+ __O uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */
+ } PORT [32]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */
+ uint32_t RESERVED0[864];
+ __IO uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */
+ uint32_t RESERVED1[15];
+ __IO uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */
+ uint32_t RESERVED2[15];
+ __IO uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */
+} ITM_Type;
+
+/* ITM Trace Privilege Register Definitions */
+#define ITM_TPR_PRIVMASK_Pos 0 /*!< ITM TPR: PRIVMASK Position */
+#define ITM_TPR_PRIVMASK_Msk (0xFUL << ITM_TPR_PRIVMASK_Pos) /*!< ITM TPR: PRIVMASK Mask */
+
+/* ITM Trace Control Register Definitions */
+#define ITM_TCR_BUSY_Pos 23 /*!< ITM TCR: BUSY Position */
+#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */
+
+#define ITM_TCR_TraceBusID_Pos 16 /*!< ITM TCR: ATBID Position */
+#define ITM_TCR_TraceBusID_Msk (0x7FUL << ITM_TCR_TraceBusID_Pos) /*!< ITM TCR: ATBID Mask */
+
+#define ITM_TCR_GTSFREQ_Pos 10 /*!< ITM TCR: Global timestamp frequency Position */
+#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */
+
+#define ITM_TCR_TSPrescale_Pos 8 /*!< ITM TCR: TSPrescale Position */
+#define ITM_TCR_TSPrescale_Msk (3UL << ITM_TCR_TSPrescale_Pos) /*!< ITM TCR: TSPrescale Mask */
+
+#define ITM_TCR_SWOENA_Pos 4 /*!< ITM TCR: SWOENA Position */
+#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */
+
+#define ITM_TCR_TXENA_Pos 3 /*!< ITM TCR: TXENA Position */
+#define ITM_TCR_TXENA_Msk (1UL << ITM_TCR_TXENA_Pos) /*!< ITM TCR: TXENA Mask */
+
+#define ITM_TCR_SYNCENA_Pos 2 /*!< ITM TCR: SYNCENA Position */
+#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */
+
+#define ITM_TCR_TSENA_Pos 1 /*!< ITM TCR: TSENA Position */
+#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */
+
+#define ITM_TCR_ITMENA_Pos 0 /*!< ITM TCR: ITM Enable bit Position */
+#define ITM_TCR_ITMENA_Msk (1UL << ITM_TCR_ITMENA_Pos) /*!< ITM TCR: ITM Enable bit Mask */
+
+/*@}*/ /* end of group CMSIS_ITM */
+
+
+#if (__MPU_PRESENT == 1)
+/** \ingroup CMSIS_core_register
+ \defgroup CMSIS_MPU CMSIS MPU
+ Type definitions for the Cortex-M Memory Protection Unit (MPU)
+ @{
+ */
+
+/** \brief Structure type to access the Memory Protection Unit (MPU).
+ */
+typedef struct
+{
+ __I uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */
+ __IO uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */
+ __IO uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */
+ __IO uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */
+ __IO uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */
+ __IO uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Alias 1 Region Base Address Register */
+ __IO uint32_t RASR_A1; /*!< Offset: 0x018 (R/W) MPU Alias 1 Region Attribute and Size Register */
+ __IO uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Alias 2 Region Base Address Register */
+ __IO uint32_t RASR_A2; /*!< Offset: 0x020 (R/W) MPU Alias 2 Region Attribute and Size Register */
+ __IO uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Alias 3 Region Base Address Register */
+ __IO uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */
+} MPU_Type;
+
+/* MPU Type Register */
+#define MPU_TYPE_IREGION_Pos 16 /*!< MPU TYPE: IREGION Position */
+#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */
+
+#define MPU_TYPE_DREGION_Pos 8 /*!< MPU TYPE: DREGION Position */
+#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */
+
+#define MPU_TYPE_SEPARATE_Pos 0 /*!< MPU TYPE: SEPARATE Position */
+#define MPU_TYPE_SEPARATE_Msk (1UL << MPU_TYPE_SEPARATE_Pos) /*!< MPU TYPE: SEPARATE Mask */
+
+/* MPU Control Register */
+#define MPU_CTRL_PRIVDEFENA_Pos 2 /*!< MPU CTRL: PRIVDEFENA Position */
+#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */
+
+#define MPU_CTRL_HFNMIENA_Pos 1 /*!< MPU CTRL: HFNMIENA Position */
+#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */
+
+#define MPU_CTRL_ENABLE_Pos 0 /*!< MPU CTRL: ENABLE Position */
+#define MPU_CTRL_ENABLE_Msk (1UL << MPU_CTRL_ENABLE_Pos) /*!< MPU CTRL: ENABLE Mask */
+
+/* MPU Region Number Register */
+#define MPU_RNR_REGION_Pos 0 /*!< MPU RNR: REGION Position */
+#define MPU_RNR_REGION_Msk (0xFFUL << MPU_RNR_REGION_Pos) /*!< MPU RNR: REGION Mask */
+
+/* MPU Region Base Address Register */
+#define MPU_RBAR_ADDR_Pos 5 /*!< MPU RBAR: ADDR Position */
+#define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */
+
+#define MPU_RBAR_VALID_Pos 4 /*!< MPU RBAR: VALID Position */
+#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */
+
+#define MPU_RBAR_REGION_Pos 0 /*!< MPU RBAR: REGION Position */
+#define MPU_RBAR_REGION_Msk (0xFUL << MPU_RBAR_REGION_Pos) /*!< MPU RBAR: REGION Mask */
+
+/* MPU Region Attribute and Size Register */
+#define MPU_RASR_ATTRS_Pos 16 /*!< MPU RASR: MPU Region Attribute field Position */
+#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */
+
+#define MPU_RASR_SRD_Pos 8 /*!< MPU RASR: Sub-Region Disable Position */
+#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */
+
+#define MPU_RASR_SIZE_Pos 1 /*!< MPU RASR: Region Size Field Position */
+#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */
+
+#define MPU_RASR_ENABLE_Pos 0 /*!< MPU RASR: Region enable bit Position */
+#define MPU_RASR_ENABLE_Msk (1UL << MPU_RASR_ENABLE_Pos) /*!< MPU RASR: Region enable bit Disable Mask */
+
+/*@} end of group CMSIS_MPU */
+#endif
+
+
+/** \ingroup CMSIS_core_register
+ \defgroup CMSIS_CoreDebug CMSIS Core Debug
+ Type definitions for the Cortex-M Core Debug Registers
+ @{
+ */
+
+/** \brief Structure type to access the Core Debug Register (CoreDebug).
+ */
+typedef struct
+{
+ __IO uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */
+ __O uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */
+ __IO uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */
+ __IO uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */
+} CoreDebug_Type;
+
+/* Debug Halting Control and Status Register */
+#define CoreDebug_DHCSR_DBGKEY_Pos 16 /*!< CoreDebug DHCSR: DBGKEY Position */
+#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */
+
+#define CoreDebug_DHCSR_S_RESET_ST_Pos 25 /*!< CoreDebug DHCSR: S_RESET_ST Position */
+#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */
+
+#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24 /*!< CoreDebug DHCSR: S_RETIRE_ST Position */
+#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */
+
+#define CoreDebug_DHCSR_S_LOCKUP_Pos 19 /*!< CoreDebug DHCSR: S_LOCKUP Position */
+#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */
+
+#define CoreDebug_DHCSR_S_SLEEP_Pos 18 /*!< CoreDebug DHCSR: S_SLEEP Position */
+#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */
+
+#define CoreDebug_DHCSR_S_HALT_Pos 17 /*!< CoreDebug DHCSR: S_HALT Position */
+#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */
+
+#define CoreDebug_DHCSR_S_REGRDY_Pos 16 /*!< CoreDebug DHCSR: S_REGRDY Position */
+#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */
+
+#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5 /*!< CoreDebug DHCSR: C_SNAPSTALL Position */
+#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */
+
+#define CoreDebug_DHCSR_C_MASKINTS_Pos 3 /*!< CoreDebug DHCSR: C_MASKINTS Position */
+#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */
+
+#define CoreDebug_DHCSR_C_STEP_Pos 2 /*!< CoreDebug DHCSR: C_STEP Position */
+#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */
+
+#define CoreDebug_DHCSR_C_HALT_Pos 1 /*!< CoreDebug DHCSR: C_HALT Position */
+#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */
+
+#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0 /*!< CoreDebug DHCSR: C_DEBUGEN Position */
+#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL << CoreDebug_DHCSR_C_DEBUGEN_Pos) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */
+
+/* Debug Core Register Selector Register */
+#define CoreDebug_DCRSR_REGWnR_Pos 16 /*!< CoreDebug DCRSR: REGWnR Position */
+#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */
+
+#define CoreDebug_DCRSR_REGSEL_Pos 0 /*!< CoreDebug DCRSR: REGSEL Position */
+#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL << CoreDebug_DCRSR_REGSEL_Pos) /*!< CoreDebug DCRSR: REGSEL Mask */
+
+/* Debug Exception and Monitor Control Register */
+#define CoreDebug_DEMCR_TRCENA_Pos 24 /*!< CoreDebug DEMCR: TRCENA Position */
+#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */
+
+#define CoreDebug_DEMCR_MON_REQ_Pos 19 /*!< CoreDebug DEMCR: MON_REQ Position */
+#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */
+
+#define CoreDebug_DEMCR_MON_STEP_Pos 18 /*!< CoreDebug DEMCR: MON_STEP Position */
+#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */
+
+#define CoreDebug_DEMCR_MON_PEND_Pos 17 /*!< CoreDebug DEMCR: MON_PEND Position */
+#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */
+
+#define CoreDebug_DEMCR_MON_EN_Pos 16 /*!< CoreDebug DEMCR: MON_EN Position */
+#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */
+
+#define CoreDebug_DEMCR_VC_HARDERR_Pos 10 /*!< CoreDebug DEMCR: VC_HARDERR Position */
+#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */
+
+#define CoreDebug_DEMCR_VC_INTERR_Pos 9 /*!< CoreDebug DEMCR: VC_INTERR Position */
+#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */
+
+#define CoreDebug_DEMCR_VC_BUSERR_Pos 8 /*!< CoreDebug DEMCR: VC_BUSERR Position */
+#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */
+
+#define CoreDebug_DEMCR_VC_STATERR_Pos 7 /*!< CoreDebug DEMCR: VC_STATERR Position */
+#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */
+
+#define CoreDebug_DEMCR_VC_CHKERR_Pos 6 /*!< CoreDebug DEMCR: VC_CHKERR Position */
+#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */
+
+#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5 /*!< CoreDebug DEMCR: VC_NOCPERR Position */
+#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */
+
+#define CoreDebug_DEMCR_VC_MMERR_Pos 4 /*!< CoreDebug DEMCR: VC_MMERR Position */
+#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */
+
+#define CoreDebug_DEMCR_VC_CORERESET_Pos 0 /*!< CoreDebug DEMCR: VC_CORERESET Position */
+#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL << CoreDebug_DEMCR_VC_CORERESET_Pos) /*!< CoreDebug DEMCR: VC_CORERESET Mask */
+
+/*@} end of group CMSIS_CoreDebug */
+
+
+/** \ingroup CMSIS_core_register
+ @{
+ */
+
+/* Memory mapping of Cortex-M3 Hardware */
+#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */
+#define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */
+#define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */
+#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */
+#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */
+#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */
+
+#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */
+#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */
+#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */
+#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */
+#define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */
+#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */
+
+#if (__MPU_PRESENT == 1)
+ #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */
+ #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */
+#endif
+
+/*@} */
+
+
+
+/*******************************************************************************
+ * Hardware Abstraction Layer
+ ******************************************************************************/
+/** \defgroup CMSIS_Core_FunctionInterface CMSIS Core Function Interface
+ Core Function Interface contains:
+ - Core NVIC Functions
+ - Core SysTick Functions
+ - Core Debug Functions
+ - Core Register Access Functions
+*/
+
+
+
+/* ########################## NVIC functions #################################### */
+/** \ingroup CMSIS_Core_FunctionInterface
+ \defgroup CMSIS_Core_NVICFunctions CMSIS Core NVIC Functions
+ @{
+ */
+
+/** \brief Set Priority Grouping
+
+ This function sets the priority grouping field using the required unlock sequence.
+ The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field.
+ Only values from 0..7 are used.
+ In case of a conflict between priority grouping and available
+ priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set.
+
+ \param [in] PriorityGroup Priority grouping field
+ */
+static __INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup)
+{
+ uint32_t reg_value;
+ uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07); /* only values 0..7 are used */
+
+ reg_value = SCB->AIRCR; /* read old register configuration */
+ reg_value &= ~(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk); /* clear bits to change */
+ reg_value = (reg_value |
+ ((uint32_t)0x5FA << SCB_AIRCR_VECTKEY_Pos) |
+ (PriorityGroupTmp << 8)); /* Insert write key and priorty group */
+ SCB->AIRCR = reg_value;
+}
+
+
+/** \brief Get Priority Grouping
+
+ This function gets the priority grouping from NVIC Interrupt Controller.
+ Priority grouping is SCB->AIRCR [10:8] PRIGROUP field.
+
+ \return Priority grouping field
+ */
+static __INLINE uint32_t NVIC_GetPriorityGrouping(void)
+{
+ return ((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos); /* read priority grouping field */
+}
+
+
+/** \brief Enable External Interrupt
+
+ This function enables a device specific interrupt in the NVIC interrupt controller.
+ The interrupt number cannot be a negative value.
+
+ \param [in] IRQn Number of the external interrupt to enable
+ */
+static __INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
+{
+ NVIC->ISER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* enable interrupt */
+}
+
+
+/** \brief Disable External Interrupt
+
+ This function disables a device specific interrupt in the NVIC interrupt controller.
+ The interrupt number cannot be a negative value.
+
+ \param [in] IRQn Number of the external interrupt to disable
+ */
+static __INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)
+{
+ NVIC->ICER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* disable interrupt */
+}
+
+
+/** \brief Get Pending Interrupt
+
+ This function reads the pending register in the NVIC and returns the pending bit
+ for the specified interrupt.
+
+ \param [in] IRQn Number of the interrupt for get pending
+ \return 0 Interrupt status is not pending
+ \return 1 Interrupt status is pending
+ */
+static __INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)
+{
+ return((uint32_t) ((NVIC->ISPR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); /* Return 1 if pending else 0 */
+}
+
+
+/** \brief Set Pending Interrupt
+
+ This function sets the pending bit for the specified interrupt.
+ The interrupt number cannot be a negative value.
+
+ \param [in] IRQn Number of the interrupt for set pending
+ */
+static __INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn)
+{
+ NVIC->ISPR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* set interrupt pending */
+}
+
+
+/** \brief Clear Pending Interrupt
+
+ This function clears the pending bit for the specified interrupt.
+ The interrupt number cannot be a negative value.
+
+ \param [in] IRQn Number of the interrupt for clear pending
+ */
+static __INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
+{
+ NVIC->ICPR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* Clear pending interrupt */
+}
+
+
+/** \brief Get Active Interrupt
+
+ This function reads the active register in NVIC and returns the active bit.
+ \param [in] IRQn Number of the interrupt for get active
+ \return 0 Interrupt status is not active
+ \return 1 Interrupt status is active
+ */
+static __INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn)
+{
+ return((uint32_t)((NVIC->IABR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); /* Return 1 if active else 0 */
+}
+
+
+/** \brief Set Interrupt Priority
+
+ This function sets the priority for the specified interrupt. The interrupt
+ number can be positive to specify an external (device specific)
+ interrupt, or negative to specify an internal (core) interrupt.
+
+ Note: The priority cannot be set for every core interrupt.
+
+ \param [in] IRQn Number of the interrupt for set priority
+ \param [in] priority Priority to set
+ */
+static __INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
+{
+ if(IRQn < 0) {
+ SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for Cortex-M System Interrupts */
+ else {
+ NVIC->IP[(uint32_t)(IRQn)] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for device specific Interrupts */
+}
+
+
+/** \brief Get Interrupt Priority
+
+ This function reads the priority for the specified interrupt. The interrupt
+ number can be positive to specify an external (device specific)
+ interrupt, or negative to specify an internal (core) interrupt.
+
+ The returned priority value is automatically aligned to the implemented
+ priority bits of the microcontroller.
+
+ \param [in] IRQn Number of the interrupt for get priority
+ \return Interrupt Priority
+ */
+static __INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn)
+{
+
+ if(IRQn < 0) {
+ return((uint32_t)(SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] >> (8 - __NVIC_PRIO_BITS))); } /* get priority for Cortex-M system interrupts */
+ else {
+ return((uint32_t)(NVIC->IP[(uint32_t)(IRQn)] >> (8 - __NVIC_PRIO_BITS))); } /* get priority for device specific interrupts */
+}
+
+
+/** \brief Encode Priority
+
+ This function encodes the priority for an interrupt with the given priority group,
+ preemptive priority value and sub priority value.
+ In case of a conflict between priority grouping and available
+ priority bits (__NVIC_PRIO_BITS) the samllest possible priority group is set.
+
+ The returned priority value can be used for NVIC_SetPriority(...) function
+
+ \param [in] PriorityGroup Used priority group
+ \param [in] PreemptPriority Preemptive priority value (starting from 0)
+ \param [in] SubPriority Sub priority value (starting from 0)
+ \return Encoded priority for the interrupt
+ */
+static __INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority)
+{
+ uint32_t PriorityGroupTmp = (PriorityGroup & 0x07); /* only values 0..7 are used */
+ uint32_t PreemptPriorityBits;
+ uint32_t SubPriorityBits;
+
+ PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp;
+ SubPriorityBits = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS;
+
+ return (
+ ((PreemptPriority & ((1 << (PreemptPriorityBits)) - 1)) << SubPriorityBits) |
+ ((SubPriority & ((1 << (SubPriorityBits )) - 1)))
+ );
+}
+
+
+/** \brief Decode Priority
+
+ This function decodes an interrupt priority value with the given priority group to
+ preemptive priority value and sub priority value.
+ In case of a conflict between priority grouping and available
+ priority bits (__NVIC_PRIO_BITS) the samllest possible priority group is set.
+
+ The priority value can be retrieved with NVIC_GetPriority(...) function
+
+ \param [in] Priority Priority value
+ \param [in] PriorityGroup Used priority group
+ \param [out] pPreemptPriority Preemptive priority value (starting from 0)
+ \param [out] pSubPriority Sub priority value (starting from 0)
+ */
+static __INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* pPreemptPriority, uint32_t* pSubPriority)
+{
+ uint32_t PriorityGroupTmp = (PriorityGroup & 0x07); /* only values 0..7 are used */
+ uint32_t PreemptPriorityBits;
+ uint32_t SubPriorityBits;
+
+ PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp;
+ SubPriorityBits = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS;
+
+ *pPreemptPriority = (Priority >> SubPriorityBits) & ((1 << (PreemptPriorityBits)) - 1);
+ *pSubPriority = (Priority ) & ((1 << (SubPriorityBits )) - 1);
+}
+
+
+/** \brief System Reset
+
+ This function initiate a system reset request to reset the MCU.
+ */
+static __INLINE void NVIC_SystemReset(void)
+{
+ __DSB(); /* Ensure all outstanding memory accesses included
+ buffered write are completed before reset */
+ SCB->AIRCR = ((0x5FA << SCB_AIRCR_VECTKEY_Pos) |
+ (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) |
+ SCB_AIRCR_SYSRESETREQ_Msk); /* Keep priority group unchanged */
+ __DSB(); /* Ensure completion of memory access */
+ while(1); /* wait until reset */
+}
+
+/*@} end of CMSIS_Core_NVICFunctions */
+
+
+
+/* ################################## SysTick function ############################################ */
+/** \ingroup CMSIS_Core_FunctionInterface
+ \defgroup CMSIS_Core_SysTickFunctions CMSIS Core SysTick Functions
+ @{
+ */
+
+#if (__Vendor_SysTickConfig == 0)
+
+/** \brief System Tick Configuration
+
+ This function initialises the system tick timer and its interrupt and start the system tick timer.
+ Counter is in free running mode to generate periodical interrupts.
+
+ \param [in] ticks Number of ticks between two interrupts
+ \return 0 Function succeeded
+ \return 1 Function failed
+ */
+static __INLINE uint32_t SysTick_Config(uint32_t ticks)
+{
+ if (ticks > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */
+
+ SysTick->LOAD = (ticks & SysTick_LOAD_RELOAD_Msk) - 1; /* set reload register */
+ NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Cortex-M0 System Interrupts */
+ SysTick->VAL = 0; /* Load the SysTick Counter Value */
+ SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
+ SysTick_CTRL_TICKINT_Msk |
+ SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */
+ return (0); /* Function successful */
+}
+
+#endif
+
+/*@} end of CMSIS_Core_SysTickFunctions */
+
+
+
+/* ##################################### Debug In/Output function ########################################### */
+/** \ingroup CMSIS_Core_FunctionInterface
+ \defgroup CMSIS_core_DebugFunctions CMSIS Core Debug Functions
+ @{
+ */
+
+extern volatile int32_t ITM_RxBuffer; /*!< external variable to receive characters */
+#define ITM_RXBUFFER_EMPTY 0x5AA55AA5 /*!< value identifying ITM_RxBuffer is ready for next character */
+
+
+/** \brief ITM Send Character
+
+ This function transmits a character via the ITM channel 0.
+ It just returns when no debugger is connected that has booked the output.
+ It is blocking when a debugger is connected, but the previous character send is not transmitted.
+
+ \param [in] ch Character to transmit
+ \return Character to transmit
+ */
+static __INLINE uint32_t ITM_SendChar (uint32_t ch)
+{
+ if ((CoreDebug->DEMCR & CoreDebug_DEMCR_TRCENA_Msk) && /* Trace enabled */
+ (ITM->TCR & ITM_TCR_ITMENA_Msk) && /* ITM enabled */
+ (ITM->TER & (1UL << 0) ) ) /* ITM Port #0 enabled */
+ {
+ while (ITM->PORT[0].u32 == 0);
+ ITM->PORT[0].u8 = (uint8_t) ch;
+ }
+ return (ch);
+}
+
+
+/** \brief ITM Receive Character
+
+ This function inputs a character via external variable ITM_RxBuffer.
+ It just returns when no debugger is connected that has booked the output.
+ It is blocking when a debugger is connected, but the previous character send is not transmitted.
+
+ \return Received character
+ \return -1 No character received
+ */
+static __INLINE int32_t ITM_ReceiveChar (void) {
+ int32_t ch = -1; /* no character available */
+
+ if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) {
+ ch = ITM_RxBuffer;
+ ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */
+ }
+
+ return (ch);
+}
+
+
+/** \brief ITM Check Character
+
+ This function checks external variable ITM_RxBuffer whether a character is available or not.
+ It returns '1' if a character is available and '0' if no character is available.
+
+ \return 0 No character available
+ \return 1 Character available
+ */
+static __INLINE int32_t ITM_CheckChar (void) {
+
+ if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) {
+ return (0); /* no character available */
+ } else {
+ return (1); /* character available */
+ }
+}
+
+/*@} end of CMSIS_core_DebugFunctions */
+
+#endif /* __CORE_CM3_H_DEPENDANT */
+
+#endif /* __CMSIS_GENERIC */
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/platform/mcu/CMSIS/Include/core_cm4.h b/platform/mcu/CMSIS/Include/core_cm4.h
new file mode 100644
index 00000000..76bf8292
--- /dev/null
+++ b/platform/mcu/CMSIS/Include/core_cm4.h
@@ -0,0 +1,1378 @@
+/**************************************************************************//**
+ * @file core_cm4.h
+ * @brief CMSIS Cortex-M4 Core Peripheral Access Layer Header File
+ * @version V2.10
+ * @date 19. July 2011
+ *
+ * @note
+ * Copyright (C) 2009-2011 ARM Limited. All rights reserved.
+ *
+ * @par
+ * ARM Limited (ARM) is supplying this software for use with Cortex-M
+ * processor based microcontrollers. This file can be freely distributed
+ * within development tools that are supporting such ARM based processors.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
+ * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
+ * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
+ * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
+ *
+ ******************************************************************************/
+#if defined ( __ICCARM__ )
+ #pragma system_include /* treat file as system include file for MISRA check */
+#endif
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#ifndef __CORE_CM4_H_GENERIC
+#define __CORE_CM4_H_GENERIC
+
+
+/** \mainpage CMSIS Cortex-M4
+
+ This documentation describes the CMSIS Cortex-M Core Peripheral Access Layer.
+ It consists of:
+
+ - Cortex-M Core Register Definitions
+ - Cortex-M functions
+ - Cortex-M instructions
+ - Cortex-M SIMD instructions
+
+ The CMSIS Cortex-M4 Core Peripheral Access Layer contains C and assembly functions that ease
+ access to the Cortex-M Core
+ */
+
+/** \defgroup CMSIS_MISRA_Exceptions CMSIS MISRA-C:2004 Compliance Exceptions
+ CMSIS violates following MISRA-C2004 Rules:
+
+ - Violates MISRA 2004 Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'.
+
+ - Violates MISRA 2004 Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers.
+
+ - Violates MISRA 2004 Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code.
+
+ */
+
+
+/*******************************************************************************
+ * CMSIS definitions
+ ******************************************************************************/
+/** \defgroup CMSIS_core_definitions CMSIS Core Definitions
+ This file defines all structures and symbols for CMSIS core:
+ - CMSIS version number
+ - Cortex-M core
+ - Cortex-M core Revision Number
+ @{
+ */
+
+/* CMSIS CM4 definitions */
+#define __CM4_CMSIS_VERSION_MAIN (0x02) /*!< [31:16] CMSIS HAL main version */
+#define __CM4_CMSIS_VERSION_SUB (0x10) /*!< [15:0] CMSIS HAL sub version */
+#define __CM4_CMSIS_VERSION ((__CM4_CMSIS_VERSION_MAIN << 16) | __CM4_CMSIS_VERSION_SUB) /*!< CMSIS HAL version number */
+
+#define __CORTEX_M (0x04) /*!< Cortex core */
+
+
+#if defined ( __CC_ARM )
+ #define __ASM __asm /*!< asm keyword for ARM Compiler */
+ #define __INLINE __inline /*!< inline keyword for ARM Compiler */
+
+#elif defined ( __ICCARM__ )
+ #define __ASM __asm /*!< asm keyword for IAR Compiler */
+ #define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */
+
+#elif defined ( __GNUC__ )
+ #define __ASM __asm /*!< asm keyword for GNU Compiler */
+ #define __INLINE inline /*!< inline keyword for GNU Compiler */
+
+#elif defined ( __TASKING__ )
+ #define __ASM __asm /*!< asm keyword for TASKING Compiler */
+ #define __INLINE inline /*!< inline keyword for TASKING Compiler */
+
+#endif
+
+/*!< __FPU_USED to be checked prior to making use of FPU specific registers and functions */
+#if defined ( __CC_ARM )
+ #if defined __TARGET_FPU_VFP
+ #if (__FPU_PRESENT == 1)
+ #define __FPU_USED 1
+ #else
+ #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #define __FPU_USED 0
+ #endif
+ #else
+ #define __FPU_USED 0
+ #endif
+
+#elif defined ( __ICCARM__ )
+ #if defined __ARMVFP__
+ #if (__FPU_PRESENT == 1)
+ #define __FPU_USED 1
+ #else
+ #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #define __FPU_USED 0
+ #endif
+ #else
+ #define __FPU_USED 0
+ #endif
+
+#elif defined ( __GNUC__ )
+ #if defined (__VFP_FP__) && !defined(__SOFTFP__)
+ #if (__FPU_PRESENT == 1)
+ #define __FPU_USED 1
+ #else
+ #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #define __FPU_USED 0
+ #endif
+ #else
+ #define __FPU_USED 0
+ #endif
+
+#elif defined ( __TASKING__ )
+ /* add preprocessor checks to define __FPU_USED */
+ #define __FPU_USED 0
+#endif
+
+#include /*!< standard types definitions */
+#include /*!< Core Instruction Access */
+#include /*!< Core Function Access */
+#include /*!< Compiler specific SIMD Intrinsics */
+
+#endif /* __CORE_CM4_H_GENERIC */
+
+#ifndef __CMSIS_GENERIC
+
+#ifndef __CORE_CM4_H_DEPENDANT
+#define __CORE_CM4_H_DEPENDANT
+
+/* check device defines and use defaults */
+#if defined __CHECK_DEVICE_DEFINES
+ #ifndef __CM4_REV
+ #define __CM4_REV 0x0000
+ #warning "__CM4_REV not defined in device header file; using default!"
+ #endif
+
+ #ifndef __FPU_PRESENT
+ #define __FPU_PRESENT 0
+ #warning "__FPU_PRESENT not defined in device header file; using default!"
+ #endif
+
+ #ifndef __MPU_PRESENT
+ #define __MPU_PRESENT 0
+ #warning "__MPU_PRESENT not defined in device header file; using default!"
+ #endif
+
+ #ifndef __NVIC_PRIO_BITS
+ #define __NVIC_PRIO_BITS 4
+ #warning "__NVIC_PRIO_BITS not defined in device header file; using default!"
+ #endif
+
+ #ifndef __Vendor_SysTickConfig
+ #define __Vendor_SysTickConfig 0
+ #warning "__Vendor_SysTickConfig not defined in device header file; using default!"
+ #endif
+#endif
+
+/* IO definitions (access restrictions to peripheral registers) */
+#ifdef __cplusplus
+ #define __I volatile /*!< defines 'read only' permissions */
+#else
+ #define __I volatile const /*!< defines 'read only' permissions */
+#endif
+#define __O volatile /*!< defines 'write only' permissions */
+#define __IO volatile /*!< defines 'read / write' permissions */
+
+/*@} end of group CMSIS_core_definitions */
+
+
+
+/*******************************************************************************
+ * Register Abstraction
+ ******************************************************************************/
+/** \defgroup CMSIS_core_register CMSIS Core Register
+ Core Register contain:
+ - Core Register
+ - Core NVIC Register
+ - Core SCB Register
+ - Core SysTick Register
+ - Core Debug Register
+ - Core MPU Register
+ - Core FPU Register
+*/
+
+/** \ingroup CMSIS_core_register
+ \defgroup CMSIS_CORE CMSIS Core
+ Type definitions for the Cortex-M Core Registers
+ @{
+ */
+
+/** \brief Union type to access the Application Program Status Register (APSR).
+ */
+typedef union
+{
+ struct
+ {
+#if (__CORTEX_M != 0x04)
+ uint32_t _reserved0:27; /*!< bit: 0..26 Reserved */
+#else
+ uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */
+ uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */
+ uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */
+#endif
+ uint32_t Q:1; /*!< bit: 27 Saturation condition flag */
+ uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
+ uint32_t C:1; /*!< bit: 29 Carry condition code flag */
+ uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
+ uint32_t N:1; /*!< bit: 31 Negative condition code flag */
+ } b; /*!< Structure used for bit access */
+ uint32_t w; /*!< Type used for word access */
+} APSR_Type;
+
+
+/** \brief Union type to access the Interrupt Program Status Register (IPSR).
+ */
+typedef union
+{
+ struct
+ {
+ uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
+ uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */
+ } b; /*!< Structure used for bit access */
+ uint32_t w; /*!< Type used for word access */
+} IPSR_Type;
+
+
+/** \brief Union type to access the Special-Purpose Program Status Registers (xPSR).
+ */
+typedef union
+{
+ struct
+ {
+ uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
+#if (__CORTEX_M != 0x04)
+ uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */
+#else
+ uint32_t _reserved0:7; /*!< bit: 9..15 Reserved */
+ uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */
+ uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */
+#endif
+ uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */
+ uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */
+ uint32_t Q:1; /*!< bit: 27 Saturation condition flag */
+ uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
+ uint32_t C:1; /*!< bit: 29 Carry condition code flag */
+ uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
+ uint32_t N:1; /*!< bit: 31 Negative condition code flag */
+ } b; /*!< Structure used for bit access */
+ uint32_t w; /*!< Type used for word access */
+} xPSR_Type;
+
+
+/** \brief Union type to access the Control Registers (CONTROL).
+ */
+typedef union
+{
+ struct
+ {
+ uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */
+ uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */
+ uint32_t FPCA:1; /*!< bit: 2 FP extension active flag */
+ uint32_t _reserved0:29; /*!< bit: 3..31 Reserved */
+ } b; /*!< Structure used for bit access */
+ uint32_t w; /*!< Type used for word access */
+} CONTROL_Type;
+
+/*@} end of group CMSIS_CORE */
+
+
+/** \ingroup CMSIS_core_register
+ \defgroup CMSIS_NVIC CMSIS NVIC
+ Type definitions for the Cortex-M NVIC Registers
+ @{
+ */
+
+/** \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC).
+ */
+typedef struct
+{
+ __IO uint32_t ISER[8]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */
+ uint32_t RESERVED0[24];
+ __IO uint32_t ICER[8]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */
+ uint32_t RSERVED1[24];
+ __IO uint32_t ISPR[8]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */
+ uint32_t RESERVED2[24];
+ __IO uint32_t ICPR[8]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */
+ uint32_t RESERVED3[24];
+ __IO uint32_t IABR[8]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */
+ uint32_t RESERVED4[56];
+ __IO uint8_t IP[240]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */
+ uint32_t RESERVED5[644];
+ __O uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */
+} NVIC_Type;
+
+/* Software Triggered Interrupt Register Definitions */
+#define NVIC_STIR_INTID_Pos 0 /*!< STIR: INTLINESNUM Position */
+#define NVIC_STIR_INTID_Msk (0x1FFUL << NVIC_STIR_INTID_Pos) /*!< STIR: INTLINESNUM Mask */
+
+/*@} end of group CMSIS_NVIC */
+
+
+/** \ingroup CMSIS_core_register
+ \defgroup CMSIS_SCB CMSIS SCB
+ Type definitions for the Cortex-M System Control Block Registers
+ @{
+ */
+
+/** \brief Structure type to access the System Control Block (SCB).
+ */
+typedef struct
+{
+ __I uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */
+ __IO uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */
+ __IO uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */
+ __IO uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */
+ __IO uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */
+ __IO uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */
+ __IO uint8_t SHP[12]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */
+ __IO uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */
+ __IO uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */
+ __IO uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */
+ __IO uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */
+ __IO uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */
+ __IO uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */
+ __IO uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */
+ __I uint32_t PFR[2]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */
+ __I uint32_t DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */
+ __I uint32_t ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */
+ __I uint32_t MMFR[4]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */
+ __I uint32_t ISAR[5]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */
+ uint32_t RESERVED0[5];
+ __IO uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */
+} SCB_Type;
+
+/* SCB CPUID Register Definitions */
+#define SCB_CPUID_IMPLEMENTER_Pos 24 /*!< SCB CPUID: IMPLEMENTER Position */
+#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */
+
+#define SCB_CPUID_VARIANT_Pos 20 /*!< SCB CPUID: VARIANT Position */
+#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */
+
+#define SCB_CPUID_ARCHITECTURE_Pos 16 /*!< SCB CPUID: ARCHITECTURE Position */
+#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */
+
+#define SCB_CPUID_PARTNO_Pos 4 /*!< SCB CPUID: PARTNO Position */
+#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */
+
+#define SCB_CPUID_REVISION_Pos 0 /*!< SCB CPUID: REVISION Position */
+#define SCB_CPUID_REVISION_Msk (0xFUL << SCB_CPUID_REVISION_Pos) /*!< SCB CPUID: REVISION Mask */
+
+/* SCB Interrupt Control State Register Definitions */
+#define SCB_ICSR_NMIPENDSET_Pos 31 /*!< SCB ICSR: NMIPENDSET Position */
+#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */
+
+#define SCB_ICSR_PENDSVSET_Pos 28 /*!< SCB ICSR: PENDSVSET Position */
+#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */
+
+#define SCB_ICSR_PENDSVCLR_Pos 27 /*!< SCB ICSR: PENDSVCLR Position */
+#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */
+
+#define SCB_ICSR_PENDSTSET_Pos 26 /*!< SCB ICSR: PENDSTSET Position */
+#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */
+
+#define SCB_ICSR_PENDSTCLR_Pos 25 /*!< SCB ICSR: PENDSTCLR Position */
+#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */
+
+#define SCB_ICSR_ISRPREEMPT_Pos 23 /*!< SCB ICSR: ISRPREEMPT Position */
+#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */
+
+#define SCB_ICSR_ISRPENDING_Pos 22 /*!< SCB ICSR: ISRPENDING Position */
+#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */
+
+#define SCB_ICSR_VECTPENDING_Pos 12 /*!< SCB ICSR: VECTPENDING Position */
+#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */
+
+#define SCB_ICSR_RETTOBASE_Pos 11 /*!< SCB ICSR: RETTOBASE Position */
+#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */
+
+#define SCB_ICSR_VECTACTIVE_Pos 0 /*!< SCB ICSR: VECTACTIVE Position */
+#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL << SCB_ICSR_VECTACTIVE_Pos) /*!< SCB ICSR: VECTACTIVE Mask */
+
+/* SCB Vector Table Offset Register Definitions */
+#define SCB_VTOR_TBLOFF_Pos 7 /*!< SCB VTOR: TBLOFF Position */
+#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */
+
+/* SCB Application Interrupt and Reset Control Register Definitions */
+#define SCB_AIRCR_VECTKEY_Pos 16 /*!< SCB AIRCR: VECTKEY Position */
+#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */
+
+#define SCB_AIRCR_VECTKEYSTAT_Pos 16 /*!< SCB AIRCR: VECTKEYSTAT Position */
+#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */
+
+#define SCB_AIRCR_ENDIANESS_Pos 15 /*!< SCB AIRCR: ENDIANESS Position */
+#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */
+
+#define SCB_AIRCR_PRIGROUP_Pos 8 /*!< SCB AIRCR: PRIGROUP Position */
+#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */
+
+#define SCB_AIRCR_SYSRESETREQ_Pos 2 /*!< SCB AIRCR: SYSRESETREQ Position */
+#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */
+
+#define SCB_AIRCR_VECTCLRACTIVE_Pos 1 /*!< SCB AIRCR: VECTCLRACTIVE Position */
+#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */
+
+#define SCB_AIRCR_VECTRESET_Pos 0 /*!< SCB AIRCR: VECTRESET Position */
+#define SCB_AIRCR_VECTRESET_Msk (1UL << SCB_AIRCR_VECTRESET_Pos) /*!< SCB AIRCR: VECTRESET Mask */
+
+/* SCB System Control Register Definitions */
+#define SCB_SCR_SEVONPEND_Pos 4 /*!< SCB SCR: SEVONPEND Position */
+#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */
+
+#define SCB_SCR_SLEEPDEEP_Pos 2 /*!< SCB SCR: SLEEPDEEP Position */
+#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */
+
+#define SCB_SCR_SLEEPONEXIT_Pos 1 /*!< SCB SCR: SLEEPONEXIT Position */
+#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */
+
+/* SCB Configuration Control Register Definitions */
+#define SCB_CCR_STKALIGN_Pos 9 /*!< SCB CCR: STKALIGN Position */
+#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */
+
+#define SCB_CCR_BFHFNMIGN_Pos 8 /*!< SCB CCR: BFHFNMIGN Position */
+#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */
+
+#define SCB_CCR_DIV_0_TRP_Pos 4 /*!< SCB CCR: DIV_0_TRP Position */
+#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */
+
+#define SCB_CCR_UNALIGN_TRP_Pos 3 /*!< SCB CCR: UNALIGN_TRP Position */
+#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */
+
+#define SCB_CCR_USERSETMPEND_Pos 1 /*!< SCB CCR: USERSETMPEND Position */
+#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */
+
+#define SCB_CCR_NONBASETHRDENA_Pos 0 /*!< SCB CCR: NONBASETHRDENA Position */
+#define SCB_CCR_NONBASETHRDENA_Msk (1UL << SCB_CCR_NONBASETHRDENA_Pos) /*!< SCB CCR: NONBASETHRDENA Mask */
+
+/* SCB System Handler Control and State Register Definitions */
+#define SCB_SHCSR_USGFAULTENA_Pos 18 /*!< SCB SHCSR: USGFAULTENA Position */
+#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */
+
+#define SCB_SHCSR_BUSFAULTENA_Pos 17 /*!< SCB SHCSR: BUSFAULTENA Position */
+#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */
+
+#define SCB_SHCSR_MEMFAULTENA_Pos 16 /*!< SCB SHCSR: MEMFAULTENA Position */
+#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */
+
+#define SCB_SHCSR_SVCALLPENDED_Pos 15 /*!< SCB SHCSR: SVCALLPENDED Position */
+#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */
+
+#define SCB_SHCSR_BUSFAULTPENDED_Pos 14 /*!< SCB SHCSR: BUSFAULTPENDED Position */
+#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */
+
+#define SCB_SHCSR_MEMFAULTPENDED_Pos 13 /*!< SCB SHCSR: MEMFAULTPENDED Position */
+#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */
+
+#define SCB_SHCSR_USGFAULTPENDED_Pos 12 /*!< SCB SHCSR: USGFAULTPENDED Position */
+#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */
+
+#define SCB_SHCSR_SYSTICKACT_Pos 11 /*!< SCB SHCSR: SYSTICKACT Position */
+#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */
+
+#define SCB_SHCSR_PENDSVACT_Pos 10 /*!< SCB SHCSR: PENDSVACT Position */
+#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */
+
+#define SCB_SHCSR_MONITORACT_Pos 8 /*!< SCB SHCSR: MONITORACT Position */
+#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */
+
+#define SCB_SHCSR_SVCALLACT_Pos 7 /*!< SCB SHCSR: SVCALLACT Position */
+#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */
+
+#define SCB_SHCSR_USGFAULTACT_Pos 3 /*!< SCB SHCSR: USGFAULTACT Position */
+#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */
+
+#define SCB_SHCSR_BUSFAULTACT_Pos 1 /*!< SCB SHCSR: BUSFAULTACT Position */
+#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */
+
+#define SCB_SHCSR_MEMFAULTACT_Pos 0 /*!< SCB SHCSR: MEMFAULTACT Position */
+#define SCB_SHCSR_MEMFAULTACT_Msk (1UL << SCB_SHCSR_MEMFAULTACT_Pos) /*!< SCB SHCSR: MEMFAULTACT Mask */
+
+/* SCB Configurable Fault Status Registers Definitions */
+#define SCB_CFSR_USGFAULTSR_Pos 16 /*!< SCB CFSR: Usage Fault Status Register Position */
+#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */
+
+#define SCB_CFSR_BUSFAULTSR_Pos 8 /*!< SCB CFSR: Bus Fault Status Register Position */
+#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */
+
+#define SCB_CFSR_MEMFAULTSR_Pos 0 /*!< SCB CFSR: Memory Manage Fault Status Register Position */
+#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL << SCB_CFSR_MEMFAULTSR_Pos) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */
+
+/* SCB Hard Fault Status Registers Definitions */
+#define SCB_HFSR_DEBUGEVT_Pos 31 /*!< SCB HFSR: DEBUGEVT Position */
+#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */
+
+#define SCB_HFSR_FORCED_Pos 30 /*!< SCB HFSR: FORCED Position */
+#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */
+
+#define SCB_HFSR_VECTTBL_Pos 1 /*!< SCB HFSR: VECTTBL Position */
+#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */
+
+/* SCB Debug Fault Status Register Definitions */
+#define SCB_DFSR_EXTERNAL_Pos 4 /*!< SCB DFSR: EXTERNAL Position */
+#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */
+
+#define SCB_DFSR_VCATCH_Pos 3 /*!< SCB DFSR: VCATCH Position */
+#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */
+
+#define SCB_DFSR_DWTTRAP_Pos 2 /*!< SCB DFSR: DWTTRAP Position */
+#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */
+
+#define SCB_DFSR_BKPT_Pos 1 /*!< SCB DFSR: BKPT Position */
+#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */
+
+#define SCB_DFSR_HALTED_Pos 0 /*!< SCB DFSR: HALTED Position */
+#define SCB_DFSR_HALTED_Msk (1UL << SCB_DFSR_HALTED_Pos) /*!< SCB DFSR: HALTED Mask */
+
+/*@} end of group CMSIS_SCB */
+
+
+/** \ingroup CMSIS_core_register
+ \defgroup CMSIS_SCnSCB CMSIS System Control and ID Register not in the SCB
+ Type definitions for the Cortex-M System Control and ID Register not in the SCB
+ @{
+ */
+
+/** \brief Structure type to access the System Control and ID Register not in the SCB.
+ */
+typedef struct
+{
+ uint32_t RESERVED0[1];
+ __I uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */
+ __IO uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */
+} SCnSCB_Type;
+
+/* Interrupt Controller Type Register Definitions */
+#define SCnSCB_ICTR_INTLINESNUM_Pos 0 /*!< ICTR: INTLINESNUM Position */
+#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL << SCnSCB_ICTR_INTLINESNUM_Pos) /*!< ICTR: INTLINESNUM Mask */
+
+/* Auxiliary Control Register Definitions */
+#define SCnSCB_ACTLR_DISOOFP_Pos 9 /*!< ACTLR: DISOOFP Position */
+#define SCnSCB_ACTLR_DISOOFP_Msk (1UL << SCnSCB_ACTLR_DISOOFP_Pos) /*!< ACTLR: DISOOFP Mask */
+
+#define SCnSCB_ACTLR_DISFPCA_Pos 8 /*!< ACTLR: DISFPCA Position */
+#define SCnSCB_ACTLR_DISFPCA_Msk (1UL << SCnSCB_ACTLR_DISFPCA_Pos) /*!< ACTLR: DISFPCA Mask */
+
+#define SCnSCB_ACTLR_DISFOLD_Pos 2 /*!< ACTLR: DISFOLD Position */
+#define SCnSCB_ACTLR_DISFOLD_Msk (1UL << SCnSCB_ACTLR_DISFOLD_Pos) /*!< ACTLR: DISFOLD Mask */
+
+#define SCnSCB_ACTLR_DISDEFWBUF_Pos 1 /*!< ACTLR: DISDEFWBUF Position */
+#define SCnSCB_ACTLR_DISDEFWBUF_Msk (1UL << SCnSCB_ACTLR_DISDEFWBUF_Pos) /*!< ACTLR: DISDEFWBUF Mask */
+
+#define SCnSCB_ACTLR_DISMCYCINT_Pos 0 /*!< ACTLR: DISMCYCINT Position */
+#define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL << SCnSCB_ACTLR_DISMCYCINT_Pos) /*!< ACTLR: DISMCYCINT Mask */
+
+/*@} end of group CMSIS_SCnotSCB */
+
+
+/** \ingroup CMSIS_core_register
+ \defgroup CMSIS_SysTick CMSIS SysTick
+ Type definitions for the Cortex-M System Timer Registers
+ @{
+ */
+
+/** \brief Structure type to access the System Timer (SysTick).
+ */
+typedef struct
+{
+ __IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */
+ __IO uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */
+ __IO uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */
+ __I uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */
+} SysTick_Type;
+
+/* SysTick Control / Status Register Definitions */
+#define SysTick_CTRL_COUNTFLAG_Pos 16 /*!< SysTick CTRL: COUNTFLAG Position */
+#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */
+
+#define SysTick_CTRL_CLKSOURCE_Pos 2 /*!< SysTick CTRL: CLKSOURCE Position */
+#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */
+
+#define SysTick_CTRL_TICKINT_Pos 1 /*!< SysTick CTRL: TICKINT Position */
+#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */
+
+#define SysTick_CTRL_ENABLE_Pos 0 /*!< SysTick CTRL: ENABLE Position */
+#define SysTick_CTRL_ENABLE_Msk (1UL << SysTick_CTRL_ENABLE_Pos) /*!< SysTick CTRL: ENABLE Mask */
+
+/* SysTick Reload Register Definitions */
+#define SysTick_LOAD_RELOAD_Pos 0 /*!< SysTick LOAD: RELOAD Position */
+#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL << SysTick_LOAD_RELOAD_Pos) /*!< SysTick LOAD: RELOAD Mask */
+
+/* SysTick Current Register Definitions */
+#define SysTick_VAL_CURRENT_Pos 0 /*!< SysTick VAL: CURRENT Position */
+#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL << SysTick_VAL_CURRENT_Pos) /*!< SysTick VAL: CURRENT Mask */
+
+/* SysTick Calibration Register Definitions */
+#define SysTick_CALIB_NOREF_Pos 31 /*!< SysTick CALIB: NOREF Position */
+#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */
+
+#define SysTick_CALIB_SKEW_Pos 30 /*!< SysTick CALIB: SKEW Position */
+#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */
+
+#define SysTick_CALIB_TENMS_Pos 0 /*!< SysTick CALIB: TENMS Position */
+#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL << SysTick_VAL_CURRENT_Pos) /*!< SysTick CALIB: TENMS Mask */
+
+/*@} end of group CMSIS_SysTick */
+
+
+/** \ingroup CMSIS_core_register
+ \defgroup CMSIS_ITM CMSIS ITM
+ Type definitions for the Cortex-M Instrumentation Trace Macrocell (ITM)
+ @{
+ */
+
+/** \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM).
+ */
+typedef struct
+{
+ __O union
+ {
+ __O uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */
+ __O uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */
+ __O uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */
+ } PORT [32]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */
+ uint32_t RESERVED0[864];
+ __IO uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */
+ uint32_t RESERVED1[15];
+ __IO uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */
+ uint32_t RESERVED2[15];
+ __IO uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */
+} ITM_Type;
+
+/* ITM Trace Privilege Register Definitions */
+#define ITM_TPR_PRIVMASK_Pos 0 /*!< ITM TPR: PRIVMASK Position */
+#define ITM_TPR_PRIVMASK_Msk (0xFUL << ITM_TPR_PRIVMASK_Pos) /*!< ITM TPR: PRIVMASK Mask */
+
+/* ITM Trace Control Register Definitions */
+#define ITM_TCR_BUSY_Pos 23 /*!< ITM TCR: BUSY Position */
+#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */
+
+#define ITM_TCR_TraceBusID_Pos 16 /*!< ITM TCR: ATBID Position */
+#define ITM_TCR_TraceBusID_Msk (0x7FUL << ITM_TCR_TraceBusID_Pos) /*!< ITM TCR: ATBID Mask */
+
+#define ITM_TCR_GTSFREQ_Pos 10 /*!< ITM TCR: Global timestamp frequency Position */
+#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */
+
+#define ITM_TCR_TSPrescale_Pos 8 /*!< ITM TCR: TSPrescale Position */
+#define ITM_TCR_TSPrescale_Msk (3UL << ITM_TCR_TSPrescale_Pos) /*!< ITM TCR: TSPrescale Mask */
+
+#define ITM_TCR_SWOENA_Pos 4 /*!< ITM TCR: SWOENA Position */
+#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */
+
+#define ITM_TCR_TXENA_Pos 3 /*!< ITM TCR: TXENA Position */
+#define ITM_TCR_TXENA_Msk (1UL << ITM_TCR_TXENA_Pos) /*!< ITM TCR: TXENA Mask */
+
+#define ITM_TCR_SYNCENA_Pos 2 /*!< ITM TCR: SYNCENA Position */
+#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */
+
+#define ITM_TCR_TSENA_Pos 1 /*!< ITM TCR: TSENA Position */
+#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */
+
+#define ITM_TCR_ITMENA_Pos 0 /*!< ITM TCR: ITM Enable bit Position */
+#define ITM_TCR_ITMENA_Msk (1UL << ITM_TCR_ITMENA_Pos) /*!< ITM TCR: ITM Enable bit Mask */
+
+/*@}*/ /* end of group CMSIS_ITM */
+
+
+#if (__MPU_PRESENT == 1)
+/** \ingroup CMSIS_core_register
+ \defgroup CMSIS_MPU CMSIS MPU
+ Type definitions for the Cortex-M Memory Protection Unit (MPU)
+ @{
+ */
+
+/** \brief Structure type to access the Memory Protection Unit (MPU).
+ */
+typedef struct
+{
+ __I uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */
+ __IO uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */
+ __IO uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */
+ __IO uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */
+ __IO uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */
+ __IO uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Alias 1 Region Base Address Register */
+ __IO uint32_t RASR_A1; /*!< Offset: 0x018 (R/W) MPU Alias 1 Region Attribute and Size Register */
+ __IO uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Alias 2 Region Base Address Register */
+ __IO uint32_t RASR_A2; /*!< Offset: 0x020 (R/W) MPU Alias 2 Region Attribute and Size Register */
+ __IO uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Alias 3 Region Base Address Register */
+ __IO uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */
+} MPU_Type;
+
+/* MPU Type Register */
+#define MPU_TYPE_IREGION_Pos 16 /*!< MPU TYPE: IREGION Position */
+#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */
+
+#define MPU_TYPE_DREGION_Pos 8 /*!< MPU TYPE: DREGION Position */
+#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */
+
+#define MPU_TYPE_SEPARATE_Pos 0 /*!< MPU TYPE: SEPARATE Position */
+#define MPU_TYPE_SEPARATE_Msk (1UL << MPU_TYPE_SEPARATE_Pos) /*!< MPU TYPE: SEPARATE Mask */
+
+/* MPU Control Register */
+#define MPU_CTRL_PRIVDEFENA_Pos 2 /*!< MPU CTRL: PRIVDEFENA Position */
+#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */
+
+#define MPU_CTRL_HFNMIENA_Pos 1 /*!< MPU CTRL: HFNMIENA Position */
+#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */
+
+#define MPU_CTRL_ENABLE_Pos 0 /*!< MPU CTRL: ENABLE Position */
+#define MPU_CTRL_ENABLE_Msk (1UL << MPU_CTRL_ENABLE_Pos) /*!< MPU CTRL: ENABLE Mask */
+
+/* MPU Region Number Register */
+#define MPU_RNR_REGION_Pos 0 /*!< MPU RNR: REGION Position */
+#define MPU_RNR_REGION_Msk (0xFFUL << MPU_RNR_REGION_Pos) /*!< MPU RNR: REGION Mask */
+
+/* MPU Region Base Address Register */
+#define MPU_RBAR_ADDR_Pos 5 /*!< MPU RBAR: ADDR Position */
+#define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */
+
+#define MPU_RBAR_VALID_Pos 4 /*!< MPU RBAR: VALID Position */
+#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */
+
+#define MPU_RBAR_REGION_Pos 0 /*!< MPU RBAR: REGION Position */
+#define MPU_RBAR_REGION_Msk (0xFUL << MPU_RBAR_REGION_Pos) /*!< MPU RBAR: REGION Mask */
+
+/* MPU Region Attribute and Size Register */
+#define MPU_RASR_ATTRS_Pos 16 /*!< MPU RASR: MPU Region Attribute field Position */
+#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */
+
+#define MPU_RASR_SRD_Pos 8 /*!< MPU RASR: Sub-Region Disable Position */
+#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */
+
+#define MPU_RASR_SIZE_Pos 1 /*!< MPU RASR: Region Size Field Position */
+#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */
+
+#define MPU_RASR_ENABLE_Pos 0 /*!< MPU RASR: Region enable bit Position */
+#define MPU_RASR_ENABLE_Msk (1UL << MPU_RASR_ENABLE_Pos) /*!< MPU RASR: Region enable bit Disable Mask */
+
+/*@} end of group CMSIS_MPU */
+#endif
+
+
+#if (__FPU_PRESENT == 1)
+/** \ingroup CMSIS_core_register
+ \defgroup CMSIS_FPU CMSIS FPU
+ Type definitions for the Cortex-M Floating Point Unit (FPU)
+ @{
+ */
+
+/** \brief Structure type to access the Floating Point Unit (FPU).
+ */
+typedef struct
+{
+ uint32_t RESERVED0[1];
+ __IO uint32_t FPCCR; /*!< Offset: 0x004 (R/W) Floating-Point Context Control Register */
+ __IO uint32_t FPCAR; /*!< Offset: 0x008 (R/W) Floating-Point Context Address Register */
+ __IO uint32_t FPDSCR; /*!< Offset: 0x00C (R/W) Floating-Point Default Status Control Register */
+ __I uint32_t MVFR0; /*!< Offset: 0x010 (R/ ) Media and FP Feature Register 0 */
+ __I uint32_t MVFR1; /*!< Offset: 0x014 (R/ ) Media and FP Feature Register 1 */
+} FPU_Type;
+
+/* Floating-Point Context Control Register */
+#define FPU_FPCCR_ASPEN_Pos 31 /*!< FPCCR: ASPEN bit Position */
+#define FPU_FPCCR_ASPEN_Msk (1UL << FPU_FPCCR_ASPEN_Pos) /*!< FPCCR: ASPEN bit Mask */
+
+#define FPU_FPCCR_LSPEN_Pos 30 /*!< FPCCR: LSPEN Position */
+#define FPU_FPCCR_LSPEN_Msk (1UL << FPU_FPCCR_LSPEN_Pos) /*!< FPCCR: LSPEN bit Mask */
+
+#define FPU_FPCCR_MONRDY_Pos 8 /*!< FPCCR: MONRDY Position */
+#define FPU_FPCCR_MONRDY_Msk (1UL << FPU_FPCCR_MONRDY_Pos) /*!< FPCCR: MONRDY bit Mask */
+
+#define FPU_FPCCR_BFRDY_Pos 6 /*!< FPCCR: BFRDY Position */
+#define FPU_FPCCR_BFRDY_Msk (1UL << FPU_FPCCR_BFRDY_Pos) /*!< FPCCR: BFRDY bit Mask */
+
+#define FPU_FPCCR_MMRDY_Pos 5 /*!< FPCCR: MMRDY Position */
+#define FPU_FPCCR_MMRDY_Msk (1UL << FPU_FPCCR_MMRDY_Pos) /*!< FPCCR: MMRDY bit Mask */
+
+#define FPU_FPCCR_HFRDY_Pos 4 /*!< FPCCR: HFRDY Position */
+#define FPU_FPCCR_HFRDY_Msk (1UL << FPU_FPCCR_HFRDY_Pos) /*!< FPCCR: HFRDY bit Mask */
+
+#define FPU_FPCCR_THREAD_Pos 3 /*!< FPCCR: processor mode bit Position */
+#define FPU_FPCCR_THREAD_Msk (1UL << FPU_FPCCR_THREAD_Pos) /*!< FPCCR: processor mode active bit Mask */
+
+#define FPU_FPCCR_USER_Pos 1 /*!< FPCCR: privilege level bit Position */
+#define FPU_FPCCR_USER_Msk (1UL << FPU_FPCCR_USER_Pos) /*!< FPCCR: privilege level bit Mask */
+
+#define FPU_FPCCR_LSPACT_Pos 0 /*!< FPCCR: Lazy state preservation active bit Position */
+#define FPU_FPCCR_LSPACT_Msk (1UL << FPU_FPCCR_LSPACT_Pos) /*!< FPCCR: Lazy state preservation active bit Mask */
+
+/* Floating-Point Context Address Register */
+#define FPU_FPCAR_ADDRESS_Pos 3 /*!< FPCAR: ADDRESS bit Position */
+#define FPU_FPCAR_ADDRESS_Msk (0x1FFFFFFFUL << FPU_FPCAR_ADDRESS_Pos) /*!< FPCAR: ADDRESS bit Mask */
+
+/* Floating-Point Default Status Control Register */
+#define FPU_FPDSCR_AHP_Pos 26 /*!< FPDSCR: AHP bit Position */
+#define FPU_FPDSCR_AHP_Msk (1UL << FPU_FPDSCR_AHP_Pos) /*!< FPDSCR: AHP bit Mask */
+
+#define FPU_FPDSCR_DN_Pos 25 /*!< FPDSCR: DN bit Position */
+#define FPU_FPDSCR_DN_Msk (1UL << FPU_FPDSCR_DN_Pos) /*!< FPDSCR: DN bit Mask */
+
+#define FPU_FPDSCR_FZ_Pos 24 /*!< FPDSCR: FZ bit Position */
+#define FPU_FPDSCR_FZ_Msk (1UL << FPU_FPDSCR_FZ_Pos) /*!< FPDSCR: FZ bit Mask */
+
+#define FPU_FPDSCR_RMode_Pos 22 /*!< FPDSCR: RMode bit Position */
+#define FPU_FPDSCR_RMode_Msk (3UL << FPU_FPDSCR_RMode_Pos) /*!< FPDSCR: RMode bit Mask */
+
+/* Media and FP Feature Register 0 */
+#define FPU_MVFR0_FP_rounding_modes_Pos 28 /*!< MVFR0: FP rounding modes bits Position */
+#define FPU_MVFR0_FP_rounding_modes_Msk (0xFUL << FPU_MVFR0_FP_rounding_modes_Pos) /*!< MVFR0: FP rounding modes bits Mask */
+
+#define FPU_MVFR0_Short_vectors_Pos 24 /*!< MVFR0: Short vectors bits Position */
+#define FPU_MVFR0_Short_vectors_Msk (0xFUL << FPU_MVFR0_Short_vectors_Pos) /*!< MVFR0: Short vectors bits Mask */
+
+#define FPU_MVFR0_Square_root_Pos 20 /*!< MVFR0: Square root bits Position */
+#define FPU_MVFR0_Square_root_Msk (0xFUL << FPU_MVFR0_Square_root_Pos) /*!< MVFR0: Square root bits Mask */
+
+#define FPU_MVFR0_Divide_Pos 16 /*!< MVFR0: Divide bits Position */
+#define FPU_MVFR0_Divide_Msk (0xFUL << FPU_MVFR0_Divide_Pos) /*!< MVFR0: Divide bits Mask */
+
+#define FPU_MVFR0_FP_excep_trapping_Pos 12 /*!< MVFR0: FP exception trapping bits Position */
+#define FPU_MVFR0_FP_excep_trapping_Msk (0xFUL << FPU_MVFR0_FP_excep_trapping_Pos) /*!< MVFR0: FP exception trapping bits Mask */
+
+#define FPU_MVFR0_Double_precision_Pos 8 /*!< MVFR0: Double-precision bits Position */
+#define FPU_MVFR0_Double_precision_Msk (0xFUL << FPU_MVFR0_Double_precision_Pos) /*!< MVFR0: Double-precision bits Mask */
+
+#define FPU_MVFR0_Single_precision_Pos 4 /*!< MVFR0: Single-precision bits Position */
+#define FPU_MVFR0_Single_precision_Msk (0xFUL << FPU_MVFR0_Single_precision_Pos) /*!< MVFR0: Single-precision bits Mask */
+
+#define FPU_MVFR0_A_SIMD_registers_Pos 0 /*!< MVFR0: A_SIMD registers bits Position */
+#define FPU_MVFR0_A_SIMD_registers_Msk (0xFUL << FPU_MVFR0_A_SIMD_registers_Pos) /*!< MVFR0: A_SIMD registers bits Mask */
+
+/* Media and FP Feature Register 1 */
+#define FPU_MVFR1_FP_fused_MAC_Pos 28 /*!< MVFR1: FP fused MAC bits Position */
+#define FPU_MVFR1_FP_fused_MAC_Msk (0xFUL << FPU_MVFR1_FP_fused_MAC_Pos) /*!< MVFR1: FP fused MAC bits Mask */
+
+#define FPU_MVFR1_FP_HPFP_Pos 24 /*!< MVFR1: FP HPFP bits Position */
+#define FPU_MVFR1_FP_HPFP_Msk (0xFUL << FPU_MVFR1_FP_HPFP_Pos) /*!< MVFR1: FP HPFP bits Mask */
+
+#define FPU_MVFR1_D_NaN_mode_Pos 4 /*!< MVFR1: D_NaN mode bits Position */
+#define FPU_MVFR1_D_NaN_mode_Msk (0xFUL << FPU_MVFR1_D_NaN_mode_Pos) /*!< MVFR1: D_NaN mode bits Mask */
+
+#define FPU_MVFR1_FtZ_mode_Pos 0 /*!< MVFR1: FtZ mode bits Position */
+#define FPU_MVFR1_FtZ_mode_Msk (0xFUL << FPU_MVFR1_FtZ_mode_Pos) /*!< MVFR1: FtZ mode bits Mask */
+
+/*@} end of group CMSIS_FPU */
+#endif
+
+
+/** \ingroup CMSIS_core_register
+ \defgroup CMSIS_CoreDebug CMSIS Core Debug
+ Type definitions for the Cortex-M Core Debug Registers
+ @{
+ */
+
+/** \brief Structure type to access the Core Debug Register (CoreDebug).
+ */
+typedef struct
+{
+ __IO uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */
+ __O uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */
+ __IO uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */
+ __IO uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */
+} CoreDebug_Type;
+
+/* Debug Halting Control and Status Register */
+#define CoreDebug_DHCSR_DBGKEY_Pos 16 /*!< CoreDebug DHCSR: DBGKEY Position */
+#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */
+
+#define CoreDebug_DHCSR_S_RESET_ST_Pos 25 /*!< CoreDebug DHCSR: S_RESET_ST Position */
+#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */
+
+#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24 /*!< CoreDebug DHCSR: S_RETIRE_ST Position */
+#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */
+
+#define CoreDebug_DHCSR_S_LOCKUP_Pos 19 /*!< CoreDebug DHCSR: S_LOCKUP Position */
+#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */
+
+#define CoreDebug_DHCSR_S_SLEEP_Pos 18 /*!< CoreDebug DHCSR: S_SLEEP Position */
+#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */
+
+#define CoreDebug_DHCSR_S_HALT_Pos 17 /*!< CoreDebug DHCSR: S_HALT Position */
+#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */
+
+#define CoreDebug_DHCSR_S_REGRDY_Pos 16 /*!< CoreDebug DHCSR: S_REGRDY Position */
+#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */
+
+#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5 /*!< CoreDebug DHCSR: C_SNAPSTALL Position */
+#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */
+
+#define CoreDebug_DHCSR_C_MASKINTS_Pos 3 /*!< CoreDebug DHCSR: C_MASKINTS Position */
+#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */
+
+#define CoreDebug_DHCSR_C_STEP_Pos 2 /*!< CoreDebug DHCSR: C_STEP Position */
+#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */
+
+#define CoreDebug_DHCSR_C_HALT_Pos 1 /*!< CoreDebug DHCSR: C_HALT Position */
+#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */
+
+#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0 /*!< CoreDebug DHCSR: C_DEBUGEN Position */
+#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL << CoreDebug_DHCSR_C_DEBUGEN_Pos) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */
+
+/* Debug Core Register Selector Register */
+#define CoreDebug_DCRSR_REGWnR_Pos 16 /*!< CoreDebug DCRSR: REGWnR Position */
+#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */
+
+#define CoreDebug_DCRSR_REGSEL_Pos 0 /*!< CoreDebug DCRSR: REGSEL Position */
+#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL << CoreDebug_DCRSR_REGSEL_Pos) /*!< CoreDebug DCRSR: REGSEL Mask */
+
+/* Debug Exception and Monitor Control Register */
+#define CoreDebug_DEMCR_TRCENA_Pos 24 /*!< CoreDebug DEMCR: TRCENA Position */
+#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */
+
+#define CoreDebug_DEMCR_MON_REQ_Pos 19 /*!< CoreDebug DEMCR: MON_REQ Position */
+#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */
+
+#define CoreDebug_DEMCR_MON_STEP_Pos 18 /*!< CoreDebug DEMCR: MON_STEP Position */
+#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */
+
+#define CoreDebug_DEMCR_MON_PEND_Pos 17 /*!< CoreDebug DEMCR: MON_PEND Position */
+#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */
+
+#define CoreDebug_DEMCR_MON_EN_Pos 16 /*!< CoreDebug DEMCR: MON_EN Position */
+#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */
+
+#define CoreDebug_DEMCR_VC_HARDERR_Pos 10 /*!< CoreDebug DEMCR: VC_HARDERR Position */
+#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */
+
+#define CoreDebug_DEMCR_VC_INTERR_Pos 9 /*!< CoreDebug DEMCR: VC_INTERR Position */
+#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */
+
+#define CoreDebug_DEMCR_VC_BUSERR_Pos 8 /*!< CoreDebug DEMCR: VC_BUSERR Position */
+#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */
+
+#define CoreDebug_DEMCR_VC_STATERR_Pos 7 /*!< CoreDebug DEMCR: VC_STATERR Position */
+#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */
+
+#define CoreDebug_DEMCR_VC_CHKERR_Pos 6 /*!< CoreDebug DEMCR: VC_CHKERR Position */
+#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */
+
+#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5 /*!< CoreDebug DEMCR: VC_NOCPERR Position */
+#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */
+
+#define CoreDebug_DEMCR_VC_MMERR_Pos 4 /*!< CoreDebug DEMCR: VC_MMERR Position */
+#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */
+
+#define CoreDebug_DEMCR_VC_CORERESET_Pos 0 /*!< CoreDebug DEMCR: VC_CORERESET Position */
+#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL << CoreDebug_DEMCR_VC_CORERESET_Pos) /*!< CoreDebug DEMCR: VC_CORERESET Mask */
+
+/*@} end of group CMSIS_CoreDebug */
+
+
+/** \ingroup CMSIS_core_register
+ @{
+ */
+
+/* Memory mapping of Cortex-M4 Hardware */
+#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */
+#define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */
+#define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */
+#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */
+#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */
+#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */
+
+#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */
+#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */
+#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */
+#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */
+#define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */
+#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */
+
+#if (__MPU_PRESENT == 1)
+ #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */
+ #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */
+#endif
+
+#if (__FPU_PRESENT == 1)
+ #define FPU_BASE (SCS_BASE + 0x0F30UL) /*!< Floating Point Unit */
+ #define FPU ((FPU_Type *) FPU_BASE ) /*!< Floating Point Unit */
+#endif
+
+/*@} */
+
+
+
+/*******************************************************************************
+ * Hardware Abstraction Layer
+ ******************************************************************************/
+/** \defgroup CMSIS_Core_FunctionInterface CMSIS Core Function Interface
+ Core Function Interface contains:
+ - Core NVIC Functions
+ - Core SysTick Functions
+ - Core Debug Functions
+ - Core Register Access Functions
+*/
+
+
+
+/* ########################## NVIC functions #################################### */
+/** \ingroup CMSIS_Core_FunctionInterface
+ \defgroup CMSIS_Core_NVICFunctions CMSIS Core NVIC Functions
+ @{
+ */
+
+/** \brief Set Priority Grouping
+
+ This function sets the priority grouping field using the required unlock sequence.
+ The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field.
+ Only values from 0..7 are used.
+ In case of a conflict between priority grouping and available
+ priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set.
+
+ \param [in] PriorityGroup Priority grouping field
+ */
+static __INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup)
+{
+ uint32_t reg_value;
+ uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07); /* only values 0..7 are used */
+
+ reg_value = SCB->AIRCR; /* read old register configuration */
+ reg_value &= ~(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk); /* clear bits to change */
+ reg_value = (reg_value |
+ ((uint32_t)0x5FA << SCB_AIRCR_VECTKEY_Pos) |
+ (PriorityGroupTmp << 8)); /* Insert write key and priorty group */
+ SCB->AIRCR = reg_value;
+}
+
+
+/** \brief Get Priority Grouping
+
+ This function gets the priority grouping from NVIC Interrupt Controller.
+ Priority grouping is SCB->AIRCR [10:8] PRIGROUP field.
+
+ \return Priority grouping field
+ */
+static __INLINE uint32_t NVIC_GetPriorityGrouping(void)
+{
+ return ((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos); /* read priority grouping field */
+}
+
+
+/** \brief Enable External Interrupt
+
+ This function enables a device specific interrupt in the NVIC interrupt controller.
+ The interrupt number cannot be a negative value.
+
+ \param [in] IRQn Number of the external interrupt to enable
+ */
+static __INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
+{
+/* NVIC->ISER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); enable interrupt */
+ NVIC->ISER[(uint32_t)((int32_t)IRQn) >> 5] = (uint32_t)(1 << ((uint32_t)((int32_t)IRQn) & (uint32_t)0x1F)); /* enable interrupt */
+}
+
+
+/** \brief Disable External Interrupt
+
+ This function disables a device specific interrupt in the NVIC interrupt controller.
+ The interrupt number cannot be a negative value.
+
+ \param [in] IRQn Number of the external interrupt to disable
+ */
+static __INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)
+{
+ NVIC->ICER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* disable interrupt */
+}
+
+
+/** \brief Get Pending Interrupt
+
+ This function reads the pending register in the NVIC and returns the pending bit
+ for the specified interrupt.
+
+ \param [in] IRQn Number of the interrupt for get pending
+ \return 0 Interrupt status is not pending
+ \return 1 Interrupt status is pending
+ */
+static __INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)
+{
+ return((uint32_t) ((NVIC->ISPR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); /* Return 1 if pending else 0 */
+}
+
+
+/** \brief Set Pending Interrupt
+
+ This function sets the pending bit for the specified interrupt.
+ The interrupt number cannot be a negative value.
+
+ \param [in] IRQn Number of the interrupt for set pending
+ */
+static __INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn)
+{
+ NVIC->ISPR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* set interrupt pending */
+}
+
+
+/** \brief Clear Pending Interrupt
+
+ This function clears the pending bit for the specified interrupt.
+ The interrupt number cannot be a negative value.
+
+ \param [in] IRQn Number of the interrupt for clear pending
+ */
+static __INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
+{
+ NVIC->ICPR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* Clear pending interrupt */
+}
+
+
+/** \brief Get Active Interrupt
+
+ This function reads the active register in NVIC and returns the active bit.
+ \param [in] IRQn Number of the interrupt for get active
+ \return 0 Interrupt status is not active
+ \return 1 Interrupt status is active
+ */
+static __INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn)
+{
+ return((uint32_t)((NVIC->IABR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); /* Return 1 if active else 0 */
+}
+
+
+/** \brief Set Interrupt Priority
+
+ This function sets the priority for the specified interrupt. The interrupt
+ number can be positive to specify an external (device specific)
+ interrupt, or negative to specify an internal (core) interrupt.
+
+ Note: The priority cannot be set for every core interrupt.
+
+ \param [in] IRQn Number of the interrupt for set priority
+ \param [in] priority Priority to set
+ */
+static __INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
+{
+ if(IRQn < 0) {
+ SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for Cortex-M System Interrupts */
+ else {
+ NVIC->IP[(uint32_t)(IRQn)] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for device specific Interrupts */
+}
+
+
+/** \brief Get Interrupt Priority
+
+ This function reads the priority for the specified interrupt. The interrupt
+ number can be positive to specify an external (device specific)
+ interrupt, or negative to specify an internal (core) interrupt.
+
+ The returned priority value is automatically aligned to the implemented
+ priority bits of the microcontroller.
+
+ \param [in] IRQn Number of the interrupt for get priority
+ \return Interrupt Priority
+ */
+static __INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn)
+{
+
+ if(IRQn < 0) {
+ return((uint32_t)(SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] >> (8 - __NVIC_PRIO_BITS))); } /* get priority for Cortex-M system interrupts */
+ else {
+ return((uint32_t)(NVIC->IP[(uint32_t)(IRQn)] >> (8 - __NVIC_PRIO_BITS))); } /* get priority for device specific interrupts */
+}
+
+
+/** \brief Encode Priority
+
+ This function encodes the priority for an interrupt with the given priority group,
+ preemptive priority value and sub priority value.
+ In case of a conflict between priority grouping and available
+ priority bits (__NVIC_PRIO_BITS) the samllest possible priority group is set.
+
+ The returned priority value can be used for NVIC_SetPriority(...) function
+
+ \param [in] PriorityGroup Used priority group
+ \param [in] PreemptPriority Preemptive priority value (starting from 0)
+ \param [in] SubPriority Sub priority value (starting from 0)
+ \return Encoded priority for the interrupt
+ */
+static __INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority)
+{
+ uint32_t PriorityGroupTmp = (PriorityGroup & 0x07); /* only values 0..7 are used */
+ uint32_t PreemptPriorityBits;
+ uint32_t SubPriorityBits;
+
+ PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp;
+ SubPriorityBits = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS;
+
+ return (
+ ((PreemptPriority & ((1 << (PreemptPriorityBits)) - 1)) << SubPriorityBits) |
+ ((SubPriority & ((1 << (SubPriorityBits )) - 1)))
+ );
+}
+
+
+/** \brief Decode Priority
+
+ This function decodes an interrupt priority value with the given priority group to
+ preemptive priority value and sub priority value.
+ In case of a conflict between priority grouping and available
+ priority bits (__NVIC_PRIO_BITS) the samllest possible priority group is set.
+
+ The priority value can be retrieved with NVIC_GetPriority(...) function
+
+ \param [in] Priority Priority value
+ \param [in] PriorityGroup Used priority group
+ \param [out] pPreemptPriority Preemptive priority value (starting from 0)
+ \param [out] pSubPriority Sub priority value (starting from 0)
+ */
+static __INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* pPreemptPriority, uint32_t* pSubPriority)
+{
+ uint32_t PriorityGroupTmp = (PriorityGroup & 0x07); /* only values 0..7 are used */
+ uint32_t PreemptPriorityBits;
+ uint32_t SubPriorityBits;
+
+ PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp;
+ SubPriorityBits = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS;
+
+ *pPreemptPriority = (Priority >> SubPriorityBits) & ((1 << (PreemptPriorityBits)) - 1);
+ *pSubPriority = (Priority ) & ((1 << (SubPriorityBits )) - 1);
+}
+
+
+/** \brief System Reset
+
+ This function initiate a system reset request to reset the MCU.
+ */
+static __INLINE void NVIC_SystemReset(void)
+{
+ __DSB(); /* Ensure all outstanding memory accesses included
+ buffered write are completed before reset */
+ SCB->AIRCR = ((0x5FA << SCB_AIRCR_VECTKEY_Pos) |
+ (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) |
+ SCB_AIRCR_SYSRESETREQ_Msk); /* Keep priority group unchanged */
+ __DSB(); /* Ensure completion of memory access */
+ while(1); /* wait until reset */
+}
+
+/*@} end of CMSIS_Core_NVICFunctions */
+
+
+
+/* ################################## SysTick function ############################################ */
+/** \ingroup CMSIS_Core_FunctionInterface
+ \defgroup CMSIS_Core_SysTickFunctions CMSIS Core SysTick Functions
+ @{
+ */
+
+#if (__Vendor_SysTickConfig == 0)
+
+/** \brief System Tick Configuration
+
+ This function initialises the system tick timer and its interrupt and start the system tick timer.
+ Counter is in free running mode to generate periodical interrupts.
+
+ \param [in] ticks Number of ticks between two interrupts
+ \return 0 Function succeeded
+ \return 1 Function failed
+ */
+static __INLINE uint32_t SysTick_Config(uint32_t ticks)
+{
+ if (ticks > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */
+
+ SysTick->LOAD = (ticks & SysTick_LOAD_RELOAD_Msk) - 1; /* set reload register */
+ NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Cortex-M0 System Interrupts */
+ SysTick->VAL = 0; /* Load the SysTick Counter Value */
+ SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
+ SysTick_CTRL_TICKINT_Msk |
+ SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */
+ return (0); /* Function successful */
+}
+
+#endif
+
+/*@} end of CMSIS_Core_SysTickFunctions */
+
+
+
+/* ##################################### Debug In/Output function ########################################### */
+/** \ingroup CMSIS_Core_FunctionInterface
+ \defgroup CMSIS_core_DebugFunctions CMSIS Core Debug Functions
+ @{
+ */
+
+extern volatile int32_t ITM_RxBuffer; /*!< external variable to receive characters */
+#define ITM_RXBUFFER_EMPTY 0x5AA55AA5 /*!< value identifying ITM_RxBuffer is ready for next character */
+
+
+/** \brief ITM Send Character
+
+ This function transmits a character via the ITM channel 0.
+ It just returns when no debugger is connected that has booked the output.
+ It is blocking when a debugger is connected, but the previous character send is not transmitted.
+
+ \param [in] ch Character to transmit
+ \return Character to transmit
+ */
+static __INLINE uint32_t ITM_SendChar (uint32_t ch)
+{
+ if ((CoreDebug->DEMCR & CoreDebug_DEMCR_TRCENA_Msk) && /* Trace enabled */
+ (ITM->TCR & ITM_TCR_ITMENA_Msk) && /* ITM enabled */
+ (ITM->TER & (1UL << 0) ) ) /* ITM Port #0 enabled */
+ {
+ while (ITM->PORT[0].u32 == 0);
+ ITM->PORT[0].u8 = (uint8_t) ch;
+ }
+ return (ch);
+}
+
+
+/** \brief ITM Receive Character
+
+ This function inputs a character via external variable ITM_RxBuffer.
+ It just returns when no debugger is connected that has booked the output.
+ It is blocking when a debugger is connected, but the previous character send is not transmitted.
+
+ \return Received character
+ \return -1 No character received
+ */
+static __INLINE int32_t ITM_ReceiveChar (void) {
+ int32_t ch = -1; /* no character available */
+
+ if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) {
+ ch = ITM_RxBuffer;
+ ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */
+ }
+
+ return (ch);
+}
+
+
+/** \brief ITM Check Character
+
+ This function checks external variable ITM_RxBuffer whether a character is available or not.
+ It returns '1' if a character is available and '0' if no character is available.
+
+ \return 0 No character available
+ \return 1 Character available
+ */
+static __INLINE int32_t ITM_CheckChar (void) {
+
+ if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) {
+ return (0); /* no character available */
+ } else {
+ return (1); /* character available */
+ }
+}
+
+/*@} end of CMSIS_core_DebugFunctions */
+
+#endif /* __CORE_CM4_H_DEPENDANT */
+
+#endif /* __CMSIS_GENERIC */
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/platform/mcu/CMSIS/Include/core_cm4_simd.h b/platform/mcu/CMSIS/Include/core_cm4_simd.h
new file mode 100644
index 00000000..47918869
--- /dev/null
+++ b/platform/mcu/CMSIS/Include/core_cm4_simd.h
@@ -0,0 +1,701 @@
+/**************************************************************************//**
+ * @file core_cm4_simd.h
+ * @brief CMSIS Cortex-M4 SIMD Header File
+ * @version V2.10
+ * @date 19. July 2011
+ *
+ * @note
+ * Copyright (C) 2010-2011 ARM Limited. All rights reserved.
+ *
+ * @par
+ * ARM Limited (ARM) is supplying this software for use with Cortex-M
+ * processor based microcontrollers. This file can be freely distributed
+ * within development tools that are supporting such ARM based processors.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
+ * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
+ * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
+ * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
+ *
+ ******************************************************************************/
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#ifndef __CORE_CM4_SIMD_H
+#define __CORE_CM4_SIMD_H
+
+
+/*******************************************************************************
+ * Hardware Abstraction Layer
+ ******************************************************************************/
+
+
+/* ################### Compiler specific Intrinsics ########################### */
+/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics
+ Access to dedicated SIMD instructions
+ @{
+*/
+
+#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/
+/* ARM armcc specific functions */
+
+/*------ CM4 SOMD Intrinsics -----------------------------------------------------*/
+#define __SADD8 __sadd8
+#define __QADD8 __qadd8
+#define __SHADD8 __shadd8
+#define __UADD8 __uadd8
+#define __UQADD8 __uqadd8
+#define __UHADD8 __uhadd8
+#define __SSUB8 __ssub8
+#define __QSUB8 __qsub8
+#define __SHSUB8 __shsub8
+#define __USUB8 __usub8
+#define __UQSUB8 __uqsub8
+#define __UHSUB8 __uhsub8
+#define __SADD16 __sadd16
+#define __QADD16 __qadd16
+#define __SHADD16 __shadd16
+#define __UADD16 __uadd16
+#define __UQADD16 __uqadd16
+#define __UHADD16 __uhadd16
+#define __SSUB16 __ssub16
+#define __QSUB16 __qsub16
+#define __SHSUB16 __shsub16
+#define __USUB16 __usub16
+#define __UQSUB16 __uqsub16
+#define __UHSUB16 __uhsub16
+#define __SASX __sasx
+#define __QASX __qasx
+#define __SHASX __shasx
+#define __UASX __uasx
+#define __UQASX __uqasx
+#define __UHASX __uhasx
+#define __SSAX __ssax
+#define __QSAX __qsax
+#define __SHSAX __shsax
+#define __USAX __usax
+#define __UQSAX __uqsax
+#define __UHSAX __uhsax
+#define __USAD8 __usad8
+#define __USADA8 __usada8
+#define __SSAT16 __ssat16
+#define __USAT16 __usat16
+#define __UXTB16 __uxtb16
+#define __UXTAB16 __uxtab16
+#define __SXTB16 __sxtb16
+#define __SXTAB16 __sxtab16
+#define __SMUAD __smuad
+#define __SMUADX __smuadx
+#define __SMLAD __smlad
+#define __SMLADX __smladx
+#define __SMLALD __smlald
+#define __SMLALDX __smlaldx
+#define __SMUSD __smusd
+#define __SMUSDX __smusdx
+#define __SMLSD __smlsd
+#define __SMLSDX __smlsdx
+#define __SMLSLD __smlsld
+#define __SMLSLDX __smlsldx
+#define __SEL __sel
+#define __QADD __qadd
+#define __QSUB __qsub
+
+#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \
+ ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) )
+
+#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \
+ ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) )
+
+
+/*-- End CM4 SIMD Intrinsics -----------------------------------------------------*/
+
+
+
+#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/
+/* IAR iccarm specific functions */
+
+#include
+
+/*------ CM4 SIMDDSP Intrinsics -----------------------------------------------------*/
+/* intrinsic __SADD8 see intrinsics.h */
+/* intrinsic __QADD8 see intrinsics.h */
+/* intrinsic __SHADD8 see intrinsics.h */
+/* intrinsic __UADD8 see intrinsics.h */
+/* intrinsic __UQADD8 see intrinsics.h */
+/* intrinsic __UHADD8 see intrinsics.h */
+/* intrinsic __SSUB8 see intrinsics.h */
+/* intrinsic __QSUB8 see intrinsics.h */
+/* intrinsic __SHSUB8 see intrinsics.h */
+/* intrinsic __USUB8 see intrinsics.h */
+/* intrinsic __UQSUB8 see intrinsics.h */
+/* intrinsic __UHSUB8 see intrinsics.h */
+/* intrinsic __SADD16 see intrinsics.h */
+/* intrinsic __QADD16 see intrinsics.h */
+/* intrinsic __SHADD16 see intrinsics.h */
+/* intrinsic __UADD16 see intrinsics.h */
+/* intrinsic __UQADD16 see intrinsics.h */
+/* intrinsic __UHADD16 see intrinsics.h */
+/* intrinsic __SSUB16 see intrinsics.h */
+/* intrinsic __QSUB16 see intrinsics.h */
+/* intrinsic __SHSUB16 see intrinsics.h */
+/* intrinsic __USUB16 see intrinsics.h */
+/* intrinsic __UQSUB16 see intrinsics.h */
+/* intrinsic __UHSUB16 see intrinsics.h */
+/* intrinsic __SASX see intrinsics.h */
+/* intrinsic __QASX see intrinsics.h */
+/* intrinsic __SHASX see intrinsics.h */
+/* intrinsic __UASX see intrinsics.h */
+/* intrinsic __UQASX see intrinsics.h */
+/* intrinsic __UHASX see intrinsics.h */
+/* intrinsic __SSAX see intrinsics.h */
+/* intrinsic __QSAX see intrinsics.h */
+/* intrinsic __SHSAX see intrinsics.h */
+/* intrinsic __USAX see intrinsics.h */
+/* intrinsic __UQSAX see intrinsics.h */
+/* intrinsic __UHSAX see intrinsics.h */
+/* intrinsic __USAD8 see intrinsics.h */
+/* intrinsic __USADA8 see intrinsics.h */
+/* intrinsic __SSAT16 see intrinsics.h */
+/* intrinsic __USAT16 see intrinsics.h */
+/* intrinsic __UXTB16 see intrinsics.h */
+/* intrinsic __SXTB16 see intrinsics.h */
+/* intrinsic __UXTAB16 see intrinsics.h */
+/* intrinsic __SXTAB16 see intrinsics.h */
+/* intrinsic __SMUAD see intrinsics.h */
+/* intrinsic __SMUADX see intrinsics.h */
+/* intrinsic __SMLAD see intrinsics.h */
+/* intrinsic __SMLADX see intrinsics.h */
+/* intrinsic __SMLALD see intrinsics.h */
+/* intrinsic __SMLALDX see intrinsics.h */
+/* intrinsic __SMUSD see intrinsics.h */
+/* intrinsic __SMUSDX see intrinsics.h */
+/* intrinsic __SMLSD see intrinsics.h */
+/* intrinsic __SMLSDX see intrinsics.h */
+/* intrinsic __SMLSLD see intrinsics.h */
+/* intrinsic __SMLSLDX see intrinsics.h */
+/* intrinsic __SEL see intrinsics.h */
+/* intrinsic __QADD see intrinsics.h */
+/* intrinsic __QSUB see intrinsics.h */
+/* intrinsic __PKHBT see intrinsics.h */
+/* intrinsic __PKHTB see intrinsics.h */
+
+/*-- End CM4 SIMD Intrinsics -----------------------------------------------------*/
+
+
+
+#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/
+/* GNU gcc specific functions */
+
+/*------ CM4 SIMD Intrinsics -----------------------------------------------------*/
+__attribute__( ( always_inline ) ) static __INLINE uint32_t __SADD8(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("sadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) static __INLINE uint32_t __QADD8(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("qadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) static __INLINE uint32_t __SHADD8(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("shadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) static __INLINE uint32_t __UADD8(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("uadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) static __INLINE uint32_t __UQADD8(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("uqadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) static __INLINE uint32_t __UHADD8(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("uhadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+
+__attribute__( ( always_inline ) ) static __INLINE uint32_t __SSUB8(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("ssub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) static __INLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("qsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) static __INLINE uint32_t __SHSUB8(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("shsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) static __INLINE uint32_t __USUB8(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("usub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) static __INLINE uint32_t __UQSUB8(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("uqsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) static __INLINE uint32_t __UHSUB8(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("uhsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+
+__attribute__( ( always_inline ) ) static __INLINE uint32_t __SADD16(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("sadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) static __INLINE uint32_t __QADD16(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("qadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) static __INLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("shadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) static __INLINE uint32_t __UADD16(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("uadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) static __INLINE uint32_t __UQADD16(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("uqadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) static __INLINE uint32_t __UHADD16(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("uhadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) static __INLINE uint32_t __SSUB16(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("ssub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) static __INLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("qsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) static __INLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("shsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) static __INLINE uint32_t __USUB16(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("usub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) static __INLINE uint32_t __UQSUB16(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("uqsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) static __INLINE uint32_t __UHSUB16(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("uhsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) static __INLINE uint32_t __SASX(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("sasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) static __INLINE uint32_t __QASX(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("qasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) static __INLINE uint32_t __SHASX(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("shasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) static __INLINE uint32_t __UASX(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("uasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) static __INLINE uint32_t __UQASX(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("uqasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) static __INLINE uint32_t __UHASX(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("uhasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) static __INLINE uint32_t __SSAX(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("ssax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) static __INLINE uint32_t __QSAX(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("qsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) static __INLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("shsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) static __INLINE uint32_t __USAX(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("usax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) static __INLINE uint32_t __UQSAX(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("uqsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) static __INLINE uint32_t __UHSAX(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("uhsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) static __INLINE uint32_t __USAD8(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("usad8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) static __INLINE uint32_t __USADA8(uint32_t op1, uint32_t op2, uint32_t op3)
+{
+ uint32_t result;
+
+ __ASM volatile ("usada8 %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
+ return(result);
+}
+
+#define __SSAT16(ARG1,ARG2) \
+({ \
+ uint32_t __RES, __ARG1 = (ARG1); \
+ __ASM ("ssat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
+ __RES; \
+ })
+
+#define __USAT16(ARG1,ARG2) \
+({ \
+ uint32_t __RES, __ARG1 = (ARG1); \
+ __ASM ("usat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
+ __RES; \
+ })
+
+__attribute__( ( always_inline ) ) static __INLINE uint32_t __UXTB16(uint32_t op1)
+{
+ uint32_t result;
+
+ __ASM volatile ("uxtb16 %0, %1" : "=r" (result) : "r" (op1));
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) static __INLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("uxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) static __INLINE uint32_t __SXTB16(uint32_t op1)
+{
+ uint32_t result;
+
+ __ASM volatile ("sxtb16 %0, %1" : "=r" (result) : "r" (op1));
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) static __INLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("sxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) static __INLINE uint32_t __SMUAD (uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("smuad %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) static __INLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("smuadx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) static __INLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3)
+{
+ uint32_t result;
+
+ __ASM volatile ("smlad %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) static __INLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3)
+{
+ uint32_t result;
+
+ __ASM volatile ("smladx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
+ return(result);
+}
+
+#define __SMLALD(ARG1,ARG2,ARG3) \
+({ \
+ uint32_t __ARG1 = (ARG1), __ARG2 = (ARG2), __ARG3_H = (uint32_t)((uint64_t)(ARG3) >> 32), __ARG3_L = (uint32_t)((uint64_t)(ARG3) & 0xFFFFFFFFUL); \
+ __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (__ARG3_L), "=r" (__ARG3_H) : "r" (__ARG1), "r" (__ARG2), "0" (__ARG3_L), "1" (__ARG3_H) ); \
+ (uint64_t)(((uint64_t)__ARG3_H << 32) | __ARG3_L); \
+ })
+
+#define __SMLALDX(ARG1,ARG2,ARG3) \
+({ \
+ uint32_t __ARG1 = (ARG1), __ARG2 = (ARG2), __ARG3_H = (uint32_t)((uint64_t)(ARG3) >> 32), __ARG3_L = (uint32_t)((uint64_t)(ARG3) & 0xFFFFFFFFUL); \
+ __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (__ARG3_L), "=r" (__ARG3_H) : "r" (__ARG1), "r" (__ARG2), "0" (__ARG3_L), "1" (__ARG3_H) ); \
+ (uint64_t)(((uint64_t)__ARG3_H << 32) | __ARG3_L); \
+ })
+
+__attribute__( ( always_inline ) ) static __INLINE uint32_t __SMUSD (uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("smusd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) static __INLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("smusdx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) static __INLINE uint32_t __SMLSD (uint32_t op1, uint32_t op2, uint32_t op3)
+{
+ uint32_t result;
+
+ __ASM volatile ("smlsd %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) static __INLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3)
+{
+ uint32_t result;
+
+ __ASM volatile ("smlsdx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
+ return(result);
+}
+
+#define __SMLSLD(ARG1,ARG2,ARG3) \
+({ \
+ uint32_t __ARG1 = (ARG1), __ARG2 = (ARG2), __ARG3_H = (uint32_t)((ARG3) >> 32), __ARG3_L = (uint32_t)((ARG3) & 0xFFFFFFFFUL); \
+ __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (__ARG3_L), "=r" (__ARG3_H) : "r" (__ARG1), "r" (__ARG2), "0" (__ARG3_L), "1" (__ARG3_H) ); \
+ (uint64_t)(((uint64_t)__ARG3_H << 32) | __ARG3_L); \
+ })
+
+#define __SMLSLDX(ARG1,ARG2,ARG3) \
+({ \
+ uint32_t __ARG1 = (ARG1), __ARG2 = (ARG2), __ARG3_H = (uint32_t)((ARG3) >> 32), __ARG3_L = (uint32_t)((ARG3) & 0xFFFFFFFFUL); \
+ __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (__ARG3_L), "=r" (__ARG3_H) : "r" (__ARG1), "r" (__ARG2), "0" (__ARG3_L), "1" (__ARG3_H) ); \
+ (uint64_t)(((uint64_t)__ARG3_H << 32) | __ARG3_L); \
+ })
+
+__attribute__( ( always_inline ) ) static __INLINE uint32_t __SEL (uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("sel %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) static __INLINE uint32_t __QADD(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) static __INLINE uint32_t __QSUB(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+#define __PKHBT(ARG1,ARG2,ARG3) \
+({ \
+ uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \
+ __ASM ("pkhbt %0, %1, %2, lsl %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \
+ __RES; \
+ })
+
+#define __PKHTB(ARG1,ARG2,ARG3) \
+({ \
+ uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \
+ if (ARG3 == 0) \
+ __ASM ("pkhtb %0, %1, %2" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2) ); \
+ else \
+ __ASM ("pkhtb %0, %1, %2, asr %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \
+ __RES; \
+ })
+
+/*-- End CM4 SIMD Intrinsics -----------------------------------------------------*/
+
+
+
+#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/
+/* TASKING carm specific functions */
+
+
+/*------ CM4 SIMD Intrinsics -----------------------------------------------------*/
+/* not yet supported */
+/*-- End CM4 SIMD Intrinsics -----------------------------------------------------*/
+
+
+#endif
+
+/*@} end of group CMSIS_SIMD_intrinsics */
+
+
+#endif /* __CORE_CM4_SIMD_H */
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/platform/mcu/CMSIS/Include/core_cmFunc.h b/platform/mcu/CMSIS/Include/core_cmFunc.h
new file mode 100644
index 00000000..c999b1c8
--- /dev/null
+++ b/platform/mcu/CMSIS/Include/core_cmFunc.h
@@ -0,0 +1,609 @@
+/**************************************************************************//**
+ * @file core_cmFunc.h
+ * @brief CMSIS Cortex-M Core Function Access Header File
+ * @version V2.10
+ * @date 26. July 2011
+ *
+ * @note
+ * Copyright (C) 2009-2011 ARM Limited. All rights reserved.
+ *
+ * @par
+ * ARM Limited (ARM) is supplying this software for use with Cortex-M
+ * processor based microcontrollers. This file can be freely distributed
+ * within development tools that are supporting such ARM based processors.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
+ * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
+ * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
+ * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
+ *
+ ******************************************************************************/
+
+#ifndef __CORE_CMFUNC_H
+#define __CORE_CMFUNC_H
+
+
+/* ########################### Core Function Access ########################### */
+/** \ingroup CMSIS_Core_FunctionInterface
+ \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions
+ @{
+ */
+
+#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/
+/* ARM armcc specific functions */
+
+#if (__ARMCC_VERSION < 400677)
+ #error "Please use ARM Compiler Toolchain V4.0.677 or later!"
+#endif
+
+/* intrinsic void __enable_irq(); */
+/* intrinsic void __disable_irq(); */
+
+/** \brief Get Control Register
+
+ This function returns the content of the Control Register.
+
+ \return Control Register value
+ */
+static __INLINE uint32_t __get_CONTROL(void)
+{
+ register uint32_t __regControl __ASM("control");
+ return(__regControl);
+}
+
+
+/** \brief Set Control Register
+
+ This function writes the given value to the Control Register.
+
+ \param [in] control Control Register value to set
+ */
+static __INLINE void __set_CONTROL(uint32_t control)
+{
+ register uint32_t __regControl __ASM("control");
+ __regControl = control;
+}
+
+
+/** \brief Get ISPR Register
+
+ This function returns the content of the ISPR Register.
+
+ \return ISPR Register value
+ */
+static __INLINE uint32_t __get_IPSR(void)
+{
+ register uint32_t __regIPSR __ASM("ipsr");
+ return(__regIPSR);
+}
+
+
+/** \brief Get APSR Register
+
+ This function returns the content of the APSR Register.
+
+ \return APSR Register value
+ */
+static __INLINE uint32_t __get_APSR(void)
+{
+ register uint32_t __regAPSR __ASM("apsr");
+ return(__regAPSR);
+}
+
+
+/** \brief Get xPSR Register
+
+ This function returns the content of the xPSR Register.
+
+ \return xPSR Register value
+ */
+static __INLINE uint32_t __get_xPSR(void)
+{
+ register uint32_t __regXPSR __ASM("xpsr");
+ return(__regXPSR);
+}
+
+
+/** \brief Get Process Stack Pointer
+
+ This function returns the current value of the Process Stack Pointer (PSP).
+
+ \return PSP Register value
+ */
+static __INLINE uint32_t __get_PSP(void)
+{
+ register uint32_t __regProcessStackPointer __ASM("psp");
+ return(__regProcessStackPointer);
+}
+
+
+/** \brief Set Process Stack Pointer
+
+ This function assigns the given value to the Process Stack Pointer (PSP).
+
+ \param [in] topOfProcStack Process Stack Pointer value to set
+ */
+static __INLINE void __set_PSP(uint32_t topOfProcStack)
+{
+ register uint32_t __regProcessStackPointer __ASM("psp");
+ __regProcessStackPointer = topOfProcStack;
+}
+
+
+/** \brief Get Main Stack Pointer
+
+ This function returns the current value of the Main Stack Pointer (MSP).
+
+ \return MSP Register value
+ */
+static __INLINE uint32_t __get_MSP(void)
+{
+ register uint32_t __regMainStackPointer __ASM("msp");
+ return(__regMainStackPointer);
+}
+
+
+/** \brief Set Main Stack Pointer
+
+ This function assigns the given value to the Main Stack Pointer (MSP).
+
+ \param [in] topOfMainStack Main Stack Pointer value to set
+ */
+static __INLINE void __set_MSP(uint32_t topOfMainStack)
+{
+ register uint32_t __regMainStackPointer __ASM("msp");
+ __regMainStackPointer = topOfMainStack;
+}
+
+
+/** \brief Get Priority Mask
+
+ This function returns the current state of the priority mask bit from the Priority Mask Register.
+
+ \return Priority Mask value
+ */
+static __INLINE uint32_t __get_PRIMASK(void)
+{
+ register uint32_t __regPriMask __ASM("primask");
+ return(__regPriMask);
+}
+
+
+/** \brief Set Priority Mask
+
+ This function assigns the given value to the Priority Mask Register.
+
+ \param [in] priMask Priority Mask
+ */
+static __INLINE void __set_PRIMASK(uint32_t priMask)
+{
+ register uint32_t __regPriMask __ASM("primask");
+ __regPriMask = (priMask);
+}
+
+
+#if (__CORTEX_M >= 0x03)
+
+/** \brief Enable FIQ
+
+ This function enables FIQ interrupts by clearing the F-bit in the CPSR.
+ Can only be executed in Privileged modes.
+ */
+#define __enable_fault_irq __enable_fiq
+
+
+/** \brief Disable FIQ
+
+ This function disables FIQ interrupts by setting the F-bit in the CPSR.
+ Can only be executed in Privileged modes.
+ */
+#define __disable_fault_irq __disable_fiq
+
+
+/** \brief Get Base Priority
+
+ This function returns the current value of the Base Priority register.
+
+ \return Base Priority register value
+ */
+static __INLINE uint32_t __get_BASEPRI(void)
+{
+ register uint32_t __regBasePri __ASM("basepri");
+ return(__regBasePri);
+}
+
+
+/** \brief Set Base Priority
+
+ This function assigns the given value to the Base Priority register.
+
+ \param [in] basePri Base Priority value to set
+ */
+static __INLINE void __set_BASEPRI(uint32_t basePri)
+{
+ register uint32_t __regBasePri __ASM("basepri");
+ __regBasePri = (basePri & 0xff);
+}
+
+
+/** \brief Get Fault Mask
+
+ This function returns the current value of the Fault Mask register.
+
+ \return Fault Mask register value
+ */
+static __INLINE uint32_t __get_FAULTMASK(void)
+{
+ register uint32_t __regFaultMask __ASM("faultmask");
+ return(__regFaultMask);
+}
+
+
+/** \brief Set Fault Mask
+
+ This function assigns the given value to the Fault Mask register.
+
+ \param [in] faultMask Fault Mask value to set
+ */
+static __INLINE void __set_FAULTMASK(uint32_t faultMask)
+{
+ register uint32_t __regFaultMask __ASM("faultmask");
+ __regFaultMask = (faultMask & (uint32_t)1);
+}
+
+#endif /* (__CORTEX_M >= 0x03) */
+
+
+#if (__CORTEX_M == 0x04)
+
+/** \brief Get FPSCR
+
+ This function returns the current value of the Floating Point Status/Control register.
+
+ \return Floating Point Status/Control register value
+ */
+static __INLINE uint32_t __get_FPSCR(void)
+{
+#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
+ register uint32_t __regfpscr __ASM("fpscr");
+ return(__regfpscr);
+#else
+ return(0);
+#endif
+}
+
+
+/** \brief Set FPSCR
+
+ This function assigns the given value to the Floating Point Status/Control register.
+
+ \param [in] fpscr Floating Point Status/Control value to set
+ */
+static __INLINE void __set_FPSCR(uint32_t fpscr)
+{
+#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
+ register uint32_t __regfpscr __ASM("fpscr");
+ __regfpscr = (fpscr);
+#endif
+}
+
+#endif /* (__CORTEX_M == 0x04) */
+
+
+#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/
+/* IAR iccarm specific functions */
+
+#include
+
+#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/
+/* GNU gcc specific functions */
+
+/** \brief Enable IRQ Interrupts
+
+ This function enables IRQ interrupts by clearing the I-bit in the CPSR.
+ Can only be executed in Privileged modes.
+ */
+__attribute__( ( always_inline ) ) static __INLINE void __enable_irq(void)
+{
+ __ASM volatile ("cpsie i");
+}
+
+
+/** \brief Disable IRQ Interrupts
+
+ This function disables IRQ interrupts by setting the I-bit in the CPSR.
+ Can only be executed in Privileged modes.
+ */
+__attribute__( ( always_inline ) ) static __INLINE void __disable_irq(void)
+{
+ __ASM volatile ("cpsid i");
+}
+
+
+/** \brief Get Control Register
+
+ This function returns the content of the Control Register.
+
+ \return Control Register value
+ */
+__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_CONTROL(void)
+{
+ uint32_t result;
+
+ __ASM volatile ("MRS %0, control" : "=r" (result) );
+ return(result);
+}
+
+
+/** \brief Set Control Register
+
+ This function writes the given value to the Control Register.
+
+ \param [in] control Control Register value to set
+ */
+__attribute__( ( always_inline ) ) static __INLINE void __set_CONTROL(uint32_t control)
+{
+ __ASM volatile ("MSR control, %0" : : "r" (control) );
+}
+
+
+/** \brief Get ISPR Register
+
+ This function returns the content of the ISPR Register.
+
+ \return ISPR Register value
+ */
+__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_IPSR(void)
+{
+ uint32_t result;
+
+ __ASM volatile ("MRS %0, ipsr" : "=r" (result) );
+ return(result);
+}
+
+
+/** \brief Get APSR Register
+
+ This function returns the content of the APSR Register.
+
+ \return APSR Register value
+ */
+__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_APSR(void)
+{
+ uint32_t result;
+
+ __ASM volatile ("MRS %0, apsr" : "=r" (result) );
+ return(result);
+}
+
+
+/** \brief Get xPSR Register
+
+ This function returns the content of the xPSR Register.
+
+ \return xPSR Register value
+ */
+__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_xPSR(void)
+{
+ uint32_t result;
+
+ __ASM volatile ("MRS %0, xpsr" : "=r" (result) );
+ return(result);
+}
+
+
+/** \brief Get Process Stack Pointer
+
+ This function returns the current value of the Process Stack Pointer (PSP).
+
+ \return PSP Register value
+ */
+__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_PSP(void)
+{
+ register uint32_t result;
+
+ __ASM volatile ("MRS %0, psp\n" : "=r" (result) );
+ return(result);
+}
+
+
+/** \brief Set Process Stack Pointer
+
+ This function assigns the given value to the Process Stack Pointer (PSP).
+
+ \param [in] topOfProcStack Process Stack Pointer value to set
+ */
+__attribute__( ( always_inline ) ) static __INLINE void __set_PSP(uint32_t topOfProcStack)
+{
+ __ASM volatile ("MSR psp, %0\n" : : "r" (topOfProcStack) );
+}
+
+
+/** \brief Get Main Stack Pointer
+
+ This function returns the current value of the Main Stack Pointer (MSP).
+
+ \return MSP Register value
+ */
+__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_MSP(void)
+{
+ register uint32_t result;
+
+ __ASM volatile ("MRS %0, msp\n" : "=r" (result) );
+ return(result);
+}
+
+
+/** \brief Set Main Stack Pointer
+
+ This function assigns the given value to the Main Stack Pointer (MSP).
+
+ \param [in] topOfMainStack Main Stack Pointer value to set
+ */
+__attribute__( ( always_inline ) ) static __INLINE void __set_MSP(uint32_t topOfMainStack)
+{
+ __ASM volatile ("MSR msp, %0\n" : : "r" (topOfMainStack) );
+}
+
+
+/** \brief Get Priority Mask
+
+ This function returns the current state of the priority mask bit from the Priority Mask Register.
+
+ \return Priority Mask value
+ */
+__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_PRIMASK(void)
+{
+ uint32_t result;
+
+ __ASM volatile ("MRS %0, primask" : "=r" (result) );
+ return(result);
+}
+
+
+/** \brief Set Priority Mask
+
+ This function assigns the given value to the Priority Mask Register.
+
+ \param [in] priMask Priority Mask
+ */
+__attribute__( ( always_inline ) ) static __INLINE void __set_PRIMASK(uint32_t priMask)
+{
+ __ASM volatile ("MSR primask, %0" : : "r" (priMask) );
+}
+
+
+#if (__CORTEX_M >= 0x03)
+
+/** \brief Enable FIQ
+
+ This function enables FIQ interrupts by clearing the F-bit in the CPSR.
+ Can only be executed in Privileged modes.
+ */
+__attribute__( ( always_inline ) ) static __INLINE void __enable_fault_irq(void)
+{
+ __ASM volatile ("cpsie f");
+}
+
+
+/** \brief Disable FIQ
+
+ This function disables FIQ interrupts by setting the F-bit in the CPSR.
+ Can only be executed in Privileged modes.
+ */
+__attribute__( ( always_inline ) ) static __INLINE void __disable_fault_irq(void)
+{
+ __ASM volatile ("cpsid f");
+}
+
+
+/** \brief Get Base Priority
+
+ This function returns the current value of the Base Priority register.
+
+ \return Base Priority register value
+ */
+__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_BASEPRI(void)
+{
+ uint32_t result;
+
+ __ASM volatile ("MRS %0, basepri_max" : "=r" (result) );
+ return(result);
+}
+
+
+/** \brief Set Base Priority
+
+ This function assigns the given value to the Base Priority register.
+
+ \param [in] basePri Base Priority value to set
+ */
+__attribute__( ( always_inline ) ) static __INLINE void __set_BASEPRI(uint32_t value)
+{
+ __ASM volatile ("MSR basepri, %0" : : "r" (value) );
+}
+
+
+/** \brief Get Fault Mask
+
+ This function returns the current value of the Fault Mask register.
+
+ \return Fault Mask register value
+ */
+__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_FAULTMASK(void)
+{
+ uint32_t result;
+
+ __ASM volatile ("MRS %0, faultmask" : "=r" (result) );
+ return(result);
+}
+
+
+/** \brief Set Fault Mask
+
+ This function assigns the given value to the Fault Mask register.
+
+ \param [in] faultMask Fault Mask value to set
+ */
+__attribute__( ( always_inline ) ) static __INLINE void __set_FAULTMASK(uint32_t faultMask)
+{
+ __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) );
+}
+
+#endif /* (__CORTEX_M >= 0x03) */
+
+
+#if (__CORTEX_M == 0x04)
+
+/** \brief Get FPSCR
+
+ This function returns the current value of the Floating Point Status/Control register.
+
+ \return Floating Point Status/Control register value
+ */
+__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_FPSCR(void)
+{
+#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
+ uint32_t result;
+
+ __ASM volatile ("VMRS %0, fpscr" : "=r" (result) );
+ return(result);
+#else
+ return(0);
+#endif
+}
+
+
+/** \brief Set FPSCR
+
+ This function assigns the given value to the Floating Point Status/Control register.
+
+ \param [in] fpscr Floating Point Status/Control value to set
+ */
+__attribute__( ( always_inline ) ) static __INLINE void __set_FPSCR(uint32_t fpscr)
+{
+#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
+ __ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) );
+#endif
+}
+
+#endif /* (__CORTEX_M == 0x04) */
+
+
+#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/
+/* TASKING carm specific functions */
+
+/*
+ * The CMSIS functions have been implemented as intrinsics in the compiler.
+ * Please use "carm -?i" to get an up to date list of all instrinsics,
+ * Including the CMSIS ones.
+ */
+
+#endif
+
+/*@} end of CMSIS_Core_RegAccFunctions */
+
+
+#endif /* __CORE_CMFUNC_H */
diff --git a/platform/mcu/CMSIS/Include/core_cmInstr.h b/platform/mcu/CMSIS/Include/core_cmInstr.h
new file mode 100644
index 00000000..ceb4f875
--- /dev/null
+++ b/platform/mcu/CMSIS/Include/core_cmInstr.h
@@ -0,0 +1,585 @@
+/**************************************************************************//**
+ * @file core_cmInstr.h
+ * @brief CMSIS Cortex-M Core Instruction Access Header File
+ * @version V2.10
+ * @date 19. July 2011
+ *
+ * @note
+ * Copyright (C) 2009-2011 ARM Limited. All rights reserved.
+ *
+ * @par
+ * ARM Limited (ARM) is supplying this software for use with Cortex-M
+ * processor based microcontrollers. This file can be freely distributed
+ * within development tools that are supporting such ARM based processors.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
+ * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
+ * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
+ * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
+ *
+ ******************************************************************************/
+
+#ifndef __CORE_CMINSTR_H
+#define __CORE_CMINSTR_H
+
+
+/* ########################## Core Instruction Access ######################### */
+/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface
+ Access to dedicated instructions
+ @{
+*/
+
+#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/
+/* ARM armcc specific functions */
+
+#if (__ARMCC_VERSION < 400677)
+ #error "Please use ARM Compiler Toolchain V4.0.677 or later!"
+#endif
+
+
+/** \brief No Operation
+
+ No Operation does nothing. This instruction can be used for code alignment purposes.
+ */
+#define __NOP __nop
+
+
+/** \brief Wait For Interrupt
+
+ Wait For Interrupt is a hint instruction that suspends execution
+ until one of a number of events occurs.
+ */
+#define __WFI __wfi
+
+
+/** \brief Wait For Event
+
+ Wait For Event is a hint instruction that permits the processor to enter
+ a low-power state until one of a number of events occurs.
+ */
+#define __WFE __wfe
+
+
+/** \brief Send Event
+
+ Send Event is a hint instruction. It causes an event to be signaled to the CPU.
+ */
+#define __SEV __sev
+
+
+/** \brief Instruction Synchronization Barrier
+
+ Instruction Synchronization Barrier flushes the pipeline in the processor,
+ so that all instructions following the ISB are fetched from cache or
+ memory, after the instruction has been completed.
+ */
+#define __ISB() __isb(0xF)
+
+
+/** \brief Data Synchronization Barrier
+
+ This function acts as a special kind of Data Memory Barrier.
+ It completes when all explicit memory accesses before this instruction complete.
+ */
+#define __DSB() __dsb(0xF)
+
+
+/** \brief Data Memory Barrier
+
+ This function ensures the apparent order of the explicit memory operations before
+ and after the instruction, without ensuring their completion.
+ */
+#define __DMB() __dmb(0xF)
+
+
+/** \brief Reverse byte order (32 bit)
+
+ This function reverses the byte order in integer value.
+
+ \param [in] value Value to reverse
+ \return Reversed value
+ */
+#define __REV __rev
+
+
+/** \brief Reverse byte order (16 bit)
+
+ This function reverses the byte order in two unsigned short values.
+
+ \param [in] value Value to reverse
+ \return Reversed value
+ */
+static __INLINE __ASM uint32_t __REV16(uint32_t value)
+{
+ rev16 r0, r0
+ bx lr
+}
+
+
+/** \brief Reverse byte order in signed short value
+
+ This function reverses the byte order in a signed short value with sign extension to integer.
+
+ \param [in] value Value to reverse
+ \return Reversed value
+ */
+static __INLINE __ASM int32_t __REVSH(int32_t value)
+{
+ revsh r0, r0
+ bx lr
+}
+
+
+#if (__CORTEX_M >= 0x03)
+
+/** \brief Reverse bit order of value
+
+ This function reverses the bit order of the given value.
+
+ \param [in] value Value to reverse
+ \return Reversed value
+ */
+#define __RBIT __rbit
+
+
+/** \brief LDR Exclusive (8 bit)
+
+ This function performs a exclusive LDR command for 8 bit value.
+
+ \param [in] ptr Pointer to data
+ \return value of type uint8_t at (*ptr)
+ */
+#define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr))
+
+
+/** \brief LDR Exclusive (16 bit)
+
+ This function performs a exclusive LDR command for 16 bit values.
+
+ \param [in] ptr Pointer to data
+ \return value of type uint16_t at (*ptr)
+ */
+#define __LDREXH(ptr) ((uint16_t) __ldrex(ptr))
+
+
+/** \brief LDR Exclusive (32 bit)
+
+ This function performs a exclusive LDR command for 32 bit values.
+
+ \param [in] ptr Pointer to data
+ \return value of type uint32_t at (*ptr)
+ */
+#define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr))
+
+
+/** \brief STR Exclusive (8 bit)
+
+ This function performs a exclusive STR command for 8 bit values.
+
+ \param [in] value Value to store
+ \param [in] ptr Pointer to location
+ \return 0 Function succeeded
+ \return 1 Function failed
+ */
+#define __STREXB(value, ptr) __strex(value, ptr)
+
+
+/** \brief STR Exclusive (16 bit)
+
+ This function performs a exclusive STR command for 16 bit values.
+
+ \param [in] value Value to store
+ \param [in] ptr Pointer to location
+ \return 0 Function succeeded
+ \return 1 Function failed
+ */
+#define __STREXH(value, ptr) __strex(value, ptr)
+
+
+/** \brief STR Exclusive (32 bit)
+
+ This function performs a exclusive STR command for 32 bit values.
+
+ \param [in] value Value to store
+ \param [in] ptr Pointer to location
+ \return 0 Function succeeded
+ \return 1 Function failed
+ */
+#define __STREXW(value, ptr) __strex(value, ptr)
+
+
+/** \brief Remove the exclusive lock
+
+ This function removes the exclusive lock which is created by LDREX.
+
+ */
+#define __CLREX __clrex
+
+
+/** \brief Signed Saturate
+
+ This function saturates a signed value.
+
+ \param [in] value Value to be saturated
+ \param [in] sat Bit position to saturate to (1..32)
+ \return Saturated value
+ */
+#define __SSAT __ssat
+
+
+/** \brief Unsigned Saturate
+
+ This function saturates an unsigned value.
+
+ \param [in] value Value to be saturated
+ \param [in] sat Bit position to saturate to (0..31)
+ \return Saturated value
+ */
+#define __USAT __usat
+
+
+/** \brief Count leading zeros
+
+ This function counts the number of leading zeros of a data value.
+
+ \param [in] value Value to count the leading zeros
+ \return number of leading zeros in value
+ */
+#define __CLZ __clz
+
+#endif /* (__CORTEX_M >= 0x03) */
+
+
+
+#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/
+/* IAR iccarm specific functions */
+
+#include
+
+
+#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/
+/* GNU gcc specific functions */
+
+/** \brief No Operation
+
+ No Operation does nothing. This instruction can be used for code alignment purposes.
+ */
+__attribute__( ( always_inline ) ) static __INLINE void __NOP(void)
+{
+ __ASM volatile ("nop");
+}
+
+
+/** \brief Wait For Interrupt
+
+ Wait For Interrupt is a hint instruction that suspends execution
+ until one of a number of events occurs.
+ */
+__attribute__( ( always_inline ) ) static __INLINE void __WFI(void)
+{
+ __ASM volatile ("wfi");
+}
+
+
+/** \brief Wait For Event
+
+ Wait For Event is a hint instruction that permits the processor to enter
+ a low-power state until one of a number of events occurs.
+ */
+__attribute__( ( always_inline ) ) static __INLINE void __WFE(void)
+{
+ __ASM volatile ("wfe");
+}
+
+
+/** \brief Send Event
+
+ Send Event is a hint instruction. It causes an event to be signaled to the CPU.
+ */
+__attribute__( ( always_inline ) ) static __INLINE void __SEV(void)
+{
+ __ASM volatile ("sev");
+}
+
+
+/** \brief Instruction Synchronization Barrier
+
+ Instruction Synchronization Barrier flushes the pipeline in the processor,
+ so that all instructions following the ISB are fetched from cache or
+ memory, after the instruction has been completed.
+ */
+__attribute__( ( always_inline ) ) static __INLINE void __ISB(void)
+{
+ __ASM volatile ("isb");
+}
+
+
+/** \brief Data Synchronization Barrier
+
+ This function acts as a special kind of Data Memory Barrier.
+ It completes when all explicit memory accesses before this instruction complete.
+ */
+__attribute__( ( always_inline ) ) static __INLINE void __DSB(void)
+{
+ __ASM volatile ("dsb");
+}
+
+
+/** \brief Data Memory Barrier
+
+ This function ensures the apparent order of the explicit memory operations before
+ and after the instruction, without ensuring their completion.
+ */
+__attribute__( ( always_inline ) ) static __INLINE void __DMB(void)
+{
+ __ASM volatile ("dmb");
+}
+
+
+/** \brief Reverse byte order (32 bit)
+
+ This function reverses the byte order in integer value.
+
+ \param [in] value Value to reverse
+ \return Reversed value
+ */
+__attribute__( ( always_inline ) ) static __INLINE uint32_t __REV(uint32_t value)
+{
+ uint32_t result;
+
+ __ASM volatile ("rev %0, %1" : "=r" (result) : "r" (value) );
+ return(result);
+}
+
+
+/** \brief Reverse byte order (16 bit)
+
+ This function reverses the byte order in two unsigned short values.
+
+ \param [in] value Value to reverse
+ \return Reversed value
+ */
+__attribute__( ( always_inline ) ) static __INLINE uint32_t __REV16(uint32_t value)
+{
+ uint32_t result;
+
+ __ASM volatile ("rev16 %0, %1" : "=r" (result) : "r" (value) );
+ return(result);
+}
+
+
+/** \brief Reverse byte order in signed short value
+
+ This function reverses the byte order in a signed short value with sign extension to integer.
+
+ \param [in] value Value to reverse
+ \return Reversed value
+ */
+__attribute__( ( always_inline ) ) static __INLINE int32_t __REVSH(int32_t value)
+{
+ uint32_t result;
+
+ __ASM volatile ("revsh %0, %1" : "=r" (result) : "r" (value) );
+ return(result);
+}
+
+
+#if (__CORTEX_M >= 0x03)
+
+/** \brief Reverse bit order of value
+
+ This function reverses the bit order of the given value.
+
+ \param [in] value Value to reverse
+ \return Reversed value
+ */
+__attribute__( ( always_inline ) ) static __INLINE uint32_t __RBIT(uint32_t value)
+{
+ uint32_t result;
+
+ __ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) );
+ return(result);
+}
+
+
+/** \brief LDR Exclusive (8 bit)
+
+ This function performs a exclusive LDR command for 8 bit value.
+
+ \param [in] ptr Pointer to data
+ \return value of type uint8_t at (*ptr)
+ */
+__attribute__( ( always_inline ) ) static __INLINE uint8_t __LDREXB(volatile uint8_t *addr)
+{
+ uint8_t result;
+
+ __ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) );
+ return(result);
+}
+
+
+/** \brief LDR Exclusive (16 bit)
+
+ This function performs a exclusive LDR command for 16 bit values.
+
+ \param [in] ptr Pointer to data
+ \return value of type uint16_t at (*ptr)
+ */
+__attribute__( ( always_inline ) ) static __INLINE uint16_t __LDREXH(volatile uint16_t *addr)
+{
+ uint16_t result;
+
+ __ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) );
+ return(result);
+}
+
+
+/** \brief LDR Exclusive (32 bit)
+
+ This function performs a exclusive LDR command for 32 bit values.
+
+ \param [in] ptr Pointer to data
+ \return value of type uint32_t at (*ptr)
+ */
+__attribute__( ( always_inline ) ) static __INLINE uint32_t __LDREXW(volatile uint32_t *addr)
+{
+ uint32_t result;
+
+ __ASM volatile ("ldrex %0, [%1]" : "=r" (result) : "r" (addr) );
+ return(result);
+}
+
+
+/** \brief STR Exclusive (8 bit)
+
+ This function performs a exclusive STR command for 8 bit values.
+
+ \param [in] value Value to store
+ \param [in] ptr Pointer to location
+ \return 0 Function succeeded
+ \return 1 Function failed
+ */
+__attribute__( ( always_inline ) ) static __INLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr)
+{
+ uint32_t result;
+
+ __ASM volatile ("strexb %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) );
+ return(result);
+}
+
+
+/** \brief STR Exclusive (16 bit)
+
+ This function performs a exclusive STR command for 16 bit values.
+
+ \param [in] value Value to store
+ \param [in] ptr Pointer to location
+ \return 0 Function succeeded
+ \return 1 Function failed
+ */
+__attribute__( ( always_inline ) ) static __INLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr)
+{
+ uint32_t result;
+
+ __ASM volatile ("strexh %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) );
+ return(result);
+}
+
+
+/** \brief STR Exclusive (32 bit)
+
+ This function performs a exclusive STR command for 32 bit values.
+
+ \param [in] value Value to store
+ \param [in] ptr Pointer to location
+ \return 0 Function succeeded
+ \return 1 Function failed
+ */
+__attribute__( ( always_inline ) ) static __INLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr)
+{
+ uint32_t result;
+
+ __ASM volatile ("strex %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) );
+ return(result);
+}
+
+
+/** \brief Remove the exclusive lock
+
+ This function removes the exclusive lock which is created by LDREX.
+
+ */
+__attribute__( ( always_inline ) ) static __INLINE void __CLREX(void)
+{
+ __ASM volatile ("clrex");
+}
+
+
+/** \brief Signed Saturate
+
+ This function saturates a signed value.
+
+ \param [in] value Value to be saturated
+ \param [in] sat Bit position to saturate to (1..32)
+ \return Saturated value
+ */
+#define __SSAT(ARG1,ARG2) \
+({ \
+ uint32_t __RES, __ARG1 = (ARG1); \
+ __ASM ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
+ __RES; \
+ })
+
+
+/** \brief Unsigned Saturate
+
+ This function saturates an unsigned value.
+
+ \param [in] value Value to be saturated
+ \param [in] sat Bit position to saturate to (0..31)
+ \return Saturated value
+ */
+#define __USAT(ARG1,ARG2) \
+({ \
+ uint32_t __RES, __ARG1 = (ARG1); \
+ __ASM ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
+ __RES; \
+ })
+
+
+/** \brief Count leading zeros
+
+ This function counts the number of leading zeros of a data value.
+
+ \param [in] value Value to count the leading zeros
+ \return number of leading zeros in value
+ */
+__attribute__( ( always_inline ) ) static __INLINE uint8_t __CLZ(uint32_t value)
+{
+ uint8_t result;
+
+ __ASM volatile ("clz %0, %1" : "=r" (result) : "r" (value) );
+ return(result);
+}
+
+#endif /* (__CORTEX_M >= 0x03) */
+
+
+
+
+#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/
+/* TASKING carm specific functions */
+
+/*
+ * The CMSIS functions have been implemented as intrinsics in the compiler.
+ * Please use "carm -?i" to get an up to date list of all intrinsics,
+ * Including the CMSIS ones.
+ */
+
+#endif
+
+/*@}*/ /* end of group CMSIS_Core_InstructionInterface */
+
+#endif /* __CORE_CMINSTR_H */
diff --git a/platform/mcu/CMSIS/Include/irq.h b/platform/mcu/CMSIS/Include/irq.h
new file mode 100644
index 00000000..0239c967
--- /dev/null
+++ b/platform/mcu/CMSIS/Include/irq.h
@@ -0,0 +1,121 @@
+/*
+ * sys/irq.h --- STM32F4 IRQ numbers.
+ *
+ * Copyright (C) 2012, Galois, Inc.
+ * All Rights Reserved.
+ *
+ * This software is released under the "BSD3" license. Read the file
+ * "LICENSE" for more information.
+ */
+
+#ifndef __hwfr_sys_irq_h
+#define __hwfr_sys_irq_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * IRQ Definition
+ */
+enum IRQn {
+/****** Cortex-M4 Processor Exceptions Numbers * *****************************/
+ NonMaskableInt_IRQn = -14, // Non Maskable Interrupt
+ MemoryManagement_IRQn = -12, // Cortex-M4 Memory Management Interrupt
+ BusFault_IRQn = -11, // Cortex-M4 Bus Fault Interrupt
+ UsageFault_IRQn = -10, // Cortex-M4 Usage Fault Interrupt
+ SVCall_IRQn = -5, // Cortex-M4 SV Call Interrupt
+ DebugMonitor_IRQn = -4, // Cortex-M4 Debug Monitor Interrupt
+ PendSV_IRQn = -2, // Cortex-M4 Pend SV Interrupt
+ SysTick_IRQn = -1, // Cortex-M4 System Tick Interrupt
+
+/****** STM32 specific Interrupt Numbers *************************************/
+ WWDG_IRQn = 0, // Window WatchDog Interrupt
+ PVD_IRQn = 1, // PVD through EXTI Line detection Interrupt
+ TAMP_STAMP_IRQn = 2, // Tamper and TimeStamp interrupts through the EXTI line
+ RTC_WKUP_IRQn = 3, // RTC Wakeup interrupt through the EXTI line
+ FLASH_IRQn = 4, // FLASH global Interrupt
+ RCC_IRQn = 5, // RCC global Interrupt
+ EXTI0_IRQn = 6, // EXTI Line0 Interrupt
+ EXTI1_IRQn = 7, // EXTI Line1 Interrupt
+ EXTI2_IRQn = 8, // EXTI Line2 Interrupt
+ EXTI3_IRQn = 9, // EXTI Line3 Interrupt
+ EXTI4_IRQn = 10, // EXTI Line4 Interrupt
+ DMA1_Stream0_IRQn = 11, // DMA1 Stream 0 global Interrupt
+ DMA1_Stream1_IRQn = 12, // DMA1 Stream 1 global Interrupt
+ DMA1_Stream2_IRQn = 13, // DMA1 Stream 2 global Interrupt
+ DMA1_Stream3_IRQn = 14, // DMA1 Stream 3 global Interrupt
+ DMA1_Stream4_IRQn = 15, // DMA1 Stream 4 global Interrupt
+ DMA1_Stream5_IRQn = 16, // DMA1 Stream 5 global Interrupt
+ DMA1_Stream6_IRQn = 17, // DMA1 Stream 6 global Interrupt
+ ADC_IRQn = 18, // ADC1, ADC2 and ADC3 global Interrupts
+ CAN1_TX_IRQn = 19, // CAN1 TX Interrupt
+ CAN1_RX0_IRQn = 20, // CAN1 RX0 Interrupt
+ CAN1_RX1_IRQn = 21, // CAN1 RX1 Interrupt
+ CAN1_SCE_IRQn = 22, // CAN1 SCE Interrupt
+ EXTI9_5_IRQn = 23, // External Line[9:5] Interrupts
+ TIM1_BRK_TIM9_IRQn = 24, // TIM1 Break interrupt and TIM9 global interrupt
+ TIM1_UP_TIM10_IRQn = 25, // TIM1 Update Interrupt and TIM10 global interrupt
+ TIM1_TRG_COM_TIM11_IRQn = 26, // TIM1 Trigger and Commutation Interrupt and TIM11 global interrupt
+ TIM1_CC_IRQn = 27, // TIM1 Capture Compare Interrupt
+ TIM2_IRQn = 28, // TIM2 global Interrupt
+ TIM3_IRQn = 29, // TIM3 global Interrupt
+ TIM4_IRQn = 30, // TIM4 global Interrupt
+ I2C1_EV_IRQn = 31, // I2C1 Event Interrupt
+ I2C1_ER_IRQn = 32, // I2C1 Error Interrupt
+ I2C2_EV_IRQn = 33, // I2C2 Event Interrupt
+ I2C2_ER_IRQn = 34, // I2C2 Error Interrupt
+ SPI1_IRQn = 35, // SPI1 global Interrupt
+ SPI2_IRQn = 36, // SPI2 global Interrupt
+ USART1_IRQn = 37, // USART1 global Interrupt
+ USART2_IRQn = 38, // USART2 global Interrupt
+ USART3_IRQn = 39, // USART3 global Interrupt
+ EXTI15_10_IRQn = 40, // External Line[15:10] Interrupts
+ RTC_Alarm_IRQn = 41, // RTC Alarm (A and B) through EXTI Line Interrupt
+ OTG_FS_WKUP_IRQn = 42, // USB OTG FS Wakeup through EXTI line interrupt
+ TIM8_BRK_TIM12_IRQn = 43, // TIM8 Break Interrupt and TIM12 global interrupt
+ TIM8_UP_TIM13_IRQn = 44, // TIM8 Update Interrupt and TIM13 global interrupt
+ TIM8_TRG_COM_TIM14_IRQn = 45, // TIM8 Trigger and Commutation Interrupt and TIM14 global interrupt
+ TIM8_CC_IRQn = 46, // TIM8 Capture Compare Interrupt
+ DMA1_Stream7_IRQn = 47, // DMA1 Stream7 Interrupt
+ FSMC_IRQn = 48, // FSMC global Interrupt
+ SDIO_IRQn = 49, // SDIO global Interrupt
+ TIM5_IRQn = 50, // TIM5 global Interrupt
+ SPI3_IRQn = 51, // SPI3 global Interrupt
+ UART4_IRQn = 52, // UART4 global Interrupt
+ UART5_IRQn = 53, // UART5 global Interrupt
+ TIM6_DAC_IRQn = 54, // TIM6 global and DAC1&2 underrun error interrupts
+ TIM7_IRQn = 55, // TIM7 global interrupt
+ DMA2_Stream0_IRQn = 56, // DMA2 Stream 0 global Interrupt
+ DMA2_Stream1_IRQn = 57, // DMA2 Stream 1 global Interrupt
+ DMA2_Stream2_IRQn = 58, // DMA2 Stream 2 global Interrupt
+ DMA2_Stream3_IRQn = 59, // DMA2 Stream 3 global Interrupt
+ DMA2_Stream4_IRQn = 60, // DMA2 Stream 4 global Interrupt
+ ETH_IRQn = 61, // Ethernet global Interrupt
+ ETH_WKUP_IRQn = 62, // Ethernet Wakeup through EXTI line Interrupt
+ CAN2_TX_IRQn = 63, // CAN2 TX Interrupt
+ CAN2_RX0_IRQn = 64, // CAN2 RX0 Interrupt
+ CAN2_RX1_IRQn = 65, // CAN2 RX1 Interrupt
+ CAN2_SCE_IRQn = 66, // CAN2 SCE Interrupt
+ OTG_FS_IRQn = 67, // USB OTG FS global Interrupt
+ DMA2_Stream5_IRQn = 68, // DMA2 Stream 5 global interrupt
+ DMA2_Stream6_IRQn = 69, // DMA2 Stream 6 global interrupt
+ DMA2_Stream7_IRQn = 70, // DMA2 Stream 7 global interrupt
+ USART6_IRQn = 71, // USART6 global interrupt
+ I2C3_EV_IRQn = 72, // I2C3 event interrupt
+ I2C3_ER_IRQn = 73, // I2C3 error interrupt
+ OTG_HS_EP1_OUT_IRQn = 74, // USB OTG HS End Point 1 Out global interrupt
+ OTG_HS_EP1_IN_IRQn = 75, // USB OTG HS End Point 1 In global interrupt
+ OTG_HS_WKUP_IRQn = 76, // USB OTG HS Wakeup through EXTI interrupt
+ OTG_HS_IRQn = 77, // USB OTG HS global interrupt
+ DCMI_IRQn = 78, // DCMI global interrupt
+ CRYP_IRQn = 79, // CRYP crypto global interrupt
+ HASH_RNG_IRQn = 80, // Hash and Rng global interrupt
+ FPU_IRQn = 81 // FPU global interrupt
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __hwfr_sys_irq_h */
diff --git a/platform/mcu/STM32F4xx/boot/libc_integration.c b/platform/mcu/STM32F4xx/boot/libc_integration.c
new file mode 100644
index 00000000..d062daab
--- /dev/null
+++ b/platform/mcu/STM32F4xx/boot/libc_integration.c
@@ -0,0 +1,361 @@
+/***************************************************************************
+ * Copyright (C) 2020 by Silvano Seva IU2KWO *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 3 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, see *
+ ***************************************************************************/
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include "../drivers/usb_vcom.h"
+
+
+void pthread_mutex_unlock(){}
+void pthread_mutex_lock() {}
+void pthread_mutex_destroy() {}
+int pthread_setcancelstate(int state, int *oldstate)
+{
+ return 0;
+}
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//
+// C atexit support, for thread safety and code size optimizations
+// ===============================================================
+
+/**
+ * Function called by atexit(), on_exit() and __cxa_atexit() to register
+ * C functions/C++ destructors to be run at program termintion.
+ * It is called in this way:
+ * atexit(): __register_exitproc(__et_atexit, fn, 0, 0)
+ * on_exit(): __register_exitproc(__et_onexit, fn, arg, 0)
+ * __cxa_atexit(): __register_exitproc(__et_cxa, fn, arg, d)
+ * \param type to understand if the function was called by atexit, on_exit, ...
+ * \param fn pointer to function to be called
+ * \param arg 0 in case of atexit, function argument in case of on_exit,
+ * "this" parameter for C++ destructors registered with __cxa_atexit
+ * \param d __dso_handle used to selectively call C++ destructors of a shared
+ * library loaded dynamically, unused since Miosix does not support shared libs
+ * \return 0 on success
+ */
+int __register_exitproc(int type, void (*fn)(void), void *arg, void *d)
+{
+ return 0;
+}
+
+/**
+ * Called by exit() to call functions registered through atexit()
+ * \param code the exit code, for example with exit(1), code==1
+ * \param d __dso_handle, see __register_exitproc
+ */
+void __call_exitprocs(int code, void *d) {}
+
+/**
+ * \internal
+ * Required by C++ standard library.
+ * See http://lists.debian.org/debian-gcc/2003/07/msg00057.html
+ */
+void *__dso_handle=(void*) &__dso_handle;
+
+
+
+
+//
+// C/C++ system calls, to support malloc, printf, fopen, etc.
+// ==========================================================
+
+/**
+ * \internal
+ * _exit, lock system in infinite loop until reboot
+ */
+void _exit(int status)
+{
+ for(;;) ;
+}
+
+/**
+ * \internal
+ * _sbrk_r, allocates memory dynamically
+ */
+void *_sbrk_r(struct _reent *ptr, ptrdiff_t incr)
+{
+ //This is the absolute start of the heap
+ extern char _end asm("_end"); //defined in the linker script
+ //This is the absolute end of the heap
+ extern char _heap_end asm("_heap_end"); //defined in the linker script
+ //This holds the current end of the heap (static)
+ static char *curHeapEnd=NULL;
+ //This holds the previous end of the heap
+ char *prevHeapEnd;
+
+ //Check if it's first time called
+ if(curHeapEnd==NULL) curHeapEnd=&_end;
+
+ prevHeapEnd=curHeapEnd;
+
+ if((curHeapEnd+incr)>&_heap_end)
+ {
+ return (void*)(-1);
+ }
+ curHeapEnd+=incr;
+
+ return (void*)(prevHeapEnd);
+}
+
+/**
+ * \internal
+ * __malloc_lock, called by malloc to ensure no context switch happens during
+ * memory allocation. Since this environment is not a multithreaded one, this
+ * function is left empty. Allocating memory inside interrupts is anyway
+ * forbidden.
+ */
+void __malloc_lock() {}
+
+/**
+ * \internal
+ * __malloc_unlock, called by malloc after performing operations on the heap
+ */
+void __malloc_unlock() {}
+
+/**
+ * \internal
+ * __getreent(), return the reentrancy structure of the current thread.
+ * Used by newlib to make the C standard library thread safe.
+ * Not a multithreaded environment, we return global reentrancy data.
+ */
+struct _reent *__getreent()
+{
+ return _GLOBAL_REENT;
+}
+
+
+
+
+/**
+ * \internal
+ * _open_r, open a file. Actually unimpemented
+ */
+int _open_r(struct _reent *ptr, const char *name, int flags, int mode)
+{
+ return -1;
+}
+
+/**
+ * \internal
+ * _close_r, close a file. Actually unimpemented
+ */
+int _close_r(struct _reent *ptr, int fd)
+{
+ return -1;
+}
+
+/**
+ * \internal
+ * _write_r, write to a file.
+ */
+int _write_r(struct _reent *ptr, int fd, const void *buf, size_t cnt)
+{
+ if(fd == STDOUT_FILENO || fd == STDERR_FILENO)
+ {
+ vcom_writeBlock(buf, cnt);
+ return cnt;
+ }
+
+ /* If fd is not stdout or stderr */
+ ptr->_errno = EBADF;
+ return -1;
+}
+
+/**
+ * \internal
+ * _read_r, read from a file.
+ */
+int _read_r(struct _reent *ptr, int fd, void *buf, size_t cnt)
+{
+ if(fd == STDIN_FILENO)
+ {
+ for(;;)
+ {
+ ssize_t r = vcom_readBlock(buf, cnt);
+ if((r < 0) || (r == cnt)) return r;
+ }
+ }
+ else
+
+ /* If fd is not stdin */
+ ptr->_errno = EBADF;
+ return -1;
+}
+
+int _read(int fd, void *buf, size_t cnt)
+{
+ return _read_r(__getreent(), fd, buf, cnt);
+}
+
+/**
+ * \internal
+ * _lseek_r, move file pointer. Actually unimpemented
+ */
+off_t _lseek_r(struct _reent *ptr, int fd, off_t pos, int whence)
+{
+ return -1;
+}
+
+off_t _lseek(int fd, off_t pos, int whence)
+{
+ return -1;
+}
+
+/**
+ * \internal
+ * _fstat_r, return file info. Actually unimpemented
+ */
+int _fstat_r(struct _reent *ptr, int fd, struct stat *pstat)
+{
+ return -1;
+}
+
+int _fstat(int fd, struct stat *pstat)
+{
+ return -1;
+}
+
+/**
+ * \internal
+ * _stat_r, collect data about a file. Actually unimpemented
+ */
+int _stat_r(struct _reent *ptr, const char *file, struct stat *pstat)
+{
+ return -1;
+}
+
+/**
+ * \internal
+ * isatty, returns 1 if fd is associated with a terminal.
+ * Always return 1 because read and write are implemented only in
+ * terms of serial communication
+ */
+int _isatty_r(struct _reent *ptr, int fd)
+{
+ return 1;
+}
+
+int isatty(int fd)
+{
+ return 1;
+}
+
+int _isatty(int fd)
+{
+ return 1;
+}
+
+/**
+ * \internal
+ * _mkdir, create a directory. Actually unimpemented
+ */
+int mkdir(const char *path, mode_t mode)
+{
+ return -1;
+}
+
+/**
+ * \internal
+ * _link_r: create hardlinks. Actually unimpemented
+ */
+int _link_r(struct _reent *ptr, const char *f_old, const char *f_new)
+{
+ return -1;
+}
+
+/**
+ * \internal
+ * _unlink_r, remove a file. Actually unimpemented
+ */
+int _unlink_r(struct _reent *ptr, const char *file)
+{
+ return -1;
+}
+
+/**
+ * \internal
+ * _times_r, return elapsed time. Actually unimpemented
+ */
+clock_t _times_r(struct _reent *ptr, struct tms *tim)
+{
+ return -1;
+}
+
+
+
+
+
+/**
+ * \internal
+ * it looks like abort() calls _kill instead of exit, this implementation
+ * calls _exit() so that calling abort() really terminates the program
+ */
+int _kill_r(struct _reent* ptr, int pid, int sig)
+{
+ if(pid == 0)
+ _exit(1);
+ else
+ return -1;
+}
+
+int _kill(int pid, int sig)
+{
+ _kill_r(0, pid, sig);
+}
+
+/**
+ * \internal
+ * _getpid_r. Not a multiprocess system, return always 0
+ */
+int _getpid_r(struct _reent* ptr)
+{
+ return 0;
+}
+
+int _getpid()
+{
+ return 0;
+}
+
+/**
+ * \internal
+ * _wait_r, unimpemented because processes are not supported.
+ */
+int _wait_r(struct _reent *ptr, int *status)
+{
+ return -1;
+}
+
+int _fork_r(struct _reent *ptr)
+{
+ return -1;
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/platform/mcu/STM32F4xx/boot/startup.c b/platform/mcu/STM32F4xx/boot/startup.c
new file mode 100644
index 00000000..8565214a
--- /dev/null
+++ b/platform/mcu/STM32F4xx/boot/startup.c
@@ -0,0 +1,393 @@
+/***************************************************************************
+ * Copyright (C) 2020 by Silvano Seva IU2KWO *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 3 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, see *
+ ***************************************************************************/
+
+
+#include
+#include
+#include "stm32f4xx.h"
+#include "../drivers/usb_vcom.h"
+
+///< Entry point for application code
+int main(int argc, char *argv[]);
+
+void Reset_Handler() __attribute__((__interrupt__, noreturn));
+void Reset_Handler()
+{
+ __disable_irq();
+
+ // Call CMSIS init function, it's safe to do it here.
+ // This function initialises VTOR, clock-tree and flash memory wait states.
+ // System clock frequency is 168MHz.
+ SystemInit();
+
+ //These are defined in the linker script
+ extern unsigned char _etext asm("_etext");
+ extern unsigned char _data asm("_data");
+ extern unsigned char _edata asm("_edata");
+ extern unsigned char _bss_start asm("_bss_start");
+ extern unsigned char _bss_end asm("_bss_end");
+
+ // Initialize .data section, clear .bss section
+ unsigned char *etext=&_etext;
+ unsigned char *data=&_data;
+ unsigned char *edata=&_edata;
+ unsigned char *bss_start=&_bss_start;
+ unsigned char *bss_end=&_bss_end;
+
+ memcpy(data, etext, edata-data);
+ memset(bss_start, 0, bss_end-bss_start);
+
+ __enable_irq();
+
+ // General system configurations: enabling all GPIO ports.
+ RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN
+ | RCC_AHB1ENR_GPIOBEN
+ | RCC_AHB1ENR_GPIOCEN
+ | RCC_AHB1ENR_GPIODEN
+ | RCC_AHB1ENR_GPIOEEN;
+
+ // Configure all GPIO pins to fast speed mode (50MHz)
+ GPIOA->OSPEEDR = 0xAAAAAAAA;
+ GPIOB->OSPEEDR = 0xAAAAAAAA;
+ GPIOC->OSPEEDR = 0xAAAAAAAA;
+ GPIOD->OSPEEDR = 0xAAAAAAAA;
+ GPIOE->OSPEEDR = 0xAAAAAAAA;
+
+ // Enable SWD interface on PA13 and PA14 (Tytera's bootloader disables this
+ // functionality).
+ // NOTE: these pins are used also for other functions (MIC power and wide/
+ // narrow FM reception), thus they cannot be always used for debugging!
+ #ifdef ENABLE_SWD
+ GPIOA->MODER &= ~0x3C000000; // Clear current setting
+ GPIOA->MODER |= 0x28000000; // Put back to alternate function
+ GPIOA->AFR[1] &= ~0x0FF00000; // SWD is AF0
+ #endif
+
+ // Enable virtual com port (for stdin, stdout and stderr redirection)
+ vcom_init();
+
+ // Set no buffer for stdin, required to make scanf, getchar, ... working
+ // correctly
+ setvbuf(stdin, NULL, _IONBF, 0);
+
+
+ // Jump to application code
+ main(0, NULL);
+
+ // If main returns loop indefinitely
+ for(;;) ;
+}
+
+void Default_Handler()
+{
+ // default handler does nothing
+}
+
+void __attribute__((weak)) NMI_Handler();
+void __attribute__((weak)) HardFault_Handler();
+void __attribute__((weak)) MemManage_Handler();
+void __attribute__((weak)) BusFault_Handler();
+void __attribute__((weak)) UsageFault_Handler();
+void __attribute__((weak)) SVC_Handler();
+void __attribute__((weak)) DebugMon_Handler();
+void __attribute__((weak)) PendSV_Handler();
+void __attribute__((weak)) SysTick_Handler();
+
+void __attribute__((weak)) WWDG_IRQHandler();
+void __attribute__((weak)) PVD_IRQHandler();
+void __attribute__((weak)) TAMP_STAMP_IRQHandler();
+void __attribute__((weak)) RTC_WKUP_IRQHandler();
+void __attribute__((weak)) FLASH_IRQHandler();
+void __attribute__((weak)) RCC_IRQHandler();
+void __attribute__((weak)) EXTI0_IRQHandler();
+void __attribute__((weak)) EXTI1_IRQHandler();
+void __attribute__((weak)) EXTI2_IRQHandler();
+void __attribute__((weak)) EXTI3_IRQHandler();
+void __attribute__((weak)) EXTI4_IRQHandler();
+void __attribute__((weak)) DMA1_Stream0_IRQHandler();
+void __attribute__((weak)) DMA1_Stream1_IRQHandler();
+void __attribute__((weak)) DMA1_Stream2_IRQHandler();
+void __attribute__((weak)) DMA1_Stream3_IRQHandler();
+void __attribute__((weak)) DMA1_Stream4_IRQHandler();
+void __attribute__((weak)) DMA1_Stream5_IRQHandler();
+void __attribute__((weak)) DMA1_Stream6_IRQHandler();
+void __attribute__((weak)) ADC_IRQHandler();
+void __attribute__((weak)) CAN1_TX_IRQHandler();
+void __attribute__((weak)) CAN1_RX0_IRQHandler();
+void __attribute__((weak)) CAN1_RX1_IRQHandler();
+void __attribute__((weak)) CAN1_SCE_IRQHandler();
+void __attribute__((weak)) EXTI9_5_IRQHandler();
+void __attribute__((weak)) TIM1_BRK_TIM9_IRQHandler();
+void __attribute__((weak)) TIM1_UP_TIM10_IRQHandler();
+void __attribute__((weak)) TIM1_TRG_COM_TIM11_IRQHandler();
+void __attribute__((weak)) TIM1_CC_IRQHandler();
+void __attribute__((weak)) TIM2_IRQHandler();
+void __attribute__((weak)) TIM3_IRQHandler();
+void __attribute__((weak)) TIM4_IRQHandler();
+void __attribute__((weak)) I2C1_EV_IRQHandler();
+void __attribute__((weak)) I2C1_ER_IRQHandler();
+void __attribute__((weak)) I2C2_EV_IRQHandler();
+void __attribute__((weak)) I2C2_ER_IRQHandler();
+void __attribute__((weak)) SPI1_IRQHandler();
+void __attribute__((weak)) SPI2_IRQHandler();
+void __attribute__((weak)) USART1_IRQHandler();
+void __attribute__((weak)) USART2_IRQHandler();
+void __attribute__((weak)) USART3_IRQHandler();
+void __attribute__((weak)) EXTI15_10_IRQHandler();
+void __attribute__((weak)) RTC_Alarm_IRQHandler();
+void __attribute__((weak)) OTG_FS_WKUP_IRQHandler();
+void __attribute__((weak)) TIM8_BRK_TIM12_IRQHandler();
+void __attribute__((weak)) TIM8_UP_TIM13_IRQHandler();
+void __attribute__((weak)) TIM8_TRG_COM_TIM14_IRQHandler();
+void __attribute__((weak)) TIM8_CC_IRQHandler();
+void __attribute__((weak)) DMA1_Stream7_IRQHandler();
+void __attribute__((weak)) FSMC_IRQHandler();
+void __attribute__((weak)) SDIO_IRQHandler();
+void __attribute__((weak)) TIM5_IRQHandler();
+void __attribute__((weak)) SPI3_IRQHandler();
+void __attribute__((weak)) UART4_IRQHandler();
+void __attribute__((weak)) UART5_IRQHandler();
+void __attribute__((weak)) TIM6_DAC_IRQHandler();
+void __attribute__((weak)) TIM7_IRQHandler();
+void __attribute__((weak)) DMA2_Stream0_IRQHandler();
+void __attribute__((weak)) DMA2_Stream1_IRQHandler();
+void __attribute__((weak)) DMA2_Stream2_IRQHandler();
+void __attribute__((weak)) DMA2_Stream3_IRQHandler();
+void __attribute__((weak)) DMA2_Stream4_IRQHandler();
+void __attribute__((weak)) ETH_IRQHandler();
+void __attribute__((weak)) ETH_WKUP_IRQHandler();
+void __attribute__((weak)) CAN2_TX_IRQHandler();
+void __attribute__((weak)) CAN2_RX0_IRQHandler();
+void __attribute__((weak)) CAN2_RX1_IRQHandler();
+void __attribute__((weak)) CAN2_SCE_IRQHandler();
+void __attribute__((weak)) OTG_FS_IRQHandler();
+void __attribute__((weak)) DMA2_Stream5_IRQHandler();
+void __attribute__((weak)) DMA2_Stream6_IRQHandler();
+void __attribute__((weak)) DMA2_Stream7_IRQHandler();
+void __attribute__((weak)) USART6_IRQHandler();
+void __attribute__((weak)) I2C3_EV_IRQHandler();
+void __attribute__((weak)) I2C3_ER_IRQHandler();
+void __attribute__((weak)) OTG_HS_EP1_OUT_IRQHandler();
+void __attribute__((weak)) OTG_HS_EP1_IN_IRQHandler();
+void __attribute__((weak)) OTG_HS_WKUP_IRQHandler();
+void __attribute__((weak)) OTG_HS_IRQHandler();
+void __attribute__((weak)) DCMI_IRQHandler();
+void __attribute__((weak)) CRYP_IRQHandler();
+void __attribute__((weak)) HASH_RNG_IRQHandler();
+void __attribute__((weak)) FPU_IRQHandler();
+
+//Stack top, defined in the linker script
+extern char _stack_top asm("_stack_top");
+
+//Interrupt vectors, must be placed @ address 0x00000000
+//The extern declaration is required otherwise g++ optimizes it out
+extern void (* const __Vectors[])();
+void (* const __Vectors[])() __attribute__ ((section(".isr_vector"))) =
+{
+ (void (*)())(&_stack_top),
+ Reset_Handler,
+ NMI_Handler,
+ HardFault_Handler,
+ MemManage_Handler,
+ BusFault_Handler,
+ UsageFault_Handler,
+ 0,
+ 0,
+ 0,
+ 0,
+ SVC_Handler,
+ DebugMon_Handler,
+ 0,
+ PendSV_Handler,
+ SysTick_Handler,
+
+ WWDG_IRQHandler,
+ PVD_IRQHandler,
+ TAMP_STAMP_IRQHandler,
+ RTC_WKUP_IRQHandler,
+ FLASH_IRQHandler,
+ RCC_IRQHandler,
+ EXTI0_IRQHandler,
+ EXTI1_IRQHandler,
+ EXTI2_IRQHandler,
+ EXTI3_IRQHandler,
+ EXTI4_IRQHandler,
+ DMA1_Stream0_IRQHandler,
+ DMA1_Stream1_IRQHandler,
+ DMA1_Stream2_IRQHandler,
+ DMA1_Stream3_IRQHandler,
+ DMA1_Stream4_IRQHandler,
+ DMA1_Stream5_IRQHandler,
+ DMA1_Stream6_IRQHandler,
+ ADC_IRQHandler,
+ CAN1_TX_IRQHandler,
+ CAN1_RX0_IRQHandler,
+ CAN1_RX1_IRQHandler,
+ CAN1_SCE_IRQHandler,
+ EXTI9_5_IRQHandler,
+ TIM1_BRK_TIM9_IRQHandler,
+ TIM1_UP_TIM10_IRQHandler,
+ TIM1_TRG_COM_TIM11_IRQHandler,
+ TIM1_CC_IRQHandler,
+ TIM2_IRQHandler,
+ TIM3_IRQHandler,
+ TIM4_IRQHandler,
+ I2C1_EV_IRQHandler,
+ I2C1_ER_IRQHandler,
+ I2C2_EV_IRQHandler,
+ I2C2_ER_IRQHandler,
+ SPI1_IRQHandler,
+ SPI2_IRQHandler,
+ USART1_IRQHandler,
+ USART2_IRQHandler,
+ USART3_IRQHandler,
+ EXTI15_10_IRQHandler,
+ RTC_Alarm_IRQHandler,
+ OTG_FS_WKUP_IRQHandler,
+ TIM8_BRK_TIM12_IRQHandler,
+ TIM8_UP_TIM13_IRQHandler,
+ TIM8_TRG_COM_TIM14_IRQHandler,
+ TIM8_CC_IRQHandler,
+ DMA1_Stream7_IRQHandler,
+ FSMC_IRQHandler,
+ SDIO_IRQHandler,
+ TIM5_IRQHandler,
+ SPI3_IRQHandler,
+ UART4_IRQHandler,
+ UART5_IRQHandler,
+ TIM6_DAC_IRQHandler,
+ TIM7_IRQHandler,
+ DMA2_Stream0_IRQHandler,
+ DMA2_Stream1_IRQHandler,
+ DMA2_Stream2_IRQHandler,
+ DMA2_Stream3_IRQHandler,
+ DMA2_Stream4_IRQHandler,
+ ETH_IRQHandler,
+ ETH_WKUP_IRQHandler,
+ CAN2_TX_IRQHandler,
+ CAN2_RX0_IRQHandler,
+ CAN2_RX1_IRQHandler,
+ CAN2_SCE_IRQHandler,
+ OTG_FS_IRQHandler,
+ DMA2_Stream5_IRQHandler,
+ DMA2_Stream6_IRQHandler,
+ DMA2_Stream7_IRQHandler,
+ USART6_IRQHandler,
+ I2C3_EV_IRQHandler,
+ I2C3_ER_IRQHandler,
+ OTG_HS_EP1_OUT_IRQHandler,
+ OTG_HS_EP1_IN_IRQHandler,
+ OTG_HS_WKUP_IRQHandler,
+ OTG_HS_IRQHandler,
+ DCMI_IRQHandler,
+ CRYP_IRQHandler,
+ HASH_RNG_IRQHandler,
+ FPU_IRQHandler
+};
+
+#pragma weak NMI_Handler= Default_Handler
+#pragma weak HardFault_Handler= Default_Handler
+#pragma weak MemManage_Handler= Default_Handler
+#pragma weak BusFault_Handler= Default_Handler
+#pragma weak UsageFault_Handler= Default_Handler
+#pragma weak SVC_Handler= Default_Handler
+#pragma weak DebugMon_Handler= Default_Handler
+#pragma weak PendSV_Handler= Default_Handler
+#pragma weak SysTick_Handler= Default_Handler
+#pragma weak WWDG_IRQHandler= Default_Handler
+
+#pragma weak PVD_IRQHandler= Default_Handler
+#pragma weak TAMP_STAMP_IRQHandler= Default_Handler
+#pragma weak RTC_WKUP_IRQHandler= Default_Handler
+#pragma weak FLASH_IRQHandler= Default_Handler
+#pragma weak RCC_IRQHandler= Default_Handler
+#pragma weak EXTI0_IRQHandler= Default_Handler
+#pragma weak EXTI1_IRQHandler= Default_Handler
+#pragma weak EXTI2_IRQHandler= Default_Handler
+#pragma weak EXTI3_IRQHandler= Default_Handler
+#pragma weak EXTI4_IRQHandler= Default_Handler
+#pragma weak DMA1_Stream0_IRQHandler= Default_Handler
+#pragma weak DMA1_Stream1_IRQHandler= Default_Handler
+#pragma weak DMA1_Stream2_IRQHandler= Default_Handler
+#pragma weak DMA1_Stream3_IRQHandler= Default_Handler
+#pragma weak DMA1_Stream4_IRQHandler= Default_Handler
+#pragma weak DMA1_Stream5_IRQHandler= Default_Handler
+#pragma weak DMA1_Stream6_IRQHandler= Default_Handler
+#pragma weak ADC_IRQHandler= Default_Handler
+#pragma weak CAN1_TX_IRQHandler= Default_Handler
+#pragma weak CAN1_RX0_IRQHandler= Default_Handler
+#pragma weak CAN1_RX1_IRQHandler= Default_Handler
+#pragma weak CAN1_SCE_IRQHandler= Default_Handler
+#pragma weak EXTI9_5_IRQHandler= Default_Handler
+#pragma weak TIM1_BRK_TIM9_IRQHandler= Default_Handler
+#pragma weak TIM1_UP_TIM10_IRQHandler= Default_Handler
+#pragma weak TIM1_TRG_COM_TIM11_IRQHandler= Default_Handler
+#pragma weak TIM1_CC_IRQHandler= Default_Handler
+#pragma weak TIM2_IRQHandler= Default_Handler
+#pragma weak TIM3_IRQHandler= Default_Handler
+#pragma weak TIM4_IRQHandler= Default_Handler
+#pragma weak I2C1_EV_IRQHandler= Default_Handler
+#pragma weak I2C1_ER_IRQHandler= Default_Handler
+#pragma weak I2C2_EV_IRQHandler= Default_Handler
+#pragma weak I2C2_ER_IRQHandler= Default_Handler
+#pragma weak SPI1_IRQHandler= Default_Handler
+#pragma weak SPI2_IRQHandler= Default_Handler
+#pragma weak USART1_IRQHandler= Default_Handler
+#pragma weak USART2_IRQHandler= Default_Handler
+#pragma weak USART3_IRQHandler= Default_Handler
+#pragma weak EXTI15_10_IRQHandler= Default_Handler
+#pragma weak RTC_Alarm_IRQHandler= Default_Handler
+#pragma weak OTG_FS_WKUP_IRQHandler= Default_Handler
+#pragma weak TIM8_BRK_TIM12_IRQHandler= Default_Handler
+#pragma weak TIM8_UP_TIM13_IRQHandler= Default_Handler
+#pragma weak TIM8_TRG_COM_TIM14_IRQHandler= Default_Handler
+#pragma weak TIM8_CC_IRQHandler= Default_Handler
+#pragma weak DMA1_Stream7_IRQHandler= Default_Handler
+#pragma weak FSMC_IRQHandler= Default_Handler
+#pragma weak SDIO_IRQHandler= Default_Handler
+#pragma weak TIM5_IRQHandler= Default_Handler
+#pragma weak SPI3_IRQHandler= Default_Handler
+#pragma weak UART4_IRQHandler= Default_Handler
+#pragma weak UART5_IRQHandler= Default_Handler
+#pragma weak TIM6_DAC_IRQHandler= Default_Handler
+#pragma weak TIM7_IRQHandler= Default_Handler
+#pragma weak DMA2_Stream0_IRQHandler= Default_Handler
+#pragma weak DMA2_Stream1_IRQHandler= Default_Handler
+#pragma weak DMA2_Stream2_IRQHandler= Default_Handler
+#pragma weak DMA2_Stream3_IRQHandler= Default_Handler
+#pragma weak DMA2_Stream4_IRQHandler= Default_Handler
+#pragma weak ETH_IRQHandler= Default_Handler
+#pragma weak ETH_WKUP_IRQHandler= Default_Handler
+#pragma weak CAN2_TX_IRQHandler= Default_Handler
+#pragma weak CAN2_RX0_IRQHandler= Default_Handler
+#pragma weak CAN2_RX1_IRQHandler= Default_Handler
+#pragma weak CAN2_SCE_IRQHandler= Default_Handler
+#pragma weak OTG_FS_IRQHandler= Default_Handler
+#pragma weak DMA2_Stream5_IRQHandler= Default_Handler
+#pragma weak DMA2_Stream6_IRQHandler= Default_Handler
+#pragma weak DMA2_Stream7_IRQHandler= Default_Handler
+#pragma weak USART6_IRQHandler= Default_Handler
+#pragma weak I2C3_EV_IRQHandler= Default_Handler
+#pragma weak I2C3_ER_IRQHandler= Default_Handler
+#pragma weak OTG_HS_EP1_OUT_IRQHandler= Default_Handler
+#pragma weak OTG_HS_EP1_IN_IRQHandler= Default_Handler
+#pragma weak OTG_HS_WKUP_IRQHandler= Default_Handler
+#pragma weak OTG_HS_IRQHandler= Default_Handler
+#pragma weak DCMI_IRQHandler= Default_Handler
+#pragma weak CRYP_IRQHandler= Default_Handler
+#pragma weak HASH_RNG_IRQHandler= Default_Handler
+#pragma weak FPU_IRQHandler= Default_Handler
diff --git a/platform/mcu/STM32F4xx/drivers/adc1.c b/platform/mcu/STM32F4xx/drivers/adc1.c
new file mode 100644
index 00000000..b756302d
--- /dev/null
+++ b/platform/mcu/STM32F4xx/drivers/adc1.c
@@ -0,0 +1,104 @@
+/***************************************************************************
+ * Copyright (C) 2020 by Silvano Seva IU2KWO and Niccolò Izzo IU2KIN *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 3 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, see *
+ ***************************************************************************/
+
+#include "adc1.h"
+#include "gpio.h"
+
+uint16_t measurements[4];
+
+void adc1_init()
+{
+ RCC->APB2ENR |= RCC_APB2ENR_ADC1EN;
+ RCC->AHB1ENR |= RCC_AHB1ENR_DMA2EN;
+
+ /*
+ * Configure GPIOs to analog input mode:
+ * - PA0: volume potentiometer level
+ * - PA1: battery voltage
+ * - PA3: vox level
+ * - PB0: RSSI level
+ */
+ gpio_setMode(GPIOA, 0, INPUT_ANALOG);
+ gpio_setMode(GPIOA, 1, INPUT_ANALOG);
+ gpio_setMode(GPIOA, 3, INPUT_ANALOG);
+ gpio_setMode(GPIOB, 0, INPUT_ANALOG);
+
+ /*
+ * ADC clock is APB2 frequency divided by 8, giving 10.5MHz.
+ * We set the sample time of each channel to 480 ADC cycles and we have to
+ * scan four channels: given that a conversion takes 12 cycles, we have a
+ * total conversion time of ~187us.
+ */
+ ADC->CCR |= ADC_CCR_ADCPRE;
+ ADC1->SMPR2 = ADC_SMPR2_SMP0
+ | ADC_SMPR2_SMP1
+ | ADC_SMPR2_SMP3
+ | ADC_SMPR2_SMP8;
+
+ /*
+ * No overrun interrupt, 12-bit resolution, no analog watchdog, no
+ * discontinuous mode, enable scan mode, no end of conversion interrupts,
+ * enable continuous conversion (free-running).
+ */
+ ADC1->CR1 |= ADC_CR1_SCAN;
+ ADC1->CR2 |= ADC_CR2_DMA
+ | ADC_CR2_DDS
+ | ADC_CR2_CONT
+ | ADC_CR2_ADON;
+
+ /* Scan sequence config. */
+ ADC1->SQR1 = 3 << 20; /* Four channels to be converted */
+ ADC1->SQR3 |= (1 << 0) /* CH1, battery voltage on PA1 */
+ | (8 << 5) /* CH8, RSSI value on PB0 */
+ | (3 << 10) /* CH3, vox level on PA3 */
+ | (0 << 15); /* CH0, volume potentiometer level on PA0 */
+
+ /* DMA2 Stream 0 configuration:
+ * - channel 0: ADC1
+ * - low priority
+ * - half-word transfer, both memory and peripheral
+ * - increment memory
+ * - circular mode
+ * - peripheral-to-memory transfer
+ * - no interrupts
+ */
+ DMA2_Stream0->PAR = ((uint32_t) &(ADC1->DR));
+ DMA2_Stream0->M0AR = ((uint32_t) &measurements);
+ DMA2_Stream0->NDTR = 4;
+ DMA2_Stream0->CR = DMA_SxCR_MSIZE_0
+ | DMA_SxCR_PSIZE_0
+ | DMA_SxCR_MINC
+ | DMA_SxCR_CIRC
+ | DMA_SxCR_EN;
+
+ /* Finally, start conversion */
+ ADC1->CR2 |= ADC_CR2_SWSTART;
+}
+
+void adc1_shutdown()
+{
+ DMA2_Stream0->CR &= ~DMA_SxCR_EN;
+ ADC1->CR2 &= ADC_CR2_ADON;
+ RCC->APB2ENR &= ~RCC_APB2ENR_ADC1EN;
+}
+
+float adc1_getMeasurement(uint8_t ch)
+{
+ if(ch > 3) return 0.0f;
+ float value = ((float) measurements[ch]);
+ return (value * 3300.0f)/4096.0f;
+}
diff --git a/platform/mcu/STM32F4xx/drivers/adc1.h b/platform/mcu/STM32F4xx/drivers/adc1.h
new file mode 100644
index 00000000..1a65c346
--- /dev/null
+++ b/platform/mcu/STM32F4xx/drivers/adc1.h
@@ -0,0 +1,65 @@
+/***************************************************************************
+ * Copyright (C) 2020 by Silvano Seva IU2KWO and Niccolò Izzo IU2KIN *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 3 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, see *
+ ***************************************************************************/
+
+#ifndef ADC1_H
+#define ADC1_H
+
+#include
+#include "stm32f4xx.h"
+
+/**
+ * Driver for ADC1, used to continuously sample the following channels:
+ * - ADC1_CH0 (PA0): output value of the volume potentiometer;
+ * - ADC1_CH1 (PA1): battery voltage through 1:3 resistor divider;
+ * - ADC1_CH3 (PA3): vox level;
+ * - ADC1_CH8 (PB0): RSSI level;
+ */
+
+/**
+ * Initialise and start ADC1 and DMA2 Stream 0.
+ *
+ * ADC is configured in free-running mode with 1:8 prescaler and a sample time
+ * for each channel of 480 cycles. This gives a sampling frequency, for each
+ * channel, of ~5.3kHz.
+ *
+ * DMA2 Stream 0 is used to transfer data from ADC1 data register to an internal
+ * buffer, from which is fetched by application code using adc1_getMeasurement().
+ */
+void adc1_init();
+
+/**
+ * Turn off ADC1 (also gating off its clock) and disable DMA2 Stream 0.
+ * DMA2 clock is kept active.
+ */
+void adc1_shutdown();
+
+/**
+ * Get current measurement of a given channel, mapped as below:
+ * - channel 0: battery voltage
+ * - channel 1: RSSI level
+ * - channel 2: vox level
+ * - channel 3: volume level
+ *
+ * NOTE: the mapping above DOES NOT correspond to the physical ADC channel
+ * mapping!
+ *
+ * @param ch: channel number, between 0 and 3.
+ * @return current value of the specified channel in mV.
+ */
+float adc1_getMeasurement(uint8_t ch);
+
+#endif /* ADC1_H */
diff --git a/platform/mcu/STM32F4xx/drivers/delays.c b/platform/mcu/STM32F4xx/drivers/delays.c
new file mode 100644
index 00000000..75c93e70
--- /dev/null
+++ b/platform/mcu/STM32F4xx/drivers/delays.c
@@ -0,0 +1,51 @@
+/***************************************************************************
+ * Copyright (C) 2020 by Silvano Seva IU2KWO and Niccolò Izzo IU2KIN *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 3 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, see *
+ ***************************************************************************/
+
+#include "delays.h"
+
+/**
+ * Implementation of the delay functions for STM32F405 MCU.
+ */
+
+void delayUs(unsigned int useconds)
+{
+ // This delay has been calibrated to take x microseconds
+ // It is written in assembler to be independent on compiler optimization
+ asm volatile(" mov r1, #42 \n"
+ " mul r2, %0, r1 \n"
+ " mov r1, #0 \n"
+ "___loop_u: cmp r1, r2 \n"
+ " itt lo \n"
+ " addlo r1, r1, #1 \n"
+ " blo ___loop_u \n"::"r"(useconds):"r1","r2");
+}
+
+void delayMs(unsigned int mseconds)
+{
+ register const unsigned int count=42000;
+
+ for(unsigned int i=0;i *
+ ***************************************************************************/
+
+#include "gpio.h"
+
+void gpio_setMode(GPIO_TypeDef *port, uint8_t pin, enum Mode mode)
+{
+ port->MODER &= ~(3 << (pin*2));
+ port->OTYPER &= ~(1 << pin);
+ port->PUPDR &= ~(3 << (pin*2));
+
+ switch(mode)
+ {
+ case INPUT:
+ // (MODE=00 TYPE=0 PUP=00)
+ port->MODER |= 0x00 << (pin*2);
+ port->OTYPER |= 0x00 << pin;
+ port->PUPDR |= 0x00 << (pin*2);
+ break;
+
+ case INPUT_PULL_UP:
+ // (MODE=00 TYPE=0 PUP=01)
+ port->MODER |= 0x00 << (pin*2);
+ port->OTYPER |= 0x00 << pin;
+ port->PUPDR |= 0x01 << (pin*2);
+ break;
+
+ case INPUT_PULL_DOWN:
+ // (MODE=00 TYPE=0 PUP=10)
+ port->MODER |= 0x00 << (pin*2);
+ port->OTYPER |= 0x00 << pin;
+ port->PUPDR |= 0x02 << (pin*2);
+ break;
+
+ case INPUT_ANALOG:
+ // (MODE=11 TYPE=0 PUP=00)
+ port->MODER |= 0x03 << (pin*2);
+ port->OTYPER |= 0x00 << pin;
+ port->PUPDR |= 0x00 << (pin*2);
+ break;
+
+ case OUTPUT:
+ // (MODE=01 TYPE=0 PUP=00)
+ port->MODER |= 0x01 << (pin*2);
+ port->OTYPER |= 0x00 << pin;
+ port->PUPDR |= 0x00 << (pin*2);
+ break;
+
+ case OPEN_DRAIN:
+ // (MODE=01 TYPE=1 PUP=00)
+ port->MODER |= 0x01 << (pin*2);
+ port->OTYPER |= 0x01 << pin;
+ port->PUPDR |= 0x00 << (pin*2);
+ break;
+
+ case ALTERNATE:
+ // (MODE=10 TYPE=0 PUP=00)
+ port->MODER |= 0x02 << (pin*2);
+ port->OTYPER |= 0x00 << pin;
+ port->PUPDR |= 0x00 << (pin*2);
+ break;
+
+ case ALTERNATE_OD:
+ // (MODE=10 TYPE=1 PUP=00)
+ port->MODER |= 0x02 << (pin*2);
+ port->OTYPER |= 0x01 << pin;
+ port->PUPDR |= 0x00 << (pin*2);
+ break;
+
+ default:
+ // Default to INPUT mode
+ port->MODER |= 0x00 << (pin*2);
+ port->OTYPER |= 0x00 << pin;
+ port->PUPDR |= 0x00 << (pin*2);
+ break;
+ }
+}
+
+void gpio_setAlternateFunction(GPIO_TypeDef *port, uint8_t pin, uint8_t afNum)
+{
+ afNum &= 0x0F;
+ if(pin < 8)
+ {
+ port->AFR[0] &= ~(0x0F << (pin*4));
+ port->AFR[0] |= (afNum << (pin*4));
+ }
+ else
+ {
+ pin -= 8;
+ port->AFR[1] &= ~(0x0F << (pin*4));
+ port->AFR[1] |= (afNum << (pin*4));
+ }
+}
+
+void gpio_setOutputSpeed(GPIO_TypeDef *port, uint8_t pin, enum Speed spd)
+{
+ port->OSPEEDR &= ~(3 << (pin*2)); // Clear old value
+ port->OSPEEDR |= spd << (pin*2); // Set new value
+}
+
+void gpio_setPin(GPIO_TypeDef *port, uint8_t pin)
+{
+ port->BSRRL = (1 << pin);
+}
+
+void gpio_clearPin(GPIO_TypeDef *port, uint8_t pin)
+{
+ port->BSRRH = (1 << pin);
+}
+
+void gpio_togglePin(GPIO_TypeDef *port, uint8_t pin)
+{
+ port->ODR ^= (1 << pin);
+}
+
+uint8_t gpio_readPin(const GPIO_TypeDef *port, uint8_t pin)
+{
+ return ((port->IDR & (1 << pin)) != 0) ? 1 : 0;
+}
diff --git a/platform/mcu/STM32F4xx/drivers/gpio.h b/platform/mcu/STM32F4xx/drivers/gpio.h
new file mode 100644
index 00000000..07c558bd
--- /dev/null
+++ b/platform/mcu/STM32F4xx/drivers/gpio.h
@@ -0,0 +1,110 @@
+/***************************************************************************
+ * Copyright (C) 2020 by Silvano Seva IU2KWO *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 3 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, see *
+ ***************************************************************************/
+
+#ifndef GPIO_H
+#define GPIO_H
+
+#include
+#include "stm32f4xx.h"
+
+/**
+ * GPIO functional modes.
+ * For more details see microcontroller's reference manual.
+ */
+enum Mode
+{
+ INPUT = 0, ///Floating Input
+ INPUT_PULL_UP = 1, ///Pullup Input
+ INPUT_PULL_DOWN = 2, ///Pulldown Input
+ INPUT_ANALOG = 3, ///Analog Input
+ OUTPUT = 4, ///Push Pull Output
+ OPEN_DRAIN = 5, ///Open Drain Output
+ ALTERNATE = 6, ///Alternate function
+ ALTERNATE_OD = 7, ///Alternate Open Drain
+};
+
+/**
+ * Maximum GPIO switching speed.
+ * For more details see microcontroller's reference manual and datasheet.
+ */
+enum Speed
+{
+ LOW = 0x0, /// 2MHz for STM32
+ MEDIUM = 0x1, /// 25MHz for STM32
+ FAST = 0x2, /// 50MHz for STM32
+ HIGH = 0x3 /// 100MHz for STM32
+};
+
+/**
+ * Configure GPIO pin functional mode.
+ * @param port: GPIO port, it has to be equal to GPIOA_BASE, GPIOB_BASE, ...
+ * @param pin: GPIO pin number, between 0 and 15.
+ * @param mode: GPIO functional mode to be set.
+ */
+void gpio_setMode(GPIO_TypeDef *port, uint8_t pin, enum Mode mode);
+
+/**
+ * Map alternate function to GPIO pin. The pin has to be configured in alternate
+ * mode by calling 'gpio_setMode'.
+ * @param port: GPIO port, it has to be equal to GPIOA_BASE, GPIOB_BASE, ...
+ * @param pin: GPIO pin number, between 0 and 15.
+ * @param afNum: alternate function number, retrieved from mapping table in
+ * microcontroller's datasheet.
+ */
+void gpio_setAlternateFunction(GPIO_TypeDef *port, uint8_t pin, uint8_t afNum);
+
+/**
+ * Configure GPIO pin maximum output speed.
+ * @param port: GPIO port, it has to be equal to GPIOA_BASE, GPIOB_BASE, ...
+ * @param pin: GPIO pin number, between 0 and 15.
+ * @param spd: GPIO output speed to be set.
+ */
+void gpio_setOutputSpeed(GPIO_TypeDef *port, uint8_t pin, enum Speed spd);
+
+/**
+ * Set GPIO pin to high logic level.
+ * NOTE: this operation is performed atomically.
+ * @param port: GPIO port, it has to be equal to GPIOA_BASE, GPIOB_BASE, ...
+ * @param pin: GPIO pin number, between 0 and 15.
+ */
+void gpio_setPin(GPIO_TypeDef *port, uint8_t pin);
+
+/**
+ * Set GPIO pin to low logic level.
+ * NOTE: this operation is performed atomically.
+ * @param port: GPIO port, it has to be equal to GPIOA_BASE, GPIOB_BASE, ...
+ * @param pin: GPIO pin number, between 0 and 15.
+ */
+void gpio_clearPin(GPIO_TypeDef *port, uint8_t pin);
+
+/**
+ * Toggle logic level of a GPIO pin, with respect to its state before calling
+ * this function.
+ * @param port: GPIO port, it has to be equal to GPIOA_BASE, GPIOB_BASE, ...
+ * @param pin: GPIO pin number, between 0 and 15.
+ */
+void gpio_togglePin(GPIO_TypeDef *port, uint8_t pin);
+
+/**
+ * Read GPIO pin's logic level.
+ * @param port: GPIO port, it has to be equal to GPIOA_BASE, GPIOB_BASE, ...
+ * @param pin: GPIO pin number, between 0 and 15.
+ * @return 1 if pin is at high logic level, 0 if pin is at low logic level.
+ */
+uint8_t gpio_readPin(const GPIO_TypeDef *port, uint8_t pin);
+
+#endif /* GPIO_H */
diff --git a/platform/mcu/STM32F4xx/drivers/rtc.c b/platform/mcu/STM32F4xx/drivers/rtc.c
new file mode 100644
index 00000000..9b28bb12
--- /dev/null
+++ b/platform/mcu/STM32F4xx/drivers/rtc.c
@@ -0,0 +1,134 @@
+/***************************************************************************
+ * Copyright (C) 2020 by Silvano Seva IU2KWO and Niccolò Izzo IU2KIN *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 3 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, see *
+ ***************************************************************************/
+
+#include "rtc.h"
+#include "FreeRTOS.h"
+#include "task.h"
+
+void rtc_init()
+{
+ /* Enable write protection for RTC registers */
+ RCC->APB1ENR |= RCC_APB1ENR_PWREN;
+ PWR->CR |= PWR_CR_DBP;
+ RTC->WPR = 0xCA;
+ RTC->WPR = 0x53;
+
+ RCC->BDCR = RCC_BDCR_RTCEN /* Enable RTC */
+ | RCC_BDCR_RTCSEL_0 /* Set LSE as clock source */
+ | RCC_BDCR_LSEON; /* Enable LSE */
+
+ /* Wait until external 32kHz crystal stabilises */
+ while((RCC->BDCR & RCC_BDCR_LSERDY) == 0) ;
+}
+
+void rtc_shutdown()
+{
+ RCC->BDCR &= ~ RCC_BDCR_RTCEN | RCC_BDCR_LSEON;
+}
+
+void rtc_setTime(curTime_t t)
+{
+ /*
+ * Convert values to BCD representation placing data in the correct
+ * positions for both time and date registers.
+ * Packing is done before updating registers, to minimise time spent with
+ * RTC in initialisation mode.
+ */
+ uint32_t date = ((t.year / 10) << 20)
+ | ((t.year % 10) << 16)
+ | ((t.month / 10) << 12)
+ | ((t.month % 10) << 8)
+ | ((t.date / 10) << 4)
+ | (t.date % 10);
+ date &= RTC_DR_YT | RTC_DR_YU | RTC_DR_MT | RTC_DR_MU | RTC_DR_DT | RTC_DR_DU;
+
+ uint32_t time = ((t.hour / 10) << 20)
+ | ((t.hour % 10) << 16)
+ | ((t.minute / 10) << 12)
+ | ((t.minute % 10) << 8)
+ | ((t.second / 10) << 4)
+ | (t.second % 10);
+ time &= RTC_TR_HT | RTC_TR_HU | RTC_TR_MNT | RTC_TR_MNU | RTC_TR_ST | RTC_TR_SU;
+
+ /* Enter initialisation mode and update registers */
+ taskENTER_CRITICAL();
+ RTC->ISR |= RTC_ISR_INIT;
+ while((RTC->ISR & RTC_ISR_INITF) == 0) ;
+ RTC->TR = time;
+ RTC->DR = date;
+ RTC->ISR &= ~RTC_ISR_INIT;
+ taskEXIT_CRITICAL();
+}
+
+void rtc_setHour(uint8_t hours, uint8_t minutes, uint8_t seconds)
+{
+ curTime_t t = rtc_getTime();
+ t.hour = hours;
+ t.minute = minutes;
+ t.second = seconds;
+ rtc_setTime(t);
+}
+
+void rtc_setDate(uint8_t date, uint8_t month, uint8_t year)
+{
+ curTime_t t = rtc_getTime();
+ t.date = date;
+ t.month = month;
+ t.year = year;
+ rtc_setTime(t);
+}
+
+curTime_t rtc_getTime()
+{
+ curTime_t t;
+
+ /*
+ * Obtain time and date values in BCD format from RTC registers, and fill
+ * the corresponding fields of the struct to be returned.
+ */
+ uint32_t time = RTC->TR;
+ t.hour = ((time & RTC_TR_HT) >> 20)*10 + ((time & RTC_TR_HU) >> 16);
+ t.minute = ((time & RTC_TR_MNT) >> 12)*10 + ((time & RTC_TR_MNU) >> 8);
+ t.second = ((time & RTC_TR_ST) >> 4)*10 + (time & RTC_TR_SU);
+
+ uint32_t date = RTC->DR;
+ t.year = ((date & RTC_DR_YT) >> 20)*10 + ((date & RTC_DR_YU) >> 16);
+ t.day = ((date & RTC_DR_WDU) >> 13);
+ t.month = ((date & RTC_DR_MT) >> 12)*10 + ((date & RTC_DR_MU) >> 8);
+ t.date = ((date & RTC_DR_DT) >> 4)*10 + (date & RTC_DR_DU);
+
+ return t;
+}
+
+void rtc_dstSet()
+{
+ /* If BKP bit is set, DST has been already set */
+ if(RTC->CR & RTC_CR_BCK) return;
+ taskENTER_CRITICAL();
+ RTC->CR |= RTC_CR_BCK | RTC_CR_ADD1H;
+ taskEXIT_CRITICAL();
+}
+
+void rtc_dstClear()
+{
+ /* If BKP bit is cleared, DST has been already removed */
+ if((RTC->CR & RTC_CR_BCK) == 0) return;
+ taskENTER_CRITICAL();
+ RTC->CR &= ~RTC_CR_BCK;
+ RTC->CR |= RTC_CR_SUB1H;
+ taskEXIT_CRITICAL();
+}
diff --git a/platform/mcu/STM32F4xx/drivers/rtc.h b/platform/mcu/STM32F4xx/drivers/rtc.h
new file mode 100644
index 00000000..5d121b5c
--- /dev/null
+++ b/platform/mcu/STM32F4xx/drivers/rtc.h
@@ -0,0 +1,100 @@
+/***************************************************************************
+ * Copyright (C) 2020 by Silvano Seva IU2KWO and Niccolò Izzo IU2KIN *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 3 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, see *
+ ***************************************************************************/
+
+#ifndef RTC_H
+#define RTC_H
+
+#include
+#include "stm32f4xx.h"
+
+/**
+ * Driver for STM32 real time clock, providing both calendar and clock
+ * functionalities.
+ *
+ * RTC is active also when radio is powered off, thanks to the internal
+ * lithium backup battery.
+ */
+
+typedef struct
+{
+ uint8_t hour : 5; /* Hours (0-23) */
+ uint8_t minute : 6; /* Minutes (0-59) */
+ uint8_t second : 6; /* Seconds (0-59) */
+ uint8_t day : 3; /* Day of the week (1-7) */
+ uint8_t date : 4; /* Day of the month (1-31) */
+ uint8_t month : 4; /* Month (1-12) */
+ uint8_t year : 7; /* Year (0-99) */
+ uint8_t : 5; /* Padding to 40 bits */
+}curTime_t;
+
+/**
+ * Initialise and start RTC, which uses as clock source the external 32.768kHz
+ * crystal connected to PC14 and PC15 (indicated with LSE in STM32 reference
+ * manual).
+ */
+void rtc_init();
+
+/**
+ * Shutdown RTC and external 32.768kHz clock source.
+ */
+void rtc_shutdown();
+
+/**
+ * Set RTC time and calendar registers to a given value.
+ * @param t: struct of type curTime_t, whose content is used to initialise both
+ * clock and calendar registers.
+ */
+void rtc_setTime(curTime_t t);
+
+/**
+ * Set RTC clock keeping untouched the calendar part.
+ * @param hours: new value for hours, between 0 and 23.
+ * @param minutes: new value for minutes, between 0 and 59.
+ * @param seconds: new value for seconds, between 0 and 59.
+ */
+void rtc_setHour(uint8_t hours, uint8_t minutes, uint8_t seconds);
+
+/**
+ * Set RTC calendar keeping untouched the clock part.
+ * @param date: new value for the date, between 1 and 31.
+ * @param month: new value for the month, between 1 and 12.
+ * @param year: new value for the year, between 00 and 99.
+ */
+void rtc_setDate(uint8_t date, uint8_t month, uint8_t year);
+
+/**
+ * Get current date and time.
+ * @return structure of type curTime_t with current clock and calendar values.
+ */
+curTime_t rtc_getTime();
+
+/**
+ * Activate daylight saving time (DST), adding one hour to the current time.
+ * This function can be safely called multiple times: calls following the one
+ * which firstly activates DST have no effect.
+ */
+void rtc_dstSet();
+
+/**
+ * Switch back from daylight saving time (DST), removing one hour from the
+ * current time.
+ * This function can be safely called multiple times: calls following the one
+ * which firstly dectivates DST have no effect.
+ */
+void rtc_dstClear();
+
+#endif /* RTC_H */
diff --git a/platform/mcu/STM32F4xx/drivers/usb/usb_bsp.c b/platform/mcu/STM32F4xx/drivers/usb/usb_bsp.c
new file mode 100644
index 00000000..00782ffe
--- /dev/null
+++ b/platform/mcu/STM32F4xx/drivers/usb/usb_bsp.c
@@ -0,0 +1,107 @@
+/**
+ ******************************************************************************
+ * @file usb_bsp.c
+ * @author MCD Application Team
+ * @version V1.1.0
+ * @date 19-March-2012
+ * @brief This file is responsible to offer board support package and is
+ * configurable by user.
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT 2012 STMicroelectronics
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (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.st.com/software_license_agreement_liberty_v2
+ *
+ * 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.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "usb_bsp.h"
+#include "usbd_conf.h"
+#include "stm32f4xx.h"
+#include "gpio.h"
+
+extern USB_OTG_CORE_HANDLE USB_OTG_dev;
+extern uint32_t USBD_OTG_ISR_Handler(USB_OTG_CORE_HANDLE *pdev);
+
+/**
+* @brief USB_OTG_BSP_Init
+* Initilizes BSP configurations
+* @param None
+* @retval None
+*/
+
+void USB_OTG_BSP_Init(USB_OTG_CORE_HANDLE *pdev)
+{
+ gpio_setMode(GPIOA, 11, ALTERNATE);
+ gpio_setAlternateFunction(GPIOA, 11, 10);
+ gpio_setOutputSpeed(GPIOA, 11, HIGH); // 100MHz output speed
+
+ gpio_setMode(GPIOA, 12, ALTERNATE);
+ gpio_setAlternateFunction(GPIOA, 12, 10);
+ gpio_setOutputSpeed(GPIOA, 12, HIGH); // 100MHz output speed
+
+ RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN;
+ RCC->AHB2ENR |= RCC_AHB2ENR_OTGFSEN;
+}
+
+/**
+* @brief USB_OTG_BSP_EnableInterrupt
+* Enabele USB Global interrupt
+* @param None
+* @retval None
+*/
+void USB_OTG_BSP_EnableInterrupt(USB_OTG_CORE_HANDLE *pdev)
+{
+ NVIC_ClearPendingIRQ(OTG_FS_IRQn);
+ NVIC_SetPriority(OTG_FS_IRQn, 14);
+ NVIC_EnableIRQ(OTG_FS_IRQn);
+}
+/**
+* @brief USB_OTG_BSP_uDelay
+* This function provides delay time in micro sec
+* @param usec : Value of delay required in micro sec
+* @retval None
+*/
+void USB_OTG_BSP_uDelay (const uint32_t usec) {
+
+ uint32_t count = 0;
+ const uint32_t utime = (120 * usec / 7);
+
+ do
+ {
+ if( ++count > utime )
+ {
+ return ;
+ }
+ } while (1);
+}
+
+
+/**
+* @brief USB_OTG_BSP_mDelay
+* This function provides delay time in milli sec
+* @param msec : Value of delay required in milli sec
+* @retval None
+*/
+void USB_OTG_BSP_mDelay (const uint32_t msec)
+{
+ USB_OTG_BSP_uDelay(msec * 1000);
+}
+
+void OTG_FS_IRQHandler(void)
+{
+ USBD_OTG_ISR_Handler (&USB_OTG_dev);
+}
+
diff --git a/platform/mcu/STM32F4xx/drivers/usb/usb_bsp.h b/platform/mcu/STM32F4xx/drivers/usb/usb_bsp.h
new file mode 100644
index 00000000..a23cd36e
--- /dev/null
+++ b/platform/mcu/STM32F4xx/drivers/usb/usb_bsp.h
@@ -0,0 +1,103 @@
+/**
+ ******************************************************************************
+ * @file usb_bsp.h
+ * @author MCD Application Team
+ * @version V2.1.0
+ * @date 19-March-2012
+ * @brief Specific api's relative to the used hardware platform
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT 2012 STMicroelectronics
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (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.st.com/software_license_agreement_liberty_v2
+ *
+ * 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.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USB_BSP__H__
+#define __USB_BSP__H__
+
+/* Includes ------------------------------------------------------------------*/
+#include "usb_core.h"
+#include "usb_conf.h"
+
+/** @addtogroup USB_OTG_DRIVER
+ * @{
+ */
+
+/** @defgroup USB_BSP
+ * @brief This file is the
+ * @{
+ */
+
+
+/** @defgroup USB_BSP_Exported_Defines
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup USB_BSP_Exported_Types
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup USB_BSP_Exported_Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USB_BSP_Exported_Variables
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USB_BSP_Exported_FunctionsPrototype
+ * @{
+ */
+void BSP_Init(void);
+
+void USB_OTG_BSP_Init (USB_OTG_CORE_HANDLE *pdev);
+void USB_OTG_BSP_uDelay (const uint32_t usec);
+void USB_OTG_BSP_mDelay (const uint32_t msec);
+void USB_OTG_BSP_EnableInterrupt (USB_OTG_CORE_HANDLE *pdev);
+#ifdef USE_HOST_MODE
+void USB_OTG_BSP_ConfigVBUS(USB_OTG_CORE_HANDLE *pdev);
+void USB_OTG_BSP_DriveVBUS(USB_OTG_CORE_HANDLE *pdev,uint8_t state);
+#endif
+/**
+ * @}
+ */
+
+#endif //__USB_BSP__H__
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
diff --git a/platform/mcu/STM32F4xx/drivers/usb/usb_conf.h b/platform/mcu/STM32F4xx/drivers/usb/usb_conf.h
new file mode 100644
index 00000000..90b1ee18
--- /dev/null
+++ b/platform/mcu/STM32F4xx/drivers/usb/usb_conf.h
@@ -0,0 +1,291 @@
+/**
+ ******************************************************************************
+ * @file usb_conf.h
+ * @author MCD Application Team
+ * @version V1.1.0
+ * @date 19-March-2012
+ * @brief General low level driver configuration
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT 2012 STMicroelectronics
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (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.st.com/software_license_agreement_liberty_v2
+ *
+ * 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.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USB_CONF__H__
+#define __USB_CONF__H__
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f4xx.h"
+#include
+#include
+
+/** @addtogroup USB_OTG_DRIVER
+ * @{
+ */
+
+/** @defgroup USB_CONF
+ * @brief USB low level driver configuration file
+ * @{
+ */
+
+/** @defgroup USB_CONF_Exported_Defines
+ * @{
+ */
+
+/* USB Core and PHY interface configuration.
+ Tip: To avoid modifying these defines each time you need to change the USB
+ configuration, you can declare the needed define in your toolchain
+ compiler preprocessor.
+ */
+/****************** USB OTG FS PHY CONFIGURATION *******************************
+* The USB OTG FS Core supports one on-chip Full Speed PHY.
+*
+* The USE_EMBEDDED_PHY symbol is defined in the project compiler preprocessor
+* when FS core is used.
+*******************************************************************************/
+#ifndef USE_USB_OTG_FS
+ #ifndef USE_USB_OTG_HS
+ #define USE_USB_OTG_FS
+ #endif
+#endif /* USE_USB_OTG_FS */
+
+#ifdef USE_USB_OTG_FS
+ #define USB_OTG_FS_CORE
+#endif
+
+#define USB_VCP_DISABLE_VBUS
+#define USB_VCP_DISABLE_ID
+
+/****************** USB OTG HS PHY CONFIGURATION *******************************
+* The USB OTG HS Core supports two PHY interfaces:
+* (i) An ULPI interface for the external High Speed PHY: the USB HS Core will
+* operate in High speed mode
+* (ii) An on-chip Full Speed PHY: the USB HS Core will operate in Full speed mode
+*
+* You can select the PHY to be used using one of these two defines:
+* (i) USE_ULPI_PHY: if the USB OTG HS Core is to be used in High speed mode
+* (ii) USE_EMBEDDED_PHY: if the USB OTG HS Core is to be used in Full speed mode
+*
+* Notes:
+* - The USE_ULPI_PHY symbol is defined in the project compiler preprocessor as
+* default PHY when HS core is used.
+* - On STM322xG-EVAL and STM324xG-EVAL boards, only configuration(i) is available.
+* Configuration (ii) need a different hardware, for more details refer to your
+* STM32 device datasheet.
+*******************************************************************************/
+#ifndef USE_USB_OTG_HS
+ //#define USE_USB_OTG_HS
+#endif /* USE_USB_OTG_HS */
+
+#ifndef USE_ULPI_PHY
+ //#define USE_ULPI_PHY
+#endif /* USE_ULPI_PHY */
+
+#ifndef USE_EMBEDDED_PHY
+ #define USE_EMBEDDED_PHY
+#endif /* USE_EMBEDDED_PHY */
+
+#ifdef USE_USB_OTG_HS
+ #define USB_OTG_HS_CORE
+#endif
+
+/*******************************************************************************
+* FIFO Size Configuration in Device mode
+*
+* (i) Receive data FIFO size = RAM for setup packets +
+* OUT endpoint control information +
+* data OUT packets + miscellaneous
+* Space = ONE 32-bits words
+* --> RAM for setup packets = 10 spaces
+* (n is the nbr of CTRL EPs the device core supports)
+* --> OUT EP CTRL info = 1 space
+* (one space for status information written to the FIFO along with each
+* received packet)
+* --> data OUT packets = (Largest Packet Size / 4) + 1 spaces
+* (MINIMUM to receive packets)
+* --> OR data OUT packets = at least 2*(Largest Packet Size / 4) + 1 spaces
+* (if high-bandwidth EP is enabled or multiple isochronous EPs)
+* --> miscellaneous = 1 space per OUT EP
+* (one space for transfer complete status information also pushed to the
+* FIFO with each endpoint's last packet)
+*
+* (ii)MINIMUM RAM space required for each IN EP Tx FIFO = MAX packet size for
+* that particular IN EP. More space allocated in the IN EP Tx FIFO results
+* in a better performance on the USB and can hide latencies on the AHB.
+*
+* (iii) TXn min size = 16 words. (n : Transmit FIFO index)
+* (iv) When a TxFIFO is not used, the Configuration should be as follows:
+* case 1 : n > m and Txn is not used (n,m : Transmit FIFO indexes)
+* --> Txm can use the space allocated for Txn.
+* case2 : n < m and Txn is not used (n,m : Transmit FIFO indexes)
+* --> Txn should be configured with the minimum space of 16 words
+* (v) The FIFO is used optimally when used TxFIFOs are allocated in the top
+* of the FIFO.Ex: use EP1 and EP2 as IN instead of EP1 and EP3 as IN ones.
+* (vi) In HS case 12 FIFO locations should be reserved for internal DMA registers
+* so total FIFO size should be 1012 Only instead of 1024
+*******************************************************************************/
+
+/****************** USB OTG HS CONFIGURATION **********************************/
+#ifdef USB_OTG_HS_CORE
+ #define RX_FIFO_HS_SIZE 512
+ #define TX0_FIFO_HS_SIZE 64
+ #define TX1_FIFO_HS_SIZE 372
+ #define TX2_FIFO_HS_SIZE 64
+ #define TX3_FIFO_HS_SIZE 0
+ #define TX4_FIFO_HS_SIZE 0
+ #define TX5_FIFO_HS_SIZE 0
+
+// #define USB_OTG_HS_SOF_OUTPUT_ENABLED
+
+ #ifdef USE_ULPI_PHY
+ #define USB_OTG_ULPI_PHY_ENABLED
+ #endif
+ #ifdef USE_EMBEDDED_PHY
+ #define USB_OTG_EMBEDDED_PHY_ENABLED
+ /* wakeup is working only when HS core is configured in FS mode */
+ #define USB_OTG_HS_LOW_PWR_MGMT_SUPPORT
+ #endif
+ /* #define USB_OTG_HS_INTERNAL_DMA_ENABLED */ /* Be aware that enabling DMA mode will result in data being sent only by
+ multiple of 4 packet sizes. This is due to the fact that USB DMA does
+ not allow sending data from non word-aligned addresses.
+ For this specific application, it is advised to not enable this option
+ unless required. */
+ #define USB_OTG_HS_DEDICATED_EP1_ENABLED
+#endif
+
+/****************** USB OTG FS CONFIGURATION **********************************/
+#ifdef USB_OTG_FS_CORE
+ #define RX_FIFO_FS_SIZE 128
+ #define TX0_FIFO_FS_SIZE 32
+ #define TX1_FIFO_FS_SIZE 128
+ #define TX2_FIFO_FS_SIZE 32
+ #define TX3_FIFO_FS_SIZE 0
+
+// #define USB_OTG_FS_LOW_PWR_MGMT_SUPPORT
+// #define USB_OTG_FS_SOF_OUTPUT_ENABLED
+#endif
+
+/****************** USB OTG MISC CONFIGURATION ********************************/
+//#define VBUS_SENSING_ENABLED
+
+/****************** USB OTG MODE CONFIGURATION ********************************/
+//#define USE_HOST_MODE
+#define USE_DEVICE_MODE
+//#define USE_OTG_MODE
+
+#ifndef USB_OTG_FS_CORE
+ #ifndef USB_OTG_HS_CORE
+ #error "USB_OTG_HS_CORE or USB_OTG_FS_CORE should be defined"
+ #endif
+#endif
+
+#ifndef USE_DEVICE_MODE
+ #ifndef USE_HOST_MODE
+ #error "USE_DEVICE_MODE or USE_HOST_MODE should be defined"
+ #endif
+#endif
+
+#ifndef USE_USB_OTG_HS
+ #ifndef USE_USB_OTG_FS
+ #error "USE_USB_OTG_HS or USE_USB_OTG_FS should be defined"
+ #endif
+#else //USE_USB_OTG_HS
+ #ifndef USE_ULPI_PHY
+ #ifndef USE_EMBEDDED_PHY
+ #error "USE_ULPI_PHY or USE_EMBEDDED_PHY should be defined"
+ #endif
+ #endif
+#endif
+
+
+/******************************************************************************
+ *
+ * By Silvano Seva: rise an error if HS USB is enabled.
+ *
+ * Actually USB virtual com port uses USB FS, thus we are pruning away code
+ * related to USB HS to improve readability.
+ *
+*******************************************************************************/
+#ifdef USE_USB_OTG_HS
+#error "USB OTG HS not implemented"
+#endif
+
+/* NOTE: #ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED pruned away! */
+#define __ALIGN_BEGIN
+#define __ALIGN_END
+
+/* NOTE: #ifdefs for __packed pruned away! They're already defined in sys/cdefs.h */
+
+// #if defined (__CC_ARM) /* ARM Compiler */
+// #define __packed __packed
+// #elif defined (__ICCARM__) /* IAR Compiler */
+// #define __packed __packed
+// #elif defined ( __GNUC__ ) /* GNU Compiler */
+// #define __packed __attribute__ ((__packed__))
+// #elif defined (__TASKING__) /* TASKING Compiler */
+// #define __packed __unaligned
+// #endif /* __CC_ARM */
+
+/**
+ * @}
+ */
+
+
+/** @defgroup USB_CONF_Exported_Types
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup USB_CONF_Exported_Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USB_CONF_Exported_Variables
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USB_CONF_Exported_FunctionsPrototype
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+#endif //__USB_CONF__H__
+
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
diff --git a/platform/mcu/STM32F4xx/drivers/usb/usb_core.c b/platform/mcu/STM32F4xx/drivers/usb/usb_core.c
new file mode 100644
index 00000000..12a207d8
--- /dev/null
+++ b/platform/mcu/STM32F4xx/drivers/usb/usb_core.c
@@ -0,0 +1,2162 @@
+/**
+ ******************************************************************************
+ * @file usb_core.c
+ * @author MCD Application Team
+ * @version V2.1.0
+ * @date 19-March-2012
+ * @brief USB-OTG Core Layer
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT 2012 STMicroelectronics
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (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.st.com/software_license_agreement_liberty_v2
+ *
+ * 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.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "usb_core.h"
+#include "usb_bsp.h"
+
+
+/** @addtogroup USB_OTG_DRIVER
+* @{
+*/
+
+/** @defgroup USB_CORE
+* @brief This file includes the USB-OTG Core Layer
+* @{
+*/
+
+
+/** @defgroup USB_CORE_Private_Defines
+* @{
+*/
+
+/**
+* @}
+*/
+
+
+/** @defgroup USB_CORE_Private_TypesDefinitions
+* @{
+*/
+/**
+* @}
+*/
+
+
+
+/** @defgroup USB_CORE_Private_Macros
+* @{
+*/
+/**
+* @}
+*/
+
+
+/** @defgroup USB_CORE_Private_Variables
+* @{
+*/
+/**
+* @}
+*/
+
+
+/** @defgroup USB_CORE_Private_FunctionPrototypes
+* @{
+*/
+/**
+* @}
+*/
+
+
+/** @defgroup USB_CORE_Private_Functions
+* @{
+*/
+
+/**
+* @brief USB_OTG_EnableCommonInt
+* Initializes the commmon interrupts, used in both device and modes
+* @param pdev : Selected device
+* @retval None
+*/
+static void USB_OTG_EnableCommonInt(USB_OTG_CORE_HANDLE *pdev)
+{
+ USB_OTG_GINTMSK_TypeDef int_mask;
+
+ int_mask.d32 = 0;
+ /* Clear any pending USB_OTG Interrupts */
+#ifndef USE_OTG_MODE
+ USB_OTG_WRITE_REG32( &pdev->regs.GREGS->GOTGINT, 0xFFFFFFFF);
+#endif
+ /* Clear any pending interrupts */
+ USB_OTG_WRITE_REG32( &pdev->regs.GREGS->GINTSTS, 0xBFFFFFFF);
+ /* Enable the interrupts in the INTMSK */
+ int_mask.b.wkupintr = 1;
+ int_mask.b.usbsuspend = 1;
+
+#ifdef USE_OTG_MODE
+ int_mask.b.otgintr = 1;
+ int_mask.b.sessreqintr = 1;
+ int_mask.b.conidstschng = 1;
+#endif
+ USB_OTG_WRITE_REG32( &pdev->regs.GREGS->GINTMSK, int_mask.d32);
+}
+
+/**
+* @brief USB_OTG_CoreReset : Soft reset of the core
+* @param pdev : Selected device
+* @retval USB_OTG_STS : status
+*/
+static USB_OTG_STS USB_OTG_CoreReset(USB_OTG_CORE_HANDLE *pdev)
+{
+ USB_OTG_STS status = USB_OTG_OK;
+ __IO USB_OTG_GRSTCTL_TypeDef greset;
+ uint32_t count = 0;
+
+ greset.d32 = 0;
+ /* Wait for AHB master IDLE state. */
+ do
+ {
+ USB_OTG_BSP_uDelay(3);
+ greset.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GRSTCTL);
+ if (++count > 200000)
+ {
+ return USB_OTG_OK;
+ }
+ }
+ while (greset.b.ahbidle == 0);
+ /* Core Soft Reset */
+ count = 0;
+ greset.b.csftrst = 1;
+ USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GRSTCTL, greset.d32 );
+ do
+ {
+ greset.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GRSTCTL);
+ if (++count > 200000)
+ {
+ break;
+ }
+ }
+ while (greset.b.csftrst == 1);
+ /* Wait for 3 PHY Clocks*/
+ USB_OTG_BSP_uDelay(3);
+ return status;
+}
+
+/**
+* @brief USB_OTG_WritePacket : Writes a packet into the Tx FIFO associated
+* with the EP
+* @param pdev : Selected device
+* @param src : source pointer
+* @param ch_ep_num : end point number
+* @param bytes : No. of bytes
+* @retval USB_OTG_STS : status
+*/
+USB_OTG_STS USB_OTG_WritePacket(USB_OTG_CORE_HANDLE *pdev,
+ uint8_t *src,
+ uint8_t ch_ep_num,
+ uint16_t len)
+{
+ USB_OTG_STS status = USB_OTG_OK;
+ if (pdev->cfg.dma_enable == 0)
+ {
+ uint32_t count32b= 0 , i= 0;
+ __IO uint32_t *fifo;
+
+ count32b = (len + 3) / 4;
+ fifo = pdev->regs.DFIFO[ch_ep_num];
+ for (i = 0; i < count32b; i++, src+=4)
+ {
+ USB_OTG_WRITE_REG32( fifo, *((__packed uint32_t *)src) );
+ }
+ }
+ return status;
+}
+
+
+/**
+* @brief USB_OTG_ReadPacket : Reads a packet from the Rx FIFO
+* @param pdev : Selected device
+* @param dest : Destination Pointer
+* @param bytes : No. of bytes
+* @retval None
+*/
+void *USB_OTG_ReadPacket(USB_OTG_CORE_HANDLE *pdev,
+ uint8_t *dest,
+ uint16_t len)
+{
+ uint32_t i=0;
+ uint32_t count32b = (len + 3) / 4;
+
+ __IO uint32_t *fifo = pdev->regs.DFIFO[0];
+
+ for ( i = 0; i < count32b; i++, dest += 4 )
+ {
+ *(__packed uint32_t *)dest = USB_OTG_READ_REG32(fifo);
+
+ }
+ return ((void *)dest);
+}
+
+/**
+* @brief USB_OTG_SelectCore
+* Initialize core registers address.
+* @param pdev : Selected device
+* @param coreID : USB OTG Core ID
+* @retval USB_OTG_STS : status
+*/
+USB_OTG_STS USB_OTG_SelectCore(USB_OTG_CORE_HANDLE *pdev,
+ USB_OTG_CORE_ID_TypeDef coreID)
+{
+ uint32_t i , baseAddress = 0;
+ USB_OTG_STS status = USB_OTG_OK;
+
+ pdev->cfg.dma_enable = 0;
+
+ /* at startup the core is in FS mode */
+ pdev->cfg.speed = USB_OTG_SPEED_FULL;
+ pdev->cfg.mps = USB_OTG_FS_MAX_PACKET_SIZE ;
+
+ /* initialize device cfg following its address */
+ if (coreID == USB_OTG_FS_CORE_ID)
+ {
+ baseAddress = USB_OTG_FS_BASE_ADDR;
+ pdev->cfg.coreID = USB_OTG_FS_CORE_ID;
+ pdev->cfg.host_channels = 8 ;
+ pdev->cfg.dev_endpoints = 4 ;
+ pdev->cfg.TotalFifoSize = 320; /* in 32-bits */
+ pdev->cfg.phy_itface = USB_OTG_EMBEDDED_PHY;
+
+#ifdef USB_OTG_FS_SOF_OUTPUT_ENABLED
+ pdev->cfg.Sof_output = 1;
+#endif
+
+#ifdef USB_OTG_FS_LOW_PWR_MGMT_SUPPORT
+ pdev->cfg.low_power = 1;
+#endif
+ }
+ else if (coreID == USB_OTG_HS_CORE_ID)
+ {
+ baseAddress = USB_OTG_HS_BASE_ADDR;
+ pdev->cfg.coreID = USB_OTG_HS_CORE_ID;
+ pdev->cfg.host_channels = 12 ;
+ pdev->cfg.dev_endpoints = 6 ;
+ pdev->cfg.TotalFifoSize = 1280;/* in 32-bits */
+
+#ifdef USB_OTG_ULPI_PHY_ENABLED
+ pdev->cfg.phy_itface = USB_OTG_ULPI_PHY;
+#else
+#ifdef USB_OTG_EMBEDDED_PHY_ENABLED
+ pdev->cfg.phy_itface = USB_OTG_EMBEDDED_PHY;
+#endif
+#endif
+
+#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
+ pdev->cfg.dma_enable = 1;
+#endif
+
+#ifdef USB_OTG_HS_SOF_OUTPUT_ENABLED
+ pdev->cfg.Sof_output = 1;
+#endif
+
+#ifdef USB_OTG_HS_LOW_PWR_MGMT_SUPPORT
+ pdev->cfg.low_power = 1;
+#endif
+
+ }
+
+ pdev->regs.GREGS = (USB_OTG_GREGS *)(baseAddress + \
+ USB_OTG_CORE_GLOBAL_REGS_OFFSET);
+ pdev->regs.DREGS = (USB_OTG_DREGS *) (baseAddress + \
+ USB_OTG_DEV_GLOBAL_REG_OFFSET);
+
+ for (i = 0; i < pdev->cfg.dev_endpoints; i++)
+ {
+ pdev->regs.INEP_REGS[i] = (USB_OTG_INEPREGS *) \
+ (baseAddress + USB_OTG_DEV_IN_EP_REG_OFFSET + \
+ (i * USB_OTG_EP_REG_OFFSET));
+ pdev->regs.OUTEP_REGS[i] = (USB_OTG_OUTEPREGS *) \
+ (baseAddress + USB_OTG_DEV_OUT_EP_REG_OFFSET + \
+ (i * USB_OTG_EP_REG_OFFSET));
+ }
+ pdev->regs.HREGS = (USB_OTG_HREGS *)(baseAddress + \
+ USB_OTG_HOST_GLOBAL_REG_OFFSET);
+ pdev->regs.HPRT0 = (uint32_t *)(baseAddress + USB_OTG_HOST_PORT_REGS_OFFSET);
+
+ for (i = 0; i < pdev->cfg.host_channels; i++)
+ {
+ pdev->regs.HC_REGS[i] = (USB_OTG_HC_REGS *)(baseAddress + \
+ USB_OTG_HOST_CHAN_REGS_OFFSET + \
+ (i * USB_OTG_CHAN_REGS_OFFSET));
+ }
+ for (i = 0; i < pdev->cfg.host_channels; i++)
+ {
+ pdev->regs.DFIFO[i] = (uint32_t *)(baseAddress + USB_OTG_DATA_FIFO_OFFSET +\
+ (i * USB_OTG_DATA_FIFO_SIZE));
+ }
+ pdev->regs.PCGCCTL = (uint32_t *)(baseAddress + USB_OTG_PCGCCTL_OFFSET);
+
+ return status;
+}
+
+
+/**
+* @brief USB_OTG_CoreInit
+* Initializes the USB_OTG controller registers and prepares the core
+* device mode or host mode operation.
+* @param pdev : Selected device
+* @retval USB_OTG_STS : status
+*/
+USB_OTG_STS USB_OTG_CoreInit(USB_OTG_CORE_HANDLE *pdev)
+{
+ USB_OTG_STS status = USB_OTG_OK;
+ USB_OTG_GUSBCFG_TypeDef usbcfg;
+ USB_OTG_GCCFG_TypeDef gccfg;
+ USB_OTG_GAHBCFG_TypeDef ahbcfg;
+
+ usbcfg.d32 = 0;
+ gccfg.d32 = 0;
+ ahbcfg.d32 = 0;
+
+
+
+ if (pdev->cfg.phy_itface == USB_OTG_ULPI_PHY)
+ {
+ gccfg.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GCCFG);
+ gccfg.b.pwdn = 0;
+
+ if (pdev->cfg.Sof_output)
+ {
+ gccfg.b.sofouten = 1;
+ }
+ USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GCCFG, gccfg.d32);
+
+ /* Init The ULPI Interface */
+ usbcfg.d32 = 0;
+ usbcfg.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GUSBCFG);
+
+ usbcfg.b.physel = 0; /* HS Interface */
+#ifdef USB_OTG_INTERNAL_VBUS_ENABLED
+ usbcfg.b.ulpi_ext_vbus_drv = 0; /* Use internal VBUS */
+#else
+#ifdef USB_OTG_EXTERNAL_VBUS_ENABLED
+ usbcfg.b.ulpi_ext_vbus_drv = 1; /* Use external VBUS */
+#endif
+#endif
+ usbcfg.b.term_sel_dl_pulse = 0; /* Data line pulsing using utmi_txvalid */
+
+ usbcfg.b.ulpi_fsls = 0;
+ usbcfg.b.ulpi_clk_sus_m = 0;
+ USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GUSBCFG, usbcfg.d32);
+
+ /* Reset after a PHY select */
+ USB_OTG_CoreReset(pdev);
+
+ if(pdev->cfg.dma_enable == 1)
+ {
+
+ ahbcfg.b.hburstlen = 5; /* 64 x 32-bits*/
+ ahbcfg.b.dmaenable = 1;
+ USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GAHBCFG, ahbcfg.d32);
+
+ }
+ }
+ else /* FS interface (embedded Phy) */
+ {
+
+ usbcfg.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GUSBCFG);;
+ usbcfg.b.physel = 1; /* FS Interface */
+ USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GUSBCFG, usbcfg.d32);
+ /* Reset after a PHY select and set Host mode */
+ USB_OTG_CoreReset(pdev);
+ /* Deactivate the power down*/
+ gccfg.d32 = 0;
+ gccfg.b.pwdn = 1;
+
+ gccfg.b.vbussensingA = 1 ;
+ gccfg.b.vbussensingB = 1 ;
+#ifndef VBUS_SENSING_ENABLED
+ gccfg.b.disablevbussensing = 1;
+#endif
+
+ if(pdev->cfg.Sof_output)
+ {
+ gccfg.b.sofouten = 1;
+ }
+
+ USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GCCFG, gccfg.d32);
+ USB_OTG_BSP_mDelay(20);
+ }
+ /* case the HS core is working in FS mode */
+ if(pdev->cfg.dma_enable == 1)
+ {
+
+ ahbcfg.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GAHBCFG);
+ ahbcfg.b.hburstlen = 5; /* 64 x 32-bits*/
+ ahbcfg.b.dmaenable = 1;
+ USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GAHBCFG, ahbcfg.d32);
+
+ }
+ /* initialize OTG features */
+#ifdef USE_OTG_MODE
+ usbcfg.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GUSBCFG);
+ usbcfg.b.hnpcap = 1;
+ usbcfg.b.srpcap = 1;
+ USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GUSBCFG, usbcfg.d32);
+ USB_OTG_EnableCommonInt(pdev);
+#endif
+ return status;
+}
+/**
+* @brief USB_OTG_EnableGlobalInt
+* Enables the controller's Global Int in the AHB Config reg
+* @param pdev : Selected device
+* @retval USB_OTG_STS : status
+*/
+USB_OTG_STS USB_OTG_EnableGlobalInt(USB_OTG_CORE_HANDLE *pdev)
+{
+ USB_OTG_STS status = USB_OTG_OK;
+ USB_OTG_GAHBCFG_TypeDef ahbcfg;
+
+ ahbcfg.d32 = 0;
+ ahbcfg.b.glblintrmsk = 1; /* Enable interrupts */
+ USB_OTG_MODIFY_REG32(&pdev->regs.GREGS->GAHBCFG, 0, ahbcfg.d32);
+ return status;
+}
+
+
+/**
+* @brief USB_OTG_DisableGlobalInt
+* Enables the controller's Global Int in the AHB Config reg
+* @param pdev : Selected device
+* @retval USB_OTG_STS : status
+*/
+USB_OTG_STS USB_OTG_DisableGlobalInt(USB_OTG_CORE_HANDLE *pdev)
+{
+ USB_OTG_STS status = USB_OTG_OK;
+ USB_OTG_GAHBCFG_TypeDef ahbcfg;
+ ahbcfg.d32 = 0;
+ ahbcfg.b.glblintrmsk = 1; /* Enable interrupts */
+ USB_OTG_MODIFY_REG32(&pdev->regs.GREGS->GAHBCFG, ahbcfg.d32, 0);
+ return status;
+}
+
+
+/**
+* @brief USB_OTG_FlushTxFifo : Flush a Tx FIFO
+* @param pdev : Selected device
+* @param num : FO num
+* @retval USB_OTG_STS : status
+*/
+USB_OTG_STS USB_OTG_FlushTxFifo (USB_OTG_CORE_HANDLE *pdev , uint32_t num )
+{
+ USB_OTG_STS status = USB_OTG_OK;
+ __IO USB_OTG_GRSTCTL_TypeDef greset;
+
+ uint32_t count = 0;
+ greset.d32 = 0;
+ greset.b.txfflsh = 1;
+ greset.b.txfnum = num;
+ USB_OTG_WRITE_REG32( &pdev->regs.GREGS->GRSTCTL, greset.d32 );
+ do
+ {
+ greset.d32 = USB_OTG_READ_REG32( &pdev->regs.GREGS->GRSTCTL);
+ if (++count > 200000)
+ {
+ break;
+ }
+ }
+ while (greset.b.txfflsh == 1);
+ /* Wait for 3 PHY Clocks*/
+ USB_OTG_BSP_uDelay(3);
+ return status;
+}
+
+
+/**
+* @brief USB_OTG_FlushRxFifo : Flush a Rx FIFO
+* @param pdev : Selected device
+* @retval USB_OTG_STS : status
+*/
+USB_OTG_STS USB_OTG_FlushRxFifo( USB_OTG_CORE_HANDLE *pdev )
+{
+ USB_OTG_STS status = USB_OTG_OK;
+ __IO USB_OTG_GRSTCTL_TypeDef greset;
+ uint32_t count = 0;
+
+ greset.d32 = 0;
+ greset.b.rxfflsh = 1;
+ USB_OTG_WRITE_REG32( &pdev->regs.GREGS->GRSTCTL, greset.d32 );
+ do
+ {
+ greset.d32 = USB_OTG_READ_REG32( &pdev->regs.GREGS->GRSTCTL);
+ if (++count > 200000)
+ {
+ break;
+ }
+ }
+ while (greset.b.rxfflsh == 1);
+ /* Wait for 3 PHY Clocks*/
+ USB_OTG_BSP_uDelay(3);
+ return status;
+}
+
+
+/**
+* @brief USB_OTG_SetCurrentMode : Set ID line
+* @param pdev : Selected device
+* @param mode : (Host/device)
+* @retval USB_OTG_STS : status
+*/
+USB_OTG_STS USB_OTG_SetCurrentMode(USB_OTG_CORE_HANDLE *pdev , uint8_t mode)
+{
+ USB_OTG_STS status = USB_OTG_OK;
+ USB_OTG_GUSBCFG_TypeDef usbcfg;
+
+ usbcfg.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GUSBCFG);
+
+ usbcfg.b.force_host = 0;
+ usbcfg.b.force_dev = 0;
+
+ if ( mode == HOST_MODE)
+ {
+ usbcfg.b.force_host = 1;
+ }
+ else if ( mode == DEVICE_MODE)
+ {
+ usbcfg.b.force_dev = 1;
+ }
+
+ USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GUSBCFG, usbcfg.d32);
+ USB_OTG_BSP_mDelay(50);
+ return status;
+}
+
+
+/**
+* @brief USB_OTG_GetMode : Get current mode
+* @param pdev : Selected device
+* @retval current mode
+*/
+uint32_t USB_OTG_GetMode(USB_OTG_CORE_HANDLE *pdev)
+{
+ return (USB_OTG_READ_REG32(&pdev->regs.GREGS->GINTSTS ) & 0x1);
+}
+
+
+/**
+* @brief USB_OTG_IsDeviceMode : Check if it is device mode
+* @param pdev : Selected device
+* @retval num_in_ep
+*/
+uint8_t USB_OTG_IsDeviceMode(USB_OTG_CORE_HANDLE *pdev)
+{
+ return (USB_OTG_GetMode(pdev) != HOST_MODE);
+}
+
+
+/**
+* @brief USB_OTG_IsHostMode : Check if it is host mode
+* @param pdev : Selected device
+* @retval num_in_ep
+*/
+uint8_t USB_OTG_IsHostMode(USB_OTG_CORE_HANDLE *pdev)
+{
+ return (USB_OTG_GetMode(pdev) == HOST_MODE);
+}
+
+
+/**
+* @brief USB_OTG_ReadCoreItr : returns the Core Interrupt register
+* @param pdev : Selected device
+* @retval Status
+*/
+uint32_t USB_OTG_ReadCoreItr(USB_OTG_CORE_HANDLE *pdev)
+{
+ uint32_t v = 0;
+ v = USB_OTG_READ_REG32(&pdev->regs.GREGS->GINTSTS);
+ v &= USB_OTG_READ_REG32(&pdev->regs.GREGS->GINTMSK);
+ return v;
+}
+
+
+/**
+* @brief USB_OTG_ReadOtgItr : returns the USB_OTG Interrupt register
+* @param pdev : Selected device
+* @retval Status
+*/
+uint32_t USB_OTG_ReadOtgItr (USB_OTG_CORE_HANDLE *pdev)
+{
+ return (USB_OTG_READ_REG32 (&pdev->regs.GREGS->GOTGINT));
+}
+
+#ifdef USE_HOST_MODE
+/**
+* @brief USB_OTG_CoreInitHost : Initializes USB_OTG controller for host mode
+* @param pdev : Selected device
+* @retval status
+*/
+USB_OTG_STS USB_OTG_CoreInitHost(USB_OTG_CORE_HANDLE *pdev)
+{
+ USB_OTG_STS status = USB_OTG_OK;
+ USB_OTG_FSIZ_TypeDef nptxfifosize;
+ USB_OTG_FSIZ_TypeDef ptxfifosize;
+ USB_OTG_HCFG_TypeDef hcfg;
+
+#ifdef USE_OTG_MODE
+ USB_OTG_OTGCTL_TypeDef gotgctl;
+#endif
+
+ uint32_t i = 0;
+
+ nptxfifosize.d32 = 0;
+ ptxfifosize.d32 = 0;
+#ifdef USE_OTG_MODE
+ gotgctl.d32 = 0;
+#endif
+ hcfg.d32 = 0;
+
+
+ /* configure charge pump IO */
+ USB_OTG_BSP_ConfigVBUS(pdev);
+
+ /* Restart the Phy Clock */
+ USB_OTG_WRITE_REG32(pdev->regs.PCGCCTL, 0);
+
+ /* Initialize Host Configuration Register */
+ if (pdev->cfg.phy_itface == USB_OTG_ULPI_PHY)
+ {
+ USB_OTG_InitFSLSPClkSel(pdev , HCFG_30_60_MHZ);
+ }
+ else
+ {
+ USB_OTG_InitFSLSPClkSel(pdev , HCFG_48_MHZ);
+ }
+ USB_OTG_ResetPort(pdev);
+
+ hcfg.d32 = USB_OTG_READ_REG32(&pdev->regs.HREGS->HCFG);
+ hcfg.b.fslssupp = 0;
+ USB_OTG_WRITE_REG32(&pdev->regs.HREGS->HCFG, hcfg.d32);
+
+ /* Configure data FIFO sizes */
+ /* Rx FIFO */
+#ifdef USB_OTG_FS_CORE
+ if(pdev->cfg.coreID == USB_OTG_FS_CORE_ID)
+ {
+ /* set Rx FIFO size */
+ USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GRXFSIZ, RX_FIFO_FS_SIZE);
+ nptxfifosize.b.startaddr = RX_FIFO_FS_SIZE;
+ nptxfifosize.b.depth = TXH_NP_FS_FIFOSIZ;
+ USB_OTG_WRITE_REG32(&pdev->regs.GREGS->DIEPTXF0_HNPTXFSIZ, nptxfifosize.d32);
+
+ ptxfifosize.b.startaddr = RX_FIFO_FS_SIZE + TXH_NP_FS_FIFOSIZ;
+ ptxfifosize.b.depth = TXH_P_FS_FIFOSIZ;
+ USB_OTG_WRITE_REG32(&pdev->regs.GREGS->HPTXFSIZ, ptxfifosize.d32);
+ }
+#endif
+#ifdef USB_OTG_HS_CORE
+ if (pdev->cfg.coreID == USB_OTG_HS_CORE_ID)
+ {
+ /* set Rx FIFO size */
+ USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GRXFSIZ, RX_FIFO_HS_SIZE);
+ nptxfifosize.b.startaddr = RX_FIFO_HS_SIZE;
+ nptxfifosize.b.depth = TXH_NP_HS_FIFOSIZ;
+ USB_OTG_WRITE_REG32(&pdev->regs.GREGS->DIEPTXF0_HNPTXFSIZ, nptxfifosize.d32);
+
+ ptxfifosize.b.startaddr = RX_FIFO_HS_SIZE + TXH_NP_HS_FIFOSIZ;
+ ptxfifosize.b.depth = TXH_P_HS_FIFOSIZ;
+ USB_OTG_WRITE_REG32(&pdev->regs.GREGS->HPTXFSIZ, ptxfifosize.d32);
+ }
+#endif
+
+#ifdef USE_OTG_MODE
+ /* Clear Host Set HNP Enable in the USB_OTG Control Register */
+ gotgctl.b.hstsethnpen = 1;
+ USB_OTG_MODIFY_REG32( &pdev->regs.GREGS->GOTGCTL, gotgctl.d32, 0);
+#endif
+
+ /* Make sure the FIFOs are flushed. */
+ USB_OTG_FlushTxFifo(pdev, 0x10 ); /* all Tx FIFOs */
+ USB_OTG_FlushRxFifo(pdev);
+
+
+ /* Clear all pending HC Interrupts */
+ for (i = 0; i < pdev->cfg.host_channels; i++)
+ {
+ USB_OTG_WRITE_REG32( &pdev->regs.HC_REGS[i]->HCINT, 0xFFFFFFFF );
+ USB_OTG_WRITE_REG32( &pdev->regs.HC_REGS[i]->HCINTMSK, 0 );
+ }
+#ifndef USE_OTG_MODE
+ USB_OTG_DriveVbus(pdev, 1);
+#endif
+
+ USB_OTG_EnableHostInt(pdev);
+ return status;
+}
+
+/**
+* @brief USB_OTG_IsEvenFrame
+* This function returns the frame number for sof packet
+* @param pdev : Selected device
+* @retval Frame number
+*/
+uint8_t USB_OTG_IsEvenFrame (USB_OTG_CORE_HANDLE *pdev)
+{
+ return !(USB_OTG_READ_REG32(&pdev->regs.HREGS->HFNUM) & 0x1);
+}
+
+/**
+* @brief USB_OTG_DriveVbus : set/reset vbus
+* @param pdev : Selected device
+* @param state : VBUS state
+* @retval None
+*/
+void USB_OTG_DriveVbus (USB_OTG_CORE_HANDLE *pdev, uint8_t state)
+{
+ USB_OTG_HPRT0_TypeDef hprt0;
+
+ hprt0.d32 = 0;
+
+ /* enable disable the external charge pump */
+ USB_OTG_BSP_DriveVBUS(pdev, state);
+
+ /* Turn on the Host port power. */
+ hprt0.d32 = USB_OTG_ReadHPRT0(pdev);
+ if ((hprt0.b.prtpwr == 0 ) && (state == 1 ))
+ {
+ hprt0.b.prtpwr = 1;
+ USB_OTG_WRITE_REG32(pdev->regs.HPRT0, hprt0.d32);
+ }
+ if ((hprt0.b.prtpwr == 1 ) && (state == 0 ))
+ {
+ hprt0.b.prtpwr = 0;
+ USB_OTG_WRITE_REG32(pdev->regs.HPRT0, hprt0.d32);
+ }
+
+ USB_OTG_BSP_mDelay(200);
+}
+/**
+* @brief USB_OTG_EnableHostInt: Enables the Host mode interrupts
+* @param pdev : Selected device
+* @retval USB_OTG_STS : status
+*/
+USB_OTG_STS USB_OTG_EnableHostInt(USB_OTG_CORE_HANDLE *pdev)
+{
+ USB_OTG_STS status = USB_OTG_OK;
+ USB_OTG_GINTMSK_TypeDef intmsk;
+ intmsk.d32 = 0;
+ /* Disable all interrupts. */
+ USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GINTMSK, 0);
+
+ /* Clear any pending interrupts. */
+ USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GINTSTS, 0xFFFFFFFF);
+
+ /* Enable the common interrupts */
+ USB_OTG_EnableCommonInt(pdev);
+
+ if (pdev->cfg.dma_enable == 0)
+ {
+ intmsk.b.rxstsqlvl = 1;
+ }
+ intmsk.b.portintr = 1;
+ intmsk.b.hcintr = 1;
+ intmsk.b.disconnect = 1;
+ intmsk.b.sofintr = 1;
+ intmsk.b.incomplisoout = 1;
+ USB_OTG_MODIFY_REG32(&pdev->regs.GREGS->GINTMSK, intmsk.d32, intmsk.d32);
+ return status;
+}
+
+/**
+* @brief USB_OTG_InitFSLSPClkSel : Initializes the FSLSPClkSel field of the
+* HCFG register on the PHY type
+* @param pdev : Selected device
+* @param freq : clock frequency
+* @retval None
+*/
+void USB_OTG_InitFSLSPClkSel(USB_OTG_CORE_HANDLE *pdev , uint8_t freq)
+{
+ USB_OTG_HCFG_TypeDef hcfg;
+
+ hcfg.d32 = USB_OTG_READ_REG32(&pdev->regs.HREGS->HCFG);
+ hcfg.b.fslspclksel = freq;
+ USB_OTG_WRITE_REG32(&pdev->regs.HREGS->HCFG, hcfg.d32);
+}
+
+
+/**
+* @brief USB_OTG_ReadHPRT0 : Reads HPRT0 to modify later
+* @param pdev : Selected device
+* @retval HPRT0 value
+*/
+uint32_t USB_OTG_ReadHPRT0(USB_OTG_CORE_HANDLE *pdev)
+{
+ USB_OTG_HPRT0_TypeDef hprt0;
+
+ hprt0.d32 = USB_OTG_READ_REG32(pdev->regs.HPRT0);
+ hprt0.b.prtena = 0;
+ hprt0.b.prtconndet = 0;
+ hprt0.b.prtenchng = 0;
+ hprt0.b.prtovrcurrchng = 0;
+ return hprt0.d32;
+}
+
+
+/**
+* @brief USB_OTG_ReadHostAllChannels_intr : Register PCD Callbacks
+* @param pdev : Selected device
+* @retval Status
+*/
+uint32_t USB_OTG_ReadHostAllChannels_intr (USB_OTG_CORE_HANDLE *pdev)
+{
+ return (USB_OTG_READ_REG32 (&pdev->regs.HREGS->HAINT));
+}
+
+
+/**
+* @brief USB_OTG_ResetPort : Reset Host Port
+* @param pdev : Selected device
+* @retval status
+* @note : (1)The application must wait at least 10 ms (+ 10 ms security)
+* before clearing the reset bit.
+*/
+uint32_t USB_OTG_ResetPort(USB_OTG_CORE_HANDLE *pdev)
+{
+ USB_OTG_HPRT0_TypeDef hprt0;
+
+ hprt0.d32 = USB_OTG_ReadHPRT0(pdev);
+ hprt0.b.prtrst = 1;
+ USB_OTG_WRITE_REG32(pdev->regs.HPRT0, hprt0.d32);
+ USB_OTG_BSP_mDelay (10); /* See Note #1 */
+ hprt0.b.prtrst = 0;
+ USB_OTG_WRITE_REG32(pdev->regs.HPRT0, hprt0.d32);
+ USB_OTG_BSP_mDelay (20);
+ return 1;
+}
+
+
+/**
+* @brief USB_OTG_HC_Init : Prepares a host channel for transferring packets
+* @param pdev : Selected device
+* @param hc_num : channel number
+* @retval USB_OTG_STS : status
+*/
+USB_OTG_STS USB_OTG_HC_Init(USB_OTG_CORE_HANDLE *pdev , uint8_t hc_num)
+{
+ USB_OTG_STS status = USB_OTG_OK;
+ uint32_t intr_enable = 0;
+ USB_OTG_HCINTMSK_TypeDef hcintmsk;
+ USB_OTG_GINTMSK_TypeDef gintmsk;
+ USB_OTG_HCCHAR_TypeDef hcchar;
+ USB_OTG_HCINTn_TypeDef hcint;
+
+
+ gintmsk.d32 = 0;
+ hcintmsk.d32 = 0;
+ hcchar.d32 = 0;
+
+ /* Clear old interrupt conditions for this host channel. */
+ hcint.d32 = 0xFFFFFFFF;
+ USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCINT, hcint.d32);
+
+ /* Enable channel interrupts required for this transfer. */
+ hcintmsk.d32 = 0;
+
+ if (pdev->cfg.dma_enable == 1)
+ {
+ hcintmsk.b.ahberr = 1;
+ }
+
+ switch (pdev->host.hc[hc_num].ep_type)
+ {
+ case EP_TYPE_CTRL:
+ case EP_TYPE_BULK:
+ hcintmsk.b.xfercompl = 1;
+ hcintmsk.b.stall = 1;
+ hcintmsk.b.xacterr = 1;
+ hcintmsk.b.datatglerr = 1;
+ hcintmsk.b.nak = 1;
+ if (pdev->host.hc[hc_num].ep_is_in)
+ {
+ hcintmsk.b.bblerr = 1;
+ }
+ else
+ {
+ hcintmsk.b.nyet = 1;
+ if (pdev->host.hc[hc_num].do_ping)
+ {
+ hcintmsk.b.ack = 1;
+ }
+ }
+ break;
+ case EP_TYPE_INTR:
+ hcintmsk.b.xfercompl = 1;
+ hcintmsk.b.nak = 1;
+ hcintmsk.b.stall = 1;
+ hcintmsk.b.xacterr = 1;
+ hcintmsk.b.datatglerr = 1;
+ hcintmsk.b.frmovrun = 1;
+
+ if (pdev->host.hc[hc_num].ep_is_in)
+ {
+ hcintmsk.b.bblerr = 1;
+ }
+
+ break;
+ case EP_TYPE_ISOC:
+ hcintmsk.b.xfercompl = 1;
+ hcintmsk.b.frmovrun = 1;
+ hcintmsk.b.ack = 1;
+
+ if (pdev->host.hc[hc_num].ep_is_in)
+ {
+ hcintmsk.b.xacterr = 1;
+ hcintmsk.b.bblerr = 1;
+ }
+ break;
+ }
+
+
+ USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCINTMSK, hcintmsk.d32);
+
+
+ /* Enable the top level host channel interrupt. */
+ intr_enable = (1 << hc_num);
+ USB_OTG_MODIFY_REG32(&pdev->regs.HREGS->HAINTMSK, 0, intr_enable);
+
+ /* Make sure host channel interrupts are enabled. */
+ gintmsk.b.hcintr = 1;
+ USB_OTG_MODIFY_REG32(&pdev->regs.GREGS->GINTMSK, 0, gintmsk.d32);
+
+ /* Program the HCCHAR register */
+ hcchar.d32 = 0;
+ hcchar.b.devaddr = pdev->host.hc[hc_num].dev_addr;
+ hcchar.b.epnum = pdev->host.hc[hc_num].ep_num;
+ hcchar.b.epdir = pdev->host.hc[hc_num].ep_is_in;
+ hcchar.b.lspddev = (pdev->host.hc[hc_num].speed == HPRT0_PRTSPD_LOW_SPEED);
+ hcchar.b.eptype = pdev->host.hc[hc_num].ep_type;
+ hcchar.b.mps = pdev->host.hc[hc_num].max_packet;
+ if (pdev->host.hc[hc_num].ep_type == HCCHAR_INTR)
+ {
+ hcchar.b.oddfrm = 1;
+ }
+ USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCCHAR, hcchar.d32);
+ return status;
+}
+
+
+/**
+* @brief USB_OTG_HC_StartXfer : Start transfer
+* @param pdev : Selected device
+* @param hc_num : channel number
+* @retval USB_OTG_STS : status
+*/
+USB_OTG_STS USB_OTG_HC_StartXfer(USB_OTG_CORE_HANDLE *pdev , uint8_t hc_num)
+{
+ USB_OTG_STS status = USB_OTG_OK;
+ USB_OTG_HCCHAR_TypeDef hcchar;
+ USB_OTG_HCTSIZn_TypeDef hctsiz;
+ USB_OTG_HNPTXSTS_TypeDef hnptxsts;
+ USB_OTG_HPTXSTS_TypeDef hptxsts;
+ USB_OTG_GINTMSK_TypeDef intmsk;
+ uint16_t len_words = 0;
+
+ uint16_t num_packets;
+ uint16_t max_hc_pkt_count;
+
+ max_hc_pkt_count = 256;
+ hctsiz.d32 = 0;
+ hcchar.d32 = 0;
+ intmsk.d32 = 0;
+
+ /* Compute the expected number of packets associated to the transfer */
+ if (pdev->host.hc[hc_num].xfer_len > 0)
+ {
+ num_packets = (pdev->host.hc[hc_num].xfer_len + \
+ pdev->host.hc[hc_num].max_packet - 1) / pdev->host.hc[hc_num].max_packet;
+
+ if (num_packets > max_hc_pkt_count)
+ {
+ num_packets = max_hc_pkt_count;
+ pdev->host.hc[hc_num].xfer_len = num_packets * \
+ pdev->host.hc[hc_num].max_packet;
+ }
+ }
+ else
+ {
+ num_packets = 1;
+ }
+ if (pdev->host.hc[hc_num].ep_is_in)
+ {
+ pdev->host.hc[hc_num].xfer_len = num_packets * \
+ pdev->host.hc[hc_num].max_packet;
+ }
+ /* Initialize the HCTSIZn register */
+ hctsiz.b.xfersize = pdev->host.hc[hc_num].xfer_len;
+ hctsiz.b.pktcnt = num_packets;
+ hctsiz.b.pid = pdev->host.hc[hc_num].data_pid;
+ USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCTSIZ, hctsiz.d32);
+
+ if (pdev->cfg.dma_enable == 1)
+ {
+ USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCDMA, (unsigned int)pdev->host.hc[hc_num].xfer_buff);
+ }
+
+
+ hcchar.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[hc_num]->HCCHAR);
+ hcchar.b.oddfrm = USB_OTG_IsEvenFrame(pdev);
+
+ /* Set host channel enable */
+ hcchar.b.chen = 1;
+ hcchar.b.chdis = 0;
+ USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCCHAR, hcchar.d32);
+
+ if (pdev->cfg.dma_enable == 0) /* Slave mode */
+ {
+ if((pdev->host.hc[hc_num].ep_is_in == 0) &&
+ (pdev->host.hc[hc_num].xfer_len > 0))
+ {
+ switch(pdev->host.hc[hc_num].ep_type)
+ {
+ /* Non periodic transfer */
+ case EP_TYPE_CTRL:
+ case EP_TYPE_BULK:
+
+ hnptxsts.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->HNPTXSTS);
+ len_words = (pdev->host.hc[hc_num].xfer_len + 3) / 4;
+
+ /* check if there is enough space in FIFO space */
+ if(len_words > hnptxsts.b.nptxfspcavail)
+ {
+ /* need to process data in nptxfempty interrupt */
+ intmsk.b.nptxfempty = 1;
+ USB_OTG_MODIFY_REG32( &pdev->regs.GREGS->GINTMSK, 0, intmsk.d32);
+ }
+
+ break;
+ /* Periodic transfer */
+ case EP_TYPE_INTR:
+ case EP_TYPE_ISOC:
+ hptxsts.d32 = USB_OTG_READ_REG32(&pdev->regs.HREGS->HPTXSTS);
+ len_words = (pdev->host.hc[hc_num].xfer_len + 3) / 4;
+ /* check if there is enough space in FIFO space */
+ if(len_words > hptxsts.b.ptxfspcavail) /* split the transfer */
+ {
+ /* need to process data in ptxfempty interrupt */
+ intmsk.b.ptxfempty = 1;
+ USB_OTG_MODIFY_REG32( &pdev->regs.GREGS->GINTMSK, 0, intmsk.d32);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ /* Write packet into the Tx FIFO. */
+ USB_OTG_WritePacket(pdev,
+ pdev->host.hc[hc_num].xfer_buff ,
+ hc_num, pdev->host.hc[hc_num].xfer_len);
+ }
+ }
+ return status;
+}
+
+
+/**
+* @brief USB_OTG_HC_Halt : Halt channel
+* @param pdev : Selected device
+* @param hc_num : channel number
+* @retval USB_OTG_STS : status
+*/
+USB_OTG_STS USB_OTG_HC_Halt(USB_OTG_CORE_HANDLE *pdev , uint8_t hc_num)
+{
+ USB_OTG_STS status = USB_OTG_OK;
+ USB_OTG_HNPTXSTS_TypeDef nptxsts;
+ USB_OTG_HPTXSTS_TypeDef hptxsts;
+ USB_OTG_HCCHAR_TypeDef hcchar;
+
+ nptxsts.d32 = 0;
+ hptxsts.d32 = 0;
+ hcchar.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[hc_num]->HCCHAR);
+ hcchar.b.chen = 1;
+ hcchar.b.chdis = 1;
+
+ /* Check for space in the request queue to issue the halt. */
+ if (hcchar.b.eptype == HCCHAR_CTRL || hcchar.b.eptype == HCCHAR_BULK)
+ {
+ nptxsts.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->HNPTXSTS);
+ if (nptxsts.b.nptxqspcavail == 0)
+ {
+ hcchar.b.chen = 0;
+ }
+ }
+ else
+ {
+ hptxsts.d32 = USB_OTG_READ_REG32(&pdev->regs.HREGS->HPTXSTS);
+ if (hptxsts.b.ptxqspcavail == 0)
+ {
+ hcchar.b.chen = 0;
+ }
+ }
+ USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCCHAR, hcchar.d32);
+ return status;
+}
+
+/**
+* @brief Issue a ping token
+* @param None
+* @retval : None
+*/
+USB_OTG_STS USB_OTG_HC_DoPing(USB_OTG_CORE_HANDLE *pdev , uint8_t hc_num)
+{
+ USB_OTG_STS status = USB_OTG_OK;
+ USB_OTG_HCCHAR_TypeDef hcchar;
+ USB_OTG_HCTSIZn_TypeDef hctsiz;
+
+ hctsiz.d32 = 0;
+ hctsiz.b.dopng = 1;
+ hctsiz.b.pktcnt = 1;
+ USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCTSIZ, hctsiz.d32);
+
+ hcchar.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[hc_num]->HCCHAR);
+ hcchar.b.chen = 1;
+ hcchar.b.chdis = 0;
+ USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCCHAR, hcchar.d32);
+ return status;
+}
+
+/**
+* @brief Stop the device and clean up fifo's
+* @param None
+* @retval : None
+*/
+void USB_OTG_StopHost(USB_OTG_CORE_HANDLE *pdev)
+{
+ USB_OTG_HCCHAR_TypeDef hcchar;
+ uint32_t i;
+
+ USB_OTG_WRITE_REG32(&pdev->regs.HREGS->HAINTMSK , 0);
+ USB_OTG_WRITE_REG32(&pdev->regs.HREGS->HAINT, 0xFFFFFFFF);
+ /* Flush out any leftover queued requests. */
+
+ for (i = 0; i < pdev->cfg.host_channels; i++)
+ {
+ hcchar.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[i]->HCCHAR);
+ hcchar.b.chen = 0;
+ hcchar.b.chdis = 1;
+ hcchar.b.epdir = 0;
+ USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[i]->HCCHAR, hcchar.d32);
+ }
+
+ /* Flush the FIFO */
+ USB_OTG_FlushRxFifo(pdev);
+ USB_OTG_FlushTxFifo(pdev , 0x10 );
+}
+#endif
+#ifdef USE_DEVICE_MODE
+/* PCD Core Layer */
+
+/**
+* @brief USB_OTG_InitDevSpeed :Initializes the DevSpd field of DCFG register
+* depending the PHY type and the enumeration speed of the device.
+* @param pdev : Selected device
+* @retval : None
+*/
+void USB_OTG_InitDevSpeed(USB_OTG_CORE_HANDLE *pdev , uint8_t speed)
+{
+ USB_OTG_DCFG_TypeDef dcfg;
+
+ dcfg.d32 = USB_OTG_READ_REG32(&pdev->regs.DREGS->DCFG);
+ dcfg.b.devspd = speed;
+ USB_OTG_WRITE_REG32(&pdev->regs.DREGS->DCFG, dcfg.d32);
+}
+
+
+/**
+* @brief USB_OTG_CoreInitDev : Initializes the USB_OTG controller registers
+* for device mode
+* @param pdev : Selected device
+* @retval USB_OTG_STS : status
+*/
+USB_OTG_STS USB_OTG_CoreInitDev (USB_OTG_CORE_HANDLE *pdev)
+{
+ USB_OTG_STS status = USB_OTG_OK;
+ USB_OTG_DEPCTL_TypeDef depctl;
+ uint32_t i;
+ USB_OTG_DCFG_TypeDef dcfg;
+ USB_OTG_FSIZ_TypeDef nptxfifosize;
+ USB_OTG_FSIZ_TypeDef txfifosize;
+ USB_OTG_DIEPMSK_TypeDef msk;
+ USB_OTG_DTHRCTL_TypeDef dthrctl;
+
+ depctl.d32 = 0;
+ dcfg.d32 = 0;
+ nptxfifosize.d32 = 0;
+ txfifosize.d32 = 0;
+ msk.d32 = 0;
+
+ /* Restart the Phy Clock */
+ USB_OTG_WRITE_REG32(pdev->regs.PCGCCTL, 0);
+ /* Device configuration register */
+ dcfg.d32 = USB_OTG_READ_REG32( &pdev->regs.DREGS->DCFG);
+ dcfg.b.perfrint = DCFG_FRAME_INTERVAL_80;
+ USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DCFG, dcfg.d32 );
+
+#ifdef USB_OTG_FS_CORE
+ if(pdev->cfg.coreID == USB_OTG_FS_CORE_ID )
+ {
+
+ /* Set Full speed phy */
+ USB_OTG_InitDevSpeed (pdev , USB_OTG_SPEED_PARAM_FULL);
+
+ /* set Rx FIFO size */
+ USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GRXFSIZ, RX_FIFO_FS_SIZE);
+
+ /* EP0 TX*/
+ nptxfifosize.b.depth = TX0_FIFO_FS_SIZE;
+ nptxfifosize.b.startaddr = RX_FIFO_FS_SIZE;
+ USB_OTG_WRITE_REG32( &pdev->regs.GREGS->DIEPTXF0_HNPTXFSIZ, nptxfifosize.d32 );
+
+
+ /* EP1 TX*/
+ txfifosize.b.startaddr = nptxfifosize.b.startaddr + nptxfifosize.b.depth;
+ txfifosize.b.depth = TX1_FIFO_FS_SIZE;
+ USB_OTG_WRITE_REG32( &pdev->regs.GREGS->DIEPTXF[0], txfifosize.d32 );
+
+
+ /* EP2 TX*/
+ txfifosize.b.startaddr += txfifosize.b.depth;
+ txfifosize.b.depth = TX2_FIFO_FS_SIZE;
+ USB_OTG_WRITE_REG32( &pdev->regs.GREGS->DIEPTXF[1], txfifosize.d32 );
+
+
+ /* EP3 TX*/
+ txfifosize.b.startaddr += txfifosize.b.depth;
+ txfifosize.b.depth = TX3_FIFO_FS_SIZE;
+ USB_OTG_WRITE_REG32( &pdev->regs.GREGS->DIEPTXF[2], txfifosize.d32 );
+ }
+#endif
+#ifdef USB_OTG_HS_CORE
+ if(pdev->cfg.coreID == USB_OTG_HS_CORE_ID )
+ {
+
+ /* Set High speed phy */
+
+ if(pdev->cfg.phy_itface == USB_OTG_ULPI_PHY)
+ {
+ USB_OTG_InitDevSpeed (pdev , USB_OTG_SPEED_PARAM_HIGH);
+ }
+ else /* set High speed phy in Full speed mode */
+ {
+ USB_OTG_InitDevSpeed (pdev , USB_OTG_SPEED_PARAM_HIGH_IN_FULL);
+ }
+
+ /* set Rx FIFO size */
+ USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GRXFSIZ, RX_FIFO_HS_SIZE);
+
+ /* EP0 TX*/
+ nptxfifosize.b.depth = TX0_FIFO_HS_SIZE;
+ nptxfifosize.b.startaddr = RX_FIFO_HS_SIZE;
+ USB_OTG_WRITE_REG32( &pdev->regs.GREGS->DIEPTXF0_HNPTXFSIZ, nptxfifosize.d32 );
+
+
+ /* EP1 TX*/
+ txfifosize.b.startaddr = nptxfifosize.b.startaddr + nptxfifosize.b.depth;
+ txfifosize.b.depth = TX1_FIFO_HS_SIZE;
+ USB_OTG_WRITE_REG32( &pdev->regs.GREGS->DIEPTXF[0], txfifosize.d32 );
+
+
+ /* EP2 TX*/
+ txfifosize.b.startaddr += txfifosize.b.depth;
+ txfifosize.b.depth = TX2_FIFO_HS_SIZE;
+ USB_OTG_WRITE_REG32( &pdev->regs.GREGS->DIEPTXF[1], txfifosize.d32 );
+
+
+ /* EP3 TX*/
+ txfifosize.b.startaddr += txfifosize.b.depth;
+ txfifosize.b.depth = TX3_FIFO_HS_SIZE;
+ USB_OTG_WRITE_REG32( &pdev->regs.GREGS->DIEPTXF[2], txfifosize.d32 );
+
+ /* EP4 TX*/
+ txfifosize.b.startaddr += txfifosize.b.depth;
+ txfifosize.b.depth = TX4_FIFO_HS_SIZE;
+ USB_OTG_WRITE_REG32( &pdev->regs.GREGS->DIEPTXF[3], txfifosize.d32 );
+
+
+ /* EP5 TX*/
+ txfifosize.b.startaddr += txfifosize.b.depth;
+ txfifosize.b.depth = TX5_FIFO_HS_SIZE;
+ USB_OTG_WRITE_REG32( &pdev->regs.GREGS->DIEPTXF[4], txfifosize.d32 );
+ }
+#endif
+ /* Flush the FIFOs */
+ USB_OTG_FlushTxFifo(pdev , 0x10); /* all Tx FIFOs */
+ USB_OTG_FlushRxFifo(pdev);
+ /* Clear all pending Device Interrupts */
+ USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DIEPMSK, 0 );
+ USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DOEPMSK, 0 );
+ USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DAINT, 0xFFFFFFFF );
+ USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DAINTMSK, 0 );
+
+ for (i = 0; i < pdev->cfg.dev_endpoints; i++)
+ {
+ depctl.d32 = USB_OTG_READ_REG32(&pdev->regs.INEP_REGS[i]->DIEPCTL);
+ if (depctl.b.epena)
+ {
+ depctl.d32 = 0;
+ depctl.b.epdis = 1;
+ depctl.b.snak = 1;
+ }
+ else
+ {
+ depctl.d32 = 0;
+ }
+ USB_OTG_WRITE_REG32( &pdev->regs.INEP_REGS[i]->DIEPCTL, depctl.d32);
+ USB_OTG_WRITE_REG32( &pdev->regs.INEP_REGS[i]->DIEPTSIZ, 0);
+ USB_OTG_WRITE_REG32( &pdev->regs.INEP_REGS[i]->DIEPINT, 0xFF);
+ }
+ for (i = 0; i < pdev->cfg.dev_endpoints; i++)
+ {
+ USB_OTG_DEPCTL_TypeDef depctl;
+ depctl.d32 = USB_OTG_READ_REG32(&pdev->regs.OUTEP_REGS[i]->DOEPCTL);
+ if (depctl.b.epena)
+ {
+ depctl.d32 = 0;
+ depctl.b.epdis = 1;
+ depctl.b.snak = 1;
+ }
+ else
+ {
+ depctl.d32 = 0;
+ }
+ USB_OTG_WRITE_REG32( &pdev->regs.OUTEP_REGS[i]->DOEPCTL, depctl.d32);
+ USB_OTG_WRITE_REG32( &pdev->regs.OUTEP_REGS[i]->DOEPTSIZ, 0);
+ USB_OTG_WRITE_REG32( &pdev->regs.OUTEP_REGS[i]->DOEPINT, 0xFF);
+ }
+ msk.d32 = 0;
+ msk.b.txfifoundrn = 1;
+ USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DIEPMSK, msk.d32, msk.d32);
+
+ if (pdev->cfg.dma_enable == 1)
+ {
+ dthrctl.d32 = 0;
+ dthrctl.b.non_iso_thr_en = 1;
+ dthrctl.b.iso_thr_en = 1;
+ dthrctl.b.tx_thr_len = 64;
+ dthrctl.b.rx_thr_en = 1;
+ dthrctl.b.rx_thr_len = 64;
+ USB_OTG_WRITE_REG32(&pdev->regs.DREGS->DTHRCTL, dthrctl.d32);
+ }
+ USB_OTG_EnableDevInt(pdev);
+ return status;
+}
+
+
+/**
+* @brief USB_OTG_EnableDevInt : Enables the Device mode interrupts
+* @param pdev : Selected device
+* @retval USB_OTG_STS : status
+*/
+USB_OTG_STS USB_OTG_EnableDevInt(USB_OTG_CORE_HANDLE *pdev)
+{
+ USB_OTG_STS status = USB_OTG_OK;
+ USB_OTG_GINTMSK_TypeDef intmsk;
+
+ intmsk.d32 = 0;
+
+ /* Disable all interrupts. */
+ USB_OTG_WRITE_REG32( &pdev->regs.GREGS->GINTMSK, 0);
+ /* Clear any pending interrupts */
+ USB_OTG_WRITE_REG32( &pdev->regs.GREGS->GINTSTS, 0xBFFFFFFF);
+ /* Enable the common interrupts */
+ USB_OTG_EnableCommonInt(pdev);
+
+ if (pdev->cfg.dma_enable == 0)
+ {
+ intmsk.b.rxstsqlvl = 1;
+ }
+
+ /* Enable interrupts matching to the Device mode ONLY */
+ intmsk.b.usbsuspend = 1;
+ intmsk.b.usbreset = 1;
+ intmsk.b.enumdone = 1;
+ intmsk.b.inepintr = 1;
+ intmsk.b.outepintr = 1;
+ intmsk.b.sofintr = 1;
+
+ intmsk.b.incomplisoin = 1;
+ intmsk.b.incomplisoout = 1;
+#ifdef VBUS_SENSING_ENABLED
+ intmsk.b.sessreqintr = 1;
+ intmsk.b.otgintr = 1;
+#endif
+ USB_OTG_MODIFY_REG32( &pdev->regs.GREGS->GINTMSK, intmsk.d32, intmsk.d32);
+ return status;
+}
+
+
+/**
+* @brief USB_OTG_GetDeviceSpeed
+* Get the device speed from the device status register
+* @param None
+* @retval status
+*/
+enum USB_OTG_SPEED USB_OTG_GetDeviceSpeed (USB_OTG_CORE_HANDLE *pdev)
+{
+ USB_OTG_DSTS_TypeDef dsts;
+ enum USB_OTG_SPEED speed = USB_SPEED_UNKNOWN;
+
+
+ dsts.d32 = USB_OTG_READ_REG32(&pdev->regs.DREGS->DSTS);
+
+ switch (dsts.b.enumspd)
+ {
+ case DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ:
+ speed = USB_SPEED_HIGH;
+ break;
+ case DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ:
+ case DSTS_ENUMSPD_FS_PHY_48MHZ:
+ speed = USB_SPEED_FULL;
+ break;
+
+ case DSTS_ENUMSPD_LS_PHY_6MHZ:
+ speed = USB_SPEED_LOW;
+ break;
+ }
+
+ return speed;
+}
+/**
+* @brief enables EP0 OUT to receive SETUP packets and configures EP0
+* for transmitting packets
+* @param None
+* @retval USB_OTG_STS : status
+*/
+USB_OTG_STS USB_OTG_EP0Activate(USB_OTG_CORE_HANDLE *pdev)
+{
+ USB_OTG_STS status = USB_OTG_OK;
+ USB_OTG_DSTS_TypeDef dsts;
+ USB_OTG_DEPCTL_TypeDef diepctl;
+ USB_OTG_DCTL_TypeDef dctl;
+
+ dctl.d32 = 0;
+ /* Read the Device Status and Endpoint 0 Control registers */
+ dsts.d32 = USB_OTG_READ_REG32(&pdev->regs.DREGS->DSTS);
+ diepctl.d32 = USB_OTG_READ_REG32(&pdev->regs.INEP_REGS[0]->DIEPCTL);
+ /* Set the MPS of the IN EP based on the enumeration speed */
+ switch (dsts.b.enumspd)
+ {
+ case DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ:
+ case DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ:
+ case DSTS_ENUMSPD_FS_PHY_48MHZ:
+ diepctl.b.mps = DEP0CTL_MPS_64;
+ break;
+ case DSTS_ENUMSPD_LS_PHY_6MHZ:
+ diepctl.b.mps = DEP0CTL_MPS_8;
+ break;
+ }
+ USB_OTG_WRITE_REG32(&pdev->regs.INEP_REGS[0]->DIEPCTL, diepctl.d32);
+ dctl.b.cgnpinnak = 1;
+ USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DCTL, dctl.d32, dctl.d32);
+ return status;
+}
+
+
+/**
+* @brief USB_OTG_EPActivate : Activates an EP
+* @param pdev : Selected device
+* @retval USB_OTG_STS : status
+*/
+USB_OTG_STS USB_OTG_EPActivate(USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep)
+{
+ USB_OTG_STS status = USB_OTG_OK;
+ USB_OTG_DEPCTL_TypeDef depctl;
+ USB_OTG_DAINT_TypeDef daintmsk;
+ __IO uint32_t *addr;
+
+
+ depctl.d32 = 0;
+ daintmsk.d32 = 0;
+ /* Read DEPCTLn register */
+ if (ep->is_in == 1)
+ {
+ addr = &pdev->regs.INEP_REGS[ep->num]->DIEPCTL;
+ daintmsk.ep.in = 1 << ep->num;
+ }
+ else
+ {
+ addr = &pdev->regs.OUTEP_REGS[ep->num]->DOEPCTL;
+ daintmsk.ep.out = 1 << ep->num;
+ }
+ /* If the EP is already active don't change the EP Control
+ * register. */
+ depctl.d32 = USB_OTG_READ_REG32(addr);
+ if (!depctl.b.usbactep)
+ {
+ depctl.b.mps = ep->maxpacket;
+ depctl.b.eptype = ep->type;
+ depctl.b.txfnum = ep->tx_fifo_num;
+ depctl.b.setd0pid = 1;
+ depctl.b.usbactep = 1;
+ USB_OTG_WRITE_REG32(addr, depctl.d32);
+ }
+ /* Enable the Interrupt for this EP */
+#ifdef USB_OTG_HS_DEDICATED_EP1_ENABLED
+ if((ep->num == 1)&&(pdev->cfg.coreID == USB_OTG_HS_CORE_ID))
+ {
+ USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DEACHMSK, 0, daintmsk.d32);
+ }
+ else
+#endif
+ USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DAINTMSK, 0, daintmsk.d32);
+ return status;
+}
+
+
+/**
+* @brief USB_OTG_EPDeactivate : Deactivates an EP
+* @param pdev : Selected device
+* @retval USB_OTG_STS : status
+*/
+USB_OTG_STS USB_OTG_EPDeactivate(USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep)
+{
+ USB_OTG_STS status = USB_OTG_OK;
+ USB_OTG_DEPCTL_TypeDef depctl;
+ USB_OTG_DAINT_TypeDef daintmsk;
+ __IO uint32_t *addr;
+
+ depctl.d32 = 0;
+ daintmsk.d32 = 0;
+ /* Read DEPCTLn register */
+ if (ep->is_in == 1)
+ {
+ addr = &pdev->regs.INEP_REGS[ep->num]->DIEPCTL;
+ daintmsk.ep.in = 1 << ep->num;
+ }
+ else
+ {
+ addr = &pdev->regs.OUTEP_REGS[ep->num]->DOEPCTL;
+ daintmsk.ep.out = 1 << ep->num;
+ }
+ depctl.b.usbactep = 0;
+ USB_OTG_WRITE_REG32(addr, depctl.d32);
+ /* Disable the Interrupt for this EP */
+
+#ifdef USB_OTG_HS_DEDICATED_EP1_ENABLED
+ if((ep->num == 1)&&(pdev->cfg.coreID == USB_OTG_HS_CORE_ID))
+ {
+ USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DEACHMSK, daintmsk.d32, 0);
+ }
+ else
+#endif
+ USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DAINTMSK, daintmsk.d32, 0);
+ return status;
+}
+
+
+/**
+* @brief USB_OTG_EPStartXfer : Handle the setup for data xfer for an EP and
+* starts the xfer
+* @param pdev : Selected device
+* @retval USB_OTG_STS : status
+*/
+USB_OTG_STS USB_OTG_EPStartXfer(USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep)
+{
+ USB_OTG_STS status = USB_OTG_OK;
+ USB_OTG_DEPCTL_TypeDef depctl;
+ USB_OTG_DEPXFRSIZ_TypeDef deptsiz;
+ USB_OTG_DSTS_TypeDef dsts;
+ uint32_t fifoemptymsk = 0;
+
+ depctl.d32 = 0;
+ deptsiz.d32 = 0;
+ /* IN endpoint */
+ if (ep->is_in == 1)
+ {
+ depctl.d32 = USB_OTG_READ_REG32(&(pdev->regs.INEP_REGS[ep->num]->DIEPCTL));
+ deptsiz.d32 = USB_OTG_READ_REG32(&(pdev->regs.INEP_REGS[ep->num]->DIEPTSIZ));
+ /* Zero Length Packet? */
+ if (ep->xfer_len == 0)
+ {
+ deptsiz.b.xfersize = 0;
+ deptsiz.b.pktcnt = 1;
+ }
+ else
+ {
+ /* Program the transfer size and packet count
+ * as follows: xfersize = N * maxpacket +
+ * short_packet pktcnt = N + (short_packet
+ * exist ? 1 : 0)
+ */
+ deptsiz.b.xfersize = ep->xfer_len;
+ deptsiz.b.pktcnt = (ep->xfer_len - 1 + ep->maxpacket) / ep->maxpacket;
+
+ if (ep->type == EP_TYPE_ISOC)
+ {
+ deptsiz.b.mc = 1;
+ }
+ }
+ USB_OTG_WRITE_REG32(&pdev->regs.INEP_REGS[ep->num]->DIEPTSIZ, deptsiz.d32);
+
+ if (pdev->cfg.dma_enable == 1)
+ {
+ USB_OTG_WRITE_REG32(&pdev->regs.INEP_REGS[ep->num]->DIEPDMA, ep->dma_addr);
+ }
+ else
+ {
+ if (ep->type != EP_TYPE_ISOC)
+ {
+ /* Enable the Tx FIFO Empty Interrupt for this EP */
+ if (ep->xfer_len > 0)
+ {
+ fifoemptymsk = 1 << ep->num;
+ USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DIEPEMPMSK, 0, fifoemptymsk);
+ }
+ }
+ }
+
+
+ if (ep->type == EP_TYPE_ISOC)
+ {
+ dsts.d32 = USB_OTG_READ_REG32(&pdev->regs.DREGS->DSTS);
+
+ if (((dsts.b.soffn)&0x1) == 0)
+ {
+ depctl.b.setd1pid = 1;
+ }
+ else
+ {
+ depctl.b.setd0pid = 1;
+ }
+ }
+
+ /* EP enable, IN data in FIFO */
+ depctl.b.cnak = 1;
+ depctl.b.epena = 1;
+ USB_OTG_WRITE_REG32(&pdev->regs.INEP_REGS[ep->num]->DIEPCTL, depctl.d32);
+
+ if (ep->type == EP_TYPE_ISOC)
+ {
+ USB_OTG_WritePacket(pdev, ep->xfer_buff, ep->num, ep->xfer_len);
+ }
+ }
+ else
+ {
+ /* OUT endpoint */
+ depctl.d32 = USB_OTG_READ_REG32(&(pdev->regs.OUTEP_REGS[ep->num]->DOEPCTL));
+ deptsiz.d32 = USB_OTG_READ_REG32(&(pdev->regs.OUTEP_REGS[ep->num]->DOEPTSIZ));
+ /* Program the transfer size and packet count as follows:
+ * pktcnt = N
+ * xfersize = N * maxpacket
+ */
+ if (ep->xfer_len == 0)
+ {
+ deptsiz.b.xfersize = ep->maxpacket;
+ deptsiz.b.pktcnt = 1;
+ }
+ else
+ {
+ deptsiz.b.pktcnt = (ep->xfer_len + (ep->maxpacket - 1)) / ep->maxpacket;
+ deptsiz.b.xfersize = deptsiz.b.pktcnt * ep->maxpacket;
+ }
+ USB_OTG_WRITE_REG32(&pdev->regs.OUTEP_REGS[ep->num]->DOEPTSIZ, deptsiz.d32);
+
+ if (pdev->cfg.dma_enable == 1)
+ {
+ USB_OTG_WRITE_REG32(&pdev->regs.OUTEP_REGS[ep->num]->DOEPDMA, ep->dma_addr);
+ }
+
+ if (ep->type == EP_TYPE_ISOC)
+ {
+ if (ep->even_odd_frame)
+ {
+ depctl.b.setd1pid = 1;
+ }
+ else
+ {
+ depctl.b.setd0pid = 1;
+ }
+ }
+ /* EP enable */
+ depctl.b.cnak = 1;
+ depctl.b.epena = 1;
+ USB_OTG_WRITE_REG32(&pdev->regs.OUTEP_REGS[ep->num]->DOEPCTL, depctl.d32);
+ }
+ return status;
+}
+
+
+/**
+* @brief USB_OTG_EP0StartXfer : Handle the setup for a data xfer for EP0 and
+* starts the xfer
+* @param pdev : Selected device
+* @retval USB_OTG_STS : status
+*/
+USB_OTG_STS USB_OTG_EP0StartXfer(USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep)
+{
+ USB_OTG_STS status = USB_OTG_OK;
+ USB_OTG_DEPCTL_TypeDef depctl;
+ USB_OTG_DEP0XFRSIZ_TypeDef deptsiz;
+ USB_OTG_INEPREGS *in_regs;
+ uint32_t fifoemptymsk = 0;
+
+ depctl.d32 = 0;
+ deptsiz.d32 = 0;
+ /* IN endpoint */
+ if (ep->is_in == 1)
+ {
+ in_regs = pdev->regs.INEP_REGS[0];
+ depctl.d32 = USB_OTG_READ_REG32(&in_regs->DIEPCTL);
+ deptsiz.d32 = USB_OTG_READ_REG32(&in_regs->DIEPTSIZ);
+ /* Zero Length Packet? */
+ if (ep->xfer_len == 0)
+ {
+ deptsiz.b.xfersize = 0;
+ deptsiz.b.pktcnt = 1;
+
+ }
+ else
+ {
+ if (ep->xfer_len > ep->maxpacket)
+ {
+ ep->xfer_len = ep->maxpacket;
+ deptsiz.b.xfersize = ep->maxpacket;
+ }
+ else
+ {
+ deptsiz.b.xfersize = ep->xfer_len;
+ }
+ deptsiz.b.pktcnt = 1;
+ }
+ USB_OTG_WRITE_REG32(&in_regs->DIEPTSIZ, deptsiz.d32);
+
+ if (pdev->cfg.dma_enable == 1)
+ {
+ USB_OTG_WRITE_REG32(&pdev->regs.INEP_REGS[ep->num]->DIEPDMA, ep->dma_addr);
+ }
+
+ /* EP enable, IN data in FIFO */
+ depctl.b.cnak = 1;
+ depctl.b.epena = 1;
+ USB_OTG_WRITE_REG32(&in_regs->DIEPCTL, depctl.d32);
+
+
+
+ if (pdev->cfg.dma_enable == 0)
+ {
+ /* Enable the Tx FIFO Empty Interrupt for this EP */
+ if (ep->xfer_len > 0)
+ {
+ {
+ fifoemptymsk |= 1 << ep->num;
+ USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DIEPEMPMSK, 0, fifoemptymsk);
+ }
+ }
+ }
+ }
+ else
+ {
+ /* OUT endpoint */
+ depctl.d32 = USB_OTG_READ_REG32(&pdev->regs.OUTEP_REGS[ep->num]->DOEPCTL);
+ deptsiz.d32 = USB_OTG_READ_REG32(&pdev->regs.OUTEP_REGS[ep->num]->DOEPTSIZ);
+ /* Program the transfer size and packet count as follows:
+ * xfersize = N * (maxpacket + 4 - (maxpacket % 4))
+ * pktcnt = N */
+ if (ep->xfer_len == 0)
+ {
+ deptsiz.b.xfersize = ep->maxpacket;
+ deptsiz.b.pktcnt = 1;
+ }
+ else
+ {
+ ep->xfer_len = ep->maxpacket;
+ deptsiz.b.xfersize = ep->maxpacket;
+ deptsiz.b.pktcnt = 1;
+ }
+ USB_OTG_WRITE_REG32(&pdev->regs.OUTEP_REGS[ep->num]->DOEPTSIZ, deptsiz.d32);
+ if (pdev->cfg.dma_enable == 1)
+ {
+ USB_OTG_WRITE_REG32(&pdev->regs.OUTEP_REGS[ep->num]->DOEPDMA, ep->dma_addr);
+ }
+ /* EP enable */
+ depctl.b.cnak = 1;
+ depctl.b.epena = 1;
+ USB_OTG_WRITE_REG32 (&(pdev->regs.OUTEP_REGS[ep->num]->DOEPCTL), depctl.d32);
+
+ }
+ return status;
+}
+
+
+/**
+* @brief USB_OTG_EPSetStall : Set the EP STALL
+* @param pdev : Selected device
+* @retval USB_OTG_STS : status
+*/
+USB_OTG_STS USB_OTG_EPSetStall(USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep)
+{
+ USB_OTG_STS status = USB_OTG_OK;
+ USB_OTG_DEPCTL_TypeDef depctl;
+ __IO uint32_t *depctl_addr;
+
+ depctl.d32 = 0;
+ if (ep->is_in == 1)
+ {
+ depctl_addr = &(pdev->regs.INEP_REGS[ep->num]->DIEPCTL);
+ depctl.d32 = USB_OTG_READ_REG32(depctl_addr);
+ /* set the disable and stall bits */
+ if (depctl.b.epena)
+ {
+ depctl.b.epdis = 1;
+ }
+ depctl.b.stall = 1;
+ USB_OTG_WRITE_REG32(depctl_addr, depctl.d32);
+ }
+ else
+ {
+ depctl_addr = &(pdev->regs.OUTEP_REGS[ep->num]->DOEPCTL);
+ depctl.d32 = USB_OTG_READ_REG32(depctl_addr);
+ /* set the stall bit */
+ depctl.b.stall = 1;
+ USB_OTG_WRITE_REG32(depctl_addr, depctl.d32);
+ }
+ return status;
+}
+
+
+/**
+* @brief Clear the EP STALL
+* @param pdev : Selected device
+* @retval USB_OTG_STS : status
+*/
+USB_OTG_STS USB_OTG_EPClearStall(USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep)
+{
+ USB_OTG_STS status = USB_OTG_OK;
+ USB_OTG_DEPCTL_TypeDef depctl;
+ __IO uint32_t *depctl_addr;
+
+ depctl.d32 = 0;
+
+ if (ep->is_in == 1)
+ {
+ depctl_addr = &(pdev->regs.INEP_REGS[ep->num]->DIEPCTL);
+ }
+ else
+ {
+ depctl_addr = &(pdev->regs.OUTEP_REGS[ep->num]->DOEPCTL);
+ }
+ depctl.d32 = USB_OTG_READ_REG32(depctl_addr);
+ /* clear the stall bits */
+ depctl.b.stall = 0;
+ if (ep->type == EP_TYPE_INTR || ep->type == EP_TYPE_BULK)
+ {
+ depctl.b.setd0pid = 1; /* DATA0 */
+ }
+ USB_OTG_WRITE_REG32(depctl_addr, depctl.d32);
+ return status;
+}
+
+
+/**
+* @brief USB_OTG_ReadDevAllOutEp_itr : returns OUT endpoint interrupt bits
+* @param pdev : Selected device
+* @retval OUT endpoint interrupt bits
+*/
+uint32_t USB_OTG_ReadDevAllOutEp_itr(USB_OTG_CORE_HANDLE *pdev)
+{
+ uint32_t v;
+ v = USB_OTG_READ_REG32(&pdev->regs.DREGS->DAINT);
+ v &= USB_OTG_READ_REG32(&pdev->regs.DREGS->DAINTMSK);
+ return ((v & 0xffff0000) >> 16);
+}
+
+
+/**
+* @brief USB_OTG_ReadDevOutEP_itr : returns Device OUT EP Interrupt register
+* @param pdev : Selected device
+* @param ep : end point number
+* @retval Device OUT EP Interrupt register
+*/
+uint32_t USB_OTG_ReadDevOutEP_itr(USB_OTG_CORE_HANDLE *pdev , uint8_t epnum)
+{
+ uint32_t v;
+ v = USB_OTG_READ_REG32(&pdev->regs.OUTEP_REGS[epnum]->DOEPINT);
+ v &= USB_OTG_READ_REG32(&pdev->regs.DREGS->DOEPMSK);
+ return v;
+}
+
+
+/**
+* @brief USB_OTG_ReadDevAllInEPItr : Get int status register
+* @param pdev : Selected device
+* @retval int status register
+*/
+uint32_t USB_OTG_ReadDevAllInEPItr(USB_OTG_CORE_HANDLE *pdev)
+{
+ uint32_t v;
+ v = USB_OTG_READ_REG32(&pdev->regs.DREGS->DAINT);
+ v &= USB_OTG_READ_REG32(&pdev->regs.DREGS->DAINTMSK);
+ return (v & 0xffff);
+}
+
+/**
+* @brief configures EPO to receive SETUP packets
+* @param None
+* @retval : None
+*/
+void USB_OTG_EP0_OutStart(USB_OTG_CORE_HANDLE *pdev)
+{
+ USB_OTG_DEP0XFRSIZ_TypeDef doeptsize0;
+ doeptsize0.d32 = 0;
+ doeptsize0.b.supcnt = 3;
+ doeptsize0.b.pktcnt = 1;
+ doeptsize0.b.xfersize = 8 * 3;
+ USB_OTG_WRITE_REG32( &pdev->regs.OUTEP_REGS[0]->DOEPTSIZ, doeptsize0.d32 );
+
+ if (pdev->cfg.dma_enable == 1)
+ {
+ USB_OTG_DEPCTL_TypeDef doepctl;
+ doepctl.d32 = 0;
+ USB_OTG_WRITE_REG32( &pdev->regs.OUTEP_REGS[0]->DOEPDMA,
+ (uint32_t)&pdev->dev.setup_packet);
+
+ /* EP enable */
+ doepctl.d32 = USB_OTG_READ_REG32(&pdev->regs.OUTEP_REGS[0]->DOEPCTL);
+ doepctl.b.epena = 1;
+ doepctl.d32 = 0x80008000;
+ USB_OTG_WRITE_REG32( &pdev->regs.OUTEP_REGS[0]->DOEPCTL, doepctl.d32);
+ }
+}
+
+/**
+* @brief USB_OTG_RemoteWakeup : active remote wakeup signalling
+* @param None
+* @retval : None
+*/
+void USB_OTG_ActiveRemoteWakeup(USB_OTG_CORE_HANDLE *pdev)
+{
+
+ USB_OTG_DCTL_TypeDef dctl;
+ USB_OTG_DSTS_TypeDef dsts;
+ USB_OTG_PCGCCTL_TypeDef power;
+
+ if (pdev->dev.DevRemoteWakeup)
+ {
+ dsts.d32 = USB_OTG_READ_REG32(&pdev->regs.DREGS->DSTS);
+ if(dsts.b.suspsts == 1)
+ {
+ if(pdev->cfg.low_power)
+ {
+ /* un-gate USB Core clock */
+ power.d32 = USB_OTG_READ_REG32(&pdev->regs.PCGCCTL);
+ power.b.gatehclk = 0;
+ power.b.stoppclk = 0;
+ USB_OTG_WRITE_REG32(pdev->regs.PCGCCTL, power.d32);
+ }
+ /* active Remote wakeup signaling */
+ dctl.d32 = 0;
+ dctl.b.rmtwkupsig = 1;
+ USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DCTL, 0, dctl.d32);
+ USB_OTG_BSP_mDelay(5);
+ USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DCTL, dctl.d32, 0 );
+ }
+ }
+}
+
+
+/**
+* @brief USB_OTG_UngateClock : active USB Core clock
+* @param None
+* @retval : None
+*/
+void USB_OTG_UngateClock(USB_OTG_CORE_HANDLE *pdev)
+{
+ if(pdev->cfg.low_power)
+ {
+
+ USB_OTG_DSTS_TypeDef dsts;
+ USB_OTG_PCGCCTL_TypeDef power;
+
+ dsts.d32 = USB_OTG_READ_REG32(&pdev->regs.DREGS->DSTS);
+
+ if(dsts.b.suspsts == 1)
+ {
+ /* un-gate USB Core clock */
+ power.d32 = USB_OTG_READ_REG32(&pdev->regs.PCGCCTL);
+ power.b.gatehclk = 0;
+ power.b.stoppclk = 0;
+ USB_OTG_WRITE_REG32(pdev->regs.PCGCCTL, power.d32);
+
+ }
+ }
+}
+
+/**
+* @brief Stop the device and clean up fifo's
+* @param None
+* @retval : None
+*/
+void USB_OTG_StopDevice(USB_OTG_CORE_HANDLE *pdev)
+{
+ uint32_t i;
+
+ pdev->dev.device_status = 1;
+
+ for (i = 0; i < pdev->cfg.dev_endpoints ; i++)
+ {
+ USB_OTG_WRITE_REG32( &pdev->regs.INEP_REGS[i]->DIEPINT, 0xFF);
+ USB_OTG_WRITE_REG32( &pdev->regs.OUTEP_REGS[i]->DOEPINT, 0xFF);
+ }
+
+ USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DIEPMSK, 0 );
+ USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DOEPMSK, 0 );
+ USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DAINTMSK, 0 );
+ USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DAINT, 0xFFFFFFFF );
+
+ /* Flush the FIFO */
+ USB_OTG_FlushRxFifo(pdev);
+ USB_OTG_FlushTxFifo(pdev , 0x10 );
+}
+
+/**
+* @brief returns the EP Status
+* @param pdev : Selected device
+* ep : endpoint structure
+* @retval : EP status
+*/
+
+uint32_t USB_OTG_GetEPStatus(USB_OTG_CORE_HANDLE *pdev ,USB_OTG_EP *ep)
+{
+ USB_OTG_DEPCTL_TypeDef depctl;
+ __IO uint32_t *depctl_addr;
+ uint32_t Status = 0;
+
+ depctl.d32 = 0;
+ if (ep->is_in == 1)
+ {
+ depctl_addr = &(pdev->regs.INEP_REGS[ep->num]->DIEPCTL);
+ depctl.d32 = USB_OTG_READ_REG32(depctl_addr);
+
+ if (depctl.b.stall == 1)
+ Status = USB_OTG_EP_TX_STALL;
+ else if (depctl.b.naksts == 1)
+ Status = USB_OTG_EP_TX_NAK;
+ else
+ Status = USB_OTG_EP_TX_VALID;
+
+ }
+ else
+ {
+ depctl_addr = &(pdev->regs.OUTEP_REGS[ep->num]->DOEPCTL);
+ depctl.d32 = USB_OTG_READ_REG32(depctl_addr);
+ if (depctl.b.stall == 1)
+ Status = USB_OTG_EP_RX_STALL;
+ else if (depctl.b.naksts == 1)
+ Status = USB_OTG_EP_RX_NAK;
+ else
+ Status = USB_OTG_EP_RX_VALID;
+ }
+
+ /* Return the current status */
+ return Status;
+}
+
+/**
+* @brief Set the EP Status
+* @param pdev : Selected device
+* Status : new Status
+* ep : EP structure
+* @retval : None
+*/
+void USB_OTG_SetEPStatus (USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep , uint32_t Status)
+{
+ USB_OTG_DEPCTL_TypeDef depctl;
+ __IO uint32_t *depctl_addr;
+
+ depctl.d32 = 0;
+
+ /* Process for IN endpoint */
+ if (ep->is_in == 1)
+ {
+ depctl_addr = &(pdev->regs.INEP_REGS[ep->num]->DIEPCTL);
+ depctl.d32 = USB_OTG_READ_REG32(depctl_addr);
+
+ if (Status == USB_OTG_EP_TX_STALL)
+ {
+ USB_OTG_EPSetStall(pdev, ep); return;
+ }
+ else if (Status == USB_OTG_EP_TX_NAK)
+ depctl.b.snak = 1;
+ else if (Status == USB_OTG_EP_TX_VALID)
+ {
+ if (depctl.b.stall == 1)
+ {
+ ep->even_odd_frame = 0;
+ USB_OTG_EPClearStall(pdev, ep);
+ return;
+ }
+ depctl.b.cnak = 1;
+ depctl.b.usbactep = 1;
+ depctl.b.epena = 1;
+ }
+ else if (Status == USB_OTG_EP_TX_DIS)
+ depctl.b.usbactep = 0;
+ }
+ else /* Process for OUT endpoint */
+ {
+ depctl_addr = &(pdev->regs.OUTEP_REGS[ep->num]->DOEPCTL);
+ depctl.d32 = USB_OTG_READ_REG32(depctl_addr);
+
+ if (Status == USB_OTG_EP_RX_STALL) {
+ depctl.b.stall = 1;
+ }
+ else if (Status == USB_OTG_EP_RX_NAK)
+ depctl.b.snak = 1;
+ else if (Status == USB_OTG_EP_RX_VALID)
+ {
+ if (depctl.b.stall == 1)
+ {
+ ep->even_odd_frame = 0;
+ USB_OTG_EPClearStall(pdev, ep);
+ return;
+ }
+ depctl.b.cnak = 1;
+ depctl.b.usbactep = 1;
+ depctl.b.epena = 1;
+ }
+ else if (Status == USB_OTG_EP_RX_DIS)
+ {
+ depctl.b.usbactep = 0;
+ }
+ }
+
+ USB_OTG_WRITE_REG32(depctl_addr, depctl.d32);
+}
+
+#endif
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/platform/mcu/STM32F4xx/drivers/usb/usb_core.h b/platform/mcu/STM32F4xx/drivers/usb/usb_core.h
new file mode 100644
index 00000000..55e0fca8
--- /dev/null
+++ b/platform/mcu/STM32F4xx/drivers/usb/usb_core.h
@@ -0,0 +1,417 @@
+/**
+ ******************************************************************************
+ * @file usb_core.h
+ * @author MCD Application Team
+ * @version V2.1.0
+ * @date 19-March-2012
+ * @brief Header of the Core Layer
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT 2012 STMicroelectronics
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (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.st.com/software_license_agreement_liberty_v2
+ *
+ * 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.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USB_CORE_H__
+#define __USB_CORE_H__
+
+/* Includes ------------------------------------------------------------------*/
+#include "usb_conf.h"
+#include "usb_regs.h"
+#include "usb_defines.h"
+
+
+/** @addtogroup USB_OTG_DRIVER
+ * @{
+ */
+
+/** @defgroup USB_CORE
+ * @brief usb otg driver core layer
+ * @{
+ */
+
+
+/** @defgroup USB_CORE_Exported_Defines
+ * @{
+ */
+
+#define USB_OTG_EP0_IDLE 0
+#define USB_OTG_EP0_SETUP 1
+#define USB_OTG_EP0_DATA_IN 2
+#define USB_OTG_EP0_DATA_OUT 3
+#define USB_OTG_EP0_STATUS_IN 4
+#define USB_OTG_EP0_STATUS_OUT 5
+#define USB_OTG_EP0_STALL 6
+
+#define USB_OTG_EP_TX_DIS 0x0000
+#define USB_OTG_EP_TX_STALL 0x0010
+#define USB_OTG_EP_TX_NAK 0x0020
+#define USB_OTG_EP_TX_VALID 0x0030
+
+#define USB_OTG_EP_RX_DIS 0x0000
+#define USB_OTG_EP_RX_STALL 0x1000
+#define USB_OTG_EP_RX_NAK 0x2000
+#define USB_OTG_EP_RX_VALID 0x3000
+/**
+ * @}
+ */
+#define MAX_DATA_LENGTH 0x200
+
+/** @defgroup USB_CORE_Exported_Types
+ * @{
+ */
+
+
+typedef enum {
+ USB_OTG_OK = 0,
+ USB_OTG_FAIL
+}USB_OTG_STS;
+
+typedef enum {
+ HC_IDLE = 0,
+ HC_XFRC,
+ HC_HALTED,
+ HC_NAK,
+ HC_NYET,
+ HC_STALL,
+ HC_XACTERR,
+ HC_BBLERR,
+ HC_DATATGLERR,
+}HC_STATUS;
+
+typedef enum {
+ URB_IDLE = 0,
+ URB_DONE,
+ URB_NOTREADY,
+ URB_ERROR,
+ URB_STALL
+}URB_STATE;
+
+typedef enum {
+ CTRL_START = 0,
+ CTRL_XFRC,
+ CTRL_HALTED,
+ CTRL_NAK,
+ CTRL_STALL,
+ CTRL_XACTERR,
+ CTRL_BBLERR,
+ CTRL_DATATGLERR,
+ CTRL_FAIL
+}CTRL_STATUS;
+
+
+typedef struct USB_OTG_hc
+{
+ uint8_t dev_addr ;
+ uint8_t ep_num;
+ uint8_t ep_is_in;
+ uint8_t speed;
+ uint8_t do_ping;
+ uint8_t ep_type;
+ uint16_t max_packet;
+ uint8_t data_pid;
+ uint8_t *xfer_buff;
+ uint32_t xfer_len;
+ uint32_t xfer_count;
+ uint8_t toggle_in;
+ uint8_t toggle_out;
+ uint32_t dma_addr;
+}
+USB_OTG_HC , *PUSB_OTG_HC;
+
+typedef struct USB_OTG_ep
+{
+ uint8_t num;
+ uint8_t is_in;
+ uint8_t is_stall;
+ uint8_t type;
+ uint8_t data_pid_start;
+ uint8_t even_odd_frame;
+ uint16_t tx_fifo_num;
+ uint32_t maxpacket;
+ /* transaction level variables*/
+ uint8_t *xfer_buff;
+ uint32_t dma_addr;
+ uint32_t xfer_len;
+ uint32_t xfer_count;
+ /* Transfer level variables*/
+ uint32_t rem_data_len;
+ uint32_t total_data_len;
+ uint32_t ctl_data_len;
+
+}
+
+USB_OTG_EP , *PUSB_OTG_EP;
+
+
+
+typedef struct USB_OTG_core_cfg
+{
+ uint8_t host_channels;
+ uint8_t dev_endpoints;
+ uint8_t speed;
+ uint8_t dma_enable;
+ uint16_t mps;
+ uint16_t TotalFifoSize;
+ uint8_t phy_itface;
+ uint8_t Sof_output;
+ uint8_t low_power;
+ uint8_t coreID;
+
+}
+USB_OTG_CORE_CFGS, *PUSB_OTG_CORE_CFGS;
+
+
+
+typedef struct usb_setup_req {
+
+ uint8_t bmRequest;
+ uint8_t bRequest;
+ uint16_t wValue;
+ uint16_t wIndex;
+ uint16_t wLength;
+} USB_SETUP_REQ;
+
+typedef struct _Device_TypeDef
+{
+ uint8_t *(*GetDeviceDescriptor)( uint8_t speed , uint16_t *length);
+ uint8_t *(*GetLangIDStrDescriptor)( uint8_t speed , uint16_t *length);
+ uint8_t *(*GetManufacturerStrDescriptor)( uint8_t speed , uint16_t *length);
+ uint8_t *(*GetProductStrDescriptor)( uint8_t speed , uint16_t *length);
+ uint8_t *(*GetSerialStrDescriptor)( uint8_t speed , uint16_t *length);
+ uint8_t *(*GetConfigurationStrDescriptor)( uint8_t speed , uint16_t *length);
+ uint8_t *(*GetInterfaceStrDescriptor)( uint8_t speed , uint16_t *length);
+} USBD_DEVICE, *pUSBD_DEVICE;
+
+//typedef struct USB_OTG_hPort
+//{
+// void (*Disconnect) (void *phost);
+// void (*Connect) (void *phost);
+// uint8_t ConnStatus;
+// uint8_t DisconnStatus;
+// uint8_t ConnHandled;
+// uint8_t DisconnHandled;
+//} USB_OTG_hPort_TypeDef;
+
+typedef struct _Device_cb
+{
+ uint8_t (*Init) (void *pdev , uint8_t cfgidx);
+ uint8_t (*DeInit) (void *pdev , uint8_t cfgidx);
+ /* Control Endpoints*/
+ uint8_t (*Setup) (void *pdev , USB_SETUP_REQ *req);
+ uint8_t (*EP0_TxSent) (void *pdev );
+ uint8_t (*EP0_RxReady) (void *pdev );
+ /* Class Specific Endpoints*/
+ uint8_t (*DataIn) (void *pdev , uint8_t epnum);
+ uint8_t (*DataOut) (void *pdev , uint8_t epnum);
+ uint8_t (*SOF) (void *pdev);
+ uint8_t (*IsoINIncomplete) (void *pdev);
+ uint8_t (*IsoOUTIncomplete) (void *pdev);
+
+ uint8_t *(*GetConfigDescriptor)( uint8_t speed , uint16_t *length);
+#ifdef USB_OTG_HS_CORE
+ uint8_t *(*GetOtherConfigDescriptor)( uint8_t speed , uint16_t *length);
+#endif
+
+#ifdef USB_SUPPORT_USER_STRING_DESC
+ uint8_t *(*GetUsrStrDescriptor)( uint8_t speed ,uint8_t index, uint16_t *length);
+#endif
+
+} USBD_Class_cb_TypeDef;
+
+
+
+typedef struct _USBD_USR_PROP
+{
+ void (*Init)(void);
+ void (*DeviceReset)(uint8_t speed);
+ void (*DeviceConfigured)(void);
+ void (*DeviceSuspended)(void);
+ void (*DeviceResumed)(void);
+
+ void (*DeviceConnected)(void);
+ void (*DeviceDisconnected)(void);
+
+}
+USBD_Usr_cb_TypeDef;
+
+typedef struct _DCD
+{
+ uint8_t device_config;
+ uint8_t device_state;
+ uint8_t device_status;
+ uint8_t device_old_status;
+ uint8_t device_address;
+ uint8_t connection_status;
+ uint8_t test_mode;
+ uint32_t DevRemoteWakeup;
+ USB_OTG_EP in_ep [USB_OTG_MAX_TX_FIFOS];
+ USB_OTG_EP out_ep [USB_OTG_MAX_TX_FIFOS];
+ uint8_t setup_packet [8*3];
+ USBD_Class_cb_TypeDef *class_cb;
+ USBD_Usr_cb_TypeDef *usr_cb;
+ USBD_DEVICE *usr_device;
+ uint8_t *pConfig_descriptor;
+ }
+DCD_DEV , *DCD_PDEV;
+
+
+typedef struct _HCD
+{
+ uint8_t Rx_Buffer [MAX_DATA_LENGTH];
+ __IO uint32_t ConnSts;
+ __IO uint32_t ErrCnt[USB_OTG_MAX_TX_FIFOS];
+ __IO uint32_t XferCnt[USB_OTG_MAX_TX_FIFOS];
+ __IO HC_STATUS HC_Status[USB_OTG_MAX_TX_FIFOS];
+ __IO URB_STATE URB_State[USB_OTG_MAX_TX_FIFOS];
+ USB_OTG_HC hc [USB_OTG_MAX_TX_FIFOS];
+ uint16_t channel [USB_OTG_MAX_TX_FIFOS];
+// USB_OTG_hPort_TypeDef *port_cb;
+}
+HCD_DEV , *USB_OTG_USBH_PDEV;
+
+
+typedef struct _OTG
+{
+ uint8_t OTG_State;
+ uint8_t OTG_PrevState;
+ uint8_t OTG_Mode;
+}
+OTG_DEV , *USB_OTG_USBO_PDEV;
+
+typedef struct USB_OTG_handle
+{
+ USB_OTG_CORE_CFGS cfg;
+ USB_OTG_CORE_REGS regs;
+#ifdef USE_DEVICE_MODE
+ DCD_DEV dev;
+#endif
+#ifdef USE_HOST_MODE
+ HCD_DEV host;
+#endif
+#ifdef USE_OTG_MODE
+ OTG_DEV otg;
+#endif
+}
+USB_OTG_CORE_HANDLE , *PUSB_OTG_CORE_HANDLE;
+
+/**
+ * @}
+ */
+
+
+/** @defgroup USB_CORE_Exported_Macros
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup USB_CORE_Exported_Variables
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USB_CORE_Exported_FunctionsPrototype
+ * @{
+ */
+
+
+USB_OTG_STS USB_OTG_CoreInit (USB_OTG_CORE_HANDLE *pdev);
+USB_OTG_STS USB_OTG_SelectCore (USB_OTG_CORE_HANDLE *pdev,
+ USB_OTG_CORE_ID_TypeDef coreID);
+USB_OTG_STS USB_OTG_EnableGlobalInt (USB_OTG_CORE_HANDLE *pdev);
+USB_OTG_STS USB_OTG_DisableGlobalInt(USB_OTG_CORE_HANDLE *pdev);
+void* USB_OTG_ReadPacket (USB_OTG_CORE_HANDLE *pdev ,
+ uint8_t *dest,
+ uint16_t len);
+USB_OTG_STS USB_OTG_WritePacket (USB_OTG_CORE_HANDLE *pdev ,
+ uint8_t *src,
+ uint8_t ch_ep_num,
+ uint16_t len);
+USB_OTG_STS USB_OTG_FlushTxFifo (USB_OTG_CORE_HANDLE *pdev , uint32_t num);
+USB_OTG_STS USB_OTG_FlushRxFifo (USB_OTG_CORE_HANDLE *pdev);
+
+uint32_t USB_OTG_ReadCoreItr (USB_OTG_CORE_HANDLE *pdev);
+uint32_t USB_OTG_ReadOtgItr (USB_OTG_CORE_HANDLE *pdev);
+uint8_t USB_OTG_IsHostMode (USB_OTG_CORE_HANDLE *pdev);
+uint8_t USB_OTG_IsDeviceMode (USB_OTG_CORE_HANDLE *pdev);
+uint32_t USB_OTG_GetMode (USB_OTG_CORE_HANDLE *pdev);
+USB_OTG_STS USB_OTG_PhyInit (USB_OTG_CORE_HANDLE *pdev);
+USB_OTG_STS USB_OTG_SetCurrentMode (USB_OTG_CORE_HANDLE *pdev,
+ uint8_t mode);
+
+/*********************** HOST APIs ********************************************/
+#ifdef USE_HOST_MODE
+USB_OTG_STS USB_OTG_CoreInitHost (USB_OTG_CORE_HANDLE *pdev);
+USB_OTG_STS USB_OTG_EnableHostInt (USB_OTG_CORE_HANDLE *pdev);
+USB_OTG_STS USB_OTG_HC_Init (USB_OTG_CORE_HANDLE *pdev, uint8_t hc_num);
+USB_OTG_STS USB_OTG_HC_Halt (USB_OTG_CORE_HANDLE *pdev, uint8_t hc_num);
+USB_OTG_STS USB_OTG_HC_StartXfer (USB_OTG_CORE_HANDLE *pdev, uint8_t hc_num);
+USB_OTG_STS USB_OTG_HC_DoPing (USB_OTG_CORE_HANDLE *pdev , uint8_t hc_num);
+uint32_t USB_OTG_ReadHostAllChannels_intr (USB_OTG_CORE_HANDLE *pdev);
+uint32_t USB_OTG_ResetPort (USB_OTG_CORE_HANDLE *pdev);
+uint32_t USB_OTG_ReadHPRT0 (USB_OTG_CORE_HANDLE *pdev);
+void USB_OTG_DriveVbus (USB_OTG_CORE_HANDLE *pdev, uint8_t state);
+void USB_OTG_InitFSLSPClkSel (USB_OTG_CORE_HANDLE *pdev ,uint8_t freq);
+uint8_t USB_OTG_IsEvenFrame (USB_OTG_CORE_HANDLE *pdev) ;
+void USB_OTG_StopHost (USB_OTG_CORE_HANDLE *pdev);
+#endif
+/********************* DEVICE APIs ********************************************/
+#ifdef USE_DEVICE_MODE
+USB_OTG_STS USB_OTG_CoreInitDev (USB_OTG_CORE_HANDLE *pdev);
+USB_OTG_STS USB_OTG_EnableDevInt (USB_OTG_CORE_HANDLE *pdev);
+uint32_t USB_OTG_ReadDevAllInEPItr (USB_OTG_CORE_HANDLE *pdev);
+enum USB_OTG_SPEED USB_OTG_GetDeviceSpeed (USB_OTG_CORE_HANDLE *pdev);
+USB_OTG_STS USB_OTG_EP0Activate (USB_OTG_CORE_HANDLE *pdev);
+USB_OTG_STS USB_OTG_EPActivate (USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep);
+USB_OTG_STS USB_OTG_EPDeactivate(USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep);
+USB_OTG_STS USB_OTG_EPStartXfer (USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep);
+USB_OTG_STS USB_OTG_EP0StartXfer(USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep);
+USB_OTG_STS USB_OTG_EPSetStall (USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep);
+USB_OTG_STS USB_OTG_EPClearStall (USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep);
+uint32_t USB_OTG_ReadDevAllOutEp_itr (USB_OTG_CORE_HANDLE *pdev);
+uint32_t USB_OTG_ReadDevOutEP_itr (USB_OTG_CORE_HANDLE *pdev , uint8_t epnum);
+uint32_t USB_OTG_ReadDevAllInEPItr (USB_OTG_CORE_HANDLE *pdev);
+void USB_OTG_InitDevSpeed (USB_OTG_CORE_HANDLE *pdev , uint8_t speed);
+uint8_t USBH_IsEvenFrame (USB_OTG_CORE_HANDLE *pdev);
+void USB_OTG_EP0_OutStart(USB_OTG_CORE_HANDLE *pdev);
+void USB_OTG_ActiveRemoteWakeup(USB_OTG_CORE_HANDLE *pdev);
+void USB_OTG_UngateClock(USB_OTG_CORE_HANDLE *pdev);
+void USB_OTG_StopDevice(USB_OTG_CORE_HANDLE *pdev);
+void USB_OTG_SetEPStatus (USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep , uint32_t Status);
+uint32_t USB_OTG_GetEPStatus(USB_OTG_CORE_HANDLE *pdev ,USB_OTG_EP *ep);
+#endif
+/**
+ * @}
+ */
+
+#endif /* __USB_CORE_H__ */
+
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
diff --git a/platform/mcu/STM32F4xx/drivers/usb/usb_dcd.c b/platform/mcu/STM32F4xx/drivers/usb/usb_dcd.c
new file mode 100644
index 00000000..36428e2a
--- /dev/null
+++ b/platform/mcu/STM32F4xx/drivers/usb/usb_dcd.c
@@ -0,0 +1,478 @@
+/**
+ ******************************************************************************
+ * @file usb_dcd.c
+ * @author MCD Application Team
+ * @version V2.1.0
+ * @date 19-March-2012
+ * @brief Peripheral Device Interface Layer
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT 2012 STMicroelectronics
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (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.st.com/software_license_agreement_liberty_v2
+ *
+ * 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.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "usb_dcd.h"
+#include "usb_bsp.h"
+
+
+/** @addtogroup USB_OTG_DRIVER
+* @{
+*/
+
+/** @defgroup USB_DCD
+* @brief This file is the interface between EFSL ans Host mass-storage class
+* @{
+*/
+
+
+/** @defgroup USB_DCD_Private_Defines
+* @{
+*/
+/**
+* @}
+*/
+
+
+/** @defgroup USB_DCD_Private_TypesDefinitions
+* @{
+*/
+/**
+* @}
+*/
+
+
+
+/** @defgroup USB_DCD_Private_Macros
+* @{
+*/
+/**
+* @}
+*/
+
+
+/** @defgroup USB_DCD_Private_Variables
+* @{
+*/
+/**
+* @}
+*/
+
+
+/** @defgroup USB_DCD_Private_FunctionPrototypes
+* @{
+*/
+
+/**
+* @}
+*/
+
+
+/** @defgroup USB_DCD_Private_Functions
+* @{
+*/
+
+
+
+void DCD_Init(USB_OTG_CORE_HANDLE *pdev ,
+ USB_OTG_CORE_ID_TypeDef coreID)
+{
+ uint32_t i;
+ USB_OTG_EP *ep;
+
+ USB_OTG_SelectCore (pdev , coreID);
+
+ pdev->dev.device_status = USB_OTG_DEFAULT;
+ pdev->dev.device_address = 0;
+
+ /* Init ep structure */
+ for (i = 0; i < pdev->cfg.dev_endpoints ; i++)
+ {
+ ep = &pdev->dev.in_ep[i];
+ /* Init ep structure */
+ ep->is_in = 1;
+ ep->num = i;
+ ep->tx_fifo_num = i;
+ /* Control until ep is actvated */
+ ep->type = EP_TYPE_CTRL;
+ ep->maxpacket = USB_OTG_MAX_EP0_SIZE;
+ ep->xfer_buff = 0;
+ ep->xfer_len = 0;
+ }
+
+ for (i = 0; i < pdev->cfg.dev_endpoints; i++)
+ {
+ ep = &pdev->dev.out_ep[i];
+ /* Init ep structure */
+ ep->is_in = 0;
+ ep->num = i;
+ ep->tx_fifo_num = i;
+ /* Control until ep is activated */
+ ep->type = EP_TYPE_CTRL;
+ ep->maxpacket = USB_OTG_MAX_EP0_SIZE;
+ ep->xfer_buff = 0;
+ ep->xfer_len = 0;
+ }
+
+ USB_OTG_DisableGlobalInt(pdev);
+
+ /*Init the Core (common init.) */
+ USB_OTG_CoreInit(pdev);
+
+
+ /* Force Device Mode*/
+ USB_OTG_SetCurrentMode(pdev, DEVICE_MODE);
+
+ /* Init Device */
+ USB_OTG_CoreInitDev(pdev);
+
+
+ /* Enable USB Global interrupt */
+ USB_OTG_EnableGlobalInt(pdev);
+}
+
+
+/**
+* @brief Configure an EP
+* @param pdev : Device instance
+* @param epdesc : Endpoint Descriptor
+* @retval : status
+*/
+uint32_t DCD_EP_Open(USB_OTG_CORE_HANDLE *pdev ,
+ uint8_t ep_addr,
+ uint16_t ep_mps,
+ uint8_t ep_type)
+{
+ USB_OTG_EP *ep;
+
+ if ((ep_addr & 0x80) == 0x80)
+ {
+ ep = &pdev->dev.in_ep[ep_addr & 0x7F];
+ }
+ else
+ {
+ ep = &pdev->dev.out_ep[ep_addr & 0x7F];
+ }
+ ep->num = ep_addr & 0x7F;
+
+ ep->is_in = (0x80 & ep_addr) != 0;
+ ep->maxpacket = ep_mps;
+ ep->type = ep_type;
+ if (ep->is_in)
+ {
+ /* Assign a Tx FIFO */
+ ep->tx_fifo_num = ep->num;
+ }
+ /* Set initial data PID. */
+ if (ep_type == USB_OTG_EP_BULK )
+ {
+ ep->data_pid_start = 0;
+ }
+ USB_OTG_EPActivate(pdev , ep );
+ return 0;
+}
+/**
+* @brief called when an EP is disabled
+* @param pdev: device instance
+* @param ep_addr: endpoint address
+* @retval : status
+*/
+uint32_t DCD_EP_Close(USB_OTG_CORE_HANDLE *pdev , uint8_t ep_addr)
+{
+ USB_OTG_EP *ep;
+
+ if ((ep_addr&0x80) == 0x80)
+ {
+ ep = &pdev->dev.in_ep[ep_addr & 0x7F];
+ }
+ else
+ {
+ ep = &pdev->dev.out_ep[ep_addr & 0x7F];
+ }
+ ep->num = ep_addr & 0x7F;
+ ep->is_in = (0x80 & ep_addr) != 0;
+ USB_OTG_EPDeactivate(pdev , ep );
+ return 0;
+}
+
+
+/**
+* @brief DCD_EP_PrepareRx
+* @param pdev: device instance
+* @param ep_addr: endpoint address
+* @param pbuf: pointer to Rx buffer
+* @param buf_len: data length
+* @retval : status
+*/
+uint32_t DCD_EP_PrepareRx( USB_OTG_CORE_HANDLE *pdev,
+ uint8_t ep_addr,
+ uint8_t *pbuf,
+ uint16_t buf_len)
+{
+ USB_OTG_EP *ep;
+
+ ep = &pdev->dev.out_ep[ep_addr & 0x7F];
+
+ /*setup and start the Xfer */
+ ep->xfer_buff = pbuf;
+ ep->xfer_len = buf_len;
+ ep->xfer_count = 0;
+ ep->is_in = 0;
+ ep->num = ep_addr & 0x7F;
+
+ if (pdev->cfg.dma_enable == 1)
+ {
+ ep->dma_addr = (uint32_t)pbuf;
+ }
+
+ if ( ep->num == 0 )
+ {
+ USB_OTG_EP0StartXfer(pdev , ep);
+ }
+ else
+ {
+ USB_OTG_EPStartXfer(pdev, ep );
+ }
+ return 0;
+}
+
+/**
+* @brief Transmit data over USB
+* @param pdev: device instance
+* @param ep_addr: endpoint address
+* @param pbuf: pointer to Tx buffer
+* @param buf_len: data length
+* @retval : status
+*/
+uint32_t DCD_EP_Tx ( USB_OTG_CORE_HANDLE *pdev,
+ uint8_t ep_addr,
+ uint8_t *pbuf,
+ uint32_t buf_len)
+{
+ USB_OTG_EP *ep;
+
+ ep = &pdev->dev.in_ep[ep_addr & 0x7F];
+
+ /* Setup and start the Transfer */
+ ep->is_in = 1;
+ ep->num = ep_addr & 0x7F;
+ ep->xfer_buff = pbuf;
+ ep->dma_addr = (uint32_t)pbuf;
+ ep->xfer_count = 0;
+ ep->xfer_len = buf_len;
+
+ if ( ep->num == 0 )
+ {
+ USB_OTG_EP0StartXfer(pdev , ep);
+ }
+ else
+ {
+ USB_OTG_EPStartXfer(pdev, ep );
+ }
+ return 0;
+}
+
+
+/**
+* @brief Stall an endpoint.
+* @param pdev: device instance
+* @param epnum: endpoint address
+* @retval : status
+*/
+uint32_t DCD_EP_Stall (USB_OTG_CORE_HANDLE *pdev, uint8_t epnum)
+{
+ USB_OTG_EP *ep;
+ if ((0x80 & epnum) == 0x80)
+ {
+ ep = &pdev->dev.in_ep[epnum & 0x7F];
+ }
+ else
+ {
+ ep = &pdev->dev.out_ep[epnum];
+ }
+
+ ep->is_stall = 1;
+ ep->num = epnum & 0x7F;
+ ep->is_in = ((epnum & 0x80) == 0x80);
+
+ USB_OTG_EPSetStall(pdev , ep);
+ return (0);
+}
+
+
+/**
+* @brief Clear stall condition on endpoints.
+* @param pdev: device instance
+* @param epnum: endpoint address
+* @retval : status
+*/
+uint32_t DCD_EP_ClrStall (USB_OTG_CORE_HANDLE *pdev, uint8_t epnum)
+{
+ USB_OTG_EP *ep;
+ if ((0x80 & epnum) == 0x80)
+ {
+ ep = &pdev->dev.in_ep[epnum & 0x7F];
+ }
+ else
+ {
+ ep = &pdev->dev.out_ep[epnum];
+ }
+
+ ep->is_stall = 0;
+ ep->num = epnum & 0x7F;
+ ep->is_in = ((epnum & 0x80) == 0x80);
+
+ USB_OTG_EPClearStall(pdev , ep);
+ return (0);
+}
+
+
+/**
+* @brief This Function flushes the FIFOs.
+* @param pdev: device instance
+* @param epnum: endpoint address
+* @retval : status
+*/
+uint32_t DCD_EP_Flush (USB_OTG_CORE_HANDLE *pdev , uint8_t epnum)
+{
+
+ if ((epnum & 0x80) == 0x80)
+ {
+ USB_OTG_FlushTxFifo(pdev, epnum & 0x7F);
+ }
+ else
+ {
+ USB_OTG_FlushRxFifo(pdev);
+ }
+
+ return (0);
+}
+
+
+/**
+* @brief This Function set USB device address
+* @param pdev: device instance
+* @param address: new device address
+* @retval : status
+*/
+void DCD_EP_SetAddress (USB_OTG_CORE_HANDLE *pdev, uint8_t address)
+{
+ USB_OTG_DCFG_TypeDef dcfg;
+ dcfg.d32 = 0;
+ dcfg.b.devaddr = address;
+ USB_OTG_MODIFY_REG32( &pdev->regs.DREGS->DCFG, 0, dcfg.d32);
+}
+
+/**
+* @brief Connect device (enable internal pull-up)
+* @param pdev: device instance
+* @retval : None
+*/
+void DCD_DevConnect (USB_OTG_CORE_HANDLE *pdev)
+{
+#ifndef USE_OTG_MODE
+ USB_OTG_DCTL_TypeDef dctl;
+ dctl.d32 = USB_OTG_READ_REG32(&pdev->regs.DREGS->DCTL);
+ /* Connect device */
+ dctl.b.sftdiscon = 0;
+ USB_OTG_WRITE_REG32(&pdev->regs.DREGS->DCTL, dctl.d32);
+ USB_OTG_BSP_mDelay(3);
+#endif
+}
+
+
+/**
+* @brief Disconnect device (disable internal pull-up)
+* @param pdev: device instance
+* @retval : None
+*/
+void DCD_DevDisconnect (USB_OTG_CORE_HANDLE *pdev)
+{
+#ifndef USE_OTG_MODE
+ USB_OTG_DCTL_TypeDef dctl;
+ dctl.d32 = USB_OTG_READ_REG32(&pdev->regs.DREGS->DCTL);
+ /* Disconnect device for 3ms */
+ dctl.b.sftdiscon = 1;
+ USB_OTG_WRITE_REG32(&pdev->regs.DREGS->DCTL, dctl.d32);
+ USB_OTG_BSP_mDelay(3);
+#endif
+}
+
+
+/**
+* @brief returns the EP Status
+* @param pdev : Selected device
+* epnum : endpoint address
+* @retval : EP status
+*/
+
+uint32_t DCD_GetEPStatus(USB_OTG_CORE_HANDLE *pdev ,uint8_t epnum)
+{
+ USB_OTG_EP *ep;
+ uint32_t Status = 0;
+
+ if ((0x80 & epnum) == 0x80)
+ {
+ ep = &pdev->dev.in_ep[epnum & 0x7F];
+ }
+ else
+ {
+ ep = &pdev->dev.out_ep[epnum];
+ }
+
+ Status = USB_OTG_GetEPStatus(pdev ,ep);
+
+ /* Return the current status */
+ return Status;
+}
+
+/**
+* @brief Set the EP Status
+* @param pdev : Selected device
+* Status : new Status
+* epnum : EP address
+* @retval : None
+*/
+void DCD_SetEPStatus (USB_OTG_CORE_HANDLE *pdev , uint8_t epnum , uint32_t Status)
+{
+ USB_OTG_EP *ep;
+
+ if ((0x80 & epnum) == 0x80)
+ {
+ ep = &pdev->dev.in_ep[epnum & 0x7F];
+ }
+ else
+ {
+ ep = &pdev->dev.out_ep[epnum];
+ }
+
+ USB_OTG_SetEPStatus(pdev ,ep , Status);
+}
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/platform/mcu/STM32F4xx/drivers/usb/usb_dcd.h b/platform/mcu/STM32F4xx/drivers/usb/usb_dcd.h
new file mode 100644
index 00000000..7b428049
--- /dev/null
+++ b/platform/mcu/STM32F4xx/drivers/usb/usb_dcd.h
@@ -0,0 +1,164 @@
+/**
+ ******************************************************************************
+ * @file usb_dcd.h
+ * @author MCD Application Team
+ * @version V2.1.0
+ * @date 19-March-2012
+ * @brief Peripheral Driver Header file
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT 2012 STMicroelectronics
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (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.st.com/software_license_agreement_liberty_v2
+ *
+ * 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.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __DCD_H__
+#define __DCD_H__
+
+/* Includes ------------------------------------------------------------------*/
+#include "usb_core.h"
+
+
+/** @addtogroup USB_OTG_DRIVER
+* @{
+*/
+
+/** @defgroup USB_DCD
+* @brief This file is the
+* @{
+*/
+
+
+/** @defgroup USB_DCD_Exported_Defines
+* @{
+*/
+#define USB_OTG_EP_CONTROL 0
+#define USB_OTG_EP_ISOC 1
+#define USB_OTG_EP_BULK 2
+#define USB_OTG_EP_INT 3
+#define USB_OTG_EP_MASK 3
+
+/* Device Status */
+#define USB_OTG_DEFAULT 1
+#define USB_OTG_ADDRESSED 2
+#define USB_OTG_CONFIGURED 3
+#define USB_OTG_SUSPENDED 4
+
+/**
+* @}
+*/
+
+
+/** @defgroup USB_DCD_Exported_Types
+* @{
+*/
+/********************************************************************************
+Data structure type
+********************************************************************************/
+typedef struct
+{
+ uint8_t bLength;
+ uint8_t bDescriptorType;
+ uint8_t bEndpointAddress;
+ uint8_t bmAttributes;
+ uint16_t wMaxPacketSize;
+ uint8_t bInterval;
+}
+EP_DESCRIPTOR , *PEP_DESCRIPTOR;
+
+/**
+* @}
+*/
+
+
+/** @defgroup USB_DCD_Exported_Macros
+* @{
+*/
+/**
+* @}
+*/
+
+/** @defgroup USB_DCD_Exported_Variables
+* @{
+*/
+/**
+* @}
+*/
+
+/** @defgroup USB_DCD_Exported_FunctionsPrototype
+* @{
+*/
+/********************************************************************************
+EXPORTED FUNCTION FROM THE USB-OTG LAYER
+********************************************************************************/
+void DCD_Init(USB_OTG_CORE_HANDLE *pdev ,
+ USB_OTG_CORE_ID_TypeDef coreID);
+
+void DCD_DevConnect (USB_OTG_CORE_HANDLE *pdev);
+void DCD_DevDisconnect (USB_OTG_CORE_HANDLE *pdev);
+void DCD_EP_SetAddress (USB_OTG_CORE_HANDLE *pdev,
+ uint8_t address);
+uint32_t DCD_EP_Open(USB_OTG_CORE_HANDLE *pdev ,
+ uint8_t ep_addr,
+ uint16_t ep_mps,
+ uint8_t ep_type);
+
+uint32_t DCD_EP_Close (USB_OTG_CORE_HANDLE *pdev,
+ uint8_t ep_addr);
+
+
+uint32_t DCD_EP_PrepareRx ( USB_OTG_CORE_HANDLE *pdev,
+ uint8_t ep_addr,
+ uint8_t *pbuf,
+ uint16_t buf_len);
+
+uint32_t DCD_EP_Tx (USB_OTG_CORE_HANDLE *pdev,
+ uint8_t ep_addr,
+ uint8_t *pbuf,
+ uint32_t buf_len);
+uint32_t DCD_EP_Stall (USB_OTG_CORE_HANDLE *pdev,
+ uint8_t epnum);
+uint32_t DCD_EP_ClrStall (USB_OTG_CORE_HANDLE *pdev,
+ uint8_t epnum);
+uint32_t DCD_EP_Flush (USB_OTG_CORE_HANDLE *pdev,
+ uint8_t epnum);
+uint32_t DCD_Handle_ISR(USB_OTG_CORE_HANDLE *pdev);
+
+uint32_t DCD_GetEPStatus(USB_OTG_CORE_HANDLE *pdev ,
+ uint8_t epnum);
+
+void DCD_SetEPStatus (USB_OTG_CORE_HANDLE *pdev ,
+ uint8_t epnum ,
+ uint32_t Status);
+
+/**
+* @}
+*/
+
+
+#endif //__DCD_H__
+
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
diff --git a/platform/mcu/STM32F4xx/drivers/usb/usb_dcd_int.c b/platform/mcu/STM32F4xx/drivers/usb/usb_dcd_int.c
new file mode 100644
index 00000000..a22da136
--- /dev/null
+++ b/platform/mcu/STM32F4xx/drivers/usb/usb_dcd_int.c
@@ -0,0 +1,869 @@
+/**
+ ******************************************************************************
+ * @file usb_dcd_int.c
+ * @author MCD Application Team
+ * @version V2.1.0
+ * @date 19-March-2012
+ * @brief Peripheral Device interrupt subroutines
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT 2012 STMicroelectronics
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (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.st.com/software_license_agreement_liberty_v2
+ *
+ * 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.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "usb_dcd_int.h"
+/** @addtogroup USB_OTG_DRIVER
+* @{
+*/
+
+/** @defgroup USB_DCD_INT
+* @brief This file contains the interrupt subroutines for the Device mode.
+* @{
+*/
+
+
+/** @defgroup USB_DCD_INT_Private_Defines
+* @{
+*/
+/**
+* @}
+*/
+
+
+/** @defgroup USB_DCD_INT_Private_TypesDefinitions
+* @{
+*/
+/**
+* @}
+*/
+
+
+
+/** @defgroup USB_DCD_INT_Private_Macros
+* @{
+*/
+/**
+* @}
+*/
+
+
+/** @defgroup USB_DCD_INT_Private_Variables
+* @{
+*/
+/**
+* @}
+*/
+
+
+/** @defgroup USB_DCD_INT_Private_FunctionPrototypes
+* @{
+*/
+/* static functions */
+static uint32_t DCD_ReadDevInEP (USB_OTG_CORE_HANDLE *pdev, uint8_t epnum);
+
+/* Interrupt Handlers */
+static uint32_t DCD_HandleInEP_ISR(USB_OTG_CORE_HANDLE *pdev);
+static uint32_t DCD_HandleOutEP_ISR(USB_OTG_CORE_HANDLE *pdev);
+static uint32_t DCD_HandleSof_ISR(USB_OTG_CORE_HANDLE *pdev);
+
+static uint32_t DCD_HandleRxStatusQueueLevel_ISR(USB_OTG_CORE_HANDLE *pdev);
+static uint32_t DCD_WriteEmptyTxFifo(USB_OTG_CORE_HANDLE *pdev , uint32_t epnum);
+
+static uint32_t DCD_HandleUsbReset_ISR(USB_OTG_CORE_HANDLE *pdev);
+static uint32_t DCD_HandleEnumDone_ISR(USB_OTG_CORE_HANDLE *pdev);
+static uint32_t DCD_HandleResume_ISR(USB_OTG_CORE_HANDLE *pdev);
+static uint32_t DCD_HandleUSBSuspend_ISR(USB_OTG_CORE_HANDLE *pdev);
+
+static uint32_t DCD_IsoINIncomplete_ISR(USB_OTG_CORE_HANDLE *pdev);
+static uint32_t DCD_IsoOUTIncomplete_ISR(USB_OTG_CORE_HANDLE *pdev);
+#ifdef VBUS_SENSING_ENABLED
+static uint32_t DCD_SessionRequest_ISR(USB_OTG_CORE_HANDLE *pdev);
+static uint32_t DCD_OTG_ISR(USB_OTG_CORE_HANDLE *pdev);
+#endif
+
+/**
+* @}
+*/
+
+
+/** @defgroup USB_DCD_INT_Private_Functions
+* @{
+*/
+
+
+#ifdef USB_OTG_HS_DEDICATED_EP1_ENABLED
+/**
+* @brief USBD_OTG_EP1OUT_ISR_Handler
+* handles all USB Interrupts
+* @param pdev: device instance
+* @retval status
+*/
+uint32_t USBD_OTG_EP1OUT_ISR_Handler (USB_OTG_CORE_HANDLE *pdev)
+{
+
+ USB_OTG_DOEPINTn_TypeDef doepint;
+ USB_OTG_DEPXFRSIZ_TypeDef deptsiz;
+
+ doepint.d32 = USB_OTG_READ_REG32(&pdev->regs.OUTEP_REGS[1]->DOEPINT);
+ doepint.d32&= USB_OTG_READ_REG32(&pdev->regs.DREGS->DOUTEP1MSK);
+
+ /* Transfer complete */
+ if ( doepint.b.xfercompl )
+ {
+ /* Clear the bit in DOEPINTn for this interrupt */
+ CLEAR_OUT_EP_INTR(1, xfercompl);
+ if (pdev->cfg.dma_enable == 1)
+ {
+ deptsiz.d32 = USB_OTG_READ_REG32(&(pdev->regs.OUTEP_REGS[1]->DOEPTSIZ));
+ /*ToDo : handle more than one single MPS size packet */
+ pdev->dev.out_ep[1].xfer_count = pdev->dev.out_ep[1].maxpacket - \
+ deptsiz.b.xfersize;
+ }
+ /* Inform upper layer: data ready */
+ /* RX COMPLETE */
+ USBD_DCD_INT_fops->DataOutStage(pdev , 1);
+
+ }
+
+ /* Endpoint disable */
+ if ( doepint.b.epdisabled )
+ {
+ /* Clear the bit in DOEPINTn for this interrupt */
+ CLEAR_OUT_EP_INTR(1, epdisabled);
+ }
+
+ return 1;
+}
+
+/**
+* @brief USBD_OTG_EP1IN_ISR_Handler
+* handles all USB Interrupts
+* @param pdev: device instance
+* @retval status
+*/
+uint32_t USBD_OTG_EP1IN_ISR_Handler (USB_OTG_CORE_HANDLE *pdev)
+{
+
+ USB_OTG_DIEPINTn_TypeDef diepint;
+ uint32_t fifoemptymsk, msk, emp;
+
+ msk = USB_OTG_READ_REG32(&pdev->regs.DREGS->DINEP1MSK);
+ emp = USB_OTG_READ_REG32(&pdev->regs.DREGS->DIEPEMPMSK);
+ msk |= ((emp >> 1 ) & 0x1) << 7;
+ diepint.d32 = USB_OTG_READ_REG32(&pdev->regs.INEP_REGS[1]->DIEPINT) & msk;
+
+ if ( diepint.b.xfercompl )
+ {
+ fifoemptymsk = 0x1 << 1;
+ USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DIEPEMPMSK, fifoemptymsk, 0);
+ CLEAR_IN_EP_INTR(1, xfercompl);
+ /* TX COMPLETE */
+ USBD_DCD_INT_fops->DataInStage(pdev , 1);
+ }
+ if ( diepint.b.epdisabled )
+ {
+ CLEAR_IN_EP_INTR(1, epdisabled);
+ }
+ if ( diepint.b.timeout )
+ {
+ CLEAR_IN_EP_INTR(1, timeout);
+ }
+ if (diepint.b.intktxfemp)
+ {
+ CLEAR_IN_EP_INTR(1, intktxfemp);
+ }
+ if (diepint.b.inepnakeff)
+ {
+ CLEAR_IN_EP_INTR(1, inepnakeff);
+ }
+ if (diepint.b.emptyintr)
+ {
+ DCD_WriteEmptyTxFifo(pdev , 1);
+ CLEAR_IN_EP_INTR(1, emptyintr);
+ }
+ return 1;
+}
+#endif
+
+/**
+* @brief STM32_USBF_OTG_ISR_Handler
+* handles all USB Interrupts
+* @param pdev: device instance
+* @retval status
+*/
+uint32_t USBD_OTG_ISR_Handler (USB_OTG_CORE_HANDLE *pdev)
+{
+ USB_OTG_GINTSTS_TypeDef gintr_status;
+ uint32_t retval = 0;
+
+ if (USB_OTG_IsDeviceMode(pdev)) /* ensure that we are in device mode */
+ {
+ gintr_status.d32 = USB_OTG_ReadCoreItr(pdev);
+ if (!gintr_status.d32) /* avoid spurious interrupt */
+ {
+ return 0;
+ }
+
+ if (gintr_status.b.outepintr)
+ {
+ retval |= DCD_HandleOutEP_ISR(pdev);
+ }
+
+ if (gintr_status.b.inepint)
+ {
+ retval |= DCD_HandleInEP_ISR(pdev);
+ }
+
+ if (gintr_status.b.modemismatch)
+ {
+ USB_OTG_GINTSTS_TypeDef gintsts;
+
+ /* Clear interrupt */
+ gintsts.d32 = 0;
+ gintsts.b.modemismatch = 1;
+ USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GINTSTS, gintsts.d32);
+ }
+
+ if (gintr_status.b.wkupintr)
+ {
+ retval |= DCD_HandleResume_ISR(pdev);
+ }
+
+ if (gintr_status.b.usbsuspend)
+ {
+ retval |= DCD_HandleUSBSuspend_ISR(pdev);
+ }
+ if (gintr_status.b.sofintr)
+ {
+ retval |= DCD_HandleSof_ISR(pdev);
+
+ }
+
+ if (gintr_status.b.rxstsqlvl)
+ {
+ retval |= DCD_HandleRxStatusQueueLevel_ISR(pdev);
+
+ }
+
+ if (gintr_status.b.usbreset)
+ {
+ retval |= DCD_HandleUsbReset_ISR(pdev);
+
+ }
+ if (gintr_status.b.enumdone)
+ {
+ retval |= DCD_HandleEnumDone_ISR(pdev);
+ }
+
+ if (gintr_status.b.incomplisoin)
+ {
+ retval |= DCD_IsoINIncomplete_ISR(pdev);
+ }
+
+ if (gintr_status.b.incomplisoout)
+ {
+ retval |= DCD_IsoOUTIncomplete_ISR(pdev);
+ }
+#ifdef VBUS_SENSING_ENABLED
+ if (gintr_status.b.sessreqintr)
+ {
+ retval |= DCD_SessionRequest_ISR(pdev);
+ }
+
+ if (gintr_status.b.otgintr)
+ {
+ retval |= DCD_OTG_ISR(pdev);
+ }
+#endif
+ }
+ return retval;
+}
+
+#ifdef VBUS_SENSING_ENABLED
+/**
+* @brief DCD_SessionRequest_ISR
+* Indicates that the USB_OTG controller has detected a connection
+* @param pdev: device instance
+* @retval status
+*/
+static uint32_t DCD_SessionRequest_ISR(USB_OTG_CORE_HANDLE *pdev)
+{
+ USB_OTG_GINTSTS_TypeDef gintsts;
+ USBD_DCD_INT_fops->DevConnected (pdev);
+
+ /* Clear interrupt */
+ gintsts.d32 = 0;
+ gintsts.b.sessreqintr = 1;
+ USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GINTSTS, gintsts.d32);
+ return 1;
+}
+
+/**
+* @brief DCD_OTG_ISR
+* Indicates that the USB_OTG controller has detected an OTG event:
+* used to detect the end of session i.e. disconnection
+* @param pdev: device instance
+* @retval status
+*/
+static uint32_t DCD_OTG_ISR(USB_OTG_CORE_HANDLE *pdev)
+{
+
+ USB_OTG_GOTGINT_TypeDef gotgint;
+
+ gotgint.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GOTGINT);
+
+ if (gotgint.b.sesenddet)
+ {
+ USBD_DCD_INT_fops->DevDisconnected (pdev);
+ }
+ /* Clear OTG interrupt */
+ USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GOTGINT, gotgint.d32);
+ return 1;
+}
+#endif
+/**
+* @brief DCD_HandleResume_ISR
+* Indicates that the USB_OTG controller has detected a resume or
+* remote Wake-up sequence
+* @param pdev: device instance
+* @retval status
+*/
+static uint32_t DCD_HandleResume_ISR(USB_OTG_CORE_HANDLE *pdev)
+{
+ USB_OTG_GINTSTS_TypeDef gintsts;
+ USB_OTG_DCTL_TypeDef devctl;
+ USB_OTG_PCGCCTL_TypeDef power;
+
+ if(pdev->cfg.low_power)
+ {
+ /* un-gate USB Core clock */
+ power.d32 = USB_OTG_READ_REG32(&pdev->regs.PCGCCTL);
+ power.b.gatehclk = 0;
+ power.b.stoppclk = 0;
+ USB_OTG_WRITE_REG32(pdev->regs.PCGCCTL, power.d32);
+ }
+
+ /* Clear the Remote Wake-up Signaling */
+ devctl.d32 = 0;
+ devctl.b.rmtwkupsig = 1;
+ USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DCTL, devctl.d32, 0);
+
+ /* Inform upper layer by the Resume Event */
+ USBD_DCD_INT_fops->Resume (pdev);
+
+ /* Clear interrupt */
+ gintsts.d32 = 0;
+ gintsts.b.wkupintr = 1;
+ USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GINTSTS, gintsts.d32);
+ return 1;
+}
+
+/**
+* @brief USB_OTG_HandleUSBSuspend_ISR
+* Indicates that SUSPEND state has been detected on the USB
+* @param pdev: device instance
+* @retval status
+*/
+static uint32_t DCD_HandleUSBSuspend_ISR(USB_OTG_CORE_HANDLE *pdev)
+{
+ USB_OTG_GINTSTS_TypeDef gintsts;
+ USB_OTG_PCGCCTL_TypeDef power;
+ USB_OTG_DSTS_TypeDef dsts;
+ __IO uint8_t prev_status = 0;
+
+ prev_status = pdev->dev.device_status;
+ USBD_DCD_INT_fops->Suspend (pdev);
+
+ dsts.d32 = USB_OTG_READ_REG32(&pdev->regs.DREGS->DSTS);
+
+ /* Clear interrupt */
+ gintsts.d32 = 0;
+ gintsts.b.usbsuspend = 1;
+ USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GINTSTS, gintsts.d32);
+
+ if((pdev->cfg.low_power) && (dsts.b.suspsts == 1) &&
+ (pdev->dev.connection_status == 1) &&
+ (prev_status == USB_OTG_CONFIGURED))
+ {
+ /* switch-off the clocks */
+ power.d32 = 0;
+ power.b.stoppclk = 1;
+ USB_OTG_MODIFY_REG32(pdev->regs.PCGCCTL, 0, power.d32);
+
+ power.b.gatehclk = 1;
+ USB_OTG_MODIFY_REG32(pdev->regs.PCGCCTL, 0, power.d32);
+
+ /* Request to enter Sleep mode after exit from current ISR */
+ SCB->SCR |= (SCB_SCR_SLEEPDEEP_Msk | SCB_SCR_SLEEPONEXIT_Msk);
+ }
+ return 1;
+}
+
+/**
+* @brief DCD_HandleInEP_ISR
+* Indicates that an IN EP has a pending Interrupt
+* @param pdev: device instance
+* @retval status
+*/
+static uint32_t DCD_HandleInEP_ISR(USB_OTG_CORE_HANDLE *pdev)
+{
+ USB_OTG_DIEPINTn_TypeDef diepint;
+
+ uint32_t ep_intr;
+ uint32_t epnum = 0;
+ uint32_t fifoemptymsk;
+ diepint.d32 = 0;
+ ep_intr = USB_OTG_ReadDevAllInEPItr(pdev);
+
+ while ( ep_intr )
+ {
+ if (ep_intr&0x1) /* In ITR */
+ {
+ diepint.d32 = DCD_ReadDevInEP(pdev , epnum); /* Get In ITR status */
+ if ( diepint.b.xfercompl )
+ {
+ fifoemptymsk = 0x1 << epnum;
+ USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DIEPEMPMSK, fifoemptymsk, 0);
+ CLEAR_IN_EP_INTR(epnum, xfercompl);
+ /* TX COMPLETE */
+ USBD_DCD_INT_fops->DataInStage(pdev , epnum);
+
+ if (pdev->cfg.dma_enable == 1)
+ {
+ if((epnum == 0) && (pdev->dev.device_state == USB_OTG_EP0_STATUS_IN))
+ {
+ /* prepare to rx more setup packets */
+ USB_OTG_EP0_OutStart(pdev);
+ }
+ }
+ }
+ if ( diepint.b.timeout )
+ {
+ CLEAR_IN_EP_INTR(epnum, timeout);
+ }
+ if (diepint.b.intktxfemp)
+ {
+ CLEAR_IN_EP_INTR(epnum, intktxfemp);
+ }
+ if (diepint.b.inepnakeff)
+ {
+ CLEAR_IN_EP_INTR(epnum, inepnakeff);
+ }
+ if ( diepint.b.epdisabled )
+ {
+ CLEAR_IN_EP_INTR(epnum, epdisabled);
+ }
+ if (diepint.b.emptyintr)
+ {
+
+ DCD_WriteEmptyTxFifo(pdev , epnum);
+
+ CLEAR_IN_EP_INTR(epnum, emptyintr);
+ }
+ }
+ epnum++;
+ ep_intr >>= 1;
+ }
+
+ return 1;
+}
+
+/**
+* @brief DCD_HandleOutEP_ISR
+* Indicates that an OUT EP has a pending Interrupt
+* @param pdev: device instance
+* @retval status
+*/
+static uint32_t DCD_HandleOutEP_ISR(USB_OTG_CORE_HANDLE *pdev)
+{
+ uint32_t ep_intr;
+ USB_OTG_DOEPINTn_TypeDef doepint;
+ USB_OTG_DEPXFRSIZ_TypeDef deptsiz;
+ uint32_t epnum = 0;
+
+ doepint.d32 = 0;
+
+ /* Read in the device interrupt bits */
+ ep_intr = USB_OTG_ReadDevAllOutEp_itr(pdev);
+
+ while ( ep_intr )
+ {
+ if (ep_intr&0x1)
+ {
+
+ doepint.d32 = USB_OTG_ReadDevOutEP_itr(pdev, epnum);
+
+ /* Transfer complete */
+ if ( doepint.b.xfercompl )
+ {
+ /* Clear the bit in DOEPINTn for this interrupt */
+ CLEAR_OUT_EP_INTR(epnum, xfercompl);
+ if (pdev->cfg.dma_enable == 1)
+ {
+ deptsiz.d32 = USB_OTG_READ_REG32(&(pdev->regs.OUTEP_REGS[epnum]->DOEPTSIZ));
+ /*ToDo : handle more than one single MPS size packet */
+ pdev->dev.out_ep[epnum].xfer_count = pdev->dev.out_ep[epnum].maxpacket - \
+ deptsiz.b.xfersize;
+ }
+ /* Inform upper layer: data ready */
+ /* RX COMPLETE */
+ USBD_DCD_INT_fops->DataOutStage(pdev , epnum);
+
+ if (pdev->cfg.dma_enable == 1)
+ {
+ if((epnum == 0) && (pdev->dev.device_state == USB_OTG_EP0_STATUS_OUT))
+ {
+ /* prepare to rx more setup packets */
+ USB_OTG_EP0_OutStart(pdev);
+ }
+ }
+ }
+ /* Endpoint disable */
+ if ( doepint.b.epdisabled )
+ {
+ /* Clear the bit in DOEPINTn for this interrupt */
+ CLEAR_OUT_EP_INTR(epnum, epdisabled);
+ }
+ /* Setup Phase Done (control EPs) */
+ if ( doepint.b.setup )
+ {
+
+ /* inform the upper layer that a setup packet is available */
+ /* SETUP COMPLETE */
+ USBD_DCD_INT_fops->SetupStage(pdev);
+ CLEAR_OUT_EP_INTR(epnum, setup);
+ }
+ }
+ epnum++;
+ ep_intr >>= 1;
+ }
+ return 1;
+}
+
+/**
+* @brief DCD_HandleSof_ISR
+* Handles the SOF Interrupts
+* @param pdev: device instance
+* @retval status
+*/
+static uint32_t DCD_HandleSof_ISR(USB_OTG_CORE_HANDLE *pdev)
+{
+ USB_OTG_GINTSTS_TypeDef GINTSTS;
+
+
+ USBD_DCD_INT_fops->SOF(pdev);
+
+ /* Clear interrupt */
+ GINTSTS.d32 = 0;
+ GINTSTS.b.sofintr = 1;
+ USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GINTSTS, GINTSTS.d32);
+
+ return 1;
+}
+
+/**
+* @brief DCD_HandleRxStatusQueueLevel_ISR
+* Handles the Rx Status Queue Level Interrupt
+* @param pdev: device instance
+* @retval status
+*/
+static uint32_t DCD_HandleRxStatusQueueLevel_ISR(USB_OTG_CORE_HANDLE *pdev)
+{
+ USB_OTG_GINTMSK_TypeDef int_mask;
+ USB_OTG_DRXSTS_TypeDef status;
+ USB_OTG_EP *ep;
+
+ /* Disable the Rx Status Queue Level interrupt */
+ int_mask.d32 = 0;
+ int_mask.b.rxstsqlvl = 1;
+ USB_OTG_MODIFY_REG32( &pdev->regs.GREGS->GINTMSK, int_mask.d32, 0);
+
+ /* Get the Status from the top of the FIFO */
+ status.d32 = USB_OTG_READ_REG32( &pdev->regs.GREGS->GRXSTSP );
+
+ ep = &pdev->dev.out_ep[status.b.epnum];
+
+ switch (status.b.pktsts)
+ {
+ case STS_GOUT_NAK:
+ break;
+ case STS_DATA_UPDT:
+ if (status.b.bcnt)
+ {
+ USB_OTG_ReadPacket(pdev,ep->xfer_buff, status.b.bcnt);
+ ep->xfer_buff += status.b.bcnt;
+ ep->xfer_count += status.b.bcnt;
+ }
+ break;
+ case STS_XFER_COMP:
+ break;
+ case STS_SETUP_COMP:
+ break;
+ case STS_SETUP_UPDT:
+ /* Copy the setup packet received in FIFO into the setup buffer in RAM */
+ USB_OTG_ReadPacket(pdev , pdev->dev.setup_packet, 8);
+ ep->xfer_count += status.b.bcnt;
+ break;
+ default:
+ break;
+ }
+
+ /* Enable the Rx Status Queue Level interrupt */
+ USB_OTG_MODIFY_REG32( &pdev->regs.GREGS->GINTMSK, 0, int_mask.d32);
+
+ return 1;
+}
+
+/**
+* @brief DCD_WriteEmptyTxFifo
+* check FIFO for the next packet to be loaded
+* @param pdev: device instance
+* @retval status
+*/
+static uint32_t DCD_WriteEmptyTxFifo(USB_OTG_CORE_HANDLE *pdev, uint32_t epnum)
+{
+ USB_OTG_DTXFSTSn_TypeDef txstatus;
+ USB_OTG_EP *ep;
+ uint32_t len = 0;
+ uint32_t len32b;
+ txstatus.d32 = 0;
+
+ ep = &pdev->dev.in_ep[epnum];
+
+ len = ep->xfer_len - ep->xfer_count;
+
+ if (len > ep->maxpacket)
+ {
+ len = ep->maxpacket;
+ }
+
+ len32b = (len + 3) / 4;
+ txstatus.d32 = USB_OTG_READ_REG32( &pdev->regs.INEP_REGS[epnum]->DTXFSTS);
+
+
+
+ while (txstatus.b.txfspcavail > len32b &&
+ ep->xfer_count < ep->xfer_len &&
+ ep->xfer_len != 0)
+ {
+ /* Write the FIFO */
+ len = ep->xfer_len - ep->xfer_count;
+
+ if (len > ep->maxpacket)
+ {
+ len = ep->maxpacket;
+ }
+ len32b = (len + 3) / 4;
+
+ USB_OTG_WritePacket (pdev , ep->xfer_buff, epnum, len);
+
+ ep->xfer_buff += len;
+ ep->xfer_count += len;
+
+ txstatus.d32 = USB_OTG_READ_REG32(&pdev->regs.INEP_REGS[epnum]->DTXFSTS);
+ }
+
+ return 1;
+}
+
+/**
+* @brief DCD_HandleUsbReset_ISR
+* This interrupt occurs when a USB Reset is detected
+* @param pdev: device instance
+* @retval status
+*/
+static uint32_t DCD_HandleUsbReset_ISR(USB_OTG_CORE_HANDLE *pdev)
+{
+ USB_OTG_DAINT_TypeDef daintmsk;
+ USB_OTG_DOEPMSK_TypeDef doepmsk;
+ USB_OTG_DIEPMSK_TypeDef diepmsk;
+ USB_OTG_DCFG_TypeDef dcfg;
+ USB_OTG_DCTL_TypeDef dctl;
+ USB_OTG_GINTSTS_TypeDef gintsts;
+ uint32_t i;
+
+ dctl.d32 = 0;
+ daintmsk.d32 = 0;
+ doepmsk.d32 = 0;
+ diepmsk.d32 = 0;
+ dcfg.d32 = 0;
+ gintsts.d32 = 0;
+
+ /* Clear the Remote Wake-up Signaling */
+ dctl.b.rmtwkupsig = 1;
+ USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DCTL, dctl.d32, 0 );
+
+ /* Flush the Tx FIFO */
+ USB_OTG_FlushTxFifo(pdev , 0 );
+
+ for (i = 0; i < pdev->cfg.dev_endpoints ; i++)
+ {
+ USB_OTG_WRITE_REG32( &pdev->regs.INEP_REGS[i]->DIEPINT, 0xFF);
+ USB_OTG_WRITE_REG32( &pdev->regs.OUTEP_REGS[i]->DOEPINT, 0xFF);
+ }
+ USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DAINT, 0xFFFFFFFF );
+
+ daintmsk.ep.in = 1;
+ daintmsk.ep.out = 1;
+ USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DAINTMSK, daintmsk.d32 );
+
+ doepmsk.b.setup = 1;
+ doepmsk.b.xfercompl = 1;
+ doepmsk.b.epdisabled = 1;
+ USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DOEPMSK, doepmsk.d32 );
+#ifdef USB_OTG_HS_DEDICATED_EP1_ENABLED
+ USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DOUTEP1MSK, doepmsk.d32 );
+#endif
+ diepmsk.b.xfercompl = 1;
+ diepmsk.b.timeout = 1;
+ diepmsk.b.epdisabled = 1;
+
+ USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DIEPMSK, diepmsk.d32 );
+#ifdef USB_OTG_HS_DEDICATED_EP1_ENABLED
+ USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DINEP1MSK, diepmsk.d32 );
+#endif
+ /* Reset Device Address */
+ dcfg.d32 = USB_OTG_READ_REG32( &pdev->regs.DREGS->DCFG);
+ dcfg.b.devaddr = 0;
+ USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DCFG, dcfg.d32);
+
+
+ /* setup EP0 to receive SETUP packets */
+ USB_OTG_EP0_OutStart(pdev);
+
+ /* Clear interrupt */
+ gintsts.d32 = 0;
+ gintsts.b.usbreset = 1;
+ USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GINTSTS, gintsts.d32);
+
+ /*Reset internal state machine */
+ USBD_DCD_INT_fops->Reset(pdev);
+ return 1;
+}
+
+/**
+* @brief DCD_HandleEnumDone_ISR
+* Read the device status register and set the device speed
+* @param pdev: device instance
+* @retval status
+*/
+static uint32_t DCD_HandleEnumDone_ISR(USB_OTG_CORE_HANDLE *pdev)
+{
+ USB_OTG_GINTSTS_TypeDef gintsts;
+ USB_OTG_GUSBCFG_TypeDef gusbcfg;
+
+ USB_OTG_EP0Activate(pdev);
+
+ /* Set USB turn-around time based on device speed and PHY interface. */
+ gusbcfg.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GUSBCFG);
+
+ /* Full or High speed */
+ if ( USB_OTG_GetDeviceSpeed(pdev) == USB_SPEED_HIGH)
+ {
+ pdev->cfg.speed = USB_OTG_SPEED_HIGH;
+ pdev->cfg.mps = USB_OTG_HS_MAX_PACKET_SIZE ;
+ gusbcfg.b.usbtrdtim = 9;
+ }
+ else
+ {
+ pdev->cfg.speed = USB_OTG_SPEED_FULL;
+ pdev->cfg.mps = USB_OTG_FS_MAX_PACKET_SIZE ;
+ gusbcfg.b.usbtrdtim = 5;
+ }
+
+ USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GUSBCFG, gusbcfg.d32);
+
+ /* Clear interrupt */
+ gintsts.d32 = 0;
+ gintsts.b.enumdone = 1;
+ USB_OTG_WRITE_REG32( &pdev->regs.GREGS->GINTSTS, gintsts.d32 );
+ return 1;
+}
+
+
+/**
+* @brief DCD_IsoINIncomplete_ISR
+* handle the ISO IN incomplete interrupt
+* @param pdev: device instance
+* @retval status
+*/
+static uint32_t DCD_IsoINIncomplete_ISR(USB_OTG_CORE_HANDLE *pdev)
+{
+ USB_OTG_GINTSTS_TypeDef gintsts;
+
+ gintsts.d32 = 0;
+
+ USBD_DCD_INT_fops->IsoINIncomplete (pdev);
+
+ /* Clear interrupt */
+ gintsts.b.incomplisoin = 1;
+ USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GINTSTS, gintsts.d32);
+
+ return 1;
+}
+
+/**
+* @brief DCD_IsoOUTIncomplete_ISR
+* handle the ISO OUT incomplete interrupt
+* @param pdev: device instance
+* @retval status
+*/
+static uint32_t DCD_IsoOUTIncomplete_ISR(USB_OTG_CORE_HANDLE *pdev)
+{
+ USB_OTG_GINTSTS_TypeDef gintsts;
+
+ gintsts.d32 = 0;
+
+ USBD_DCD_INT_fops->IsoOUTIncomplete (pdev);
+
+ /* Clear interrupt */
+ gintsts.b.incomplisoout = 1;
+ USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GINTSTS, gintsts.d32);
+ return 1;
+}
+/**
+* @brief DCD_ReadDevInEP
+* Reads ep flags
+* @param pdev: device instance
+* @retval status
+*/
+static uint32_t DCD_ReadDevInEP (USB_OTG_CORE_HANDLE *pdev, uint8_t epnum)
+{
+ uint32_t v, msk, emp;
+ msk = USB_OTG_READ_REG32(&pdev->regs.DREGS->DIEPMSK);
+ emp = USB_OTG_READ_REG32(&pdev->regs.DREGS->DIEPEMPMSK);
+ msk |= ((emp >> epnum) & 0x1) << 7;
+ v = USB_OTG_READ_REG32(&pdev->regs.INEP_REGS[epnum]->DIEPINT) & msk;
+ return v;
+}
+
+
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/platform/mcu/STM32F4xx/drivers/usb/usb_dcd_int.h b/platform/mcu/STM32F4xx/drivers/usb/usb_dcd_int.h
new file mode 100644
index 00000000..69e525a2
--- /dev/null
+++ b/platform/mcu/STM32F4xx/drivers/usb/usb_dcd_int.h
@@ -0,0 +1,127 @@
+/**
+ ******************************************************************************
+ * @file usb_dcd_int.h
+ * @author MCD Application Team
+ * @version V2.1.0
+ * @date 19-March-2012
+ * @brief Peripheral Device Interface Layer
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT 2012 STMicroelectronics
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (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.st.com/software_license_agreement_liberty_v2
+ *
+ * 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.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef USB_DCD_INT_H__
+#define USB_DCD_INT_H__
+
+/* Includes ------------------------------------------------------------------*/
+#include "usb_dcd.h"
+
+
+
+/** @addtogroup USB_OTG_DRIVER
+ * @{
+ */
+
+/** @defgroup USB_DCD_INT
+ * @brief This file is the
+ * @{
+ */
+
+
+/** @defgroup USB_DCD_INT_Exported_Defines
+ * @{
+ */
+
+typedef struct _USBD_DCD_INT
+{
+ uint8_t (* DataOutStage) (USB_OTG_CORE_HANDLE *pdev , uint8_t epnum);
+ uint8_t (* DataInStage) (USB_OTG_CORE_HANDLE *pdev , uint8_t epnum);
+ uint8_t (* SetupStage) (USB_OTG_CORE_HANDLE *pdev);
+ uint8_t (* SOF) (USB_OTG_CORE_HANDLE *pdev);
+ uint8_t (* Reset) (USB_OTG_CORE_HANDLE *pdev);
+ uint8_t (* Suspend) (USB_OTG_CORE_HANDLE *pdev);
+ uint8_t (* Resume) (USB_OTG_CORE_HANDLE *pdev);
+ uint8_t (* IsoINIncomplete) (USB_OTG_CORE_HANDLE *pdev);
+ uint8_t (* IsoOUTIncomplete) (USB_OTG_CORE_HANDLE *pdev);
+
+ uint8_t (* DevConnected) (USB_OTG_CORE_HANDLE *pdev);
+ uint8_t (* DevDisconnected) (USB_OTG_CORE_HANDLE *pdev);
+
+}USBD_DCD_INT_cb_TypeDef;
+
+extern USBD_DCD_INT_cb_TypeDef *USBD_DCD_INT_fops;
+/**
+ * @}
+ */
+
+
+/** @defgroup USB_DCD_INT_Exported_Types
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USB_DCD_INT_Exported_Macros
+ * @{
+ */
+
+#define CLEAR_IN_EP_INTR(epnum,intr) \
+ diepint.d32=0; \
+ diepint.b.intr = 1; \
+ USB_OTG_WRITE_REG32(&pdev->regs.INEP_REGS[epnum]->DIEPINT,diepint.d32);
+
+#define CLEAR_OUT_EP_INTR(epnum,intr) \
+ doepint.d32=0; \
+ doepint.b.intr = 1; \
+ USB_OTG_WRITE_REG32(&pdev->regs.OUTEP_REGS[epnum]->DOEPINT,doepint.d32);
+
+/**
+ * @}
+ */
+
+/** @defgroup USB_DCD_INT_Exported_Variables
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USB_DCD_INT_Exported_FunctionsPrototype
+ * @{
+ */
+
+uint32_t USBD_OTG_ISR_Handler (USB_OTG_CORE_HANDLE *pdev);
+
+/**
+ * @}
+ */
+
+
+#endif // USB_DCD_INT_H__
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
diff --git a/platform/mcu/STM32F4xx/drivers/usb/usb_defines.h b/platform/mcu/STM32F4xx/drivers/usb/usb_defines.h
new file mode 100644
index 00000000..333aeedb
--- /dev/null
+++ b/platform/mcu/STM32F4xx/drivers/usb/usb_defines.h
@@ -0,0 +1,249 @@
+/**
+ ******************************************************************************
+ * @file usb_defines.h
+ * @author MCD Application Team
+ * @version V2.1.0
+ * @date 19-March-2012
+ * @brief Header of the Core Layer
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT 2012 STMicroelectronics
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (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.st.com/software_license_agreement_liberty_v2
+ *
+ * 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.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USB_DEF_H__
+#define __USB_DEF_H__
+
+/* Includes ------------------------------------------------------------------*/
+#include "usb_conf.h"
+
+/** @addtogroup USB_OTG_DRIVER
+ * @{
+ */
+
+/** @defgroup USB_DEFINES
+ * @brief This file is the
+ * @{
+ */
+
+
+/** @defgroup USB_DEFINES_Exported_Defines
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup _CORE_DEFINES_
+ * @{
+ */
+
+#define USB_OTG_SPEED_PARAM_HIGH 0
+#define USB_OTG_SPEED_PARAM_HIGH_IN_FULL 1
+#define USB_OTG_SPEED_PARAM_FULL 3
+
+#define USB_OTG_SPEED_HIGH 0
+#define USB_OTG_SPEED_FULL 1
+
+#define USB_OTG_ULPI_PHY 1
+#define USB_OTG_EMBEDDED_PHY 2
+
+/**
+ * @}
+ */
+
+
+/** @defgroup _GLOBAL_DEFINES_
+ * @{
+ */
+#define GAHBCFG_TXFEMPTYLVL_EMPTY 1
+#define GAHBCFG_TXFEMPTYLVL_HALFEMPTY 0
+#define GAHBCFG_GLBINT_ENABLE 1
+#define GAHBCFG_INT_DMA_BURST_SINGLE 0
+#define GAHBCFG_INT_DMA_BURST_INCR 1
+#define GAHBCFG_INT_DMA_BURST_INCR4 3
+#define GAHBCFG_INT_DMA_BURST_INCR8 5
+#define GAHBCFG_INT_DMA_BURST_INCR16 7
+#define GAHBCFG_DMAENABLE 1
+#define GAHBCFG_TXFEMPTYLVL_EMPTY 1
+#define GAHBCFG_TXFEMPTYLVL_HALFEMPTY 0
+#define GRXSTS_PKTSTS_IN 2
+#define GRXSTS_PKTSTS_IN_XFER_COMP 3
+#define GRXSTS_PKTSTS_DATA_TOGGLE_ERR 5
+#define GRXSTS_PKTSTS_CH_HALTED 7
+/**
+ * @}
+ */
+
+
+/** @defgroup _OnTheGo_DEFINES_
+ * @{
+ */
+#define MODE_HNP_SRP_CAPABLE 0
+#define MODE_SRP_ONLY_CAPABLE 1
+#define MODE_NO_HNP_SRP_CAPABLE 2
+#define MODE_SRP_CAPABLE_DEVICE 3
+#define MODE_NO_SRP_CAPABLE_DEVICE 4
+#define MODE_SRP_CAPABLE_HOST 5
+#define MODE_NO_SRP_CAPABLE_HOST 6
+#define A_HOST 1
+#define A_SUSPEND 2
+#define A_PERIPHERAL 3
+#define B_PERIPHERAL 4
+#define B_HOST 5
+#define DEVICE_MODE 0
+#define HOST_MODE 1
+#define OTG_MODE 2
+/**
+ * @}
+ */
+
+
+/** @defgroup __DEVICE_DEFINES_
+ * @{
+ */
+#define DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ 0
+#define DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ 1
+#define DSTS_ENUMSPD_LS_PHY_6MHZ 2
+#define DSTS_ENUMSPD_FS_PHY_48MHZ 3
+
+#define DCFG_FRAME_INTERVAL_80 0
+#define DCFG_FRAME_INTERVAL_85 1
+#define DCFG_FRAME_INTERVAL_90 2
+#define DCFG_FRAME_INTERVAL_95 3
+
+#define DEP0CTL_MPS_64 0
+#define DEP0CTL_MPS_32 1
+#define DEP0CTL_MPS_16 2
+#define DEP0CTL_MPS_8 3
+
+#define EP_SPEED_LOW 0
+#define EP_SPEED_FULL 1
+#define EP_SPEED_HIGH 2
+
+#define EP_TYPE_CTRL 0
+#define EP_TYPE_ISOC 1
+#define EP_TYPE_BULK 2
+#define EP_TYPE_INTR 3
+#define EP_TYPE_MSK 3
+
+#define STS_GOUT_NAK 1
+#define STS_DATA_UPDT 2
+#define STS_XFER_COMP 3
+#define STS_SETUP_COMP 4
+#define STS_SETUP_UPDT 6
+/**
+ * @}
+ */
+
+
+/** @defgroup __HOST_DEFINES_
+ * @{
+ */
+#define HC_PID_DATA0 0
+#define HC_PID_DATA2 1
+#define HC_PID_DATA1 2
+#define HC_PID_SETUP 3
+
+#define HPRT0_PRTSPD_HIGH_SPEED 0
+#define HPRT0_PRTSPD_FULL_SPEED 1
+#define HPRT0_PRTSPD_LOW_SPEED 2
+
+#define HCFG_30_60_MHZ 0
+#define HCFG_48_MHZ 1
+#define HCFG_6_MHZ 2
+
+#define HCCHAR_CTRL 0
+#define HCCHAR_ISOC 1
+#define HCCHAR_BULK 2
+#define HCCHAR_INTR 3
+
+#define MIN(a, b) (((a) < (b)) ? (a) : (b))
+
+/**
+ * @}
+ */
+
+
+/** @defgroup USB_DEFINES_Exported_Types
+ * @{
+ */
+
+typedef enum
+{
+ USB_OTG_HS_CORE_ID = 0,
+ USB_OTG_FS_CORE_ID = 1
+}USB_OTG_CORE_ID_TypeDef;
+/**
+ * @}
+ */
+
+
+/** @defgroup USB_DEFINES_Exported_Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USB_DEFINES_Exported_Variables
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USB_DEFINES_Exported_FunctionsPrototype
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup Internal_Macro's
+ * @{
+ */
+#define USB_OTG_READ_REG32(reg) (*(__IO uint32_t *)reg)
+#define USB_OTG_WRITE_REG32(reg,value) (*(__IO uint32_t *)reg = value)
+#define USB_OTG_MODIFY_REG32(reg,clear_mask,set_mask) \
+ USB_OTG_WRITE_REG32(reg, (((USB_OTG_READ_REG32(reg)) & ~clear_mask) | set_mask ) )
+
+/********************************************************************************
+ ENUMERATION TYPE
+********************************************************************************/
+enum USB_OTG_SPEED {
+ USB_SPEED_UNKNOWN = 0,
+ USB_SPEED_LOW,
+ USB_SPEED_FULL,
+ USB_SPEED_HIGH
+};
+
+#endif //__USB_DEFINES__H__
+
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
diff --git a/platform/mcu/STM32F4xx/drivers/usb/usb_regs.h b/platform/mcu/STM32F4xx/drivers/usb/usb_regs.h
new file mode 100644
index 00000000..7befb51d
--- /dev/null
+++ b/platform/mcu/STM32F4xx/drivers/usb/usb_regs.h
@@ -0,0 +1,1188 @@
+/**
+ ******************************************************************************
+ * @file usb_regs.h
+ * @author MCD Application Team
+ * @version V2.1.0
+ * @date 19-March-2012
+ * @brief hardware registers
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT 2012 STMicroelectronics
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (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.st.com/software_license_agreement_liberty_v2
+ *
+ * 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.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USB_OTG_REGS_H__
+#define __USB_OTG_REGS_H__
+
+/* Includes ------------------------------------------------------------------*/
+#include "usb_conf.h"
+
+
+/** @addtogroup USB_OTG_DRIVER
+ * @{
+ */
+
+/** @defgroup USB_REGS
+ * @brief This file is the
+ * @{
+ */
+
+
+/** @defgroup USB_REGS_Exported_Defines
+ * @{
+ */
+
+#define USB_OTG_HS_BASE_ADDR 0x40040000
+#define USB_OTG_FS_BASE_ADDR 0x50000000
+
+#define USB_OTG_CORE_GLOBAL_REGS_OFFSET 0x000
+#define USB_OTG_DEV_GLOBAL_REG_OFFSET 0x800
+#define USB_OTG_DEV_IN_EP_REG_OFFSET 0x900
+#define USB_OTG_EP_REG_OFFSET 0x20
+#define USB_OTG_DEV_OUT_EP_REG_OFFSET 0xB00
+#define USB_OTG_HOST_GLOBAL_REG_OFFSET 0x400
+#define USB_OTG_HOST_PORT_REGS_OFFSET 0x440
+#define USB_OTG_HOST_CHAN_REGS_OFFSET 0x500
+#define USB_OTG_CHAN_REGS_OFFSET 0x20
+#define USB_OTG_PCGCCTL_OFFSET 0xE00
+#define USB_OTG_DATA_FIFO_OFFSET 0x1000
+#define USB_OTG_DATA_FIFO_SIZE 0x1000
+
+
+#define USB_OTG_MAX_TX_FIFOS 15
+
+#define USB_OTG_HS_MAX_PACKET_SIZE 512
+#define USB_OTG_FS_MAX_PACKET_SIZE 64
+#define USB_OTG_MAX_EP0_SIZE 64
+/**
+ * @}
+ */
+
+/** @defgroup USB_REGS_Exported_Types
+ * @{
+ */
+
+/** @defgroup __USB_OTG_Core_register
+ * @{
+ */
+typedef struct _USB_OTG_GREGS //000h
+{
+ __IO uint32_t GOTGCTL; /* USB_OTG Control and Status Register 000h*/
+ __IO uint32_t GOTGINT; /* USB_OTG Interrupt Register 004h*/
+ __IO uint32_t GAHBCFG; /* Core AHB Configuration Register 008h*/
+ __IO uint32_t GUSBCFG; /* Core USB Configuration Register 00Ch*/
+ __IO uint32_t GRSTCTL; /* Core Reset Register 010h*/
+ __IO uint32_t GINTSTS; /* Core Interrupt Register 014h*/
+ __IO uint32_t GINTMSK; /* Core Interrupt Mask Register 018h*/
+ __IO uint32_t GRXSTSR; /* Receive Sts Q Read Register 01Ch*/
+ __IO uint32_t GRXSTSP; /* Receive Sts Q Read & POP Register 020h*/
+ __IO uint32_t GRXFSIZ; /* Receive FIFO Size Register 024h*/
+ __IO uint32_t DIEPTXF0_HNPTXFSIZ; /* EP0 / Non Periodic Tx FIFO Size Register 028h*/
+ __IO uint32_t HNPTXSTS; /* Non Periodic Tx FIFO/Queue Sts reg 02Ch*/
+ uint32_t Reserved30[2]; /* Reserved 030h*/
+ __IO uint32_t GCCFG; /* General Purpose IO Register 038h*/
+ __IO uint32_t CID; /* User ID Register 03Ch*/
+ uint32_t Reserved40[48]; /* Reserved 040h-0FFh*/
+ __IO uint32_t HPTXFSIZ; /* Host Periodic Tx FIFO Size Reg 100h*/
+ __IO uint32_t DIEPTXF[USB_OTG_MAX_TX_FIFOS];/* dev Periodic Transmit FIFO */
+}
+USB_OTG_GREGS;
+/**
+ * @}
+ */
+
+
+/** @defgroup __device_Registers
+ * @{
+ */
+typedef struct _USB_OTG_DREGS // 800h
+{
+ __IO uint32_t DCFG; /* dev Configuration Register 800h*/
+ __IO uint32_t DCTL; /* dev Control Register 804h*/
+ __IO uint32_t DSTS; /* dev Status Register (RO) 808h*/
+ uint32_t Reserved0C; /* Reserved 80Ch*/
+ __IO uint32_t DIEPMSK; /* dev IN Endpoint Mask 810h*/
+ __IO uint32_t DOEPMSK; /* dev OUT Endpoint Mask 814h*/
+ __IO uint32_t DAINT; /* dev All Endpoints Itr Reg 818h*/
+ __IO uint32_t DAINTMSK; /* dev All Endpoints Itr Mask 81Ch*/
+ uint32_t Reserved20; /* Reserved 820h*/
+ uint32_t Reserved9; /* Reserved 824h*/
+ __IO uint32_t DVBUSDIS; /* dev VBUS discharge Register 828h*/
+ __IO uint32_t DVBUSPULSE; /* dev VBUS Pulse Register 82Ch*/
+ __IO uint32_t DTHRCTL; /* dev thr 830h*/
+ __IO uint32_t DIEPEMPMSK; /* dev empty msk 834h*/
+ __IO uint32_t DEACHINT; /* dedicated EP interrupt 838h*/
+ __IO uint32_t DEACHMSK; /* dedicated EP msk 83Ch*/
+ uint32_t Reserved40; /* dedicated EP mask 840h*/
+ __IO uint32_t DINEP1MSK; /* dedicated EP mask 844h*/
+ uint32_t Reserved44[15]; /* Reserved 844-87Ch*/
+ __IO uint32_t DOUTEP1MSK; /* dedicated EP msk 884h*/
+}
+USB_OTG_DREGS;
+/**
+ * @}
+ */
+
+
+/** @defgroup __IN_Endpoint-Specific_Register
+ * @{
+ */
+typedef struct _USB_OTG_INEPREGS
+{
+ __IO uint32_t DIEPCTL; /* dev IN Endpoint Control Reg 900h + (ep_num * 20h) + 00h*/
+ uint32_t Reserved04; /* Reserved 900h + (ep_num * 20h) + 04h*/
+ __IO uint32_t DIEPINT; /* dev IN Endpoint Itr Reg 900h + (ep_num * 20h) + 08h*/
+ uint32_t Reserved0C; /* Reserved 900h + (ep_num * 20h) + 0Ch*/
+ __IO uint32_t DIEPTSIZ; /* IN Endpoint Txfer Size 900h + (ep_num * 20h) + 10h*/
+ __IO uint32_t DIEPDMA; /* IN Endpoint DMA Address Reg 900h + (ep_num * 20h) + 14h*/
+ __IO uint32_t DTXFSTS;/*IN Endpoint Tx FIFO Status Reg 900h + (ep_num * 20h) + 18h*/
+ uint32_t Reserved18; /* Reserved 900h+(ep_num*20h)+1Ch-900h+ (ep_num * 20h) + 1Ch*/
+}
+USB_OTG_INEPREGS;
+/**
+ * @}
+ */
+
+
+/** @defgroup __OUT_Endpoint-Specific_Registers
+ * @{
+ */
+typedef struct _USB_OTG_OUTEPREGS
+{
+ __IO uint32_t DOEPCTL; /* dev OUT Endpoint Control Reg B00h + (ep_num * 20h) + 00h*/
+ uint32_t Reserved04; /* Reserved B00h + (ep_num * 20h) + 04h*/
+ __IO uint32_t DOEPINT; /* dev OUT Endpoint Itr Reg B00h + (ep_num * 20h) + 08h*/
+ uint32_t Reserved0C; /* Reserved B00h + (ep_num * 20h) + 0Ch*/
+ __IO uint32_t DOEPTSIZ; /* dev OUT Endpoint Txfer Size B00h + (ep_num * 20h) + 10h*/
+ __IO uint32_t DOEPDMA; /* dev OUT Endpoint DMA Address B00h + (ep_num * 20h) + 14h*/
+ uint32_t Reserved18[2]; /* Reserved B00h + (ep_num * 20h) + 18h - B00h + (ep_num * 20h) + 1Ch*/
+}
+USB_OTG_OUTEPREGS;
+/**
+ * @}
+ */
+
+
+/** @defgroup __Host_Mode_Register_Structures
+ * @{
+ */
+typedef struct _USB_OTG_HREGS
+{
+ __IO uint32_t HCFG; /* Host Configuration Register 400h*/
+ __IO uint32_t HFIR; /* Host Frame Interval Register 404h*/
+ __IO uint32_t HFNUM; /* Host Frame Nbr/Frame Remaining 408h*/
+ uint32_t Reserved40C; /* Reserved 40Ch*/
+ __IO uint32_t HPTXSTS; /* Host Periodic Tx FIFO/ Queue Status 410h*/
+ __IO uint32_t HAINT; /* Host All Channels Interrupt Register 414h*/
+ __IO uint32_t HAINTMSK; /* Host All Channels Interrupt Mask 418h*/
+}
+USB_OTG_HREGS;
+/**
+ * @}
+ */
+
+
+/** @defgroup __Host_Channel_Specific_Registers
+ * @{
+ */
+typedef struct _USB_OTG_HC_REGS
+{
+ __IO uint32_t HCCHAR;
+ __IO uint32_t HCSPLT;
+ __IO uint32_t HCINT;
+ __IO uint32_t HCINTMSK;
+ __IO uint32_t HCTSIZ;
+ __IO uint32_t HCDMA;
+ uint32_t Reserved[2];
+}
+USB_OTG_HC_REGS;
+/**
+ * @}
+ */
+
+
+/** @defgroup __otg_Core_registers
+ * @{
+ */
+typedef struct USB_OTG_core_regs //000h
+{
+ USB_OTG_GREGS *GREGS;
+ USB_OTG_DREGS *DREGS;
+ USB_OTG_HREGS *HREGS;
+ USB_OTG_INEPREGS *INEP_REGS[USB_OTG_MAX_TX_FIFOS];
+ USB_OTG_OUTEPREGS *OUTEP_REGS[USB_OTG_MAX_TX_FIFOS];
+ USB_OTG_HC_REGS *HC_REGS[USB_OTG_MAX_TX_FIFOS];
+ __IO uint32_t *HPRT0;
+ __IO uint32_t *DFIFO[USB_OTG_MAX_TX_FIFOS];
+ __IO uint32_t *PCGCCTL;
+}
+USB_OTG_CORE_REGS , *PUSB_OTG_CORE_REGS;
+typedef union _USB_OTG_GOTGCTL_TypeDef
+{
+ uint32_t d32;
+ struct
+ {
+uint32_t sesreqscs :
+ 1;
+uint32_t sesreq :
+ 1;
+uint32_t Reserved2_7 :
+ 6;
+uint32_t hstnegscs :
+ 1;
+uint32_t hnpreq :
+ 1;
+uint32_t hstsethnpen :
+ 1;
+uint32_t devhnpen :
+ 1;
+uint32_t Reserved12_15 :
+ 4;
+uint32_t conidsts :
+ 1;
+uint32_t dbct :
+ 1;
+uint32_t asesvld :
+ 1;
+uint32_t bsesvld :
+ 1;
+uint32_t Reserved20_31 :
+ 12;
+ }
+ b;
+} USB_OTG_GOTGCTL_TypeDef ;
+
+typedef union _USB_OTG_GOTGINT_TypeDef
+{
+ uint32_t d32;
+ struct
+ {
+uint32_t Reserved0_1 :
+ 2;
+uint32_t sesenddet :
+ 1;
+uint32_t Reserved3_7 :
+ 5;
+uint32_t sesreqsucstschng :
+ 1;
+uint32_t hstnegsucstschng :
+ 1;
+uint32_t reserver10_16 :
+ 7;
+uint32_t hstnegdet :
+ 1;
+uint32_t adevtoutchng :
+ 1;
+uint32_t debdone :
+ 1;
+uint32_t Reserved31_20 :
+ 12;
+ }
+ b;
+} USB_OTG_GOTGINT_TypeDef ;
+typedef union _USB_OTG_GAHBCFG_TypeDef
+{
+ uint32_t d32;
+ struct
+ {
+uint32_t glblintrmsk :
+ 1;
+uint32_t hburstlen :
+ 4;
+uint32_t dmaenable :
+ 1;
+uint32_t Reserved :
+ 1;
+uint32_t nptxfemplvl_txfemplvl :
+ 1;
+uint32_t ptxfemplvl :
+ 1;
+uint32_t Reserved9_31 :
+ 23;
+ }
+ b;
+} USB_OTG_GAHBCFG_TypeDef ;
+typedef union _USB_OTG_GUSBCFG_TypeDef
+{
+ uint32_t d32;
+ struct
+ {
+uint32_t toutcal :
+ 3;
+uint32_t Reserved3_5 :
+ 3;
+uint32_t physel :
+ 1;
+uint32_t Reserved7 :
+ 1;
+uint32_t srpcap :
+ 1;
+uint32_t hnpcap :
+ 1;
+uint32_t usbtrdtim :
+ 4;
+uint32_t Reserved14 :
+ 1;
+uint32_t phylpwrclksel :
+ 1;
+uint32_t Reserved16 :
+ 1;
+uint32_t ulpi_fsls :
+ 1;
+uint32_t ulpi_auto_res :
+ 1;
+uint32_t ulpi_clk_sus_m :
+ 1;
+uint32_t ulpi_ext_vbus_drv :
+ 1;
+uint32_t ulpi_int_vbus_ind :
+ 1;
+uint32_t term_sel_dl_pulse :
+ 1;
+uint32_t ulpi_ind_cpl :
+ 1;
+uint32_t ulpi_passthrough :
+ 1;
+uint32_t ulpi_protect_disable :
+ 1;
+uint32_t Reserved26_28 :
+ 3;
+uint32_t force_host :
+ 1;
+uint32_t force_dev :
+ 1;
+uint32_t corrupt_tx :
+ 1;
+ }
+ b;
+} USB_OTG_GUSBCFG_TypeDef ;
+typedef union _USB_OTG_GRSTCTL_TypeDef
+{
+ uint32_t d32;
+ struct
+ {
+uint32_t csftrst :
+ 1;
+uint32_t hsftrst :
+ 1;
+uint32_t hstfrm :
+ 1;
+uint32_t Reserved3 :
+ 1;
+uint32_t rxfflsh :
+ 1;
+uint32_t txfflsh :
+ 1;
+uint32_t txfnum :
+ 5;
+uint32_t Reserved11_29 :
+ 19;
+uint32_t dmareq :
+ 1;
+uint32_t ahbidle :
+ 1;
+ }
+ b;
+} USB_OTG_GRSTCTL_TypeDef ;
+typedef union _USB_OTG_GINTMSK_TypeDef
+{
+ uint32_t d32;
+ struct
+ {
+uint32_t Reserved0 :
+ 1;
+uint32_t modemismatch :
+ 1;
+uint32_t otgintr :
+ 1;
+uint32_t sofintr :
+ 1;
+uint32_t rxstsqlvl :
+ 1;
+uint32_t nptxfempty :
+ 1;
+uint32_t ginnakeff :
+ 1;
+uint32_t goutnakeff :
+ 1;
+uint32_t Reserved8_9 :
+ 2;
+uint32_t erlysuspend :
+ 1;
+uint32_t usbsuspend :
+ 1;
+uint32_t usbreset :
+ 1;
+uint32_t enumdone :
+ 1;
+uint32_t isooutdrop :
+ 1;
+uint32_t eopframe :
+ 1;
+uint32_t Reserved16 :
+ 1;
+uint32_t epmismatch :
+ 1;
+uint32_t inepintr :
+ 1;
+uint32_t outepintr :
+ 1;
+uint32_t incomplisoin :
+ 1;
+uint32_t incomplisoout :
+ 1;
+uint32_t Reserved22_23 :
+ 2;
+uint32_t portintr :
+ 1;
+uint32_t hcintr :
+ 1;
+uint32_t ptxfempty :
+ 1;
+uint32_t Reserved27 :
+ 1;
+uint32_t conidstschng :
+ 1;
+uint32_t disconnect :
+ 1;
+uint32_t sessreqintr :
+ 1;
+uint32_t wkupintr :
+ 1;
+ }
+ b;
+} USB_OTG_GINTMSK_TypeDef ;
+typedef union _USB_OTG_GINTSTS_TypeDef
+{
+ uint32_t d32;
+ struct
+ {
+uint32_t curmode :
+ 1;
+uint32_t modemismatch :
+ 1;
+uint32_t otgintr :
+ 1;
+uint32_t sofintr :
+ 1;
+uint32_t rxstsqlvl :
+ 1;
+uint32_t nptxfempty :
+ 1;
+uint32_t ginnakeff :
+ 1;
+uint32_t goutnakeff :
+ 1;
+uint32_t Reserved8_9 :
+ 2;
+uint32_t erlysuspend :
+ 1;
+uint32_t usbsuspend :
+ 1;
+uint32_t usbreset :
+ 1;
+uint32_t enumdone :
+ 1;
+uint32_t isooutdrop :
+ 1;
+uint32_t eopframe :
+ 1;
+uint32_t Reserved16_17 :
+ 2;
+uint32_t inepint:
+ 1;
+uint32_t outepintr :
+ 1;
+uint32_t incomplisoin :
+ 1;
+uint32_t incomplisoout :
+ 1;
+uint32_t Reserved22_23 :
+ 2;
+uint32_t portintr :
+ 1;
+uint32_t hcintr :
+ 1;
+uint32_t ptxfempty :
+ 1;
+uint32_t Reserved27 :
+ 1;
+uint32_t conidstschng :
+ 1;
+uint32_t disconnect :
+ 1;
+uint32_t sessreqintr :
+ 1;
+uint32_t wkupintr :
+ 1;
+ }
+ b;
+} USB_OTG_GINTSTS_TypeDef ;
+typedef union _USB_OTG_DRXSTS_TypeDef
+{
+ uint32_t d32;
+ struct
+ {
+uint32_t epnum :
+ 4;
+uint32_t bcnt :
+ 11;
+uint32_t dpid :
+ 2;
+uint32_t pktsts :
+ 4;
+uint32_t fn :
+ 4;
+uint32_t Reserved :
+ 7;
+ }
+ b;
+} USB_OTG_DRXSTS_TypeDef ;
+typedef union _USB_OTG_GRXSTS_TypeDef
+{
+ uint32_t d32;
+ struct
+ {
+uint32_t chnum :
+ 4;
+uint32_t bcnt :
+ 11;
+uint32_t dpid :
+ 2;
+uint32_t pktsts :
+ 4;
+uint32_t Reserved :
+ 11;
+ }
+ b;
+} USB_OTG_GRXFSTS_TypeDef ;
+typedef union _USB_OTG_FSIZ_TypeDef
+{
+ uint32_t d32;
+ struct
+ {
+uint32_t startaddr :
+ 16;
+uint32_t depth :
+ 16;
+ }
+ b;
+} USB_OTG_FSIZ_TypeDef ;
+typedef union _USB_OTG_HNPTXSTS_TypeDef
+{
+ uint32_t d32;
+ struct
+ {
+ uint32_t nptxfspcavail :
+ 16;
+ uint32_t nptxqspcavail :
+ 8;
+ struct
+ {
+ uint32_t terminate :
+ 1;
+ uint32_t token :
+ 2;
+ uint32_t chnum :
+ 4;
+ } nptxqtop;
+ uint32_t Reserved :
+ 1;
+ }
+ b;
+} USB_OTG_HNPTXSTS_TypeDef ;
+typedef union _USB_OTG_DTXFSTSn_TypeDef
+{
+ uint32_t d32;
+ struct
+ {
+uint32_t txfspcavail :
+ 16;
+uint32_t Reserved :
+ 16;
+ }
+ b;
+} USB_OTG_DTXFSTSn_TypeDef ;
+
+typedef union _USB_OTG_GCCFG_TypeDef
+{
+ uint32_t d32;
+ struct
+ {
+uint32_t Reserved_in :
+ 16;
+uint32_t pwdn :
+ 1;
+uint32_t Reserved_17 :
+ 1;
+uint32_t vbussensingA :
+ 1;
+uint32_t vbussensingB :
+ 1;
+uint32_t sofouten :
+ 1;
+uint32_t disablevbussensing :
+ 1;
+uint32_t Reserved_out :
+ 10;
+ }
+ b;
+} USB_OTG_GCCFG_TypeDef ;
+
+typedef union _USB_OTG_DCFG_TypeDef
+{
+ uint32_t d32;
+ struct
+ {
+uint32_t devspd :
+ 2;
+uint32_t nzstsouthshk :
+ 1;
+uint32_t Reserved3 :
+ 1;
+uint32_t devaddr :
+ 7;
+uint32_t perfrint :
+ 2;
+uint32_t Reserved12_31 :
+ 19;
+ }
+ b;
+} USB_OTG_DCFG_TypeDef ;
+typedef union _USB_OTG_DCTL_TypeDef
+{
+ uint32_t d32;
+ struct
+ {
+uint32_t rmtwkupsig :
+ 1;
+uint32_t sftdiscon :
+ 1;
+uint32_t gnpinnaksts :
+ 1;
+uint32_t goutnaksts :
+ 1;
+uint32_t tstctl :
+ 3;
+uint32_t sgnpinnak :
+ 1;
+uint32_t cgnpinnak :
+ 1;
+uint32_t sgoutnak :
+ 1;
+uint32_t cgoutnak :
+ 1;
+uint32_t poprg_done :
+ 1;
+uint32_t Reserved :
+ 20;
+ }
+ b;
+} USB_OTG_DCTL_TypeDef ;
+typedef union _USB_OTG_DSTS_TypeDef
+{
+ uint32_t d32;
+ struct
+ {
+uint32_t suspsts :
+ 1;
+uint32_t enumspd :
+ 2;
+uint32_t errticerr :
+ 1;
+uint32_t Reserved4_7:
+ 4;
+uint32_t soffn :
+ 14;
+uint32_t Reserved22_31 :
+ 10;
+ }
+ b;
+} USB_OTG_DSTS_TypeDef ;
+typedef union _USB_OTG_DIEPINTn_TypeDef
+{
+ uint32_t d32;
+ struct
+ {
+uint32_t xfercompl :
+ 1;
+uint32_t epdisabled :
+ 1;
+uint32_t Reserved2 :
+ 1;
+uint32_t timeout :
+ 1;
+uint32_t intktxfemp :
+ 1;
+uint32_t Reserved5 :
+ 1;
+uint32_t inepnakeff :
+ 1;
+uint32_t emptyintr :
+ 1;
+uint32_t txfifoundrn :
+ 1;
+uint32_t Reserved14_31 :
+ 23;
+ }
+ b;
+} USB_OTG_DIEPINTn_TypeDef ;
+typedef union _USB_OTG_DIEPINTn_TypeDef USB_OTG_DIEPMSK_TypeDef ;
+typedef union _USB_OTG_DOEPINTn_TypeDef
+{
+ uint32_t d32;
+ struct
+ {
+uint32_t xfercompl :
+ 1;
+uint32_t epdisabled :
+ 1;
+uint32_t Reserved2 :
+ 1;
+uint32_t setup :
+ 1;
+uint32_t Reserved04_31 :
+ 28;
+ }
+ b;
+} USB_OTG_DOEPINTn_TypeDef ;
+typedef union _USB_OTG_DOEPINTn_TypeDef USB_OTG_DOEPMSK_TypeDef ;
+
+typedef union _USB_OTG_DAINT_TypeDef
+{
+ uint32_t d32;
+ struct
+ {
+uint32_t in :
+ 16;
+uint32_t out :
+ 16;
+ }
+ ep;
+} USB_OTG_DAINT_TypeDef ;
+
+typedef union _USB_OTG_DTHRCTL_TypeDef
+{
+ uint32_t d32;
+ struct
+ {
+uint32_t non_iso_thr_en :
+ 1;
+uint32_t iso_thr_en :
+ 1;
+uint32_t tx_thr_len :
+ 9;
+uint32_t Reserved11_15 :
+ 5;
+uint32_t rx_thr_en :
+ 1;
+uint32_t rx_thr_len :
+ 9;
+uint32_t Reserved26 :
+ 1;
+uint32_t arp_en :
+ 1;
+uint32_t Reserved28_31 :
+ 4;
+ }
+ b;
+} USB_OTG_DTHRCTL_TypeDef ;
+typedef union _USB_OTG_DEPCTL_TypeDef
+{
+ uint32_t d32;
+ struct
+ {
+uint32_t mps :
+ 11;
+uint32_t reserved :
+ 4;
+uint32_t usbactep :
+ 1;
+uint32_t dpid :
+ 1;
+uint32_t naksts :
+ 1;
+uint32_t eptype :
+ 2;
+uint32_t snp :
+ 1;
+uint32_t stall :
+ 1;
+uint32_t txfnum :
+ 4;
+uint32_t cnak :
+ 1;
+uint32_t snak :
+ 1;
+uint32_t setd0pid :
+ 1;
+uint32_t setd1pid :
+ 1;
+uint32_t epdis :
+ 1;
+uint32_t epena :
+ 1;
+ }
+ b;
+} USB_OTG_DEPCTL_TypeDef ;
+typedef union _USB_OTG_DEPXFRSIZ_TypeDef
+{
+ uint32_t d32;
+ struct
+ {
+uint32_t xfersize :
+ 19;
+uint32_t pktcnt :
+ 10;
+uint32_t mc :
+ 2;
+uint32_t Reserved :
+ 1;
+ }
+ b;
+} USB_OTG_DEPXFRSIZ_TypeDef ;
+typedef union _USB_OTG_DEP0XFRSIZ_TypeDef
+{
+ uint32_t d32;
+ struct
+ {
+uint32_t xfersize :
+ 7;
+uint32_t Reserved7_18 :
+ 12;
+uint32_t pktcnt :
+ 2;
+uint32_t Reserved20_28 :
+ 9;
+uint32_t supcnt :
+ 2;
+ uint32_t Reserved31;
+ }
+ b;
+} USB_OTG_DEP0XFRSIZ_TypeDef ;
+typedef union _USB_OTG_HCFG_TypeDef
+{
+ uint32_t d32;
+ struct
+ {
+uint32_t fslspclksel :
+ 2;
+uint32_t fslssupp :
+ 1;
+ }
+ b;
+} USB_OTG_HCFG_TypeDef ;
+typedef union _USB_OTG_HFRMINTRVL_TypeDef
+{
+ uint32_t d32;
+ struct
+ {
+uint32_t frint :
+ 16;
+uint32_t Reserved :
+ 16;
+ }
+ b;
+} USB_OTG_HFRMINTRVL_TypeDef ;
+
+typedef union _USB_OTG_HFNUM_TypeDef
+{
+ uint32_t d32;
+ struct
+ {
+uint32_t frnum :
+ 16;
+uint32_t frrem :
+ 16;
+ }
+ b;
+} USB_OTG_HFNUM_TypeDef ;
+typedef union _USB_OTG_HPTXSTS_TypeDef
+{
+ uint32_t d32;
+ struct
+ {
+uint32_t ptxfspcavail :
+ 16;
+uint32_t ptxqspcavail :
+ 8;
+ struct
+ {
+ uint32_t terminate :
+ 1;
+ uint32_t token :
+ 2;
+ uint32_t chnum :
+ 4;
+ uint32_t odd_even :
+ 1;
+ } ptxqtop;
+ }
+ b;
+} USB_OTG_HPTXSTS_TypeDef ;
+typedef union _USB_OTG_HPRT0_TypeDef
+{
+ uint32_t d32;
+ struct
+ {
+uint32_t prtconnsts :
+ 1;
+uint32_t prtconndet :
+ 1;
+uint32_t prtena :
+ 1;
+uint32_t prtenchng :
+ 1;
+uint32_t prtovrcurract :
+ 1;
+uint32_t prtovrcurrchng :
+ 1;
+uint32_t prtres :
+ 1;
+uint32_t prtsusp :
+ 1;
+uint32_t prtrst :
+ 1;
+uint32_t Reserved9 :
+ 1;
+uint32_t prtlnsts :
+ 2;
+uint32_t prtpwr :
+ 1;
+uint32_t prttstctl :
+ 4;
+uint32_t prtspd :
+ 2;
+uint32_t Reserved19_31 :
+ 13;
+ }
+ b;
+} USB_OTG_HPRT0_TypeDef ;
+typedef union _USB_OTG_HAINT_TypeDef
+{
+ uint32_t d32;
+ struct
+ {
+uint32_t chint :
+ 16;
+uint32_t Reserved :
+ 16;
+ }
+ b;
+} USB_OTG_HAINT_TypeDef ;
+typedef union _USB_OTG_HAINTMSK_TypeDef
+{
+ uint32_t d32;
+ struct
+ {
+uint32_t chint :
+ 16;
+uint32_t Reserved :
+ 16;
+ }
+ b;
+} USB_OTG_HAINTMSK_TypeDef ;
+typedef union _USB_OTG_HCCHAR_TypeDef
+{
+ uint32_t d32;
+ struct
+ {
+uint32_t mps :
+ 11;
+uint32_t epnum :
+ 4;
+uint32_t epdir :
+ 1;
+uint32_t Reserved :
+ 1;
+uint32_t lspddev :
+ 1;
+uint32_t eptype :
+ 2;
+uint32_t multicnt :
+ 2;
+uint32_t devaddr :
+ 7;
+uint32_t oddfrm :
+ 1;
+uint32_t chdis :
+ 1;
+uint32_t chen :
+ 1;
+ }
+ b;
+} USB_OTG_HCCHAR_TypeDef ;
+typedef union _USB_OTG_HCSPLT_TypeDef
+{
+ uint32_t d32;
+ struct
+ {
+uint32_t prtaddr :
+ 7;
+uint32_t hubaddr :
+ 7;
+uint32_t xactpos :
+ 2;
+uint32_t compsplt :
+ 1;
+uint32_t Reserved :
+ 14;
+uint32_t spltena :
+ 1;
+ }
+ b;
+} USB_OTG_HCSPLT_TypeDef ;
+typedef union _USB_OTG_HCINTn_TypeDef
+{
+ uint32_t d32;
+ struct
+ {
+uint32_t xfercompl :
+ 1;
+uint32_t chhltd :
+ 1;
+uint32_t ahberr :
+ 1;
+uint32_t stall :
+ 1;
+uint32_t nak :
+ 1;
+uint32_t ack :
+ 1;
+uint32_t nyet :
+ 1;
+uint32_t xacterr :
+ 1;
+uint32_t bblerr :
+ 1;
+uint32_t frmovrun :
+ 1;
+uint32_t datatglerr :
+ 1;
+uint32_t Reserved :
+ 21;
+ }
+ b;
+} USB_OTG_HCINTn_TypeDef ;
+typedef union _USB_OTG_HCTSIZn_TypeDef
+{
+ uint32_t d32;
+ struct
+ {
+uint32_t xfersize :
+ 19;
+uint32_t pktcnt :
+ 10;
+uint32_t pid :
+ 2;
+uint32_t dopng :
+ 1;
+ }
+ b;
+} USB_OTG_HCTSIZn_TypeDef ;
+typedef union _USB_OTG_HCINTMSK_TypeDef
+{
+ uint32_t d32;
+ struct
+ {
+uint32_t xfercompl :
+ 1;
+uint32_t chhltd :
+ 1;
+uint32_t ahberr :
+ 1;
+uint32_t stall :
+ 1;
+uint32_t nak :
+ 1;
+uint32_t ack :
+ 1;
+uint32_t nyet :
+ 1;
+uint32_t xacterr :
+ 1;
+uint32_t bblerr :
+ 1;
+uint32_t frmovrun :
+ 1;
+uint32_t datatglerr :
+ 1;
+uint32_t Reserved :
+ 21;
+ }
+ b;
+} USB_OTG_HCINTMSK_TypeDef ;
+
+typedef union _USB_OTG_PCGCCTL_TypeDef
+{
+ uint32_t d32;
+ struct
+ {
+uint32_t stoppclk :
+ 1;
+uint32_t gatehclk :
+ 1;
+uint32_t Reserved2_3 :
+ 2;
+uint32_t phy_susp :
+ 1;
+uint32_t Reserved5_31 :
+ 27;
+ }
+ b;
+} USB_OTG_PCGCCTL_TypeDef ;
+
+/**
+ * @}
+ */
+
+
+/** @defgroup USB_REGS_Exported_Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USB_REGS_Exported_Variables
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USB_REGS_Exported_FunctionsPrototype
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+#endif //__USB_OTG_REGS_H__
+
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
diff --git a/platform/mcu/STM32F4xx/drivers/usb/usbd_cdc_core.h b/platform/mcu/STM32F4xx/drivers/usb/usbd_cdc_core.h
new file mode 100644
index 00000000..0c0c3bdd
--- /dev/null
+++ b/platform/mcu/STM32F4xx/drivers/usb/usbd_cdc_core.h
@@ -0,0 +1,143 @@
+/**
+ ******************************************************************************
+ * @file usbd_cdc_core.h
+ * @author MCD Application Team
+ * @version V1.1.0
+ * @date 19-March-2012
+ * @brief header file for the usbd_cdc_core.c file.
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT 2012 STMicroelectronics
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (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.st.com/software_license_agreement_liberty_v2
+ *
+ * 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.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+
+#ifndef __USB_CDC_CORE_H_
+#define __USB_CDC_CORE_H_
+
+#include "usbd_ioreq.h"
+
+/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
+ * @{
+ */
+
+/** @defgroup usbd_cdc
+ * @brief This file is the Header file for USBD_cdc.c
+ * @{
+ */
+
+
+/** @defgroup usbd_cdc_Exported_Defines
+ * @{
+ */
+#define USB_CDC_CONFIG_DESC_SIZ (67)
+#define USB_CDC_DESC_SIZ (67-9)
+
+#define CDC_DESCRIPTOR_TYPE 0x21
+
+#define DEVICE_CLASS_CDC 0x02
+#define DEVICE_SUBCLASS_CDC 0x00
+
+
+#define USB_DEVICE_DESCRIPTOR_TYPE 0x01
+#define USB_CONFIGURATION_DESCRIPTOR_TYPE 0x02
+#define USB_STRING_DESCRIPTOR_TYPE 0x03
+#define USB_INTERFACE_DESCRIPTOR_TYPE 0x04
+#define USB_ENDPOINT_DESCRIPTOR_TYPE 0x05
+
+#define STANDARD_ENDPOINT_DESC_SIZE 0x09
+
+#define CDC_DATA_IN_PACKET_SIZE CDC_DATA_MAX_PACKET_SIZE
+
+#define CDC_DATA_OUT_PACKET_SIZE CDC_DATA_MAX_PACKET_SIZE
+
+/*---------------------------------------------------------------------*/
+/* CDC definitions */
+/*---------------------------------------------------------------------*/
+
+/**************************************************/
+/* CDC Requests */
+/**************************************************/
+#define SEND_ENCAPSULATED_COMMAND 0x00
+#define GET_ENCAPSULATED_RESPONSE 0x01
+#define SET_COMM_FEATURE 0x02
+#define GET_COMM_FEATURE 0x03
+#define CLEAR_COMM_FEATURE 0x04
+#define SET_LINE_CODING 0x20
+#define GET_LINE_CODING 0x21
+#define SET_CONTROL_LINE_STATE 0x22
+#define SEND_BREAK 0x23
+#define NO_CMD 0xFF
+
+/**
+ * @}
+ */
+
+
+/** @defgroup USBD_CORE_Exported_TypesDefinitions
+ * @{
+ */
+typedef struct _CDC_IF_PROP
+{
+ uint16_t (*pIf_Init) (void);
+ uint16_t (*pIf_DeInit) (void);
+ uint16_t (*pIf_Ctrl) (uint32_t Cmd, uint8_t* Buf, uint32_t Len);
+ uint16_t (*pIf_DataTx) (uint8_t* Buf, uint32_t Len);
+ uint16_t (*pIf_DataRx) (uint8_t* Buf, uint32_t Len);
+}
+CDC_IF_Prop_TypeDef;
+/**
+ * @}
+ */
+
+
+
+/** @defgroup USBD_CORE_Exported_Macros
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_CORE_Exported_Variables
+ * @{
+ */
+
+extern USBD_Class_cb_TypeDef USBD_CDC_cb;
+/**
+ * @}
+ */
+
+/** @defgroup USB_CORE_Exported_Functions
+ * @{
+ */
+/**
+ * @}
+ */
+
+#endif // __USB_CDC_CORE_H_
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/platform/mcu/STM32F4xx/drivers/usb/usbd_conf.h b/platform/mcu/STM32F4xx/drivers/usb/usbd_conf.h
new file mode 100644
index 00000000..00d4f095
--- /dev/null
+++ b/platform/mcu/STM32F4xx/drivers/usb/usbd_conf.h
@@ -0,0 +1,107 @@
+/**
+ ******************************************************************************
+ * @file usbd_conf.h
+ * @author MCD Application Team
+ * @version V1.1.0
+ * @date 19-March-2012
+ * @brief USB Device configuration file
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT 2012 STMicroelectronics
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (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.st.com/software_license_agreement_liberty_v2
+ *
+ * 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.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USBD_CONF__H__
+#define __USBD_CONF__H__
+
+/* Includes ------------------------------------------------------------------*/
+#include "usb_conf.h"
+
+/** @defgroup USB_CONF_Exported_Defines
+ * @{
+ */
+#define USBD_CFG_MAX_NUM 1
+#define USBD_ITF_MAX_NUM 1
+
+#define USBD_SELF_POWERED
+
+#define USB_MAX_STR_DESC_SIZ 255
+
+/** @defgroup USB_VCP_Class_Layer_Parameter
+ * @{
+ */
+#define CDC_IN_EP 0x81 /* EP1 for data IN */
+#define CDC_OUT_EP 0x01 /* EP1 for data OUT */
+#define CDC_CMD_EP 0x82 /* EP2 for CDC commands */
+
+/* CDC Endpoints parameters: you can fine tune these values depending on the needed baudrates and performance. */
+#ifdef USE_USB_OTG_HS
+ #define CDC_DATA_MAX_PACKET_SIZE 64 /* Endpoint IN & OUT Packet size */
+ #define CDC_CMD_PACKET_SZE 8 /* Control Endpoint Packet size */
+
+ #define CDC_IN_FRAME_INTERVAL 40 /* Number of micro-frames between IN transfers */
+ #define APP_RX_DATA_SIZE 2048 /* Total size of IN buffer:
+ APP_RX_DATA_SIZE*8/MAX_BAUDARATE*1000 should be > CDC_IN_FRAME_INTERVAL*8 */
+#else
+ #define CDC_DATA_MAX_PACKET_SIZE 64 /* Endpoint IN & OUT Packet size */
+ #define CDC_CMD_PACKET_SZE 8 /* Control Endpoint Packet size */
+
+ #define CDC_IN_FRAME_INTERVAL 5 /* Number of frames between IN transfers */
+ #define APP_RX_DATA_SIZE 2048 /* Total size of IN buffer:
+ APP_RX_DATA_SIZE*8/MAX_BAUDARATE*1000 should be > CDC_IN_FRAME_INTERVAL */
+#endif /* USE_USB_OTG_HS */
+
+#define APP_FOPS VCP_fops
+/**
+ * @}
+ */
+
+/** @defgroup USB_CONF_Exported_Types
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup USB_CONF_Exported_Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USB_CONF_Exported_Variables
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USB_CONF_Exported_FunctionsPrototype
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+#endif //__USBD_CONF__H__
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
diff --git a/platform/mcu/STM32F4xx/drivers/usb/usbd_core.c b/platform/mcu/STM32F4xx/drivers/usb/usbd_core.c
new file mode 100644
index 00000000..c09028ee
--- /dev/null
+++ b/platform/mcu/STM32F4xx/drivers/usb/usbd_core.c
@@ -0,0 +1,506 @@
+/**
+ ******************************************************************************
+ * @file usbd_core.c
+ * @author MCD Application Team
+ * @version V1.1.0
+ * @date 19-March-2012
+ * @brief This file provides all the USBD core functions.
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT 2012 STMicroelectronics
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (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.st.com/software_license_agreement_liberty_v2
+ *
+ * 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.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_core.h"
+#include "usbd_req.h"
+#include "usbd_ioreq.h"
+#include "usb_dcd_int.h"
+#include "usb_bsp.h"
+
+/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
+* @{
+*/
+
+
+/** @defgroup USBD_CORE
+* @brief usbd core module
+* @{
+*/
+
+/** @defgroup USBD_CORE_Private_TypesDefinitions
+* @{
+*/
+/**
+* @}
+*/
+
+
+/** @defgroup USBD_CORE_Private_Defines
+* @{
+*/
+
+/**
+* @}
+*/
+
+
+/** @defgroup USBD_CORE_Private_Macros
+* @{
+*/
+/**
+* @}
+*/
+
+
+
+
+/** @defgroup USBD_CORE_Private_FunctionPrototypes
+* @{
+*/
+static uint8_t USBD_SetupStage(USB_OTG_CORE_HANDLE *pdev);
+static uint8_t USBD_DataOutStage(USB_OTG_CORE_HANDLE *pdev , uint8_t epnum);
+static uint8_t USBD_DataInStage(USB_OTG_CORE_HANDLE *pdev , uint8_t epnum);
+static uint8_t USBD_SOF(USB_OTG_CORE_HANDLE *pdev);
+static uint8_t USBD_Reset(USB_OTG_CORE_HANDLE *pdev);
+static uint8_t USBD_Suspend(USB_OTG_CORE_HANDLE *pdev);
+static uint8_t USBD_Resume(USB_OTG_CORE_HANDLE *pdev);
+#ifdef VBUS_SENSING_ENABLED
+static uint8_t USBD_DevConnected(USB_OTG_CORE_HANDLE *pdev);
+static uint8_t USBD_DevDisconnected(USB_OTG_CORE_HANDLE *pdev);
+#endif
+static uint8_t USBD_IsoINIncomplete(USB_OTG_CORE_HANDLE *pdev);
+static uint8_t USBD_IsoOUTIncomplete(USB_OTG_CORE_HANDLE *pdev);
+static uint8_t USBD_RunTestMode (USB_OTG_CORE_HANDLE *pdev) ;
+/**
+* @}
+*/
+
+/** @defgroup USBD_CORE_Private_Variables
+* @{
+*/
+
+__IO USB_OTG_DCTL_TypeDef SET_TEST_MODE;
+
+USBD_DCD_INT_cb_TypeDef USBD_DCD_INT_cb =
+{
+ USBD_DataOutStage,
+ USBD_DataInStage,
+ USBD_SetupStage,
+ USBD_SOF,
+ USBD_Reset,
+ USBD_Suspend,
+ USBD_Resume,
+ USBD_IsoINIncomplete,
+ USBD_IsoOUTIncomplete,
+#ifdef VBUS_SENSING_ENABLED
+USBD_DevConnected,
+USBD_DevDisconnected,
+#endif
+};
+
+USBD_DCD_INT_cb_TypeDef *USBD_DCD_INT_fops = &USBD_DCD_INT_cb;
+/**
+* @}
+*/
+
+/** @defgroup USBD_CORE_Private_Functions
+* @{
+*/
+
+/**
+* @brief USBD_Init
+* Initailizes the device stack and load the class driver
+* @param pdev: device instance
+* @param core_address: USB OTG core ID
+* @param class_cb: Class callback structure address
+* @param usr_cb: User callback structure address
+* @retval None
+*/
+void USBD_Init(USB_OTG_CORE_HANDLE *pdev,
+ USB_OTG_CORE_ID_TypeDef coreID,
+ USBD_DEVICE *pDevice,
+ USBD_Class_cb_TypeDef *class_cb,
+ USBD_Usr_cb_TypeDef *usr_cb)
+{
+ /* Hardware Init */
+ USB_OTG_BSP_Init(pdev);
+
+ USBD_DeInit(pdev);
+
+ /*Register class and user callbacks */
+ pdev->dev.class_cb = class_cb;
+ pdev->dev.usr_cb = usr_cb;
+ pdev->dev.usr_device = pDevice;
+
+ /* set USB OTG core params */
+ DCD_Init(pdev , coreID);
+
+ /* Upon Init call usr callback */
+ pdev->dev.usr_cb->Init();
+
+ /* Enable Interrupts */
+ USB_OTG_BSP_EnableInterrupt(pdev);
+}
+
+/**
+* @brief USBD_DeInit
+* Re-Initialize th device library
+* @param pdev: device instance
+* @retval status: status
+*/
+USBD_Status USBD_DeInit(USB_OTG_CORE_HANDLE *pdev)
+{
+ /* Software Init */
+
+ return USBD_OK;
+}
+
+/**
+* @brief USBD_SetupStage
+* Handle the setup stage
+* @param pdev: device instance
+* @retval status
+*/
+static uint8_t USBD_SetupStage(USB_OTG_CORE_HANDLE *pdev)
+{
+ USB_SETUP_REQ req;
+
+ USBD_ParseSetupRequest(pdev , &req);
+
+ switch (req.bmRequest & 0x1F)
+ {
+ case USB_REQ_RECIPIENT_DEVICE:
+ USBD_StdDevReq (pdev, &req);
+ break;
+
+ case USB_REQ_RECIPIENT_INTERFACE:
+ USBD_StdItfReq(pdev, &req);
+ break;
+
+ case USB_REQ_RECIPIENT_ENDPOINT:
+ USBD_StdEPReq(pdev, &req);
+ break;
+
+ default:
+ DCD_EP_Stall(pdev , req.bmRequest & 0x80);
+ break;
+ }
+ return USBD_OK;
+}
+
+/**
+* @brief USBD_DataOutStage
+* Handle data out stage
+* @param pdev: device instance
+* @param epnum: endpoint index
+* @retval status
+*/
+static uint8_t USBD_DataOutStage(USB_OTG_CORE_HANDLE *pdev , uint8_t epnum)
+{
+ USB_OTG_EP *ep;
+
+ if(epnum == 0)
+ {
+ ep = &pdev->dev.out_ep[0];
+ if ( pdev->dev.device_state == USB_OTG_EP0_DATA_OUT)
+ {
+ if(ep->rem_data_len > ep->maxpacket)
+ {
+ ep->rem_data_len -= ep->maxpacket;
+
+ if(pdev->cfg.dma_enable == 1)
+ {
+ /* in slave mode this, is handled by the RxSTSQLvl ISR */
+ ep->xfer_buff += ep->maxpacket;
+ }
+ USBD_CtlContinueRx (pdev,
+ ep->xfer_buff,
+ MIN(ep->rem_data_len ,ep->maxpacket));
+ }
+ else
+ {
+ if((pdev->dev.class_cb->EP0_RxReady != NULL)&&
+ (pdev->dev.device_status == USB_OTG_CONFIGURED))
+ {
+ pdev->dev.class_cb->EP0_RxReady(pdev);
+ }
+ USBD_CtlSendStatus(pdev);
+ }
+ }
+ }
+ else if((pdev->dev.class_cb->DataOut != NULL)&&
+ (pdev->dev.device_status == USB_OTG_CONFIGURED))
+ {
+ pdev->dev.class_cb->DataOut(pdev, epnum);
+ }
+ return USBD_OK;
+}
+
+/**
+* @brief USBD_DataInStage
+* Handle data in stage
+* @param pdev: device instance
+* @param epnum: endpoint index
+* @retval status
+*/
+static uint8_t USBD_DataInStage(USB_OTG_CORE_HANDLE *pdev , uint8_t epnum)
+{
+ USB_OTG_EP *ep;
+
+ if(epnum == 0)
+ {
+ ep = &pdev->dev.in_ep[0];
+ if ( pdev->dev.device_state == USB_OTG_EP0_DATA_IN)
+ {
+ if(ep->rem_data_len > ep->maxpacket)
+ {
+ ep->rem_data_len -= ep->maxpacket;
+ if(pdev->cfg.dma_enable == 1)
+ {
+ /* in slave mode this, is handled by the TxFifoEmpty ISR */
+ ep->xfer_buff += ep->maxpacket;
+ }
+ USBD_CtlContinueSendData (pdev,
+ ep->xfer_buff,
+ ep->rem_data_len);
+ }
+ else
+ { /* last packet is MPS multiple, so send ZLP packet */
+ if((ep->total_data_len % ep->maxpacket == 0) &&
+ (ep->total_data_len >= ep->maxpacket) &&
+ (ep->total_data_len < ep->ctl_data_len ))
+ {
+
+ USBD_CtlContinueSendData(pdev , NULL, 0);
+ ep->ctl_data_len = 0;
+ }
+ else
+ {
+ if((pdev->dev.class_cb->EP0_TxSent != NULL)&&
+ (pdev->dev.device_status == USB_OTG_CONFIGURED))
+ {
+ pdev->dev.class_cb->EP0_TxSent(pdev);
+ }
+ USBD_CtlReceiveStatus(pdev);
+ }
+ }
+ }
+ if (pdev->dev.test_mode == 1)
+ {
+ USBD_RunTestMode(pdev);
+ pdev->dev.test_mode = 0;
+ }
+ }
+ else if((pdev->dev.class_cb->DataIn != NULL)&&
+ (pdev->dev.device_status == USB_OTG_CONFIGURED))
+ {
+ pdev->dev.class_cb->DataIn(pdev, epnum);
+ }
+ return USBD_OK;
+}
+
+
+
+
+/**
+* @brief USBD_RunTestMode
+* Launch test mode process
+* @param pdev: device instance
+* @retval status
+*/
+static uint8_t USBD_RunTestMode (USB_OTG_CORE_HANDLE *pdev)
+{
+ USB_OTG_WRITE_REG32(&pdev->regs.DREGS->DCTL, SET_TEST_MODE.d32);
+ return USBD_OK;
+}
+
+/**
+* @brief USBD_Reset
+* Handle Reset event
+* @param pdev: device instance
+* @retval status
+*/
+
+static uint8_t USBD_Reset(USB_OTG_CORE_HANDLE *pdev)
+{
+ /* Open EP0 OUT */
+ DCD_EP_Open(pdev,
+ 0x00,
+ USB_OTG_MAX_EP0_SIZE,
+ EP_TYPE_CTRL);
+
+ /* Open EP0 IN */
+ DCD_EP_Open(pdev,
+ 0x80,
+ USB_OTG_MAX_EP0_SIZE,
+ EP_TYPE_CTRL);
+
+ /* Upon Reset call usr call back */
+ pdev->dev.device_status = USB_OTG_DEFAULT;
+ pdev->dev.usr_cb->DeviceReset(pdev->cfg.speed);
+
+ return USBD_OK;
+}
+
+/**
+* @brief USBD_Resume
+* Handle Resume event
+* @param pdev: device instance
+* @retval status
+*/
+
+static uint8_t USBD_Resume(USB_OTG_CORE_HANDLE *pdev)
+{
+ /* Upon Resume call usr call back */
+ pdev->dev.usr_cb->DeviceResumed();
+ pdev->dev.device_status = pdev->dev.device_old_status;
+ pdev->dev.device_status = USB_OTG_CONFIGURED;
+ return USBD_OK;
+}
+
+
+/**
+* @brief USBD_Suspend
+* Handle Suspend event
+* @param pdev: device instance
+* @retval status
+*/
+
+static uint8_t USBD_Suspend(USB_OTG_CORE_HANDLE *pdev)
+{
+ pdev->dev.device_old_status = pdev->dev.device_status;
+ pdev->dev.device_status = USB_OTG_SUSPENDED;
+ /* Upon Resume call usr call back */
+ pdev->dev.usr_cb->DeviceSuspended();
+ return USBD_OK;
+}
+
+
+/**
+* @brief USBD_SOF
+* Handle SOF event
+* @param pdev: device instance
+* @retval status
+*/
+
+static uint8_t USBD_SOF(USB_OTG_CORE_HANDLE *pdev)
+{
+ if(pdev->dev.class_cb->SOF)
+ {
+ pdev->dev.class_cb->SOF(pdev);
+ }
+ return USBD_OK;
+}
+/**
+* @brief USBD_SetCfg
+* Configure device and start the interface
+* @param pdev: device instance
+* @param cfgidx: configuration index
+* @retval status
+*/
+
+USBD_Status USBD_SetCfg(USB_OTG_CORE_HANDLE *pdev, uint8_t cfgidx)
+{
+ pdev->dev.class_cb->Init(pdev, cfgidx);
+
+ /* Upon set config call usr call back */
+ pdev->dev.usr_cb->DeviceConfigured();
+ return USBD_OK;
+}
+
+/**
+* @brief USBD_ClrCfg
+* Clear current configuration
+* @param pdev: device instance
+* @param cfgidx: configuration index
+* @retval status: USBD_Status
+*/
+USBD_Status USBD_ClrCfg(USB_OTG_CORE_HANDLE *pdev, uint8_t cfgidx)
+{
+ pdev->dev.class_cb->DeInit(pdev, cfgidx);
+ return USBD_OK;
+}
+
+/**
+* @brief USBD_IsoINIncomplete
+* Handle iso in incomplete event
+* @param pdev: device instance
+* @retval status
+*/
+static uint8_t USBD_IsoINIncomplete(USB_OTG_CORE_HANDLE *pdev)
+{
+ pdev->dev.class_cb->IsoINIncomplete(pdev);
+ return USBD_OK;
+}
+
+/**
+* @brief USBD_IsoOUTIncomplete
+* Handle iso out incomplete event
+* @param pdev: device instance
+* @retval status
+*/
+static uint8_t USBD_IsoOUTIncomplete(USB_OTG_CORE_HANDLE *pdev)
+{
+ pdev->dev.class_cb->IsoOUTIncomplete(pdev);
+ return USBD_OK;
+}
+
+#ifdef VBUS_SENSING_ENABLED
+/**
+* @brief USBD_DevConnected
+* Handle device connection event
+* @param pdev: device instance
+* @retval status
+*/
+static uint8_t USBD_DevConnected(USB_OTG_CORE_HANDLE *pdev)
+{
+ pdev->dev.usr_cb->DeviceConnected();
+ pdev->dev.connection_status = 1;
+ return USBD_OK;
+}
+
+/**
+* @brief USBD_DevDisconnected
+* Handle device disconnection event
+* @param pdev: device instance
+* @retval status
+*/
+static uint8_t USBD_DevDisconnected(USB_OTG_CORE_HANDLE *pdev)
+{
+ pdev->dev.usr_cb->DeviceDisconnected();
+ pdev->dev.class_cb->DeInit(pdev, 0);
+ pdev->dev.connection_status = 0;
+ return USBD_OK;
+}
+#endif
+/**
+* @}
+*/
+
+
+/**
+* @}
+*/
+
+
+/**
+* @}
+*/
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
diff --git a/platform/mcu/STM32F4xx/drivers/usb/usbd_core.h b/platform/mcu/STM32F4xx/drivers/usb/usbd_core.h
new file mode 100644
index 00000000..1ba845c5
--- /dev/null
+++ b/platform/mcu/STM32F4xx/drivers/usb/usbd_core.h
@@ -0,0 +1,120 @@
+/**
+ ******************************************************************************
+ * @file usbd_core.h
+ * @author MCD Application Team
+ * @version V1.1.0
+ * @date 19-March-2012
+ * @brief Header file for usbd_core.c
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT 2012 STMicroelectronics
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (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.st.com/software_license_agreement_liberty_v2
+ *
+ * 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.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USBD_CORE_H
+#define __USBD_CORE_H
+
+/* Includes ------------------------------------------------------------------*/
+#include "usb_dcd.h"
+#include "usbd_def.h"
+#include "usbd_conf.h"
+
+/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
+ * @{
+ */
+
+/** @defgroup USBD_CORE
+ * @brief This file is the Header file for usbd_core.c file
+ * @{
+ */
+
+
+/** @defgroup USBD_CORE_Exported_Defines
+ * @{
+ */
+
+typedef enum {
+ USBD_OK = 0,
+ USBD_BUSY,
+ USBD_FAIL,
+}USBD_Status;
+/**
+ * @}
+ */
+
+
+/** @defgroup USBD_CORE_Exported_TypesDefinitions
+ * @{
+ */
+
+
+/**
+ * @}
+ */
+
+
+
+/** @defgroup USBD_CORE_Exported_Macros
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_CORE_Exported_Variables
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_CORE_Exported_FunctionsPrototype
+ * @{
+ */
+void USBD_Init(USB_OTG_CORE_HANDLE *pdev,
+ USB_OTG_CORE_ID_TypeDef coreID,
+ USBD_DEVICE *pDevice,
+ USBD_Class_cb_TypeDef *class_cb,
+ USBD_Usr_cb_TypeDef *usr_cb);
+
+USBD_Status USBD_DeInit(USB_OTG_CORE_HANDLE *pdev);
+
+USBD_Status USBD_ClrCfg(USB_OTG_CORE_HANDLE *pdev, uint8_t cfgidx);
+
+USBD_Status USBD_SetCfg(USB_OTG_CORE_HANDLE *pdev, uint8_t cfgidx);
+
+/**
+ * @}
+ */
+
+#endif /* __USBD_CORE_H */
+
+/**
+ * @}
+ */
+
+/**
+* @}
+*/
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
+
+
diff --git a/platform/mcu/STM32F4xx/drivers/usb/usbd_def.h b/platform/mcu/STM32F4xx/drivers/usb/usbd_def.h
new file mode 100644
index 00000000..2aa13254
--- /dev/null
+++ b/platform/mcu/STM32F4xx/drivers/usb/usbd_def.h
@@ -0,0 +1,156 @@
+/**
+ ******************************************************************************
+ * @file usbd_def.h
+ * @author MCD Application Team
+ * @version V1.1.0
+ * @date 19-March-2012
+ * @brief general defines for the usb device library
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT 2012 STMicroelectronics
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (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.st.com/software_license_agreement_liberty_v2
+ *
+ * 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.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+
+#ifndef __USBD_DEF_H
+#define __USBD_DEF_H
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_conf.h"
+
+/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
+ * @{
+ */
+
+/** @defgroup USB_DEF
+ * @brief general defines for the usb device library file
+ * @{
+ */
+
+/** @defgroup USB_DEF_Exported_Defines
+ * @{
+ */
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+#define USB_LEN_DEV_QUALIFIER_DESC 0x0A
+#define USB_LEN_DEV_DESC 0x12
+#define USB_LEN_CFG_DESC 0x09
+#define USB_LEN_IF_DESC 0x09
+#define USB_LEN_EP_DESC 0x07
+#define USB_LEN_OTG_DESC 0x03
+
+#define USBD_IDX_LANGID_STR 0x00
+#define USBD_IDX_MFC_STR 0x01
+#define USBD_IDX_PRODUCT_STR 0x02
+#define USBD_IDX_SERIAL_STR 0x03
+#define USBD_IDX_CONFIG_STR 0x04
+#define USBD_IDX_INTERFACE_STR 0x05
+
+#define USB_REQ_TYPE_STANDARD 0x00
+#define USB_REQ_TYPE_CLASS 0x20
+#define USB_REQ_TYPE_VENDOR 0x40
+#define USB_REQ_TYPE_MASK 0x60
+
+#define USB_REQ_RECIPIENT_DEVICE 0x00
+#define USB_REQ_RECIPIENT_INTERFACE 0x01
+#define USB_REQ_RECIPIENT_ENDPOINT 0x02
+#define USB_REQ_RECIPIENT_MASK 0x03
+
+#define USB_REQ_GET_STATUS 0x00
+#define USB_REQ_CLEAR_FEATURE 0x01
+#define USB_REQ_SET_FEATURE 0x03
+#define USB_REQ_SET_ADDRESS 0x05
+#define USB_REQ_GET_DESCRIPTOR 0x06
+#define USB_REQ_SET_DESCRIPTOR 0x07
+#define USB_REQ_GET_CONFIGURATION 0x08
+#define USB_REQ_SET_CONFIGURATION 0x09
+#define USB_REQ_GET_INTERFACE 0x0A
+#define USB_REQ_SET_INTERFACE 0x0B
+#define USB_REQ_SYNCH_FRAME 0x0C
+
+#define USB_DESC_TYPE_DEVICE 1
+#define USB_DESC_TYPE_CONFIGURATION 2
+#define USB_DESC_TYPE_STRING 3
+#define USB_DESC_TYPE_INTERFACE 4
+#define USB_DESC_TYPE_ENDPOINT 5
+#define USB_DESC_TYPE_DEVICE_QUALIFIER 6
+#define USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION 7
+
+
+#define USB_CONFIG_REMOTE_WAKEUP 2
+#define USB_CONFIG_SELF_POWERED 1
+
+#define USB_FEATURE_EP_HALT 0
+#define USB_FEATURE_REMOTE_WAKEUP 1
+#define USB_FEATURE_TEST_MODE 2
+
+/**
+ * @}
+ */
+
+
+/** @defgroup USBD_DEF_Exported_TypesDefinitions
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+
+/** @defgroup USBD_DEF_Exported_Macros
+ * @{
+ */
+#define SWAPBYTE(addr) (((uint16_t)(*((uint8_t *)(addr)))) + \
+ (((uint16_t)(*(((uint8_t *)(addr)) + 1))) << 8))
+
+#define LOBYTE(x) ((uint8_t)(x & 0x00FF))
+#define HIBYTE(x) ((uint8_t)((x & 0xFF00) >>8))
+/**
+ * @}
+ */
+
+/** @defgroup USBD_DEF_Exported_Variables
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_DEF_Exported_FunctionsPrototype
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+#endif /* __USBD_DEF_H */
+
+/**
+ * @}
+ */
+
+/**
+* @}
+*/
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/platform/mcu/STM32F4xx/drivers/usb/usbd_desc.c b/platform/mcu/STM32F4xx/drivers/usb/usbd_desc.c
new file mode 100644
index 00000000..47284da9
--- /dev/null
+++ b/platform/mcu/STM32F4xx/drivers/usb/usbd_desc.c
@@ -0,0 +1,212 @@
+/**
+ ******************************************************************************
+ * @file usbd_desc.c
+ * @author MCD Application Team
+ * @version V1.1.0
+ * @date 19-March-2012
+ * @brief This file provides the USBD descriptors and string formating method.
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT 2012 STMicroelectronics
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (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.st.com/software_license_agreement_liberty_v2
+ *
+ * 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.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_core.h"
+#include "usbd_desc.h"
+#include "usbd_req.h"
+#include "usbd_conf.h"
+#include "usb_regs.h"
+
+#define USBD_VID 0x0483
+#define USBD_PID 0x5740
+
+/** @defgroup USB_String_Descriptors
+ * @{
+ */
+#define USBD_LANGID_STRING 0x409
+#define USBD_MANUFACTURER_STRING "STMicroelectronics"
+
+#define USBD_PRODUCT_HS_STRING "STM32 Virtual ComPort in HS mode"
+#define USBD_SERIALNUMBER_HS_STRING "00000000050B"
+
+#define USBD_PRODUCT_FS_STRING "STM32 Virtual ComPort in FS Mode"
+#define USBD_SERIALNUMBER_FS_STRING "00000000050C"
+
+#define USBD_CONFIGURATION_HS_STRING "VCP Config"
+#define USBD_INTERFACE_HS_STRING "VCP Interface"
+
+#define USBD_CONFIGURATION_FS_STRING "VCP Config"
+#define USBD_INTERFACE_FS_STRING "VCP Interface"
+
+
+USBD_DEVICE USR_desc =
+{
+ USBD_USR_DeviceDescriptor,
+ USBD_USR_LangIDStrDescriptor,
+ USBD_USR_ManufacturerStrDescriptor,
+ USBD_USR_ProductStrDescriptor,
+ USBD_USR_SerialStrDescriptor,
+ USBD_USR_ConfigStrDescriptor,
+ USBD_USR_InterfaceStrDescriptor,
+
+};
+
+/* USB Standard Device Descriptor */
+__ALIGN_BEGIN uint8_t USBD_DeviceDesc[USB_SIZ_DEVICE_DESC] __ALIGN_END =
+ {
+ 0x12, /*bLength */
+ USB_DEVICE_DESCRIPTOR_TYPE, /*bDescriptorType*/
+ 0x00, /*bcdUSB */
+ 0x02,
+ 0x00, /*bDeviceClass*/
+ 0x00, /*bDeviceSubClass*/
+ 0x00, /*bDeviceProtocol*/
+ USB_OTG_MAX_EP0_SIZE, /*bMaxPacketSize*/
+ LOBYTE(USBD_VID), /*idVendor*/
+ HIBYTE(USBD_VID), /*idVendor*/
+ LOBYTE(USBD_PID), /*idVendor*/
+ HIBYTE(USBD_PID), /*idVendor*/
+ 0x00, /*bcdDevice rel. 2.00*/
+ 0x02,
+ USBD_IDX_MFC_STR, /*Index of manufacturer string*/
+ USBD_IDX_PRODUCT_STR, /*Index of product string*/
+ USBD_IDX_SERIAL_STR, /*Index of serial number string*/
+ USBD_CFG_MAX_NUM /*bNumConfigurations*/
+ } ; /* USB_DeviceDescriptor */
+
+/* USB Standard Device Descriptor */
+__ALIGN_BEGIN uint8_t USBD_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END =
+{
+ USB_LEN_DEV_QUALIFIER_DESC,
+ USB_DESC_TYPE_DEVICE_QUALIFIER,
+ 0x00,
+ 0x02,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x40,
+ 0x01,
+ 0x00,
+};
+
+/* USB Standard Device Descriptor */
+__ALIGN_BEGIN uint8_t USBD_LangIDDesc[USB_SIZ_STRING_LANGID] __ALIGN_END =
+{
+ USB_SIZ_STRING_LANGID,
+ USB_DESC_TYPE_STRING,
+ LOBYTE(USBD_LANGID_STRING),
+ HIBYTE(USBD_LANGID_STRING),
+};
+
+/**
+* @brief USBD_USR_DeviceDescriptor
+* return the device descriptor
+* @param speed : current device speed
+* @param length : pointer to data length variable
+* @retval pointer to descriptor buffer
+*/
+uint8_t * USBD_USR_DeviceDescriptor( uint8_t speed , uint16_t *length)
+{
+ *length = sizeof(USBD_DeviceDesc);
+ return USBD_DeviceDesc;
+}
+
+/**
+* @brief USBD_USR_LangIDStrDescriptor
+* return the LangID string descriptor
+* @param speed : current device speed
+* @param length : pointer to data length variable
+* @retval pointer to descriptor buffer
+*/
+uint8_t * USBD_USR_LangIDStrDescriptor( uint8_t speed , uint16_t *length)
+{
+ *length = sizeof(USBD_LangIDDesc);
+ return USBD_LangIDDesc;
+}
+
+
+/**
+* @brief USBD_USR_ProductStrDescriptor
+* return the product string descriptor
+* @param speed : current device speed
+* @param length : pointer to data length variable
+* @retval pointer to descriptor buffer
+*/
+uint8_t * USBD_USR_ProductStrDescriptor( uint8_t speed , uint16_t *length)
+{
+ USBD_GetString (USBD_PRODUCT_FS_STRING, USBD_StrDesc, length);
+ return USBD_StrDesc;
+}
+
+/**
+* @brief USBD_USR_ManufacturerStrDescriptor
+* return the manufacturer string descriptor
+* @param speed : current device speed
+* @param length : pointer to data length variable
+* @retval pointer to descriptor buffer
+*/
+uint8_t * USBD_USR_ManufacturerStrDescriptor( uint8_t speed , uint16_t *length)
+{
+ USBD_GetString (USBD_MANUFACTURER_STRING, USBD_StrDesc, length);
+ return USBD_StrDesc;
+}
+
+/**
+* @brief USBD_USR_SerialStrDescriptor
+* return the serial number string descriptor
+* @param speed : current device speed
+* @param length : pointer to data length variable
+* @retval pointer to descriptor buffer
+*/
+uint8_t * USBD_USR_SerialStrDescriptor( uint8_t speed , uint16_t *length)
+{
+ USBD_GetString (USBD_SERIALNUMBER_FS_STRING, USBD_StrDesc, length);
+ return USBD_StrDesc;
+}
+
+/**
+* @brief USBD_USR_ConfigStrDescriptor
+* return the configuration string descriptor
+* @param speed : current device speed
+* @param length : pointer to data length variable
+* @retval pointer to descriptor buffer
+*/
+uint8_t * USBD_USR_ConfigStrDescriptor( uint8_t speed , uint16_t *length)
+{
+ USBD_GetString (USBD_CONFIGURATION_FS_STRING, USBD_StrDesc, length);
+ return USBD_StrDesc;
+}
+
+
+/**
+* @brief USBD_USR_InterfaceStrDescriptor
+* return the interface string descriptor
+* @param speed : current device speed
+* @param length : pointer to data length variable
+* @retval pointer to descriptor buffer
+*/
+uint8_t * USBD_USR_InterfaceStrDescriptor( uint8_t speed , uint16_t *length)
+{
+ USBD_GetString (USBD_INTERFACE_FS_STRING, USBD_StrDesc, length);
+ return USBD_StrDesc;
+}
+
+
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
diff --git a/platform/mcu/STM32F4xx/drivers/usb/usbd_desc.h b/platform/mcu/STM32F4xx/drivers/usb/usbd_desc.h
new file mode 100644
index 00000000..75b694e7
--- /dev/null
+++ b/platform/mcu/STM32F4xx/drivers/usb/usbd_desc.h
@@ -0,0 +1,120 @@
+/**
+ ******************************************************************************
+ * @file usbd_desc.h
+ * @author MCD Application Team
+ * @version V1.1.0
+ * @date 19-March-2012
+ * @brief header file for the usbd_desc.c file
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT 2012 STMicroelectronics
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (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.st.com/software_license_agreement_liberty_v2
+ *
+ * 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.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+
+#ifndef __USB_DESC_H
+#define __USB_DESC_H
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_def.h"
+
+/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
+ * @{
+ */
+
+/** @defgroup USB_DESC
+ * @brief general defines for the usb device library file
+ * @{
+ */
+
+/** @defgroup USB_DESC_Exported_Defines
+ * @{
+ */
+#define USB_DEVICE_DESCRIPTOR_TYPE 0x01
+#define USB_CONFIGURATION_DESCRIPTOR_TYPE 0x02
+#define USB_STRING_DESCRIPTOR_TYPE 0x03
+#define USB_INTERFACE_DESCRIPTOR_TYPE 0x04
+#define USB_ENDPOINT_DESCRIPTOR_TYPE 0x05
+#define USB_SIZ_DEVICE_DESC 18
+#define USB_SIZ_STRING_LANGID 4
+
+/**
+ * @}
+ */
+
+
+/** @defgroup USBD_DESC_Exported_TypesDefinitions
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+
+/** @defgroup USBD_DESC_Exported_Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USBD_DESC_Exported_Variables
+ * @{
+ */
+extern uint8_t USBD_DeviceDesc [USB_SIZ_DEVICE_DESC];
+extern uint8_t USBD_StrDesc[USB_MAX_STR_DESC_SIZ];
+extern uint8_t USBD_OtherSpeedCfgDesc[USB_LEN_CFG_DESC];
+extern uint8_t USBD_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC];
+extern uint8_t USBD_LangIDDesc[USB_SIZ_STRING_LANGID];
+extern USBD_DEVICE USR_desc;
+/**
+ * @}
+ */
+
+/** @defgroup USBD_DESC_Exported_FunctionsPrototype
+ * @{
+ */
+
+
+uint8_t * USBD_USR_DeviceDescriptor( uint8_t speed , uint16_t *length);
+uint8_t * USBD_USR_LangIDStrDescriptor( uint8_t speed , uint16_t *length);
+uint8_t * USBD_USR_ManufacturerStrDescriptor ( uint8_t speed , uint16_t *length);
+uint8_t * USBD_USR_ProductStrDescriptor ( uint8_t speed , uint16_t *length);
+uint8_t * USBD_USR_SerialStrDescriptor( uint8_t speed , uint16_t *length);
+uint8_t * USBD_USR_ConfigStrDescriptor( uint8_t speed , uint16_t *length);
+uint8_t * USBD_USR_InterfaceStrDescriptor( uint8_t speed , uint16_t *length);
+
+#ifdef USB_SUPPORT_USER_STRING_DESC
+uint8_t * USBD_USR_USRStringDesc (uint8_t speed, uint8_t idx , uint16_t *length);
+#endif /* USB_SUPPORT_USER_STRING_DESC */
+
+/**
+ * @}
+ */
+
+#endif /* __USBD_DESC_H */
+
+/**
+ * @}
+ */
+
+/**
+* @}
+*/
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/platform/mcu/STM32F4xx/drivers/usb/usbd_ioreq.c b/platform/mcu/STM32F4xx/drivers/usb/usbd_ioreq.c
new file mode 100644
index 00000000..139a86a9
--- /dev/null
+++ b/platform/mcu/STM32F4xx/drivers/usb/usbd_ioreq.c
@@ -0,0 +1,244 @@
+/**
+ ******************************************************************************
+ * @file usbd_ioreq.c
+ * @author MCD Application Team
+ * @version V1.1.0
+ * @date 19-March-2012
+ * @brief This file provides the IO requests APIs for control endpoints.
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT 2012 STMicroelectronics
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (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.st.com/software_license_agreement_liberty_v2
+ *
+ * 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.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_ioreq.h"
+
+/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
+ * @{
+ */
+
+
+/** @defgroup USBD_IOREQ
+ * @brief control I/O requests module
+ * @{
+ */
+
+/** @defgroup USBD_IOREQ_Private_TypesDefinitions
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup USBD_IOREQ_Private_Defines
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+
+/** @defgroup USBD_IOREQ_Private_Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup USBD_IOREQ_Private_Variables
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+
+/** @defgroup USBD_IOREQ_Private_FunctionPrototypes
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup USBD_IOREQ_Private_Functions
+ * @{
+ */
+
+/**
+* @brief USBD_CtlSendData
+* send data on the ctl pipe
+* @param pdev: device instance
+* @param buff: pointer to data buffer
+* @param len: length of data to be sent
+* @retval status
+*/
+USBD_Status USBD_CtlSendData (USB_OTG_CORE_HANDLE *pdev,
+ uint8_t *pbuf,
+ uint16_t len)
+{
+ USBD_Status ret = USBD_OK;
+
+ pdev->dev.in_ep[0].total_data_len = len;
+ pdev->dev.in_ep[0].rem_data_len = len;
+ pdev->dev.device_state = USB_OTG_EP0_DATA_IN;
+
+ DCD_EP_Tx (pdev, 0, pbuf, len);
+
+ return ret;
+}
+
+/**
+* @brief USBD_CtlContinueSendData
+* continue sending data on the ctl pipe
+* @param pdev: device instance
+* @param buff: pointer to data buffer
+* @param len: length of data to be sent
+* @retval status
+*/
+USBD_Status USBD_CtlContinueSendData (USB_OTG_CORE_HANDLE *pdev,
+ uint8_t *pbuf,
+ uint16_t len)
+{
+ USBD_Status ret = USBD_OK;
+
+ DCD_EP_Tx (pdev, 0, pbuf, len);
+
+
+ return ret;
+}
+
+/**
+* @brief USBD_CtlPrepareRx
+* receive data on the ctl pipe
+* @param pdev: USB OTG device instance
+* @param buff: pointer to data buffer
+* @param len: length of data to be received
+* @retval status
+*/
+USBD_Status USBD_CtlPrepareRx (USB_OTG_CORE_HANDLE *pdev,
+ uint8_t *pbuf,
+ uint16_t len)
+{
+ USBD_Status ret = USBD_OK;
+
+ pdev->dev.out_ep[0].total_data_len = len;
+ pdev->dev.out_ep[0].rem_data_len = len;
+ pdev->dev.device_state = USB_OTG_EP0_DATA_OUT;
+
+ DCD_EP_PrepareRx (pdev,
+ 0,
+ pbuf,
+ len);
+
+
+ return ret;
+}
+
+/**
+* @brief USBD_CtlContinueRx
+* continue receive data on the ctl pipe
+* @param pdev: USB OTG device instance
+* @param buff: pointer to data buffer
+* @param len: length of data to be received
+* @retval status
+*/
+USBD_Status USBD_CtlContinueRx (USB_OTG_CORE_HANDLE *pdev,
+ uint8_t *pbuf,
+ uint16_t len)
+{
+ USBD_Status ret = USBD_OK;
+
+ DCD_EP_PrepareRx (pdev,
+ 0,
+ pbuf,
+ len);
+ return ret;
+}
+/**
+* @brief USBD_CtlSendStatus
+* send zero lzngth packet on the ctl pipe
+* @param pdev: USB OTG device instance
+* @retval status
+*/
+USBD_Status USBD_CtlSendStatus (USB_OTG_CORE_HANDLE *pdev)
+{
+ USBD_Status ret = USBD_OK;
+ pdev->dev.device_state = USB_OTG_EP0_STATUS_IN;
+ DCD_EP_Tx (pdev,
+ 0,
+ NULL,
+ 0);
+
+ USB_OTG_EP0_OutStart(pdev);
+
+ return ret;
+}
+
+/**
+* @brief USBD_CtlReceiveStatus
+* receive zero lzngth packet on the ctl pipe
+* @param pdev: USB OTG device instance
+* @retval status
+*/
+USBD_Status USBD_CtlReceiveStatus (USB_OTG_CORE_HANDLE *pdev)
+{
+ USBD_Status ret = USBD_OK;
+ pdev->dev.device_state = USB_OTG_EP0_STATUS_OUT;
+ DCD_EP_PrepareRx ( pdev,
+ 0,
+ NULL,
+ 0);
+
+ USB_OTG_EP0_OutStart(pdev);
+
+ return ret;
+}
+
+
+/**
+* @brief USBD_GetRxCount
+* returns the received data length
+* @param pdev: USB OTG device instance
+* epnum: endpoint index
+* @retval Rx Data blength
+*/
+uint16_t USBD_GetRxCount (USB_OTG_CORE_HANDLE *pdev , uint8_t epnum)
+{
+ return pdev->dev.out_ep[epnum].xfer_count;
+}
+
+/**
+ * @}
+ */
+
+
+/**
+ * @}
+ */
+
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/platform/mcu/STM32F4xx/drivers/usb/usbd_ioreq.h b/platform/mcu/STM32F4xx/drivers/usb/usbd_ioreq.h
new file mode 100644
index 00000000..b385b31c
--- /dev/null
+++ b/platform/mcu/STM32F4xx/drivers/usb/usbd_ioreq.h
@@ -0,0 +1,121 @@
+/**
+ ******************************************************************************
+ * @file usbd_ioreq.h
+ * @author MCD Application Team
+ * @version V1.1.0
+ * @date 19-March-2012
+ * @brief header file for the usbd_ioreq.c file
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT 2012 STMicroelectronics
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (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.st.com/software_license_agreement_liberty_v2
+ *
+ * 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.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+
+#ifndef __USBD_IOREQ_H_
+#define __USBD_IOREQ_H_
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_def.h"
+#include "usbd_core.h"
+
+/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
+ * @{
+ */
+
+/** @defgroup USBD_IOREQ
+ * @brief header file for the usbd_ioreq.c file
+ * @{
+ */
+
+/** @defgroup USBD_IOREQ_Exported_Defines
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup USBD_IOREQ_Exported_Types
+ * @{
+ */
+
+
+/**
+ * @}
+ */
+
+
+
+/** @defgroup USBD_IOREQ_Exported_Macros
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_IOREQ_Exported_Variables
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_IOREQ_Exported_FunctionsPrototype
+ * @{
+ */
+
+USBD_Status USBD_CtlSendData (USB_OTG_CORE_HANDLE *pdev,
+ uint8_t *buf,
+ uint16_t len);
+
+USBD_Status USBD_CtlContinueSendData (USB_OTG_CORE_HANDLE *pdev,
+ uint8_t *pbuf,
+ uint16_t len);
+
+USBD_Status USBD_CtlPrepareRx (USB_OTG_CORE_HANDLE *pdev,
+ uint8_t *pbuf,
+ uint16_t len);
+
+USBD_Status USBD_CtlContinueRx (USB_OTG_CORE_HANDLE *pdev,
+ uint8_t *pbuf,
+ uint16_t len);
+
+USBD_Status USBD_CtlSendStatus (USB_OTG_CORE_HANDLE *pdev);
+
+USBD_Status USBD_CtlReceiveStatus (USB_OTG_CORE_HANDLE *pdev);
+
+uint16_t USBD_GetRxCount (USB_OTG_CORE_HANDLE *pdev ,
+ uint8_t epnum);
+
+/**
+ * @}
+ */
+
+#endif /* __USBD_IOREQ_H_ */
+
+/**
+ * @}
+ */
+
+/**
+* @}
+*/
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/platform/mcu/STM32F4xx/drivers/usb/usbd_req.c b/platform/mcu/STM32F4xx/drivers/usb/usbd_req.c
new file mode 100644
index 00000000..f2ed4f45
--- /dev/null
+++ b/platform/mcu/STM32F4xx/drivers/usb/usbd_req.c
@@ -0,0 +1,868 @@
+/**
+ ******************************************************************************
+ * @file usbd_req.c
+ * @author MCD Application Team
+ * @version V1.1.0
+ * @date 19-March-2012
+ * @brief This file provides the standard USB requests following chapter 9.
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT 2012 STMicroelectronics
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (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.st.com/software_license_agreement_liberty_v2
+ *
+ * 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.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_req.h"
+#include "usbd_ioreq.h"
+#include "usbd_desc.h"
+
+
+/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
+ * @{
+ */
+
+
+/** @defgroup USBD_REQ
+ * @brief USB standard requests module
+ * @{
+ */
+
+/** @defgroup USBD_REQ_Private_TypesDefinitions
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup USBD_REQ_Private_Defines
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+
+/** @defgroup USBD_REQ_Private_Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup USBD_REQ_Private_Variables
+ * @{
+ */
+extern __IO USB_OTG_DCTL_TypeDef SET_TEST_MODE;
+
+#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
+ #if defined ( __ICCARM__ ) /*!< IAR Compiler */
+ #pragma data_alignment=4
+ #endif
+#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
+__ALIGN_BEGIN uint32_t USBD_ep_status __ALIGN_END = 0;
+
+#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
+ #if defined ( __ICCARM__ ) /*!< IAR Compiler */
+ #pragma data_alignment=4
+ #endif
+#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
+__ALIGN_BEGIN uint32_t USBD_default_cfg __ALIGN_END = 0;
+
+#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
+ #if defined ( __ICCARM__ ) /*!< IAR Compiler */
+ #pragma data_alignment=4
+ #endif
+#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
+__ALIGN_BEGIN uint32_t USBD_cfg_status __ALIGN_END = 0;
+
+#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
+ #if defined ( __ICCARM__ ) /*!< IAR Compiler */
+ #pragma data_alignment=4
+ #endif
+#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
+__ALIGN_BEGIN uint8_t USBD_StrDesc[USB_MAX_STR_DESC_SIZ] __ALIGN_END ;
+/**
+ * @}
+ */
+
+
+/** @defgroup USBD_REQ_Private_FunctionPrototypes
+ * @{
+ */
+static void USBD_GetDescriptor(USB_OTG_CORE_HANDLE *pdev,
+ USB_SETUP_REQ *req);
+
+static void USBD_SetAddress(USB_OTG_CORE_HANDLE *pdev,
+ USB_SETUP_REQ *req);
+
+static void USBD_SetConfig(USB_OTG_CORE_HANDLE *pdev,
+ USB_SETUP_REQ *req);
+
+static void USBD_GetConfig(USB_OTG_CORE_HANDLE *pdev,
+ USB_SETUP_REQ *req);
+
+static void USBD_GetStatus(USB_OTG_CORE_HANDLE *pdev,
+ USB_SETUP_REQ *req);
+
+static void USBD_SetFeature(USB_OTG_CORE_HANDLE *pdev,
+ USB_SETUP_REQ *req);
+
+static void USBD_ClrFeature(USB_OTG_CORE_HANDLE *pdev,
+ USB_SETUP_REQ *req);
+
+static uint8_t USBD_GetLen(uint8_t *buf);
+/**
+ * @}
+ */
+
+
+/** @defgroup USBD_REQ_Private_Functions
+ * @{
+ */
+
+
+/**
+* @brief USBD_StdDevReq
+* Handle standard usb device requests
+* @param pdev: device instance
+* @param req: usb request
+* @retval status
+*/
+USBD_Status USBD_StdDevReq (USB_OTG_CORE_HANDLE *pdev, USB_SETUP_REQ *req)
+{
+ USBD_Status ret = USBD_OK;
+
+ switch (req->bRequest)
+ {
+ case USB_REQ_GET_DESCRIPTOR:
+
+ USBD_GetDescriptor (pdev, req) ;
+ break;
+
+ case USB_REQ_SET_ADDRESS:
+ USBD_SetAddress(pdev, req);
+ break;
+
+ case USB_REQ_SET_CONFIGURATION:
+ USBD_SetConfig (pdev , req);
+ break;
+
+ case USB_REQ_GET_CONFIGURATION:
+ USBD_GetConfig (pdev , req);
+ break;
+
+ case USB_REQ_GET_STATUS:
+ USBD_GetStatus (pdev , req);
+ break;
+
+
+ case USB_REQ_SET_FEATURE:
+ USBD_SetFeature (pdev , req);
+ break;
+
+ case USB_REQ_CLEAR_FEATURE:
+ USBD_ClrFeature (pdev , req);
+ break;
+
+ default:
+ USBD_CtlError(pdev , req);
+ break;
+ }
+
+ return ret;
+}
+
+/**
+* @brief USBD_StdItfReq
+* Handle standard usb interface requests
+* @param pdev: USB OTG device instance
+* @param req: usb request
+* @retval status
+*/
+USBD_Status USBD_StdItfReq (USB_OTG_CORE_HANDLE *pdev, USB_SETUP_REQ *req)
+{
+ USBD_Status ret = USBD_OK;
+
+ switch (pdev->dev.device_status)
+ {
+ case USB_OTG_CONFIGURED:
+
+ if (LOBYTE(req->wIndex) <= USBD_ITF_MAX_NUM)
+ {
+ pdev->dev.class_cb->Setup (pdev, req);
+
+ if((req->wLength == 0)&& (ret == USBD_OK))
+ {
+ USBD_CtlSendStatus(pdev);
+ }
+ }
+ else
+ {
+ USBD_CtlError(pdev , req);
+ }
+ break;
+
+ default:
+ USBD_CtlError(pdev , req);
+ break;
+ }
+ return ret;
+}
+
+/**
+* @brief USBD_StdEPReq
+* Handle standard usb endpoint requests
+* @param pdev: USB OTG device instance
+* @param req: usb request
+* @retval status
+*/
+USBD_Status USBD_StdEPReq (USB_OTG_CORE_HANDLE *pdev, USB_SETUP_REQ *req)
+{
+
+ uint8_t ep_addr;
+ USBD_Status ret = USBD_OK;
+
+ ep_addr = LOBYTE(req->wIndex);
+
+ switch (req->bRequest)
+ {
+
+ case USB_REQ_SET_FEATURE :
+
+ switch (pdev->dev.device_status)
+ {
+ case USB_OTG_ADDRESSED:
+ if ((ep_addr != 0x00) && (ep_addr != 0x80))
+ {
+ DCD_EP_Stall(pdev , ep_addr);
+ }
+ break;
+
+ case USB_OTG_CONFIGURED:
+ if (req->wValue == USB_FEATURE_EP_HALT)
+ {
+ if ((ep_addr != 0x00) && (ep_addr != 0x80))
+ {
+ DCD_EP_Stall(pdev , ep_addr);
+
+ }
+ }
+ pdev->dev.class_cb->Setup (pdev, req);
+ USBD_CtlSendStatus(pdev);
+
+ break;
+
+ default:
+ USBD_CtlError(pdev , req);
+ break;
+ }
+ break;
+
+ case USB_REQ_CLEAR_FEATURE :
+
+ switch (pdev->dev.device_status)
+ {
+ case USB_OTG_ADDRESSED:
+ if ((ep_addr != 0x00) && (ep_addr != 0x80))
+ {
+ DCD_EP_Stall(pdev , ep_addr);
+ }
+ break;
+
+ case USB_OTG_CONFIGURED:
+ if (req->wValue == USB_FEATURE_EP_HALT)
+ {
+ if ((ep_addr != 0x00) && (ep_addr != 0x80))
+ {
+ DCD_EP_ClrStall(pdev , ep_addr);
+ pdev->dev.class_cb->Setup (pdev, req);
+ }
+ USBD_CtlSendStatus(pdev);
+ }
+ break;
+
+ default:
+ USBD_CtlError(pdev , req);
+ break;
+ }
+ break;
+
+ case USB_REQ_GET_STATUS:
+ switch (pdev->dev.device_status)
+ {
+ case USB_OTG_ADDRESSED:
+ if ((ep_addr != 0x00) && (ep_addr != 0x80))
+ {
+ DCD_EP_Stall(pdev , ep_addr);
+ }
+ break;
+
+ case USB_OTG_CONFIGURED:
+
+
+ if ((ep_addr & 0x80)== 0x80)
+ {
+ if(pdev->dev.in_ep[ep_addr & 0x7F].is_stall)
+ {
+ USBD_ep_status = 0x0001;
+ }
+ else
+ {
+ USBD_ep_status = 0x0000;
+ }
+ }
+ else if ((ep_addr & 0x80)== 0x00)
+ {
+ if(pdev->dev.out_ep[ep_addr].is_stall)
+ {
+ USBD_ep_status = 0x0001;
+ }
+
+ else
+ {
+ USBD_ep_status = 0x0000;
+ }
+ }
+ USBD_CtlSendData (pdev,
+ (uint8_t *)&USBD_ep_status,
+ 2);
+ break;
+
+ default:
+ USBD_CtlError(pdev , req);
+ break;
+ }
+ break;
+
+ default:
+ break;
+ }
+ return ret;
+}
+/**
+* @brief USBD_GetDescriptor
+* Handle Get Descriptor requests
+* @param pdev: device instance
+* @param req: usb request
+* @retval status
+*/
+static void USBD_GetDescriptor(USB_OTG_CORE_HANDLE *pdev,
+ USB_SETUP_REQ *req)
+{
+ uint16_t len;
+ uint8_t *pbuf;
+
+
+ switch (req->wValue >> 8)
+ {
+ case USB_DESC_TYPE_DEVICE:
+ pbuf = pdev->dev.usr_device->GetDeviceDescriptor(pdev->cfg.speed, &len);
+ if ((req->wLength == 64) ||( pdev->dev.device_status == USB_OTG_DEFAULT))
+ {
+ len = 8;
+ }
+ break;
+
+ case USB_DESC_TYPE_CONFIGURATION:
+ pbuf = (uint8_t *)pdev->dev.class_cb->GetConfigDescriptor(pdev->cfg.speed, &len);
+#ifdef USB_OTG_HS_CORE
+ if((pdev->cfg.speed == USB_OTG_SPEED_FULL )&&
+ (pdev->cfg.phy_itface == USB_OTG_ULPI_PHY))
+ {
+ pbuf = (uint8_t *)pdev->dev.class_cb->GetOtherConfigDescriptor(pdev->cfg.speed, &len);
+ }
+#endif
+ pbuf[1] = USB_DESC_TYPE_CONFIGURATION;
+ pdev->dev.pConfig_descriptor = pbuf;
+ break;
+
+ case USB_DESC_TYPE_STRING:
+ switch ((uint8_t)(req->wValue))
+ {
+ case USBD_IDX_LANGID_STR:
+ pbuf = pdev->dev.usr_device->GetLangIDStrDescriptor(pdev->cfg.speed, &len);
+ break;
+
+ case USBD_IDX_MFC_STR:
+ pbuf = pdev->dev.usr_device->GetManufacturerStrDescriptor(pdev->cfg.speed, &len);
+ break;
+
+ case USBD_IDX_PRODUCT_STR:
+ pbuf = pdev->dev.usr_device->GetProductStrDescriptor(pdev->cfg.speed, &len);
+ break;
+
+ case USBD_IDX_SERIAL_STR:
+ pbuf = pdev->dev.usr_device->GetSerialStrDescriptor(pdev->cfg.speed, &len);
+ break;
+
+ case USBD_IDX_CONFIG_STR:
+ pbuf = pdev->dev.usr_device->GetConfigurationStrDescriptor(pdev->cfg.speed, &len);
+ break;
+
+ case USBD_IDX_INTERFACE_STR:
+ pbuf = pdev->dev.usr_device->GetInterfaceStrDescriptor(pdev->cfg.speed, &len);
+ break;
+
+ default:
+#ifdef USB_SUPPORT_USER_STRING_DESC
+ pbuf = pdev->dev.class_cb->GetUsrStrDescriptor(pdev->cfg.speed, (req->wValue) , &len);
+ break;
+#else
+ USBD_CtlError(pdev , req);
+ return;
+#endif /* USBD_CtlError(pdev , req); */
+ }
+ break;
+ case USB_DESC_TYPE_DEVICE_QUALIFIER:
+#ifdef USB_OTG_HS_CORE
+ if(pdev->cfg.speed == USB_OTG_SPEED_HIGH )
+ {
+
+ pbuf = (uint8_t *)pdev->dev.class_cb->GetConfigDescriptor(pdev->cfg.speed, &len);
+
+ USBD_DeviceQualifierDesc[4]= pbuf[14];
+ USBD_DeviceQualifierDesc[5]= pbuf[15];
+ USBD_DeviceQualifierDesc[6]= pbuf[16];
+
+ pbuf = USBD_DeviceQualifierDesc;
+ len = USB_LEN_DEV_QUALIFIER_DESC;
+ break;
+ }
+ else
+ {
+ USBD_CtlError(pdev , req);
+ return;
+ }
+#else
+ USBD_CtlError(pdev , req);
+ return;
+#endif
+
+ case USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION:
+#ifdef USB_OTG_HS_CORE
+
+ if(pdev->cfg.speed == USB_OTG_SPEED_HIGH )
+ {
+ pbuf = (uint8_t *)pdev->dev.class_cb->GetOtherConfigDescriptor(pdev->cfg.speed, &len);
+ pbuf[1] = USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION;
+ break;
+ }
+ else
+ {
+ USBD_CtlError(pdev , req);
+ return;
+ }
+#else
+ USBD_CtlError(pdev , req);
+ return;
+#endif
+
+
+ default:
+ USBD_CtlError(pdev , req);
+ return;
+ }
+
+ if((len != 0)&& (req->wLength != 0))
+ {
+
+ len = MIN(len , req->wLength);
+
+ USBD_CtlSendData (pdev,
+ pbuf,
+ len);
+ }
+
+}
+
+/**
+* @brief USBD_SetAddress
+* Set device address
+* @param pdev: device instance
+* @param req: usb request
+* @retval status
+*/
+static void USBD_SetAddress(USB_OTG_CORE_HANDLE *pdev,
+ USB_SETUP_REQ *req)
+{
+ uint8_t dev_addr;
+
+ if ((req->wIndex == 0) && (req->wLength == 0))
+ {
+ dev_addr = (uint8_t)(req->wValue) & 0x7F;
+
+ if (pdev->dev.device_status == USB_OTG_CONFIGURED)
+ {
+ USBD_CtlError(pdev , req);
+ }
+ else
+ {
+ pdev->dev.device_address = dev_addr;
+ DCD_EP_SetAddress(pdev, dev_addr);
+ USBD_CtlSendStatus(pdev);
+
+ if (dev_addr != 0)
+ {
+ pdev->dev.device_status = USB_OTG_ADDRESSED;
+ }
+ else
+ {
+ pdev->dev.device_status = USB_OTG_DEFAULT;
+ }
+ }
+ }
+ else
+ {
+ USBD_CtlError(pdev , req);
+ }
+}
+
+/**
+* @brief USBD_SetConfig
+* Handle Set device configuration request
+* @param pdev: device instance
+* @param req: usb request
+* @retval status
+*/
+static void USBD_SetConfig(USB_OTG_CORE_HANDLE *pdev,
+ USB_SETUP_REQ *req)
+{
+
+ static uint8_t cfgidx;
+
+ cfgidx = (uint8_t)(req->wValue);
+
+ if (cfgidx > USBD_CFG_MAX_NUM )
+ {
+ USBD_CtlError(pdev , req);
+ }
+ else
+ {
+ switch (pdev->dev.device_status)
+ {
+ case USB_OTG_ADDRESSED:
+ if (cfgidx)
+ {
+ pdev->dev.device_config = cfgidx;
+ pdev->dev.device_status = USB_OTG_CONFIGURED;
+ USBD_SetCfg(pdev , cfgidx);
+ USBD_CtlSendStatus(pdev);
+ }
+ else
+ {
+ USBD_CtlSendStatus(pdev);
+ }
+ break;
+
+ case USB_OTG_CONFIGURED:
+ if (cfgidx == 0)
+ {
+ pdev->dev.device_status = USB_OTG_ADDRESSED;
+ pdev->dev.device_config = cfgidx;
+ USBD_ClrCfg(pdev , cfgidx);
+ USBD_CtlSendStatus(pdev);
+
+ }
+ else if (cfgidx != pdev->dev.device_config)
+ {
+ /* Clear old configuration */
+ USBD_ClrCfg(pdev , pdev->dev.device_config);
+
+ /* set new configuration */
+ pdev->dev.device_config = cfgidx;
+ USBD_SetCfg(pdev , cfgidx);
+ USBD_CtlSendStatus(pdev);
+ }
+ else
+ {
+ USBD_CtlSendStatus(pdev);
+ }
+ break;
+
+ default:
+ USBD_CtlError(pdev , req);
+ break;
+ }
+ }
+}
+
+/**
+* @brief USBD_GetConfig
+* Handle Get device configuration request
+* @param pdev: device instance
+* @param req: usb request
+* @retval status
+*/
+static void USBD_GetConfig(USB_OTG_CORE_HANDLE *pdev,
+ USB_SETUP_REQ *req)
+{
+
+ if (req->wLength != 1)
+ {
+ USBD_CtlError(pdev , req);
+ }
+ else
+ {
+ switch (pdev->dev.device_status )
+ {
+ case USB_OTG_ADDRESSED:
+
+ USBD_CtlSendData (pdev,
+ (uint8_t *)&USBD_default_cfg,
+ 1);
+ break;
+
+ case USB_OTG_CONFIGURED:
+
+ USBD_CtlSendData (pdev,
+ &pdev->dev.device_config,
+ 1);
+ break;
+
+ default:
+ USBD_CtlError(pdev , req);
+ break;
+ }
+ }
+}
+
+/**
+* @brief USBD_GetStatus
+* Handle Get Status request
+* @param pdev: device instance
+* @param req: usb request
+* @retval status
+*/
+static void USBD_GetStatus(USB_OTG_CORE_HANDLE *pdev,
+ USB_SETUP_REQ *req)
+{
+
+
+ switch (pdev->dev.device_status)
+ {
+ case USB_OTG_ADDRESSED:
+ case USB_OTG_CONFIGURED:
+
+#ifdef USBD_SELF_POWERED
+ USBD_cfg_status = USB_CONFIG_SELF_POWERED;
+#else
+ USBD_cfg_status = 0x00;
+#endif
+
+ if (pdev->dev.DevRemoteWakeup)
+ {
+ USBD_cfg_status |= USB_CONFIG_REMOTE_WAKEUP;
+ }
+
+ USBD_CtlSendData (pdev,
+ (uint8_t *)&USBD_cfg_status,
+ 2);
+ break;
+
+ default :
+ USBD_CtlError(pdev , req);
+ break;
+ }
+}
+
+
+/**
+* @brief USBD_SetFeature
+* Handle Set device feature request
+* @param pdev: device instance
+* @param req: usb request
+* @retval status
+*/
+static void USBD_SetFeature(USB_OTG_CORE_HANDLE *pdev,
+ USB_SETUP_REQ *req)
+{
+
+ USB_OTG_DCTL_TypeDef dctl;
+ uint8_t test_mode = 0;
+
+ if (req->wValue == USB_FEATURE_REMOTE_WAKEUP)
+ {
+ pdev->dev.DevRemoteWakeup = 1;
+ pdev->dev.class_cb->Setup (pdev, req);
+ USBD_CtlSendStatus(pdev);
+ }
+
+ else if ((req->wValue == USB_FEATURE_TEST_MODE) &&
+ ((req->wIndex & 0xFF) == 0))
+ {
+ dctl.d32 = USB_OTG_READ_REG32(&pdev->regs.DREGS->DCTL);
+
+ test_mode = req->wIndex >> 8;
+ switch (test_mode)
+ {
+ case 1: // TEST_J
+ dctl.b.tstctl = 1;
+ break;
+
+ case 2: // TEST_K
+ dctl.b.tstctl = 2;
+ break;
+
+ case 3: // TEST_SE0_NAK
+ dctl.b.tstctl = 3;
+ break;
+
+ case 4: // TEST_PACKET
+ dctl.b.tstctl = 4;
+ break;
+
+ case 5: // TEST_FORCE_ENABLE
+ dctl.b.tstctl = 5;
+ break;
+ }
+ SET_TEST_MODE = dctl;
+ pdev->dev.test_mode = 1;
+ USBD_CtlSendStatus(pdev);
+ }
+
+}
+
+
+/**
+* @brief USBD_ClrFeature
+* Handle clear device feature request
+* @param pdev: device instance
+* @param req: usb request
+* @retval status
+*/
+static void USBD_ClrFeature(USB_OTG_CORE_HANDLE *pdev,
+ USB_SETUP_REQ *req)
+{
+ switch (pdev->dev.device_status)
+ {
+ case USB_OTG_ADDRESSED:
+ case USB_OTG_CONFIGURED:
+ if (req->wValue == USB_FEATURE_REMOTE_WAKEUP)
+ {
+ pdev->dev.DevRemoteWakeup = 0;
+ pdev->dev.class_cb->Setup (pdev, req);
+ USBD_CtlSendStatus(pdev);
+ }
+ break;
+
+ default :
+ USBD_CtlError(pdev , req);
+ break;
+ }
+}
+
+/**
+* @brief USBD_ParseSetupRequest
+* Copy buffer into setup structure
+* @param pdev: device instance
+* @param req: usb request
+* @retval None
+*/
+
+void USBD_ParseSetupRequest( USB_OTG_CORE_HANDLE *pdev,
+ USB_SETUP_REQ *req)
+{
+ req->bmRequest = *(uint8_t *) (pdev->dev.setup_packet);
+ req->bRequest = *(uint8_t *) (pdev->dev.setup_packet + 1);
+ req->wValue = SWAPBYTE (pdev->dev.setup_packet + 2);
+ req->wIndex = SWAPBYTE (pdev->dev.setup_packet + 4);
+ req->wLength = SWAPBYTE (pdev->dev.setup_packet + 6);
+
+ pdev->dev.in_ep[0].ctl_data_len = req->wLength ;
+ pdev->dev.device_state = USB_OTG_EP0_SETUP;
+}
+
+/**
+* @brief USBD_CtlError
+* Handle USB low level Error
+* @param pdev: device instance
+* @param req: usb request
+* @retval None
+*/
+
+void USBD_CtlError( USB_OTG_CORE_HANDLE *pdev,
+ USB_SETUP_REQ *req)
+{
+
+ DCD_EP_Stall(pdev , 0x80);
+ DCD_EP_Stall(pdev , 0);
+ USB_OTG_EP0_OutStart(pdev);
+}
+
+
+/**
+ * @brief USBD_GetString
+ * Convert Ascii string into unicode one
+ * @param desc : descriptor buffer
+ * @param unicode : Formatted string buffer (unicode)
+ * @param len : descriptor length
+ * @retval None
+ */
+void USBD_GetString(uint8_t *desc, uint8_t *unicode, uint16_t *len)
+{
+ uint8_t idx = 0;
+
+ if (desc != NULL)
+ {
+ *len = USBD_GetLen(desc) * 2 + 2;
+ unicode[idx++] = *len;
+ unicode[idx++] = USB_DESC_TYPE_STRING;
+
+ while (*desc != NULL)
+ {
+ unicode[idx++] = *desc++;
+ unicode[idx++] = 0x00;
+ }
+ }
+}
+
+/**
+ * @brief USBD_GetLen
+ * return the string length
+ * @param buf : pointer to the ascii string buffer
+ * @retval string length
+ */
+static uint8_t USBD_GetLen(uint8_t *buf)
+{
+ uint8_t len = 0;
+
+ while (*buf != NULL)
+ {
+ len++;
+ buf++;
+ }
+
+ return len;
+}
+/**
+ * @}
+ */
+
+
+/**
+ * @}
+ */
+
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/platform/mcu/STM32F4xx/drivers/usb/usbd_req.h b/platform/mcu/STM32F4xx/drivers/usb/usbd_req.h
new file mode 100644
index 00000000..e1659373
--- /dev/null
+++ b/platform/mcu/STM32F4xx/drivers/usb/usbd_req.h
@@ -0,0 +1,108 @@
+/**
+ ******************************************************************************
+ * @file usbd_req.h
+ * @author MCD Application Team
+ * @version V1.1.0
+ * @date 19-March-2012
+ * @brief header file for the usbd_req.c file
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT 2012 STMicroelectronics
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (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.st.com/software_license_agreement_liberty_v2
+ *
+ * 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.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+
+#ifndef __USB_REQUEST_H_
+#define __USB_REQUEST_H_
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_def.h"
+#include "usbd_core.h"
+#include "usbd_conf.h"
+
+
+/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
+ * @{
+ */
+
+/** @defgroup USBD_REQ
+ * @brief header file for the usbd_ioreq.c file
+ * @{
+ */
+
+/** @defgroup USBD_REQ_Exported_Defines
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup USBD_REQ_Exported_Types
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+
+/** @defgroup USBD_REQ_Exported_Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USBD_REQ_Exported_Variables
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USBD_REQ_Exported_FunctionsPrototype
+ * @{
+ */
+
+USBD_Status USBD_StdDevReq (USB_OTG_CORE_HANDLE *pdev, USB_SETUP_REQ *req);
+USBD_Status USBD_StdItfReq (USB_OTG_CORE_HANDLE *pdev, USB_SETUP_REQ *req);
+USBD_Status USBD_StdEPReq (USB_OTG_CORE_HANDLE *pdev, USB_SETUP_REQ *req);
+void USBD_ParseSetupRequest( USB_OTG_CORE_HANDLE *pdev,
+ USB_SETUP_REQ *req);
+
+void USBD_CtlError( USB_OTG_CORE_HANDLE *pdev,
+ USB_SETUP_REQ *req);
+
+void USBD_GetString(uint8_t *desc, uint8_t *unicode, uint16_t *len);
+/**
+ * @}
+ */
+
+#endif /* __USB_REQUEST_H_ */
+
+/**
+ * @}
+ */
+
+/**
+* @}
+*/
+
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/platform/mcu/STM32F4xx/drivers/usb/usbd_usr.c b/platform/mcu/STM32F4xx/drivers/usb/usbd_usr.c
new file mode 100644
index 00000000..0c4598ec
--- /dev/null
+++ b/platform/mcu/STM32F4xx/drivers/usb/usbd_usr.c
@@ -0,0 +1,69 @@
+/**
+ ******************************************************************************
+ * @file usbd_usr.c
+ * @author MCD Application Team
+ * @version V1.1.0
+ * @date 19-March-2012
+ * @brief This file includes the user application layer
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT 2012 STMicroelectronics
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (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.st.com/software_license_agreement_liberty_v2
+ *
+ * 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.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_usr.h"
+#include "usbd_ioreq.h"
+
+#include
+
+USBD_Usr_cb_TypeDef USR_cb =
+{
+ USBD_USR_Init,
+ USBD_USR_DeviceReset,
+ USBD_USR_DeviceConfigured,
+ USBD_USR_DeviceSuspended,
+ USBD_USR_DeviceResumed,
+ USBD_USR_DeviceConnected,
+ USBD_USR_DeviceDisconnected,
+};
+
+
+
+void USBD_USR_Init(void) { }
+
+void USBD_USR_DeviceReset(uint8_t speed ) { }
+
+void USBD_USR_DeviceConfigured (void) { }
+
+void USBD_USR_DeviceSuspended(void) { }
+
+void USBD_USR_DeviceResumed(void) { }
+
+void USBD_USR_DeviceConnected (void) { }
+
+void USBD_USR_DeviceDisconnected (void) { }
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/platform/mcu/STM32F4xx/drivers/usb/usbd_usr.h b/platform/mcu/STM32F4xx/drivers/usb/usbd_usr.h
new file mode 100644
index 00000000..0943d89d
--- /dev/null
+++ b/platform/mcu/STM32F4xx/drivers/usb/usbd_usr.h
@@ -0,0 +1,141 @@
+/**
+ ******************************************************************************
+ * @file usbd_usr.h
+ * @author MCD Application Team
+ * @version V1.1.0
+ * @date 19-March-2012
+ * @brief Header file for usbd_usr.c
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT 2012 STMicroelectronics
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (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.st.com/software_license_agreement_liberty_v2
+ *
+ * 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.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USBD_USR_H__
+#define __USBD_USR_H__
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_core.h"
+
+
+/** @addtogroup USBD_USER
+ * @{
+ */
+
+/** @addtogroup USBD_MSC_DEMO_USER_CALLBACKS
+ * @{
+ */
+
+/** @defgroup USBD_USR
+ * @brief This file is the Header file for usbd_usr.c
+ * @{
+ */
+
+
+/** @defgroup USBD_USR_Exported_Types
+ * @{
+ */
+
+extern USBD_Usr_cb_TypeDef USR_cb;
+extern USBD_Usr_cb_TypeDef USR_FS_cb;
+extern USBD_Usr_cb_TypeDef USR_HS_cb;
+
+
+
+/**
+ * @}
+ */
+
+
+
+/** @defgroup USBD_USR_Exported_Defines
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_USR_Exported_Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USBD_USR_Exported_Variables
+ * @{
+ */
+
+void USBD_USR_Init(void);
+void USBD_USR_DeviceReset (uint8_t speed);
+void USBD_USR_DeviceConfigured (void);
+void USBD_USR_DeviceSuspended(void);
+void USBD_USR_DeviceResumed(void);
+
+void USBD_USR_DeviceConnected(void);
+void USBD_USR_DeviceDisconnected(void);
+
+void USBD_USR_FS_Init(void);
+void USBD_USR_FS_DeviceReset (uint8_t speed);
+void USBD_USR_FS_DeviceConfigured (void);
+void USBD_USR_FS_DeviceSuspended(void);
+void USBD_USR_FS_DeviceResumed(void);
+
+void USBD_USR_FS_DeviceConnected(void);
+void USBD_USR_FS_DeviceDisconnected(void);
+
+void USBD_USR_HS_Init(void);
+void USBD_USR_HS_DeviceReset (uint8_t speed);
+void USBD_USR_HS_DeviceConfigured (void);
+void USBD_USR_HS_DeviceSuspended(void);
+void USBD_USR_HS_DeviceResumed(void);
+
+void USBD_USR_HS_DeviceConnected(void);
+void USBD_USR_HS_DeviceDisconnected(void);
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_USR_Exported_FunctionsPrototype
+ * @{
+ */
+/**
+ * @}
+ */
+
+#endif /*__USBD_USR_H__*/
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
+
+
+
diff --git a/platform/mcu/STM32F4xx/drivers/usb_vcom.c b/platform/mcu/STM32F4xx/drivers/usb_vcom.c
new file mode 100644
index 00000000..bdfa6e46
--- /dev/null
+++ b/platform/mcu/STM32F4xx/drivers/usb_vcom.c
@@ -0,0 +1,450 @@
+/***************************************************************************
+ * Copyright (C) 2020 by Silvano Seva IU2KWO *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 3 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, see *
+ ***************************************************************************/
+
+#include
+#include "usbd_core.h"
+#include "usb_defines.h"
+#include "usbd_desc.h"
+#include "usbd_cdc_core.h"
+#include "usbd_usr.h"
+#include "usbd_req.h"
+
+#include "usb_vcom.h"
+
+/* Common USB OTG handle, also defined as 'extern' in other modules */
+USB_OTG_CORE_HANDLE USB_OTG_dev;
+
+/* 'Service' variables: command buffer, ... */
+extern uint8_t USBD_DeviceDesc [USB_SIZ_DEVICE_DESC];
+uint8_t CmdBuff[CDC_CMD_PACKET_SZE];
+static uint32_t cdcCmd = 0xFF;
+static uint32_t cdcLen = 0;
+static __IO uint32_t usbd_cdc_AltSet = 0;
+
+/* Buffer for OUT endpoint, the one receiving data from host */
+uint8_t outEnpBuffer[CDC_DATA_OUT_PACKET_SIZE];
+
+/* Circular buffer for incoming data enqueuement: each packet coming from host
+ * is stored here, eventually erasing oldest data
+ */
+struct rb
+{
+ uint8_t *data;
+ size_t readPtr;
+ size_t writePtr;
+}
+rxRingBuf;
+
+/* USB CDC device Configuration Descriptor */
+uint8_t usbd_cdc_CfgDesc[USB_CDC_CONFIG_DESC_SIZ] =
+{
+ /*Configuration Descriptor*/
+ 0x09, /* bLength: Configuration Descriptor size */
+ USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType: Configuration */
+ USB_CDC_CONFIG_DESC_SIZ, /* wTotalLength:no of returned bytes */
+ 0x00,
+ 0x02, /* bNumInterfaces: 2 interface */
+ 0x01, /* bConfigurationValue: Configuration value */
+ 0x00, /* iConfiguration: Index of string descriptor describing the configuration */
+ 0xC0, /* bmAttributes: self powered */
+ 0x32, /* MaxPower 0 mA */
+
+ /*Interface Descriptor */
+ 0x09, /* bLength: Interface Descriptor size */
+ USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType: Interface */
+ /* Interface descriptor type */
+ 0x00, /* bInterfaceNumber: Number of Interface */
+ 0x00, /* bAlternateSetting: Alternate setting */
+ 0x01, /* bNumEndpoints: One endpoints used */
+ 0x02, /* bInterfaceClass: Communication Interface Class */
+ 0x02, /* bInterfaceSubClass: Abstract Control Model */
+ 0x01, /* bInterfaceProtocol: Common AT commands */
+ 0x00, /* iInterface: */
+
+ /*Header Functional Descriptor*/
+ 0x05, /* bLength: Endpoint Descriptor size */
+ 0x24, /* bDescriptorType: CS_INTERFACE */
+ 0x00, /* bDescriptorSubtype: Header Func Desc */
+ 0x10, /* bcdCDC: spec release number */
+ 0x01,
+
+ /*Call Management Functional Descriptor*/
+ 0x05, /* bFunctionLength */
+ 0x24, /* bDescriptorType: CS_INTERFACE */
+ 0x01, /* bDescriptorSubtype: Call Management Func Desc */
+ 0x00, /* bmCapabilities: D0+D1 */
+ 0x01, /* bDataInterface: 1 */
+
+ /*ACM Functional Descriptor*/
+ 0x04, /* bFunctionLength */
+ 0x24, /* bDescriptorType: CS_INTERFACE */
+ 0x02, /* bDescriptorSubtype: Abstract Control Management desc */
+ 0x02, /* bmCapabilities */
+
+ /*Union Functional Descriptor*/
+ 0x05, /* bFunctionLength */
+ 0x24, /* bDescriptorType: CS_INTERFACE */
+ 0x06, /* bDescriptorSubtype: Union func desc */
+ 0x00, /* bMasterInterface: Communication class interface */
+ 0x01, /* bSlaveInterface0: Data Class Interface */
+
+ /*Endpoint 2 Descriptor*/
+ 0x07, /* bLength: Endpoint Descriptor size */
+ USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */
+ CDC_CMD_EP, /* bEndpointAddress */
+ 0x03, /* bmAttributes: Interrupt */
+ LOBYTE(CDC_CMD_PACKET_SZE), /* wMaxPacketSize: */
+ HIBYTE(CDC_CMD_PACKET_SZE),
+ 0x10, /* bInterval: */
+
+ /*Data class interface descriptor*/
+ 0x09, /* bLength: Endpoint Descriptor size */
+ USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType: */
+ 0x01, /* bInterfaceNumber: Number of Interface */
+ 0x00, /* bAlternateSetting: Alternate setting */
+ 0x02, /* bNumEndpoints: Two endpoints used */
+ 0x0A, /* bInterfaceClass: CDC */
+ 0x00, /* bInterfaceSubClass: */
+ 0x00, /* bInterfaceProtocol: */
+ 0x00, /* iInterface: */
+
+ /*Endpoint OUT Descriptor*/
+ 0x07, /* bLength: Endpoint Descriptor size */
+ USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */
+ CDC_OUT_EP, /* bEndpointAddress */
+ 0x02, /* bmAttributes: Bulk */
+ LOBYTE(CDC_DATA_MAX_PACKET_SIZE), /* wMaxPacketSize: */
+ HIBYTE(CDC_DATA_MAX_PACKET_SIZE),
+ 0x00, /* bInterval: ignore for Bulk transfer */
+
+ /*Endpoint IN Descriptor*/
+ 0x07, /* bLength: Endpoint Descriptor size */
+ USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */
+ CDC_IN_EP, /* bEndpointAddress */
+ 0x02, /* bmAttributes: Bulk */
+ LOBYTE(CDC_DATA_MAX_PACKET_SIZE), /* wMaxPacketSize: */
+ HIBYTE(CDC_DATA_MAX_PACKET_SIZE),
+ 0x00 /* bInterval: ignore for Bulk transfer */
+};
+
+/* The following structures groups all needed parameters to be configured for
+ * the ComPort. These parameters can modified on the fly by the host through
+ * CDC class command class requests.
+ */
+typedef struct
+{
+ uint32_t bitrate;
+ uint8_t format;
+ uint8_t paritytype;
+ uint8_t datatype;
+ uint8_t changed;
+}LINE_CODING;
+
+/* USB virtual com settings: 115200 baud, 8n1 */
+LINE_CODING linecoding =
+{
+ 115200, /* baud rate */
+ 0x00, /* stop bits-1 */
+ 0x00, /* parity - none */
+ 0x08, /* nb. of bits 8 */
+ 1 /* Changed flag */
+};
+
+/* USB CDC callbacks */
+static uint8_t usbd_cdc_Init (void *pdev, uint8_t cfgidx);
+static uint8_t usbd_cdc_DeInit (void *pdev, uint8_t cfgidx);
+static uint8_t usbd_cdc_Setup (void *pdev, USB_SETUP_REQ *req);
+static uint8_t usbd_cdc_EP0_RxReady (void *pdev);
+static uint8_t usbd_cdc_DataIn (void *pdev, uint8_t epnum);
+static uint8_t usbd_cdc_DataOut (void *pdev, uint8_t epnum);
+static uint8_t usbd_cdc_SOF (void *pdev);
+static uint8_t *USBD_cdc_GetCfgDesc (uint8_t speed, uint16_t *length);
+
+USBD_Class_cb_TypeDef USBD_CDC_cb =
+{
+ usbd_cdc_Init,
+ usbd_cdc_DeInit,
+ usbd_cdc_Setup,
+ NULL, /* EP0_TxSent, */
+ usbd_cdc_EP0_RxReady,
+ usbd_cdc_DataIn,
+ usbd_cdc_DataOut,
+ usbd_cdc_SOF,
+ NULL,
+ NULL,
+ USBD_cdc_GetCfgDesc
+};
+
+/* 'Service' function for CDC callbacks */
+static uint16_t VCP_Ctrl (uint32_t Cmd, uint8_t* Buf, uint32_t Len);
+
+/******************************************************************************
+ * *
+ * Implementation of USB vcom functions *
+ * *
+ ******************************************************************************/
+
+int vcom_init()
+{
+ rxRingBuf.readPtr = 0;
+ rxRingBuf.writePtr = 0;
+
+ rxRingBuf.data = (uint8_t *) malloc(RX_RING_BUF_SIZE);
+ if(rxRingBuf.data == NULL) return -1;
+
+ USBD_Init(&USB_OTG_dev, USB_OTG_FS_CORE_ID, &USR_desc, &USBD_CDC_cb,
+ &USR_cb);
+
+ return 0;
+}
+
+ssize_t vcom_writeBlock(const void* buf, size_t len)
+{
+ uint32_t rv = DCD_EP_Tx (&USB_OTG_dev, CDC_IN_EP, (uint8_t*) buf, len);
+ if(rv != 0) return -1;
+ return len;
+}
+
+ssize_t vcom_readBlock(void* buf, size_t len)
+{
+ uint8_t *b = ((uint8_t *) buf);
+ size_t i;
+ for(i = 0; i < len; i++)
+ {
+ /* Terminate if all data available has been popped out */
+ if(rxRingBuf.readPtr == rxRingBuf.writePtr) break;
+ b[i] = rxRingBuf.data[rxRingBuf.readPtr];
+ rxRingBuf.readPtr = (rxRingBuf.readPtr + 1)%RX_RING_BUF_SIZE;
+ }
+
+ return i;
+}
+
+/******************************************************************************
+ * *
+ * Implementation of USB CDC callbacks *
+ * *
+ ******************************************************************************/
+
+static uint8_t usbd_cdc_Init (void *pdev, uint8_t cfgidx)
+{
+ uint8_t *pbuf;
+
+ /* Open EP IN */
+ DCD_EP_Open(pdev, CDC_IN_EP, CDC_DATA_IN_PACKET_SIZE, USB_OTG_EP_BULK);
+
+ /* Open EP OUT */
+ DCD_EP_Open(pdev, CDC_OUT_EP, CDC_DATA_OUT_PACKET_SIZE, USB_OTG_EP_BULK);
+
+ /* Open Command IN EP */
+ DCD_EP_Open(pdev, CDC_CMD_EP, CDC_CMD_PACKET_SZE, USB_OTG_EP_INT);
+
+ pbuf = (uint8_t *)USBD_DeviceDesc;
+ pbuf[4] = DEVICE_CLASS_CDC;
+ pbuf[5] = DEVICE_SUBCLASS_CDC;
+
+ /* Prepare Out endpoint to receive next packet */
+ DCD_EP_PrepareRx(pdev, CDC_OUT_EP, outEnpBuffer, CDC_DATA_OUT_PACKET_SIZE);
+
+ return USBD_OK;
+}
+
+static uint8_t usbd_cdc_DeInit (void *pdev, uint8_t cfgidx)
+{
+ /* Open EP IN */
+ DCD_EP_Close(pdev, CDC_IN_EP);
+
+ /* Open EP OUT */
+ DCD_EP_Close(pdev, CDC_OUT_EP);
+
+ /* Open Command IN EP */
+ DCD_EP_Close(pdev,CDC_CMD_EP);
+
+ /* Deallocate RX buffer */
+ if(rxRingBuf.data != NULL) free(rxRingBuf.data);
+
+ return USBD_OK;
+}
+
+static uint8_t usbd_cdc_Setup (void *pdev, USB_SETUP_REQ *req)
+{
+ uint16_t len=USB_CDC_DESC_SIZ;
+ uint8_t *pbuf=usbd_cdc_CfgDesc + 9;
+
+ switch (req->bmRequest & USB_REQ_TYPE_MASK)
+ {
+ /* CDC Class Requests -------------------------------*/
+ case USB_REQ_TYPE_CLASS :
+ /* Check if the request is a data setup packet */
+ if (req->wLength)
+ {
+ /* Check if the request is Device-to-Host */
+ if (req->bmRequest & 0x80)
+ {
+ /* Get the data to be sent to Host from interface layer */
+ VCP_Ctrl(req->bRequest, CmdBuff, req->wLength);
+
+ /* Send the data to the host */
+ USBD_CtlSendData (pdev, CmdBuff, req->wLength);
+ }
+ else /* Host-to-Device requeset */
+ {
+ /* Set the value of the current command to be processed */
+ cdcCmd = req->bRequest;
+ cdcLen = req->wLength;
+
+ /* Prepare the reception of the buffer over EP0
+ Next step: the received data will be managed in
+ usbd_cdc_EP0_TxSent() function.
+ */
+ USBD_CtlPrepareRx (pdev, CmdBuff, req->wLength);
+ }
+ }
+ else /* No Data request */
+ {
+ /* Transfer the command to the interface layer */
+ VCP_Ctrl(req->bRequest, NULL, 0);
+ }
+
+ return USBD_OK;
+
+ default:
+ USBD_CtlError (pdev, req);
+ return USBD_FAIL;
+
+ case USB_REQ_TYPE_STANDARD:
+ switch (req->bRequest)
+ {
+ case USB_REQ_GET_DESCRIPTOR:
+ if( (req->wValue >> 8) == CDC_DESCRIPTOR_TYPE)
+ {
+ pbuf = usbd_cdc_CfgDesc + 9 + (9 * USBD_ITF_MAX_NUM);
+ len = MIN(USB_CDC_DESC_SIZ , req->wLength);
+ }
+
+ USBD_CtlSendData (pdev, pbuf, len);
+ break;
+
+ case USB_REQ_GET_INTERFACE:
+ USBD_CtlSendData (pdev, (uint8_t *)&usbd_cdc_AltSet, 1);
+ break;
+
+ case USB_REQ_SET_INTERFACE :
+ if ((uint8_t)(req->wValue) < USBD_ITF_MAX_NUM)
+ {
+ usbd_cdc_AltSet = (uint8_t)(req->wValue);
+ }
+ else
+ {
+ /* Call the error management function
+ * (command will be nacked)
+ */
+ USBD_CtlError (pdev, req);
+ }
+ break;
+ }
+ }
+ return USBD_OK;
+}
+
+static uint8_t usbd_cdc_EP0_RxReady (void *pdev)
+{
+ if (cdcCmd != NO_CMD)
+ {
+ VCP_Ctrl(cdcCmd, CmdBuff, cdcLen);
+ cdcCmd = NO_CMD;
+ }
+
+ return USBD_OK;
+}
+
+static uint8_t usbd_cdc_DataIn (void *pdev, uint8_t epnum)
+{
+ return USBD_OK;
+}
+
+static uint8_t usbd_cdc_DataOut (void *pdev, uint8_t epnum)
+{
+ /* Get size of received data */
+ size_t len = ((USB_OTG_CORE_HANDLE*)pdev)->dev.out_ep[epnum].xfer_count;
+
+ /* Transfer data to RX ring buffer */
+ for(size_t i = 0; i < len; i++)
+ {
+ rxRingBuf.data[rxRingBuf.writePtr] = outEnpBuffer[i];
+ if((rxRingBuf.writePtr + 1) == rxRingBuf.readPtr)
+ {
+ // Buffer full, pop one byte from tail.
+ rxRingBuf.readPtr = (rxRingBuf.readPtr + 1)%RX_RING_BUF_SIZE;
+ }
+ rxRingBuf.writePtr = (rxRingBuf.writePtr + 1)%RX_RING_BUF_SIZE;
+ }
+
+ /* Prepare Out endpoint to receive next packet */
+ DCD_EP_PrepareRx(pdev, CDC_OUT_EP, outEnpBuffer, CDC_DATA_OUT_PACKET_SIZE);
+
+ return USBD_OK;
+}
+
+static uint8_t usbd_cdc_SOF (void *pdev)
+{
+ return USBD_OK;
+}
+
+static uint8_t *USBD_cdc_GetCfgDesc (uint8_t speed, uint16_t *length)
+{
+ *length = sizeof (usbd_cdc_CfgDesc);
+ return usbd_cdc_CfgDesc;
+}
+
+static uint16_t VCP_Ctrl (uint32_t Cmd, uint8_t* Buf, uint32_t Len)
+{
+
+ /* NOTE:commands not needed for this driver:
+ * SEND_ENCAPSULATED_COMMAND
+ * GET_ENCAPSULATED_RESPONSE
+ * SET_COMM_FEATURE
+ * GET_COMM_FEATURE
+ * CLEAR_COMM_FEATURE
+ * SET_LINE_CODING
+ * GET_LINE_CODING
+ * SET_CONTROL_LINE_STATE
+ * SEND_BREAK
+ */
+
+ if(Cmd == SET_LINE_CODING)
+ {
+ linecoding.bitrate = (uint32_t)(Buf[0] | (Buf[1] << 8)
+ | (Buf[2] << 16) | (Buf[3] << 24));
+ linecoding.format = Buf[4];
+ linecoding.paritytype = Buf[5];
+ linecoding.datatype = Buf[6];
+ linecoding.changed = 1;
+ }
+ else if(Cmd == GET_LINE_CODING)
+ {
+ Buf[0] = (uint8_t)(linecoding.bitrate);
+ Buf[1] = (uint8_t)(linecoding.bitrate >> 8);
+ Buf[2] = (uint8_t)(linecoding.bitrate >> 16);
+ Buf[3] = (uint8_t)(linecoding.bitrate >> 24);
+ Buf[4] = linecoding.format;
+ Buf[5] = linecoding.paritytype;
+ Buf[6] = linecoding.datatype;
+ }
+
+ return USBD_OK;
+}
diff --git a/platform/mcu/STM32F4xx/drivers/usb_vcom.h b/platform/mcu/STM32F4xx/drivers/usb_vcom.h
new file mode 100644
index 00000000..545e6553
--- /dev/null
+++ b/platform/mcu/STM32F4xx/drivers/usb_vcom.h
@@ -0,0 +1,56 @@
+/***************************************************************************
+ * Copyright (C) 2020 by Silvano Seva IU2KWO *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 3 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, see *
+ ***************************************************************************/
+
+#ifndef USB_VCOM_H
+#define USB_VCOM_H
+
+#include
+#include
+#include "stm32f4xx.h"
+
+/**
+ * Size of the reception buffer for incoming data from the USB host, in bytes.
+ * NOTE: value is equal to the size of one USB bulk transfer, do not change
+ * this parameter.
+ */
+#define RX_RING_BUF_SIZE 1024
+
+/**
+ * Initialise USB virtual com port. Parameters: 115200 baud, 8N1.
+ * @return zero on success, negative value on failure.
+ */
+int vcom_init();
+
+/**
+* Write a block of data. This function blocks until all data have been sent.
+* \param buffer buffer where take data to write.
+* \param size buffer size
+* \return number of bytes written or a negative number on failure.
+*/
+ssize_t vcom_writeBlock(const void *buf, size_t len);
+
+/**
+* Read a block of data, nonblocking function.
+* \param buffer buffer where read data will be stored.
+* \param size buffer size.
+* \return number of bytes read or a negative number on failure. Note that
+* it is normal for this function to return less character than the amount
+* asked.
+*/
+ssize_t vcom_readBlock(void *buf, size_t len);
+
+#endif /* USB_VCOM_H */
diff --git a/platform/mcu/STM32F4xx/linker_script.ld b/platform/mcu/STM32F4xx/linker_script.ld
new file mode 100644
index 00000000..b3097281
--- /dev/null
+++ b/platform/mcu/STM32F4xx/linker_script.ld
@@ -0,0 +1,135 @@
+/*
+ RAM space is organized in this way: the stack begins at the end of
+ the RAM space and grows down towards the base, while the heap begins
+ at the end of the bss space (symbol _end) and grows up towards the
+ end of the RAM.
+
+ WARNING: with this configuration we have an high risk of collision
+ between stack and heap, since none of them is limited. One thing to
+ do in the future is to put this limit to the stack.
+ */
+
+/* stack top in large ram, at an address which, masked with 0x2FFE0000,
+ gives 0x20000000
+*/
+_stack_top = 0x2001FFFF;
+
+/* temporary set heap end equal to stack top */
+_heap_end = _stack_top;
+
+
+/* identify the Entry Point */
+ENTRY(Reset_Handler)
+
+/* specify the memory areas */
+MEMORY
+{
+ flash(rx) : ORIGIN = 0x0800C000, LENGTH = 1M - 48K
+ smallram(wx) : ORIGIN = 0x10000200, LENGTH = 64K
+ largeram(wx) : ORIGIN = 0x20000000, LENGTH = 128K
+}
+
+/* now define the output sections */
+SECTIONS
+{
+ . = 0;
+
+ /* .text section: code goes to flash */
+ .text :
+ {
+ /* Startup code must go at address 0 */
+ KEEP(*(.isr_vector))
+
+ *(.text)
+ *(.text.*)
+ *(.gnu.linkonce.t.*)
+ /* these sections for thumb interwork? */
+ *(.glue_7)
+ *(.glue_7t)
+ /* these sections for C++? */
+ *(.gcc_except_table)
+ *(.gcc_except_table.*)
+ *(.ARM.extab*)
+ *(.gnu.linkonce.armextab.*)
+
+ . = ALIGN(4);
+ /* .rodata: constant data */
+ *(.rodata)
+ *(.rodata.*)
+ *(.gnu.linkonce.r.*)
+
+ /* C++ Static constructors/destructors (eabi) */
+ . = ALIGN(4);
+ KEEP(*(.init))
+
+ . = ALIGN(4);
+ __preinit_array_start = .;
+ KEEP (*(.preinit_array))
+ __preinit_array_end = .;
+
+ . = ALIGN(4);
+ __init_array_start = .;
+ KEEP (*(SORT(.init_array.*)))
+ KEEP (*(.init_array))
+ __init_array_end = .;
+
+ . = ALIGN(4);
+ KEEP(*(.fini))
+
+ . = ALIGN(4);
+ __fini_array_start = .;
+ KEEP (*(.fini_array))
+ KEEP (*(SORT(.fini_array.*)))
+ __fini_array_end = .;
+
+ /* C++ Static constructors/destructors (elf) */
+ . = ALIGN(4);
+ _ctor_start = .;
+ KEEP (*crtbegin.o(.ctors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
+ KEEP (*(SORT(.ctors.*)))
+ KEEP (*crtend.o(.ctors))
+ _ctor_end = .;
+
+ . = ALIGN(4);
+ KEEP (*crtbegin.o(.dtors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
+ KEEP (*(SORT(.dtors.*)))
+ KEEP (*crtend.o(.dtors))
+ } > flash
+
+ /* .ARM.exidx is sorted, so has to go in its own output section. */
+ __exidx_start = .;
+ .ARM.exidx :
+ {
+ *(.ARM.exidx* .gnu.linkonce.armexidx.*)
+ } > flash
+ __exidx_end = .;
+
+ /* .data section: global variables go to ram, but also store a copy to
+ flash to initialize them */
+ .data : ALIGN(8)
+ {
+ _data = .;
+ *(.data)
+ *(.data.*)
+ *(.gnu.linkonce.d.*)
+ . = ALIGN(8);
+ _edata = .;
+ } > smallram AT > flash
+ _etext = LOADADDR(.data);
+
+ /* .bss section: uninitialized global variables go to ram */
+ .bss :
+ {
+ _bss_start = .;
+ *(.bss)
+ *(.bss.*)
+ *(.gnu.linkonce.b.*)
+ . = ALIGN(8);
+ } > largeram
+ _bss_end = .;
+
+ _end = .;
+ PROVIDE(end = .);
+}