diff --git a/SPARK_Firmware_Driver/inc/hw_config.h b/SPARK_Firmware_Driver/inc/hw_config.h
index 437534d..56a9ed9 100644
--- a/SPARK_Firmware_Driver/inc/hw_config.h
+++ b/SPARK_Firmware_Driver/inc/hw_config.h
@@ -35,6 +35,7 @@
#include "cc3000_common.h"
#include "usb_type.h"
#include "rgbled.h"
+#include "usb_hal.h"
enum SpiBusOwner {
BUS_OWNER_NONE = 0,
@@ -129,18 +130,6 @@ typedef struct ServerAddress {
| FLASH_WRProt_Pages8to11 \
| FLASH_WRProt_Pages12to15 )
-/* USB Config : IMR_MSK */
-/* mask defining which events has to be handled */
-/* by the device application software */
-#define IMR_MSK (CNTR_CTRM | \
- CNTR_WKUPM | \
- CNTR_SUSPM | \
- CNTR_ERRM | \
- CNTR_SOFM | \
- CNTR_ESOFM | \
- CNTR_RESETM \
- )
-
#define TIMING_IWDG_RELOAD 1000 //1sec
#define SYSTEM_US_TICKS (SystemCoreClock / 1000000)//cycles per microsecond
diff --git a/SPARK_Firmware_Driver/inc/usb_conf.h b/SPARK_Firmware_Driver/inc/usb_conf.h
new file mode 100644
index 0000000..bc5dfea
--- /dev/null
+++ b/SPARK_Firmware_Driver/inc/usb_conf.h
@@ -0,0 +1,134 @@
+/**
+ ******************************************************************************
+ * @file usb_conf.h
+ * @author Satish Nair
+ * @version V1.0.0
+ * @date 24-April-2013
+ * @brief USB CDC-HID configuration header
+ ******************************************************************************
+ Copyright (c) 2013-14 Spark Labs, Inc. All rights reserved.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation, either
+ version 3 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see .
+ ******************************************************************************
+*/
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USB_CONF_H
+#define __USB_CONF_H
+
+/* Includes ------------------------------------------------------------------*/
+#include "usb_hal.h"
+
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions ------------------------------------------------------- */
+/* External variables --------------------------------------------------------*/
+
+#if !defined (SPARK_USB_SERIAL) && !defined (SPARK_USB_MOUSE) && !defined (SPARK_USB_KEYBOARD)
+#define USB_CDC_ENABLE //Use USB Serial feature by default if none is defined
+#elif defined (SPARK_USB_SERIAL)
+#define USB_CDC_ENABLE //Enable USB CDC code
+#elif defined (SPARK_USB_MOUSE) || defined (SPARK_USB_KEYBOARD)
+#define USB_HID_ENABLE //Enable USB HID code
+#endif
+
+/*-------------------------------------------------------------*/
+/* EP_NUM */
+/* defines how many endpoints are used by the device */
+/*-------------------------------------------------------------*/
+
+#ifdef USB_CDC_ENABLE
+#define EP_NUM (4)
+#endif
+
+#ifdef USB_HID_ENABLE
+#define EP_NUM (2)
+#endif
+
+/*-------------------------------------------------------------*/
+/* -------------- Buffer Description Table -----------------*/
+/*-------------------------------------------------------------*/
+/* buffer table base address */
+/* buffer table base address */
+#define BTABLE_ADDRESS (0x00)
+
+#ifdef USB_CDC_ENABLE
+/* EP0 */
+/* rx/tx buffer base address */
+#define ENDP0_RXADDR (0x40)
+#define ENDP0_TXADDR (0x80)
+
+/* EP1 */
+/* tx buffer base address */
+#define ENDP1_TXADDR (0xC0)
+#define ENDP2_TXADDR (0x100)
+#define ENDP3_RXADDR (0x110)
+#endif
+
+#ifdef USB_HID_ENABLE
+/* EP0 */
+/* rx/tx buffer base address */
+#define ENDP0_RXADDR (0x18)
+#define ENDP0_TXADDR (0x58)
+
+/* EP1 */
+/* tx buffer base address */
+#define ENDP1_TXADDR (0x100)
+#endif
+
+/*-------------------------------------------------------------*/
+/* ------------------- ISTR events -------------------------*/
+/*-------------------------------------------------------------*/
+/* IMR_MSK defined in hw_config.h */
+
+/*#define CTR_CALLBACK*/
+/*#define DOVR_CALLBACK*/
+/*#define ERR_CALLBACK*/
+/*#define WKUP_CALLBACK*/
+/*#define SUSP_CALLBACK*/
+/*#define RESET_CALLBACK*/
+#ifdef USB_CDC_ENABLE
+#define SOF_CALLBACK
+#endif
+/*#define ESOF_CALLBACK*/
+/* CTR service routines */
+/* associated to defined endpoints */
+#ifdef USB_CDC_ENABLE
+/*#define EP1_IN_Callback NOP_Process*/
+#endif
+#ifdef USB_HID_ENABLE
+/*#define EP1_IN_Callback NOP_Process*/
+#endif
+#define EP2_IN_Callback NOP_Process
+#define EP3_IN_Callback NOP_Process
+#define EP4_IN_Callback NOP_Process
+#define EP5_IN_Callback NOP_Process
+#define EP6_IN_Callback NOP_Process
+#define EP7_IN_Callback NOP_Process
+
+#define EP1_OUT_Callback NOP_Process
+#define EP2_OUT_Callback NOP_Process
+#ifdef USB_CDC_ENABLE
+/*#define EP3_OUT_Callback NOP_Process*/
+#endif
+#ifdef USB_HID_ENABLE
+#define EP3_OUT_Callback NOP_Process
+#endif
+#define EP4_OUT_Callback NOP_Process
+#define EP5_OUT_Callback NOP_Process
+#define EP6_OUT_Callback NOP_Process
+#define EP7_OUT_Callback NOP_Process
+
+#endif /* __USB_CONF_H */
diff --git a/SPARK_Firmware_Driver/inc/usb_desc.h b/SPARK_Firmware_Driver/inc/usb_desc.h
new file mode 100644
index 0000000..e8a5f55
--- /dev/null
+++ b/SPARK_Firmware_Driver/inc/usb_desc.h
@@ -0,0 +1,88 @@
+/**
+ ******************************************************************************
+ * @file usb_desc.h
+ * @author Satish Nair
+ * @version V1.0.0
+ * @date 24-April-2013
+ * @brief Descriptor Header for USB CDC-HID Device
+ ******************************************************************************
+ Copyright (c) 2013-14 Spark Labs, Inc. All rights reserved.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation, either
+ version 3 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see .
+ ******************************************************************************
+*/
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USB_DESC_H
+#define __USB_DESC_H
+
+/* Includes ------------------------------------------------------------------*/
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+/* Exported macro ------------------------------------------------------------*/
+/* Exported define -----------------------------------------------------------*/
+#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 CDC_DATA_SIZE 64
+#define CDC_INT_SIZE 8
+
+#ifdef USB_CDC_ENABLE
+#define CDC_SIZ_DEVICE_DESC 18
+#define CDC_SIZ_CONFIG_DESC 67
+#endif
+
+#define HID_DESCRIPTOR_TYPE 0x21
+#define HID_SIZ_HID_DESC 0x09
+#define HID_OFF_HID_DESC 0x12
+
+#ifdef USB_HID_ENABLE
+#define HID_SIZ_DEVICE_DESC 18
+#define HID_SIZ_CONFIG_DESC 34
+
+#if defined (SPARK_USB_MOUSE)
+#define HID_SIZ_REPORT_DESC 52
+#elif defined (SPARK_USB_KEYBOARD)
+#define HID_SIZ_REPORT_DESC 45
+#endif
+#endif
+
+#define USB_SIZ_STRING_LANGID 4
+#define USB_SIZ_STRING_VENDOR 38
+#define USB_SIZ_STRING_PRODUCT 50
+#define USB_SIZ_STRING_SERIAL 26
+
+#define STANDARD_ENDPOINT_DESC_SIZE 0x09
+
+/* Exported functions ------------------------------------------------------- */
+#ifdef USB_CDC_ENABLE
+extern const uint8_t CDC_DeviceDescriptor[CDC_SIZ_DEVICE_DESC];
+extern const uint8_t CDC_ConfigDescriptor[CDC_SIZ_CONFIG_DESC];
+#endif
+
+#ifdef USB_HID_ENABLE
+extern const uint8_t HID_DeviceDescriptor[HID_SIZ_DEVICE_DESC];
+extern const uint8_t HID_ConfigDescriptor[HID_SIZ_CONFIG_DESC];
+extern const uint8_t HID_ReportDescriptor[HID_SIZ_REPORT_DESC];
+#endif
+
+extern const uint8_t USB_StringLangID[USB_SIZ_STRING_LANGID];
+extern const uint8_t USB_StringVendor[USB_SIZ_STRING_VENDOR];
+extern const uint8_t USB_StringProduct[USB_SIZ_STRING_PRODUCT];
+extern uint8_t USB_StringSerial[USB_SIZ_STRING_SERIAL];
+
+#endif /* __USB_DESC_H */
diff --git a/SPARK_Firmware_Driver/inc/usb_istr.h b/SPARK_Firmware_Driver/inc/usb_istr.h
new file mode 100644
index 0000000..10d28f3
--- /dev/null
+++ b/SPARK_Firmware_Driver/inc/usb_istr.h
@@ -0,0 +1,102 @@
+/**
+ ******************************************************************************
+ * @file usb_istr.h
+ * @author Satish Nair
+ * @version V1.0.0
+ * @date 24-April-2013
+ * @brief This file includes the peripherals header files in the user application.
+ ******************************************************************************
+ Copyright (c) 2013-14 Spark Labs, Inc. All rights reserved.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation, either
+ version 3 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see .
+ ******************************************************************************
+*/
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USB_ISTR_H
+#define __USB_ISTR_H
+
+/* Includes ------------------------------------------------------------------*/
+#include "usb_conf.h"
+
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions ------------------------------------------------------- */
+
+void USB_Istr(void);
+
+/* function prototypes Automatically built defining related macros */
+
+#ifdef USB_CDC_ENABLE
+void EP1_IN_Callback(void);
+#endif
+#ifdef USB_HID_ENABLE
+void EP1_IN_Callback(void);
+#endif
+void EP2_IN_Callback(void);
+void EP3_IN_Callback(void);
+void EP4_IN_Callback(void);
+void EP5_IN_Callback(void);
+void EP6_IN_Callback(void);
+void EP7_IN_Callback(void);
+
+void EP1_OUT_Callback(void);
+void EP2_OUT_Callback(void);
+#ifdef USB_CDC_ENABLE
+void EP3_OUT_Callback(void);
+#endif
+#ifdef USB_HID_ENABLE
+void EP3_OUT_Callback(void);
+#endif
+void EP4_OUT_Callback(void);
+void EP5_OUT_Callback(void);
+void EP6_OUT_Callback(void);
+void EP7_OUT_Callback(void);
+
+#ifdef CTR_CALLBACK
+void CTR_Callback(void);
+#endif
+
+#ifdef DOVR_CALLBACK
+void DOVR_Callback(void);
+#endif
+
+#ifdef ERR_CALLBACK
+void ERR_Callback(void);
+#endif
+
+#ifdef WKUP_CALLBACK
+void WKUP_Callback(void);
+#endif
+
+#ifdef SUSP_CALLBACK
+void SUSP_Callback(void);
+#endif
+
+#ifdef RESET_CALLBACK
+void RESET_Callback(void);
+#endif
+
+#ifdef SOF_CALLBACK
+#ifdef USB_CDC_ENABLE
+void SOF_Callback(void);
+#endif
+#endif
+
+#ifdef ESOF_CALLBACK
+void ESOF_Callback(void);
+#endif
+#endif /*__USB_ISTR_H*/
+
diff --git a/SPARK_Firmware_Driver/inc/usb_prop.h b/SPARK_Firmware_Driver/inc/usb_prop.h
new file mode 100644
index 0000000..ebc5db3
--- /dev/null
+++ b/SPARK_Firmware_Driver/inc/usb_prop.h
@@ -0,0 +1,104 @@
+/**
+ ******************************************************************************
+ * @file usb_prop.h
+ * @author Satish Nair
+ * @version V1.0.0
+ * @date 24-April-2013
+ * @brief All processing related to USB CDC-HID (Endpoint 0)
+ ******************************************************************************
+ Copyright (c) 2013-14 Spark Labs, Inc. All rights reserved.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation, either
+ version 3 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see .
+ ******************************************************************************
+*/
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __usb_prop_H
+#define __usb_prop_H
+
+/* Includes ------------------------------------------------------------------*/
+/* Exported types ------------------------------------------------------------*/
+typedef struct
+{
+ uint32_t bitrate;
+ uint8_t format;
+ uint8_t paritytype;
+ uint8_t datatype;
+} LINE_CODING;
+
+typedef enum _HID_REQUESTS
+{
+ GET_REPORT = 1,
+ GET_IDLE,
+ GET_PROTOCOL,
+
+ SET_REPORT = 9,
+ SET_IDLE,
+ SET_PROTOCOL
+} HID_REQUESTS;
+
+/* Exported constants --------------------------------------------------------*/
+/* Exported macro ------------------------------------------------------------*/
+/* Exported define -----------------------------------------------------------*/
+
+#define USB_GetConfiguration NOP_Process
+//#define USB_SetConfiguration NOP_Process
+#define USB_GetInterface NOP_Process
+#define USB_SetInterface NOP_Process
+#define USB_GetStatus NOP_Process
+#define USB_ClearFeature NOP_Process
+#define USB_SetEndPointFeature NOP_Process
+#define USB_SetDeviceFeature NOP_Process
+//#define USB_SetDeviceAddress NOP_Process
+
+#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 REPORT_DESCRIPTOR 0x22
+
+/* Exported functions ------------------------------------------------------- */
+void USB_init(void);
+void USB_Reset(void);
+void USB_SetConfiguration(void);
+void USB_SetDeviceAddress (void);
+void USB_Status_In (void);
+void USB_Status_Out (void);
+RESULT USB_Data_Setup(uint8_t);
+RESULT USB_NoData_Setup(uint8_t);
+RESULT USB_Get_Interface_Setting(uint8_t Interface, uint8_t AlternateSetting);
+uint8_t *USB_GetDeviceDescriptor(uint16_t );
+uint8_t *USB_GetConfigDescriptor(uint16_t);
+uint8_t *USB_GetStringDescriptor(uint16_t);
+
+#ifdef USB_CDC_ENABLE
+uint8_t *CDC_GetLineCoding(uint16_t Length);
+uint8_t *CDC_SetLineCoding(uint16_t Length);
+#endif
+
+#ifdef USB_HID_ENABLE
+uint8_t *HID_GetReportDescriptor(uint16_t Length);
+uint8_t *HID_GetDescriptor(uint16_t Length);
+RESULT HID_SetProtocol(void);
+uint8_t *HID_GetProtocolValue(uint16_t Length);
+#endif
+
+#endif /* __usb_prop_H */
+
diff --git a/SPARK_Firmware_Driver/src/build.mk b/SPARK_Firmware_Driver/src/build.mk
index 1a469d5..c213477 100644
--- a/SPARK_Firmware_Driver/src/build.mk
+++ b/SPARK_Firmware_Driver/src/build.mk
@@ -16,10 +16,14 @@ CSRC += $(TARGET_SPARK_SRC_PATH)/cc3000_spi.c
CSRC += $(TARGET_SPARK_SRC_PATH)/hw_config.c
CSRC += $(TARGET_SPARK_SRC_PATH)/sst25vf_spi.c
CSRC += $(TARGET_SPARK_SRC_PATH)/system_stm32f10x.c
-CSRC += $(TARGET_SPARK_SRC_PATH)/usb_pwr.c
CSRC += $(TARGET_SPARK_SRC_PATH)/debug.c
CSRC += $(TARGET_SPARK_SRC_PATH)/panic.c
CSRC += $(TARGET_SPARK_SRC_PATH)/spi_bus.c
+CSRC += $(TARGET_SPARK_SRC_PATH)/usb_desc.c
+CSRC += $(TARGET_SPARK_SRC_PATH)/usb_endp.c
+CSRC += $(TARGET_SPARK_SRC_PATH)/usb_istr.c
+CSRC += $(TARGET_SPARK_SRC_PATH)/usb_prop.c
+CSRC += $(TARGET_SPARK_SRC_PATH)/usb_pwr.c
# C++ source files included in this build.
CPPSRC +=
diff --git a/SPARK_Firmware_Driver/src/usb_desc.c b/SPARK_Firmware_Driver/src/usb_desc.c
new file mode 100644
index 0000000..192e1a6
--- /dev/null
+++ b/SPARK_Firmware_Driver/src/usb_desc.c
@@ -0,0 +1,320 @@
+/**
+ ******************************************************************************
+ * @file usb_desc.cpp
+ * @author Satish Nair
+ * @version V1.0.0
+ * @date 24-April-2013
+ * @brief Descriptors for USB CDC-HID
+ ******************************************************************************
+ Copyright (c) 2013-14 Spark Labs, Inc. All rights reserved.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation, either
+ version 3 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see .
+ ******************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "usb_conf.h"
+#include "usb_lib.h"
+#include "usb_desc.h"
+
+#ifdef USB_CDC_ENABLE
+/* USB Standard Device Descriptor */
+const uint8_t CDC_DeviceDescriptor[] =
+ {
+ 0x12, /* bLength */
+ USB_DEVICE_DESCRIPTOR_TYPE, /* bDescriptorType */
+ 0x00,
+ 0x02, /* bcdUSB = 2.00 */
+ 0x02, /* bDeviceClass: CDC */
+ 0x00, /* bDeviceSubClass */
+ 0x00, /* bDeviceProtocol */
+ 0x40, /* bMaxPacketSize0 */
+ 0x50,
+ 0x1D, /* idVendor = 0x1D50 */
+ 0x7D,
+ 0x60, /* idProduct = 0x607D */
+ 0x00,
+ 0x02, /* bcdDevice = 2.00 */
+ 1, /* Index of string descriptor describing manufacturer */
+ 2, /* Index of string descriptor describing product */
+ 3, /* Index of string descriptor describing the device's serial number */
+ 0x01 /* bNumConfigurations */
+ };
+
+const uint8_t CDC_ConfigDescriptor[] =
+ {
+ /*Configuration Descriptor*/
+ 0x09, /* bLength: Configuration Descriptor size */
+ USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType: Configuration */
+ CDC_SIZ_CONFIG_DESC, /* 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/bus powered */
+ 0xE1, /* MaxPower 450 mA (225 x 2 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 */
+ 0x82, /* bEndpointAddress: (IN2) */
+ 0x03, /* bmAttributes: Interrupt */
+ CDC_INT_SIZE, /* wMaxPacketSize: */
+ 0x00,
+ 0xFF, /* 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 3 Descriptor*/
+ 0x07, /* bLength: Endpoint Descriptor size */
+ USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */
+ 0x03, /* bEndpointAddress: (OUT3) */
+ 0x02, /* bmAttributes: Bulk */
+ CDC_DATA_SIZE, /* wMaxPacketSize: */
+ 0x00,
+ 0x00, /* bInterval: ignore for Bulk transfer */
+ /*Endpoint 1 Descriptor*/
+ 0x07, /* bLength: Endpoint Descriptor size */
+ USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */
+ 0x81, /* bEndpointAddress: (IN1) */
+ 0x02, /* bmAttributes: Bulk */
+ CDC_DATA_SIZE, /* wMaxPacketSize: */
+ 0x00,
+ 0x00 /* bInterval */
+ };
+#endif
+
+#ifdef USB_HID_ENABLE
+/* USB Standard Device Descriptor */
+const uint8_t HID_DeviceDescriptor[HID_SIZ_DEVICE_DESC] =
+ {
+ 0x12, /*bLength */
+ USB_DEVICE_DESCRIPTOR_TYPE, /*bDescriptorType*/
+ 0x00, /*bcdUSB */
+ 0x02,
+ 0x00, /*bDeviceClass*/
+ 0x00, /*bDeviceSubClass*/
+ 0x00, /*bDeviceProtocol*/
+ 0x40, /*bMaxPacketSize 64*/
+ 0x50,
+ 0x1D, /* idVendor = 0x1D50 */
+#if defined (SPARK_USB_MOUSE)
+ 0x7D,
+ 0x70, /* idProduct = 0x707D (Temporary, need to request a new one from openmoko) */
+#elif defined (SPARK_USB_KEYBOARD)
+ 0x7D,
+ 0x80, /* idProduct = 0x807D (Temporary, need to request a new one from openmoko) */
+#endif
+ 0x00,
+ 0x02, /* bcdDevice = 2.00 */
+ 1, /*Index of string descriptor describing manufacturer */
+ 2, /*Index of string descriptor describing product*/
+ 3, /*Index of string descriptor describing the device serial number */
+ 0x01 /*bNumConfigurations*/
+ };
+
+/* USB Configuration Descriptor */
+/* All Descriptors (Configuration, Interface, Endpoint, Class, Vendor */
+const uint8_t HID_ConfigDescriptor[HID_SIZ_CONFIG_DESC] =
+ {
+ 0x09, /* bLength: Configuration Descriptor size */
+ USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType: Configuration */
+ HID_SIZ_CONFIG_DESC, /* wTotalLength: Bytes returned */
+ 0x00,
+ 0x01, /*bNumInterfaces: 1 interface*/
+ 0x01, /*bConfigurationValue: Configuration value*/
+ 0x00, /*iConfiguration: Index of string descriptor describing the configuration*/
+ 0xE0, /*bmAttributes: Self powered */
+ 0x32, /*MaxPower 100 mA: this current is used for detecting Vbus*/
+
+ /************** Descriptor of HID Mouse interface ****************/
+ /* 09 */
+ 0x09, /*bLength: Interface Descriptor size*/
+ USB_INTERFACE_DESCRIPTOR_TYPE,/*bDescriptorType: Interface descriptor type*/
+ 0x00, /*bInterfaceNumber: Number of Interface*/
+ 0x00, /*bAlternateSetting: Alternate setting*/
+ 0x01, /*bNumEndpoints*/
+ 0x03, /*bInterfaceClass: HID*/
+ 0x01, /*bInterfaceSubClass : 1=BOOT, 0=no boot*/
+#if defined (SPARK_USB_MOUSE)
+ 0x02, /*nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse*/
+#elif defined (SPARK_USB_KEYBOARD)
+ 0x01, /*nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse*/
+#endif
+ 0, /*iInterface: Index of string descriptor*/
+ /******************** Descriptor of HID Mouse HID ********************/
+ /* 18 */
+ 0x09, /*bLength: HID Descriptor size*/
+ HID_DESCRIPTOR_TYPE, /*bDescriptorType: HID*/
+ 0x00, /*bcdHID: HID Class Spec release number*/
+ 0x01,
+ 0x00, /*bCountryCode: Hardware target country*/
+ 0x01, /*bNumDescriptors: Number of HID class descriptors to follow*/
+ 0x22, /*bDescriptorType*/
+ HID_SIZ_REPORT_DESC,/*wItemLength: Total length of Report descriptor*/
+ 0x00,
+ /******************** Descriptor of HID Mouse endpoint ********************/
+ /* 27 */
+ 0x07, /*bLength: Endpoint Descriptor size*/
+ USB_ENDPOINT_DESCRIPTOR_TYPE, /*bDescriptorType:*/
+
+ 0x81, /*bEndpointAddress: Endpoint Address (IN)*/
+ 0x03, /*bmAttributes: Interrupt endpoint*/
+#if defined (SPARK_USB_MOUSE)
+ 0x04, /*wMaxPacketSize: 4 Bytes max */
+#elif defined (SPARK_USB_KEYBOARD)
+ 0x08, /*wMaxPacketSize: 8 Bytes max */
+#endif
+ 0x00,
+ 0x20, /*bInterval: Polling Interval (32 ms)*/
+ /* 34 */
+ };
+
+#if defined (SPARK_USB_MOUSE)
+/* Generated report descriptor using : "http://www.usb.org/developers/hidpage#HID Descriptor Tool" */
+const uint8_t HID_ReportDescriptor[HID_SIZ_REPORT_DESC] = {
+ 0x05, 0x01, // USAGE_PAGE (Generic Desktop)
+ 0x09, 0x02, // USAGE (Mouse)
+ 0xa1, 0x01, // COLLECTION (Application)
+ 0x09, 0x01, // USAGE (Pointer)
+ 0xa1, 0x00, // COLLECTION (Physical)
+ 0x05, 0x09, // USAGE_PAGE (Button)
+ 0x19, 0x01, // USAGE_MINIMUM (Button 1)
+ 0x29, 0x03, // USAGE_MAXIMUM (Button 3)
+ 0x15, 0x00, // LOGICAL_MINIMUM (0)
+ 0x25, 0x01, // LOGICAL_MAXIMUM (1)
+ 0x95, 0x03, // REPORT_COUNT (3)
+ 0x75, 0x01, // REPORT_SIZE (1)
+ 0x81, 0x02, // INPUT (Data,Var,Abs)
+ 0x95, 0x01, // REPORT_COUNT (1)
+ 0x75, 0x05, // REPORT_SIZE (5)
+ 0x81, 0x03, // INPUT (Cnst,Var,Abs)
+ 0x05, 0x01, // USAGE_PAGE (Generic Desktop)
+ 0x09, 0x30, // USAGE (X)
+ 0x09, 0x31, // USAGE (Y)
+ 0x09, 0x38, // USAGE (Wheel)
+ 0x15, 0x81, // LOGICAL_MINIMUM (-127)
+ 0x25, 0x7f, // LOGICAL_MAXIMUM (127)
+ 0x75, 0x08, // REPORT_SIZE (8)
+ 0x95, 0x03, // REPORT_COUNT (3)
+ 0x81, 0x06, // INPUT (Data,Var,Rel)
+ 0xc0, // END_COLLECTION
+ 0xc0 // END_COLLECTION
+};
+#elif defined (SPARK_USB_KEYBOARD)
+/* Generated report descriptor using : "http://www.usb.org/developers/hidpage#HID Descriptor Tool" */
+const uint8_t HID_ReportDescriptor[HID_SIZ_REPORT_DESC] = {
+ 0x05, 0x01, // USAGE_PAGE (Generic Desktop)
+ 0x09, 0x06, // USAGE (Keyboard)
+ 0xa1, 0x01, // COLLECTION (Application)
+ 0x05, 0x07, // USAGE_PAGE (Keyboard)
+ 0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl)
+ 0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI)
+ 0x15, 0x00, // LOGICAL_MINIMUM (0)
+ 0x25, 0x01, // LOGICAL_MAXIMUM (1)
+ 0x75, 0x01, // REPORT_SIZE (1)
+ 0x95, 0x08, // REPORT_COUNT (8)
+ 0x81, 0x02, // INPUT (Data,Var,Abs)
+ 0x95, 0x01, // REPORT_COUNT (1)
+ 0x75, 0x08, // REPORT_SIZE (8)
+ 0x81, 0x03, // INPUT (Cnst,Var,Abs)
+ 0x95, 0x06, // REPORT_COUNT (6)
+ 0x75, 0x08, // REPORT_SIZE (8)
+ 0x15, 0x00, // LOGICAL_MINIMUM (0)
+ 0x25, 0x65, // LOGICAL_MAXIMUM (101)
+ 0x05, 0x07, // USAGE_PAGE (Keyboard)
+ 0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated))
+ 0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application)
+ 0x81, 0x00, // INPUT (Data,Ary,Abs)
+ 0xc0 // END_COLLECTION
+};
+#endif
+#endif
+
+/* USB String Descriptors */
+const uint8_t USB_StringLangID[USB_SIZ_STRING_LANGID] =
+ {
+ USB_SIZ_STRING_LANGID,
+ USB_STRING_DESCRIPTOR_TYPE,
+ 0x09,
+ 0x04 /* LangID = 0x0409: U.S. English */
+ };
+
+const uint8_t USB_StringVendor[USB_SIZ_STRING_VENDOR] =
+ {
+ USB_SIZ_STRING_VENDOR, /* Size of Vendor string */
+ USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType*/
+ /* Manufacturer: "Spark Devices " */
+ 'S', 0, 'p', 0, 'a', 0, 'r', 0, 'k', 0, ' ', 0, 'D', 0, 'e', 0,
+ 'v', 0, 'i', 0, 'c', 0, 'e', 0, 's', 0, ' ', 0, ' ', 0, ' ', 0,
+ ' ', 0, ' ', 0
+ };
+
+const uint8_t USB_StringProduct[USB_SIZ_STRING_PRODUCT] =
+ {
+ USB_SIZ_STRING_PRODUCT, /* bLength */
+ USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */
+ /* Product name: "Spark Core with WiFi " */
+ 'S', 0, 'p', 0, 'a', 0, 'r', 0, 'k', 0, ' ', 0, 'C', 0, 'o', 0,
+ 'r', 0, 'e', 0, ' ', 0, 'w', 0, 'i', 0, 't', 0, 'h', 0, ' ', 0,
+ 'W', 0, 'i', 0, 'F', 0, 'i', 0, ' ', 0, ' ', 0, ' ', 0, ' ', 0
+ };
+
+uint8_t USB_StringSerial[USB_SIZ_STRING_SERIAL] =
+ {
+ USB_SIZ_STRING_SERIAL, /* bLength */
+ USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */
+ 'C', 0, 'O', 0, 'R', 0, 'E', 0, ' ', 0
+ };
+
diff --git a/SPARK_Firmware_Driver/src/usb_endp.c b/SPARK_Firmware_Driver/src/usb_endp.c
new file mode 100644
index 0000000..ccaf1bb
--- /dev/null
+++ b/SPARK_Firmware_Driver/src/usb_endp.c
@@ -0,0 +1,221 @@
+/**
+ ******************************************************************************
+ * @file usb_endp.cpp
+ * @author Satish Nair
+ * @version V1.0.0
+ * @date 24-April-2013
+ * @brief Endpoint routines
+ ******************************************************************************
+ Copyright (c) 2013-14 Spark Labs, Inc. All rights reserved.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation, either
+ version 3 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see .
+ ******************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "usb_hal.h"
+#include "usb_lib.h"
+#include "usb_desc.h"
+#include "usb_mem.h"
+#include "usb_istr.h"
+#include "usb_pwr.h"
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+
+/* Interval between sending IN packets in frame number (1 frame = 1ms) */
+#define CDC_IN_FRAME_INTERVAL 5
+
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+
+extern uint8_t USART_Rx_Buffer[];
+extern uint32_t USART_Rx_ptr_in;
+extern uint32_t USART_Rx_ptr_out;
+extern uint32_t USART_Rx_length;
+
+extern uint8_t USB_Rx_Buffer[];
+extern uint16_t USB_Rx_length;
+extern uint16_t USB_Rx_ptr;
+
+extern uint8_t USB_Tx_State;
+extern uint8_t USB_Rx_State;
+
+extern __IO uint8_t PrevXferComplete;
+
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+#ifdef USB_CDC_ENABLE
+/*******************************************************************************
+* Function Name : EP1_IN_Callback.
+* Description : EP1 IN Callback Routine.
+* Input : None.
+* Output : None.
+* Return : None.
+*******************************************************************************/
+void EP1_IN_Callback (void)
+{
+ uint16_t USB_Tx_ptr;
+ uint16_t USB_Tx_length;
+
+ if (USB_Tx_State == 1)
+ {
+ if (USART_Rx_length == 0)
+ {
+ USB_Tx_State = 0;
+ }
+ else
+ {
+ if (USART_Rx_length > CDC_DATA_SIZE){
+ USB_Tx_ptr = USART_Rx_ptr_out;
+ USB_Tx_length = CDC_DATA_SIZE;
+
+ USART_Rx_ptr_out += CDC_DATA_SIZE;
+ USART_Rx_length -= CDC_DATA_SIZE;
+ }
+ else
+ {
+ USB_Tx_ptr = USART_Rx_ptr_out;
+ USB_Tx_length = USART_Rx_length;
+
+ USART_Rx_ptr_out += USART_Rx_length;
+ USART_Rx_length = 0;
+ }
+ UserToPMABufferCopy(&USART_Rx_Buffer[USB_Tx_ptr], ENDP1_TXADDR, USB_Tx_length);
+ SetEPTxCount(ENDP1, USB_Tx_length);
+ SetEPTxValid(ENDP1);
+ }
+ }
+}
+
+/*******************************************************************************
+* Function Name : EP3_OUT_Callback
+* Description : EP3 OUT Callback Routine.
+* Input : None.
+* Output : None.
+* Return : None.
+*******************************************************************************/
+void EP3_OUT_Callback(void)
+{
+ USB_Rx_State = 1;
+
+ USB_Rx_ptr = 0;
+
+ /* Get the number of received data on the selected Endpoint */
+ USB_Rx_length = GetEPRxCount(ENDP3);
+
+ /* Use the memory interface function to write to the selected endpoint */
+ PMAToUserBufferCopy(USB_Rx_Buffer, ENDP3_RXADDR, USB_Rx_length);
+
+ /* USB data should be immediately processed, this allow next USB traffic being
+ NAKed till the end of the processing */
+}
+
+/*******************************************************************************
+ * Function Name : Handle_USBAsynchXfer.
+ * Description : send data to USB.
+ * Input : None.
+ * Return : None.
+ *******************************************************************************/
+void Handle_USBAsynchXfer (void)
+{
+ uint16_t USB_Tx_ptr;
+ uint16_t USB_Tx_length;
+
+ if(USB_Tx_State != 1)
+ {
+ if (USART_Rx_ptr_out == USART_RX_DATA_SIZE)
+ {
+ USART_Rx_ptr_out = 0;
+ }
+
+ if(USART_Rx_ptr_out == USART_Rx_ptr_in)
+ {
+ USB_Tx_State = 0;
+ return;
+ }
+
+ if(USART_Rx_ptr_out > USART_Rx_ptr_in) /* rollback */
+ {
+ USART_Rx_length = USART_RX_DATA_SIZE - USART_Rx_ptr_out;
+ }
+ else
+ {
+ USART_Rx_length = USART_Rx_ptr_in - USART_Rx_ptr_out;
+ }
+
+ if (USART_Rx_length > CDC_DATA_SIZE)
+ {
+ USB_Tx_ptr = USART_Rx_ptr_out;
+ USB_Tx_length = CDC_DATA_SIZE;
+
+ USART_Rx_ptr_out += CDC_DATA_SIZE;
+ USART_Rx_length -= CDC_DATA_SIZE;
+ }
+ else
+ {
+ USB_Tx_ptr = USART_Rx_ptr_out;
+ USB_Tx_length = USART_Rx_length;
+
+ USART_Rx_ptr_out += USART_Rx_length;
+ USART_Rx_length = 0;
+ }
+ USB_Tx_State = 1;
+ UserToPMABufferCopy(&USART_Rx_Buffer[USB_Tx_ptr], ENDP1_TXADDR, USB_Tx_length);
+ SetEPTxCount(ENDP1, USB_Tx_length);
+ SetEPTxValid(ENDP1);
+ }
+}
+
+/*******************************************************************************
+* Function Name : SOF_Callback / INTR_SOFINTR_Callback
+* Description : SOF Callback Routine.
+* Input : None.
+* Output : None.
+* Return : None.
+*******************************************************************************/
+void SOF_Callback(void)
+{
+ static uint32_t FrameCount = 0;
+
+ if(bDeviceState == CONFIGURED)
+ {
+ if (FrameCount++ == CDC_IN_FRAME_INTERVAL)
+ {
+ /* Reset the frame counter */
+ FrameCount = 0;
+
+ /* Check the data to be sent through IN pipe */
+ Handle_USBAsynchXfer();
+ }
+ }
+}
+#endif
+
+#ifdef USB_HID_ENABLE
+/*******************************************************************************
+* Function Name : EP1_IN_Callback.
+* Description : EP1 IN Callback Routine.
+* Input : None.
+* Output : None.
+* Return : None.
+*******************************************************************************/
+void EP1_IN_Callback(void)
+{
+ /* Set the transfer complete token to inform upper layer that the current
+ transfer has been complete */
+ PrevXferComplete = 1;
+}
+#endif
diff --git a/SPARK_Firmware_Driver/src/usb_istr.c b/SPARK_Firmware_Driver/src/usb_istr.c
new file mode 100644
index 0000000..666e9dd
--- /dev/null
+++ b/SPARK_Firmware_Driver/src/usb_istr.c
@@ -0,0 +1,180 @@
+/**
+ ******************************************************************************
+ * @file usb_istr.cpp
+ * @author Satish Nair
+ * @version V1.0.0
+ * @date 24-April-2013
+ * @brief ISTR events interrupt service routines
+ ******************************************************************************
+ Copyright (c) 2013-14 Spark Labs, Inc. All rights reserved.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation, either
+ version 3 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see .
+ ******************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "usb_lib.h"
+#include "usb_prop.h"
+#include "usb_pwr.h"
+#include "usb_istr.h"
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+__IO uint16_t wIstr; /* ISTR register last read value */
+__IO uint8_t bIntPackSOF = 0; /* SOFs received between 2 consecutive packets */
+
+/* Extern variables ----------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+/* function pointers to non-control endpoints service routines */
+void (*pEpInt_IN[7])(void) =
+ {
+ EP1_IN_Callback,
+ EP2_IN_Callback,
+ EP3_IN_Callback,
+ EP4_IN_Callback,
+ EP5_IN_Callback,
+ EP6_IN_Callback,
+ EP7_IN_Callback,
+ };
+
+void (*pEpInt_OUT[7])(void) =
+ {
+ EP1_OUT_Callback,
+ EP2_OUT_Callback,
+ EP3_OUT_Callback,
+ EP4_OUT_Callback,
+ EP5_OUT_Callback,
+ EP6_OUT_Callback,
+ EP7_OUT_Callback,
+ };
+
+/*******************************************************************************
+* Function Name : USB_Istr
+* Description : ISTR events interrupt service routine
+* Input : None.
+* Output : None.
+* Return : None.
+*******************************************************************************/
+void USB_Istr(void)
+{
+
+ wIstr = _GetISTR();
+
+#if (IMR_MSK & ISTR_SOF)
+ if (wIstr & ISTR_SOF & wInterrupt_Mask)
+ {
+ _SetISTR((uint16_t)CLR_SOF);
+ bIntPackSOF++;
+
+#ifdef SOF_CALLBACK
+ SOF_Callback();
+#endif
+ }
+#endif
+ /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
+
+#if (IMR_MSK & ISTR_CTR)
+ if (wIstr & ISTR_CTR & wInterrupt_Mask)
+ {
+ /* servicing of the endpoint correct transfer interrupt */
+ /* clear of the CTR flag into the sub */
+ CTR_LP();
+#ifdef CTR_CALLBACK
+ CTR_Callback();
+#endif
+ }
+#endif
+ /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
+#if (IMR_MSK & ISTR_RESET)
+ if (wIstr & ISTR_RESET & wInterrupt_Mask)
+ {
+ _SetISTR((uint16_t)CLR_RESET);
+ Device_Property.Reset();
+#ifdef RESET_CALLBACK
+ RESET_Callback();
+#endif
+ }
+#endif
+ /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
+#if (IMR_MSK & ISTR_DOVR)
+ if (wIstr & ISTR_DOVR & wInterrupt_Mask)
+ {
+ _SetISTR((uint16_t)CLR_DOVR);
+#ifdef DOVR_CALLBACK
+ DOVR_Callback();
+#endif
+ }
+#endif
+ /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
+#if (IMR_MSK & ISTR_ERR)
+ if (wIstr & ISTR_ERR & wInterrupt_Mask)
+ {
+ _SetISTR((uint16_t)CLR_ERR);
+#ifdef ERR_CALLBACK
+ ERR_Callback();
+#endif
+ }
+#endif
+ /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
+#if (IMR_MSK & ISTR_WKUP)
+ if (wIstr & ISTR_WKUP & wInterrupt_Mask)
+ {
+ _SetISTR((uint16_t)CLR_WKUP);
+ Resume(RESUME_EXTERNAL);
+#ifdef WKUP_CALLBACK
+ WKUP_Callback();
+#endif
+ }
+#endif
+ /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
+#if (IMR_MSK & ISTR_SUSP)
+ if (wIstr & ISTR_SUSP & wInterrupt_Mask)
+ {
+
+ /* check if SUSPEND is possible */
+ if (fSuspendEnabled)
+ {
+ Suspend();
+ }
+ else
+ {
+ /* if not possible then resume after xx ms */
+ Resume(RESUME_LATER);
+ }
+ /* clear of the ISTR bit must be done after setting of CNTR_FSUSP */
+ _SetISTR((uint16_t)CLR_SUSP);
+#ifdef SUSP_CALLBACK
+ SUSP_Callback();
+#endif
+ }
+#endif
+ /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
+
+#if (IMR_MSK & ISTR_ESOF)
+ if (wIstr & ISTR_ESOF & wInterrupt_Mask)
+ {
+ _SetISTR((uint16_t)CLR_ESOF);
+ /* resume handling timing is made with ESOFs */
+ Resume(RESUME_ESOF); /* request without change of the machine state */
+
+#ifdef ESOF_CALLBACK
+ ESOF_Callback();
+#endif
+ }
+#endif
+} /* USB_Istr */
+
diff --git a/SPARK_Firmware_Driver/src/usb_prop.c b/SPARK_Firmware_Driver/src/usb_prop.c
new file mode 100644
index 0000000..9ffa3d9
--- /dev/null
+++ b/SPARK_Firmware_Driver/src/usb_prop.c
@@ -0,0 +1,561 @@
+/**
+ ******************************************************************************
+ * @file usb_prop.cpp
+ * @author Satish Nair
+ * @version V1.0.0
+ * @date 24-April-2013
+ * @brief All processing related to USB CDC-HID
+ ******************************************************************************
+ Copyright (c) 2013-14 Spark Labs, Inc. All rights reserved.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation, either
+ version 3 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see .
+ ******************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "usb_hal.h"
+#include "usb_lib.h"
+#include "usb_conf.h"
+#include "usb_prop.h"
+#include "usb_desc.h"
+#include "usb_pwr.h"
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+uint8_t Request = 0;
+
+LINE_CODING linecoding =
+ {
+ 115200, /* baud rate*/
+ 0x00, /* stop bits-1*/
+ 0x00, /* parity - none*/
+ 0x08 /* no. of bits 8*/
+ };
+
+uint32_t ProtocolValue;
+
+/* -------------------------------------------------------------------------- */
+/* Structures initializations */
+/* -------------------------------------------------------------------------- */
+
+DEVICE Device_Table =
+ {
+ EP_NUM,
+ 1
+ };
+
+DEVICE_PROP Device_Property =
+ {
+ USB_init,
+ USB_Reset,
+ USB_Status_In,
+ USB_Status_Out,
+ USB_Data_Setup,
+ USB_NoData_Setup,
+ USB_Get_Interface_Setting,
+ USB_GetDeviceDescriptor,
+ USB_GetConfigDescriptor,
+ USB_GetStringDescriptor,
+ 0,
+ 0x40 /*MAX PACKET SIZE*/
+ };
+
+USER_STANDARD_REQUESTS User_Standard_Requests =
+ {
+ USB_GetConfiguration,
+ USB_SetConfiguration,
+ USB_GetInterface,
+ USB_SetInterface,
+ USB_GetStatus,
+ USB_ClearFeature,
+ USB_SetEndPointFeature,
+ USB_SetDeviceFeature,
+ USB_SetDeviceAddress
+ };
+
+#ifdef USB_CDC_ENABLE
+ONE_DESCRIPTOR Device_Descriptor =
+ {
+ (uint8_t*)CDC_DeviceDescriptor,
+ CDC_SIZ_DEVICE_DESC
+ };
+
+ONE_DESCRIPTOR Config_Descriptor =
+ {
+ (uint8_t*)CDC_ConfigDescriptor,
+ CDC_SIZ_CONFIG_DESC
+ };
+#endif
+
+#ifdef USB_HID_ENABLE
+ONE_DESCRIPTOR Device_Descriptor =
+ {
+ (uint8_t*)HID_DeviceDescriptor,
+ HID_SIZ_DEVICE_DESC
+ };
+
+ONE_DESCRIPTOR Config_Descriptor =
+ {
+ (uint8_t*)HID_ConfigDescriptor,
+ HID_SIZ_CONFIG_DESC
+ };
+
+ONE_DESCRIPTOR HID_Report_Descriptor =
+ {
+ (uint8_t *)HID_ReportDescriptor,
+ HID_SIZ_REPORT_DESC
+ };
+
+ONE_DESCRIPTOR HID_Descriptor =
+ {
+ (uint8_t*)HID_ConfigDescriptor + HID_OFF_HID_DESC,
+ HID_SIZ_HID_DESC
+ };
+#endif
+
+ONE_DESCRIPTOR String_Descriptor[4] =
+ {
+ {(uint8_t*)USB_StringLangID, USB_SIZ_STRING_LANGID},
+ {(uint8_t*)USB_StringVendor, USB_SIZ_STRING_VENDOR},
+ {(uint8_t*)USB_StringProduct, USB_SIZ_STRING_PRODUCT},
+ {(uint8_t*)USB_StringSerial, USB_SIZ_STRING_SERIAL}
+ };
+
+/* Extern variables ----------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Extern function prototypes ------------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+/*******************************************************************************
+* Function Name : USB_init.
+* Description : USB init routine.
+* Input : None.
+* Output : None.
+* Return : None.
+*******************************************************************************/
+void USB_init(void)
+{
+
+ /* Update the serial number string descriptor with the data from the unique
+ ID*/
+ Get_SerialNum();
+
+ pInformation->Current_Configuration = 0;
+
+ /* Connect the device */
+ PowerOn();
+
+ /* Perform basic device initialization operations */
+ USB_SIL_Init();
+
+ bDeviceState = UNCONNECTED;
+}
+
+/*******************************************************************************
+* Function Name : USB_Reset
+* Description : USB reset routine
+* Input : None.
+* Output : None.
+* Return : None.
+*******************************************************************************/
+void USB_Reset(void)
+{
+ /* Set USB DEVICE as not configured */
+ pInformation->Current_Configuration = 0;
+
+ /* Set USB DEVICE with the default Interface*/
+ pInformation->Current_Interface = 0;
+
+#ifdef USB_CDC_ENABLE
+ /* Current Feature initialization */
+ pInformation->Current_Feature = CDC_ConfigDescriptor[7];
+#endif
+
+#ifdef USB_HID_ENABLE
+ /* Current Feature initialization */
+ pInformation->Current_Feature = HID_ConfigDescriptor[7];
+#endif
+
+ SetBTABLE(BTABLE_ADDRESS);
+
+ /* Initialize Endpoint 0 */
+ SetEPType(ENDP0, EP_CONTROL);
+ SetEPTxStatus(ENDP0, EP_TX_STALL);
+ SetEPRxAddr(ENDP0, ENDP0_RXADDR);
+ SetEPTxAddr(ENDP0, ENDP0_TXADDR);
+ Clear_Status_Out(ENDP0);
+ SetEPRxCount(ENDP0, Device_Property.MaxPacketSize);
+ SetEPRxValid(ENDP0);
+
+#ifdef USB_CDC_ENABLE
+ /* Initialize Endpoint 1 */
+ SetEPType(ENDP1, EP_BULK);
+ SetEPTxAddr(ENDP1, ENDP1_TXADDR);
+ SetEPTxStatus(ENDP1, EP_TX_NAK);
+ SetEPRxStatus(ENDP1, EP_RX_DIS);
+
+ /* Initialize Endpoint 2 */
+ SetEPType(ENDP2, EP_INTERRUPT);
+ SetEPTxAddr(ENDP2, ENDP2_TXADDR);
+ SetEPRxStatus(ENDP2, EP_RX_DIS);
+ SetEPTxStatus(ENDP2, EP_TX_NAK);
+
+ /* Initialize Endpoint 3 */
+ SetEPType(ENDP3, EP_BULK);
+ SetEPRxAddr(ENDP3, ENDP3_RXADDR);
+ SetEPRxCount(ENDP3, CDC_DATA_SIZE);
+ SetEPRxStatus(ENDP3, EP_RX_VALID);
+ SetEPTxStatus(ENDP3, EP_TX_DIS);
+#endif
+
+#ifdef USB_HID_ENABLE
+ /* Initialize Endpoint 1 */
+ SetEPType(ENDP1, EP_INTERRUPT);
+ SetEPTxAddr(ENDP1, ENDP1_TXADDR);
+#if defined (SPARK_USB_MOUSE)
+ SetEPTxCount(ENDP1, 4);
+#elif defined (SPARK_USB_KEYBOARD)
+ SetEPTxCount(ENDP1, 8);
+#endif
+ SetEPRxStatus(ENDP1, EP_RX_DIS);
+ SetEPTxStatus(ENDP1, EP_TX_NAK);
+#endif
+
+ /* Set this device to response on default address */
+ SetDeviceAddress(0);
+
+ bDeviceState = ATTACHED;
+}
+
+/*******************************************************************************
+* Function Name : USB_SetConfiguration.
+* Description : Update the device state to configured.
+* Input : None.
+* Output : None.
+* Return : None.
+*******************************************************************************/
+void USB_SetConfiguration(void)
+{
+ DEVICE_INFO *pInfo = &Device_Info;
+
+ if (pInfo->Current_Configuration != 0)
+ {
+ /* Device configured */
+ bDeviceState = CONFIGURED;
+ }
+}
+
+/*******************************************************************************
+* Function Name : USB_SetConfiguration.
+* Description : Update the device state to addressed.
+* Input : None.
+* Output : None.
+* Return : None.
+*******************************************************************************/
+void USB_SetDeviceAddress (void)
+{
+ bDeviceState = ADDRESSED;
+}
+
+/*******************************************************************************
+* Function Name : USB_Status_In.
+* Description : USB Status In Routine.
+* Input : None.
+* Output : None.
+* Return : None.
+*******************************************************************************/
+void USB_Status_In(void)
+{
+#ifdef USB_CDC_ENABLE
+ if (Request == SET_LINE_CODING)
+ {
+ //Set Usart BaudRate here
+ Request = 0;
+ }
+#endif
+}
+
+/*******************************************************************************
+* Function Name : USB_Status_Out
+* Description : USB Status OUT Routine.
+* Input : None.
+* Output : None.
+* Return : None.
+*******************************************************************************/
+void USB_Status_Out(void)
+{
+}
+
+/*******************************************************************************
+* Function Name : USB_Data_Setup
+* Description : handle the data class specific requests
+* Input : Request Nb.
+* Output : None.
+* Return : USB_UNSUPPORT or USB_SUCCESS.
+*******************************************************************************/
+RESULT USB_Data_Setup(uint8_t RequestNo)
+{
+ uint8_t *(*CopyRoutine)(uint16_t);
+
+ CopyRoutine = NULL;
+
+#ifdef USB_CDC_ENABLE
+ if (RequestNo == GET_LINE_CODING)
+ {
+ if (Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT))
+ {
+ CopyRoutine = CDC_GetLineCoding;
+ }
+ }
+ else if (RequestNo == SET_LINE_CODING)
+ {
+ if (Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT))
+ {
+ CopyRoutine = CDC_SetLineCoding;
+ }
+ Request = SET_LINE_CODING;
+ }
+#endif
+
+#ifdef USB_HID_ENABLE
+ if ((RequestNo == GET_DESCRIPTOR)
+ && (Type_Recipient == (STANDARD_REQUEST | INTERFACE_RECIPIENT))
+ && (pInformation->USBwIndex0 == 0))
+ {
+ if (pInformation->USBwValue1 == REPORT_DESCRIPTOR)
+ {
+ CopyRoutine = HID_GetReportDescriptor;
+ }
+ else if (pInformation->USBwValue1 == HID_DESCRIPTOR_TYPE)
+ {
+ CopyRoutine = HID_GetDescriptor;
+ }
+
+ } /* End of GET_DESCRIPTOR */
+
+ /*** GET_PROTOCOL ***/
+ else if ((Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT))
+ && RequestNo == GET_PROTOCOL)
+ {
+ CopyRoutine = HID_GetProtocolValue;
+ }
+#endif
+
+ if (CopyRoutine == NULL)
+ {
+ return USB_UNSUPPORT;
+ }
+
+ pInformation->Ctrl_Info.CopyData = CopyRoutine;
+ pInformation->Ctrl_Info.Usb_wOffset = 0;
+ (*CopyRoutine)(0);
+ return USB_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name : USB_NoData_Setup.
+* Description : handle the no data class specific requests.
+* Input : Request Nb.
+* Output : None.
+* Return : USB_UNSUPPORT or USB_SUCCESS.
+*******************************************************************************/
+RESULT USB_NoData_Setup(uint8_t RequestNo)
+{
+#ifdef USB_CDC_ENABLE
+ if (Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT))
+ {
+ if (RequestNo == SET_COMM_FEATURE)
+ {
+ return USB_SUCCESS;
+ }
+ else if (RequestNo == SET_CONTROL_LINE_STATE)
+ {
+ return USB_SUCCESS;
+ }
+ }
+#endif
+
+#ifdef USB_HID_ENABLE
+ if ((Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT))
+ && (RequestNo == SET_PROTOCOL))
+ {
+ return HID_SetProtocol();
+ }
+#endif
+
+ return USB_UNSUPPORT;
+}
+
+/*******************************************************************************
+* Function Name : USB_GetDeviceDescriptor.
+* Description : Gets the device descriptor.
+* Input : Length.
+* Output : None.
+* Return : The address of the device descriptor.
+*******************************************************************************/
+uint8_t *USB_GetDeviceDescriptor(uint16_t Length)
+{
+ return Standard_GetDescriptorData(Length, &Device_Descriptor);
+}
+
+/*******************************************************************************
+* Function Name : USB_GetConfigDescriptor.
+* Description : get the configuration descriptor.
+* Input : Length.
+* Output : None.
+* Return : The address of the configuration descriptor.
+*******************************************************************************/
+uint8_t *USB_GetConfigDescriptor(uint16_t Length)
+{
+ return Standard_GetDescriptorData(Length, &Config_Descriptor);
+}
+
+/*******************************************************************************
+* Function Name : USB_GetStringDescriptor
+* Description : Gets the string descriptors according to the needed index
+* Input : Length.
+* Output : None.
+* Return : The address of the string descriptors.
+*******************************************************************************/
+uint8_t *USB_GetStringDescriptor(uint16_t Length)
+{
+ uint8_t wValue0 = pInformation->USBwValue0;
+ if (wValue0 > 4)
+ {
+ return NULL;
+ }
+ else
+ {
+ return Standard_GetDescriptorData(Length, &String_Descriptor[wValue0]);
+ }
+}
+
+/*******************************************************************************
+* Function Name : USB_Get_Interface_Setting.
+* Description : test the interface and the alternate setting according to the
+* supported one.
+* Input1 : uint8_t: Interface : interface number.
+* Input2 : uint8_t: AlternateSetting : Alternate Setting number.
+* Output : None.
+* Return : The address of the string descriptors.
+*******************************************************************************/
+RESULT USB_Get_Interface_Setting(uint8_t Interface, uint8_t AlternateSetting)
+{
+ if (AlternateSetting > 0)
+ {
+ return USB_UNSUPPORT;
+ }
+ else if (Interface > 1)
+ {
+ return USB_UNSUPPORT;
+ }
+ return USB_SUCCESS;
+}
+
+#ifdef USB_CDC_ENABLE
+/*******************************************************************************
+* Function Name : CDC_GetLineCoding.
+* Description : send the linecoding structure to the PC host.
+* Input : Length.
+* Output : None.
+* Return : Linecoding structure base address.
+*******************************************************************************/
+uint8_t *CDC_GetLineCoding(uint16_t Length)
+{
+ if (Length == 0)
+ {
+ pInformation->Ctrl_Info.Usb_wLength = sizeof(linecoding);
+ return NULL;
+ }
+ return(uint8_t *)&linecoding;
+}
+
+/*******************************************************************************
+* Function Name : CDC_SetLineCoding.
+* Description : Set the linecoding structure fields.
+* Input : Length.
+* Output : None.
+* Return : Linecoding structure base address.
+*******************************************************************************/
+uint8_t *CDC_SetLineCoding(uint16_t Length)
+{
+ if (Length == 0)
+ {
+ pInformation->Ctrl_Info.Usb_wLength = sizeof(linecoding);
+ return NULL;
+ }
+ return(uint8_t *)&linecoding;
+}
+#endif
+
+#ifdef USB_HID_ENABLE
+/*******************************************************************************
+* Function Name : HID_GetReportDescriptor.
+* Description : Gets the HID report descriptor.
+* Input : Length
+* Output : None.
+* Return : The address of the configuration descriptor.
+*******************************************************************************/
+uint8_t *HID_GetReportDescriptor(uint16_t Length)
+{
+ return Standard_GetDescriptorData(Length, &HID_Report_Descriptor);
+}
+
+/*******************************************************************************
+* Function Name : HID_GetDescriptor.
+* Description : Gets the HID descriptor.
+* Input : Length
+* Output : None.
+* Return : The address of the configuration descriptor.
+*******************************************************************************/
+uint8_t *HID_GetDescriptor(uint16_t Length)
+{
+ return Standard_GetDescriptorData(Length, &HID_Descriptor);
+}
+
+/*******************************************************************************
+* Function Name : HID_SetProtocol
+* Description : HID Set Protocol request routine.
+* Input : None.
+* Output : None.
+* Return : USB SUCCESS.
+*******************************************************************************/
+RESULT HID_SetProtocol(void)
+{
+ uint8_t wValue0 = pInformation->USBwValue0;
+ ProtocolValue = wValue0;
+ return USB_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name : HID_GetProtocolValue
+* Description : get the protocol value
+* Input : Length.
+* Output : None.
+* Return : address of the protocol value.
+*******************************************************************************/
+uint8_t *HID_GetProtocolValue(uint16_t Length)
+{
+ if (Length == 0)
+ {
+ pInformation->Ctrl_Info.Usb_wLength = 1;
+ return NULL;
+ }
+ else
+ {
+ return (uint8_t *)(&ProtocolValue);
+ }
+}
+#endif
diff --git a/SPARK_Firmware_Driver/src/usb_pwr.c b/SPARK_Firmware_Driver/src/usb_pwr.c
index ae6addc..ddfc4cc 100644
--- a/SPARK_Firmware_Driver/src/usb_pwr.c
+++ b/SPARK_Firmware_Driver/src/usb_pwr.c
@@ -29,7 +29,6 @@
#include "usb_lib.h"
#include "usb_pwr.h"
-
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
diff --git a/CMSIS/Device/ST/STM32F10x/Include/stm32f10x.h b/SPARK_Platform/MCU/STM32F1xx/CMSIS/Device/ST/STM32F10x/Include/stm32f10x.h
similarity index 100%
rename from CMSIS/Device/ST/STM32F10x/Include/stm32f10x.h
rename to SPARK_Platform/MCU/STM32F1xx/CMSIS/Device/ST/STM32F10x/Include/stm32f10x.h
diff --git a/CMSIS/Device/ST/STM32F10x/Include/system_stm32f10x.h b/SPARK_Platform/MCU/STM32F1xx/CMSIS/Device/ST/STM32F10x/Include/system_stm32f10x.h
similarity index 100%
rename from CMSIS/Device/ST/STM32F10x/Include/system_stm32f10x.h
rename to SPARK_Platform/MCU/STM32F1xx/CMSIS/Device/ST/STM32F10x/Include/system_stm32f10x.h
diff --git a/CMSIS/Include/arm_common_tables.h b/SPARK_Platform/MCU/STM32F1xx/CMSIS/Include/arm_common_tables.h
similarity index 100%
rename from CMSIS/Include/arm_common_tables.h
rename to SPARK_Platform/MCU/STM32F1xx/CMSIS/Include/arm_common_tables.h
diff --git a/CMSIS/Include/arm_math.h b/SPARK_Platform/MCU/STM32F1xx/CMSIS/Include/arm_math.h
similarity index 100%
rename from CMSIS/Include/arm_math.h
rename to SPARK_Platform/MCU/STM32F1xx/CMSIS/Include/arm_math.h
diff --git a/CMSIS/Include/core_cm3.h b/SPARK_Platform/MCU/STM32F1xx/CMSIS/Include/core_cm3.h
similarity index 100%
rename from CMSIS/Include/core_cm3.h
rename to SPARK_Platform/MCU/STM32F1xx/CMSIS/Include/core_cm3.h
diff --git a/CMSIS/Include/core_cmFunc.h b/SPARK_Platform/MCU/STM32F1xx/CMSIS/Include/core_cmFunc.h
similarity index 100%
rename from CMSIS/Include/core_cmFunc.h
rename to SPARK_Platform/MCU/STM32F1xx/CMSIS/Include/core_cmFunc.h
diff --git a/CMSIS/Include/core_cmInstr.h b/SPARK_Platform/MCU/STM32F1xx/CMSIS/Include/core_cmInstr.h
similarity index 100%
rename from CMSIS/Include/core_cmInstr.h
rename to SPARK_Platform/MCU/STM32F1xx/CMSIS/Include/core_cmInstr.h
diff --git a/STM32F10x_StdPeriph_Driver/inc/misc.h b/SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/inc/misc.h
similarity index 100%
rename from STM32F10x_StdPeriph_Driver/inc/misc.h
rename to SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/inc/misc.h
diff --git a/STM32F10x_StdPeriph_Driver/inc/stm32f10x_adc.h b/SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/inc/stm32f10x_adc.h
similarity index 100%
rename from STM32F10x_StdPeriph_Driver/inc/stm32f10x_adc.h
rename to SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/inc/stm32f10x_adc.h
diff --git a/STM32F10x_StdPeriph_Driver/inc/stm32f10x_bkp.h b/SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/inc/stm32f10x_bkp.h
similarity index 100%
rename from STM32F10x_StdPeriph_Driver/inc/stm32f10x_bkp.h
rename to SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/inc/stm32f10x_bkp.h
diff --git a/STM32F10x_StdPeriph_Driver/inc/stm32f10x_can.h b/SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/inc/stm32f10x_can.h
similarity index 100%
rename from STM32F10x_StdPeriph_Driver/inc/stm32f10x_can.h
rename to SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/inc/stm32f10x_can.h
diff --git a/STM32F10x_StdPeriph_Driver/inc/stm32f10x_cec.h b/SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/inc/stm32f10x_cec.h
similarity index 100%
rename from STM32F10x_StdPeriph_Driver/inc/stm32f10x_cec.h
rename to SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/inc/stm32f10x_cec.h
diff --git a/STM32F10x_StdPeriph_Driver/inc/stm32f10x_crc.h b/SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/inc/stm32f10x_crc.h
similarity index 100%
rename from STM32F10x_StdPeriph_Driver/inc/stm32f10x_crc.h
rename to SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/inc/stm32f10x_crc.h
diff --git a/STM32F10x_StdPeriph_Driver/inc/stm32f10x_dac.h b/SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/inc/stm32f10x_dac.h
similarity index 100%
rename from STM32F10x_StdPeriph_Driver/inc/stm32f10x_dac.h
rename to SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/inc/stm32f10x_dac.h
diff --git a/STM32F10x_StdPeriph_Driver/inc/stm32f10x_dbgmcu.h b/SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/inc/stm32f10x_dbgmcu.h
similarity index 100%
rename from STM32F10x_StdPeriph_Driver/inc/stm32f10x_dbgmcu.h
rename to SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/inc/stm32f10x_dbgmcu.h
diff --git a/STM32F10x_StdPeriph_Driver/inc/stm32f10x_dma.h b/SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/inc/stm32f10x_dma.h
similarity index 100%
rename from STM32F10x_StdPeriph_Driver/inc/stm32f10x_dma.h
rename to SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/inc/stm32f10x_dma.h
diff --git a/STM32F10x_StdPeriph_Driver/inc/stm32f10x_exti.h b/SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/inc/stm32f10x_exti.h
similarity index 100%
rename from STM32F10x_StdPeriph_Driver/inc/stm32f10x_exti.h
rename to SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/inc/stm32f10x_exti.h
diff --git a/STM32F10x_StdPeriph_Driver/inc/stm32f10x_flash.h b/SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/inc/stm32f10x_flash.h
similarity index 100%
rename from STM32F10x_StdPeriph_Driver/inc/stm32f10x_flash.h
rename to SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/inc/stm32f10x_flash.h
diff --git a/STM32F10x_StdPeriph_Driver/inc/stm32f10x_fsmc.h b/SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/inc/stm32f10x_fsmc.h
similarity index 100%
rename from STM32F10x_StdPeriph_Driver/inc/stm32f10x_fsmc.h
rename to SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/inc/stm32f10x_fsmc.h
diff --git a/STM32F10x_StdPeriph_Driver/inc/stm32f10x_gpio.h b/SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/inc/stm32f10x_gpio.h
similarity index 100%
rename from STM32F10x_StdPeriph_Driver/inc/stm32f10x_gpio.h
rename to SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/inc/stm32f10x_gpio.h
diff --git a/STM32F10x_StdPeriph_Driver/inc/stm32f10x_i2c.h b/SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/inc/stm32f10x_i2c.h
similarity index 100%
rename from STM32F10x_StdPeriph_Driver/inc/stm32f10x_i2c.h
rename to SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/inc/stm32f10x_i2c.h
diff --git a/STM32F10x_StdPeriph_Driver/inc/stm32f10x_iwdg.h b/SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/inc/stm32f10x_iwdg.h
similarity index 100%
rename from STM32F10x_StdPeriph_Driver/inc/stm32f10x_iwdg.h
rename to SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/inc/stm32f10x_iwdg.h
diff --git a/STM32F10x_StdPeriph_Driver/inc/stm32f10x_pwr.h b/SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/inc/stm32f10x_pwr.h
similarity index 100%
rename from STM32F10x_StdPeriph_Driver/inc/stm32f10x_pwr.h
rename to SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/inc/stm32f10x_pwr.h
diff --git a/STM32F10x_StdPeriph_Driver/inc/stm32f10x_rcc.h b/SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/inc/stm32f10x_rcc.h
similarity index 100%
rename from STM32F10x_StdPeriph_Driver/inc/stm32f10x_rcc.h
rename to SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/inc/stm32f10x_rcc.h
diff --git a/STM32F10x_StdPeriph_Driver/inc/stm32f10x_rtc.h b/SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/inc/stm32f10x_rtc.h
similarity index 100%
rename from STM32F10x_StdPeriph_Driver/inc/stm32f10x_rtc.h
rename to SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/inc/stm32f10x_rtc.h
diff --git a/STM32F10x_StdPeriph_Driver/inc/stm32f10x_sdio.h b/SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/inc/stm32f10x_sdio.h
similarity index 100%
rename from STM32F10x_StdPeriph_Driver/inc/stm32f10x_sdio.h
rename to SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/inc/stm32f10x_sdio.h
diff --git a/STM32F10x_StdPeriph_Driver/inc/stm32f10x_spi.h b/SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/inc/stm32f10x_spi.h
similarity index 100%
rename from STM32F10x_StdPeriph_Driver/inc/stm32f10x_spi.h
rename to SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/inc/stm32f10x_spi.h
diff --git a/STM32F10x_StdPeriph_Driver/inc/stm32f10x_tim.h b/SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/inc/stm32f10x_tim.h
similarity index 100%
rename from STM32F10x_StdPeriph_Driver/inc/stm32f10x_tim.h
rename to SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/inc/stm32f10x_tim.h
diff --git a/STM32F10x_StdPeriph_Driver/inc/stm32f10x_usart.h b/SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/inc/stm32f10x_usart.h
similarity index 100%
rename from STM32F10x_StdPeriph_Driver/inc/stm32f10x_usart.h
rename to SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/inc/stm32f10x_usart.h
diff --git a/STM32F10x_StdPeriph_Driver/inc/stm32f10x_wwdg.h b/SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/inc/stm32f10x_wwdg.h
similarity index 100%
rename from STM32F10x_StdPeriph_Driver/inc/stm32f10x_wwdg.h
rename to SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/inc/stm32f10x_wwdg.h
diff --git a/STM32F10x_StdPeriph_Driver/src/build.mk b/SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/src/build.mk
similarity index 94%
rename from STM32F10x_StdPeriph_Driver/src/build.mk
rename to SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/src/build.mk
index 2afce8a..b28e51b 100644
--- a/STM32F10x_StdPeriph_Driver/src/build.mk
+++ b/SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/src/build.mk
@@ -4,7 +4,7 @@
# Define the prefix to this directory.
# Note: The name must be unique within this build and should be
# based on the root of the project
-TARGET_STDPERIPH_PATH = STM32F10x_StdPeriph_Driver
+TARGET_STDPERIPH_PATH = SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver
TARGET_STDPERIPH_SRC_PATH = $(TARGET_STDPERIPH_PATH)/src
# Add tropicssl include to all objects built for this target
diff --git a/STM32F10x_StdPeriph_Driver/src/misc.c b/SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/src/misc.c
similarity index 100%
rename from STM32F10x_StdPeriph_Driver/src/misc.c
rename to SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/src/misc.c
diff --git a/STM32F10x_StdPeriph_Driver/src/stm32f10x_adc.c b/SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/src/stm32f10x_adc.c
similarity index 100%
rename from STM32F10x_StdPeriph_Driver/src/stm32f10x_adc.c
rename to SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/src/stm32f10x_adc.c
diff --git a/STM32F10x_StdPeriph_Driver/src/stm32f10x_bkp.c b/SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/src/stm32f10x_bkp.c
similarity index 100%
rename from STM32F10x_StdPeriph_Driver/src/stm32f10x_bkp.c
rename to SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/src/stm32f10x_bkp.c
diff --git a/STM32F10x_StdPeriph_Driver/src/stm32f10x_can.c b/SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/src/stm32f10x_can.c
similarity index 100%
rename from STM32F10x_StdPeriph_Driver/src/stm32f10x_can.c
rename to SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/src/stm32f10x_can.c
diff --git a/STM32F10x_StdPeriph_Driver/src/stm32f10x_cec.c b/SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/src/stm32f10x_cec.c
similarity index 100%
rename from STM32F10x_StdPeriph_Driver/src/stm32f10x_cec.c
rename to SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/src/stm32f10x_cec.c
diff --git a/STM32F10x_StdPeriph_Driver/src/stm32f10x_crc.c b/SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/src/stm32f10x_crc.c
similarity index 100%
rename from STM32F10x_StdPeriph_Driver/src/stm32f10x_crc.c
rename to SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/src/stm32f10x_crc.c
diff --git a/STM32F10x_StdPeriph_Driver/src/stm32f10x_dac.c b/SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/src/stm32f10x_dac.c
similarity index 100%
rename from STM32F10x_StdPeriph_Driver/src/stm32f10x_dac.c
rename to SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/src/stm32f10x_dac.c
diff --git a/STM32F10x_StdPeriph_Driver/src/stm32f10x_dbgmcu.c b/SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/src/stm32f10x_dbgmcu.c
similarity index 100%
rename from STM32F10x_StdPeriph_Driver/src/stm32f10x_dbgmcu.c
rename to SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/src/stm32f10x_dbgmcu.c
diff --git a/STM32F10x_StdPeriph_Driver/src/stm32f10x_dma.c b/SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/src/stm32f10x_dma.c
similarity index 100%
rename from STM32F10x_StdPeriph_Driver/src/stm32f10x_dma.c
rename to SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/src/stm32f10x_dma.c
diff --git a/STM32F10x_StdPeriph_Driver/src/stm32f10x_exti.c b/SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/src/stm32f10x_exti.c
similarity index 100%
rename from STM32F10x_StdPeriph_Driver/src/stm32f10x_exti.c
rename to SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/src/stm32f10x_exti.c
diff --git a/STM32F10x_StdPeriph_Driver/src/stm32f10x_flash.c b/SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/src/stm32f10x_flash.c
similarity index 100%
rename from STM32F10x_StdPeriph_Driver/src/stm32f10x_flash.c
rename to SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/src/stm32f10x_flash.c
diff --git a/STM32F10x_StdPeriph_Driver/src/stm32f10x_fsmc.c b/SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/src/stm32f10x_fsmc.c
similarity index 100%
rename from STM32F10x_StdPeriph_Driver/src/stm32f10x_fsmc.c
rename to SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/src/stm32f10x_fsmc.c
diff --git a/STM32F10x_StdPeriph_Driver/src/stm32f10x_gpio.c b/SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/src/stm32f10x_gpio.c
similarity index 100%
rename from STM32F10x_StdPeriph_Driver/src/stm32f10x_gpio.c
rename to SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/src/stm32f10x_gpio.c
diff --git a/STM32F10x_StdPeriph_Driver/src/stm32f10x_i2c.c b/SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/src/stm32f10x_i2c.c
similarity index 100%
rename from STM32F10x_StdPeriph_Driver/src/stm32f10x_i2c.c
rename to SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/src/stm32f10x_i2c.c
diff --git a/STM32F10x_StdPeriph_Driver/src/stm32f10x_iwdg.c b/SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/src/stm32f10x_iwdg.c
similarity index 100%
rename from STM32F10x_StdPeriph_Driver/src/stm32f10x_iwdg.c
rename to SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/src/stm32f10x_iwdg.c
diff --git a/STM32F10x_StdPeriph_Driver/src/stm32f10x_pwr.c b/SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/src/stm32f10x_pwr.c
similarity index 100%
rename from STM32F10x_StdPeriph_Driver/src/stm32f10x_pwr.c
rename to SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/src/stm32f10x_pwr.c
diff --git a/STM32F10x_StdPeriph_Driver/src/stm32f10x_rcc.c b/SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/src/stm32f10x_rcc.c
similarity index 100%
rename from STM32F10x_StdPeriph_Driver/src/stm32f10x_rcc.c
rename to SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/src/stm32f10x_rcc.c
diff --git a/STM32F10x_StdPeriph_Driver/src/stm32f10x_rtc.c b/SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/src/stm32f10x_rtc.c
similarity index 100%
rename from STM32F10x_StdPeriph_Driver/src/stm32f10x_rtc.c
rename to SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/src/stm32f10x_rtc.c
diff --git a/STM32F10x_StdPeriph_Driver/src/stm32f10x_sdio.c b/SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/src/stm32f10x_sdio.c
similarity index 100%
rename from STM32F10x_StdPeriph_Driver/src/stm32f10x_sdio.c
rename to SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/src/stm32f10x_sdio.c
diff --git a/STM32F10x_StdPeriph_Driver/src/stm32f10x_spi.c b/SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/src/stm32f10x_spi.c
similarity index 100%
rename from STM32F10x_StdPeriph_Driver/src/stm32f10x_spi.c
rename to SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/src/stm32f10x_spi.c
diff --git a/STM32F10x_StdPeriph_Driver/src/stm32f10x_tim.c b/SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/src/stm32f10x_tim.c
similarity index 100%
rename from STM32F10x_StdPeriph_Driver/src/stm32f10x_tim.c
rename to SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/src/stm32f10x_tim.c
diff --git a/STM32F10x_StdPeriph_Driver/src/stm32f10x_usart.c b/SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/src/stm32f10x_usart.c
similarity index 100%
rename from STM32F10x_StdPeriph_Driver/src/stm32f10x_usart.c
rename to SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/src/stm32f10x_usart.c
diff --git a/STM32F10x_StdPeriph_Driver/src/stm32f10x_wwdg.c b/SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/src/stm32f10x_wwdg.c
similarity index 100%
rename from STM32F10x_StdPeriph_Driver/src/stm32f10x_wwdg.c
rename to SPARK_Platform/MCU/STM32F1xx/STM32F10x_StdPeriph_Driver/src/stm32f10x_wwdg.c
diff --git a/STM32_USB-FS-Device_Driver/inc/usb_core.h b/SPARK_Platform/MCU/STM32F1xx/STM32_USB-FS-Device_Driver/inc/usb_core.h
similarity index 100%
rename from STM32_USB-FS-Device_Driver/inc/usb_core.h
rename to SPARK_Platform/MCU/STM32F1xx/STM32_USB-FS-Device_Driver/inc/usb_core.h
diff --git a/STM32_USB-FS-Device_Driver/inc/usb_def.h b/SPARK_Platform/MCU/STM32F1xx/STM32_USB-FS-Device_Driver/inc/usb_def.h
similarity index 100%
rename from STM32_USB-FS-Device_Driver/inc/usb_def.h
rename to SPARK_Platform/MCU/STM32F1xx/STM32_USB-FS-Device_Driver/inc/usb_def.h
diff --git a/STM32_USB-FS-Device_Driver/inc/usb_init.h b/SPARK_Platform/MCU/STM32F1xx/STM32_USB-FS-Device_Driver/inc/usb_init.h
similarity index 100%
rename from STM32_USB-FS-Device_Driver/inc/usb_init.h
rename to SPARK_Platform/MCU/STM32F1xx/STM32_USB-FS-Device_Driver/inc/usb_init.h
diff --git a/STM32_USB-FS-Device_Driver/inc/usb_int.h b/SPARK_Platform/MCU/STM32F1xx/STM32_USB-FS-Device_Driver/inc/usb_int.h
similarity index 100%
rename from STM32_USB-FS-Device_Driver/inc/usb_int.h
rename to SPARK_Platform/MCU/STM32F1xx/STM32_USB-FS-Device_Driver/inc/usb_int.h
diff --git a/STM32_USB-FS-Device_Driver/inc/usb_lib.h b/SPARK_Platform/MCU/STM32F1xx/STM32_USB-FS-Device_Driver/inc/usb_lib.h
similarity index 100%
rename from STM32_USB-FS-Device_Driver/inc/usb_lib.h
rename to SPARK_Platform/MCU/STM32F1xx/STM32_USB-FS-Device_Driver/inc/usb_lib.h
diff --git a/STM32_USB-FS-Device_Driver/inc/usb_mem.h b/SPARK_Platform/MCU/STM32F1xx/STM32_USB-FS-Device_Driver/inc/usb_mem.h
similarity index 100%
rename from STM32_USB-FS-Device_Driver/inc/usb_mem.h
rename to SPARK_Platform/MCU/STM32F1xx/STM32_USB-FS-Device_Driver/inc/usb_mem.h
diff --git a/STM32_USB-FS-Device_Driver/inc/usb_regs.h b/SPARK_Platform/MCU/STM32F1xx/STM32_USB-FS-Device_Driver/inc/usb_regs.h
similarity index 100%
rename from STM32_USB-FS-Device_Driver/inc/usb_regs.h
rename to SPARK_Platform/MCU/STM32F1xx/STM32_USB-FS-Device_Driver/inc/usb_regs.h
diff --git a/STM32_USB-FS-Device_Driver/inc/usb_sil.h b/SPARK_Platform/MCU/STM32F1xx/STM32_USB-FS-Device_Driver/inc/usb_sil.h
similarity index 100%
rename from STM32_USB-FS-Device_Driver/inc/usb_sil.h
rename to SPARK_Platform/MCU/STM32F1xx/STM32_USB-FS-Device_Driver/inc/usb_sil.h
diff --git a/STM32_USB-FS-Device_Driver/inc/usb_type.h b/SPARK_Platform/MCU/STM32F1xx/STM32_USB-FS-Device_Driver/inc/usb_type.h
similarity index 100%
rename from STM32_USB-FS-Device_Driver/inc/usb_type.h
rename to SPARK_Platform/MCU/STM32F1xx/STM32_USB-FS-Device_Driver/inc/usb_type.h
diff --git a/STM32_USB-FS-Device_Driver/src/build.mk b/SPARK_Platform/MCU/STM32F1xx/STM32_USB-FS-Device_Driver/src/build.mk
similarity index 91%
rename from STM32_USB-FS-Device_Driver/src/build.mk
rename to SPARK_Platform/MCU/STM32F1xx/STM32_USB-FS-Device_Driver/src/build.mk
index ee53963..919f884 100644
--- a/STM32_USB-FS-Device_Driver/src/build.mk
+++ b/SPARK_Platform/MCU/STM32F1xx/STM32_USB-FS-Device_Driver/src/build.mk
@@ -4,7 +4,7 @@
# Define the prefix to this directory.
# Note: The name must be unique within this build and should be
# based on the root of the project
-TARGET_USB_FS_PATH = STM32_USB-FS-Device_Driver
+TARGET_USB_FS_PATH = SPARK_Platform/MCU/STM32F1xx/STM32_USB-FS-Device_Driver
TARGET_USB_FS_SRC_PATH = $(TARGET_USB_FS_PATH)/src
# Add tropicssl include to all objects built for this target
diff --git a/STM32_USB-FS-Device_Driver/src/usb_core.c b/SPARK_Platform/MCU/STM32F1xx/STM32_USB-FS-Device_Driver/src/usb_core.c
similarity index 100%
rename from STM32_USB-FS-Device_Driver/src/usb_core.c
rename to SPARK_Platform/MCU/STM32F1xx/STM32_USB-FS-Device_Driver/src/usb_core.c
diff --git a/STM32_USB-FS-Device_Driver/src/usb_init.c b/SPARK_Platform/MCU/STM32F1xx/STM32_USB-FS-Device_Driver/src/usb_init.c
similarity index 100%
rename from STM32_USB-FS-Device_Driver/src/usb_init.c
rename to SPARK_Platform/MCU/STM32F1xx/STM32_USB-FS-Device_Driver/src/usb_init.c
diff --git a/STM32_USB-FS-Device_Driver/src/usb_int.c b/SPARK_Platform/MCU/STM32F1xx/STM32_USB-FS-Device_Driver/src/usb_int.c
similarity index 100%
rename from STM32_USB-FS-Device_Driver/src/usb_int.c
rename to SPARK_Platform/MCU/STM32F1xx/STM32_USB-FS-Device_Driver/src/usb_int.c
diff --git a/STM32_USB-FS-Device_Driver/src/usb_mem.c b/SPARK_Platform/MCU/STM32F1xx/STM32_USB-FS-Device_Driver/src/usb_mem.c
similarity index 100%
rename from STM32_USB-FS-Device_Driver/src/usb_mem.c
rename to SPARK_Platform/MCU/STM32F1xx/STM32_USB-FS-Device_Driver/src/usb_mem.c
diff --git a/STM32_USB-FS-Device_Driver/src/usb_regs.c b/SPARK_Platform/MCU/STM32F1xx/STM32_USB-FS-Device_Driver/src/usb_regs.c
similarity index 100%
rename from STM32_USB-FS-Device_Driver/src/usb_regs.c
rename to SPARK_Platform/MCU/STM32F1xx/STM32_USB-FS-Device_Driver/src/usb_regs.c
diff --git a/STM32_USB-FS-Device_Driver/src/usb_sil.c b/SPARK_Platform/MCU/STM32F1xx/STM32_USB-FS-Device_Driver/src/usb_sil.c
similarity index 100%
rename from STM32_USB-FS-Device_Driver/src/usb_sil.c
rename to SPARK_Platform/MCU/STM32F1xx/STM32_USB-FS-Device_Driver/src/usb_sil.c
diff --git a/SPARK_Platform/MCU/STM32F2xx/CMSIS/Device/ST/STM32F2xx/Include/stm32f2xx.h b/SPARK_Platform/MCU/STM32F2xx/CMSIS/Device/ST/STM32F2xx/Include/stm32f2xx.h
new file mode 100644
index 0000000..8ec7e1b
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/CMSIS/Device/ST/STM32F2xx/Include/stm32f2xx.h
@@ -0,0 +1,6963 @@
+/**
+ ******************************************************************************
+ * @file stm32f2xx.h
+ * @author MCD Application Team
+ * @version V1.1.3
+ * @date 05-March-2012
+ * @brief CMSIS Cortex-M3 Device Peripheral Access Layer Header File.
+ * This file contains all the peripheral register's definitions, bits
+ * definitions and memory mapping for STM32F2xx devices.
+ *
+ * The file is the unique include file that the application programmer
+ * is using in the C source code, usually in main.c. This file contains:
+ * - Configuration section that allows to select:
+ * - The device used in the target application
+ * - To use or not the peripheral�s drivers in application code(i.e.
+ * code will be based on direct access to peripheral�s registers
+ * rather than drivers API), this option is controlled by
+ * "#define USE_STDPERIPH_DRIVER"
+ * - To change few application-specific parameters such as the HSE
+ * crystal frequency
+ * - Data structures and the address mapping for all peripherals
+ * - Peripheral's registers declarations and bits definition
+ * - Macros to access peripheral�s registers hardware
+ *
+ ******************************************************************************
+ * @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.
+ *
+ ******************************************************************************
+ */
+
+/** @addtogroup CMSIS
+ * @{
+ */
+
+/** @addtogroup stm32f2xx
+ * @{
+ */
+
+#ifndef __STM32F2xx_H
+#define __STM32F2xx_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif /* __cplusplus */
+
+/** @addtogroup Library_configuration_section
+ * @{
+ */
+
+/* Uncomment the line below according to the target STM32 device used in your
+ application
+ */
+
+#if !defined (STM32F2XX)
+ #define STM32F2XX
+#endif
+
+/* Tip: To avoid modifying this file each time you need to switch between these
+ devices, you can define the device in your toolchain compiler preprocessor.
+ */
+
+#if !defined (STM32F2XX)
+ #error "Please select first the target STM32F2XX device used in your application (in stm32f2xx.h file)"
+#endif
+
+#if !defined (USE_STDPERIPH_DRIVER)
+/**
+ * @brief Comment the line below if you will not use the peripherals drivers.
+ In this case, these drivers will not be included and the application code will
+ be based on direct access to peripherals registers
+ */
+ /*#define USE_STDPERIPH_DRIVER*/
+#endif /* USE_STDPERIPH_DRIVER */
+
+/**
+ * @brief In the following line adjust the value of External High Speed oscillator (HSE)
+ used in your application
+
+ Tip: To avoid modifying this file each time you need to use different HSE, you
+ can define the HSE value in your toolchain compiler preprocessor.
+ */
+#if !defined (HSE_VALUE)
+ #define HSE_VALUE ((uint32_t)25000000) /*!< Value of the External oscillator in Hz */
+#endif /* HSE_VALUE */
+
+/**
+ * @brief In the following line adjust the External High Speed oscillator (HSE) Startup
+ Timeout value
+ */
+#if !defined (HSE_STARTUP_TIMEOUT)
+ #define HSE_STARTUP_TIMEOUT ((uint16_t)0x0500) /*!< Time out for HSE start up */
+#endif /* HSE_STARTUP_TIMEOUT */
+
+#if !defined (HSI_VALUE)
+ #define HSI_VALUE ((uint32_t)16000000) /*!< Value of the Internal oscillator in Hz*/
+#endif /* HSI_VALUE */
+
+/**
+ * @brief STM32F2XX Standard Peripherals Library version number V1.1.3
+ */
+#define __STM32F2XX_STDPERIPH_VERSION_MAIN (0x01) /*!< [31:24] main version */
+#define __STM32F2XX_STDPERIPH_VERSION_SUB1 (0x01) /*!< [23:16] sub1 version */
+#define __STM32F2XX_STDPERIPH_VERSION_SUB2 (0x03) /*!< [15:8] sub2 version */
+#define __STM32F2XX_STDPERIPH_VERSION_RC (0x00) /*!< [7:0] release candidate */
+#define __STM32F2XX_STDPERIPH_VERSION ((__STM32F2XX_STDPERIPH_VERSION_MAIN << 24)\
+ |(__STM32F2XX_STDPERIPH_VERSION_SUB1 << 16)\
+ |(__STM32F2XX_STDPERIPH_VERSION_SUB2 << 8)\
+ |(__STM32F2XX_STDPERIPH_VERSION_RC))
+
+/**
+ * @}
+ */
+
+/** @addtogroup Configuration_section_for_CMSIS
+ * @{
+ */
+
+/**
+ * @brief Configuration of the Cortex-M3 Processor and Core Peripherals
+ */
+#define __CM3_REV 0x0200 /*!< Core Revision r2p0 */
+#define __MPU_PRESENT 1 /*!< STM32F2XX provides an MPU */
+#define __NVIC_PRIO_BITS 4 /*!< STM32F2XX uses 4 Bits for the Priority Levels */
+#define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */
+
+/**
+ * @brief STM32F2XX Interrupt Number Definition, according to the selected device
+ * in @ref Library_configuration_section
+ */
+typedef enum IRQn
+{
+/****** Cortex-M3 Processor Exceptions Numbers ****************************************************************/
+ NonMaskableInt_IRQn = -14, /*!< 2 Non Maskable Interrupt */
+ MemoryManagement_IRQn = -12, /*!< 4 Cortex-M3 Memory Management Interrupt */
+ BusFault_IRQn = -11, /*!< 5 Cortex-M3 Bus Fault Interrupt */
+ UsageFault_IRQn = -10, /*!< 6 Cortex-M3 Usage Fault Interrupt */
+ SVCall_IRQn = -5, /*!< 11 Cortex-M3 SV Call Interrupt */
+ DebugMonitor_IRQn = -4, /*!< 12 Cortex-M3 Debug Monitor Interrupt */
+ PendSV_IRQn = -2, /*!< 14 Cortex-M3 Pend SV Interrupt */
+ SysTick_IRQn = -1, /*!< 15 Cortex-M3 System Tick Interrupt */
+/****** 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 */
+} IRQn_Type;
+
+/**
+ * @}
+ */
+
+#include "core_cm3.h"
+#include "system_stm32f2xx.h"
+#include
+
+/** @addtogroup Exported_types
+ * @{
+ */
+/*!< STM32F10x Standard Peripheral Library old types (maintained for legacy purpose) */
+typedef int32_t s32;
+typedef int16_t s16;
+typedef int8_t s8;
+
+typedef const int32_t sc32; /*!< Read Only */
+typedef const int16_t sc16; /*!< Read Only */
+typedef const int8_t sc8; /*!< Read Only */
+
+typedef __IO int32_t vs32;
+typedef __IO int16_t vs16;
+typedef __IO int8_t vs8;
+
+typedef __I int32_t vsc32; /*!< Read Only */
+typedef __I int16_t vsc16; /*!< Read Only */
+typedef __I int8_t vsc8; /*!< Read Only */
+
+typedef uint32_t u32;
+typedef uint16_t u16;
+typedef uint8_t u8;
+
+typedef const uint32_t uc32; /*!< Read Only */
+typedef const uint16_t uc16; /*!< Read Only */
+typedef const uint8_t uc8; /*!< Read Only */
+
+typedef __IO uint32_t vu32;
+typedef __IO uint16_t vu16;
+typedef __IO uint8_t vu8;
+
+typedef __I uint32_t vuc32; /*!< Read Only */
+typedef __I uint16_t vuc16; /*!< Read Only */
+typedef __I uint8_t vuc8; /*!< Read Only */
+
+typedef enum {RESET = 0, SET = !RESET} FlagStatus, ITStatus;
+
+typedef enum {DISABLE = 0, ENABLE = !DISABLE} FunctionalState;
+#define IS_FUNCTIONAL_STATE(STATE) (((STATE) == DISABLE) || ((STATE) == ENABLE))
+
+typedef enum {ERROR = 0, SUCCESS = !ERROR} ErrorStatus;
+
+/**
+ * @}
+ */
+
+/** @addtogroup Peripheral_registers_structures
+ * @{
+ */
+
+/**
+ * @brief Analog to Digital Converter
+ */
+
+typedef struct
+{
+ __IO uint32_t SR; /*!< ADC status register, Address offset: 0x00 */
+ __IO uint32_t CR1; /*!< ADC control register 1, Address offset: 0x04 */
+ __IO uint32_t CR2; /*!< ADC control register 2, Address offset: 0x08 */
+ __IO uint32_t SMPR1; /*!< ADC sample time register 1, Address offset: 0x0C */
+ __IO uint32_t SMPR2; /*!< ADC sample time register 2, Address offset: 0x10 */
+ __IO uint32_t JOFR1; /*!< ADC injected channel data offset register 1, Address offset: 0x14 */
+ __IO uint32_t JOFR2; /*!< ADC injected channel data offset register 2, Address offset: 0x18 */
+ __IO uint32_t JOFR3; /*!< ADC injected channel data offset register 3, Address offset: 0x1C */
+ __IO uint32_t JOFR4; /*!< ADC injected channel data offset register 4, Address offset: 0x20 */
+ __IO uint32_t HTR; /*!< ADC watchdog higher threshold register, Address offset: 0x24 */
+ __IO uint32_t LTR; /*!< ADC watchdog lower threshold register, Address offset: 0x28 */
+ __IO uint32_t SQR1; /*!< ADC regular sequence register 1, Address offset: 0x2C */
+ __IO uint32_t SQR2; /*!< ADC regular sequence register 2, Address offset: 0x30 */
+ __IO uint32_t SQR3; /*!< ADC regular sequence register 3, Address offset: 0x34 */
+ __IO uint32_t JSQR; /*!< ADC injected sequence register, Address offset: 0x38*/
+ __IO uint32_t JDR1; /*!< ADC injected data register 1, Address offset: 0x3C */
+ __IO uint32_t JDR2; /*!< ADC injected data register 2, Address offset: 0x40 */
+ __IO uint32_t JDR3; /*!< ADC injected data register 3, Address offset: 0x44 */
+ __IO uint32_t JDR4; /*!< ADC injected data register 4, Address offset: 0x48 */
+ __IO uint32_t DR; /*!< ADC regular data register, Address offset: 0x4C */
+} ADC_TypeDef;
+
+typedef struct
+{
+ __IO uint32_t CSR; /*!< ADC Common status register, Address offset: ADC1 base address + 0x300 */
+ __IO uint32_t CCR; /*!< ADC common control register, Address offset: ADC1 base address + 0x304 */
+ __IO uint32_t CDR; /*!< ADC common regular data register for dual
+ AND triple modes, Address offset: ADC1 base address + 0x308 */
+} ADC_Common_TypeDef;
+
+
+/**
+ * @brief Controller Area Network TxMailBox
+ */
+
+typedef struct
+{
+ __IO uint32_t TIR; /*!< CAN TX mailbox identifier register */
+ __IO uint32_t TDTR; /*!< CAN mailbox data length control and time stamp register */
+ __IO uint32_t TDLR; /*!< CAN mailbox data low register */
+ __IO uint32_t TDHR; /*!< CAN mailbox data high register */
+} CAN_TxMailBox_TypeDef;
+
+/**
+ * @brief Controller Area Network FIFOMailBox
+ */
+
+typedef struct
+{
+ __IO uint32_t RIR; /*!< CAN receive FIFO mailbox identifier register */
+ __IO uint32_t RDTR; /*!< CAN receive FIFO mailbox data length control and time stamp register */
+ __IO uint32_t RDLR; /*!< CAN receive FIFO mailbox data low register */
+ __IO uint32_t RDHR; /*!< CAN receive FIFO mailbox data high register */
+} CAN_FIFOMailBox_TypeDef;
+
+/**
+ * @brief Controller Area Network FilterRegister
+ */
+
+typedef struct
+{
+ __IO uint32_t FR1; /*!< CAN Filter bank register 1 */
+ __IO uint32_t FR2; /*!< CAN Filter bank register 1 */
+} CAN_FilterRegister_TypeDef;
+
+/**
+ * @brief Controller Area Network
+ */
+
+typedef struct
+{
+ __IO uint32_t MCR; /*!< CAN master control register, Address offset: 0x00 */
+ __IO uint32_t MSR; /*!< CAN master status register, Address offset: 0x04 */
+ __IO uint32_t TSR; /*!< CAN transmit status register, Address offset: 0x08 */
+ __IO uint32_t RF0R; /*!< CAN receive FIFO 0 register, Address offset: 0x0C */
+ __IO uint32_t RF1R; /*!< CAN receive FIFO 1 register, Address offset: 0x10 */
+ __IO uint32_t IER; /*!< CAN interrupt enable register, Address offset: 0x14 */
+ __IO uint32_t ESR; /*!< CAN error status register, Address offset: 0x18 */
+ __IO uint32_t BTR; /*!< CAN bit timing register, Address offset: 0x1C */
+ uint32_t RESERVED0[88]; /*!< Reserved, 0x020 - 0x17F */
+ CAN_TxMailBox_TypeDef sTxMailBox[3]; /*!< CAN Tx MailBox, Address offset: 0x180 - 0x1AC */
+ CAN_FIFOMailBox_TypeDef sFIFOMailBox[2]; /*!< CAN FIFO MailBox, Address offset: 0x1B0 - 0x1CC */
+ uint32_t RESERVED1[12]; /*!< Reserved, 0x1D0 - 0x1FF */
+ __IO uint32_t FMR; /*!< CAN filter master register, Address offset: 0x200 */
+ __IO uint32_t FM1R; /*!< CAN filter mode register, Address offset: 0x204 */
+ uint32_t RESERVED2; /*!< Reserved, 0x208 */
+ __IO uint32_t FS1R; /*!< CAN filter scale register, Address offset: 0x20C */
+ uint32_t RESERVED3; /*!< Reserved, 0x210 */
+ __IO uint32_t FFA1R; /*!< CAN filter FIFO assignment register, Address offset: 0x214 */
+ uint32_t RESERVED4; /*!< Reserved, 0x218 */
+ __IO uint32_t FA1R; /*!< CAN filter activation register, Address offset: 0x21C */
+ uint32_t RESERVED5[8]; /*!< Reserved, 0x220-0x23F */
+ CAN_FilterRegister_TypeDef sFilterRegister[28]; /*!< CAN Filter Register, Address offset: 0x240-0x31C */
+} CAN_TypeDef;
+
+/**
+ * @brief CRC calculation unit
+ */
+
+typedef struct
+{
+ __IO uint32_t DR; /*!< CRC Data register, Address offset: 0x00 */
+ __IO uint8_t IDR; /*!< CRC Independent data register, Address offset: 0x04 */
+ uint8_t RESERVED0; /*!< Reserved, 0x05 */
+ uint16_t RESERVED1; /*!< Reserved, 0x06 */
+ __IO uint32_t CR; /*!< CRC Control register, Address offset: 0x08 */
+} CRC_TypeDef;
+
+/**
+ * @brief Digital to Analog Converter
+ */
+
+typedef struct
+{
+ __IO uint32_t CR; /*!< DAC control register, Address offset: 0x00 */
+ __IO uint32_t SWTRIGR; /*!< DAC software trigger register, Address offset: 0x04 */
+ __IO uint32_t DHR12R1; /*!< DAC channel1 12-bit right-aligned data holding register, Address offset: 0x08 */
+ __IO uint32_t DHR12L1; /*!< DAC channel1 12-bit left aligned data holding register, Address offset: 0x0C */
+ __IO uint32_t DHR8R1; /*!< DAC channel1 8-bit right aligned data holding register, Address offset: 0x10 */
+ __IO uint32_t DHR12R2; /*!< DAC channel2 12-bit right aligned data holding register, Address offset: 0x14 */
+ __IO uint32_t DHR12L2; /*!< DAC channel2 12-bit left aligned data holding register, Address offset: 0x18 */
+ __IO uint32_t DHR8R2; /*!< DAC channel2 8-bit right-aligned data holding register, Address offset: 0x1C */
+ __IO uint32_t DHR12RD; /*!< Dual DAC 12-bit right-aligned data holding register, Address offset: 0x20 */
+ __IO uint32_t DHR12LD; /*!< DUAL DAC 12-bit left aligned data holding register, Address offset: 0x24 */
+ __IO uint32_t DHR8RD; /*!< DUAL DAC 8-bit right aligned data holding register, Address offset: 0x28 */
+ __IO uint32_t DOR1; /*!< DAC channel1 data output register, Address offset: 0x2C */
+ __IO uint32_t DOR2; /*!< DAC channel2 data output register, Address offset: 0x30 */
+ __IO uint32_t SR; /*!< DAC status register, Address offset: 0x34 */
+} DAC_TypeDef;
+
+/**
+ * @brief Debug MCU
+ */
+
+typedef struct
+{
+ __IO uint32_t IDCODE; /*!< MCU device ID code, Address offset: 0x00 */
+ __IO uint32_t CR; /*!< Debug MCU configuration register, Address offset: 0x04 */
+ __IO uint32_t APB1FZ; /*!< Debug MCU APB1 freeze register, Address offset: 0x08 */
+ __IO uint32_t APB2FZ; /*!< Debug MCU APB2 freeze register, Address offset: 0x0C */
+}DBGMCU_TypeDef;
+
+/**
+ * @brief DCMI
+ */
+
+typedef struct
+{
+ __IO uint32_t CR; /*!< DCMI control register 1, Address offset: 0x00 */
+ __IO uint32_t SR; /*!< DCMI status register, Address offset: 0x04 */
+ __IO uint32_t RISR; /*!< DCMI raw interrupt status register, Address offset: 0x08 */
+ __IO uint32_t IER; /*!< DCMI interrupt enable register, Address offset: 0x0C */
+ __IO uint32_t MISR; /*!< DCMI masked interrupt status register, Address offset: 0x10 */
+ __IO uint32_t ICR; /*!< DCMI interrupt clear register, Address offset: 0x14 */
+ __IO uint32_t ESCR; /*!< DCMI embedded synchronization code register, Address offset: 0x18 */
+ __IO uint32_t ESUR; /*!< DCMI embedded synchronization unmask register, Address offset: 0x1C */
+ __IO uint32_t CWSTRTR; /*!< DCMI crop window start, Address offset: 0x20 */
+ __IO uint32_t CWSIZER; /*!< DCMI crop window size, Address offset: 0x24 */
+ __IO uint32_t DR; /*!< DCMI data register, Address offset: 0x28 */
+} DCMI_TypeDef;
+
+/**
+ * @brief DMA Controller
+ */
+
+typedef struct
+{
+ __IO uint32_t CR; /*!< DMA stream x configuration register */
+ __IO uint32_t NDTR; /*!< DMA stream x number of data register */
+ __IO uint32_t PAR; /*!< DMA stream x peripheral address register */
+ __IO uint32_t M0AR; /*!< DMA stream x memory 0 address register */
+ __IO uint32_t M1AR; /*!< DMA stream x memory 1 address register */
+ __IO uint32_t FCR; /*!< DMA stream x FIFO control register */
+} DMA_Stream_TypeDef;
+
+typedef struct
+{
+ __IO uint32_t LISR; /*!< DMA low interrupt status register, Address offset: 0x00 */
+ __IO uint32_t HISR; /*!< DMA high interrupt status register, Address offset: 0x04 */
+ __IO uint32_t LIFCR; /*!< DMA low interrupt flag clear register, Address offset: 0x08 */
+ __IO uint32_t HIFCR; /*!< DMA high interrupt flag clear register, Address offset: 0x0C */
+} DMA_TypeDef;
+
+/**
+ * @brief Ethernet MAC
+ */
+
+typedef struct
+{
+ __IO uint32_t MACCR;
+ __IO uint32_t MACFFR;
+ __IO uint32_t MACHTHR;
+ __IO uint32_t MACHTLR;
+ __IO uint32_t MACMIIAR;
+ __IO uint32_t MACMIIDR;
+ __IO uint32_t MACFCR;
+ __IO uint32_t MACVLANTR; /* 8 */
+ uint32_t RESERVED0[2];
+ __IO uint32_t MACRWUFFR; /* 11 */
+ __IO uint32_t MACPMTCSR;
+ uint32_t RESERVED1[2];
+ __IO uint32_t MACSR; /* 15 */
+ __IO uint32_t MACIMR;
+ __IO uint32_t MACA0HR;
+ __IO uint32_t MACA0LR;
+ __IO uint32_t MACA1HR;
+ __IO uint32_t MACA1LR;
+ __IO uint32_t MACA2HR;
+ __IO uint32_t MACA2LR;
+ __IO uint32_t MACA3HR;
+ __IO uint32_t MACA3LR; /* 24 */
+ uint32_t RESERVED2[40];
+ __IO uint32_t MMCCR; /* 65 */
+ __IO uint32_t MMCRIR;
+ __IO uint32_t MMCTIR;
+ __IO uint32_t MMCRIMR;
+ __IO uint32_t MMCTIMR; /* 69 */
+ uint32_t RESERVED3[14];
+ __IO uint32_t MMCTGFSCCR; /* 84 */
+ __IO uint32_t MMCTGFMSCCR;
+ uint32_t RESERVED4[5];
+ __IO uint32_t MMCTGFCR;
+ uint32_t RESERVED5[10];
+ __IO uint32_t MMCRFCECR;
+ __IO uint32_t MMCRFAECR;
+ uint32_t RESERVED6[10];
+ __IO uint32_t MMCRGUFCR;
+ uint32_t RESERVED7[334];
+ __IO uint32_t PTPTSCR;
+ __IO uint32_t PTPSSIR;
+ __IO uint32_t PTPTSHR;
+ __IO uint32_t PTPTSLR;
+ __IO uint32_t PTPTSHUR;
+ __IO uint32_t PTPTSLUR;
+ __IO uint32_t PTPTSAR;
+ __IO uint32_t PTPTTHR;
+ __IO uint32_t PTPTTLR;
+ __IO uint32_t RESERVED8;
+ __IO uint32_t PTPTSSR; /* added for STM32F2xx */
+ uint32_t RESERVED9[565];
+ __IO uint32_t DMABMR;
+ __IO uint32_t DMATPDR;
+ __IO uint32_t DMARPDR;
+ __IO uint32_t DMARDLAR;
+ __IO uint32_t DMATDLAR;
+ __IO uint32_t DMASR;
+ __IO uint32_t DMAOMR;
+ __IO uint32_t DMAIER;
+ __IO uint32_t DMAMFBOCR;
+ __IO uint32_t DMARSWTR; /* added for STM32F2xx */
+ uint32_t RESERVED10[8];
+ __IO uint32_t DMACHTDR;
+ __IO uint32_t DMACHRDR;
+ __IO uint32_t DMACHTBAR;
+ __IO uint32_t DMACHRBAR;
+} ETH_TypeDef;
+
+/**
+ * @brief External Interrupt/Event Controller
+ */
+
+typedef struct
+{
+ __IO uint32_t IMR; /*!< EXTI Interrupt mask register, Address offset: 0x00 */
+ __IO uint32_t EMR; /*!< EXTI Event mask register, Address offset: 0x04 */
+ __IO uint32_t RTSR; /*!< EXTI Rising trigger selection register, Address offset: 0x08 */
+ __IO uint32_t FTSR; /*!< EXTI Falling trigger selection register, Address offset: 0x0C */
+ __IO uint32_t SWIER; /*!< EXTI Software interrupt event register, Address offset: 0x10 */
+ __IO uint32_t PR; /*!< EXTI Pending register, Address offset: 0x14 */
+} EXTI_TypeDef;
+
+/**
+ * @brief FLASH Registers
+ */
+
+typedef struct
+{
+ __IO uint32_t ACR; /*!< FLASH access control register, Address offset: 0x00 */
+ __IO uint32_t KEYR; /*!< FLASH key register, Address offset: 0x04 */
+ __IO uint32_t OPTKEYR; /*!< FLASH option key register, Address offset: 0x08 */
+ __IO uint32_t SR; /*!< FLASH status register, Address offset: 0x0C */
+ __IO uint32_t CR; /*!< FLASH control register, Address offset: 0x10 */
+ __IO uint32_t OPTCR; /*!< FLASH option control register, Address offset: 0x14 */
+} FLASH_TypeDef;
+
+/**
+ * @brief Flexible Static Memory Controller
+ */
+
+typedef struct
+{
+ __IO uint32_t BTCR[8]; /*!< NOR/PSRAM chip-select control register(BCR) and chip-select timing register(BTR), Address offset: 0x00-1C */
+} FSMC_Bank1_TypeDef;
+
+/**
+ * @brief Flexible Static Memory Controller Bank1E
+ */
+
+typedef struct
+{
+ __IO uint32_t BWTR[7]; /*!< NOR/PSRAM write timing registers, Address offset: 0x104-0x11C */
+} FSMC_Bank1E_TypeDef;
+
+/**
+ * @brief Flexible Static Memory Controller Bank2
+ */
+
+typedef struct
+{
+ __IO uint32_t PCR2; /*!< NAND Flash control register 2, Address offset: 0x60 */
+ __IO uint32_t SR2; /*!< NAND Flash FIFO status and interrupt register 2, Address offset: 0x64 */
+ __IO uint32_t PMEM2; /*!< NAND Flash Common memory space timing register 2, Address offset: 0x68 */
+ __IO uint32_t PATT2; /*!< NAND Flash Attribute memory space timing register 2, Address offset: 0x6C */
+ uint32_t RESERVED0; /*!< Reserved, 0x70 */
+ __IO uint32_t ECCR2; /*!< NAND Flash ECC result registers 2, Address offset: 0x74 */
+} FSMC_Bank2_TypeDef;
+
+/**
+ * @brief Flexible Static Memory Controller Bank3
+ */
+
+typedef struct
+{
+ __IO uint32_t PCR3; /*!< NAND Flash control register 3, Address offset: 0x80 */
+ __IO uint32_t SR3; /*!< NAND Flash FIFO status and interrupt register 3, Address offset: 0x84 */
+ __IO uint32_t PMEM3; /*!< NAND Flash Common memory space timing register 3, Address offset: 0x88 */
+ __IO uint32_t PATT3; /*!< NAND Flash Attribute memory space timing register 3, Address offset: 0x8C */
+ uint32_t RESERVED0; /*!< Reserved, 0x90 */
+ __IO uint32_t ECCR3; /*!< NAND Flash ECC result registers 3, Address offset: 0x94 */
+} FSMC_Bank3_TypeDef;
+
+/**
+ * @brief Flexible Static Memory Controller Bank4
+ */
+
+typedef struct
+{
+ __IO uint32_t PCR4; /*!< PC Card control register 4, Address offset: 0xA0 */
+ __IO uint32_t SR4; /*!< PC Card FIFO status and interrupt register 4, Address offset: 0xA4 */
+ __IO uint32_t PMEM4; /*!< PC Card Common memory space timing register 4, Address offset: 0xA8 */
+ __IO uint32_t PATT4; /*!< PC Card Attribute memory space timing register 4, Address offset: 0xAC */
+ __IO uint32_t PIO4; /*!< PC Card I/O space timing register 4, Address offset: 0xB0 */
+} FSMC_Bank4_TypeDef;
+
+/**
+ * @brief General Purpose I/O
+ */
+
+typedef struct
+{
+ __IO uint32_t MODER; /*!< GPIO port mode register, Address offset: 0x00 */
+ __IO uint32_t OTYPER; /*!< GPIO port output type register, Address offset: 0x04 */
+ __IO uint32_t OSPEEDR; /*!< GPIO port output speed register, Address offset: 0x08 */
+ __IO uint32_t PUPDR; /*!< GPIO port pull-up/pull-down register, Address offset: 0x0C */
+ __IO uint32_t IDR; /*!< GPIO port input data register, Address offset: 0x10 */
+ __IO uint32_t ODR; /*!< GPIO port output data register, Address offset: 0x14 */
+ __IO uint16_t BSRRL; /*!< GPIO port bit set/reset low register, Address offset: 0x18 */
+ __IO uint16_t BSRRH; /*!< GPIO port bit set/reset high register, Address offset: 0x1A */
+ __IO uint32_t LCKR; /*!< GPIO port configuration lock register, Address offset: 0x1C */
+ __IO uint32_t AFR[2]; /*!< GPIO alternate function registers, Address offset: 0x20-0x24 */
+} GPIO_TypeDef;
+
+/**
+ * @brief System configuration controller
+ */
+
+typedef struct
+{
+ __IO uint32_t MEMRMP; /*!< SYSCFG memory remap register, Address offset: 0x00 */
+ __IO uint32_t PMC; /*!< SYSCFG peripheral mode configuration register, Address offset: 0x04 */
+ __IO uint32_t EXTICR[4]; /*!< SYSCFG external interrupt configuration registers, Address offset: 0x08-0x14 */
+ uint32_t RESERVED[2]; /*!< Reserved, 0x18-0x1C */
+ __IO uint32_t CMPCR; /*!< SYSCFG Compensation cell control register, Address offset: 0x20 */
+} SYSCFG_TypeDef;
+
+/**
+ * @brief Inter-integrated Circuit Interface
+ */
+
+typedef struct
+{
+ __IO uint16_t CR1; /*!< I2C Control register 1, Address offset: 0x00 */
+ uint16_t RESERVED0; /*!< Reserved, 0x02 */
+ __IO uint16_t CR2; /*!< I2C Control register 2, Address offset: 0x04 */
+ uint16_t RESERVED1; /*!< Reserved, 0x06 */
+ __IO uint16_t OAR1; /*!< I2C Own address register 1, Address offset: 0x08 */
+ uint16_t RESERVED2; /*!< Reserved, 0x0A */
+ __IO uint16_t OAR2; /*!< I2C Own address register 2, Address offset: 0x0C */
+ uint16_t RESERVED3; /*!< Reserved, 0x0E */
+ __IO uint16_t DR; /*!< I2C Data register, Address offset: 0x10 */
+ uint16_t RESERVED4; /*!< Reserved, 0x12 */
+ __IO uint16_t SR1; /*!< I2C Status register 1, Address offset: 0x14 */
+ uint16_t RESERVED5; /*!< Reserved, 0x16 */
+ __IO uint16_t SR2; /*!< I2C Status register 2, Address offset: 0x18 */
+ uint16_t RESERVED6; /*!< Reserved, 0x1A */
+ __IO uint16_t CCR; /*!< I2C Clock control register, Address offset: 0x1C */
+ uint16_t RESERVED7; /*!< Reserved, 0x1E */
+ __IO uint16_t TRISE; /*!< I2C TRISE register, Address offset: 0x20 */
+ uint16_t RESERVED8; /*!< Reserved, 0x22 */
+} I2C_TypeDef;
+
+/**
+ * @brief Independent WATCHDOG
+ */
+
+typedef struct
+{
+ __IO uint32_t KR; /*!< IWDG Key register, Address offset: 0x00 */
+ __IO uint32_t PR; /*!< IWDG Prescaler register, Address offset: 0x04 */
+ __IO uint32_t RLR; /*!< IWDG Reload register, Address offset: 0x08 */
+ __IO uint32_t SR; /*!< IWDG Status register, Address offset: 0x0C */
+} IWDG_TypeDef;
+
+/**
+ * @brief Power Control
+ */
+
+typedef struct
+{
+ __IO uint32_t CR; /*!< PWR power control register, Address offset: 0x00 */
+ __IO uint32_t CSR; /*!< PWR power control/status register, Address offset: 0x04 */
+} PWR_TypeDef;
+
+/**
+ * @brief Reset and Clock Control
+ */
+
+typedef struct
+{
+ __IO uint32_t CR; /*!< RCC clock control register, Address offset: 0x00 */
+ __IO uint32_t PLLCFGR; /*!< RCC PLL configuration register, Address offset: 0x04 */
+ __IO uint32_t CFGR; /*!< RCC clock configuration register, Address offset: 0x08 */
+ __IO uint32_t CIR; /*!< RCC clock interrupt register, Address offset: 0x0C */
+ __IO uint32_t AHB1RSTR; /*!< RCC AHB1 peripheral reset register, Address offset: 0x10 */
+ __IO uint32_t AHB2RSTR; /*!< RCC AHB2 peripheral reset register, Address offset: 0x14 */
+ __IO uint32_t AHB3RSTR; /*!< RCC AHB3 peripheral reset register, Address offset: 0x18 */
+ uint32_t RESERVED0; /*!< Reserved, 0x1C */
+ __IO uint32_t APB1RSTR; /*!< RCC APB1 peripheral reset register, Address offset: 0x20 */
+ __IO uint32_t APB2RSTR; /*!< RCC APB2 peripheral reset register, Address offset: 0x24 */
+ uint32_t RESERVED1[2]; /*!< Reserved, 0x28-0x2C */
+ __IO uint32_t AHB1ENR; /*!< RCC AHB1 peripheral clock register, Address offset: 0x30 */
+ __IO uint32_t AHB2ENR; /*!< RCC AHB2 peripheral clock register, Address offset: 0x34 */
+ __IO uint32_t AHB3ENR; /*!< RCC AHB3 peripheral clock register, Address offset: 0x38 */
+ uint32_t RESERVED2; /*!< Reserved, 0x3C */
+ __IO uint32_t APB1ENR; /*!< RCC APB1 peripheral clock enable register, Address offset: 0x40 */
+ __IO uint32_t APB2ENR; /*!< RCC APB2 peripheral clock enable register, Address offset: 0x44 */
+ uint32_t RESERVED3[2]; /*!< Reserved, 0x48-0x4C */
+ __IO uint32_t AHB1LPENR; /*!< RCC AHB1 peripheral clock enable in low power mode register, Address offset: 0x50 */
+ __IO uint32_t AHB2LPENR; /*!< RCC AHB2 peripheral clock enable in low power mode register, Address offset: 0x54 */
+ __IO uint32_t AHB3LPENR; /*!< RCC AHB3 peripheral clock enable in low power mode register, Address offset: 0x58 */
+ uint32_t RESERVED4; /*!< Reserved, 0x5C */
+ __IO uint32_t APB1LPENR; /*!< RCC APB1 peripheral clock enable in low power mode register, Address offset: 0x60 */
+ __IO uint32_t APB2LPENR; /*!< RCC APB2 peripheral clock enable in low power mode register, Address offset: 0x64 */
+ uint32_t RESERVED5[2]; /*!< Reserved, 0x68-0x6C */
+ __IO uint32_t BDCR; /*!< RCC Backup domain control register, Address offset: 0x70 */
+ __IO uint32_t CSR; /*!< RCC clock control & status register, Address offset: 0x74 */
+ uint32_t RESERVED6[2]; /*!< Reserved, 0x78-0x7C */
+ __IO uint32_t SSCGR; /*!< RCC spread spectrum clock generation register, Address offset: 0x80 */
+ __IO uint32_t PLLI2SCFGR; /*!< RCC PLLI2S configuration register, Address offset: 0x84 */
+} RCC_TypeDef;
+
+/**
+ * @brief Real-Time Clock
+ */
+
+typedef struct
+{
+ __IO uint32_t TR; /*!< RTC time register, Address offset: 0x00 */
+ __IO uint32_t DR; /*!< RTC date register, Address offset: 0x04 */
+ __IO uint32_t CR; /*!< RTC control register, Address offset: 0x08 */
+ __IO uint32_t ISR; /*!< RTC initialization and status register, Address offset: 0x0C */
+ __IO uint32_t PRER; /*!< RTC prescaler register, Address offset: 0x10 */
+ __IO uint32_t WUTR; /*!< RTC wakeup timer register, Address offset: 0x14 */
+ __IO uint32_t CALIBR; /*!< RTC calibration register, Address offset: 0x18 */
+ __IO uint32_t ALRMAR; /*!< RTC alarm A register, Address offset: 0x1C */
+ __IO uint32_t ALRMBR; /*!< RTC alarm B register, Address offset: 0x20 */
+ __IO uint32_t WPR; /*!< RTC write protection register, Address offset: 0x24 */
+ uint32_t RESERVED1; /*!< Reserved, 0x28 */
+ uint32_t RESERVED2; /*!< Reserved, 0x2C */
+ __IO uint32_t TSTR; /*!< RTC time stamp time register, Address offset: 0x30 */
+ __IO uint32_t TSDR; /*!< RTC time stamp date register, Address offset: 0x34 */
+ uint32_t RESERVED3; /*!< Reserved, 0x38 */
+ uint32_t RESERVED4; /*!< Reserved, 0x3C */
+ __IO uint32_t TAFCR; /*!< RTC tamper and alternate function configuration register, Address offset: 0x40 */
+ uint32_t RESERVED5; /*!< Reserved, 0x44 */
+ uint32_t RESERVED6; /*!< Reserved, 0x48 */
+ uint32_t RESERVED7; /*!< Reserved, 0x4C */
+ __IO uint32_t BKP0R; /*!< RTC backup register 1, Address offset: 0x50 */
+ __IO uint32_t BKP1R; /*!< RTC backup register 1, Address offset: 0x54 */
+ __IO uint32_t BKP2R; /*!< RTC backup register 2, Address offset: 0x58 */
+ __IO uint32_t BKP3R; /*!< RTC backup register 3, Address offset: 0x5C */
+ __IO uint32_t BKP4R; /*!< RTC backup register 4, Address offset: 0x60 */
+ __IO uint32_t BKP5R; /*!< RTC backup register 5, Address offset: 0x64 */
+ __IO uint32_t BKP6R; /*!< RTC backup register 6, Address offset: 0x68 */
+ __IO uint32_t BKP7R; /*!< RTC backup register 7, Address offset: 0x6C */
+ __IO uint32_t BKP8R; /*!< RTC backup register 8, Address offset: 0x70 */
+ __IO uint32_t BKP9R; /*!< RTC backup register 9, Address offset: 0x74 */
+ __IO uint32_t BKP10R; /*!< RTC backup register 10, Address offset: 0x78 */
+ __IO uint32_t BKP11R; /*!< RTC backup register 11, Address offset: 0x7C */
+ __IO uint32_t BKP12R; /*!< RTC backup register 12, Address offset: 0x80 */
+ __IO uint32_t BKP13R; /*!< RTC backup register 13, Address offset: 0x84 */
+ __IO uint32_t BKP14R; /*!< RTC backup register 14, Address offset: 0x88 */
+ __IO uint32_t BKP15R; /*!< RTC backup register 15, Address offset: 0x8C */
+ __IO uint32_t BKP16R; /*!< RTC backup register 16, Address offset: 0x90 */
+ __IO uint32_t BKP17R; /*!< RTC backup register 17, Address offset: 0x94 */
+ __IO uint32_t BKP18R; /*!< RTC backup register 18, Address offset: 0x98 */
+ __IO uint32_t BKP19R; /*!< RTC backup register 19, Address offset: 0x9C */
+} RTC_TypeDef;
+
+/**
+ * @brief SD host Interface
+ */
+
+typedef struct
+{
+ __IO uint32_t POWER; /*!< SDIO power control register, Address offset: 0x00 */
+ __IO uint32_t CLKCR; /*!< SDI clock control register, Address offset: 0x04 */
+ __IO uint32_t ARG; /*!< SDIO argument register, Address offset: 0x08 */
+ __IO uint32_t CMD; /*!< SDIO command register, Address offset: 0x0C */
+ __I uint32_t RESPCMD; /*!< SDIO command response register, Address offset: 0x10 */
+ __I uint32_t RESP1; /*!< SDIO response 1 register, Address offset: 0x14 */
+ __I uint32_t RESP2; /*!< SDIO response 2 register, Address offset: 0x18 */
+ __I uint32_t RESP3; /*!< SDIO response 3 register, Address offset: 0x1C */
+ __I uint32_t RESP4; /*!< SDIO response 4 register, Address offset: 0x20 */
+ __IO uint32_t DTIMER; /*!< SDIO data timer register, Address offset: 0x24 */
+ __IO uint32_t DLEN; /*!< SDIO data length register, Address offset: 0x28 */
+ __IO uint32_t DCTRL; /*!< SDIO data control register, Address offset: 0x2C */
+ __I uint32_t DCOUNT; /*!< SDIO data counter register, Address offset: 0x30 */
+ __I uint32_t STA; /*!< SDIO status register, Address offset: 0x34 */
+ __IO uint32_t ICR; /*!< SDIO interrupt clear register, Address offset: 0x38 */
+ __IO uint32_t MASK; /*!< SDIO mask register, Address offset: 0x3C */
+ uint32_t RESERVED0[2]; /*!< Reserved, 0x40-0x44 */
+ __I uint32_t FIFOCNT; /*!< SDIO FIFO counter register, Address offset: 0x48 */
+ uint32_t RESERVED1[13]; /*!< Reserved, 0x4C-0x7C */
+ __IO uint32_t FIFO; /*!< SDIO data FIFO register, Address offset: 0x80 */
+} SDIO_TypeDef;
+
+/**
+ * @brief Serial Peripheral Interface
+ */
+
+typedef struct
+{
+ __IO uint16_t CR1; /*!< SPI control register 1 (not used in I2S mode), Address offset: 0x00 */
+ uint16_t RESERVED0; /*!< Reserved, 0x02 */
+ __IO uint16_t CR2; /*!< SPI control register 2, Address offset: 0x04 */
+ uint16_t RESERVED1; /*!< Reserved, 0x06 */
+ __IO uint16_t SR; /*!< SPI status register, Address offset: 0x08 */
+ uint16_t RESERVED2; /*!< Reserved, 0x0A */
+ __IO uint16_t DR; /*!< SPI data register, Address offset: 0x0C */
+ uint16_t RESERVED3; /*!< Reserved, 0x0E */
+ __IO uint16_t CRCPR; /*!< SPI CRC polynomial register (not used in I2S mode), Address offset: 0x10 */
+ uint16_t RESERVED4; /*!< Reserved, 0x12 */
+ __IO uint16_t RXCRCR; /*!< SPI RX CRC register (not used in I2S mode), Address offset: 0x14 */
+ uint16_t RESERVED5; /*!< Reserved, 0x16 */
+ __IO uint16_t TXCRCR; /*!< SPI TX CRC register (not used in I2S mode), Address offset: 0x18 */
+ uint16_t RESERVED6; /*!< Reserved, 0x1A */
+ __IO uint16_t I2SCFGR; /*!< SPI_I2S configuration register, Address offset: 0x1C */
+ uint16_t RESERVED7; /*!< Reserved, 0x1E */
+ __IO uint16_t I2SPR; /*!< SPI_I2S prescaler register, Address offset: 0x20 */
+ uint16_t RESERVED8; /*!< Reserved, 0x22 */
+} SPI_TypeDef;
+
+/**
+ * @brief TIM
+ */
+
+typedef struct
+{
+ __IO uint16_t CR1; /*!< TIM control register 1, Address offset: 0x00 */
+ uint16_t RESERVED0; /*!< Reserved, 0x02 */
+ __IO uint16_t CR2; /*!< TIM control register 2, Address offset: 0x04 */
+ uint16_t RESERVED1; /*!< Reserved, 0x06 */
+ __IO uint16_t SMCR; /*!< TIM slave mode control register, Address offset: 0x08 */
+ uint16_t RESERVED2; /*!< Reserved, 0x0A */
+ __IO uint16_t DIER; /*!< TIM DMA/interrupt enable register, Address offset: 0x0C */
+ uint16_t RESERVED3; /*!< Reserved, 0x0E */
+ __IO uint16_t SR; /*!< TIM status register, Address offset: 0x10 */
+ uint16_t RESERVED4; /*!< Reserved, 0x12 */
+ __IO uint16_t EGR; /*!< TIM event generation register, Address offset: 0x14 */
+ uint16_t RESERVED5; /*!< Reserved, 0x16 */
+ __IO uint16_t CCMR1; /*!< TIM capture/compare mode register 1, Address offset: 0x18 */
+ uint16_t RESERVED6; /*!< Reserved, 0x1A */
+ __IO uint16_t CCMR2; /*!< TIM capture/compare mode register 2, Address offset: 0x1C */
+ uint16_t RESERVED7; /*!< Reserved, 0x1E */
+ __IO uint16_t CCER; /*!< TIM capture/compare enable register, Address offset: 0x20 */
+ uint16_t RESERVED8; /*!< Reserved, 0x22 */
+ __IO uint32_t CNT; /*!< TIM counter register, Address offset: 0x24 */
+ __IO uint16_t PSC; /*!< TIM prescaler, Address offset: 0x28 */
+ uint16_t RESERVED9; /*!< Reserved, 0x2A */
+ __IO uint32_t ARR; /*!< TIM auto-reload register, Address offset: 0x2C */
+ __IO uint16_t RCR; /*!< TIM repetition counter register, Address offset: 0x30 */
+ uint16_t RESERVED10; /*!< Reserved, 0x32 */
+ __IO uint32_t CCR1; /*!< TIM capture/compare register 1, Address offset: 0x34 */
+ __IO uint32_t CCR2; /*!< TIM capture/compare register 2, Address offset: 0x38 */
+ __IO uint32_t CCR3; /*!< TIM capture/compare register 3, Address offset: 0x3C */
+ __IO uint32_t CCR4; /*!< TIM capture/compare register 4, Address offset: 0x40 */
+ __IO uint16_t BDTR; /*!< TIM break and dead-time register, Address offset: 0x44 */
+ uint16_t RESERVED11; /*!< Reserved, 0x46 */
+ __IO uint16_t DCR; /*!< TIM DMA control register, Address offset: 0x48 */
+ uint16_t RESERVED12; /*!< Reserved, 0x4A */
+ __IO uint16_t DMAR; /*!< TIM DMA address for full transfer, Address offset: 0x4C */
+ uint16_t RESERVED13; /*!< Reserved, 0x4E */
+ __IO uint16_t OR; /*!< TIM option register, Address offset: 0x50 */
+ uint16_t RESERVED14; /*!< Reserved, 0x52 */
+} TIM_TypeDef;
+
+/**
+ * @brief Universal Synchronous Asynchronous Receiver Transmitter
+ */
+
+typedef struct
+{
+ __IO uint16_t SR; /*!< USART Status register, Address offset: 0x00 */
+ uint16_t RESERVED0; /*!< Reserved, 0x02 */
+ __IO uint16_t DR; /*!< USART Data register, Address offset: 0x04 */
+ uint16_t RESERVED1; /*!< Reserved, 0x06 */
+ __IO uint16_t BRR; /*!< USART Baud rate register, Address offset: 0x08 */
+ uint16_t RESERVED2; /*!< Reserved, 0x0A */
+ __IO uint16_t CR1; /*!< USART Control register 1, Address offset: 0x0C */
+ uint16_t RESERVED3; /*!< Reserved, 0x0E */
+ __IO uint16_t CR2; /*!< USART Control register 2, Address offset: 0x10 */
+ uint16_t RESERVED4; /*!< Reserved, 0x12 */
+ __IO uint16_t CR3; /*!< USART Control register 3, Address offset: 0x14 */
+ uint16_t RESERVED5; /*!< Reserved, 0x16 */
+ __IO uint16_t GTPR; /*!< USART Guard time and prescaler register, Address offset: 0x18 */
+ uint16_t RESERVED6; /*!< Reserved, 0x1A */
+} USART_TypeDef;
+
+/**
+ * @brief Window WATCHDOG
+ */
+
+typedef struct
+{
+ __IO uint32_t CR; /*!< WWDG Control register, Address offset: 0x00 */
+ __IO uint32_t CFR; /*!< WWDG Configuration register, Address offset: 0x04 */
+ __IO uint32_t SR; /*!< WWDG Status register, Address offset: 0x08 */
+} WWDG_TypeDef;
+
+/**
+ * @brief Crypto Processor
+ */
+
+typedef struct
+{
+ __IO uint32_t CR; /*!< CRYP control register, Address offset: 0x00 */
+ __IO uint32_t SR; /*!< CRYP status register, Address offset: 0x04 */
+ __IO uint32_t DR; /*!< CRYP data input register, Address offset: 0x08 */
+ __IO uint32_t DOUT; /*!< CRYP data output register, Address offset: 0x0C */
+ __IO uint32_t DMACR; /*!< CRYP DMA control register, Address offset: 0x10 */
+ __IO uint32_t IMSCR; /*!< CRYP interrupt mask set/clear register, Address offset: 0x14 */
+ __IO uint32_t RISR; /*!< CRYP raw interrupt status register, Address offset: 0x18 */
+ __IO uint32_t MISR; /*!< CRYP masked interrupt status register, Address offset: 0x1C */
+ __IO uint32_t K0LR; /*!< CRYP key left register 0, Address offset: 0x20 */
+ __IO uint32_t K0RR; /*!< CRYP key right register 0, Address offset: 0x24 */
+ __IO uint32_t K1LR; /*!< CRYP key left register 1, Address offset: 0x28 */
+ __IO uint32_t K1RR; /*!< CRYP key right register 1, Address offset: 0x2C */
+ __IO uint32_t K2LR; /*!< CRYP key left register 2, Address offset: 0x30 */
+ __IO uint32_t K2RR; /*!< CRYP key right register 2, Address offset: 0x34 */
+ __IO uint32_t K3LR; /*!< CRYP key left register 3, Address offset: 0x38 */
+ __IO uint32_t K3RR; /*!< CRYP key right register 3, Address offset: 0x3C */
+ __IO uint32_t IV0LR; /*!< CRYP initialization vector left-word register 0, Address offset: 0x40 */
+ __IO uint32_t IV0RR; /*!< CRYP initialization vector right-word register 0, Address offset: 0x44 */
+ __IO uint32_t IV1LR; /*!< CRYP initialization vector left-word register 1, Address offset: 0x48 */
+ __IO uint32_t IV1RR; /*!< CRYP initialization vector right-word register 1, Address offset: 0x4C */
+} CRYP_TypeDef;
+
+/**
+ * @brief HASH
+ */
+
+typedef struct
+{
+ __IO uint32_t CR; /*!< HASH control register, Address offset: 0x00 */
+ __IO uint32_t DIN; /*!< HASH data input register, Address offset: 0x04 */
+ __IO uint32_t STR; /*!< HASH start register, Address offset: 0x08 */
+ __IO uint32_t HR[5]; /*!< HASH digest registers, Address offset: 0x0C-0x1C */
+ __IO uint32_t IMR; /*!< HASH interrupt enable register, Address offset: 0x20 */
+ __IO uint32_t SR; /*!< HASH status register, Address offset: 0x24 */
+ uint32_t RESERVED[52]; /*!< Reserved, 0x28-0xF4 */
+ __IO uint32_t CSR[51]; /*!< HASH context swap registers, Address offset: 0x0F8-0x1C0 */
+} HASH_TypeDef;
+
+/**
+ * @brief HASH
+ */
+
+typedef struct
+{
+ __IO uint32_t CR; /*!< RNG control register, Address offset: 0x00 */
+ __IO uint32_t SR; /*!< RNG status register, Address offset: 0x04 */
+ __IO uint32_t DR; /*!< RNG data register, Address offset: 0x08 */
+} RNG_TypeDef;
+
+/**
+ * @}
+ */
+
+/** @addtogroup Peripheral_memory_map
+ * @{
+ */
+
+#define FLASH_BASE ((uint32_t)0x08000000) /*!< FLASH base address in the alias region */
+#define SRAM_BASE ((uint32_t)0x20000000) /*!< SRAM base address in the alias region */
+#define PERIPH_BASE ((uint32_t)0x40000000) /*!< Peripheral base address in the alias region */
+
+#define SRAM_BB_BASE ((uint32_t)0x22000000) /*!< SRAM base address in the bit-band region */
+#define PERIPH_BB_BASE ((uint32_t)0x42000000) /*!< Peripheral base address in the bit-band region */
+
+#define FSMC_R_BASE ((uint32_t)0xA0000000) /*!< FSMC registers base address */
+
+/*!< Peripheral memory map */
+#define APB1PERIPH_BASE PERIPH_BASE
+#define APB2PERIPH_BASE (PERIPH_BASE + 0x00010000)
+#define AHB1PERIPH_BASE (PERIPH_BASE + 0x00020000)
+#define AHB2PERIPH_BASE (PERIPH_BASE + 0x10000000)
+
+/*!< APB1 peripherals */
+#define TIM2_BASE (APB1PERIPH_BASE + 0x0000)
+#define TIM3_BASE (APB1PERIPH_BASE + 0x0400)
+#define TIM4_BASE (APB1PERIPH_BASE + 0x0800)
+#define TIM5_BASE (APB1PERIPH_BASE + 0x0C00)
+#define TIM6_BASE (APB1PERIPH_BASE + 0x1000)
+#define TIM7_BASE (APB1PERIPH_BASE + 0x1400)
+#define TIM12_BASE (APB1PERIPH_BASE + 0x1800)
+#define TIM13_BASE (APB1PERIPH_BASE + 0x1C00)
+#define TIM14_BASE (APB1PERIPH_BASE + 0x2000)
+#define RTC_BASE (APB1PERIPH_BASE + 0x2800)
+#define WWDG_BASE (APB1PERIPH_BASE + 0x2C00)
+#define IWDG_BASE (APB1PERIPH_BASE + 0x3000)
+#define SPI2_BASE (APB1PERIPH_BASE + 0x3800)
+#define SPI3_BASE (APB1PERIPH_BASE + 0x3C00)
+#define USART2_BASE (APB1PERIPH_BASE + 0x4400)
+#define USART3_BASE (APB1PERIPH_BASE + 0x4800)
+#define UART4_BASE (APB1PERIPH_BASE + 0x4C00)
+#define UART5_BASE (APB1PERIPH_BASE + 0x5000)
+#define I2C1_BASE (APB1PERIPH_BASE + 0x5400)
+#define I2C2_BASE (APB1PERIPH_BASE + 0x5800)
+#define I2C3_BASE (APB1PERIPH_BASE + 0x5C00)
+#define CAN1_BASE (APB1PERIPH_BASE + 0x6400)
+#define CAN2_BASE (APB1PERIPH_BASE + 0x6800)
+#define PWR_BASE (APB1PERIPH_BASE + 0x7000)
+#define DAC_BASE (APB1PERIPH_BASE + 0x7400)
+
+/*!< APB2 peripherals */
+#define TIM1_BASE (APB2PERIPH_BASE + 0x0000)
+#define TIM8_BASE (APB2PERIPH_BASE + 0x0400)
+#define USART1_BASE (APB2PERIPH_BASE + 0x1000)
+#define USART6_BASE (APB2PERIPH_BASE + 0x1400)
+#define ADC1_BASE (APB2PERIPH_BASE + 0x2000)
+#define ADC2_BASE (APB2PERIPH_BASE + 0x2100)
+#define ADC3_BASE (APB2PERIPH_BASE + 0x2200)
+#define ADC_BASE (APB2PERIPH_BASE + 0x2300)
+#define SDIO_BASE (APB2PERIPH_BASE + 0x2C00)
+#define SPI1_BASE (APB2PERIPH_BASE + 0x3000)
+#define SYSCFG_BASE (APB2PERIPH_BASE + 0x3800)
+#define EXTI_BASE (APB2PERIPH_BASE + 0x3C00)
+#define TIM9_BASE (APB2PERIPH_BASE + 0x4000)
+#define TIM10_BASE (APB2PERIPH_BASE + 0x4400)
+#define TIM11_BASE (APB2PERIPH_BASE + 0x4800)
+
+/*!< AHB1 peripherals */
+#define GPIOA_BASE (AHB1PERIPH_BASE + 0x0000)
+#define GPIOB_BASE (AHB1PERIPH_BASE + 0x0400)
+#define GPIOC_BASE (AHB1PERIPH_BASE + 0x0800)
+#define GPIOD_BASE (AHB1PERIPH_BASE + 0x0C00)
+#define GPIOE_BASE (AHB1PERIPH_BASE + 0x1000)
+#define GPIOF_BASE (AHB1PERIPH_BASE + 0x1400)
+#define GPIOG_BASE (AHB1PERIPH_BASE + 0x1800)
+#define GPIOH_BASE (AHB1PERIPH_BASE + 0x1C00)
+#define GPIOI_BASE (AHB1PERIPH_BASE + 0x2000)
+#define CRC_BASE (AHB1PERIPH_BASE + 0x3000)
+#define RCC_BASE (AHB1PERIPH_BASE + 0x3800)
+#define FLASH_R_BASE (AHB1PERIPH_BASE + 0x3C00)
+#define BKPSRAM_BASE (AHB1PERIPH_BASE + 0x4000)
+#define DMA1_BASE (AHB1PERIPH_BASE + 0x6000)
+#define DMA1_Stream0_BASE (DMA1_BASE + 0x010)
+#define DMA1_Stream1_BASE (DMA1_BASE + 0x028)
+#define DMA1_Stream2_BASE (DMA1_BASE + 0x040)
+#define DMA1_Stream3_BASE (DMA1_BASE + 0x058)
+#define DMA1_Stream4_BASE (DMA1_BASE + 0x070)
+#define DMA1_Stream5_BASE (DMA1_BASE + 0x088)
+#define DMA1_Stream6_BASE (DMA1_BASE + 0x0A0)
+#define DMA1_Stream7_BASE (DMA1_BASE + 0x0B8)
+#define DMA2_BASE (AHB1PERIPH_BASE + 0x6400)
+#define DMA2_Stream0_BASE (DMA2_BASE + 0x010)
+#define DMA2_Stream1_BASE (DMA2_BASE + 0x028)
+#define DMA2_Stream2_BASE (DMA2_BASE + 0x040)
+#define DMA2_Stream3_BASE (DMA2_BASE + 0x058)
+#define DMA2_Stream4_BASE (DMA2_BASE + 0x070)
+#define DMA2_Stream5_BASE (DMA2_BASE + 0x088)
+#define DMA2_Stream6_BASE (DMA2_BASE + 0x0A0)
+#define DMA2_Stream7_BASE (DMA2_BASE + 0x0B8)
+#define ETH_BASE (AHB1PERIPH_BASE + 0x8000)
+#define ETH_MAC_BASE (ETH_BASE)
+#define ETH_MMC_BASE (ETH_BASE + 0x0100)
+#define ETH_PTP_BASE (ETH_BASE + 0x0700)
+#define ETH_DMA_BASE (ETH_BASE + 0x1000)
+
+/*!< AHB2 peripherals */
+#define DCMI_BASE (AHB2PERIPH_BASE + 0x50000)
+#define CRYP_BASE (AHB2PERIPH_BASE + 0x60000)
+#define HASH_BASE (AHB2PERIPH_BASE + 0x60400)
+#define RNG_BASE (AHB2PERIPH_BASE + 0x60800)
+
+/*!< FSMC Bankx registers base address */
+#define FSMC_Bank1_R_BASE (FSMC_R_BASE + 0x0000)
+#define FSMC_Bank1E_R_BASE (FSMC_R_BASE + 0x0104)
+#define FSMC_Bank2_R_BASE (FSMC_R_BASE + 0x0060)
+#define FSMC_Bank3_R_BASE (FSMC_R_BASE + 0x0080)
+#define FSMC_Bank4_R_BASE (FSMC_R_BASE + 0x00A0)
+
+/* Debug MCU registers base address */
+#define DBGMCU_BASE ((uint32_t )0xE0042000)
+
+/**
+ * @}
+ */
+
+/** @addtogroup Peripheral_declaration
+ * @{
+ */
+#define TIM2 ((TIM_TypeDef *) TIM2_BASE)
+#define TIM3 ((TIM_TypeDef *) TIM3_BASE)
+#define TIM4 ((TIM_TypeDef *) TIM4_BASE)
+#define TIM5 ((TIM_TypeDef *) TIM5_BASE)
+#define TIM6 ((TIM_TypeDef *) TIM6_BASE)
+#define TIM7 ((TIM_TypeDef *) TIM7_BASE)
+#define TIM12 ((TIM_TypeDef *) TIM12_BASE)
+#define TIM13 ((TIM_TypeDef *) TIM13_BASE)
+#define TIM14 ((TIM_TypeDef *) TIM14_BASE)
+#define RTC ((RTC_TypeDef *) RTC_BASE)
+#define WWDG ((WWDG_TypeDef *) WWDG_BASE)
+#define IWDG ((IWDG_TypeDef *) IWDG_BASE)
+#define SPI2 ((SPI_TypeDef *) SPI2_BASE)
+#define SPI3 ((SPI_TypeDef *) SPI3_BASE)
+#define USART2 ((USART_TypeDef *) USART2_BASE)
+#define USART3 ((USART_TypeDef *) USART3_BASE)
+#define UART4 ((USART_TypeDef *) UART4_BASE)
+#define UART5 ((USART_TypeDef *) UART5_BASE)
+#define I2C1 ((I2C_TypeDef *) I2C1_BASE)
+#define I2C2 ((I2C_TypeDef *) I2C2_BASE)
+#define I2C3 ((I2C_TypeDef *) I2C3_BASE)
+#define CAN1 ((CAN_TypeDef *) CAN1_BASE)
+#define CAN2 ((CAN_TypeDef *) CAN2_BASE)
+#define PWR ((PWR_TypeDef *) PWR_BASE)
+#define DAC ((DAC_TypeDef *) DAC_BASE)
+#define TIM1 ((TIM_TypeDef *) TIM1_BASE)
+#define TIM8 ((TIM_TypeDef *) TIM8_BASE)
+#define USART1 ((USART_TypeDef *) USART1_BASE)
+#define USART6 ((USART_TypeDef *) USART6_BASE)
+#define ADC ((ADC_Common_TypeDef *) ADC_BASE)
+#define ADC1 ((ADC_TypeDef *) ADC1_BASE)
+#define ADC2 ((ADC_TypeDef *) ADC2_BASE)
+#define ADC3 ((ADC_TypeDef *) ADC3_BASE)
+#define SDIO ((SDIO_TypeDef *) SDIO_BASE)
+#define SPI1 ((SPI_TypeDef *) SPI1_BASE)
+#define SYSCFG ((SYSCFG_TypeDef *) SYSCFG_BASE)
+#define EXTI ((EXTI_TypeDef *) EXTI_BASE)
+#define TIM9 ((TIM_TypeDef *) TIM9_BASE)
+#define TIM10 ((TIM_TypeDef *) TIM10_BASE)
+#define TIM11 ((TIM_TypeDef *) TIM11_BASE)
+#define GPIOA ((GPIO_TypeDef *) GPIOA_BASE)
+#define GPIOB ((GPIO_TypeDef *) GPIOB_BASE)
+#define GPIOC ((GPIO_TypeDef *) GPIOC_BASE)
+#define GPIOD ((GPIO_TypeDef *) GPIOD_BASE)
+#define GPIOE ((GPIO_TypeDef *) GPIOE_BASE)
+#define GPIOF ((GPIO_TypeDef *) GPIOF_BASE)
+#define GPIOG ((GPIO_TypeDef *) GPIOG_BASE)
+#define GPIOH ((GPIO_TypeDef *) GPIOH_BASE)
+#define GPIOI ((GPIO_TypeDef *) GPIOI_BASE)
+#define CRC ((CRC_TypeDef *) CRC_BASE)
+#define RCC ((RCC_TypeDef *) RCC_BASE)
+#define FLASH ((FLASH_TypeDef *) FLASH_R_BASE)
+#define DMA1 ((DMA_TypeDef *) DMA1_BASE)
+#define DMA1_Stream0 ((DMA_Stream_TypeDef *) DMA1_Stream0_BASE)
+#define DMA1_Stream1 ((DMA_Stream_TypeDef *) DMA1_Stream1_BASE)
+#define DMA1_Stream2 ((DMA_Stream_TypeDef *) DMA1_Stream2_BASE)
+#define DMA1_Stream3 ((DMA_Stream_TypeDef *) DMA1_Stream3_BASE)
+#define DMA1_Stream4 ((DMA_Stream_TypeDef *) DMA1_Stream4_BASE)
+#define DMA1_Stream5 ((DMA_Stream_TypeDef *) DMA1_Stream5_BASE)
+#define DMA1_Stream6 ((DMA_Stream_TypeDef *) DMA1_Stream6_BASE)
+#define DMA1_Stream7 ((DMA_Stream_TypeDef *) DMA1_Stream7_BASE)
+#define DMA2 ((DMA_TypeDef *) DMA2_BASE)
+#define DMA2_Stream0 ((DMA_Stream_TypeDef *) DMA2_Stream0_BASE)
+#define DMA2_Stream1 ((DMA_Stream_TypeDef *) DMA2_Stream1_BASE)
+#define DMA2_Stream2 ((DMA_Stream_TypeDef *) DMA2_Stream2_BASE)
+#define DMA2_Stream3 ((DMA_Stream_TypeDef *) DMA2_Stream3_BASE)
+#define DMA2_Stream4 ((DMA_Stream_TypeDef *) DMA2_Stream4_BASE)
+#define DMA2_Stream5 ((DMA_Stream_TypeDef *) DMA2_Stream5_BASE)
+#define DMA2_Stream6 ((DMA_Stream_TypeDef *) DMA2_Stream6_BASE)
+#define DMA2_Stream7 ((DMA_Stream_TypeDef *) DMA2_Stream7_BASE)
+#define ETH ((ETH_TypeDef *) ETH_BASE)
+#define DCMI ((DCMI_TypeDef *) DCMI_BASE)
+#define CRYP ((CRYP_TypeDef *) CRYP_BASE)
+#define HASH ((HASH_TypeDef *) HASH_BASE)
+#define RNG ((RNG_TypeDef *) RNG_BASE)
+#define FSMC_Bank1 ((FSMC_Bank1_TypeDef *) FSMC_Bank1_R_BASE)
+#define FSMC_Bank1E ((FSMC_Bank1E_TypeDef *) FSMC_Bank1E_R_BASE)
+#define FSMC_Bank2 ((FSMC_Bank2_TypeDef *) FSMC_Bank2_R_BASE)
+#define FSMC_Bank3 ((FSMC_Bank3_TypeDef *) FSMC_Bank3_R_BASE)
+#define FSMC_Bank4 ((FSMC_Bank4_TypeDef *) FSMC_Bank4_R_BASE)
+#define DBGMCU ((DBGMCU_TypeDef *) DBGMCU_BASE)
+
+/**
+ * @}
+ */
+
+/** @addtogroup Exported_constants
+ * @{
+ */
+
+ /** @addtogroup Peripheral_Registers_Bits_Definition
+ * @{
+ */
+
+/******************************************************************************/
+/* Peripheral Registers_Bits_Definition */
+/******************************************************************************/
+
+/******************************************************************************/
+/* */
+/* Analog to Digital Converter */
+/* */
+/******************************************************************************/
+/******************** Bit definition for ADC_SR register ********************/
+#define ADC_SR_AWD ((uint8_t)0x01) /*!*/
+
+#define DAC_CR_EN2 ((uint32_t)0x00010000) /*!*/
+
+/***************** Bit definition for DAC_SWTRIGR register ******************/
+#define DAC_SWTRIGR_SWTRIG1 ((uint8_t)0x01) /*!© 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.
+ *
+ ******************************************************************************
+ */
+
+/** @addtogroup CMSIS
+ * @{
+ */
+
+/** @addtogroup stm32f2xx_system
+ * @{
+ */
+
+/**
+ * @brief Define to prevent recursive inclusion
+ */
+#ifndef __SYSTEM_STM32F2XX_H
+#define __SYSTEM_STM32F2XX_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/** @addtogroup STM32F2xx_System_Includes
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+
+/** @addtogroup STM32F2xx_System_Exported_types
+ * @{
+ */
+
+extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */
+
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32F2xx_System_Exported_Constants
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32F2xx_System_Exported_Macros
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32F2xx_System_Exported_Functions
+ * @{
+ */
+
+extern void SystemInit(void);
+extern void SystemCoreClockUpdate(void);
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*__SYSTEM_STM32F2XX_H */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/SPARK_Platform/MCU/STM32F2xx/CMSIS/Device/ST/STM32F2xx/Source/startup_stm32f2xx.s b/SPARK_Platform/MCU/STM32F2xx/CMSIS/Device/ST/STM32F2xx/Source/startup_stm32f2xx.s
new file mode 100644
index 0000000..3205505
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/CMSIS/Device/ST/STM32F2xx/Source/startup_stm32f2xx.s
@@ -0,0 +1,512 @@
+/**
+ ******************************************************************************
+ * @file startup_stm32f2xx.s
+ * @author MCD Application Team
+ * @version V1.1.3
+ * @date 05-March-2012
+ * @brief STM32F2xx Devices vector table for RIDE7 toolchain.
+ * This module performs:
+ * - Set the initial SP
+ * - Set the initial PC == Reset_Handler,
+ * - Set the vector table entries with the exceptions ISR address
+ * - Configure the system clock and the external SRAM mounted on
+ * STM322xG-EVAL board to be used as data memory (optional,
+ * to be enabled by user)
+ * - Branches to main in the C library (which eventually
+ * calls main()).
+ * After Reset the Cortex-M3 processor is in Thread mode,
+ * priority is Privileged, and the Stack is set to Main.
+ ******************************************************************************
+ * @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.
+ *
+ ******************************************************************************
+ */
+
+ .syntax unified
+ .cpu cortex-m3
+ .fpu softvfp
+ .thumb
+
+.global g_pfnVectors
+.global Default_Handler
+
+/* start address for the initialization values of the .data section.
+defined in linker script */
+.word _sidata
+/* start address for the .data section. defined in linker script */
+.word _sdata
+/* end address for the .data section. defined in linker script */
+.word _edata
+/* start address for the .bss section. defined in linker script */
+.word _sbss
+/* end address for the .bss section. defined in linker script */
+.word _ebss
+/* stack used for SystemInit_ExtMemCtl; always internal RAM used */
+
+/**
+ * @brief This is the code that gets called when the processor first
+ * starts execution following a reset event. Only the absolutely
+ * necessary set is performed, after which the application
+ * supplied main() routine is called.
+ * @param None
+ * @retval : None
+*/
+
+ .section .text.Reset_Handler
+ .weak Reset_Handler
+ .type Reset_Handler, %function
+Reset_Handler:
+
+/* Copy the data segment initializers from flash to SRAM */
+ movs r1, #0
+ b LoopCopyDataInit
+
+CopyDataInit:
+ ldr r3, =_sidata
+ ldr r3, [r3, r1]
+ str r3, [r0, r1]
+ adds r1, r1, #4
+
+LoopCopyDataInit:
+ ldr r0, =_sdata
+ ldr r3, =_edata
+ adds r2, r0, r1
+ cmp r2, r3
+ bcc CopyDataInit
+ ldr r2, =_sbss
+ b LoopFillZerobss
+/* Zero fill the bss segment. */
+FillZerobss:
+ movs r3, #0
+ str r3, [r2], #4
+
+LoopFillZerobss:
+ ldr r3, = _ebss
+ cmp r2, r3
+ bcc FillZerobss
+/* Call the clock system intitialization function.*/
+ bl SystemInit
+/* Call the application's entry point.*/
+ bl main
+ bx lr
+.size Reset_Handler, .-Reset_Handler
+
+/**
+ * @brief This is the code that gets called when the processor receives an
+ * unexpected interrupt. This simply enters an infinite loop, preserving
+ * the system state for examination by a debugger.
+ * @param None
+ * @retval None
+*/
+ .section .text.Default_Handler,"ax",%progbits
+Default_Handler:
+Infinite_Loop:
+ b Infinite_Loop
+ .size Default_Handler, .-Default_Handler
+/******************************************************************************
+*
+* The minimal vector table for a Cortex M3. Note that the proper constructs
+* must be placed on this to ensure that it ends up at physical address
+* 0x0000.0000.
+*
+*******************************************************************************/
+ .section .isr_vector,"a",%progbits
+ .type g_pfnVectors, %object
+ .size g_pfnVectors, .-g_pfnVectors
+
+
+g_pfnVectors:
+ .word _estack
+ .word Reset_Handler
+ .word NMI_Handler
+ .word HardFault_Handler
+ .word MemManage_Handler
+ .word BusFault_Handler
+ .word UsageFault_Handler
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word SVC_Handler
+ .word DebugMon_Handler
+ .word 0
+ .word PendSV_Handler
+ .word SysTick_Handler
+
+ /* External Interrupts */
+ .word WWDG_IRQHandler /* Window WatchDog */
+ .word PVD_IRQHandler /* PVD through EXTI Line detection */
+ .word TAMP_STAMP_IRQHandler /* Tamper and TimeStamps through the EXTI line */
+ .word RTC_WKUP_IRQHandler /* RTC Wakeup through the EXTI line */
+ .word FLASH_IRQHandler /* FLASH */
+ .word RCC_IRQHandler /* RCC */
+ .word EXTI0_IRQHandler /* EXTI Line0 */
+ .word EXTI1_IRQHandler /* EXTI Line1 */
+ .word EXTI2_IRQHandler /* EXTI Line2 */
+ .word EXTI3_IRQHandler /* EXTI Line3 */
+ .word EXTI4_IRQHandler /* EXTI Line4 */
+ .word DMA1_Stream0_IRQHandler /* DMA1 Stream 0 */
+ .word DMA1_Stream1_IRQHandler /* DMA1 Stream 1 */
+ .word DMA1_Stream2_IRQHandler /* DMA1 Stream 2 */
+ .word DMA1_Stream3_IRQHandler /* DMA1 Stream 3 */
+ .word DMA1_Stream4_IRQHandler /* DMA1 Stream 4 */
+ .word DMA1_Stream5_IRQHandler /* DMA1 Stream 5 */
+ .word DMA1_Stream6_IRQHandler /* DMA1 Stream 6 */
+ .word ADC_IRQHandler /* ADC1, ADC2 and ADC3s */
+ .word CAN1_TX_IRQHandler /* CAN1 TX */
+ .word CAN1_RX0_IRQHandler /* CAN1 RX0 */
+ .word CAN1_RX1_IRQHandler /* CAN1 RX1 */
+ .word CAN1_SCE_IRQHandler /* CAN1 SCE */
+ .word EXTI9_5_IRQHandler /* External Line[9:5]s */
+ .word TIM1_BRK_TIM9_IRQHandler /* TIM1 Break and TIM9 */
+ .word TIM1_UP_TIM10_IRQHandler /* TIM1 Update and TIM10 */
+ .word TIM1_TRG_COM_TIM11_IRQHandler /* TIM1 Trigger and Commutation and TIM11 */
+ .word TIM1_CC_IRQHandler /* TIM1 Capture Compare */
+ .word TIM2_IRQHandler /* TIM2 */
+ .word TIM3_IRQHandler /* TIM3 */
+ .word TIM4_IRQHandler /* TIM4 */
+ .word I2C1_EV_IRQHandler /* I2C1 Event */
+ .word I2C1_ER_IRQHandler /* I2C1 Error */
+ .word I2C2_EV_IRQHandler /* I2C2 Event */
+ .word I2C2_ER_IRQHandler /* I2C2 Error */
+ .word SPI1_IRQHandler /* SPI1 */
+ .word SPI2_IRQHandler /* SPI2 */
+ .word USART1_IRQHandler /* USART1 */
+ .word USART2_IRQHandler /* USART2 */
+ .word USART3_IRQHandler /* USART3 */
+ .word EXTI15_10_IRQHandler /* External Line[15:10]s */
+ .word RTC_Alarm_IRQHandler /* RTC Alarm (A and B) through EXTI Line */
+ .word OTG_FS_WKUP_IRQHandler /* USB OTG FS Wakeup through EXTI line */
+ .word TIM8_BRK_TIM12_IRQHandler /* TIM8 Break and TIM12 */
+ .word TIM8_UP_TIM13_IRQHandler /* TIM8 Update and TIM13 */
+ .word TIM8_TRG_COM_TIM14_IRQHandler /* TIM8 Trigger and Commutation and TIM14 */
+ .word TIM8_CC_IRQHandler /* TIM8 Capture Compare */
+ .word DMA1_Stream7_IRQHandler /* DMA1 Stream7 */
+ .word FSMC_IRQHandler /* FSMC */
+ .word SDIO_IRQHandler /* SDIO */
+ .word TIM5_IRQHandler /* TIM5 */
+ .word SPI3_IRQHandler /* SPI3 */
+ .word UART4_IRQHandler /* UART4 */
+ .word UART5_IRQHandler /* UART5 */
+ .word TIM6_DAC_IRQHandler /* TIM6 and DAC1&2 underrun errors */
+ .word TIM7_IRQHandler /* TIM7 */
+ .word DMA2_Stream0_IRQHandler /* DMA2 Stream 0 */
+ .word DMA2_Stream1_IRQHandler /* DMA2 Stream 1 */
+ .word DMA2_Stream2_IRQHandler /* DMA2 Stream 2 */
+ .word DMA2_Stream3_IRQHandler /* DMA2 Stream 3 */
+ .word DMA2_Stream4_IRQHandler /* DMA2 Stream 4 */
+ .word ETH_IRQHandler /* Ethernet */
+ .word ETH_WKUP_IRQHandler /* Ethernet Wakeup through EXTI line */
+ .word CAN2_TX_IRQHandler /* CAN2 TX */
+ .word CAN2_RX0_IRQHandler /* CAN2 RX0 */
+ .word CAN2_RX1_IRQHandler /* CAN2 RX1 */
+ .word CAN2_SCE_IRQHandler /* CAN2 SCE */
+ .word OTG_FS_IRQHandler /* USB OTG FS */
+ .word DMA2_Stream5_IRQHandler /* DMA2 Stream 5 */
+ .word DMA2_Stream6_IRQHandler /* DMA2 Stream 6 */
+ .word DMA2_Stream7_IRQHandler /* DMA2 Stream 7 */
+ .word USART6_IRQHandler /* USART6 */
+ .word I2C3_EV_IRQHandler /* I2C3 event */
+ .word I2C3_ER_IRQHandler /* I2C3 error */
+ .word OTG_HS_EP1_OUT_IRQHandler /* USB OTG HS End Point 1 Out */
+ .word OTG_HS_EP1_IN_IRQHandler /* USB OTG HS End Point 1 In */
+ .word OTG_HS_WKUP_IRQHandler /* USB OTG HS Wakeup through EXTI */
+ .word OTG_HS_IRQHandler /* USB OTG HS */
+ .word DCMI_IRQHandler /* DCMI */
+ .word CRYP_IRQHandler /* CRYP crypto */
+ .word HASH_RNG_IRQHandler /* Hash and Rng */
+
+
+/*******************************************************************************
+*
+* Provide weak aliases for each Exception handler to the Default_Handler.
+* As they are weak aliases, any function with the same name will override
+* this definition.
+*
+*******************************************************************************/
+ .weak NMI_Handler
+ .thumb_set NMI_Handler,Default_Handler
+
+ .weak HardFault_Handler
+ .thumb_set HardFault_Handler,Default_Handler
+
+ .weak MemManage_Handler
+ .thumb_set MemManage_Handler,Default_Handler
+
+ .weak BusFault_Handler
+ .thumb_set BusFault_Handler,Default_Handler
+
+ .weak UsageFault_Handler
+ .thumb_set UsageFault_Handler,Default_Handler
+
+ .weak SVC_Handler
+ .thumb_set SVC_Handler,Default_Handler
+
+ .weak DebugMon_Handler
+ .thumb_set DebugMon_Handler,Default_Handler
+
+ .weak PendSV_Handler
+ .thumb_set PendSV_Handler,Default_Handler
+
+ .weak SysTick_Handler
+ .thumb_set SysTick_Handler,Default_Handler
+
+ .weak WWDG_IRQHandler
+ .thumb_set WWDG_IRQHandler,Default_Handler
+
+ .weak PVD_IRQHandler
+ .thumb_set PVD_IRQHandler,Default_Handler
+
+ .weak TAMP_STAMP_IRQHandler
+ .thumb_set TAMP_STAMP_IRQHandler,Default_Handler
+
+ .weak RTC_WKUP_IRQHandler
+ .thumb_set RTC_WKUP_IRQHandler,Default_Handler
+
+ .weak FLASH_IRQHandler
+ .thumb_set FLASH_IRQHandler,Default_Handler
+
+ .weak RCC_IRQHandler
+ .thumb_set RCC_IRQHandler,Default_Handler
+
+ .weak EXTI0_IRQHandler
+ .thumb_set EXTI0_IRQHandler,Default_Handler
+
+ .weak EXTI1_IRQHandler
+ .thumb_set EXTI1_IRQHandler,Default_Handler
+
+ .weak EXTI2_IRQHandler
+ .thumb_set EXTI2_IRQHandler,Default_Handler
+
+ .weak EXTI3_IRQHandler
+ .thumb_set EXTI3_IRQHandler,Default_Handler
+
+ .weak EXTI4_IRQHandler
+ .thumb_set EXTI4_IRQHandler,Default_Handler
+
+ .weak DMA1_Stream0_IRQHandler
+ .thumb_set DMA1_Stream0_IRQHandler,Default_Handler
+
+ .weak DMA1_Stream1_IRQHandler
+ .thumb_set DMA1_Stream1_IRQHandler,Default_Handler
+
+ .weak DMA1_Stream2_IRQHandler
+ .thumb_set DMA1_Stream2_IRQHandler,Default_Handler
+
+ .weak DMA1_Stream3_IRQHandler
+ .thumb_set DMA1_Stream3_IRQHandler,Default_Handler
+
+ .weak DMA1_Stream4_IRQHandler
+ .thumb_set DMA1_Stream4_IRQHandler,Default_Handler
+
+ .weak DMA1_Stream5_IRQHandler
+ .thumb_set DMA1_Stream5_IRQHandler,Default_Handler
+
+ .weak DMA1_Stream6_IRQHandler
+ .thumb_set DMA1_Stream6_IRQHandler,Default_Handler
+
+ .weak ADC_IRQHandler
+ .thumb_set ADC_IRQHandler,Default_Handler
+
+ .weak CAN1_TX_IRQHandler
+ .thumb_set CAN1_TX_IRQHandler,Default_Handler
+
+ .weak CAN1_RX0_IRQHandler
+ .thumb_set CAN1_RX0_IRQHandler,Default_Handler
+
+ .weak CAN1_RX1_IRQHandler
+ .thumb_set CAN1_RX1_IRQHandler,Default_Handler
+
+ .weak CAN1_SCE_IRQHandler
+ .thumb_set CAN1_SCE_IRQHandler,Default_Handler
+
+ .weak EXTI9_5_IRQHandler
+ .thumb_set EXTI9_5_IRQHandler,Default_Handler
+
+ .weak TIM1_BRK_TIM9_IRQHandler
+ .thumb_set TIM1_BRK_TIM9_IRQHandler,Default_Handler
+
+ .weak TIM1_UP_TIM10_IRQHandler
+ .thumb_set TIM1_UP_TIM10_IRQHandler,Default_Handler
+
+ .weak TIM1_TRG_COM_TIM11_IRQHandler
+ .thumb_set TIM1_TRG_COM_TIM11_IRQHandler,Default_Handler
+
+ .weak TIM1_CC_IRQHandler
+ .thumb_set TIM1_CC_IRQHandler,Default_Handler
+
+ .weak TIM2_IRQHandler
+ .thumb_set TIM2_IRQHandler,Default_Handler
+
+ .weak TIM3_IRQHandler
+ .thumb_set TIM3_IRQHandler,Default_Handler
+
+ .weak TIM4_IRQHandler
+ .thumb_set TIM4_IRQHandler,Default_Handler
+
+ .weak I2C1_EV_IRQHandler
+ .thumb_set I2C1_EV_IRQHandler,Default_Handler
+
+ .weak I2C1_ER_IRQHandler
+ .thumb_set I2C1_ER_IRQHandler,Default_Handler
+
+ .weak I2C2_EV_IRQHandler
+ .thumb_set I2C2_EV_IRQHandler,Default_Handler
+
+ .weak I2C2_ER_IRQHandler
+ .thumb_set I2C2_ER_IRQHandler,Default_Handler
+
+ .weak SPI1_IRQHandler
+ .thumb_set SPI1_IRQHandler,Default_Handler
+
+ .weak SPI2_IRQHandler
+ .thumb_set SPI2_IRQHandler,Default_Handler
+
+ .weak USART1_IRQHandler
+ .thumb_set USART1_IRQHandler,Default_Handler
+
+ .weak USART2_IRQHandler
+ .thumb_set USART2_IRQHandler,Default_Handler
+
+ .weak USART3_IRQHandler
+ .thumb_set USART3_IRQHandler,Default_Handler
+
+ .weak EXTI15_10_IRQHandler
+ .thumb_set EXTI15_10_IRQHandler,Default_Handler
+
+ .weak RTC_Alarm_IRQHandler
+ .thumb_set RTC_Alarm_IRQHandler,Default_Handler
+
+ .weak OTG_FS_WKUP_IRQHandler
+ .thumb_set OTG_FS_WKUP_IRQHandler,Default_Handler
+
+ .weak TIM8_BRK_TIM12_IRQHandler
+ .thumb_set TIM8_BRK_TIM12_IRQHandler,Default_Handler
+
+ .weak TIM8_UP_TIM13_IRQHandler
+ .thumb_set TIM8_UP_TIM13_IRQHandler,Default_Handler
+
+ .weak TIM8_TRG_COM_TIM14_IRQHandler
+ .thumb_set TIM8_TRG_COM_TIM14_IRQHandler,Default_Handler
+
+ .weak TIM8_CC_IRQHandler
+ .thumb_set TIM8_CC_IRQHandler,Default_Handler
+
+ .weak DMA1_Stream7_IRQHandler
+ .thumb_set DMA1_Stream7_IRQHandler,Default_Handler
+
+ .weak FSMC_IRQHandler
+ .thumb_set FSMC_IRQHandler,Default_Handler
+
+ .weak SDIO_IRQHandler
+ .thumb_set SDIO_IRQHandler,Default_Handler
+
+ .weak TIM5_IRQHandler
+ .thumb_set TIM5_IRQHandler,Default_Handler
+
+ .weak SPI3_IRQHandler
+ .thumb_set SPI3_IRQHandler,Default_Handler
+
+ .weak UART4_IRQHandler
+ .thumb_set UART4_IRQHandler,Default_Handler
+
+ .weak UART5_IRQHandler
+ .thumb_set UART5_IRQHandler,Default_Handler
+
+ .weak TIM6_DAC_IRQHandler
+ .thumb_set TIM6_DAC_IRQHandler,Default_Handler
+
+ .weak TIM7_IRQHandler
+ .thumb_set TIM7_IRQHandler,Default_Handler
+
+ .weak DMA2_Stream0_IRQHandler
+ .thumb_set DMA2_Stream0_IRQHandler,Default_Handler
+
+ .weak DMA2_Stream1_IRQHandler
+ .thumb_set DMA2_Stream1_IRQHandler,Default_Handler
+
+ .weak DMA2_Stream2_IRQHandler
+ .thumb_set DMA2_Stream2_IRQHandler,Default_Handler
+
+ .weak DMA2_Stream3_IRQHandler
+ .thumb_set DMA2_Stream3_IRQHandler,Default_Handler
+
+ .weak DMA2_Stream4_IRQHandler
+ .thumb_set DMA2_Stream4_IRQHandler,Default_Handler
+
+ .weak ETH_IRQHandler
+ .thumb_set ETH_IRQHandler,Default_Handler
+
+ .weak ETH_WKUP_IRQHandler
+ .thumb_set ETH_WKUP_IRQHandler,Default_Handler
+
+ .weak CAN2_TX_IRQHandler
+ .thumb_set CAN2_TX_IRQHandler,Default_Handler
+
+ .weak CAN2_RX0_IRQHandler
+ .thumb_set CAN2_RX0_IRQHandler,Default_Handler
+
+ .weak CAN2_RX1_IRQHandler
+ .thumb_set CAN2_RX1_IRQHandler,Default_Handler
+
+ .weak CAN2_SCE_IRQHandler
+ .thumb_set CAN2_SCE_IRQHandler,Default_Handler
+
+ .weak OTG_FS_IRQHandler
+ .thumb_set OTG_FS_IRQHandler,Default_Handler
+
+ .weak DMA2_Stream5_IRQHandler
+ .thumb_set DMA2_Stream5_IRQHandler,Default_Handler
+
+ .weak DMA2_Stream6_IRQHandler
+ .thumb_set DMA2_Stream6_IRQHandler,Default_Handler
+
+ .weak DMA2_Stream7_IRQHandler
+ .thumb_set DMA2_Stream7_IRQHandler,Default_Handler
+
+ .weak USART6_IRQHandler
+ .thumb_set USART6_IRQHandler,Default_Handler
+
+ .weak I2C3_EV_IRQHandler
+ .thumb_set I2C3_EV_IRQHandler,Default_Handler
+
+ .weak I2C3_ER_IRQHandler
+ .thumb_set I2C3_ER_IRQHandler,Default_Handler
+
+ .weak OTG_HS_EP1_OUT_IRQHandler
+ .thumb_set OTG_HS_EP1_OUT_IRQHandler,Default_Handler
+
+ .weak OTG_HS_EP1_IN_IRQHandler
+ .thumb_set OTG_HS_EP1_IN_IRQHandler,Default_Handler
+
+ .weak OTG_HS_WKUP_IRQHandler
+ .thumb_set OTG_HS_WKUP_IRQHandler,Default_Handler
+
+ .weak OTG_HS_IRQHandler
+ .thumb_set OTG_HS_IRQHandler,Default_Handler
+
+ .weak DCMI_IRQHandler
+ .thumb_set DCMI_IRQHandler,Default_Handler
+
+ .weak CRYP_IRQHandler
+ .thumb_set CRYP_IRQHandler,Default_Handler
+
+ .weak HASH_RNG_IRQHandler
+ .thumb_set HASH_RNG_IRQHandler,Default_Handler
+
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/SPARK_Platform/MCU/STM32F2xx/CMSIS/Device/ST/STM32F2xx/Source/system_stm32f2xx.c b/SPARK_Platform/MCU/STM32F2xx/CMSIS/Device/ST/STM32F2xx/Source/system_stm32f2xx.c
new file mode 100644
index 0000000..b2221a6
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/CMSIS/Device/ST/STM32F2xx/Source/system_stm32f2xx.c
@@ -0,0 +1,542 @@
+/**
+ ******************************************************************************
+ * @file system_stm32f2xx.c
+ * @author MCD Application Team
+ * @version V1.1.3
+ * @date 05-March-2012
+ * @brief CMSIS Cortex-M3 Device Peripheral Access Layer System Source File.
+ * This file contains the system clock configuration for STM32F2xx devices,
+ * and is generated by the clock configuration tool
+ * "STM32f2xx_Clock_Configuration_V1.0.0.xls"
+ *
+ * 1. This file provides two functions and one global variable to be called from
+ * user application:
+ * - SystemInit(): Setups the system clock (System clock source, PLL Multiplier
+ * and Divider factors, AHB/APBx prescalers and Flash settings),
+ * depending on the configuration made in the clock xls tool.
+ * This function is called at startup just after reset and
+ * before branch to main program. This call is made inside
+ * the "startup_stm32f2xx.s" file.
+ *
+ * - SystemCoreClock variable: Contains the core clock (HCLK), it can be used
+ * by the user application to setup the SysTick
+ * timer or configure other parameters.
+ *
+ * - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must
+ * be called whenever the core clock is changed
+ * during program execution.
+ *
+ * 2. After each device reset the HSI (16 MHz) is used as system clock source.
+ * Then SystemInit() function is called, in "startup_stm32f2xx.s" file, to
+ * configure the system clock before to branch to main program.
+ *
+ * 3. If the system clock source selected by user fails to startup, the SystemInit()
+ * function will do nothing and HSI still used as system clock source. User can
+ * add some code to deal with this issue inside the SetSysClock() function.
+ *
+ * 4. The default value of HSE crystal is set to 25MHz, refer to "HSE_VALUE" define
+ * in "stm32f2xx.h" file. When HSE is used as system clock source, directly or
+ * through PLL, and you are using different crystal you have to adapt the HSE
+ * value to your own configuration.
+ *
+ * 5. This file configures the system clock as follows:
+ *=============================================================================
+ *=============================================================================
+ * Supported STM32F2xx device revision | Rev B and Y
+ *-----------------------------------------------------------------------------
+ * System Clock source | PLL (HSE)
+ *-----------------------------------------------------------------------------
+ * SYSCLK(Hz) | 120000000
+ *-----------------------------------------------------------------------------
+ * HCLK(Hz) | 120000000
+ *-----------------------------------------------------------------------------
+ * AHB Prescaler | 1
+ *-----------------------------------------------------------------------------
+ * APB1 Prescaler | 4
+ *-----------------------------------------------------------------------------
+ * APB2 Prescaler | 2
+ *-----------------------------------------------------------------------------
+ * HSE Frequency(Hz) | 25000000
+ *-----------------------------------------------------------------------------
+ * PLL_M | 25
+ *-----------------------------------------------------------------------------
+ * PLL_N | 240
+ *-----------------------------------------------------------------------------
+ * PLL_P | 2
+ *-----------------------------------------------------------------------------
+ * PLL_Q | 5
+ *-----------------------------------------------------------------------------
+ * PLLI2S_N | NA
+ *-----------------------------------------------------------------------------
+ * PLLI2S_R | NA
+ *-----------------------------------------------------------------------------
+ * I2S input clock | NA
+ *-----------------------------------------------------------------------------
+ * VDD(V) | 3.3
+ *-----------------------------------------------------------------------------
+ * Flash Latency(WS) | 3
+ *-----------------------------------------------------------------------------
+ * Prefetch Buffer | ON
+ *-----------------------------------------------------------------------------
+ * Instruction cache | ON
+ *-----------------------------------------------------------------------------
+ * Data cache | ON
+ *-----------------------------------------------------------------------------
+ * Require 48MHz for USB OTG FS, | Enabled
+ * SDIO and RNG clock |
+ *-----------------------------------------------------------------------------
+ *=============================================================================
+ ******************************************************************************
+ * @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.
+ *
+ ******************************************************************************
+ */
+
+/** @addtogroup CMSIS
+ * @{
+ */
+
+/** @addtogroup stm32f2xx_system
+ * @{
+ */
+
+/** @addtogroup STM32F2xx_System_Private_Includes
+ * @{
+ */
+
+#include "stm32f2xx.h"
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32F2xx_System_Private_TypesDefinitions
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32F2xx_System_Private_Defines
+ * @{
+ */
+
+/*!< Uncomment the following line if you need to use external SRAM mounted
+ on STM322xG_EVAL board as data memory */
+/* #define DATA_IN_ExtSRAM */
+
+/*!< Uncomment the following line if you need to relocate your vector Table in
+ Internal SRAM. */
+/* #define VECT_TAB_SRAM */
+#define VECT_TAB_OFFSET 0x00 /*!< Vector Table base offset field.
+ This value must be a multiple of 0x200. */
+
+
+/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */
+#define PLL_M 25
+#define PLL_N 240
+
+/* SYSCLK = PLL_VCO / PLL_P */
+#define PLL_P 2
+
+/* USB OTG FS, SDIO and RNG Clock = PLL_VCO / PLLQ */
+#define PLL_Q 5
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32F2xx_System_Private_Macros
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32F2xx_System_Private_Variables
+ * @{
+ */
+
+ uint32_t SystemCoreClock = 120000000;
+
+ __I uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32F2xx_System_Private_FunctionPrototypes
+ * @{
+ */
+
+static void SetSysClock(void);
+#ifdef DATA_IN_ExtSRAM
+ static void SystemInit_ExtMemCtl(void);
+#endif /* DATA_IN_ExtSRAM */
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32F2xx_System_Private_Functions
+ * @{
+ */
+
+/**
+ * @brief Setup the microcontroller system
+ * Initialize the Embedded Flash Interface, the PLL and update the
+ * SystemFrequency variable.
+ * @param None
+ * @retval None
+ */
+void SystemInit(void)
+{
+ /* 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;
+
+#ifdef DATA_IN_ExtSRAM
+ SystemInit_ExtMemCtl();
+#endif /* DATA_IN_ExtSRAM */
+
+ /* 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 ------------------*/
+#ifdef VECT_TAB_SRAM
+ SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */
+#else
+ SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */
+#endif
+}
+
+/**
+ * @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 stm32f2xx.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 stm32f2xx.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)
+ {
+ /* 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_PRFTEN | FLASH_ACR_ICEN | FLASH_ACR_DCEN | FLASH_ACR_LATENCY_3WS;
+
+ /* 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 */
+ }
+
+}
+
+/**
+ * @brief Setup the external memory controller. Called in startup_stm32f2xx.s
+ * before jump to __main
+ * @param None
+ * @retval None
+ */
+#ifdef DATA_IN_ExtSRAM
+/**
+ * @brief Setup the external memory controller.
+ * Called in startup_stm32f2xx.s before jump to main.
+ * This function configures the external SRAM mounted on STM322xG_EVAL board
+ * This SRAM will be used as program data memory (including heap and stack).
+ * @param None
+ * @retval None
+ */
+void SystemInit_ExtMemCtl(void)
+{
+/*-- GPIOs Configuration -----------------------------------------------------*/
+/*
+ +-------------------+--------------------+------------------+------------------+
+ + SRAM pins assignment +
+ +-------------------+--------------------+------------------+------------------+
+ | PD0 <-> FSMC_D2 | PE0 <-> FSMC_NBL0 | PF0 <-> FSMC_A0 | PG0 <-> FSMC_A10 |
+ | PD1 <-> FSMC_D3 | PE1 <-> FSMC_NBL1 | PF1 <-> FSMC_A1 | PG1 <-> FSMC_A11 |
+ | PD4 <-> FSMC_NOE | PE7 <-> FSMC_D4 | PF2 <-> FSMC_A2 | PG2 <-> FSMC_A12 |
+ | PD5 <-> FSMC_NWE | PE8 <-> FSMC_D5 | PF3 <-> FSMC_A3 | PG3 <-> FSMC_A13 |
+ | PD8 <-> FSMC_D13 | PE9 <-> FSMC_D6 | PF4 <-> FSMC_A4 | PG4 <-> FSMC_A14 |
+ | PD9 <-> FSMC_D14 | PE10 <-> FSMC_D7 | PF5 <-> FSMC_A5 | PG5 <-> FSMC_A15 |
+ | PD10 <-> FSMC_D15 | PE11 <-> FSMC_D8 | PF12 <-> FSMC_A6 | PG9 <-> FSMC_NE2 |
+ | PD11 <-> FSMC_A16 | PE12 <-> FSMC_D9 | PF13 <-> FSMC_A7 |------------------+
+ | PD12 <-> FSMC_A17 | PE13 <-> FSMC_D10 | PF14 <-> FSMC_A8 |
+ | PD14 <-> FSMC_D0 | PE14 <-> FSMC_D11 | PF15 <-> FSMC_A9 |
+ | PD15 <-> FSMC_D1 | PE15 <-> FSMC_D12 |------------------+
+ +-------------------+--------------------+
+*/
+ /* Enable GPIOD, GPIOE, GPIOF and GPIOG interface clock */
+ RCC->AHB1ENR = 0x00000078;
+
+ /* Connect PDx pins to FSMC Alternate function */
+ GPIOD->AFR[0] = 0x00cc00cc;
+ GPIOD->AFR[1] = 0xcc0ccccc;
+ /* Configure PDx pins in Alternate function mode */
+ GPIOD->MODER = 0xa2aa0a0a;
+ /* Configure PDx pins speed to 100 MHz */
+ GPIOD->OSPEEDR = 0xf3ff0f0f;
+ /* Configure PDx pins Output type to push-pull */
+ GPIOD->OTYPER = 0x00000000;
+ /* No pull-up, pull-down for PDx pins */
+ GPIOD->PUPDR = 0x00000000;
+
+ /* Connect PEx pins to FSMC Alternate function */
+ GPIOE->AFR[0] = 0xc00000cc;
+ GPIOE->AFR[1] = 0xcccccccc;
+ /* Configure PEx pins in Alternate function mode */
+ GPIOE->MODER = 0xaaaa800a;
+ /* Configure PEx pins speed to 100 MHz */
+ GPIOE->OSPEEDR = 0xffffc00f;
+ /* Configure PEx pins Output type to push-pull */
+ GPIOE->OTYPER = 0x00000000;
+ /* No pull-up, pull-down for PEx pins */
+ GPIOE->PUPDR = 0x00000000;
+
+ /* Connect PFx pins to FSMC Alternate function */
+ GPIOF->AFR[0] = 0x00cccccc;
+ GPIOF->AFR[1] = 0xcccc0000;
+ /* Configure PFx pins in Alternate function mode */
+ GPIOF->MODER = 0xaa000aaa;
+ /* Configure PFx pins speed to 100 MHz */
+ GPIOF->OSPEEDR = 0xff000fff;
+ /* Configure PFx pins Output type to push-pull */
+ GPIOF->OTYPER = 0x00000000;
+ /* No pull-up, pull-down for PFx pins */
+ GPIOF->PUPDR = 0x00000000;
+
+ /* Connect PGx pins to FSMC Alternate function */
+ GPIOG->AFR[0] = 0x00cccccc;
+ GPIOG->AFR[1] = 0x000000c0;
+ /* Configure PGx pins in Alternate function mode */
+ GPIOG->MODER = 0x00080aaa;
+ /* Configure PGx pins speed to 100 MHz */
+ GPIOG->OSPEEDR = 0x000c0fff;
+ /* Configure PGx pins Output type to push-pull */
+ GPIOG->OTYPER = 0x00000000;
+ /* No pull-up, pull-down for PGx pins */
+ GPIOG->PUPDR = 0x00000000;
+
+/*-- FSMC Configuration ------------------------------------------------------*/
+ /* Enable the FSMC interface clock */
+ RCC->AHB3ENR = 0x00000001;
+
+ /* Configure and enable Bank1_SRAM2 */
+ FSMC_Bank1->BTCR[2] = 0x00001015;
+ FSMC_Bank1->BTCR[3] = 0x00010400;
+ FSMC_Bank1E->BWTR[2] = 0x0fffffff;
+/*
+ Bank1_SRAM2 is configured as follow:
+
+ p.FSMC_AddressSetupTime = 0;
+ p.FSMC_AddressHoldTime = 0;
+ p.FSMC_DataSetupTime = 4;
+ p.FSMC_BusTurnAroundDuration = 1;
+ p.FSMC_CLKDivision = 0;
+ p.FSMC_DataLatency = 0;
+ p.FSMC_AccessMode = FSMC_AccessMode_A;
+
+ FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM2;
+ FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable;
+ FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_PSRAM;
+ FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b;
+ FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable;
+ FSMC_NORSRAMInitStructure.FSMC_AsynchronousWait = FSMC_AsynchronousWait_Disable;
+ FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;
+ FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable;
+ FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState;
+ FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable;
+ FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable;
+ FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable;
+ FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable;
+ FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &p;
+ FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &p;
+*/
+
+}
+#endif /* DATA_IN_ExtSRAM */
+
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/SPARK_Platform/MCU/STM32F2xx/CMSIS/Include/arm_common_tables.h b/SPARK_Platform/MCU/STM32F2xx/CMSIS/Include/arm_common_tables.h
new file mode 100644
index 0000000..7245c4f
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/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/SPARK_Platform/MCU/STM32F2xx/CMSIS/Include/arm_math.h b/SPARK_Platform/MCU/STM32F2xx/CMSIS/Include/arm_math.h
new file mode 100644
index 0000000..ffa03b6
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/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/SPARK_Platform/MCU/STM32F2xx/CMSIS/Include/core_cm0.h b/SPARK_Platform/MCU/STM32F2xx/CMSIS/Include/core_cm0.h
new file mode 100644
index 0000000..9d7a19f
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/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/SPARK_Platform/MCU/STM32F2xx/CMSIS/Include/core_cm3.h b/SPARK_Platform/MCU/STM32F2xx/CMSIS/Include/core_cm3.h
new file mode 100644
index 0000000..1c68818
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/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/SPARK_Platform/MCU/STM32F2xx/CMSIS/Include/core_cm4.h b/SPARK_Platform/MCU/STM32F2xx/CMSIS/Include/core_cm4.h
new file mode 100644
index 0000000..bf022ba
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/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/SPARK_Platform/MCU/STM32F2xx/CMSIS/Include/core_cm4_simd.h b/SPARK_Platform/MCU/STM32F2xx/CMSIS/Include/core_cm4_simd.h
new file mode 100644
index 0000000..e7b6765
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/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/SPARK_Platform/MCU/STM32F2xx/CMSIS/Include/core_cmFunc.h b/SPARK_Platform/MCU/STM32F2xx/CMSIS/Include/core_cmFunc.h
new file mode 100644
index 0000000..88819f9
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/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/SPARK_Platform/MCU/STM32F2xx/CMSIS/Include/core_cmInstr.h b/SPARK_Platform/MCU/STM32F2xx/CMSIS/Include/core_cmInstr.h
new file mode 100644
index 0000000..78d2ef8
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/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/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/inc/misc.h b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/inc/misc.h
new file mode 100644
index 0000000..ff3f154
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/inc/misc.h
@@ -0,0 +1,178 @@
+/**
+ ******************************************************************************
+ * @file misc.h
+ * @author MCD Application Team
+ * @version V1.1.2
+ * @date 05-March-2012
+ * @brief This file contains all the functions prototypes for the miscellaneous
+ * firmware library functions (add-on to CMSIS 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.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __MISC_H
+#define __MISC_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f2xx.h"
+
+/** @addtogroup STM32F2xx_StdPeriph_Driver
+ * @{
+ */
+
+/** @addtogroup MISC
+ * @{
+ */
+
+/* Exported types ------------------------------------------------------------*/
+
+/**
+ * @brief NVIC Init Structure definition
+ */
+
+typedef struct
+{
+ uint8_t NVIC_IRQChannel; /*!< Specifies the IRQ channel to be enabled or disabled.
+ This parameter can be an enumerator of @ref IRQn_Type
+ enumeration (For the complete STM32 Devices IRQ Channels
+ list, please refer to stm32f2xx.h file) */
+
+ uint8_t NVIC_IRQChannelPreemptionPriority; /*!< Specifies the pre-emption priority for the IRQ channel
+ specified in NVIC_IRQChannel. This parameter can be a value
+ between 0 and 15 as described in the table @ref MISC_NVIC_Priority_Table
+ A lower priority value indicates a higher priority */
+
+ uint8_t NVIC_IRQChannelSubPriority; /*!< Specifies the subpriority level for the IRQ channel specified
+ in NVIC_IRQChannel. This parameter can be a value
+ between 0 and 15 as described in the table @ref MISC_NVIC_Priority_Table
+ A lower priority value indicates a higher priority */
+
+ FunctionalState NVIC_IRQChannelCmd; /*!< Specifies whether the IRQ channel defined in NVIC_IRQChannel
+ will be enabled or disabled.
+ This parameter can be set either to ENABLE or DISABLE */
+} NVIC_InitTypeDef;
+
+/* Exported constants --------------------------------------------------------*/
+
+/** @defgroup MISC_Exported_Constants
+ * @{
+ */
+
+/** @defgroup MISC_Vector_Table_Base
+ * @{
+ */
+
+#define NVIC_VectTab_RAM ((uint32_t)0x20000000)
+#define NVIC_VectTab_FLASH ((uint32_t)0x08000000)
+#define IS_NVIC_VECTTAB(VECTTAB) (((VECTTAB) == NVIC_VectTab_RAM) || \
+ ((VECTTAB) == NVIC_VectTab_FLASH))
+/**
+ * @}
+ */
+
+/** @defgroup MISC_System_Low_Power
+ * @{
+ */
+
+#define NVIC_LP_SEVONPEND ((uint8_t)0x10)
+#define NVIC_LP_SLEEPDEEP ((uint8_t)0x04)
+#define NVIC_LP_SLEEPONEXIT ((uint8_t)0x02)
+#define IS_NVIC_LP(LP) (((LP) == NVIC_LP_SEVONPEND) || \
+ ((LP) == NVIC_LP_SLEEPDEEP) || \
+ ((LP) == NVIC_LP_SLEEPONEXIT))
+/**
+ * @}
+ */
+
+/** @defgroup MISC_Preemption_Priority_Group
+ * @{
+ */
+
+#define NVIC_PriorityGroup_0 ((uint32_t)0x700) /*!< 0 bits for pre-emption priority
+ 4 bits for subpriority */
+#define NVIC_PriorityGroup_1 ((uint32_t)0x600) /*!< 1 bits for pre-emption priority
+ 3 bits for subpriority */
+#define NVIC_PriorityGroup_2 ((uint32_t)0x500) /*!< 2 bits for pre-emption priority
+ 2 bits for subpriority */
+#define NVIC_PriorityGroup_3 ((uint32_t)0x400) /*!< 3 bits for pre-emption priority
+ 1 bits for subpriority */
+#define NVIC_PriorityGroup_4 ((uint32_t)0x300) /*!< 4 bits for pre-emption priority
+ 0 bits for subpriority */
+
+#define IS_NVIC_PRIORITY_GROUP(GROUP) (((GROUP) == NVIC_PriorityGroup_0) || \
+ ((GROUP) == NVIC_PriorityGroup_1) || \
+ ((GROUP) == NVIC_PriorityGroup_2) || \
+ ((GROUP) == NVIC_PriorityGroup_3) || \
+ ((GROUP) == NVIC_PriorityGroup_4))
+
+#define IS_NVIC_PREEMPTION_PRIORITY(PRIORITY) ((PRIORITY) < 0x10)
+
+#define IS_NVIC_SUB_PRIORITY(PRIORITY) ((PRIORITY) < 0x10)
+
+#define IS_NVIC_OFFSET(OFFSET) ((OFFSET) < 0x000FFFFF)
+
+/**
+ * @}
+ */
+
+/** @defgroup MISC_SysTick_clock_source
+ * @{
+ */
+
+#define SysTick_CLKSource_HCLK_Div8 ((uint32_t)0xFFFFFFFB)
+#define SysTick_CLKSource_HCLK ((uint32_t)0x00000004)
+#define IS_SYSTICK_CLK_SOURCE(SOURCE) (((SOURCE) == SysTick_CLKSource_HCLK) || \
+ ((SOURCE) == SysTick_CLKSource_HCLK_Div8))
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions --------------------------------------------------------*/
+
+void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup);
+void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct);
+void NVIC_SetVectorTable(uint32_t NVIC_VectTab, uint32_t Offset);
+void NVIC_SystemLPConfig(uint8_t LowPowerMode, FunctionalState NewState);
+void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __MISC_H */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/inc/stm32f2xx_adc.h b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/inc/stm32f2xx_adc.h
new file mode 100644
index 0000000..ef3923a
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/inc/stm32f2xx_adc.h
@@ -0,0 +1,649 @@
+/**
+ ******************************************************************************
+ * @file stm32f2xx_adc.h
+ * @author MCD Application Team
+ * @version V1.1.2
+ * @date 05-March-2012
+ * @brief This file contains all the functions prototypes for the ADC firmware
+ * 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 __STM32F2xx_ADC_H
+#define __STM32F2xx_ADC_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f2xx.h"
+
+/** @addtogroup STM32F2xx_StdPeriph_Driver
+ * @{
+ */
+
+/** @addtogroup ADC
+ * @{
+ */
+
+/* Exported types ------------------------------------------------------------*/
+
+/**
+ * @brief ADC Init structure definition
+ */
+typedef struct
+{
+ uint32_t ADC_Resolution; /*!< Configures the ADC resolution dual mode.
+ This parameter can be a value of @ref ADC_resolution */
+ FunctionalState ADC_ScanConvMode; /*!< Specifies whether the conversion
+ is performed in Scan (multichannels)
+ or Single (one channel) mode.
+ This parameter can be set to ENABLE or DISABLE */
+ FunctionalState ADC_ContinuousConvMode; /*!< Specifies whether the conversion
+ is performed in Continuous or Single mode.
+ This parameter can be set to ENABLE or DISABLE. */
+ uint32_t ADC_ExternalTrigConvEdge; /*!< Select the external trigger edge and
+ enable the trigger of a regular group.
+ This parameter can be a value of
+ @ref ADC_external_trigger_edge_for_regular_channels_conversion */
+ uint32_t ADC_ExternalTrigConv; /*!< Select the external event used to trigger
+ the start of conversion of a regular group.
+ This parameter can be a value of
+ @ref ADC_extrenal_trigger_sources_for_regular_channels_conversion */
+ uint32_t ADC_DataAlign; /*!< Specifies whether the ADC data alignment
+ is left or right. This parameter can be
+ a value of @ref ADC_data_align */
+ uint8_t ADC_NbrOfConversion; /*!< Specifies the number of ADC conversions
+ that will be done using the sequencer for
+ regular channel group.
+ This parameter must range from 1 to 16. */
+}ADC_InitTypeDef;
+
+/**
+ * @brief ADC Common Init structure definition
+ */
+typedef struct
+{
+ uint32_t ADC_Mode; /*!< Configures the ADC to operate in
+ independent or multi mode.
+ This parameter can be a value of @ref ADC_Common_mode */
+ uint32_t ADC_Prescaler; /*!< Select the frequency of the clock
+ to the ADC. The clock is common for all the ADCs.
+ This parameter can be a value of @ref ADC_Prescaler */
+ uint32_t ADC_DMAAccessMode; /*!< Configures the Direct memory access
+ mode for multi ADC mode.
+ This parameter can be a value of
+ @ref ADC_Direct_memory_access_mode_for_multi_mode */
+ uint32_t ADC_TwoSamplingDelay; /*!< Configures the Delay between 2 sampling phases.
+ This parameter can be a value of
+ @ref ADC_delay_between_2_sampling_phases */
+
+}ADC_CommonInitTypeDef;
+
+
+/* Exported constants --------------------------------------------------------*/
+
+/** @defgroup ADC_Exported_Constants
+ * @{
+ */
+#define IS_ADC_ALL_PERIPH(PERIPH) (((PERIPH) == ADC1) || \
+ ((PERIPH) == ADC2) || \
+ ((PERIPH) == ADC3))
+
+/** @defgroup ADC_Common_mode
+ * @{
+ */
+#define ADC_Mode_Independent ((uint32_t)0x00000000)
+#define ADC_DualMode_RegSimult_InjecSimult ((uint32_t)0x00000001)
+#define ADC_DualMode_RegSimult_AlterTrig ((uint32_t)0x00000002)
+#define ADC_DualMode_InjecSimult ((uint32_t)0x00000005)
+#define ADC_DualMode_RegSimult ((uint32_t)0x00000006)
+#define ADC_DualMode_Interl ((uint32_t)0x00000007)
+#define ADC_DualMode_AlterTrig ((uint32_t)0x00000009)
+#define ADC_TripleMode_RegSimult_InjecSimult ((uint32_t)0x00000011)
+#define ADC_TripleMode_RegSimult_AlterTrig ((uint32_t)0x00000012)
+#define ADC_TripleMode_InjecSimult ((uint32_t)0x00000015)
+#define ADC_TripleMode_RegSimult ((uint32_t)0x00000016)
+#define ADC_TripleMode_Interl ((uint32_t)0x00000017)
+#define ADC_TripleMode_AlterTrig ((uint32_t)0x00000019)
+#define IS_ADC_MODE(MODE) (((MODE) == ADC_Mode_Independent) || \
+ ((MODE) == ADC_DualMode_RegSimult_InjecSimult) || \
+ ((MODE) == ADC_DualMode_RegSimult_AlterTrig) || \
+ ((MODE) == ADC_DualMode_InjecSimult) || \
+ ((MODE) == ADC_DualMode_RegSimult) || \
+ ((MODE) == ADC_DualMode_Interl) || \
+ ((MODE) == ADC_DualMode_AlterTrig) || \
+ ((MODE) == ADC_TripleMode_RegSimult_InjecSimult) || \
+ ((MODE) == ADC_TripleMode_RegSimult_AlterTrig) || \
+ ((MODE) == ADC_TripleMode_InjecSimult) || \
+ ((MODE) == ADC_TripleMode_RegSimult) || \
+ ((MODE) == ADC_TripleMode_Interl) || \
+ ((MODE) == ADC_TripleMode_AlterTrig))
+/**
+ * @}
+ */
+
+
+/** @defgroup ADC_Prescaler
+ * @{
+ */
+#define ADC_Prescaler_Div2 ((uint32_t)0x00000000)
+#define ADC_Prescaler_Div4 ((uint32_t)0x00010000)
+#define ADC_Prescaler_Div6 ((uint32_t)0x00020000)
+#define ADC_Prescaler_Div8 ((uint32_t)0x00030000)
+#define IS_ADC_PRESCALER(PRESCALER) (((PRESCALER) == ADC_Prescaler_Div2) || \
+ ((PRESCALER) == ADC_Prescaler_Div4) || \
+ ((PRESCALER) == ADC_Prescaler_Div6) || \
+ ((PRESCALER) == ADC_Prescaler_Div8))
+/**
+ * @}
+ */
+
+
+/** @defgroup ADC_Direct_memory_access_mode_for_multi_mode
+ * @{
+ */
+#define ADC_DMAAccessMode_Disabled ((uint32_t)0x00000000) /* DMA mode disabled */
+#define ADC_DMAAccessMode_1 ((uint32_t)0x00004000) /* DMA mode 1 enabled (2 / 3 half-words one by one - 1 then 2 then 3)*/
+#define ADC_DMAAccessMode_2 ((uint32_t)0x00008000) /* DMA mode 2 enabled (2 / 3 half-words by pairs - 2&1 then 1&3 then 3&2)*/
+#define ADC_DMAAccessMode_3 ((uint32_t)0x0000C000) /* DMA mode 3 enabled (2 / 3 bytes by pairs - 2&1 then 1&3 then 3&2) */
+#define IS_ADC_DMA_ACCESS_MODE(MODE) (((MODE) == ADC_DMAAccessMode_Disabled) || \
+ ((MODE) == ADC_DMAAccessMode_1) || \
+ ((MODE) == ADC_DMAAccessMode_2) || \
+ ((MODE) == ADC_DMAAccessMode_3))
+
+/**
+ * @}
+ */
+
+
+/** @defgroup ADC_delay_between_2_sampling_phases
+ * @{
+ */
+#define ADC_TwoSamplingDelay_5Cycles ((uint32_t)0x00000000)
+#define ADC_TwoSamplingDelay_6Cycles ((uint32_t)0x00000100)
+#define ADC_TwoSamplingDelay_7Cycles ((uint32_t)0x00000200)
+#define ADC_TwoSamplingDelay_8Cycles ((uint32_t)0x00000300)
+#define ADC_TwoSamplingDelay_9Cycles ((uint32_t)0x00000400)
+#define ADC_TwoSamplingDelay_10Cycles ((uint32_t)0x00000500)
+#define ADC_TwoSamplingDelay_11Cycles ((uint32_t)0x00000600)
+#define ADC_TwoSamplingDelay_12Cycles ((uint32_t)0x00000700)
+#define ADC_TwoSamplingDelay_13Cycles ((uint32_t)0x00000800)
+#define ADC_TwoSamplingDelay_14Cycles ((uint32_t)0x00000900)
+#define ADC_TwoSamplingDelay_15Cycles ((uint32_t)0x00000A00)
+#define ADC_TwoSamplingDelay_16Cycles ((uint32_t)0x00000B00)
+#define ADC_TwoSamplingDelay_17Cycles ((uint32_t)0x00000C00)
+#define ADC_TwoSamplingDelay_18Cycles ((uint32_t)0x00000D00)
+#define ADC_TwoSamplingDelay_19Cycles ((uint32_t)0x00000E00)
+#define ADC_TwoSamplingDelay_20Cycles ((uint32_t)0x00000F00)
+#define IS_ADC_SAMPLING_DELAY(DELAY) (((DELAY) == ADC_TwoSamplingDelay_5Cycles) || \
+ ((DELAY) == ADC_TwoSamplingDelay_6Cycles) || \
+ ((DELAY) == ADC_TwoSamplingDelay_7Cycles) || \
+ ((DELAY) == ADC_TwoSamplingDelay_8Cycles) || \
+ ((DELAY) == ADC_TwoSamplingDelay_9Cycles) || \
+ ((DELAY) == ADC_TwoSamplingDelay_10Cycles) || \
+ ((DELAY) == ADC_TwoSamplingDelay_11Cycles) || \
+ ((DELAY) == ADC_TwoSamplingDelay_12Cycles) || \
+ ((DELAY) == ADC_TwoSamplingDelay_13Cycles) || \
+ ((DELAY) == ADC_TwoSamplingDelay_14Cycles) || \
+ ((DELAY) == ADC_TwoSamplingDelay_15Cycles) || \
+ ((DELAY) == ADC_TwoSamplingDelay_16Cycles) || \
+ ((DELAY) == ADC_TwoSamplingDelay_17Cycles) || \
+ ((DELAY) == ADC_TwoSamplingDelay_18Cycles) || \
+ ((DELAY) == ADC_TwoSamplingDelay_19Cycles) || \
+ ((DELAY) == ADC_TwoSamplingDelay_20Cycles))
+
+/**
+ * @}
+ */
+
+
+/** @defgroup ADC_resolution
+ * @{
+ */
+#define ADC_Resolution_12b ((uint32_t)0x00000000)
+#define ADC_Resolution_10b ((uint32_t)0x01000000)
+#define ADC_Resolution_8b ((uint32_t)0x02000000)
+#define ADC_Resolution_6b ((uint32_t)0x03000000)
+#define IS_ADC_RESOLUTION(RESOLUTION) (((RESOLUTION) == ADC_Resolution_12b) || \
+ ((RESOLUTION) == ADC_Resolution_10b) || \
+ ((RESOLUTION) == ADC_Resolution_8b) || \
+ ((RESOLUTION) == ADC_Resolution_6b))
+
+/**
+ * @}
+ */
+
+
+/** @defgroup ADC_external_trigger_edge_for_regular_channels_conversion
+ * @{
+ */
+#define ADC_ExternalTrigConvEdge_None ((uint32_t)0x00000000)
+#define ADC_ExternalTrigConvEdge_Rising ((uint32_t)0x10000000)
+#define ADC_ExternalTrigConvEdge_Falling ((uint32_t)0x20000000)
+#define ADC_ExternalTrigConvEdge_RisingFalling ((uint32_t)0x30000000)
+#define IS_ADC_EXT_TRIG_EDGE(EDGE) (((EDGE) == ADC_ExternalTrigConvEdge_None) || \
+ ((EDGE) == ADC_ExternalTrigConvEdge_Rising) || \
+ ((EDGE) == ADC_ExternalTrigConvEdge_Falling) || \
+ ((EDGE) == ADC_ExternalTrigConvEdge_RisingFalling))
+/**
+ * @}
+ */
+
+
+/** @defgroup ADC_extrenal_trigger_sources_for_regular_channels_conversion
+ * @{
+ */
+#define ADC_ExternalTrigConv_T1_CC1 ((uint32_t)0x00000000)
+#define ADC_ExternalTrigConv_T1_CC2 ((uint32_t)0x01000000)
+#define ADC_ExternalTrigConv_T1_CC3 ((uint32_t)0x02000000)
+#define ADC_ExternalTrigConv_T2_CC2 ((uint32_t)0x03000000)
+#define ADC_ExternalTrigConv_T2_CC3 ((uint32_t)0x04000000)
+#define ADC_ExternalTrigConv_T2_CC4 ((uint32_t)0x05000000)
+#define ADC_ExternalTrigConv_T2_TRGO ((uint32_t)0x06000000)
+#define ADC_ExternalTrigConv_T3_CC1 ((uint32_t)0x07000000)
+#define ADC_ExternalTrigConv_T3_TRGO ((uint32_t)0x08000000)
+#define ADC_ExternalTrigConv_T4_CC4 ((uint32_t)0x09000000)
+#define ADC_ExternalTrigConv_T5_CC1 ((uint32_t)0x0A000000)
+#define ADC_ExternalTrigConv_T5_CC2 ((uint32_t)0x0B000000)
+#define ADC_ExternalTrigConv_T5_CC3 ((uint32_t)0x0C000000)
+#define ADC_ExternalTrigConv_T8_CC1 ((uint32_t)0x0D000000)
+#define ADC_ExternalTrigConv_T8_TRGO ((uint32_t)0x0E000000)
+#define ADC_ExternalTrigConv_Ext_IT11 ((uint32_t)0x0F000000)
+#define IS_ADC_EXT_TRIG(REGTRIG) (((REGTRIG) == ADC_ExternalTrigConv_T1_CC1) || \
+ ((REGTRIG) == ADC_ExternalTrigConv_T1_CC2) || \
+ ((REGTRIG) == ADC_ExternalTrigConv_T1_CC3) || \
+ ((REGTRIG) == ADC_ExternalTrigConv_T2_CC2) || \
+ ((REGTRIG) == ADC_ExternalTrigConv_T2_CC3) || \
+ ((REGTRIG) == ADC_ExternalTrigConv_T2_CC4) || \
+ ((REGTRIG) == ADC_ExternalTrigConv_T2_TRGO) || \
+ ((REGTRIG) == ADC_ExternalTrigConv_T3_CC1) || \
+ ((REGTRIG) == ADC_ExternalTrigConv_T3_TRGO) || \
+ ((REGTRIG) == ADC_ExternalTrigConv_T4_CC4) || \
+ ((REGTRIG) == ADC_ExternalTrigConv_T5_CC1) || \
+ ((REGTRIG) == ADC_ExternalTrigConv_T5_CC2) || \
+ ((REGTRIG) == ADC_ExternalTrigConv_T5_CC3) || \
+ ((REGTRIG) == ADC_ExternalTrigConv_T8_CC1) || \
+ ((REGTRIG) == ADC_ExternalTrigConv_T8_TRGO) || \
+ ((REGTRIG) == ADC_ExternalTrigConv_Ext_IT11))
+/**
+ * @}
+ */
+
+
+/** @defgroup ADC_data_align
+ * @{
+ */
+#define ADC_DataAlign_Right ((uint32_t)0x00000000)
+#define ADC_DataAlign_Left ((uint32_t)0x00000800)
+#define IS_ADC_DATA_ALIGN(ALIGN) (((ALIGN) == ADC_DataAlign_Right) || \
+ ((ALIGN) == ADC_DataAlign_Left))
+/**
+ * @}
+ */
+
+
+/** @defgroup ADC_channels
+ * @{
+ */
+#define ADC_Channel_0 ((uint8_t)0x00)
+#define ADC_Channel_1 ((uint8_t)0x01)
+#define ADC_Channel_2 ((uint8_t)0x02)
+#define ADC_Channel_3 ((uint8_t)0x03)
+#define ADC_Channel_4 ((uint8_t)0x04)
+#define ADC_Channel_5 ((uint8_t)0x05)
+#define ADC_Channel_6 ((uint8_t)0x06)
+#define ADC_Channel_7 ((uint8_t)0x07)
+#define ADC_Channel_8 ((uint8_t)0x08)
+#define ADC_Channel_9 ((uint8_t)0x09)
+#define ADC_Channel_10 ((uint8_t)0x0A)
+#define ADC_Channel_11 ((uint8_t)0x0B)
+#define ADC_Channel_12 ((uint8_t)0x0C)
+#define ADC_Channel_13 ((uint8_t)0x0D)
+#define ADC_Channel_14 ((uint8_t)0x0E)
+#define ADC_Channel_15 ((uint8_t)0x0F)
+#define ADC_Channel_16 ((uint8_t)0x10)
+#define ADC_Channel_17 ((uint8_t)0x11)
+#define ADC_Channel_18 ((uint8_t)0x12)
+
+#define ADC_Channel_TempSensor ((uint8_t)ADC_Channel_16)
+#define ADC_Channel_Vrefint ((uint8_t)ADC_Channel_17)
+#define ADC_Channel_Vbat ((uint8_t)ADC_Channel_18)
+
+#define IS_ADC_CHANNEL(CHANNEL) (((CHANNEL) == ADC_Channel_0) || \
+ ((CHANNEL) == ADC_Channel_1) || \
+ ((CHANNEL) == ADC_Channel_2) || \
+ ((CHANNEL) == ADC_Channel_3) || \
+ ((CHANNEL) == ADC_Channel_4) || \
+ ((CHANNEL) == ADC_Channel_5) || \
+ ((CHANNEL) == ADC_Channel_6) || \
+ ((CHANNEL) == ADC_Channel_7) || \
+ ((CHANNEL) == ADC_Channel_8) || \
+ ((CHANNEL) == ADC_Channel_9) || \
+ ((CHANNEL) == ADC_Channel_10) || \
+ ((CHANNEL) == ADC_Channel_11) || \
+ ((CHANNEL) == ADC_Channel_12) || \
+ ((CHANNEL) == ADC_Channel_13) || \
+ ((CHANNEL) == ADC_Channel_14) || \
+ ((CHANNEL) == ADC_Channel_15) || \
+ ((CHANNEL) == ADC_Channel_16) || \
+ ((CHANNEL) == ADC_Channel_17) || \
+ ((CHANNEL) == ADC_Channel_18))
+/**
+ * @}
+ */
+
+
+/** @defgroup ADC_sampling_times
+ * @{
+ */
+#define ADC_SampleTime_3Cycles ((uint8_t)0x00)
+#define ADC_SampleTime_15Cycles ((uint8_t)0x01)
+#define ADC_SampleTime_28Cycles ((uint8_t)0x02)
+#define ADC_SampleTime_56Cycles ((uint8_t)0x03)
+#define ADC_SampleTime_84Cycles ((uint8_t)0x04)
+#define ADC_SampleTime_112Cycles ((uint8_t)0x05)
+#define ADC_SampleTime_144Cycles ((uint8_t)0x06)
+#define ADC_SampleTime_480Cycles ((uint8_t)0x07)
+#define IS_ADC_SAMPLE_TIME(TIME) (((TIME) == ADC_SampleTime_3Cycles) || \
+ ((TIME) == ADC_SampleTime_15Cycles) || \
+ ((TIME) == ADC_SampleTime_28Cycles) || \
+ ((TIME) == ADC_SampleTime_56Cycles) || \
+ ((TIME) == ADC_SampleTime_84Cycles) || \
+ ((TIME) == ADC_SampleTime_112Cycles) || \
+ ((TIME) == ADC_SampleTime_144Cycles) || \
+ ((TIME) == ADC_SampleTime_480Cycles))
+/**
+ * @}
+ */
+
+
+/** @defgroup ADC_external_trigger_edge_for_injected_channels_conversion
+ * @{
+ */
+#define ADC_ExternalTrigInjecConvEdge_None ((uint32_t)0x00000000)
+#define ADC_ExternalTrigInjecConvEdge_Rising ((uint32_t)0x00100000)
+#define ADC_ExternalTrigInjecConvEdge_Falling ((uint32_t)0x00200000)
+#define ADC_ExternalTrigInjecConvEdge_RisingFalling ((uint32_t)0x00300000)
+#define IS_ADC_EXT_INJEC_TRIG_EDGE(EDGE) (((EDGE) == ADC_ExternalTrigInjecConvEdge_None) || \
+ ((EDGE) == ADC_ExternalTrigInjecConvEdge_Rising) || \
+ ((EDGE) == ADC_ExternalTrigInjecConvEdge_Falling) || \
+ ((EDGE) == ADC_ExternalTrigInjecConvEdge_RisingFalling))
+
+/**
+ * @}
+ */
+
+
+/** @defgroup ADC_extrenal_trigger_sources_for_injected_channels_conversion
+ * @{
+ */
+#define ADC_ExternalTrigInjecConv_T1_CC4 ((uint32_t)0x00000000)
+#define ADC_ExternalTrigInjecConv_T1_TRGO ((uint32_t)0x00010000)
+#define ADC_ExternalTrigInjecConv_T2_CC1 ((uint32_t)0x00020000)
+#define ADC_ExternalTrigInjecConv_T2_TRGO ((uint32_t)0x00030000)
+#define ADC_ExternalTrigInjecConv_T3_CC2 ((uint32_t)0x00040000)
+#define ADC_ExternalTrigInjecConv_T3_CC4 ((uint32_t)0x00050000)
+#define ADC_ExternalTrigInjecConv_T4_CC1 ((uint32_t)0x00060000)
+#define ADC_ExternalTrigInjecConv_T4_CC2 ((uint32_t)0x00070000)
+#define ADC_ExternalTrigInjecConv_T4_CC3 ((uint32_t)0x00080000)
+#define ADC_ExternalTrigInjecConv_T4_TRGO ((uint32_t)0x00090000)
+#define ADC_ExternalTrigInjecConv_T5_CC4 ((uint32_t)0x000A0000)
+#define ADC_ExternalTrigInjecConv_T5_TRGO ((uint32_t)0x000B0000)
+#define ADC_ExternalTrigInjecConv_T8_CC2 ((uint32_t)0x000C0000)
+#define ADC_ExternalTrigInjecConv_T8_CC3 ((uint32_t)0x000D0000)
+#define ADC_ExternalTrigInjecConv_T8_CC4 ((uint32_t)0x000E0000)
+#define ADC_ExternalTrigInjecConv_Ext_IT15 ((uint32_t)0x000F0000)
+#define IS_ADC_EXT_INJEC_TRIG(INJTRIG) (((INJTRIG) == ADC_ExternalTrigInjecConv_T1_CC4) || \
+ ((INJTRIG) == ADC_ExternalTrigInjecConv_T1_TRGO) || \
+ ((INJTRIG) == ADC_ExternalTrigInjecConv_T2_CC1) || \
+ ((INJTRIG) == ADC_ExternalTrigInjecConv_T2_TRGO) || \
+ ((INJTRIG) == ADC_ExternalTrigInjecConv_T3_CC2) || \
+ ((INJTRIG) == ADC_ExternalTrigInjecConv_T3_CC4) || \
+ ((INJTRIG) == ADC_ExternalTrigInjecConv_T4_CC1) || \
+ ((INJTRIG) == ADC_ExternalTrigInjecConv_T4_CC2) || \
+ ((INJTRIG) == ADC_ExternalTrigInjecConv_T4_CC3) || \
+ ((INJTRIG) == ADC_ExternalTrigInjecConv_T4_TRGO) || \
+ ((INJTRIG) == ADC_ExternalTrigInjecConv_T5_CC4) || \
+ ((INJTRIG) == ADC_ExternalTrigInjecConv_T5_TRGO) || \
+ ((INJTRIG) == ADC_ExternalTrigInjecConv_T8_CC2) || \
+ ((INJTRIG) == ADC_ExternalTrigInjecConv_T8_CC3) || \
+ ((INJTRIG) == ADC_ExternalTrigInjecConv_T8_CC4) || \
+ ((INJTRIG) == ADC_ExternalTrigInjecConv_Ext_IT15))
+/**
+ * @}
+ */
+
+
+/** @defgroup ADC_injected_channel_selection
+ * @{
+ */
+#define ADC_InjectedChannel_1 ((uint8_t)0x14)
+#define ADC_InjectedChannel_2 ((uint8_t)0x18)
+#define ADC_InjectedChannel_3 ((uint8_t)0x1C)
+#define ADC_InjectedChannel_4 ((uint8_t)0x20)
+#define IS_ADC_INJECTED_CHANNEL(CHANNEL) (((CHANNEL) == ADC_InjectedChannel_1) || \
+ ((CHANNEL) == ADC_InjectedChannel_2) || \
+ ((CHANNEL) == ADC_InjectedChannel_3) || \
+ ((CHANNEL) == ADC_InjectedChannel_4))
+/**
+ * @}
+ */
+
+
+/** @defgroup ADC_analog_watchdog_selection
+ * @{
+ */
+#define ADC_AnalogWatchdog_SingleRegEnable ((uint32_t)0x00800200)
+#define ADC_AnalogWatchdog_SingleInjecEnable ((uint32_t)0x00400200)
+#define ADC_AnalogWatchdog_SingleRegOrInjecEnable ((uint32_t)0x00C00200)
+#define ADC_AnalogWatchdog_AllRegEnable ((uint32_t)0x00800000)
+#define ADC_AnalogWatchdog_AllInjecEnable ((uint32_t)0x00400000)
+#define ADC_AnalogWatchdog_AllRegAllInjecEnable ((uint32_t)0x00C00000)
+#define ADC_AnalogWatchdog_None ((uint32_t)0x00000000)
+#define IS_ADC_ANALOG_WATCHDOG(WATCHDOG) (((WATCHDOG) == ADC_AnalogWatchdog_SingleRegEnable) || \
+ ((WATCHDOG) == ADC_AnalogWatchdog_SingleInjecEnable) || \
+ ((WATCHDOG) == ADC_AnalogWatchdog_SingleRegOrInjecEnable) || \
+ ((WATCHDOG) == ADC_AnalogWatchdog_AllRegEnable) || \
+ ((WATCHDOG) == ADC_AnalogWatchdog_AllInjecEnable) || \
+ ((WATCHDOG) == ADC_AnalogWatchdog_AllRegAllInjecEnable) || \
+ ((WATCHDOG) == ADC_AnalogWatchdog_None))
+/**
+ * @}
+ */
+
+
+/** @defgroup ADC_interrupts_definition
+ * @{
+ */
+#define ADC_IT_EOC ((uint16_t)0x0205)
+#define ADC_IT_AWD ((uint16_t)0x0106)
+#define ADC_IT_JEOC ((uint16_t)0x0407)
+#define ADC_IT_OVR ((uint16_t)0x201A)
+#define IS_ADC_IT(IT) (((IT) == ADC_IT_EOC) || ((IT) == ADC_IT_AWD) || \
+ ((IT) == ADC_IT_JEOC)|| ((IT) == ADC_IT_OVR))
+/**
+ * @}
+ */
+
+
+/** @defgroup ADC_flags_definition
+ * @{
+ */
+#define ADC_FLAG_AWD ((uint8_t)0x01)
+#define ADC_FLAG_EOC ((uint8_t)0x02)
+#define ADC_FLAG_JEOC ((uint8_t)0x04)
+#define ADC_FLAG_JSTRT ((uint8_t)0x08)
+#define ADC_FLAG_STRT ((uint8_t)0x10)
+#define ADC_FLAG_OVR ((uint8_t)0x20)
+
+#define IS_ADC_CLEAR_FLAG(FLAG) ((((FLAG) & (uint8_t)0xC0) == 0x00) && ((FLAG) != 0x00))
+#define IS_ADC_GET_FLAG(FLAG) (((FLAG) == ADC_FLAG_AWD) || \
+ ((FLAG) == ADC_FLAG_EOC) || \
+ ((FLAG) == ADC_FLAG_JEOC) || \
+ ((FLAG)== ADC_FLAG_JSTRT) || \
+ ((FLAG) == ADC_FLAG_STRT) || \
+ ((FLAG)== ADC_FLAG_OVR))
+/**
+ * @}
+ */
+
+
+/** @defgroup ADC_thresholds
+ * @{
+ */
+#define IS_ADC_THRESHOLD(THRESHOLD) ((THRESHOLD) <= 0xFFF)
+/**
+ * @}
+ */
+
+
+/** @defgroup ADC_injected_offset
+ * @{
+ */
+#define IS_ADC_OFFSET(OFFSET) ((OFFSET) <= 0xFFF)
+/**
+ * @}
+ */
+
+
+/** @defgroup ADC_injected_length
+ * @{
+ */
+#define IS_ADC_INJECTED_LENGTH(LENGTH) (((LENGTH) >= 0x1) && ((LENGTH) <= 0x4))
+/**
+ * @}
+ */
+
+
+/** @defgroup ADC_injected_rank
+ * @{
+ */
+#define IS_ADC_INJECTED_RANK(RANK) (((RANK) >= 0x1) && ((RANK) <= 0x4))
+/**
+ * @}
+ */
+
+
+/** @defgroup ADC_regular_length
+ * @{
+ */
+#define IS_ADC_REGULAR_LENGTH(LENGTH) (((LENGTH) >= 0x1) && ((LENGTH) <= 0x10))
+/**
+ * @}
+ */
+
+
+/** @defgroup ADC_regular_rank
+ * @{
+ */
+#define IS_ADC_REGULAR_RANK(RANK) (((RANK) >= 0x1) && ((RANK) <= 0x10))
+/**
+ * @}
+ */
+
+
+/** @defgroup ADC_regular_discontinuous_mode_number
+ * @{
+ */
+#define IS_ADC_REGULAR_DISC_NUMBER(NUMBER) (((NUMBER) >= 0x1) && ((NUMBER) <= 0x8))
+/**
+ * @}
+ */
+
+
+/**
+ * @}
+ */
+
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions --------------------------------------------------------*/
+
+/* Function used to set the ADC configuration to the default reset state *****/
+void ADC_DeInit(void);
+
+/* Initialization and Configuration functions *********************************/
+void ADC_Init(ADC_TypeDef* ADCx, ADC_InitTypeDef* ADC_InitStruct);
+void ADC_StructInit(ADC_InitTypeDef* ADC_InitStruct);
+void ADC_CommonInit(ADC_CommonInitTypeDef* ADC_CommonInitStruct);
+void ADC_CommonStructInit(ADC_CommonInitTypeDef* ADC_CommonInitStruct);
+void ADC_Cmd(ADC_TypeDef* ADCx, FunctionalState NewState);
+
+/* Analog Watchdog configuration functions ************************************/
+void ADC_AnalogWatchdogCmd(ADC_TypeDef* ADCx, uint32_t ADC_AnalogWatchdog);
+void ADC_AnalogWatchdogThresholdsConfig(ADC_TypeDef* ADCx, uint16_t HighThreshold,uint16_t LowThreshold);
+void ADC_AnalogWatchdogSingleChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel);
+
+/* Temperature Sensor, Vrefint and VBAT management functions ******************/
+void ADC_TempSensorVrefintCmd(FunctionalState NewState);
+void ADC_VBATCmd(FunctionalState NewState);
+
+/* Regular Channels Configuration functions ***********************************/
+void ADC_RegularChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime);
+void ADC_SoftwareStartConv(ADC_TypeDef* ADCx);
+FlagStatus ADC_GetSoftwareStartConvStatus(ADC_TypeDef* ADCx);
+void ADC_EOCOnEachRegularChannelCmd(ADC_TypeDef* ADCx, FunctionalState NewState);
+void ADC_ContinuousModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState);
+void ADC_DiscModeChannelCountConfig(ADC_TypeDef* ADCx, uint8_t Number);
+void ADC_DiscModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState);
+uint16_t ADC_GetConversionValue(ADC_TypeDef* ADCx);
+uint32_t ADC_GetMultiModeConversionValue(void);
+
+/* Regular Channels DMA Configuration functions *******************************/
+void ADC_DMACmd(ADC_TypeDef* ADCx, FunctionalState NewState);
+void ADC_DMARequestAfterLastTransferCmd(ADC_TypeDef* ADCx, FunctionalState NewState);
+void ADC_MultiModeDMARequestAfterLastTransferCmd(FunctionalState NewState);
+
+/* Injected channels Configuration functions **********************************/
+void ADC_InjectedChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime);
+void ADC_InjectedSequencerLengthConfig(ADC_TypeDef* ADCx, uint8_t Length);
+void ADC_SetInjectedOffset(ADC_TypeDef* ADCx, uint8_t ADC_InjectedChannel, uint16_t Offset);
+void ADC_ExternalTrigInjectedConvConfig(ADC_TypeDef* ADCx, uint32_t ADC_ExternalTrigInjecConv);
+void ADC_ExternalTrigInjectedConvEdgeConfig(ADC_TypeDef* ADCx, uint32_t ADC_ExternalTrigInjecConvEdge);
+void ADC_SoftwareStartInjectedConv(ADC_TypeDef* ADCx);
+FlagStatus ADC_GetSoftwareStartInjectedConvCmdStatus(ADC_TypeDef* ADCx);
+void ADC_AutoInjectedConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState);
+void ADC_InjectedDiscModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState);
+uint16_t ADC_GetInjectedConversionValue(ADC_TypeDef* ADCx, uint8_t ADC_InjectedChannel);
+
+/* Interrupts and flags management functions **********************************/
+void ADC_ITConfig(ADC_TypeDef* ADCx, uint16_t ADC_IT, FunctionalState NewState);
+FlagStatus ADC_GetFlagStatus(ADC_TypeDef* ADCx, uint8_t ADC_FLAG);
+void ADC_ClearFlag(ADC_TypeDef* ADCx, uint8_t ADC_FLAG);
+ITStatus ADC_GetITStatus(ADC_TypeDef* ADCx, uint16_t ADC_IT);
+void ADC_ClearITPendingBit(ADC_TypeDef* ADCx, uint16_t ADC_IT);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*__STM32F2xx_ADC_H */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/inc/stm32f2xx_can.h b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/inc/stm32f2xx_can.h
new file mode 100644
index 0000000..ba287d7
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/inc/stm32f2xx_can.h
@@ -0,0 +1,644 @@
+/**
+ ******************************************************************************
+ * @file stm32f2xx_can.h
+ * @author MCD Application Team
+ * @version V1.1.2
+ * @date 05-March-2012
+ * @brief This file contains all the functions prototypes for the CAN firmware
+ * 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 __STM32F2xx_CAN_H
+#define __STM32F2xx_CAN_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f2xx.h"
+
+/** @addtogroup STM32F2xx_StdPeriph_Driver
+ * @{
+ */
+
+/** @addtogroup CAN
+ * @{
+ */
+
+/* Exported types ------------------------------------------------------------*/
+
+#define IS_CAN_ALL_PERIPH(PERIPH) (((PERIPH) == CAN1) || \
+ ((PERIPH) == CAN2))
+
+/**
+ * @brief CAN init structure definition
+ */
+typedef struct
+{
+ uint16_t CAN_Prescaler; /*!< Specifies the length of a time quantum.
+ It ranges from 1 to 1024. */
+
+ uint8_t CAN_Mode; /*!< Specifies the CAN operating mode.
+ This parameter can be a value of @ref CAN_operating_mode */
+
+ uint8_t CAN_SJW; /*!< Specifies the maximum number of time quanta
+ the CAN hardware is allowed to lengthen or
+ shorten a bit to perform resynchronization.
+ This parameter can be a value of @ref CAN_synchronisation_jump_width */
+
+ uint8_t CAN_BS1; /*!< Specifies the number of time quanta in Bit
+ Segment 1. This parameter can be a value of
+ @ref CAN_time_quantum_in_bit_segment_1 */
+
+ uint8_t CAN_BS2; /*!< Specifies the number of time quanta in Bit Segment 2.
+ This parameter can be a value of @ref CAN_time_quantum_in_bit_segment_2 */
+
+ FunctionalState CAN_TTCM; /*!< Enable or disable the time triggered communication mode.
+ This parameter can be set either to ENABLE or DISABLE. */
+
+ FunctionalState CAN_ABOM; /*!< Enable or disable the automatic bus-off management.
+ This parameter can be set either to ENABLE or DISABLE. */
+
+ FunctionalState CAN_AWUM; /*!< Enable or disable the automatic wake-up mode.
+ This parameter can be set either to ENABLE or DISABLE. */
+
+ FunctionalState CAN_NART; /*!< Enable or disable the non-automatic retransmission mode.
+ This parameter can be set either to ENABLE or DISABLE. */
+
+ FunctionalState CAN_RFLM; /*!< Enable or disable the Receive FIFO Locked mode.
+ This parameter can be set either to ENABLE or DISABLE. */
+
+ FunctionalState CAN_TXFP; /*!< Enable or disable the transmit FIFO priority.
+ This parameter can be set either to ENABLE or DISABLE. */
+} CAN_InitTypeDef;
+
+/**
+ * @brief CAN filter init structure definition
+ */
+typedef struct
+{
+ uint16_t CAN_FilterIdHigh; /*!< Specifies the filter identification number (MSBs for a 32-bit
+ configuration, first one for a 16-bit configuration).
+ This parameter can be a value between 0x0000 and 0xFFFF */
+
+ uint16_t CAN_FilterIdLow; /*!< Specifies the filter identification number (LSBs for a 32-bit
+ configuration, second one for a 16-bit configuration).
+ This parameter can be a value between 0x0000 and 0xFFFF */
+
+ uint16_t CAN_FilterMaskIdHigh; /*!< Specifies the filter mask number or identification number,
+ according to the mode (MSBs for a 32-bit configuration,
+ first one for a 16-bit configuration).
+ This parameter can be a value between 0x0000 and 0xFFFF */
+
+ uint16_t CAN_FilterMaskIdLow; /*!< Specifies the filter mask number or identification number,
+ according to the mode (LSBs for a 32-bit configuration,
+ second one for a 16-bit configuration).
+ This parameter can be a value between 0x0000 and 0xFFFF */
+
+ uint16_t CAN_FilterFIFOAssignment; /*!< Specifies the FIFO (0 or 1) which will be assigned to the filter.
+ This parameter can be a value of @ref CAN_filter_FIFO */
+
+ uint8_t CAN_FilterNumber; /*!< Specifies the filter which will be initialized. It ranges from 0 to 13. */
+
+ uint8_t CAN_FilterMode; /*!< Specifies the filter mode to be initialized.
+ This parameter can be a value of @ref CAN_filter_mode */
+
+ uint8_t CAN_FilterScale; /*!< Specifies the filter scale.
+ This parameter can be a value of @ref CAN_filter_scale */
+
+ FunctionalState CAN_FilterActivation; /*!< Enable or disable the filter.
+ This parameter can be set either to ENABLE or DISABLE. */
+} CAN_FilterInitTypeDef;
+
+/**
+ * @brief CAN Tx message structure definition
+ */
+typedef struct
+{
+ uint32_t StdId; /*!< Specifies the standard identifier.
+ This parameter can be a value between 0 to 0x7FF. */
+
+ uint32_t ExtId; /*!< Specifies the extended identifier.
+ This parameter can be a value between 0 to 0x1FFFFFFF. */
+
+ uint8_t IDE; /*!< Specifies the type of identifier for the message that
+ will be transmitted. This parameter can be a value
+ of @ref CAN_identifier_type */
+
+ uint8_t RTR; /*!< Specifies the type of frame for the message that will
+ be transmitted. This parameter can be a value of
+ @ref CAN_remote_transmission_request */
+
+ uint8_t DLC; /*!< Specifies the length of the frame that will be
+ transmitted. This parameter can be a value between
+ 0 to 8 */
+
+ uint8_t Data[8]; /*!< Contains the data to be transmitted. It ranges from 0
+ to 0xFF. */
+} CanTxMsg;
+
+/**
+ * @brief CAN Rx message structure definition
+ */
+typedef struct
+{
+ uint32_t StdId; /*!< Specifies the standard identifier.
+ This parameter can be a value between 0 to 0x7FF. */
+
+ uint32_t ExtId; /*!< Specifies the extended identifier.
+ This parameter can be a value between 0 to 0x1FFFFFFF. */
+
+ uint8_t IDE; /*!< Specifies the type of identifier for the message that
+ will be received. This parameter can be a value of
+ @ref CAN_identifier_type */
+
+ uint8_t RTR; /*!< Specifies the type of frame for the received message.
+ This parameter can be a value of
+ @ref CAN_remote_transmission_request */
+
+ uint8_t DLC; /*!< Specifies the length of the frame that will be received.
+ This parameter can be a value between 0 to 8 */
+
+ uint8_t Data[8]; /*!< Contains the data to be received. It ranges from 0 to
+ 0xFF. */
+
+ uint8_t FMI; /*!< Specifies the index of the filter the message stored in
+ the mailbox passes through. This parameter can be a
+ value between 0 to 0xFF */
+} CanRxMsg;
+
+/* Exported constants --------------------------------------------------------*/
+
+/** @defgroup CAN_Exported_Constants
+ * @{
+ */
+
+/** @defgroup CAN_InitStatus
+ * @{
+ */
+
+#define CAN_InitStatus_Failed ((uint8_t)0x00) /*!< CAN initialization failed */
+#define CAN_InitStatus_Success ((uint8_t)0x01) /*!< CAN initialization OK */
+
+
+/* Legacy defines */
+#define CANINITFAILED CAN_InitStatus_Failed
+#define CANINITOK CAN_InitStatus_Success
+/**
+ * @}
+ */
+
+/** @defgroup CAN_operating_mode
+ * @{
+ */
+
+#define CAN_Mode_Normal ((uint8_t)0x00) /*!< normal mode */
+#define CAN_Mode_LoopBack ((uint8_t)0x01) /*!< loopback mode */
+#define CAN_Mode_Silent ((uint8_t)0x02) /*!< silent mode */
+#define CAN_Mode_Silent_LoopBack ((uint8_t)0x03) /*!< loopback combined with silent mode */
+
+#define IS_CAN_MODE(MODE) (((MODE) == CAN_Mode_Normal) || \
+ ((MODE) == CAN_Mode_LoopBack)|| \
+ ((MODE) == CAN_Mode_Silent) || \
+ ((MODE) == CAN_Mode_Silent_LoopBack))
+/**
+ * @}
+ */
+
+
+ /**
+ * @defgroup CAN_operating_mode
+ * @{
+ */
+#define CAN_OperatingMode_Initialization ((uint8_t)0x00) /*!< Initialization mode */
+#define CAN_OperatingMode_Normal ((uint8_t)0x01) /*!< Normal mode */
+#define CAN_OperatingMode_Sleep ((uint8_t)0x02) /*!< sleep mode */
+
+
+#define IS_CAN_OPERATING_MODE(MODE) (((MODE) == CAN_OperatingMode_Initialization) ||\
+ ((MODE) == CAN_OperatingMode_Normal)|| \
+ ((MODE) == CAN_OperatingMode_Sleep))
+/**
+ * @}
+ */
+
+/**
+ * @defgroup CAN_operating_mode_status
+ * @{
+ */
+
+#define CAN_ModeStatus_Failed ((uint8_t)0x00) /*!< CAN entering the specific mode failed */
+#define CAN_ModeStatus_Success ((uint8_t)!CAN_ModeStatus_Failed) /*!< CAN entering the specific mode Succeed */
+/**
+ * @}
+ */
+
+/** @defgroup CAN_synchronisation_jump_width
+ * @{
+ */
+#define CAN_SJW_1tq ((uint8_t)0x00) /*!< 1 time quantum */
+#define CAN_SJW_2tq ((uint8_t)0x01) /*!< 2 time quantum */
+#define CAN_SJW_3tq ((uint8_t)0x02) /*!< 3 time quantum */
+#define CAN_SJW_4tq ((uint8_t)0x03) /*!< 4 time quantum */
+
+#define IS_CAN_SJW(SJW) (((SJW) == CAN_SJW_1tq) || ((SJW) == CAN_SJW_2tq)|| \
+ ((SJW) == CAN_SJW_3tq) || ((SJW) == CAN_SJW_4tq))
+/**
+ * @}
+ */
+
+/** @defgroup CAN_time_quantum_in_bit_segment_1
+ * @{
+ */
+#define CAN_BS1_1tq ((uint8_t)0x00) /*!< 1 time quantum */
+#define CAN_BS1_2tq ((uint8_t)0x01) /*!< 2 time quantum */
+#define CAN_BS1_3tq ((uint8_t)0x02) /*!< 3 time quantum */
+#define CAN_BS1_4tq ((uint8_t)0x03) /*!< 4 time quantum */
+#define CAN_BS1_5tq ((uint8_t)0x04) /*!< 5 time quantum */
+#define CAN_BS1_6tq ((uint8_t)0x05) /*!< 6 time quantum */
+#define CAN_BS1_7tq ((uint8_t)0x06) /*!< 7 time quantum */
+#define CAN_BS1_8tq ((uint8_t)0x07) /*!< 8 time quantum */
+#define CAN_BS1_9tq ((uint8_t)0x08) /*!< 9 time quantum */
+#define CAN_BS1_10tq ((uint8_t)0x09) /*!< 10 time quantum */
+#define CAN_BS1_11tq ((uint8_t)0x0A) /*!< 11 time quantum */
+#define CAN_BS1_12tq ((uint8_t)0x0B) /*!< 12 time quantum */
+#define CAN_BS1_13tq ((uint8_t)0x0C) /*!< 13 time quantum */
+#define CAN_BS1_14tq ((uint8_t)0x0D) /*!< 14 time quantum */
+#define CAN_BS1_15tq ((uint8_t)0x0E) /*!< 15 time quantum */
+#define CAN_BS1_16tq ((uint8_t)0x0F) /*!< 16 time quantum */
+
+#define IS_CAN_BS1(BS1) ((BS1) <= CAN_BS1_16tq)
+/**
+ * @}
+ */
+
+/** @defgroup CAN_time_quantum_in_bit_segment_2
+ * @{
+ */
+#define CAN_BS2_1tq ((uint8_t)0x00) /*!< 1 time quantum */
+#define CAN_BS2_2tq ((uint8_t)0x01) /*!< 2 time quantum */
+#define CAN_BS2_3tq ((uint8_t)0x02) /*!< 3 time quantum */
+#define CAN_BS2_4tq ((uint8_t)0x03) /*!< 4 time quantum */
+#define CAN_BS2_5tq ((uint8_t)0x04) /*!< 5 time quantum */
+#define CAN_BS2_6tq ((uint8_t)0x05) /*!< 6 time quantum */
+#define CAN_BS2_7tq ((uint8_t)0x06) /*!< 7 time quantum */
+#define CAN_BS2_8tq ((uint8_t)0x07) /*!< 8 time quantum */
+
+#define IS_CAN_BS2(BS2) ((BS2) <= CAN_BS2_8tq)
+/**
+ * @}
+ */
+
+/** @defgroup CAN_clock_prescaler
+ * @{
+ */
+#define IS_CAN_PRESCALER(PRESCALER) (((PRESCALER) >= 1) && ((PRESCALER) <= 1024))
+/**
+ * @}
+ */
+
+/** @defgroup CAN_filter_number
+ * @{
+ */
+#define IS_CAN_FILTER_NUMBER(NUMBER) ((NUMBER) <= 27)
+/**
+ * @}
+ */
+
+/** @defgroup CAN_filter_mode
+ * @{
+ */
+#define CAN_FilterMode_IdMask ((uint8_t)0x00) /*!< identifier/mask mode */
+#define CAN_FilterMode_IdList ((uint8_t)0x01) /*!< identifier list mode */
+
+#define IS_CAN_FILTER_MODE(MODE) (((MODE) == CAN_FilterMode_IdMask) || \
+ ((MODE) == CAN_FilterMode_IdList))
+/**
+ * @}
+ */
+
+/** @defgroup CAN_filter_scale
+ * @{
+ */
+#define CAN_FilterScale_16bit ((uint8_t)0x00) /*!< Two 16-bit filters */
+#define CAN_FilterScale_32bit ((uint8_t)0x01) /*!< One 32-bit filter */
+
+#define IS_CAN_FILTER_SCALE(SCALE) (((SCALE) == CAN_FilterScale_16bit) || \
+ ((SCALE) == CAN_FilterScale_32bit))
+/**
+ * @}
+ */
+
+/** @defgroup CAN_filter_FIFO
+ * @{
+ */
+#define CAN_Filter_FIFO0 ((uint8_t)0x00) /*!< Filter FIFO 0 assignment for filter x */
+#define CAN_Filter_FIFO1 ((uint8_t)0x01) /*!< Filter FIFO 1 assignment for filter x */
+#define IS_CAN_FILTER_FIFO(FIFO) (((FIFO) == CAN_FilterFIFO0) || \
+ ((FIFO) == CAN_FilterFIFO1))
+
+/* Legacy defines */
+#define CAN_FilterFIFO0 CAN_Filter_FIFO0
+#define CAN_FilterFIFO1 CAN_Filter_FIFO1
+/**
+ * @}
+ */
+
+/** @defgroup CAN_Start_bank_filter_for_slave_CAN
+ * @{
+ */
+#define IS_CAN_BANKNUMBER(BANKNUMBER) (((BANKNUMBER) >= 1) && ((BANKNUMBER) <= 27))
+/**
+ * @}
+ */
+
+/** @defgroup CAN_Tx
+ * @{
+ */
+#define IS_CAN_TRANSMITMAILBOX(TRANSMITMAILBOX) ((TRANSMITMAILBOX) <= ((uint8_t)0x02))
+#define IS_CAN_STDID(STDID) ((STDID) <= ((uint32_t)0x7FF))
+#define IS_CAN_EXTID(EXTID) ((EXTID) <= ((uint32_t)0x1FFFFFFF))
+#define IS_CAN_DLC(DLC) ((DLC) <= ((uint8_t)0x08))
+/**
+ * @}
+ */
+
+/** @defgroup CAN_identifier_type
+ * @{
+ */
+#define CAN_Id_Standard ((uint32_t)0x00000000) /*!< Standard Id */
+#define CAN_Id_Extended ((uint32_t)0x00000004) /*!< Extended Id */
+#define IS_CAN_IDTYPE(IDTYPE) (((IDTYPE) == CAN_Id_Standard) || \
+ ((IDTYPE) == CAN_Id_Extended))
+
+/* Legacy defines */
+#define CAN_ID_STD CAN_Id_Standard
+#define CAN_ID_EXT CAN_Id_Extended
+/**
+ * @}
+ */
+
+/** @defgroup CAN_remote_transmission_request
+ * @{
+ */
+#define CAN_RTR_Data ((uint32_t)0x00000000) /*!< Data frame */
+#define CAN_RTR_Remote ((uint32_t)0x00000002) /*!< Remote frame */
+#define IS_CAN_RTR(RTR) (((RTR) == CAN_RTR_Data) || ((RTR) == CAN_RTR_Remote))
+
+/* Legacy defines */
+#define CAN_RTR_DATA CAN_RTR_Data
+#define CAN_RTR_REMOTE CAN_RTR_Remote
+/**
+ * @}
+ */
+
+/** @defgroup CAN_transmit_constants
+ * @{
+ */
+#define CAN_TxStatus_Failed ((uint8_t)0x00)/*!< CAN transmission failed */
+#define CAN_TxStatus_Ok ((uint8_t)0x01) /*!< CAN transmission succeeded */
+#define CAN_TxStatus_Pending ((uint8_t)0x02) /*!< CAN transmission pending */
+#define CAN_TxStatus_NoMailBox ((uint8_t)0x04) /*!< CAN cell did not provide
+ an empty mailbox */
+/* Legacy defines */
+#define CANTXFAILED CAN_TxStatus_Failed
+#define CANTXOK CAN_TxStatus_Ok
+#define CANTXPENDING CAN_TxStatus_Pending
+#define CAN_NO_MB CAN_TxStatus_NoMailBox
+/**
+ * @}
+ */
+
+/** @defgroup CAN_receive_FIFO_number_constants
+ * @{
+ */
+#define CAN_FIFO0 ((uint8_t)0x00) /*!< CAN FIFO 0 used to receive */
+#define CAN_FIFO1 ((uint8_t)0x01) /*!< CAN FIFO 1 used to receive */
+
+#define IS_CAN_FIFO(FIFO) (((FIFO) == CAN_FIFO0) || ((FIFO) == CAN_FIFO1))
+/**
+ * @}
+ */
+
+/** @defgroup CAN_sleep_constants
+ * @{
+ */
+#define CAN_Sleep_Failed ((uint8_t)0x00) /*!< CAN did not enter the sleep mode */
+#define CAN_Sleep_Ok ((uint8_t)0x01) /*!< CAN entered the sleep mode */
+
+/* Legacy defines */
+#define CANSLEEPFAILED CAN_Sleep_Failed
+#define CANSLEEPOK CAN_Sleep_Ok
+/**
+ * @}
+ */
+
+/** @defgroup CAN_wake_up_constants
+ * @{
+ */
+#define CAN_WakeUp_Failed ((uint8_t)0x00) /*!< CAN did not leave the sleep mode */
+#define CAN_WakeUp_Ok ((uint8_t)0x01) /*!< CAN leaved the sleep mode */
+
+/* Legacy defines */
+#define CANWAKEUPFAILED CAN_WakeUp_Failed
+#define CANWAKEUPOK CAN_WakeUp_Ok
+/**
+ * @}
+ */
+
+/**
+ * @defgroup CAN_Error_Code_constants
+ * @{
+ */
+#define CAN_ErrorCode_NoErr ((uint8_t)0x00) /*!< No Error */
+#define CAN_ErrorCode_StuffErr ((uint8_t)0x10) /*!< Stuff Error */
+#define CAN_ErrorCode_FormErr ((uint8_t)0x20) /*!< Form Error */
+#define CAN_ErrorCode_ACKErr ((uint8_t)0x30) /*!< Acknowledgment Error */
+#define CAN_ErrorCode_BitRecessiveErr ((uint8_t)0x40) /*!< Bit Recessive Error */
+#define CAN_ErrorCode_BitDominantErr ((uint8_t)0x50) /*!< Bit Dominant Error */
+#define CAN_ErrorCode_CRCErr ((uint8_t)0x60) /*!< CRC Error */
+#define CAN_ErrorCode_SoftwareSetErr ((uint8_t)0x70) /*!< Software Set Error */
+/**
+ * @}
+ */
+
+/** @defgroup CAN_flags
+ * @{
+ */
+/* If the flag is 0x3XXXXXXX, it means that it can be used with CAN_GetFlagStatus()
+ and CAN_ClearFlag() functions. */
+/* If the flag is 0x1XXXXXXX, it means that it can only be used with
+ CAN_GetFlagStatus() function. */
+
+/* Transmit Flags */
+#define CAN_FLAG_RQCP0 ((uint32_t)0x38000001) /*!< Request MailBox0 Flag */
+#define CAN_FLAG_RQCP1 ((uint32_t)0x38000100) /*!< Request MailBox1 Flag */
+#define CAN_FLAG_RQCP2 ((uint32_t)0x38010000) /*!< Request MailBox2 Flag */
+
+/* Receive Flags */
+#define CAN_FLAG_FMP0 ((uint32_t)0x12000003) /*!< FIFO 0 Message Pending Flag */
+#define CAN_FLAG_FF0 ((uint32_t)0x32000008) /*!< FIFO 0 Full Flag */
+#define CAN_FLAG_FOV0 ((uint32_t)0x32000010) /*!< FIFO 0 Overrun Flag */
+#define CAN_FLAG_FMP1 ((uint32_t)0x14000003) /*!< FIFO 1 Message Pending Flag */
+#define CAN_FLAG_FF1 ((uint32_t)0x34000008) /*!< FIFO 1 Full Flag */
+#define CAN_FLAG_FOV1 ((uint32_t)0x34000010) /*!< FIFO 1 Overrun Flag */
+
+/* Operating Mode Flags */
+#define CAN_FLAG_WKU ((uint32_t)0x31000008) /*!< Wake up Flag */
+#define CAN_FLAG_SLAK ((uint32_t)0x31000012) /*!< Sleep acknowledge Flag */
+/* @note When SLAK interrupt is disabled (SLKIE=0), no polling on SLAKI is possible.
+ In this case the SLAK bit can be polled.*/
+
+/* Error Flags */
+#define CAN_FLAG_EWG ((uint32_t)0x10F00001) /*!< Error Warning Flag */
+#define CAN_FLAG_EPV ((uint32_t)0x10F00002) /*!< Error Passive Flag */
+#define CAN_FLAG_BOF ((uint32_t)0x10F00004) /*!< Bus-Off Flag */
+#define CAN_FLAG_LEC ((uint32_t)0x30F00070) /*!< Last error code Flag */
+
+#define IS_CAN_GET_FLAG(FLAG) (((FLAG) == CAN_FLAG_LEC) || ((FLAG) == CAN_FLAG_BOF) || \
+ ((FLAG) == CAN_FLAG_EPV) || ((FLAG) == CAN_FLAG_EWG) || \
+ ((FLAG) == CAN_FLAG_WKU) || ((FLAG) == CAN_FLAG_FOV0) || \
+ ((FLAG) == CAN_FLAG_FF0) || ((FLAG) == CAN_FLAG_FMP0) || \
+ ((FLAG) == CAN_FLAG_FOV1) || ((FLAG) == CAN_FLAG_FF1) || \
+ ((FLAG) == CAN_FLAG_FMP1) || ((FLAG) == CAN_FLAG_RQCP2) || \
+ ((FLAG) == CAN_FLAG_RQCP1)|| ((FLAG) == CAN_FLAG_RQCP0) || \
+ ((FLAG) == CAN_FLAG_SLAK ))
+
+#define IS_CAN_CLEAR_FLAG(FLAG)(((FLAG) == CAN_FLAG_LEC) || ((FLAG) == CAN_FLAG_RQCP2) || \
+ ((FLAG) == CAN_FLAG_RQCP1) || ((FLAG) == CAN_FLAG_RQCP0) || \
+ ((FLAG) == CAN_FLAG_FF0) || ((FLAG) == CAN_FLAG_FOV0) ||\
+ ((FLAG) == CAN_FLAG_FF1) || ((FLAG) == CAN_FLAG_FOV1) || \
+ ((FLAG) == CAN_FLAG_WKU) || ((FLAG) == CAN_FLAG_SLAK))
+/**
+ * @}
+ */
+
+
+/** @defgroup CAN_interrupts
+ * @{
+ */
+#define CAN_IT_TME ((uint32_t)0x00000001) /*!< Transmit mailbox empty Interrupt*/
+
+/* Receive Interrupts */
+#define CAN_IT_FMP0 ((uint32_t)0x00000002) /*!< FIFO 0 message pending Interrupt*/
+#define CAN_IT_FF0 ((uint32_t)0x00000004) /*!< FIFO 0 full Interrupt*/
+#define CAN_IT_FOV0 ((uint32_t)0x00000008) /*!< FIFO 0 overrun Interrupt*/
+#define CAN_IT_FMP1 ((uint32_t)0x00000010) /*!< FIFO 1 message pending Interrupt*/
+#define CAN_IT_FF1 ((uint32_t)0x00000020) /*!< FIFO 1 full Interrupt*/
+#define CAN_IT_FOV1 ((uint32_t)0x00000040) /*!< FIFO 1 overrun Interrupt*/
+
+/* Operating Mode Interrupts */
+#define CAN_IT_WKU ((uint32_t)0x00010000) /*!< Wake-up Interrupt*/
+#define CAN_IT_SLK ((uint32_t)0x00020000) /*!< Sleep acknowledge Interrupt*/
+
+/* Error Interrupts */
+#define CAN_IT_EWG ((uint32_t)0x00000100) /*!< Error warning Interrupt*/
+#define CAN_IT_EPV ((uint32_t)0x00000200) /*!< Error passive Interrupt*/
+#define CAN_IT_BOF ((uint32_t)0x00000400) /*!< Bus-off Interrupt*/
+#define CAN_IT_LEC ((uint32_t)0x00000800) /*!< Last error code Interrupt*/
+#define CAN_IT_ERR ((uint32_t)0x00008000) /*!< Error Interrupt*/
+
+/* Flags named as Interrupts : kept only for FW compatibility */
+#define CAN_IT_RQCP0 CAN_IT_TME
+#define CAN_IT_RQCP1 CAN_IT_TME
+#define CAN_IT_RQCP2 CAN_IT_TME
+
+
+#define IS_CAN_IT(IT) (((IT) == CAN_IT_TME) || ((IT) == CAN_IT_FMP0) ||\
+ ((IT) == CAN_IT_FF0) || ((IT) == CAN_IT_FOV0) ||\
+ ((IT) == CAN_IT_FMP1) || ((IT) == CAN_IT_FF1) ||\
+ ((IT) == CAN_IT_FOV1) || ((IT) == CAN_IT_EWG) ||\
+ ((IT) == CAN_IT_EPV) || ((IT) == CAN_IT_BOF) ||\
+ ((IT) == CAN_IT_LEC) || ((IT) == CAN_IT_ERR) ||\
+ ((IT) == CAN_IT_WKU) || ((IT) == CAN_IT_SLK))
+
+#define IS_CAN_CLEAR_IT(IT) (((IT) == CAN_IT_TME) || ((IT) == CAN_IT_FF0) ||\
+ ((IT) == CAN_IT_FOV0)|| ((IT) == CAN_IT_FF1) ||\
+ ((IT) == CAN_IT_FOV1)|| ((IT) == CAN_IT_EWG) ||\
+ ((IT) == CAN_IT_EPV) || ((IT) == CAN_IT_BOF) ||\
+ ((IT) == CAN_IT_LEC) || ((IT) == CAN_IT_ERR) ||\
+ ((IT) == CAN_IT_WKU) || ((IT) == CAN_IT_SLK))
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions --------------------------------------------------------*/
+
+/* Function used to set the CAN configuration to the default reset state *****/
+void CAN_DeInit(CAN_TypeDef* CANx);
+
+/* Initialization and Configuration functions *********************************/
+uint8_t CAN_Init(CAN_TypeDef* CANx, CAN_InitTypeDef* CAN_InitStruct);
+void CAN_FilterInit(CAN_FilterInitTypeDef* CAN_FilterInitStruct);
+void CAN_StructInit(CAN_InitTypeDef* CAN_InitStruct);
+void CAN_SlaveStartBank(uint8_t CAN_BankNumber);
+void CAN_DBGFreeze(CAN_TypeDef* CANx, FunctionalState NewState);
+void CAN_TTComModeCmd(CAN_TypeDef* CANx, FunctionalState NewState);
+
+/* CAN Frames Transmission functions ******************************************/
+uint8_t CAN_Transmit(CAN_TypeDef* CANx, CanTxMsg* TxMessage);
+uint8_t CAN_TransmitStatus(CAN_TypeDef* CANx, uint8_t TransmitMailbox);
+void CAN_CancelTransmit(CAN_TypeDef* CANx, uint8_t Mailbox);
+
+/* CAN Frames Reception functions *********************************************/
+void CAN_Receive(CAN_TypeDef* CANx, uint8_t FIFONumber, CanRxMsg* RxMessage);
+void CAN_FIFORelease(CAN_TypeDef* CANx, uint8_t FIFONumber);
+uint8_t CAN_MessagePending(CAN_TypeDef* CANx, uint8_t FIFONumber);
+
+/* Operation modes functions **************************************************/
+uint8_t CAN_OperatingModeRequest(CAN_TypeDef* CANx, uint8_t CAN_OperatingMode);
+uint8_t CAN_Sleep(CAN_TypeDef* CANx);
+uint8_t CAN_WakeUp(CAN_TypeDef* CANx);
+
+/* CAN Bus Error management functions *****************************************/
+uint8_t CAN_GetLastErrorCode(CAN_TypeDef* CANx);
+uint8_t CAN_GetReceiveErrorCounter(CAN_TypeDef* CANx);
+uint8_t CAN_GetLSBTransmitErrorCounter(CAN_TypeDef* CANx);
+
+/* Interrupts and flags management functions **********************************/
+void CAN_ITConfig(CAN_TypeDef* CANx, uint32_t CAN_IT, FunctionalState NewState);
+FlagStatus CAN_GetFlagStatus(CAN_TypeDef* CANx, uint32_t CAN_FLAG);
+void CAN_ClearFlag(CAN_TypeDef* CANx, uint32_t CAN_FLAG);
+ITStatus CAN_GetITStatus(CAN_TypeDef* CANx, uint32_t CAN_IT);
+void CAN_ClearITPendingBit(CAN_TypeDef* CANx, uint32_t CAN_IT);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F2xx_CAN_H */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/inc/stm32f2xx_crc.h b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/inc/stm32f2xx_crc.h
new file mode 100644
index 0000000..3361bbc
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/inc/stm32f2xx_crc.h
@@ -0,0 +1,83 @@
+/**
+ ******************************************************************************
+ * @file stm32f2xx_crc.h
+ * @author MCD Application Team
+ * @version V1.1.2
+ * @date 05-March-2012
+ * @brief This file contains all the functions prototypes for the CRC firmware
+ * 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 __STM32F2xx_CRC_H
+#define __STM32F2xx_CRC_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f2xx.h"
+
+/** @addtogroup STM32F2xx_StdPeriph_Driver
+ * @{
+ */
+
+/** @addtogroup CRC
+ * @{
+ */
+
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+
+/** @defgroup CRC_Exported_Constants
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions --------------------------------------------------------*/
+
+void CRC_ResetDR(void);
+uint32_t CRC_CalcCRC(uint32_t Data);
+uint32_t CRC_CalcBlockCRC(uint32_t pBuffer[], uint32_t BufferLength);
+uint32_t CRC_GetCRC(void);
+void CRC_SetIDRegister(uint8_t IDValue);
+uint8_t CRC_GetIDRegister(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F2xx_CRC_H */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/inc/stm32f2xx_cryp.h b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/inc/stm32f2xx_cryp.h
new file mode 100644
index 0000000..e0b4501
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/inc/stm32f2xx_cryp.h
@@ -0,0 +1,344 @@
+/**
+ ******************************************************************************
+ * @file stm32f2xx_cryp.h
+ * @author MCD Application Team
+ * @version V1.1.2
+ * @date 05-March-2012
+ * @brief This file contains all the functions prototypes for the Cryptographic
+ * processor(CRYP) firmware 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 __STM32F2xx_CRYP_H
+#define __STM32F2xx_CRYP_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f2xx.h"
+
+/** @addtogroup STM32F2xx_StdPeriph_Driver
+ * @{
+ */
+
+/** @addtogroup CRYP
+ * @{
+ */
+
+/* Exported types ------------------------------------------------------------*/
+
+/**
+ * @brief CRYP Init structure definition
+ */
+typedef struct
+{
+ uint16_t CRYP_AlgoDir; /*!< Encrypt or Decrypt. This parameter can be a
+ value of @ref CRYP_Algorithm_Direction */
+ uint16_t CRYP_AlgoMode; /*!< TDES-ECB, TDES-CBC, DES-ECB, DES-CBC, AES-ECB,
+ AES-CBC, AES-CTR, AES-Key. This parameter can be
+ a value of @ref CRYP_Algorithm_Mode */
+ uint16_t CRYP_DataType; /*!< 32-bit data, 16-bit data, bit data or bit-string.
+ This parameter can be a value of @ref CRYP_Data_Type */
+ uint16_t CRYP_KeySize; /*!< Used only in AES mode only : 128, 192 or 256 bit
+ key length. This parameter can be a value of
+ @ref CRYP_Key_Size_for_AES_only */
+}CRYP_InitTypeDef;
+
+/**
+ * @brief CRYP Key(s) structure definition
+ */
+typedef struct
+{
+ uint32_t CRYP_Key0Left; /*!< Key 0 Left */
+ uint32_t CRYP_Key0Right; /*!< Key 0 Right */
+ uint32_t CRYP_Key1Left; /*!< Key 1 left */
+ uint32_t CRYP_Key1Right; /*!< Key 1 Right */
+ uint32_t CRYP_Key2Left; /*!< Key 2 left */
+ uint32_t CRYP_Key2Right; /*!< Key 2 Right */
+ uint32_t CRYP_Key3Left; /*!< Key 3 left */
+ uint32_t CRYP_Key3Right; /*!< Key 3 Right */
+}CRYP_KeyInitTypeDef;
+/**
+ * @brief CRYP Initialization Vectors (IV) structure definition
+ */
+typedef struct
+{
+ uint32_t CRYP_IV0Left; /*!< Init Vector 0 Left */
+ uint32_t CRYP_IV0Right; /*!< Init Vector 0 Right */
+ uint32_t CRYP_IV1Left; /*!< Init Vector 1 left */
+ uint32_t CRYP_IV1Right; /*!< Init Vector 1 Right */
+}CRYP_IVInitTypeDef;
+
+/**
+ * @brief CRYP context swapping structure definition
+ */
+typedef struct
+{
+ /*!< Configuration */
+ uint32_t CR_bits9to2;
+ /*!< KEY */
+ uint32_t CRYP_IV0LR;
+ uint32_t CRYP_IV0RR;
+ uint32_t CRYP_IV1LR;
+ uint32_t CRYP_IV1RR;
+ /*!< IV */
+ uint32_t CRYP_K0LR;
+ uint32_t CRYP_K0RR;
+ uint32_t CRYP_K1LR;
+ uint32_t CRYP_K1RR;
+ uint32_t CRYP_K2LR;
+ uint32_t CRYP_K2RR;
+ uint32_t CRYP_K3LR;
+ uint32_t CRYP_K3RR;
+}CRYP_Context;
+
+
+/* Exported constants --------------------------------------------------------*/
+
+/** @defgroup CRYP_Exported_Constants
+ * @{
+ */
+
+/** @defgroup CRYP_Algorithm_Direction
+ * @{
+ */
+#define CRYP_AlgoDir_Encrypt ((uint16_t)0x0000)
+#define CRYP_AlgoDir_Decrypt ((uint16_t)0x0004)
+#define IS_CRYP_ALGODIR(ALGODIR) (((ALGODIR) == CRYP_AlgoDir_Encrypt) || \
+ ((ALGODIR) == CRYP_AlgoDir_Decrypt))
+
+/**
+ * @}
+ */
+
+/** @defgroup CRYP_Algorithm_Mode
+ * @{
+ */
+
+/*!< TDES Modes */
+#define CRYP_AlgoMode_TDES_ECB ((uint16_t)0x0000)
+#define CRYP_AlgoMode_TDES_CBC ((uint16_t)0x0008)
+
+/*!< DES Modes */
+#define CRYP_AlgoMode_DES_ECB ((uint16_t)0x0010)
+#define CRYP_AlgoMode_DES_CBC ((uint16_t)0x0018)
+
+/*!< AES Modes */
+#define CRYP_AlgoMode_AES_ECB ((uint16_t)0x0020)
+#define CRYP_AlgoMode_AES_CBC ((uint16_t)0x0028)
+#define CRYP_AlgoMode_AES_CTR ((uint16_t)0x0030)
+#define CRYP_AlgoMode_AES_Key ((uint16_t)0x0038)
+
+#define IS_CRYP_ALGOMODE(ALGOMODE) (((ALGOMODE) == CRYP_AlgoMode_TDES_ECB) || \
+ ((ALGOMODE) == CRYP_AlgoMode_TDES_CBC)|| \
+ ((ALGOMODE) == CRYP_AlgoMode_DES_ECB)|| \
+ ((ALGOMODE) == CRYP_AlgoMode_DES_CBC) || \
+ ((ALGOMODE) == CRYP_AlgoMode_AES_ECB) || \
+ ((ALGOMODE) == CRYP_AlgoMode_AES_CBC) || \
+ ((ALGOMODE) == CRYP_AlgoMode_AES_CTR) || \
+ ((ALGOMODE) == CRYP_AlgoMode_AES_Key))
+/**
+ * @}
+ */
+
+/** @defgroup CRYP_Data_Type
+ * @{
+ */
+#define CRYP_DataType_32b ((uint16_t)0x0000)
+#define CRYP_DataType_16b ((uint16_t)0x0040)
+#define CRYP_DataType_8b ((uint16_t)0x0080)
+#define CRYP_DataType_1b ((uint16_t)0x00C0)
+#define IS_CRYP_DATATYPE(DATATYPE) (((DATATYPE) == CRYP_DataType_32b) || \
+ ((DATATYPE) == CRYP_DataType_16b)|| \
+ ((DATATYPE) == CRYP_DataType_8b)|| \
+ ((DATATYPE) == CRYP_DataType_1b))
+/**
+ * @}
+ */
+
+/** @defgroup CRYP_Key_Size_for_AES_only
+ * @{
+ */
+#define CRYP_KeySize_128b ((uint16_t)0x0000)
+#define CRYP_KeySize_192b ((uint16_t)0x0100)
+#define CRYP_KeySize_256b ((uint16_t)0x0200)
+#define IS_CRYP_KEYSIZE(KEYSIZE) (((KEYSIZE) == CRYP_KeySize_128b)|| \
+ ((KEYSIZE) == CRYP_KeySize_192b)|| \
+ ((KEYSIZE) == CRYP_KeySize_256b))
+/**
+ * @}
+ */
+
+/** @defgroup CRYP_flags_definition
+ * @{
+ */
+#define CRYP_FLAG_BUSY ((uint8_t)0x10) /*!< The CRYP core is currently
+ processing a block of data
+ or a key preparation (for
+ AES decryption). */
+#define CRYP_FLAG_IFEM ((uint8_t)0x01) /*!< Input Fifo Empty */
+#define CRYP_FLAG_IFNF ((uint8_t)0x02) /*!< Input Fifo is Not Full */
+#define CRYP_FLAG_INRIS ((uint8_t)0x22) /*!< Raw interrupt pending */
+#define CRYP_FLAG_OFNE ((uint8_t)0x04) /*!< Input Fifo service raw
+ interrupt status */
+#define CRYP_FLAG_OFFU ((uint8_t)0x08) /*!< Output Fifo is Full */
+#define CRYP_FLAG_OUTRIS ((uint8_t)0x21) /*!< Output Fifo service raw
+ interrupt status */
+
+#define IS_CRYP_GET_FLAG(FLAG) (((FLAG) == CRYP_FLAG_IFEM) || \
+ ((FLAG) == CRYP_FLAG_IFNF) || \
+ ((FLAG) == CRYP_FLAG_OFNE) || \
+ ((FLAG) == CRYP_FLAG_OFFU) || \
+ ((FLAG) == CRYP_FLAG_BUSY) || \
+ ((FLAG) == CRYP_FLAG_OUTRIS)|| \
+ ((FLAG) == CRYP_FLAG_INRIS))
+/**
+ * @}
+ */
+
+/** @defgroup CRYP_interrupts_definition
+ * @{
+ */
+#define CRYP_IT_INI ((uint8_t)0x01) /*!< IN Fifo Interrupt */
+#define CRYP_IT_OUTI ((uint8_t)0x02) /*!< OUT Fifo Interrupt */
+#define IS_CRYP_CONFIG_IT(IT) ((((IT) & (uint8_t)0xFC) == 0x00) && ((IT) != 0x00))
+#define IS_CRYP_GET_IT(IT) (((IT) == CRYP_IT_INI) || ((IT) == CRYP_IT_OUTI))
+
+/**
+ * @}
+ */
+
+/** @defgroup CRYP_Encryption_Decryption_modes_definition
+ * @{
+ */
+#define MODE_ENCRYPT ((uint8_t)0x01)
+#define MODE_DECRYPT ((uint8_t)0x00)
+
+/**
+ * @}
+ */
+
+/** @defgroup CRYP_DMA_transfer_requests
+ * @{
+ */
+#define CRYP_DMAReq_DataIN ((uint8_t)0x01)
+#define CRYP_DMAReq_DataOUT ((uint8_t)0x02)
+#define IS_CRYP_DMAREQ(DMAREQ) ((((DMAREQ) & (uint8_t)0xFC) == 0x00) && ((DMAREQ) != 0x00))
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions --------------------------------------------------------*/
+
+/* Function used to set the CRYP configuration to the default reset state ****/
+void CRYP_DeInit(void);
+
+/* CRYP Initialization and Configuration functions ****************************/
+void CRYP_Init(CRYP_InitTypeDef* CRYP_InitStruct);
+void CRYP_StructInit(CRYP_InitTypeDef* CRYP_InitStruct);
+void CRYP_KeyInit(CRYP_KeyInitTypeDef* CRYP_KeyInitStruct);
+void CRYP_KeyStructInit(CRYP_KeyInitTypeDef* CRYP_KeyInitStruct);
+void CRYP_IVInit(CRYP_IVInitTypeDef* CRYP_IVInitStruct);
+void CRYP_IVStructInit(CRYP_IVInitTypeDef* CRYP_IVInitStruct);
+void CRYP_Cmd(FunctionalState NewState);
+
+/* CRYP Data processing functions *********************************************/
+void CRYP_DataIn(uint32_t Data);
+uint32_t CRYP_DataOut(void);
+void CRYP_FIFOFlush(void);
+
+/* CRYP Context swapping functions ********************************************/
+ErrorStatus CRYP_SaveContext(CRYP_Context* CRYP_ContextSave,
+ CRYP_KeyInitTypeDef* CRYP_KeyInitStruct);
+void CRYP_RestoreContext(CRYP_Context* CRYP_ContextRestore);
+
+/* CRYP's DMA interface function **********************************************/
+void CRYP_DMACmd(uint8_t CRYP_DMAReq, FunctionalState NewState);
+
+/* Interrupts and flags management functions **********************************/
+void CRYP_ITConfig(uint8_t CRYP_IT, FunctionalState NewState);
+ITStatus CRYP_GetITStatus(uint8_t CRYP_IT);
+FlagStatus CRYP_GetFlagStatus(uint8_t CRYP_FLAG);
+
+/* High Level AES functions **************************************************/
+ErrorStatus CRYP_AES_ECB(uint8_t Mode,
+ uint8_t *Key, uint16_t Keysize,
+ uint8_t *Input, uint32_t Ilength,
+ uint8_t *Output);
+
+ErrorStatus CRYP_AES_CBC(uint8_t Mode,
+ uint8_t InitVectors[16],
+ uint8_t *Key, uint16_t Keysize,
+ uint8_t *Input, uint32_t Ilength,
+ uint8_t *Output);
+
+ErrorStatus CRYP_AES_CTR(uint8_t Mode,
+ uint8_t InitVectors[16],
+ uint8_t *Key, uint16_t Keysize,
+ uint8_t *Input, uint32_t Ilength,
+ uint8_t *Output);
+
+/* High Level TDES functions **************************************************/
+ErrorStatus CRYP_TDES_ECB(uint8_t Mode,
+ uint8_t Key[24],
+ uint8_t *Input, uint32_t Ilength,
+ uint8_t *Output);
+
+ErrorStatus CRYP_TDES_CBC(uint8_t Mode,
+ uint8_t Key[24],
+ uint8_t InitVectors[8],
+ uint8_t *Input, uint32_t Ilength,
+ uint8_t *Output);
+
+/* High Level DES functions **************************************************/
+ErrorStatus CRYP_DES_ECB(uint8_t Mode,
+ uint8_t Key[8],
+ uint8_t *Input, uint32_t Ilength,
+ uint8_t *Output);
+
+ErrorStatus CRYP_DES_CBC(uint8_t Mode,
+ uint8_t Key[8],
+ uint8_t InitVectors[8],
+ uint8_t *Input,uint32_t Ilength,
+ uint8_t *Output);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*__STM32F2xx_CRYP_H */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/inc/stm32f2xx_dac.h b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/inc/stm32f2xx_dac.h
new file mode 100644
index 0000000..2a0afc3
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/inc/stm32f2xx_dac.h
@@ -0,0 +1,304 @@
+/**
+ ******************************************************************************
+ * @file stm32f2xx_dac.h
+ * @author MCD Application Team
+ * @version V1.1.2
+ * @date 05-March-2012
+ * @brief This file contains all the functions prototypes for the DAC firmware
+ * 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 __STM32F2xx_DAC_H
+#define __STM32F2xx_DAC_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f2xx.h"
+
+/** @addtogroup STM32F2xx_StdPeriph_Driver
+ * @{
+ */
+
+/** @addtogroup DAC
+ * @{
+ */
+
+/* Exported types ------------------------------------------------------------*/
+
+/**
+ * @brief DAC Init structure definition
+ */
+
+typedef struct
+{
+ uint32_t DAC_Trigger; /*!< Specifies the external trigger for the selected DAC channel.
+ This parameter can be a value of @ref DAC_trigger_selection */
+
+ uint32_t DAC_WaveGeneration; /*!< Specifies whether DAC channel noise waves or triangle waves
+ are generated, or whether no wave is generated.
+ This parameter can be a value of @ref DAC_wave_generation */
+
+ uint32_t DAC_LFSRUnmask_TriangleAmplitude; /*!< Specifies the LFSR mask for noise wave generation or
+ the maximum amplitude triangle generation for the DAC channel.
+ This parameter can be a value of @ref DAC_lfsrunmask_triangleamplitude */
+
+ uint32_t DAC_OutputBuffer; /*!< Specifies whether the DAC channel output buffer is enabled or disabled.
+ This parameter can be a value of @ref DAC_output_buffer */
+}DAC_InitTypeDef;
+
+/* Exported constants --------------------------------------------------------*/
+
+/** @defgroup DAC_Exported_Constants
+ * @{
+ */
+
+/** @defgroup DAC_trigger_selection
+ * @{
+ */
+
+#define DAC_Trigger_None ((uint32_t)0x00000000) /*!< Conversion is automatic once the DAC1_DHRxxxx register
+ has been loaded, and not by external trigger */
+#define DAC_Trigger_T2_TRGO ((uint32_t)0x00000024) /*!< TIM2 TRGO selected as external conversion trigger for DAC channel */
+#define DAC_Trigger_T4_TRGO ((uint32_t)0x0000002C) /*!< TIM4 TRGO selected as external conversion trigger for DAC channel */
+#define DAC_Trigger_T5_TRGO ((uint32_t)0x0000001C) /*!< TIM5 TRGO selected as external conversion trigger for DAC channel */
+#define DAC_Trigger_T6_TRGO ((uint32_t)0x00000004) /*!< TIM6 TRGO selected as external conversion trigger for DAC channel */
+#define DAC_Trigger_T7_TRGO ((uint32_t)0x00000014) /*!< TIM7 TRGO selected as external conversion trigger for DAC channel */
+#define DAC_Trigger_T8_TRGO ((uint32_t)0x0000000C) /*!< TIM8 TRGO selected as external conversion trigger for DAC channel */
+
+#define DAC_Trigger_Ext_IT9 ((uint32_t)0x00000034) /*!< EXTI Line9 event selected as external conversion trigger for DAC channel */
+#define DAC_Trigger_Software ((uint32_t)0x0000003C) /*!< Conversion started by software trigger for DAC channel */
+
+#define IS_DAC_TRIGGER(TRIGGER) (((TRIGGER) == DAC_Trigger_None) || \
+ ((TRIGGER) == DAC_Trigger_T6_TRGO) || \
+ ((TRIGGER) == DAC_Trigger_T8_TRGO) || \
+ ((TRIGGER) == DAC_Trigger_T7_TRGO) || \
+ ((TRIGGER) == DAC_Trigger_T5_TRGO) || \
+ ((TRIGGER) == DAC_Trigger_T2_TRGO) || \
+ ((TRIGGER) == DAC_Trigger_T4_TRGO) || \
+ ((TRIGGER) == DAC_Trigger_Ext_IT9) || \
+ ((TRIGGER) == DAC_Trigger_Software))
+
+/**
+ * @}
+ */
+
+/** @defgroup DAC_wave_generation
+ * @{
+ */
+
+#define DAC_WaveGeneration_None ((uint32_t)0x00000000)
+#define DAC_WaveGeneration_Noise ((uint32_t)0x00000040)
+#define DAC_WaveGeneration_Triangle ((uint32_t)0x00000080)
+#define IS_DAC_GENERATE_WAVE(WAVE) (((WAVE) == DAC_WaveGeneration_None) || \
+ ((WAVE) == DAC_WaveGeneration_Noise) || \
+ ((WAVE) == DAC_WaveGeneration_Triangle))
+/**
+ * @}
+ */
+
+/** @defgroup DAC_lfsrunmask_triangleamplitude
+ * @{
+ */
+
+#define DAC_LFSRUnmask_Bit0 ((uint32_t)0x00000000) /*!< Unmask DAC channel LFSR bit0 for noise wave generation */
+#define DAC_LFSRUnmask_Bits1_0 ((uint32_t)0x00000100) /*!< Unmask DAC channel LFSR bit[1:0] for noise wave generation */
+#define DAC_LFSRUnmask_Bits2_0 ((uint32_t)0x00000200) /*!< Unmask DAC channel LFSR bit[2:0] for noise wave generation */
+#define DAC_LFSRUnmask_Bits3_0 ((uint32_t)0x00000300) /*!< Unmask DAC channel LFSR bit[3:0] for noise wave generation */
+#define DAC_LFSRUnmask_Bits4_0 ((uint32_t)0x00000400) /*!< Unmask DAC channel LFSR bit[4:0] for noise wave generation */
+#define DAC_LFSRUnmask_Bits5_0 ((uint32_t)0x00000500) /*!< Unmask DAC channel LFSR bit[5:0] for noise wave generation */
+#define DAC_LFSRUnmask_Bits6_0 ((uint32_t)0x00000600) /*!< Unmask DAC channel LFSR bit[6:0] for noise wave generation */
+#define DAC_LFSRUnmask_Bits7_0 ((uint32_t)0x00000700) /*!< Unmask DAC channel LFSR bit[7:0] for noise wave generation */
+#define DAC_LFSRUnmask_Bits8_0 ((uint32_t)0x00000800) /*!< Unmask DAC channel LFSR bit[8:0] for noise wave generation */
+#define DAC_LFSRUnmask_Bits9_0 ((uint32_t)0x00000900) /*!< Unmask DAC channel LFSR bit[9:0] for noise wave generation */
+#define DAC_LFSRUnmask_Bits10_0 ((uint32_t)0x00000A00) /*!< Unmask DAC channel LFSR bit[10:0] for noise wave generation */
+#define DAC_LFSRUnmask_Bits11_0 ((uint32_t)0x00000B00) /*!< Unmask DAC channel LFSR bit[11:0] for noise wave generation */
+#define DAC_TriangleAmplitude_1 ((uint32_t)0x00000000) /*!< Select max triangle amplitude of 1 */
+#define DAC_TriangleAmplitude_3 ((uint32_t)0x00000100) /*!< Select max triangle amplitude of 3 */
+#define DAC_TriangleAmplitude_7 ((uint32_t)0x00000200) /*!< Select max triangle amplitude of 7 */
+#define DAC_TriangleAmplitude_15 ((uint32_t)0x00000300) /*!< Select max triangle amplitude of 15 */
+#define DAC_TriangleAmplitude_31 ((uint32_t)0x00000400) /*!< Select max triangle amplitude of 31 */
+#define DAC_TriangleAmplitude_63 ((uint32_t)0x00000500) /*!< Select max triangle amplitude of 63 */
+#define DAC_TriangleAmplitude_127 ((uint32_t)0x00000600) /*!< Select max triangle amplitude of 127 */
+#define DAC_TriangleAmplitude_255 ((uint32_t)0x00000700) /*!< Select max triangle amplitude of 255 */
+#define DAC_TriangleAmplitude_511 ((uint32_t)0x00000800) /*!< Select max triangle amplitude of 511 */
+#define DAC_TriangleAmplitude_1023 ((uint32_t)0x00000900) /*!< Select max triangle amplitude of 1023 */
+#define DAC_TriangleAmplitude_2047 ((uint32_t)0x00000A00) /*!< Select max triangle amplitude of 2047 */
+#define DAC_TriangleAmplitude_4095 ((uint32_t)0x00000B00) /*!< Select max triangle amplitude of 4095 */
+
+#define IS_DAC_LFSR_UNMASK_TRIANGLE_AMPLITUDE(VALUE) (((VALUE) == DAC_LFSRUnmask_Bit0) || \
+ ((VALUE) == DAC_LFSRUnmask_Bits1_0) || \
+ ((VALUE) == DAC_LFSRUnmask_Bits2_0) || \
+ ((VALUE) == DAC_LFSRUnmask_Bits3_0) || \
+ ((VALUE) == DAC_LFSRUnmask_Bits4_0) || \
+ ((VALUE) == DAC_LFSRUnmask_Bits5_0) || \
+ ((VALUE) == DAC_LFSRUnmask_Bits6_0) || \
+ ((VALUE) == DAC_LFSRUnmask_Bits7_0) || \
+ ((VALUE) == DAC_LFSRUnmask_Bits8_0) || \
+ ((VALUE) == DAC_LFSRUnmask_Bits9_0) || \
+ ((VALUE) == DAC_LFSRUnmask_Bits10_0) || \
+ ((VALUE) == DAC_LFSRUnmask_Bits11_0) || \
+ ((VALUE) == DAC_TriangleAmplitude_1) || \
+ ((VALUE) == DAC_TriangleAmplitude_3) || \
+ ((VALUE) == DAC_TriangleAmplitude_7) || \
+ ((VALUE) == DAC_TriangleAmplitude_15) || \
+ ((VALUE) == DAC_TriangleAmplitude_31) || \
+ ((VALUE) == DAC_TriangleAmplitude_63) || \
+ ((VALUE) == DAC_TriangleAmplitude_127) || \
+ ((VALUE) == DAC_TriangleAmplitude_255) || \
+ ((VALUE) == DAC_TriangleAmplitude_511) || \
+ ((VALUE) == DAC_TriangleAmplitude_1023) || \
+ ((VALUE) == DAC_TriangleAmplitude_2047) || \
+ ((VALUE) == DAC_TriangleAmplitude_4095))
+/**
+ * @}
+ */
+
+/** @defgroup DAC_output_buffer
+ * @{
+ */
+
+#define DAC_OutputBuffer_Enable ((uint32_t)0x00000000)
+#define DAC_OutputBuffer_Disable ((uint32_t)0x00000002)
+#define IS_DAC_OUTPUT_BUFFER_STATE(STATE) (((STATE) == DAC_OutputBuffer_Enable) || \
+ ((STATE) == DAC_OutputBuffer_Disable))
+/**
+ * @}
+ */
+
+/** @defgroup DAC_Channel_selection
+ * @{
+ */
+
+#define DAC_Channel_1 ((uint32_t)0x00000000)
+#define DAC_Channel_2 ((uint32_t)0x00000010)
+#define IS_DAC_CHANNEL(CHANNEL) (((CHANNEL) == DAC_Channel_1) || \
+ ((CHANNEL) == DAC_Channel_2))
+/**
+ * @}
+ */
+
+/** @defgroup DAC_data_alignement
+ * @{
+ */
+
+#define DAC_Align_12b_R ((uint32_t)0x00000000)
+#define DAC_Align_12b_L ((uint32_t)0x00000004)
+#define DAC_Align_8b_R ((uint32_t)0x00000008)
+#define IS_DAC_ALIGN(ALIGN) (((ALIGN) == DAC_Align_12b_R) || \
+ ((ALIGN) == DAC_Align_12b_L) || \
+ ((ALIGN) == DAC_Align_8b_R))
+/**
+ * @}
+ */
+
+/** @defgroup DAC_wave_generation
+ * @{
+ */
+
+#define DAC_Wave_Noise ((uint32_t)0x00000040)
+#define DAC_Wave_Triangle ((uint32_t)0x00000080)
+#define IS_DAC_WAVE(WAVE) (((WAVE) == DAC_Wave_Noise) || \
+ ((WAVE) == DAC_Wave_Triangle))
+/**
+ * @}
+ */
+
+/** @defgroup DAC_data
+ * @{
+ */
+
+#define IS_DAC_DATA(DATA) ((DATA) <= 0xFFF0)
+/**
+ * @}
+ */
+
+/** @defgroup DAC_interrupts_definition
+ * @{
+ */
+#define DAC_IT_DMAUDR ((uint32_t)0x00002000)
+#define IS_DAC_IT(IT) (((IT) == DAC_IT_DMAUDR))
+
+/**
+ * @}
+ */
+
+/** @defgroup DAC_flags_definition
+ * @{
+ */
+
+#define DAC_FLAG_DMAUDR ((uint32_t)0x00002000)
+#define IS_DAC_FLAG(FLAG) (((FLAG) == DAC_FLAG_DMAUDR))
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions --------------------------------------------------------*/
+
+/* Function used to set the DAC configuration to the default reset state *****/
+void DAC_DeInit(void);
+
+/* DAC channels configuration: trigger, output buffer, data format functions */
+void DAC_Init(uint32_t DAC_Channel, DAC_InitTypeDef* DAC_InitStruct);
+void DAC_StructInit(DAC_InitTypeDef* DAC_InitStruct);
+void DAC_Cmd(uint32_t DAC_Channel, FunctionalState NewState);
+void DAC_SoftwareTriggerCmd(uint32_t DAC_Channel, FunctionalState NewState);
+void DAC_DualSoftwareTriggerCmd(FunctionalState NewState);
+void DAC_WaveGenerationCmd(uint32_t DAC_Channel, uint32_t DAC_Wave, FunctionalState NewState);
+void DAC_SetChannel1Data(uint32_t DAC_Align, uint16_t Data);
+void DAC_SetChannel2Data(uint32_t DAC_Align, uint16_t Data);
+void DAC_SetDualChannelData(uint32_t DAC_Align, uint16_t Data2, uint16_t Data1);
+uint16_t DAC_GetDataOutputValue(uint32_t DAC_Channel);
+
+/* DMA management functions ***************************************************/
+void DAC_DMACmd(uint32_t DAC_Channel, FunctionalState NewState);
+
+/* Interrupts and flags management functions **********************************/
+void DAC_ITConfig(uint32_t DAC_Channel, uint32_t DAC_IT, FunctionalState NewState);
+FlagStatus DAC_GetFlagStatus(uint32_t DAC_Channel, uint32_t DAC_FLAG);
+void DAC_ClearFlag(uint32_t DAC_Channel, uint32_t DAC_FLAG);
+ITStatus DAC_GetITStatus(uint32_t DAC_Channel, uint32_t DAC_IT);
+void DAC_ClearITPendingBit(uint32_t DAC_Channel, uint32_t DAC_IT);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*__STM32F2xx_DAC_H */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/inc/stm32f2xx_dbgmcu.h b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/inc/stm32f2xx_dbgmcu.h
new file mode 100644
index 0000000..bd64c25
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/inc/stm32f2xx_dbgmcu.h
@@ -0,0 +1,109 @@
+/**
+ ******************************************************************************
+ * @file stm32f2xx_dbgmcu.h
+ * @author MCD Application Team
+ * @version V1.1.2
+ * @date 05-March-2012
+ * @brief This file contains all the functions prototypes for the DBGMCU firmware 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 __STM32F2xx_DBGMCU_H
+#define __STM32F2xx_DBGMCU_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f2xx.h"
+
+/** @addtogroup STM32F2xx_StdPeriph_Driver
+ * @{
+ */
+
+/** @addtogroup DBGMCU
+ * @{
+ */
+
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+
+/** @defgroup DBGMCU_Exported_Constants
+ * @{
+ */
+#define DBGMCU_SLEEP ((uint32_t)0x00000001)
+#define DBGMCU_STOP ((uint32_t)0x00000002)
+#define DBGMCU_STANDBY ((uint32_t)0x00000004)
+#define IS_DBGMCU_PERIPH(PERIPH) ((((PERIPH) & 0xFFFFFFF8) == 0x00) && ((PERIPH) != 0x00))
+
+#define DBGMCU_TIM2_STOP ((uint32_t)0x00000001)
+#define DBGMCU_TIM3_STOP ((uint32_t)0x00000002)
+#define DBGMCU_TIM4_STOP ((uint32_t)0x00000004)
+#define DBGMCU_TIM5_STOP ((uint32_t)0x00000008)
+#define DBGMCU_TIM6_STOP ((uint32_t)0x00000010)
+#define DBGMCU_TIM7_STOP ((uint32_t)0x00000020)
+#define DBGMCU_TIM12_STOP ((uint32_t)0x00000040)
+#define DBGMCU_TIM13_STOP ((uint32_t)0x00000080)
+#define DBGMCU_TIM14_STOP ((uint32_t)0x00000100)
+#define DBGMCU_RTC_STOP ((uint32_t)0x00000400)
+#define DBGMCU_WWDG_STOP ((uint32_t)0x00000800)
+#define DBGMCU_IWDG_STOP ((uint32_t)0x00001000)
+#define DBGMCU_I2C1_SMBUS_TIMEOUT ((uint32_t)0x00200000)
+#define DBGMCU_I2C2_SMBUS_TIMEOUT ((uint32_t)0x00400000)
+#define DBGMCU_I2C3_SMBUS_TIMEOUT ((uint32_t)0x00800000)
+#define DBGMCU_CAN1_STOP ((uint32_t)0x02000000)
+#define DBGMCU_CAN2_STOP ((uint32_t)0x04000000)
+#define IS_DBGMCU_APB1PERIPH(PERIPH) ((((PERIPH) & 0xF91FE200) == 0x00) && ((PERIPH) != 0x00))
+
+#define DBGMCU_TIM1_STOP ((uint32_t)0x00000001)
+#define DBGMCU_TIM8_STOP ((uint32_t)0x00000002)
+#define DBGMCU_TIM9_STOP ((uint32_t)0x00010000)
+#define DBGMCU_TIM10_STOP ((uint32_t)0x00020000)
+#define DBGMCU_TIM11_STOP ((uint32_t)0x00040000)
+#define IS_DBGMCU_APB2PERIPH(PERIPH) ((((PERIPH) & 0xFFF8FFFC) == 0x00) && ((PERIPH) != 0x00))
+/**
+ * @}
+ */
+
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions --------------------------------------------------------*/
+uint32_t DBGMCU_GetREVID(void);
+uint32_t DBGMCU_GetDEVID(void);
+void DBGMCU_Config(uint32_t DBGMCU_Periph, FunctionalState NewState);
+void DBGMCU_APB1PeriphConfig(uint32_t DBGMCU_Periph, FunctionalState NewState);
+void DBGMCU_APB2PeriphConfig(uint32_t DBGMCU_Periph, FunctionalState NewState);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F2xx_DBGMCU_H */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/inc/stm32f2xx_dcmi.h b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/inc/stm32f2xx_dcmi.h
new file mode 100644
index 0000000..d6baafd
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/inc/stm32f2xx_dcmi.h
@@ -0,0 +1,312 @@
+/**
+ ******************************************************************************
+ * @file stm32f2xx_dcmi.h
+ * @author MCD Application Team
+ * @version V1.1.2
+ * @date 05-March-2012
+ * @brief This file contains all the functions prototypes for the DCMI firmware 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 __STM32F2xx_DCMI_H
+#define __STM32F2xx_DCMI_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f2xx.h"
+
+/** @addtogroup STM32F2xx_StdPeriph_Driver
+ * @{
+ */
+
+/** @addtogroup DCMI
+ * @{
+ */
+
+/* Exported types ------------------------------------------------------------*/
+/**
+ * @brief DCMI Init structure definition
+ */
+typedef struct
+{
+ uint16_t DCMI_CaptureMode; /*!< Specifies the Capture Mode: Continuous or Snapshot.
+ This parameter can be a value of @ref DCMI_Capture_Mode */
+
+ uint16_t DCMI_SynchroMode; /*!< Specifies the Synchronization Mode: Hardware or Embedded.
+ This parameter can be a value of @ref DCMI_Synchronization_Mode */
+
+ uint16_t DCMI_PCKPolarity; /*!< Specifies the Pixel clock polarity: Falling or Rising.
+ This parameter can be a value of @ref DCMI_PIXCK_Polarity */
+
+ uint16_t DCMI_VSPolarity; /*!< Specifies the Vertical synchronization polarity: High or Low.
+ This parameter can be a value of @ref DCMI_VSYNC_Polarity */
+
+ uint16_t DCMI_HSPolarity; /*!< Specifies the Horizontal synchronization polarity: High or Low.
+ This parameter can be a value of @ref DCMI_HSYNC_Polarity */
+
+ uint16_t DCMI_CaptureRate; /*!< Specifies the frequency of frame capture: All, 1/2 or 1/4.
+ This parameter can be a value of @ref DCMI_Capture_Rate */
+
+ uint16_t DCMI_ExtendedDataMode; /*!< Specifies the data width: 8-bit, 10-bit, 12-bit or 14-bit.
+ This parameter can be a value of @ref DCMI_Extended_Data_Mode */
+} DCMI_InitTypeDef;
+
+/**
+ * @brief DCMI CROP Init structure definition
+ */
+typedef struct
+{
+ uint16_t DCMI_VerticalStartLine; /*!< Specifies the Vertical start line count from which the image capture
+ will start. This parameter can be a value between 0x00 and 0x1FFF */
+
+ uint16_t DCMI_HorizontalOffsetCount; /*!< Specifies the number of pixel clocks to count before starting a capture.
+ This parameter can be a value between 0x00 and 0x3FFF */
+
+ uint16_t DCMI_VerticalLineCount; /*!< Specifies the number of lines to be captured from the starting point.
+ This parameter can be a value between 0x00 and 0x3FFF */
+
+ uint16_t DCMI_CaptureCount; /*!< Specifies the number of pixel clocks to be captured from the starting
+ point on the same line.
+ This parameter can be a value between 0x00 and 0x3FFF */
+} DCMI_CROPInitTypeDef;
+
+/**
+ * @brief DCMI Embedded Synchronisation CODE Init structure definition
+ */
+typedef struct
+{
+ uint8_t DCMI_FrameStartCode; /*!< Specifies the code of the frame start delimiter. */
+ uint8_t DCMI_LineStartCode; /*!< Specifies the code of the line start delimiter. */
+ uint8_t DCMI_LineEndCode; /*!< Specifies the code of the line end delimiter. */
+ uint8_t DCMI_FrameEndCode; /*!< Specifies the code of the frame end delimiter. */
+} DCMI_CodesInitTypeDef;
+
+/* Exported constants --------------------------------------------------------*/
+
+/** @defgroup DCMI_Exported_Constants
+ * @{
+ */
+
+/** @defgroup DCMI_Capture_Mode
+ * @{
+ */
+#define DCMI_CaptureMode_Continuous ((uint16_t)0x0000) /*!< The received data are transferred continuously
+ into the destination memory through the DMA */
+#define DCMI_CaptureMode_SnapShot ((uint16_t)0x0002) /*!< Once activated, the interface waits for the start of
+ frame and then transfers a single frame through the DMA */
+#define IS_DCMI_CAPTURE_MODE(MODE)(((MODE) == DCMI_CaptureMode_Continuous) || \
+ ((MODE) == DCMI_CaptureMode_SnapShot))
+/**
+ * @}
+ */
+
+
+/** @defgroup DCMI_Synchronization_Mode
+ * @{
+ */
+#define DCMI_SynchroMode_Hardware ((uint16_t)0x0000) /*!< Hardware synchronization data capture (frame/line start/stop)
+ is synchronized with the HSYNC/VSYNC signals */
+#define DCMI_SynchroMode_Embedded ((uint16_t)0x0010) /*!< Embedded synchronization data capture is synchronized with
+ synchronization codes embedded in the data flow */
+#define IS_DCMI_SYNCHRO(MODE)(((MODE) == DCMI_SynchroMode_Hardware) || \
+ ((MODE) == DCMI_SynchroMode_Embedded))
+/**
+ * @}
+ */
+
+
+/** @defgroup DCMI_PIXCK_Polarity
+ * @{
+ */
+#define DCMI_PCKPolarity_Falling ((uint16_t)0x0000) /*!< Pixel clock active on Falling edge */
+#define DCMI_PCKPolarity_Rising ((uint16_t)0x0020) /*!< Pixel clock active on Rising edge */
+#define IS_DCMI_PCKPOLARITY(POLARITY)(((POLARITY) == DCMI_PCKPolarity_Falling) || \
+ ((POLARITY) == DCMI_PCKPolarity_Rising))
+/**
+ * @}
+ */
+
+
+/** @defgroup DCMI_VSYNC_Polarity
+ * @{
+ */
+#define DCMI_VSPolarity_Low ((uint16_t)0x0000) /*!< Vertical synchronization active Low */
+#define DCMI_VSPolarity_High ((uint16_t)0x0080) /*!< Vertical synchronization active High */
+#define IS_DCMI_VSPOLARITY(POLARITY)(((POLARITY) == DCMI_VSPolarity_Low) || \
+ ((POLARITY) == DCMI_VSPolarity_High))
+/**
+ * @}
+ */
+
+
+/** @defgroup DCMI_HSYNC_Polarity
+ * @{
+ */
+#define DCMI_HSPolarity_Low ((uint16_t)0x0000) /*!< Horizontal synchronization active Low */
+#define DCMI_HSPolarity_High ((uint16_t)0x0040) /*!< Horizontal synchronization active High */
+#define IS_DCMI_HSPOLARITY(POLARITY)(((POLARITY) == DCMI_HSPolarity_Low) || \
+ ((POLARITY) == DCMI_HSPolarity_High))
+/**
+ * @}
+ */
+
+
+/** @defgroup DCMI_Capture_Rate
+ * @{
+ */
+#define DCMI_CaptureRate_All_Frame ((uint16_t)0x0000) /*!< All frames are captured */
+#define DCMI_CaptureRate_1of2_Frame ((uint16_t)0x0100) /*!< Every alternate frame captured */
+#define DCMI_CaptureRate_1of4_Frame ((uint16_t)0x0200) /*!< One frame in 4 frames captured */
+#define IS_DCMI_CAPTURE_RATE(RATE) (((RATE) == DCMI_CaptureRate_All_Frame) || \
+ ((RATE) == DCMI_CaptureRate_1of2_Frame) ||\
+ ((RATE) == DCMI_CaptureRate_1of4_Frame))
+/**
+ * @}
+ */
+
+
+/** @defgroup DCMI_Extended_Data_Mode
+ * @{
+ */
+#define DCMI_ExtendedDataMode_8b ((uint16_t)0x0000) /*!< Interface captures 8-bit data on every pixel clock */
+#define DCMI_ExtendedDataMode_10b ((uint16_t)0x0400) /*!< Interface captures 10-bit data on every pixel clock */
+#define DCMI_ExtendedDataMode_12b ((uint16_t)0x0800) /*!< Interface captures 12-bit data on every pixel clock */
+#define DCMI_ExtendedDataMode_14b ((uint16_t)0x0C00) /*!< Interface captures 14-bit data on every pixel clock */
+#define IS_DCMI_EXTENDED_DATA(DATA)(((DATA) == DCMI_ExtendedDataMode_8b) || \
+ ((DATA) == DCMI_ExtendedDataMode_10b) ||\
+ ((DATA) == DCMI_ExtendedDataMode_12b) ||\
+ ((DATA) == DCMI_ExtendedDataMode_14b))
+/**
+ * @}
+ */
+
+
+/** @defgroup DCMI_interrupt_sources
+ * @{
+ */
+#define DCMI_IT_FRAME ((uint16_t)0x0001)
+#define DCMI_IT_OVF ((uint16_t)0x0002)
+#define DCMI_IT_ERR ((uint16_t)0x0004)
+#define DCMI_IT_VSYNC ((uint16_t)0x0008)
+#define DCMI_IT_LINE ((uint16_t)0x0010)
+#define IS_DCMI_CONFIG_IT(IT) ((((IT) & (uint16_t)0xFFE0) == 0x0000) && ((IT) != 0x0000))
+#define IS_DCMI_GET_IT(IT) (((IT) == DCMI_IT_FRAME) || \
+ ((IT) == DCMI_IT_OVF) || \
+ ((IT) == DCMI_IT_ERR) || \
+ ((IT) == DCMI_IT_VSYNC) || \
+ ((IT) == DCMI_IT_LINE))
+/**
+ * @}
+ */
+
+
+/** @defgroup DCMI_Flags
+ * @{
+ */
+/**
+ * @brief DCMI SR register
+ */
+#define DCMI_FLAG_HSYNC ((uint16_t)0x2001)
+#define DCMI_FLAG_VSYNC ((uint16_t)0x2002)
+#define DCMI_FLAG_FNE ((uint16_t)0x2004)
+/**
+ * @brief DCMI RISR register
+ */
+#define DCMI_FLAG_FRAMERI ((uint16_t)0x0001)
+#define DCMI_FLAG_OVFRI ((uint16_t)0x0002)
+#define DCMI_FLAG_ERRRI ((uint16_t)0x0004)
+#define DCMI_FLAG_VSYNCRI ((uint16_t)0x0008)
+#define DCMI_FLAG_LINERI ((uint16_t)0x0010)
+/**
+ * @brief DCMI MISR register
+ */
+#define DCMI_FLAG_FRAMEMI ((uint16_t)0x1001)
+#define DCMI_FLAG_OVFMI ((uint16_t)0x1002)
+#define DCMI_FLAG_ERRMI ((uint16_t)0x1004)
+#define DCMI_FLAG_VSYNCMI ((uint16_t)0x1008)
+#define DCMI_FLAG_LINEMI ((uint16_t)0x1010)
+#define IS_DCMI_GET_FLAG(FLAG) (((FLAG) == DCMI_FLAG_HSYNC) || \
+ ((FLAG) == DCMI_FLAG_VSYNC) || \
+ ((FLAG) == DCMI_FLAG_FNE) || \
+ ((FLAG) == DCMI_FLAG_FRAMERI) || \
+ ((FLAG) == DCMI_FLAG_OVFRI) || \
+ ((FLAG) == DCMI_FLAG_ERRRI) || \
+ ((FLAG) == DCMI_FLAG_VSYNCRI) || \
+ ((FLAG) == DCMI_FLAG_LINERI) || \
+ ((FLAG) == DCMI_FLAG_FRAMEMI) || \
+ ((FLAG) == DCMI_FLAG_OVFMI) || \
+ ((FLAG) == DCMI_FLAG_ERRMI) || \
+ ((FLAG) == DCMI_FLAG_VSYNCMI) || \
+ ((FLAG) == DCMI_FLAG_LINEMI))
+
+#define IS_DCMI_CLEAR_FLAG(FLAG) ((((FLAG) & (uint16_t)0xFFE0) == 0x0000) && ((FLAG) != 0x0000))
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions --------------------------------------------------------*/
+
+/* Function used to set the DCMI configuration to the default reset state ****/
+void DCMI_DeInit(void);
+
+/* Initialization and Configuration functions *********************************/
+void DCMI_Init(DCMI_InitTypeDef* DCMI_InitStruct);
+void DCMI_StructInit(DCMI_InitTypeDef* DCMI_InitStruct);
+void DCMI_CROPConfig(DCMI_CROPInitTypeDef* DCMI_CROPInitStruct);
+void DCMI_CROPCmd(FunctionalState NewState);
+void DCMI_SetEmbeddedSynchroCodes(DCMI_CodesInitTypeDef* DCMI_CodesInitStruct);
+void DCMI_JPEGCmd(FunctionalState NewState);
+
+/* Image capture functions ****************************************************/
+void DCMI_Cmd(FunctionalState NewState);
+void DCMI_CaptureCmd(FunctionalState NewState);
+uint32_t DCMI_ReadData(void);
+
+/* Interrupts and flags management functions **********************************/
+void DCMI_ITConfig(uint16_t DCMI_IT, FunctionalState NewState);
+FlagStatus DCMI_GetFlagStatus(uint16_t DCMI_FLAG);
+void DCMI_ClearFlag(uint16_t DCMI_FLAG);
+ITStatus DCMI_GetITStatus(uint16_t DCMI_IT);
+void DCMI_ClearITPendingBit(uint16_t DCMI_IT);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*__STM32F2xx_DCMI_H */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/inc/stm32f2xx_dma.h b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/inc/stm32f2xx_dma.h
new file mode 100644
index 0000000..2f31e14
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/inc/stm32f2xx_dma.h
@@ -0,0 +1,609 @@
+/**
+ ******************************************************************************
+ * @file stm32f2xx_dma.h
+ * @author MCD Application Team
+ * @version V1.1.2
+ * @date 05-March-2012
+ * @brief This file contains all the functions prototypes for the DMA firmware
+ * 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 __STM32F2xx_DMA_H
+#define __STM32F2xx_DMA_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f2xx.h"
+
+/** @addtogroup STM32F2xx_StdPeriph_Driver
+ * @{
+ */
+
+/** @addtogroup DMA
+ * @{
+ */
+
+/* Exported types ------------------------------------------------------------*/
+
+/**
+ * @brief DMA Init structure definition
+ */
+
+typedef struct
+{
+ uint32_t DMA_Channel; /*!< Specifies the channel used for the specified stream.
+ This parameter can be a value of @ref DMA_channel */
+
+ uint32_t DMA_PeripheralBaseAddr; /*!< Specifies the peripheral base address for DMAy Streamx. */
+
+ uint32_t DMA_Memory0BaseAddr; /*!< Specifies the memory 0 base address for DMAy Streamx.
+ This memory is the default memory used when double buffer mode is
+ not enabled. */
+
+ uint32_t DMA_DIR; /*!< Specifies if the data will be transferred from memory to peripheral,
+ from memory to memory or from peripheral to memory.
+ This parameter can be a value of @ref DMA_data_transfer_direction */
+
+ uint32_t DMA_BufferSize; /*!< Specifies the buffer size, in data unit, of the specified Stream.
+ The data unit is equal to the configuration set in DMA_PeripheralDataSize
+ or DMA_MemoryDataSize members depending in the transfer direction. */
+
+ uint32_t DMA_PeripheralInc; /*!< Specifies whether the Peripheral address register should be incremented or not.
+ This parameter can be a value of @ref DMA_peripheral_incremented_mode */
+
+ uint32_t DMA_MemoryInc; /*!< Specifies whether the memory address register should be incremented or not.
+ This parameter can be a value of @ref DMA_memory_incremented_mode */
+
+ uint32_t DMA_PeripheralDataSize; /*!< Specifies the Peripheral data width.
+ This parameter can be a value of @ref DMA_peripheral_data_size */
+
+ uint32_t DMA_MemoryDataSize; /*!< Specifies the Memory data width.
+ This parameter can be a value of @ref DMA_memory_data_size */
+
+ uint32_t DMA_Mode; /*!< Specifies the operation mode of the DMAy Streamx.
+ This parameter can be a value of @ref DMA_circular_normal_mode
+ @note The circular buffer mode cannot be used if the memory-to-memory
+ data transfer is configured on the selected Stream */
+
+ uint32_t DMA_Priority; /*!< Specifies the software priority for the DMAy Streamx.
+ This parameter can be a value of @ref DMA_priority_level */
+
+ uint32_t DMA_FIFOMode; /*!< Specifies if the FIFO mode or Direct mode will be used for the specified Stream.
+ This parameter can be a value of @ref DMA_fifo_direct_mode
+ @note The Direct mode (FIFO mode disabled) cannot be used if the
+ memory-to-memory data transfer is configured on the selected Stream */
+
+ uint32_t DMA_FIFOThreshold; /*!< Specifies the FIFO threshold level.
+ This parameter can be a value of @ref DMA_fifo_threshold_level */
+
+ uint32_t DMA_MemoryBurst; /*!< Specifies the Burst transfer configuration for the memory transfers.
+ It specifies the amount of data to be transferred in a single non interruptable
+ transaction. This parameter can be a value of @ref DMA_memory_burst
+ @note The burst mode is possible only if the address Increment mode is enabled. */
+
+ uint32_t DMA_PeripheralBurst; /*!< Specifies the Burst transfer configuration for the peripheral transfers.
+ It specifies the amount of data to be transferred in a single non interruptable
+ transaction. This parameter can be a value of @ref DMA_peripheral_burst
+ @note The burst mode is possible only if the address Increment mode is enabled. */
+}DMA_InitTypeDef;
+
+/* Exported constants --------------------------------------------------------*/
+
+/** @defgroup DMA_Exported_Constants
+ * @{
+ */
+
+#define IS_DMA_ALL_PERIPH(PERIPH) (((PERIPH) == DMA1_Stream0) || \
+ ((PERIPH) == DMA1_Stream1) || \
+ ((PERIPH) == DMA1_Stream2) || \
+ ((PERIPH) == DMA1_Stream3) || \
+ ((PERIPH) == DMA1_Stream4) || \
+ ((PERIPH) == DMA1_Stream5) || \
+ ((PERIPH) == DMA1_Stream6) || \
+ ((PERIPH) == DMA1_Stream7) || \
+ ((PERIPH) == DMA2_Stream0) || \
+ ((PERIPH) == DMA2_Stream1) || \
+ ((PERIPH) == DMA2_Stream2) || \
+ ((PERIPH) == DMA2_Stream3) || \
+ ((PERIPH) == DMA2_Stream4) || \
+ ((PERIPH) == DMA2_Stream5) || \
+ ((PERIPH) == DMA2_Stream6) || \
+ ((PERIPH) == DMA2_Stream7))
+
+#define IS_DMA_ALL_CONTROLLER(CONTROLLER) (((CONTROLLER) == DMA1) || \
+ ((CONTROLLER) == DMA2))
+
+/** @defgroup DMA_channel
+ * @{
+ */
+#define DMA_Channel_0 ((uint32_t)0x00000000)
+#define DMA_Channel_1 ((uint32_t)0x02000000)
+#define DMA_Channel_2 ((uint32_t)0x04000000)
+#define DMA_Channel_3 ((uint32_t)0x06000000)
+#define DMA_Channel_4 ((uint32_t)0x08000000)
+#define DMA_Channel_5 ((uint32_t)0x0A000000)
+#define DMA_Channel_6 ((uint32_t)0x0C000000)
+#define DMA_Channel_7 ((uint32_t)0x0E000000)
+
+#define IS_DMA_CHANNEL(CHANNEL) (((CHANNEL) == DMA_Channel_0) || \
+ ((CHANNEL) == DMA_Channel_1) || \
+ ((CHANNEL) == DMA_Channel_2) || \
+ ((CHANNEL) == DMA_Channel_3) || \
+ ((CHANNEL) == DMA_Channel_4) || \
+ ((CHANNEL) == DMA_Channel_5) || \
+ ((CHANNEL) == DMA_Channel_6) || \
+ ((CHANNEL) == DMA_Channel_7))
+/**
+ * @}
+ */
+
+
+/** @defgroup DMA_data_transfer_direction
+ * @{
+ */
+#define DMA_DIR_PeripheralToMemory ((uint32_t)0x00000000)
+#define DMA_DIR_MemoryToPeripheral ((uint32_t)0x00000040)
+#define DMA_DIR_MemoryToMemory ((uint32_t)0x00000080)
+
+#define IS_DMA_DIRECTION(DIRECTION) (((DIRECTION) == DMA_DIR_PeripheralToMemory ) || \
+ ((DIRECTION) == DMA_DIR_MemoryToPeripheral) || \
+ ((DIRECTION) == DMA_DIR_MemoryToMemory))
+/**
+ * @}
+ */
+
+
+/** @defgroup DMA_data_buffer_size
+ * @{
+ */
+#define IS_DMA_BUFFER_SIZE(SIZE) (((SIZE) >= 0x1) && ((SIZE) < 0x10000))
+/**
+ * @}
+ */
+
+
+/** @defgroup DMA_peripheral_incremented_mode
+ * @{
+ */
+#define DMA_PeripheralInc_Enable ((uint32_t)0x00000200)
+#define DMA_PeripheralInc_Disable ((uint32_t)0x00000000)
+
+#define IS_DMA_PERIPHERAL_INC_STATE(STATE) (((STATE) == DMA_PeripheralInc_Enable) || \
+ ((STATE) == DMA_PeripheralInc_Disable))
+/**
+ * @}
+ */
+
+
+/** @defgroup DMA_memory_incremented_mode
+ * @{
+ */
+#define DMA_MemoryInc_Enable ((uint32_t)0x00000400)
+#define DMA_MemoryInc_Disable ((uint32_t)0x00000000)
+
+#define IS_DMA_MEMORY_INC_STATE(STATE) (((STATE) == DMA_MemoryInc_Enable) || \
+ ((STATE) == DMA_MemoryInc_Disable))
+/**
+ * @}
+ */
+
+
+/** @defgroup DMA_peripheral_data_size
+ * @{
+ */
+#define DMA_PeripheralDataSize_Byte ((uint32_t)0x00000000)
+#define DMA_PeripheralDataSize_HalfWord ((uint32_t)0x00000800)
+#define DMA_PeripheralDataSize_Word ((uint32_t)0x00001000)
+
+#define IS_DMA_PERIPHERAL_DATA_SIZE(SIZE) (((SIZE) == DMA_PeripheralDataSize_Byte) || \
+ ((SIZE) == DMA_PeripheralDataSize_HalfWord) || \
+ ((SIZE) == DMA_PeripheralDataSize_Word))
+/**
+ * @}
+ */
+
+
+/** @defgroup DMA_memory_data_size
+ * @{
+ */
+#define DMA_MemoryDataSize_Byte ((uint32_t)0x00000000)
+#define DMA_MemoryDataSize_HalfWord ((uint32_t)0x00002000)
+#define DMA_MemoryDataSize_Word ((uint32_t)0x00004000)
+
+#define IS_DMA_MEMORY_DATA_SIZE(SIZE) (((SIZE) == DMA_MemoryDataSize_Byte) || \
+ ((SIZE) == DMA_MemoryDataSize_HalfWord) || \
+ ((SIZE) == DMA_MemoryDataSize_Word ))
+/**
+ * @}
+ */
+
+
+/** @defgroup DMA_circular_normal_mode
+ * @{
+ */
+#define DMA_Mode_Normal ((uint32_t)0x00000000)
+#define DMA_Mode_Circular ((uint32_t)0x00000100)
+
+#define IS_DMA_MODE(MODE) (((MODE) == DMA_Mode_Normal ) || \
+ ((MODE) == DMA_Mode_Circular))
+/**
+ * @}
+ */
+
+
+/** @defgroup DMA_priority_level
+ * @{
+ */
+#define DMA_Priority_Low ((uint32_t)0x00000000)
+#define DMA_Priority_Medium ((uint32_t)0x00010000)
+#define DMA_Priority_High ((uint32_t)0x00020000)
+#define DMA_Priority_VeryHigh ((uint32_t)0x00030000)
+
+#define IS_DMA_PRIORITY(PRIORITY) (((PRIORITY) == DMA_Priority_Low ) || \
+ ((PRIORITY) == DMA_Priority_Medium) || \
+ ((PRIORITY) == DMA_Priority_High) || \
+ ((PRIORITY) == DMA_Priority_VeryHigh))
+/**
+ * @}
+ */
+
+
+/** @defgroup DMA_fifo_direct_mode
+ * @{
+ */
+#define DMA_FIFOMode_Disable ((uint32_t)0x00000000)
+#define DMA_FIFOMode_Enable ((uint32_t)0x00000004)
+
+#define IS_DMA_FIFO_MODE_STATE(STATE) (((STATE) == DMA_FIFOMode_Disable ) || \
+ ((STATE) == DMA_FIFOMode_Enable))
+/**
+ * @}
+ */
+
+
+/** @defgroup DMA_fifo_threshold_level
+ * @{
+ */
+#define DMA_FIFOThreshold_1QuarterFull ((uint32_t)0x00000000)
+#define DMA_FIFOThreshold_HalfFull ((uint32_t)0x00000001)
+#define DMA_FIFOThreshold_3QuartersFull ((uint32_t)0x00000002)
+#define DMA_FIFOThreshold_Full ((uint32_t)0x00000003)
+
+#define IS_DMA_FIFO_THRESHOLD(THRESHOLD) (((THRESHOLD) == DMA_FIFOThreshold_1QuarterFull ) || \
+ ((THRESHOLD) == DMA_FIFOThreshold_HalfFull) || \
+ ((THRESHOLD) == DMA_FIFOThreshold_3QuartersFull) || \
+ ((THRESHOLD) == DMA_FIFOThreshold_Full))
+/**
+ * @}
+ */
+
+
+/** @defgroup DMA_memory_burst
+ * @{
+ */
+#define DMA_MemoryBurst_Single ((uint32_t)0x00000000)
+#define DMA_MemoryBurst_INC4 ((uint32_t)0x00800000)
+#define DMA_MemoryBurst_INC8 ((uint32_t)0x01000000)
+#define DMA_MemoryBurst_INC16 ((uint32_t)0x01800000)
+
+#define IS_DMA_MEMORY_BURST(BURST) (((BURST) == DMA_MemoryBurst_Single) || \
+ ((BURST) == DMA_MemoryBurst_INC4) || \
+ ((BURST) == DMA_MemoryBurst_INC8) || \
+ ((BURST) == DMA_MemoryBurst_INC16))
+/**
+ * @}
+ */
+
+
+/** @defgroup DMA_peripheral_burst
+ * @{
+ */
+#define DMA_PeripheralBurst_Single ((uint32_t)0x00000000)
+#define DMA_PeripheralBurst_INC4 ((uint32_t)0x00200000)
+#define DMA_PeripheralBurst_INC8 ((uint32_t)0x00400000)
+#define DMA_PeripheralBurst_INC16 ((uint32_t)0x00600000)
+
+#define IS_DMA_PERIPHERAL_BURST(BURST) (((BURST) == DMA_PeripheralBurst_Single) || \
+ ((BURST) == DMA_PeripheralBurst_INC4) || \
+ ((BURST) == DMA_PeripheralBurst_INC8) || \
+ ((BURST) == DMA_PeripheralBurst_INC16))
+/**
+ * @}
+ */
+
+
+/** @defgroup DMA_fifo_status_level
+ * @{
+ */
+#define DMA_FIFOStatus_Less1QuarterFull ((uint32_t)0x00000000 << 3)
+#define DMA_FIFOStatus_1QuarterFull ((uint32_t)0x00000001 << 3)
+#define DMA_FIFOStatus_HalfFull ((uint32_t)0x00000002 << 3)
+#define DMA_FIFOStatus_3QuartersFull ((uint32_t)0x00000003 << 3)
+#define DMA_FIFOStatus_Empty ((uint32_t)0x00000004 << 3)
+#define DMA_FIFOStatus_Full ((uint32_t)0x00000005 << 3)
+
+#define IS_DMA_FIFO_STATUS(STATUS) (((STATUS) == DMA_FIFOStatus_Less1QuarterFull ) || \
+ ((STATUS) == DMA_FIFOStatus_HalfFull) || \
+ ((STATUS) == DMA_FIFOStatus_1QuarterFull) || \
+ ((STATUS) == DMA_FIFOStatus_3QuartersFull) || \
+ ((STATUS) == DMA_FIFOStatus_Full) || \
+ ((STATUS) == DMA_FIFOStatus_Empty))
+/**
+ * @}
+ */
+
+/** @defgroup DMA_flags_definition
+ * @{
+ */
+#define DMA_FLAG_FEIF0 ((uint32_t)0x10800001)
+#define DMA_FLAG_DMEIF0 ((uint32_t)0x10800004)
+#define DMA_FLAG_TEIF0 ((uint32_t)0x10000008)
+#define DMA_FLAG_HTIF0 ((uint32_t)0x10000010)
+#define DMA_FLAG_TCIF0 ((uint32_t)0x10000020)
+#define DMA_FLAG_FEIF1 ((uint32_t)0x10000040)
+#define DMA_FLAG_DMEIF1 ((uint32_t)0x10000100)
+#define DMA_FLAG_TEIF1 ((uint32_t)0x10000200)
+#define DMA_FLAG_HTIF1 ((uint32_t)0x10000400)
+#define DMA_FLAG_TCIF1 ((uint32_t)0x10000800)
+#define DMA_FLAG_FEIF2 ((uint32_t)0x10010000)
+#define DMA_FLAG_DMEIF2 ((uint32_t)0x10040000)
+#define DMA_FLAG_TEIF2 ((uint32_t)0x10080000)
+#define DMA_FLAG_HTIF2 ((uint32_t)0x10100000)
+#define DMA_FLAG_TCIF2 ((uint32_t)0x10200000)
+#define DMA_FLAG_FEIF3 ((uint32_t)0x10400000)
+#define DMA_FLAG_DMEIF3 ((uint32_t)0x11000000)
+#define DMA_FLAG_TEIF3 ((uint32_t)0x12000000)
+#define DMA_FLAG_HTIF3 ((uint32_t)0x14000000)
+#define DMA_FLAG_TCIF3 ((uint32_t)0x18000000)
+#define DMA_FLAG_FEIF4 ((uint32_t)0x20000001)
+#define DMA_FLAG_DMEIF4 ((uint32_t)0x20000004)
+#define DMA_FLAG_TEIF4 ((uint32_t)0x20000008)
+#define DMA_FLAG_HTIF4 ((uint32_t)0x20000010)
+#define DMA_FLAG_TCIF4 ((uint32_t)0x20000020)
+#define DMA_FLAG_FEIF5 ((uint32_t)0x20000040)
+#define DMA_FLAG_DMEIF5 ((uint32_t)0x20000100)
+#define DMA_FLAG_TEIF5 ((uint32_t)0x20000200)
+#define DMA_FLAG_HTIF5 ((uint32_t)0x20000400)
+#define DMA_FLAG_TCIF5 ((uint32_t)0x20000800)
+#define DMA_FLAG_FEIF6 ((uint32_t)0x20010000)
+#define DMA_FLAG_DMEIF6 ((uint32_t)0x20040000)
+#define DMA_FLAG_TEIF6 ((uint32_t)0x20080000)
+#define DMA_FLAG_HTIF6 ((uint32_t)0x20100000)
+#define DMA_FLAG_TCIF6 ((uint32_t)0x20200000)
+#define DMA_FLAG_FEIF7 ((uint32_t)0x20400000)
+#define DMA_FLAG_DMEIF7 ((uint32_t)0x21000000)
+#define DMA_FLAG_TEIF7 ((uint32_t)0x22000000)
+#define DMA_FLAG_HTIF7 ((uint32_t)0x24000000)
+#define DMA_FLAG_TCIF7 ((uint32_t)0x28000000)
+
+#define IS_DMA_CLEAR_FLAG(FLAG) ((((FLAG) & 0x30000000) != 0x30000000) && (((FLAG) & 0x30000000) != 0) && \
+ (((FLAG) & 0xC082F082) == 0x00) && ((FLAG) != 0x00))
+
+#define IS_DMA_GET_FLAG(FLAG) (((FLAG) == DMA_FLAG_TCIF0) || ((FLAG) == DMA_FLAG_HTIF0) || \
+ ((FLAG) == DMA_FLAG_TEIF0) || ((FLAG) == DMA_FLAG_DMEIF0) || \
+ ((FLAG) == DMA_FLAG_FEIF0) || ((FLAG) == DMA_FLAG_TCIF1) || \
+ ((FLAG) == DMA_FLAG_HTIF1) || ((FLAG) == DMA_FLAG_TEIF1) || \
+ ((FLAG) == DMA_FLAG_DMEIF1) || ((FLAG) == DMA_FLAG_FEIF1) || \
+ ((FLAG) == DMA_FLAG_TCIF2) || ((FLAG) == DMA_FLAG_HTIF2) || \
+ ((FLAG) == DMA_FLAG_TEIF2) || ((FLAG) == DMA_FLAG_DMEIF2) || \
+ ((FLAG) == DMA_FLAG_FEIF2) || ((FLAG) == DMA_FLAG_TCIF3) || \
+ ((FLAG) == DMA_FLAG_HTIF3) || ((FLAG) == DMA_FLAG_TEIF3) || \
+ ((FLAG) == DMA_FLAG_DMEIF3) || ((FLAG) == DMA_FLAG_FEIF3) || \
+ ((FLAG) == DMA_FLAG_TCIF4) || ((FLAG) == DMA_FLAG_HTIF4) || \
+ ((FLAG) == DMA_FLAG_TEIF4) || ((FLAG) == DMA_FLAG_DMEIF4) || \
+ ((FLAG) == DMA_FLAG_FEIF4) || ((FLAG) == DMA_FLAG_TCIF5) || \
+ ((FLAG) == DMA_FLAG_HTIF5) || ((FLAG) == DMA_FLAG_TEIF5) || \
+ ((FLAG) == DMA_FLAG_DMEIF5) || ((FLAG) == DMA_FLAG_FEIF5) || \
+ ((FLAG) == DMA_FLAG_TCIF6) || ((FLAG) == DMA_FLAG_HTIF6) || \
+ ((FLAG) == DMA_FLAG_TEIF6) || ((FLAG) == DMA_FLAG_DMEIF6) || \
+ ((FLAG) == DMA_FLAG_FEIF6) || ((FLAG) == DMA_FLAG_TCIF7) || \
+ ((FLAG) == DMA_FLAG_HTIF7) || ((FLAG) == DMA_FLAG_TEIF7) || \
+ ((FLAG) == DMA_FLAG_DMEIF7) || ((FLAG) == DMA_FLAG_FEIF7))
+/**
+ * @}
+ */
+
+
+/** @defgroup DMA_interrupt_enable_definitions
+ * @{
+ */
+#define DMA_IT_TC ((uint32_t)0x00000010)
+#define DMA_IT_HT ((uint32_t)0x00000008)
+#define DMA_IT_TE ((uint32_t)0x00000004)
+#define DMA_IT_DME ((uint32_t)0x00000002)
+#define DMA_IT_FE ((uint32_t)0x00000080)
+
+#define IS_DMA_CONFIG_IT(IT) ((((IT) & 0xFFFFFF61) == 0x00) && ((IT) != 0x00))
+/**
+ * @}
+ */
+
+
+/** @defgroup DMA_interrupts_definitions
+ * @{
+ */
+#define DMA_IT_FEIF0 ((uint32_t)0x90000001)
+#define DMA_IT_DMEIF0 ((uint32_t)0x10001004)
+#define DMA_IT_TEIF0 ((uint32_t)0x10002008)
+#define DMA_IT_HTIF0 ((uint32_t)0x10004010)
+#define DMA_IT_TCIF0 ((uint32_t)0x10008020)
+#define DMA_IT_FEIF1 ((uint32_t)0x90000040)
+#define DMA_IT_DMEIF1 ((uint32_t)0x10001100)
+#define DMA_IT_TEIF1 ((uint32_t)0x10002200)
+#define DMA_IT_HTIF1 ((uint32_t)0x10004400)
+#define DMA_IT_TCIF1 ((uint32_t)0x10008800)
+#define DMA_IT_FEIF2 ((uint32_t)0x90010000)
+#define DMA_IT_DMEIF2 ((uint32_t)0x10041000)
+#define DMA_IT_TEIF2 ((uint32_t)0x10082000)
+#define DMA_IT_HTIF2 ((uint32_t)0x10104000)
+#define DMA_IT_TCIF2 ((uint32_t)0x10208000)
+#define DMA_IT_FEIF3 ((uint32_t)0x90400000)
+#define DMA_IT_DMEIF3 ((uint32_t)0x11001000)
+#define DMA_IT_TEIF3 ((uint32_t)0x12002000)
+#define DMA_IT_HTIF3 ((uint32_t)0x14004000)
+#define DMA_IT_TCIF3 ((uint32_t)0x18008000)
+#define DMA_IT_FEIF4 ((uint32_t)0xA0000001)
+#define DMA_IT_DMEIF4 ((uint32_t)0x20001004)
+#define DMA_IT_TEIF4 ((uint32_t)0x20002008)
+#define DMA_IT_HTIF4 ((uint32_t)0x20004010)
+#define DMA_IT_TCIF4 ((uint32_t)0x20008020)
+#define DMA_IT_FEIF5 ((uint32_t)0xA0000040)
+#define DMA_IT_DMEIF5 ((uint32_t)0x20001100)
+#define DMA_IT_TEIF5 ((uint32_t)0x20002200)
+#define DMA_IT_HTIF5 ((uint32_t)0x20004400)
+#define DMA_IT_TCIF5 ((uint32_t)0x20008800)
+#define DMA_IT_FEIF6 ((uint32_t)0xA0010000)
+#define DMA_IT_DMEIF6 ((uint32_t)0x20041000)
+#define DMA_IT_TEIF6 ((uint32_t)0x20082000)
+#define DMA_IT_HTIF6 ((uint32_t)0x20104000)
+#define DMA_IT_TCIF6 ((uint32_t)0x20208000)
+#define DMA_IT_FEIF7 ((uint32_t)0xA0400000)
+#define DMA_IT_DMEIF7 ((uint32_t)0x21001000)
+#define DMA_IT_TEIF7 ((uint32_t)0x22002000)
+#define DMA_IT_HTIF7 ((uint32_t)0x24004000)
+#define DMA_IT_TCIF7 ((uint32_t)0x28008000)
+
+#define IS_DMA_CLEAR_IT(IT) ((((IT) & 0x30000000) != 0x30000000) && \
+ (((IT) & 0x30000000) != 0) && ((IT) != 0x00) && \
+ (((IT) & 0x40820082) == 0x00))
+
+#define IS_DMA_GET_IT(IT) (((IT) == DMA_IT_TCIF0) || ((IT) == DMA_IT_HTIF0) || \
+ ((IT) == DMA_IT_TEIF0) || ((IT) == DMA_IT_DMEIF0) || \
+ ((IT) == DMA_IT_FEIF0) || ((IT) == DMA_IT_TCIF1) || \
+ ((IT) == DMA_IT_HTIF1) || ((IT) == DMA_IT_TEIF1) || \
+ ((IT) == DMA_IT_DMEIF1)|| ((IT) == DMA_IT_FEIF1) || \
+ ((IT) == DMA_IT_TCIF2) || ((IT) == DMA_IT_HTIF2) || \
+ ((IT) == DMA_IT_TEIF2) || ((IT) == DMA_IT_DMEIF2) || \
+ ((IT) == DMA_IT_FEIF2) || ((IT) == DMA_IT_TCIF3) || \
+ ((IT) == DMA_IT_HTIF3) || ((IT) == DMA_IT_TEIF3) || \
+ ((IT) == DMA_IT_DMEIF3)|| ((IT) == DMA_IT_FEIF3) || \
+ ((IT) == DMA_IT_TCIF4) || ((IT) == DMA_IT_HTIF4) || \
+ ((IT) == DMA_IT_TEIF4) || ((IT) == DMA_IT_DMEIF4) || \
+ ((IT) == DMA_IT_FEIF4) || ((IT) == DMA_IT_TCIF5) || \
+ ((IT) == DMA_IT_HTIF5) || ((IT) == DMA_IT_TEIF5) || \
+ ((IT) == DMA_IT_DMEIF5)|| ((IT) == DMA_IT_FEIF5) || \
+ ((IT) == DMA_IT_TCIF6) || ((IT) == DMA_IT_HTIF6) || \
+ ((IT) == DMA_IT_TEIF6) || ((IT) == DMA_IT_DMEIF6) || \
+ ((IT) == DMA_IT_FEIF6) || ((IT) == DMA_IT_TCIF7) || \
+ ((IT) == DMA_IT_HTIF7) || ((IT) == DMA_IT_TEIF7) || \
+ ((IT) == DMA_IT_DMEIF7)|| ((IT) == DMA_IT_FEIF7))
+/**
+ * @}
+ */
+
+
+/** @defgroup DMA_peripheral_increment_offset
+ * @{
+ */
+#define DMA_PINCOS_Psize ((uint32_t)0x00000000)
+#define DMA_PINCOS_WordAligned ((uint32_t)0x00008000)
+
+#define IS_DMA_PINCOS_SIZE(SIZE) (((SIZE) == DMA_PINCOS_Psize) || \
+ ((SIZE) == DMA_PINCOS_WordAligned))
+/**
+ * @}
+ */
+
+
+/** @defgroup DMA_flow_controller_definitions
+ * @{
+ */
+#define DMA_FlowCtrl_Memory ((uint32_t)0x00000000)
+#define DMA_FlowCtrl_Peripheral ((uint32_t)0x00000020)
+
+#define IS_DMA_FLOW_CTRL(CTRL) (((CTRL) == DMA_FlowCtrl_Memory) || \
+ ((CTRL) == DMA_FlowCtrl_Peripheral))
+/**
+ * @}
+ */
+
+
+/** @defgroup DMA_memory_targets_definitions
+ * @{
+ */
+#define DMA_Memory_0 ((uint32_t)0x00000000)
+#define DMA_Memory_1 ((uint32_t)0x00080000)
+
+#define IS_DMA_CURRENT_MEM(MEM) (((MEM) == DMA_Memory_0) || ((MEM) == DMA_Memory_1))
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions --------------------------------------------------------*/
+
+/* Function used to set the DMA configuration to the default reset state *****/
+void DMA_DeInit(DMA_Stream_TypeDef* DMAy_Streamx);
+
+/* Initialization and Configuration functions *********************************/
+void DMA_Init(DMA_Stream_TypeDef* DMAy_Streamx, DMA_InitTypeDef* DMA_InitStruct);
+void DMA_StructInit(DMA_InitTypeDef* DMA_InitStruct);
+void DMA_Cmd(DMA_Stream_TypeDef* DMAy_Streamx, FunctionalState NewState);
+
+/* Optional Configuration functions *******************************************/
+void DMA_PeriphIncOffsetSizeConfig(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t DMA_Pincos);
+void DMA_FlowControllerConfig(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t DMA_FlowCtrl);
+
+/* Data Counter functions *****************************************************/
+void DMA_SetCurrDataCounter(DMA_Stream_TypeDef* DMAy_Streamx, uint16_t Counter);
+uint16_t DMA_GetCurrDataCounter(DMA_Stream_TypeDef* DMAy_Streamx);
+
+/* Double Buffer mode functions ***********************************************/
+void DMA_DoubleBufferModeConfig(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t Memory1BaseAddr,
+ uint32_t DMA_CurrentMemory);
+void DMA_DoubleBufferModeCmd(DMA_Stream_TypeDef* DMAy_Streamx, FunctionalState NewState);
+void DMA_MemoryTargetConfig(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t MemoryBaseAddr,
+ uint32_t DMA_MemoryTarget);
+uint32_t DMA_GetCurrentMemoryTarget(DMA_Stream_TypeDef* DMAy_Streamx);
+
+/* Interrupts and flags management functions **********************************/
+FunctionalState DMA_GetCmdStatus(DMA_Stream_TypeDef* DMAy_Streamx);
+uint32_t DMA_GetFIFOStatus(DMA_Stream_TypeDef* DMAy_Streamx);
+FlagStatus DMA_GetFlagStatus(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t DMA_FLAG);
+void DMA_ClearFlag(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t DMA_FLAG);
+void DMA_ITConfig(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t DMA_IT, FunctionalState NewState);
+ITStatus DMA_GetITStatus(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t DMA_IT);
+void DMA_ClearITPendingBit(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t DMA_IT);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*__STM32F2xx_DMA_H */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/inc/stm32f2xx_exti.h b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/inc/stm32f2xx_exti.h
new file mode 100644
index 0000000..f9f0a91
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/inc/stm32f2xx_exti.h
@@ -0,0 +1,183 @@
+/**
+ ******************************************************************************
+ * @file stm32f2xx_exti.h
+ * @author MCD Application Team
+ * @version V1.1.2
+ * @date 05-March-2012
+ * @brief This file contains all the functions prototypes for the EXTI firmware
+ * 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 __STM32F2xx_EXTI_H
+#define __STM32F2xx_EXTI_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f2xx.h"
+
+/** @addtogroup STM32F2xx_StdPeriph_Driver
+ * @{
+ */
+
+/** @addtogroup EXTI
+ * @{
+ */
+
+/* Exported types ------------------------------------------------------------*/
+
+/**
+ * @brief EXTI mode enumeration
+ */
+
+typedef enum
+{
+ EXTI_Mode_Interrupt = 0x00,
+ EXTI_Mode_Event = 0x04
+}EXTIMode_TypeDef;
+
+#define IS_EXTI_MODE(MODE) (((MODE) == EXTI_Mode_Interrupt) || ((MODE) == EXTI_Mode_Event))
+
+/**
+ * @brief EXTI Trigger enumeration
+ */
+
+typedef enum
+{
+ EXTI_Trigger_Rising = 0x08,
+ EXTI_Trigger_Falling = 0x0C,
+ EXTI_Trigger_Rising_Falling = 0x10
+}EXTITrigger_TypeDef;
+
+#define IS_EXTI_TRIGGER(TRIGGER) (((TRIGGER) == EXTI_Trigger_Rising) || \
+ ((TRIGGER) == EXTI_Trigger_Falling) || \
+ ((TRIGGER) == EXTI_Trigger_Rising_Falling))
+/**
+ * @brief EXTI Init Structure definition
+ */
+
+typedef struct
+{
+ uint32_t EXTI_Line; /*!< Specifies the EXTI lines to be enabled or disabled.
+ This parameter can be any combination value of @ref EXTI_Lines */
+
+ EXTIMode_TypeDef EXTI_Mode; /*!< Specifies the mode for the EXTI lines.
+ This parameter can be a value of @ref EXTIMode_TypeDef */
+
+ EXTITrigger_TypeDef EXTI_Trigger; /*!< Specifies the trigger signal active edge for the EXTI lines.
+ This parameter can be a value of @ref EXTITrigger_TypeDef */
+
+ FunctionalState EXTI_LineCmd; /*!< Specifies the new state of the selected EXTI lines.
+ This parameter can be set either to ENABLE or DISABLE */
+}EXTI_InitTypeDef;
+
+/* Exported constants --------------------------------------------------------*/
+
+/** @defgroup EXTI_Exported_Constants
+ * @{
+ */
+
+/** @defgroup EXTI_Lines
+ * @{
+ */
+
+#define EXTI_Line0 ((uint32_t)0x00001) /*!< External interrupt line 0 */
+#define EXTI_Line1 ((uint32_t)0x00002) /*!< External interrupt line 1 */
+#define EXTI_Line2 ((uint32_t)0x00004) /*!< External interrupt line 2 */
+#define EXTI_Line3 ((uint32_t)0x00008) /*!< External interrupt line 3 */
+#define EXTI_Line4 ((uint32_t)0x00010) /*!< External interrupt line 4 */
+#define EXTI_Line5 ((uint32_t)0x00020) /*!< External interrupt line 5 */
+#define EXTI_Line6 ((uint32_t)0x00040) /*!< External interrupt line 6 */
+#define EXTI_Line7 ((uint32_t)0x00080) /*!< External interrupt line 7 */
+#define EXTI_Line8 ((uint32_t)0x00100) /*!< External interrupt line 8 */
+#define EXTI_Line9 ((uint32_t)0x00200) /*!< External interrupt line 9 */
+#define EXTI_Line10 ((uint32_t)0x00400) /*!< External interrupt line 10 */
+#define EXTI_Line11 ((uint32_t)0x00800) /*!< External interrupt line 11 */
+#define EXTI_Line12 ((uint32_t)0x01000) /*!< External interrupt line 12 */
+#define EXTI_Line13 ((uint32_t)0x02000) /*!< External interrupt line 13 */
+#define EXTI_Line14 ((uint32_t)0x04000) /*!< External interrupt line 14 */
+#define EXTI_Line15 ((uint32_t)0x08000) /*!< External interrupt line 15 */
+#define EXTI_Line16 ((uint32_t)0x10000) /*!< External interrupt line 16 Connected to the PVD Output */
+#define EXTI_Line17 ((uint32_t)0x20000) /*!< External interrupt line 17 Connected to the RTC Alarm event */
+#define EXTI_Line18 ((uint32_t)0x40000) /*!< External interrupt line 18 Connected to the USB OTG FS Wakeup from suspend event */
+#define EXTI_Line19 ((uint32_t)0x80000) /*!< External interrupt line 19 Connected to the Ethernet Wakeup event */
+#define EXTI_Line20 ((uint32_t)0x00100000) /*!< External interrupt line 20 Connected to the USB OTG HS (configured in FS) Wakeup event */
+#define EXTI_Line21 ((uint32_t)0x00200000) /*!< External interrupt line 21 Connected to the RTC Tamper and Time Stamp events */
+#define EXTI_Line22 ((uint32_t)0x00400000) /*!< External interrupt line 22 Connected to the RTC Wakeup event */
+
+#define IS_EXTI_LINE(LINE) ((((LINE) & (uint32_t)0xFF800000) == 0x00) && ((LINE) != (uint16_t)0x00))
+
+#define IS_GET_EXTI_LINE(LINE) (((LINE) == EXTI_Line0) || ((LINE) == EXTI_Line1) || \
+ ((LINE) == EXTI_Line2) || ((LINE) == EXTI_Line3) || \
+ ((LINE) == EXTI_Line4) || ((LINE) == EXTI_Line5) || \
+ ((LINE) == EXTI_Line6) || ((LINE) == EXTI_Line7) || \
+ ((LINE) == EXTI_Line8) || ((LINE) == EXTI_Line9) || \
+ ((LINE) == EXTI_Line10) || ((LINE) == EXTI_Line11) || \
+ ((LINE) == EXTI_Line12) || ((LINE) == EXTI_Line13) || \
+ ((LINE) == EXTI_Line14) || ((LINE) == EXTI_Line15) || \
+ ((LINE) == EXTI_Line16) || ((LINE) == EXTI_Line17) || \
+ ((LINE) == EXTI_Line18) || ((LINE) == EXTI_Line19) || \
+ ((LINE) == EXTI_Line20) || ((LINE) == EXTI_Line21) ||\
+ ((LINE) == EXTI_Line22))
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions --------------------------------------------------------*/
+
+/* Function used to set the EXTI configuration to the default reset state *****/
+void EXTI_DeInit(void);
+
+/* Initialization and Configuration functions *********************************/
+void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct);
+void EXTI_StructInit(EXTI_InitTypeDef* EXTI_InitStruct);
+void EXTI_GenerateSWInterrupt(uint32_t EXTI_Line);
+
+/* Interrupts and flags management functions **********************************/
+FlagStatus EXTI_GetFlagStatus(uint32_t EXTI_Line);
+void EXTI_ClearFlag(uint32_t EXTI_Line);
+ITStatus EXTI_GetITStatus(uint32_t EXTI_Line);
+void EXTI_ClearITPendingBit(uint32_t EXTI_Line);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F2xx_EXTI_H */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/inc/stm32f2xx_flash.h b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/inc/stm32f2xx_flash.h
new file mode 100644
index 0000000..96f1689
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/inc/stm32f2xx_flash.h
@@ -0,0 +1,340 @@
+/**
+ ******************************************************************************
+ * @file stm32f2xx_flash.h
+ * @author MCD Application Team
+ * @version V1.1.2
+ * @date 05-March-2012
+ * @brief This file contains all the functions prototypes for the FLASH
+ * firmware 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 __STM32F2xx_FLASH_H
+#define __STM32F2xx_FLASH_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f2xx.h"
+
+/** @addtogroup STM32F2xx_StdPeriph_Driver
+ * @{
+ */
+
+/** @addtogroup FLASH
+ * @{
+ */
+
+/* Exported types ------------------------------------------------------------*/
+/**
+ * @brief FLASH Status
+ */
+typedef enum
+{
+ FLASH_BUSY = 1,
+ FLASH_ERROR_PGS,
+ FLASH_ERROR_PGP,
+ FLASH_ERROR_PGA,
+ FLASH_ERROR_WRP,
+ FLASH_ERROR_PROGRAM,
+ FLASH_ERROR_OPERATION,
+ FLASH_COMPLETE
+}FLASH_Status;
+
+/* Exported constants --------------------------------------------------------*/
+
+/** @defgroup FLASH_Exported_Constants
+ * @{
+ */
+
+/** @defgroup Flash_Latency
+ * @{
+ */
+#define FLASH_Latency_0 ((uint8_t)0x0000) /*!< FLASH Zero Latency cycle */
+#define FLASH_Latency_1 ((uint8_t)0x0001) /*!< FLASH One Latency cycle */
+#define FLASH_Latency_2 ((uint8_t)0x0002) /*!< FLASH Two Latency cycles */
+#define FLASH_Latency_3 ((uint8_t)0x0003) /*!< FLASH Three Latency cycles */
+#define FLASH_Latency_4 ((uint8_t)0x0004) /*!< FLASH Four Latency cycles */
+#define FLASH_Latency_5 ((uint8_t)0x0005) /*!< FLASH Five Latency cycles */
+#define FLASH_Latency_6 ((uint8_t)0x0006) /*!< FLASH Six Latency cycles */
+#define FLASH_Latency_7 ((uint8_t)0x0007) /*!< FLASH Seven Latency cycles */
+
+#define IS_FLASH_LATENCY(LATENCY) (((LATENCY) == FLASH_Latency_0) || \
+ ((LATENCY) == FLASH_Latency_1) || \
+ ((LATENCY) == FLASH_Latency_2) || \
+ ((LATENCY) == FLASH_Latency_3) || \
+ ((LATENCY) == FLASH_Latency_4) || \
+ ((LATENCY) == FLASH_Latency_5) || \
+ ((LATENCY) == FLASH_Latency_6) || \
+ ((LATENCY) == FLASH_Latency_7))
+/**
+ * @}
+ */
+
+/** @defgroup FLASH_Voltage_Range
+ * @{
+ */
+#define VoltageRange_1 ((uint8_t)0x00) /*!< Device operating range: 1.8V to 2.1V */
+#define VoltageRange_2 ((uint8_t)0x01) /*!= 0x08000000) && ((ADDRESS) < 0x080FFFFF)) ||\
+ (((ADDRESS) >= 0x1FFF7800) && ((ADDRESS) < 0x1FFF7A0F)))
+/**
+ * @}
+ */
+
+/** @defgroup Option_Bytes_Write_Protection
+ * @{
+ */
+#define OB_WRP_Sector_0 ((uint32_t)0x00000001) /*!< Write protection of Sector0 */
+#define OB_WRP_Sector_1 ((uint32_t)0x00000002) /*!< Write protection of Sector1 */
+#define OB_WRP_Sector_2 ((uint32_t)0x00000004) /*!< Write protection of Sector2 */
+#define OB_WRP_Sector_3 ((uint32_t)0x00000008) /*!< Write protection of Sector3 */
+#define OB_WRP_Sector_4 ((uint32_t)0x00000010) /*!< Write protection of Sector4 */
+#define OB_WRP_Sector_5 ((uint32_t)0x00000020) /*!< Write protection of Sector5 */
+#define OB_WRP_Sector_6 ((uint32_t)0x00000040) /*!< Write protection of Sector6 */
+#define OB_WRP_Sector_7 ((uint32_t)0x00000080) /*!< Write protection of Sector7 */
+#define OB_WRP_Sector_8 ((uint32_t)0x00000100) /*!< Write protection of Sector8 */
+#define OB_WRP_Sector_9 ((uint32_t)0x00000200) /*!< Write protection of Sector9 */
+#define OB_WRP_Sector_10 ((uint32_t)0x00000400) /*!< Write protection of Sector10 */
+#define OB_WRP_Sector_11 ((uint32_t)0x00000800) /*!< Write protection of Sector11 */
+#define OB_WRP_Sector_All ((uint32_t)0x00000FFF) /*!< Write protection of all Sectors */
+
+#define IS_OB_WRP(SECTOR)((((SECTOR) & (uint32_t)0xFFFFF000) == 0x00000000) && ((SECTOR) != 0x00000000))
+/**
+ * @}
+ */
+
+/** @defgroup FLASH_Option_Bytes_Read_Protection
+ * @{
+ */
+#define OB_RDP_Level_0 ((uint8_t)0xAA)
+#define OB_RDP_Level_1 ((uint8_t)0x55)
+/*#define OB_RDP_Level_2 ((uint8_t)0xCC)*/ /*!< Warning: When enabling read protection level 2
+ it's no more possible to go back to level 1 or 0 */
+#define IS_OB_RDP(LEVEL) (((LEVEL) == OB_RDP_Level_0)||\
+ ((LEVEL) == OB_RDP_Level_1))/*||\
+ ((LEVEL) == OB_RDP_Level_2))*/
+/**
+ * @}
+ */
+
+/** @defgroup FLASH_Option_Bytes_IWatchdog
+ * @{
+ */
+#define OB_IWDG_SW ((uint8_t)0x20) /*!< Software IWDG selected */
+#define OB_IWDG_HW ((uint8_t)0x00) /*!< Hardware IWDG selected */
+#define IS_OB_IWDG_SOURCE(SOURCE) (((SOURCE) == OB_IWDG_SW) || ((SOURCE) == OB_IWDG_HW))
+/**
+ * @}
+ */
+
+/** @defgroup FLASH_Option_Bytes_nRST_STOP
+ * @{
+ */
+#define OB_STOP_NoRST ((uint8_t)0x40) /*!< No reset generated when entering in STOP */
+#define OB_STOP_RST ((uint8_t)0x00) /*!< Reset generated when entering in STOP */
+#define IS_OB_STOP_SOURCE(SOURCE) (((SOURCE) == OB_STOP_NoRST) || ((SOURCE) == OB_STOP_RST))
+/**
+ * @}
+ */
+
+
+/** @defgroup FLASH_Option_Bytes_nRST_STDBY
+ * @{
+ */
+#define OB_STDBY_NoRST ((uint8_t)0x80) /*!< No reset generated when entering in STANDBY */
+#define OB_STDBY_RST ((uint8_t)0x00) /*!< Reset generated when entering in STANDBY */
+#define IS_OB_STDBY_SOURCE(SOURCE) (((SOURCE) == OB_STDBY_NoRST) || ((SOURCE) == OB_STDBY_RST))
+/**
+ * @}
+ */
+
+/** @defgroup FLASH_BOR_Reset_Level
+ * @{
+ */
+#define OB_BOR_LEVEL3 ((uint8_t)0x00) /*!< Supply voltage ranges from 2.70 to 3.60 V */
+#define OB_BOR_LEVEL2 ((uint8_t)0x04) /*!< Supply voltage ranges from 2.40 to 2.70 V */
+#define OB_BOR_LEVEL1 ((uint8_t)0x08) /*!< Supply voltage ranges from 2.10 to 2.40 V */
+#define OB_BOR_OFF ((uint8_t)0x0C) /*!< Supply voltage ranges from 1.62 to 2.10 V */
+#define IS_OB_BOR(LEVEL) (((LEVEL) == OB_BOR_LEVEL1) || ((LEVEL) == OB_BOR_LEVEL2) ||\
+ ((LEVEL) == OB_BOR_LEVEL3) || ((LEVEL) == OB_BOR_OFF))
+/**
+ * @}
+ */
+
+/** @defgroup FLASH_Interrupts
+ * @{
+ */
+#define FLASH_IT_EOP ((uint32_t)0x01000000) /*!< End of FLASH Operation Interrupt source */
+#define FLASH_IT_ERR ((uint32_t)0x02000000) /*!< Error Interrupt source */
+#define IS_FLASH_IT(IT) ((((IT) & (uint32_t)0xFCFFFFFF) == 0x00000000) && ((IT) != 0x00000000))
+/**
+ * @}
+ */
+
+/** @defgroup FLASH_Flags
+ * @{
+ */
+#define FLASH_FLAG_EOP ((uint32_t)0x00000001) /*!< FLASH End of Operation flag */
+#define FLASH_FLAG_OPERR ((uint32_t)0x00000002) /*!< FLASH operation Error flag */
+#define FLASH_FLAG_WRPERR ((uint32_t)0x00000010) /*!< FLASH Write protected error flag */
+#define FLASH_FLAG_PGAERR ((uint32_t)0x00000020) /*!< FLASH Programming Alignment error flag */
+#define FLASH_FLAG_PGPERR ((uint32_t)0x00000040) /*!< FLASH Programming Parallelism error flag */
+#define FLASH_FLAG_PGSERR ((uint32_t)0x00000080) /*!< FLASH Programming Sequence error flag */
+#define FLASH_FLAG_BSY ((uint32_t)0x00010000) /*!< FLASH Busy flag */
+#define IS_FLASH_CLEAR_FLAG(FLAG) ((((FLAG) & (uint32_t)0xFFFFFF0C) == 0x00000000) && ((FLAG) != 0x00000000))
+#define IS_FLASH_GET_FLAG(FLAG) (((FLAG) == FLASH_FLAG_EOP) || ((FLAG) == FLASH_FLAG_OPERR) || \
+ ((FLAG) == FLASH_FLAG_WRPERR) || ((FLAG) == FLASH_FLAG_PGAERR) || \
+ ((FLAG) == FLASH_FLAG_PGPERR) || ((FLAG) == FLASH_FLAG_PGSERR) || \
+ ((FLAG) == FLASH_FLAG_BSY))
+/**
+ * @}
+ */
+
+/** @defgroup FLASH_Program_Parallelism
+ * @{
+ */
+#define FLASH_PSIZE_BYTE ((uint32_t)0x00000000)
+#define FLASH_PSIZE_HALF_WORD ((uint32_t)0x00000100)
+#define FLASH_PSIZE_WORD ((uint32_t)0x00000200)
+#define FLASH_PSIZE_DOUBLE_WORD ((uint32_t)0x00000300)
+#define CR_PSIZE_MASK ((uint32_t)0xFFFFFCFF)
+/**
+ * @}
+ */
+
+/** @defgroup FLASH_Keys
+ * @{
+ */
+#define RDP_KEY ((uint16_t)0x00A5)
+#define FLASH_KEY1 ((uint32_t)0x45670123)
+#define FLASH_KEY2 ((uint32_t)0xCDEF89AB)
+#define FLASH_OPT_KEY1 ((uint32_t)0x08192A3B)
+#define FLASH_OPT_KEY2 ((uint32_t)0x4C5D6E7F)
+/**
+ * @}
+ */
+
+/**
+ * @brief ACR register byte 0 (Bits[8:0]) base address
+ */
+#define ACR_BYTE0_ADDRESS ((uint32_t)0x40023C00)
+/**
+ * @brief OPTCR register byte 3 (Bits[24:16]) base address
+ */
+#define OPTCR_BYTE0_ADDRESS ((uint32_t)0x40023C14)
+#define OPTCR_BYTE1_ADDRESS ((uint32_t)0x40023C15)
+#define OPTCR_BYTE2_ADDRESS ((uint32_t)0x40023C16)
+
+/**
+ * @}
+ */
+
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions --------------------------------------------------------*/
+
+/* FLASH Interface configuration functions ************************************/
+void FLASH_SetLatency(uint32_t FLASH_Latency);
+void FLASH_PrefetchBufferCmd(FunctionalState NewState);
+void FLASH_InstructionCacheCmd(FunctionalState NewState);
+void FLASH_DataCacheCmd(FunctionalState NewState);
+void FLASH_InstructionCacheReset(void);
+void FLASH_DataCacheReset(void);
+
+/* FLASH Memory Programming functions *****************************************/
+void FLASH_Unlock(void);
+void FLASH_Lock(void);
+FLASH_Status FLASH_EraseSector(uint32_t FLASH_Sector, uint8_t VoltageRange);
+FLASH_Status FLASH_EraseAllSectors(uint8_t VoltageRange);
+FLASH_Status FLASH_ProgramDoubleWord(uint32_t Address, uint64_t Data);
+FLASH_Status FLASH_ProgramWord(uint32_t Address, uint32_t Data);
+FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data);
+FLASH_Status FLASH_ProgramByte(uint32_t Address, uint8_t Data);
+
+/* Option Bytes Programming functions *****************************************/
+void FLASH_OB_Unlock(void);
+void FLASH_OB_Lock(void);
+void FLASH_OB_WRPConfig(uint32_t OB_WRP, FunctionalState NewState);
+void FLASH_OB_RDPConfig(uint8_t OB_RDP);
+void FLASH_OB_UserConfig(uint8_t OB_IWDG, uint8_t OB_STOP, uint8_t OB_STDBY);
+void FLASH_OB_BORConfig(uint8_t OB_BOR);
+FLASH_Status FLASH_OB_Launch(void);
+uint8_t FLASH_OB_GetUser(void);
+uint16_t FLASH_OB_GetWRP(void);
+FlagStatus FLASH_OB_GetRDP(void);
+uint8_t FLASH_OB_GetBOR(void);
+
+/* Interrupts and flags management functions **********************************/
+void FLASH_ITConfig(uint32_t FLASH_IT, FunctionalState NewState);
+FlagStatus FLASH_GetFlagStatus(uint32_t FLASH_FLAG);
+void FLASH_ClearFlag(uint32_t FLASH_FLAG);
+FLASH_Status FLASH_GetStatus(void);
+FLASH_Status FLASH_WaitForLastOperation(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F2xx_FLASH_H */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/inc/stm32f2xx_fsmc.h b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/inc/stm32f2xx_fsmc.h
new file mode 100644
index 0000000..102b1cf
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/inc/stm32f2xx_fsmc.h
@@ -0,0 +1,675 @@
+/**
+ ******************************************************************************
+ * @file stm32f2xx_fsmc.h
+ * @author MCD Application Team
+ * @version V1.1.2
+ * @date 05-March-2012
+ * @brief This file contains all the functions prototypes for the FSMC firmware
+ * 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 __STM32F2xx_FSMC_H
+#define __STM32F2xx_FSMC_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f2xx.h"
+
+/** @addtogroup STM32F2xx_StdPeriph_Driver
+ * @{
+ */
+
+/** @addtogroup FSMC
+ * @{
+ */
+
+/* Exported types ------------------------------------------------------------*/
+
+/**
+ * @brief Timing parameters For NOR/SRAM Banks
+ */
+typedef struct
+{
+ uint32_t FSMC_AddressSetupTime; /*!< Defines the number of HCLK cycles to configure
+ the duration of the address setup time.
+ This parameter can be a value between 0 and 0xF.
+ @note This parameter is not used with synchronous NOR Flash memories. */
+
+ uint32_t FSMC_AddressHoldTime; /*!< Defines the number of HCLK cycles to configure
+ the duration of the address hold time.
+ This parameter can be a value between 0 and 0xF.
+ @note This parameter is not used with synchronous NOR Flash memories.*/
+
+ uint32_t FSMC_DataSetupTime; /*!< Defines the number of HCLK cycles to configure
+ the duration of the data setup time.
+ This parameter can be a value between 0 and 0xFF.
+ @note This parameter is used for SRAMs, ROMs and asynchronous multiplexed NOR Flash memories. */
+
+ uint32_t FSMC_BusTurnAroundDuration; /*!< Defines the number of HCLK cycles to configure
+ the duration of the bus turnaround.
+ This parameter can be a value between 0 and 0xF.
+ @note This parameter is only used for multiplexed NOR Flash memories. */
+
+ uint32_t FSMC_CLKDivision; /*!< Defines the period of CLK clock output signal, expressed in number of HCLK cycles.
+ This parameter can be a value between 1 and 0xF.
+ @note This parameter is not used for asynchronous NOR Flash, SRAM or ROM accesses. */
+
+ uint32_t FSMC_DataLatency; /*!< Defines the number of memory clock cycles to issue
+ to the memory before getting the first data.
+ The parameter value depends on the memory type as shown below:
+ - It must be set to 0 in case of a CRAM
+ - It is don't care in asynchronous NOR, SRAM or ROM accesses
+ - It may assume a value between 0 and 0xF in NOR Flash memories
+ with synchronous burst mode enable */
+
+ uint32_t FSMC_AccessMode; /*!< Specifies the asynchronous access mode.
+ This parameter can be a value of @ref FSMC_Access_Mode */
+}FSMC_NORSRAMTimingInitTypeDef;
+
+/**
+ * @brief FSMC NOR/SRAM Init structure definition
+ */
+typedef struct
+{
+ uint32_t FSMC_Bank; /*!< Specifies the NOR/SRAM memory bank that will be used.
+ This parameter can be a value of @ref FSMC_NORSRAM_Bank */
+
+ uint32_t FSMC_DataAddressMux; /*!< Specifies whether the address and data values are
+ multiplexed on the databus or not.
+ This parameter can be a value of @ref FSMC_Data_Address_Bus_Multiplexing */
+
+ uint32_t FSMC_MemoryType; /*!< Specifies the type of external memory attached to
+ the corresponding memory bank.
+ This parameter can be a value of @ref FSMC_Memory_Type */
+
+ uint32_t FSMC_MemoryDataWidth; /*!< Specifies the external memory device width.
+ This parameter can be a value of @ref FSMC_Data_Width */
+
+ uint32_t FSMC_BurstAccessMode; /*!< Enables or disables the burst access mode for Flash memory,
+ valid only with synchronous burst Flash memories.
+ This parameter can be a value of @ref FSMC_Burst_Access_Mode */
+
+ uint32_t FSMC_AsynchronousWait; /*!< Enables or disables wait signal during asynchronous transfers,
+ valid only with asynchronous Flash memories.
+ This parameter can be a value of @ref FSMC_AsynchronousWait */
+
+ uint32_t FSMC_WaitSignalPolarity; /*!< Specifies the wait signal polarity, valid only when accessing
+ the Flash memory in burst mode.
+ This parameter can be a value of @ref FSMC_Wait_Signal_Polarity */
+
+ uint32_t FSMC_WrapMode; /*!< Enables or disables the Wrapped burst access mode for Flash
+ memory, valid only when accessing Flash memories in burst mode.
+ This parameter can be a value of @ref FSMC_Wrap_Mode */
+
+ uint32_t FSMC_WaitSignalActive; /*!< Specifies if the wait signal is asserted by the memory one
+ clock cycle before the wait state or during the wait state,
+ valid only when accessing memories in burst mode.
+ This parameter can be a value of @ref FSMC_Wait_Timing */
+
+ uint32_t FSMC_WriteOperation; /*!< Enables or disables the write operation in the selected bank by the FSMC.
+ This parameter can be a value of @ref FSMC_Write_Operation */
+
+ uint32_t FSMC_WaitSignal; /*!< Enables or disables the wait-state insertion via wait
+ signal, valid for Flash memory access in burst mode.
+ This parameter can be a value of @ref FSMC_Wait_Signal */
+
+ uint32_t FSMC_ExtendedMode; /*!< Enables or disables the extended mode.
+ This parameter can be a value of @ref FSMC_Extended_Mode */
+
+ uint32_t FSMC_WriteBurst; /*!< Enables or disables the write burst operation.
+ This parameter can be a value of @ref FSMC_Write_Burst */
+
+ FSMC_NORSRAMTimingInitTypeDef* FSMC_ReadWriteTimingStruct; /*!< Timing Parameters for write and read access if the ExtendedMode is not used*/
+
+ FSMC_NORSRAMTimingInitTypeDef* FSMC_WriteTimingStruct; /*!< Timing Parameters for write access if the ExtendedMode is used*/
+}FSMC_NORSRAMInitTypeDef;
+
+/**
+ * @brief Timing parameters For FSMC NAND and PCCARD Banks
+ */
+typedef struct
+{
+ uint32_t FSMC_SetupTime; /*!< Defines the number of HCLK cycles to setup address before
+ the command assertion for NAND-Flash read or write access
+ to common/Attribute or I/O memory space (depending on
+ the memory space timing to be configured).
+ This parameter can be a value between 0 and 0xFF.*/
+
+ uint32_t FSMC_WaitSetupTime; /*!< Defines the minimum number of HCLK cycles to assert the
+ command for NAND-Flash read or write access to
+ common/Attribute or I/O memory space (depending on the
+ memory space timing to be configured).
+ This parameter can be a number between 0x00 and 0xFF */
+
+ uint32_t FSMC_HoldSetupTime; /*!< Defines the number of HCLK clock cycles to hold address
+ (and data for write access) after the command deassertion
+ for NAND-Flash read or write access to common/Attribute
+ or I/O memory space (depending on the memory space timing
+ to be configured).
+ This parameter can be a number between 0x00 and 0xFF */
+
+ uint32_t FSMC_HiZSetupTime; /*!< Defines the number of HCLK clock cycles during which the
+ databus is kept in HiZ after the start of a NAND-Flash
+ write access to common/Attribute or I/O memory space (depending
+ on the memory space timing to be configured).
+ This parameter can be a number between 0x00 and 0xFF */
+}FSMC_NAND_PCCARDTimingInitTypeDef;
+
+/**
+ * @brief FSMC NAND Init structure definition
+ */
+typedef struct
+{
+ uint32_t FSMC_Bank; /*!< Specifies the NAND memory bank that will be used.
+ This parameter can be a value of @ref FSMC_NAND_Bank */
+
+ uint32_t FSMC_Waitfeature; /*!< Enables or disables the Wait feature for the NAND Memory Bank.
+ This parameter can be any value of @ref FSMC_Wait_feature */
+
+ uint32_t FSMC_MemoryDataWidth; /*!< Specifies the external memory device width.
+ This parameter can be any value of @ref FSMC_Data_Width */
+
+ uint32_t FSMC_ECC; /*!< Enables or disables the ECC computation.
+ This parameter can be any value of @ref FSMC_ECC */
+
+ uint32_t FSMC_ECCPageSize; /*!< Defines the page size for the extended ECC.
+ This parameter can be any value of @ref FSMC_ECC_Page_Size */
+
+ uint32_t FSMC_TCLRSetupTime; /*!< Defines the number of HCLK cycles to configure the
+ delay between CLE low and RE low.
+ This parameter can be a value between 0 and 0xFF. */
+
+ uint32_t FSMC_TARSetupTime; /*!< Defines the number of HCLK cycles to configure the
+ delay between ALE low and RE low.
+ This parameter can be a number between 0x0 and 0xFF */
+
+ FSMC_NAND_PCCARDTimingInitTypeDef* FSMC_CommonSpaceTimingStruct; /*!< FSMC Common Space Timing */
+
+ FSMC_NAND_PCCARDTimingInitTypeDef* FSMC_AttributeSpaceTimingStruct; /*!< FSMC Attribute Space Timing */
+}FSMC_NANDInitTypeDef;
+
+/**
+ * @brief FSMC PCCARD Init structure definition
+ */
+
+typedef struct
+{
+ uint32_t FSMC_Waitfeature; /*!< Enables or disables the Wait feature for the Memory Bank.
+ This parameter can be any value of @ref FSMC_Wait_feature */
+
+ uint32_t FSMC_TCLRSetupTime; /*!< Defines the number of HCLK cycles to configure the
+ delay between CLE low and RE low.
+ This parameter can be a value between 0 and 0xFF. */
+
+ uint32_t FSMC_TARSetupTime; /*!< Defines the number of HCLK cycles to configure the
+ delay between ALE low and RE low.
+ This parameter can be a number between 0x0 and 0xFF */
+
+
+ FSMC_NAND_PCCARDTimingInitTypeDef* FSMC_CommonSpaceTimingStruct; /*!< FSMC Common Space Timing */
+
+ FSMC_NAND_PCCARDTimingInitTypeDef* FSMC_AttributeSpaceTimingStruct; /*!< FSMC Attribute Space Timing */
+
+ FSMC_NAND_PCCARDTimingInitTypeDef* FSMC_IOSpaceTimingStruct; /*!< FSMC IO Space Timing */
+}FSMC_PCCARDInitTypeDef;
+
+/* Exported constants --------------------------------------------------------*/
+
+/** @defgroup FSMC_Exported_Constants
+ * @{
+ */
+
+/** @defgroup FSMC_NORSRAM_Bank
+ * @{
+ */
+#define FSMC_Bank1_NORSRAM1 ((uint32_t)0x00000000)
+#define FSMC_Bank1_NORSRAM2 ((uint32_t)0x00000002)
+#define FSMC_Bank1_NORSRAM3 ((uint32_t)0x00000004)
+#define FSMC_Bank1_NORSRAM4 ((uint32_t)0x00000006)
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_NAND_Bank
+ * @{
+ */
+#define FSMC_Bank2_NAND ((uint32_t)0x00000010)
+#define FSMC_Bank3_NAND ((uint32_t)0x00000100)
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_PCCARD_Bank
+ * @{
+ */
+#define FSMC_Bank4_PCCARD ((uint32_t)0x00001000)
+/**
+ * @}
+ */
+
+#define IS_FSMC_NORSRAM_BANK(BANK) (((BANK) == FSMC_Bank1_NORSRAM1) || \
+ ((BANK) == FSMC_Bank1_NORSRAM2) || \
+ ((BANK) == FSMC_Bank1_NORSRAM3) || \
+ ((BANK) == FSMC_Bank1_NORSRAM4))
+
+#define IS_FSMC_NAND_BANK(BANK) (((BANK) == FSMC_Bank2_NAND) || \
+ ((BANK) == FSMC_Bank3_NAND))
+
+#define IS_FSMC_GETFLAG_BANK(BANK) (((BANK) == FSMC_Bank2_NAND) || \
+ ((BANK) == FSMC_Bank3_NAND) || \
+ ((BANK) == FSMC_Bank4_PCCARD))
+
+#define IS_FSMC_IT_BANK(BANK) (((BANK) == FSMC_Bank2_NAND) || \
+ ((BANK) == FSMC_Bank3_NAND) || \
+ ((BANK) == FSMC_Bank4_PCCARD))
+
+/** @defgroup FSMC_NOR_SRAM_Controller
+ * @{
+ */
+
+/** @defgroup FSMC_Data_Address_Bus_Multiplexing
+ * @{
+ */
+
+#define FSMC_DataAddressMux_Disable ((uint32_t)0x00000000)
+#define FSMC_DataAddressMux_Enable ((uint32_t)0x00000002)
+#define IS_FSMC_MUX(MUX) (((MUX) == FSMC_DataAddressMux_Disable) || \
+ ((MUX) == FSMC_DataAddressMux_Enable))
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Memory_Type
+ * @{
+ */
+
+#define FSMC_MemoryType_SRAM ((uint32_t)0x00000000)
+#define FSMC_MemoryType_PSRAM ((uint32_t)0x00000004)
+#define FSMC_MemoryType_NOR ((uint32_t)0x00000008)
+#define IS_FSMC_MEMORY(MEMORY) (((MEMORY) == FSMC_MemoryType_SRAM) || \
+ ((MEMORY) == FSMC_MemoryType_PSRAM)|| \
+ ((MEMORY) == FSMC_MemoryType_NOR))
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Data_Width
+ * @{
+ */
+
+#define FSMC_MemoryDataWidth_8b ((uint32_t)0x00000000)
+#define FSMC_MemoryDataWidth_16b ((uint32_t)0x00000010)
+#define IS_FSMC_MEMORY_WIDTH(WIDTH) (((WIDTH) == FSMC_MemoryDataWidth_8b) || \
+ ((WIDTH) == FSMC_MemoryDataWidth_16b))
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Burst_Access_Mode
+ * @{
+ */
+
+#define FSMC_BurstAccessMode_Disable ((uint32_t)0x00000000)
+#define FSMC_BurstAccessMode_Enable ((uint32_t)0x00000100)
+#define IS_FSMC_BURSTMODE(STATE) (((STATE) == FSMC_BurstAccessMode_Disable) || \
+ ((STATE) == FSMC_BurstAccessMode_Enable))
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_AsynchronousWait
+ * @{
+ */
+#define FSMC_AsynchronousWait_Disable ((uint32_t)0x00000000)
+#define FSMC_AsynchronousWait_Enable ((uint32_t)0x00008000)
+#define IS_FSMC_ASYNWAIT(STATE) (((STATE) == FSMC_AsynchronousWait_Disable) || \
+ ((STATE) == FSMC_AsynchronousWait_Enable))
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Wait_Signal_Polarity
+ * @{
+ */
+#define FSMC_WaitSignalPolarity_Low ((uint32_t)0x00000000)
+#define FSMC_WaitSignalPolarity_High ((uint32_t)0x00000200)
+#define IS_FSMC_WAIT_POLARITY(POLARITY) (((POLARITY) == FSMC_WaitSignalPolarity_Low) || \
+ ((POLARITY) == FSMC_WaitSignalPolarity_High))
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Wrap_Mode
+ * @{
+ */
+#define FSMC_WrapMode_Disable ((uint32_t)0x00000000)
+#define FSMC_WrapMode_Enable ((uint32_t)0x00000400)
+#define IS_FSMC_WRAP_MODE(MODE) (((MODE) == FSMC_WrapMode_Disable) || \
+ ((MODE) == FSMC_WrapMode_Enable))
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Wait_Timing
+ * @{
+ */
+#define FSMC_WaitSignalActive_BeforeWaitState ((uint32_t)0x00000000)
+#define FSMC_WaitSignalActive_DuringWaitState ((uint32_t)0x00000800)
+#define IS_FSMC_WAIT_SIGNAL_ACTIVE(ACTIVE) (((ACTIVE) == FSMC_WaitSignalActive_BeforeWaitState) || \
+ ((ACTIVE) == FSMC_WaitSignalActive_DuringWaitState))
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Write_Operation
+ * @{
+ */
+#define FSMC_WriteOperation_Disable ((uint32_t)0x00000000)
+#define FSMC_WriteOperation_Enable ((uint32_t)0x00001000)
+#define IS_FSMC_WRITE_OPERATION(OPERATION) (((OPERATION) == FSMC_WriteOperation_Disable) || \
+ ((OPERATION) == FSMC_WriteOperation_Enable))
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Wait_Signal
+ * @{
+ */
+#define FSMC_WaitSignal_Disable ((uint32_t)0x00000000)
+#define FSMC_WaitSignal_Enable ((uint32_t)0x00002000)
+#define IS_FSMC_WAITE_SIGNAL(SIGNAL) (((SIGNAL) == FSMC_WaitSignal_Disable) || \
+ ((SIGNAL) == FSMC_WaitSignal_Enable))
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Extended_Mode
+ * @{
+ */
+#define FSMC_ExtendedMode_Disable ((uint32_t)0x00000000)
+#define FSMC_ExtendedMode_Enable ((uint32_t)0x00004000)
+
+#define IS_FSMC_EXTENDED_MODE(MODE) (((MODE) == FSMC_ExtendedMode_Disable) || \
+ ((MODE) == FSMC_ExtendedMode_Enable))
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Write_Burst
+ * @{
+ */
+
+#define FSMC_WriteBurst_Disable ((uint32_t)0x00000000)
+#define FSMC_WriteBurst_Enable ((uint32_t)0x00080000)
+#define IS_FSMC_WRITE_BURST(BURST) (((BURST) == FSMC_WriteBurst_Disable) || \
+ ((BURST) == FSMC_WriteBurst_Enable))
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Address_Setup_Time
+ * @{
+ */
+#define IS_FSMC_ADDRESS_SETUP_TIME(TIME) ((TIME) <= 0xF)
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Address_Hold_Time
+ * @{
+ */
+#define IS_FSMC_ADDRESS_HOLD_TIME(TIME) ((TIME) <= 0xF)
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Data_Setup_Time
+ * @{
+ */
+#define IS_FSMC_DATASETUP_TIME(TIME) (((TIME) > 0) && ((TIME) <= 0xFF))
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Bus_Turn_around_Duration
+ * @{
+ */
+#define IS_FSMC_TURNAROUND_TIME(TIME) ((TIME) <= 0xF)
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_CLK_Division
+ * @{
+ */
+#define IS_FSMC_CLK_DIV(DIV) ((DIV) <= 0xF)
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Data_Latency
+ * @{
+ */
+#define IS_FSMC_DATA_LATENCY(LATENCY) ((LATENCY) <= 0xF)
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Access_Mode
+ * @{
+ */
+#define FSMC_AccessMode_A ((uint32_t)0x00000000)
+#define FSMC_AccessMode_B ((uint32_t)0x10000000)
+#define FSMC_AccessMode_C ((uint32_t)0x20000000)
+#define FSMC_AccessMode_D ((uint32_t)0x30000000)
+#define IS_FSMC_ACCESS_MODE(MODE) (((MODE) == FSMC_AccessMode_A) || \
+ ((MODE) == FSMC_AccessMode_B) || \
+ ((MODE) == FSMC_AccessMode_C) || \
+ ((MODE) == FSMC_AccessMode_D))
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_NAND_PCCARD_Controller
+ * @{
+ */
+
+/** @defgroup FSMC_Wait_feature
+ * @{
+ */
+#define FSMC_Waitfeature_Disable ((uint32_t)0x00000000)
+#define FSMC_Waitfeature_Enable ((uint32_t)0x00000002)
+#define IS_FSMC_WAIT_FEATURE(FEATURE) (((FEATURE) == FSMC_Waitfeature_Disable) || \
+ ((FEATURE) == FSMC_Waitfeature_Enable))
+/**
+ * @}
+ */
+
+
+/** @defgroup FSMC_ECC
+ * @{
+ */
+#define FSMC_ECC_Disable ((uint32_t)0x00000000)
+#define FSMC_ECC_Enable ((uint32_t)0x00000040)
+#define IS_FSMC_ECC_STATE(STATE) (((STATE) == FSMC_ECC_Disable) || \
+ ((STATE) == FSMC_ECC_Enable))
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_ECC_Page_Size
+ * @{
+ */
+#define FSMC_ECCPageSize_256Bytes ((uint32_t)0x00000000)
+#define FSMC_ECCPageSize_512Bytes ((uint32_t)0x00020000)
+#define FSMC_ECCPageSize_1024Bytes ((uint32_t)0x00040000)
+#define FSMC_ECCPageSize_2048Bytes ((uint32_t)0x00060000)
+#define FSMC_ECCPageSize_4096Bytes ((uint32_t)0x00080000)
+#define FSMC_ECCPageSize_8192Bytes ((uint32_t)0x000A0000)
+#define IS_FSMC_ECCPAGE_SIZE(SIZE) (((SIZE) == FSMC_ECCPageSize_256Bytes) || \
+ ((SIZE) == FSMC_ECCPageSize_512Bytes) || \
+ ((SIZE) == FSMC_ECCPageSize_1024Bytes) || \
+ ((SIZE) == FSMC_ECCPageSize_2048Bytes) || \
+ ((SIZE) == FSMC_ECCPageSize_4096Bytes) || \
+ ((SIZE) == FSMC_ECCPageSize_8192Bytes))
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_TCLR_Setup_Time
+ * @{
+ */
+#define IS_FSMC_TCLR_TIME(TIME) ((TIME) <= 0xFF)
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_TAR_Setup_Time
+ * @{
+ */
+#define IS_FSMC_TAR_TIME(TIME) ((TIME) <= 0xFF)
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Setup_Time
+ * @{
+ */
+#define IS_FSMC_SETUP_TIME(TIME) ((TIME) <= 0xFF)
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Wait_Setup_Time
+ * @{
+ */
+#define IS_FSMC_WAIT_TIME(TIME) ((TIME) <= 0xFF)
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Hold_Setup_Time
+ * @{
+ */
+#define IS_FSMC_HOLD_TIME(TIME) ((TIME) <= 0xFF)
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_HiZ_Setup_Time
+ * @{
+ */
+#define IS_FSMC_HIZ_TIME(TIME) ((TIME) <= 0xFF)
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Interrupt_sources
+ * @{
+ */
+#define FSMC_IT_RisingEdge ((uint32_t)0x00000008)
+#define FSMC_IT_Level ((uint32_t)0x00000010)
+#define FSMC_IT_FallingEdge ((uint32_t)0x00000020)
+#define IS_FSMC_IT(IT) ((((IT) & (uint32_t)0xFFFFFFC7) == 0x00000000) && ((IT) != 0x00000000))
+#define IS_FSMC_GET_IT(IT) (((IT) == FSMC_IT_RisingEdge) || \
+ ((IT) == FSMC_IT_Level) || \
+ ((IT) == FSMC_IT_FallingEdge))
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Flags
+ * @{
+ */
+#define FSMC_FLAG_RisingEdge ((uint32_t)0x00000001)
+#define FSMC_FLAG_Level ((uint32_t)0x00000002)
+#define FSMC_FLAG_FallingEdge ((uint32_t)0x00000004)
+#define FSMC_FLAG_FEMPT ((uint32_t)0x00000040)
+#define IS_FSMC_GET_FLAG(FLAG) (((FLAG) == FSMC_FLAG_RisingEdge) || \
+ ((FLAG) == FSMC_FLAG_Level) || \
+ ((FLAG) == FSMC_FLAG_FallingEdge) || \
+ ((FLAG) == FSMC_FLAG_FEMPT))
+
+#define IS_FSMC_CLEAR_FLAG(FLAG) ((((FLAG) & (uint32_t)0xFFFFFFF8) == 0x00000000) && ((FLAG) != 0x00000000))
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions --------------------------------------------------------*/
+
+/* NOR/SRAM Controller functions **********************************************/
+void FSMC_NORSRAMDeInit(uint32_t FSMC_Bank);
+void FSMC_NORSRAMInit(FSMC_NORSRAMInitTypeDef* FSMC_NORSRAMInitStruct);
+void FSMC_NORSRAMStructInit(FSMC_NORSRAMInitTypeDef* FSMC_NORSRAMInitStruct);
+void FSMC_NORSRAMCmd(uint32_t FSMC_Bank, FunctionalState NewState);
+
+/* NAND Controller functions **************************************************/
+void FSMC_NANDDeInit(uint32_t FSMC_Bank);
+void FSMC_NANDInit(FSMC_NANDInitTypeDef* FSMC_NANDInitStruct);
+void FSMC_NANDStructInit(FSMC_NANDInitTypeDef* FSMC_NANDInitStruct);
+void FSMC_NANDCmd(uint32_t FSMC_Bank, FunctionalState NewState);
+void FSMC_NANDECCCmd(uint32_t FSMC_Bank, FunctionalState NewState);
+uint32_t FSMC_GetECC(uint32_t FSMC_Bank);
+
+/* PCCARD Controller functions ************************************************/
+void FSMC_PCCARDDeInit(void);
+void FSMC_PCCARDInit(FSMC_PCCARDInitTypeDef* FSMC_PCCARDInitStruct);
+void FSMC_PCCARDStructInit(FSMC_PCCARDInitTypeDef* FSMC_PCCARDInitStruct);
+void FSMC_PCCARDCmd(FunctionalState NewState);
+
+/* Interrupts and flags management functions **********************************/
+void FSMC_ITConfig(uint32_t FSMC_Bank, uint32_t FSMC_IT, FunctionalState NewState);
+FlagStatus FSMC_GetFlagStatus(uint32_t FSMC_Bank, uint32_t FSMC_FLAG);
+void FSMC_ClearFlag(uint32_t FSMC_Bank, uint32_t FSMC_FLAG);
+ITStatus FSMC_GetITStatus(uint32_t FSMC_Bank, uint32_t FSMC_IT);
+void FSMC_ClearITPendingBit(uint32_t FSMC_Bank, uint32_t FSMC_IT);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*__STM32F2xx_FSMC_H */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/inc/stm32f2xx_gpio.h b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/inc/stm32f2xx_gpio.h
new file mode 100644
index 0000000..c2fe965
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/inc/stm32f2xx_gpio.h
@@ -0,0 +1,411 @@
+/**
+ ******************************************************************************
+ * @file stm32f2xx_gpio.h
+ * @author MCD Application Team
+ * @version V1.1.2
+ * @date 05-March-2012
+ * @brief This file contains all the functions prototypes for the GPIO firmware
+ * 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 __STM32F2xx_GPIO_H
+#define __STM32F2xx_GPIO_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f2xx.h"
+
+/** @addtogroup STM32F2xx_StdPeriph_Driver
+ * @{
+ */
+
+/** @addtogroup GPIO
+ * @{
+ */
+
+/* Exported types ------------------------------------------------------------*/
+
+#define IS_GPIO_ALL_PERIPH(PERIPH) (((PERIPH) == GPIOA) || \
+ ((PERIPH) == GPIOB) || \
+ ((PERIPH) == GPIOC) || \
+ ((PERIPH) == GPIOD) || \
+ ((PERIPH) == GPIOE) || \
+ ((PERIPH) == GPIOF) || \
+ ((PERIPH) == GPIOG) || \
+ ((PERIPH) == GPIOH) || \
+ ((PERIPH) == GPIOI))
+
+/**
+ * @brief GPIO Configuration Mode enumeration
+ */
+typedef enum
+{
+ GPIO_Mode_IN = 0x00, /*!< GPIO Input Mode */
+ GPIO_Mode_OUT = 0x01, /*!< GPIO Output Mode */
+ GPIO_Mode_AF = 0x02, /*!< GPIO Alternate function Mode */
+ GPIO_Mode_AN = 0x03 /*!< GPIO Analog Mode */
+}GPIOMode_TypeDef;
+#define IS_GPIO_MODE(MODE) (((MODE) == GPIO_Mode_IN) || ((MODE) == GPIO_Mode_OUT) || \
+ ((MODE) == GPIO_Mode_AF)|| ((MODE) == GPIO_Mode_AN))
+
+/**
+ * @brief GPIO Output type enumeration
+ */
+typedef enum
+{
+ GPIO_OType_PP = 0x00,
+ GPIO_OType_OD = 0x01
+}GPIOOType_TypeDef;
+#define IS_GPIO_OTYPE(OTYPE) (((OTYPE) == GPIO_OType_PP) || ((OTYPE) == GPIO_OType_OD))
+
+
+/**
+ * @brief GPIO Output Maximum frequency enumeration
+ */
+typedef enum
+{
+ GPIO_Speed_2MHz = 0x00, /*!< Low speed */
+ GPIO_Speed_25MHz = 0x01, /*!< Medium speed */
+ GPIO_Speed_50MHz = 0x02, /*!< Fast speed */
+ GPIO_Speed_100MHz = 0x03 /*!< High speed on 30 pF (80 MHz Output max speed on 15 pF) */
+}GPIOSpeed_TypeDef;
+#define IS_GPIO_SPEED(SPEED) (((SPEED) == GPIO_Speed_2MHz) || ((SPEED) == GPIO_Speed_25MHz) || \
+ ((SPEED) == GPIO_Speed_50MHz)|| ((SPEED) == GPIO_Speed_100MHz))
+
+/**
+ * @brief GPIO Configuration PullUp PullDown enumeration
+ */
+typedef enum
+{
+ GPIO_PuPd_NOPULL = 0x00,
+ GPIO_PuPd_UP = 0x01,
+ GPIO_PuPd_DOWN = 0x02
+}GPIOPuPd_TypeDef;
+#define IS_GPIO_PUPD(PUPD) (((PUPD) == GPIO_PuPd_NOPULL) || ((PUPD) == GPIO_PuPd_UP) || \
+ ((PUPD) == GPIO_PuPd_DOWN))
+
+/**
+ * @brief GPIO Bit SET and Bit RESET enumeration
+ */
+typedef enum
+{
+ Bit_RESET = 0,
+ Bit_SET
+}BitAction;
+#define IS_GPIO_BIT_ACTION(ACTION) (((ACTION) == Bit_RESET) || ((ACTION) == Bit_SET))
+
+
+/**
+ * @brief GPIO Init structure definition
+ */
+typedef struct
+{
+ uint32_t GPIO_Pin; /*!< Specifies the GPIO pins to be configured.
+ This parameter can be any value of @ref GPIO_pins_define */
+
+ GPIOMode_TypeDef GPIO_Mode; /*!< Specifies the operating mode for the selected pins.
+ This parameter can be a value of @ref GPIOMode_TypeDef */
+
+ GPIOSpeed_TypeDef GPIO_Speed; /*!< Specifies the speed for the selected pins.
+ This parameter can be a value of @ref GPIOSpeed_TypeDef */
+
+ GPIOOType_TypeDef GPIO_OType; /*!< Specifies the operating output type for the selected pins.
+ This parameter can be a value of @ref GPIOOType_TypeDef */
+
+ GPIOPuPd_TypeDef GPIO_PuPd; /*!< Specifies the operating Pull-up/Pull down for the selected pins.
+ This parameter can be a value of @ref GPIOPuPd_TypeDef */
+}GPIO_InitTypeDef;
+
+/* Exported constants --------------------------------------------------------*/
+
+/** @defgroup GPIO_Exported_Constants
+ * @{
+ */
+
+/** @defgroup GPIO_pins_define
+ * @{
+ */
+#define GPIO_Pin_0 ((uint16_t)0x0001) /* Pin 0 selected */
+#define GPIO_Pin_1 ((uint16_t)0x0002) /* Pin 1 selected */
+#define GPIO_Pin_2 ((uint16_t)0x0004) /* Pin 2 selected */
+#define GPIO_Pin_3 ((uint16_t)0x0008) /* Pin 3 selected */
+#define GPIO_Pin_4 ((uint16_t)0x0010) /* Pin 4 selected */
+#define GPIO_Pin_5 ((uint16_t)0x0020) /* Pin 5 selected */
+#define GPIO_Pin_6 ((uint16_t)0x0040) /* Pin 6 selected */
+#define GPIO_Pin_7 ((uint16_t)0x0080) /* Pin 7 selected */
+#define GPIO_Pin_8 ((uint16_t)0x0100) /* Pin 8 selected */
+#define GPIO_Pin_9 ((uint16_t)0x0200) /* Pin 9 selected */
+#define GPIO_Pin_10 ((uint16_t)0x0400) /* Pin 10 selected */
+#define GPIO_Pin_11 ((uint16_t)0x0800) /* Pin 11 selected */
+#define GPIO_Pin_12 ((uint16_t)0x1000) /* Pin 12 selected */
+#define GPIO_Pin_13 ((uint16_t)0x2000) /* Pin 13 selected */
+#define GPIO_Pin_14 ((uint16_t)0x4000) /* Pin 14 selected */
+#define GPIO_Pin_15 ((uint16_t)0x8000) /* Pin 15 selected */
+#define GPIO_Pin_All ((uint16_t)0xFFFF) /* All pins selected */
+
+#define IS_GPIO_PIN(PIN) ((((PIN) & (uint16_t)0x00) == 0x00) && ((PIN) != (uint16_t)0x00))
+#define IS_GET_GPIO_PIN(PIN) (((PIN) == GPIO_Pin_0) || \
+ ((PIN) == GPIO_Pin_1) || \
+ ((PIN) == GPIO_Pin_2) || \
+ ((PIN) == GPIO_Pin_3) || \
+ ((PIN) == GPIO_Pin_4) || \
+ ((PIN) == GPIO_Pin_5) || \
+ ((PIN) == GPIO_Pin_6) || \
+ ((PIN) == GPIO_Pin_7) || \
+ ((PIN) == GPIO_Pin_8) || \
+ ((PIN) == GPIO_Pin_9) || \
+ ((PIN) == GPIO_Pin_10) || \
+ ((PIN) == GPIO_Pin_11) || \
+ ((PIN) == GPIO_Pin_12) || \
+ ((PIN) == GPIO_Pin_13) || \
+ ((PIN) == GPIO_Pin_14) || \
+ ((PIN) == GPIO_Pin_15))
+/**
+ * @}
+ */
+
+
+/** @defgroup GPIO_Pin_sources
+ * @{
+ */
+#define GPIO_PinSource0 ((uint8_t)0x00)
+#define GPIO_PinSource1 ((uint8_t)0x01)
+#define GPIO_PinSource2 ((uint8_t)0x02)
+#define GPIO_PinSource3 ((uint8_t)0x03)
+#define GPIO_PinSource4 ((uint8_t)0x04)
+#define GPIO_PinSource5 ((uint8_t)0x05)
+#define GPIO_PinSource6 ((uint8_t)0x06)
+#define GPIO_PinSource7 ((uint8_t)0x07)
+#define GPIO_PinSource8 ((uint8_t)0x08)
+#define GPIO_PinSource9 ((uint8_t)0x09)
+#define GPIO_PinSource10 ((uint8_t)0x0A)
+#define GPIO_PinSource11 ((uint8_t)0x0B)
+#define GPIO_PinSource12 ((uint8_t)0x0C)
+#define GPIO_PinSource13 ((uint8_t)0x0D)
+#define GPIO_PinSource14 ((uint8_t)0x0E)
+#define GPIO_PinSource15 ((uint8_t)0x0F)
+
+#define IS_GPIO_PIN_SOURCE(PINSOURCE) (((PINSOURCE) == GPIO_PinSource0) || \
+ ((PINSOURCE) == GPIO_PinSource1) || \
+ ((PINSOURCE) == GPIO_PinSource2) || \
+ ((PINSOURCE) == GPIO_PinSource3) || \
+ ((PINSOURCE) == GPIO_PinSource4) || \
+ ((PINSOURCE) == GPIO_PinSource5) || \
+ ((PINSOURCE) == GPIO_PinSource6) || \
+ ((PINSOURCE) == GPIO_PinSource7) || \
+ ((PINSOURCE) == GPIO_PinSource8) || \
+ ((PINSOURCE) == GPIO_PinSource9) || \
+ ((PINSOURCE) == GPIO_PinSource10) || \
+ ((PINSOURCE) == GPIO_PinSource11) || \
+ ((PINSOURCE) == GPIO_PinSource12) || \
+ ((PINSOURCE) == GPIO_PinSource13) || \
+ ((PINSOURCE) == GPIO_PinSource14) || \
+ ((PINSOURCE) == GPIO_PinSource15))
+/**
+ * @}
+ */
+
+/** @defgroup GPIO_Alternat_function_selection_define
+ * @{
+ */
+/**
+ * @brief AF 0 selection
+ */
+#define GPIO_AF_RTC_50Hz ((uint8_t)0x00) /* RTC_50Hz Alternate Function mapping */
+#define GPIO_AF_MCO ((uint8_t)0x00) /* MCO (MCO1 and MCO2) Alternate Function mapping */
+#define GPIO_AF_TAMPER ((uint8_t)0x00) /* TAMPER (TAMPER_1 and TAMPER_2) Alternate Function mapping */
+#define GPIO_AF_SWJ ((uint8_t)0x00) /* SWJ (SWD and JTAG) Alternate Function mapping */
+#define GPIO_AF_TRACE ((uint8_t)0x00) /* TRACE Alternate Function mapping */
+
+/**
+ * @brief AF 1 selection
+ */
+#define GPIO_AF_TIM1 ((uint8_t)0x01) /* TIM1 Alternate Function mapping */
+#define GPIO_AF_TIM2 ((uint8_t)0x01) /* TIM2 Alternate Function mapping */
+
+/**
+ * @brief AF 2 selection
+ */
+#define GPIO_AF_TIM3 ((uint8_t)0x02) /* TIM3 Alternate Function mapping */
+#define GPIO_AF_TIM4 ((uint8_t)0x02) /* TIM4 Alternate Function mapping */
+#define GPIO_AF_TIM5 ((uint8_t)0x02) /* TIM5 Alternate Function mapping */
+
+/**
+ * @brief AF 3 selection
+ */
+#define GPIO_AF_TIM8 ((uint8_t)0x03) /* TIM8 Alternate Function mapping */
+#define GPIO_AF_TIM9 ((uint8_t)0x03) /* TIM9 Alternate Function mapping */
+#define GPIO_AF_TIM10 ((uint8_t)0x03) /* TIM10 Alternate Function mapping */
+#define GPIO_AF_TIM11 ((uint8_t)0x03) /* TIM11 Alternate Function mapping */
+
+/**
+ * @brief AF 4 selection
+ */
+#define GPIO_AF_I2C1 ((uint8_t)0x04) /* I2C1 Alternate Function mapping */
+#define GPIO_AF_I2C2 ((uint8_t)0x04) /* I2C2 Alternate Function mapping */
+#define GPIO_AF_I2C3 ((uint8_t)0x04) /* I2C3 Alternate Function mapping */
+
+/**
+ * @brief AF 5 selection
+ */
+#define GPIO_AF_SPI1 ((uint8_t)0x05) /* SPI1 Alternate Function mapping */
+#define GPIO_AF_SPI2 ((uint8_t)0x05) /* SPI2/I2S2 Alternate Function mapping */
+
+/**
+ * @brief AF 6 selection
+ */
+#define GPIO_AF_SPI3 ((uint8_t)0x06) /* SPI3/I2S3 Alternate Function mapping */
+
+/**
+ * @brief AF 7 selection
+ */
+#define GPIO_AF_USART1 ((uint8_t)0x07) /* USART1 Alternate Function mapping */
+#define GPIO_AF_USART2 ((uint8_t)0x07) /* USART2 Alternate Function mapping */
+#define GPIO_AF_USART3 ((uint8_t)0x07) /* USART3 Alternate Function mapping */
+
+/**
+ * @brief AF 8 selection
+ */
+#define GPIO_AF_UART4 ((uint8_t)0x08) /* UART4 Alternate Function mapping */
+#define GPIO_AF_UART5 ((uint8_t)0x08) /* UART5 Alternate Function mapping */
+#define GPIO_AF_USART6 ((uint8_t)0x08) /* USART6 Alternate Function mapping */
+
+/**
+ * @brief AF 9 selection
+ */
+#define GPIO_AF_CAN1 ((uint8_t)0x09) /* CAN1 Alternate Function mapping */
+#define GPIO_AF_CAN2 ((uint8_t)0x09) /* CAN2 Alternate Function mapping */
+#define GPIO_AF_TIM12 ((uint8_t)0x09) /* TIM12 Alternate Function mapping */
+#define GPIO_AF_TIM13 ((uint8_t)0x09) /* TIM13 Alternate Function mapping */
+#define GPIO_AF_TIM14 ((uint8_t)0x09) /* TIM14 Alternate Function mapping */
+
+/**
+ * @brief AF 10 selection
+ */
+#define GPIO_AF_OTG_FS ((uint8_t)0xA) /* OTG_FS Alternate Function mapping */
+#define GPIO_AF_OTG_HS ((uint8_t)0xA) /* OTG_HS Alternate Function mapping */
+
+/**
+ * @brief AF 11 selection
+ */
+#define GPIO_AF_ETH ((uint8_t)0x0B) /* ETHERNET Alternate Function mapping */
+
+/**
+ * @brief AF 12 selection
+ */
+#define GPIO_AF_FSMC ((uint8_t)0xC) /* FSMC Alternate Function mapping */
+#define GPIO_AF_OTG_HS_FS ((uint8_t)0xC) /* OTG HS configured in FS, Alternate Function mapping */
+#define GPIO_AF_SDIO ((uint8_t)0xC) /* SDIO Alternate Function mapping */
+
+/**
+ * @brief AF 13 selection
+ */
+#define GPIO_AF_DCMI ((uint8_t)0x0D) /* DCMI Alternate Function mapping */
+
+/**
+ * @brief AF 15 selection
+ */
+#define GPIO_AF_EVENTOUT ((uint8_t)0x0F) /* EVENTOUT Alternate Function mapping */
+
+#define IS_GPIO_AF(AF) (((AF) == GPIO_AF_RTC_50Hz) || ((AF) == GPIO_AF_TIM14) || \
+ ((AF) == GPIO_AF_MCO) || ((AF) == GPIO_AF_TAMPER) || \
+ ((AF) == GPIO_AF_SWJ) || ((AF) == GPIO_AF_TRACE) || \
+ ((AF) == GPIO_AF_TIM1) || ((AF) == GPIO_AF_TIM2) || \
+ ((AF) == GPIO_AF_TIM3) || ((AF) == GPIO_AF_TIM4) || \
+ ((AF) == GPIO_AF_TIM5) || ((AF) == GPIO_AF_TIM8) || \
+ ((AF) == GPIO_AF_I2C1) || ((AF) == GPIO_AF_I2C2) || \
+ ((AF) == GPIO_AF_I2C3) || ((AF) == GPIO_AF_SPI1) || \
+ ((AF) == GPIO_AF_SPI2) || ((AF) == GPIO_AF_TIM13) || \
+ ((AF) == GPIO_AF_SPI3) || ((AF) == GPIO_AF_TIM14) || \
+ ((AF) == GPIO_AF_USART1) || ((AF) == GPIO_AF_USART2) || \
+ ((AF) == GPIO_AF_USART3) || ((AF) == GPIO_AF_UART4) || \
+ ((AF) == GPIO_AF_UART5) || ((AF) == GPIO_AF_USART6) || \
+ ((AF) == GPIO_AF_CAN1) || ((AF) == GPIO_AF_CAN2) || \
+ ((AF) == GPIO_AF_OTG_FS) || ((AF) == GPIO_AF_OTG_HS) || \
+ ((AF) == GPIO_AF_ETH) || ((AF) == GPIO_AF_FSMC) || \
+ ((AF) == GPIO_AF_OTG_HS_FS) || ((AF) == GPIO_AF_SDIO) || \
+ ((AF) == GPIO_AF_DCMI) || ((AF) == GPIO_AF_EVENTOUT))
+/**
+ * @}
+ */
+
+/** @defgroup GPIO_Legacy
+ * @{
+ */
+
+#define GPIO_Mode_AIN GPIO_Mode_AN
+
+#define GPIO_AF_OTG1_FS GPIO_AF_OTG_FS
+#define GPIO_AF_OTG2_HS GPIO_AF_OTG_HS
+#define GPIO_AF_OTG2_FS GPIO_AF_OTG_HS_FS
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions --------------------------------------------------------*/
+
+/* Function used to set the GPIO configuration to the default reset state ****/
+void GPIO_DeInit(GPIO_TypeDef* GPIOx);
+
+/* Initialization and Configuration functions *********************************/
+void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);
+void GPIO_StructInit(GPIO_InitTypeDef* GPIO_InitStruct);
+void GPIO_PinLockConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
+
+/* GPIO Read and Write functions **********************************************/
+uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
+uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx);
+uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
+uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx);
+void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
+void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
+void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal);
+void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal);
+void GPIO_ToggleBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
+
+/* GPIO Alternate functions configuration function ****************************/
+void GPIO_PinAFConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_PinSource, uint8_t GPIO_AF);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*__STM32F2xx_GPIO_H */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/inc/stm32f2xx_hash.h b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/inc/stm32f2xx_hash.h
new file mode 100644
index 0000000..2e5039e
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/inc/stm32f2xx_hash.h
@@ -0,0 +1,250 @@
+/**
+ ******************************************************************************
+ * @file stm32f2xx_hash.h
+ * @author MCD Application Team
+ * @version V1.1.2
+ * @date 05-March-2012
+ * @brief This file contains all the functions prototypes for the HASH
+ * firmware 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 __STM32F2xx_HASH_H
+#define __STM32F2xx_HASH_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f2xx.h"
+
+/** @addtogroup STM32F2xx_StdPeriph_Driver
+ * @{
+ */
+
+/** @addtogroup HASH
+ * @{
+ */
+
+/* Exported types ------------------------------------------------------------*/
+
+/**
+ * @brief HASH Init structure definition
+ */
+typedef struct
+{
+ uint32_t HASH_AlgoSelection; /*!< SHA-1 or MD5. This parameter can be a value
+ of @ref HASH_Algo_Selection */
+ uint32_t HASH_AlgoMode; /*!< HASH or HMAC. This parameter can be a value
+ of @ref HASH_processor_Algorithm_Mode */
+ uint32_t HASH_DataType; /*!< 32-bit data, 16-bit data, 8-bit data or
+ bit-string. This parameter can be a value of
+ @ref HASH_Data_Type */
+ uint32_t HASH_HMACKeyType; /*!< HMAC Short key or HMAC Long Key. This parameter
+ can be a value of @ref HASH_HMAC_Long_key_only_for_HMAC_mode */
+}HASH_InitTypeDef;
+
+/**
+ * @brief HASH message digest result structure definition
+ */
+typedef struct
+{
+ uint32_t Data[5]; /*!< Message digest result : 5x 32bit words for SHA1 or
+ 4x 32bit words for MD5 */
+} HASH_MsgDigest;
+
+/**
+ * @brief HASH context swapping structure definition
+ */
+typedef struct
+{
+ uint32_t HASH_IMR;
+ uint32_t HASH_STR;
+ uint32_t HASH_CR;
+ uint32_t HASH_CSR[51];
+}HASH_Context;
+
+/* Exported constants --------------------------------------------------------*/
+
+/** @defgroup HASH_Exported_Constants
+ * @{
+ */
+
+/** @defgroup HASH_Algo_Selection
+ * @{
+ */
+#define HASH_AlgoSelection_SHA1 ((uint16_t)0x0000) /*!< HASH function is SHA1 */
+#define HASH_AlgoSelection_MD5 ((uint16_t)0x0080) /*!< HASH function is MD5 */
+
+#define IS_HASH_ALGOSELECTION(ALGOSELECTION) (((ALGOSELECTION) == HASH_AlgoSelection_SHA1) || \
+ ((ALGOSELECTION) == HASH_AlgoSelection_MD5))
+/**
+ * @}
+ */
+
+/** @defgroup HASH_processor_Algorithm_Mode
+ * @{
+ */
+#define HASH_AlgoMode_HASH ((uint16_t)0x0000) /*!< Algorithm is HASH */
+#define HASH_AlgoMode_HMAC ((uint16_t)0x0040) /*!< Algorithm is HMAC */
+
+#define IS_HASH_ALGOMODE(ALGOMODE) (((ALGOMODE) == HASH_AlgoMode_HASH) || \
+ ((ALGOMODE) == HASH_AlgoMode_HMAC))
+/**
+ * @}
+ */
+
+/** @defgroup HASH_Data_Type
+ * @{
+ */
+#define HASH_DataType_32b ((uint16_t)0x0000)
+#define HASH_DataType_16b ((uint16_t)0x0010)
+#define HASH_DataType_8b ((uint16_t)0x0020)
+#define HASH_DataType_1b ((uint16_t)0x0030)
+
+#define IS_HASH_DATATYPE(DATATYPE) (((DATATYPE) == HASH_DataType_32b)|| \
+ ((DATATYPE) == HASH_DataType_16b)|| \
+ ((DATATYPE) == HASH_DataType_8b)|| \
+ ((DATATYPE) == HASH_DataType_1b))
+/**
+ * @}
+ */
+
+/** @defgroup HASH_HMAC_Long_key_only_for_HMAC_mode
+ * @{
+ */
+#define HASH_HMACKeyType_ShortKey ((uint32_t)0x00000000) /*!< HMAC Key is <= 64 bytes */
+#define HASH_HMACKeyType_LongKey ((uint32_t)0x00010000) /*!< HMAC Key is > 64 bytes */
+
+#define IS_HASH_HMAC_KEYTYPE(KEYTYPE) (((KEYTYPE) == HASH_HMACKeyType_ShortKey) || \
+ ((KEYTYPE) == HASH_HMACKeyType_LongKey))
+/**
+ * @}
+ */
+
+/** @defgroup Number_of_valid_bits_in_last_word_of_the_message
+ * @{
+ */
+#define IS_HASH_VALIDBITSNUMBER(VALIDBITS) ((VALIDBITS) <= 0x1F)
+
+/**
+ * @}
+ */
+
+/** @defgroup HASH_interrupts_definition
+ * @{
+ */
+#define HASH_IT_DINI ((uint8_t)0x01) /*!< A new block can be entered into the input buffer (DIN)*/
+#define HASH_IT_DCI ((uint8_t)0x02) /*!< Digest calculation complete */
+
+#define IS_HASH_IT(IT) ((((IT) & (uint8_t)0xFC) == 0x00) && ((IT) != 0x00))
+#define IS_HASH_GET_IT(IT) (((IT) == HASH_IT_DINI) || ((IT) == HASH_IT_DCI))
+
+/**
+ * @}
+ */
+
+/** @defgroup HASH_flags_definition
+ * @{
+ */
+#define HASH_FLAG_DINIS ((uint16_t)0x0001) /*!< 16 locations are free in the DIN : A new block can be entered into the input buffer.*/
+#define HASH_FLAG_DCIS ((uint16_t)0x0002) /*!< Digest calculation complete */
+#define HASH_FLAG_DMAS ((uint16_t)0x0004) /*!< DMA interface is enabled (DMAE=1) or a transfer is ongoing */
+#define HASH_FLAG_BUSY ((uint16_t)0x0008) /*!< The hash core is Busy : processing a block of data */
+#define HASH_FLAG_DINNE ((uint16_t)0x1000) /*!< DIN not empty : The input buffer contains at least one word of data */
+
+#define IS_HASH_GET_FLAG(FLAG) (((FLAG) == HASH_FLAG_DINIS) || \
+ ((FLAG) == HASH_FLAG_DCIS) || \
+ ((FLAG) == HASH_FLAG_DMAS) || \
+ ((FLAG) == HASH_FLAG_BUSY) || \
+ ((FLAG) == HASH_FLAG_DINNE))
+
+#define IS_HASH_CLEAR_FLAG(FLAG)(((FLAG) == HASH_FLAG_DINIS) || \
+ ((FLAG) == HASH_FLAG_DCIS))
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions --------------------------------------------------------*/
+
+/* Function used to set the HASH configuration to the default reset state ****/
+void HASH_DeInit(void);
+
+/* HASH Configuration function ************************************************/
+void HASH_Init(HASH_InitTypeDef* HASH_InitStruct);
+void HASH_StructInit(HASH_InitTypeDef* HASH_InitStruct);
+void HASH_Reset(void);
+
+/* HASH Message Digest generation functions ***********************************/
+void HASH_DataIn(uint32_t Data);
+uint8_t HASH_GetInFIFOWordsNbr(void);
+void HASH_SetLastWordValidBitsNbr(uint16_t ValidNumber);
+void HASH_StartDigest(void);
+void HASH_GetDigest(HASH_MsgDigest* HASH_MessageDigest);
+
+/* HASH Context swapping functions ********************************************/
+void HASH_SaveContext(HASH_Context* HASH_ContextSave);
+void HASH_RestoreContext(HASH_Context* HASH_ContextRestore);
+
+/* HASH's DMA interface function **********************************************/
+void HASH_DMACmd(FunctionalState NewState);
+
+/* HASH Interrupts and flags management functions *****************************/
+void HASH_ITConfig(uint8_t HASH_IT, FunctionalState NewState);
+FlagStatus HASH_GetFlagStatus(uint16_t HASH_FLAG);
+void HASH_ClearFlag(uint16_t HASH_FLAG);
+ITStatus HASH_GetITStatus(uint8_t HASH_IT);
+void HASH_ClearITPendingBit(uint8_t HASH_IT);
+
+/* High Level SHA1 functions **************************************************/
+ErrorStatus HASH_SHA1(uint8_t *Input, uint32_t Ilen, uint8_t Output[20]);
+ErrorStatus HMAC_SHA1(uint8_t *Key, uint32_t Keylen,
+ uint8_t *Input, uint32_t Ilen,
+ uint8_t Output[20]);
+
+/* High Level MD5 functions ***************************************************/
+ErrorStatus HASH_MD5(uint8_t *Input, uint32_t Ilen, uint8_t Output[16]);
+ErrorStatus HMAC_MD5(uint8_t *Key, uint32_t Keylen,
+ uint8_t *Input, uint32_t Ilen,
+ uint8_t Output[16]);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*__STM32F2xx_HASH_H */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/inc/stm32f2xx_i2c.h b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/inc/stm32f2xx_i2c.h
new file mode 100644
index 0000000..473d05d
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/inc/stm32f2xx_i2c.h
@@ -0,0 +1,698 @@
+/**
+ ******************************************************************************
+ * @file stm32f2xx_i2c.h
+ * @author MCD Application Team
+ * @version V1.1.2
+ * @date 05-March-2012
+ * @brief This file contains all the functions prototypes for the I2C firmware
+ * 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 __STM32F2xx_I2C_H
+#define __STM32F2xx_I2C_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f2xx.h"
+
+/** @addtogroup STM32F2xx_StdPeriph_Driver
+ * @{
+ */
+
+/** @addtogroup I2C
+ * @{
+ */
+
+/* Exported types ------------------------------------------------------------*/
+
+/**
+ * @brief I2C Init structure definition
+ */
+
+typedef struct
+{
+ uint32_t I2C_ClockSpeed; /*!< Specifies the clock frequency.
+ This parameter must be set to a value lower than 400kHz */
+
+ uint16_t I2C_Mode; /*!< Specifies the I2C mode.
+ This parameter can be a value of @ref I2C_mode */
+
+ uint16_t I2C_DutyCycle; /*!< Specifies the I2C fast mode duty cycle.
+ This parameter can be a value of @ref I2C_duty_cycle_in_fast_mode */
+
+ uint16_t I2C_OwnAddress1; /*!< Specifies the first device own address.
+ This parameter can be a 7-bit or 10-bit address. */
+
+ uint16_t I2C_Ack; /*!< Enables or disables the acknowledgement.
+ This parameter can be a value of @ref I2C_acknowledgement */
+
+ uint16_t I2C_AcknowledgedAddress; /*!< Specifies if 7-bit or 10-bit address is acknowledged.
+ This parameter can be a value of @ref I2C_acknowledged_address */
+}I2C_InitTypeDef;
+
+/* Exported constants --------------------------------------------------------*/
+
+
+/** @defgroup I2C_Exported_Constants
+ * @{
+ */
+
+#define IS_I2C_ALL_PERIPH(PERIPH) (((PERIPH) == I2C1) || \
+ ((PERIPH) == I2C2) || \
+ ((PERIPH) == I2C3))
+/** @defgroup I2C_mode
+ * @{
+ */
+
+#define I2C_Mode_I2C ((uint16_t)0x0000)
+#define I2C_Mode_SMBusDevice ((uint16_t)0x0002)
+#define I2C_Mode_SMBusHost ((uint16_t)0x000A)
+#define IS_I2C_MODE(MODE) (((MODE) == I2C_Mode_I2C) || \
+ ((MODE) == I2C_Mode_SMBusDevice) || \
+ ((MODE) == I2C_Mode_SMBusHost))
+/**
+ * @}
+ */
+
+/** @defgroup I2C_duty_cycle_in_fast_mode
+ * @{
+ */
+
+#define I2C_DutyCycle_16_9 ((uint16_t)0x4000) /*!< I2C fast mode Tlow/Thigh = 16/9 */
+#define I2C_DutyCycle_2 ((uint16_t)0xBFFF) /*!< I2C fast mode Tlow/Thigh = 2 */
+#define IS_I2C_DUTY_CYCLE(CYCLE) (((CYCLE) == I2C_DutyCycle_16_9) || \
+ ((CYCLE) == I2C_DutyCycle_2))
+/**
+ * @}
+ */
+
+/** @defgroup I2C_acknowledgement
+ * @{
+ */
+
+#define I2C_Ack_Enable ((uint16_t)0x0400)
+#define I2C_Ack_Disable ((uint16_t)0x0000)
+#define IS_I2C_ACK_STATE(STATE) (((STATE) == I2C_Ack_Enable) || \
+ ((STATE) == I2C_Ack_Disable))
+/**
+ * @}
+ */
+
+/** @defgroup I2C_transfer_direction
+ * @{
+ */
+
+#define I2C_Direction_Transmitter ((uint8_t)0x00)
+#define I2C_Direction_Receiver ((uint8_t)0x01)
+#define IS_I2C_DIRECTION(DIRECTION) (((DIRECTION) == I2C_Direction_Transmitter) || \
+ ((DIRECTION) == I2C_Direction_Receiver))
+/**
+ * @}
+ */
+
+/** @defgroup I2C_acknowledged_address
+ * @{
+ */
+
+#define I2C_AcknowledgedAddress_7bit ((uint16_t)0x4000)
+#define I2C_AcknowledgedAddress_10bit ((uint16_t)0xC000)
+#define IS_I2C_ACKNOWLEDGE_ADDRESS(ADDRESS) (((ADDRESS) == I2C_AcknowledgedAddress_7bit) || \
+ ((ADDRESS) == I2C_AcknowledgedAddress_10bit))
+/**
+ * @}
+ */
+
+/** @defgroup I2C_registers
+ * @{
+ */
+
+#define I2C_Register_CR1 ((uint8_t)0x00)
+#define I2C_Register_CR2 ((uint8_t)0x04)
+#define I2C_Register_OAR1 ((uint8_t)0x08)
+#define I2C_Register_OAR2 ((uint8_t)0x0C)
+#define I2C_Register_DR ((uint8_t)0x10)
+#define I2C_Register_SR1 ((uint8_t)0x14)
+#define I2C_Register_SR2 ((uint8_t)0x18)
+#define I2C_Register_CCR ((uint8_t)0x1C)
+#define I2C_Register_TRISE ((uint8_t)0x20)
+#define IS_I2C_REGISTER(REGISTER) (((REGISTER) == I2C_Register_CR1) || \
+ ((REGISTER) == I2C_Register_CR2) || \
+ ((REGISTER) == I2C_Register_OAR1) || \
+ ((REGISTER) == I2C_Register_OAR2) || \
+ ((REGISTER) == I2C_Register_DR) || \
+ ((REGISTER) == I2C_Register_SR1) || \
+ ((REGISTER) == I2C_Register_SR2) || \
+ ((REGISTER) == I2C_Register_CCR) || \
+ ((REGISTER) == I2C_Register_TRISE))
+/**
+ * @}
+ */
+
+/** @defgroup I2C_NACK_position
+ * @{
+ */
+
+#define I2C_NACKPosition_Next ((uint16_t)0x0800)
+#define I2C_NACKPosition_Current ((uint16_t)0xF7FF)
+#define IS_I2C_NACK_POSITION(POSITION) (((POSITION) == I2C_NACKPosition_Next) || \
+ ((POSITION) == I2C_NACKPosition_Current))
+/**
+ * @}
+ */
+
+/** @defgroup I2C_SMBus_alert_pin_level
+ * @{
+ */
+
+#define I2C_SMBusAlert_Low ((uint16_t)0x2000)
+#define I2C_SMBusAlert_High ((uint16_t)0xDFFF)
+#define IS_I2C_SMBUS_ALERT(ALERT) (((ALERT) == I2C_SMBusAlert_Low) || \
+ ((ALERT) == I2C_SMBusAlert_High))
+/**
+ * @}
+ */
+
+/** @defgroup I2C_PEC_position
+ * @{
+ */
+
+#define I2C_PECPosition_Next ((uint16_t)0x0800)
+#define I2C_PECPosition_Current ((uint16_t)0xF7FF)
+#define IS_I2C_PEC_POSITION(POSITION) (((POSITION) == I2C_PECPosition_Next) || \
+ ((POSITION) == I2C_PECPosition_Current))
+/**
+ * @}
+ */
+
+/** @defgroup I2C_interrupts_definition
+ * @{
+ */
+
+#define I2C_IT_BUF ((uint16_t)0x0400)
+#define I2C_IT_EVT ((uint16_t)0x0200)
+#define I2C_IT_ERR ((uint16_t)0x0100)
+#define IS_I2C_CONFIG_IT(IT) ((((IT) & (uint16_t)0xF8FF) == 0x00) && ((IT) != 0x00))
+/**
+ * @}
+ */
+
+/** @defgroup I2C_interrupts_definition
+ * @{
+ */
+
+#define I2C_IT_SMBALERT ((uint32_t)0x01008000)
+#define I2C_IT_TIMEOUT ((uint32_t)0x01004000)
+#define I2C_IT_PECERR ((uint32_t)0x01001000)
+#define I2C_IT_OVR ((uint32_t)0x01000800)
+#define I2C_IT_AF ((uint32_t)0x01000400)
+#define I2C_IT_ARLO ((uint32_t)0x01000200)
+#define I2C_IT_BERR ((uint32_t)0x01000100)
+#define I2C_IT_TXE ((uint32_t)0x06000080)
+#define I2C_IT_RXNE ((uint32_t)0x06000040)
+#define I2C_IT_STOPF ((uint32_t)0x02000010)
+#define I2C_IT_ADD10 ((uint32_t)0x02000008)
+#define I2C_IT_BTF ((uint32_t)0x02000004)
+#define I2C_IT_ADDR ((uint32_t)0x02000002)
+#define I2C_IT_SB ((uint32_t)0x02000001)
+
+#define IS_I2C_CLEAR_IT(IT) ((((IT) & (uint16_t)0x20FF) == 0x00) && ((IT) != (uint16_t)0x00))
+
+#define IS_I2C_GET_IT(IT) (((IT) == I2C_IT_SMBALERT) || ((IT) == I2C_IT_TIMEOUT) || \
+ ((IT) == I2C_IT_PECERR) || ((IT) == I2C_IT_OVR) || \
+ ((IT) == I2C_IT_AF) || ((IT) == I2C_IT_ARLO) || \
+ ((IT) == I2C_IT_BERR) || ((IT) == I2C_IT_TXE) || \
+ ((IT) == I2C_IT_RXNE) || ((IT) == I2C_IT_STOPF) || \
+ ((IT) == I2C_IT_ADD10) || ((IT) == I2C_IT_BTF) || \
+ ((IT) == I2C_IT_ADDR) || ((IT) == I2C_IT_SB))
+/**
+ * @}
+ */
+
+/** @defgroup I2C_flags_definition
+ * @{
+ */
+
+/**
+ * @brief SR2 register flags
+ */
+
+#define I2C_FLAG_DUALF ((uint32_t)0x00800000)
+#define I2C_FLAG_SMBHOST ((uint32_t)0x00400000)
+#define I2C_FLAG_SMBDEFAULT ((uint32_t)0x00200000)
+#define I2C_FLAG_GENCALL ((uint32_t)0x00100000)
+#define I2C_FLAG_TRA ((uint32_t)0x00040000)
+#define I2C_FLAG_BUSY ((uint32_t)0x00020000)
+#define I2C_FLAG_MSL ((uint32_t)0x00010000)
+
+/**
+ * @brief SR1 register flags
+ */
+
+#define I2C_FLAG_SMBALERT ((uint32_t)0x10008000)
+#define I2C_FLAG_TIMEOUT ((uint32_t)0x10004000)
+#define I2C_FLAG_PECERR ((uint32_t)0x10001000)
+#define I2C_FLAG_OVR ((uint32_t)0x10000800)
+#define I2C_FLAG_AF ((uint32_t)0x10000400)
+#define I2C_FLAG_ARLO ((uint32_t)0x10000200)
+#define I2C_FLAG_BERR ((uint32_t)0x10000100)
+#define I2C_FLAG_TXE ((uint32_t)0x10000080)
+#define I2C_FLAG_RXNE ((uint32_t)0x10000040)
+#define I2C_FLAG_STOPF ((uint32_t)0x10000010)
+#define I2C_FLAG_ADD10 ((uint32_t)0x10000008)
+#define I2C_FLAG_BTF ((uint32_t)0x10000004)
+#define I2C_FLAG_ADDR ((uint32_t)0x10000002)
+#define I2C_FLAG_SB ((uint32_t)0x10000001)
+
+#define IS_I2C_CLEAR_FLAG(FLAG) ((((FLAG) & (uint16_t)0x20FF) == 0x00) && ((FLAG) != (uint16_t)0x00))
+
+#define IS_I2C_GET_FLAG(FLAG) (((FLAG) == I2C_FLAG_DUALF) || ((FLAG) == I2C_FLAG_SMBHOST) || \
+ ((FLAG) == I2C_FLAG_SMBDEFAULT) || ((FLAG) == I2C_FLAG_GENCALL) || \
+ ((FLAG) == I2C_FLAG_TRA) || ((FLAG) == I2C_FLAG_BUSY) || \
+ ((FLAG) == I2C_FLAG_MSL) || ((FLAG) == I2C_FLAG_SMBALERT) || \
+ ((FLAG) == I2C_FLAG_TIMEOUT) || ((FLAG) == I2C_FLAG_PECERR) || \
+ ((FLAG) == I2C_FLAG_OVR) || ((FLAG) == I2C_FLAG_AF) || \
+ ((FLAG) == I2C_FLAG_ARLO) || ((FLAG) == I2C_FLAG_BERR) || \
+ ((FLAG) == I2C_FLAG_TXE) || ((FLAG) == I2C_FLAG_RXNE) || \
+ ((FLAG) == I2C_FLAG_STOPF) || ((FLAG) == I2C_FLAG_ADD10) || \
+ ((FLAG) == I2C_FLAG_BTF) || ((FLAG) == I2C_FLAG_ADDR) || \
+ ((FLAG) == I2C_FLAG_SB))
+/**
+ * @}
+ */
+
+/** @defgroup I2C_Events
+ * @{
+ */
+
+/**
+ ===============================================================================
+ I2C Master Events (Events grouped in order of communication)
+ ===============================================================================
+ */
+
+/**
+ * @brief Communication start
+ *
+ * After sending the START condition (I2C_GenerateSTART() function) the master
+ * has to wait for this event. It means that the Start condition has been correctly
+ * released on the I2C bus (the bus is free, no other devices is communicating).
+ *
+ */
+/* --EV5 */
+#define I2C_EVENT_MASTER_MODE_SELECT ((uint32_t)0x00030001) /* BUSY, MSL and SB flag */
+
+/**
+ * @brief Address Acknowledge
+ *
+ * After checking on EV5 (start condition correctly released on the bus), the
+ * master sends the address of the slave(s) with which it will communicate
+ * (I2C_Send7bitAddress() function, it also determines the direction of the communication:
+ * Master transmitter or Receiver). Then the master has to wait that a slave acknowledges
+ * his address. If an acknowledge is sent on the bus, one of the following events will
+ * be set:
+ *
+ * 1) In case of Master Receiver (7-bit addressing): the I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED
+ * event is set.
+ *
+ * 2) In case of Master Transmitter (7-bit addressing): the I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED
+ * is set
+ *
+ * 3) In case of 10-Bit addressing mode, the master (just after generating the START
+ * and checking on EV5) has to send the header of 10-bit addressing mode (I2C_SendData()
+ * function). Then master should wait on EV9. It means that the 10-bit addressing
+ * header has been correctly sent on the bus. Then master should send the second part of
+ * the 10-bit address (LSB) using the function I2C_Send7bitAddress(). Then master
+ * should wait for event EV6.
+ *
+ */
+
+/* --EV6 */
+#define I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED ((uint32_t)0x00070082) /* BUSY, MSL, ADDR, TXE and TRA flags */
+#define I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED ((uint32_t)0x00030002) /* BUSY, MSL and ADDR flags */
+/* --EV9 */
+#define I2C_EVENT_MASTER_MODE_ADDRESS10 ((uint32_t)0x00030008) /* BUSY, MSL and ADD10 flags */
+
+/**
+ * @brief Communication events
+ *
+ * If a communication is established (START condition generated and slave address
+ * acknowledged) then the master has to check on one of the following events for
+ * communication procedures:
+ *
+ * 1) Master Receiver mode: The master has to wait on the event EV7 then to read
+ * the data received from the slave (I2C_ReceiveData() function).
+ *
+ * 2) Master Transmitter mode: The master has to send data (I2C_SendData()
+ * function) then to wait on event EV8 or EV8_2.
+ * These two events are similar:
+ * - EV8 means that the data has been written in the data register and is
+ * being shifted out.
+ * - EV8_2 means that the data has been physically shifted out and output
+ * on the bus.
+ * In most cases, using EV8 is sufficient for the application.
+ * Using EV8_2 leads to a slower communication but ensure more reliable test.
+ * EV8_2 is also more suitable than EV8 for testing on the last data transmission
+ * (before Stop condition generation).
+ *
+ * @note In case the user software does not guarantee that this event EV7 is
+ * managed before the current byte end of transfer, then user may check on EV7
+ * and BTF flag at the same time (ie. (I2C_EVENT_MASTER_BYTE_RECEIVED | I2C_FLAG_BTF)).
+ * In this case the communication may be slower.
+ *
+ */
+
+/* Master RECEIVER mode -----------------------------*/
+/* --EV7 */
+#define I2C_EVENT_MASTER_BYTE_RECEIVED ((uint32_t)0x00030040) /* BUSY, MSL and RXNE flags */
+
+/* Master TRANSMITTER mode --------------------------*/
+/* --EV8 */
+#define I2C_EVENT_MASTER_BYTE_TRANSMITTING ((uint32_t)0x00070080) /* TRA, BUSY, MSL, TXE flags */
+/* --EV8_2 */
+#define I2C_EVENT_MASTER_BYTE_TRANSMITTED ((uint32_t)0x00070084) /* TRA, BUSY, MSL, TXE and BTF flags */
+
+
+/**
+ ===============================================================================
+ I2C Slave Events (Events grouped in order of communication)
+ ===============================================================================
+ */
+
+
+/**
+ * @brief Communication start events
+ *
+ * Wait on one of these events at the start of the communication. It means that
+ * the I2C peripheral detected a Start condition on the bus (generated by master
+ * device) followed by the peripheral address. The peripheral generates an ACK
+ * condition on the bus (if the acknowledge feature is enabled through function
+ * I2C_AcknowledgeConfig()) and the events listed above are set :
+ *
+ * 1) In normal case (only one address managed by the slave), when the address
+ * sent by the master matches the own address of the peripheral (configured by
+ * I2C_OwnAddress1 field) the I2C_EVENT_SLAVE_XXX_ADDRESS_MATCHED event is set
+ * (where XXX could be TRANSMITTER or RECEIVER).
+ *
+ * 2) In case the address sent by the master matches the second address of the
+ * peripheral (configured by the function I2C_OwnAddress2Config() and enabled
+ * by the function I2C_DualAddressCmd()) the events I2C_EVENT_SLAVE_XXX_SECONDADDRESS_MATCHED
+ * (where XXX could be TRANSMITTER or RECEIVER) are set.
+ *
+ * 3) In case the address sent by the master is General Call (address 0x00) and
+ * if the General Call is enabled for the peripheral (using function I2C_GeneralCallCmd())
+ * the following event is set I2C_EVENT_SLAVE_GENERALCALLADDRESS_MATCHED.
+ *
+ */
+
+/* --EV1 (all the events below are variants of EV1) */
+/* 1) Case of One Single Address managed by the slave */
+#define I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED ((uint32_t)0x00020002) /* BUSY and ADDR flags */
+#define I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED ((uint32_t)0x00060082) /* TRA, BUSY, TXE and ADDR flags */
+
+/* 2) Case of Dual address managed by the slave */
+#define I2C_EVENT_SLAVE_RECEIVER_SECONDADDRESS_MATCHED ((uint32_t)0x00820000) /* DUALF and BUSY flags */
+#define I2C_EVENT_SLAVE_TRANSMITTER_SECONDADDRESS_MATCHED ((uint32_t)0x00860080) /* DUALF, TRA, BUSY and TXE flags */
+
+/* 3) Case of General Call enabled for the slave */
+#define I2C_EVENT_SLAVE_GENERALCALLADDRESS_MATCHED ((uint32_t)0x00120000) /* GENCALL and BUSY flags */
+
+/**
+ * @brief Communication events
+ *
+ * Wait on one of these events when EV1 has already been checked and:
+ *
+ * - Slave RECEIVER mode:
+ * - EV2: When the application is expecting a data byte to be received.
+ * - EV4: When the application is expecting the end of the communication: master
+ * sends a stop condition and data transmission is stopped.
+ *
+ * - Slave Transmitter mode:
+ * - EV3: When a byte has been transmitted by the slave and the application is expecting
+ * the end of the byte transmission. The two events I2C_EVENT_SLAVE_BYTE_TRANSMITTED and
+ * I2C_EVENT_SLAVE_BYTE_TRANSMITTING are similar. The second one can optionally be
+ * used when the user software doesn't guarantee the EV3 is managed before the
+ * current byte end of transfer.
+ * - EV3_2: When the master sends a NACK in order to tell slave that data transmission
+ * shall end (before sending the STOP condition). In this case slave has to stop sending
+ * data bytes and expect a Stop condition on the bus.
+ *
+ * @note In case the user software does not guarantee that the event EV2 is
+ * managed before the current byte end of transfer, then user may check on EV2
+ * and BTF flag at the same time (ie. (I2C_EVENT_SLAVE_BYTE_RECEIVED | I2C_FLAG_BTF)).
+ * In this case the communication may be slower.
+ *
+ */
+
+/* Slave RECEIVER mode --------------------------*/
+/* --EV2 */
+#define I2C_EVENT_SLAVE_BYTE_RECEIVED ((uint32_t)0x00020040) /* BUSY and RXNE flags */
+/* --EV4 */
+#define I2C_EVENT_SLAVE_STOP_DETECTED ((uint32_t)0x00000010) /* STOPF flag */
+
+/* Slave TRANSMITTER mode -----------------------*/
+/* --EV3 */
+#define I2C_EVENT_SLAVE_BYTE_TRANSMITTED ((uint32_t)0x00060084) /* TRA, BUSY, TXE and BTF flags */
+#define I2C_EVENT_SLAVE_BYTE_TRANSMITTING ((uint32_t)0x00060080) /* TRA, BUSY and TXE flags */
+/* --EV3_2 */
+#define I2C_EVENT_SLAVE_ACK_FAILURE ((uint32_t)0x00000400) /* AF flag */
+
+/*
+ ===============================================================================
+ End of Events Description
+ ===============================================================================
+ */
+
+#define IS_I2C_EVENT(EVENT) (((EVENT) == I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED) || \
+ ((EVENT) == I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED) || \
+ ((EVENT) == I2C_EVENT_SLAVE_TRANSMITTER_SECONDADDRESS_MATCHED) || \
+ ((EVENT) == I2C_EVENT_SLAVE_RECEIVER_SECONDADDRESS_MATCHED) || \
+ ((EVENT) == I2C_EVENT_SLAVE_GENERALCALLADDRESS_MATCHED) || \
+ ((EVENT) == I2C_EVENT_SLAVE_BYTE_RECEIVED) || \
+ ((EVENT) == (I2C_EVENT_SLAVE_BYTE_RECEIVED | I2C_FLAG_DUALF)) || \
+ ((EVENT) == (I2C_EVENT_SLAVE_BYTE_RECEIVED | I2C_FLAG_GENCALL)) || \
+ ((EVENT) == I2C_EVENT_SLAVE_BYTE_TRANSMITTED) || \
+ ((EVENT) == (I2C_EVENT_SLAVE_BYTE_TRANSMITTED | I2C_FLAG_DUALF)) || \
+ ((EVENT) == (I2C_EVENT_SLAVE_BYTE_TRANSMITTED | I2C_FLAG_GENCALL)) || \
+ ((EVENT) == I2C_EVENT_SLAVE_STOP_DETECTED) || \
+ ((EVENT) == I2C_EVENT_MASTER_MODE_SELECT) || \
+ ((EVENT) == I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED) || \
+ ((EVENT) == I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED) || \
+ ((EVENT) == I2C_EVENT_MASTER_BYTE_RECEIVED) || \
+ ((EVENT) == I2C_EVENT_MASTER_BYTE_TRANSMITTED) || \
+ ((EVENT) == I2C_EVENT_MASTER_BYTE_TRANSMITTING) || \
+ ((EVENT) == I2C_EVENT_MASTER_MODE_ADDRESS10) || \
+ ((EVENT) == I2C_EVENT_SLAVE_ACK_FAILURE))
+/**
+ * @}
+ */
+
+/** @defgroup I2C_own_address1
+ * @{
+ */
+
+#define IS_I2C_OWN_ADDRESS1(ADDRESS1) ((ADDRESS1) <= 0x3FF)
+/**
+ * @}
+ */
+
+/** @defgroup I2C_clock_speed
+ * @{
+ */
+
+#define IS_I2C_CLOCK_SPEED(SPEED) (((SPEED) >= 0x1) && ((SPEED) <= 400000))
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions --------------------------------------------------------*/
+
+/* Function used to set the I2C configuration to the default reset state *****/
+void I2C_DeInit(I2C_TypeDef* I2Cx);
+
+/* Initialization and Configuration functions *********************************/
+void I2C_Init(I2C_TypeDef* I2Cx, I2C_InitTypeDef* I2C_InitStruct);
+void I2C_StructInit(I2C_InitTypeDef* I2C_InitStruct);
+void I2C_Cmd(I2C_TypeDef* I2Cx, FunctionalState NewState);
+void I2C_GenerateSTART(I2C_TypeDef* I2Cx, FunctionalState NewState);
+void I2C_GenerateSTOP(I2C_TypeDef* I2Cx, FunctionalState NewState);
+void I2C_Send7bitAddress(I2C_TypeDef* I2Cx, uint8_t Address, uint8_t I2C_Direction);
+void I2C_AcknowledgeConfig(I2C_TypeDef* I2Cx, FunctionalState NewState);
+void I2C_OwnAddress2Config(I2C_TypeDef* I2Cx, uint8_t Address);
+void I2C_DualAddressCmd(I2C_TypeDef* I2Cx, FunctionalState NewState);
+void I2C_GeneralCallCmd(I2C_TypeDef* I2Cx, FunctionalState NewState);
+void I2C_SoftwareResetCmd(I2C_TypeDef* I2Cx, FunctionalState NewState);
+void I2C_StretchClockCmd(I2C_TypeDef* I2Cx, FunctionalState NewState);
+void I2C_FastModeDutyCycleConfig(I2C_TypeDef* I2Cx, uint16_t I2C_DutyCycle);
+void I2C_NACKPositionConfig(I2C_TypeDef* I2Cx, uint16_t I2C_NACKPosition);
+void I2C_SMBusAlertConfig(I2C_TypeDef* I2Cx, uint16_t I2C_SMBusAlert);
+void I2C_ARPCmd(I2C_TypeDef* I2Cx, FunctionalState NewState);
+
+/* Data transfers functions ***************************************************/
+void I2C_SendData(I2C_TypeDef* I2Cx, uint8_t Data);
+uint8_t I2C_ReceiveData(I2C_TypeDef* I2Cx);
+
+/* PEC management functions ***************************************************/
+void I2C_TransmitPEC(I2C_TypeDef* I2Cx, FunctionalState NewState);
+void I2C_PECPositionConfig(I2C_TypeDef* I2Cx, uint16_t I2C_PECPosition);
+void I2C_CalculatePEC(I2C_TypeDef* I2Cx, FunctionalState NewState);
+uint8_t I2C_GetPEC(I2C_TypeDef* I2Cx);
+
+/* DMA transfers management functions *****************************************/
+void I2C_DMACmd(I2C_TypeDef* I2Cx, FunctionalState NewState);
+void I2C_DMALastTransferCmd(I2C_TypeDef* I2Cx, FunctionalState NewState);
+
+/* Interrupts, events and flags management functions **************************/
+uint16_t I2C_ReadRegister(I2C_TypeDef* I2Cx, uint8_t I2C_Register);
+void I2C_ITConfig(I2C_TypeDef* I2Cx, uint16_t I2C_IT, FunctionalState NewState);
+
+/*
+ ===============================================================================
+ I2C State Monitoring Functions
+ ===============================================================================
+ This I2C driver provides three different ways for I2C state monitoring
+ depending on the application requirements and constraints:
+
+
+ 1. Basic state monitoring (Using I2C_CheckEvent() function)
+ -----------------------------------------------------------
+ It compares the status registers (SR1 and SR2) content to a given event
+ (can be the combination of one or more flags).
+ It returns SUCCESS if the current status includes the given flags
+ and returns ERROR if one or more flags are missing in the current status.
+
+ - When to use
+ - This function is suitable for most applications as well as for startup
+ activity since the events are fully described in the product reference
+ manual (RM0033).
+ - It is also suitable for users who need to define their own events.
+
+ - Limitations
+ - If an error occurs (ie. error flags are set besides to the monitored
+ flags), the I2C_CheckEvent() function may return SUCCESS despite
+ the communication hold or corrupted real state.
+ In this case, it is advised to use error interrupts to monitor
+ the error events and handle them in the interrupt IRQ handler.
+
+ Note
+ For error management, it is advised to use the following functions:
+ - I2C_ITConfig() to configure and enable the error interrupts (I2C_IT_ERR).
+ - I2Cx_ER_IRQHandler() which is called when the error interrupt occurs.
+ Where x is the peripheral instance (I2C1, I2C2 ...)
+ - I2C_GetFlagStatus() or I2C_GetITStatus() to be called into the
+ I2Cx_ER_IRQHandler() function in order to determine which error occurred.
+ - I2C_ClearFlag() or I2C_ClearITPendingBit() and/or I2C_SoftwareResetCmd()
+ and/or I2C_GenerateStop() in order to clear the error flag and source
+ and return to correct communication status.
+
+
+ 2. Advanced state monitoring (Using the function I2C_GetLastEvent())
+ --------------------------------------------------------------------
+ Using the function I2C_GetLastEvent() which returns the image of both status
+ registers in a single word (uint32_t) (Status Register 2 value is shifted left
+ by 16 bits and concatenated to Status Register 1).
+
+ - When to use
+ - This function is suitable for the same applications above but it
+ allows to overcome the mentioned limitation of I2C_GetFlagStatus()
+ function.
+ - The returned value could be compared to events already defined in
+ this file or to custom values defined by user.
+ This function is suitable when multiple flags are monitored at the
+ same time.
+ - At the opposite of I2C_CheckEvent() function, this function allows
+ user to choose when an event is accepted (when all events flags are
+ set and no other flags are set or just when the needed flags are set
+ like I2C_CheckEvent() function.
+
+ - Limitations
+ - User may need to define his own events.
+ - Same remark concerning the error management is applicable for this
+ function if user decides to check only regular communication flags
+ (and ignores error flags).
+
+
+ 3. Flag-based state monitoring (Using the function I2C_GetFlagStatus())
+ -----------------------------------------------------------------------
+
+ Using the function I2C_GetFlagStatus() which simply returns the status of
+ one single flag (ie. I2C_FLAG_RXNE ...).
+
+ - When to use
+ - This function could be used for specific applications or in debug
+ phase.
+ - It is suitable when only one flag checking is needed (most I2C
+ events are monitored through multiple flags).
+ - Limitations:
+ - When calling this function, the Status register is accessed.
+ Some flags are cleared when the status register is accessed.
+ So checking the status of one Flag, may clear other ones.
+ - Function may need to be called twice or more in order to monitor
+ one single event.
+ */
+
+/*
+ ===============================================================================
+ 1. Basic state monitoring
+ ===============================================================================
+ */
+ErrorStatus I2C_CheckEvent(I2C_TypeDef* I2Cx, uint32_t I2C_EVENT);
+/*
+ ===============================================================================
+ 2. Advanced state monitoring
+ ===============================================================================
+ */
+uint32_t I2C_GetLastEvent(I2C_TypeDef* I2Cx);
+/*
+ ===============================================================================
+ 3. Flag-based state monitoring
+ ===============================================================================
+ */
+FlagStatus I2C_GetFlagStatus(I2C_TypeDef* I2Cx, uint32_t I2C_FLAG);
+
+
+void I2C_ClearFlag(I2C_TypeDef* I2Cx, uint32_t I2C_FLAG);
+ITStatus I2C_GetITStatus(I2C_TypeDef* I2Cx, uint32_t I2C_IT);
+void I2C_ClearITPendingBit(I2C_TypeDef* I2Cx, uint32_t I2C_IT);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*__STM32F2xx_I2C_H */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/inc/stm32f2xx_iwdg.h b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/inc/stm32f2xx_iwdg.h
new file mode 100644
index 0000000..731ca2f
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/inc/stm32f2xx_iwdg.h
@@ -0,0 +1,131 @@
+/**
+ ******************************************************************************
+ * @file stm32f2xx_iwdg.h
+ * @author MCD Application Team
+ * @version V1.1.2
+ * @date 05-March-2012
+ * @brief This file contains all the functions prototypes for the IWDG
+ * firmware 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 __STM32F2xx_IWDG_H
+#define __STM32F2xx_IWDG_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f2xx.h"
+
+/** @addtogroup STM32F2xx_StdPeriph_Driver
+ * @{
+ */
+
+/** @addtogroup IWDG
+ * @{
+ */
+
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+
+/** @defgroup IWDG_Exported_Constants
+ * @{
+ */
+
+/** @defgroup IWDG_WriteAccess
+ * @{
+ */
+#define IWDG_WriteAccess_Enable ((uint16_t)0x5555)
+#define IWDG_WriteAccess_Disable ((uint16_t)0x0000)
+#define IS_IWDG_WRITE_ACCESS(ACCESS) (((ACCESS) == IWDG_WriteAccess_Enable) || \
+ ((ACCESS) == IWDG_WriteAccess_Disable))
+/**
+ * @}
+ */
+
+/** @defgroup IWDG_prescaler
+ * @{
+ */
+#define IWDG_Prescaler_4 ((uint8_t)0x00)
+#define IWDG_Prescaler_8 ((uint8_t)0x01)
+#define IWDG_Prescaler_16 ((uint8_t)0x02)
+#define IWDG_Prescaler_32 ((uint8_t)0x03)
+#define IWDG_Prescaler_64 ((uint8_t)0x04)
+#define IWDG_Prescaler_128 ((uint8_t)0x05)
+#define IWDG_Prescaler_256 ((uint8_t)0x06)
+#define IS_IWDG_PRESCALER(PRESCALER) (((PRESCALER) == IWDG_Prescaler_4) || \
+ ((PRESCALER) == IWDG_Prescaler_8) || \
+ ((PRESCALER) == IWDG_Prescaler_16) || \
+ ((PRESCALER) == IWDG_Prescaler_32) || \
+ ((PRESCALER) == IWDG_Prescaler_64) || \
+ ((PRESCALER) == IWDG_Prescaler_128)|| \
+ ((PRESCALER) == IWDG_Prescaler_256))
+/**
+ * @}
+ */
+
+/** @defgroup IWDG_Flag
+ * @{
+ */
+#define IWDG_FLAG_PVU ((uint16_t)0x0001)
+#define IWDG_FLAG_RVU ((uint16_t)0x0002)
+#define IS_IWDG_FLAG(FLAG) (((FLAG) == IWDG_FLAG_PVU) || ((FLAG) == IWDG_FLAG_RVU))
+#define IS_IWDG_RELOAD(RELOAD) ((RELOAD) <= 0xFFF)
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions --------------------------------------------------------*/
+
+/* Prescaler and Counter configuration functions ******************************/
+void IWDG_WriteAccessCmd(uint16_t IWDG_WriteAccess);
+void IWDG_SetPrescaler(uint8_t IWDG_Prescaler);
+void IWDG_SetReload(uint16_t Reload);
+void IWDG_ReloadCounter(void);
+
+/* IWDG activation function ***************************************************/
+void IWDG_Enable(void);
+
+/* Flag management function ***************************************************/
+FlagStatus IWDG_GetFlagStatus(uint16_t IWDG_FLAG);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F2xx_IWDG_H */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/inc/stm32f2xx_pwr.h b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/inc/stm32f2xx_pwr.h
new file mode 100644
index 0000000..4a02234
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/inc/stm32f2xx_pwr.h
@@ -0,0 +1,166 @@
+/**
+ ******************************************************************************
+ * @file stm32f2xx_pwr.h
+ * @author MCD Application Team
+ * @version V1.1.2
+ * @date 05-March-2012
+ * @brief This file contains all the functions prototypes for the PWR firmware
+ * 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 __STM32F2xx_PWR_H
+#define __STM32F2xx_PWR_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f2xx.h"
+
+/** @addtogroup STM32F2xx_StdPeriph_Driver
+ * @{
+ */
+
+/** @addtogroup PWR
+ * @{
+ */
+
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+
+/** @defgroup PWR_Exported_Constants
+ * @{
+ */
+
+/** @defgroup PWR_PVD_detection_level
+ * @{
+ */
+
+#define PWR_PVDLevel_0 PWR_CR_PLS_LEV0
+#define PWR_PVDLevel_1 PWR_CR_PLS_LEV1
+#define PWR_PVDLevel_2 PWR_CR_PLS_LEV2
+#define PWR_PVDLevel_3 PWR_CR_PLS_LEV3
+#define PWR_PVDLevel_4 PWR_CR_PLS_LEV4
+#define PWR_PVDLevel_5 PWR_CR_PLS_LEV5
+#define PWR_PVDLevel_6 PWR_CR_PLS_LEV6
+#define PWR_PVDLevel_7 PWR_CR_PLS_LEV7
+
+#define IS_PWR_PVD_LEVEL(LEVEL) (((LEVEL) == PWR_PVDLevel_0) || ((LEVEL) == PWR_PVDLevel_1)|| \
+ ((LEVEL) == PWR_PVDLevel_2) || ((LEVEL) == PWR_PVDLevel_3)|| \
+ ((LEVEL) == PWR_PVDLevel_4) || ((LEVEL) == PWR_PVDLevel_5)|| \
+ ((LEVEL) == PWR_PVDLevel_6) || ((LEVEL) == PWR_PVDLevel_7))
+/**
+ * @}
+ */
+
+
+/** @defgroup PWR_Regulator_state_in_STOP_mode
+ * @{
+ */
+
+#define PWR_Regulator_ON ((uint32_t)0x00000000)
+#define PWR_Regulator_LowPower PWR_CR_LPDS
+#define IS_PWR_REGULATOR(REGULATOR) (((REGULATOR) == PWR_Regulator_ON) || \
+ ((REGULATOR) == PWR_Regulator_LowPower))
+/**
+ * @}
+ */
+
+/** @defgroup PWR_STOP_mode_entry
+ * @{
+ */
+
+#define PWR_STOPEntry_WFI ((uint8_t)0x01)
+#define PWR_STOPEntry_WFE ((uint8_t)0x02)
+#define IS_PWR_STOP_ENTRY(ENTRY) (((ENTRY) == PWR_STOPEntry_WFI) || ((ENTRY) == PWR_STOPEntry_WFE))
+
+/**
+ * @}
+ */
+
+/** @defgroup PWR_Flag
+ * @{
+ */
+
+#define PWR_FLAG_WU PWR_CSR_WUF
+#define PWR_FLAG_SB PWR_CSR_SBF
+#define PWR_FLAG_PVDO PWR_CSR_PVDO
+#define PWR_FLAG_BRR PWR_CSR_BRR
+
+#define IS_PWR_GET_FLAG(FLAG) (((FLAG) == PWR_FLAG_WU) || ((FLAG) == PWR_FLAG_SB) || \
+ ((FLAG) == PWR_FLAG_PVDO) || ((FLAG) == PWR_FLAG_BRR))
+
+#define IS_PWR_CLEAR_FLAG(FLAG) (((FLAG) == PWR_FLAG_WU) || ((FLAG) == PWR_FLAG_SB))
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions --------------------------------------------------------*/
+
+/* Function used to set the PWR configuration to the default reset state ******/
+void PWR_DeInit(void);
+
+/* Backup Domain Access function **********************************************/
+void PWR_BackupAccessCmd(FunctionalState NewState);
+
+/* PVD configuration functions ************************************************/
+void PWR_PVDLevelConfig(uint32_t PWR_PVDLevel);
+void PWR_PVDCmd(FunctionalState NewState);
+
+/* WakeUp pins configuration functions ****************************************/
+void PWR_WakeUpPinCmd(FunctionalState NewState);
+
+/* Backup Regulator configuration functions ***********************************/
+void PWR_BackupRegulatorCmd(FunctionalState NewState);
+
+/* FLASH Power Down configuration functions ***********************************/
+void PWR_FlashPowerDownCmd(FunctionalState NewState);
+
+/* Low Power modes configuration functions ************************************/
+void PWR_EnterSTOPMode(uint32_t PWR_Regulator, uint8_t PWR_STOPEntry);
+void PWR_EnterSTANDBYMode(void);
+
+/* Flags management functions *************************************************/
+FlagStatus PWR_GetFlagStatus(uint32_t PWR_FLAG);
+void PWR_ClearFlag(uint32_t PWR_FLAG);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F2xx_PWR_H */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/inc/stm32f2xx_rcc.h b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/inc/stm32f2xx_rcc.h
new file mode 100644
index 0000000..b87733e
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/inc/stm32f2xx_rcc.h
@@ -0,0 +1,515 @@
+/**
+ ******************************************************************************
+ * @file stm32f2xx_rcc.h
+ * @author MCD Application Team
+ * @version V1.1.2
+ * @date 05-March-2012
+ * @brief This file contains all the functions prototypes for the RCC firmware 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 __STM32F2xx_RCC_H
+#define __STM32F2xx_RCC_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f2xx.h"
+
+/** @addtogroup STM32F2xx_StdPeriph_Driver
+ * @{
+ */
+
+/** @addtogroup RCC
+ * @{
+ */
+
+/* Exported types ------------------------------------------------------------*/
+typedef struct
+{
+ uint32_t SYSCLK_Frequency; /*!< SYSCLK clock frequency expressed in Hz */
+ uint32_t HCLK_Frequency; /*!< HCLK clock frequency expressed in Hz */
+ uint32_t PCLK1_Frequency; /*!< PCLK1 clock frequency expressed in Hz */
+ uint32_t PCLK2_Frequency; /*!< PCLK2 clock frequency expressed in Hz */
+}RCC_ClocksTypeDef;
+
+/* Exported constants --------------------------------------------------------*/
+
+/** @defgroup RCC_Exported_Constants
+ * @{
+ */
+
+/** @defgroup RCC_HSE_configuration
+ * @{
+ */
+#define RCC_HSE_OFF ((uint8_t)0x00)
+#define RCC_HSE_ON ((uint8_t)0x01)
+#define RCC_HSE_Bypass ((uint8_t)0x05)
+#define IS_RCC_HSE(HSE) (((HSE) == RCC_HSE_OFF) || ((HSE) == RCC_HSE_ON) || \
+ ((HSE) == RCC_HSE_Bypass))
+/**
+ * @}
+ */
+
+/** @defgroup RCC_PLL_Clock_Source
+ * @{
+ */
+#define RCC_PLLSource_HSI ((uint32_t)0x00000000)
+#define RCC_PLLSource_HSE ((uint32_t)0x00400000)
+#define IS_RCC_PLL_SOURCE(SOURCE) (((SOURCE) == RCC_PLLSource_HSI) || \
+ ((SOURCE) == RCC_PLLSource_HSE))
+#define IS_RCC_PLLM_VALUE(VALUE) ((VALUE) <= 63)
+#define IS_RCC_PLLN_VALUE(VALUE) ((192 <= (VALUE)) && ((VALUE) <= 432))
+#define IS_RCC_PLLP_VALUE(VALUE) (((VALUE) == 2) || ((VALUE) == 4) || ((VALUE) == 6) || ((VALUE) == 8))
+#define IS_RCC_PLLQ_VALUE(VALUE) ((4 <= (VALUE)) && ((VALUE) <= 15))
+
+#define IS_RCC_PLLI2SN_VALUE(VALUE) ((192 <= (VALUE)) && ((VALUE) <= 432))
+#define IS_RCC_PLLI2SR_VALUE(VALUE) ((2 <= (VALUE)) && ((VALUE) <= 7))
+/**
+ * @}
+ */
+
+/** @defgroup RCC_System_Clock_Source
+ * @{
+ */
+#define RCC_SYSCLKSource_HSI ((uint32_t)0x00000000)
+#define RCC_SYSCLKSource_HSE ((uint32_t)0x00000001)
+#define RCC_SYSCLKSource_PLLCLK ((uint32_t)0x00000002)
+#define IS_RCC_SYSCLK_SOURCE(SOURCE) (((SOURCE) == RCC_SYSCLKSource_HSI) || \
+ ((SOURCE) == RCC_SYSCLKSource_HSE) || \
+ ((SOURCE) == RCC_SYSCLKSource_PLLCLK))
+/**
+ * @}
+ */
+
+/** @defgroup RCC_AHB_Clock_Source
+ * @{
+ */
+#define RCC_SYSCLK_Div1 ((uint32_t)0x00000000)
+#define RCC_SYSCLK_Div2 ((uint32_t)0x00000080)
+#define RCC_SYSCLK_Div4 ((uint32_t)0x00000090)
+#define RCC_SYSCLK_Div8 ((uint32_t)0x000000A0)
+#define RCC_SYSCLK_Div16 ((uint32_t)0x000000B0)
+#define RCC_SYSCLK_Div64 ((uint32_t)0x000000C0)
+#define RCC_SYSCLK_Div128 ((uint32_t)0x000000D0)
+#define RCC_SYSCLK_Div256 ((uint32_t)0x000000E0)
+#define RCC_SYSCLK_Div512 ((uint32_t)0x000000F0)
+#define IS_RCC_HCLK(HCLK) (((HCLK) == RCC_SYSCLK_Div1) || ((HCLK) == RCC_SYSCLK_Div2) || \
+ ((HCLK) == RCC_SYSCLK_Div4) || ((HCLK) == RCC_SYSCLK_Div8) || \
+ ((HCLK) == RCC_SYSCLK_Div16) || ((HCLK) == RCC_SYSCLK_Div64) || \
+ ((HCLK) == RCC_SYSCLK_Div128) || ((HCLK) == RCC_SYSCLK_Div256) || \
+ ((HCLK) == RCC_SYSCLK_Div512))
+/**
+ * @}
+ */
+
+/** @defgroup RCC_APB1_APB2_Clock_Source
+ * @{
+ */
+#define RCC_HCLK_Div1 ((uint32_t)0x00000000)
+#define RCC_HCLK_Div2 ((uint32_t)0x00001000)
+#define RCC_HCLK_Div4 ((uint32_t)0x00001400)
+#define RCC_HCLK_Div8 ((uint32_t)0x00001800)
+#define RCC_HCLK_Div16 ((uint32_t)0x00001C00)
+#define IS_RCC_PCLK(PCLK) (((PCLK) == RCC_HCLK_Div1) || ((PCLK) == RCC_HCLK_Div2) || \
+ ((PCLK) == RCC_HCLK_Div4) || ((PCLK) == RCC_HCLK_Div8) || \
+ ((PCLK) == RCC_HCLK_Div16))
+/**
+ * @}
+ */
+
+/** @defgroup RCC_Interrupt_Source
+ * @{
+ */
+#define RCC_IT_LSIRDY ((uint8_t)0x01)
+#define RCC_IT_LSERDY ((uint8_t)0x02)
+#define RCC_IT_HSIRDY ((uint8_t)0x04)
+#define RCC_IT_HSERDY ((uint8_t)0x08)
+#define RCC_IT_PLLRDY ((uint8_t)0x10)
+#define RCC_IT_PLLI2SRDY ((uint8_t)0x20)
+#define RCC_IT_CSS ((uint8_t)0x80)
+#define IS_RCC_IT(IT) ((((IT) & (uint8_t)0xC0) == 0x00) && ((IT) != 0x00))
+#define IS_RCC_GET_IT(IT) (((IT) == RCC_IT_LSIRDY) || ((IT) == RCC_IT_LSERDY) || \
+ ((IT) == RCC_IT_HSIRDY) || ((IT) == RCC_IT_HSERDY) || \
+ ((IT) == RCC_IT_PLLRDY) || ((IT) == RCC_IT_CSS) || \
+ ((IT) == RCC_IT_PLLI2SRDY))
+#define IS_RCC_CLEAR_IT(IT) ((((IT) & (uint8_t)0x40) == 0x00) && ((IT) != 0x00))
+/**
+ * @}
+ */
+
+/** @defgroup RCC_LSE_Configuration
+ * @{
+ */
+#define RCC_LSE_OFF ((uint8_t)0x00)
+#define RCC_LSE_ON ((uint8_t)0x01)
+#define RCC_LSE_Bypass ((uint8_t)0x04)
+#define IS_RCC_LSE(LSE) (((LSE) == RCC_LSE_OFF) || ((LSE) == RCC_LSE_ON) || \
+ ((LSE) == RCC_LSE_Bypass))
+/**
+ * @}
+ */
+
+/** @defgroup RCC_RTC_Clock_Source
+ * @{
+ */
+#define RCC_RTCCLKSource_LSE ((uint32_t)0x00000100)
+#define RCC_RTCCLKSource_LSI ((uint32_t)0x00000200)
+#define RCC_RTCCLKSource_HSE_Div2 ((uint32_t)0x00020300)
+#define RCC_RTCCLKSource_HSE_Div3 ((uint32_t)0x00030300)
+#define RCC_RTCCLKSource_HSE_Div4 ((uint32_t)0x00040300)
+#define RCC_RTCCLKSource_HSE_Div5 ((uint32_t)0x00050300)
+#define RCC_RTCCLKSource_HSE_Div6 ((uint32_t)0x00060300)
+#define RCC_RTCCLKSource_HSE_Div7 ((uint32_t)0x00070300)
+#define RCC_RTCCLKSource_HSE_Div8 ((uint32_t)0x00080300)
+#define RCC_RTCCLKSource_HSE_Div9 ((uint32_t)0x00090300)
+#define RCC_RTCCLKSource_HSE_Div10 ((uint32_t)0x000A0300)
+#define RCC_RTCCLKSource_HSE_Div11 ((uint32_t)0x000B0300)
+#define RCC_RTCCLKSource_HSE_Div12 ((uint32_t)0x000C0300)
+#define RCC_RTCCLKSource_HSE_Div13 ((uint32_t)0x000D0300)
+#define RCC_RTCCLKSource_HSE_Div14 ((uint32_t)0x000E0300)
+#define RCC_RTCCLKSource_HSE_Div15 ((uint32_t)0x000F0300)
+#define RCC_RTCCLKSource_HSE_Div16 ((uint32_t)0x00100300)
+#define RCC_RTCCLKSource_HSE_Div17 ((uint32_t)0x00110300)
+#define RCC_RTCCLKSource_HSE_Div18 ((uint32_t)0x00120300)
+#define RCC_RTCCLKSource_HSE_Div19 ((uint32_t)0x00130300)
+#define RCC_RTCCLKSource_HSE_Div20 ((uint32_t)0x00140300)
+#define RCC_RTCCLKSource_HSE_Div21 ((uint32_t)0x00150300)
+#define RCC_RTCCLKSource_HSE_Div22 ((uint32_t)0x00160300)
+#define RCC_RTCCLKSource_HSE_Div23 ((uint32_t)0x00170300)
+#define RCC_RTCCLKSource_HSE_Div24 ((uint32_t)0x00180300)
+#define RCC_RTCCLKSource_HSE_Div25 ((uint32_t)0x00190300)
+#define RCC_RTCCLKSource_HSE_Div26 ((uint32_t)0x001A0300)
+#define RCC_RTCCLKSource_HSE_Div27 ((uint32_t)0x001B0300)
+#define RCC_RTCCLKSource_HSE_Div28 ((uint32_t)0x001C0300)
+#define RCC_RTCCLKSource_HSE_Div29 ((uint32_t)0x001D0300)
+#define RCC_RTCCLKSource_HSE_Div30 ((uint32_t)0x001E0300)
+#define RCC_RTCCLKSource_HSE_Div31 ((uint32_t)0x001F0300)
+#define IS_RCC_RTCCLK_SOURCE(SOURCE) (((SOURCE) == RCC_RTCCLKSource_LSE) || \
+ ((SOURCE) == RCC_RTCCLKSource_LSI) || \
+ ((SOURCE) == RCC_RTCCLKSource_HSE_Div2) || \
+ ((SOURCE) == RCC_RTCCLKSource_HSE_Div3) || \
+ ((SOURCE) == RCC_RTCCLKSource_HSE_Div4) || \
+ ((SOURCE) == RCC_RTCCLKSource_HSE_Div5) || \
+ ((SOURCE) == RCC_RTCCLKSource_HSE_Div6) || \
+ ((SOURCE) == RCC_RTCCLKSource_HSE_Div7) || \
+ ((SOURCE) == RCC_RTCCLKSource_HSE_Div8) || \
+ ((SOURCE) == RCC_RTCCLKSource_HSE_Div9) || \
+ ((SOURCE) == RCC_RTCCLKSource_HSE_Div10) || \
+ ((SOURCE) == RCC_RTCCLKSource_HSE_Div11) || \
+ ((SOURCE) == RCC_RTCCLKSource_HSE_Div12) || \
+ ((SOURCE) == RCC_RTCCLKSource_HSE_Div13) || \
+ ((SOURCE) == RCC_RTCCLKSource_HSE_Div14) || \
+ ((SOURCE) == RCC_RTCCLKSource_HSE_Div15) || \
+ ((SOURCE) == RCC_RTCCLKSource_HSE_Div16) || \
+ ((SOURCE) == RCC_RTCCLKSource_HSE_Div17) || \
+ ((SOURCE) == RCC_RTCCLKSource_HSE_Div18) || \
+ ((SOURCE) == RCC_RTCCLKSource_HSE_Div19) || \
+ ((SOURCE) == RCC_RTCCLKSource_HSE_Div20) || \
+ ((SOURCE) == RCC_RTCCLKSource_HSE_Div21) || \
+ ((SOURCE) == RCC_RTCCLKSource_HSE_Div22) || \
+ ((SOURCE) == RCC_RTCCLKSource_HSE_Div23) || \
+ ((SOURCE) == RCC_RTCCLKSource_HSE_Div24) || \
+ ((SOURCE) == RCC_RTCCLKSource_HSE_Div25) || \
+ ((SOURCE) == RCC_RTCCLKSource_HSE_Div26) || \
+ ((SOURCE) == RCC_RTCCLKSource_HSE_Div27) || \
+ ((SOURCE) == RCC_RTCCLKSource_HSE_Div28) || \
+ ((SOURCE) == RCC_RTCCLKSource_HSE_Div29) || \
+ ((SOURCE) == RCC_RTCCLKSource_HSE_Div30) || \
+ ((SOURCE) == RCC_RTCCLKSource_HSE_Div31))
+/**
+ * @}
+ */
+
+/** @defgroup RCC_I2S_Clock_Source
+ * @{
+ */
+#define RCC_I2S2CLKSource_PLLI2S ((uint8_t)0x00)
+#define RCC_I2S2CLKSource_Ext ((uint8_t)0x01)
+
+#define IS_RCC_I2SCLK_SOURCE(SOURCE) (((SOURCE) == RCC_I2S2CLKSource_PLLI2S) || ((SOURCE) == RCC_I2S2CLKSource_Ext))
+/**
+ * @}
+ */
+
+/** @defgroup RCC_AHB1_Peripherals
+ * @{
+ */
+#define RCC_AHB1Periph_GPIOA ((uint32_t)0x00000001)
+#define RCC_AHB1Periph_GPIOB ((uint32_t)0x00000002)
+#define RCC_AHB1Periph_GPIOC ((uint32_t)0x00000004)
+#define RCC_AHB1Periph_GPIOD ((uint32_t)0x00000008)
+#define RCC_AHB1Periph_GPIOE ((uint32_t)0x00000010)
+#define RCC_AHB1Periph_GPIOF ((uint32_t)0x00000020)
+#define RCC_AHB1Periph_GPIOG ((uint32_t)0x00000040)
+#define RCC_AHB1Periph_GPIOH ((uint32_t)0x00000080)
+#define RCC_AHB1Periph_GPIOI ((uint32_t)0x00000100)
+#define RCC_AHB1Periph_CRC ((uint32_t)0x00001000)
+#define RCC_AHB1Periph_FLITF ((uint32_t)0x00008000)
+#define RCC_AHB1Periph_SRAM1 ((uint32_t)0x00010000)
+#define RCC_AHB1Periph_SRAM2 ((uint32_t)0x00020000)
+#define RCC_AHB1Periph_BKPSRAM ((uint32_t)0x00040000)
+#define RCC_AHB1Periph_DMA1 ((uint32_t)0x00200000)
+#define RCC_AHB1Periph_DMA2 ((uint32_t)0x00400000)
+#define RCC_AHB1Periph_ETH_MAC ((uint32_t)0x02000000)
+#define RCC_AHB1Periph_ETH_MAC_Tx ((uint32_t)0x04000000)
+#define RCC_AHB1Periph_ETH_MAC_Rx ((uint32_t)0x08000000)
+#define RCC_AHB1Periph_ETH_MAC_PTP ((uint32_t)0x10000000)
+#define RCC_AHB1Periph_OTG_HS ((uint32_t)0x20000000)
+#define RCC_AHB1Periph_OTG_HS_ULPI ((uint32_t)0x40000000)
+#define IS_RCC_AHB1_CLOCK_PERIPH(PERIPH) ((((PERIPH) & 0x819BEE00) == 0x00) && ((PERIPH) != 0x00))
+#define IS_RCC_AHB1_RESET_PERIPH(PERIPH) ((((PERIPH) & 0xDD9FEE00) == 0x00) && ((PERIPH) != 0x00))
+#define IS_RCC_AHB1_LPMODE_PERIPH(PERIPH) ((((PERIPH) & 0x81986E00) == 0x00) && ((PERIPH) != 0x00))
+/**
+ * @}
+ */
+
+/** @defgroup RCC_AHB2_Peripherals
+ * @{
+ */
+#define RCC_AHB2Periph_DCMI ((uint32_t)0x00000001)
+#define RCC_AHB2Periph_CRYP ((uint32_t)0x00000010)
+#define RCC_AHB2Periph_HASH ((uint32_t)0x00000020)
+#define RCC_AHB2Periph_RNG ((uint32_t)0x00000040)
+#define RCC_AHB2Periph_OTG_FS ((uint32_t)0x00000080)
+#define IS_RCC_AHB2_PERIPH(PERIPH) ((((PERIPH) & 0xFFFFFF0E) == 0x00) && ((PERIPH) != 0x00))
+/**
+ * @}
+ */
+
+/** @defgroup RCC_AHB3_Peripherals
+ * @{
+ */
+#define RCC_AHB3Periph_FSMC ((uint32_t)0x00000001)
+#define IS_RCC_AHB3_PERIPH(PERIPH) ((((PERIPH) & 0xFFFFFFFE) == 0x00) && ((PERIPH) != 0x00))
+/**
+ * @}
+ */
+
+/** @defgroup RCC_APB1_Peripherals
+ * @{
+ */
+#define RCC_APB1Periph_TIM2 ((uint32_t)0x00000001)
+#define RCC_APB1Periph_TIM3 ((uint32_t)0x00000002)
+#define RCC_APB1Periph_TIM4 ((uint32_t)0x00000004)
+#define RCC_APB1Periph_TIM5 ((uint32_t)0x00000008)
+#define RCC_APB1Periph_TIM6 ((uint32_t)0x00000010)
+#define RCC_APB1Periph_TIM7 ((uint32_t)0x00000020)
+#define RCC_APB1Periph_TIM12 ((uint32_t)0x00000040)
+#define RCC_APB1Periph_TIM13 ((uint32_t)0x00000080)
+#define RCC_APB1Periph_TIM14 ((uint32_t)0x00000100)
+#define RCC_APB1Periph_WWDG ((uint32_t)0x00000800)
+#define RCC_APB1Periph_SPI2 ((uint32_t)0x00004000)
+#define RCC_APB1Periph_SPI3 ((uint32_t)0x00008000)
+#define RCC_APB1Periph_USART2 ((uint32_t)0x00020000)
+#define RCC_APB1Periph_USART3 ((uint32_t)0x00040000)
+#define RCC_APB1Periph_UART4 ((uint32_t)0x00080000)
+#define RCC_APB1Periph_UART5 ((uint32_t)0x00100000)
+#define RCC_APB1Periph_I2C1 ((uint32_t)0x00200000)
+#define RCC_APB1Periph_I2C2 ((uint32_t)0x00400000)
+#define RCC_APB1Periph_I2C3 ((uint32_t)0x00800000)
+#define RCC_APB1Periph_CAN1 ((uint32_t)0x02000000)
+#define RCC_APB1Periph_CAN2 ((uint32_t)0x04000000)
+#define RCC_APB1Periph_PWR ((uint32_t)0x10000000)
+#define RCC_APB1Periph_DAC ((uint32_t)0x20000000)
+#define IS_RCC_APB1_PERIPH(PERIPH) ((((PERIPH) & 0xC9013600) == 0x00) && ((PERIPH) != 0x00))
+/**
+ * @}
+ */
+
+/** @defgroup RCC_APB2_Peripherals
+ * @{
+ */
+#define RCC_APB2Periph_TIM1 ((uint32_t)0x00000001)
+#define RCC_APB2Periph_TIM8 ((uint32_t)0x00000002)
+#define RCC_APB2Periph_USART1 ((uint32_t)0x00000010)
+#define RCC_APB2Periph_USART6 ((uint32_t)0x00000020)
+#define RCC_APB2Periph_ADC ((uint32_t)0x00000100)
+#define RCC_APB2Periph_ADC1 ((uint32_t)0x00000100)
+#define RCC_APB2Periph_ADC2 ((uint32_t)0x00000200)
+#define RCC_APB2Periph_ADC3 ((uint32_t)0x00000400)
+#define RCC_APB2Periph_SDIO ((uint32_t)0x00000800)
+#define RCC_APB2Periph_SPI1 ((uint32_t)0x00001000)
+#define RCC_APB2Periph_SYSCFG ((uint32_t)0x00004000)
+#define RCC_APB2Periph_TIM9 ((uint32_t)0x00010000)
+#define RCC_APB2Periph_TIM10 ((uint32_t)0x00020000)
+#define RCC_APB2Periph_TIM11 ((uint32_t)0x00040000)
+#define IS_RCC_APB2_PERIPH(PERIPH) ((((PERIPH) & 0xFFF8A0CC) == 0x00) && ((PERIPH) != 0x00))
+#define IS_RCC_APB2_RESET_PERIPH(PERIPH) ((((PERIPH) & 0xFFF8A6CC) == 0x00) && ((PERIPH) != 0x00))
+/**
+ * @}
+ */
+
+/** @defgroup RCC_MCO1_Clock_Source_Prescaler
+ * @{
+ */
+#define RCC_MCO1Source_HSI ((uint32_t)0x00000000)
+#define RCC_MCO1Source_LSE ((uint32_t)0x00200000)
+#define RCC_MCO1Source_HSE ((uint32_t)0x00400000)
+#define RCC_MCO1Source_PLLCLK ((uint32_t)0x00600000)
+#define RCC_MCO1Div_1 ((uint32_t)0x00000000)
+#define RCC_MCO1Div_2 ((uint32_t)0x04000000)
+#define RCC_MCO1Div_3 ((uint32_t)0x05000000)
+#define RCC_MCO1Div_4 ((uint32_t)0x06000000)
+#define RCC_MCO1Div_5 ((uint32_t)0x07000000)
+#define IS_RCC_MCO1SOURCE(SOURCE) (((SOURCE) == RCC_MCO1Source_HSI) || ((SOURCE) == RCC_MCO1Source_LSE) || \
+ ((SOURCE) == RCC_MCO1Source_HSE) || ((SOURCE) == RCC_MCO1Source_PLLCLK))
+
+#define IS_RCC_MCO1DIV(DIV) (((DIV) == RCC_MCO1Div_1) || ((DIV) == RCC_MCO1Div_2) || \
+ ((DIV) == RCC_MCO1Div_3) || ((DIV) == RCC_MCO1Div_4) || \
+ ((DIV) == RCC_MCO1Div_5))
+/**
+ * @}
+ */
+
+/** @defgroup RCC_MCO2_Clock_Source_Prescaler
+ * @{
+ */
+#define RCC_MCO2Source_SYSCLK ((uint32_t)0x00000000)
+#define RCC_MCO2Source_PLLI2SCLK ((uint32_t)0x40000000)
+#define RCC_MCO2Source_HSE ((uint32_t)0x80000000)
+#define RCC_MCO2Source_PLLCLK ((uint32_t)0xC0000000)
+#define RCC_MCO2Div_1 ((uint32_t)0x00000000)
+#define RCC_MCO2Div_2 ((uint32_t)0x20000000)
+#define RCC_MCO2Div_3 ((uint32_t)0x28000000)
+#define RCC_MCO2Div_4 ((uint32_t)0x30000000)
+#define RCC_MCO2Div_5 ((uint32_t)0x38000000)
+#define IS_RCC_MCO2SOURCE(SOURCE) (((SOURCE) == RCC_MCO2Source_SYSCLK) || ((SOURCE) == RCC_MCO2Source_PLLI2SCLK)|| \
+ ((SOURCE) == RCC_MCO2Source_HSE) || ((SOURCE) == RCC_MCO2Source_PLLCLK))
+
+#define IS_RCC_MCO2DIV(DIV) (((DIV) == RCC_MCO2Div_1) || ((DIV) == RCC_MCO2Div_2) || \
+ ((DIV) == RCC_MCO2Div_3) || ((DIV) == RCC_MCO2Div_4) || \
+ ((DIV) == RCC_MCO2Div_5))
+/**
+ * @}
+ */
+
+/** @defgroup RCC_Flag
+ * @{
+ */
+#define RCC_FLAG_HSIRDY ((uint8_t)0x21)
+#define RCC_FLAG_HSERDY ((uint8_t)0x31)
+#define RCC_FLAG_PLLRDY ((uint8_t)0x39)
+#define RCC_FLAG_PLLI2SRDY ((uint8_t)0x3B)
+#define RCC_FLAG_LSERDY ((uint8_t)0x41)
+#define RCC_FLAG_LSIRDY ((uint8_t)0x61)
+#define RCC_FLAG_BORRST ((uint8_t)0x79)
+#define RCC_FLAG_PINRST ((uint8_t)0x7A)
+#define RCC_FLAG_PORRST ((uint8_t)0x7B)
+#define RCC_FLAG_SFTRST ((uint8_t)0x7C)
+#define RCC_FLAG_IWDGRST ((uint8_t)0x7D)
+#define RCC_FLAG_WWDGRST ((uint8_t)0x7E)
+#define RCC_FLAG_LPWRRST ((uint8_t)0x7F)
+#define IS_RCC_FLAG(FLAG) (((FLAG) == RCC_FLAG_HSIRDY) || ((FLAG) == RCC_FLAG_HSERDY) || \
+ ((FLAG) == RCC_FLAG_PLLRDY) || ((FLAG) == RCC_FLAG_LSERDY) || \
+ ((FLAG) == RCC_FLAG_LSIRDY) || ((FLAG) == RCC_FLAG_BORRST) || \
+ ((FLAG) == RCC_FLAG_PINRST) || ((FLAG) == RCC_FLAG_PORRST) || \
+ ((FLAG) == RCC_FLAG_SFTRST) || ((FLAG) == RCC_FLAG_IWDGRST)|| \
+ ((FLAG) == RCC_FLAG_WWDGRST)|| ((FLAG) == RCC_FLAG_LPWRRST)|| \
+ ((FLAG) == RCC_FLAG_PLLI2SRDY))
+#define IS_RCC_CALIBRATION_VALUE(VALUE) ((VALUE) <= 0x1F)
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions --------------------------------------------------------*/
+
+/* Function used to set the RCC clock configuration to the default reset state */
+void RCC_DeInit(void);
+
+/* Internal/external clocks, PLL, CSS and MCO configuration functions *********/
+void RCC_HSEConfig(uint8_t RCC_HSE);
+ErrorStatus RCC_WaitForHSEStartUp(void);
+void RCC_AdjustHSICalibrationValue(uint8_t HSICalibrationValue);
+void RCC_HSICmd(FunctionalState NewState);
+void RCC_LSEConfig(uint8_t RCC_LSE);
+void RCC_LSICmd(FunctionalState NewState);
+
+void RCC_PLLConfig(uint32_t RCC_PLLSource, uint32_t PLLM, uint32_t PLLN, uint32_t PLLP, uint32_t PLLQ);
+void RCC_PLLCmd(FunctionalState NewState);
+void RCC_PLLI2SConfig(uint32_t PLLI2SN, uint32_t PLLI2SR);
+void RCC_PLLI2SCmd(FunctionalState NewState);
+
+void RCC_ClockSecuritySystemCmd(FunctionalState NewState);
+void RCC_MCO1Config(uint32_t RCC_MCO1Source, uint32_t RCC_MCO1Div);
+void RCC_MCO2Config(uint32_t RCC_MCO2Source, uint32_t RCC_MCO2Div);
+
+/* System, AHB and APB busses clocks configuration functions ******************/
+void RCC_SYSCLKConfig(uint32_t RCC_SYSCLKSource);
+uint8_t RCC_GetSYSCLKSource(void);
+void RCC_HCLKConfig(uint32_t RCC_SYSCLK);
+void RCC_PCLK1Config(uint32_t RCC_HCLK);
+void RCC_PCLK2Config(uint32_t RCC_HCLK);
+void RCC_GetClocksFreq(RCC_ClocksTypeDef* RCC_Clocks);
+
+/* Peripheral clocks configuration functions **********************************/
+void RCC_RTCCLKConfig(uint32_t RCC_RTCCLKSource);
+void RCC_RTCCLKCmd(FunctionalState NewState);
+void RCC_BackupResetCmd(FunctionalState NewState);
+void RCC_I2SCLKConfig(uint32_t RCC_I2SCLKSource);
+
+void RCC_AHB1PeriphClockCmd(uint32_t RCC_AHB1Periph, FunctionalState NewState);
+void RCC_AHB2PeriphClockCmd(uint32_t RCC_AHB2Periph, FunctionalState NewState);
+void RCC_AHB3PeriphClockCmd(uint32_t RCC_AHB3Periph, FunctionalState NewState);
+void RCC_APB1PeriphClockCmd(uint32_t RCC_APB1Periph, FunctionalState NewState);
+void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState);
+
+void RCC_AHB1PeriphResetCmd(uint32_t RCC_AHB1Periph, FunctionalState NewState);
+void RCC_AHB2PeriphResetCmd(uint32_t RCC_AHB2Periph, FunctionalState NewState);
+void RCC_AHB3PeriphResetCmd(uint32_t RCC_AHB3Periph, FunctionalState NewState);
+void RCC_APB1PeriphResetCmd(uint32_t RCC_APB1Periph, FunctionalState NewState);
+void RCC_APB2PeriphResetCmd(uint32_t RCC_APB2Periph, FunctionalState NewState);
+
+void RCC_AHB1PeriphClockLPModeCmd(uint32_t RCC_AHB1Periph, FunctionalState NewState);
+void RCC_AHB2PeriphClockLPModeCmd(uint32_t RCC_AHB2Periph, FunctionalState NewState);
+void RCC_AHB3PeriphClockLPModeCmd(uint32_t RCC_AHB3Periph, FunctionalState NewState);
+void RCC_APB1PeriphClockLPModeCmd(uint32_t RCC_APB1Periph, FunctionalState NewState);
+void RCC_APB2PeriphClockLPModeCmd(uint32_t RCC_APB2Periph, FunctionalState NewState);
+
+/* Interrupts and flags management functions **********************************/
+void RCC_ITConfig(uint8_t RCC_IT, FunctionalState NewState);
+FlagStatus RCC_GetFlagStatus(uint8_t RCC_FLAG);
+void RCC_ClearFlag(void);
+ITStatus RCC_GetITStatus(uint8_t RCC_IT);
+void RCC_ClearITPendingBit(uint8_t RCC_IT);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F2xx_RCC_H */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/inc/stm32f2xx_rng.h b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/inc/stm32f2xx_rng.h
new file mode 100644
index 0000000..72f33cb
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/inc/stm32f2xx_rng.h
@@ -0,0 +1,120 @@
+/**
+ ******************************************************************************
+ * @file stm32f2xx_rng.h
+ * @author MCD Application Team
+ * @version V1.1.2
+ * @date 05-March-2012
+ * @brief This file contains all the functions prototypes for the Random
+ * Number Generator(RNG) firmware 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 __STM32F2xx_RNG_H
+#define __STM32F2xx_RNG_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f2xx.h"
+
+/** @addtogroup STM32F2xx_StdPeriph_Driver
+ * @{
+ */
+
+/** @addtogroup RNG
+ * @{
+ */
+
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+
+/** @defgroup RNG_Exported_Constants
+ * @{
+ */
+
+/** @defgroup RNG_flags_definition
+ * @{
+ */
+#define RNG_FLAG_DRDY ((uint8_t)0x0001) /*!< Data ready */
+#define RNG_FLAG_CECS ((uint8_t)0x0002) /*!< Clock error current status */
+#define RNG_FLAG_SECS ((uint8_t)0x0004) /*!< Seed error current status */
+
+#define IS_RNG_GET_FLAG(RNG_FLAG) (((RNG_FLAG) == RNG_FLAG_DRDY) || \
+ ((RNG_FLAG) == RNG_FLAG_CECS) || \
+ ((RNG_FLAG) == RNG_FLAG_SECS))
+#define IS_RNG_CLEAR_FLAG(RNG_FLAG) (((RNG_FLAG) == RNG_FLAG_CECS) || \
+ ((RNG_FLAG) == RNG_FLAG_SECS))
+/**
+ * @}
+ */
+
+/** @defgroup RNG_interrupts_definition
+ * @{
+ */
+#define RNG_IT_CEI ((uint8_t)0x20) /*!< Clock error interrupt */
+#define RNG_IT_SEI ((uint8_t)0x40) /*!< Seed error interrupt */
+
+#define IS_RNG_IT(IT) ((((IT) & (uint8_t)0x9F) == 0x00) && ((IT) != 0x00))
+#define IS_RNG_GET_IT(RNG_IT) (((RNG_IT) == RNG_IT_CEI) || ((RNG_IT) == RNG_IT_SEI))
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions --------------------------------------------------------*/
+
+/* Function used to set the RNG configuration to the default reset state *****/
+void RNG_DeInit(void);
+
+/* Configuration function *****************************************************/
+void RNG_Cmd(FunctionalState NewState);
+
+/* Get 32 bit Random number function ******************************************/
+uint32_t RNG_GetRandomNumber(void);
+
+/* Interrupts and flags management functions **********************************/
+void RNG_ITConfig(FunctionalState NewState);
+FlagStatus RNG_GetFlagStatus(uint8_t RNG_FLAG);
+void RNG_ClearFlag(uint8_t RNG_FLAG);
+ITStatus RNG_GetITStatus(uint8_t RNG_IT);
+void RNG_ClearITPendingBit(uint8_t RNG_IT);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*__STM32F2xx_RNG_H */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/inc/stm32f2xx_rtc.h b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/inc/stm32f2xx_rtc.h
new file mode 100644
index 0000000..1bba2f3
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/inc/stm32f2xx_rtc.h
@@ -0,0 +1,650 @@
+/**
+ ******************************************************************************
+ * @file stm32f2xx_rtc.h
+ * @author MCD Application Team
+ * @version V1.1.2
+ * @date 05-March-2012
+ * @brief This file contains all the functions prototypes for the RTC firmware
+ * 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 __STM32F2xx_RTC_H
+#define __STM32F2xx_RTC_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f2xx.h"
+
+/** @addtogroup STM32F2xx_StdPeriph_Driver
+ * @{
+ */
+
+/** @addtogroup RTC
+ * @{
+ */
+
+/* Exported types ------------------------------------------------------------*/
+
+/**
+ * @brief RTC Init structures definition
+ */
+typedef struct
+{
+ uint32_t RTC_HourFormat; /*!< Specifies the RTC Hour Format.
+ This parameter can be a value of @ref RTC_Hour_Formats */
+
+ uint32_t RTC_AsynchPrediv; /*!< Specifies the RTC Asynchronous Predivider value.
+ This parameter must be set to a value lower than 0x7F */
+
+ uint32_t RTC_SynchPrediv; /*!< Specifies the RTC Synchronous Predivider value.
+ This parameter must be set to a value lower than 0x1FFF */
+}RTC_InitTypeDef;
+
+/**
+ * @brief RTC Time structure definition
+ */
+typedef struct
+{
+ uint8_t RTC_Hours; /*!< Specifies the RTC Time Hour.
+ This parameter must be set to a value in the 0-12 range
+ if the RTC_HourFormat_12 is selected or 0-23 range if
+ the RTC_HourFormat_24 is selected. */
+
+ uint8_t RTC_Minutes; /*!< Specifies the RTC Time Minutes.
+ This parameter must be set to a value in the 0-59 range. */
+
+ uint8_t RTC_Seconds; /*!< Specifies the RTC Time Seconds.
+ This parameter must be set to a value in the 0-59 range. */
+
+ uint8_t RTC_H12; /*!< Specifies the RTC AM/PM Time.
+ This parameter can be a value of @ref RTC_AM_PM_Definitions */
+}RTC_TimeTypeDef;
+
+/**
+ * @brief RTC Date structure definition
+ */
+typedef struct
+{
+ uint8_t RTC_WeekDay; /*!< Specifies the RTC Date WeekDay.
+ This parameter can be a value of @ref RTC_WeekDay_Definitions */
+
+ uint8_t RTC_Month; /*!< Specifies the RTC Date Month (in BCD format).
+ This parameter can be a value of @ref RTC_Month_Date_Definitions */
+
+ uint8_t RTC_Date; /*!< Specifies the RTC Date.
+ This parameter must be set to a value in the 1-31 range. */
+
+ uint8_t RTC_Year; /*!< Specifies the RTC Date Year.
+ This parameter must be set to a value in the 0-99 range. */
+}RTC_DateTypeDef;
+
+/**
+ * @brief RTC Alarm structure definition
+ */
+typedef struct
+{
+ RTC_TimeTypeDef RTC_AlarmTime; /*!< Specifies the RTC Alarm Time members. */
+
+ uint32_t RTC_AlarmMask; /*!< Specifies the RTC Alarm Masks.
+ This parameter can be a value of @ref RTC_AlarmMask_Definitions */
+
+ uint32_t RTC_AlarmDateWeekDaySel; /*!< Specifies the RTC Alarm is on Date or WeekDay.
+ This parameter can be a value of @ref RTC_AlarmDateWeekDay_Definitions */
+
+ uint8_t RTC_AlarmDateWeekDay; /*!< Specifies the RTC Alarm Date/WeekDay.
+ If the Alarm Date is selected, this parameter
+ must be set to a value in the 1-31 range.
+ If the Alarm WeekDay is selected, this
+ parameter can be a value of @ref RTC_WeekDay_Definitions */
+}RTC_AlarmTypeDef;
+
+/* Exported constants --------------------------------------------------------*/
+
+/** @defgroup RTC_Exported_Constants
+ * @{
+ */
+
+
+/** @defgroup RTC_Hour_Formats
+ * @{
+ */
+#define RTC_HourFormat_24 ((uint32_t)0x00000000)
+#define RTC_HourFormat_12 ((uint32_t)0x00000040)
+#define IS_RTC_HOUR_FORMAT(FORMAT) (((FORMAT) == RTC_HourFormat_12) || \
+ ((FORMAT) == RTC_HourFormat_24))
+/**
+ * @}
+ */
+
+/** @defgroup RTC_Asynchronous_Predivider
+ * @{
+ */
+#define IS_RTC_ASYNCH_PREDIV(PREDIV) ((PREDIV) <= 0x7F)
+
+/**
+ * @}
+ */
+
+
+/** @defgroup RTC_Synchronous_Predivider
+ * @{
+ */
+#define IS_RTC_SYNCH_PREDIV(PREDIV) ((PREDIV) <= 0x1FFF)
+
+/**
+ * @}
+ */
+
+/** @defgroup RTC_Time_Definitions
+ * @{
+ */
+#define IS_RTC_HOUR12(HOUR) (((HOUR) > 0) && ((HOUR) <= 12))
+#define IS_RTC_HOUR24(HOUR) ((HOUR) <= 23)
+#define IS_RTC_MINUTES(MINUTES) ((MINUTES) <= 59)
+#define IS_RTC_SECONDS(SECONDS) ((SECONDS) <= 59)
+
+/**
+ * @}
+ */
+
+/** @defgroup RTC_AM_PM_Definitions
+ * @{
+ */
+#define RTC_H12_AM ((uint8_t)0x00)
+#define RTC_H12_PM ((uint8_t)0x40)
+#define IS_RTC_H12(PM) (((PM) == RTC_H12_AM) || ((PM) == RTC_H12_PM))
+
+/**
+ * @}
+ */
+
+/** @defgroup RTC_Year_Date_Definitions
+ * @{
+ */
+#define IS_RTC_YEAR(YEAR) ((YEAR) <= 99)
+
+/**
+ * @}
+ */
+
+/** @defgroup RTC_Month_Date_Definitions
+ * @{
+ */
+
+/* Coded in BCD format */
+#define RTC_Month_January ((uint8_t)0x01)
+#define RTC_Month_February ((uint8_t)0x02)
+#define RTC_Month_March ((uint8_t)0x03)
+#define RTC_Month_April ((uint8_t)0x04)
+#define RTC_Month_May ((uint8_t)0x05)
+#define RTC_Month_June ((uint8_t)0x06)
+#define RTC_Month_July ((uint8_t)0x07)
+#define RTC_Month_August ((uint8_t)0x08)
+#define RTC_Month_September ((uint8_t)0x09)
+#define RTC_Month_October ((uint8_t)0x10)
+#define RTC_Month_November ((uint8_t)0x11)
+#define RTC_Month_December ((uint8_t)0x12)
+#define IS_RTC_MONTH(MONTH) (((MONTH) >= 1) && ((MONTH) <= 12))
+#define IS_RTC_DATE(DATE) (((DATE) >= 1) && ((DATE) <= 31))
+
+/**
+ * @}
+ */
+
+/** @defgroup RTC_WeekDay_Definitions
+ * @{
+ */
+
+#define RTC_Weekday_Monday ((uint8_t)0x01)
+#define RTC_Weekday_Tuesday ((uint8_t)0x02)
+#define RTC_Weekday_Wednesday ((uint8_t)0x03)
+#define RTC_Weekday_Thursday ((uint8_t)0x04)
+#define RTC_Weekday_Friday ((uint8_t)0x05)
+#define RTC_Weekday_Saturday ((uint8_t)0x06)
+#define RTC_Weekday_Sunday ((uint8_t)0x07)
+#define IS_RTC_WEEKDAY(WEEKDAY) (((WEEKDAY) == RTC_Weekday_Monday) || \
+ ((WEEKDAY) == RTC_Weekday_Tuesday) || \
+ ((WEEKDAY) == RTC_Weekday_Wednesday) || \
+ ((WEEKDAY) == RTC_Weekday_Thursday) || \
+ ((WEEKDAY) == RTC_Weekday_Friday) || \
+ ((WEEKDAY) == RTC_Weekday_Saturday) || \
+ ((WEEKDAY) == RTC_Weekday_Sunday))
+/**
+ * @}
+ */
+
+
+/** @defgroup RTC_Alarm_Definitions
+ * @{
+ */
+#define IS_RTC_ALARM_DATE_WEEKDAY_DATE(DATE) (((DATE) > 0) && ((DATE) <= 31))
+#define IS_RTC_ALARM_DATE_WEEKDAY_WEEKDAY(WEEKDAY) (((WEEKDAY) == RTC_Weekday_Monday) || \
+ ((WEEKDAY) == RTC_Weekday_Tuesday) || \
+ ((WEEKDAY) == RTC_Weekday_Wednesday) || \
+ ((WEEKDAY) == RTC_Weekday_Thursday) || \
+ ((WEEKDAY) == RTC_Weekday_Friday) || \
+ ((WEEKDAY) == RTC_Weekday_Saturday) || \
+ ((WEEKDAY) == RTC_Weekday_Sunday))
+
+/**
+ * @}
+ */
+
+
+/** @defgroup RTC_AlarmDateWeekDay_Definitions
+ * @{
+ */
+#define RTC_AlarmDateWeekDaySel_Date ((uint32_t)0x00000000)
+#define RTC_AlarmDateWeekDaySel_WeekDay ((uint32_t)0x40000000)
+
+#define IS_RTC_ALARM_DATE_WEEKDAY_SEL(SEL) (((SEL) == RTC_AlarmDateWeekDaySel_Date) || \
+ ((SEL) == RTC_AlarmDateWeekDaySel_WeekDay))
+
+/**
+ * @}
+ */
+
+
+/** @defgroup RTC_AlarmMask_Definitions
+ * @{
+ */
+#define RTC_AlarmMask_None ((uint32_t)0x00000000)
+#define RTC_AlarmMask_DateWeekDay ((uint32_t)0x80000000)
+#define RTC_AlarmMask_Hours ((uint32_t)0x00800000)
+#define RTC_AlarmMask_Minutes ((uint32_t)0x00008000)
+#define RTC_AlarmMask_Seconds ((uint32_t)0x00000080)
+#define RTC_AlarmMask_All ((uint32_t)0x80808080)
+#define IS_ALARM_MASK(MASK) (((MASK) & 0x7F7F7F7F) == (uint32_t)RESET)
+
+/**
+ * @}
+ */
+
+/** @defgroup RTC_Alarms_Definitions
+ * @{
+ */
+#define RTC_Alarm_A ((uint32_t)0x00000100)
+#define RTC_Alarm_B ((uint32_t)0x00000200)
+#define IS_RTC_ALARM(ALARM) (((ALARM) == RTC_Alarm_A) || ((ALARM) == RTC_Alarm_B))
+#define IS_RTC_CMD_ALARM(ALARM) (((ALARM) & (RTC_Alarm_A | RTC_Alarm_B)) != (uint32_t)RESET)
+
+/**
+ * @}
+ */
+
+/** @defgroup RTC_Wakeup_Timer_Definitions
+ * @{
+ */
+#define RTC_WakeUpClock_RTCCLK_Div16 ((uint32_t)0x00000000)
+#define RTC_WakeUpClock_RTCCLK_Div8 ((uint32_t)0x00000001)
+#define RTC_WakeUpClock_RTCCLK_Div4 ((uint32_t)0x00000002)
+#define RTC_WakeUpClock_RTCCLK_Div2 ((uint32_t)0x00000003)
+#define RTC_WakeUpClock_CK_SPRE_16bits ((uint32_t)0x00000004)
+#define RTC_WakeUpClock_CK_SPRE_17bits ((uint32_t)0x00000006)
+#define IS_RTC_WAKEUP_CLOCK(CLOCK) (((CLOCK) == RTC_WakeUpClock_RTCCLK_Div16) || \
+ ((CLOCK) == RTC_WakeUpClock_RTCCLK_Div8) || \
+ ((CLOCK) == RTC_WakeUpClock_RTCCLK_Div4) || \
+ ((CLOCK) == RTC_WakeUpClock_RTCCLK_Div2) || \
+ ((CLOCK) == RTC_WakeUpClock_CK_SPRE_16bits) || \
+ ((CLOCK) == RTC_WakeUpClock_CK_SPRE_17bits))
+#define IS_RTC_WAKEUP_COUNTER(COUNTER) ((COUNTER) <= 0xFFFF)
+/**
+ * @}
+ */
+
+/** @defgroup RTC_Time_Stamp_Edges_definitions
+ * @{
+ */
+#define RTC_TimeStampEdge_Rising ((uint32_t)0x00000000)
+#define RTC_TimeStampEdge_Falling ((uint32_t)0x00000008)
+#define IS_RTC_TIMESTAMP_EDGE(EDGE) (((EDGE) == RTC_TimeStampEdge_Rising) || \
+ ((EDGE) == RTC_TimeStampEdge_Falling))
+/**
+ * @}
+ */
+
+/** @defgroup RTC_Output_selection_Definitions
+ * @{
+ */
+#define RTC_Output_Disable ((uint32_t)0x00000000)
+#define RTC_Output_AlarmA ((uint32_t)0x00200000)
+#define RTC_Output_AlarmB ((uint32_t)0x00400000)
+#define RTC_Output_WakeUp ((uint32_t)0x00600000)
+
+#define IS_RTC_OUTPUT(OUTPUT) (((OUTPUT) == RTC_Output_Disable) || \
+ ((OUTPUT) == RTC_Output_AlarmA) || \
+ ((OUTPUT) == RTC_Output_AlarmB) || \
+ ((OUTPUT) == RTC_Output_WakeUp))
+
+/**
+ * @}
+ */
+
+/** @defgroup RTC_Output_Polarity_Definitions
+ * @{
+ */
+#define RTC_OutputPolarity_High ((uint32_t)0x00000000)
+#define RTC_OutputPolarity_Low ((uint32_t)0x00100000)
+#define IS_RTC_OUTPUT_POL(POL) (((POL) == RTC_OutputPolarity_High) || \
+ ((POL) == RTC_OutputPolarity_Low))
+/**
+ * @}
+ */
+
+
+/** @defgroup RTC_Digital_Calibration_Definitions
+ * @{
+ */
+#define RTC_CalibSign_Positive ((uint32_t)0x00000000)
+#define RTC_CalibSign_Negative ((uint32_t)0x00000080)
+#define IS_RTC_CALIB_SIGN(SIGN) (((SIGN) == RTC_CalibSign_Positive) || \
+ ((SIGN) == RTC_CalibSign_Negative))
+#define IS_RTC_CALIB_VALUE(VALUE) ((VALUE) < 0x20)
+
+/**
+ * @}
+ */
+
+
+/** @defgroup RTC_DayLightSaving_Definitions
+ * @{
+ */
+#define RTC_DayLightSaving_SUB1H ((uint32_t)0x00020000)
+#define RTC_DayLightSaving_ADD1H ((uint32_t)0x00010000)
+#define IS_RTC_DAYLIGHT_SAVING(SAVE) (((SAVE) == RTC_DayLightSaving_SUB1H) || \
+ ((SAVE) == RTC_DayLightSaving_ADD1H))
+
+#define RTC_StoreOperation_Reset ((uint32_t)0x00000000)
+#define RTC_StoreOperation_Set ((uint32_t)0x00040000)
+#define IS_RTC_STORE_OPERATION(OPERATION) (((OPERATION) == RTC_StoreOperation_Reset) || \
+ ((OPERATION) == RTC_StoreOperation_Set))
+/**
+ * @}
+ */
+
+/** @defgroup RTC_Tamper_Trigger_Definitions
+ * @{
+ */
+#define RTC_TamperTrigger_RisingEdge ((uint32_t)0x00000000)
+#define RTC_TamperTrigger_FallingEdge ((uint32_t)0x00000001)
+#define IS_RTC_TAMPER_TRIGGER(TRIGGER) (((TRIGGER) == RTC_TamperTrigger_RisingEdge) || \
+ ((TRIGGER) == RTC_TamperTrigger_FallingEdge))
+
+/**
+ * @}
+ */
+
+/** @defgroup RTC_Tamper_Pins_Definitions
+ * @{
+ */
+#define RTC_Tamper_1 RTC_TAFCR_TAMP1E
+#define IS_RTC_TAMPER(TAMPER) (((TAMPER) == RTC_Tamper_1))
+
+/**
+ * @}
+ */
+
+/** @defgroup RTC_Tamper_Pin_Selection
+ * @{
+ */
+#define RTC_TamperPin_PC13 ((uint32_t)0x00000000)
+#define RTC_TamperPin_PI8 ((uint32_t)0x00010000)
+#define IS_RTC_TAMPER_PIN(PIN) (((PIN) == RTC_TamperPin_PC13) || \
+ ((PIN) == RTC_TamperPin_PI8))
+/**
+ * @}
+ */
+
+/** @defgroup RTC_TimeStamp_Pin_Selection
+ * @{
+ */
+#define RTC_TimeStampPin_PC13 ((uint32_t)0x00000000)
+#define RTC_TimeStampPin_PI8 ((uint32_t)0x00020000)
+#define IS_RTC_TIMESTAMP_PIN(PIN) (((PIN) == RTC_TimeStampPin_PC13) || \
+ ((PIN) == RTC_TimeStampPin_PI8))
+/**
+ * @}
+ */
+
+/** @defgroup RTC_Output_Type_ALARM_OUT
+ * @{
+ */
+#define RTC_OutputType_OpenDrain ((uint32_t)0x00000000)
+#define RTC_OutputType_PushPull ((uint32_t)0x00040000)
+#define IS_RTC_OUTPUT_TYPE(TYPE) (((TYPE) == RTC_OutputType_OpenDrain) || \
+ ((TYPE) == RTC_OutputType_PushPull))
+
+/**
+ * @}
+ */
+
+/** @defgroup RTC_Backup_Registers_Definitions
+ * @{
+ */
+
+#define RTC_BKP_DR0 ((uint32_t)0x00000000)
+#define RTC_BKP_DR1 ((uint32_t)0x00000001)
+#define RTC_BKP_DR2 ((uint32_t)0x00000002)
+#define RTC_BKP_DR3 ((uint32_t)0x00000003)
+#define RTC_BKP_DR4 ((uint32_t)0x00000004)
+#define RTC_BKP_DR5 ((uint32_t)0x00000005)
+#define RTC_BKP_DR6 ((uint32_t)0x00000006)
+#define RTC_BKP_DR7 ((uint32_t)0x00000007)
+#define RTC_BKP_DR8 ((uint32_t)0x00000008)
+#define RTC_BKP_DR9 ((uint32_t)0x00000009)
+#define RTC_BKP_DR10 ((uint32_t)0x0000000A)
+#define RTC_BKP_DR11 ((uint32_t)0x0000000B)
+#define RTC_BKP_DR12 ((uint32_t)0x0000000C)
+#define RTC_BKP_DR13 ((uint32_t)0x0000000D)
+#define RTC_BKP_DR14 ((uint32_t)0x0000000E)
+#define RTC_BKP_DR15 ((uint32_t)0x0000000F)
+#define RTC_BKP_DR16 ((uint32_t)0x00000010)
+#define RTC_BKP_DR17 ((uint32_t)0x00000011)
+#define RTC_BKP_DR18 ((uint32_t)0x00000012)
+#define RTC_BKP_DR19 ((uint32_t)0x00000013)
+#define IS_RTC_BKP(BKP) (((BKP) == RTC_BKP_DR0) || \
+ ((BKP) == RTC_BKP_DR1) || \
+ ((BKP) == RTC_BKP_DR2) || \
+ ((BKP) == RTC_BKP_DR3) || \
+ ((BKP) == RTC_BKP_DR4) || \
+ ((BKP) == RTC_BKP_DR5) || \
+ ((BKP) == RTC_BKP_DR6) || \
+ ((BKP) == RTC_BKP_DR7) || \
+ ((BKP) == RTC_BKP_DR8) || \
+ ((BKP) == RTC_BKP_DR9) || \
+ ((BKP) == RTC_BKP_DR10) || \
+ ((BKP) == RTC_BKP_DR11) || \
+ ((BKP) == RTC_BKP_DR12) || \
+ ((BKP) == RTC_BKP_DR13) || \
+ ((BKP) == RTC_BKP_DR14) || \
+ ((BKP) == RTC_BKP_DR15) || \
+ ((BKP) == RTC_BKP_DR16) || \
+ ((BKP) == RTC_BKP_DR17) || \
+ ((BKP) == RTC_BKP_DR18) || \
+ ((BKP) == RTC_BKP_DR19))
+/**
+ * @}
+ */
+
+/** @defgroup RTC_Input_parameter_format_definitions
+ * @{
+ */
+#define RTC_Format_BIN ((uint32_t)0x000000000)
+#define RTC_Format_BCD ((uint32_t)0x000000001)
+#define IS_RTC_FORMAT(FORMAT) (((FORMAT) == RTC_Format_BIN) || ((FORMAT) == RTC_Format_BCD))
+
+/**
+ * @}
+ */
+
+/** @defgroup RTC_Flags_Definitions
+ * @{
+ */
+#define RTC_FLAG_TAMP1F ((uint32_t)0x00002000)
+#define RTC_FLAG_TSOVF ((uint32_t)0x00001000)
+#define RTC_FLAG_TSF ((uint32_t)0x00000800)
+#define RTC_FLAG_WUTF ((uint32_t)0x00000400)
+#define RTC_FLAG_ALRBF ((uint32_t)0x00000200)
+#define RTC_FLAG_ALRAF ((uint32_t)0x00000100)
+#define RTC_FLAG_INITF ((uint32_t)0x00000040)
+#define RTC_FLAG_RSF ((uint32_t)0x00000020)
+#define RTC_FLAG_INITS ((uint32_t)0x00000010)
+#define RTC_FLAG_WUTWF ((uint32_t)0x00000004)
+#define RTC_FLAG_ALRBWF ((uint32_t)0x00000002)
+#define RTC_FLAG_ALRAWF ((uint32_t)0x00000001)
+#define IS_RTC_GET_FLAG(FLAG) (((FLAG) == RTC_FLAG_TSOVF) || ((FLAG) == RTC_FLAG_TSF) || \
+ ((FLAG) == RTC_FLAG_WUTF) || ((FLAG) == RTC_FLAG_ALRBF) || \
+ ((FLAG) == RTC_FLAG_ALRAF) || ((FLAG) == RTC_FLAG_INITF) || \
+ ((FLAG) == RTC_FLAG_RSF) || ((FLAG) == RTC_FLAG_WUTWF) || \
+ ((FLAG) == RTC_FLAG_ALRBWF) || ((FLAG) == RTC_FLAG_ALRAWF) || \
+ ((FLAG) == RTC_FLAG_TAMP1F))
+#define IS_RTC_CLEAR_FLAG(FLAG) (((FLAG) != (uint32_t)RESET) && (((FLAG) & 0xFFFFC0DF) == (uint32_t)RESET))
+
+/**
+ * @}
+ */
+
+/** @defgroup RTC_Interrupts_Definitions
+ * @{
+ */
+#define RTC_IT_TS ((uint32_t)0x00008000)
+#define RTC_IT_WUT ((uint32_t)0x00004000)
+#define RTC_IT_ALRB ((uint32_t)0x00002000)
+#define RTC_IT_ALRA ((uint32_t)0x00001000)
+#define RTC_IT_TAMP ((uint32_t)0x00000004) /* Used only to Enable the Tamper Interrupt */
+#define RTC_IT_TAMP1 ((uint32_t)0x00020000)
+
+#define IS_RTC_CONFIG_IT(IT) (((IT) != (uint32_t)RESET) && (((IT) & 0xFFFF0FFB) == (uint32_t)RESET))
+#define IS_RTC_GET_IT(IT) (((IT) == RTC_IT_TS) || ((IT) == RTC_IT_WUT) || \
+ ((IT) == RTC_IT_ALRB) || ((IT) == RTC_IT_ALRA) || \
+ ((IT) == RTC_IT_TAMP1))
+#define IS_RTC_CLEAR_IT(IT) (((IT) != (uint32_t)RESET) && (((IT) & 0xFFFD0FFF) == (uint32_t)RESET))
+
+/**
+ * @}
+ */
+
+/** @defgroup RTC_Legacy
+ * @{
+ */
+#define RTC_DigitalCalibConfig RTC_CoarseCalibConfig
+#define RTC_DigitalCalibCmd RTC_CoarseCalibCmd
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions --------------------------------------------------------*/
+
+/* Function used to set the RTC configuration to the default reset state *****/
+ErrorStatus RTC_DeInit(void);
+
+/* Initialization and Configuration functions *********************************/
+ErrorStatus RTC_Init(RTC_InitTypeDef* RTC_InitStruct);
+void RTC_StructInit(RTC_InitTypeDef* RTC_InitStruct);
+void RTC_WriteProtectionCmd(FunctionalState NewState);
+ErrorStatus RTC_EnterInitMode(void);
+void RTC_ExitInitMode(void);
+ErrorStatus RTC_WaitForSynchro(void);
+ErrorStatus RTC_RefClockCmd(FunctionalState NewState);
+
+/* Time and Date configuration functions **************************************/
+ErrorStatus RTC_SetTime(uint32_t RTC_Format, RTC_TimeTypeDef* RTC_TimeStruct);
+void RTC_TimeStructInit(RTC_TimeTypeDef* RTC_TimeStruct);
+void RTC_GetTime(uint32_t RTC_Format, RTC_TimeTypeDef* RTC_TimeStruct);
+ErrorStatus RTC_SetDate(uint32_t RTC_Format, RTC_DateTypeDef* RTC_DateStruct);
+void RTC_DateStructInit(RTC_DateTypeDef* RTC_DateStruct);
+void RTC_GetDate(uint32_t RTC_Format, RTC_DateTypeDef* RTC_DateStruct);
+
+/* Alarms (Alarm A and Alarm B) configuration functions **********************/
+void RTC_SetAlarm(uint32_t RTC_Format, uint32_t RTC_Alarm, RTC_AlarmTypeDef* RTC_AlarmStruct);
+void RTC_AlarmStructInit(RTC_AlarmTypeDef* RTC_AlarmStruct);
+void RTC_GetAlarm(uint32_t RTC_Format, uint32_t RTC_Alarm, RTC_AlarmTypeDef* RTC_AlarmStruct);
+ErrorStatus RTC_AlarmCmd(uint32_t RTC_Alarm, FunctionalState NewState);
+
+/* WakeUp Timer configuration functions ***************************************/
+void RTC_WakeUpClockConfig(uint32_t RTC_WakeUpClock);
+void RTC_SetWakeUpCounter(uint32_t RTC_WakeUpCounter);
+uint32_t RTC_GetWakeUpCounter(void);
+ErrorStatus RTC_WakeUpCmd(FunctionalState NewState);
+
+/* Daylight Saving configuration functions ************************************/
+void RTC_DayLightSavingConfig(uint32_t RTC_DayLightSaving, uint32_t RTC_StoreOperation);
+uint32_t RTC_GetStoreOperation(void);
+
+/* Output pin Configuration function ******************************************/
+void RTC_OutputConfig(uint32_t RTC_Output, uint32_t RTC_OutputPolarity);
+
+/* Coarse Calibration configuration functions *********************************/
+ErrorStatus RTC_CoarseCalibConfig(uint32_t RTC_CalibSign, uint32_t Value);
+ErrorStatus RTC_CoarseCalibCmd(FunctionalState NewState);
+void RTC_CalibOutputCmd(FunctionalState NewState);
+
+/* TimeStamp configuration functions ******************************************/
+void RTC_TimeStampCmd(uint32_t RTC_TimeStampEdge, FunctionalState NewState);
+void RTC_GetTimeStamp(uint32_t RTC_Format, RTC_TimeTypeDef* RTC_StampTimeStruct,
+ RTC_DateTypeDef* RTC_StampDateStruct);
+
+/* Tampers configuration functions ********************************************/
+void RTC_TamperTriggerConfig(uint32_t RTC_Tamper, uint32_t RTC_TamperTrigger);
+void RTC_TamperCmd(uint32_t RTC_Tamper, FunctionalState NewState);
+
+/* Backup Data Registers configuration functions ******************************/
+void RTC_WriteBackupRegister(uint32_t RTC_BKP_DR, uint32_t Data);
+uint32_t RTC_ReadBackupRegister(uint32_t RTC_BKP_DR);
+
+/* RTC Tamper and TimeStamp Pins Selection and Output Type Config configuration
+ functions ******************************************************************/
+void RTC_TamperPinSelection(uint32_t RTC_TamperPin);
+void RTC_TimeStampPinSelection(uint32_t RTC_TimeStampPin);
+void RTC_OutputTypeConfig(uint32_t RTC_OutputType);
+
+/* Interrupts and flags management functions **********************************/
+void RTC_ITConfig(uint32_t RTC_IT, FunctionalState NewState);
+FlagStatus RTC_GetFlagStatus(uint32_t RTC_FLAG);
+void RTC_ClearFlag(uint32_t RTC_FLAG);
+ITStatus RTC_GetITStatus(uint32_t RTC_IT);
+void RTC_ClearITPendingBit(uint32_t RTC_IT);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*__STM32F2xx_RTC_H */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/inc/stm32f2xx_sdio.h b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/inc/stm32f2xx_sdio.h
new file mode 100644
index 0000000..dbe2e3d
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/inc/stm32f2xx_sdio.h
@@ -0,0 +1,536 @@
+/**
+ ******************************************************************************
+ * @file stm32f2xx_sdio.h
+ * @author MCD Application Team
+ * @version V1.1.2
+ * @date 05-March-2012
+ * @brief This file contains all the functions prototypes for the SDIO firmware
+ * 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 __STM32F2xx_SDIO_H
+#define __STM32F2xx_SDIO_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f2xx.h"
+
+/** @addtogroup STM32F2xx_StdPeriph_Driver
+ * @{
+ */
+
+/** @addtogroup SDIO
+ * @{
+ */
+
+/* Exported types ------------------------------------------------------------*/
+
+typedef struct
+{
+ uint32_t SDIO_ClockEdge; /*!< Specifies the clock transition on which the bit capture is made.
+ This parameter can be a value of @ref SDIO_Clock_Edge */
+
+ uint32_t SDIO_ClockBypass; /*!< Specifies whether the SDIO Clock divider bypass is
+ enabled or disabled.
+ This parameter can be a value of @ref SDIO_Clock_Bypass */
+
+ uint32_t SDIO_ClockPowerSave; /*!< Specifies whether SDIO Clock output is enabled or
+ disabled when the bus is idle.
+ This parameter can be a value of @ref SDIO_Clock_Power_Save */
+
+ uint32_t SDIO_BusWide; /*!< Specifies the SDIO bus width.
+ This parameter can be a value of @ref SDIO_Bus_Wide */
+
+ uint32_t SDIO_HardwareFlowControl; /*!< Specifies whether the SDIO hardware flow control is enabled or disabled.
+ This parameter can be a value of @ref SDIO_Hardware_Flow_Control */
+
+ uint8_t SDIO_ClockDiv; /*!< Specifies the clock frequency of the SDIO controller.
+ This parameter can be a value between 0x00 and 0xFF. */
+
+} SDIO_InitTypeDef;
+
+typedef struct
+{
+ uint32_t SDIO_Argument; /*!< Specifies the SDIO command argument which is sent
+ to a card as part of a command message. If a command
+ contains an argument, it must be loaded into this register
+ before writing the command to the command register */
+
+ uint32_t SDIO_CmdIndex; /*!< Specifies the SDIO command index. It must be lower than 0x40. */
+
+ uint32_t SDIO_Response; /*!< Specifies the SDIO response type.
+ This parameter can be a value of @ref SDIO_Response_Type */
+
+ uint32_t SDIO_Wait; /*!< Specifies whether SDIO wait-for-interrupt request is enabled or disabled.
+ This parameter can be a value of @ref SDIO_Wait_Interrupt_State */
+
+ uint32_t SDIO_CPSM; /*!< Specifies whether SDIO Command path state machine (CPSM)
+ is enabled or disabled.
+ This parameter can be a value of @ref SDIO_CPSM_State */
+} SDIO_CmdInitTypeDef;
+
+typedef struct
+{
+ uint32_t SDIO_DataTimeOut; /*!< Specifies the data timeout period in card bus clock periods. */
+
+ uint32_t SDIO_DataLength; /*!< Specifies the number of data bytes to be transferred. */
+
+ uint32_t SDIO_DataBlockSize; /*!< Specifies the data block size for block transfer.
+ This parameter can be a value of @ref SDIO_Data_Block_Size */
+
+ uint32_t SDIO_TransferDir; /*!< Specifies the data transfer direction, whether the transfer
+ is a read or write.
+ This parameter can be a value of @ref SDIO_Transfer_Direction */
+
+ uint32_t SDIO_TransferMode; /*!< Specifies whether data transfer is in stream or block mode.
+ This parameter can be a value of @ref SDIO_Transfer_Type */
+
+ uint32_t SDIO_DPSM; /*!< Specifies whether SDIO Data path state machine (DPSM)
+ is enabled or disabled.
+ This parameter can be a value of @ref SDIO_DPSM_State */
+} SDIO_DataInitTypeDef;
+
+
+/* Exported constants --------------------------------------------------------*/
+
+/** @defgroup SDIO_Exported_Constants
+ * @{
+ */
+
+/** @defgroup SDIO_Clock_Edge
+ * @{
+ */
+
+#define SDIO_ClockEdge_Rising ((uint32_t)0x00000000)
+#define SDIO_ClockEdge_Falling ((uint32_t)0x00002000)
+#define IS_SDIO_CLOCK_EDGE(EDGE) (((EDGE) == SDIO_ClockEdge_Rising) || \
+ ((EDGE) == SDIO_ClockEdge_Falling))
+/**
+ * @}
+ */
+
+/** @defgroup SDIO_Clock_Bypass
+ * @{
+ */
+
+#define SDIO_ClockBypass_Disable ((uint32_t)0x00000000)
+#define SDIO_ClockBypass_Enable ((uint32_t)0x00000400)
+#define IS_SDIO_CLOCK_BYPASS(BYPASS) (((BYPASS) == SDIO_ClockBypass_Disable) || \
+ ((BYPASS) == SDIO_ClockBypass_Enable))
+/**
+ * @}
+ */
+
+/** @defgroup SDIO_Clock_Power_Save
+ * @{
+ */
+
+#define SDIO_ClockPowerSave_Disable ((uint32_t)0x00000000)
+#define SDIO_ClockPowerSave_Enable ((uint32_t)0x00000200)
+#define IS_SDIO_CLOCK_POWER_SAVE(SAVE) (((SAVE) == SDIO_ClockPowerSave_Disable) || \
+ ((SAVE) == SDIO_ClockPowerSave_Enable))
+/**
+ * @}
+ */
+
+/** @defgroup SDIO_Bus_Wide
+ * @{
+ */
+
+#define SDIO_BusWide_1b ((uint32_t)0x00000000)
+#define SDIO_BusWide_4b ((uint32_t)0x00000800)
+#define SDIO_BusWide_8b ((uint32_t)0x00001000)
+#define IS_SDIO_BUS_WIDE(WIDE) (((WIDE) == SDIO_BusWide_1b) || ((WIDE) == SDIO_BusWide_4b) || \
+ ((WIDE) == SDIO_BusWide_8b))
+
+/**
+ * @}
+ */
+
+/** @defgroup SDIO_Hardware_Flow_Control
+ * @{
+ */
+
+#define SDIO_HardwareFlowControl_Disable ((uint32_t)0x00000000)
+#define SDIO_HardwareFlowControl_Enable ((uint32_t)0x00004000)
+#define IS_SDIO_HARDWARE_FLOW_CONTROL(CONTROL) (((CONTROL) == SDIO_HardwareFlowControl_Disable) || \
+ ((CONTROL) == SDIO_HardwareFlowControl_Enable))
+/**
+ * @}
+ */
+
+/** @defgroup SDIO_Power_State
+ * @{
+ */
+
+#define SDIO_PowerState_OFF ((uint32_t)0x00000000)
+#define SDIO_PowerState_ON ((uint32_t)0x00000003)
+#define IS_SDIO_POWER_STATE(STATE) (((STATE) == SDIO_PowerState_OFF) || ((STATE) == SDIO_PowerState_ON))
+/**
+ * @}
+ */
+
+
+/** @defgroup SDIO_Interrupt_sources
+ * @{
+ */
+
+#define SDIO_IT_CCRCFAIL ((uint32_t)0x00000001)
+#define SDIO_IT_DCRCFAIL ((uint32_t)0x00000002)
+#define SDIO_IT_CTIMEOUT ((uint32_t)0x00000004)
+#define SDIO_IT_DTIMEOUT ((uint32_t)0x00000008)
+#define SDIO_IT_TXUNDERR ((uint32_t)0x00000010)
+#define SDIO_IT_RXOVERR ((uint32_t)0x00000020)
+#define SDIO_IT_CMDREND ((uint32_t)0x00000040)
+#define SDIO_IT_CMDSENT ((uint32_t)0x00000080)
+#define SDIO_IT_DATAEND ((uint32_t)0x00000100)
+#define SDIO_IT_STBITERR ((uint32_t)0x00000200)
+#define SDIO_IT_DBCKEND ((uint32_t)0x00000400)
+#define SDIO_IT_CMDACT ((uint32_t)0x00000800)
+#define SDIO_IT_TXACT ((uint32_t)0x00001000)
+#define SDIO_IT_RXACT ((uint32_t)0x00002000)
+#define SDIO_IT_TXFIFOHE ((uint32_t)0x00004000)
+#define SDIO_IT_RXFIFOHF ((uint32_t)0x00008000)
+#define SDIO_IT_TXFIFOF ((uint32_t)0x00010000)
+#define SDIO_IT_RXFIFOF ((uint32_t)0x00020000)
+#define SDIO_IT_TXFIFOE ((uint32_t)0x00040000)
+#define SDIO_IT_RXFIFOE ((uint32_t)0x00080000)
+#define SDIO_IT_TXDAVL ((uint32_t)0x00100000)
+#define SDIO_IT_RXDAVL ((uint32_t)0x00200000)
+#define SDIO_IT_SDIOIT ((uint32_t)0x00400000)
+#define SDIO_IT_CEATAEND ((uint32_t)0x00800000)
+#define IS_SDIO_IT(IT) ((((IT) & (uint32_t)0xFF000000) == 0x00) && ((IT) != (uint32_t)0x00))
+/**
+ * @}
+ */
+
+/** @defgroup SDIO_Command_Index
+ * @{
+ */
+
+#define IS_SDIO_CMD_INDEX(INDEX) ((INDEX) < 0x40)
+/**
+ * @}
+ */
+
+/** @defgroup SDIO_Response_Type
+ * @{
+ */
+
+#define SDIO_Response_No ((uint32_t)0x00000000)
+#define SDIO_Response_Short ((uint32_t)0x00000040)
+#define SDIO_Response_Long ((uint32_t)0x000000C0)
+#define IS_SDIO_RESPONSE(RESPONSE) (((RESPONSE) == SDIO_Response_No) || \
+ ((RESPONSE) == SDIO_Response_Short) || \
+ ((RESPONSE) == SDIO_Response_Long))
+/**
+ * @}
+ */
+
+/** @defgroup SDIO_Wait_Interrupt_State
+ * @{
+ */
+
+#define SDIO_Wait_No ((uint32_t)0x00000000) /*!< SDIO No Wait, TimeOut is enabled */
+#define SDIO_Wait_IT ((uint32_t)0x00000100) /*!< SDIO Wait Interrupt Request */
+#define SDIO_Wait_Pend ((uint32_t)0x00000200) /*!< SDIO Wait End of transfer */
+#define IS_SDIO_WAIT(WAIT) (((WAIT) == SDIO_Wait_No) || ((WAIT) == SDIO_Wait_IT) || \
+ ((WAIT) == SDIO_Wait_Pend))
+/**
+ * @}
+ */
+
+/** @defgroup SDIO_CPSM_State
+ * @{
+ */
+
+#define SDIO_CPSM_Disable ((uint32_t)0x00000000)
+#define SDIO_CPSM_Enable ((uint32_t)0x00000400)
+#define IS_SDIO_CPSM(CPSM) (((CPSM) == SDIO_CPSM_Enable) || ((CPSM) == SDIO_CPSM_Disable))
+/**
+ * @}
+ */
+
+/** @defgroup SDIO_Response_Registers
+ * @{
+ */
+
+#define SDIO_RESP1 ((uint32_t)0x00000000)
+#define SDIO_RESP2 ((uint32_t)0x00000004)
+#define SDIO_RESP3 ((uint32_t)0x00000008)
+#define SDIO_RESP4 ((uint32_t)0x0000000C)
+#define IS_SDIO_RESP(RESP) (((RESP) == SDIO_RESP1) || ((RESP) == SDIO_RESP2) || \
+ ((RESP) == SDIO_RESP3) || ((RESP) == SDIO_RESP4))
+/**
+ * @}
+ */
+
+/** @defgroup SDIO_Data_Length
+ * @{
+ */
+
+#define IS_SDIO_DATA_LENGTH(LENGTH) ((LENGTH) <= 0x01FFFFFF)
+/**
+ * @}
+ */
+
+/** @defgroup SDIO_Data_Block_Size
+ * @{
+ */
+
+#define SDIO_DataBlockSize_1b ((uint32_t)0x00000000)
+#define SDIO_DataBlockSize_2b ((uint32_t)0x00000010)
+#define SDIO_DataBlockSize_4b ((uint32_t)0x00000020)
+#define SDIO_DataBlockSize_8b ((uint32_t)0x00000030)
+#define SDIO_DataBlockSize_16b ((uint32_t)0x00000040)
+#define SDIO_DataBlockSize_32b ((uint32_t)0x00000050)
+#define SDIO_DataBlockSize_64b ((uint32_t)0x00000060)
+#define SDIO_DataBlockSize_128b ((uint32_t)0x00000070)
+#define SDIO_DataBlockSize_256b ((uint32_t)0x00000080)
+#define SDIO_DataBlockSize_512b ((uint32_t)0x00000090)
+#define SDIO_DataBlockSize_1024b ((uint32_t)0x000000A0)
+#define SDIO_DataBlockSize_2048b ((uint32_t)0x000000B0)
+#define SDIO_DataBlockSize_4096b ((uint32_t)0x000000C0)
+#define SDIO_DataBlockSize_8192b ((uint32_t)0x000000D0)
+#define SDIO_DataBlockSize_16384b ((uint32_t)0x000000E0)
+#define IS_SDIO_BLOCK_SIZE(SIZE) (((SIZE) == SDIO_DataBlockSize_1b) || \
+ ((SIZE) == SDIO_DataBlockSize_2b) || \
+ ((SIZE) == SDIO_DataBlockSize_4b) || \
+ ((SIZE) == SDIO_DataBlockSize_8b) || \
+ ((SIZE) == SDIO_DataBlockSize_16b) || \
+ ((SIZE) == SDIO_DataBlockSize_32b) || \
+ ((SIZE) == SDIO_DataBlockSize_64b) || \
+ ((SIZE) == SDIO_DataBlockSize_128b) || \
+ ((SIZE) == SDIO_DataBlockSize_256b) || \
+ ((SIZE) == SDIO_DataBlockSize_512b) || \
+ ((SIZE) == SDIO_DataBlockSize_1024b) || \
+ ((SIZE) == SDIO_DataBlockSize_2048b) || \
+ ((SIZE) == SDIO_DataBlockSize_4096b) || \
+ ((SIZE) == SDIO_DataBlockSize_8192b) || \
+ ((SIZE) == SDIO_DataBlockSize_16384b))
+/**
+ * @}
+ */
+
+/** @defgroup SDIO_Transfer_Direction
+ * @{
+ */
+
+#define SDIO_TransferDir_ToCard ((uint32_t)0x00000000)
+#define SDIO_TransferDir_ToSDIO ((uint32_t)0x00000002)
+#define IS_SDIO_TRANSFER_DIR(DIR) (((DIR) == SDIO_TransferDir_ToCard) || \
+ ((DIR) == SDIO_TransferDir_ToSDIO))
+/**
+ * @}
+ */
+
+/** @defgroup SDIO_Transfer_Type
+ * @{
+ */
+
+#define SDIO_TransferMode_Block ((uint32_t)0x00000000)
+#define SDIO_TransferMode_Stream ((uint32_t)0x00000004)
+#define IS_SDIO_TRANSFER_MODE(MODE) (((MODE) == SDIO_TransferMode_Stream) || \
+ ((MODE) == SDIO_TransferMode_Block))
+/**
+ * @}
+ */
+
+/** @defgroup SDIO_DPSM_State
+ * @{
+ */
+
+#define SDIO_DPSM_Disable ((uint32_t)0x00000000)
+#define SDIO_DPSM_Enable ((uint32_t)0x00000001)
+#define IS_SDIO_DPSM(DPSM) (((DPSM) == SDIO_DPSM_Enable) || ((DPSM) == SDIO_DPSM_Disable))
+/**
+ * @}
+ */
+
+/** @defgroup SDIO_Flags
+ * @{
+ */
+
+#define SDIO_FLAG_CCRCFAIL ((uint32_t)0x00000001)
+#define SDIO_FLAG_DCRCFAIL ((uint32_t)0x00000002)
+#define SDIO_FLAG_CTIMEOUT ((uint32_t)0x00000004)
+#define SDIO_FLAG_DTIMEOUT ((uint32_t)0x00000008)
+#define SDIO_FLAG_TXUNDERR ((uint32_t)0x00000010)
+#define SDIO_FLAG_RXOVERR ((uint32_t)0x00000020)
+#define SDIO_FLAG_CMDREND ((uint32_t)0x00000040)
+#define SDIO_FLAG_CMDSENT ((uint32_t)0x00000080)
+#define SDIO_FLAG_DATAEND ((uint32_t)0x00000100)
+#define SDIO_FLAG_STBITERR ((uint32_t)0x00000200)
+#define SDIO_FLAG_DBCKEND ((uint32_t)0x00000400)
+#define SDIO_FLAG_CMDACT ((uint32_t)0x00000800)
+#define SDIO_FLAG_TXACT ((uint32_t)0x00001000)
+#define SDIO_FLAG_RXACT ((uint32_t)0x00002000)
+#define SDIO_FLAG_TXFIFOHE ((uint32_t)0x00004000)
+#define SDIO_FLAG_RXFIFOHF ((uint32_t)0x00008000)
+#define SDIO_FLAG_TXFIFOF ((uint32_t)0x00010000)
+#define SDIO_FLAG_RXFIFOF ((uint32_t)0x00020000)
+#define SDIO_FLAG_TXFIFOE ((uint32_t)0x00040000)
+#define SDIO_FLAG_RXFIFOE ((uint32_t)0x00080000)
+#define SDIO_FLAG_TXDAVL ((uint32_t)0x00100000)
+#define SDIO_FLAG_RXDAVL ((uint32_t)0x00200000)
+#define SDIO_FLAG_SDIOIT ((uint32_t)0x00400000)
+#define SDIO_FLAG_CEATAEND ((uint32_t)0x00800000)
+#define IS_SDIO_FLAG(FLAG) (((FLAG) == SDIO_FLAG_CCRCFAIL) || \
+ ((FLAG) == SDIO_FLAG_DCRCFAIL) || \
+ ((FLAG) == SDIO_FLAG_CTIMEOUT) || \
+ ((FLAG) == SDIO_FLAG_DTIMEOUT) || \
+ ((FLAG) == SDIO_FLAG_TXUNDERR) || \
+ ((FLAG) == SDIO_FLAG_RXOVERR) || \
+ ((FLAG) == SDIO_FLAG_CMDREND) || \
+ ((FLAG) == SDIO_FLAG_CMDSENT) || \
+ ((FLAG) == SDIO_FLAG_DATAEND) || \
+ ((FLAG) == SDIO_FLAG_STBITERR) || \
+ ((FLAG) == SDIO_FLAG_DBCKEND) || \
+ ((FLAG) == SDIO_FLAG_CMDACT) || \
+ ((FLAG) == SDIO_FLAG_TXACT) || \
+ ((FLAG) == SDIO_FLAG_RXACT) || \
+ ((FLAG) == SDIO_FLAG_TXFIFOHE) || \
+ ((FLAG) == SDIO_FLAG_RXFIFOHF) || \
+ ((FLAG) == SDIO_FLAG_TXFIFOF) || \
+ ((FLAG) == SDIO_FLAG_RXFIFOF) || \
+ ((FLAG) == SDIO_FLAG_TXFIFOE) || \
+ ((FLAG) == SDIO_FLAG_RXFIFOE) || \
+ ((FLAG) == SDIO_FLAG_TXDAVL) || \
+ ((FLAG) == SDIO_FLAG_RXDAVL) || \
+ ((FLAG) == SDIO_FLAG_SDIOIT) || \
+ ((FLAG) == SDIO_FLAG_CEATAEND))
+
+#define IS_SDIO_CLEAR_FLAG(FLAG) ((((FLAG) & (uint32_t)0xFF3FF800) == 0x00) && ((FLAG) != (uint32_t)0x00))
+
+#define IS_SDIO_GET_IT(IT) (((IT) == SDIO_IT_CCRCFAIL) || \
+ ((IT) == SDIO_IT_DCRCFAIL) || \
+ ((IT) == SDIO_IT_CTIMEOUT) || \
+ ((IT) == SDIO_IT_DTIMEOUT) || \
+ ((IT) == SDIO_IT_TXUNDERR) || \
+ ((IT) == SDIO_IT_RXOVERR) || \
+ ((IT) == SDIO_IT_CMDREND) || \
+ ((IT) == SDIO_IT_CMDSENT) || \
+ ((IT) == SDIO_IT_DATAEND) || \
+ ((IT) == SDIO_IT_STBITERR) || \
+ ((IT) == SDIO_IT_DBCKEND) || \
+ ((IT) == SDIO_IT_CMDACT) || \
+ ((IT) == SDIO_IT_TXACT) || \
+ ((IT) == SDIO_IT_RXACT) || \
+ ((IT) == SDIO_IT_TXFIFOHE) || \
+ ((IT) == SDIO_IT_RXFIFOHF) || \
+ ((IT) == SDIO_IT_TXFIFOF) || \
+ ((IT) == SDIO_IT_RXFIFOF) || \
+ ((IT) == SDIO_IT_TXFIFOE) || \
+ ((IT) == SDIO_IT_RXFIFOE) || \
+ ((IT) == SDIO_IT_TXDAVL) || \
+ ((IT) == SDIO_IT_RXDAVL) || \
+ ((IT) == SDIO_IT_SDIOIT) || \
+ ((IT) == SDIO_IT_CEATAEND))
+
+#define IS_SDIO_CLEAR_IT(IT) ((((IT) & (uint32_t)0xFF3FF800) == 0x00) && ((IT) != (uint32_t)0x00))
+
+/**
+ * @}
+ */
+
+/** @defgroup SDIO_Read_Wait_Mode
+ * @{
+ */
+
+#define SDIO_ReadWaitMode_CLK ((uint32_t)0x00000000)
+#define SDIO_ReadWaitMode_DATA2 ((uint32_t)0x00000001)
+#define IS_SDIO_READWAIT_MODE(MODE) (((MODE) == SDIO_ReadWaitMode_CLK) || \
+ ((MODE) == SDIO_ReadWaitMode_DATA2))
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions --------------------------------------------------------*/
+/* Function used to set the SDIO configuration to the default reset state ****/
+void SDIO_DeInit(void);
+
+/* Initialization and Configuration functions *********************************/
+void SDIO_Init(SDIO_InitTypeDef* SDIO_InitStruct);
+void SDIO_StructInit(SDIO_InitTypeDef* SDIO_InitStruct);
+void SDIO_ClockCmd(FunctionalState NewState);
+void SDIO_SetPowerState(uint32_t SDIO_PowerState);
+uint32_t SDIO_GetPowerState(void);
+
+/* Command path state machine (CPSM) management functions *********************/
+void SDIO_SendCommand(SDIO_CmdInitTypeDef *SDIO_CmdInitStruct);
+void SDIO_CmdStructInit(SDIO_CmdInitTypeDef* SDIO_CmdInitStruct);
+uint8_t SDIO_GetCommandResponse(void);
+uint32_t SDIO_GetResponse(uint32_t SDIO_RESP);
+
+/* Data path state machine (DPSM) management functions ************************/
+void SDIO_DataConfig(SDIO_DataInitTypeDef* SDIO_DataInitStruct);
+void SDIO_DataStructInit(SDIO_DataInitTypeDef* SDIO_DataInitStruct);
+uint32_t SDIO_GetDataCounter(void);
+uint32_t SDIO_ReadData(void);
+void SDIO_WriteData(uint32_t Data);
+uint32_t SDIO_GetFIFOCount(void);
+
+/* SDIO IO Cards mode management functions ************************************/
+void SDIO_StartSDIOReadWait(FunctionalState NewState);
+void SDIO_StopSDIOReadWait(FunctionalState NewState);
+void SDIO_SetSDIOReadWaitMode(uint32_t SDIO_ReadWaitMode);
+void SDIO_SetSDIOOperation(FunctionalState NewState);
+void SDIO_SendSDIOSuspendCmd(FunctionalState NewState);
+
+/* CE-ATA mode management functions *******************************************/
+void SDIO_CommandCompletionCmd(FunctionalState NewState);
+void SDIO_CEATAITCmd(FunctionalState NewState);
+void SDIO_SendCEATACmd(FunctionalState NewState);
+
+/* DMA transfers management functions *****************************************/
+void SDIO_DMACmd(FunctionalState NewState);
+
+/* Interrupts and flags management functions **********************************/
+void SDIO_ITConfig(uint32_t SDIO_IT, FunctionalState NewState);
+FlagStatus SDIO_GetFlagStatus(uint32_t SDIO_FLAG);
+void SDIO_ClearFlag(uint32_t SDIO_FLAG);
+ITStatus SDIO_GetITStatus(uint32_t SDIO_IT);
+void SDIO_ClearITPendingBit(uint32_t SDIO_IT);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F2xx_SDIO_H */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/inc/stm32f2xx_spi.h b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/inc/stm32f2xx_spi.h
new file mode 100644
index 0000000..30b4431
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/inc/stm32f2xx_spi.h
@@ -0,0 +1,526 @@
+/**
+ ******************************************************************************
+ * @file stm32f2xx_spi.h
+ * @author MCD Application Team
+ * @version V1.1.2
+ * @date 05-March-2012
+ * @brief This file contains all the functions prototypes for the SPI
+ * firmware 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 __STM32F2xx_SPI_H
+#define __STM32F2xx_SPI_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f2xx.h"
+
+/** @addtogroup STM32F2xx_StdPeriph_Driver
+ * @{
+ */
+
+/** @addtogroup SPI
+ * @{
+ */
+
+/* Exported types ------------------------------------------------------------*/
+
+/**
+ * @brief SPI Init structure definition
+ */
+
+typedef struct
+{
+ uint16_t SPI_Direction; /*!< Specifies the SPI unidirectional or bidirectional data mode.
+ This parameter can be a value of @ref SPI_data_direction */
+
+ uint16_t SPI_Mode; /*!< Specifies the SPI operating mode.
+ This parameter can be a value of @ref SPI_mode */
+
+ uint16_t SPI_DataSize; /*!< Specifies the SPI data size.
+ This parameter can be a value of @ref SPI_data_size */
+
+ uint16_t SPI_CPOL; /*!< Specifies the serial clock steady state.
+ This parameter can be a value of @ref SPI_Clock_Polarity */
+
+ uint16_t SPI_CPHA; /*!< Specifies the clock active edge for the bit capture.
+ This parameter can be a value of @ref SPI_Clock_Phase */
+
+ uint16_t SPI_NSS; /*!< Specifies whether the NSS signal is managed by
+ hardware (NSS pin) or by software using the SSI bit.
+ This parameter can be a value of @ref SPI_Slave_Select_management */
+
+ uint16_t SPI_BaudRatePrescaler; /*!< Specifies the Baud Rate prescaler value which will be
+ used to configure the transmit and receive SCK clock.
+ This parameter can be a value of @ref SPI_BaudRate_Prescaler
+ @note The communication clock is derived from the master
+ clock. The slave clock does not need to be set. */
+
+ uint16_t SPI_FirstBit; /*!< Specifies whether data transfers start from MSB or LSB bit.
+ This parameter can be a value of @ref SPI_MSB_LSB_transmission */
+
+ uint16_t SPI_CRCPolynomial; /*!< Specifies the polynomial used for the CRC calculation. */
+}SPI_InitTypeDef;
+
+/**
+ * @brief I2S Init structure definition
+ */
+
+typedef struct
+{
+
+ uint16_t I2S_Mode; /*!< Specifies the I2S operating mode.
+ This parameter can be a value of @ref I2S_Mode */
+
+ uint16_t I2S_Standard; /*!< Specifies the standard used for the I2S communication.
+ This parameter can be a value of @ref I2S_Standard */
+
+ uint16_t I2S_DataFormat; /*!< Specifies the data format for the I2S communication.
+ This parameter can be a value of @ref I2S_Data_Format */
+
+ uint16_t I2S_MCLKOutput; /*!< Specifies whether the I2S MCLK output is enabled or not.
+ This parameter can be a value of @ref I2S_MCLK_Output */
+
+ uint32_t I2S_AudioFreq; /*!< Specifies the frequency selected for the I2S communication.
+ This parameter can be a value of @ref I2S_Audio_Frequency */
+
+ uint16_t I2S_CPOL; /*!< Specifies the idle state of the I2S clock.
+ This parameter can be a value of @ref I2S_Clock_Polarity */
+}I2S_InitTypeDef;
+
+/* Exported constants --------------------------------------------------------*/
+
+/** @defgroup SPI_Exported_Constants
+ * @{
+ */
+
+#define IS_SPI_ALL_PERIPH(PERIPH) (((PERIPH) == SPI1) || \
+ ((PERIPH) == SPI2) || \
+ ((PERIPH) == SPI3))
+
+#define IS_SPI_23_PERIPH(PERIPH) (((PERIPH) == SPI2) || \
+ ((PERIPH) == SPI3))
+
+/** @defgroup SPI_data_direction
+ * @{
+ */
+
+#define SPI_Direction_2Lines_FullDuplex ((uint16_t)0x0000)
+#define SPI_Direction_2Lines_RxOnly ((uint16_t)0x0400)
+#define SPI_Direction_1Line_Rx ((uint16_t)0x8000)
+#define SPI_Direction_1Line_Tx ((uint16_t)0xC000)
+#define IS_SPI_DIRECTION_MODE(MODE) (((MODE) == SPI_Direction_2Lines_FullDuplex) || \
+ ((MODE) == SPI_Direction_2Lines_RxOnly) || \
+ ((MODE) == SPI_Direction_1Line_Rx) || \
+ ((MODE) == SPI_Direction_1Line_Tx))
+/**
+ * @}
+ */
+
+/** @defgroup SPI_mode
+ * @{
+ */
+
+#define SPI_Mode_Master ((uint16_t)0x0104)
+#define SPI_Mode_Slave ((uint16_t)0x0000)
+#define IS_SPI_MODE(MODE) (((MODE) == SPI_Mode_Master) || \
+ ((MODE) == SPI_Mode_Slave))
+/**
+ * @}
+ */
+
+/** @defgroup SPI_data_size
+ * @{
+ */
+
+#define SPI_DataSize_16b ((uint16_t)0x0800)
+#define SPI_DataSize_8b ((uint16_t)0x0000)
+#define IS_SPI_DATASIZE(DATASIZE) (((DATASIZE) == SPI_DataSize_16b) || \
+ ((DATASIZE) == SPI_DataSize_8b))
+/**
+ * @}
+ */
+
+/** @defgroup SPI_Clock_Polarity
+ * @{
+ */
+
+#define SPI_CPOL_Low ((uint16_t)0x0000)
+#define SPI_CPOL_High ((uint16_t)0x0002)
+#define IS_SPI_CPOL(CPOL) (((CPOL) == SPI_CPOL_Low) || \
+ ((CPOL) == SPI_CPOL_High))
+/**
+ * @}
+ */
+
+/** @defgroup SPI_Clock_Phase
+ * @{
+ */
+
+#define SPI_CPHA_1Edge ((uint16_t)0x0000)
+#define SPI_CPHA_2Edge ((uint16_t)0x0001)
+#define IS_SPI_CPHA(CPHA) (((CPHA) == SPI_CPHA_1Edge) || \
+ ((CPHA) == SPI_CPHA_2Edge))
+/**
+ * @}
+ */
+
+/** @defgroup SPI_Slave_Select_management
+ * @{
+ */
+
+#define SPI_NSS_Soft ((uint16_t)0x0200)
+#define SPI_NSS_Hard ((uint16_t)0x0000)
+#define IS_SPI_NSS(NSS) (((NSS) == SPI_NSS_Soft) || \
+ ((NSS) == SPI_NSS_Hard))
+/**
+ * @}
+ */
+
+/** @defgroup SPI_BaudRate_Prescaler
+ * @{
+ */
+
+#define SPI_BaudRatePrescaler_2 ((uint16_t)0x0000)
+#define SPI_BaudRatePrescaler_4 ((uint16_t)0x0008)
+#define SPI_BaudRatePrescaler_8 ((uint16_t)0x0010)
+#define SPI_BaudRatePrescaler_16 ((uint16_t)0x0018)
+#define SPI_BaudRatePrescaler_32 ((uint16_t)0x0020)
+#define SPI_BaudRatePrescaler_64 ((uint16_t)0x0028)
+#define SPI_BaudRatePrescaler_128 ((uint16_t)0x0030)
+#define SPI_BaudRatePrescaler_256 ((uint16_t)0x0038)
+#define IS_SPI_BAUDRATE_PRESCALER(PRESCALER) (((PRESCALER) == SPI_BaudRatePrescaler_2) || \
+ ((PRESCALER) == SPI_BaudRatePrescaler_4) || \
+ ((PRESCALER) == SPI_BaudRatePrescaler_8) || \
+ ((PRESCALER) == SPI_BaudRatePrescaler_16) || \
+ ((PRESCALER) == SPI_BaudRatePrescaler_32) || \
+ ((PRESCALER) == SPI_BaudRatePrescaler_64) || \
+ ((PRESCALER) == SPI_BaudRatePrescaler_128) || \
+ ((PRESCALER) == SPI_BaudRatePrescaler_256))
+/**
+ * @}
+ */
+
+/** @defgroup SPI_MSB_LSB_transmission
+ * @{
+ */
+
+#define SPI_FirstBit_MSB ((uint16_t)0x0000)
+#define SPI_FirstBit_LSB ((uint16_t)0x0080)
+#define IS_SPI_FIRST_BIT(BIT) (((BIT) == SPI_FirstBit_MSB) || \
+ ((BIT) == SPI_FirstBit_LSB))
+/**
+ * @}
+ */
+
+/** @defgroup SPI_I2S_Mode
+ * @{
+ */
+
+#define I2S_Mode_SlaveTx ((uint16_t)0x0000)
+#define I2S_Mode_SlaveRx ((uint16_t)0x0100)
+#define I2S_Mode_MasterTx ((uint16_t)0x0200)
+#define I2S_Mode_MasterRx ((uint16_t)0x0300)
+#define IS_I2S_MODE(MODE) (((MODE) == I2S_Mode_SlaveTx) || \
+ ((MODE) == I2S_Mode_SlaveRx) || \
+ ((MODE) == I2S_Mode_MasterTx)|| \
+ ((MODE) == I2S_Mode_MasterRx))
+/**
+ * @}
+ */
+
+
+/** @defgroup SPI_I2S_Standard
+ * @{
+ */
+
+#define I2S_Standard_Phillips ((uint16_t)0x0000)
+#define I2S_Standard_MSB ((uint16_t)0x0010)
+#define I2S_Standard_LSB ((uint16_t)0x0020)
+#define I2S_Standard_PCMShort ((uint16_t)0x0030)
+#define I2S_Standard_PCMLong ((uint16_t)0x00B0)
+#define IS_I2S_STANDARD(STANDARD) (((STANDARD) == I2S_Standard_Phillips) || \
+ ((STANDARD) == I2S_Standard_MSB) || \
+ ((STANDARD) == I2S_Standard_LSB) || \
+ ((STANDARD) == I2S_Standard_PCMShort) || \
+ ((STANDARD) == I2S_Standard_PCMLong))
+/**
+ * @}
+ */
+
+/** @defgroup SPI_I2S_Data_Format
+ * @{
+ */
+
+#define I2S_DataFormat_16b ((uint16_t)0x0000)
+#define I2S_DataFormat_16bextended ((uint16_t)0x0001)
+#define I2S_DataFormat_24b ((uint16_t)0x0003)
+#define I2S_DataFormat_32b ((uint16_t)0x0005)
+#define IS_I2S_DATA_FORMAT(FORMAT) (((FORMAT) == I2S_DataFormat_16b) || \
+ ((FORMAT) == I2S_DataFormat_16bextended) || \
+ ((FORMAT) == I2S_DataFormat_24b) || \
+ ((FORMAT) == I2S_DataFormat_32b))
+/**
+ * @}
+ */
+
+/** @defgroup SPI_I2S_MCLK_Output
+ * @{
+ */
+
+#define I2S_MCLKOutput_Enable ((uint16_t)0x0200)
+#define I2S_MCLKOutput_Disable ((uint16_t)0x0000)
+#define IS_I2S_MCLK_OUTPUT(OUTPUT) (((OUTPUT) == I2S_MCLKOutput_Enable) || \
+ ((OUTPUT) == I2S_MCLKOutput_Disable))
+/**
+ * @}
+ */
+
+/** @defgroup SPI_I2S_Audio_Frequency
+ * @{
+ */
+
+#define I2S_AudioFreq_192k ((uint32_t)192000)
+#define I2S_AudioFreq_96k ((uint32_t)96000)
+#define I2S_AudioFreq_48k ((uint32_t)48000)
+#define I2S_AudioFreq_44k ((uint32_t)44100)
+#define I2S_AudioFreq_32k ((uint32_t)32000)
+#define I2S_AudioFreq_22k ((uint32_t)22050)
+#define I2S_AudioFreq_16k ((uint32_t)16000)
+#define I2S_AudioFreq_11k ((uint32_t)11025)
+#define I2S_AudioFreq_8k ((uint32_t)8000)
+#define I2S_AudioFreq_Default ((uint32_t)2)
+
+#define IS_I2S_AUDIO_FREQ(FREQ) ((((FREQ) >= I2S_AudioFreq_8k) && \
+ ((FREQ) <= I2S_AudioFreq_192k)) || \
+ ((FREQ) == I2S_AudioFreq_Default))
+/**
+ * @}
+ */
+
+/** @defgroup SPI_I2S_Clock_Polarity
+ * @{
+ */
+
+#define I2S_CPOL_Low ((uint16_t)0x0000)
+#define I2S_CPOL_High ((uint16_t)0x0008)
+#define IS_I2S_CPOL(CPOL) (((CPOL) == I2S_CPOL_Low) || \
+ ((CPOL) == I2S_CPOL_High))
+/**
+ * @}
+ */
+
+/** @defgroup SPI_I2S_DMA_transfer_requests
+ * @{
+ */
+
+#define SPI_I2S_DMAReq_Tx ((uint16_t)0x0002)
+#define SPI_I2S_DMAReq_Rx ((uint16_t)0x0001)
+#define IS_SPI_I2S_DMAREQ(DMAREQ) ((((DMAREQ) & (uint16_t)0xFFFC) == 0x00) && ((DMAREQ) != 0x00))
+/**
+ * @}
+ */
+
+/** @defgroup SPI_NSS_internal_software_management
+ * @{
+ */
+
+#define SPI_NSSInternalSoft_Set ((uint16_t)0x0100)
+#define SPI_NSSInternalSoft_Reset ((uint16_t)0xFEFF)
+#define IS_SPI_NSS_INTERNAL(INTERNAL) (((INTERNAL) == SPI_NSSInternalSoft_Set) || \
+ ((INTERNAL) == SPI_NSSInternalSoft_Reset))
+/**
+ * @}
+ */
+
+/** @defgroup SPI_CRC_Transmit_Receive
+ * @{
+ */
+
+#define SPI_CRC_Tx ((uint8_t)0x00)
+#define SPI_CRC_Rx ((uint8_t)0x01)
+#define IS_SPI_CRC(CRC) (((CRC) == SPI_CRC_Tx) || ((CRC) == SPI_CRC_Rx))
+/**
+ * @}
+ */
+
+/** @defgroup SPI_direction_transmit_receive
+ * @{
+ */
+
+#define SPI_Direction_Rx ((uint16_t)0xBFFF)
+#define SPI_Direction_Tx ((uint16_t)0x4000)
+#define IS_SPI_DIRECTION(DIRECTION) (((DIRECTION) == SPI_Direction_Rx) || \
+ ((DIRECTION) == SPI_Direction_Tx))
+/**
+ * @}
+ */
+
+/** @defgroup SPI_I2S_interrupts_definition
+ * @{
+ */
+
+#define SPI_I2S_IT_TXE ((uint8_t)0x71)
+#define SPI_I2S_IT_RXNE ((uint8_t)0x60)
+#define SPI_I2S_IT_ERR ((uint8_t)0x50)
+#define I2S_IT_UDR ((uint8_t)0x53)
+#define SPI_I2S_IT_TIFRFE ((uint8_t)0x58)
+
+#define IS_SPI_I2S_CONFIG_IT(IT) (((IT) == SPI_I2S_IT_TXE) || \
+ ((IT) == SPI_I2S_IT_RXNE) || \
+ ((IT) == SPI_I2S_IT_ERR))
+
+#define SPI_I2S_IT_OVR ((uint8_t)0x56)
+#define SPI_IT_MODF ((uint8_t)0x55)
+#define SPI_IT_CRCERR ((uint8_t)0x54)
+
+#define IS_SPI_I2S_CLEAR_IT(IT) (((IT) == SPI_IT_CRCERR))
+
+#define IS_SPI_I2S_GET_IT(IT) (((IT) == SPI_I2S_IT_RXNE)|| ((IT) == SPI_I2S_IT_TXE) || \
+ ((IT) == SPI_IT_CRCERR) || ((IT) == SPI_IT_MODF) || \
+ ((IT) == SPI_I2S_IT_OVR) || ((IT) == I2S_IT_UDR) ||\
+ ((IT) == SPI_I2S_IT_TIFRFE))
+/**
+ * @}
+ */
+
+/** @defgroup SPI_I2S_flags_definition
+ * @{
+ */
+
+#define SPI_I2S_FLAG_RXNE ((uint16_t)0x0001)
+#define SPI_I2S_FLAG_TXE ((uint16_t)0x0002)
+#define I2S_FLAG_CHSIDE ((uint16_t)0x0004)
+#define I2S_FLAG_UDR ((uint16_t)0x0008)
+#define SPI_FLAG_CRCERR ((uint16_t)0x0010)
+#define SPI_FLAG_MODF ((uint16_t)0x0020)
+#define SPI_I2S_FLAG_OVR ((uint16_t)0x0040)
+#define SPI_I2S_FLAG_BSY ((uint16_t)0x0080)
+#define SPI_I2S_FLAG_TIFRFE ((uint16_t)0x0100)
+
+#define IS_SPI_I2S_CLEAR_FLAG(FLAG) (((FLAG) == SPI_FLAG_CRCERR))
+#define IS_SPI_I2S_GET_FLAG(FLAG) (((FLAG) == SPI_I2S_FLAG_BSY) || ((FLAG) == SPI_I2S_FLAG_OVR) || \
+ ((FLAG) == SPI_FLAG_MODF) || ((FLAG) == SPI_FLAG_CRCERR) || \
+ ((FLAG) == I2S_FLAG_UDR) || ((FLAG) == I2S_FLAG_CHSIDE) || \
+ ((FLAG) == SPI_I2S_FLAG_TXE) || ((FLAG) == SPI_I2S_FLAG_RXNE)|| \
+ ((FLAG) == SPI_I2S_FLAG_TIFRFE))
+/**
+ * @}
+ */
+
+/** @defgroup SPI_CRC_polynomial
+ * @{
+ */
+
+#define IS_SPI_CRC_POLYNOMIAL(POLYNOMIAL) ((POLYNOMIAL) >= 0x1)
+/**
+ * @}
+ */
+
+/** @defgroup SPI_I2S_Legacy
+ * @{
+ */
+
+#define SPI_DMAReq_Tx SPI_I2S_DMAReq_Tx
+#define SPI_DMAReq_Rx SPI_I2S_DMAReq_Rx
+#define SPI_IT_TXE SPI_I2S_IT_TXE
+#define SPI_IT_RXNE SPI_I2S_IT_RXNE
+#define SPI_IT_ERR SPI_I2S_IT_ERR
+#define SPI_IT_OVR SPI_I2S_IT_OVR
+#define SPI_FLAG_RXNE SPI_I2S_FLAG_RXNE
+#define SPI_FLAG_TXE SPI_I2S_FLAG_TXE
+#define SPI_FLAG_OVR SPI_I2S_FLAG_OVR
+#define SPI_FLAG_BSY SPI_I2S_FLAG_BSY
+#define SPI_DeInit SPI_I2S_DeInit
+#define SPI_ITConfig SPI_I2S_ITConfig
+#define SPI_DMACmd SPI_I2S_DMACmd
+#define SPI_SendData SPI_I2S_SendData
+#define SPI_ReceiveData SPI_I2S_ReceiveData
+#define SPI_GetFlagStatus SPI_I2S_GetFlagStatus
+#define SPI_ClearFlag SPI_I2S_ClearFlag
+#define SPI_GetITStatus SPI_I2S_GetITStatus
+#define SPI_ClearITPendingBit SPI_I2S_ClearITPendingBit
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions --------------------------------------------------------*/
+
+/* Function used to set the SPI configuration to the default reset state *****/
+void SPI_I2S_DeInit(SPI_TypeDef* SPIx);
+
+/* Initialization and Configuration functions *********************************/
+void SPI_Init(SPI_TypeDef* SPIx, SPI_InitTypeDef* SPI_InitStruct);
+void I2S_Init(SPI_TypeDef* SPIx, I2S_InitTypeDef* I2S_InitStruct);
+void SPI_StructInit(SPI_InitTypeDef* SPI_InitStruct);
+void I2S_StructInit(I2S_InitTypeDef* I2S_InitStruct);
+void SPI_Cmd(SPI_TypeDef* SPIx, FunctionalState NewState);
+void I2S_Cmd(SPI_TypeDef* SPIx, FunctionalState NewState);
+void SPI_DataSizeConfig(SPI_TypeDef* SPIx, uint16_t SPI_DataSize);
+void SPI_BiDirectionalLineConfig(SPI_TypeDef* SPIx, uint16_t SPI_Direction);
+void SPI_NSSInternalSoftwareConfig(SPI_TypeDef* SPIx, uint16_t SPI_NSSInternalSoft);
+void SPI_SSOutputCmd(SPI_TypeDef* SPIx, FunctionalState NewState);
+void SPI_TIModeCmd(SPI_TypeDef* SPIx, FunctionalState NewState);
+
+/* Data transfers functions ***************************************************/
+void SPI_I2S_SendData(SPI_TypeDef* SPIx, uint16_t Data);
+uint16_t SPI_I2S_ReceiveData(SPI_TypeDef* SPIx);
+
+/* Hardware CRC Calculation functions *****************************************/
+void SPI_CalculateCRC(SPI_TypeDef* SPIx, FunctionalState NewState);
+void SPI_TransmitCRC(SPI_TypeDef* SPIx);
+uint16_t SPI_GetCRC(SPI_TypeDef* SPIx, uint8_t SPI_CRC);
+uint16_t SPI_GetCRCPolynomial(SPI_TypeDef* SPIx);
+
+/* DMA transfers management functions *****************************************/
+void SPI_I2S_DMACmd(SPI_TypeDef* SPIx, uint16_t SPI_I2S_DMAReq, FunctionalState NewState);
+
+/* Interrupts and flags management functions **********************************/
+void SPI_I2S_ITConfig(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT, FunctionalState NewState);
+FlagStatus SPI_I2S_GetFlagStatus(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG);
+void SPI_I2S_ClearFlag(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG);
+ITStatus SPI_I2S_GetITStatus(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT);
+void SPI_I2S_ClearITPendingBit(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*__STM32F2xx_SPI_H */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/inc/stm32f2xx_syscfg.h b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/inc/stm32f2xx_syscfg.h
new file mode 100644
index 0000000..de6f3a0
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/inc/stm32f2xx_syscfg.h
@@ -0,0 +1,179 @@
+/**
+ ******************************************************************************
+ * @file stm32f2xx_syscfg.h
+ * @author MCD Application Team
+ * @version V1.1.2
+ * @date 05-March-2012
+ * @brief This file contains all the functions prototypes for the SYSCFG firmware
+ * 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 __STM32F2xx_SYSCFG_H
+#define __STM32F2xx_SYSCFG_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f2xx.h"
+
+/** @addtogroup STM32F2xx_StdPeriph_Driver
+ * @{
+ */
+
+/** @addtogroup SYSCFG
+ * @{
+ */
+
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+
+/** @defgroup SYSCFG_Exported_Constants
+ * @{
+ */
+
+/** @defgroup SYSCFG_EXTI_Port_Sources
+ * @{
+ */
+#define EXTI_PortSourceGPIOA ((uint8_t)0x00)
+#define EXTI_PortSourceGPIOB ((uint8_t)0x01)
+#define EXTI_PortSourceGPIOC ((uint8_t)0x02)
+#define EXTI_PortSourceGPIOD ((uint8_t)0x03)
+#define EXTI_PortSourceGPIOE ((uint8_t)0x04)
+#define EXTI_PortSourceGPIOF ((uint8_t)0x05)
+#define EXTI_PortSourceGPIOG ((uint8_t)0x06)
+#define EXTI_PortSourceGPIOH ((uint8_t)0x07)
+#define EXTI_PortSourceGPIOI ((uint8_t)0x08)
+
+#define IS_EXTI_PORT_SOURCE(PORTSOURCE) (((PORTSOURCE) == EXTI_PortSourceGPIOA) || \
+ ((PORTSOURCE) == EXTI_PortSourceGPIOB) || \
+ ((PORTSOURCE) == EXTI_PortSourceGPIOC) || \
+ ((PORTSOURCE) == EXTI_PortSourceGPIOD) || \
+ ((PORTSOURCE) == EXTI_PortSourceGPIOE) || \
+ ((PORTSOURCE) == EXTI_PortSourceGPIOF) || \
+ ((PORTSOURCE) == EXTI_PortSourceGPIOG) || \
+ ((PORTSOURCE) == EXTI_PortSourceGPIOH) || \
+ ((PORTSOURCE) == EXTI_PortSourceGPIOI))
+/**
+ * @}
+ */
+
+
+/** @defgroup SYSCFG_EXTI_Pin_Sources
+ * @{
+ */
+#define EXTI_PinSource0 ((uint8_t)0x00)
+#define EXTI_PinSource1 ((uint8_t)0x01)
+#define EXTI_PinSource2 ((uint8_t)0x02)
+#define EXTI_PinSource3 ((uint8_t)0x03)
+#define EXTI_PinSource4 ((uint8_t)0x04)
+#define EXTI_PinSource5 ((uint8_t)0x05)
+#define EXTI_PinSource6 ((uint8_t)0x06)
+#define EXTI_PinSource7 ((uint8_t)0x07)
+#define EXTI_PinSource8 ((uint8_t)0x08)
+#define EXTI_PinSource9 ((uint8_t)0x09)
+#define EXTI_PinSource10 ((uint8_t)0x0A)
+#define EXTI_PinSource11 ((uint8_t)0x0B)
+#define EXTI_PinSource12 ((uint8_t)0x0C)
+#define EXTI_PinSource13 ((uint8_t)0x0D)
+#define EXTI_PinSource14 ((uint8_t)0x0E)
+#define EXTI_PinSource15 ((uint8_t)0x0F)
+#define IS_EXTI_PIN_SOURCE(PINSOURCE) (((PINSOURCE) == EXTI_PinSource0) || \
+ ((PINSOURCE) == EXTI_PinSource1) || \
+ ((PINSOURCE) == EXTI_PinSource2) || \
+ ((PINSOURCE) == EXTI_PinSource3) || \
+ ((PINSOURCE) == EXTI_PinSource4) || \
+ ((PINSOURCE) == EXTI_PinSource5) || \
+ ((PINSOURCE) == EXTI_PinSource6) || \
+ ((PINSOURCE) == EXTI_PinSource7) || \
+ ((PINSOURCE) == EXTI_PinSource8) || \
+ ((PINSOURCE) == EXTI_PinSource9) || \
+ ((PINSOURCE) == EXTI_PinSource10) || \
+ ((PINSOURCE) == EXTI_PinSource11) || \
+ ((PINSOURCE) == EXTI_PinSource12) || \
+ ((PINSOURCE) == EXTI_PinSource13) || \
+ ((PINSOURCE) == EXTI_PinSource14) || \
+ ((PINSOURCE) == EXTI_PinSource15))
+/**
+ * @}
+ */
+
+
+/** @defgroup SYSCFG_Memory_Remap_Config
+ * @{
+ */
+#define SYSCFG_MemoryRemap_Flash ((uint8_t)0x00)
+#define SYSCFG_MemoryRemap_SystemFlash ((uint8_t)0x01)
+#define SYSCFG_MemoryRemap_FSMC ((uint8_t)0x02)
+#define SYSCFG_MemoryRemap_SRAM ((uint8_t)0x03)
+
+#define IS_SYSCFG_MEMORY_REMAP_CONFING(REMAP) (((REMAP) == SYSCFG_MemoryRemap_Flash) || \
+ ((REMAP) == SYSCFG_MemoryRemap_SystemFlash) || \
+ ((REMAP) == SYSCFG_MemoryRemap_SRAM) || \
+ ((REMAP) == SYSCFG_MemoryRemap_FSMC))
+/**
+ * @}
+ */
+
+
+/** @defgroup SYSCFG_ETHERNET_Media_Interface
+ * @{
+ */
+#define SYSCFG_ETH_MediaInterface_MII ((uint32_t)0x00000000)
+#define SYSCFG_ETH_MediaInterface_RMII ((uint32_t)0x00000001)
+
+#define IS_SYSCFG_ETH_MEDIA_INTERFACE(INTERFACE) (((INTERFACE) == SYSCFG_ETH_MediaInterface_MII) || \
+ ((INTERFACE) == SYSCFG_ETH_MediaInterface_RMII))
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions --------------------------------------------------------*/
+
+void SYSCFG_DeInit(void);
+void SYSCFG_MemoryRemapConfig(uint8_t SYSCFG_MemoryRemap);
+void SYSCFG_EXTILineConfig(uint8_t EXTI_PortSourceGPIOx, uint8_t EXTI_PinSourcex);
+void SYSCFG_ETH_MediaInterfaceConfig(uint32_t SYSCFG_ETH_MediaInterface);
+void SYSCFG_CompensationCellCmd(FunctionalState NewState);
+FlagStatus SYSCFG_GetCompensationCellStatus(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*__STM32F2xx_SYSCFG_H */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/inc/stm32f2xx_tim.h b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/inc/stm32f2xx_tim.h
new file mode 100644
index 0000000..2c48f2a
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/inc/stm32f2xx_tim.h
@@ -0,0 +1,1150 @@
+/**
+ ******************************************************************************
+ * @file stm32f2xx_tim.h
+ * @author MCD Application Team
+ * @version V1.1.2
+ * @date 05-March-2012
+ * @brief This file contains all the functions prototypes for the TIM firmware
+ * 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 __STM32F2xx_TIM_H
+#define __STM32F2xx_TIM_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f2xx.h"
+
+/** @addtogroup STM32F2xx_StdPeriph_Driver
+ * @{
+ */
+
+/** @addtogroup TIM
+ * @{
+ */
+
+/* Exported types ------------------------------------------------------------*/
+
+/**
+ * @brief TIM Time Base Init structure definition
+ * @note This structure is used with all TIMx except for TIM6 and TIM7.
+ */
+
+typedef struct
+{
+ uint16_t TIM_Prescaler; /*!< Specifies the prescaler value used to divide the TIM clock.
+ This parameter can be a number between 0x0000 and 0xFFFF */
+
+ uint16_t TIM_CounterMode; /*!< Specifies the counter mode.
+ This parameter can be a value of @ref TIM_Counter_Mode */
+
+ uint32_t TIM_Period; /*!< Specifies the period value to be loaded into the active
+ Auto-Reload Register at the next update event.
+ This parameter must be a number between 0x0000 and 0xFFFF. */
+
+ uint16_t TIM_ClockDivision; /*!< Specifies the clock division.
+ This parameter can be a value of @ref TIM_Clock_Division_CKD */
+
+ uint8_t TIM_RepetitionCounter; /*!< Specifies the repetition counter value. Each time the RCR downcounter
+ reaches zero, an update event is generated and counting restarts
+ from the RCR value (N).
+ This means in PWM mode that (N+1) corresponds to:
+ - the number of PWM periods in edge-aligned mode
+ - the number of half PWM period in center-aligned mode
+ This parameter must be a number between 0x00 and 0xFF.
+ @note This parameter is valid only for TIM1 and TIM8. */
+} TIM_TimeBaseInitTypeDef;
+
+/**
+ * @brief TIM Output Compare Init structure definition
+ */
+
+typedef struct
+{
+ uint16_t TIM_OCMode; /*!< Specifies the TIM mode.
+ This parameter can be a value of @ref TIM_Output_Compare_and_PWM_modes */
+
+ uint16_t TIM_OutputState; /*!< Specifies the TIM Output Compare state.
+ This parameter can be a value of @ref TIM_Output_Compare_State */
+
+ uint16_t TIM_OutputNState; /*!< Specifies the TIM complementary Output Compare state.
+ This parameter can be a value of @ref TIM_Output_Compare_N_State
+ @note This parameter is valid only for TIM1 and TIM8. */
+
+ uint32_t TIM_Pulse; /*!< Specifies the pulse value to be loaded into the Capture Compare Register.
+ This parameter can be a number between 0x0000 and 0xFFFF */
+
+ uint16_t TIM_OCPolarity; /*!< Specifies the output polarity.
+ This parameter can be a value of @ref TIM_Output_Compare_Polarity */
+
+ uint16_t TIM_OCNPolarity; /*!< Specifies the complementary output polarity.
+ This parameter can be a value of @ref TIM_Output_Compare_N_Polarity
+ @note This parameter is valid only for TIM1 and TIM8. */
+
+ uint16_t TIM_OCIdleState; /*!< Specifies the TIM Output Compare pin state during Idle state.
+ This parameter can be a value of @ref TIM_Output_Compare_Idle_State
+ @note This parameter is valid only for TIM1 and TIM8. */
+
+ uint16_t TIM_OCNIdleState; /*!< Specifies the TIM Output Compare pin state during Idle state.
+ This parameter can be a value of @ref TIM_Output_Compare_N_Idle_State
+ @note This parameter is valid only for TIM1 and TIM8. */
+} TIM_OCInitTypeDef;
+
+/**
+ * @brief TIM Input Capture Init structure definition
+ */
+
+typedef struct
+{
+
+ uint16_t TIM_Channel; /*!< Specifies the TIM channel.
+ This parameter can be a value of @ref TIM_Channel */
+
+ uint16_t TIM_ICPolarity; /*!< Specifies the active edge of the input signal.
+ This parameter can be a value of @ref TIM_Input_Capture_Polarity */
+
+ uint16_t TIM_ICSelection; /*!< Specifies the input.
+ This parameter can be a value of @ref TIM_Input_Capture_Selection */
+
+ uint16_t TIM_ICPrescaler; /*!< Specifies the Input Capture Prescaler.
+ This parameter can be a value of @ref TIM_Input_Capture_Prescaler */
+
+ uint16_t TIM_ICFilter; /*!< Specifies the input capture filter.
+ This parameter can be a number between 0x0 and 0xF */
+} TIM_ICInitTypeDef;
+
+/**
+ * @brief BDTR structure definition
+ * @note This structure is used only with TIM1 and TIM8.
+ */
+
+typedef struct
+{
+
+ uint16_t TIM_OSSRState; /*!< Specifies the Off-State selection used in Run mode.
+ This parameter can be a value of @ref TIM_OSSR_Off_State_Selection_for_Run_mode_state */
+
+ uint16_t TIM_OSSIState; /*!< Specifies the Off-State used in Idle state.
+ This parameter can be a value of @ref TIM_OSSI_Off_State_Selection_for_Idle_mode_state */
+
+ uint16_t TIM_LOCKLevel; /*!< Specifies the LOCK level parameters.
+ This parameter can be a value of @ref TIM_Lock_level */
+
+ uint16_t TIM_DeadTime; /*!< Specifies the delay time between the switching-off and the
+ switching-on of the outputs.
+ This parameter can be a number between 0x00 and 0xFF */
+
+ uint16_t TIM_Break; /*!< Specifies whether the TIM Break input is enabled or not.
+ This parameter can be a value of @ref TIM_Break_Input_enable_disable */
+
+ uint16_t TIM_BreakPolarity; /*!< Specifies the TIM Break Input pin polarity.
+ This parameter can be a value of @ref TIM_Break_Polarity */
+
+ uint16_t TIM_AutomaticOutput; /*!< Specifies whether the TIM Automatic Output feature is enabled or not.
+ This parameter can be a value of @ref TIM_AOE_Bit_Set_Reset */
+} TIM_BDTRInitTypeDef;
+
+/* Exported constants --------------------------------------------------------*/
+
+/** @defgroup TIM_Exported_constants
+ * @{
+ */
+
+#define IS_TIM_ALL_PERIPH(PERIPH) (((PERIPH) == TIM1) || \
+ ((PERIPH) == TIM2) || \
+ ((PERIPH) == TIM3) || \
+ ((PERIPH) == TIM4) || \
+ ((PERIPH) == TIM5) || \
+ ((PERIPH) == TIM6) || \
+ ((PERIPH) == TIM7) || \
+ ((PERIPH) == TIM8) || \
+ ((PERIPH) == TIM9) || \
+ ((PERIPH) == TIM10) || \
+ ((PERIPH) == TIM11) || \
+ ((PERIPH) == TIM12) || \
+ (((PERIPH) == TIM13) || \
+ ((PERIPH) == TIM14)))
+/* LIST1: TIM1, TIM2, TIM3, TIM4, TIM5, TIM8, TIM9, TIM10, TIM11, TIM12, TIM13 and TIM14 */
+#define IS_TIM_LIST1_PERIPH(PERIPH) (((PERIPH) == TIM1) || \
+ ((PERIPH) == TIM2) || \
+ ((PERIPH) == TIM3) || \
+ ((PERIPH) == TIM4) || \
+ ((PERIPH) == TIM5) || \
+ ((PERIPH) == TIM8) || \
+ ((PERIPH) == TIM9) || \
+ ((PERIPH) == TIM10) || \
+ ((PERIPH) == TIM11) || \
+ ((PERIPH) == TIM12) || \
+ ((PERIPH) == TIM13) || \
+ ((PERIPH) == TIM14))
+
+/* LIST2: TIM1, TIM2, TIM3, TIM4, TIM5, TIM8, TIM9 and TIM12 */
+#define IS_TIM_LIST2_PERIPH(PERIPH) (((PERIPH) == TIM1) || \
+ ((PERIPH) == TIM2) || \
+ ((PERIPH) == TIM3) || \
+ ((PERIPH) == TIM4) || \
+ ((PERIPH) == TIM5) || \
+ ((PERIPH) == TIM8) || \
+ ((PERIPH) == TIM9) || \
+ ((PERIPH) == TIM12))
+/* LIST3: TIM1, TIM2, TIM3, TIM4, TIM5 and TIM8 */
+#define IS_TIM_LIST3_PERIPH(PERIPH) (((PERIPH) == TIM1) || \
+ ((PERIPH) == TIM2) || \
+ ((PERIPH) == TIM3) || \
+ ((PERIPH) == TIM4) || \
+ ((PERIPH) == TIM5) || \
+ ((PERIPH) == TIM8))
+/* LIST4: TIM1 and TIM8 */
+#define IS_TIM_LIST4_PERIPH(PERIPH) (((PERIPH) == TIM1) || \
+ ((PERIPH) == TIM8))
+/* LIST5: TIM1, TIM2, TIM3, TIM4, TIM5, TIM6, TIM7 and TIM8 */
+#define IS_TIM_LIST5_PERIPH(PERIPH) (((PERIPH) == TIM1) || \
+ ((PERIPH) == TIM2) || \
+ ((PERIPH) == TIM3) || \
+ ((PERIPH) == TIM4) || \
+ ((PERIPH) == TIM5) || \
+ ((PERIPH) == TIM6) || \
+ ((PERIPH) == TIM7) || \
+ ((PERIPH) == TIM8))
+/* LIST6: TIM2, TIM5 and TIM11 */
+#define IS_TIM_LIST6_PERIPH(TIMx)(((TIMx) == TIM2) || \
+ ((TIMx) == TIM5) || \
+ ((TIMx) == TIM11))
+
+/** @defgroup TIM_Output_Compare_and_PWM_modes
+ * @{
+ */
+
+#define TIM_OCMode_Timing ((uint16_t)0x0000)
+#define TIM_OCMode_Active ((uint16_t)0x0010)
+#define TIM_OCMode_Inactive ((uint16_t)0x0020)
+#define TIM_OCMode_Toggle ((uint16_t)0x0030)
+#define TIM_OCMode_PWM1 ((uint16_t)0x0060)
+#define TIM_OCMode_PWM2 ((uint16_t)0x0070)
+#define IS_TIM_OC_MODE(MODE) (((MODE) == TIM_OCMode_Timing) || \
+ ((MODE) == TIM_OCMode_Active) || \
+ ((MODE) == TIM_OCMode_Inactive) || \
+ ((MODE) == TIM_OCMode_Toggle)|| \
+ ((MODE) == TIM_OCMode_PWM1) || \
+ ((MODE) == TIM_OCMode_PWM2))
+#define IS_TIM_OCM(MODE) (((MODE) == TIM_OCMode_Timing) || \
+ ((MODE) == TIM_OCMode_Active) || \
+ ((MODE) == TIM_OCMode_Inactive) || \
+ ((MODE) == TIM_OCMode_Toggle)|| \
+ ((MODE) == TIM_OCMode_PWM1) || \
+ ((MODE) == TIM_OCMode_PWM2) || \
+ ((MODE) == TIM_ForcedAction_Active) || \
+ ((MODE) == TIM_ForcedAction_InActive))
+/**
+ * @}
+ */
+
+/** @defgroup TIM_One_Pulse_Mode
+ * @{
+ */
+
+#define TIM_OPMode_Single ((uint16_t)0x0008)
+#define TIM_OPMode_Repetitive ((uint16_t)0x0000)
+#define IS_TIM_OPM_MODE(MODE) (((MODE) == TIM_OPMode_Single) || \
+ ((MODE) == TIM_OPMode_Repetitive))
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Channel
+ * @{
+ */
+
+#define TIM_Channel_1 ((uint16_t)0x0000)
+#define TIM_Channel_2 ((uint16_t)0x0004)
+#define TIM_Channel_3 ((uint16_t)0x0008)
+#define TIM_Channel_4 ((uint16_t)0x000C)
+
+#define IS_TIM_CHANNEL(CHANNEL) (((CHANNEL) == TIM_Channel_1) || \
+ ((CHANNEL) == TIM_Channel_2) || \
+ ((CHANNEL) == TIM_Channel_3) || \
+ ((CHANNEL) == TIM_Channel_4))
+
+#define IS_TIM_PWMI_CHANNEL(CHANNEL) (((CHANNEL) == TIM_Channel_1) || \
+ ((CHANNEL) == TIM_Channel_2))
+#define IS_TIM_COMPLEMENTARY_CHANNEL(CHANNEL) (((CHANNEL) == TIM_Channel_1) || \
+ ((CHANNEL) == TIM_Channel_2) || \
+ ((CHANNEL) == TIM_Channel_3))
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Clock_Division_CKD
+ * @{
+ */
+
+#define TIM_CKD_DIV1 ((uint16_t)0x0000)
+#define TIM_CKD_DIV2 ((uint16_t)0x0100)
+#define TIM_CKD_DIV4 ((uint16_t)0x0200)
+#define IS_TIM_CKD_DIV(DIV) (((DIV) == TIM_CKD_DIV1) || \
+ ((DIV) == TIM_CKD_DIV2) || \
+ ((DIV) == TIM_CKD_DIV4))
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Counter_Mode
+ * @{
+ */
+
+#define TIM_CounterMode_Up ((uint16_t)0x0000)
+#define TIM_CounterMode_Down ((uint16_t)0x0010)
+#define TIM_CounterMode_CenterAligned1 ((uint16_t)0x0020)
+#define TIM_CounterMode_CenterAligned2 ((uint16_t)0x0040)
+#define TIM_CounterMode_CenterAligned3 ((uint16_t)0x0060)
+#define IS_TIM_COUNTER_MODE(MODE) (((MODE) == TIM_CounterMode_Up) || \
+ ((MODE) == TIM_CounterMode_Down) || \
+ ((MODE) == TIM_CounterMode_CenterAligned1) || \
+ ((MODE) == TIM_CounterMode_CenterAligned2) || \
+ ((MODE) == TIM_CounterMode_CenterAligned3))
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Output_Compare_Polarity
+ * @{
+ */
+
+#define TIM_OCPolarity_High ((uint16_t)0x0000)
+#define TIM_OCPolarity_Low ((uint16_t)0x0002)
+#define IS_TIM_OC_POLARITY(POLARITY) (((POLARITY) == TIM_OCPolarity_High) || \
+ ((POLARITY) == TIM_OCPolarity_Low))
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Output_Compare_N_Polarity
+ * @{
+ */
+
+#define TIM_OCNPolarity_High ((uint16_t)0x0000)
+#define TIM_OCNPolarity_Low ((uint16_t)0x0008)
+#define IS_TIM_OCN_POLARITY(POLARITY) (((POLARITY) == TIM_OCNPolarity_High) || \
+ ((POLARITY) == TIM_OCNPolarity_Low))
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Output_Compare_State
+ * @{
+ */
+
+#define TIM_OutputState_Disable ((uint16_t)0x0000)
+#define TIM_OutputState_Enable ((uint16_t)0x0001)
+#define IS_TIM_OUTPUT_STATE(STATE) (((STATE) == TIM_OutputState_Disable) || \
+ ((STATE) == TIM_OutputState_Enable))
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Output_Compare_N_State
+ * @{
+ */
+
+#define TIM_OutputNState_Disable ((uint16_t)0x0000)
+#define TIM_OutputNState_Enable ((uint16_t)0x0004)
+#define IS_TIM_OUTPUTN_STATE(STATE) (((STATE) == TIM_OutputNState_Disable) || \
+ ((STATE) == TIM_OutputNState_Enable))
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Capture_Compare_State
+ * @{
+ */
+
+#define TIM_CCx_Enable ((uint16_t)0x0001)
+#define TIM_CCx_Disable ((uint16_t)0x0000)
+#define IS_TIM_CCX(CCX) (((CCX) == TIM_CCx_Enable) || \
+ ((CCX) == TIM_CCx_Disable))
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Capture_Compare_N_State
+ * @{
+ */
+
+#define TIM_CCxN_Enable ((uint16_t)0x0004)
+#define TIM_CCxN_Disable ((uint16_t)0x0000)
+#define IS_TIM_CCXN(CCXN) (((CCXN) == TIM_CCxN_Enable) || \
+ ((CCXN) == TIM_CCxN_Disable))
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Break_Input_enable_disable
+ * @{
+ */
+
+#define TIM_Break_Enable ((uint16_t)0x1000)
+#define TIM_Break_Disable ((uint16_t)0x0000)
+#define IS_TIM_BREAK_STATE(STATE) (((STATE) == TIM_Break_Enable) || \
+ ((STATE) == TIM_Break_Disable))
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Break_Polarity
+ * @{
+ */
+
+#define TIM_BreakPolarity_Low ((uint16_t)0x0000)
+#define TIM_BreakPolarity_High ((uint16_t)0x2000)
+#define IS_TIM_BREAK_POLARITY(POLARITY) (((POLARITY) == TIM_BreakPolarity_Low) || \
+ ((POLARITY) == TIM_BreakPolarity_High))
+/**
+ * @}
+ */
+
+/** @defgroup TIM_AOE_Bit_Set_Reset
+ * @{
+ */
+
+#define TIM_AutomaticOutput_Enable ((uint16_t)0x4000)
+#define TIM_AutomaticOutput_Disable ((uint16_t)0x0000)
+#define IS_TIM_AUTOMATIC_OUTPUT_STATE(STATE) (((STATE) == TIM_AutomaticOutput_Enable) || \
+ ((STATE) == TIM_AutomaticOutput_Disable))
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Lock_level
+ * @{
+ */
+
+#define TIM_LOCKLevel_OFF ((uint16_t)0x0000)
+#define TIM_LOCKLevel_1 ((uint16_t)0x0100)
+#define TIM_LOCKLevel_2 ((uint16_t)0x0200)
+#define TIM_LOCKLevel_3 ((uint16_t)0x0300)
+#define IS_TIM_LOCK_LEVEL(LEVEL) (((LEVEL) == TIM_LOCKLevel_OFF) || \
+ ((LEVEL) == TIM_LOCKLevel_1) || \
+ ((LEVEL) == TIM_LOCKLevel_2) || \
+ ((LEVEL) == TIM_LOCKLevel_3))
+/**
+ * @}
+ */
+
+/** @defgroup TIM_OSSI_Off_State_Selection_for_Idle_mode_state
+ * @{
+ */
+
+#define TIM_OSSIState_Enable ((uint16_t)0x0400)
+#define TIM_OSSIState_Disable ((uint16_t)0x0000)
+#define IS_TIM_OSSI_STATE(STATE) (((STATE) == TIM_OSSIState_Enable) || \
+ ((STATE) == TIM_OSSIState_Disable))
+/**
+ * @}
+ */
+
+/** @defgroup TIM_OSSR_Off_State_Selection_for_Run_mode_state
+ * @{
+ */
+
+#define TIM_OSSRState_Enable ((uint16_t)0x0800)
+#define TIM_OSSRState_Disable ((uint16_t)0x0000)
+#define IS_TIM_OSSR_STATE(STATE) (((STATE) == TIM_OSSRState_Enable) || \
+ ((STATE) == TIM_OSSRState_Disable))
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Output_Compare_Idle_State
+ * @{
+ */
+
+#define TIM_OCIdleState_Set ((uint16_t)0x0100)
+#define TIM_OCIdleState_Reset ((uint16_t)0x0000)
+#define IS_TIM_OCIDLE_STATE(STATE) (((STATE) == TIM_OCIdleState_Set) || \
+ ((STATE) == TIM_OCIdleState_Reset))
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Output_Compare_N_Idle_State
+ * @{
+ */
+
+#define TIM_OCNIdleState_Set ((uint16_t)0x0200)
+#define TIM_OCNIdleState_Reset ((uint16_t)0x0000)
+#define IS_TIM_OCNIDLE_STATE(STATE) (((STATE) == TIM_OCNIdleState_Set) || \
+ ((STATE) == TIM_OCNIdleState_Reset))
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Input_Capture_Polarity
+ * @{
+ */
+
+#define TIM_ICPolarity_Rising ((uint16_t)0x0000)
+#define TIM_ICPolarity_Falling ((uint16_t)0x0002)
+#define TIM_ICPolarity_BothEdge ((uint16_t)0x000A)
+#define IS_TIM_IC_POLARITY(POLARITY) (((POLARITY) == TIM_ICPolarity_Rising) || \
+ ((POLARITY) == TIM_ICPolarity_Falling)|| \
+ ((POLARITY) == TIM_ICPolarity_BothEdge))
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Input_Capture_Selection
+ * @{
+ */
+
+#define TIM_ICSelection_DirectTI ((uint16_t)0x0001) /*!< TIM Input 1, 2, 3 or 4 is selected to be
+ connected to IC1, IC2, IC3 or IC4, respectively */
+#define TIM_ICSelection_IndirectTI ((uint16_t)0x0002) /*!< TIM Input 1, 2, 3 or 4 is selected to be
+ connected to IC2, IC1, IC4 or IC3, respectively. */
+#define TIM_ICSelection_TRC ((uint16_t)0x0003) /*!< TIM Input 1, 2, 3 or 4 is selected to be connected to TRC. */
+#define IS_TIM_IC_SELECTION(SELECTION) (((SELECTION) == TIM_ICSelection_DirectTI) || \
+ ((SELECTION) == TIM_ICSelection_IndirectTI) || \
+ ((SELECTION) == TIM_ICSelection_TRC))
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Input_Capture_Prescaler
+ * @{
+ */
+
+#define TIM_ICPSC_DIV1 ((uint16_t)0x0000) /*!< Capture performed each time an edge is detected on the capture input. */
+#define TIM_ICPSC_DIV2 ((uint16_t)0x0004) /*!< Capture performed once every 2 events. */
+#define TIM_ICPSC_DIV4 ((uint16_t)0x0008) /*!< Capture performed once every 4 events. */
+#define TIM_ICPSC_DIV8 ((uint16_t)0x000C) /*!< Capture performed once every 8 events. */
+#define IS_TIM_IC_PRESCALER(PRESCALER) (((PRESCALER) == TIM_ICPSC_DIV1) || \
+ ((PRESCALER) == TIM_ICPSC_DIV2) || \
+ ((PRESCALER) == TIM_ICPSC_DIV4) || \
+ ((PRESCALER) == TIM_ICPSC_DIV8))
+/**
+ * @}
+ */
+
+/** @defgroup TIM_interrupt_sources
+ * @{
+ */
+
+#define TIM_IT_Update ((uint16_t)0x0001)
+#define TIM_IT_CC1 ((uint16_t)0x0002)
+#define TIM_IT_CC2 ((uint16_t)0x0004)
+#define TIM_IT_CC3 ((uint16_t)0x0008)
+#define TIM_IT_CC4 ((uint16_t)0x0010)
+#define TIM_IT_COM ((uint16_t)0x0020)
+#define TIM_IT_Trigger ((uint16_t)0x0040)
+#define TIM_IT_Break ((uint16_t)0x0080)
+#define IS_TIM_IT(IT) ((((IT) & (uint16_t)0xFF00) == 0x0000) && ((IT) != 0x0000))
+
+#define IS_TIM_GET_IT(IT) (((IT) == TIM_IT_Update) || \
+ ((IT) == TIM_IT_CC1) || \
+ ((IT) == TIM_IT_CC2) || \
+ ((IT) == TIM_IT_CC3) || \
+ ((IT) == TIM_IT_CC4) || \
+ ((IT) == TIM_IT_COM) || \
+ ((IT) == TIM_IT_Trigger) || \
+ ((IT) == TIM_IT_Break))
+/**
+ * @}
+ */
+
+/** @defgroup TIM_DMA_Base_address
+ * @{
+ */
+
+#define TIM_DMABase_CR1 ((uint16_t)0x0000)
+#define TIM_DMABase_CR2 ((uint16_t)0x0001)
+#define TIM_DMABase_SMCR ((uint16_t)0x0002)
+#define TIM_DMABase_DIER ((uint16_t)0x0003)
+#define TIM_DMABase_SR ((uint16_t)0x0004)
+#define TIM_DMABase_EGR ((uint16_t)0x0005)
+#define TIM_DMABase_CCMR1 ((uint16_t)0x0006)
+#define TIM_DMABase_CCMR2 ((uint16_t)0x0007)
+#define TIM_DMABase_CCER ((uint16_t)0x0008)
+#define TIM_DMABase_CNT ((uint16_t)0x0009)
+#define TIM_DMABase_PSC ((uint16_t)0x000A)
+#define TIM_DMABase_ARR ((uint16_t)0x000B)
+#define TIM_DMABase_RCR ((uint16_t)0x000C)
+#define TIM_DMABase_CCR1 ((uint16_t)0x000D)
+#define TIM_DMABase_CCR2 ((uint16_t)0x000E)
+#define TIM_DMABase_CCR3 ((uint16_t)0x000F)
+#define TIM_DMABase_CCR4 ((uint16_t)0x0010)
+#define TIM_DMABase_BDTR ((uint16_t)0x0011)
+#define TIM_DMABase_DCR ((uint16_t)0x0012)
+#define TIM_DMABase_OR ((uint16_t)0x0013)
+#define IS_TIM_DMA_BASE(BASE) (((BASE) == TIM_DMABase_CR1) || \
+ ((BASE) == TIM_DMABase_CR2) || \
+ ((BASE) == TIM_DMABase_SMCR) || \
+ ((BASE) == TIM_DMABase_DIER) || \
+ ((BASE) == TIM_DMABase_SR) || \
+ ((BASE) == TIM_DMABase_EGR) || \
+ ((BASE) == TIM_DMABase_CCMR1) || \
+ ((BASE) == TIM_DMABase_CCMR2) || \
+ ((BASE) == TIM_DMABase_CCER) || \
+ ((BASE) == TIM_DMABase_CNT) || \
+ ((BASE) == TIM_DMABase_PSC) || \
+ ((BASE) == TIM_DMABase_ARR) || \
+ ((BASE) == TIM_DMABase_RCR) || \
+ ((BASE) == TIM_DMABase_CCR1) || \
+ ((BASE) == TIM_DMABase_CCR2) || \
+ ((BASE) == TIM_DMABase_CCR3) || \
+ ((BASE) == TIM_DMABase_CCR4) || \
+ ((BASE) == TIM_DMABase_BDTR) || \
+ ((BASE) == TIM_DMABase_DCR) || \
+ ((BASE) == TIM_DMABase_OR))
+/**
+ * @}
+ */
+
+/** @defgroup TIM_DMA_Burst_Length
+ * @{
+ */
+
+#define TIM_DMABurstLength_1Transfer ((uint16_t)0x0000)
+#define TIM_DMABurstLength_2Transfers ((uint16_t)0x0100)
+#define TIM_DMABurstLength_3Transfers ((uint16_t)0x0200)
+#define TIM_DMABurstLength_4Transfers ((uint16_t)0x0300)
+#define TIM_DMABurstLength_5Transfers ((uint16_t)0x0400)
+#define TIM_DMABurstLength_6Transfers ((uint16_t)0x0500)
+#define TIM_DMABurstLength_7Transfers ((uint16_t)0x0600)
+#define TIM_DMABurstLength_8Transfers ((uint16_t)0x0700)
+#define TIM_DMABurstLength_9Transfers ((uint16_t)0x0800)
+#define TIM_DMABurstLength_10Transfers ((uint16_t)0x0900)
+#define TIM_DMABurstLength_11Transfers ((uint16_t)0x0A00)
+#define TIM_DMABurstLength_12Transfers ((uint16_t)0x0B00)
+#define TIM_DMABurstLength_13Transfers ((uint16_t)0x0C00)
+#define TIM_DMABurstLength_14Transfers ((uint16_t)0x0D00)
+#define TIM_DMABurstLength_15Transfers ((uint16_t)0x0E00)
+#define TIM_DMABurstLength_16Transfers ((uint16_t)0x0F00)
+#define TIM_DMABurstLength_17Transfers ((uint16_t)0x1000)
+#define TIM_DMABurstLength_18Transfers ((uint16_t)0x1100)
+#define IS_TIM_DMA_LENGTH(LENGTH) (((LENGTH) == TIM_DMABurstLength_1Transfer) || \
+ ((LENGTH) == TIM_DMABurstLength_2Transfers) || \
+ ((LENGTH) == TIM_DMABurstLength_3Transfers) || \
+ ((LENGTH) == TIM_DMABurstLength_4Transfers) || \
+ ((LENGTH) == TIM_DMABurstLength_5Transfers) || \
+ ((LENGTH) == TIM_DMABurstLength_6Transfers) || \
+ ((LENGTH) == TIM_DMABurstLength_7Transfers) || \
+ ((LENGTH) == TIM_DMABurstLength_8Transfers) || \
+ ((LENGTH) == TIM_DMABurstLength_9Transfers) || \
+ ((LENGTH) == TIM_DMABurstLength_10Transfers) || \
+ ((LENGTH) == TIM_DMABurstLength_11Transfers) || \
+ ((LENGTH) == TIM_DMABurstLength_12Transfers) || \
+ ((LENGTH) == TIM_DMABurstLength_13Transfers) || \
+ ((LENGTH) == TIM_DMABurstLength_14Transfers) || \
+ ((LENGTH) == TIM_DMABurstLength_15Transfers) || \
+ ((LENGTH) == TIM_DMABurstLength_16Transfers) || \
+ ((LENGTH) == TIM_DMABurstLength_17Transfers) || \
+ ((LENGTH) == TIM_DMABurstLength_18Transfers))
+/**
+ * @}
+ */
+
+/** @defgroup TIM_DMA_sources
+ * @{
+ */
+
+#define TIM_DMA_Update ((uint16_t)0x0100)
+#define TIM_DMA_CC1 ((uint16_t)0x0200)
+#define TIM_DMA_CC2 ((uint16_t)0x0400)
+#define TIM_DMA_CC3 ((uint16_t)0x0800)
+#define TIM_DMA_CC4 ((uint16_t)0x1000)
+#define TIM_DMA_COM ((uint16_t)0x2000)
+#define TIM_DMA_Trigger ((uint16_t)0x4000)
+#define IS_TIM_DMA_SOURCE(SOURCE) ((((SOURCE) & (uint16_t)0x80FF) == 0x0000) && ((SOURCE) != 0x0000))
+
+/**
+ * @}
+ */
+
+/** @defgroup TIM_External_Trigger_Prescaler
+ * @{
+ */
+
+#define TIM_ExtTRGPSC_OFF ((uint16_t)0x0000)
+#define TIM_ExtTRGPSC_DIV2 ((uint16_t)0x1000)
+#define TIM_ExtTRGPSC_DIV4 ((uint16_t)0x2000)
+#define TIM_ExtTRGPSC_DIV8 ((uint16_t)0x3000)
+#define IS_TIM_EXT_PRESCALER(PRESCALER) (((PRESCALER) == TIM_ExtTRGPSC_OFF) || \
+ ((PRESCALER) == TIM_ExtTRGPSC_DIV2) || \
+ ((PRESCALER) == TIM_ExtTRGPSC_DIV4) || \
+ ((PRESCALER) == TIM_ExtTRGPSC_DIV8))
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Internal_Trigger_Selection
+ * @{
+ */
+
+#define TIM_TS_ITR0 ((uint16_t)0x0000)
+#define TIM_TS_ITR1 ((uint16_t)0x0010)
+#define TIM_TS_ITR2 ((uint16_t)0x0020)
+#define TIM_TS_ITR3 ((uint16_t)0x0030)
+#define TIM_TS_TI1F_ED ((uint16_t)0x0040)
+#define TIM_TS_TI1FP1 ((uint16_t)0x0050)
+#define TIM_TS_TI2FP2 ((uint16_t)0x0060)
+#define TIM_TS_ETRF ((uint16_t)0x0070)
+#define IS_TIM_TRIGGER_SELECTION(SELECTION) (((SELECTION) == TIM_TS_ITR0) || \
+ ((SELECTION) == TIM_TS_ITR1) || \
+ ((SELECTION) == TIM_TS_ITR2) || \
+ ((SELECTION) == TIM_TS_ITR3) || \
+ ((SELECTION) == TIM_TS_TI1F_ED) || \
+ ((SELECTION) == TIM_TS_TI1FP1) || \
+ ((SELECTION) == TIM_TS_TI2FP2) || \
+ ((SELECTION) == TIM_TS_ETRF))
+#define IS_TIM_INTERNAL_TRIGGER_SELECTION(SELECTION) (((SELECTION) == TIM_TS_ITR0) || \
+ ((SELECTION) == TIM_TS_ITR1) || \
+ ((SELECTION) == TIM_TS_ITR2) || \
+ ((SELECTION) == TIM_TS_ITR3))
+/**
+ * @}
+ */
+
+/** @defgroup TIM_TIx_External_Clock_Source
+ * @{
+ */
+
+#define TIM_TIxExternalCLK1Source_TI1 ((uint16_t)0x0050)
+#define TIM_TIxExternalCLK1Source_TI2 ((uint16_t)0x0060)
+#define TIM_TIxExternalCLK1Source_TI1ED ((uint16_t)0x0040)
+
+/**
+ * @}
+ */
+
+/** @defgroup TIM_External_Trigger_Polarity
+ * @{
+ */
+#define TIM_ExtTRGPolarity_Inverted ((uint16_t)0x8000)
+#define TIM_ExtTRGPolarity_NonInverted ((uint16_t)0x0000)
+#define IS_TIM_EXT_POLARITY(POLARITY) (((POLARITY) == TIM_ExtTRGPolarity_Inverted) || \
+ ((POLARITY) == TIM_ExtTRGPolarity_NonInverted))
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Prescaler_Reload_Mode
+ * @{
+ */
+
+#define TIM_PSCReloadMode_Update ((uint16_t)0x0000)
+#define TIM_PSCReloadMode_Immediate ((uint16_t)0x0001)
+#define IS_TIM_PRESCALER_RELOAD(RELOAD) (((RELOAD) == TIM_PSCReloadMode_Update) || \
+ ((RELOAD) == TIM_PSCReloadMode_Immediate))
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Forced_Action
+ * @{
+ */
+
+#define TIM_ForcedAction_Active ((uint16_t)0x0050)
+#define TIM_ForcedAction_InActive ((uint16_t)0x0040)
+#define IS_TIM_FORCED_ACTION(ACTION) (((ACTION) == TIM_ForcedAction_Active) || \
+ ((ACTION) == TIM_ForcedAction_InActive))
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Encoder_Mode
+ * @{
+ */
+
+#define TIM_EncoderMode_TI1 ((uint16_t)0x0001)
+#define TIM_EncoderMode_TI2 ((uint16_t)0x0002)
+#define TIM_EncoderMode_TI12 ((uint16_t)0x0003)
+#define IS_TIM_ENCODER_MODE(MODE) (((MODE) == TIM_EncoderMode_TI1) || \
+ ((MODE) == TIM_EncoderMode_TI2) || \
+ ((MODE) == TIM_EncoderMode_TI12))
+/**
+ * @}
+ */
+
+
+/** @defgroup TIM_Event_Source
+ * @{
+ */
+
+#define TIM_EventSource_Update ((uint16_t)0x0001)
+#define TIM_EventSource_CC1 ((uint16_t)0x0002)
+#define TIM_EventSource_CC2 ((uint16_t)0x0004)
+#define TIM_EventSource_CC3 ((uint16_t)0x0008)
+#define TIM_EventSource_CC4 ((uint16_t)0x0010)
+#define TIM_EventSource_COM ((uint16_t)0x0020)
+#define TIM_EventSource_Trigger ((uint16_t)0x0040)
+#define TIM_EventSource_Break ((uint16_t)0x0080)
+#define IS_TIM_EVENT_SOURCE(SOURCE) ((((SOURCE) & (uint16_t)0xFF00) == 0x0000) && ((SOURCE) != 0x0000))
+
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Update_Source
+ * @{
+ */
+
+#define TIM_UpdateSource_Global ((uint16_t)0x0000) /*!< Source of update is the counter overflow/underflow
+ or the setting of UG bit, or an update generation
+ through the slave mode controller. */
+#define TIM_UpdateSource_Regular ((uint16_t)0x0001) /*!< Source of update is counter overflow/underflow. */
+#define IS_TIM_UPDATE_SOURCE(SOURCE) (((SOURCE) == TIM_UpdateSource_Global) || \
+ ((SOURCE) == TIM_UpdateSource_Regular))
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Output_Compare_Preload_State
+ * @{
+ */
+
+#define TIM_OCPreload_Enable ((uint16_t)0x0008)
+#define TIM_OCPreload_Disable ((uint16_t)0x0000)
+#define IS_TIM_OCPRELOAD_STATE(STATE) (((STATE) == TIM_OCPreload_Enable) || \
+ ((STATE) == TIM_OCPreload_Disable))
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Output_Compare_Fast_State
+ * @{
+ */
+
+#define TIM_OCFast_Enable ((uint16_t)0x0004)
+#define TIM_OCFast_Disable ((uint16_t)0x0000)
+#define IS_TIM_OCFAST_STATE(STATE) (((STATE) == TIM_OCFast_Enable) || \
+ ((STATE) == TIM_OCFast_Disable))
+
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Output_Compare_Clear_State
+ * @{
+ */
+
+#define TIM_OCClear_Enable ((uint16_t)0x0080)
+#define TIM_OCClear_Disable ((uint16_t)0x0000)
+#define IS_TIM_OCCLEAR_STATE(STATE) (((STATE) == TIM_OCClear_Enable) || \
+ ((STATE) == TIM_OCClear_Disable))
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Trigger_Output_Source
+ * @{
+ */
+
+#define TIM_TRGOSource_Reset ((uint16_t)0x0000)
+#define TIM_TRGOSource_Enable ((uint16_t)0x0010)
+#define TIM_TRGOSource_Update ((uint16_t)0x0020)
+#define TIM_TRGOSource_OC1 ((uint16_t)0x0030)
+#define TIM_TRGOSource_OC1Ref ((uint16_t)0x0040)
+#define TIM_TRGOSource_OC2Ref ((uint16_t)0x0050)
+#define TIM_TRGOSource_OC3Ref ((uint16_t)0x0060)
+#define TIM_TRGOSource_OC4Ref ((uint16_t)0x0070)
+#define IS_TIM_TRGO_SOURCE(SOURCE) (((SOURCE) == TIM_TRGOSource_Reset) || \
+ ((SOURCE) == TIM_TRGOSource_Enable) || \
+ ((SOURCE) == TIM_TRGOSource_Update) || \
+ ((SOURCE) == TIM_TRGOSource_OC1) || \
+ ((SOURCE) == TIM_TRGOSource_OC1Ref) || \
+ ((SOURCE) == TIM_TRGOSource_OC2Ref) || \
+ ((SOURCE) == TIM_TRGOSource_OC3Ref) || \
+ ((SOURCE) == TIM_TRGOSource_OC4Ref))
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Slave_Mode
+ * @{
+ */
+
+#define TIM_SlaveMode_Reset ((uint16_t)0x0004)
+#define TIM_SlaveMode_Gated ((uint16_t)0x0005)
+#define TIM_SlaveMode_Trigger ((uint16_t)0x0006)
+#define TIM_SlaveMode_External1 ((uint16_t)0x0007)
+#define IS_TIM_SLAVE_MODE(MODE) (((MODE) == TIM_SlaveMode_Reset) || \
+ ((MODE) == TIM_SlaveMode_Gated) || \
+ ((MODE) == TIM_SlaveMode_Trigger) || \
+ ((MODE) == TIM_SlaveMode_External1))
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Master_Slave_Mode
+ * @{
+ */
+
+#define TIM_MasterSlaveMode_Enable ((uint16_t)0x0080)
+#define TIM_MasterSlaveMode_Disable ((uint16_t)0x0000)
+#define IS_TIM_MSM_STATE(STATE) (((STATE) == TIM_MasterSlaveMode_Enable) || \
+ ((STATE) == TIM_MasterSlaveMode_Disable))
+/**
+ * @}
+ */
+/** @defgroup TIM_Remap
+ * @{
+ */
+
+#define TIM2_TIM8_TRGO ((uint16_t)0x0000)
+#define TIM2_ETH_PTP ((uint16_t)0x0400)
+#define TIM2_USBFS_SOF ((uint16_t)0x0800)
+#define TIM2_USBHS_SOF ((uint16_t)0x0C00)
+
+#define TIM5_GPIO ((uint16_t)0x0000)
+#define TIM5_LSI ((uint16_t)0x0040)
+#define TIM5_LSE ((uint16_t)0x0080)
+#define TIM5_RTC ((uint16_t)0x00C0)
+
+#define TIM11_GPIO ((uint16_t)0x0000)
+#define TIM11_HSE ((uint16_t)0x0002)
+
+#define IS_TIM_REMAP(TIM_REMAP) (((TIM_REMAP) == TIM2_TIM8_TRGO)||\
+ ((TIM_REMAP) == TIM2_ETH_PTP)||\
+ ((TIM_REMAP) == TIM2_USBFS_SOF)||\
+ ((TIM_REMAP) == TIM2_USBHS_SOF)||\
+ ((TIM_REMAP) == TIM5_GPIO)||\
+ ((TIM_REMAP) == TIM5_LSI)||\
+ ((TIM_REMAP) == TIM5_LSE)||\
+ ((TIM_REMAP) == TIM5_RTC)||\
+ ((TIM_REMAP) == TIM11_GPIO)||\
+ ((TIM_REMAP) == TIM11_HSE))
+
+/**
+ * @}
+ */
+/** @defgroup TIM_Flags
+ * @{
+ */
+
+#define TIM_FLAG_Update ((uint16_t)0x0001)
+#define TIM_FLAG_CC1 ((uint16_t)0x0002)
+#define TIM_FLAG_CC2 ((uint16_t)0x0004)
+#define TIM_FLAG_CC3 ((uint16_t)0x0008)
+#define TIM_FLAG_CC4 ((uint16_t)0x0010)
+#define TIM_FLAG_COM ((uint16_t)0x0020)
+#define TIM_FLAG_Trigger ((uint16_t)0x0040)
+#define TIM_FLAG_Break ((uint16_t)0x0080)
+#define TIM_FLAG_CC1OF ((uint16_t)0x0200)
+#define TIM_FLAG_CC2OF ((uint16_t)0x0400)
+#define TIM_FLAG_CC3OF ((uint16_t)0x0800)
+#define TIM_FLAG_CC4OF ((uint16_t)0x1000)
+#define IS_TIM_GET_FLAG(FLAG) (((FLAG) == TIM_FLAG_Update) || \
+ ((FLAG) == TIM_FLAG_CC1) || \
+ ((FLAG) == TIM_FLAG_CC2) || \
+ ((FLAG) == TIM_FLAG_CC3) || \
+ ((FLAG) == TIM_FLAG_CC4) || \
+ ((FLAG) == TIM_FLAG_COM) || \
+ ((FLAG) == TIM_FLAG_Trigger) || \
+ ((FLAG) == TIM_FLAG_Break) || \
+ ((FLAG) == TIM_FLAG_CC1OF) || \
+ ((FLAG) == TIM_FLAG_CC2OF) || \
+ ((FLAG) == TIM_FLAG_CC3OF) || \
+ ((FLAG) == TIM_FLAG_CC4OF))
+
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Input_Capture_Filer_Value
+ * @{
+ */
+
+#define IS_TIM_IC_FILTER(ICFILTER) ((ICFILTER) <= 0xF)
+/**
+ * @}
+ */
+
+/** @defgroup TIM_External_Trigger_Filter
+ * @{
+ */
+
+#define IS_TIM_EXT_FILTER(EXTFILTER) ((EXTFILTER) <= 0xF)
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Legacy
+ * @{
+ */
+
+#define TIM_DMABurstLength_1Byte TIM_DMABurstLength_1Transfer
+#define TIM_DMABurstLength_2Bytes TIM_DMABurstLength_2Transfers
+#define TIM_DMABurstLength_3Bytes TIM_DMABurstLength_3Transfers
+#define TIM_DMABurstLength_4Bytes TIM_DMABurstLength_4Transfers
+#define TIM_DMABurstLength_5Bytes TIM_DMABurstLength_5Transfers
+#define TIM_DMABurstLength_6Bytes TIM_DMABurstLength_6Transfers
+#define TIM_DMABurstLength_7Bytes TIM_DMABurstLength_7Transfers
+#define TIM_DMABurstLength_8Bytes TIM_DMABurstLength_8Transfers
+#define TIM_DMABurstLength_9Bytes TIM_DMABurstLength_9Transfers
+#define TIM_DMABurstLength_10Bytes TIM_DMABurstLength_10Transfers
+#define TIM_DMABurstLength_11Bytes TIM_DMABurstLength_11Transfers
+#define TIM_DMABurstLength_12Bytes TIM_DMABurstLength_12Transfers
+#define TIM_DMABurstLength_13Bytes TIM_DMABurstLength_13Transfers
+#define TIM_DMABurstLength_14Bytes TIM_DMABurstLength_14Transfers
+#define TIM_DMABurstLength_15Bytes TIM_DMABurstLength_15Transfers
+#define TIM_DMABurstLength_16Bytes TIM_DMABurstLength_16Transfers
+#define TIM_DMABurstLength_17Bytes TIM_DMABurstLength_17Transfers
+#define TIM_DMABurstLength_18Bytes TIM_DMABurstLength_18Transfers
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions --------------------------------------------------------*/
+
+/* TimeBase management ********************************************************/
+void TIM_DeInit(TIM_TypeDef* TIMx);
+void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);
+void TIM_TimeBaseStructInit(TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);
+void TIM_PrescalerConfig(TIM_TypeDef* TIMx, uint16_t Prescaler, uint16_t TIM_PSCReloadMode);
+void TIM_CounterModeConfig(TIM_TypeDef* TIMx, uint16_t TIM_CounterMode);
+void TIM_SetCounter(TIM_TypeDef* TIMx, uint32_t Counter);
+void TIM_SetAutoreload(TIM_TypeDef* TIMx, uint32_t Autoreload);
+uint32_t TIM_GetCounter(TIM_TypeDef* TIMx);
+uint16_t TIM_GetPrescaler(TIM_TypeDef* TIMx);
+void TIM_UpdateDisableConfig(TIM_TypeDef* TIMx, FunctionalState NewState);
+void TIM_UpdateRequestConfig(TIM_TypeDef* TIMx, uint16_t TIM_UpdateSource);
+void TIM_ARRPreloadConfig(TIM_TypeDef* TIMx, FunctionalState NewState);
+void TIM_SelectOnePulseMode(TIM_TypeDef* TIMx, uint16_t TIM_OPMode);
+void TIM_SetClockDivision(TIM_TypeDef* TIMx, uint16_t TIM_CKD);
+void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState);
+
+/* Output Compare management **************************************************/
+void TIM_OC1Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
+void TIM_OC2Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
+void TIM_OC3Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
+void TIM_OC4Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
+void TIM_OCStructInit(TIM_OCInitTypeDef* TIM_OCInitStruct);
+void TIM_SelectOCxM(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_OCMode);
+void TIM_SetCompare1(TIM_TypeDef* TIMx, uint32_t Compare1);
+void TIM_SetCompare2(TIM_TypeDef* TIMx, uint32_t Compare2);
+void TIM_SetCompare3(TIM_TypeDef* TIMx, uint32_t Compare3);
+void TIM_SetCompare4(TIM_TypeDef* TIMx, uint32_t Compare4);
+void TIM_ForcedOC1Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction);
+void TIM_ForcedOC2Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction);
+void TIM_ForcedOC3Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction);
+void TIM_ForcedOC4Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction);
+void TIM_OC1PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);
+void TIM_OC2PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);
+void TIM_OC3PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);
+void TIM_OC4PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);
+void TIM_OC1FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast);
+void TIM_OC2FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast);
+void TIM_OC3FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast);
+void TIM_OC4FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast);
+void TIM_ClearOC1Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear);
+void TIM_ClearOC2Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear);
+void TIM_ClearOC3Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear);
+void TIM_ClearOC4Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear);
+void TIM_OC1PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity);
+void TIM_OC1NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity);
+void TIM_OC2PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity);
+void TIM_OC2NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity);
+void TIM_OC3PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity);
+void TIM_OC3NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity);
+void TIM_OC4PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity);
+void TIM_CCxCmd(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_CCx);
+void TIM_CCxNCmd(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_CCxN);
+
+/* Input Capture management ***************************************************/
+void TIM_ICInit(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct);
+void TIM_ICStructInit(TIM_ICInitTypeDef* TIM_ICInitStruct);
+void TIM_PWMIConfig(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct);
+uint32_t TIM_GetCapture1(TIM_TypeDef* TIMx);
+uint32_t TIM_GetCapture2(TIM_TypeDef* TIMx);
+uint32_t TIM_GetCapture3(TIM_TypeDef* TIMx);
+uint32_t TIM_GetCapture4(TIM_TypeDef* TIMx);
+void TIM_SetIC1Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC);
+void TIM_SetIC2Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC);
+void TIM_SetIC3Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC);
+void TIM_SetIC4Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC);
+
+/* Advanced-control timers (TIM1 and TIM8) specific features ******************/
+void TIM_BDTRConfig(TIM_TypeDef* TIMx, TIM_BDTRInitTypeDef *TIM_BDTRInitStruct);
+void TIM_BDTRStructInit(TIM_BDTRInitTypeDef* TIM_BDTRInitStruct);
+void TIM_CtrlPWMOutputs(TIM_TypeDef* TIMx, FunctionalState NewState);
+void TIM_SelectCOM(TIM_TypeDef* TIMx, FunctionalState NewState);
+void TIM_CCPreloadControl(TIM_TypeDef* TIMx, FunctionalState NewState);
+
+/* Interrupts, DMA and flags management ***************************************/
+void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState);
+void TIM_GenerateEvent(TIM_TypeDef* TIMx, uint16_t TIM_EventSource);
+FlagStatus TIM_GetFlagStatus(TIM_TypeDef* TIMx, uint16_t TIM_FLAG);
+void TIM_ClearFlag(TIM_TypeDef* TIMx, uint16_t TIM_FLAG);
+ITStatus TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t TIM_IT);
+void TIM_ClearITPendingBit(TIM_TypeDef* TIMx, uint16_t TIM_IT);
+void TIM_DMAConfig(TIM_TypeDef* TIMx, uint16_t TIM_DMABase, uint16_t TIM_DMABurstLength);
+void TIM_DMACmd(TIM_TypeDef* TIMx, uint16_t TIM_DMASource, FunctionalState NewState);
+void TIM_SelectCCDMA(TIM_TypeDef* TIMx, FunctionalState NewState);
+
+/* Clocks management **********************************************************/
+void TIM_InternalClockConfig(TIM_TypeDef* TIMx);
+void TIM_ITRxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource);
+void TIM_TIxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_TIxExternalCLKSource,
+ uint16_t TIM_ICPolarity, uint16_t ICFilter);
+void TIM_ETRClockMode1Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity,
+ uint16_t ExtTRGFilter);
+void TIM_ETRClockMode2Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler,
+ uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter);
+
+/* Synchronization management *************************************************/
+void TIM_SelectInputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource);
+void TIM_SelectOutputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_TRGOSource);
+void TIM_SelectSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_SlaveMode);
+void TIM_SelectMasterSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_MasterSlaveMode);
+void TIM_ETRConfig(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity,
+ uint16_t ExtTRGFilter);
+
+/* Specific interface management **********************************************/
+void TIM_EncoderInterfaceConfig(TIM_TypeDef* TIMx, uint16_t TIM_EncoderMode,
+ uint16_t TIM_IC1Polarity, uint16_t TIM_IC2Polarity);
+void TIM_SelectHallSensor(TIM_TypeDef* TIMx, FunctionalState NewState);
+
+/* Specific remapping management **********************************************/
+void TIM_RemapConfig(TIM_TypeDef* TIMx, uint16_t TIM_Remap);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*__STM32F2xx_TIM_H */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/inc/stm32f2xx_usart.h b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/inc/stm32f2xx_usart.h
new file mode 100644
index 0000000..20fa92f
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/inc/stm32f2xx_usart.h
@@ -0,0 +1,429 @@
+/**
+ ******************************************************************************
+ * @file stm32f2xx_usart.h
+ * @author MCD Application Team
+ * @version V1.1.2
+ * @date 05-March-2012
+ * @brief This file contains all the functions prototypes for the USART
+ * firmware 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 __STM32F2xx_USART_H
+#define __STM32F2xx_USART_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f2xx.h"
+
+/** @addtogroup STM32F2xx_StdPeriph_Driver
+ * @{
+ */
+
+/** @addtogroup USART
+ * @{
+ */
+
+/* Exported types ------------------------------------------------------------*/
+
+/**
+ * @brief USART Init Structure definition
+ */
+
+typedef struct
+{
+ uint32_t USART_BaudRate; /*!< This member configures the USART communication baud rate.
+ The baud rate is computed using the following formula:
+ - IntegerDivider = ((PCLKx) / (8 * (OVR8+1) * (USART_InitStruct->USART_BaudRate)))
+ - FractionalDivider = ((IntegerDivider - ((u32) IntegerDivider)) * 8 * (OVR8+1)) + 0.5
+ Where OVR8 is the "oversampling by 8 mode" configuration bit in the CR1 register. */
+
+ uint16_t USART_WordLength; /*!< Specifies the number of data bits transmitted or received in a frame.
+ This parameter can be a value of @ref USART_Word_Length */
+
+ uint16_t USART_StopBits; /*!< Specifies the number of stop bits transmitted.
+ This parameter can be a value of @ref USART_Stop_Bits */
+
+ uint16_t USART_Parity; /*!< Specifies the parity mode.
+ This parameter can be a value of @ref USART_Parity
+ @note When parity is enabled, the computed parity is inserted
+ at the MSB position of the transmitted data (9th bit when
+ the word length is set to 9 data bits; 8th bit when the
+ word length is set to 8 data bits). */
+
+ uint16_t USART_Mode; /*!< Specifies wether the Receive or Transmit mode is enabled or disabled.
+ This parameter can be a value of @ref USART_Mode */
+
+ uint16_t USART_HardwareFlowControl; /*!< Specifies wether the hardware flow control mode is enabled
+ or disabled.
+ This parameter can be a value of @ref USART_Hardware_Flow_Control */
+} USART_InitTypeDef;
+
+/**
+ * @brief USART Clock Init Structure definition
+ */
+
+typedef struct
+{
+
+ uint16_t USART_Clock; /*!< Specifies whether the USART clock is enabled or disabled.
+ This parameter can be a value of @ref USART_Clock */
+
+ uint16_t USART_CPOL; /*!< Specifies the steady state of the serial clock.
+ This parameter can be a value of @ref USART_Clock_Polarity */
+
+ uint16_t USART_CPHA; /*!< Specifies the clock transition on which the bit capture is made.
+ This parameter can be a value of @ref USART_Clock_Phase */
+
+ uint16_t USART_LastBit; /*!< Specifies whether the clock pulse corresponding to the last transmitted
+ data bit (MSB) has to be output on the SCLK pin in synchronous mode.
+ This parameter can be a value of @ref USART_Last_Bit */
+} USART_ClockInitTypeDef;
+
+/* Exported constants --------------------------------------------------------*/
+
+/** @defgroup USART_Exported_Constants
+ * @{
+ */
+
+#define IS_USART_ALL_PERIPH(PERIPH) (((PERIPH) == USART1) || \
+ ((PERIPH) == USART2) || \
+ ((PERIPH) == USART3) || \
+ ((PERIPH) == UART4) || \
+ ((PERIPH) == UART5) || \
+ ((PERIPH) == USART6))
+
+#define IS_USART_1236_PERIPH(PERIPH) (((PERIPH) == USART1) || \
+ ((PERIPH) == USART2) || \
+ ((PERIPH) == USART3) || \
+ ((PERIPH) == USART6))
+
+/** @defgroup USART_Word_Length
+ * @{
+ */
+
+#define USART_WordLength_8b ((uint16_t)0x0000)
+#define USART_WordLength_9b ((uint16_t)0x1000)
+
+#define IS_USART_WORD_LENGTH(LENGTH) (((LENGTH) == USART_WordLength_8b) || \
+ ((LENGTH) == USART_WordLength_9b))
+/**
+ * @}
+ */
+
+/** @defgroup USART_Stop_Bits
+ * @{
+ */
+
+#define USART_StopBits_1 ((uint16_t)0x0000)
+#define USART_StopBits_0_5 ((uint16_t)0x1000)
+#define USART_StopBits_2 ((uint16_t)0x2000)
+#define USART_StopBits_1_5 ((uint16_t)0x3000)
+#define IS_USART_STOPBITS(STOPBITS) (((STOPBITS) == USART_StopBits_1) || \
+ ((STOPBITS) == USART_StopBits_0_5) || \
+ ((STOPBITS) == USART_StopBits_2) || \
+ ((STOPBITS) == USART_StopBits_1_5))
+/**
+ * @}
+ */
+
+/** @defgroup USART_Parity
+ * @{
+ */
+
+#define USART_Parity_No ((uint16_t)0x0000)
+#define USART_Parity_Even ((uint16_t)0x0400)
+#define USART_Parity_Odd ((uint16_t)0x0600)
+#define IS_USART_PARITY(PARITY) (((PARITY) == USART_Parity_No) || \
+ ((PARITY) == USART_Parity_Even) || \
+ ((PARITY) == USART_Parity_Odd))
+/**
+ * @}
+ */
+
+/** @defgroup USART_Mode
+ * @{
+ */
+
+#define USART_Mode_Rx ((uint16_t)0x0004)
+#define USART_Mode_Tx ((uint16_t)0x0008)
+#define IS_USART_MODE(MODE) ((((MODE) & (uint16_t)0xFFF3) == 0x00) && ((MODE) != (uint16_t)0x00))
+/**
+ * @}
+ */
+
+/** @defgroup USART_Hardware_Flow_Control
+ * @{
+ */
+#define USART_HardwareFlowControl_None ((uint16_t)0x0000)
+#define USART_HardwareFlowControl_RTS ((uint16_t)0x0100)
+#define USART_HardwareFlowControl_CTS ((uint16_t)0x0200)
+#define USART_HardwareFlowControl_RTS_CTS ((uint16_t)0x0300)
+#define IS_USART_HARDWARE_FLOW_CONTROL(CONTROL)\
+ (((CONTROL) == USART_HardwareFlowControl_None) || \
+ ((CONTROL) == USART_HardwareFlowControl_RTS) || \
+ ((CONTROL) == USART_HardwareFlowControl_CTS) || \
+ ((CONTROL) == USART_HardwareFlowControl_RTS_CTS))
+/**
+ * @}
+ */
+
+/** @defgroup USART_Clock
+ * @{
+ */
+#define USART_Clock_Disable ((uint16_t)0x0000)
+#define USART_Clock_Enable ((uint16_t)0x0800)
+#define IS_USART_CLOCK(CLOCK) (((CLOCK) == USART_Clock_Disable) || \
+ ((CLOCK) == USART_Clock_Enable))
+/**
+ * @}
+ */
+
+/** @defgroup USART_Clock_Polarity
+ * @{
+ */
+
+#define USART_CPOL_Low ((uint16_t)0x0000)
+#define USART_CPOL_High ((uint16_t)0x0400)
+#define IS_USART_CPOL(CPOL) (((CPOL) == USART_CPOL_Low) || ((CPOL) == USART_CPOL_High))
+
+/**
+ * @}
+ */
+
+/** @defgroup USART_Clock_Phase
+ * @{
+ */
+
+#define USART_CPHA_1Edge ((uint16_t)0x0000)
+#define USART_CPHA_2Edge ((uint16_t)0x0200)
+#define IS_USART_CPHA(CPHA) (((CPHA) == USART_CPHA_1Edge) || ((CPHA) == USART_CPHA_2Edge))
+
+/**
+ * @}
+ */
+
+/** @defgroup USART_Last_Bit
+ * @{
+ */
+
+#define USART_LastBit_Disable ((uint16_t)0x0000)
+#define USART_LastBit_Enable ((uint16_t)0x0100)
+#define IS_USART_LASTBIT(LASTBIT) (((LASTBIT) == USART_LastBit_Disable) || \
+ ((LASTBIT) == USART_LastBit_Enable))
+/**
+ * @}
+ */
+
+/** @defgroup USART_Interrupt_definition
+ * @{
+ */
+
+#define USART_IT_PE ((uint16_t)0x0028)
+#define USART_IT_TXE ((uint16_t)0x0727)
+#define USART_IT_TC ((uint16_t)0x0626)
+#define USART_IT_RXNE ((uint16_t)0x0525)
+#define USART_IT_ORE_RX ((uint16_t)0x0325) /* In case interrupt is generated if the RXNEIE bit is set */
+#define USART_IT_IDLE ((uint16_t)0x0424)
+#define USART_IT_LBD ((uint16_t)0x0846)
+#define USART_IT_CTS ((uint16_t)0x096A)
+#define USART_IT_ERR ((uint16_t)0x0060)
+#define USART_IT_ORE_ER ((uint16_t)0x0360) /* In case interrupt is generated if the EIE bit is set */
+#define USART_IT_NE ((uint16_t)0x0260)
+#define USART_IT_FE ((uint16_t)0x0160)
+
+/** @defgroup USART_Legacy
+ * @{
+ */
+#define USART_IT_ORE USART_IT_ORE_ER
+/**
+ * @}
+ */
+
+#define IS_USART_CONFIG_IT(IT) (((IT) == USART_IT_PE) || ((IT) == USART_IT_TXE) || \
+ ((IT) == USART_IT_TC) || ((IT) == USART_IT_RXNE) || \
+ ((IT) == USART_IT_IDLE) || ((IT) == USART_IT_LBD) || \
+ ((IT) == USART_IT_CTS) || ((IT) == USART_IT_ERR))
+#define IS_USART_GET_IT(IT) (((IT) == USART_IT_PE) || ((IT) == USART_IT_TXE) || \
+ ((IT) == USART_IT_TC) || ((IT) == USART_IT_RXNE) || \
+ ((IT) == USART_IT_IDLE) || ((IT) == USART_IT_LBD) || \
+ ((IT) == USART_IT_CTS) || ((IT) == USART_IT_ORE) || \
+ ((IT) == USART_IT_ORE_RX) || ((IT) == USART_IT_ORE_ER) || \
+ ((IT) == USART_IT_NE) || ((IT) == USART_IT_FE))
+#define IS_USART_CLEAR_IT(IT) (((IT) == USART_IT_TC) || ((IT) == USART_IT_RXNE) || \
+ ((IT) == USART_IT_LBD) || ((IT) == USART_IT_CTS))
+/**
+ * @}
+ */
+
+/** @defgroup USART_DMA_Requests
+ * @{
+ */
+
+#define USART_DMAReq_Tx ((uint16_t)0x0080)
+#define USART_DMAReq_Rx ((uint16_t)0x0040)
+#define IS_USART_DMAREQ(DMAREQ) ((((DMAREQ) & (uint16_t)0xFF3F) == 0x00) && ((DMAREQ) != (uint16_t)0x00))
+
+/**
+ * @}
+ */
+
+/** @defgroup USART_WakeUp_methods
+ * @{
+ */
+
+#define USART_WakeUp_IdleLine ((uint16_t)0x0000)
+#define USART_WakeUp_AddressMark ((uint16_t)0x0800)
+#define IS_USART_WAKEUP(WAKEUP) (((WAKEUP) == USART_WakeUp_IdleLine) || \
+ ((WAKEUP) == USART_WakeUp_AddressMark))
+/**
+ * @}
+ */
+
+/** @defgroup USART_LIN_Break_Detection_Length
+ * @{
+ */
+
+#define USART_LINBreakDetectLength_10b ((uint16_t)0x0000)
+#define USART_LINBreakDetectLength_11b ((uint16_t)0x0020)
+#define IS_USART_LIN_BREAK_DETECT_LENGTH(LENGTH) \
+ (((LENGTH) == USART_LINBreakDetectLength_10b) || \
+ ((LENGTH) == USART_LINBreakDetectLength_11b))
+/**
+ * @}
+ */
+
+/** @defgroup USART_IrDA_Low_Power
+ * @{
+ */
+
+#define USART_IrDAMode_LowPower ((uint16_t)0x0004)
+#define USART_IrDAMode_Normal ((uint16_t)0x0000)
+#define IS_USART_IRDA_MODE(MODE) (((MODE) == USART_IrDAMode_LowPower) || \
+ ((MODE) == USART_IrDAMode_Normal))
+/**
+ * @}
+ */
+
+/** @defgroup USART_Flags
+ * @{
+ */
+
+#define USART_FLAG_CTS ((uint16_t)0x0200)
+#define USART_FLAG_LBD ((uint16_t)0x0100)
+#define USART_FLAG_TXE ((uint16_t)0x0080)
+#define USART_FLAG_TC ((uint16_t)0x0040)
+#define USART_FLAG_RXNE ((uint16_t)0x0020)
+#define USART_FLAG_IDLE ((uint16_t)0x0010)
+#define USART_FLAG_ORE ((uint16_t)0x0008)
+#define USART_FLAG_NE ((uint16_t)0x0004)
+#define USART_FLAG_FE ((uint16_t)0x0002)
+#define USART_FLAG_PE ((uint16_t)0x0001)
+#define IS_USART_FLAG(FLAG) (((FLAG) == USART_FLAG_PE) || ((FLAG) == USART_FLAG_TXE) || \
+ ((FLAG) == USART_FLAG_TC) || ((FLAG) == USART_FLAG_RXNE) || \
+ ((FLAG) == USART_FLAG_IDLE) || ((FLAG) == USART_FLAG_LBD) || \
+ ((FLAG) == USART_FLAG_CTS) || ((FLAG) == USART_FLAG_ORE) || \
+ ((FLAG) == USART_FLAG_NE) || ((FLAG) == USART_FLAG_FE))
+
+#define IS_USART_CLEAR_FLAG(FLAG) ((((FLAG) & (uint16_t)0xFC9F) == 0x00) && ((FLAG) != (uint16_t)0x00))
+
+#define IS_USART_BAUDRATE(BAUDRATE) (((BAUDRATE) > 0) && ((BAUDRATE) < 7500001))
+#define IS_USART_ADDRESS(ADDRESS) ((ADDRESS) <= 0xF)
+#define IS_USART_DATA(DATA) ((DATA) <= 0x1FF)
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions --------------------------------------------------------*/
+
+/* Function used to set the USART configuration to the default reset state ***/
+void USART_DeInit(USART_TypeDef* USARTx);
+
+/* Initialization and Configuration functions *********************************/
+void USART_Init(USART_TypeDef* USARTx, USART_InitTypeDef* USART_InitStruct);
+void USART_StructInit(USART_InitTypeDef* USART_InitStruct);
+void USART_ClockInit(USART_TypeDef* USARTx, USART_ClockInitTypeDef* USART_ClockInitStruct);
+void USART_ClockStructInit(USART_ClockInitTypeDef* USART_ClockInitStruct);
+void USART_Cmd(USART_TypeDef* USARTx, FunctionalState NewState);
+void USART_SetPrescaler(USART_TypeDef* USARTx, uint8_t USART_Prescaler);
+void USART_OverSampling8Cmd(USART_TypeDef* USARTx, FunctionalState NewState);
+void USART_OneBitMethodCmd(USART_TypeDef* USARTx, FunctionalState NewState);
+
+/* Data transfers functions ***************************************************/
+void USART_SendData(USART_TypeDef* USARTx, uint16_t Data);
+uint16_t USART_ReceiveData(USART_TypeDef* USARTx);
+
+/* Multi-Processor Communication functions ************************************/
+void USART_SetAddress(USART_TypeDef* USARTx, uint8_t USART_Address);
+void USART_WakeUpConfig(USART_TypeDef* USARTx, uint16_t USART_WakeUp);
+void USART_ReceiverWakeUpCmd(USART_TypeDef* USARTx, FunctionalState NewState);
+
+/* LIN mode functions *********************************************************/
+void USART_LINBreakDetectLengthConfig(USART_TypeDef* USARTx, uint16_t USART_LINBreakDetectLength);
+void USART_LINCmd(USART_TypeDef* USARTx, FunctionalState NewState);
+void USART_SendBreak(USART_TypeDef* USARTx);
+
+/* Half-duplex mode function **************************************************/
+void USART_HalfDuplexCmd(USART_TypeDef* USARTx, FunctionalState NewState);
+
+/* Smartcard mode functions ***************************************************/
+void USART_SmartCardCmd(USART_TypeDef* USARTx, FunctionalState NewState);
+void USART_SmartCardNACKCmd(USART_TypeDef* USARTx, FunctionalState NewState);
+void USART_SetGuardTime(USART_TypeDef* USARTx, uint8_t USART_GuardTime);
+
+/* IrDA mode functions ********************************************************/
+void USART_IrDAConfig(USART_TypeDef* USARTx, uint16_t USART_IrDAMode);
+void USART_IrDACmd(USART_TypeDef* USARTx, FunctionalState NewState);
+
+/* DMA transfers management functions *****************************************/
+void USART_DMACmd(USART_TypeDef* USARTx, uint16_t USART_DMAReq, FunctionalState NewState);
+
+/* Interrupts and flags management functions **********************************/
+void USART_ITConfig(USART_TypeDef* USARTx, uint16_t USART_IT, FunctionalState NewState);
+FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG);
+void USART_ClearFlag(USART_TypeDef* USARTx, uint16_t USART_FLAG);
+ITStatus USART_GetITStatus(USART_TypeDef* USARTx, uint16_t USART_IT);
+void USART_ClearITPendingBit(USART_TypeDef* USARTx, uint16_t USART_IT);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F2xx_USART_H */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/inc/stm32f2xx_wwdg.h b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/inc/stm32f2xx_wwdg.h
new file mode 100644
index 0000000..4cf5f03
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/inc/stm32f2xx_wwdg.h
@@ -0,0 +1,111 @@
+/**
+ ******************************************************************************
+ * @file stm32f2xx_wwdg.h
+ * @author MCD Application Team
+ * @version V1.1.2
+ * @date 05-March-2012
+ * @brief This file contains all the functions prototypes for the WWDG firmware
+ * 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 __STM32F2xx_WWDG_H
+#define __STM32F2xx_WWDG_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f2xx.h"
+
+/** @addtogroup STM32F2xx_StdPeriph_Driver
+ * @{
+ */
+
+/** @addtogroup WWDG
+ * @{
+ */
+
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+
+/** @defgroup WWDG_Exported_Constants
+ * @{
+ */
+
+/** @defgroup WWDG_Prescaler
+ * @{
+ */
+
+#define WWDG_Prescaler_1 ((uint32_t)0x00000000)
+#define WWDG_Prescaler_2 ((uint32_t)0x00000080)
+#define WWDG_Prescaler_4 ((uint32_t)0x00000100)
+#define WWDG_Prescaler_8 ((uint32_t)0x00000180)
+#define IS_WWDG_PRESCALER(PRESCALER) (((PRESCALER) == WWDG_Prescaler_1) || \
+ ((PRESCALER) == WWDG_Prescaler_2) || \
+ ((PRESCALER) == WWDG_Prescaler_4) || \
+ ((PRESCALER) == WWDG_Prescaler_8))
+#define IS_WWDG_WINDOW_VALUE(VALUE) ((VALUE) <= 0x7F)
+#define IS_WWDG_COUNTER(COUNTER) (((COUNTER) >= 0x40) && ((COUNTER) <= 0x7F))
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions --------------------------------------------------------*/
+
+/* Function used to set the WWDG configuration to the default reset state ****/
+void WWDG_DeInit(void);
+
+/* Prescaler, Refresh window and Counter configuration functions **************/
+void WWDG_SetPrescaler(uint32_t WWDG_Prescaler);
+void WWDG_SetWindowValue(uint8_t WindowValue);
+void WWDG_EnableIT(void);
+void WWDG_SetCounter(uint8_t Counter);
+
+/* WWDG activation function ***************************************************/
+void WWDG_Enable(uint8_t Counter);
+
+/* Interrupts and flags management functions **********************************/
+FlagStatus WWDG_GetFlagStatus(void);
+void WWDG_ClearFlag(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F2xx_WWDG_H */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/src/misc.c b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/src/misc.c
new file mode 100644
index 0000000..7d01162
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/src/misc.c
@@ -0,0 +1,249 @@
+/**
+ ******************************************************************************
+ * @file misc.c
+ * @author MCD Application Team
+ * @version V1.1.2
+ * @date 05-March-2012
+ * @brief This file provides all the miscellaneous firmware functions (add-on
+ * to CMSIS functions).
+ *
+ * @verbatim
+ *
+ * ===================================================================
+ * How to configure Interrupts using driver
+ * ===================================================================
+ *
+ * This section provide functions allowing to configure the NVIC interrupts (IRQ).
+ * The Cortex-M3 exceptions are managed by CMSIS functions.
+ *
+ * 1. Configure the NVIC Priority Grouping using NVIC_PriorityGroupConfig()
+ * function according to the following table.
+
+ * The table below gives the allowed values of the pre-emption priority and subpriority according
+ * to the Priority Grouping configuration performed by NVIC_PriorityGroupConfig function
+ * ==========================================================================================================================
+ * NVIC_PriorityGroup | NVIC_IRQChannelPreemptionPriority | NVIC_IRQChannelSubPriority | Description
+ * ==========================================================================================================================
+ * NVIC_PriorityGroup_0 | 0 | 0-15 | 0 bits for pre-emption priority
+ * | | | 4 bits for subpriority
+ * --------------------------------------------------------------------------------------------------------------------------
+ * NVIC_PriorityGroup_1 | 0-1 | 0-7 | 1 bits for pre-emption priority
+ * | | | 3 bits for subpriority
+ * --------------------------------------------------------------------------------------------------------------------------
+ * NVIC_PriorityGroup_2 | 0-3 | 0-3 | 2 bits for pre-emption priority
+ * | | | 2 bits for subpriority
+ * --------------------------------------------------------------------------------------------------------------------------
+ * NVIC_PriorityGroup_3 | 0-7 | 0-1 | 3 bits for pre-emption priority
+ * | | | 1 bits for subpriority
+ * --------------------------------------------------------------------------------------------------------------------------
+ * NVIC_PriorityGroup_4 | 0-15 | 0 | 4 bits for pre-emption priority
+ * | | | 0 bits for subpriority
+ * ==========================================================================================================================
+ *
+ * 2. Enable and Configure the priority of the selected IRQ Channels using NVIC_Init()
+ *
+ * @note When the NVIC_PriorityGroup_0 is selected, IRQ pre-emption is no more possible.
+ * The pending IRQ priority will be managed only by the subpriority.
+ *
+ * @note IRQ priority order (sorted by highest to lowest priority):
+ * - Lowest pre-emption priority
+ * - Lowest subpriority
+ * - Lowest hardware priority (IRQ number)
+ *
+ * @endverbatim
+ *
+ ******************************************************************************
+ * @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 "misc.h"
+
+/** @addtogroup STM32F2xx_StdPeriph_Driver
+ * @{
+ */
+
+/** @defgroup MISC
+ * @brief MISC driver modules
+ * @{
+ */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+#define AIRCR_VECTKEY_MASK ((uint32_t)0x05FA0000)
+
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+/** @defgroup MISC_Private_Functions
+ * @{
+ */
+
+/**
+ * @brief Configures the priority grouping: pre-emption priority and subpriority.
+ * @param NVIC_PriorityGroup: specifies the priority grouping bits length.
+ * This parameter can be one of the following values:
+ * @arg NVIC_PriorityGroup_0: 0 bits for pre-emption priority
+ * 4 bits for subpriority
+ * @arg NVIC_PriorityGroup_1: 1 bits for pre-emption priority
+ * 3 bits for subpriority
+ * @arg NVIC_PriorityGroup_2: 2 bits for pre-emption priority
+ * 2 bits for subpriority
+ * @arg NVIC_PriorityGroup_3: 3 bits for pre-emption priority
+ * 1 bits for subpriority
+ * @arg NVIC_PriorityGroup_4: 4 bits for pre-emption priority
+ * 0 bits for subpriority
+ * @note When the NVIC_PriorityGroup_0 is selected, IRQ pre-emption is no more possible.
+ * The pending IRQ priority will be managed only by the subpriority.
+ * @retval None
+ */
+void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup)
+{
+ /* Check the parameters */
+ assert_param(IS_NVIC_PRIORITY_GROUP(NVIC_PriorityGroup));
+
+ /* Set the PRIGROUP[10:8] bits according to NVIC_PriorityGroup value */
+ SCB->AIRCR = AIRCR_VECTKEY_MASK | NVIC_PriorityGroup;
+}
+
+/**
+ * @brief Initializes the NVIC peripheral according to the specified
+ * parameters in the NVIC_InitStruct.
+ * @note To configure interrupts priority correctly, the NVIC_PriorityGroupConfig()
+ * function should be called before.
+ * @param NVIC_InitStruct: pointer to a NVIC_InitTypeDef structure that contains
+ * the configuration information for the specified NVIC peripheral.
+ * @retval None
+ */
+void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct)
+{
+ uint8_t tmppriority = 0x00, tmppre = 0x00, tmpsub = 0x0F;
+
+ /* Check the parameters */
+ assert_param(IS_FUNCTIONAL_STATE(NVIC_InitStruct->NVIC_IRQChannelCmd));
+ assert_param(IS_NVIC_PREEMPTION_PRIORITY(NVIC_InitStruct->NVIC_IRQChannelPreemptionPriority));
+ assert_param(IS_NVIC_SUB_PRIORITY(NVIC_InitStruct->NVIC_IRQChannelSubPriority));
+
+ if (NVIC_InitStruct->NVIC_IRQChannelCmd != DISABLE)
+ {
+ /* Compute the Corresponding IRQ Priority --------------------------------*/
+ tmppriority = (0x700 - ((SCB->AIRCR) & (uint32_t)0x700))>> 0x08;
+ tmppre = (0x4 - tmppriority);
+ tmpsub = tmpsub >> tmppriority;
+
+ tmppriority = NVIC_InitStruct->NVIC_IRQChannelPreemptionPriority << tmppre;
+ tmppriority |= (uint8_t)(NVIC_InitStruct->NVIC_IRQChannelSubPriority & tmpsub);
+
+ tmppriority = tmppriority << 0x04;
+
+ NVIC->IP[NVIC_InitStruct->NVIC_IRQChannel] = tmppriority;
+
+ /* Enable the Selected IRQ Channels --------------------------------------*/
+ NVIC->ISER[NVIC_InitStruct->NVIC_IRQChannel >> 0x05] =
+ (uint32_t)0x01 << (NVIC_InitStruct->NVIC_IRQChannel & (uint8_t)0x1F);
+ }
+ else
+ {
+ /* Disable the Selected IRQ Channels -------------------------------------*/
+ NVIC->ICER[NVIC_InitStruct->NVIC_IRQChannel >> 0x05] =
+ (uint32_t)0x01 << (NVIC_InitStruct->NVIC_IRQChannel & (uint8_t)0x1F);
+ }
+}
+
+/**
+ * @brief Sets the vector table location and Offset.
+ * @param NVIC_VectTab: specifies if the vector table is in RAM or FLASH memory.
+ * This parameter can be one of the following values:
+ * @arg NVIC_VectTab_RAM: Vector Table in internal SRAM.
+ * @arg NVIC_VectTab_FLASH: Vector Table in internal FLASH.
+ * @param Offset: Vector Table base offset field. This value must be a multiple of 0x200.
+ * @retval None
+ */
+void NVIC_SetVectorTable(uint32_t NVIC_VectTab, uint32_t Offset)
+{
+ /* Check the parameters */
+ assert_param(IS_NVIC_VECTTAB(NVIC_VectTab));
+ assert_param(IS_NVIC_OFFSET(Offset));
+
+ SCB->VTOR = NVIC_VectTab | (Offset & (uint32_t)0x1FFFFF80);
+}
+
+/**
+ * @brief Selects the condition for the system to enter low power mode.
+ * @param LowPowerMode: Specifies the new mode for the system to enter low power mode.
+ * This parameter can be one of the following values:
+ * @arg NVIC_LP_SEVONPEND: Low Power SEV on Pend.
+ * @arg NVIC_LP_SLEEPDEEP: Low Power DEEPSLEEP request.
+ * @arg NVIC_LP_SLEEPONEXIT: Low Power Sleep on Exit.
+ * @param NewState: new state of LP condition. This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void NVIC_SystemLPConfig(uint8_t LowPowerMode, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_NVIC_LP(LowPowerMode));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ SCB->SCR |= LowPowerMode;
+ }
+ else
+ {
+ SCB->SCR &= (uint32_t)(~(uint32_t)LowPowerMode);
+ }
+}
+
+/**
+ * @brief Configures the SysTick clock source.
+ * @param SysTick_CLKSource: specifies the SysTick clock source.
+ * This parameter can be one of the following values:
+ * @arg SysTick_CLKSource_HCLK_Div8: AHB clock divided by 8 selected as SysTick clock source.
+ * @arg SysTick_CLKSource_HCLK: AHB clock selected as SysTick clock source.
+ * @retval None
+ */
+void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource)
+{
+ /* Check the parameters */
+ assert_param(IS_SYSTICK_CLK_SOURCE(SysTick_CLKSource));
+ if (SysTick_CLKSource == SysTick_CLKSource_HCLK)
+ {
+ SysTick->CTRL |= SysTick_CLKSource_HCLK;
+ }
+ else
+ {
+ SysTick->CTRL &= SysTick_CLKSource_HCLK_Div8;
+ }
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/src/stm32f2xx_adc.c b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/src/stm32f2xx_adc.c
new file mode 100644
index 0000000..37ead26
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/src/stm32f2xx_adc.c
@@ -0,0 +1,1748 @@
+/**
+ ******************************************************************************
+ * @file stm32f2xx_adc.c
+ * @author MCD Application Team
+ * @version V1.1.2
+ * @date 05-March-2012
+ * @brief This file provides firmware functions to manage the following
+ * functionalities of the Analog to Digital Convertor (ADC) peripheral:
+ * - Initialization and Configuration (in addition to ADC multi mode
+ * selection)
+ * - Analog Watchdog configuration
+ * - Temperature Sensor & Vrefint (Voltage Reference internal) & VBAT
+ * management
+ * - Regular Channels Configuration
+ * - Regular Channels DMA Configuration
+ * - Injected channels Configuration
+ * - Interrupts and flags management
+ *
+ * @verbatim
+ *
+ * ===================================================================
+ * How to use this driver
+ * ===================================================================
+
+ * 1. Enable the ADC interface clock using
+ * RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADCx, ENABLE);
+ *
+ * 2. ADC pins configuration
+ * - Enable the clock for the ADC GPIOs using the following function:
+ * RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOx, ENABLE);
+ * - Configure these ADC pins in analog mode using GPIO_Init();
+ *
+ * 3. Configure the ADC Prescaler, conversion resolution and data
+ * alignment using the ADC_Init() function.
+ * 4. Activate the ADC peripheral using ADC_Cmd() function.
+ *
+ * Regular channels group configuration
+ * ====================================
+ * - To configure the ADC regular channels group features, use
+ * ADC_Init() and ADC_RegularChannelConfig() functions.
+ * - To activate the continuous mode, use the ADC_continuousModeCmd()
+ * function.
+ * - To configurate and activate the Discontinuous mode, use the
+ * ADC_DiscModeChannelCountConfig() and ADC_DiscModeCmd() functions.
+ * - To read the ADC converted values, use the ADC_GetConversionValue()
+ * function.
+ *
+ * Multi mode ADCs Regular channels configuration
+ * ===============================================
+ * - Refer to "Regular channels group configuration" description to
+ * configure the ADC1, ADC2 and ADC3 regular channels.
+ * - Select the Multi mode ADC regular channels features (dual or
+ * triple mode) using ADC_CommonInit() function and configure
+ * the DMA mode using ADC_MultiModeDMARequestAfterLastTransferCmd()
+ * functions.
+ * - Read the ADCs converted values using the
+ * ADC_GetMultiModeConversionValue() function.
+ *
+ * DMA for Regular channels group features configuration
+ * ======================================================
+ * - To enable the DMA mode for regular channels group, use the
+ * ADC_DMACmd() function.
+ * - To enable the generation of DMA requests continuously at the end
+ * of the last DMA transfer, use the ADC_DMARequestAfterLastTransferCmd()
+ * function.
+ *
+ * Injected channels group configuration
+ * =====================================
+ * - To configure the ADC Injected channels group features, use
+ * ADC_InjectedChannelConfig() and ADC_InjectedSequencerLengthConfig()
+ * functions.
+ * - To activate the continuous mode, use the ADC_continuousModeCmd()
+ * function.
+ * - To activate the Injected Discontinuous mode, use the
+ * ADC_InjectedDiscModeCmd() function.
+ * - To activate the AutoInjected mode, use the ADC_AutoInjectedConvCmd()
+ * function.
+ * - To read the ADC converted values, use the ADC_GetInjectedConversionValue()
+ * function.
+ *
+ * @endverbatim
+ *
+ ******************************************************************************
+ * @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 "stm32f2xx_adc.h"
+#include "stm32f2xx_rcc.h"
+
+/** @addtogroup STM32F2xx_StdPeriph_Driver
+ * @{
+ */
+
+/** @defgroup ADC
+ * @brief ADC driver modules
+ * @{
+ */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+
+/* ADC DISCNUM mask */
+#define CR1_DISCNUM_RESET ((uint32_t)0xFFFF1FFF)
+
+/* ADC AWDCH mask */
+#define CR1_AWDCH_RESET ((uint32_t)0xFFFFFFE0)
+
+/* ADC Analog watchdog enable mode mask */
+#define CR1_AWDMode_RESET ((uint32_t)0xFF3FFDFF)
+
+/* CR1 register Mask */
+#define CR1_CLEAR_MASK ((uint32_t)0xFCFFFEFF)
+
+/* ADC EXTEN mask */
+#define CR2_EXTEN_RESET ((uint32_t)0xCFFFFFFF)
+
+/* ADC JEXTEN mask */
+#define CR2_JEXTEN_RESET ((uint32_t)0xFFCFFFFF)
+
+/* ADC JEXTSEL mask */
+#define CR2_JEXTSEL_RESET ((uint32_t)0xFFF0FFFF)
+
+/* CR2 register Mask */
+#define CR2_CLEAR_MASK ((uint32_t)0xC0FFF7FD)
+
+/* ADC SQx mask */
+#define SQR3_SQ_SET ((uint32_t)0x0000001F)
+#define SQR2_SQ_SET ((uint32_t)0x0000001F)
+#define SQR1_SQ_SET ((uint32_t)0x0000001F)
+
+/* ADC L Mask */
+#define SQR1_L_RESET ((uint32_t)0xFF0FFFFF)
+
+/* ADC JSQx mask */
+#define JSQR_JSQ_SET ((uint32_t)0x0000001F)
+
+/* ADC JL mask */
+#define JSQR_JL_SET ((uint32_t)0x00300000)
+#define JSQR_JL_RESET ((uint32_t)0xFFCFFFFF)
+
+/* ADC SMPx mask */
+#define SMPR1_SMP_SET ((uint32_t)0x00000007)
+#define SMPR2_SMP_SET ((uint32_t)0x00000007)
+
+/* ADC JDRx registers offset */
+#define JDR_OFFSET ((uint8_t)0x28)
+
+/* ADC CDR register base address */
+#define CDR_ADDRESS ((uint32_t)0x40012308)
+
+/* ADC CCR register Mask */
+#define CR_CLEAR_MASK ((uint32_t)0xFFFC30E0)
+
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+/** @defgroup ADC_Private_Functions
+ * @{
+ */
+
+/** @defgroup ADC_Group1 Initialization and Configuration functions
+ * @brief Initialization and Configuration functions
+ *
+@verbatim
+ ===============================================================================
+ Initialization and Configuration functions
+ ===============================================================================
+ This section provides functions allowing to:
+ - Initialize and configure the ADC Prescaler
+ - ADC Conversion Resolution (12bit..6bit)
+ - Scan Conversion Mode (multichannels or one channel) for regular group
+ - ADC Continuous Conversion Mode (Continuous or Single conversion) for
+ regular group
+ - External trigger Edge and source of regular group,
+ - Converted data alignment (left or right)
+ - The number of ADC conversions that will be done using the sequencer for
+ regular channel group
+ - Multi ADC mode selection
+ - Direct memory access mode selection for multi ADC mode
+ - Delay between 2 sampling phases (used in dual or triple interleaved modes)
+ - Enable or disable the ADC peripheral
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Deinitializes all ADCs peripherals registers to their default reset
+ * values.
+ * @param None
+ * @retval None
+ */
+void ADC_DeInit(void)
+{
+ /* Enable all ADCs reset state */
+ RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC, ENABLE);
+
+ /* Release all ADCs from reset state */
+ RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC, DISABLE);
+}
+
+/**
+ * @brief Initializes the ADCx peripheral according to the specified parameters
+ * in the ADC_InitStruct.
+ * @note This function is used to configure the global features of the ADC (
+ * Resolution and Data Alignment), however, the rest of the configuration
+ * parameters are specific to the regular channels group (scan mode
+ * activation, continuous mode activation, External trigger source and
+ * edge, number of conversion in the regular channels group sequencer).
+ * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral.
+ * @param ADC_InitStruct: pointer to an ADC_InitTypeDef structure that contains
+ * the configuration information for the specified ADC peripheral.
+ * @retval None
+ */
+void ADC_Init(ADC_TypeDef* ADCx, ADC_InitTypeDef* ADC_InitStruct)
+{
+ uint32_t tmpreg1 = 0;
+ uint8_t tmpreg2 = 0;
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+ assert_param(IS_ADC_RESOLUTION(ADC_InitStruct->ADC_Resolution));
+ assert_param(IS_FUNCTIONAL_STATE(ADC_InitStruct->ADC_ScanConvMode));
+ assert_param(IS_FUNCTIONAL_STATE(ADC_InitStruct->ADC_ContinuousConvMode));
+ assert_param(IS_ADC_EXT_TRIG_EDGE(ADC_InitStruct->ADC_ExternalTrigConvEdge));
+ assert_param(IS_ADC_EXT_TRIG(ADC_InitStruct->ADC_ExternalTrigConv));
+ assert_param(IS_ADC_DATA_ALIGN(ADC_InitStruct->ADC_DataAlign));
+ assert_param(IS_ADC_REGULAR_LENGTH(ADC_InitStruct->ADC_NbrOfConversion));
+
+ /*---------------------------- ADCx CR1 Configuration -----------------*/
+ /* Get the ADCx CR1 value */
+ tmpreg1 = ADCx->CR1;
+
+ /* Clear RES and SCAN bits */
+ tmpreg1 &= CR1_CLEAR_MASK;
+
+ /* Configure ADCx: scan conversion mode and resolution */
+ /* Set SCAN bit according to ADC_ScanConvMode value */
+ /* Set RES bit according to ADC_Resolution value */
+ tmpreg1 |= (uint32_t)(((uint32_t)ADC_InitStruct->ADC_ScanConvMode << 8) | \
+ ADC_InitStruct->ADC_Resolution);
+ /* Write to ADCx CR1 */
+ ADCx->CR1 = tmpreg1;
+ /*---------------------------- ADCx CR2 Configuration -----------------*/
+ /* Get the ADCx CR2 value */
+ tmpreg1 = ADCx->CR2;
+
+ /* Clear CONT, ALIGN, EXTEN and EXTSEL bits */
+ tmpreg1 &= CR2_CLEAR_MASK;
+
+ /* Configure ADCx: external trigger event and edge, data alignment and
+ continuous conversion mode */
+ /* Set ALIGN bit according to ADC_DataAlign value */
+ /* Set EXTEN bits according to ADC_ExternalTrigConvEdge value */
+ /* Set EXTSEL bits according to ADC_ExternalTrigConv value */
+ /* Set CONT bit according to ADC_ContinuousConvMode value */
+ tmpreg1 |= (uint32_t)(ADC_InitStruct->ADC_DataAlign | \
+ ADC_InitStruct->ADC_ExternalTrigConv |
+ ADC_InitStruct->ADC_ExternalTrigConvEdge | \
+ ((uint32_t)ADC_InitStruct->ADC_ContinuousConvMode << 1));
+
+ /* Write to ADCx CR2 */
+ ADCx->CR2 = tmpreg1;
+ /*---------------------------- ADCx SQR1 Configuration -----------------*/
+ /* Get the ADCx SQR1 value */
+ tmpreg1 = ADCx->SQR1;
+
+ /* Clear L bits */
+ tmpreg1 &= SQR1_L_RESET;
+
+ /* Configure ADCx: regular channel sequence length */
+ /* Set L bits according to ADC_NbrOfConversion value */
+ tmpreg2 |= (uint8_t)(ADC_InitStruct->ADC_NbrOfConversion - (uint8_t)1);
+ tmpreg1 |= ((uint32_t)tmpreg2 << 20);
+
+ /* Write to ADCx SQR1 */
+ ADCx->SQR1 = tmpreg1;
+}
+
+/**
+ * @brief Fills each ADC_InitStruct member with its default value.
+ * @note This function is used to initialize the global features of the ADC (
+ * Resolution and Data Alignment), however, the rest of the configuration
+ * parameters are specific to the regular channels group (scan mode
+ * activation, continuous mode activation, External trigger source and
+ * edge, number of conversion in the regular channels group sequencer).
+ * @param ADC_InitStruct: pointer to an ADC_InitTypeDef structure which will
+ * be initialized.
+ * @retval None
+ */
+void ADC_StructInit(ADC_InitTypeDef* ADC_InitStruct)
+{
+ /* Initialize the ADC_Mode member */
+ ADC_InitStruct->ADC_Resolution = ADC_Resolution_12b;
+
+ /* initialize the ADC_ScanConvMode member */
+ ADC_InitStruct->ADC_ScanConvMode = DISABLE;
+
+ /* Initialize the ADC_ContinuousConvMode member */
+ ADC_InitStruct->ADC_ContinuousConvMode = DISABLE;
+
+ /* Initialize the ADC_ExternalTrigConvEdge member */
+ ADC_InitStruct->ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
+
+ /* Initialize the ADC_ExternalTrigConv member */
+ ADC_InitStruct->ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;
+
+ /* Initialize the ADC_DataAlign member */
+ ADC_InitStruct->ADC_DataAlign = ADC_DataAlign_Right;
+
+ /* Initialize the ADC_NbrOfConversion member */
+ ADC_InitStruct->ADC_NbrOfConversion = 1;
+}
+
+/**
+ * @brief Initializes the ADCs peripherals according to the specified parameters
+ * in the ADC_CommonInitStruct.
+ * @param ADC_CommonInitStruct: pointer to an ADC_CommonInitTypeDef structure
+ * that contains the configuration information for All ADCs peripherals.
+ * @retval None
+ */
+void ADC_CommonInit(ADC_CommonInitTypeDef* ADC_CommonInitStruct)
+{
+ uint32_t tmpreg1 = 0;
+ /* Check the parameters */
+ assert_param(IS_ADC_MODE(ADC_CommonInitStruct->ADC_Mode));
+ assert_param(IS_ADC_PRESCALER(ADC_CommonInitStruct->ADC_Prescaler));
+ assert_param(IS_ADC_DMA_ACCESS_MODE(ADC_CommonInitStruct->ADC_DMAAccessMode));
+ assert_param(IS_ADC_SAMPLING_DELAY(ADC_CommonInitStruct->ADC_TwoSamplingDelay));
+ /*---------------------------- ADC CCR Configuration -----------------*/
+ /* Get the ADC CCR value */
+ tmpreg1 = ADC->CCR;
+
+ /* Clear MULTI, DELAY, DMA and ADCPRE bits */
+ tmpreg1 &= CR_CLEAR_MASK;
+
+ /* Configure ADCx: Multi mode, Delay between two sampling time, ADC prescaler,
+ and DMA access mode for multimode */
+ /* Set MULTI bits according to ADC_Mode value */
+ /* Set ADCPRE bits according to ADC_Prescaler value */
+ /* Set DMA bits according to ADC_DMAAccessMode value */
+ /* Set DELAY bits according to ADC_TwoSamplingDelay value */
+ tmpreg1 |= (uint32_t)(ADC_CommonInitStruct->ADC_Mode |
+ ADC_CommonInitStruct->ADC_Prescaler |
+ ADC_CommonInitStruct->ADC_DMAAccessMode |
+ ADC_CommonInitStruct->ADC_TwoSamplingDelay);
+
+ /* Write to ADC CCR */
+ ADC->CCR = tmpreg1;
+}
+
+/**
+ * @brief Fills each ADC_CommonInitStruct member with its default value.
+ * @param ADC_CommonInitStruct: pointer to an ADC_CommonInitTypeDef structure
+ * which will be initialized.
+ * @retval None
+ */
+void ADC_CommonStructInit(ADC_CommonInitTypeDef* ADC_CommonInitStruct)
+{
+ /* Initialize the ADC_Mode member */
+ ADC_CommonInitStruct->ADC_Mode = ADC_Mode_Independent;
+
+ /* initialize the ADC_Prescaler member */
+ ADC_CommonInitStruct->ADC_Prescaler = ADC_Prescaler_Div2;
+
+ /* Initialize the ADC_DMAAccessMode member */
+ ADC_CommonInitStruct->ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
+
+ /* Initialize the ADC_TwoSamplingDelay member */
+ ADC_CommonInitStruct->ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
+}
+
+/**
+ * @brief Enables or disables the specified ADC peripheral.
+ * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral.
+ * @param NewState: new state of the ADCx peripheral.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void ADC_Cmd(ADC_TypeDef* ADCx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ if (NewState != DISABLE)
+ {
+ /* Set the ADON bit to wake up the ADC from power down mode */
+ ADCx->CR2 |= (uint32_t)ADC_CR2_ADON;
+ }
+ else
+ {
+ /* Disable the selected ADC peripheral */
+ ADCx->CR2 &= (uint32_t)(~ADC_CR2_ADON);
+ }
+}
+/**
+ * @}
+ */
+
+/** @defgroup ADC_Group2 Analog Watchdog configuration functions
+ * @brief Analog Watchdog configuration functions
+ *
+@verbatim
+ ===============================================================================
+ Analog Watchdog configuration functions
+ ===============================================================================
+
+ This section provides functions allowing to configure the Analog Watchdog
+ (AWD) feature in the ADC.
+
+ A typical configuration Analog Watchdog is done following these steps :
+ 1. the ADC guarded channel(s) is (are) selected using the
+ ADC_AnalogWatchdogSingleChannelConfig() function.
+ 2. The Analog watchdog lower and higher threshold are configured using the
+ ADC_AnalogWatchdogThresholdsConfig() function.
+ 3. The Analog watchdog is enabled and configured to enable the check, on one
+ or more channels, using the ADC_AnalogWatchdogCmd() function.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Enables or disables the analog watchdog on single/all regular or
+ * injected channels
+ * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral.
+ * @param ADC_AnalogWatchdog: the ADC analog watchdog configuration.
+ * This parameter can be one of the following values:
+ * @arg ADC_AnalogWatchdog_SingleRegEnable: Analog watchdog on a single regular channel
+ * @arg ADC_AnalogWatchdog_SingleInjecEnable: Analog watchdog on a single injected channel
+ * @arg ADC_AnalogWatchdog_SingleRegOrInjecEnable: Analog watchdog on a single regular or injected channel
+ * @arg ADC_AnalogWatchdog_AllRegEnable: Analog watchdog on all regular channel
+ * @arg ADC_AnalogWatchdog_AllInjecEnable: Analog watchdog on all injected channel
+ * @arg ADC_AnalogWatchdog_AllRegAllInjecEnable: Analog watchdog on all regular and injected channels
+ * @arg ADC_AnalogWatchdog_None: No channel guarded by the analog watchdog
+ * @retval None
+ */
+void ADC_AnalogWatchdogCmd(ADC_TypeDef* ADCx, uint32_t ADC_AnalogWatchdog)
+{
+ uint32_t tmpreg = 0;
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+ assert_param(IS_ADC_ANALOG_WATCHDOG(ADC_AnalogWatchdog));
+
+ /* Get the old register value */
+ tmpreg = ADCx->CR1;
+
+ /* Clear AWDEN, JAWDEN and AWDSGL bits */
+ tmpreg &= CR1_AWDMode_RESET;
+
+ /* Set the analog watchdog enable mode */
+ tmpreg |= ADC_AnalogWatchdog;
+
+ /* Store the new register value */
+ ADCx->CR1 = tmpreg;
+}
+
+/**
+ * @brief Configures the high and low thresholds of the analog watchdog.
+ * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral.
+ * @param HighThreshold: the ADC analog watchdog High threshold value.
+ * This parameter must be a 12-bit value.
+ * @param LowThreshold: the ADC analog watchdog Low threshold value.
+ * This parameter must be a 12-bit value.
+ * @retval None
+ */
+void ADC_AnalogWatchdogThresholdsConfig(ADC_TypeDef* ADCx, uint16_t HighThreshold,
+ uint16_t LowThreshold)
+{
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+ assert_param(IS_ADC_THRESHOLD(HighThreshold));
+ assert_param(IS_ADC_THRESHOLD(LowThreshold));
+
+ /* Set the ADCx high threshold */
+ ADCx->HTR = HighThreshold;
+
+ /* Set the ADCx low threshold */
+ ADCx->LTR = LowThreshold;
+}
+
+/**
+ * @brief Configures the analog watchdog guarded single channel
+ * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral.
+ * @param ADC_Channel: the ADC channel to configure for the analog watchdog.
+ * This parameter can be one of the following values:
+ * @arg ADC_Channel_0: ADC Channel0 selected
+ * @arg ADC_Channel_1: ADC Channel1 selected
+ * @arg ADC_Channel_2: ADC Channel2 selected
+ * @arg ADC_Channel_3: ADC Channel3 selected
+ * @arg ADC_Channel_4: ADC Channel4 selected
+ * @arg ADC_Channel_5: ADC Channel5 selected
+ * @arg ADC_Channel_6: ADC Channel6 selected
+ * @arg ADC_Channel_7: ADC Channel7 selected
+ * @arg ADC_Channel_8: ADC Channel8 selected
+ * @arg ADC_Channel_9: ADC Channel9 selected
+ * @arg ADC_Channel_10: ADC Channel10 selected
+ * @arg ADC_Channel_11: ADC Channel11 selected
+ * @arg ADC_Channel_12: ADC Channel12 selected
+ * @arg ADC_Channel_13: ADC Channel13 selected
+ * @arg ADC_Channel_14: ADC Channel14 selected
+ * @arg ADC_Channel_15: ADC Channel15 selected
+ * @arg ADC_Channel_16: ADC Channel16 selected
+ * @arg ADC_Channel_17: ADC Channel17 selected
+ * @arg ADC_Channel_18: ADC Channel18 selected
+ * @retval None
+ */
+void ADC_AnalogWatchdogSingleChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel)
+{
+ uint32_t tmpreg = 0;
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+ assert_param(IS_ADC_CHANNEL(ADC_Channel));
+
+ /* Get the old register value */
+ tmpreg = ADCx->CR1;
+
+ /* Clear the Analog watchdog channel select bits */
+ tmpreg &= CR1_AWDCH_RESET;
+
+ /* Set the Analog watchdog channel */
+ tmpreg |= ADC_Channel;
+
+ /* Store the new register value */
+ ADCx->CR1 = tmpreg;
+}
+/**
+ * @}
+ */
+
+/** @defgroup ADC_Group3 Temperature Sensor, Vrefint (Voltage Reference internal)
+ * and VBAT (Voltage BATtery) management functions
+ * @brief Temperature Sensor, Vrefint and VBAT management functions
+ *
+@verbatim
+ ===============================================================================
+ Temperature Sensor, Vrefint and VBAT management functions
+ ===============================================================================
+
+ This section provides functions allowing to enable/ disable the internal
+ connections between the ADC and the Temperature Sensor, the Vrefint and the
+ Vbat sources.
+
+ A typical configuration to get the Temperature sensor and Vrefint channels
+ voltages is done following these steps :
+ 1. Enable the internal connection of Temperature sensor and Vrefint sources
+ with the ADC channels using ADC_TempSensorVrefintCmd() function.
+ 2. Select the ADC_Channel_TempSensor and/or ADC_Channel_Vrefint using
+ ADC_RegularChannelConfig() or ADC_InjectedChannelConfig() functions
+ 3. Get the voltage values, using ADC_GetConversionValue() or
+ ADC_GetInjectedConversionValue().
+
+ A typical configuration to get the VBAT channel voltage is done following
+ these steps :
+ 1. Enable the internal connection of VBAT source with the ADC channel using
+ ADC_VBATCmd() function.
+ 2. Select the ADC_Channel_Vbat using ADC_RegularChannelConfig() or
+ ADC_InjectedChannelConfig() functions
+ 3. Get the voltage value, using ADC_GetConversionValue() or
+ ADC_GetInjectedConversionValue().
+
+@endverbatim
+ * @{
+ */
+
+
+/**
+ * @brief Enables or disables the temperature sensor and Vrefint channels.
+ * @param NewState: new state of the temperature sensor and Vrefint channels.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void ADC_TempSensorVrefintCmd(FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ if (NewState != DISABLE)
+ {
+ /* Enable the temperature sensor and Vrefint channel*/
+ ADC->CCR |= (uint32_t)ADC_CCR_TSVREFE;
+ }
+ else
+ {
+ /* Disable the temperature sensor and Vrefint channel*/
+ ADC->CCR &= (uint32_t)(~ADC_CCR_TSVREFE);
+ }
+}
+
+/**
+ * @brief Enables or disables the VBAT (Voltage Battery) channel.
+ * @param NewState: new state of the VBAT channel.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void ADC_VBATCmd(FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ if (NewState != DISABLE)
+ {
+ /* Enable the VBAT channel*/
+ ADC->CCR |= (uint32_t)ADC_CCR_VBATE;
+ }
+ else
+ {
+ /* Disable the VBAT channel*/
+ ADC->CCR &= (uint32_t)(~ADC_CCR_VBATE);
+ }
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup ADC_Group4 Regular Channels Configuration functions
+ * @brief Regular Channels Configuration functions
+ *
+@verbatim
+ ===============================================================================
+ Regular Channels Configuration functions
+ ===============================================================================
+
+ This section provides functions allowing to manage the ADC's regular channels,
+ it is composed of 2 sub sections :
+
+ 1. Configuration and management functions for regular channels: This subsection
+ provides functions allowing to configure the ADC regular channels :
+ - Configure the rank in the regular group sequencer for each channel
+ - Configure the sampling time for each channel
+ - select the conversion Trigger for regular channels
+ - select the desired EOC event behavior configuration
+ - Activate the continuous Mode (*)
+ - Activate the Discontinuous Mode
+ Please Note that the following features for regular channels are configurated
+ using the ADC_Init() function :
+ - scan mode activation
+ - continuous mode activation (**)
+ - External trigger source
+ - External trigger edge
+ - number of conversion in the regular channels group sequencer.
+
+ @note (*) and (**) are performing the same configuration
+
+ 2. Get the conversion data: This subsection provides an important function in
+ the ADC peripheral since it returns the converted data of the current
+ regular channel. When the Conversion value is read, the EOC Flag is
+ automatically cleared.
+
+ @note For multi ADC mode, the last ADC1, ADC2 and ADC3 regular conversions
+ results data (in the selected multi mode) can be returned in the same
+ time using ADC_GetMultiModeConversionValue() function.
+
+
+@endverbatim
+ * @{
+ */
+/**
+ * @brief Configures for the selected ADC regular channel its corresponding
+ * rank in the sequencer and its sample time.
+ * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral.
+ * @param ADC_Channel: the ADC channel to configure.
+ * This parameter can be one of the following values:
+ * @arg ADC_Channel_0: ADC Channel0 selected
+ * @arg ADC_Channel_1: ADC Channel1 selected
+ * @arg ADC_Channel_2: ADC Channel2 selected
+ * @arg ADC_Channel_3: ADC Channel3 selected
+ * @arg ADC_Channel_4: ADC Channel4 selected
+ * @arg ADC_Channel_5: ADC Channel5 selected
+ * @arg ADC_Channel_6: ADC Channel6 selected
+ * @arg ADC_Channel_7: ADC Channel7 selected
+ * @arg ADC_Channel_8: ADC Channel8 selected
+ * @arg ADC_Channel_9: ADC Channel9 selected
+ * @arg ADC_Channel_10: ADC Channel10 selected
+ * @arg ADC_Channel_11: ADC Channel11 selected
+ * @arg ADC_Channel_12: ADC Channel12 selected
+ * @arg ADC_Channel_13: ADC Channel13 selected
+ * @arg ADC_Channel_14: ADC Channel14 selected
+ * @arg ADC_Channel_15: ADC Channel15 selected
+ * @arg ADC_Channel_16: ADC Channel16 selected
+ * @arg ADC_Channel_17: ADC Channel17 selected
+ * @arg ADC_Channel_18: ADC Channel18 selected
+ * @param Rank: The rank in the regular group sequencer.
+ * This parameter must be between 1 to 16.
+ * @param ADC_SampleTime: The sample time value to be set for the selected channel.
+ * This parameter can be one of the following values:
+ * @arg ADC_SampleTime_3Cycles: Sample time equal to 3 cycles
+ * @arg ADC_SampleTime_15Cycles: Sample time equal to 15 cycles
+ * @arg ADC_SampleTime_28Cycles: Sample time equal to 28 cycles
+ * @arg ADC_SampleTime_56Cycles: Sample time equal to 56 cycles
+ * @arg ADC_SampleTime_84Cycles: Sample time equal to 84 cycles
+ * @arg ADC_SampleTime_112Cycles: Sample time equal to 112 cycles
+ * @arg ADC_SampleTime_144Cycles: Sample time equal to 144 cycles
+ * @arg ADC_SampleTime_480Cycles: Sample time equal to 480 cycles
+ * @retval None
+ */
+void ADC_RegularChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime)
+{
+ uint32_t tmpreg1 = 0, tmpreg2 = 0;
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+ assert_param(IS_ADC_CHANNEL(ADC_Channel));
+ assert_param(IS_ADC_REGULAR_RANK(Rank));
+ assert_param(IS_ADC_SAMPLE_TIME(ADC_SampleTime));
+
+ /* if ADC_Channel_10 ... ADC_Channel_18 is selected */
+ if (ADC_Channel > ADC_Channel_9)
+ {
+ /* Get the old register value */
+ tmpreg1 = ADCx->SMPR1;
+
+ /* Calculate the mask to clear */
+ tmpreg2 = SMPR1_SMP_SET << (3 * (ADC_Channel - 10));
+
+ /* Clear the old sample time */
+ tmpreg1 &= ~tmpreg2;
+
+ /* Calculate the mask to set */
+ tmpreg2 = (uint32_t)ADC_SampleTime << (3 * (ADC_Channel - 10));
+
+ /* Set the new sample time */
+ tmpreg1 |= tmpreg2;
+
+ /* Store the new register value */
+ ADCx->SMPR1 = tmpreg1;
+ }
+ else /* ADC_Channel include in ADC_Channel_[0..9] */
+ {
+ /* Get the old register value */
+ tmpreg1 = ADCx->SMPR2;
+
+ /* Calculate the mask to clear */
+ tmpreg2 = SMPR2_SMP_SET << (3 * ADC_Channel);
+
+ /* Clear the old sample time */
+ tmpreg1 &= ~tmpreg2;
+
+ /* Calculate the mask to set */
+ tmpreg2 = (uint32_t)ADC_SampleTime << (3 * ADC_Channel);
+
+ /* Set the new sample time */
+ tmpreg1 |= tmpreg2;
+
+ /* Store the new register value */
+ ADCx->SMPR2 = tmpreg1;
+ }
+ /* For Rank 1 to 6 */
+ if (Rank < 7)
+ {
+ /* Get the old register value */
+ tmpreg1 = ADCx->SQR3;
+
+ /* Calculate the mask to clear */
+ tmpreg2 = SQR3_SQ_SET << (5 * (Rank - 1));
+
+ /* Clear the old SQx bits for the selected rank */
+ tmpreg1 &= ~tmpreg2;
+
+ /* Calculate the mask to set */
+ tmpreg2 = (uint32_t)ADC_Channel << (5 * (Rank - 1));
+
+ /* Set the SQx bits for the selected rank */
+ tmpreg1 |= tmpreg2;
+
+ /* Store the new register value */
+ ADCx->SQR3 = tmpreg1;
+ }
+ /* For Rank 7 to 12 */
+ else if (Rank < 13)
+ {
+ /* Get the old register value */
+ tmpreg1 = ADCx->SQR2;
+
+ /* Calculate the mask to clear */
+ tmpreg2 = SQR2_SQ_SET << (5 * (Rank - 7));
+
+ /* Clear the old SQx bits for the selected rank */
+ tmpreg1 &= ~tmpreg2;
+
+ /* Calculate the mask to set */
+ tmpreg2 = (uint32_t)ADC_Channel << (5 * (Rank - 7));
+
+ /* Set the SQx bits for the selected rank */
+ tmpreg1 |= tmpreg2;
+
+ /* Store the new register value */
+ ADCx->SQR2 = tmpreg1;
+ }
+ /* For Rank 13 to 16 */
+ else
+ {
+ /* Get the old register value */
+ tmpreg1 = ADCx->SQR1;
+
+ /* Calculate the mask to clear */
+ tmpreg2 = SQR1_SQ_SET << (5 * (Rank - 13));
+
+ /* Clear the old SQx bits for the selected rank */
+ tmpreg1 &= ~tmpreg2;
+
+ /* Calculate the mask to set */
+ tmpreg2 = (uint32_t)ADC_Channel << (5 * (Rank - 13));
+
+ /* Set the SQx bits for the selected rank */
+ tmpreg1 |= tmpreg2;
+
+ /* Store the new register value */
+ ADCx->SQR1 = tmpreg1;
+ }
+}
+
+/**
+ * @brief Enables the selected ADC software start conversion of the regular channels.
+ * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral.
+ * @retval None
+ */
+void ADC_SoftwareStartConv(ADC_TypeDef* ADCx)
+{
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+
+ /* Enable the selected ADC conversion for regular group */
+ ADCx->CR2 |= (uint32_t)ADC_CR2_SWSTART;
+}
+
+/**
+ * @brief Gets the selected ADC Software start regular conversion Status.
+ * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral.
+ * @retval The new state of ADC software start conversion (SET or RESET).
+ */
+FlagStatus ADC_GetSoftwareStartConvStatus(ADC_TypeDef* ADCx)
+{
+ FlagStatus bitstatus = RESET;
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+
+ /* Check the status of SWSTART bit */
+ if ((ADCx->CR2 & ADC_CR2_JSWSTART) != (uint32_t)RESET)
+ {
+ /* SWSTART bit is set */
+ bitstatus = SET;
+ }
+ else
+ {
+ /* SWSTART bit is reset */
+ bitstatus = RESET;
+ }
+
+ /* Return the SWSTART bit status */
+ return bitstatus;
+}
+
+
+/**
+ * @brief Enables or disables the EOC on each regular channel conversion
+ * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral.
+ * @param NewState: new state of the selected ADC EOC flag rising
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void ADC_EOCOnEachRegularChannelCmd(ADC_TypeDef* ADCx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the selected ADC EOC rising on each regular channel conversion */
+ ADCx->CR2 |= (uint32_t)ADC_CR2_EOCS;
+ }
+ else
+ {
+ /* Disable the selected ADC EOC rising on each regular channel conversion */
+ ADCx->CR2 &= (uint32_t)(~ADC_CR2_EOCS);
+ }
+}
+
+/**
+ * @brief Enables or disables the ADC continuous conversion mode
+ * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral.
+ * @param NewState: new state of the selected ADC continuous conversion mode
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void ADC_ContinuousModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the selected ADC continuous conversion mode */
+ ADCx->CR2 |= (uint32_t)ADC_CR2_CONT;
+ }
+ else
+ {
+ /* Disable the selected ADC continuous conversion mode */
+ ADCx->CR2 &= (uint32_t)(~ADC_CR2_CONT);
+ }
+}
+
+/**
+ * @brief Configures the discontinuous mode for the selected ADC regular group
+ * channel.
+ * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral.
+ * @param Number: specifies the discontinuous mode regular channel count value.
+ * This number must be between 1 and 8.
+ * @retval None
+ */
+void ADC_DiscModeChannelCountConfig(ADC_TypeDef* ADCx, uint8_t Number)
+{
+ uint32_t tmpreg1 = 0;
+ uint32_t tmpreg2 = 0;
+
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+ assert_param(IS_ADC_REGULAR_DISC_NUMBER(Number));
+
+ /* Get the old register value */
+ tmpreg1 = ADCx->CR1;
+
+ /* Clear the old discontinuous mode channel count */
+ tmpreg1 &= CR1_DISCNUM_RESET;
+
+ /* Set the discontinuous mode channel count */
+ tmpreg2 = Number - 1;
+ tmpreg1 |= tmpreg2 << 13;
+
+ /* Store the new register value */
+ ADCx->CR1 = tmpreg1;
+}
+
+/**
+ * @brief Enables or disables the discontinuous mode on regular group channel
+ * for the specified ADC
+ * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral.
+ * @param NewState: new state of the selected ADC discontinuous mode on
+ * regular group channel.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void ADC_DiscModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the selected ADC regular discontinuous mode */
+ ADCx->CR1 |= (uint32_t)ADC_CR1_DISCEN;
+ }
+ else
+ {
+ /* Disable the selected ADC regular discontinuous mode */
+ ADCx->CR1 &= (uint32_t)(~ADC_CR1_DISCEN);
+ }
+}
+
+/**
+ * @brief Returns the last ADCx conversion result data for regular channel.
+ * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral.
+ * @retval The Data conversion value.
+ */
+uint16_t ADC_GetConversionValue(ADC_TypeDef* ADCx)
+{
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+
+ /* Return the selected ADC conversion value */
+ return (uint16_t) ADCx->DR;
+}
+
+/**
+ * @brief Returns the last ADC1, ADC2 and ADC3 regular conversions results
+ * data in the selected multi mode.
+ * @param None
+ * @retval The Data conversion value.
+ * @note In dual mode, the value returned by this function is as following
+ * Data[15:0] : these bits contain the regular data of ADC1.
+ * Data[31:16]: these bits contain the regular data of ADC2.
+ * @note In triple mode, the value returned by this function is as following
+ * Data[15:0] : these bits contain alternatively the regular data of ADC1, ADC3 and ADC2.
+ * Data[31:16]: these bits contain alternatively the regular data of ADC2, ADC1 and ADC3.
+ */
+uint32_t ADC_GetMultiModeConversionValue(void)
+{
+ /* Return the multi mode conversion value */
+ return (*(__IO uint32_t *) CDR_ADDRESS);
+}
+/**
+ * @}
+ */
+
+/** @defgroup ADC_Group5 Regular Channels DMA Configuration functions
+ * @brief Regular Channels DMA Configuration functions
+ *
+@verbatim
+ ===============================================================================
+ Regular Channels DMA Configuration functions
+ ===============================================================================
+
+ This section provides functions allowing to configure the DMA for ADC regular
+ channels.
+ Since converted regular channel values are stored into a unique data register,
+ it is useful to use DMA for conversion of more than one regular channel. This
+ avoids the loss of the data already stored in the ADC Data register.
+
+ When the DMA mode is enabled (using the ADC_DMACmd() function), after each
+ conversion of a regular channel, a DMA request is generated.
+
+ Depending on the "DMA disable selection for Independent ADC mode"
+ configuration (using the ADC_DMARequestAfterLastTransferCmd() function),
+ at the end of the last DMA transfer, two possibilities are allowed:
+ - No new DMA request is issued to the DMA controller (feature DISABLED)
+ - Requests can continue to be generated (feature ENABLED).
+
+ Depending on the "DMA disable selection for multi ADC mode" configuration
+ (using the void ADC_MultiModeDMARequestAfterLastTransferCmd() function),
+ at the end of the last DMA transfer, two possibilities are allowed:
+ - No new DMA request is issued to the DMA controller (feature DISABLED)
+ - Requests can continue to be generated (feature ENABLED).
+
+@endverbatim
+ * @{
+ */
+
+ /**
+ * @brief Enables or disables the specified ADC DMA request.
+ * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral.
+ * @param NewState: new state of the selected ADC DMA transfer.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void ADC_DMACmd(ADC_TypeDef* ADCx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ if (NewState != DISABLE)
+ {
+ /* Enable the selected ADC DMA request */
+ ADCx->CR2 |= (uint32_t)ADC_CR2_DMA;
+ }
+ else
+ {
+ /* Disable the selected ADC DMA request */
+ ADCx->CR2 &= (uint32_t)(~ADC_CR2_DMA);
+ }
+}
+
+/**
+ * @brief Enables or disables the ADC DMA request after last transfer (Single-ADC mode)
+ * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral.
+ * @param NewState: new state of the selected ADC DMA request after last transfer.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void ADC_DMARequestAfterLastTransferCmd(ADC_TypeDef* ADCx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ if (NewState != DISABLE)
+ {
+ /* Enable the selected ADC DMA request after last transfer */
+ ADCx->CR2 |= (uint32_t)ADC_CR2_DDS;
+ }
+ else
+ {
+ /* Disable the selected ADC DMA request after last transfer */
+ ADCx->CR2 &= (uint32_t)(~ADC_CR2_DDS);
+ }
+}
+
+/**
+ * @brief Enables or disables the ADC DMA request after last transfer in multi ADC mode
+ * @param NewState: new state of the selected ADC DMA request after last transfer.
+ * This parameter can be: ENABLE or DISABLE.
+ * @note if Enabled, DMA requests are issued as long as data are converted and
+ * DMA mode for multi ADC mode (selected using ADC_CommonInit() function
+ * by ADC_CommonInitStruct.ADC_DMAAccessMode structure member) is
+ * ADC_DMAAccessMode_1, ADC_DMAAccessMode_2 or ADC_DMAAccessMode_3.
+ * @retval None
+ */
+void ADC_MultiModeDMARequestAfterLastTransferCmd(FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ if (NewState != DISABLE)
+ {
+ /* Enable the selected ADC DMA request after last transfer */
+ ADC->CCR |= (uint32_t)ADC_CCR_DDS;
+ }
+ else
+ {
+ /* Disable the selected ADC DMA request after last transfer */
+ ADC->CCR &= (uint32_t)(~ADC_CCR_DDS);
+ }
+}
+/**
+ * @}
+ */
+
+/** @defgroup ADC_Group6 Injected channels Configuration functions
+ * @brief Injected channels Configuration functions
+ *
+@verbatim
+ ===============================================================================
+ Injected channels Configuration functions
+ ===============================================================================
+
+ This section provide functions allowing to configure the ADC Injected channels,
+ it is composed of 2 sub sections :
+
+ 1. Configuration functions for Injected channels: This subsection provides
+ functions allowing to configure the ADC injected channels :
+ - Configure the rank in the injected group sequencer for each channel
+ - Configure the sampling time for each channel
+ - Activate the Auto injected Mode
+ - Activate the Discontinuous Mode
+ - scan mode activation
+ - External/software trigger source
+ - External trigger edge
+ - injected channels sequencer.
+
+ 2. Get the Specified Injected channel conversion data: This subsection
+ provides an important function in the ADC peripheral since it returns the
+ converted data of the specific injected channel.
+
+@endverbatim
+ * @{
+ */
+/**
+ * @brief Configures for the selected ADC injected channel its corresponding
+ * rank in the sequencer and its sample time.
+ * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral.
+ * @param ADC_Channel: the ADC channel to configure.
+ * This parameter can be one of the following values:
+ * @arg ADC_Channel_0: ADC Channel0 selected
+ * @arg ADC_Channel_1: ADC Channel1 selected
+ * @arg ADC_Channel_2: ADC Channel2 selected
+ * @arg ADC_Channel_3: ADC Channel3 selected
+ * @arg ADC_Channel_4: ADC Channel4 selected
+ * @arg ADC_Channel_5: ADC Channel5 selected
+ * @arg ADC_Channel_6: ADC Channel6 selected
+ * @arg ADC_Channel_7: ADC Channel7 selected
+ * @arg ADC_Channel_8: ADC Channel8 selected
+ * @arg ADC_Channel_9: ADC Channel9 selected
+ * @arg ADC_Channel_10: ADC Channel10 selected
+ * @arg ADC_Channel_11: ADC Channel11 selected
+ * @arg ADC_Channel_12: ADC Channel12 selected
+ * @arg ADC_Channel_13: ADC Channel13 selected
+ * @arg ADC_Channel_14: ADC Channel14 selected
+ * @arg ADC_Channel_15: ADC Channel15 selected
+ * @arg ADC_Channel_16: ADC Channel16 selected
+ * @arg ADC_Channel_17: ADC Channel17 selected
+ * @arg ADC_Channel_18: ADC Channel18 selected
+ * @param Rank: The rank in the injected group sequencer.
+ * This parameter must be between 1 to 4.
+ * @param ADC_SampleTime: The sample time value to be set for the selected channel.
+ * This parameter can be one of the following values:
+ * @arg ADC_SampleTime_3Cycles: Sample time equal to 3 cycles
+ * @arg ADC_SampleTime_15Cycles: Sample time equal to 15 cycles
+ * @arg ADC_SampleTime_28Cycles: Sample time equal to 28 cycles
+ * @arg ADC_SampleTime_56Cycles: Sample time equal to 56 cycles
+ * @arg ADC_SampleTime_84Cycles: Sample time equal to 84 cycles
+ * @arg ADC_SampleTime_112Cycles: Sample time equal to 112 cycles
+ * @arg ADC_SampleTime_144Cycles: Sample time equal to 144 cycles
+ * @arg ADC_SampleTime_480Cycles: Sample time equal to 480 cycles
+ * @retval None
+ */
+void ADC_InjectedChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime)
+{
+ uint32_t tmpreg1 = 0, tmpreg2 = 0, tmpreg3 = 0;
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+ assert_param(IS_ADC_CHANNEL(ADC_Channel));
+ assert_param(IS_ADC_INJECTED_RANK(Rank));
+ assert_param(IS_ADC_SAMPLE_TIME(ADC_SampleTime));
+ /* if ADC_Channel_10 ... ADC_Channel_18 is selected */
+ if (ADC_Channel > ADC_Channel_9)
+ {
+ /* Get the old register value */
+ tmpreg1 = ADCx->SMPR1;
+ /* Calculate the mask to clear */
+ tmpreg2 = SMPR1_SMP_SET << (3*(ADC_Channel - 10));
+ /* Clear the old sample time */
+ tmpreg1 &= ~tmpreg2;
+ /* Calculate the mask to set */
+ tmpreg2 = (uint32_t)ADC_SampleTime << (3*(ADC_Channel - 10));
+ /* Set the new sample time */
+ tmpreg1 |= tmpreg2;
+ /* Store the new register value */
+ ADCx->SMPR1 = tmpreg1;
+ }
+ else /* ADC_Channel include in ADC_Channel_[0..9] */
+ {
+ /* Get the old register value */
+ tmpreg1 = ADCx->SMPR2;
+ /* Calculate the mask to clear */
+ tmpreg2 = SMPR2_SMP_SET << (3 * ADC_Channel);
+ /* Clear the old sample time */
+ tmpreg1 &= ~tmpreg2;
+ /* Calculate the mask to set */
+ tmpreg2 = (uint32_t)ADC_SampleTime << (3 * ADC_Channel);
+ /* Set the new sample time */
+ tmpreg1 |= tmpreg2;
+ /* Store the new register value */
+ ADCx->SMPR2 = tmpreg1;
+ }
+ /* Rank configuration */
+ /* Get the old register value */
+ tmpreg1 = ADCx->JSQR;
+ /* Get JL value: Number = JL+1 */
+ tmpreg3 = (tmpreg1 & JSQR_JL_SET)>> 20;
+ /* Calculate the mask to clear: ((Rank-1)+(4-JL-1)) */
+ tmpreg2 = JSQR_JSQ_SET << (5 * (uint8_t)((Rank + 3) - (tmpreg3 + 1)));
+ /* Clear the old JSQx bits for the selected rank */
+ tmpreg1 &= ~tmpreg2;
+ /* Calculate the mask to set: ((Rank-1)+(4-JL-1)) */
+ tmpreg2 = (uint32_t)ADC_Channel << (5 * (uint8_t)((Rank + 3) - (tmpreg3 + 1)));
+ /* Set the JSQx bits for the selected rank */
+ tmpreg1 |= tmpreg2;
+ /* Store the new register value */
+ ADCx->JSQR = tmpreg1;
+}
+
+/**
+ * @brief Configures the sequencer length for injected channels
+ * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral.
+ * @param Length: The sequencer length.
+ * This parameter must be a number between 1 to 4.
+ * @retval None
+ */
+void ADC_InjectedSequencerLengthConfig(ADC_TypeDef* ADCx, uint8_t Length)
+{
+ uint32_t tmpreg1 = 0;
+ uint32_t tmpreg2 = 0;
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+ assert_param(IS_ADC_INJECTED_LENGTH(Length));
+
+ /* Get the old register value */
+ tmpreg1 = ADCx->JSQR;
+
+ /* Clear the old injected sequence length JL bits */
+ tmpreg1 &= JSQR_JL_RESET;
+
+ /* Set the injected sequence length JL bits */
+ tmpreg2 = Length - 1;
+ tmpreg1 |= tmpreg2 << 20;
+
+ /* Store the new register value */
+ ADCx->JSQR = tmpreg1;
+}
+
+/**
+ * @brief Set the injected channels conversion value offset
+ * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral.
+ * @param ADC_InjectedChannel: the ADC injected channel to set its offset.
+ * This parameter can be one of the following values:
+ * @arg ADC_InjectedChannel_1: Injected Channel1 selected
+ * @arg ADC_InjectedChannel_2: Injected Channel2 selected
+ * @arg ADC_InjectedChannel_3: Injected Channel3 selected
+ * @arg ADC_InjectedChannel_4: Injected Channel4 selected
+ * @param Offset: the offset value for the selected ADC injected channel
+ * This parameter must be a 12bit value.
+ * @retval None
+ */
+void ADC_SetInjectedOffset(ADC_TypeDef* ADCx, uint8_t ADC_InjectedChannel, uint16_t Offset)
+{
+ __IO uint32_t tmp = 0;
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+ assert_param(IS_ADC_INJECTED_CHANNEL(ADC_InjectedChannel));
+ assert_param(IS_ADC_OFFSET(Offset));
+
+ tmp = (uint32_t)ADCx;
+ tmp += ADC_InjectedChannel;
+
+ /* Set the selected injected channel data offset */
+ *(__IO uint32_t *) tmp = (uint32_t)Offset;
+}
+
+ /**
+ * @brief Configures the ADCx external trigger for injected channels conversion.
+ * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral.
+ * @param ADC_ExternalTrigInjecConv: specifies the ADC trigger to start injected conversion.
+ * This parameter can be one of the following values:
+ * @arg ADC_ExternalTrigInjecConv_T1_CC4: Timer1 capture compare4 selected
+ * @arg ADC_ExternalTrigInjecConv_T1_TRGO: Timer1 TRGO event selected
+ * @arg ADC_ExternalTrigInjecConv_T2_CC1: Timer2 capture compare1 selected
+ * @arg ADC_ExternalTrigInjecConv_T2_TRGO: Timer2 TRGO event selected
+ * @arg ADC_ExternalTrigInjecConv_T3_CC2: Timer3 capture compare2 selected
+ * @arg ADC_ExternalTrigInjecConv_T3_CC4: Timer3 capture compare4 selected
+ * @arg ADC_ExternalTrigInjecConv_T4_CC1: Timer4 capture compare1 selected
+ * @arg ADC_ExternalTrigInjecConv_T4_CC2: Timer4 capture compare2 selected
+ * @arg ADC_ExternalTrigInjecConv_T4_CC3: Timer4 capture compare3 selected
+ * @arg ADC_ExternalTrigInjecConv_T4_TRGO: Timer4 TRGO event selected
+ * @arg ADC_ExternalTrigInjecConv_T5_CC4: Timer5 capture compare4 selected
+ * @arg ADC_ExternalTrigInjecConv_T5_TRGO: Timer5 TRGO event selected
+ * @arg ADC_ExternalTrigInjecConv_T8_CC2: Timer8 capture compare2 selected
+ * @arg ADC_ExternalTrigInjecConv_T8_CC3: Timer8 capture compare3 selected
+ * @arg ADC_ExternalTrigInjecConv_T8_CC4: Timer8 capture compare4 selected
+ * @arg ADC_ExternalTrigInjecConv_Ext_IT15: External interrupt line 15 event selected
+ * @retval None
+ */
+void ADC_ExternalTrigInjectedConvConfig(ADC_TypeDef* ADCx, uint32_t ADC_ExternalTrigInjecConv)
+{
+ uint32_t tmpreg = 0;
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+ assert_param(IS_ADC_EXT_INJEC_TRIG(ADC_ExternalTrigInjecConv));
+
+ /* Get the old register value */
+ tmpreg = ADCx->CR2;
+
+ /* Clear the old external event selection for injected group */
+ tmpreg &= CR2_JEXTSEL_RESET;
+
+ /* Set the external event selection for injected group */
+ tmpreg |= ADC_ExternalTrigInjecConv;
+
+ /* Store the new register value */
+ ADCx->CR2 = tmpreg;
+}
+
+/**
+ * @brief Configures the ADCx external trigger edge for injected channels conversion.
+ * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral.
+ * @param ADC_ExternalTrigInjecConvEdge: specifies the ADC external trigger edge
+ * to start injected conversion.
+ * This parameter can be one of the following values:
+ * @arg ADC_ExternalTrigInjecConvEdge_None: external trigger disabled for
+ * injected conversion
+ * @arg ADC_ExternalTrigInjecConvEdge_Rising: detection on rising edge
+ * @arg ADC_ExternalTrigInjecConvEdge_Falling: detection on falling edge
+ * @arg ADC_ExternalTrigInjecConvEdge_RisingFalling: detection on both rising
+ * and falling edge
+ * @retval None
+ */
+void ADC_ExternalTrigInjectedConvEdgeConfig(ADC_TypeDef* ADCx, uint32_t ADC_ExternalTrigInjecConvEdge)
+{
+ uint32_t tmpreg = 0;
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+ assert_param(IS_ADC_EXT_INJEC_TRIG_EDGE(ADC_ExternalTrigInjecConvEdge));
+ /* Get the old register value */
+ tmpreg = ADCx->CR2;
+ /* Clear the old external trigger edge for injected group */
+ tmpreg &= CR2_JEXTEN_RESET;
+ /* Set the new external trigger edge for injected group */
+ tmpreg |= ADC_ExternalTrigInjecConvEdge;
+ /* Store the new register value */
+ ADCx->CR2 = tmpreg;
+}
+
+/**
+ * @brief Enables the selected ADC software start conversion of the injected channels.
+ * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral.
+ * @retval None
+ */
+void ADC_SoftwareStartInjectedConv(ADC_TypeDef* ADCx)
+{
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+ /* Enable the selected ADC conversion for injected group */
+ ADCx->CR2 |= (uint32_t)ADC_CR2_JSWSTART;
+}
+
+/**
+ * @brief Gets the selected ADC Software start injected conversion Status.
+ * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral.
+ * @retval The new state of ADC software start injected conversion (SET or RESET).
+ */
+FlagStatus ADC_GetSoftwareStartInjectedConvCmdStatus(ADC_TypeDef* ADCx)
+{
+ FlagStatus bitstatus = RESET;
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+
+ /* Check the status of JSWSTART bit */
+ if ((ADCx->CR2 & ADC_CR2_JSWSTART) != (uint32_t)RESET)
+ {
+ /* JSWSTART bit is set */
+ bitstatus = SET;
+ }
+ else
+ {
+ /* JSWSTART bit is reset */
+ bitstatus = RESET;
+ }
+ /* Return the JSWSTART bit status */
+ return bitstatus;
+}
+
+/**
+ * @brief Enables or disables the selected ADC automatic injected group
+ * conversion after regular one.
+ * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral.
+ * @param NewState: new state of the selected ADC auto injected conversion
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void ADC_AutoInjectedConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ if (NewState != DISABLE)
+ {
+ /* Enable the selected ADC automatic injected group conversion */
+ ADCx->CR1 |= (uint32_t)ADC_CR1_JAUTO;
+ }
+ else
+ {
+ /* Disable the selected ADC automatic injected group conversion */
+ ADCx->CR1 &= (uint32_t)(~ADC_CR1_JAUTO);
+ }
+}
+
+/**
+ * @brief Enables or disables the discontinuous mode for injected group
+ * channel for the specified ADC
+ * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral.
+ * @param NewState: new state of the selected ADC discontinuous mode on injected
+ * group channel.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void ADC_InjectedDiscModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ if (NewState != DISABLE)
+ {
+ /* Enable the selected ADC injected discontinuous mode */
+ ADCx->CR1 |= (uint32_t)ADC_CR1_JDISCEN;
+ }
+ else
+ {
+ /* Disable the selected ADC injected discontinuous mode */
+ ADCx->CR1 &= (uint32_t)(~ADC_CR1_JDISCEN);
+ }
+}
+
+/**
+ * @brief Returns the ADC injected channel conversion result
+ * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral.
+ * @param ADC_InjectedChannel: the converted ADC injected channel.
+ * This parameter can be one of the following values:
+ * @arg ADC_InjectedChannel_1: Injected Channel1 selected
+ * @arg ADC_InjectedChannel_2: Injected Channel2 selected
+ * @arg ADC_InjectedChannel_3: Injected Channel3 selected
+ * @arg ADC_InjectedChannel_4: Injected Channel4 selected
+ * @retval The Data conversion value.
+ */
+uint16_t ADC_GetInjectedConversionValue(ADC_TypeDef* ADCx, uint8_t ADC_InjectedChannel)
+{
+ __IO uint32_t tmp = 0;
+
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+ assert_param(IS_ADC_INJECTED_CHANNEL(ADC_InjectedChannel));
+
+ tmp = (uint32_t)ADCx;
+ tmp += ADC_InjectedChannel + JDR_OFFSET;
+
+ /* Returns the selected injected channel conversion data value */
+ return (uint16_t) (*(__IO uint32_t*) tmp);
+}
+/**
+ * @}
+ */
+
+/** @defgroup ADC_Group7 Interrupts and flags management functions
+ * @brief Interrupts and flags management functions
+ *
+@verbatim
+ ===============================================================================
+ Interrupts and flags management functions
+ ===============================================================================
+
+ This section provides functions allowing to configure the ADC Interrupts and
+ to get the status and clear flags and Interrupts pending bits.
+
+ Each ADC provides 4 Interrupts sources and 6 Flags which can be divided into
+ 3 groups:
+
+ I. Flags and Interrupts for ADC regular channels
+ =================================================
+ Flags :
+ ----------
+ 1. ADC_FLAG_OVR : Overrun detection when regular converted data are lost
+
+ 2. ADC_FLAG_EOC : Regular channel end of conversion ==> to indicate (depending
+ on EOCS bit, managed by ADC_EOCOnEachRegularChannelCmd() ) the end of:
+ ==> a regular CHANNEL conversion
+ ==> sequence of regular GROUP conversions .
+
+ 3. ADC_FLAG_STRT: Regular channel start ==> to indicate when regular CHANNEL
+ conversion starts.
+
+ Interrupts :
+ ------------
+ 1. ADC_IT_OVR : specifies the interrupt source for Overrun detection event.
+ 2. ADC_IT_EOC : specifies the interrupt source for Regular channel end of
+ conversion event.
+
+
+ II. Flags and Interrupts for ADC Injected channels
+ =================================================
+ Flags :
+ ----------
+ 1. ADC_FLAG_JEOC : Injected channel end of conversion ==> to indicate at
+ the end of injected GROUP conversion
+
+ 2. ADC_FLAG_JSTRT: Injected channel start ==> to indicate hardware when
+ injected GROUP conversion starts.
+
+ Interrupts :
+ ------------
+ 1. ADC_IT_JEOC : specifies the interrupt source for Injected channel end of
+ conversion event.
+
+ III. General Flags and Interrupts for the ADC
+ =================================================
+ Flags :
+ ----------
+ 1. ADC_FLAG_AWD: Analog watchdog ==> to indicate if the converted voltage
+ crosses the programmed thresholds values.
+
+ Interrupts :
+ ------------
+ 1. ADC_IT_AWD : specifies the interrupt source for Analog watchdog event.
+
+
+ The user should identify which mode will be used in his application to manage
+ the ADC controller events: Polling mode or Interrupt mode.
+
+ In the Polling Mode it is advised to use the following functions:
+ - ADC_GetFlagStatus() : to check if flags events occur.
+ - ADC_ClearFlag() : to clear the flags events.
+
+ In the Interrupt Mode it is advised to use the following functions:
+ - ADC_ITConfig() : to enable or disable the interrupt source.
+ - ADC_GetITStatus() : to check if Interrupt occurs.
+ - ADC_ClearITPendingBit() : to clear the Interrupt pending Bit
+ (corresponding Flag).
+@endverbatim
+ * @{
+ */
+/**
+ * @brief Enables or disables the specified ADC interrupts.
+ * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral.
+ * @param ADC_IT: specifies the ADC interrupt sources to be enabled or disabled.
+ * This parameter can be one of the following values:
+ * @arg ADC_IT_EOC: End of conversion interrupt mask
+ * @arg ADC_IT_AWD: Analog watchdog interrupt mask
+ * @arg ADC_IT_JEOC: End of injected conversion interrupt mask
+ * @arg ADC_IT_OVR: Overrun interrupt enable
+ * @param NewState: new state of the specified ADC interrupts.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void ADC_ITConfig(ADC_TypeDef* ADCx, uint16_t ADC_IT, FunctionalState NewState)
+{
+ uint32_t itmask = 0;
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ assert_param(IS_ADC_IT(ADC_IT));
+
+ /* Get the ADC IT index */
+ itmask = (uint8_t)ADC_IT;
+ itmask = (uint32_t)0x01 << itmask;
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the selected ADC interrupts */
+ ADCx->CR1 |= itmask;
+ }
+ else
+ {
+ /* Disable the selected ADC interrupts */
+ ADCx->CR1 &= (~(uint32_t)itmask);
+ }
+}
+
+/**
+ * @brief Checks whether the specified ADC flag is set or not.
+ * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral.
+ * @param ADC_FLAG: specifies the flag to check.
+ * This parameter can be one of the following values:
+ * @arg ADC_FLAG_AWD: Analog watchdog flag
+ * @arg ADC_FLAG_EOC: End of conversion flag
+ * @arg ADC_FLAG_JEOC: End of injected group conversion flag
+ * @arg ADC_FLAG_JSTRT: Start of injected group conversion flag
+ * @arg ADC_FLAG_STRT: Start of regular group conversion flag
+ * @arg ADC_FLAG_OVR: Overrun flag
+ * @retval The new state of ADC_FLAG (SET or RESET).
+ */
+FlagStatus ADC_GetFlagStatus(ADC_TypeDef* ADCx, uint8_t ADC_FLAG)
+{
+ FlagStatus bitstatus = RESET;
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+ assert_param(IS_ADC_GET_FLAG(ADC_FLAG));
+
+ /* Check the status of the specified ADC flag */
+ if ((ADCx->SR & ADC_FLAG) != (uint8_t)RESET)
+ {
+ /* ADC_FLAG is set */
+ bitstatus = SET;
+ }
+ else
+ {
+ /* ADC_FLAG is reset */
+ bitstatus = RESET;
+ }
+ /* Return the ADC_FLAG status */
+ return bitstatus;
+}
+
+/**
+ * @brief Clears the ADCx's pending flags.
+ * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral.
+ * @param ADC_FLAG: specifies the flag to clear.
+ * This parameter can be any combination of the following values:
+ * @arg ADC_FLAG_AWD: Analog watchdog flag
+ * @arg ADC_FLAG_EOC: End of conversion flag
+ * @arg ADC_FLAG_JEOC: End of injected group conversion flag
+ * @arg ADC_FLAG_JSTRT: Start of injected group conversion flag
+ * @arg ADC_FLAG_STRT: Start of regular group conversion flag
+ * @arg ADC_FLAG_OVR: Overrun flag
+ * @retval None
+ */
+void ADC_ClearFlag(ADC_TypeDef* ADCx, uint8_t ADC_FLAG)
+{
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+ assert_param(IS_ADC_CLEAR_FLAG(ADC_FLAG));
+
+ /* Clear the selected ADC flags */
+ ADCx->SR = ~(uint32_t)ADC_FLAG;
+}
+
+/**
+ * @brief Checks whether the specified ADC interrupt has occurred or not.
+ * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral.
+ * @param ADC_IT: specifies the ADC interrupt source to check.
+ * This parameter can be one of the following values:
+ * @arg ADC_IT_EOC: End of conversion interrupt mask
+ * @arg ADC_IT_AWD: Analog watchdog interrupt mask
+ * @arg ADC_IT_JEOC: End of injected conversion interrupt mask
+ * @arg ADC_IT_OVR: Overrun interrupt mask
+ * @retval The new state of ADC_IT (SET or RESET).
+ */
+ITStatus ADC_GetITStatus(ADC_TypeDef* ADCx, uint16_t ADC_IT)
+{
+ ITStatus bitstatus = RESET;
+ uint32_t itmask = 0, enablestatus = 0;
+
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+ assert_param(IS_ADC_IT(ADC_IT));
+
+ /* Get the ADC IT index */
+ itmask = ADC_IT >> 8;
+
+ /* Get the ADC_IT enable bit status */
+ enablestatus = (ADCx->CR1 & ((uint32_t)0x01 << (uint8_t)ADC_IT)) ;
+
+ /* Check the status of the specified ADC interrupt */
+ if (((ADCx->SR & itmask) != (uint32_t)RESET) && enablestatus)
+ {
+ /* ADC_IT is set */
+ bitstatus = SET;
+ }
+ else
+ {
+ /* ADC_IT is reset */
+ bitstatus = RESET;
+ }
+ /* Return the ADC_IT status */
+ return bitstatus;
+}
+
+/**
+ * @brief Clears the ADCx's interrupt pending bits.
+ * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral.
+ * @param ADC_IT: specifies the ADC interrupt pending bit to clear.
+ * This parameter can be one of the following values:
+ * @arg ADC_IT_EOC: End of conversion interrupt mask
+ * @arg ADC_IT_AWD: Analog watchdog interrupt mask
+ * @arg ADC_IT_JEOC: End of injected conversion interrupt mask
+ * @arg ADC_IT_OVR: Overrun interrupt mask
+ * @retval None
+ */
+void ADC_ClearITPendingBit(ADC_TypeDef* ADCx, uint16_t ADC_IT)
+{
+ uint8_t itmask = 0;
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+ assert_param(IS_ADC_IT(ADC_IT));
+ /* Get the ADC IT index */
+ itmask = (uint8_t)(ADC_IT >> 8);
+ /* Clear the selected ADC interrupt pending bits */
+ ADCx->SR = ~(uint32_t)itmask;
+}
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/src/stm32f2xx_can.c b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/src/stm32f2xx_can.c
new file mode 100644
index 0000000..433a947
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/src/stm32f2xx_can.c
@@ -0,0 +1,1704 @@
+/**
+ ******************************************************************************
+ * @file stm32f2xx_can.c
+ * @author MCD Application Team
+ * @version V1.1.2
+ * @date 05-March-2012
+ * @brief This file provides firmware functions to manage the following
+ * functionalities of the Controller area network (CAN) peripheral:
+ * - Initialization and Configuration
+ * - CAN Frames Transmission
+ * - CAN Frames Reception
+ * - Operation modes switch
+ * - Error management
+ * - Interrupts and flags
+ *
+ * @verbatim
+ *
+ * ===================================================================
+ * How to use this driver
+ * ===================================================================
+
+ * 1. Enable the CAN controller interface clock using
+ * RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE); for CAN1
+ * and RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN2, ENABLE); for CAN2
+ * @note In case you are using CAN2 only, you have to enable the CAN1 clock.
+ *
+ * 2. CAN pins configuration
+ * - Enable the clock for the CAN GPIOs using the following function:
+ * RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOx, ENABLE);
+ * - Connect the involved CAN pins to AF9 using the following function
+ * GPIO_PinAFConfig(GPIOx, GPIO_PinSourcex, GPIO_AF_CANx);
+ * - Configure these CAN pins in alternate function mode by calling
+ * the function GPIO_Init();
+ *
+ * 3. Initialise and configure the CAN using CAN_Init() and
+ * CAN_FilterInit() functions.
+ *
+ * 4. Transmit the desired CAN frame using CAN_Transmit() function.
+ *
+ * 5. Check the transmission of a CAN frame using CAN_TransmitStatus()
+ * function.
+ *
+ * 6. Cancel the transmission of a CAN frame using CAN_CancelTransmit()
+ * function.
+ *
+ * 7. Receive a CAN frame using CAN_Recieve() function.
+ *
+ * 8. Release the receive FIFOs using CAN_FIFORelease() function.
+ *
+ * 9. Return the number of pending received frames using
+ * CAN_MessagePending() function.
+ *
+ * 10. To control CAN events you can use one of the following two methods:
+ * - Check on CAN flags using the CAN_GetFlagStatus() function.
+ * - Use CAN interrupts through the function CAN_ITConfig() at
+ * initialization phase and CAN_GetITStatus() function into
+ * interrupt routines to check if the event has occurred or not.
+ * After checking on a flag you should clear it using CAN_ClearFlag()
+ * function. And after checking on an interrupt event you should
+ * clear it using CAN_ClearITPendingBit() function.
+ *
+ *
+ * @endverbatim
+ *
+ ******************************************************************************
+ * @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 "stm32f2xx_can.h"
+#include "stm32f2xx_rcc.h"
+
+/** @addtogroup STM32F2xx_StdPeriph_Driver
+ * @{
+ */
+
+/** @defgroup CAN
+ * @brief CAN driver modules
+ * @{
+ */
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+
+/* CAN Master Control Register bits */
+#define MCR_DBF ((uint32_t)0x00010000) /* software master reset */
+
+/* CAN Mailbox Transmit Request */
+#define TMIDxR_TXRQ ((uint32_t)0x00000001) /* Transmit mailbox request */
+
+/* CAN Filter Master Register bits */
+#define FMR_FINIT ((uint32_t)0x00000001) /* Filter init mode */
+
+/* Time out for INAK bit */
+#define INAK_TIMEOUT ((uint32_t)0x0000FFFF)
+/* Time out for SLAK bit */
+#define SLAK_TIMEOUT ((uint32_t)0x0000FFFF)
+
+/* Flags in TSR register */
+#define CAN_FLAGS_TSR ((uint32_t)0x08000000)
+/* Flags in RF1R register */
+#define CAN_FLAGS_RF1R ((uint32_t)0x04000000)
+/* Flags in RF0R register */
+#define CAN_FLAGS_RF0R ((uint32_t)0x02000000)
+/* Flags in MSR register */
+#define CAN_FLAGS_MSR ((uint32_t)0x01000000)
+/* Flags in ESR register */
+#define CAN_FLAGS_ESR ((uint32_t)0x00F00000)
+
+/* Mailboxes definition */
+#define CAN_TXMAILBOX_0 ((uint8_t)0x00)
+#define CAN_TXMAILBOX_1 ((uint8_t)0x01)
+#define CAN_TXMAILBOX_2 ((uint8_t)0x02)
+
+#define CAN_MODE_MASK ((uint32_t) 0x00000003)
+
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+static ITStatus CheckITStatus(uint32_t CAN_Reg, uint32_t It_Bit);
+
+/** @defgroup CAN_Private_Functions
+ * @{
+ */
+
+/** @defgroup CAN_Group1 Initialization and Configuration functions
+ * @brief Initialization and Configuration functions
+ *
+@verbatim
+ ===============================================================================
+ Initialization and Configuration functions
+ ===============================================================================
+ This section provides functions allowing to
+ - Initialize the CAN peripherals : Prescaler, operating mode, the maximum number
+ of time quanta to perform resynchronization, the number of time quanta in
+ Bit Segment 1 and 2 and many other modes.
+ Refer to @ref CAN_InitTypeDef for more details.
+ - Configures the CAN reception filter.
+ - Select the start bank filter for slave CAN.
+ - Enables or disables the Debug Freeze mode for CAN
+ - Enables or disables the CAN Time Trigger Operation communication mode
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Deinitializes the CAN peripheral registers to their default reset values.
+ * @param CANx: where x can be 1 or 2 to select the CAN peripheral.
+ * @retval None.
+ */
+void CAN_DeInit(CAN_TypeDef* CANx)
+{
+ /* Check the parameters */
+ assert_param(IS_CAN_ALL_PERIPH(CANx));
+
+ if (CANx == CAN1)
+ {
+ /* Enable CAN1 reset state */
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_CAN1, ENABLE);
+ /* Release CAN1 from reset state */
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_CAN1, DISABLE);
+ }
+ else
+ {
+ /* Enable CAN2 reset state */
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_CAN2, ENABLE);
+ /* Release CAN2 from reset state */
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_CAN2, DISABLE);
+ }
+}
+
+/**
+ * @brief Initializes the CAN peripheral according to the specified
+ * parameters in the CAN_InitStruct.
+ * @param CANx: where x can be 1 or 2 to select the CAN peripheral.
+ * @param CAN_InitStruct: pointer to a CAN_InitTypeDef structure that contains
+ * the configuration information for the CAN peripheral.
+ * @retval Constant indicates initialization succeed which will be
+ * CAN_InitStatus_Failed or CAN_InitStatus_Success.
+ */
+uint8_t CAN_Init(CAN_TypeDef* CANx, CAN_InitTypeDef* CAN_InitStruct)
+{
+ uint8_t InitStatus = CAN_InitStatus_Failed;
+ uint32_t wait_ack = 0x00000000;
+ /* Check the parameters */
+ assert_param(IS_CAN_ALL_PERIPH(CANx));
+ assert_param(IS_FUNCTIONAL_STATE(CAN_InitStruct->CAN_TTCM));
+ assert_param(IS_FUNCTIONAL_STATE(CAN_InitStruct->CAN_ABOM));
+ assert_param(IS_FUNCTIONAL_STATE(CAN_InitStruct->CAN_AWUM));
+ assert_param(IS_FUNCTIONAL_STATE(CAN_InitStruct->CAN_NART));
+ assert_param(IS_FUNCTIONAL_STATE(CAN_InitStruct->CAN_RFLM));
+ assert_param(IS_FUNCTIONAL_STATE(CAN_InitStruct->CAN_TXFP));
+ assert_param(IS_CAN_MODE(CAN_InitStruct->CAN_Mode));
+ assert_param(IS_CAN_SJW(CAN_InitStruct->CAN_SJW));
+ assert_param(IS_CAN_BS1(CAN_InitStruct->CAN_BS1));
+ assert_param(IS_CAN_BS2(CAN_InitStruct->CAN_BS2));
+ assert_param(IS_CAN_PRESCALER(CAN_InitStruct->CAN_Prescaler));
+
+ /* Exit from sleep mode */
+ CANx->MCR &= (~(uint32_t)CAN_MCR_SLEEP);
+
+ /* Request initialisation */
+ CANx->MCR |= CAN_MCR_INRQ ;
+
+ /* Wait the acknowledge */
+ while (((CANx->MSR & CAN_MSR_INAK) != CAN_MSR_INAK) && (wait_ack != INAK_TIMEOUT))
+ {
+ wait_ack++;
+ }
+
+ /* Check acknowledge */
+ if ((CANx->MSR & CAN_MSR_INAK) != CAN_MSR_INAK)
+ {
+ InitStatus = CAN_InitStatus_Failed;
+ }
+ else
+ {
+ /* Set the time triggered communication mode */
+ if (CAN_InitStruct->CAN_TTCM == ENABLE)
+ {
+ CANx->MCR |= CAN_MCR_TTCM;
+ }
+ else
+ {
+ CANx->MCR &= ~(uint32_t)CAN_MCR_TTCM;
+ }
+
+ /* Set the automatic bus-off management */
+ if (CAN_InitStruct->CAN_ABOM == ENABLE)
+ {
+ CANx->MCR |= CAN_MCR_ABOM;
+ }
+ else
+ {
+ CANx->MCR &= ~(uint32_t)CAN_MCR_ABOM;
+ }
+
+ /* Set the automatic wake-up mode */
+ if (CAN_InitStruct->CAN_AWUM == ENABLE)
+ {
+ CANx->MCR |= CAN_MCR_AWUM;
+ }
+ else
+ {
+ CANx->MCR &= ~(uint32_t)CAN_MCR_AWUM;
+ }
+
+ /* Set the no automatic retransmission */
+ if (CAN_InitStruct->CAN_NART == ENABLE)
+ {
+ CANx->MCR |= CAN_MCR_NART;
+ }
+ else
+ {
+ CANx->MCR &= ~(uint32_t)CAN_MCR_NART;
+ }
+
+ /* Set the receive FIFO locked mode */
+ if (CAN_InitStruct->CAN_RFLM == ENABLE)
+ {
+ CANx->MCR |= CAN_MCR_RFLM;
+ }
+ else
+ {
+ CANx->MCR &= ~(uint32_t)CAN_MCR_RFLM;
+ }
+
+ /* Set the transmit FIFO priority */
+ if (CAN_InitStruct->CAN_TXFP == ENABLE)
+ {
+ CANx->MCR |= CAN_MCR_TXFP;
+ }
+ else
+ {
+ CANx->MCR &= ~(uint32_t)CAN_MCR_TXFP;
+ }
+
+ /* Set the bit timing register */
+ CANx->BTR = (uint32_t)((uint32_t)CAN_InitStruct->CAN_Mode << 30) | \
+ ((uint32_t)CAN_InitStruct->CAN_SJW << 24) | \
+ ((uint32_t)CAN_InitStruct->CAN_BS1 << 16) | \
+ ((uint32_t)CAN_InitStruct->CAN_BS2 << 20) | \
+ ((uint32_t)CAN_InitStruct->CAN_Prescaler - 1);
+
+ /* Request leave initialisation */
+ CANx->MCR &= ~(uint32_t)CAN_MCR_INRQ;
+
+ /* Wait the acknowledge */
+ wait_ack = 0;
+
+ while (((CANx->MSR & CAN_MSR_INAK) == CAN_MSR_INAK) && (wait_ack != INAK_TIMEOUT))
+ {
+ wait_ack++;
+ }
+
+ /* ...and check acknowledged */
+ if ((CANx->MSR & CAN_MSR_INAK) == CAN_MSR_INAK)
+ {
+ InitStatus = CAN_InitStatus_Failed;
+ }
+ else
+ {
+ InitStatus = CAN_InitStatus_Success ;
+ }
+ }
+
+ /* At this step, return the status of initialization */
+ return InitStatus;
+}
+
+/**
+ * @brief Configures the CAN reception filter according to the specified
+ * parameters in the CAN_FilterInitStruct.
+ * @param CAN_FilterInitStruct: pointer to a CAN_FilterInitTypeDef structure that
+ * contains the configuration information.
+ * @retval None
+ */
+void CAN_FilterInit(CAN_FilterInitTypeDef* CAN_FilterInitStruct)
+{
+ uint32_t filter_number_bit_pos = 0;
+ /* Check the parameters */
+ assert_param(IS_CAN_FILTER_NUMBER(CAN_FilterInitStruct->CAN_FilterNumber));
+ assert_param(IS_CAN_FILTER_MODE(CAN_FilterInitStruct->CAN_FilterMode));
+ assert_param(IS_CAN_FILTER_SCALE(CAN_FilterInitStruct->CAN_FilterScale));
+ assert_param(IS_CAN_FILTER_FIFO(CAN_FilterInitStruct->CAN_FilterFIFOAssignment));
+ assert_param(IS_FUNCTIONAL_STATE(CAN_FilterInitStruct->CAN_FilterActivation));
+
+ filter_number_bit_pos = ((uint32_t)1) << CAN_FilterInitStruct->CAN_FilterNumber;
+
+ /* Initialisation mode for the filter */
+ CAN1->FMR |= FMR_FINIT;
+
+ /* Filter Deactivation */
+ CAN1->FA1R &= ~(uint32_t)filter_number_bit_pos;
+
+ /* Filter Scale */
+ if (CAN_FilterInitStruct->CAN_FilterScale == CAN_FilterScale_16bit)
+ {
+ /* 16-bit scale for the filter */
+ CAN1->FS1R &= ~(uint32_t)filter_number_bit_pos;
+
+ /* First 16-bit identifier and First 16-bit mask */
+ /* Or First 16-bit identifier and Second 16-bit identifier */
+ CAN1->sFilterRegister[CAN_FilterInitStruct->CAN_FilterNumber].FR1 =
+ ((0x0000FFFF & (uint32_t)CAN_FilterInitStruct->CAN_FilterMaskIdLow) << 16) |
+ (0x0000FFFF & (uint32_t)CAN_FilterInitStruct->CAN_FilterIdLow);
+
+ /* Second 16-bit identifier and Second 16-bit mask */
+ /* Or Third 16-bit identifier and Fourth 16-bit identifier */
+ CAN1->sFilterRegister[CAN_FilterInitStruct->CAN_FilterNumber].FR2 =
+ ((0x0000FFFF & (uint32_t)CAN_FilterInitStruct->CAN_FilterMaskIdHigh) << 16) |
+ (0x0000FFFF & (uint32_t)CAN_FilterInitStruct->CAN_FilterIdHigh);
+ }
+
+ if (CAN_FilterInitStruct->CAN_FilterScale == CAN_FilterScale_32bit)
+ {
+ /* 32-bit scale for the filter */
+ CAN1->FS1R |= filter_number_bit_pos;
+ /* 32-bit identifier or First 32-bit identifier */
+ CAN1->sFilterRegister[CAN_FilterInitStruct->CAN_FilterNumber].FR1 =
+ ((0x0000FFFF & (uint32_t)CAN_FilterInitStruct->CAN_FilterIdHigh) << 16) |
+ (0x0000FFFF & (uint32_t)CAN_FilterInitStruct->CAN_FilterIdLow);
+ /* 32-bit mask or Second 32-bit identifier */
+ CAN1->sFilterRegister[CAN_FilterInitStruct->CAN_FilterNumber].FR2 =
+ ((0x0000FFFF & (uint32_t)CAN_FilterInitStruct->CAN_FilterMaskIdHigh) << 16) |
+ (0x0000FFFF & (uint32_t)CAN_FilterInitStruct->CAN_FilterMaskIdLow);
+ }
+
+ /* Filter Mode */
+ if (CAN_FilterInitStruct->CAN_FilterMode == CAN_FilterMode_IdMask)
+ {
+ /*Id/Mask mode for the filter*/
+ CAN1->FM1R &= ~(uint32_t)filter_number_bit_pos;
+ }
+ else /* CAN_FilterInitStruct->CAN_FilterMode == CAN_FilterMode_IdList */
+ {
+ /*Identifier list mode for the filter*/
+ CAN1->FM1R |= (uint32_t)filter_number_bit_pos;
+ }
+
+ /* Filter FIFO assignment */
+ if (CAN_FilterInitStruct->CAN_FilterFIFOAssignment == CAN_Filter_FIFO0)
+ {
+ /* FIFO 0 assignation for the filter */
+ CAN1->FFA1R &= ~(uint32_t)filter_number_bit_pos;
+ }
+
+ if (CAN_FilterInitStruct->CAN_FilterFIFOAssignment == CAN_Filter_FIFO1)
+ {
+ /* FIFO 1 assignation for the filter */
+ CAN1->FFA1R |= (uint32_t)filter_number_bit_pos;
+ }
+
+ /* Filter activation */
+ if (CAN_FilterInitStruct->CAN_FilterActivation == ENABLE)
+ {
+ CAN1->FA1R |= filter_number_bit_pos;
+ }
+
+ /* Leave the initialisation mode for the filter */
+ CAN1->FMR &= ~FMR_FINIT;
+}
+
+/**
+ * @brief Fills each CAN_InitStruct member with its default value.
+ * @param CAN_InitStruct: pointer to a CAN_InitTypeDef structure which ill be initialized.
+ * @retval None
+ */
+void CAN_StructInit(CAN_InitTypeDef* CAN_InitStruct)
+{
+ /* Reset CAN init structure parameters values */
+
+ /* Initialize the time triggered communication mode */
+ CAN_InitStruct->CAN_TTCM = DISABLE;
+
+ /* Initialize the automatic bus-off management */
+ CAN_InitStruct->CAN_ABOM = DISABLE;
+
+ /* Initialize the automatic wake-up mode */
+ CAN_InitStruct->CAN_AWUM = DISABLE;
+
+ /* Initialize the no automatic retransmission */
+ CAN_InitStruct->CAN_NART = DISABLE;
+
+ /* Initialize the receive FIFO locked mode */
+ CAN_InitStruct->CAN_RFLM = DISABLE;
+
+ /* Initialize the transmit FIFO priority */
+ CAN_InitStruct->CAN_TXFP = DISABLE;
+
+ /* Initialize the CAN_Mode member */
+ CAN_InitStruct->CAN_Mode = CAN_Mode_Normal;
+
+ /* Initialize the CAN_SJW member */
+ CAN_InitStruct->CAN_SJW = CAN_SJW_1tq;
+
+ /* Initialize the CAN_BS1 member */
+ CAN_InitStruct->CAN_BS1 = CAN_BS1_4tq;
+
+ /* Initialize the CAN_BS2 member */
+ CAN_InitStruct->CAN_BS2 = CAN_BS2_3tq;
+
+ /* Initialize the CAN_Prescaler member */
+ CAN_InitStruct->CAN_Prescaler = 1;
+}
+
+/**
+ * @brief Select the start bank filter for slave CAN.
+ * @param CAN_BankNumber: Select the start slave bank filter from 1..27.
+ * @retval None
+ */
+void CAN_SlaveStartBank(uint8_t CAN_BankNumber)
+{
+ /* Check the parameters */
+ assert_param(IS_CAN_BANKNUMBER(CAN_BankNumber));
+
+ /* Enter Initialisation mode for the filter */
+ CAN1->FMR |= FMR_FINIT;
+
+ /* Select the start slave bank */
+ CAN1->FMR &= (uint32_t)0xFFFFC0F1 ;
+ CAN1->FMR |= (uint32_t)(CAN_BankNumber)<<8;
+
+ /* Leave Initialisation mode for the filter */
+ CAN1->FMR &= ~FMR_FINIT;
+}
+
+/**
+ * @brief Enables or disables the DBG Freeze for CAN.
+ * @param CANx: where x can be 1 or 2 to to select the CAN peripheral.
+ * @param NewState: new state of the CAN peripheral.
+ * This parameter can be: ENABLE (CAN reception/transmission is frozen
+ * during debug. Reception FIFOs can still be accessed/controlled normally)
+ * or DISABLE (CAN is working during debug).
+ * @retval None
+ */
+void CAN_DBGFreeze(CAN_TypeDef* CANx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_CAN_ALL_PERIPH(CANx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable Debug Freeze */
+ CANx->MCR |= MCR_DBF;
+ }
+ else
+ {
+ /* Disable Debug Freeze */
+ CANx->MCR &= ~MCR_DBF;
+ }
+}
+
+
+/**
+ * @brief Enables or disables the CAN Time TriggerOperation communication mode.
+ * @note DLC must be programmed as 8 in order Time Stamp (2 bytes) to be
+ * sent over the CAN bus.
+ * @param CANx: where x can be 1 or 2 to to select the CAN peripheral.
+ * @param NewState: Mode new state. This parameter can be: ENABLE or DISABLE.
+ * When enabled, Time stamp (TIME[15:0]) value is sent in the last two
+ * data bytes of the 8-byte message: TIME[7:0] in data byte 6 and TIME[15:8]
+ * in data byte 7.
+ * @retval None
+ */
+void CAN_TTComModeCmd(CAN_TypeDef* CANx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_CAN_ALL_PERIPH(CANx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ if (NewState != DISABLE)
+ {
+ /* Enable the TTCM mode */
+ CANx->MCR |= CAN_MCR_TTCM;
+
+ /* Set TGT bits */
+ CANx->sTxMailBox[0].TDTR |= ((uint32_t)CAN_TDT0R_TGT);
+ CANx->sTxMailBox[1].TDTR |= ((uint32_t)CAN_TDT1R_TGT);
+ CANx->sTxMailBox[2].TDTR |= ((uint32_t)CAN_TDT2R_TGT);
+ }
+ else
+ {
+ /* Disable the TTCM mode */
+ CANx->MCR &= (uint32_t)(~(uint32_t)CAN_MCR_TTCM);
+
+ /* Reset TGT bits */
+ CANx->sTxMailBox[0].TDTR &= ((uint32_t)~CAN_TDT0R_TGT);
+ CANx->sTxMailBox[1].TDTR &= ((uint32_t)~CAN_TDT1R_TGT);
+ CANx->sTxMailBox[2].TDTR &= ((uint32_t)~CAN_TDT2R_TGT);
+ }
+}
+/**
+ * @}
+ */
+
+
+/** @defgroup CAN_Group2 CAN Frames Transmission functions
+ * @brief CAN Frames Transmission functions
+ *
+@verbatim
+ ===============================================================================
+ CAN Frames Transmission functions
+ ===============================================================================
+ This section provides functions allowing to
+ - Initiate and transmit a CAN frame message (if there is an empty mailbox).
+ - Check the transmission status of a CAN Frame
+ - Cancel a transmit request
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Initiates and transmits a CAN frame message.
+ * @param CANx: where x can be 1 or 2 to to select the CAN peripheral.
+ * @param TxMessage: pointer to a structure which contains CAN Id, CAN DLC and CAN data.
+ * @retval The number of the mailbox that is used for transmission or
+ * CAN_TxStatus_NoMailBox if there is no empty mailbox.
+ */
+uint8_t CAN_Transmit(CAN_TypeDef* CANx, CanTxMsg* TxMessage)
+{
+ uint8_t transmit_mailbox = 0;
+ /* Check the parameters */
+ assert_param(IS_CAN_ALL_PERIPH(CANx));
+ assert_param(IS_CAN_IDTYPE(TxMessage->IDE));
+ assert_param(IS_CAN_RTR(TxMessage->RTR));
+ assert_param(IS_CAN_DLC(TxMessage->DLC));
+
+ /* Select one empty transmit mailbox */
+ if ((CANx->TSR&CAN_TSR_TME0) == CAN_TSR_TME0)
+ {
+ transmit_mailbox = 0;
+ }
+ else if ((CANx->TSR&CAN_TSR_TME1) == CAN_TSR_TME1)
+ {
+ transmit_mailbox = 1;
+ }
+ else if ((CANx->TSR&CAN_TSR_TME2) == CAN_TSR_TME2)
+ {
+ transmit_mailbox = 2;
+ }
+ else
+ {
+ transmit_mailbox = CAN_TxStatus_NoMailBox;
+ }
+
+ if (transmit_mailbox != CAN_TxStatus_NoMailBox)
+ {
+ /* Set up the Id */
+ CANx->sTxMailBox[transmit_mailbox].TIR &= TMIDxR_TXRQ;
+ if (TxMessage->IDE == CAN_Id_Standard)
+ {
+ assert_param(IS_CAN_STDID(TxMessage->StdId));
+ CANx->sTxMailBox[transmit_mailbox].TIR |= ((TxMessage->StdId << 21) | \
+ TxMessage->RTR);
+ }
+ else
+ {
+ assert_param(IS_CAN_EXTID(TxMessage->ExtId));
+ CANx->sTxMailBox[transmit_mailbox].TIR |= ((TxMessage->ExtId << 3) | \
+ TxMessage->IDE | \
+ TxMessage->RTR);
+ }
+
+ /* Set up the DLC */
+ TxMessage->DLC &= (uint8_t)0x0000000F;
+ CANx->sTxMailBox[transmit_mailbox].TDTR &= (uint32_t)0xFFFFFFF0;
+ CANx->sTxMailBox[transmit_mailbox].TDTR |= TxMessage->DLC;
+
+ /* Set up the data field */
+ CANx->sTxMailBox[transmit_mailbox].TDLR = (((uint32_t)TxMessage->Data[3] << 24) |
+ ((uint32_t)TxMessage->Data[2] << 16) |
+ ((uint32_t)TxMessage->Data[1] << 8) |
+ ((uint32_t)TxMessage->Data[0]));
+ CANx->sTxMailBox[transmit_mailbox].TDHR = (((uint32_t)TxMessage->Data[7] << 24) |
+ ((uint32_t)TxMessage->Data[6] << 16) |
+ ((uint32_t)TxMessage->Data[5] << 8) |
+ ((uint32_t)TxMessage->Data[4]));
+ /* Request transmission */
+ CANx->sTxMailBox[transmit_mailbox].TIR |= TMIDxR_TXRQ;
+ }
+ return transmit_mailbox;
+}
+
+/**
+ * @brief Checks the transmission status of a CAN Frame.
+ * @param CANx: where x can be 1 or 2 to select the CAN peripheral.
+ * @param TransmitMailbox: the number of the mailbox that is used for transmission.
+ * @retval CAN_TxStatus_Ok if the CAN driver transmits the message,
+ * CAN_TxStatus_Failed in an other case.
+ */
+uint8_t CAN_TransmitStatus(CAN_TypeDef* CANx, uint8_t TransmitMailbox)
+{
+ uint32_t state = 0;
+
+ /* Check the parameters */
+ assert_param(IS_CAN_ALL_PERIPH(CANx));
+ assert_param(IS_CAN_TRANSMITMAILBOX(TransmitMailbox));
+
+ switch (TransmitMailbox)
+ {
+ case (CAN_TXMAILBOX_0):
+ state = CANx->TSR & (CAN_TSR_RQCP0 | CAN_TSR_TXOK0 | CAN_TSR_TME0);
+ break;
+ case (CAN_TXMAILBOX_1):
+ state = CANx->TSR & (CAN_TSR_RQCP1 | CAN_TSR_TXOK1 | CAN_TSR_TME1);
+ break;
+ case (CAN_TXMAILBOX_2):
+ state = CANx->TSR & (CAN_TSR_RQCP2 | CAN_TSR_TXOK2 | CAN_TSR_TME2);
+ break;
+ default:
+ state = CAN_TxStatus_Failed;
+ break;
+ }
+ switch (state)
+ {
+ /* transmit pending */
+ case (0x0): state = CAN_TxStatus_Pending;
+ break;
+ /* transmit failed */
+ case (CAN_TSR_RQCP0 | CAN_TSR_TME0): state = CAN_TxStatus_Failed;
+ break;
+ case (CAN_TSR_RQCP1 | CAN_TSR_TME1): state = CAN_TxStatus_Failed;
+ break;
+ case (CAN_TSR_RQCP2 | CAN_TSR_TME2): state = CAN_TxStatus_Failed;
+ break;
+ /* transmit succeeded */
+ case (CAN_TSR_RQCP0 | CAN_TSR_TXOK0 | CAN_TSR_TME0):state = CAN_TxStatus_Ok;
+ break;
+ case (CAN_TSR_RQCP1 | CAN_TSR_TXOK1 | CAN_TSR_TME1):state = CAN_TxStatus_Ok;
+ break;
+ case (CAN_TSR_RQCP2 | CAN_TSR_TXOK2 | CAN_TSR_TME2):state = CAN_TxStatus_Ok;
+ break;
+ default: state = CAN_TxStatus_Failed;
+ break;
+ }
+ return (uint8_t) state;
+}
+
+/**
+ * @brief Cancels a transmit request.
+ * @param CANx: where x can be 1 or 2 to select the CAN peripheral.
+ * @param Mailbox: Mailbox number.
+ * @retval None
+ */
+void CAN_CancelTransmit(CAN_TypeDef* CANx, uint8_t Mailbox)
+{
+ /* Check the parameters */
+ assert_param(IS_CAN_ALL_PERIPH(CANx));
+ assert_param(IS_CAN_TRANSMITMAILBOX(Mailbox));
+ /* abort transmission */
+ switch (Mailbox)
+ {
+ case (CAN_TXMAILBOX_0): CANx->TSR |= CAN_TSR_ABRQ0;
+ break;
+ case (CAN_TXMAILBOX_1): CANx->TSR |= CAN_TSR_ABRQ1;
+ break;
+ case (CAN_TXMAILBOX_2): CANx->TSR |= CAN_TSR_ABRQ2;
+ break;
+ default:
+ break;
+ }
+}
+/**
+ * @}
+ */
+
+
+/** @defgroup CAN_Group3 CAN Frames Reception functions
+ * @brief CAN Frames Reception functions
+ *
+@verbatim
+ ===============================================================================
+ CAN Frames Reception functions
+ ===============================================================================
+ This section provides functions allowing to
+ - Receive a correct CAN frame
+ - Release a specified receive FIFO (2 FIFOs are available)
+ - Return the number of the pending received CAN frames
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Receives a correct CAN frame.
+ * @param CANx: where x can be 1 or 2 to select the CAN peripheral.
+ * @param FIFONumber: Receive FIFO number, CAN_FIFO0 or CAN_FIFO1.
+ * @param RxMessage: pointer to a structure receive frame which contains CAN Id,
+ * CAN DLC, CAN data and FMI number.
+ * @retval None
+ */
+void CAN_Receive(CAN_TypeDef* CANx, uint8_t FIFONumber, CanRxMsg* RxMessage)
+{
+ /* Check the parameters */
+ assert_param(IS_CAN_ALL_PERIPH(CANx));
+ assert_param(IS_CAN_FIFO(FIFONumber));
+ /* Get the Id */
+ RxMessage->IDE = (uint8_t)0x04 & CANx->sFIFOMailBox[FIFONumber].RIR;
+ if (RxMessage->IDE == CAN_Id_Standard)
+ {
+ RxMessage->StdId = (uint32_t)0x000007FF & (CANx->sFIFOMailBox[FIFONumber].RIR >> 21);
+ }
+ else
+ {
+ RxMessage->ExtId = (uint32_t)0x1FFFFFFF & (CANx->sFIFOMailBox[FIFONumber].RIR >> 3);
+ }
+
+ RxMessage->RTR = (uint8_t)0x02 & CANx->sFIFOMailBox[FIFONumber].RIR;
+ /* Get the DLC */
+ RxMessage->DLC = (uint8_t)0x0F & CANx->sFIFOMailBox[FIFONumber].RDTR;
+ /* Get the FMI */
+ RxMessage->FMI = (uint8_t)0xFF & (CANx->sFIFOMailBox[FIFONumber].RDTR >> 8);
+ /* Get the data field */
+ RxMessage->Data[0] = (uint8_t)0xFF & CANx->sFIFOMailBox[FIFONumber].RDLR;
+ RxMessage->Data[1] = (uint8_t)0xFF & (CANx->sFIFOMailBox[FIFONumber].RDLR >> 8);
+ RxMessage->Data[2] = (uint8_t)0xFF & (CANx->sFIFOMailBox[FIFONumber].RDLR >> 16);
+ RxMessage->Data[3] = (uint8_t)0xFF & (CANx->sFIFOMailBox[FIFONumber].RDLR >> 24);
+ RxMessage->Data[4] = (uint8_t)0xFF & CANx->sFIFOMailBox[FIFONumber].RDHR;
+ RxMessage->Data[5] = (uint8_t)0xFF & (CANx->sFIFOMailBox[FIFONumber].RDHR >> 8);
+ RxMessage->Data[6] = (uint8_t)0xFF & (CANx->sFIFOMailBox[FIFONumber].RDHR >> 16);
+ RxMessage->Data[7] = (uint8_t)0xFF & (CANx->sFIFOMailBox[FIFONumber].RDHR >> 24);
+ /* Release the FIFO */
+ /* Release FIFO0 */
+ if (FIFONumber == CAN_FIFO0)
+ {
+ CANx->RF0R |= CAN_RF0R_RFOM0;
+ }
+ /* Release FIFO1 */
+ else /* FIFONumber == CAN_FIFO1 */
+ {
+ CANx->RF1R |= CAN_RF1R_RFOM1;
+ }
+}
+
+/**
+ * @brief Releases the specified receive FIFO.
+ * @param CANx: where x can be 1 or 2 to select the CAN peripheral.
+ * @param FIFONumber: FIFO to release, CAN_FIFO0 or CAN_FIFO1.
+ * @retval None
+ */
+void CAN_FIFORelease(CAN_TypeDef* CANx, uint8_t FIFONumber)
+{
+ /* Check the parameters */
+ assert_param(IS_CAN_ALL_PERIPH(CANx));
+ assert_param(IS_CAN_FIFO(FIFONumber));
+ /* Release FIFO0 */
+ if (FIFONumber == CAN_FIFO0)
+ {
+ CANx->RF0R |= CAN_RF0R_RFOM0;
+ }
+ /* Release FIFO1 */
+ else /* FIFONumber == CAN_FIFO1 */
+ {
+ CANx->RF1R |= CAN_RF1R_RFOM1;
+ }
+}
+
+/**
+ * @brief Returns the number of pending received messages.
+ * @param CANx: where x can be 1 or 2 to select the CAN peripheral.
+ * @param FIFONumber: Receive FIFO number, CAN_FIFO0 or CAN_FIFO1.
+ * @retval NbMessage : which is the number of pending message.
+ */
+uint8_t CAN_MessagePending(CAN_TypeDef* CANx, uint8_t FIFONumber)
+{
+ uint8_t message_pending=0;
+ /* Check the parameters */
+ assert_param(IS_CAN_ALL_PERIPH(CANx));
+ assert_param(IS_CAN_FIFO(FIFONumber));
+ if (FIFONumber == CAN_FIFO0)
+ {
+ message_pending = (uint8_t)(CANx->RF0R&(uint32_t)0x03);
+ }
+ else if (FIFONumber == CAN_FIFO1)
+ {
+ message_pending = (uint8_t)(CANx->RF1R&(uint32_t)0x03);
+ }
+ else
+ {
+ message_pending = 0;
+ }
+ return message_pending;
+}
+/**
+ * @}
+ */
+
+
+/** @defgroup CAN_Group4 CAN Operation modes functions
+ * @brief CAN Operation modes functions
+ *
+@verbatim
+ ===============================================================================
+ CAN Operation modes functions
+ ===============================================================================
+ This section provides functions allowing to select the CAN Operation modes
+ - sleep mode
+ - normal mode
+ - initialization mode
+
+@endverbatim
+ * @{
+ */
+
+
+/**
+ * @brief Selects the CAN Operation mode.
+ * @param CAN_OperatingMode: CAN Operating Mode.
+ * This parameter can be one of @ref CAN_OperatingMode_TypeDef enumeration.
+ * @retval status of the requested mode which can be
+ * - CAN_ModeStatus_Failed: CAN failed entering the specific mode
+ * - CAN_ModeStatus_Success: CAN Succeed entering the specific mode
+ */
+uint8_t CAN_OperatingModeRequest(CAN_TypeDef* CANx, uint8_t CAN_OperatingMode)
+{
+ uint8_t status = CAN_ModeStatus_Failed;
+
+ /* Timeout for INAK or also for SLAK bits*/
+ uint32_t timeout = INAK_TIMEOUT;
+
+ /* Check the parameters */
+ assert_param(IS_CAN_ALL_PERIPH(CANx));
+ assert_param(IS_CAN_OPERATING_MODE(CAN_OperatingMode));
+
+ if (CAN_OperatingMode == CAN_OperatingMode_Initialization)
+ {
+ /* Request initialisation */
+ CANx->MCR = (uint32_t)((CANx->MCR & (uint32_t)(~(uint32_t)CAN_MCR_SLEEP)) | CAN_MCR_INRQ);
+
+ /* Wait the acknowledge */
+ while (((CANx->MSR & CAN_MODE_MASK) != CAN_MSR_INAK) && (timeout != 0))
+ {
+ timeout--;
+ }
+ if ((CANx->MSR & CAN_MODE_MASK) != CAN_MSR_INAK)
+ {
+ status = CAN_ModeStatus_Failed;
+ }
+ else
+ {
+ status = CAN_ModeStatus_Success;
+ }
+ }
+ else if (CAN_OperatingMode == CAN_OperatingMode_Normal)
+ {
+ /* Request leave initialisation and sleep mode and enter Normal mode */
+ CANx->MCR &= (uint32_t)(~(CAN_MCR_SLEEP|CAN_MCR_INRQ));
+
+ /* Wait the acknowledge */
+ while (((CANx->MSR & CAN_MODE_MASK) != 0) && (timeout!=0))
+ {
+ timeout--;
+ }
+ if ((CANx->MSR & CAN_MODE_MASK) != 0)
+ {
+ status = CAN_ModeStatus_Failed;
+ }
+ else
+ {
+ status = CAN_ModeStatus_Success;
+ }
+ }
+ else if (CAN_OperatingMode == CAN_OperatingMode_Sleep)
+ {
+ /* Request Sleep mode */
+ CANx->MCR = (uint32_t)((CANx->MCR & (uint32_t)(~(uint32_t)CAN_MCR_INRQ)) | CAN_MCR_SLEEP);
+
+ /* Wait the acknowledge */
+ while (((CANx->MSR & CAN_MODE_MASK) != CAN_MSR_SLAK) && (timeout!=0))
+ {
+ timeout--;
+ }
+ if ((CANx->MSR & CAN_MODE_MASK) != CAN_MSR_SLAK)
+ {
+ status = CAN_ModeStatus_Failed;
+ }
+ else
+ {
+ status = CAN_ModeStatus_Success;
+ }
+ }
+ else
+ {
+ status = CAN_ModeStatus_Failed;
+ }
+
+ return (uint8_t) status;
+}
+
+/**
+ * @brief Enters the Sleep (low power) mode.
+ * @param CANx: where x can be 1 or 2 to select the CAN peripheral.
+ * @retval CAN_Sleep_Ok if sleep entered, CAN_Sleep_Failed otherwise.
+ */
+uint8_t CAN_Sleep(CAN_TypeDef* CANx)
+{
+ uint8_t sleepstatus = CAN_Sleep_Failed;
+
+ /* Check the parameters */
+ assert_param(IS_CAN_ALL_PERIPH(CANx));
+
+ /* Request Sleep mode */
+ CANx->MCR = (((CANx->MCR) & (uint32_t)(~(uint32_t)CAN_MCR_INRQ)) | CAN_MCR_SLEEP);
+
+ /* Sleep mode status */
+ if ((CANx->MSR & (CAN_MSR_SLAK|CAN_MSR_INAK)) == CAN_MSR_SLAK)
+ {
+ /* Sleep mode not entered */
+ sleepstatus = CAN_Sleep_Ok;
+ }
+ /* return sleep mode status */
+ return (uint8_t)sleepstatus;
+}
+
+/**
+ * @brief Wakes up the CAN peripheral from sleep mode .
+ * @param CANx: where x can be 1 or 2 to select the CAN peripheral.
+ * @retval CAN_WakeUp_Ok if sleep mode left, CAN_WakeUp_Failed otherwise.
+ */
+uint8_t CAN_WakeUp(CAN_TypeDef* CANx)
+{
+ uint32_t wait_slak = SLAK_TIMEOUT;
+ uint8_t wakeupstatus = CAN_WakeUp_Failed;
+
+ /* Check the parameters */
+ assert_param(IS_CAN_ALL_PERIPH(CANx));
+
+ /* Wake up request */
+ CANx->MCR &= ~(uint32_t)CAN_MCR_SLEEP;
+
+ /* Sleep mode status */
+ while(((CANx->MSR & CAN_MSR_SLAK) == CAN_MSR_SLAK)&&(wait_slak!=0x00))
+ {
+ wait_slak--;
+ }
+ if((CANx->MSR & CAN_MSR_SLAK) != CAN_MSR_SLAK)
+ {
+ /* wake up done : Sleep mode exited */
+ wakeupstatus = CAN_WakeUp_Ok;
+ }
+ /* return wakeup status */
+ return (uint8_t)wakeupstatus;
+}
+/**
+ * @}
+ */
+
+
+/** @defgroup CAN_Group5 CAN Bus Error management functions
+ * @brief CAN Bus Error management functions
+ *
+@verbatim
+ ===============================================================================
+ CAN Bus Error management functions
+ ===============================================================================
+ This section provides functions allowing to
+ - Return the CANx's last error code (LEC)
+ - Return the CANx Receive Error Counter (REC)
+ - Return the LSB of the 9-bit CANx Transmit Error Counter(TEC).
+
+ @note If TEC is greater than 255, The CAN is in bus-off state.
+ @note if REC or TEC are greater than 96, an Error warning flag occurs.
+ @note if REC or TEC are greater than 127, an Error Passive Flag occurs.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Returns the CANx's last error code (LEC).
+ * @param CANx: where x can be 1 or 2 to select the CAN peripheral.
+ * @retval Error code:
+ * - CAN_ERRORCODE_NoErr: No Error
+ * - CAN_ERRORCODE_StuffErr: Stuff Error
+ * - CAN_ERRORCODE_FormErr: Form Error
+ * - CAN_ERRORCODE_ACKErr : Acknowledgment Error
+ * - CAN_ERRORCODE_BitRecessiveErr: Bit Recessive Error
+ * - CAN_ERRORCODE_BitDominantErr: Bit Dominant Error
+ * - CAN_ERRORCODE_CRCErr: CRC Error
+ * - CAN_ERRORCODE_SoftwareSetErr: Software Set Error
+ */
+uint8_t CAN_GetLastErrorCode(CAN_TypeDef* CANx)
+{
+ uint8_t errorcode=0;
+
+ /* Check the parameters */
+ assert_param(IS_CAN_ALL_PERIPH(CANx));
+
+ /* Get the error code*/
+ errorcode = (((uint8_t)CANx->ESR) & (uint8_t)CAN_ESR_LEC);
+
+ /* Return the error code*/
+ return errorcode;
+}
+
+/**
+ * @brief Returns the CANx Receive Error Counter (REC).
+ * @note In case of an error during reception, this counter is incremented
+ * by 1 or by 8 depending on the error condition as defined by the CAN
+ * standard. After every successful reception, the counter is
+ * decremented by 1 or reset to 120 if its value was higher than 128.
+ * When the counter value exceeds 127, the CAN controller enters the
+ * error passive state.
+ * @param CANx: where x can be 1 or 2 to to select the CAN peripheral.
+ * @retval CAN Receive Error Counter.
+ */
+uint8_t CAN_GetReceiveErrorCounter(CAN_TypeDef* CANx)
+{
+ uint8_t counter=0;
+
+ /* Check the parameters */
+ assert_param(IS_CAN_ALL_PERIPH(CANx));
+
+ /* Get the Receive Error Counter*/
+ counter = (uint8_t)((CANx->ESR & CAN_ESR_REC)>> 24);
+
+ /* Return the Receive Error Counter*/
+ return counter;
+}
+
+
+/**
+ * @brief Returns the LSB of the 9-bit CANx Transmit Error Counter(TEC).
+ * @param CANx: where x can be 1 or 2 to to select the CAN peripheral.
+ * @retval LSB of the 9-bit CAN Transmit Error Counter.
+ */
+uint8_t CAN_GetLSBTransmitErrorCounter(CAN_TypeDef* CANx)
+{
+ uint8_t counter=0;
+
+ /* Check the parameters */
+ assert_param(IS_CAN_ALL_PERIPH(CANx));
+
+ /* Get the LSB of the 9-bit CANx Transmit Error Counter(TEC) */
+ counter = (uint8_t)((CANx->ESR & CAN_ESR_TEC)>> 16);
+
+ /* Return the LSB of the 9-bit CANx Transmit Error Counter(TEC) */
+ return counter;
+}
+/**
+ * @}
+ */
+
+/** @defgroup CAN_Group6 Interrupts and flags management functions
+ * @brief Interrupts and flags management functions
+ *
+@verbatim
+ ===============================================================================
+ Interrupts and flags management functions
+ ===============================================================================
+
+ This section provides functions allowing to configure the CAN Interrupts and
+ to get the status and clear flags and Interrupts pending bits.
+
+ The CAN provides 14 Interrupts sources and 15 Flags:
+
+ ===============
+ Flags :
+ ===============
+ The 15 flags can be divided on 4 groups:
+
+ A. Transmit Flags
+ -----------------------
+ CAN_FLAG_RQCP0,
+ CAN_FLAG_RQCP1,
+ CAN_FLAG_RQCP2 : Request completed MailBoxes 0, 1 and 2 Flags
+ Set when when the last request (transmit or abort) has
+ been performed.
+
+ B. Receive Flags
+ -----------------------
+
+ CAN_FLAG_FMP0,
+ CAN_FLAG_FMP1 : FIFO 0 and 1 Message Pending Flags
+ set to signal that messages are pending in the receive
+ FIFO.
+ These Flags are cleared only by hardware.
+
+ CAN_FLAG_FF0,
+ CAN_FLAG_FF1 : FIFO 0 and 1 Full Flags
+ set when three messages are stored in the selected
+ FIFO.
+
+ CAN_FLAG_FOV0
+ CAN_FLAG_FOV1 : FIFO 0 and 1 Overrun Flags
+ set when a new message has been received and passed
+ the filter while the FIFO was full.
+
+ C. Operating Mode Flags
+ -----------------------
+ CAN_FLAG_WKU : Wake up Flag
+ set to signal that a SOF bit has been detected while
+ the CAN hardware was in Sleep mode.
+
+ CAN_FLAG_SLAK : Sleep acknowledge Flag
+ Set to signal that the CAN has entered Sleep Mode.
+
+ D. Error Flags
+ -----------------------
+ CAN_FLAG_EWG : Error Warning Flag
+ Set when the warning limit has been reached (Receive
+ Error Counter or Transmit Error Counter greater than 96).
+ This Flag is cleared only by hardware.
+
+ CAN_FLAG_EPV : Error Passive Flag
+ Set when the Error Passive limit has been reached
+ (Receive Error Counter or Transmit Error Counter
+ greater than 127).
+ This Flag is cleared only by hardware.
+
+ CAN_FLAG_BOF : Bus-Off Flag
+ set when CAN enters the bus-off state. The bus-off
+ state is entered on TEC overflow, greater than 255.
+ This Flag is cleared only by hardware.
+
+ CAN_FLAG_LEC : Last error code Flag
+ set If a message has been transferred (reception or
+ transmission) with error, and the error code is hold.
+
+ ===============
+ Interrupts :
+ ===============
+ The 14 interrupts can be divided on 4 groups:
+
+ A. Transmit interrupt
+ -----------------------
+ CAN_IT_TME : Transmit mailbox empty Interrupt
+ if enabled, this interrupt source is pending when
+ no transmit request are pending for Tx mailboxes.
+
+ B. Receive Interrupts
+ -----------------------
+ CAN_IT_FMP0,
+ CAN_IT_FMP1 : FIFO 0 and FIFO1 message pending Interrupts
+ if enabled, these interrupt sources are pending when
+ messages are pending in the receive FIFO.
+ The corresponding interrupt pending bits are cleared
+ only by hardware.
+
+ CAN_IT_FF0,
+ CAN_IT_FF1 : FIFO 0 and FIFO1 full Interrupts
+ if enabled, these interrupt sources are pending when
+ three messages are stored in the selected FIFO.
+
+ CAN_IT_FOV0,
+ CAN_IT_FOV1 : FIFO 0 and FIFO1 overrun Interrupts
+ if enabled, these interrupt sources are pending when
+ a new message has been received and passed the filter
+ while the FIFO was full.
+
+ C. Operating Mode Interrupts
+ -------------------------------
+ CAN_IT_WKU : Wake-up Interrupt
+ if enabled, this interrupt source is pending when
+ a SOF bit has been detected while the CAN hardware was
+ in Sleep mode.
+
+ CAN_IT_SLK : Sleep acknowledge Interrupt
+ if enabled, this interrupt source is pending when
+ the CAN has entered Sleep Mode.
+
+ D. Error Interrupts
+ -----------------------
+ CAN_IT_EWG : Error warning Interrupt
+ if enabled, this interrupt source is pending when
+ the warning limit has been reached (Receive Error
+ Counter or Transmit Error Counter=96).
+
+ CAN_IT_EPV : Error passive Interrupt
+ if enabled, this interrupt source is pending when
+ the Error Passive limit has been reached (Receive
+ Error Counter or Transmit Error Counter>127).
+
+ CAN_IT_BOF : Bus-off Interrupt
+ if enabled, this interrupt source is pending when
+ CAN enters the bus-off state. The bus-off state is
+ entered on TEC overflow, greater than 255.
+ This Flag is cleared only by hardware.
+
+ CAN_IT_LEC : Last error code Interrupt
+ if enabled, this interrupt source is pending when
+ a message has been transferred (reception or
+ transmission) with error, and the error code is hold.
+
+ CAN_IT_ERR : Error Interrupt
+ if enabled, this interrupt source is pending when
+ an error condition is pending.
+
+
+ Managing the CAN controller events :
+ ------------------------------------
+ The user should identify which mode will be used in his application to manage
+ the CAN controller events: Polling mode or Interrupt mode.
+
+ 1. In the Polling Mode it is advised to use the following functions:
+ - CAN_GetFlagStatus() : to check if flags events occur.
+ - CAN_ClearFlag() : to clear the flags events.
+
+
+
+ 2. In the Interrupt Mode it is advised to use the following functions:
+ - CAN_ITConfig() : to enable or disable the interrupt source.
+ - CAN_GetITStatus() : to check if Interrupt occurs.
+ - CAN_ClearITPendingBit() : to clear the Interrupt pending Bit (corresponding Flag).
+ @note This function has no impact on CAN_IT_FMP0 and CAN_IT_FMP1 Interrupts
+ pending bits since there are cleared only by hardware.
+
+@endverbatim
+ * @{
+ */
+/**
+ * @brief Enables or disables the specified CANx interrupts.
+ * @param CANx: where x can be 1 or 2 to to select the CAN peripheral.
+ * @param CAN_IT: specifies the CAN interrupt sources to be enabled or disabled.
+ * This parameter can be:
+ * @arg CAN_IT_TME: Transmit mailbox empty Interrupt
+ * @arg CAN_IT_FMP0: FIFO 0 message pending Interrupt
+ * @arg CAN_IT_FF0: FIFO 0 full Interrupt
+ * @arg CAN_IT_FOV0: FIFO 0 overrun Interrupt
+ * @arg CAN_IT_FMP1: FIFO 1 message pending Interrupt
+ * @arg CAN_IT_FF1: FIFO 1 full Interrupt
+ * @arg CAN_IT_FOV1: FIFO 1 overrun Interrupt
+ * @arg CAN_IT_WKU: Wake-up Interrupt
+ * @arg CAN_IT_SLK: Sleep acknowledge Interrupt
+ * @arg CAN_IT_EWG: Error warning Interrupt
+ * @arg CAN_IT_EPV: Error passive Interrupt
+ * @arg CAN_IT_BOF: Bus-off Interrupt
+ * @arg CAN_IT_LEC: Last error code Interrupt
+ * @arg CAN_IT_ERR: Error Interrupt
+ * @param NewState: new state of the CAN interrupts.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void CAN_ITConfig(CAN_TypeDef* CANx, uint32_t CAN_IT, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_CAN_ALL_PERIPH(CANx));
+ assert_param(IS_CAN_IT(CAN_IT));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the selected CANx interrupt */
+ CANx->IER |= CAN_IT;
+ }
+ else
+ {
+ /* Disable the selected CANx interrupt */
+ CANx->IER &= ~CAN_IT;
+ }
+}
+/**
+ * @brief Checks whether the specified CAN flag is set or not.
+ * @param CANx: where x can be 1 or 2 to to select the CAN peripheral.
+ * @param CAN_FLAG: specifies the flag to check.
+ * This parameter can be one of the following values:
+ * @arg CAN_FLAG_RQCP0: Request MailBox0 Flag
+ * @arg CAN_FLAG_RQCP1: Request MailBox1 Flag
+ * @arg CAN_FLAG_RQCP2: Request MailBox2 Flag
+ * @arg CAN_FLAG_FMP0: FIFO 0 Message Pending Flag
+ * @arg CAN_FLAG_FF0: FIFO 0 Full Flag
+ * @arg CAN_FLAG_FOV0: FIFO 0 Overrun Flag
+ * @arg CAN_FLAG_FMP1: FIFO 1 Message Pending Flag
+ * @arg CAN_FLAG_FF1: FIFO 1 Full Flag
+ * @arg CAN_FLAG_FOV1: FIFO 1 Overrun Flag
+ * @arg CAN_FLAG_WKU: Wake up Flag
+ * @arg CAN_FLAG_SLAK: Sleep acknowledge Flag
+ * @arg CAN_FLAG_EWG: Error Warning Flag
+ * @arg CAN_FLAG_EPV: Error Passive Flag
+ * @arg CAN_FLAG_BOF: Bus-Off Flag
+ * @arg CAN_FLAG_LEC: Last error code Flag
+ * @retval The new state of CAN_FLAG (SET or RESET).
+ */
+FlagStatus CAN_GetFlagStatus(CAN_TypeDef* CANx, uint32_t CAN_FLAG)
+{
+ FlagStatus bitstatus = RESET;
+
+ /* Check the parameters */
+ assert_param(IS_CAN_ALL_PERIPH(CANx));
+ assert_param(IS_CAN_GET_FLAG(CAN_FLAG));
+
+
+ if((CAN_FLAG & CAN_FLAGS_ESR) != (uint32_t)RESET)
+ {
+ /* Check the status of the specified CAN flag */
+ if ((CANx->ESR & (CAN_FLAG & 0x000FFFFF)) != (uint32_t)RESET)
+ {
+ /* CAN_FLAG is set */
+ bitstatus = SET;
+ }
+ else
+ {
+ /* CAN_FLAG is reset */
+ bitstatus = RESET;
+ }
+ }
+ else if((CAN_FLAG & CAN_FLAGS_MSR) != (uint32_t)RESET)
+ {
+ /* Check the status of the specified CAN flag */
+ if ((CANx->MSR & (CAN_FLAG & 0x000FFFFF)) != (uint32_t)RESET)
+ {
+ /* CAN_FLAG is set */
+ bitstatus = SET;
+ }
+ else
+ {
+ /* CAN_FLAG is reset */
+ bitstatus = RESET;
+ }
+ }
+ else if((CAN_FLAG & CAN_FLAGS_TSR) != (uint32_t)RESET)
+ {
+ /* Check the status of the specified CAN flag */
+ if ((CANx->TSR & (CAN_FLAG & 0x000FFFFF)) != (uint32_t)RESET)
+ {
+ /* CAN_FLAG is set */
+ bitstatus = SET;
+ }
+ else
+ {
+ /* CAN_FLAG is reset */
+ bitstatus = RESET;
+ }
+ }
+ else if((CAN_FLAG & CAN_FLAGS_RF0R) != (uint32_t)RESET)
+ {
+ /* Check the status of the specified CAN flag */
+ if ((CANx->RF0R & (CAN_FLAG & 0x000FFFFF)) != (uint32_t)RESET)
+ {
+ /* CAN_FLAG is set */
+ bitstatus = SET;
+ }
+ else
+ {
+ /* CAN_FLAG is reset */
+ bitstatus = RESET;
+ }
+ }
+ else /* If(CAN_FLAG & CAN_FLAGS_RF1R != (uint32_t)RESET) */
+ {
+ /* Check the status of the specified CAN flag */
+ if ((uint32_t)(CANx->RF1R & (CAN_FLAG & 0x000FFFFF)) != (uint32_t)RESET)
+ {
+ /* CAN_FLAG is set */
+ bitstatus = SET;
+ }
+ else
+ {
+ /* CAN_FLAG is reset */
+ bitstatus = RESET;
+ }
+ }
+ /* Return the CAN_FLAG status */
+ return bitstatus;
+}
+
+/**
+ * @brief Clears the CAN's pending flags.
+ * @param CANx: where x can be 1 or 2 to to select the CAN peripheral.
+ * @param CAN_FLAG: specifies the flag to clear.
+ * This parameter can be one of the following values:
+ * @arg CAN_FLAG_RQCP0: Request MailBox0 Flag
+ * @arg CAN_FLAG_RQCP1: Request MailBox1 Flag
+ * @arg CAN_FLAG_RQCP2: Request MailBox2 Flag
+ * @arg CAN_FLAG_FF0: FIFO 0 Full Flag
+ * @arg CAN_FLAG_FOV0: FIFO 0 Overrun Flag
+ * @arg CAN_FLAG_FF1: FIFO 1 Full Flag
+ * @arg CAN_FLAG_FOV1: FIFO 1 Overrun Flag
+ * @arg CAN_FLAG_WKU: Wake up Flag
+ * @arg CAN_FLAG_SLAK: Sleep acknowledge Flag
+ * @arg CAN_FLAG_LEC: Last error code Flag
+ * @retval None
+ */
+void CAN_ClearFlag(CAN_TypeDef* CANx, uint32_t CAN_FLAG)
+{
+ uint32_t flagtmp=0;
+ /* Check the parameters */
+ assert_param(IS_CAN_ALL_PERIPH(CANx));
+ assert_param(IS_CAN_CLEAR_FLAG(CAN_FLAG));
+
+ if (CAN_FLAG == CAN_FLAG_LEC) /* ESR register */
+ {
+ /* Clear the selected CAN flags */
+ CANx->ESR = (uint32_t)RESET;
+ }
+ else /* MSR or TSR or RF0R or RF1R */
+ {
+ flagtmp = CAN_FLAG & 0x000FFFFF;
+
+ if ((CAN_FLAG & CAN_FLAGS_RF0R)!=(uint32_t)RESET)
+ {
+ /* Receive Flags */
+ CANx->RF0R = (uint32_t)(flagtmp);
+ }
+ else if ((CAN_FLAG & CAN_FLAGS_RF1R)!=(uint32_t)RESET)
+ {
+ /* Receive Flags */
+ CANx->RF1R = (uint32_t)(flagtmp);
+ }
+ else if ((CAN_FLAG & CAN_FLAGS_TSR)!=(uint32_t)RESET)
+ {
+ /* Transmit Flags */
+ CANx->TSR = (uint32_t)(flagtmp);
+ }
+ else /* If((CAN_FLAG & CAN_FLAGS_MSR)!=(uint32_t)RESET) */
+ {
+ /* Operating mode Flags */
+ CANx->MSR = (uint32_t)(flagtmp);
+ }
+ }
+}
+
+/**
+ * @brief Checks whether the specified CANx interrupt has occurred or not.
+ * @param CANx: where x can be 1 or 2 to to select the CAN peripheral.
+ * @param CAN_IT: specifies the CAN interrupt source to check.
+ * This parameter can be one of the following values:
+ * @arg CAN_IT_TME: Transmit mailbox empty Interrupt
+ * @arg CAN_IT_FMP0: FIFO 0 message pending Interrupt
+ * @arg CAN_IT_FF0: FIFO 0 full Interrupt
+ * @arg CAN_IT_FOV0: FIFO 0 overrun Interrupt
+ * @arg CAN_IT_FMP1: FIFO 1 message pending Interrupt
+ * @arg CAN_IT_FF1: FIFO 1 full Interrupt
+ * @arg CAN_IT_FOV1: FIFO 1 overrun Interrupt
+ * @arg CAN_IT_WKU: Wake-up Interrupt
+ * @arg CAN_IT_SLK: Sleep acknowledge Interrupt
+ * @arg CAN_IT_EWG: Error warning Interrupt
+ * @arg CAN_IT_EPV: Error passive Interrupt
+ * @arg CAN_IT_BOF: Bus-off Interrupt
+ * @arg CAN_IT_LEC: Last error code Interrupt
+ * @arg CAN_IT_ERR: Error Interrupt
+ * @retval The current state of CAN_IT (SET or RESET).
+ */
+ITStatus CAN_GetITStatus(CAN_TypeDef* CANx, uint32_t CAN_IT)
+{
+ ITStatus itstatus = RESET;
+ /* Check the parameters */
+ assert_param(IS_CAN_ALL_PERIPH(CANx));
+ assert_param(IS_CAN_IT(CAN_IT));
+
+ /* check the interrupt enable bit */
+ if((CANx->IER & CAN_IT) != RESET)
+ {
+ /* in case the Interrupt is enabled, .... */
+ switch (CAN_IT)
+ {
+ case CAN_IT_TME:
+ /* Check CAN_TSR_RQCPx bits */
+ itstatus = CheckITStatus(CANx->TSR, CAN_TSR_RQCP0|CAN_TSR_RQCP1|CAN_TSR_RQCP2);
+ break;
+ case CAN_IT_FMP0:
+ /* Check CAN_RF0R_FMP0 bit */
+ itstatus = CheckITStatus(CANx->RF0R, CAN_RF0R_FMP0);
+ break;
+ case CAN_IT_FF0:
+ /* Check CAN_RF0R_FULL0 bit */
+ itstatus = CheckITStatus(CANx->RF0R, CAN_RF0R_FULL0);
+ break;
+ case CAN_IT_FOV0:
+ /* Check CAN_RF0R_FOVR0 bit */
+ itstatus = CheckITStatus(CANx->RF0R, CAN_RF0R_FOVR0);
+ break;
+ case CAN_IT_FMP1:
+ /* Check CAN_RF1R_FMP1 bit */
+ itstatus = CheckITStatus(CANx->RF1R, CAN_RF1R_FMP1);
+ break;
+ case CAN_IT_FF1:
+ /* Check CAN_RF1R_FULL1 bit */
+ itstatus = CheckITStatus(CANx->RF1R, CAN_RF1R_FULL1);
+ break;
+ case CAN_IT_FOV1:
+ /* Check CAN_RF1R_FOVR1 bit */
+ itstatus = CheckITStatus(CANx->RF1R, CAN_RF1R_FOVR1);
+ break;
+ case CAN_IT_WKU:
+ /* Check CAN_MSR_WKUI bit */
+ itstatus = CheckITStatus(CANx->MSR, CAN_MSR_WKUI);
+ break;
+ case CAN_IT_SLK:
+ /* Check CAN_MSR_SLAKI bit */
+ itstatus = CheckITStatus(CANx->MSR, CAN_MSR_SLAKI);
+ break;
+ case CAN_IT_EWG:
+ /* Check CAN_ESR_EWGF bit */
+ itstatus = CheckITStatus(CANx->ESR, CAN_ESR_EWGF);
+ break;
+ case CAN_IT_EPV:
+ /* Check CAN_ESR_EPVF bit */
+ itstatus = CheckITStatus(CANx->ESR, CAN_ESR_EPVF);
+ break;
+ case CAN_IT_BOF:
+ /* Check CAN_ESR_BOFF bit */
+ itstatus = CheckITStatus(CANx->ESR, CAN_ESR_BOFF);
+ break;
+ case CAN_IT_LEC:
+ /* Check CAN_ESR_LEC bit */
+ itstatus = CheckITStatus(CANx->ESR, CAN_ESR_LEC);
+ break;
+ case CAN_IT_ERR:
+ /* Check CAN_MSR_ERRI bit */
+ itstatus = CheckITStatus(CANx->MSR, CAN_MSR_ERRI);
+ break;
+ default:
+ /* in case of error, return RESET */
+ itstatus = RESET;
+ break;
+ }
+ }
+ else
+ {
+ /* in case the Interrupt is not enabled, return RESET */
+ itstatus = RESET;
+ }
+
+ /* Return the CAN_IT status */
+ return itstatus;
+}
+
+/**
+ * @brief Clears the CANx's interrupt pending bits.
+ * @param CANx: where x can be 1 or 2 to to select the CAN peripheral.
+ * @param CAN_IT: specifies the interrupt pending bit to clear.
+ * This parameter can be one of the following values:
+ * @arg CAN_IT_TME: Transmit mailbox empty Interrupt
+ * @arg CAN_IT_FF0: FIFO 0 full Interrupt
+ * @arg CAN_IT_FOV0: FIFO 0 overrun Interrupt
+ * @arg CAN_IT_FF1: FIFO 1 full Interrupt
+ * @arg CAN_IT_FOV1: FIFO 1 overrun Interrupt
+ * @arg CAN_IT_WKU: Wake-up Interrupt
+ * @arg CAN_IT_SLK: Sleep acknowledge Interrupt
+ * @arg CAN_IT_EWG: Error warning Interrupt
+ * @arg CAN_IT_EPV: Error passive Interrupt
+ * @arg CAN_IT_BOF: Bus-off Interrupt
+ * @arg CAN_IT_LEC: Last error code Interrupt
+ * @arg CAN_IT_ERR: Error Interrupt
+ * @retval None
+ */
+void CAN_ClearITPendingBit(CAN_TypeDef* CANx, uint32_t CAN_IT)
+{
+ /* Check the parameters */
+ assert_param(IS_CAN_ALL_PERIPH(CANx));
+ assert_param(IS_CAN_CLEAR_IT(CAN_IT));
+
+ switch (CAN_IT)
+ {
+ case CAN_IT_TME:
+ /* Clear CAN_TSR_RQCPx (rc_w1)*/
+ CANx->TSR = CAN_TSR_RQCP0|CAN_TSR_RQCP1|CAN_TSR_RQCP2;
+ break;
+ case CAN_IT_FF0:
+ /* Clear CAN_RF0R_FULL0 (rc_w1)*/
+ CANx->RF0R = CAN_RF0R_FULL0;
+ break;
+ case CAN_IT_FOV0:
+ /* Clear CAN_RF0R_FOVR0 (rc_w1)*/
+ CANx->RF0R = CAN_RF0R_FOVR0;
+ break;
+ case CAN_IT_FF1:
+ /* Clear CAN_RF1R_FULL1 (rc_w1)*/
+ CANx->RF1R = CAN_RF1R_FULL1;
+ break;
+ case CAN_IT_FOV1:
+ /* Clear CAN_RF1R_FOVR1 (rc_w1)*/
+ CANx->RF1R = CAN_RF1R_FOVR1;
+ break;
+ case CAN_IT_WKU:
+ /* Clear CAN_MSR_WKUI (rc_w1)*/
+ CANx->MSR = CAN_MSR_WKUI;
+ break;
+ case CAN_IT_SLK:
+ /* Clear CAN_MSR_SLAKI (rc_w1)*/
+ CANx->MSR = CAN_MSR_SLAKI;
+ break;
+ case CAN_IT_EWG:
+ /* Clear CAN_MSR_ERRI (rc_w1) */
+ CANx->MSR = CAN_MSR_ERRI;
+ /* @note the corresponding Flag is cleared by hardware depending on the CAN Bus status*/
+ break;
+ case CAN_IT_EPV:
+ /* Clear CAN_MSR_ERRI (rc_w1) */
+ CANx->MSR = CAN_MSR_ERRI;
+ /* @note the corresponding Flag is cleared by hardware depending on the CAN Bus status*/
+ break;
+ case CAN_IT_BOF:
+ /* Clear CAN_MSR_ERRI (rc_w1) */
+ CANx->MSR = CAN_MSR_ERRI;
+ /* @note the corresponding Flag is cleared by hardware depending on the CAN Bus status*/
+ break;
+ case CAN_IT_LEC:
+ /* Clear LEC bits */
+ CANx->ESR = RESET;
+ /* Clear CAN_MSR_ERRI (rc_w1) */
+ CANx->MSR = CAN_MSR_ERRI;
+ break;
+ case CAN_IT_ERR:
+ /*Clear LEC bits */
+ CANx->ESR = RESET;
+ /* Clear CAN_MSR_ERRI (rc_w1) */
+ CANx->MSR = CAN_MSR_ERRI;
+ /* @note BOFF, EPVF and EWGF Flags are cleared by hardware depending on the CAN Bus status*/
+ break;
+ default:
+ break;
+ }
+}
+ /**
+ * @}
+ */
+
+/**
+ * @brief Checks whether the CAN interrupt has occurred or not.
+ * @param CAN_Reg: specifies the CAN interrupt register to check.
+ * @param It_Bit: specifies the interrupt source bit to check.
+ * @retval The new state of the CAN Interrupt (SET or RESET).
+ */
+static ITStatus CheckITStatus(uint32_t CAN_Reg, uint32_t It_Bit)
+{
+ ITStatus pendingbitstatus = RESET;
+
+ if ((CAN_Reg & It_Bit) != (uint32_t)RESET)
+ {
+ /* CAN_IT is set */
+ pendingbitstatus = SET;
+ }
+ else
+ {
+ /* CAN_IT is reset */
+ pendingbitstatus = RESET;
+ }
+ return pendingbitstatus;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/src/stm32f2xx_crc.c b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/src/stm32f2xx_crc.c
new file mode 100644
index 0000000..4273770
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/src/stm32f2xx_crc.c
@@ -0,0 +1,133 @@
+/**
+ ******************************************************************************
+ * @file stm32f2xx_crc.c
+ * @author MCD Application Team
+ * @version V1.1.2
+ * @date 05-March-2012
+ * @brief This file provides all the CRC firmware 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 "stm32f2xx_crc.h"
+
+/** @addtogroup STM32F2xx_StdPeriph_Driver
+ * @{
+ */
+
+/** @defgroup CRC
+ * @brief CRC driver modules
+ * @{
+ */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+/** @defgroup CRC_Private_Functions
+ * @{
+ */
+
+/**
+ * @brief Resets the CRC Data register (DR).
+ * @param None
+ * @retval None
+ */
+void CRC_ResetDR(void)
+{
+ /* Reset CRC generator */
+ CRC->CR = CRC_CR_RESET;
+}
+
+/**
+ * @brief Computes the 32-bit CRC of a given data word(32-bit).
+ * @param Data: data word(32-bit) to compute its CRC
+ * @retval 32-bit CRC
+ */
+uint32_t CRC_CalcCRC(uint32_t Data)
+{
+ CRC->DR = Data;
+
+ return (CRC->DR);
+}
+
+/**
+ * @brief Computes the 32-bit CRC of a given buffer of data word(32-bit).
+ * @param pBuffer: pointer to the buffer containing the data to be computed
+ * @param BufferLength: length of the buffer to be computed
+ * @retval 32-bit CRC
+ */
+uint32_t CRC_CalcBlockCRC(uint32_t pBuffer[], uint32_t BufferLength)
+{
+ uint32_t index = 0;
+
+ for(index = 0; index < BufferLength; index++)
+ {
+ CRC->DR = pBuffer[index];
+ }
+ return (CRC->DR);
+}
+
+/**
+ * @brief Returns the current CRC value.
+ * @param None
+ * @retval 32-bit CRC
+ */
+uint32_t CRC_GetCRC(void)
+{
+ return (CRC->DR);
+}
+
+/**
+ * @brief Stores a 8-bit data in the Independent Data(ID) register.
+ * @param IDValue: 8-bit value to be stored in the ID register
+ * @retval None
+ */
+void CRC_SetIDRegister(uint8_t IDValue)
+{
+ CRC->IDR = IDValue;
+}
+
+/**
+ * @brief Returns the 8-bit data stored in the Independent Data(ID) register
+ * @param None
+ * @retval 8-bit value of the ID register
+ */
+uint8_t CRC_GetIDRegister(void)
+{
+ return (CRC->IDR);
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/src/stm32f2xx_cryp.c b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/src/stm32f2xx_cryp.c
new file mode 100644
index 0000000..d97a8c1
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/src/stm32f2xx_cryp.c
@@ -0,0 +1,856 @@
+/**
+ ******************************************************************************
+ * @file stm32f2xx_cryp.c
+ * @author MCD Application Team
+ * @version V1.1.2
+ * @date 05-March-2012
+ * @brief This file provides firmware functions to manage the following
+ * functionalities of the Cryptographic processor (CRYP) peripheral:
+ * - Initialization and Configuration functions
+ * - Data treatment functions
+ * - Context swapping functions
+ * - DMA interface function
+ * - Interrupts and flags management
+ *
+ * @verbatim
+ *
+ * ===================================================================
+ * How to use this driver
+ * ===================================================================
+ * 1. Enable the CRYP controller clock using
+ * RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_CRYP, ENABLE); function.
+ *
+ * 2. Initialise the CRYP using CRYP_Init(), CRYP_KeyInit() and if
+ * needed CRYP_IVInit().
+ *
+ * 3. Flush the IN and OUT FIFOs by using CRYP_FIFOFlush() function.
+ *
+ * 4. Enable the CRYP controller using the CRYP_Cmd() function.
+ *
+ * 5. If using DMA for Data input and output transfer,
+ * Activate the needed DMA Requests using CRYP_DMACmd() function
+
+ * 6. If DMA is not used for data transfer, use CRYP_DataIn() and
+ * CRYP_DataOut() functions to enter data to IN FIFO and get result
+ * from OUT FIFO.
+ *
+ * 7. To control CRYP events you can use one of the following
+ * two methods:
+ * - Check on CRYP flags using the CRYP_GetFlagStatus() function.
+ * - Use CRYP interrupts through the function CRYP_ITConfig() at
+ * initialization phase and CRYP_GetITStatus() function into
+ * interrupt routines in processing phase.
+ *
+ * 8. Save and restore Cryptographic processor context using
+ * CRYP_SaveContext() and CRYP_RestoreContext() functions.
+ *
+ *
+ * ===================================================================
+ * Procedure to perform an encryption or a decryption
+ * ===================================================================
+ *
+ * Initialization
+ * ===============
+ * 1. Initialize the peripheral using CRYP_Init(), CRYP_KeyInit() and
+ * CRYP_IVInit functions:
+ * - Configure the key size (128-, 192- or 256-bit, in the AES only)
+ * - Enter the symmetric key
+ * - Configure the data type
+ * - In case of decryption in AES-ECB or AES-CBC, you must prepare
+ * the key: configure the key preparation mode. Then Enable the CRYP
+ * peripheral using CRYP_Cmd() function: the BUSY flag is set.
+ * Wait until BUSY flag is reset : the key is prepared for decryption
+ * - Configure the algorithm and chaining (the DES/TDES in ECB/CBC, the
+ * AES in ECB/CBC/CTR)
+ * - Configure the direction (encryption/decryption).
+ * - Write the initialization vectors (in CBC or CTR modes only)
+ *
+ * 2. Flush the IN and OUT FIFOs using the CRYP_FIFOFlush() function
+ *
+ *
+ * Basic Processing mode (polling mode)
+ * ====================================
+ * 1. Enable the cryptographic processor using CRYP_Cmd() function.
+ *
+ * 2. Write the first blocks in the input FIFO (2 to 8 words) using
+ * CRYP_DataIn() function.
+ *
+ * 3. Repeat the following sequence until the complete message has been
+ * processed:
+ *
+ * a) Wait for flag CRYP_FLAG_OFNE occurs (using CRYP_GetFlagStatus()
+ * function), then read the OUT-FIFO using CRYP_DataOut() function
+ * (1 block or until the FIFO is empty)
+ *
+ * b) Wait for flag CRYP_FLAG_IFNF occurs, (using CRYP_GetFlagStatus()
+ * function then write the IN FIFO using CRYP_DataIn() function
+ * (1 block or until the FIFO is full)
+ *
+ * 4. At the end of the processing, CRYP_FLAG_BUSY flag will be reset and
+ * both FIFOs are empty (CRYP_FLAG_IFEM is set and CRYP_FLAG_OFNE is
+ * reset). You can disable the peripheral using CRYP_Cmd() function.
+ *
+ * Interrupts Processing mode
+ * ===========================
+ * In this mode, Processing is done when the data are transferred by the
+ * CPU during interrupts.
+ *
+ * 1. Enable the interrupts CRYP_IT_INI and CRYP_IT_OUTI using
+ * CRYP_ITConfig() function.
+ *
+ * 2. Enable the cryptographic processor using CRYP_Cmd() function.
+ *
+ * 3. In the CRYP_IT_INI interrupt handler : load the input message into the
+ * IN FIFO using CRYP_DataIn() function . You can load 2 or 4 words at a
+ * time, or load data until the IN FIFO is full. When the last word of
+ * the message has been entered into the IN FIFO, disable the CRYP_IT_INI
+ * interrupt (using CRYP_ITConfig() function).
+ *
+ * 4. In the CRYP_IT_OUTI interrupt handler : read the output message from
+ * the OUT FIFO using CRYP_DataOut() function. You can read 1 block (2 or
+ * 4 words) at a time or read data until the FIFO is empty.
+ * When the last word has been read, INIM=0, BUSY=0 and both FIFOs are
+ * empty (CRYP_FLAG_IFEM is set and CRYP_FLAG_OFNE is reset).
+ * You can disable the CRYP_IT_OUTI interrupt (using CRYP_ITConfig()
+ * function) and you can disable the peripheral using CRYP_Cmd() function.
+ *
+ * DMA Processing mode
+ * ====================
+ * In this mode, Processing is done when the DMA is used to transfer the
+ * data from/to the memory.
+ *
+ * 1. Configure the DMA controller to transfer the input data from the
+ * memory using DMA_Init() function.
+ * The transfer length is the length of the message.
+ * As message padding is not managed by the peripheral, the message
+ * length must be an entire number of blocks. The data are transferred
+ * in burst mode. The burst length is 4 words in the AES and 2 or 4
+ * words in the DES/TDES. The DMA should be configured to set an
+ * interrupt on transfer completion of the output data to indicate that
+ * the processing is finished.
+ * Refer to DMA peripheral driver for more details.
+ *
+ * 2. Enable the cryptographic processor using CRYP_Cmd() function.
+ * Enable the DMA requests CRYP_DMAReq_DataIN and CRYP_DMAReq_DataOUT
+ * using CRYP_DMACmd() function.
+ *
+ * 3. All the transfers and processing are managed by the DMA and the
+ * cryptographic processor. The DMA transfer complete interrupt indicates
+ * that the processing is complete. Both FIFOs are normally empty and
+ * CRYP_FLAG_BUSY flag is reset.
+ *
+ * @endverbatim
+ *
+ ******************************************************************************
+ * @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 "stm32f2xx_cryp.h"
+#include "stm32f2xx_rcc.h"
+
+/** @addtogroup STM32F2xx_StdPeriph_Driver
+ * @{
+ */
+
+/** @defgroup CRYP
+ * @brief CRYP driver modules
+ * @{
+ */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+#define FLAG_MASK ((uint8_t)0x20)
+#define MAX_TIMEOUT ((uint16_t)0xFFFF)
+
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+/** @defgroup CRYP_Private_Functions
+ * @{
+ */
+
+/** @defgroup CRYP_Group1 Initialization and Configuration functions
+ * @brief Initialization and Configuration functions
+ *
+@verbatim
+ ===============================================================================
+ Initialization and Configuration functions
+ ===============================================================================
+ This section provides functions allowing to
+ - Initialize the cryptographic Processor using CRYP_Init() function
+ - Encrypt or Decrypt
+ - mode : TDES-ECB, TDES-CBC,
+ DES-ECB, DES-CBC,
+ AES-ECB, AES-CBC, AES-CTR, AES-Key
+ - DataType : 32-bit data, 16-bit data, bit data or bit-string
+ - Key Size (only in AES modes)
+ - Configure the Encrypt or Decrypt Key using CRYP_KeyInit() function
+ - Configure the Initialization Vectors(IV) for CBC and CTR modes using
+ CRYP_IVInit() function.
+ - Flushes the IN and OUT FIFOs : using CRYP_FIFOFlush() function.
+ - Enable or disable the CRYP Processor using CRYP_Cmd() function
+
+
+@endverbatim
+ * @{
+ */
+/**
+ * @brief Deinitializes the CRYP peripheral registers to their default reset values
+ * @param None
+ * @retval None
+ */
+void CRYP_DeInit(void)
+{
+ /* Enable CRYP reset state */
+ RCC_AHB2PeriphResetCmd(RCC_AHB2Periph_CRYP, ENABLE);
+
+ /* Release CRYP from reset state */
+ RCC_AHB2PeriphResetCmd(RCC_AHB2Periph_CRYP, DISABLE);
+}
+
+/**
+ * @brief Initializes the CRYP peripheral according to the specified parameters
+ * in the CRYP_InitStruct.
+ * @param CRYP_InitStruct: pointer to a CRYP_InitTypeDef structure that contains
+ * the configuration information for the CRYP peripheral.
+ * @retval None
+ */
+void CRYP_Init(CRYP_InitTypeDef* CRYP_InitStruct)
+{
+ /* Check the parameters */
+ assert_param(IS_CRYP_ALGOMODE(CRYP_InitStruct->CRYP_AlgoMode));
+ assert_param(IS_CRYP_DATATYPE(CRYP_InitStruct->CRYP_DataType));
+ assert_param(IS_CRYP_ALGODIR(CRYP_InitStruct->CRYP_AlgoDir));
+
+ /* Select Algorithm mode*/
+ CRYP->CR &= ~CRYP_CR_ALGOMODE;
+ CRYP->CR |= CRYP_InitStruct->CRYP_AlgoMode;
+
+ /* Select dataType */
+ CRYP->CR &= ~CRYP_CR_DATATYPE;
+ CRYP->CR |= CRYP_InitStruct->CRYP_DataType;
+
+ /* select Key size (used only with AES algorithm) */
+ if ((CRYP_InitStruct->CRYP_AlgoMode == CRYP_AlgoMode_AES_ECB) ||
+ (CRYP_InitStruct->CRYP_AlgoMode == CRYP_AlgoMode_AES_CBC) ||
+ (CRYP_InitStruct->CRYP_AlgoMode == CRYP_AlgoMode_AES_CTR) ||
+ (CRYP_InitStruct->CRYP_AlgoMode == CRYP_AlgoMode_AES_Key))
+ {
+ assert_param(IS_CRYP_KEYSIZE(CRYP_InitStruct->CRYP_KeySize));
+ CRYP->CR &= ~CRYP_CR_KEYSIZE;
+ CRYP->CR |= CRYP_InitStruct->CRYP_KeySize; /* Key size and value must be
+ configured once the key has
+ been prepared */
+ }
+
+ /* Select data Direction */
+ CRYP->CR &= ~CRYP_CR_ALGODIR;
+ CRYP->CR |= CRYP_InitStruct->CRYP_AlgoDir;
+}
+
+/**
+ * @brief Fills each CRYP_InitStruct member with its default value.
+ * @param CRYP_InitStruct: pointer to a CRYP_InitTypeDef structure which will
+ * be initialized.
+ * @retval None
+ */
+void CRYP_StructInit(CRYP_InitTypeDef* CRYP_InitStruct)
+{
+ /* Initialize the CRYP_AlgoDir member */
+ CRYP_InitStruct->CRYP_AlgoDir = CRYP_AlgoDir_Encrypt;
+
+ /* initialize the CRYP_AlgoMode member */
+ CRYP_InitStruct->CRYP_AlgoMode = CRYP_AlgoMode_TDES_ECB;
+
+ /* initialize the CRYP_DataType member */
+ CRYP_InitStruct->CRYP_DataType = CRYP_DataType_32b;
+
+ /* Initialize the CRYP_KeySize member */
+ CRYP_InitStruct->CRYP_KeySize = CRYP_KeySize_128b;
+}
+
+/**
+ * @brief Initializes the CRYP Keys according to the specified parameters in
+ * the CRYP_KeyInitStruct.
+ * @param CRYP_KeyInitStruct: pointer to a CRYP_KeyInitTypeDef structure that
+ * contains the configuration information for the CRYP Keys.
+ * @retval None
+ */
+void CRYP_KeyInit(CRYP_KeyInitTypeDef* CRYP_KeyInitStruct)
+{
+ /* Key Initialisation */
+ CRYP->K0LR = CRYP_KeyInitStruct->CRYP_Key0Left;
+ CRYP->K0RR = CRYP_KeyInitStruct->CRYP_Key0Right;
+ CRYP->K1LR = CRYP_KeyInitStruct->CRYP_Key1Left;
+ CRYP->K1RR = CRYP_KeyInitStruct->CRYP_Key1Right;
+ CRYP->K2LR = CRYP_KeyInitStruct->CRYP_Key2Left;
+ CRYP->K2RR = CRYP_KeyInitStruct->CRYP_Key2Right;
+ CRYP->K3LR = CRYP_KeyInitStruct->CRYP_Key3Left;
+ CRYP->K3RR = CRYP_KeyInitStruct->CRYP_Key3Right;
+}
+
+/**
+ * @brief Fills each CRYP_KeyInitStruct member with its default value.
+ * @param CRYP_KeyInitStruct: pointer to a CRYP_KeyInitTypeDef structure
+ * which will be initialized.
+ * @retval None
+ */
+void CRYP_KeyStructInit(CRYP_KeyInitTypeDef* CRYP_KeyInitStruct)
+{
+ CRYP_KeyInitStruct->CRYP_Key0Left = 0;
+ CRYP_KeyInitStruct->CRYP_Key0Right = 0;
+ CRYP_KeyInitStruct->CRYP_Key1Left = 0;
+ CRYP_KeyInitStruct->CRYP_Key1Right = 0;
+ CRYP_KeyInitStruct->CRYP_Key2Left = 0;
+ CRYP_KeyInitStruct->CRYP_Key2Right = 0;
+ CRYP_KeyInitStruct->CRYP_Key3Left = 0;
+ CRYP_KeyInitStruct->CRYP_Key3Right = 0;
+}
+/**
+ * @brief Initializes the CRYP Initialization Vectors(IV) according to the
+ * specified parameters in the CRYP_IVInitStruct.
+ * @param CRYP_IVInitStruct: pointer to a CRYP_IVInitTypeDef structure that contains
+ * the configuration information for the CRYP Initialization Vectors(IV).
+ * @retval None
+ */
+void CRYP_IVInit(CRYP_IVInitTypeDef* CRYP_IVInitStruct)
+{
+ CRYP->IV0LR = CRYP_IVInitStruct->CRYP_IV0Left;
+ CRYP->IV0RR = CRYP_IVInitStruct->CRYP_IV0Right;
+ CRYP->IV1LR = CRYP_IVInitStruct->CRYP_IV1Left;
+ CRYP->IV1RR = CRYP_IVInitStruct->CRYP_IV1Right;
+}
+
+/**
+ * @brief Fills each CRYP_IVInitStruct member with its default value.
+ * @param CRYP_IVInitStruct: pointer to a CRYP_IVInitTypeDef Initialization
+ * Vectors(IV) structure which will be initialized.
+ * @retval None
+ */
+void CRYP_IVStructInit(CRYP_IVInitTypeDef* CRYP_IVInitStruct)
+{
+ CRYP_IVInitStruct->CRYP_IV0Left = 0;
+ CRYP_IVInitStruct->CRYP_IV0Right = 0;
+ CRYP_IVInitStruct->CRYP_IV1Left = 0;
+ CRYP_IVInitStruct->CRYP_IV1Right = 0;
+}
+
+/**
+ * @brief Flushes the IN and OUT FIFOs (that is read and write pointers of the
+ * FIFOs are reset)
+ * @note The FIFOs must be flushed only when BUSY flag is reset.
+ * @param None
+ * @retval None
+ */
+void CRYP_FIFOFlush(void)
+{
+ /* Reset the read and write pointers of the FIFOs */
+ CRYP->CR |= CRYP_CR_FFLUSH;
+}
+
+/**
+ * @brief Enables or disables the CRYP peripheral.
+ * @param NewState: new state of the CRYP peripheral.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void CRYP_Cmd(FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the Cryptographic processor */
+ CRYP->CR |= CRYP_CR_CRYPEN;
+ }
+ else
+ {
+ /* Disable the Cryptographic processor */
+ CRYP->CR &= ~CRYP_CR_CRYPEN;
+ }
+}
+/**
+ * @}
+ */
+
+/** @defgroup CRYP_Group2 CRYP Data processing functions
+ * @brief CRYP Data processing functions
+ *
+@verbatim
+ ===============================================================================
+ CRYP Data processing functions
+ ===============================================================================
+ This section provides functions allowing the encryption and decryption
+ operations:
+ - Enter data to be treated in the IN FIFO : using CRYP_DataIn() function.
+ - Get the data result from the OUT FIFO : using CRYP_DataOut() function.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Writes data in the Data Input register (DIN).
+ * @note After the DIN register has been read once or several times,
+ * the FIFO must be flushed (using CRYP_FIFOFlush() function).
+ * @param Data: data to write in Data Input register
+ * @retval None
+ */
+void CRYP_DataIn(uint32_t Data)
+{
+ CRYP->DR = Data;
+}
+
+/**
+ * @brief Returns the last data entered into the output FIFO.
+ * @param None
+ * @retval Last data entered into the output FIFO.
+ */
+uint32_t CRYP_DataOut(void)
+{
+ return CRYP->DOUT;
+}
+/**
+ * @}
+ */
+
+/** @defgroup CRYP_Group3 Context swapping functions
+ * @brief Context swapping functions
+ *
+@verbatim
+ ===============================================================================
+ Context swapping functions
+ ===============================================================================
+
+ This section provides functions allowing to save and store CRYP Context
+
+ It is possible to interrupt an encryption/ decryption/ key generation process
+ to perform another processing with a higher priority, and to complete the
+ interrupted process later on, when the higher-priority task is complete. To do
+ so, the context of the interrupted task must be saved from the CRYP registers
+ to memory, and then be restored from memory to the CRYP registers.
+
+ 1. To save the current context, use CRYP_SaveContext() function
+ 2. To restore the saved context, use CRYP_RestoreContext() function
+
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Saves the CRYP peripheral Context.
+ * @note This function stops DMA transfer before to save the context. After
+ * restoring the context, you have to enable the DMA again (if the DMA
+ * was previously used).
+ * @param CRYP_ContextSave: pointer to a CRYP_Context structure that contains
+ * the repository for current context.
+ * @param CRYP_KeyInitStruct: pointer to a CRYP_KeyInitTypeDef structure that
+ * contains the configuration information for the CRYP Keys.
+ * @retval None
+ */
+ErrorStatus CRYP_SaveContext(CRYP_Context* CRYP_ContextSave,
+ CRYP_KeyInitTypeDef* CRYP_KeyInitStruct)
+{
+ __IO uint32_t timeout = 0;
+ uint32_t ckeckmask = 0, bitstatus;
+ ErrorStatus status = ERROR;
+
+ /* Stop DMA transfers on the IN FIFO by clearing the DIEN bit in the CRYP_DMACR */
+ CRYP->DMACR &= ~(uint32_t)CRYP_DMACR_DIEN;
+
+ /* Wait until both the IN and OUT FIFOs are empty
+ (IFEM=1 and OFNE=0 in the CRYP_SR register) and the
+ BUSY bit is cleared. */
+
+ if ((CRYP->CR & (uint32_t)(CRYP_CR_ALGOMODE_TDES_ECB | CRYP_CR_ALGOMODE_TDES_CBC)) != (uint32_t)0 )/* TDES */
+ {
+ ckeckmask = CRYP_SR_IFEM | CRYP_SR_BUSY ;
+ }
+ else /* AES or DES */
+ {
+ ckeckmask = CRYP_SR_IFEM | CRYP_SR_BUSY | CRYP_SR_OFNE;
+ }
+
+ do
+ {
+ bitstatus = CRYP->SR & ckeckmask;
+ timeout++;
+ }
+ while ((timeout != MAX_TIMEOUT) && (bitstatus != CRYP_SR_IFEM));
+
+ if ((CRYP->SR & ckeckmask) != CRYP_SR_IFEM)
+ {
+ status = ERROR;
+ }
+ else
+ {
+ /* Stop DMA transfers on the OUT FIFO by
+ - writing the DOEN bit to 0 in the CRYP_DMACR register
+ - and clear the CRYPEN bit. */
+
+ CRYP->DMACR &= ~(uint32_t)CRYP_DMACR_DOEN;
+ CRYP->CR &= ~(uint32_t)CRYP_CR_CRYPEN;
+
+ /* Save the current configuration (bits [9:2] in the CRYP_CR register) */
+ CRYP_ContextSave->CR_bits9to2 = CRYP->CR & (CRYP_CR_KEYSIZE |
+ CRYP_CR_DATATYPE |
+ CRYP_CR_ALGOMODE |
+ CRYP_CR_ALGODIR);
+
+ /* and, if not in ECB mode, the initialization vectors. */
+ CRYP_ContextSave->CRYP_IV0LR = CRYP->IV0LR;
+ CRYP_ContextSave->CRYP_IV0RR = CRYP->IV0RR;
+ CRYP_ContextSave->CRYP_IV1LR = CRYP->IV1LR;
+ CRYP_ContextSave->CRYP_IV1RR = CRYP->IV1RR;
+
+ /* save The key value */
+ CRYP_ContextSave->CRYP_K0LR = CRYP_KeyInitStruct->CRYP_Key0Left;
+ CRYP_ContextSave->CRYP_K0RR = CRYP_KeyInitStruct->CRYP_Key0Right;
+ CRYP_ContextSave->CRYP_K1LR = CRYP_KeyInitStruct->CRYP_Key1Left;
+ CRYP_ContextSave->CRYP_K1RR = CRYP_KeyInitStruct->CRYP_Key1Right;
+ CRYP_ContextSave->CRYP_K2LR = CRYP_KeyInitStruct->CRYP_Key2Left;
+ CRYP_ContextSave->CRYP_K2RR = CRYP_KeyInitStruct->CRYP_Key2Right;
+ CRYP_ContextSave->CRYP_K3LR = CRYP_KeyInitStruct->CRYP_Key3Left;
+ CRYP_ContextSave->CRYP_K3RR = CRYP_KeyInitStruct->CRYP_Key3Right;
+
+ /* When needed, save the DMA status (pointers for IN and OUT messages,
+ number of remaining bytes, etc.) */
+
+ status = SUCCESS;
+ }
+
+ return status;
+}
+
+/**
+ * @brief Restores the CRYP peripheral Context.
+ * @note Since teh DMA transfer is stopped in CRYP_SaveContext() function,
+ * after restoring the context, you have to enable the DMA again (if the
+ * DMA was previously used).
+ * @param CRYP_ContextRestore: pointer to a CRYP_Context structure that contains
+ * the repository for saved context.
+ * @note The data that were saved during context saving must be rewrited into
+ * the IN FIFO.
+ * @retval None
+ */
+void CRYP_RestoreContext(CRYP_Context* CRYP_ContextRestore)
+{
+
+ /* Configure the processor with the saved configuration */
+ CRYP->CR = CRYP_ContextRestore->CR_bits9to2;
+
+ /* restore The key value */
+ CRYP->K0LR = CRYP_ContextRestore->CRYP_K0LR;
+ CRYP->K0RR = CRYP_ContextRestore->CRYP_K0RR;
+ CRYP->K1LR = CRYP_ContextRestore->CRYP_K1LR;
+ CRYP->K1RR = CRYP_ContextRestore->CRYP_K1RR;
+ CRYP->K2LR = CRYP_ContextRestore->CRYP_K2LR;
+ CRYP->K2RR = CRYP_ContextRestore->CRYP_K2RR;
+ CRYP->K3LR = CRYP_ContextRestore->CRYP_K3LR;
+ CRYP->K3RR = CRYP_ContextRestore->CRYP_K3RR;
+
+ /* and the initialization vectors. */
+ CRYP->IV0LR = CRYP_ContextRestore->CRYP_IV0LR;
+ CRYP->IV0RR = CRYP_ContextRestore->CRYP_IV0RR;
+ CRYP->IV1LR = CRYP_ContextRestore->CRYP_IV1LR;
+ CRYP->IV1RR = CRYP_ContextRestore->CRYP_IV1RR;
+
+ /* Enable the cryptographic processor */
+ CRYP->CR |= CRYP_CR_CRYPEN;
+}
+/**
+ * @}
+ */
+
+/** @defgroup CRYP_Group4 CRYP's DMA interface Configuration function
+ * @brief CRYP's DMA interface Configuration function
+ *
+@verbatim
+ ===============================================================================
+ CRYP's DMA interface Configuration function
+ ===============================================================================
+
+ This section provides functions allowing to configure the DMA interface for
+ CRYP data input and output transfer.
+
+ When the DMA mode is enabled (using the CRYP_DMACmd() function), data can be
+ transferred:
+ - From memory to the CRYP IN FIFO using the DMA peripheral by enabling
+ the CRYP_DMAReq_DataIN request.
+ - From the CRYP OUT FIFO to the memory using the DMA peripheral by enabling
+ the CRYP_DMAReq_DataOUT request.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Enables or disables the CRYP DMA interface.
+ * @param CRYP_DMAReq: specifies the CRYP DMA transfer request to be enabled or disabled.
+ * This parameter can be any combination of the following values:
+ * @arg CRYP_DMAReq_DataOUT: DMA for outgoing(Tx) data transfer
+ * @arg CRYP_DMAReq_DataIN: DMA for incoming(Rx) data transfer
+ * @param NewState: new state of the selected CRYP DMA transfer request.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void CRYP_DMACmd(uint8_t CRYP_DMAReq, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_CRYP_DMAREQ(CRYP_DMAReq));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the selected CRYP DMA request */
+ CRYP->DMACR |= CRYP_DMAReq;
+ }
+ else
+ {
+ /* Disable the selected CRYP DMA request */
+ CRYP->DMACR &= (uint8_t)~CRYP_DMAReq;
+ }
+}
+/**
+ * @}
+ */
+
+/** @defgroup CRYP_Group5 Interrupts and flags management functions
+ * @brief Interrupts and flags management functions
+ *
+@verbatim
+ ===============================================================================
+ Interrupts and flags management functions
+ ===============================================================================
+
+ This section provides functions allowing to configure the CRYP Interrupts and
+ to get the status and Interrupts pending bits.
+
+ The CRYP provides 2 Interrupts sources and 7 Flags:
+
+ Flags :
+ -------
+
+ 1. CRYP_FLAG_IFEM : Set when Input FIFO is empty.
+ This Flag is cleared only by hardware.
+
+ 2. CRYP_FLAG_IFNF : Set when Input FIFO is not full.
+ This Flag is cleared only by hardware.
+
+
+ 3. CRYP_FLAG_INRIS : Set when Input FIFO Raw interrupt is pending
+ it gives the raw interrupt state prior to masking
+ of the input FIFO service interrupt.
+ This Flag is cleared only by hardware.
+
+ 4. CRYP_FLAG_OFNE : Set when Output FIFO not empty.
+ This Flag is cleared only by hardware.
+
+ 5. CRYP_FLAG_OFFU : Set when Output FIFO is full.
+ This Flag is cleared only by hardware.
+
+ 6. CRYP_FLAG_OUTRIS : Set when Output FIFO Raw interrupt is pending
+ it gives the raw interrupt state prior to masking
+ of the output FIFO service interrupt.
+ This Flag is cleared only by hardware.
+
+ 7. CRYP_FLAG_BUSY : Set when the CRYP core is currently processing a
+ block of data or a key preparation (for AES
+ decryption).
+ This Flag is cleared only by hardware.
+ To clear it, the CRYP core must be disabled and the
+ last processing has completed.
+
+ Interrupts :
+ ------------
+
+ 1. CRYP_IT_INI : The input FIFO service interrupt is asserted when there
+ are less than 4 words in the input FIFO.
+ This interrupt is associated to CRYP_FLAG_INRIS flag.
+
+ @note This interrupt is cleared by performing write operations
+ to the input FIFO until it holds 4 or more words. The
+ input FIFO service interrupt INMIS is enabled with the
+ CRYP enable bit. Consequently, when CRYP is disabled, the
+ INMIS signal is low even if the input FIFO is empty.
+
+
+
+ 2. CRYP_IT_OUTI : The output FIFO service interrupt is asserted when there
+ is one or more (32-bit word) data items in the output FIFO.
+ This interrupt is associated to CRYP_FLAG_OUTRIS flag.
+
+ @note This interrupt is cleared by reading data from the output
+ FIFO until there is no valid (32-bit) word left (that is,
+ the interrupt follows the state of the OFNE (output FIFO
+ not empty) flag).
+
+
+ Managing the CRYP controller events :
+ ------------------------------------
+ The user should identify which mode will be used in his application to manage
+ the CRYP controller events: Polling mode or Interrupt mode.
+
+ 1. In the Polling Mode it is advised to use the following functions:
+ - CRYP_GetFlagStatus() : to check if flags events occur.
+
+ @note The CRYPT flags do not need to be cleared since they are cleared as
+ soon as the associated event are reset.
+
+
+ 2. In the Interrupt Mode it is advised to use the following functions:
+ - CRYP_ITConfig() : to enable or disable the interrupt source.
+ - CRYP_GetITStatus() : to check if Interrupt occurs.
+
+ @note The CRYPT interrupts have no pending bits, the interrupt is cleared as
+ soon as the associated event is reset.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Enables or disables the specified CRYP interrupts.
+ * @param CRYP_IT: specifies the CRYP interrupt source to be enabled or disabled.
+ * This parameter can be any combination of the following values:
+ * @arg CRYP_IT_INI: Input FIFO interrupt
+ * @arg CRYP_IT_OUTI: Output FIFO interrupt
+ * @param NewState: new state of the specified CRYP interrupt.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void CRYP_ITConfig(uint8_t CRYP_IT, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_CRYP_CONFIG_IT(CRYP_IT));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the selected CRYP interrupt */
+ CRYP->IMSCR |= CRYP_IT;
+ }
+ else
+ {
+ /* Disable the selected CRYP interrupt */
+ CRYP->IMSCR &= (uint8_t)~CRYP_IT;
+ }
+}
+
+/**
+ * @brief Checks whether the specified CRYP interrupt has occurred or not.
+ * @note This function checks the status of the masked interrupt (i.e the
+ * interrupt should be previously enabled).
+ * @param CRYP_IT: specifies the CRYP (masked) interrupt source to check.
+ * This parameter can be one of the following values:
+ * @arg CRYP_IT_INI: Input FIFO interrupt
+ * @arg CRYP_IT_OUTI: Output FIFO interrupt
+ * @retval The new state of CRYP_IT (SET or RESET).
+ */
+ITStatus CRYP_GetITStatus(uint8_t CRYP_IT)
+{
+ ITStatus bitstatus = RESET;
+ /* Check the parameters */
+ assert_param(IS_CRYP_GET_IT(CRYP_IT));
+
+ /* Check the status of the specified CRYP interrupt */
+ if ((CRYP->MISR & CRYP_IT) != (uint8_t)RESET)
+ {
+ /* CRYP_IT is set */
+ bitstatus = SET;
+ }
+ else
+ {
+ /* CRYP_IT is reset */
+ bitstatus = RESET;
+ }
+ /* Return the CRYP_IT status */
+ return bitstatus;
+}
+
+/**
+ * @brief Checks whether the specified CRYP flag is set or not.
+ * @param CRYP_FLAG: specifies the CRYP flag to check.
+ * This parameter can be one of the following values:
+ * @arg CRYP_FLAG_IFEM: Input FIFO Empty flag.
+ * @arg CRYP_FLAG_IFNF: Input FIFO Not Full flag.
+ * @arg CRYP_FLAG_OFNE: Output FIFO Not Empty flag.
+ * @arg CRYP_FLAG_OFFU: Output FIFO Full flag.
+ * @arg CRYP_FLAG_BUSY: Busy flag.
+ * @arg CRYP_FLAG_OUTRIS: Output FIFO raw interrupt flag.
+ * @arg CRYP_FLAG_INRIS: Input FIFO raw interrupt flag.
+ * @retval The new state of CRYP_FLAG (SET or RESET).
+ */
+FlagStatus CRYP_GetFlagStatus(uint8_t CRYP_FLAG)
+{
+ FlagStatus bitstatus = RESET;
+ uint32_t tempreg = 0;
+
+ /* Check the parameters */
+ assert_param(IS_CRYP_GET_FLAG(CRYP_FLAG));
+
+ /* check if the FLAG is in RISR register */
+ if ((CRYP_FLAG & FLAG_MASK) != 0x00)
+ {
+ tempreg = CRYP->RISR;
+ }
+ else /* The FLAG is in SR register */
+ {
+ tempreg = CRYP->SR;
+ }
+
+
+ /* Check the status of the specified CRYP flag */
+ if ((tempreg & CRYP_FLAG ) != (uint8_t)RESET)
+ {
+ /* CRYP_FLAG is set */
+ bitstatus = SET;
+ }
+ else
+ {
+ /* CRYP_FLAG is reset */
+ bitstatus = RESET;
+ }
+
+ /* Return the CRYP_FLAG status */
+ return bitstatus;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/src/stm32f2xx_cryp_aes.c b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/src/stm32f2xx_cryp_aes.c
new file mode 100644
index 0000000..a13aca3
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/src/stm32f2xx_cryp_aes.c
@@ -0,0 +1,644 @@
+/**
+ ******************************************************************************
+ * @file stm32f2xx_cryp_aes.c
+ * @author MCD Application Team
+ * @version V1.1.2
+ * @date 05-March-2012
+ * @brief This file provides high level functions to encrypt and decrypt an
+ * input message using AES in ECB/CBC/CTR modes.
+ * It uses the stm32f2xx_cryp.c/.h drivers to access the STM32F2xx CRYP
+ * peripheral.
+ *
+ * @verbatim
+ *
+ * ===================================================================
+ * How to use this driver
+ * ===================================================================
+ * 1. Enable The CRYP controller clock using
+ * RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_CRYP, ENABLE); function.
+ *
+ * 2. Encrypt and decrypt using AES in ECB Mode using CRYP_AES_ECB()
+ * function.
+ *
+ * 3. Encrypt and decrypt using AES in CBC Mode using CRYP_AES_CBC()
+ * function.
+ *
+ * 4. Encrypt and decrypt using AES in CTR Mode using CRYP_AES_CTR()
+ * function.
+ *
+ * @endverbatim
+ *
+ ******************************************************************************
+ * @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 "stm32f2xx_cryp.h"
+
+/** @addtogroup STM32F2xx_StdPeriph_Driver
+ * @{
+ */
+
+/** @defgroup CRYP
+ * @brief CRYP driver modules
+ * @{
+ */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+#define AESBUSY_TIMEOUT ((uint32_t) 0x00010000)
+
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+/** @defgroup CRYP_Private_Functions
+ * @{
+ */
+
+/** @defgroup CRYP_Group6 High Level AES functions
+ * @brief High Level AES functions
+ *
+@verbatim
+ ===============================================================================
+ High Level AES functions
+ ===============================================================================
+
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Encrypt and decrypt using AES in ECB Mode
+ * @param Mode: encryption or decryption Mode.
+ * This parameter can be one of the following values:
+ * @arg MODE_ENCRYPT: Encryption
+ * @arg MODE_DECRYPT: Decryption
+ * @param Key: Key used for AES algorithm.
+ * @param Keysize: length of the Key, must be a 128, 192 or 256.
+ * @param Input: pointer to the Input buffer.
+ * @param Ilength: length of the Input buffer, must be a multiple of 16.
+ * @param Output: pointer to the returned buffer.
+ * @retval An ErrorStatus enumeration value:
+ * - SUCCESS: Operation done
+ * - ERROR: Operation failed
+ */
+ErrorStatus CRYP_AES_ECB(uint8_t Mode, uint8_t* Key, uint16_t Keysize,
+ uint8_t* Input, uint32_t Ilength, uint8_t* Output)
+{
+ CRYP_InitTypeDef AES_CRYP_InitStructure;
+ CRYP_KeyInitTypeDef AES_CRYP_KeyInitStructure;
+ __IO uint32_t counter = 0;
+ uint32_t busystatus = 0;
+ ErrorStatus status = SUCCESS;
+ uint32_t keyaddr = (uint32_t)Key;
+ uint32_t inputaddr = (uint32_t)Input;
+ uint32_t outputaddr = (uint32_t)Output;
+ uint32_t i = 0;
+
+ /* Crypto structures initialisation*/
+ CRYP_KeyStructInit(&AES_CRYP_KeyInitStructure);
+
+ switch(Keysize)
+ {
+ case 128:
+ AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_128b;
+ AES_CRYP_KeyInitStructure.CRYP_Key2Left = __REV(*(uint32_t*)(keyaddr));
+ keyaddr+=4;
+ AES_CRYP_KeyInitStructure.CRYP_Key2Right= __REV(*(uint32_t*)(keyaddr));
+ keyaddr+=4;
+ AES_CRYP_KeyInitStructure.CRYP_Key3Left = __REV(*(uint32_t*)(keyaddr));
+ keyaddr+=4;
+ AES_CRYP_KeyInitStructure.CRYP_Key3Right= __REV(*(uint32_t*)(keyaddr));
+ break;
+ case 192:
+ AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_192b;
+ AES_CRYP_KeyInitStructure.CRYP_Key1Left = __REV(*(uint32_t*)(keyaddr));
+ keyaddr+=4;
+ AES_CRYP_KeyInitStructure.CRYP_Key1Right= __REV(*(uint32_t*)(keyaddr));
+ keyaddr+=4;
+ AES_CRYP_KeyInitStructure.CRYP_Key2Left = __REV(*(uint32_t*)(keyaddr));
+ keyaddr+=4;
+ AES_CRYP_KeyInitStructure.CRYP_Key2Right= __REV(*(uint32_t*)(keyaddr));
+ keyaddr+=4;
+ AES_CRYP_KeyInitStructure.CRYP_Key3Left = __REV(*(uint32_t*)(keyaddr));
+ keyaddr+=4;
+ AES_CRYP_KeyInitStructure.CRYP_Key3Right= __REV(*(uint32_t*)(keyaddr));
+ break;
+ case 256:
+ AES_CRYP_InitStructure.CRYP_KeySize = CRYP_KeySize_256b;
+ AES_CRYP_KeyInitStructure.CRYP_Key0Left = __REV(*(uint32_t*)(keyaddr));
+ keyaddr+=4;
+ AES_CRYP_KeyInitStructure.CRYP_Key0Right= __REV(*(uint32_t*)(keyaddr));
+ keyaddr+=4;
+ AES_CRYP_KeyInitStructure.CRYP_Key1Left = __REV(*(uint32_t*)(keyaddr));
+ keyaddr+=4;
+ AES_CRYP_KeyInitStructure.CRYP_Key1Right= __REV(*(uint32_t*)(keyaddr));
+ keyaddr+=4;
+ AES_CRYP_KeyInitStructure.CRYP_Key2Left = __REV(*(uint32_t*)(keyaddr));
+ keyaddr+=4;
+ AES_CRYP_KeyInitStructure.CRYP_Key2Right= __REV(*(uint32_t*)(keyaddr));
+ keyaddr+=4;
+ AES_CRYP_KeyInitStructure.CRYP_Key3Left = __REV(*(uint32_t*)(keyaddr));
+ keyaddr+=4;
+ AES_CRYP_KeyInitStructure.CRYP_Key3Right= __REV(*(uint32_t*)(keyaddr));
+ break;
+ default:
+ break;
+ }
+
+ /*------------------ AES Decryption ------------------*/
+ if(Mode == MODE_DECRYPT) /* AES decryption */
+ {
+ /* Flush IN/OUT FIFOs */
+ CRYP_FIFOFlush();
+
+ /* Crypto Init for Key preparation for decryption process */
+ AES_CRYP_InitStructure.CRYP_AlgoDir = CRYP_AlgoDir_Decrypt;
+ AES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_AES_Key;
+ AES_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_32b;
+ CRYP_Init(&AES_CRYP_InitStructure);
+
+ /* Key Initialisation */
+ CRYP_KeyInit(&AES_CRYP_KeyInitStructure);
+
+ /* Enable Crypto processor */
+ CRYP_Cmd(ENABLE);
+
+ /* wait until the Busy flag is RESET */
+ do
+ {
+ busystatus = CRYP_GetFlagStatus(CRYP_FLAG_BUSY);
+ counter++;
+ }while ((counter != AESBUSY_TIMEOUT) && (busystatus != RESET));
+
+ if (busystatus != RESET)
+ {
+ status = ERROR;
+ }
+ else
+ {
+ /* Crypto Init for decryption process */
+ AES_CRYP_InitStructure.CRYP_AlgoDir = CRYP_AlgoDir_Decrypt;
+ }
+ }
+ /*------------------ AES Encryption ------------------*/
+ else /* AES encryption */
+ {
+
+ CRYP_KeyInit(&AES_CRYP_KeyInitStructure);
+
+ /* Crypto Init for Encryption process */
+ AES_CRYP_InitStructure.CRYP_AlgoDir = CRYP_AlgoDir_Encrypt;
+ }
+
+ AES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_AES_ECB;
+ AES_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_8b;
+ CRYP_Init(&AES_CRYP_InitStructure);
+
+ /* Flush IN/OUT FIFOs */
+ CRYP_FIFOFlush();
+
+ /* Enable Crypto processor */
+ CRYP_Cmd(ENABLE);
+
+ for(i=0; ((i© 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 "stm32f2xx_cryp.h"
+
+
+/** @addtogroup STM32F2xx_StdPeriph_Driver
+ * @{
+ */
+
+/** @defgroup CRYP
+ * @brief CRYP driver modules
+ * @{
+ */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+#define DESBUSY_TIMEOUT ((uint32_t) 0x00010000)
+
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+
+/** @defgroup CRYP_Private_Functions
+ * @{
+ */
+
+/** @defgroup CRYP_Group8 High Level DES functions
+ * @brief High Level DES functions
+ *
+@verbatim
+ ===============================================================================
+ High Level DES functions
+ ===============================================================================
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Encrypt and decrypt using DES in ECB Mode
+ * @param Mode: encryption or decryption Mode.
+ * This parameter can be one of the following values:
+ * @arg MODE_ENCRYPT: Encryption
+ * @arg MODE_DECRYPT: Decryption
+ * @param Key: Key used for DES algorithm.
+ * @param Ilength: length of the Input buffer, must be a multiple of 8.
+ * @param Input: pointer to the Input buffer.
+ * @param Output: pointer to the returned buffer.
+ * @retval An ErrorStatus enumeration value:
+ * - SUCCESS: Operation done
+ * - ERROR: Operation failed
+ */
+ErrorStatus CRYP_DES_ECB(uint8_t Mode, uint8_t Key[8], uint8_t *Input,
+ uint32_t Ilength, uint8_t *Output)
+{
+ CRYP_InitTypeDef DES_CRYP_InitStructure;
+ CRYP_KeyInitTypeDef DES_CRYP_KeyInitStructure;
+ __IO uint32_t counter = 0;
+ uint32_t busystatus = 0;
+ ErrorStatus status = SUCCESS;
+ uint32_t keyaddr = (uint32_t)Key;
+ uint32_t inputaddr = (uint32_t)Input;
+ uint32_t outputaddr = (uint32_t)Output;
+ uint32_t i = 0;
+
+ /* Crypto structures initialisation*/
+ CRYP_KeyStructInit(&DES_CRYP_KeyInitStructure);
+
+ /* Crypto Init for Encryption process */
+ if( Mode == MODE_ENCRYPT ) /* DES encryption */
+ {
+ DES_CRYP_InitStructure.CRYP_AlgoDir = CRYP_AlgoDir_Encrypt;
+ }
+ else/* if( Mode == MODE_DECRYPT )*/ /* DES decryption */
+ {
+ DES_CRYP_InitStructure.CRYP_AlgoDir = CRYP_AlgoDir_Decrypt;
+ }
+
+ DES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_DES_ECB;
+ DES_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_8b;
+ CRYP_Init(&DES_CRYP_InitStructure);
+
+ /* Key Initialisation */
+ DES_CRYP_KeyInitStructure.CRYP_Key1Left = __REV(*(uint32_t*)(keyaddr));
+ keyaddr+=4;
+ DES_CRYP_KeyInitStructure.CRYP_Key1Right= __REV(*(uint32_t*)(keyaddr));
+ CRYP_KeyInit(& DES_CRYP_KeyInitStructure);
+
+ /* Flush IN/OUT FIFO */
+ CRYP_FIFOFlush();
+
+ /* Enable Crypto processor */
+ CRYP_Cmd(ENABLE);
+
+ for(i=0; ((i© 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 "stm32f2xx_cryp.h"
+
+
+/** @addtogroup STM32F2xx_StdPeriph_Driver
+ * @{
+ */
+
+/** @defgroup CRYP
+ * @brief CRYP driver modules
+ * @{
+ */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+#define TDESBUSY_TIMEOUT ((uint32_t) 0x00010000)
+
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+
+/** @defgroup CRYP_Private_Functions
+ * @{
+ */
+
+/** @defgroup CRYP_Group7 High Level TDES functions
+ * @brief High Level TDES functions
+ *
+@verbatim
+ ===============================================================================
+ High Level TDES functions
+ ===============================================================================
+
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Encrypt and decrypt using TDES in ECB Mode
+ * @param Mode: encryption or decryption Mode.
+ * This parameter can be one of the following values:
+ * @arg MODE_ENCRYPT: Encryption
+ * @arg MODE_DECRYPT: Decryption
+ * @param Key: Key used for TDES algorithm.
+ * @param Ilength: length of the Input buffer, must be a multiple of 8.
+ * @param Input: pointer to the Input buffer.
+ * @param Output: pointer to the returned buffer.
+ * @retval An ErrorStatus enumeration value:
+ * - SUCCESS: Operation done
+ * - ERROR: Operation failed
+ */
+ErrorStatus CRYP_TDES_ECB(uint8_t Mode, uint8_t Key[24], uint8_t *Input,
+ uint32_t Ilength, uint8_t *Output)
+{
+ CRYP_InitTypeDef TDES_CRYP_InitStructure;
+ CRYP_KeyInitTypeDef TDES_CRYP_KeyInitStructure;
+ __IO uint32_t counter = 0;
+ uint32_t busystatus = 0;
+ ErrorStatus status = SUCCESS;
+ uint32_t keyaddr = (uint32_t)Key;
+ uint32_t inputaddr = (uint32_t)Input;
+ uint32_t outputaddr = (uint32_t)Output;
+ uint32_t i = 0;
+
+ /* Crypto structures initialisation*/
+ CRYP_KeyStructInit(&TDES_CRYP_KeyInitStructure);
+
+ /* Crypto Init for Encryption process */
+ if(Mode == MODE_ENCRYPT) /* TDES encryption */
+ {
+ TDES_CRYP_InitStructure.CRYP_AlgoDir = CRYP_AlgoDir_Encrypt;
+ }
+ else /*if(Mode == MODE_DECRYPT)*/ /* TDES decryption */
+ {
+ TDES_CRYP_InitStructure.CRYP_AlgoDir = CRYP_AlgoDir_Decrypt;
+ }
+
+ TDES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_TDES_ECB;
+ TDES_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_8b;
+ CRYP_Init(&TDES_CRYP_InitStructure);
+
+ /* Key Initialisation */
+ TDES_CRYP_KeyInitStructure.CRYP_Key1Left = __REV(*(uint32_t*)(keyaddr));
+ keyaddr+=4;
+ TDES_CRYP_KeyInitStructure.CRYP_Key1Right= __REV(*(uint32_t*)(keyaddr));
+ keyaddr+=4;
+ TDES_CRYP_KeyInitStructure.CRYP_Key2Left = __REV(*(uint32_t*)(keyaddr));
+ keyaddr+=4;
+ TDES_CRYP_KeyInitStructure.CRYP_Key2Right= __REV(*(uint32_t*)(keyaddr));
+ keyaddr+=4;
+ TDES_CRYP_KeyInitStructure.CRYP_Key3Left = __REV(*(uint32_t*)(keyaddr));
+ keyaddr+=4;
+ TDES_CRYP_KeyInitStructure.CRYP_Key3Right= __REV(*(uint32_t*)(keyaddr));
+ CRYP_KeyInit(& TDES_CRYP_KeyInitStructure);
+
+ /* Flush IN/OUT FIFO */
+ CRYP_FIFOFlush();
+
+ /* Enable Crypto processor */
+ CRYP_Cmd(ENABLE);
+
+ for(i=0; ((i© 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 "stm32f2xx_dac.h"
+#include "stm32f2xx_rcc.h"
+
+/** @addtogroup STM32F2xx_StdPeriph_Driver
+ * @{
+ */
+
+/** @defgroup DAC
+ * @brief DAC driver modules
+ * @{
+ */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+
+/* CR register Mask */
+#define CR_CLEAR_MASK ((uint32_t)0x00000FFE)
+
+/* DAC Dual Channels SWTRIG masks */
+#define DUAL_SWTRIG_SET ((uint32_t)0x00000003)
+#define DUAL_SWTRIG_RESET ((uint32_t)0xFFFFFFFC)
+
+/* DHR registers offsets */
+#define DHR12R1_OFFSET ((uint32_t)0x00000008)
+#define DHR12R2_OFFSET ((uint32_t)0x00000014)
+#define DHR12RD_OFFSET ((uint32_t)0x00000020)
+
+/* DOR register offset */
+#define DOR_OFFSET ((uint32_t)0x0000002C)
+
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+/** @defgroup DAC_Private_Functions
+ * @{
+ */
+
+/** @defgroup DAC_Group1 DAC channels configuration
+ * @brief DAC channels configuration: trigger, output buffer, data format
+ *
+@verbatim
+ ===============================================================================
+ DAC channels configuration: trigger, output buffer, data format
+ ===============================================================================
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Deinitializes the DAC peripheral registers to their default reset values.
+ * @param None
+ * @retval None
+ */
+void DAC_DeInit(void)
+{
+ /* Enable DAC reset state */
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_DAC, ENABLE);
+ /* Release DAC from reset state */
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_DAC, DISABLE);
+}
+
+/**
+ * @brief Initializes the DAC peripheral according to the specified parameters
+ * in the DAC_InitStruct.
+ * @param DAC_Channel: the selected DAC channel.
+ * This parameter can be one of the following values:
+ * @arg DAC_Channel_1: DAC Channel1 selected
+ * @arg DAC_Channel_2: DAC Channel2 selected
+ * @param DAC_InitStruct: pointer to a DAC_InitTypeDef structure that contains
+ * the configuration information for the specified DAC channel.
+ * @retval None
+ */
+void DAC_Init(uint32_t DAC_Channel, DAC_InitTypeDef* DAC_InitStruct)
+{
+ uint32_t tmpreg1 = 0, tmpreg2 = 0;
+
+ /* Check the DAC parameters */
+ assert_param(IS_DAC_TRIGGER(DAC_InitStruct->DAC_Trigger));
+ assert_param(IS_DAC_GENERATE_WAVE(DAC_InitStruct->DAC_WaveGeneration));
+ assert_param(IS_DAC_LFSR_UNMASK_TRIANGLE_AMPLITUDE(DAC_InitStruct->DAC_LFSRUnmask_TriangleAmplitude));
+ assert_param(IS_DAC_OUTPUT_BUFFER_STATE(DAC_InitStruct->DAC_OutputBuffer));
+
+/*---------------------------- DAC CR Configuration --------------------------*/
+ /* Get the DAC CR value */
+ tmpreg1 = DAC->CR;
+ /* Clear BOFFx, TENx, TSELx, WAVEx and MAMPx bits */
+ tmpreg1 &= ~(CR_CLEAR_MASK << DAC_Channel);
+ /* Configure for the selected DAC channel: buffer output, trigger,
+ wave generation, mask/amplitude for wave generation */
+ /* Set TSELx and TENx bits according to DAC_Trigger value */
+ /* Set WAVEx bits according to DAC_WaveGeneration value */
+ /* Set MAMPx bits according to DAC_LFSRUnmask_TriangleAmplitude value */
+ /* Set BOFFx bit according to DAC_OutputBuffer value */
+ tmpreg2 = (DAC_InitStruct->DAC_Trigger | DAC_InitStruct->DAC_WaveGeneration |
+ DAC_InitStruct->DAC_LFSRUnmask_TriangleAmplitude | \
+ DAC_InitStruct->DAC_OutputBuffer);
+ /* Calculate CR register value depending on DAC_Channel */
+ tmpreg1 |= tmpreg2 << DAC_Channel;
+ /* Write to DAC CR */
+ DAC->CR = tmpreg1;
+}
+
+/**
+ * @brief Fills each DAC_InitStruct member with its default value.
+ * @param DAC_InitStruct: pointer to a DAC_InitTypeDef structure which will
+ * be initialized.
+ * @retval None
+ */
+void DAC_StructInit(DAC_InitTypeDef* DAC_InitStruct)
+{
+/*--------------- Reset DAC init structure parameters values -----------------*/
+ /* Initialize the DAC_Trigger member */
+ DAC_InitStruct->DAC_Trigger = DAC_Trigger_None;
+ /* Initialize the DAC_WaveGeneration member */
+ DAC_InitStruct->DAC_WaveGeneration = DAC_WaveGeneration_None;
+ /* Initialize the DAC_LFSRUnmask_TriangleAmplitude member */
+ DAC_InitStruct->DAC_LFSRUnmask_TriangleAmplitude = DAC_LFSRUnmask_Bit0;
+ /* Initialize the DAC_OutputBuffer member */
+ DAC_InitStruct->DAC_OutputBuffer = DAC_OutputBuffer_Enable;
+}
+
+/**
+ * @brief Enables or disables the specified DAC channel.
+ * @param DAC_Channel: The selected DAC channel.
+ * This parameter can be one of the following values:
+ * @arg DAC_Channel_1: DAC Channel1 selected
+ * @arg DAC_Channel_2: DAC Channel2 selected
+ * @param NewState: new state of the DAC channel.
+ * This parameter can be: ENABLE or DISABLE.
+ * @note When the DAC channel is enabled the trigger source can no more be modified.
+ * @retval None
+ */
+void DAC_Cmd(uint32_t DAC_Channel, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_DAC_CHANNEL(DAC_Channel));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the selected DAC channel */
+ DAC->CR |= (DAC_CR_EN1 << DAC_Channel);
+ }
+ else
+ {
+ /* Disable the selected DAC channel */
+ DAC->CR &= (~(DAC_CR_EN1 << DAC_Channel));
+ }
+}
+
+/**
+ * @brief Enables or disables the selected DAC channel software trigger.
+ * @param DAC_Channel: The selected DAC channel.
+ * This parameter can be one of the following values:
+ * @arg DAC_Channel_1: DAC Channel1 selected
+ * @arg DAC_Channel_2: DAC Channel2 selected
+ * @param NewState: new state of the selected DAC channel software trigger.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void DAC_SoftwareTriggerCmd(uint32_t DAC_Channel, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_DAC_CHANNEL(DAC_Channel));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable software trigger for the selected DAC channel */
+ DAC->SWTRIGR |= (uint32_t)DAC_SWTRIGR_SWTRIG1 << (DAC_Channel >> 4);
+ }
+ else
+ {
+ /* Disable software trigger for the selected DAC channel */
+ DAC->SWTRIGR &= ~((uint32_t)DAC_SWTRIGR_SWTRIG1 << (DAC_Channel >> 4));
+ }
+}
+
+/**
+ * @brief Enables or disables simultaneously the two DAC channels software triggers.
+ * @param NewState: new state of the DAC channels software triggers.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void DAC_DualSoftwareTriggerCmd(FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable software trigger for both DAC channels */
+ DAC->SWTRIGR |= DUAL_SWTRIG_SET;
+ }
+ else
+ {
+ /* Disable software trigger for both DAC channels */
+ DAC->SWTRIGR &= DUAL_SWTRIG_RESET;
+ }
+}
+
+/**
+ * @brief Enables or disables the selected DAC channel wave generation.
+ * @param DAC_Channel: The selected DAC channel.
+ * This parameter can be one of the following values:
+ * @arg DAC_Channel_1: DAC Channel1 selected
+ * @arg DAC_Channel_2: DAC Channel2 selected
+ * @param DAC_Wave: specifies the wave type to enable or disable.
+ * This parameter can be one of the following values:
+ * @arg DAC_Wave_Noise: noise wave generation
+ * @arg DAC_Wave_Triangle: triangle wave generation
+ * @param NewState: new state of the selected DAC channel wave generation.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void DAC_WaveGenerationCmd(uint32_t DAC_Channel, uint32_t DAC_Wave, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_DAC_CHANNEL(DAC_Channel));
+ assert_param(IS_DAC_WAVE(DAC_Wave));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the selected wave generation for the selected DAC channel */
+ DAC->CR |= DAC_Wave << DAC_Channel;
+ }
+ else
+ {
+ /* Disable the selected wave generation for the selected DAC channel */
+ DAC->CR &= ~(DAC_Wave << DAC_Channel);
+ }
+}
+
+/**
+ * @brief Set the specified data holding register value for DAC channel1.
+ * @param DAC_Align: Specifies the data alignment for DAC channel1.
+ * This parameter can be one of the following values:
+ * @arg DAC_Align_8b_R: 8bit right data alignment selected
+ * @arg DAC_Align_12b_L: 12bit left data alignment selected
+ * @arg DAC_Align_12b_R: 12bit right data alignment selected
+ * @param Data: Data to be loaded in the selected data holding register.
+ * @retval None
+ */
+void DAC_SetChannel1Data(uint32_t DAC_Align, uint16_t Data)
+{
+ __IO uint32_t tmp = 0;
+
+ /* Check the parameters */
+ assert_param(IS_DAC_ALIGN(DAC_Align));
+ assert_param(IS_DAC_DATA(Data));
+
+ tmp = (uint32_t)DAC_BASE;
+ tmp += DHR12R1_OFFSET + DAC_Align;
+
+ /* Set the DAC channel1 selected data holding register */
+ *(__IO uint32_t *) tmp = Data;
+}
+
+/**
+ * @brief Set the specified data holding register value for DAC channel2.
+ * @param DAC_Align: Specifies the data alignment for DAC channel2.
+ * This parameter can be one of the following values:
+ * @arg DAC_Align_8b_R: 8bit right data alignment selected
+ * @arg DAC_Align_12b_L: 12bit left data alignment selected
+ * @arg DAC_Align_12b_R: 12bit right data alignment selected
+ * @param Data: Data to be loaded in the selected data holding register.
+ * @retval None
+ */
+void DAC_SetChannel2Data(uint32_t DAC_Align, uint16_t Data)
+{
+ __IO uint32_t tmp = 0;
+
+ /* Check the parameters */
+ assert_param(IS_DAC_ALIGN(DAC_Align));
+ assert_param(IS_DAC_DATA(Data));
+
+ tmp = (uint32_t)DAC_BASE;
+ tmp += DHR12R2_OFFSET + DAC_Align;
+
+ /* Set the DAC channel2 selected data holding register */
+ *(__IO uint32_t *)tmp = Data;
+}
+
+/**
+ * @brief Set the specified data holding register value for dual channel DAC.
+ * @param DAC_Align: Specifies the data alignment for dual channel DAC.
+ * This parameter can be one of the following values:
+ * @arg DAC_Align_8b_R: 8bit right data alignment selected
+ * @arg DAC_Align_12b_L: 12bit left data alignment selected
+ * @arg DAC_Align_12b_R: 12bit right data alignment selected
+ * @param Data2: Data for DAC Channel2 to be loaded in the selected data holding register.
+ * @param Data1: Data for DAC Channel1 to be loaded in the selected data holding register.
+ * @note In dual mode, a unique register access is required to write in both
+ * DAC channels at the same time.
+ * @retval None
+ */
+void DAC_SetDualChannelData(uint32_t DAC_Align, uint16_t Data2, uint16_t Data1)
+{
+ uint32_t data = 0, tmp = 0;
+
+ /* Check the parameters */
+ assert_param(IS_DAC_ALIGN(DAC_Align));
+ assert_param(IS_DAC_DATA(Data1));
+ assert_param(IS_DAC_DATA(Data2));
+
+ /* Calculate and set dual DAC data holding register value */
+ if (DAC_Align == DAC_Align_8b_R)
+ {
+ data = ((uint32_t)Data2 << 8) | Data1;
+ }
+ else
+ {
+ data = ((uint32_t)Data2 << 16) | Data1;
+ }
+
+ tmp = (uint32_t)DAC_BASE;
+ tmp += DHR12RD_OFFSET + DAC_Align;
+
+ /* Set the dual DAC selected data holding register */
+ *(__IO uint32_t *)tmp = data;
+}
+
+/**
+ * @brief Returns the last data output value of the selected DAC channel.
+ * @param DAC_Channel: The selected DAC channel.
+ * This parameter can be one of the following values:
+ * @arg DAC_Channel_1: DAC Channel1 selected
+ * @arg DAC_Channel_2: DAC Channel2 selected
+ * @retval The selected DAC channel data output value.
+ */
+uint16_t DAC_GetDataOutputValue(uint32_t DAC_Channel)
+{
+ __IO uint32_t tmp = 0;
+
+ /* Check the parameters */
+ assert_param(IS_DAC_CHANNEL(DAC_Channel));
+
+ tmp = (uint32_t) DAC_BASE ;
+ tmp += DOR_OFFSET + ((uint32_t)DAC_Channel >> 2);
+
+ /* Returns the DAC channel data output register value */
+ return (uint16_t) (*(__IO uint32_t*) tmp);
+}
+/**
+ * @}
+ */
+
+/** @defgroup DAC_Group2 DMA management functions
+ * @brief DMA management functions
+ *
+@verbatim
+ ===============================================================================
+ DMA management functions
+ ===============================================================================
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Enables or disables the specified DAC channel DMA request.
+ * @note When enabled DMA1 is generated when an external trigger (EXTI Line9,
+ * TIM2, TIM4, TIM5, TIM6, TIM7 or TIM8 but not a software trigger) occurs.
+ * @param DAC_Channel: The selected DAC channel.
+ * This parameter can be one of the following values:
+ * @arg DAC_Channel_1: DAC Channel1 selected
+ * @arg DAC_Channel_2: DAC Channel2 selected
+ * @param NewState: new state of the selected DAC channel DMA request.
+ * This parameter can be: ENABLE or DISABLE.
+ * @note The DAC channel1 is mapped on DMA1 Stream 5 channel7 which must be
+ * already configured.
+ * @note The DAC channel2 is mapped on DMA1 Stream 6 channel7 which must be
+ * already configured.
+ * @retval None
+ */
+void DAC_DMACmd(uint32_t DAC_Channel, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_DAC_CHANNEL(DAC_Channel));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the selected DAC channel DMA request */
+ DAC->CR |= (DAC_CR_DMAEN1 << DAC_Channel);
+ }
+ else
+ {
+ /* Disable the selected DAC channel DMA request */
+ DAC->CR &= (~(DAC_CR_DMAEN1 << DAC_Channel));
+ }
+}
+/**
+ * @}
+ */
+
+/** @defgroup DAC_Group3 Interrupts and flags management functions
+ * @brief Interrupts and flags management functions
+ *
+@verbatim
+ ===============================================================================
+ Interrupts and flags management functions
+ ===============================================================================
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Enables or disables the specified DAC interrupts.
+ * @param DAC_Channel: The selected DAC channel.
+ * This parameter can be one of the following values:
+ * @arg DAC_Channel_1: DAC Channel1 selected
+ * @arg DAC_Channel_2: DAC Channel2 selected
+ * @param DAC_IT: specifies the DAC interrupt sources to be enabled or disabled.
+ * This parameter can be the following values:
+ * @arg DAC_IT_DMAUDR: DMA underrun interrupt mask
+ * @note The DMA underrun occurs when a second external trigger arrives before the
+ * acknowledgement for the first external trigger is received (first request).
+ * @param NewState: new state of the specified DAC interrupts.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void DAC_ITConfig(uint32_t DAC_Channel, uint32_t DAC_IT, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_DAC_CHANNEL(DAC_Channel));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ assert_param(IS_DAC_IT(DAC_IT));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the selected DAC interrupts */
+ DAC->CR |= (DAC_IT << DAC_Channel);
+ }
+ else
+ {
+ /* Disable the selected DAC interrupts */
+ DAC->CR &= (~(uint32_t)(DAC_IT << DAC_Channel));
+ }
+}
+
+/**
+ * @brief Checks whether the specified DAC flag is set or not.
+ * @param DAC_Channel: The selected DAC channel.
+ * This parameter can be one of the following values:
+ * @arg DAC_Channel_1: DAC Channel1 selected
+ * @arg DAC_Channel_2: DAC Channel2 selected
+ * @param DAC_FLAG: specifies the flag to check.
+ * This parameter can be only of the following value:
+ * @arg DAC_FLAG_DMAUDR: DMA underrun flag
+ * @note The DMA underrun occurs when a second external trigger arrives before the
+ * acknowledgement for the first external trigger is received (first request).
+ * @retval The new state of DAC_FLAG (SET or RESET).
+ */
+FlagStatus DAC_GetFlagStatus(uint32_t DAC_Channel, uint32_t DAC_FLAG)
+{
+ FlagStatus bitstatus = RESET;
+ /* Check the parameters */
+ assert_param(IS_DAC_CHANNEL(DAC_Channel));
+ assert_param(IS_DAC_FLAG(DAC_FLAG));
+
+ /* Check the status of the specified DAC flag */
+ if ((DAC->SR & (DAC_FLAG << DAC_Channel)) != (uint8_t)RESET)
+ {
+ /* DAC_FLAG is set */
+ bitstatus = SET;
+ }
+ else
+ {
+ /* DAC_FLAG is reset */
+ bitstatus = RESET;
+ }
+ /* Return the DAC_FLAG status */
+ return bitstatus;
+}
+
+/**
+ * @brief Clears the DAC channel's pending flags.
+ * @param DAC_Channel: The selected DAC channel.
+ * This parameter can be one of the following values:
+ * @arg DAC_Channel_1: DAC Channel1 selected
+ * @arg DAC_Channel_2: DAC Channel2 selected
+ * @param DAC_FLAG: specifies the flag to clear.
+ * This parameter can be of the following value:
+ * @arg DAC_FLAG_DMAUDR: DMA underrun flag
+ * @note The DMA underrun occurs when a second external trigger arrives before the
+ * acknowledgement for the first external trigger is received (first request).
+ * @retval None
+ */
+void DAC_ClearFlag(uint32_t DAC_Channel, uint32_t DAC_FLAG)
+{
+ /* Check the parameters */
+ assert_param(IS_DAC_CHANNEL(DAC_Channel));
+ assert_param(IS_DAC_FLAG(DAC_FLAG));
+
+ /* Clear the selected DAC flags */
+ DAC->SR = (DAC_FLAG << DAC_Channel);
+}
+
+/**
+ * @brief Checks whether the specified DAC interrupt has occurred or not.
+ * @param DAC_Channel: The selected DAC channel.
+ * This parameter can be one of the following values:
+ * @arg DAC_Channel_1: DAC Channel1 selected
+ * @arg DAC_Channel_2: DAC Channel2 selected
+ * @param DAC_IT: specifies the DAC interrupt source to check.
+ * This parameter can be the following values:
+ * @arg DAC_IT_DMAUDR: DMA underrun interrupt mask
+ * @note The DMA underrun occurs when a second external trigger arrives before the
+ * acknowledgement for the first external trigger is received (first request).
+ * @retval The new state of DAC_IT (SET or RESET).
+ */
+ITStatus DAC_GetITStatus(uint32_t DAC_Channel, uint32_t DAC_IT)
+{
+ ITStatus bitstatus = RESET;
+ uint32_t enablestatus = 0;
+
+ /* Check the parameters */
+ assert_param(IS_DAC_CHANNEL(DAC_Channel));
+ assert_param(IS_DAC_IT(DAC_IT));
+
+ /* Get the DAC_IT enable bit status */
+ enablestatus = (DAC->CR & (DAC_IT << DAC_Channel)) ;
+
+ /* Check the status of the specified DAC interrupt */
+ if (((DAC->SR & (DAC_IT << DAC_Channel)) != (uint32_t)RESET) && enablestatus)
+ {
+ /* DAC_IT is set */
+ bitstatus = SET;
+ }
+ else
+ {
+ /* DAC_IT is reset */
+ bitstatus = RESET;
+ }
+ /* Return the DAC_IT status */
+ return bitstatus;
+}
+
+/**
+ * @brief Clears the DAC channel's interrupt pending bits.
+ * @param DAC_Channel: The selected DAC channel.
+ * This parameter can be one of the following values:
+ * @arg DAC_Channel_1: DAC Channel1 selected
+ * @arg DAC_Channel_2: DAC Channel2 selected
+ * @param DAC_IT: specifies the DAC interrupt pending bit to clear.
+ * This parameter can be the following values:
+ * @arg DAC_IT_DMAUDR: DMA underrun interrupt mask
+ * @note The DMA underrun occurs when a second external trigger arrives before the
+ * acknowledgement for the first external trigger is received (first request).
+ * @retval None
+ */
+void DAC_ClearITPendingBit(uint32_t DAC_Channel, uint32_t DAC_IT)
+{
+ /* Check the parameters */
+ assert_param(IS_DAC_CHANNEL(DAC_Channel));
+ assert_param(IS_DAC_IT(DAC_IT));
+
+ /* Clear the selected DAC interrupt pending bits */
+ DAC->SR = (DAC_IT << DAC_Channel);
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/src/stm32f2xx_dbgmcu.c b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/src/stm32f2xx_dbgmcu.c
new file mode 100644
index 0000000..160f2b4
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/src/stm32f2xx_dbgmcu.c
@@ -0,0 +1,180 @@
+/**
+ ******************************************************************************
+ * @file stm32f2xx_dbgmcu.c
+ * @author MCD Application Team
+ * @version V1.1.2
+ * @date 05-March-2012
+ * @brief This file provides all the DBGMCU firmware 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 "stm32f2xx_dbgmcu.h"
+
+/** @addtogroup STM32F2xx_StdPeriph_Driver
+ * @{
+ */
+
+/** @defgroup DBGMCU
+ * @brief DBGMCU driver modules
+ * @{
+ */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+#define IDCODE_DEVID_MASK ((uint32_t)0x00000FFF)
+
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+/** @defgroup DBGMCU_Private_Functions
+ * @{
+ */
+
+/**
+ * @brief Returns the device revision identifier.
+ * @param None
+ * @retval Device revision identifier
+ */
+uint32_t DBGMCU_GetREVID(void)
+{
+ return(DBGMCU->IDCODE >> 16);
+}
+
+/**
+ * @brief Returns the device identifier.
+ * @param None
+ * @retval Device identifier
+ */
+uint32_t DBGMCU_GetDEVID(void)
+{
+ return(DBGMCU->IDCODE & IDCODE_DEVID_MASK);
+}
+
+/**
+ * @brief Configures low power mode behavior when the MCU is in Debug mode.
+ * @param DBGMCU_Periph: specifies the low power mode.
+ * This parameter can be any combination of the following values:
+ * @arg DBGMCU_SLEEP: Keep debugger connection during SLEEP mode
+ * @arg DBGMCU_STOP: Keep debugger connection during STOP mode
+ * @arg DBGMCU_STANDBY: Keep debugger connection during STANDBY mode
+ * @param NewState: new state of the specified low power mode in Debug mode.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void DBGMCU_Config(uint32_t DBGMCU_Periph, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_DBGMCU_PERIPH(DBGMCU_Periph));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ if (NewState != DISABLE)
+ {
+ DBGMCU->CR |= DBGMCU_Periph;
+ }
+ else
+ {
+ DBGMCU->CR &= ~DBGMCU_Periph;
+ }
+}
+
+/**
+ * @brief Configures APB1 peripheral behavior when the MCU is in Debug mode.
+ * @param DBGMCU_Periph: specifies the APB1 peripheral.
+ * This parameter can be any combination of the following values:
+ * @arg DBGMCU_TIM2_STOP: TIM2 counter stopped when Core is halted
+ * @arg DBGMCU_TIM3_STOP: TIM3 counter stopped when Core is halted
+ * @arg DBGMCU_TIM4_STOP: TIM4 counter stopped when Core is halted
+ * @arg DBGMCU_TIM5_STOP: TIM5 counter stopped when Core is halted
+ * @arg DBGMCU_TIM6_STOP: TIM6 counter stopped when Core is halted
+ * @arg DBGMCU_TIM7_STOP: TIM7 counter stopped when Core is halted
+ * @arg DBGMCU_TIM12_STOP: TIM12 counter stopped when Core is halted
+ * @arg DBGMCU_TIM13_STOP: TIM13 counter stopped when Core is halted
+ * @arg DBGMCU_TIM14_STOP: TIM14 counter stopped when Core is halted
+ * @arg DBGMCU_RTC_STOP: RTC Wakeup counter stopped when Core is halted.
+ * @arg DBGMCU_WWDG_STOP: Debug WWDG stopped when Core is halted
+ * @arg DBGMCU_IWDG_STOP: Debug IWDG stopped when Core is halted
+ * @arg DBGMCU_I2C1_SMBUS_TIMEOUT: I2C1 SMBUS timeout mode stopped when Core is halted
+ * @arg DBGMCU_I2C2_SMBUS_TIMEOUT: I2C2 SMBUS timeout mode stopped when Core is halted
+ * @arg DBGMCU_I2C3_SMBUS_TIMEOUT: I2C3 SMBUS timeout mode stopped when Core is halted
+ * @arg DBGMCU_CAN2_STOP: Debug CAN1 stopped when Core is halted
+ * @arg DBGMCU_CAN1_STOP: Debug CAN2 stopped when Core is halted
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void DBGMCU_APB1PeriphConfig(uint32_t DBGMCU_Periph, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_DBGMCU_APB1PERIPH(DBGMCU_Periph));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ DBGMCU->APB1FZ |= DBGMCU_Periph;
+ }
+ else
+ {
+ DBGMCU->APB1FZ &= ~DBGMCU_Periph;
+ }
+}
+
+/**
+ * @brief Configures APB2 peripheral behavior when the MCU is in Debug mode.
+ * @param DBGMCU_Periph: specifies the APB2 peripheral.
+ * This parameter can be any combination of the following values:
+ * @arg DBGMCU_TIM1_STOP: TIM1 counter stopped when Core is halted
+ * @arg DBGMCU_TIM8_STOP: TIM8 counter stopped when Core is halted
+ * @arg DBGMCU_TIM9_STOP: TIM9 counter stopped when Core is halted
+ * @arg DBGMCU_TIM10_STOP: TIM10 counter stopped when Core is halted
+ * @arg DBGMCU_TIM11_STOP: TIM11 counter stopped when Core is halted
+ * @param NewState: new state of the specified peripheral in Debug mode.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void DBGMCU_APB2PeriphConfig(uint32_t DBGMCU_Periph, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_DBGMCU_APB2PERIPH(DBGMCU_Periph));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ DBGMCU->APB2FZ |= DBGMCU_Periph;
+ }
+ else
+ {
+ DBGMCU->APB2FZ &= ~DBGMCU_Periph;
+ }
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/src/stm32f2xx_dcmi.c b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/src/stm32f2xx_dcmi.c
new file mode 100644
index 0000000..5bf4c9c
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/src/stm32f2xx_dcmi.c
@@ -0,0 +1,540 @@
+/**
+ ******************************************************************************
+ * @file stm32f2xx_dcmi.c
+ * @author MCD Application Team
+ * @version V1.1.2
+ * @date 05-March-2012
+ * @brief This file provides firmware functions to manage the following
+ * functionalities of the DCMI peripheral:
+ * - Initialization and Configuration
+ * - Image capture functions
+ * - Interrupts and flags management
+ *
+ * @verbatim
+ *
+ *
+ * ===================================================================
+ * How to use this driver
+ * ===================================================================
+ *
+ * The sequence below describes how to use this driver to capture image
+ * from a camera module connected to the DCMI Interface.
+ * This sequence does not take into account the configuration of the
+ * camera module, which should be made before to configure and enable
+ * the DCMI to capture images.
+ *
+ * 1. Enable the clock for the DCMI and associated GPIOs using the following functions:
+ * RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_DCMI, ENABLE);
+ * RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOx, ENABLE);
+ *
+ * 2. DCMI pins configuration
+ * - Connect the involved DCMI pins to AF13 using the following function
+ * GPIO_PinAFConfig(GPIOx, GPIO_PinSourcex, GPIO_AF_DCMI);
+ * - Configure these DCMI pins in alternate function mode by calling the function
+ * GPIO_Init();
+ *
+ * 3. Declare a DCMI_InitTypeDef structure, for example:
+ * DCMI_InitTypeDef DCMI_InitStructure;
+ * and fill the DCMI_InitStructure variable with the allowed values
+ * of the structure member.
+ *
+ * 4. Initialize the DCMI interface by calling the function
+ * DCMI_Init(&DCMI_InitStructure);
+ *
+ * 5. Configure the DMA2_Stream1 channel1 to transfer Data from DCMI DR
+ * register to the destination memory buffer.
+ *
+ * 6. Enable DCMI interface using the function
+ * DCMI_Cmd(ENABLE);
+ *
+ * 7. Start the image capture using the function
+ * DCMI_CaptureCmd(ENABLE);
+ *
+ * 8. At this stage the DCMI interface waits for the first start of frame,
+ * then a DMA request is generated continuously/once (depending on the
+ * mode used, Continuous/Snapshot) to transfer the received data into
+ * the destination memory.
+ *
+ * @note If you need to capture only a rectangular window from the received
+ * image, you have to use the DCMI_CROPConfig() function to configure
+ * the coordinates and size of the window to be captured, then enable
+ * the Crop feature using DCMI_CROPCmd(ENABLE);
+ * In this case, the Crop configuration should be made before to enable
+ * and start the DCMI interface.
+ *
+ * @endverbatim
+ *
+ ******************************************************************************
+ * @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 "stm32f2xx_dcmi.h"
+#include "stm32f2xx_rcc.h"
+
+/** @addtogroup STM32F2xx_StdPeriph_Driver
+ * @{
+ */
+
+/** @defgroup DCMI
+ * @brief DCMI driver modules
+ * @{
+ */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+/** @defgroup DCMI_Private_Functions
+ * @{
+ */
+
+/** @defgroup DCMI_Group1 Initialization and Configuration functions
+ * @brief Initialization and Configuration functions
+ *
+@verbatim
+ ===============================================================================
+ Initialization and Configuration functions
+ ===============================================================================
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Deinitializes the DCMI registers to their default reset values.
+ * @param None
+ * @retval None
+ */
+void DCMI_DeInit(void)
+{
+ DCMI->CR = 0x0;
+ DCMI->IER = 0x0;
+ DCMI->ICR = 0x1F;
+ DCMI->ESCR = 0x0;
+ DCMI->ESUR = 0x0;
+ DCMI->CWSTRTR = 0x0;
+ DCMI->CWSIZER = 0x0;
+}
+
+/**
+ * @brief Initializes the DCMI according to the specified parameters in the DCMI_InitStruct.
+ * @param DCMI_InitStruct: pointer to a DCMI_InitTypeDef structure that contains
+ * the configuration information for the DCMI.
+ * @retval None
+ */
+void DCMI_Init(DCMI_InitTypeDef* DCMI_InitStruct)
+{
+ uint32_t temp = 0x0;
+
+ /* Check the parameters */
+ assert_param(IS_DCMI_CAPTURE_MODE(DCMI_InitStruct->DCMI_CaptureMode));
+ assert_param(IS_DCMI_SYNCHRO(DCMI_InitStruct->DCMI_SynchroMode));
+ assert_param(IS_DCMI_PCKPOLARITY(DCMI_InitStruct->DCMI_PCKPolarity));
+ assert_param(IS_DCMI_VSPOLARITY(DCMI_InitStruct->DCMI_VSPolarity));
+ assert_param(IS_DCMI_HSPOLARITY(DCMI_InitStruct->DCMI_HSPolarity));
+ assert_param(IS_DCMI_CAPTURE_RATE(DCMI_InitStruct->DCMI_CaptureRate));
+ assert_param(IS_DCMI_EXTENDED_DATA(DCMI_InitStruct->DCMI_ExtendedDataMode));
+
+ /* The DCMI configuration registers should be programmed correctly before
+ enabling the CR_ENABLE Bit and the CR_CAPTURE Bit */
+ DCMI->CR &= ~(DCMI_CR_ENABLE | DCMI_CR_CAPTURE);
+
+ /* Reset the old DCMI configuration */
+ temp = DCMI->CR;
+
+ temp &= ~((uint32_t)DCMI_CR_CM | DCMI_CR_ESS | DCMI_CR_PCKPOL |
+ DCMI_CR_HSPOL | DCMI_CR_VSPOL | DCMI_CR_FCRC_0 |
+ DCMI_CR_FCRC_1 | DCMI_CR_EDM_0 | DCMI_CR_EDM_1);
+
+ /* Sets the new configuration of the DCMI peripheral */
+ temp |= ((uint32_t)DCMI_InitStruct->DCMI_CaptureMode |
+ DCMI_InitStruct->DCMI_SynchroMode |
+ DCMI_InitStruct->DCMI_PCKPolarity |
+ DCMI_InitStruct->DCMI_VSPolarity |
+ DCMI_InitStruct->DCMI_HSPolarity |
+ DCMI_InitStruct->DCMI_CaptureRate |
+ DCMI_InitStruct->DCMI_ExtendedDataMode);
+
+ DCMI->CR = temp;
+}
+
+/**
+ * @brief Fills each DCMI_InitStruct member with its default value.
+ * @param DCMI_InitStruct : pointer to a DCMI_InitTypeDef structure which will
+ * be initialized.
+ * @retval None
+ */
+void DCMI_StructInit(DCMI_InitTypeDef* DCMI_InitStruct)
+{
+ /* Set the default configuration */
+ DCMI_InitStruct->DCMI_CaptureMode = DCMI_CaptureMode_Continuous;
+ DCMI_InitStruct->DCMI_SynchroMode = DCMI_SynchroMode_Hardware;
+ DCMI_InitStruct->DCMI_PCKPolarity = DCMI_PCKPolarity_Falling;
+ DCMI_InitStruct->DCMI_VSPolarity = DCMI_VSPolarity_Low;
+ DCMI_InitStruct->DCMI_HSPolarity = DCMI_HSPolarity_Low;
+ DCMI_InitStruct->DCMI_CaptureRate = DCMI_CaptureRate_All_Frame;
+ DCMI_InitStruct->DCMI_ExtendedDataMode = DCMI_ExtendedDataMode_8b;
+}
+
+/**
+ * @brief Initializes the DCMI peripheral CROP mode according to the specified
+ * parameters in the DCMI_CROPInitStruct.
+ * @note This function should be called before to enable and start the DCMI interface.
+ * @param DCMI_CROPInitStruct: pointer to a DCMI_CROPInitTypeDef structure that
+ * contains the configuration information for the DCMI peripheral CROP mode.
+ * @retval None
+ */
+void DCMI_CROPConfig(DCMI_CROPInitTypeDef* DCMI_CROPInitStruct)
+{
+ /* Sets the CROP window coordinates */
+ DCMI->CWSTRTR = (uint32_t)((uint32_t)DCMI_CROPInitStruct->DCMI_HorizontalOffsetCount |
+ ((uint32_t)DCMI_CROPInitStruct->DCMI_VerticalStartLine << 16));
+
+ /* Sets the CROP window size */
+ DCMI->CWSIZER = (uint32_t)(DCMI_CROPInitStruct->DCMI_CaptureCount |
+ ((uint32_t)DCMI_CROPInitStruct->DCMI_VerticalLineCount << 16));
+}
+
+/**
+ * @brief Enables or disables the DCMI Crop feature.
+ * @note This function should be called before to enable and start the DCMI interface.
+ * @param NewState: new state of the DCMI Crop feature.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void DCMI_CROPCmd(FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the DCMI Crop feature */
+ DCMI->CR |= (uint32_t)DCMI_CR_CROP;
+ }
+ else
+ {
+ /* Disable the DCMI Crop feature */
+ DCMI->CR &= ~(uint32_t)DCMI_CR_CROP;
+ }
+}
+
+/**
+ * @brief Sets the embedded synchronization codes
+ * @param DCMI_CodesInitTypeDef: pointer to a DCMI_CodesInitTypeDef structure that
+ * contains the embedded synchronization codes for the DCMI peripheral.
+ * @retval None
+ */
+void DCMI_SetEmbeddedSynchroCodes(DCMI_CodesInitTypeDef* DCMI_CodesInitStruct)
+{
+ DCMI->ESCR = (uint32_t)(DCMI_CodesInitStruct->DCMI_FrameStartCode |
+ ((uint32_t)DCMI_CodesInitStruct->DCMI_LineStartCode << 8)|
+ ((uint32_t)DCMI_CodesInitStruct->DCMI_LineEndCode << 16)|
+ ((uint32_t)DCMI_CodesInitStruct->DCMI_FrameEndCode << 24));
+}
+
+/**
+ * @brief Enables or disables the DCMI JPEG format.
+ * @note The Crop and Embedded Synchronization features cannot be used in this mode.
+ * @param NewState: new state of the DCMI JPEG format.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void DCMI_JPEGCmd(FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the DCMI JPEG format */
+ DCMI->CR |= (uint32_t)DCMI_CR_JPEG;
+ }
+ else
+ {
+ /* Disable the DCMI JPEG format */
+ DCMI->CR &= ~(uint32_t)DCMI_CR_JPEG;
+ }
+}
+/**
+ * @}
+ */
+
+/** @defgroup DCMI_Group2 Image capture functions
+ * @brief Image capture functions
+ *
+@verbatim
+ ===============================================================================
+ Image capture functions
+ ===============================================================================
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Enables or disables the DCMI interface.
+ * @param NewState: new state of the DCMI interface.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void DCMI_Cmd(FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the DCMI by setting ENABLE bit */
+ DCMI->CR |= (uint32_t)DCMI_CR_ENABLE;
+ }
+ else
+ {
+ /* Disable the DCMI by clearing ENABLE bit */
+ DCMI->CR &= ~(uint32_t)DCMI_CR_ENABLE;
+ }
+}
+
+/**
+ * @brief Enables or disables the DCMI Capture.
+ * @param NewState: new state of the DCMI capture.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void DCMI_CaptureCmd(FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the DCMI Capture */
+ DCMI->CR |= (uint32_t)DCMI_CR_CAPTURE;
+ }
+ else
+ {
+ /* Disable the DCMI Capture */
+ DCMI->CR &= ~(uint32_t)DCMI_CR_CAPTURE;
+ }
+}
+
+/**
+ * @brief Reads the data stored in the DR register.
+ * @param None
+ * @retval Data register value
+ */
+uint32_t DCMI_ReadData(void)
+{
+ return DCMI->DR;
+}
+/**
+ * @}
+ */
+
+/** @defgroup DCMI_Group3 Interrupts and flags management functions
+ * @brief Interrupts and flags management functions
+ *
+@verbatim
+ ===============================================================================
+ Interrupts and flags management functions
+ ===============================================================================
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Enables or disables the DCMI interface interrupts.
+ * @param DCMI_IT: specifies the DCMI interrupt sources to be enabled or disabled.
+ * This parameter can be any combination of the following values:
+ * @arg DCMI_IT_FRAME: Frame capture complete interrupt mask
+ * @arg DCMI_IT_OVF: Overflow interrupt mask
+ * @arg DCMI_IT_ERR: Synchronization error interrupt mask
+ * @arg DCMI_IT_VSYNC: VSYNC interrupt mask
+ * @arg DCMI_IT_LINE: Line interrupt mask
+ * @param NewState: new state of the specified DCMI interrupts.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void DCMI_ITConfig(uint16_t DCMI_IT, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_DCMI_CONFIG_IT(DCMI_IT));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the Interrupt sources */
+ DCMI->IER |= DCMI_IT;
+ }
+ else
+ {
+ /* Disable the Interrupt sources */
+ DCMI->IER &= (uint16_t)(~DCMI_IT);
+ }
+}
+
+/**
+ * @brief Checks whether the DCMI interface flag is set or not.
+ * @param DCMI_FLAG: specifies the flag to check.
+ * This parameter can be one of the following values:
+ * @arg DCMI_FLAG_FRAMERI: Frame capture complete Raw flag mask
+ * @arg DCMI_FLAG_OVFRI: Overflow Raw flag mask
+ * @arg DCMI_FLAG_ERRRI: Synchronization error Raw flag mask
+ * @arg DCMI_FLAG_VSYNCRI: VSYNC Raw flag mask
+ * @arg DCMI_FLAG_LINERI: Line Raw flag mask
+ * @arg DCMI_FLAG_FRAMEMI: Frame capture complete Masked flag mask
+ * @arg DCMI_FLAG_OVFMI: Overflow Masked flag mask
+ * @arg DCMI_FLAG_ERRMI: Synchronization error Masked flag mask
+ * @arg DCMI_FLAG_VSYNCMI: VSYNC Masked flag mask
+ * @arg DCMI_FLAG_LINEMI: Line Masked flag mask
+ * @arg DCMI_FLAG_HSYNC: HSYNC flag mask
+ * @arg DCMI_FLAG_VSYNC: VSYNC flag mask
+ * @arg DCMI_FLAG_FNE: Fifo not empty flag mask
+ * @retval The new state of DCMI_FLAG (SET or RESET).
+ */
+FlagStatus DCMI_GetFlagStatus(uint16_t DCMI_FLAG)
+{
+ FlagStatus bitstatus = RESET;
+ uint32_t dcmireg, tempreg = 0;
+
+ /* Check the parameters */
+ assert_param(IS_DCMI_GET_FLAG(DCMI_FLAG));
+
+ /* Get the DCMI register index */
+ dcmireg = (((uint16_t)DCMI_FLAG) >> 12);
+
+ if (dcmireg == 0x00) /* The FLAG is in RISR register */
+ {
+ tempreg= DCMI->RISR;
+ }
+ else if (dcmireg == 0x02) /* The FLAG is in SR register */
+ {
+ tempreg = DCMI->SR;
+ }
+ else /* The FLAG is in MISR register */
+ {
+ tempreg = DCMI->MISR;
+ }
+
+ if ((tempreg & DCMI_FLAG) != (uint16_t)RESET )
+ {
+ bitstatus = SET;
+ }
+ else
+ {
+ bitstatus = RESET;
+ }
+ /* Return the DCMI_FLAG status */
+ return bitstatus;
+}
+
+/**
+ * @brief Clears the DCMI's pending flags.
+ * @param DCMI_FLAG: specifies the flag to clear.
+ * This parameter can be any combination of the following values:
+ * @arg DCMI_FLAG_FRAMERI: Frame capture complete Raw flag mask
+ * @arg DCMI_FLAG_OVFRI: Overflow Raw flag mask
+ * @arg DCMI_FLAG_ERRRI: Synchronization error Raw flag mask
+ * @arg DCMI_FLAG_VSYNCRI: VSYNC Raw flag mask
+ * @arg DCMI_FLAG_LINERI: Line Raw flag mask
+ * @retval None
+ */
+void DCMI_ClearFlag(uint16_t DCMI_FLAG)
+{
+ /* Check the parameters */
+ assert_param(IS_DCMI_CLEAR_FLAG(DCMI_FLAG));
+
+ /* Clear the flag by writing in the ICR register 1 in the corresponding
+ Flag position*/
+
+ DCMI->ICR = DCMI_FLAG;
+}
+
+/**
+ * @brief Checks whether the DCMI interrupt has occurred or not.
+ * @param DCMI_IT: specifies the DCMI interrupt source to check.
+ * This parameter can be one of the following values:
+ * @arg DCMI_IT_FRAME: Frame capture complete interrupt mask
+ * @arg DCMI_IT_OVF: Overflow interrupt mask
+ * @arg DCMI_IT_ERR: Synchronization error interrupt mask
+ * @arg DCMI_IT_VSYNC: VSYNC interrupt mask
+ * @arg DCMI_IT_LINE: Line interrupt mask
+ * @retval The new state of DCMI_IT (SET or RESET).
+ */
+ITStatus DCMI_GetITStatus(uint16_t DCMI_IT)
+{
+ ITStatus bitstatus = RESET;
+ uint32_t itstatus = 0;
+
+ /* Check the parameters */
+ assert_param(IS_DCMI_GET_IT(DCMI_IT));
+
+ itstatus = DCMI->MISR & DCMI_IT; /* Only masked interrupts are checked */
+
+ if ((itstatus != (uint16_t)RESET))
+ {
+ bitstatus = SET;
+ }
+ else
+ {
+ bitstatus = RESET;
+ }
+ return bitstatus;
+}
+
+/**
+ * @brief Clears the DCMI's interrupt pending bits.
+ * @param DCMI_IT: specifies the DCMI interrupt pending bit to clear.
+ * This parameter can be any combination of the following values:
+ * @arg DCMI_IT_FRAME: Frame capture complete interrupt mask
+ * @arg DCMI_IT_OVF: Overflow interrupt mask
+ * @arg DCMI_IT_ERR: Synchronization error interrupt mask
+ * @arg DCMI_IT_VSYNC: VSYNC interrupt mask
+ * @arg DCMI_IT_LINE: Line interrupt mask
+ * @retval None
+ */
+void DCMI_ClearITPendingBit(uint16_t DCMI_IT)
+{
+ /* Clear the interrupt pending Bit by writing in the ICR register 1 in the
+ corresponding pending Bit position*/
+
+ DCMI->ICR = DCMI_IT;
+}
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/src/stm32f2xx_dma.c b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/src/stm32f2xx_dma.c
new file mode 100644
index 0000000..92f9e85
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/src/stm32f2xx_dma.c
@@ -0,0 +1,1289 @@
+/**
+ ******************************************************************************
+ * @file stm32f2xx_dma.c
+ * @author MCD Application Team
+ * @version V1.1.2
+ * @date 05-March-2012
+ * @brief This file provides firmware functions to manage the following
+ * functionalities of the Direct Memory Access controller (DMA):
+ * - Initialization and Configuration
+ * - Data Counter
+ * - Double Buffer mode configuration and command
+ * - Interrupts and flags management
+ *
+ * @verbatim
+ *
+ * ===================================================================
+ * How to use this driver
+ * ===================================================================
+ * 1. Enable The DMA controller clock using RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_DMA1, ENABLE)
+ * function for DMA1 or using RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_DMA2, ENABLE)
+ * function for DMA2.
+ *
+ * 2. Enable and configure the peripheral to be connected to the DMA Stream
+ * (except for internal SRAM / FLASH memories: no initialization is
+ * necessary).
+ *
+ * 3. For a given Stream, program the required configuration through following parameters:
+ * Source and Destination addresses, Transfer Direction, Transfer size, Source and Destination
+ * data formats, Circular or Normal mode, Stream Priority level, Source and Destination
+ * Incrementation mode, FIFO mode and its Threshold (if needed), Burst mode for Source and/or
+ * Destination (if needed) using the DMA_Init() function.
+ * To avoid filling un-nesecessary fields, you can call DMA_StructInit() function
+ * to initialize a given structure with default values (reset values), the modify
+ * only necessary fields (ie. Source and Destination addresses, Transfer size and Data Formats).
+ *
+ * 4. Enable the NVIC and the corresponding interrupt(s) using the function
+ * DMA_ITConfig() if you need to use DMA interrupts.
+ *
+ * 5. Optionally, if the Circular mode is enabled, you can use the Double buffer mode by configuring
+ * the second Memory address and the first Memory to be used through the function
+ * DMA_DoubleBufferModeConfig(). Then enable the Double buffer mode through the function
+ * DMA_DoubleBufferModeCmd(). These operations must be done before step 6.
+ *
+ * 6. Enable the DMA stream using the DMA_Cmd() function.
+ *
+ * 7. Activate the needed Stream Request using PPP_DMACmd() function for
+ * any PPP peripheral except internal SRAM and FLASH (ie. SPI, USART ...)
+ * The function allowing this operation is provided in each PPP peripheral
+ * driver (ie. SPI_DMACmd for SPI peripheral).
+ * Once the Stream is enabled, it is not possible to modify its configuration
+ * unless the stream is stopped and disabled.
+ * After enabling the Stream, it is advised to monitor the EN bit status using
+ * the function DMA_GetCmdStatus(). In case of configuration errors or bus errors
+ * this bit will remain reset and all transfers on this Stream will remain on hold.
+ *
+ * 8. Optionally, you can configure the number of data to be transferred
+ * when the Stream is disabled (ie. after each Transfer Complete event
+ * or when a Transfer Error occurs) using the function DMA_SetCurrDataCounter().
+ * And you can get the number of remaining data to be transferred using
+ * the function DMA_GetCurrDataCounter() at run time (when the DMA Stream is
+ * enabled and running).
+ *
+ * 9. To control DMA events you can use one of the following
+ * two methods:
+ * a- Check on DMA Stream flags using the function DMA_GetFlagStatus().
+ * b- Use DMA interrupts through the function DMA_ITConfig() at initialization
+ * phase and DMA_GetITStatus() function into interrupt routines in
+ * communication phase.
+ * After checking on a flag you should clear it using DMA_ClearFlag()
+ * function. And after checking on an interrupt event you should
+ * clear it using DMA_ClearITPendingBit() function.
+ *
+ * 10. Optionally, if Circular mode and Double Buffer mode are enabled, you can modify
+ * the Memory Addresses using the function DMA_MemoryTargetConfig(). Make sure that
+ * the Memory Address to be modified is not the one currently in use by DMA Stream.
+ * This condition can be monitored using the function DMA_GetCurrentMemoryTarget().
+ *
+ * 11. Optionally, Pause-Resume operations may be performed:
+ * The DMA_Cmd() function may be used to perform Pause-Resume operation. When a
+ * transfer is ongoing, calling this function to disable the Stream will cause the
+ * transfer to be paused. All configuration registers and the number of remaining
+ * data will be preserved. When calling again this function to re-enable the Stream,
+ * the transfer will be resumed from the point where it was paused.
+ *
+ * @note Memory-to-Memory transfer is possible by setting the address of the memory into
+ * the Peripheral registers. In this mode, Circular mode and Double Buffer mode
+ * are not allowed.
+ *
+ * @note The FIFO is used mainly to reduce bus usage and to allow data packing/unpacking: it is
+ * possible to set different Data Sizes for the Peripheral and the Memory (ie. you can set
+ * Half-Word data size for the peripheral to access its data register and set Word data size
+ * for the Memory to gain in access time. Each two Half-words will be packed and written in
+ * a single access to a Word in the Memory).
+ *
+ * @note When FIFO is disabled, it is not allowed to configure different Data Sizes for Source
+ * and Destination. In this case the Peripheral Data Size will be applied to both Source
+ * and Destination.
+ *
+ * @endverbatim
+ *
+ ******************************************************************************
+ * @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 "stm32f2xx_dma.h"
+#include "stm32f2xx_rcc.h"
+
+/** @addtogroup STM32F2xx_StdPeriph_Driver
+ * @{
+ */
+
+/** @defgroup DMA
+ * @brief DMA driver modules
+ * @{
+ */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+
+/* Masks Definition */
+#define TRANSFER_IT_ENABLE_MASK (uint32_t)(DMA_SxCR_TCIE | DMA_SxCR_HTIE | \
+ DMA_SxCR_TEIE | DMA_SxCR_DMEIE)
+
+#define DMA_Stream0_IT_MASK (uint32_t)(DMA_LISR_FEIF0 | DMA_LISR_DMEIF0 | \
+ DMA_LISR_TEIF0 | DMA_LISR_HTIF0 | \
+ DMA_LISR_TCIF0)
+
+#define DMA_Stream1_IT_MASK (uint32_t)(DMA_Stream0_IT_MASK << 6)
+#define DMA_Stream2_IT_MASK (uint32_t)(DMA_Stream0_IT_MASK << 16)
+#define DMA_Stream3_IT_MASK (uint32_t)(DMA_Stream0_IT_MASK << 22)
+#define DMA_Stream4_IT_MASK (uint32_t)(DMA_Stream0_IT_MASK | (uint32_t)0x20000000)
+#define DMA_Stream5_IT_MASK (uint32_t)(DMA_Stream1_IT_MASK | (uint32_t)0x20000000)
+#define DMA_Stream6_IT_MASK (uint32_t)(DMA_Stream2_IT_MASK | (uint32_t)0x20000000)
+#define DMA_Stream7_IT_MASK (uint32_t)(DMA_Stream3_IT_MASK | (uint32_t)0x20000000)
+#define TRANSFER_IT_MASK (uint32_t)0x0F3C0F3C
+#define HIGH_ISR_MASK (uint32_t)0x20000000
+#define RESERVED_MASK (uint32_t)0x0F7D0F7D
+
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+
+/** @defgroup DMA_Private_Functions
+ * @{
+ */
+
+/** @defgroup DMA_Group1 Initialization and Configuration functions
+ * @brief Initialization and Configuration functions
+ *
+@verbatim
+ ===============================================================================
+ Initialization and Configuration functions
+ ===============================================================================
+
+ This subsection provides functions allowing to initialize the DMA Stream source
+ and destination addresses, incrementation and data sizes, transfer direction,
+ buffer size, circular/normal mode selection, memory-to-memory mode selection
+ and Stream priority value.
+
+ The DMA_Init() function follows the DMA configuration procedures as described in
+ reference manual (RM0033) except the first point: waiting on EN bit to be reset.
+ This condition should be checked by user application using the function DMA_GetCmdStatus()
+ before calling the DMA_Init() function.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Deinitialize the DMAy Streamx registers to their default reset values.
+ * @param DMAy_Streamx: where y can be 1 or 2 to select the DMA and x can be 0
+ * to 7 to select the DMA Stream.
+ * @retval None
+ */
+void DMA_DeInit(DMA_Stream_TypeDef* DMAy_Streamx)
+{
+ /* Check the parameters */
+ assert_param(IS_DMA_ALL_PERIPH(DMAy_Streamx));
+
+ /* Disable the selected DMAy Streamx */
+ DMAy_Streamx->CR &= ~((uint32_t)DMA_SxCR_EN);
+
+ /* Reset DMAy Streamx control register */
+ DMAy_Streamx->CR = 0;
+
+ /* Reset DMAy Streamx Number of Data to Transfer register */
+ DMAy_Streamx->NDTR = 0;
+
+ /* Reset DMAy Streamx peripheral address register */
+ DMAy_Streamx->PAR = 0;
+
+ /* Reset DMAy Streamx memory 0 address register */
+ DMAy_Streamx->M0AR = 0;
+
+ /* Reset DMAy Streamx memory 1 address register */
+ DMAy_Streamx->M1AR = 0;
+
+ /* Reset DMAy Streamx FIFO control register */
+ DMAy_Streamx->FCR = (uint32_t)0x00000021;
+
+ /* Reset interrupt pending bits for the selected stream */
+ if (DMAy_Streamx == DMA1_Stream0)
+ {
+ /* Reset interrupt pending bits for DMA1 Stream0 */
+ DMA1->LIFCR = DMA_Stream0_IT_MASK;
+ }
+ else if (DMAy_Streamx == DMA1_Stream1)
+ {
+ /* Reset interrupt pending bits for DMA1 Stream1 */
+ DMA1->LIFCR = DMA_Stream1_IT_MASK;
+ }
+ else if (DMAy_Streamx == DMA1_Stream2)
+ {
+ /* Reset interrupt pending bits for DMA1 Stream2 */
+ DMA1->LIFCR = DMA_Stream2_IT_MASK;
+ }
+ else if (DMAy_Streamx == DMA1_Stream3)
+ {
+ /* Reset interrupt pending bits for DMA1 Stream3 */
+ DMA1->LIFCR = DMA_Stream3_IT_MASK;
+ }
+ else if (DMAy_Streamx == DMA1_Stream4)
+ {
+ /* Reset interrupt pending bits for DMA1 Stream4 */
+ DMA1->HIFCR = DMA_Stream4_IT_MASK;
+ }
+ else if (DMAy_Streamx == DMA1_Stream5)
+ {
+ /* Reset interrupt pending bits for DMA1 Stream5 */
+ DMA1->HIFCR = DMA_Stream5_IT_MASK;
+ }
+ else if (DMAy_Streamx == DMA1_Stream6)
+ {
+ /* Reset interrupt pending bits for DMA1 Stream6 */
+ DMA1->HIFCR = (uint32_t)DMA_Stream6_IT_MASK;
+ }
+ else if (DMAy_Streamx == DMA1_Stream7)
+ {
+ /* Reset interrupt pending bits for DMA1 Stream7 */
+ DMA1->HIFCR = DMA_Stream7_IT_MASK;
+ }
+ else if (DMAy_Streamx == DMA2_Stream0)
+ {
+ /* Reset interrupt pending bits for DMA2 Stream0 */
+ DMA2->LIFCR = DMA_Stream0_IT_MASK;
+ }
+ else if (DMAy_Streamx == DMA2_Stream1)
+ {
+ /* Reset interrupt pending bits for DMA2 Stream1 */
+ DMA2->LIFCR = DMA_Stream1_IT_MASK;
+ }
+ else if (DMAy_Streamx == DMA2_Stream2)
+ {
+ /* Reset interrupt pending bits for DMA2 Stream2 */
+ DMA2->LIFCR = DMA_Stream2_IT_MASK;
+ }
+ else if (DMAy_Streamx == DMA2_Stream3)
+ {
+ /* Reset interrupt pending bits for DMA2 Stream3 */
+ DMA2->LIFCR = DMA_Stream3_IT_MASK;
+ }
+ else if (DMAy_Streamx == DMA2_Stream4)
+ {
+ /* Reset interrupt pending bits for DMA2 Stream4 */
+ DMA2->HIFCR = DMA_Stream4_IT_MASK;
+ }
+ else if (DMAy_Streamx == DMA2_Stream5)
+ {
+ /* Reset interrupt pending bits for DMA2 Stream5 */
+ DMA2->HIFCR = DMA_Stream5_IT_MASK;
+ }
+ else if (DMAy_Streamx == DMA2_Stream6)
+ {
+ /* Reset interrupt pending bits for DMA2 Stream6 */
+ DMA2->HIFCR = DMA_Stream6_IT_MASK;
+ }
+ else
+ {
+ if (DMAy_Streamx == DMA2_Stream7)
+ {
+ /* Reset interrupt pending bits for DMA2 Stream7 */
+ DMA2->HIFCR = DMA_Stream7_IT_MASK;
+ }
+ }
+}
+
+/**
+ * @brief Initializes the DMAy Streamx according to the specified parameters in
+ * the DMA_InitStruct structure.
+ * @note Before calling this function, it is recommended to check that the Stream
+ * is actually disabled using the function DMA_GetCmdStatus().
+ * @param DMAy_Streamx: where y can be 1 or 2 to select the DMA and x can be 0
+ * to 7 to select the DMA Stream.
+ * @param DMA_InitStruct: pointer to a DMA_InitTypeDef structure that contains
+ * the configuration information for the specified DMA Stream.
+ * @retval None
+ */
+void DMA_Init(DMA_Stream_TypeDef* DMAy_Streamx, DMA_InitTypeDef* DMA_InitStruct)
+{
+ uint32_t tmpreg = 0;
+
+ /* Check the parameters */
+ assert_param(IS_DMA_ALL_PERIPH(DMAy_Streamx));
+ assert_param(IS_DMA_CHANNEL(DMA_InitStruct->DMA_Channel));
+ assert_param(IS_DMA_DIRECTION(DMA_InitStruct->DMA_DIR));
+ assert_param(IS_DMA_BUFFER_SIZE(DMA_InitStruct->DMA_BufferSize));
+ assert_param(IS_DMA_PERIPHERAL_INC_STATE(DMA_InitStruct->DMA_PeripheralInc));
+ assert_param(IS_DMA_MEMORY_INC_STATE(DMA_InitStruct->DMA_MemoryInc));
+ assert_param(IS_DMA_PERIPHERAL_DATA_SIZE(DMA_InitStruct->DMA_PeripheralDataSize));
+ assert_param(IS_DMA_MEMORY_DATA_SIZE(DMA_InitStruct->DMA_MemoryDataSize));
+ assert_param(IS_DMA_MODE(DMA_InitStruct->DMA_Mode));
+ assert_param(IS_DMA_PRIORITY(DMA_InitStruct->DMA_Priority));
+ assert_param(IS_DMA_FIFO_MODE_STATE(DMA_InitStruct->DMA_FIFOMode));
+ assert_param(IS_DMA_FIFO_THRESHOLD(DMA_InitStruct->DMA_FIFOThreshold));
+ assert_param(IS_DMA_MEMORY_BURST(DMA_InitStruct->DMA_MemoryBurst));
+ assert_param(IS_DMA_PERIPHERAL_BURST(DMA_InitStruct->DMA_PeripheralBurst));
+
+ /*------------------------- DMAy Streamx CR Configuration ------------------*/
+ /* Get the DMAy_Streamx CR value */
+ tmpreg = DMAy_Streamx->CR;
+
+ /* Clear CHSEL, MBURST, PBURST, PL, MSIZE, PSIZE, MINC, PINC, CIRC and DIR bits */
+ tmpreg &= ((uint32_t)~(DMA_SxCR_CHSEL | DMA_SxCR_MBURST | DMA_SxCR_PBURST | \
+ DMA_SxCR_PL | DMA_SxCR_MSIZE | DMA_SxCR_PSIZE | \
+ DMA_SxCR_MINC | DMA_SxCR_PINC | DMA_SxCR_CIRC | \
+ DMA_SxCR_DIR));
+
+ /* Configure DMAy Streamx: */
+ /* Set CHSEL bits according to DMA_CHSEL value */
+ /* Set DIR bits according to DMA_DIR value */
+ /* Set PINC bit according to DMA_PeripheralInc value */
+ /* Set MINC bit according to DMA_MemoryInc value */
+ /* Set PSIZE bits according to DMA_PeripheralDataSize value */
+ /* Set MSIZE bits according to DMA_MemoryDataSize value */
+ /* Set CIRC bit according to DMA_Mode value */
+ /* Set PL bits according to DMA_Priority value */
+ /* Set MBURST bits according to DMA_MemoryBurst value */
+ /* Set PBURST bits according to DMA_PeripheralBurst value */
+ tmpreg |= DMA_InitStruct->DMA_Channel | DMA_InitStruct->DMA_DIR |
+ DMA_InitStruct->DMA_PeripheralInc | DMA_InitStruct->DMA_MemoryInc |
+ DMA_InitStruct->DMA_PeripheralDataSize | DMA_InitStruct->DMA_MemoryDataSize |
+ DMA_InitStruct->DMA_Mode | DMA_InitStruct->DMA_Priority |
+ DMA_InitStruct->DMA_MemoryBurst | DMA_InitStruct->DMA_PeripheralBurst;
+
+ /* Write to DMAy Streamx CR register */
+ DMAy_Streamx->CR = tmpreg;
+
+ /*------------------------- DMAy Streamx FCR Configuration -----------------*/
+ /* Get the DMAy_Streamx FCR value */
+ tmpreg = DMAy_Streamx->FCR;
+
+ /* Clear DMDIS and FTH bits */
+ tmpreg &= (uint32_t)~(DMA_SxFCR_DMDIS | DMA_SxFCR_FTH);
+
+ /* Configure DMAy Streamx FIFO:
+ Set DMDIS bits according to DMA_FIFOMode value
+ Set FTH bits according to DMA_FIFOThreshold value */
+ tmpreg |= DMA_InitStruct->DMA_FIFOMode | DMA_InitStruct->DMA_FIFOThreshold;
+
+ /* Write to DMAy Streamx CR */
+ DMAy_Streamx->FCR = tmpreg;
+
+ /*------------------------- DMAy Streamx NDTR Configuration ----------------*/
+ /* Write to DMAy Streamx NDTR register */
+ DMAy_Streamx->NDTR = DMA_InitStruct->DMA_BufferSize;
+
+ /*------------------------- DMAy Streamx PAR Configuration -----------------*/
+ /* Write to DMAy Streamx PAR */
+ DMAy_Streamx->PAR = DMA_InitStruct->DMA_PeripheralBaseAddr;
+
+ /*------------------------- DMAy Streamx M0AR Configuration ----------------*/
+ /* Write to DMAy Streamx M0AR */
+ DMAy_Streamx->M0AR = DMA_InitStruct->DMA_Memory0BaseAddr;
+}
+
+/**
+ * @brief Fills each DMA_InitStruct member with its default value.
+ * @param DMA_InitStruct : pointer to a DMA_InitTypeDef structure which will
+ * be initialized.
+ * @retval None
+ */
+void DMA_StructInit(DMA_InitTypeDef* DMA_InitStruct)
+{
+ /*-------------- Reset DMA init structure parameters values ----------------*/
+ /* Initialize the DMA_Channel member */
+ DMA_InitStruct->DMA_Channel = 0;
+
+ /* Initialize the DMA_PeripheralBaseAddr member */
+ DMA_InitStruct->DMA_PeripheralBaseAddr = 0;
+
+ /* Initialize the DMA_Memory0BaseAddr member */
+ DMA_InitStruct->DMA_Memory0BaseAddr = 0;
+
+ /* Initialize the DMA_DIR member */
+ DMA_InitStruct->DMA_DIR = DMA_DIR_PeripheralToMemory;
+
+ /* Initialize the DMA_BufferSize member */
+ DMA_InitStruct->DMA_BufferSize = 0;
+
+ /* Initialize the DMA_PeripheralInc member */
+ DMA_InitStruct->DMA_PeripheralInc = DMA_PeripheralInc_Disable;
+
+ /* Initialize the DMA_MemoryInc member */
+ DMA_InitStruct->DMA_MemoryInc = DMA_MemoryInc_Disable;
+
+ /* Initialize the DMA_PeripheralDataSize member */
+ DMA_InitStruct->DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
+
+ /* Initialize the DMA_MemoryDataSize member */
+ DMA_InitStruct->DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
+
+ /* Initialize the DMA_Mode member */
+ DMA_InitStruct->DMA_Mode = DMA_Mode_Normal;
+
+ /* Initialize the DMA_Priority member */
+ DMA_InitStruct->DMA_Priority = DMA_Priority_Low;
+
+ /* Initialize the DMA_FIFOMode member */
+ DMA_InitStruct->DMA_FIFOMode = DMA_FIFOMode_Disable;
+
+ /* Initialize the DMA_FIFOThreshold member */
+ DMA_InitStruct->DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull;
+
+ /* Initialize the DMA_MemoryBurst member */
+ DMA_InitStruct->DMA_MemoryBurst = DMA_MemoryBurst_Single;
+
+ /* Initialize the DMA_PeripheralBurst member */
+ DMA_InitStruct->DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
+}
+
+/**
+ * @brief Enables or disables the specified DMAy Streamx.
+ * @param DMAy_Streamx: where y can be 1 or 2 to select the DMA and x can be 0
+ * to 7 to select the DMA Stream.
+ * @param NewState: new state of the DMAy Streamx.
+ * This parameter can be: ENABLE or DISABLE.
+ *
+ * @note This function may be used to perform Pause-Resume operation. When a
+ * transfer is ongoing, calling this function to disable the Stream will
+ * cause the transfer to be paused. All configuration registers and the
+ * number of remaining data will be preserved. When calling again this
+ * function to re-enable the Stream, the transfer will be resumed from
+ * the point where it was paused.
+ *
+ * @note After configuring the DMA Stream (DMA_Init() function) and enabling the
+ * stream, it is recommended to check (or wait until) the DMA Stream is
+ * effectively enabled. A Stream may remain disabled if a configuration
+ * parameter is wrong.
+ * After disabling a DMA Stream, it is also recommended to check (or wait
+ * until) the DMA Stream is effectively disabled. If a Stream is disabled
+ * while a data transfer is ongoing, the current data will be transferred
+ * and the Stream will be effectively disabled only after the transfer of
+ * this single data is finished.
+ *
+ * @retval None
+ */
+void DMA_Cmd(DMA_Stream_TypeDef* DMAy_Streamx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_DMA_ALL_PERIPH(DMAy_Streamx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the selected DMAy Streamx by setting EN bit */
+ DMAy_Streamx->CR |= (uint32_t)DMA_SxCR_EN;
+ }
+ else
+ {
+ /* Disable the selected DMAy Streamx by clearing EN bit */
+ DMAy_Streamx->CR &= ~(uint32_t)DMA_SxCR_EN;
+ }
+}
+
+/**
+ * @brief Configures, when the PINC (Peripheral Increment address mode) bit is
+ * set, if the peripheral address should be incremented with the data
+ * size (configured with PSIZE bits) or by a fixed offset equal to 4
+ * (32-bit aligned addresses).
+ *
+ * @note This function has no effect if the Peripheral Increment mode is disabled.
+ *
+ * @param DMAy_Streamx: where y can be 1 or 2 to select the DMA and x can be 0
+ * to 7 to select the DMA Stream.
+ * @param DMA_Pincos: specifies the Peripheral increment offset size.
+ * This parameter can be one of the following values:
+ * @arg DMA_PINCOS_Psize: Peripheral address increment is done
+ * accordingly to PSIZE parameter.
+ * @arg DMA_PINCOS_WordAligned: Peripheral address increment offset is
+ * fixed to 4 (32-bit aligned addresses).
+ * @retval None
+ */
+void DMA_PeriphIncOffsetSizeConfig(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t DMA_Pincos)
+{
+ /* Check the parameters */
+ assert_param(IS_DMA_ALL_PERIPH(DMAy_Streamx));
+ assert_param(IS_DMA_PINCOS_SIZE(DMA_Pincos));
+
+ /* Check the needed Peripheral increment offset */
+ if(DMA_Pincos != DMA_PINCOS_Psize)
+ {
+ /* Configure DMA_SxCR_PINCOS bit with the input parameter */
+ DMAy_Streamx->CR |= (uint32_t)DMA_SxCR_PINCOS;
+ }
+ else
+ {
+ /* Clear the PINCOS bit: Peripheral address incremented according to PSIZE */
+ DMAy_Streamx->CR &= ~(uint32_t)DMA_SxCR_PINCOS;
+ }
+}
+
+/**
+ * @brief Configures, when the DMAy Streamx is disabled, the flow controller for
+ * the next transactions (Peripheral or Memory).
+ *
+ * @note Before enabling this feature, check if the used peripheral supports
+ * the Flow Controller mode or not.
+ *
+ * @param DMAy_Streamx: where y can be 1 or 2 to select the DMA and x can be 0
+ * to 7 to select the DMA Stream.
+ * @param DMA_FlowCtrl: specifies the DMA flow controller.
+ * This parameter can be one of the following values:
+ * @arg DMA_FlowCtrl_Memory: DMAy_Streamx transactions flow controller is
+ * the DMA controller.
+ * @arg DMA_FlowCtrl_Peripheral: DMAy_Streamx transactions flow controller
+ * is the peripheral.
+ * @retval None
+ */
+void DMA_FlowControllerConfig(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t DMA_FlowCtrl)
+{
+ /* Check the parameters */
+ assert_param(IS_DMA_ALL_PERIPH(DMAy_Streamx));
+ assert_param(IS_DMA_FLOW_CTRL(DMA_FlowCtrl));
+
+ /* Check the needed flow controller */
+ if(DMA_FlowCtrl != DMA_FlowCtrl_Memory)
+ {
+ /* Configure DMA_SxCR_PFCTRL bit with the input parameter */
+ DMAy_Streamx->CR |= (uint32_t)DMA_SxCR_PFCTRL;
+ }
+ else
+ {
+ /* Clear the PFCTRL bit: Memory is the flow controller */
+ DMAy_Streamx->CR &= ~(uint32_t)DMA_SxCR_PFCTRL;
+ }
+}
+/**
+ * @}
+ */
+
+/** @defgroup DMA_Group2 Data Counter functions
+ * @brief Data Counter functions
+ *
+@verbatim
+ ===============================================================================
+ Data Counter functions
+ ===============================================================================
+
+ This subsection provides function allowing to configure and read the buffer size
+ (number of data to be transferred).
+
+ The DMA data counter can be written only when the DMA Stream is disabled
+ (ie. after transfer complete event).
+
+ The following function can be used to write the Stream data counter value:
+ - void DMA_SetCurrDataCounter(DMA_Stream_TypeDef* DMAy_Streamx, uint16_t Counter);
+
+@note It is advised to use this function rather than DMA_Init() in situations where
+ only the Data buffer needs to be reloaded.
+
+@note If the Source and Destination Data Sizes are different, then the value written in
+ data counter, expressing the number of transfers, is relative to the number of
+ transfers from the Peripheral point of view.
+ ie. If Memory data size is Word, Peripheral data size is Half-Words, then the value
+ to be configured in the data counter is the number of Half-Words to be transferred
+ from/to the peripheral.
+
+ The DMA data counter can be read to indicate the number of remaining transfers for
+ the relative DMA Stream. This counter is decremented at the end of each data
+ transfer and when the transfer is complete:
+ - If Normal mode is selected: the counter is set to 0.
+ - If Circular mode is selected: the counter is reloaded with the initial value
+ (configured before enabling the DMA Stream)
+
+ The following function can be used to read the Stream data counter value:
+ - uint16_t DMA_GetCurrDataCounter(DMA_Stream_TypeDef* DMAy_Streamx);
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Writes the number of data units to be transferred on the DMAy Streamx.
+ * @param DMAy_Streamx: where y can be 1 or 2 to select the DMA and x can be 0
+ * to 7 to select the DMA Stream.
+ * @param Counter: Number of data units to be transferred (from 0 to 65535)
+ * Number of data items depends only on the Peripheral data format.
+ *
+ * @note If Peripheral data format is Bytes: number of data units is equal
+ * to total number of bytes to be transferred.
+ *
+ * @note If Peripheral data format is Half-Word: number of data units is
+ * equal to total number of bytes to be transferred / 2.
+ *
+ * @note If Peripheral data format is Word: number of data units is equal
+ * to total number of bytes to be transferred / 4.
+ *
+ * @note In Memory-to-Memory transfer mode, the memory buffer pointed by
+ * DMAy_SxPAR register is considered as Peripheral.
+ *
+ * @retval The number of remaining data units in the current DMAy Streamx transfer.
+ */
+void DMA_SetCurrDataCounter(DMA_Stream_TypeDef* DMAy_Streamx, uint16_t Counter)
+{
+ /* Check the parameters */
+ assert_param(IS_DMA_ALL_PERIPH(DMAy_Streamx));
+
+ /* Write the number of data units to be transferred */
+ DMAy_Streamx->NDTR = (uint16_t)Counter;
+}
+
+/**
+ * @brief Returns the number of remaining data units in the current DMAy Streamx transfer.
+ * @param DMAy_Streamx: where y can be 1 or 2 to select the DMA and x can be 0
+ * to 7 to select the DMA Stream.
+ * @retval The number of remaining data units in the current DMAy Streamx transfer.
+ */
+uint16_t DMA_GetCurrDataCounter(DMA_Stream_TypeDef* DMAy_Streamx)
+{
+ /* Check the parameters */
+ assert_param(IS_DMA_ALL_PERIPH(DMAy_Streamx));
+
+ /* Return the number of remaining data units for DMAy Streamx */
+ return ((uint16_t)(DMAy_Streamx->NDTR));
+}
+/**
+ * @}
+ */
+
+/** @defgroup DMA_Group3 Double Buffer mode functions
+ * @brief Double Buffer mode functions
+ *
+@verbatim
+ ===============================================================================
+ Double Buffer mode functions
+ ===============================================================================
+
+ This subsection provides function allowing to configure and control the double
+ buffer mode parameters.
+
+ The Double Buffer mode can be used only when Circular mode is enabled.
+ The Double Buffer mode cannot be used when transferring data from Memory to Memory.
+
+ The Double Buffer mode allows to set two different Memory addresses from/to which
+ the DMA controller will access alternatively (after completing transfer to/from target
+ memory 0, it will start transfer to/from target memory 1).
+ This allows to reduce software overhead for double buffering and reduce the CPU
+ access time.
+
+ Two functions must be called before calling the DMA_Init() function:
+ - void DMA_DoubleBufferModeConfig(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t Memory1BaseAddr,
+ uint32_t DMA_CurrentMemory);
+ - void DMA_DoubleBufferModeCmd(DMA_Stream_TypeDef* DMAy_Streamx, FunctionalState NewState);
+
+ DMA_DoubleBufferModeConfig() is called to configure the Memory 1 base address and the first
+ Memory target from/to which the transfer will start after enabling the DMA Stream.
+ Then DMA_DoubleBufferModeCmd() must be called to enable the Double Buffer mode (or disable
+ it when it should not be used).
+
+
+ Two functions can be called dynamically when the transfer is ongoing (or when the DMA Stream is
+ stopped) to modify on of the target Memories addresses or to check wich Memory target is currently
+ used:
+ - void DMA_MemoryTargetConfig(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t MemoryBaseAddr,
+ uint32_t DMA_MemoryTarget);
+ - uint32_t DMA_GetCurrentMemoryTarget(DMA_Stream_TypeDef* DMAy_Streamx);
+
+ DMA_MemoryTargetConfig() can be called to modify the base address of one of the two target Memories.
+ The Memory of which the base address will be modified must not be currently be used by the DMA Stream
+ (ie. if the DMA Stream is currently transferring from Memory 1 then you can only modify base address
+ of target Memory 0 and vice versa).
+ To check this condition, it is recommended to use the function DMA_GetCurrentMemoryTarget() which
+ returns the index of the Memory target currently in use by the DMA Stream.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Configures, when the DMAy Streamx is disabled, the double buffer mode
+ * and the current memory target.
+ * @param DMAy_Streamx: where y can be 1 or 2 to select the DMA and x can be 0
+ * to 7 to select the DMA Stream.
+ * @param Memory1BaseAddr: the base address of the second buffer (Memory 1)
+ * @param DMA_CurrentMemory: specifies which memory will be first buffer for
+ * the transactions when the Stream will be enabled.
+ * This parameter can be one of the following values:
+ * @arg DMA_Memory_0: Memory 0 is the current buffer.
+ * @arg DMA_Memory_1: Memory 1 is the current buffer.
+ *
+ * @note Memory0BaseAddr is set by the DMA structure configuration in DMA_Init().
+ *
+ * @retval None
+ */
+void DMA_DoubleBufferModeConfig(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t Memory1BaseAddr,
+ uint32_t DMA_CurrentMemory)
+{
+ /* Check the parameters */
+ assert_param(IS_DMA_ALL_PERIPH(DMAy_Streamx));
+ assert_param(IS_DMA_CURRENT_MEM(DMA_CurrentMemory));
+
+ if (DMA_CurrentMemory != DMA_Memory_0)
+ {
+ /* Set Memory 1 as current memory address */
+ DMAy_Streamx->CR |= (uint32_t)(DMA_SxCR_CT);
+ }
+ else
+ {
+ /* Set Memory 0 as current memory address */
+ DMAy_Streamx->CR &= ~(uint32_t)(DMA_SxCR_CT);
+ }
+
+ /* Write to DMAy Streamx M1AR */
+ DMAy_Streamx->M1AR = Memory1BaseAddr;
+}
+
+/**
+ * @brief Enables or disables the double buffer mode for the selected DMA stream.
+ * @note This function can be called only when the DMA Stream is disabled.
+ * @param DMAy_Streamx: where y can be 1 or 2 to select the DMA and x can be 0
+ * to 7 to select the DMA Stream.
+ * @param NewState: new state of the DMAy Streamx double buffer mode.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void DMA_DoubleBufferModeCmd(DMA_Stream_TypeDef* DMAy_Streamx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_DMA_ALL_PERIPH(DMAy_Streamx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ /* Configure the Double Buffer mode */
+ if (NewState != DISABLE)
+ {
+ /* Enable the Double buffer mode */
+ DMAy_Streamx->CR |= (uint32_t)DMA_SxCR_DBM;
+ }
+ else
+ {
+ /* Disable the Double buffer mode */
+ DMAy_Streamx->CR &= ~(uint32_t)DMA_SxCR_DBM;
+ }
+}
+
+/**
+ * @brief Configures the Memory address for the next buffer transfer in double
+ * buffer mode (for dynamic use). This function can be called when the
+ * DMA Stream is enabled and when the transfer is ongoing.
+ * @param DMAy_Streamx: where y can be 1 or 2 to select the DMA and x can be 0
+ * to 7 to select the DMA Stream.
+ * @param MemoryBaseAddr: The base address of the target memory buffer
+ * @param DMA_MemoryTarget: Next memory target to be used.
+ * This parameter can be one of the following values:
+ * @arg DMA_Memory_0: To use the memory address 0
+ * @arg DMA_Memory_1: To use the memory address 1
+ *
+ * @note It is not allowed to modify the Base Address of a target Memory when
+ * this target is involved in the current transfer. ie. If the DMA Stream
+ * is currently transferring to/from Memory 1, then it not possible to
+ * modify Base address of Memory 1, but it is possible to modify Base
+ * address of Memory 0.
+ * To know which Memory is currently used, you can use the function
+ * DMA_GetCurrentMemoryTarget().
+ *
+ * @retval None
+ */
+void DMA_MemoryTargetConfig(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t MemoryBaseAddr,
+ uint32_t DMA_MemoryTarget)
+{
+ /* Check the parameters */
+ assert_param(IS_DMA_ALL_PERIPH(DMAy_Streamx));
+ assert_param(IS_DMA_CURRENT_MEM(DMA_MemoryTarget));
+
+ /* Check the Memory target to be configured */
+ if (DMA_MemoryTarget != DMA_Memory_0)
+ {
+ /* Write to DMAy Streamx M1AR */
+ DMAy_Streamx->M1AR = MemoryBaseAddr;
+ }
+ else
+ {
+ /* Write to DMAy Streamx M0AR */
+ DMAy_Streamx->M0AR = MemoryBaseAddr;
+ }
+}
+
+/**
+ * @brief Returns the current memory target used by double buffer transfer.
+ * @param DMAy_Streamx: where y can be 1 or 2 to select the DMA and x can be 0
+ * to 7 to select the DMA Stream.
+ * @retval The memory target number: 0 for Memory0 or 1 for Memory1.
+ */
+uint32_t DMA_GetCurrentMemoryTarget(DMA_Stream_TypeDef* DMAy_Streamx)
+{
+ uint32_t tmp = 0;
+
+ /* Check the parameters */
+ assert_param(IS_DMA_ALL_PERIPH(DMAy_Streamx));
+
+ /* Get the current memory target */
+ if ((DMAy_Streamx->CR & DMA_SxCR_CT) != 0)
+ {
+ /* Current memory buffer used is Memory 1 */
+ tmp = 1;
+ }
+ else
+ {
+ /* Current memory buffer used is Memory 0 */
+ tmp = 0;
+ }
+ return tmp;
+}
+/**
+ * @}
+ */
+
+/** @defgroup DMA_Group4 Interrupts and flags management functions
+ * @brief Interrupts and flags management functions
+ *
+@verbatim
+ ===============================================================================
+ Interrupts and flags management functions
+ ===============================================================================
+
+ This subsection provides functions allowing to
+ - Check the DMA enable status
+ - Check the FIFO status
+ - Configure the DMA Interrupts sources and check or clear the flags or pending bits status.
+
+ 1. DMA Enable status:
+ After configuring the DMA Stream (DMA_Init() function) and enabling the stream,
+ it is recommended to check (or wait until) the DMA Stream is effectively enabled.
+ A Stream may remain disabled if a configuration parameter is wrong.
+ After disabling a DMA Stream, it is also recommended to check (or wait until) the DMA
+ Stream is effectively disabled. If a Stream is disabled while a data transfer is ongoing,
+ the current data will be transferred and the Stream will be effectively disabled only after
+ this data transfer completion.
+ To monitor this state it is possible to use the following function:
+ - FunctionalState DMA_GetCmdStatus(DMA_Stream_TypeDef* DMAy_Streamx);
+
+ 2. FIFO Status:
+ It is possible to monitor the FIFO status when a transfer is ongoing using the following
+ function:
+ - uint32_t DMA_GetFIFOStatus(DMA_Stream_TypeDef* DMAy_Streamx);
+
+ 3. DMA Interrupts and Flags:
+ The user should identify which mode will be used in his application to manage the
+ DMA controller events: Polling mode or Interrupt mode.
+
+ Polling Mode
+ =============
+ Each DMA stream can be managed through 4 event Flags:
+ (x : DMA Stream number )
+ 1. DMA_FLAG_FEIFx : to indicate that a FIFO Mode Transfer Error event occurred.
+ 2. DMA_FLAG_DMEIFx : to indicate that a Direct Mode Transfer Error event occurred.
+ 3. DMA_FLAG_TEIFx : to indicate that a Transfer Error event occurred.
+ 4. DMA_FLAG_HTIFx : to indicate that a Half-Transfer Complete event occurred.
+ 5. DMA_FLAG_TCIFx : to indicate that a Transfer Complete event occurred .
+
+ In this Mode it is advised to use the following functions:
+ - FlagStatus DMA_GetFlagStatus(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t DMA_FLAG);
+ - void DMA_ClearFlag(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t DMA_FLAG);
+
+ Interrupt Mode
+ ===============
+ Each DMA Stream can be managed through 4 Interrupts:
+
+ Interrupt Source
+ ----------------
+ 1. DMA_IT_FEIFx : specifies the interrupt source for the FIFO Mode Transfer Error event.
+ 2. DMA_IT_DMEIFx : specifies the interrupt source for the Direct Mode Transfer Error event.
+ 3. DMA_IT_TEIFx : specifies the interrupt source for the Transfer Error event.
+ 4. DMA_IT_HTIFx : specifies the interrupt source for the Half-Transfer Complete event.
+ 5. DMA_IT_TCIFx : specifies the interrupt source for the a Transfer Complete event.
+
+ In this Mode it is advised to use the following functions:
+ - void DMA_ITConfig(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t DMA_IT, FunctionalState NewState);
+ - ITStatus DMA_GetITStatus(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t DMA_IT);
+ - void DMA_ClearITPendingBit(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t DMA_IT);
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Returns the status of EN bit for the specified DMAy Streamx.
+ * @param DMAy_Streamx: where y can be 1 or 2 to select the DMA and x can be 0
+ * to 7 to select the DMA Stream.
+ *
+ * @note After configuring the DMA Stream (DMA_Init() function) and enabling
+ * the stream, it is recommended to check (or wait until) the DMA Stream
+ * is effectively enabled. A Stream may remain disabled if a configuration
+ * parameter is wrong.
+ * After disabling a DMA Stream, it is also recommended to check (or wait
+ * until) the DMA Stream is effectively disabled. If a Stream is disabled
+ * while a data transfer is ongoing, the current data will be transferred
+ * and the Stream will be effectively disabled only after the transfer
+ * of this single data is finished.
+ *
+ * @retval Current state of the DMAy Streamx (ENABLE or DISABLE).
+ */
+FunctionalState DMA_GetCmdStatus(DMA_Stream_TypeDef* DMAy_Streamx)
+{
+ FunctionalState state = DISABLE;
+
+ /* Check the parameters */
+ assert_param(IS_DMA_ALL_PERIPH(DMAy_Streamx));
+
+ if ((DMAy_Streamx->CR & (uint32_t)DMA_SxCR_EN) != 0)
+ {
+ /* The selected DMAy Streamx EN bit is set (DMA is still transferring) */
+ state = ENABLE;
+ }
+ else
+ {
+ /* The selected DMAy Streamx EN bit is cleared (DMA is disabled and
+ all transfers are complete) */
+ state = DISABLE;
+ }
+ return state;
+}
+
+/**
+ * @brief Returns the current DMAy Streamx FIFO filled level.
+ * @param DMAy_Streamx: where y can be 1 or 2 to select the DMA and x can be 0
+ * to 7 to select the DMA Stream.
+ * @retval The FIFO filling state.
+ * - DMA_FIFOStatus_Less1QuarterFull: when FIFO is less than 1 quarter-full
+ * and not empty.
+ * - DMA_FIFOStatus_1QuarterFull: if more than 1 quarter-full.
+ * - DMA_FIFOStatus_HalfFull: if more than 1 half-full.
+ * - DMA_FIFOStatus_3QuartersFull: if more than 3 quarters-full.
+ * - DMA_FIFOStatus_Empty: when FIFO is empty
+ * - DMA_FIFOStatus_Full: when FIFO is full
+ */
+uint32_t DMA_GetFIFOStatus(DMA_Stream_TypeDef* DMAy_Streamx)
+{
+ uint32_t tmpreg = 0;
+
+ /* Check the parameters */
+ assert_param(IS_DMA_ALL_PERIPH(DMAy_Streamx));
+
+ /* Get the FIFO level bits */
+ tmpreg = (uint32_t)((DMAy_Streamx->FCR & DMA_SxFCR_FS));
+
+ return tmpreg;
+}
+
+/**
+ * @brief Checks whether the specified DMAy Streamx flag is set or not.
+ * @param DMAy_Streamx: where y can be 1 or 2 to select the DMA and x can be 0
+ * to 7 to select the DMA Stream.
+ * @param DMA_FLAG: specifies the flag to check.
+ * This parameter can be one of the following values:
+ * @arg DMA_FLAG_TCIFx: Streamx transfer complete flag
+ * @arg DMA_FLAG_HTIFx: Streamx half transfer complete flag
+ * @arg DMA_FLAG_TEIFx: Streamx transfer error flag
+ * @arg DMA_FLAG_DMEIFx: Streamx direct mode error flag
+ * @arg DMA_FLAG_FEIFx: Streamx FIFO error flag
+ * Where x can be 0 to 7 to select the DMA Stream.
+ * @retval The new state of DMA_FLAG (SET or RESET).
+ */
+FlagStatus DMA_GetFlagStatus(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t DMA_FLAG)
+{
+ FlagStatus bitstatus = RESET;
+ DMA_TypeDef* DMAy;
+ uint32_t tmpreg = 0;
+
+ /* Check the parameters */
+ assert_param(IS_DMA_ALL_PERIPH(DMAy_Streamx));
+ assert_param(IS_DMA_GET_FLAG(DMA_FLAG));
+
+ /* Determine the DMA to which belongs the stream */
+ if (DMAy_Streamx < DMA2_Stream0)
+ {
+ /* DMAy_Streamx belongs to DMA1 */
+ DMAy = DMA1;
+ }
+ else
+ {
+ /* DMAy_Streamx belongs to DMA2 */
+ DMAy = DMA2;
+ }
+
+ /* Check if the flag is in HISR or LISR */
+ if ((DMA_FLAG & HIGH_ISR_MASK) != (uint32_t)RESET)
+ {
+ /* Get DMAy HISR register value */
+ tmpreg = DMAy->HISR;
+ }
+ else
+ {
+ /* Get DMAy LISR register value */
+ tmpreg = DMAy->LISR;
+ }
+
+ /* Mask the reserved bits */
+ tmpreg &= (uint32_t)RESERVED_MASK;
+
+ /* Check the status of the specified DMA flag */
+ if ((tmpreg & DMA_FLAG) != (uint32_t)RESET)
+ {
+ /* DMA_FLAG is set */
+ bitstatus = SET;
+ }
+ else
+ {
+ /* DMA_FLAG is reset */
+ bitstatus = RESET;
+ }
+
+ /* Return the DMA_FLAG status */
+ return bitstatus;
+}
+
+/**
+ * @brief Clears the DMAy Streamx's pending flags.
+ * @param DMAy_Streamx: where y can be 1 or 2 to select the DMA and x can be 0
+ * to 7 to select the DMA Stream.
+ * @param DMA_FLAG: specifies the flag to clear.
+ * This parameter can be any combination of the following values:
+ * @arg DMA_FLAG_TCIFx: Streamx transfer complete flag
+ * @arg DMA_FLAG_HTIFx: Streamx half transfer complete flag
+ * @arg DMA_FLAG_TEIFx: Streamx transfer error flag
+ * @arg DMA_FLAG_DMEIFx: Streamx direct mode error flag
+ * @arg DMA_FLAG_FEIFx: Streamx FIFO error flag
+ * Where x can be 0 to 7 to select the DMA Stream.
+ * @retval None
+ */
+void DMA_ClearFlag(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t DMA_FLAG)
+{
+ DMA_TypeDef* DMAy;
+
+ /* Check the parameters */
+ assert_param(IS_DMA_ALL_PERIPH(DMAy_Streamx));
+ assert_param(IS_DMA_CLEAR_FLAG(DMA_FLAG));
+
+ /* Determine the DMA to which belongs the stream */
+ if (DMAy_Streamx < DMA2_Stream0)
+ {
+ /* DMAy_Streamx belongs to DMA1 */
+ DMAy = DMA1;
+ }
+ else
+ {
+ /* DMAy_Streamx belongs to DMA2 */
+ DMAy = DMA2;
+ }
+
+ /* Check if LIFCR or HIFCR register is targeted */
+ if ((DMA_FLAG & HIGH_ISR_MASK) != (uint32_t)RESET)
+ {
+ /* Set DMAy HIFCR register clear flag bits */
+ DMAy->HIFCR = (uint32_t)(DMA_FLAG & RESERVED_MASK);
+ }
+ else
+ {
+ /* Set DMAy LIFCR register clear flag bits */
+ DMAy->LIFCR = (uint32_t)(DMA_FLAG & RESERVED_MASK);
+ }
+}
+
+/**
+ * @brief Enables or disables the specified DMAy Streamx interrupts.
+ * @param DMAy_Streamx: where y can be 1 or 2 to select the DMA and x can be 0
+ * to 7 to select the DMA Stream.
+ * @param DMA_IT: specifies the DMA interrupt sources to be enabled or disabled.
+ * This parameter can be any combination of the following values:
+ * @arg DMA_IT_TC: Transfer complete interrupt mask
+ * @arg DMA_IT_HT: Half transfer complete interrupt mask
+ * @arg DMA_IT_TE: Transfer error interrupt mask
+ * @arg DMA_IT_FE: FIFO error interrupt mask
+ * @param NewState: new state of the specified DMA interrupts.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void DMA_ITConfig(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t DMA_IT, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_DMA_ALL_PERIPH(DMAy_Streamx));
+ assert_param(IS_DMA_CONFIG_IT(DMA_IT));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ /* Check if the DMA_IT parameter contains a FIFO interrupt */
+ if ((DMA_IT & DMA_IT_FE) != 0)
+ {
+ if (NewState != DISABLE)
+ {
+ /* Enable the selected DMA FIFO interrupts */
+ DMAy_Streamx->FCR |= (uint32_t)DMA_IT_FE;
+ }
+ else
+ {
+ /* Disable the selected DMA FIFO interrupts */
+ DMAy_Streamx->FCR &= ~(uint32_t)DMA_IT_FE;
+ }
+ }
+
+ /* Check if the DMA_IT parameter contains a Transfer interrupt */
+ if (DMA_IT != DMA_IT_FE)
+ {
+ if (NewState != DISABLE)
+ {
+ /* Enable the selected DMA transfer interrupts */
+ DMAy_Streamx->CR |= (uint32_t)(DMA_IT & TRANSFER_IT_ENABLE_MASK);
+ }
+ else
+ {
+ /* Disable the selected DMA transfer interrupts */
+ DMAy_Streamx->CR &= ~(uint32_t)(DMA_IT & TRANSFER_IT_ENABLE_MASK);
+ }
+ }
+}
+
+/**
+ * @brief Checks whether the specified DMAy Streamx interrupt has occurred or not.
+ * @param DMAy_Streamx: where y can be 1 or 2 to select the DMA and x can be 0
+ * to 7 to select the DMA Stream.
+ * @param DMA_IT: specifies the DMA interrupt source to check.
+ * This parameter can be one of the following values:
+ * @arg DMA_IT_TCIFx: Streamx transfer complete interrupt
+ * @arg DMA_IT_HTIFx: Streamx half transfer complete interrupt
+ * @arg DMA_IT_TEIFx: Streamx transfer error interrupt
+ * @arg DMA_IT_DMEIFx: Streamx direct mode error interrupt
+ * @arg DMA_IT_FEIFx: Streamx FIFO error interrupt
+ * Where x can be 0 to 7 to select the DMA Stream.
+ * @retval The new state of DMA_IT (SET or RESET).
+ */
+ITStatus DMA_GetITStatus(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t DMA_IT)
+{
+ ITStatus bitstatus = RESET;
+ DMA_TypeDef* DMAy;
+ uint32_t tmpreg = 0, enablestatus = 0;
+
+ /* Check the parameters */
+ assert_param(IS_DMA_ALL_PERIPH(DMAy_Streamx));
+ assert_param(IS_DMA_GET_IT(DMA_IT));
+
+ /* Determine the DMA to which belongs the stream */
+ if (DMAy_Streamx < DMA2_Stream0)
+ {
+ /* DMAy_Streamx belongs to DMA1 */
+ DMAy = DMA1;
+ }
+ else
+ {
+ /* DMAy_Streamx belongs to DMA2 */
+ DMAy = DMA2;
+ }
+
+ /* Check if the interrupt enable bit is in the CR or FCR register */
+ if ((DMA_IT & TRANSFER_IT_MASK) != (uint32_t)RESET)
+ {
+ /* Get the interrupt enable position mask in CR register */
+ tmpreg = (uint32_t)((DMA_IT >> 11) & TRANSFER_IT_ENABLE_MASK);
+
+ /* Check the enable bit in CR register */
+ enablestatus = (uint32_t)(DMAy_Streamx->CR & tmpreg);
+ }
+ else
+ {
+ /* Check the enable bit in FCR register */
+ enablestatus = (uint32_t)(DMAy_Streamx->FCR & DMA_IT_FE);
+ }
+
+ /* Check if the interrupt pending flag is in LISR or HISR */
+ if ((DMA_IT & HIGH_ISR_MASK) != (uint32_t)RESET)
+ {
+ /* Get DMAy HISR register value */
+ tmpreg = DMAy->HISR ;
+ }
+ else
+ {
+ /* Get DMAy LISR register value */
+ tmpreg = DMAy->LISR ;
+ }
+
+ /* mask all reserved bits */
+ tmpreg &= (uint32_t)RESERVED_MASK;
+
+ /* Check the status of the specified DMA interrupt */
+ if (((tmpreg & DMA_IT) != (uint32_t)RESET) && (enablestatus != (uint32_t)RESET))
+ {
+ /* DMA_IT is set */
+ bitstatus = SET;
+ }
+ else
+ {
+ /* DMA_IT is reset */
+ bitstatus = RESET;
+ }
+
+ /* Return the DMA_IT status */
+ return bitstatus;
+}
+
+/**
+ * @brief Clears the DMAy Streamx's interrupt pending bits.
+ * @param DMAy_Streamx: where y can be 1 or 2 to select the DMA and x can be 0
+ * to 7 to select the DMA Stream.
+ * @param DMA_IT: specifies the DMA interrupt pending bit to clear.
+ * This parameter can be any combination of the following values:
+ * @arg DMA_IT_TCIFx: Streamx transfer complete interrupt
+ * @arg DMA_IT_HTIFx: Streamx half transfer complete interrupt
+ * @arg DMA_IT_TEIFx: Streamx transfer error interrupt
+ * @arg DMA_IT_DMEIFx: Streamx direct mode error interrupt
+ * @arg DMA_IT_FEIFx: Streamx FIFO error interrupt
+ * Where x can be 0 to 7 to select the DMA Stream.
+ * @retval None
+ */
+void DMA_ClearITPendingBit(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t DMA_IT)
+{
+ DMA_TypeDef* DMAy;
+
+ /* Check the parameters */
+ assert_param(IS_DMA_ALL_PERIPH(DMAy_Streamx));
+ assert_param(IS_DMA_CLEAR_IT(DMA_IT));
+
+ /* Determine the DMA to which belongs the stream */
+ if (DMAy_Streamx < DMA2_Stream0)
+ {
+ /* DMAy_Streamx belongs to DMA1 */
+ DMAy = DMA1;
+ }
+ else
+ {
+ /* DMAy_Streamx belongs to DMA2 */
+ DMAy = DMA2;
+ }
+
+ /* Check if LIFCR or HIFCR register is targeted */
+ if ((DMA_IT & HIGH_ISR_MASK) != (uint32_t)RESET)
+ {
+ /* Set DMAy HIFCR register clear interrupt bits */
+ DMAy->HIFCR = (uint32_t)(DMA_IT & RESERVED_MASK);
+ }
+ else
+ {
+ /* Set DMAy LIFCR register clear interrupt bits */
+ DMAy->LIFCR = (uint32_t)(DMA_IT & RESERVED_MASK);
+ }
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/src/stm32f2xx_exti.c b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/src/stm32f2xx_exti.c
new file mode 100644
index 0000000..9cf97ee
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/src/stm32f2xx_exti.c
@@ -0,0 +1,312 @@
+/**
+ ******************************************************************************
+ * @file stm32f2xx_exti.c
+ * @author MCD Application Team
+ * @version V1.1.2
+ * @date 05-March-2012
+ * @brief This file provides firmware functions to manage the following
+ * functionalities of the EXTI peripheral:
+ * - Initialization and Configuration
+ * - Interrupts and flags management
+ *
+ * @verbatim
+ *
+ * ===================================================================
+ * EXTI features
+ * ===================================================================
+ *
+ * External interrupt/event lines are mapped as following:
+ * 1- All available GPIO pins are connected to the 16 external
+ * interrupt/event lines from EXTI0 to EXTI15.
+ * 2- EXTI line 16 is connected to the PVD Output
+ * 3- EXTI line 17 is connected to the RTC Alarm event
+ * 4- EXTI line 18 is connected to the USB OTG FS Wakeup from suspend event
+ * 5- EXTI line 19 is connected to the Ethernet Wakeup event
+ * 6- EXTI line 20 is connected to the USB OTG HS (configured in FS) Wakeup event
+ * 7- EXTI line 21 is connected to the RTC Tamper and Time Stamp events
+ * 8- EXTI line 22 is connected to the RTC Wakeup event
+ *
+ * ===================================================================
+ * How to use this driver
+ * ===================================================================
+ *
+ * In order to use an I/O pin as an external interrupt source, follow
+ * steps below:
+ * 1- Configure the I/O in input mode using GPIO_Init()
+ * 2- Select the input source pin for the EXTI line using SYSCFG_EXTILineConfig()
+ * 3- Select the mode(interrupt, event) and configure the trigger
+ * selection (Rising, falling or both) using EXTI_Init()
+ * 4- Configure NVIC IRQ channel mapped to the EXTI line using NVIC_Init()
+ *
+ * @note SYSCFG APB clock must be enabled to get write access to SYSCFG_EXTICRx
+ * registers using RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
+ *
+ * @endverbatim
+ *
+ ******************************************************************************
+ * @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 "stm32f2xx_exti.h"
+
+/** @addtogroup STM32F2xx_StdPeriph_Driver
+ * @{
+ */
+
+/** @defgroup EXTI
+ * @brief EXTI driver modules
+ * @{
+ */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+
+#define EXTI_LINENONE ((uint32_t)0x00000) /* No interrupt selected */
+
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+/** @defgroup EXTI_Private_Functions
+ * @{
+ */
+
+/** @defgroup EXTI_Group1 Initialization and Configuration functions
+ * @brief Initialization and Configuration functions
+ *
+@verbatim
+ ===============================================================================
+ Initialization and Configuration functions
+ ===============================================================================
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Deinitializes the EXTI peripheral registers to their default reset values.
+ * @param None
+ * @retval None
+ */
+void EXTI_DeInit(void)
+{
+ EXTI->IMR = 0x00000000;
+ EXTI->EMR = 0x00000000;
+ EXTI->RTSR = 0x00000000;
+ EXTI->FTSR = 0x00000000;
+ EXTI->PR = 0x007FFFFF;
+}
+
+/**
+ * @brief Initializes the EXTI peripheral according to the specified
+ * parameters in the EXTI_InitStruct.
+ * @param EXTI_InitStruct: pointer to a EXTI_InitTypeDef structure
+ * that contains the configuration information for the EXTI peripheral.
+ * @retval None
+ */
+void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct)
+{
+ uint32_t tmp = 0;
+
+ /* Check the parameters */
+ assert_param(IS_EXTI_MODE(EXTI_InitStruct->EXTI_Mode));
+ assert_param(IS_EXTI_TRIGGER(EXTI_InitStruct->EXTI_Trigger));
+ assert_param(IS_EXTI_LINE(EXTI_InitStruct->EXTI_Line));
+ assert_param(IS_FUNCTIONAL_STATE(EXTI_InitStruct->EXTI_LineCmd));
+
+ tmp = (uint32_t)EXTI_BASE;
+
+ if (EXTI_InitStruct->EXTI_LineCmd != DISABLE)
+ {
+ /* Clear EXTI line configuration */
+ EXTI->IMR &= ~EXTI_InitStruct->EXTI_Line;
+ EXTI->EMR &= ~EXTI_InitStruct->EXTI_Line;
+
+ tmp += EXTI_InitStruct->EXTI_Mode;
+
+ *(__IO uint32_t *) tmp |= EXTI_InitStruct->EXTI_Line;
+
+ /* Clear Rising Falling edge configuration */
+ EXTI->RTSR &= ~EXTI_InitStruct->EXTI_Line;
+ EXTI->FTSR &= ~EXTI_InitStruct->EXTI_Line;
+
+ /* Select the trigger for the selected external interrupts */
+ if (EXTI_InitStruct->EXTI_Trigger == EXTI_Trigger_Rising_Falling)
+ {
+ /* Rising Falling edge */
+ EXTI->RTSR |= EXTI_InitStruct->EXTI_Line;
+ EXTI->FTSR |= EXTI_InitStruct->EXTI_Line;
+ }
+ else
+ {
+ tmp = (uint32_t)EXTI_BASE;
+ tmp += EXTI_InitStruct->EXTI_Trigger;
+
+ *(__IO uint32_t *) tmp |= EXTI_InitStruct->EXTI_Line;
+ }
+ }
+ else
+ {
+ tmp += EXTI_InitStruct->EXTI_Mode;
+
+ /* Disable the selected external lines */
+ *(__IO uint32_t *) tmp &= ~EXTI_InitStruct->EXTI_Line;
+ }
+}
+
+/**
+ * @brief Fills each EXTI_InitStruct member with its reset value.
+ * @param EXTI_InitStruct: pointer to a EXTI_InitTypeDef structure which will
+ * be initialized.
+ * @retval None
+ */
+void EXTI_StructInit(EXTI_InitTypeDef* EXTI_InitStruct)
+{
+ EXTI_InitStruct->EXTI_Line = EXTI_LINENONE;
+ EXTI_InitStruct->EXTI_Mode = EXTI_Mode_Interrupt;
+ EXTI_InitStruct->EXTI_Trigger = EXTI_Trigger_Falling;
+ EXTI_InitStruct->EXTI_LineCmd = DISABLE;
+}
+
+/**
+ * @brief Generates a Software interrupt on selected EXTI line.
+ * @param EXTI_Line: specifies the EXTI line on which the software interrupt
+ * will be generated.
+ * This parameter can be any combination of EXTI_Linex where x can be (0..22)
+ * @retval None
+ */
+void EXTI_GenerateSWInterrupt(uint32_t EXTI_Line)
+{
+ /* Check the parameters */
+ assert_param(IS_EXTI_LINE(EXTI_Line));
+
+ EXTI->SWIER |= EXTI_Line;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup EXTI_Group2 Interrupts and flags management functions
+ * @brief Interrupts and flags management functions
+ *
+@verbatim
+ ===============================================================================
+ Interrupts and flags management functions
+ ===============================================================================
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Checks whether the specified EXTI line flag is set or not.
+ * @param EXTI_Line: specifies the EXTI line flag to check.
+ * This parameter can be EXTI_Linex where x can be(0..22)
+ * @retval The new state of EXTI_Line (SET or RESET).
+ */
+FlagStatus EXTI_GetFlagStatus(uint32_t EXTI_Line)
+{
+ FlagStatus bitstatus = RESET;
+ /* Check the parameters */
+ assert_param(IS_GET_EXTI_LINE(EXTI_Line));
+
+ if ((EXTI->PR & EXTI_Line) != (uint32_t)RESET)
+ {
+ bitstatus = SET;
+ }
+ else
+ {
+ bitstatus = RESET;
+ }
+ return bitstatus;
+}
+
+/**
+ * @brief Clears the EXTI's line pending flags.
+ * @param EXTI_Line: specifies the EXTI lines flags to clear.
+ * This parameter can be any combination of EXTI_Linex where x can be (0..22)
+ * @retval None
+ */
+void EXTI_ClearFlag(uint32_t EXTI_Line)
+{
+ /* Check the parameters */
+ assert_param(IS_EXTI_LINE(EXTI_Line));
+
+ EXTI->PR = EXTI_Line;
+}
+
+/**
+ * @brief Checks whether the specified EXTI line is asserted or not.
+ * @param EXTI_Line: specifies the EXTI line to check.
+ * This parameter can be EXTI_Linex where x can be(0..22)
+ * @retval The new state of EXTI_Line (SET or RESET).
+ */
+ITStatus EXTI_GetITStatus(uint32_t EXTI_Line)
+{
+ ITStatus bitstatus = RESET;
+ uint32_t enablestatus = 0;
+ /* Check the parameters */
+ assert_param(IS_GET_EXTI_LINE(EXTI_Line));
+
+ enablestatus = EXTI->IMR & EXTI_Line;
+ if (((EXTI->PR & EXTI_Line) != (uint32_t)RESET) && (enablestatus != (uint32_t)RESET))
+ {
+ bitstatus = SET;
+ }
+ else
+ {
+ bitstatus = RESET;
+ }
+ return bitstatus;
+}
+
+/**
+ * @brief Clears the EXTI's line pending bits.
+ * @param EXTI_Line: specifies the EXTI lines to clear.
+ * This parameter can be any combination of EXTI_Linex where x can be (0..22)
+ * @retval None
+ */
+void EXTI_ClearITPendingBit(uint32_t EXTI_Line)
+{
+ /* Check the parameters */
+ assert_param(IS_EXTI_LINE(EXTI_Line));
+
+ EXTI->PR = EXTI_Line;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/src/stm32f2xx_flash.c b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/src/stm32f2xx_flash.c
new file mode 100644
index 0000000..ff0f65e
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/src/stm32f2xx_flash.c
@@ -0,0 +1,1060 @@
+/**
+ ******************************************************************************
+ * @file stm32f2xx_flash.c
+ * @author MCD Application Team
+ * @version V1.1.2
+ * @date 05-March-2012
+ * @brief This file provides firmware functions to manage the following
+ * functionalities of the FLASH peripheral:
+ * - FLASH Interface configuration
+ * - FLASH Memory Programming
+ * - Option Bytes Programming
+ * - Interrupts and flags management
+ *
+ * @verbatim
+ *
+ * ===================================================================
+ * How to use this driver
+ * ===================================================================
+ *
+ * This driver provides functions to configure and program the FLASH
+ * memory of all STM32F2xx devices.
+ * These functions are split in 4 groups:
+ *
+ * 1. FLASH Interface configuration functions: this group includes the
+ * management of the following features:
+ * - Set the latency
+ * - Enable/Disable the prefetch buffer
+ * - Enable/Disable the Instruction cache and the Data cache
+ * - Reset the Instruction cache and the Data cache
+ *
+ * 2. FLASH Memory Programming functions: this group includes all needed
+ * functions to erase and program the main memory:
+ * - Lock and Unlock the FLASH interface
+ * - Erase function: Erase sector, erase all sectors
+ * - Program functions: byte, half word, word and double word
+ *
+ * 3. Option Bytes Programming functions: this group includes all needed
+ * functions to manage the Option Bytes:
+ * - Set/Reset the write protection
+ * - Set the Read protection Level
+ * - Set the BOR level
+ * - Program the user Option Bytes
+ * - Launch the Option Bytes loader
+ *
+ * 4. Interrupts and flags management functions: this group
+ * includes all needed functions to:
+ * - Enable/Disable the FLASH interrupt sources
+ * - Get flags status
+ * - Clear flags
+ * - Get FLASH operation status
+ * - Wait for last FLASH operation
+ *
+ * @endverbatim
+ *
+ ******************************************************************************
+ * @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 "stm32f2xx_flash.h"
+
+/** @addtogroup STM32F2xx_StdPeriph_Driver
+ * @{
+ */
+
+/** @defgroup FLASH
+ * @brief FLASH driver modules
+ * @{
+ */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+#define SECTOR_MASK ((uint32_t)0xFFFFFF07)
+
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+/** @defgroup FLASH_Private_Functions
+ * @{
+ */
+
+/** @defgroup FLASH_Group1 FLASH Interface configuration functions
+ * @brief FLASH Interface configuration functions
+ *
+
+@verbatim
+ ===============================================================================
+ FLASH Interface configuration functions
+ ===============================================================================
+
+ This group includes the following functions:
+ - void FLASH_SetLatency(uint32_t FLASH_Latency)
+ To correctly read data from FLASH memory, the number of wait states (LATENCY)
+ must be correctly programmed according to the frequency of the CPU clock
+ (HCLK) and the supply voltage of the device.
+ +-------------------------------------------------------------------------------------+
+ | Latency | HCLK clock frequency (MHz) |
+ | |---------------------------------------------------------------------|
+ | | voltage range | voltage range | voltage range | voltage range |
+ | | 2.7 V - 3.6 V | 2.4 V - 2.7 V | 2.1 V - 2.4 V | 1.8 V - 2.1 V |
+ |---------------|----------------|----------------|-----------------|-----------------|
+ |0WS(1CPU cycle)|0 < HCLK <= 30 |0 < HCLK <= 24 |0 < HCLK <= 18 |0 < HCLK <= 16 |
+ |---------------|----------------|----------------|-----------------|-----------------|
+ |1WS(2CPU cycle)|30 < HCLK <= 60 |24 < HCLK <= 48 |18 < HCLK <= 36 |16 < HCLK <= 32 |
+ |---------------|----------------|----------------|-----------------|-----------------|
+ |2WS(3CPU cycle)|60 < HCLK <= 90 |48 < HCLK <= 72 |36 < HCLK <= 54 |32 < HCLK <= 48 |
+ |---------------|----------------|----------------|-----------------|-----------------|
+ |3WS(4CPU cycle)|90 < HCLK <= 120|72 < HCLK <= 96 |54 < HCLK <= 72 |48 < HCLK <= 64 |
+ |---------------|----------------|----------------|-----------------|-----------------|
+ |4WS(5CPU cycle)| NA |96 < HCLK <= 120|72 < HCLK <= 90 |64 < HCLK <= 80 |
+ |---------------|----------------|----------------|-----------------|-----------------|
+ |5WS(6CPU cycle)| NA | NA |90 < HCLK <= 108 |80 < HCLK <= 96 |
+ |---------------|----------------|----------------|-----------------|-----------------|
+ |6WS(7CPU cycle)| NA | NA |108 < HCLK <= 120|96 < HCLK <= 112 |
+ |---------------|----------------|----------------|-----------------|-----------------|
+ |7WS(8CPU cycle)| NA | NA | NA |112 < HCLK <= 120|
+ |***************|****************|****************|*****************|*****************|*****************************+
+ | | voltage range | voltage range | voltage range | voltage range | voltage range 2.7 V - 3.6 V |
+ | | 2.7 V - 3.6 V | 2.4 V - 2.7 V | 2.1 V - 2.4 V | 1.8 V - 2.1 V | with External Vpp = 9V |
+ |---------------|----------------|----------------|-----------------|-----------------|-----------------------------|
+ |Max Parallelism| x32 | x16 | x8 | x64 |
+ |---------------|----------------|----------------|-----------------|-----------------|-----------------------------|
+ |PSIZE[1:0] | 10 | 01 | 00 | 11 |
+ +-------------------------------------------------------------------------------------------------------------------+
+
+ - void FLASH_PrefetchBufferCmd(FunctionalState NewState)
+ - void FLASH_InstructionCacheCmd(FunctionalState NewState)
+ - void FLASH_DataCacheCmd(FunctionalState NewState)
+ - void FLASH_InstructionCacheReset(void)
+ - void FLASH_DataCacheReset(void)
+
+ The unlock sequence is not needed for these functions.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Sets the code latency value.
+ * @param FLASH_Latency: specifies the FLASH Latency value.
+ * This parameter can be one of the following values:
+ * @arg FLASH_Latency_0: FLASH Zero Latency cycle
+ * @arg FLASH_Latency_1: FLASH One Latency cycle
+ * @arg FLASH_Latency_2: FLASH Two Latency cycles
+ * @arg FLASH_Latency_3: FLASH Three Latency cycles
+ * @arg FLASH_Latency_4: FLASH Four Latency cycles
+ * @arg FLASH_Latency_5: FLASH Five Latency cycles
+ * @arg FLASH_Latency_6: FLASH Six Latency cycles
+ * @arg FLASH_Latency_7: FLASH Seven Latency cycles
+ * @retval None
+ */
+void FLASH_SetLatency(uint32_t FLASH_Latency)
+{
+ /* Check the parameters */
+ assert_param(IS_FLASH_LATENCY(FLASH_Latency));
+
+ /* Perform Byte access to FLASH_ACR[8:0] to set the Latency value */
+ *(__IO uint8_t *)ACR_BYTE0_ADDRESS = (uint8_t)FLASH_Latency;
+}
+
+/**
+ * @brief Enables or disables the Prefetch Buffer.
+ * @param NewState: new state of the Prefetch Buffer.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void FLASH_PrefetchBufferCmd(FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ /* Enable or disable the Prefetch Buffer */
+ if(NewState != DISABLE)
+ {
+ FLASH->ACR |= FLASH_ACR_PRFTEN;
+ }
+ else
+ {
+ FLASH->ACR &= (~FLASH_ACR_PRFTEN);
+ }
+}
+
+/**
+ * @brief Enables or disables the Instruction Cache feature.
+ * @param NewState: new state of the Instruction Cache.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void FLASH_InstructionCacheCmd(FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if(NewState != DISABLE)
+ {
+ FLASH->ACR |= FLASH_ACR_ICEN;
+ }
+ else
+ {
+ FLASH->ACR &= (~FLASH_ACR_ICEN);
+ }
+}
+
+/**
+ * @brief Enables or disables the Data Cache feature.
+ * @param NewState: new state of the Data Cache.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void FLASH_DataCacheCmd(FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if(NewState != DISABLE)
+ {
+ FLASH->ACR |= FLASH_ACR_DCEN;
+ }
+ else
+ {
+ FLASH->ACR &= (~FLASH_ACR_DCEN);
+ }
+}
+
+/**
+ * @brief Resets the Instruction Cache.
+ * @note This function must be used only when the Instruction Cache is disabled.
+ * @param None
+ * @retval None
+ */
+void FLASH_InstructionCacheReset(void)
+{
+ FLASH->ACR |= FLASH_ACR_ICRST;
+}
+
+/**
+ * @brief Resets the Data Cache.
+ * @note This function must be used only when the Data Cache is disabled.
+ * @param None
+ * @retval None
+ */
+void FLASH_DataCacheReset(void)
+{
+ FLASH->ACR |= FLASH_ACR_DCRST;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup FLASH_Group2 FLASH Memory Programming functions
+ * @brief FLASH Memory Programming functions
+ *
+@verbatim
+ ===============================================================================
+ FLASH Memory Programming functions
+ ===============================================================================
+
+ This group includes the following functions:
+ - void FLASH_Unlock(void)
+ - void FLASH_Lock(void)
+ - FLASH_Status FLASH_EraseSector(uint32_t FLASH_Sector, uint8_t VoltageRange)
+ - FLASH_Status FLASH_EraseAllSectors(uint8_t VoltageRange)
+ - FLASH_Status FLASH_ProgramDoubleWord(uint32_t Address, uint64_t Data)
+ - FLASH_Status FLASH_ProgramWord(uint32_t Address, uint32_t Data)
+ - FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data)
+ - FLASH_Status FLASH_ProgramByte(uint32_t Address, uint8_t Data)
+
+ Any operation of erase or program should follow these steps:
+ 1. Call the FLASH_Unlock() function to enable the FLASH control register access
+
+ 2. Call the desired function to erase sector(s) or program data
+
+ 3. Call the FLASH_Lock() function to disable the FLASH control register access
+ (recommended to protect the FLASH memory against possible unwanted operation)
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Unlocks the FLASH control register access
+ * @param None
+ * @retval None
+ */
+void FLASH_Unlock(void)
+{
+ if((FLASH->CR & FLASH_CR_LOCK) != RESET)
+ {
+ /* Authorize the FLASH Registers access */
+ FLASH->KEYR = FLASH_KEY1;
+ FLASH->KEYR = FLASH_KEY2;
+ }
+}
+
+/**
+ * @brief Locks the FLASH control register access
+ * @param None
+ * @retval None
+ */
+void FLASH_Lock(void)
+{
+ /* Set the LOCK Bit to lock the FLASH Registers access */
+ FLASH->CR |= FLASH_CR_LOCK;
+}
+
+/**
+ * @brief Erases a specified FLASH Sector.
+ *
+ * @param FLASH_Sector: The Sector number to be erased.
+ * This parameter can be a value between FLASH_Sector_0 and FLASH_Sector_11
+ *
+ * @param VoltageRange: The device voltage range which defines the erase parallelism.
+ * This parameter can be one of the following values:
+ * @arg VoltageRange_1: when the device voltage range is 1.8V to 2.1V,
+ * the operation will be done by byte (8-bit)
+ * @arg VoltageRange_2: when the device voltage range is 2.1V to 2.7V,
+ * the operation will be done by half word (16-bit)
+ * @arg VoltageRange_3: when the device voltage range is 2.7V to 3.6V,
+ * the operation will be done by word (32-bit)
+ * @arg VoltageRange_4: when the device voltage range is 2.7V to 3.6V + External Vpp,
+ * the operation will be done by double word (64-bit)
+ *
+ * @retval FLASH Status: The returned value can be: FLASH_BUSY, FLASH_ERROR_PROGRAM,
+ * FLASH_ERROR_WRP, FLASH_ERROR_OPERATION or FLASH_COMPLETE.
+ */
+FLASH_Status FLASH_EraseSector(uint32_t FLASH_Sector, uint8_t VoltageRange)
+{
+ uint32_t tmp_psize = 0x0;
+ FLASH_Status status = FLASH_COMPLETE;
+
+ /* Check the parameters */
+ assert_param(IS_FLASH_SECTOR(FLASH_Sector));
+ assert_param(IS_VOLTAGERANGE(VoltageRange));
+
+ if(VoltageRange == VoltageRange_1)
+ {
+ tmp_psize = FLASH_PSIZE_BYTE;
+ }
+ else if(VoltageRange == VoltageRange_2)
+ {
+ tmp_psize = FLASH_PSIZE_HALF_WORD;
+ }
+ else if(VoltageRange == VoltageRange_3)
+ {
+ tmp_psize = FLASH_PSIZE_WORD;
+ }
+ else
+ {
+ tmp_psize = FLASH_PSIZE_DOUBLE_WORD;
+ }
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation();
+
+ if(status == FLASH_COMPLETE)
+ {
+ /* if the previous operation is completed, proceed to erase the sector */
+ FLASH->CR &= CR_PSIZE_MASK;
+ FLASH->CR |= tmp_psize;
+ FLASH->CR &= SECTOR_MASK;
+ FLASH->CR |= FLASH_CR_SER | FLASH_Sector;
+ FLASH->CR |= FLASH_CR_STRT;
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation();
+
+ /* if the erase operation is completed, disable the SER Bit */
+ FLASH->CR &= (~FLASH_CR_SER);
+ FLASH->CR &= SECTOR_MASK;
+ }
+ /* Return the Erase Status */
+ return status;
+}
+
+/**
+ * @brief Erases all FLASH Sectors.
+ *
+ * @param VoltageRange: The device voltage range which defines the erase parallelism.
+ * This parameter can be one of the following values:
+ * @arg VoltageRange_1: when the device voltage range is 1.8V to 2.1V,
+ * the operation will be done by byte (8-bit)
+ * @arg VoltageRange_2: when the device voltage range is 2.1V to 2.7V,
+ * the operation will be done by half word (16-bit)
+ * @arg VoltageRange_3: when the device voltage range is 2.7V to 3.6V,
+ * the operation will be done by word (32-bit)
+ * @arg VoltageRange_4: when the device voltage range is 2.7V to 3.6V + External Vpp,
+ * the operation will be done by double word (64-bit)
+ *
+ * @retval FLASH Status: The returned value can be: FLASH_BUSY, FLASH_ERROR_PROGRAM,
+ * FLASH_ERROR_WRP, FLASH_ERROR_OPERATION or FLASH_COMPLETE.
+ */
+FLASH_Status FLASH_EraseAllSectors(uint8_t VoltageRange)
+{
+ uint32_t tmp_psize = 0x0;
+ FLASH_Status status = FLASH_COMPLETE;
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation();
+ assert_param(IS_VOLTAGERANGE(VoltageRange));
+
+ if(VoltageRange == VoltageRange_1)
+ {
+ tmp_psize = FLASH_PSIZE_BYTE;
+ }
+ else if(VoltageRange == VoltageRange_2)
+ {
+ tmp_psize = FLASH_PSIZE_HALF_WORD;
+ }
+ else if(VoltageRange == VoltageRange_3)
+ {
+ tmp_psize = FLASH_PSIZE_WORD;
+ }
+ else
+ {
+ tmp_psize = FLASH_PSIZE_DOUBLE_WORD;
+ }
+ if(status == FLASH_COMPLETE)
+ {
+ /* if the previous operation is completed, proceed to erase all sectors */
+ FLASH->CR &= CR_PSIZE_MASK;
+ FLASH->CR |= tmp_psize;
+ FLASH->CR |= FLASH_CR_MER;
+ FLASH->CR |= FLASH_CR_STRT;
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation();
+
+ /* if the erase operation is completed, disable the MER Bit */
+ FLASH->CR &= (~FLASH_CR_MER);
+
+ }
+ /* Return the Erase Status */
+ return status;
+}
+
+/**
+ * @brief Programs a double word (64-bit) at a specified address.
+ * @note This function must be used when the device voltage range is from
+ * 2.7V to 3.6V and an External Vpp is present.
+ * @param Address: specifies the address to be programmed.
+ * @param Data: specifies the data to be programmed.
+ * @retval FLASH Status: The returned value can be: FLASH_BUSY, FLASH_ERROR_PROGRAM,
+ * FLASH_ERROR_WRP, FLASH_ERROR_OPERATION or FLASH_COMPLETE.
+ */
+FLASH_Status FLASH_ProgramDoubleWord(uint32_t Address, uint64_t Data)
+{
+ FLASH_Status status = FLASH_COMPLETE;
+
+ /* Check the parameters */
+ assert_param(IS_FLASH_ADDRESS(Address));
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation();
+
+ if(status == FLASH_COMPLETE)
+ {
+ /* if the previous operation is completed, proceed to program the new data */
+ FLASH->CR &= CR_PSIZE_MASK;
+ FLASH->CR |= FLASH_PSIZE_DOUBLE_WORD;
+ FLASH->CR |= FLASH_CR_PG;
+
+ *(__IO uint64_t*)Address = Data;
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation();
+
+ /* if the program operation is completed, disable the PG Bit */
+ FLASH->CR &= (~FLASH_CR_PG);
+ }
+ /* Return the Program Status */
+ return status;
+}
+
+/**
+ * @brief Programs a word (32-bit) at a specified address.
+ * @param Address: specifies the address to be programmed.
+ * This parameter can be any address in Program memory zone or in OTP zone.
+ * @note This function must be used when the device voltage range is from 2.7V to 3.6V.
+ * @param Data: specifies the data to be programmed.
+ * @retval FLASH Status: The returned value can be: FLASH_BUSY, FLASH_ERROR_PROGRAM,
+ * FLASH_ERROR_WRP, FLASH_ERROR_OPERATION or FLASH_COMPLETE.
+ */
+FLASH_Status FLASH_ProgramWord(uint32_t Address, uint32_t Data)
+{
+ FLASH_Status status = FLASH_COMPLETE;
+
+ /* Check the parameters */
+ assert_param(IS_FLASH_ADDRESS(Address));
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation();
+
+ if(status == FLASH_COMPLETE)
+ {
+ /* if the previous operation is completed, proceed to program the new data */
+ FLASH->CR &= CR_PSIZE_MASK;
+ FLASH->CR |= FLASH_PSIZE_WORD;
+ FLASH->CR |= FLASH_CR_PG;
+
+ *(__IO uint32_t*)Address = Data;
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation();
+
+ /* if the program operation is completed, disable the PG Bit */
+ FLASH->CR &= (~FLASH_CR_PG);
+ }
+ /* Return the Program Status */
+ return status;
+}
+
+/**
+ * @brief Programs a half word (16-bit) at a specified address.
+ * @note This function must be used when the device voltage range is from 2.1V to 3.6V.
+ * @param Address: specifies the address to be programmed.
+ * This parameter can be any address in Program memory zone or in OTP zone.
+ * @param Data: specifies the data to be programmed.
+ * @retval FLASH Status: The returned value can be: FLASH_BUSY, FLASH_ERROR_PROGRAM,
+ * FLASH_ERROR_WRP, FLASH_ERROR_OPERATION or FLASH_COMPLETE.
+ */
+FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data)
+{
+ FLASH_Status status = FLASH_COMPLETE;
+
+ /* Check the parameters */
+ assert_param(IS_FLASH_ADDRESS(Address));
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation();
+
+ if(status == FLASH_COMPLETE)
+ {
+ /* if the previous operation is completed, proceed to program the new data */
+ FLASH->CR &= CR_PSIZE_MASK;
+ FLASH->CR |= FLASH_PSIZE_HALF_WORD;
+ FLASH->CR |= FLASH_CR_PG;
+
+ *(__IO uint16_t*)Address = Data;
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation();
+
+ /* if the program operation is completed, disable the PG Bit */
+ FLASH->CR &= (~FLASH_CR_PG);
+ }
+ /* Return the Program Status */
+ return status;
+}
+
+/**
+ * @brief Programs a byte (8-bit) at a specified address.
+ * @note This function can be used within all the device supply voltage ranges.
+ * @param Address: specifies the address to be programmed.
+ * This parameter can be any address in Program memory zone or in OTP zone.
+ * @param Data: specifies the data to be programmed.
+ * @retval FLASH Status: The returned value can be: FLASH_BUSY, FLASH_ERROR_PROGRAM,
+ * FLASH_ERROR_WRP, FLASH_ERROR_OPERATION or FLASH_COMPLETE.
+ */
+FLASH_Status FLASH_ProgramByte(uint32_t Address, uint8_t Data)
+{
+ FLASH_Status status = FLASH_COMPLETE;
+
+ /* Check the parameters */
+ assert_param(IS_FLASH_ADDRESS(Address));
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation();
+
+ if(status == FLASH_COMPLETE)
+ {
+ /* if the previous operation is completed, proceed to program the new data */
+ FLASH->CR &= CR_PSIZE_MASK;
+ FLASH->CR |= FLASH_PSIZE_BYTE;
+ FLASH->CR |= FLASH_CR_PG;
+
+ *(__IO uint8_t*)Address = Data;
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation();
+
+ /* if the program operation is completed, disable the PG Bit */
+ FLASH->CR &= (~FLASH_CR_PG);
+ }
+
+ /* Return the Program Status */
+ return status;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup FLASH_Group3 Option Bytes Programming functions
+ * @brief Option Bytes Programming functions
+ *
+@verbatim
+ ===============================================================================
+ Option Bytes Programming functions
+ ===============================================================================
+
+ This group includes the following functions:
+ - void FLASH_OB_Unlock(void)
+ - void FLASH_OB_Lock(void)
+ - void FLASH_OB_WRPConfig(uint32_t OB_WRP, FunctionalState NewState)
+ - void FLASH_OB_RDPConfig(uint8_t OB_RDP)
+ - void FLASH_OB_UserConfig(uint8_t OB_IWDG, uint8_t OB_STOP, uint8_t OB_STDBY)
+ - void FLASH_OB_BORConfig(uint8_t OB_BOR)
+ - FLASH_Status FLASH_ProgramOTP(uint32_t Address, uint32_t Data)
+ - FLASH_Status FLASH_OB_Launch(void)
+ - uint32_t FLASH_OB_GetUser(void)
+ - uint8_t FLASH_OB_GetWRP(void)
+ - uint8_t FLASH_OB_GetRDP(void)
+ - uint8_t FLASH_OB_GetBOR(void)
+
+ Any operation of erase or program should follow these steps:
+ 1. Call the FLASH_OB_Unlock() function to enable the FLASH option control register access
+
+ 2. Call one or several functions to program the desired Option Bytes:
+ - void FLASH_OB_WRPConfig(uint32_t OB_WRP, FunctionalState NewState) => to Enable/Disable
+ the desired sector write protection
+ - void FLASH_OB_RDPConfig(uint8_t OB_RDP) => to set the desired read Protection Level
+ - void FLASH_OB_UserConfig(uint8_t OB_IWDG, uint8_t OB_STOP, uint8_t OB_STDBY) => to configure
+ the user Option Bytes.
+ - void FLASH_OB_BORConfig(uint8_t OB_BOR) => to set the BOR Level
+
+ 3. Once all needed Option Bytes to be programmed are correctly written, call the
+ FLASH_OB_Launch() function to launch the Option Bytes programming process.
+
+ @note When changing the IWDG mode from HW to SW or from SW to HW, a system
+ reset is needed to make the change effective.
+
+ 4. Call the FLASH_OB_Lock() function to disable the FLASH option control register
+ access (recommended to protect the Option Bytes against possible unwanted operations)
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Unlocks the FLASH Option Control Registers access.
+ * @param None
+ * @retval None
+ */
+void FLASH_OB_Unlock(void)
+{
+ if((FLASH->OPTCR & FLASH_OPTCR_OPTLOCK) != RESET)
+ {
+ /* Authorizes the Option Byte register programming */
+ FLASH->OPTKEYR = FLASH_OPT_KEY1;
+ FLASH->OPTKEYR = FLASH_OPT_KEY2;
+ }
+}
+
+/**
+ * @brief Locks the FLASH Option Control Registers access.
+ * @param None
+ * @retval None
+ */
+void FLASH_OB_Lock(void)
+{
+ /* Set the OPTLOCK Bit to lock the FLASH Option Byte Registers access */
+ FLASH->OPTCR |= FLASH_OPTCR_OPTLOCK;
+}
+
+/**
+ * @brief Enables or disables the write protection of the desired sectors
+ * @param OB_WRP: specifies the sector(s) to be write protected or unprotected.
+ * This parameter can be one of the following values:
+ * @arg OB_WRP: A value between OB_WRP_Sector0 and OB_WRP_Sector11
+ * @arg OB_WRP_Sector_All
+ * @param Newstate: new state of the Write Protection.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void FLASH_OB_WRPConfig(uint32_t OB_WRP, FunctionalState NewState)
+{
+ FLASH_Status status = FLASH_COMPLETE;
+
+ /* Check the parameters */
+ assert_param(IS_OB_WRP(OB_WRP));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ status = FLASH_WaitForLastOperation();
+
+ if(status == FLASH_COMPLETE)
+ {
+ if(NewState != DISABLE)
+ {
+ *(__IO uint16_t*)OPTCR_BYTE2_ADDRESS &= (~OB_WRP);
+ }
+ else
+ {
+ *(__IO uint16_t*)OPTCR_BYTE2_ADDRESS |= (uint16_t)OB_WRP;
+ }
+ }
+}
+
+/**
+ * @brief Sets the read protection level.
+ * @param OB_RDP: specifies the read protection level.
+ * This parameter can be one of the following values:
+ * @arg OB_RDP_Level_0: No protection
+ * @arg OB_RDP_Level_1: Read protection of the memory
+ * @arg OB_RDP_Level_2: Full chip protection
+ *
+ * !!!Warning!!! When enabling OB_RDP level 2 it's no more possible to go back to level 1 or 0
+ *
+ * @retval None
+ */
+void FLASH_OB_RDPConfig(uint8_t OB_RDP)
+{
+ FLASH_Status status = FLASH_COMPLETE;
+
+ /* Check the parameters */
+ assert_param(IS_OB_RDP(OB_RDP));
+
+ status = FLASH_WaitForLastOperation();
+
+ if(status == FLASH_COMPLETE)
+ {
+ *(__IO uint8_t*)OPTCR_BYTE1_ADDRESS = OB_RDP;
+
+ }
+}
+
+/**
+ * @brief Programs the FLASH User Option Byte: IWDG_SW / RST_STOP / RST_STDBY.
+ * @param OB_IWDG: Selects the IWDG mode
+ * This parameter can be one of the following values:
+ * @arg OB_IWDG_SW: Software IWDG selected
+ * @arg OB_IWDG_HW: Hardware IWDG selected
+ * @param OB_STOP: Reset event when entering STOP mode.
+ * This parameter can be one of the following values:
+ * @arg OB_STOP_NoRST: No reset generated when entering in STOP
+ * @arg OB_STOP_RST: Reset generated when entering in STOP
+ * @param OB_STDBY: Reset event when entering Standby mode.
+ * This parameter can be one of the following values:
+ * @arg OB_STDBY_NoRST: No reset generated when entering in STANDBY
+ * @arg OB_STDBY_RST: Reset generated when entering in STANDBY
+ * @retval None
+ */
+void FLASH_OB_UserConfig(uint8_t OB_IWDG, uint8_t OB_STOP, uint8_t OB_STDBY)
+{
+ uint8_t optiontmp = 0xFF;
+ FLASH_Status status = FLASH_COMPLETE;
+
+ /* Check the parameters */
+ assert_param(IS_OB_IWDG_SOURCE(OB_IWDG));
+ assert_param(IS_OB_STOP_SOURCE(OB_STOP));
+ assert_param(IS_OB_STDBY_SOURCE(OB_STDBY));
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation();
+
+ if(status == FLASH_COMPLETE)
+ {
+ /* Mask OPTLOCK, OPTSTRT and BOR_LEV bits */
+ optiontmp = (uint8_t)((*(__IO uint8_t *)OPTCR_BYTE0_ADDRESS) & (uint8_t)0x0F);
+
+ /* Update User Option Byte */
+ *(__IO uint8_t *)OPTCR_BYTE0_ADDRESS = OB_IWDG | (uint8_t)(OB_STDBY | (uint8_t)(OB_STOP | ((uint8_t)optiontmp)));
+ }
+}
+
+/**
+ * @brief Sets the BOR Level.
+ * @param OB_BOR: specifies the Option Bytes BOR Reset Level.
+ * This parameter can be one of the following values:
+ * @arg OB_BOR_LEVEL3: Supply voltage ranges from 2.7 to 3.6 V
+ * @arg OB_BOR_LEVEL2: Supply voltage ranges from 2.4 to 2.7 V
+ * @arg OB_BOR_LEVEL1: Supply voltage ranges from 2.1 to 2.4 V
+ * @arg OB_BOR_OFF: Supply voltage ranges from 1.62 to 2.1 V
+ * @retval None
+ */
+void FLASH_OB_BORConfig(uint8_t OB_BOR)
+{
+ /* Check the parameters */
+ assert_param(IS_OB_BOR(OB_BOR));
+
+ /* Set the BOR Level */
+ *(__IO uint8_t *)OPTCR_BYTE0_ADDRESS &= (~FLASH_OPTCR_BOR_LEV);
+ *(__IO uint8_t *)OPTCR_BYTE0_ADDRESS |= OB_BOR;
+
+}
+
+/**
+ * @brief Launch the option byte loading.
+ * @param None
+ * @retval FLASH Status: The returned value can be: FLASH_BUSY, FLASH_ERROR_PROGRAM,
+ * FLASH_ERROR_WRP, FLASH_ERROR_OPERATION or FLASH_COMPLETE.
+ */
+FLASH_Status FLASH_OB_Launch(void)
+{
+ FLASH_Status status = FLASH_COMPLETE;
+
+ /* Set the OPTSTRT bit in OPTCR register */
+ *(__IO uint8_t *)OPTCR_BYTE0_ADDRESS |= FLASH_OPTCR_OPTSTRT;
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation();
+
+ return status;
+}
+
+/**
+ * @brief Returns the FLASH User Option Bytes values.
+ * @param None
+ * @retval The FLASH User Option Bytes values: IWDG_SW(Bit0), RST_STOP(Bit1)
+ * and RST_STDBY(Bit2).
+ */
+uint8_t FLASH_OB_GetUser(void)
+{
+ /* Return the User Option Byte */
+ return (uint8_t)(FLASH->OPTCR >> 5);
+}
+
+/**
+ * @brief Returns the FLASH Write Protection Option Bytes value.
+ * @param None
+ * @retval The FLASH Write Protection Option Bytes value
+ */
+uint16_t FLASH_OB_GetWRP(void)
+{
+ /* Return the FLASH write protection Register value */
+ return (*(__IO uint16_t *)(OPTCR_BYTE2_ADDRESS));
+}
+
+/**
+ * @brief Returns the FLASH Read Protection level.
+ * @param None
+ * @retval FLASH ReadOut Protection Status:
+ * - SET, when OB_RDP_Level_1 or OB_RDP_Level_2 is set
+ * - RESET, when OB_RDP_Level_0 is set
+ */
+FlagStatus FLASH_OB_GetRDP(void)
+{
+ FlagStatus readstatus = RESET;
+
+ if ((*(__IO uint8_t*)(OPTCR_BYTE1_ADDRESS) != (uint8_t)OB_RDP_Level_0))
+ {
+ readstatus = SET;
+ }
+ else
+ {
+ readstatus = RESET;
+ }
+ return readstatus;
+}
+
+/**
+ * @brief Returns the FLASH BOR level.
+ * @param None
+ * @retval The FLASH BOR level:
+ * - OB_BOR_LEVEL3: Supply voltage ranges from 2.7 to 3.6 V
+ * - OB_BOR_LEVEL2: Supply voltage ranges from 2.4 to 2.7 V
+ * - OB_BOR_LEVEL1: Supply voltage ranges from 2.1 to 2.4 V
+ * - OB_BOR_OFF : Supply voltage ranges from 1.62 to 2.1 V
+ */
+uint8_t FLASH_OB_GetBOR(void)
+{
+ /* Return the FLASH BOR level */
+ return (uint8_t)(*(__IO uint8_t *)(OPTCR_BYTE0_ADDRESS) & (uint8_t)0x0C);
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup FLASH_Group4 Interrupts and flags management functions
+ * @brief Interrupts and flags management functions
+ *
+@verbatim
+ ===============================================================================
+ Interrupts and flags management functions
+ ===============================================================================
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Enables or disables the specified FLASH interrupts.
+ * @param FLASH_IT: specifies the FLASH interrupt sources to be enabled or disabled.
+ * This parameter can be any combination of the following values:
+ * @arg FLASH_IT_ERR: FLASH Error Interrupt
+ * @arg FLASH_IT_EOP: FLASH end of operation Interrupt
+ * @retval None
+ */
+void FLASH_ITConfig(uint32_t FLASH_IT, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_FLASH_IT(FLASH_IT));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if(NewState != DISABLE)
+ {
+ /* Enable the interrupt sources */
+ FLASH->CR |= FLASH_IT;
+ }
+ else
+ {
+ /* Disable the interrupt sources */
+ FLASH->CR &= ~(uint32_t)FLASH_IT;
+ }
+}
+
+/**
+ * @brief Checks whether the specified FLASH flag is set or not.
+ * @param FLASH_FLAG: specifies the FLASH flag to check.
+ * This parameter can be one of the following values:
+ * @arg FLASH_FLAG_EOP: FLASH End of Operation flag
+ * @arg FLASH_FLAG_OPERR: FLASH operation Error flag
+ * @arg FLASH_FLAG_WRPERR: FLASH Write protected error flag
+ * @arg FLASH_FLAG_PGAERR: FLASH Programming Alignment error flag
+ * @arg FLASH_FLAG_PGPERR: FLASH Programming Parallelism error flag
+ * @arg FLASH_FLAG_PGSERR: FLASH Programming Sequence error flag
+ * @arg FLASH_FLAG_BSY: FLASH Busy flag
+ * @retval The new state of FLASH_FLAG (SET or RESET).
+ */
+FlagStatus FLASH_GetFlagStatus(uint32_t FLASH_FLAG)
+{
+ FlagStatus bitstatus = RESET;
+ /* Check the parameters */
+ assert_param(IS_FLASH_GET_FLAG(FLASH_FLAG));
+
+ if((FLASH->SR & FLASH_FLAG) != (uint32_t)RESET)
+ {
+ bitstatus = SET;
+ }
+ else
+ {
+ bitstatus = RESET;
+ }
+ /* Return the new state of FLASH_FLAG (SET or RESET) */
+ return bitstatus;
+}
+
+/**
+ * @brief Clears the FLASH's pending flags.
+ * @param FLASH_FLAG: specifies the FLASH flags to clear.
+ * This parameter can be any combination of the following values:
+ * @arg FLASH_FLAG_EOP: FLASH End of Operation flag
+ * @arg FLASH_FLAG_OPERR: FLASH operation Error flag
+ * @arg FLASH_FLAG_WRPERR: FLASH Write protected error flag
+ * @arg FLASH_FLAG_PGAERR: FLASH Programming Alignment error flag
+ * @arg FLASH_FLAG_PGPERR: FLASH Programming Parallelism error flag
+ * @arg FLASH_FLAG_PGSERR: FLASH Programming Sequence error flag
+ * @retval None
+ */
+void FLASH_ClearFlag(uint32_t FLASH_FLAG)
+{
+ /* Check the parameters */
+ assert_param(IS_FLASH_CLEAR_FLAG(FLASH_FLAG));
+
+ /* Clear the flags */
+ FLASH->SR = FLASH_FLAG;
+}
+
+/**
+ * @brief Returns the FLASH Status.
+ * @param None
+ * @retval FLASH Status: The returned value can be: FLASH_BUSY, FLASH_ERROR_PROGRAM,
+ * FLASH_ERROR_WRP, FLASH_ERROR_OPERATION or FLASH_COMPLETE.
+ */
+FLASH_Status FLASH_GetStatus(void)
+{
+ FLASH_Status flashstatus = FLASH_COMPLETE;
+
+ if((FLASH->SR & FLASH_FLAG_BSY) == FLASH_FLAG_BSY)
+ {
+ flashstatus = FLASH_BUSY;
+ }
+ else
+ {
+ if((FLASH->SR & FLASH_FLAG_WRPERR) != (uint32_t)0x00)
+ {
+ flashstatus = FLASH_ERROR_WRP;
+ }
+ else
+ {
+ if((FLASH->SR & (uint32_t)0xEF) != (uint32_t)0x00)
+ {
+ flashstatus = FLASH_ERROR_PROGRAM;
+ }
+ else
+ {
+ if((FLASH->SR & FLASH_FLAG_OPERR) != (uint32_t)0x00)
+ {
+ flashstatus = FLASH_ERROR_OPERATION;
+ }
+ else
+ {
+ flashstatus = FLASH_COMPLETE;
+ }
+ }
+ }
+ }
+ /* Return the FLASH Status */
+ return flashstatus;
+}
+
+/**
+ * @brief Waits for a FLASH operation to complete.
+ * @param None
+ * @retval FLASH Status: The returned value can be: FLASH_BUSY, FLASH_ERROR_PROGRAM,
+ * FLASH_ERROR_WRP, FLASH_ERROR_OPERATION or FLASH_COMPLETE.
+ */
+FLASH_Status FLASH_WaitForLastOperation(void)
+{
+ __IO FLASH_Status status = FLASH_COMPLETE;
+
+ /* Check for the FLASH Status */
+ status = FLASH_GetStatus();
+
+ /* Wait for the FLASH operation to complete by polling on BUSY flag to be reset.
+ Even if the FLASH operation fails, the BUSY flag will be reset and an error
+ flag will be set */
+ while(status == FLASH_BUSY)
+ {
+ status = FLASH_GetStatus();
+ }
+ /* Return the operation status */
+ return status;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/src/stm32f2xx_fsmc.c b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/src/stm32f2xx_fsmc.c
new file mode 100644
index 0000000..3571882
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/src/stm32f2xx_fsmc.c
@@ -0,0 +1,987 @@
+/**
+ ******************************************************************************
+ * @file stm32f2xx_fsmc.c
+ * @author MCD Application Team
+ * @version V1.1.2
+ * @date 05-March-2012
+ * @brief This file provides firmware functions to manage the following
+ * functionalities of the FSMC peripheral:
+ * - Interface with SRAM, PSRAM, NOR and OneNAND memories
+ * - Interface with NAND memories
+ * - Interface with 16-bit PC Card compatible memories
+ * - Interrupts and flags management
+ *
+ ******************************************************************************
+ * @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 "stm32f2xx_fsmc.h"
+#include "stm32f2xx_rcc.h"
+
+/** @addtogroup STM32F2xx_StdPeriph_Driver
+ * @{
+ */
+
+/** @defgroup FSMC
+ * @brief FSMC driver modules
+ * @{
+ */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+
+/* --------------------- FSMC registers bit mask ---------------------------- */
+/* FSMC BCRx Mask */
+#define BCR_MBKEN_SET ((uint32_t)0x00000001)
+#define BCR_MBKEN_RESET ((uint32_t)0x000FFFFE)
+#define BCR_FACCEN_SET ((uint32_t)0x00000040)
+
+/* FSMC PCRx Mask */
+#define PCR_PBKEN_SET ((uint32_t)0x00000004)
+#define PCR_PBKEN_RESET ((uint32_t)0x000FFFFB)
+#define PCR_ECCEN_SET ((uint32_t)0x00000040)
+#define PCR_ECCEN_RESET ((uint32_t)0x000FFFBF)
+#define PCR_MEMORYTYPE_NAND ((uint32_t)0x00000008)
+
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+/** @defgroup FSMC_Private_Functions
+ * @{
+ */
+
+/** @defgroup FSMC_Group1 NOR/SRAM Controller functions
+ * @brief NOR/SRAM Controller functions
+ *
+@verbatim
+ ===============================================================================
+ NOR/SRAM Controller functions
+ ===============================================================================
+
+ The following sequence should be followed to configure the FSMC to interface with
+ SRAM, PSRAM, NOR or OneNAND memory connected to the NOR/SRAM Bank:
+
+ 1. Enable the clock for the FSMC and associated GPIOs using the following functions:
+ RCC_AHB3PeriphClockCmd(RCC_AHB3Periph_FSMC, ENABLE);
+ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOx, ENABLE);
+
+ 2. FSMC pins configuration
+ - Connect the involved FSMC pins to AF12 using the following function
+ GPIO_PinAFConfig(GPIOx, GPIO_PinSourcex, GPIO_AF_FSMC);
+ - Configure these FSMC pins in alternate function mode by calling the function
+ GPIO_Init();
+
+ 3. Declare a FSMC_NORSRAMInitTypeDef structure, for example:
+ FSMC_NORSRAMInitTypeDef FSMC_NORSRAMInitStructure;
+ and fill the FSMC_NORSRAMInitStructure variable with the allowed values of
+ the structure member.
+
+ 4. Initialize the NOR/SRAM Controller by calling the function
+ FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure);
+
+ 5. Then enable the NOR/SRAM Bank, for example:
+ FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM2, ENABLE);
+
+ 6. At this stage you can read/write from/to the memory connected to the NOR/SRAM Bank.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Deinitializes the FSMC NOR/SRAM Banks registers to their default
+ * reset values.
+ * @param FSMC_Bank: specifies the FSMC Bank to be used
+ * This parameter can be one of the following values:
+ * @arg FSMC_Bank1_NORSRAM1: FSMC Bank1 NOR/SRAM1
+ * @arg FSMC_Bank1_NORSRAM2: FSMC Bank1 NOR/SRAM2
+ * @arg FSMC_Bank1_NORSRAM3: FSMC Bank1 NOR/SRAM3
+ * @arg FSMC_Bank1_NORSRAM4: FSMC Bank1 NOR/SRAM4
+ * @retval None
+ */
+void FSMC_NORSRAMDeInit(uint32_t FSMC_Bank)
+{
+ /* Check the parameter */
+ assert_param(IS_FSMC_NORSRAM_BANK(FSMC_Bank));
+
+ /* FSMC_Bank1_NORSRAM1 */
+ if(FSMC_Bank == FSMC_Bank1_NORSRAM1)
+ {
+ FSMC_Bank1->BTCR[FSMC_Bank] = 0x000030DB;
+ }
+ /* FSMC_Bank1_NORSRAM2, FSMC_Bank1_NORSRAM3 or FSMC_Bank1_NORSRAM4 */
+ else
+ {
+ FSMC_Bank1->BTCR[FSMC_Bank] = 0x000030D2;
+ }
+ FSMC_Bank1->BTCR[FSMC_Bank + 1] = 0x0FFFFFFF;
+ FSMC_Bank1E->BWTR[FSMC_Bank] = 0x0FFFFFFF;
+}
+
+/**
+ * @brief Initializes the FSMC NOR/SRAM Banks according to the specified
+ * parameters in the FSMC_NORSRAMInitStruct.
+ * @param FSMC_NORSRAMInitStruct : pointer to a FSMC_NORSRAMInitTypeDef structure
+ * that contains the configuration information for the FSMC NOR/SRAM
+ * specified Banks.
+ * @retval None
+ */
+void FSMC_NORSRAMInit(FSMC_NORSRAMInitTypeDef* FSMC_NORSRAMInitStruct)
+{
+ /* Check the parameters */
+ assert_param(IS_FSMC_NORSRAM_BANK(FSMC_NORSRAMInitStruct->FSMC_Bank));
+ assert_param(IS_FSMC_MUX(FSMC_NORSRAMInitStruct->FSMC_DataAddressMux));
+ assert_param(IS_FSMC_MEMORY(FSMC_NORSRAMInitStruct->FSMC_MemoryType));
+ assert_param(IS_FSMC_MEMORY_WIDTH(FSMC_NORSRAMInitStruct->FSMC_MemoryDataWidth));
+ assert_param(IS_FSMC_BURSTMODE(FSMC_NORSRAMInitStruct->FSMC_BurstAccessMode));
+ assert_param(IS_FSMC_ASYNWAIT(FSMC_NORSRAMInitStruct->FSMC_AsynchronousWait));
+ assert_param(IS_FSMC_WAIT_POLARITY(FSMC_NORSRAMInitStruct->FSMC_WaitSignalPolarity));
+ assert_param(IS_FSMC_WRAP_MODE(FSMC_NORSRAMInitStruct->FSMC_WrapMode));
+ assert_param(IS_FSMC_WAIT_SIGNAL_ACTIVE(FSMC_NORSRAMInitStruct->FSMC_WaitSignalActive));
+ assert_param(IS_FSMC_WRITE_OPERATION(FSMC_NORSRAMInitStruct->FSMC_WriteOperation));
+ assert_param(IS_FSMC_WAITE_SIGNAL(FSMC_NORSRAMInitStruct->FSMC_WaitSignal));
+ assert_param(IS_FSMC_EXTENDED_MODE(FSMC_NORSRAMInitStruct->FSMC_ExtendedMode));
+ assert_param(IS_FSMC_WRITE_BURST(FSMC_NORSRAMInitStruct->FSMC_WriteBurst));
+ assert_param(IS_FSMC_ADDRESS_SETUP_TIME(FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_AddressSetupTime));
+ assert_param(IS_FSMC_ADDRESS_HOLD_TIME(FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_AddressHoldTime));
+ assert_param(IS_FSMC_DATASETUP_TIME(FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_DataSetupTime));
+ assert_param(IS_FSMC_TURNAROUND_TIME(FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_BusTurnAroundDuration));
+ assert_param(IS_FSMC_CLK_DIV(FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_CLKDivision));
+ assert_param(IS_FSMC_DATA_LATENCY(FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_DataLatency));
+ assert_param(IS_FSMC_ACCESS_MODE(FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_AccessMode));
+
+ /* Bank1 NOR/SRAM control register configuration */
+ FSMC_Bank1->BTCR[FSMC_NORSRAMInitStruct->FSMC_Bank] =
+ (uint32_t)FSMC_NORSRAMInitStruct->FSMC_DataAddressMux |
+ FSMC_NORSRAMInitStruct->FSMC_MemoryType |
+ FSMC_NORSRAMInitStruct->FSMC_MemoryDataWidth |
+ FSMC_NORSRAMInitStruct->FSMC_BurstAccessMode |
+ FSMC_NORSRAMInitStruct->FSMC_AsynchronousWait |
+ FSMC_NORSRAMInitStruct->FSMC_WaitSignalPolarity |
+ FSMC_NORSRAMInitStruct->FSMC_WrapMode |
+ FSMC_NORSRAMInitStruct->FSMC_WaitSignalActive |
+ FSMC_NORSRAMInitStruct->FSMC_WriteOperation |
+ FSMC_NORSRAMInitStruct->FSMC_WaitSignal |
+ FSMC_NORSRAMInitStruct->FSMC_ExtendedMode |
+ FSMC_NORSRAMInitStruct->FSMC_WriteBurst;
+ if(FSMC_NORSRAMInitStruct->FSMC_MemoryType == FSMC_MemoryType_NOR)
+ {
+ FSMC_Bank1->BTCR[FSMC_NORSRAMInitStruct->FSMC_Bank] |= (uint32_t)BCR_FACCEN_SET;
+ }
+ /* Bank1 NOR/SRAM timing register configuration */
+ FSMC_Bank1->BTCR[FSMC_NORSRAMInitStruct->FSMC_Bank+1] =
+ (uint32_t)FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_AddressSetupTime |
+ (FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_AddressHoldTime << 4) |
+ (FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_DataSetupTime << 8) |
+ (FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_BusTurnAroundDuration << 16) |
+ (FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_CLKDivision << 20) |
+ (FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_DataLatency << 24) |
+ FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_AccessMode;
+
+
+ /* Bank1 NOR/SRAM timing register for write configuration, if extended mode is used */
+ if(FSMC_NORSRAMInitStruct->FSMC_ExtendedMode == FSMC_ExtendedMode_Enable)
+ {
+ assert_param(IS_FSMC_ADDRESS_SETUP_TIME(FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_AddressSetupTime));
+ assert_param(IS_FSMC_ADDRESS_HOLD_TIME(FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_AddressHoldTime));
+ assert_param(IS_FSMC_DATASETUP_TIME(FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_DataSetupTime));
+ assert_param(IS_FSMC_CLK_DIV(FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_CLKDivision));
+ assert_param(IS_FSMC_DATA_LATENCY(FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_DataLatency));
+ assert_param(IS_FSMC_ACCESS_MODE(FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_AccessMode));
+ FSMC_Bank1E->BWTR[FSMC_NORSRAMInitStruct->FSMC_Bank] =
+ (uint32_t)FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_AddressSetupTime |
+ (FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_AddressHoldTime << 4 )|
+ (FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_DataSetupTime << 8) |
+ (FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_CLKDivision << 20) |
+ (FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_DataLatency << 24) |
+ FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_AccessMode;
+ }
+ else
+ {
+ FSMC_Bank1E->BWTR[FSMC_NORSRAMInitStruct->FSMC_Bank] = 0x0FFFFFFF;
+ }
+}
+
+/**
+ * @brief Fills each FSMC_NORSRAMInitStruct member with its default value.
+ * @param FSMC_NORSRAMInitStruct: pointer to a FSMC_NORSRAMInitTypeDef structure
+ * which will be initialized.
+ * @retval None
+ */
+void FSMC_NORSRAMStructInit(FSMC_NORSRAMInitTypeDef* FSMC_NORSRAMInitStruct)
+{
+ /* Reset NOR/SRAM Init structure parameters values */
+ FSMC_NORSRAMInitStruct->FSMC_Bank = FSMC_Bank1_NORSRAM1;
+ FSMC_NORSRAMInitStruct->FSMC_DataAddressMux = FSMC_DataAddressMux_Enable;
+ FSMC_NORSRAMInitStruct->FSMC_MemoryType = FSMC_MemoryType_SRAM;
+ FSMC_NORSRAMInitStruct->FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_8b;
+ FSMC_NORSRAMInitStruct->FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable;
+ FSMC_NORSRAMInitStruct->FSMC_AsynchronousWait = FSMC_AsynchronousWait_Disable;
+ FSMC_NORSRAMInitStruct->FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;
+ FSMC_NORSRAMInitStruct->FSMC_WrapMode = FSMC_WrapMode_Disable;
+ FSMC_NORSRAMInitStruct->FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState;
+ FSMC_NORSRAMInitStruct->FSMC_WriteOperation = FSMC_WriteOperation_Enable;
+ FSMC_NORSRAMInitStruct->FSMC_WaitSignal = FSMC_WaitSignal_Enable;
+ FSMC_NORSRAMInitStruct->FSMC_ExtendedMode = FSMC_ExtendedMode_Disable;
+ FSMC_NORSRAMInitStruct->FSMC_WriteBurst = FSMC_WriteBurst_Disable;
+ FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_AddressSetupTime = 0xF;
+ FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_AddressHoldTime = 0xF;
+ FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_DataSetupTime = 0xFF;
+ FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_BusTurnAroundDuration = 0xF;
+ FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_CLKDivision = 0xF;
+ FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_DataLatency = 0xF;
+ FSMC_NORSRAMInitStruct->FSMC_ReadWriteTimingStruct->FSMC_AccessMode = FSMC_AccessMode_A;
+ FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_AddressSetupTime = 0xF;
+ FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_AddressHoldTime = 0xF;
+ FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_DataSetupTime = 0xFF;
+ FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_BusTurnAroundDuration = 0xF;
+ FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_CLKDivision = 0xF;
+ FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_DataLatency = 0xF;
+ FSMC_NORSRAMInitStruct->FSMC_WriteTimingStruct->FSMC_AccessMode = FSMC_AccessMode_A;
+}
+
+/**
+ * @brief Enables or disables the specified NOR/SRAM Memory Bank.
+ * @param FSMC_Bank: specifies the FSMC Bank to be used
+ * This parameter can be one of the following values:
+ * @arg FSMC_Bank1_NORSRAM1: FSMC Bank1 NOR/SRAM1
+ * @arg FSMC_Bank1_NORSRAM2: FSMC Bank1 NOR/SRAM2
+ * @arg FSMC_Bank1_NORSRAM3: FSMC Bank1 NOR/SRAM3
+ * @arg FSMC_Bank1_NORSRAM4: FSMC Bank1 NOR/SRAM4
+ * @param NewState: new state of the FSMC_Bank. This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void FSMC_NORSRAMCmd(uint32_t FSMC_Bank, FunctionalState NewState)
+{
+ assert_param(IS_FSMC_NORSRAM_BANK(FSMC_Bank));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the selected NOR/SRAM Bank by setting the PBKEN bit in the BCRx register */
+ FSMC_Bank1->BTCR[FSMC_Bank] |= BCR_MBKEN_SET;
+ }
+ else
+ {
+ /* Disable the selected NOR/SRAM Bank by clearing the PBKEN bit in the BCRx register */
+ FSMC_Bank1->BTCR[FSMC_Bank] &= BCR_MBKEN_RESET;
+ }
+}
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Group2 NAND Controller functions
+ * @brief NAND Controller functions
+ *
+@verbatim
+ ===============================================================================
+ NAND Controller functions
+ ===============================================================================
+
+ The following sequence should be followed to configure the FSMC to interface with
+ 8-bit or 16-bit NAND memory connected to the NAND Bank:
+
+ 1. Enable the clock for the FSMC and associated GPIOs using the following functions:
+ RCC_AHB3PeriphClockCmd(RCC_AHB3Periph_FSMC, ENABLE);
+ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOx, ENABLE);
+
+ 2. FSMC pins configuration
+ - Connect the involved FSMC pins to AF12 using the following function
+ GPIO_PinAFConfig(GPIOx, GPIO_PinSourcex, GPIO_AF_FSMC);
+ - Configure these FSMC pins in alternate function mode by calling the function
+ GPIO_Init();
+
+ 3. Declare a FSMC_NANDInitTypeDef structure, for example:
+ FSMC_NANDInitTypeDef FSMC_NANDInitStructure;
+ and fill the FSMC_NANDInitStructure variable with the allowed values of
+ the structure member.
+
+ 4. Initialize the NAND Controller by calling the function
+ FSMC_NANDInit(&FSMC_NANDInitStructure);
+
+ 5. Then enable the NAND Bank, for example:
+ FSMC_NANDCmd(FSMC_Bank3_NAND, ENABLE);
+
+ 6. At this stage you can read/write from/to the memory connected to the NAND Bank.
+
+@note To enable the Error Correction Code (ECC), you have to use the function
+ FSMC_NANDECCCmd(FSMC_Bank3_NAND, ENABLE);
+ and to get the current ECC value you have to use the function
+ ECCval = FSMC_GetECC(FSMC_Bank3_NAND);
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Deinitializes the FSMC NAND Banks registers to their default reset values.
+ * @param FSMC_Bank: specifies the FSMC Bank to be used
+ * This parameter can be one of the following values:
+ * @arg FSMC_Bank2_NAND: FSMC Bank2 NAND
+ * @arg FSMC_Bank3_NAND: FSMC Bank3 NAND
+ * @retval None
+ */
+void FSMC_NANDDeInit(uint32_t FSMC_Bank)
+{
+ /* Check the parameter */
+ assert_param(IS_FSMC_NAND_BANK(FSMC_Bank));
+
+ if(FSMC_Bank == FSMC_Bank2_NAND)
+ {
+ /* Set the FSMC_Bank2 registers to their reset values */
+ FSMC_Bank2->PCR2 = 0x00000018;
+ FSMC_Bank2->SR2 = 0x00000040;
+ FSMC_Bank2->PMEM2 = 0xFCFCFCFC;
+ FSMC_Bank2->PATT2 = 0xFCFCFCFC;
+ }
+ /* FSMC_Bank3_NAND */
+ else
+ {
+ /* Set the FSMC_Bank3 registers to their reset values */
+ FSMC_Bank3->PCR3 = 0x00000018;
+ FSMC_Bank3->SR3 = 0x00000040;
+ FSMC_Bank3->PMEM3 = 0xFCFCFCFC;
+ FSMC_Bank3->PATT3 = 0xFCFCFCFC;
+ }
+}
+
+/**
+ * @brief Initializes the FSMC NAND Banks according to the specified parameters
+ * in the FSMC_NANDInitStruct.
+ * @param FSMC_NANDInitStruct : pointer to a FSMC_NANDInitTypeDef structure that
+ * contains the configuration information for the FSMC NAND specified Banks.
+ * @retval None
+ */
+void FSMC_NANDInit(FSMC_NANDInitTypeDef* FSMC_NANDInitStruct)
+{
+ uint32_t tmppcr = 0x00000000, tmppmem = 0x00000000, tmppatt = 0x00000000;
+
+ /* Check the parameters */
+ assert_param( IS_FSMC_NAND_BANK(FSMC_NANDInitStruct->FSMC_Bank));
+ assert_param( IS_FSMC_WAIT_FEATURE(FSMC_NANDInitStruct->FSMC_Waitfeature));
+ assert_param( IS_FSMC_MEMORY_WIDTH(FSMC_NANDInitStruct->FSMC_MemoryDataWidth));
+ assert_param( IS_FSMC_ECC_STATE(FSMC_NANDInitStruct->FSMC_ECC));
+ assert_param( IS_FSMC_ECCPAGE_SIZE(FSMC_NANDInitStruct->FSMC_ECCPageSize));
+ assert_param( IS_FSMC_TCLR_TIME(FSMC_NANDInitStruct->FSMC_TCLRSetupTime));
+ assert_param( IS_FSMC_TAR_TIME(FSMC_NANDInitStruct->FSMC_TARSetupTime));
+ assert_param(IS_FSMC_SETUP_TIME(FSMC_NANDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_SetupTime));
+ assert_param(IS_FSMC_WAIT_TIME(FSMC_NANDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_WaitSetupTime));
+ assert_param(IS_FSMC_HOLD_TIME(FSMC_NANDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_HoldSetupTime));
+ assert_param(IS_FSMC_HIZ_TIME(FSMC_NANDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_HiZSetupTime));
+ assert_param(IS_FSMC_SETUP_TIME(FSMC_NANDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_SetupTime));
+ assert_param(IS_FSMC_WAIT_TIME(FSMC_NANDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_WaitSetupTime));
+ assert_param(IS_FSMC_HOLD_TIME(FSMC_NANDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_HoldSetupTime));
+ assert_param(IS_FSMC_HIZ_TIME(FSMC_NANDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_HiZSetupTime));
+
+ /* Set the tmppcr value according to FSMC_NANDInitStruct parameters */
+ tmppcr = (uint32_t)FSMC_NANDInitStruct->FSMC_Waitfeature |
+ PCR_MEMORYTYPE_NAND |
+ FSMC_NANDInitStruct->FSMC_MemoryDataWidth |
+ FSMC_NANDInitStruct->FSMC_ECC |
+ FSMC_NANDInitStruct->FSMC_ECCPageSize |
+ (FSMC_NANDInitStruct->FSMC_TCLRSetupTime << 9 )|
+ (FSMC_NANDInitStruct->FSMC_TARSetupTime << 13);
+
+ /* Set tmppmem value according to FSMC_CommonSpaceTimingStructure parameters */
+ tmppmem = (uint32_t)FSMC_NANDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_SetupTime |
+ (FSMC_NANDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_WaitSetupTime << 8) |
+ (FSMC_NANDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_HoldSetupTime << 16)|
+ (FSMC_NANDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_HiZSetupTime << 24);
+
+ /* Set tmppatt value according to FSMC_AttributeSpaceTimingStructure parameters */
+ tmppatt = (uint32_t)FSMC_NANDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_SetupTime |
+ (FSMC_NANDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_WaitSetupTime << 8) |
+ (FSMC_NANDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_HoldSetupTime << 16)|
+ (FSMC_NANDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_HiZSetupTime << 24);
+
+ if(FSMC_NANDInitStruct->FSMC_Bank == FSMC_Bank2_NAND)
+ {
+ /* FSMC_Bank2_NAND registers configuration */
+ FSMC_Bank2->PCR2 = tmppcr;
+ FSMC_Bank2->PMEM2 = tmppmem;
+ FSMC_Bank2->PATT2 = tmppatt;
+ }
+ else
+ {
+ /* FSMC_Bank3_NAND registers configuration */
+ FSMC_Bank3->PCR3 = tmppcr;
+ FSMC_Bank3->PMEM3 = tmppmem;
+ FSMC_Bank3->PATT3 = tmppatt;
+ }
+}
+
+
+/**
+ * @brief Fills each FSMC_NANDInitStruct member with its default value.
+ * @param FSMC_NANDInitStruct: pointer to a FSMC_NANDInitTypeDef structure which
+ * will be initialized.
+ * @retval None
+ */
+void FSMC_NANDStructInit(FSMC_NANDInitTypeDef* FSMC_NANDInitStruct)
+{
+ /* Reset NAND Init structure parameters values */
+ FSMC_NANDInitStruct->FSMC_Bank = FSMC_Bank2_NAND;
+ FSMC_NANDInitStruct->FSMC_Waitfeature = FSMC_Waitfeature_Disable;
+ FSMC_NANDInitStruct->FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_8b;
+ FSMC_NANDInitStruct->FSMC_ECC = FSMC_ECC_Disable;
+ FSMC_NANDInitStruct->FSMC_ECCPageSize = FSMC_ECCPageSize_256Bytes;
+ FSMC_NANDInitStruct->FSMC_TCLRSetupTime = 0x0;
+ FSMC_NANDInitStruct->FSMC_TARSetupTime = 0x0;
+ FSMC_NANDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_SetupTime = 0xFC;
+ FSMC_NANDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_WaitSetupTime = 0xFC;
+ FSMC_NANDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_HoldSetupTime = 0xFC;
+ FSMC_NANDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_HiZSetupTime = 0xFC;
+ FSMC_NANDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_SetupTime = 0xFC;
+ FSMC_NANDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_WaitSetupTime = 0xFC;
+ FSMC_NANDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_HoldSetupTime = 0xFC;
+ FSMC_NANDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_HiZSetupTime = 0xFC;
+}
+
+/**
+ * @brief Enables or disables the specified NAND Memory Bank.
+ * @param FSMC_Bank: specifies the FSMC Bank to be used
+ * This parameter can be one of the following values:
+ * @arg FSMC_Bank2_NAND: FSMC Bank2 NAND
+ * @arg FSMC_Bank3_NAND: FSMC Bank3 NAND
+ * @param NewState: new state of the FSMC_Bank. This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void FSMC_NANDCmd(uint32_t FSMC_Bank, FunctionalState NewState)
+{
+ assert_param(IS_FSMC_NAND_BANK(FSMC_Bank));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the selected NAND Bank by setting the PBKEN bit in the PCRx register */
+ if(FSMC_Bank == FSMC_Bank2_NAND)
+ {
+ FSMC_Bank2->PCR2 |= PCR_PBKEN_SET;
+ }
+ else
+ {
+ FSMC_Bank3->PCR3 |= PCR_PBKEN_SET;
+ }
+ }
+ else
+ {
+ /* Disable the selected NAND Bank by clearing the PBKEN bit in the PCRx register */
+ if(FSMC_Bank == FSMC_Bank2_NAND)
+ {
+ FSMC_Bank2->PCR2 &= PCR_PBKEN_RESET;
+ }
+ else
+ {
+ FSMC_Bank3->PCR3 &= PCR_PBKEN_RESET;
+ }
+ }
+}
+/**
+ * @brief Enables or disables the FSMC NAND ECC feature.
+ * @param FSMC_Bank: specifies the FSMC Bank to be used
+ * This parameter can be one of the following values:
+ * @arg FSMC_Bank2_NAND: FSMC Bank2 NAND
+ * @arg FSMC_Bank3_NAND: FSMC Bank3 NAND
+ * @param NewState: new state of the FSMC NAND ECC feature.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void FSMC_NANDECCCmd(uint32_t FSMC_Bank, FunctionalState NewState)
+{
+ assert_param(IS_FSMC_NAND_BANK(FSMC_Bank));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the selected NAND Bank ECC function by setting the ECCEN bit in the PCRx register */
+ if(FSMC_Bank == FSMC_Bank2_NAND)
+ {
+ FSMC_Bank2->PCR2 |= PCR_ECCEN_SET;
+ }
+ else
+ {
+ FSMC_Bank3->PCR3 |= PCR_ECCEN_SET;
+ }
+ }
+ else
+ {
+ /* Disable the selected NAND Bank ECC function by clearing the ECCEN bit in the PCRx register */
+ if(FSMC_Bank == FSMC_Bank2_NAND)
+ {
+ FSMC_Bank2->PCR2 &= PCR_ECCEN_RESET;
+ }
+ else
+ {
+ FSMC_Bank3->PCR3 &= PCR_ECCEN_RESET;
+ }
+ }
+}
+
+/**
+ * @brief Returns the error correction code register value.
+ * @param FSMC_Bank: specifies the FSMC Bank to be used
+ * This parameter can be one of the following values:
+ * @arg FSMC_Bank2_NAND: FSMC Bank2 NAND
+ * @arg FSMC_Bank3_NAND: FSMC Bank3 NAND
+ * @retval The Error Correction Code (ECC) value.
+ */
+uint32_t FSMC_GetECC(uint32_t FSMC_Bank)
+{
+ uint32_t eccval = 0x00000000;
+
+ if(FSMC_Bank == FSMC_Bank2_NAND)
+ {
+ /* Get the ECCR2 register value */
+ eccval = FSMC_Bank2->ECCR2;
+ }
+ else
+ {
+ /* Get the ECCR3 register value */
+ eccval = FSMC_Bank3->ECCR3;
+ }
+ /* Return the error correction code value */
+ return(eccval);
+}
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Group3 PCCARD Controller functions
+ * @brief PCCARD Controller functions
+ *
+@verbatim
+ ===============================================================================
+ PCCARD Controller functions
+ ===============================================================================
+
+ The following sequence should be followed to configure the FSMC to interface with
+ 16-bit PC Card compatible memory connected to the PCCARD Bank:
+
+ 1. Enable the clock for the FSMC and associated GPIOs using the following functions:
+ RCC_AHB3PeriphClockCmd(RCC_AHB3Periph_FSMC, ENABLE);
+ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOx, ENABLE);
+
+ 2. FSMC pins configuration
+ - Connect the involved FSMC pins to AF12 using the following function
+ GPIO_PinAFConfig(GPIOx, GPIO_PinSourcex, GPIO_AF_FSMC);
+ - Configure these FSMC pins in alternate function mode by calling the function
+ GPIO_Init();
+
+ 3. Declare a FSMC_PCCARDInitTypeDef structure, for example:
+ FSMC_PCCARDInitTypeDef FSMC_PCCARDInitStructure;
+ and fill the FSMC_PCCARDInitStructure variable with the allowed values of
+ the structure member.
+
+ 4. Initialize the PCCARD Controller by calling the function
+ FSMC_PCCARDInit(&FSMC_PCCARDInitStructure);
+
+ 5. Then enable the PCCARD Bank:
+ FSMC_PCCARDCmd(ENABLE);
+
+ 6. At this stage you can read/write from/to the memory connected to the PCCARD Bank.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Deinitializes the FSMC PCCARD Bank registers to their default reset values.
+ * @param None
+ * @retval None
+ */
+void FSMC_PCCARDDeInit(void)
+{
+ /* Set the FSMC_Bank4 registers to their reset values */
+ FSMC_Bank4->PCR4 = 0x00000018;
+ FSMC_Bank4->SR4 = 0x00000000;
+ FSMC_Bank4->PMEM4 = 0xFCFCFCFC;
+ FSMC_Bank4->PATT4 = 0xFCFCFCFC;
+ FSMC_Bank4->PIO4 = 0xFCFCFCFC;
+}
+
+/**
+ * @brief Initializes the FSMC PCCARD Bank according to the specified parameters
+ * in the FSMC_PCCARDInitStruct.
+ * @param FSMC_PCCARDInitStruct : pointer to a FSMC_PCCARDInitTypeDef structure
+ * that contains the configuration information for the FSMC PCCARD Bank.
+ * @retval None
+ */
+void FSMC_PCCARDInit(FSMC_PCCARDInitTypeDef* FSMC_PCCARDInitStruct)
+{
+ /* Check the parameters */
+ assert_param(IS_FSMC_WAIT_FEATURE(FSMC_PCCARDInitStruct->FSMC_Waitfeature));
+ assert_param(IS_FSMC_TCLR_TIME(FSMC_PCCARDInitStruct->FSMC_TCLRSetupTime));
+ assert_param(IS_FSMC_TAR_TIME(FSMC_PCCARDInitStruct->FSMC_TARSetupTime));
+
+ assert_param(IS_FSMC_SETUP_TIME(FSMC_PCCARDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_SetupTime));
+ assert_param(IS_FSMC_WAIT_TIME(FSMC_PCCARDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_WaitSetupTime));
+ assert_param(IS_FSMC_HOLD_TIME(FSMC_PCCARDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_HoldSetupTime));
+ assert_param(IS_FSMC_HIZ_TIME(FSMC_PCCARDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_HiZSetupTime));
+
+ assert_param(IS_FSMC_SETUP_TIME(FSMC_PCCARDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_SetupTime));
+ assert_param(IS_FSMC_WAIT_TIME(FSMC_PCCARDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_WaitSetupTime));
+ assert_param(IS_FSMC_HOLD_TIME(FSMC_PCCARDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_HoldSetupTime));
+ assert_param(IS_FSMC_HIZ_TIME(FSMC_PCCARDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_HiZSetupTime));
+ assert_param(IS_FSMC_SETUP_TIME(FSMC_PCCARDInitStruct->FSMC_IOSpaceTimingStruct->FSMC_SetupTime));
+ assert_param(IS_FSMC_WAIT_TIME(FSMC_PCCARDInitStruct->FSMC_IOSpaceTimingStruct->FSMC_WaitSetupTime));
+ assert_param(IS_FSMC_HOLD_TIME(FSMC_PCCARDInitStruct->FSMC_IOSpaceTimingStruct->FSMC_HoldSetupTime));
+ assert_param(IS_FSMC_HIZ_TIME(FSMC_PCCARDInitStruct->FSMC_IOSpaceTimingStruct->FSMC_HiZSetupTime));
+
+ /* Set the PCR4 register value according to FSMC_PCCARDInitStruct parameters */
+ FSMC_Bank4->PCR4 = (uint32_t)FSMC_PCCARDInitStruct->FSMC_Waitfeature |
+ FSMC_MemoryDataWidth_16b |
+ (FSMC_PCCARDInitStruct->FSMC_TCLRSetupTime << 9) |
+ (FSMC_PCCARDInitStruct->FSMC_TARSetupTime << 13);
+
+ /* Set PMEM4 register value according to FSMC_CommonSpaceTimingStructure parameters */
+ FSMC_Bank4->PMEM4 = (uint32_t)FSMC_PCCARDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_SetupTime |
+ (FSMC_PCCARDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_WaitSetupTime << 8) |
+ (FSMC_PCCARDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_HoldSetupTime << 16)|
+ (FSMC_PCCARDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_HiZSetupTime << 24);
+
+ /* Set PATT4 register value according to FSMC_AttributeSpaceTimingStructure parameters */
+ FSMC_Bank4->PATT4 = (uint32_t)FSMC_PCCARDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_SetupTime |
+ (FSMC_PCCARDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_WaitSetupTime << 8) |
+ (FSMC_PCCARDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_HoldSetupTime << 16)|
+ (FSMC_PCCARDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_HiZSetupTime << 24);
+
+ /* Set PIO4 register value according to FSMC_IOSpaceTimingStructure parameters */
+ FSMC_Bank4->PIO4 = (uint32_t)FSMC_PCCARDInitStruct->FSMC_IOSpaceTimingStruct->FSMC_SetupTime |
+ (FSMC_PCCARDInitStruct->FSMC_IOSpaceTimingStruct->FSMC_WaitSetupTime << 8) |
+ (FSMC_PCCARDInitStruct->FSMC_IOSpaceTimingStruct->FSMC_HoldSetupTime << 16)|
+ (FSMC_PCCARDInitStruct->FSMC_IOSpaceTimingStruct->FSMC_HiZSetupTime << 24);
+}
+
+/**
+ * @brief Fills each FSMC_PCCARDInitStruct member with its default value.
+ * @param FSMC_PCCARDInitStruct: pointer to a FSMC_PCCARDInitTypeDef structure
+ * which will be initialized.
+ * @retval None
+ */
+void FSMC_PCCARDStructInit(FSMC_PCCARDInitTypeDef* FSMC_PCCARDInitStruct)
+{
+ /* Reset PCCARD Init structure parameters values */
+ FSMC_PCCARDInitStruct->FSMC_Waitfeature = FSMC_Waitfeature_Disable;
+ FSMC_PCCARDInitStruct->FSMC_TCLRSetupTime = 0x0;
+ FSMC_PCCARDInitStruct->FSMC_TARSetupTime = 0x0;
+ FSMC_PCCARDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_SetupTime = 0xFC;
+ FSMC_PCCARDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_WaitSetupTime = 0xFC;
+ FSMC_PCCARDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_HoldSetupTime = 0xFC;
+ FSMC_PCCARDInitStruct->FSMC_CommonSpaceTimingStruct->FSMC_HiZSetupTime = 0xFC;
+ FSMC_PCCARDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_SetupTime = 0xFC;
+ FSMC_PCCARDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_WaitSetupTime = 0xFC;
+ FSMC_PCCARDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_HoldSetupTime = 0xFC;
+ FSMC_PCCARDInitStruct->FSMC_AttributeSpaceTimingStruct->FSMC_HiZSetupTime = 0xFC;
+ FSMC_PCCARDInitStruct->FSMC_IOSpaceTimingStruct->FSMC_SetupTime = 0xFC;
+ FSMC_PCCARDInitStruct->FSMC_IOSpaceTimingStruct->FSMC_WaitSetupTime = 0xFC;
+ FSMC_PCCARDInitStruct->FSMC_IOSpaceTimingStruct->FSMC_HoldSetupTime = 0xFC;
+ FSMC_PCCARDInitStruct->FSMC_IOSpaceTimingStruct->FSMC_HiZSetupTime = 0xFC;
+}
+
+/**
+ * @brief Enables or disables the PCCARD Memory Bank.
+ * @param NewState: new state of the PCCARD Memory Bank.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void FSMC_PCCARDCmd(FunctionalState NewState)
+{
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the PCCARD Bank by setting the PBKEN bit in the PCR4 register */
+ FSMC_Bank4->PCR4 |= PCR_PBKEN_SET;
+ }
+ else
+ {
+ /* Disable the PCCARD Bank by clearing the PBKEN bit in the PCR4 register */
+ FSMC_Bank4->PCR4 &= PCR_PBKEN_RESET;
+ }
+}
+/**
+ * @}
+ */
+
+/** @defgroup FSMC_Group4 Interrupts and flags management functions
+ * @brief Interrupts and flags management functions
+ *
+@verbatim
+ ===============================================================================
+ Interrupts and flags management functions
+ ===============================================================================
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Enables or disables the specified FSMC interrupts.
+ * @param FSMC_Bank: specifies the FSMC Bank to be used
+ * This parameter can be one of the following values:
+ * @arg FSMC_Bank2_NAND: FSMC Bank2 NAND
+ * @arg FSMC_Bank3_NAND: FSMC Bank3 NAND
+ * @arg FSMC_Bank4_PCCARD: FSMC Bank4 PCCARD
+ * @param FSMC_IT: specifies the FSMC interrupt sources to be enabled or disabled.
+ * This parameter can be any combination of the following values:
+ * @arg FSMC_IT_RisingEdge: Rising edge detection interrupt.
+ * @arg FSMC_IT_Level: Level edge detection interrupt.
+ * @arg FSMC_IT_FallingEdge: Falling edge detection interrupt.
+ * @param NewState: new state of the specified FSMC interrupts.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void FSMC_ITConfig(uint32_t FSMC_Bank, uint32_t FSMC_IT, FunctionalState NewState)
+{
+ assert_param(IS_FSMC_IT_BANK(FSMC_Bank));
+ assert_param(IS_FSMC_IT(FSMC_IT));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the selected FSMC_Bank2 interrupts */
+ if(FSMC_Bank == FSMC_Bank2_NAND)
+ {
+ FSMC_Bank2->SR2 |= FSMC_IT;
+ }
+ /* Enable the selected FSMC_Bank3 interrupts */
+ else if (FSMC_Bank == FSMC_Bank3_NAND)
+ {
+ FSMC_Bank3->SR3 |= FSMC_IT;
+ }
+ /* Enable the selected FSMC_Bank4 interrupts */
+ else
+ {
+ FSMC_Bank4->SR4 |= FSMC_IT;
+ }
+ }
+ else
+ {
+ /* Disable the selected FSMC_Bank2 interrupts */
+ if(FSMC_Bank == FSMC_Bank2_NAND)
+ {
+
+ FSMC_Bank2->SR2 &= (uint32_t)~FSMC_IT;
+ }
+ /* Disable the selected FSMC_Bank3 interrupts */
+ else if (FSMC_Bank == FSMC_Bank3_NAND)
+ {
+ FSMC_Bank3->SR3 &= (uint32_t)~FSMC_IT;
+ }
+ /* Disable the selected FSMC_Bank4 interrupts */
+ else
+ {
+ FSMC_Bank4->SR4 &= (uint32_t)~FSMC_IT;
+ }
+ }
+}
+
+/**
+ * @brief Checks whether the specified FSMC flag is set or not.
+ * @param FSMC_Bank: specifies the FSMC Bank to be used
+ * This parameter can be one of the following values:
+ * @arg FSMC_Bank2_NAND: FSMC Bank2 NAND
+ * @arg FSMC_Bank3_NAND: FSMC Bank3 NAND
+ * @arg FSMC_Bank4_PCCARD: FSMC Bank4 PCCARD
+ * @param FSMC_FLAG: specifies the flag to check.
+ * This parameter can be one of the following values:
+ * @arg FSMC_FLAG_RisingEdge: Rising edge detection Flag.
+ * @arg FSMC_FLAG_Level: Level detection Flag.
+ * @arg FSMC_FLAG_FallingEdge: Falling edge detection Flag.
+ * @arg FSMC_FLAG_FEMPT: Fifo empty Flag.
+ * @retval The new state of FSMC_FLAG (SET or RESET).
+ */
+FlagStatus FSMC_GetFlagStatus(uint32_t FSMC_Bank, uint32_t FSMC_FLAG)
+{
+ FlagStatus bitstatus = RESET;
+ uint32_t tmpsr = 0x00000000;
+
+ /* Check the parameters */
+ assert_param(IS_FSMC_GETFLAG_BANK(FSMC_Bank));
+ assert_param(IS_FSMC_GET_FLAG(FSMC_FLAG));
+
+ if(FSMC_Bank == FSMC_Bank2_NAND)
+ {
+ tmpsr = FSMC_Bank2->SR2;
+ }
+ else if(FSMC_Bank == FSMC_Bank3_NAND)
+ {
+ tmpsr = FSMC_Bank3->SR3;
+ }
+ /* FSMC_Bank4_PCCARD*/
+ else
+ {
+ tmpsr = FSMC_Bank4->SR4;
+ }
+
+ /* Get the flag status */
+ if ((tmpsr & FSMC_FLAG) != (uint16_t)RESET )
+ {
+ bitstatus = SET;
+ }
+ else
+ {
+ bitstatus = RESET;
+ }
+ /* Return the flag status */
+ return bitstatus;
+}
+
+/**
+ * @brief Clears the FSMC's pending flags.
+ * @param FSMC_Bank: specifies the FSMC Bank to be used
+ * This parameter can be one of the following values:
+ * @arg FSMC_Bank2_NAND: FSMC Bank2 NAND
+ * @arg FSMC_Bank3_NAND: FSMC Bank3 NAND
+ * @arg FSMC_Bank4_PCCARD: FSMC Bank4 PCCARD
+ * @param FSMC_FLAG: specifies the flag to clear.
+ * This parameter can be any combination of the following values:
+ * @arg FSMC_FLAG_RisingEdge: Rising edge detection Flag.
+ * @arg FSMC_FLAG_Level: Level detection Flag.
+ * @arg FSMC_FLAG_FallingEdge: Falling edge detection Flag.
+ * @retval None
+ */
+void FSMC_ClearFlag(uint32_t FSMC_Bank, uint32_t FSMC_FLAG)
+{
+ /* Check the parameters */
+ assert_param(IS_FSMC_GETFLAG_BANK(FSMC_Bank));
+ assert_param(IS_FSMC_CLEAR_FLAG(FSMC_FLAG)) ;
+
+ if(FSMC_Bank == FSMC_Bank2_NAND)
+ {
+ FSMC_Bank2->SR2 &= ~FSMC_FLAG;
+ }
+ else if(FSMC_Bank == FSMC_Bank3_NAND)
+ {
+ FSMC_Bank3->SR3 &= ~FSMC_FLAG;
+ }
+ /* FSMC_Bank4_PCCARD*/
+ else
+ {
+ FSMC_Bank4->SR4 &= ~FSMC_FLAG;
+ }
+}
+
+/**
+ * @brief Checks whether the specified FSMC interrupt has occurred or not.
+ * @param FSMC_Bank: specifies the FSMC Bank to be used
+ * This parameter can be one of the following values:
+ * @arg FSMC_Bank2_NAND: FSMC Bank2 NAND
+ * @arg FSMC_Bank3_NAND: FSMC Bank3 NAND
+ * @arg FSMC_Bank4_PCCARD: FSMC Bank4 PCCARD
+ * @param FSMC_IT: specifies the FSMC interrupt source to check.
+ * This parameter can be one of the following values:
+ * @arg FSMC_IT_RisingEdge: Rising edge detection interrupt.
+ * @arg FSMC_IT_Level: Level edge detection interrupt.
+ * @arg FSMC_IT_FallingEdge: Falling edge detection interrupt.
+ * @retval The new state of FSMC_IT (SET or RESET).
+ */
+ITStatus FSMC_GetITStatus(uint32_t FSMC_Bank, uint32_t FSMC_IT)
+{
+ ITStatus bitstatus = RESET;
+ uint32_t tmpsr = 0x0, itstatus = 0x0, itenable = 0x0;
+
+ /* Check the parameters */
+ assert_param(IS_FSMC_IT_BANK(FSMC_Bank));
+ assert_param(IS_FSMC_GET_IT(FSMC_IT));
+
+ if(FSMC_Bank == FSMC_Bank2_NAND)
+ {
+ tmpsr = FSMC_Bank2->SR2;
+ }
+ else if(FSMC_Bank == FSMC_Bank3_NAND)
+ {
+ tmpsr = FSMC_Bank3->SR3;
+ }
+ /* FSMC_Bank4_PCCARD*/
+ else
+ {
+ tmpsr = FSMC_Bank4->SR4;
+ }
+
+ itstatus = tmpsr & FSMC_IT;
+
+ itenable = tmpsr & (FSMC_IT >> 3);
+ if ((itstatus != (uint32_t)RESET) && (itenable != (uint32_t)RESET))
+ {
+ bitstatus = SET;
+ }
+ else
+ {
+ bitstatus = RESET;
+ }
+ return bitstatus;
+}
+
+/**
+ * @brief Clears the FSMC's interrupt pending bits.
+ * @param FSMC_Bank: specifies the FSMC Bank to be used
+ * This parameter can be one of the following values:
+ * @arg FSMC_Bank2_NAND: FSMC Bank2 NAND
+ * @arg FSMC_Bank3_NAND: FSMC Bank3 NAND
+ * @arg FSMC_Bank4_PCCARD: FSMC Bank4 PCCARD
+ * @param FSMC_IT: specifies the interrupt pending bit to clear.
+ * This parameter can be any combination of the following values:
+ * @arg FSMC_IT_RisingEdge: Rising edge detection interrupt.
+ * @arg FSMC_IT_Level: Level edge detection interrupt.
+ * @arg FSMC_IT_FallingEdge: Falling edge detection interrupt.
+ * @retval None
+ */
+void FSMC_ClearITPendingBit(uint32_t FSMC_Bank, uint32_t FSMC_IT)
+{
+ /* Check the parameters */
+ assert_param(IS_FSMC_IT_BANK(FSMC_Bank));
+ assert_param(IS_FSMC_IT(FSMC_IT));
+
+ if(FSMC_Bank == FSMC_Bank2_NAND)
+ {
+ FSMC_Bank2->SR2 &= ~(FSMC_IT >> 3);
+ }
+ else if(FSMC_Bank == FSMC_Bank3_NAND)
+ {
+ FSMC_Bank3->SR3 &= ~(FSMC_IT >> 3);
+ }
+ /* FSMC_Bank4_PCCARD*/
+ else
+ {
+ FSMC_Bank4->SR4 &= ~(FSMC_IT >> 3);
+ }
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/src/stm32f2xx_gpio.c b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/src/stm32f2xx_gpio.c
new file mode 100644
index 0000000..c53371e
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/src/stm32f2xx_gpio.c
@@ -0,0 +1,566 @@
+/**
+ ******************************************************************************
+ * @file stm32f2xx_gpio.c
+ * @author MCD Application Team
+ * @version V1.1.2
+ * @date 05-March-2012
+ * @brief This file provides firmware functions to manage the following
+ * functionalities of the GPIO peripheral:
+ * - Initialization and Configuration
+ * - GPIO Read and Write
+ * - GPIO Alternate functions configuration
+ *
+ * @verbatim
+ *
+ * ===================================================================
+ * How to use this driver
+ * ===================================================================
+ * 1. Enable the GPIO AHB clock using the following function
+ * RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOx, ENABLE);
+ *
+ * 2. Configure the GPIO pin(s) using GPIO_Init()
+ * Four possible configuration are available for each pin:
+ * - Input: Floating, Pull-up, Pull-down.
+ * - Output: Push-Pull (Pull-up, Pull-down or no Pull)
+ * Open Drain (Pull-up, Pull-down or no Pull).
+ * In output mode, the speed is configurable: 2 MHz, 25 MHz,
+ * 50 MHz or 100 MHz.
+ * - Alternate Function: Push-Pull (Pull-up, Pull-down or no Pull)
+ * Open Drain (Pull-up, Pull-down or no Pull).
+ * - Analog: required mode when a pin is to be used as ADC channel
+ * or DAC output.
+ *
+ * 3- Peripherals alternate function:
+ * - For ADC and DAC, configure the desired pin in analog mode using
+ * GPIO_InitStruct->GPIO_Mode = GPIO_Mode_AN;
+ * - For other peripherals (TIM, USART...):
+ * - Connect the pin to the desired peripherals' Alternate
+ * Function (AF) using GPIO_PinAFConfig() function
+ * - Configure the desired pin in alternate function mode using
+ * GPIO_InitStruct->GPIO_Mode = GPIO_Mode_AF
+ * - Select the type, pull-up/pull-down and output speed via
+ * GPIO_PuPd, GPIO_OType and GPIO_Speed members
+ * - Call GPIO_Init() function
+ *
+ * 4. To get the level of a pin configured in input mode use GPIO_ReadInputDataBit()
+ *
+ * 5. To set/reset the level of a pin configured in output mode use
+ * GPIO_SetBits()/GPIO_ResetBits()
+ *
+ * 6. During and just after reset, the alternate functions are not
+ * active and the GPIO pins are configured in input floating mode
+ * (except JTAG pins).
+ *
+ * 7. The LSE oscillator pins OSC32_IN and OSC32_OUT can be used as
+ * general-purpose (PC14 and PC15, respectively) when the LSE
+ * oscillator is off. The LSE has priority over the GPIO function.
+ *
+ * 8. The HSE oscillator pins OSC_IN/OSC_OUT can be used as
+ * general-purpose PH0 and PH1, respectively, when the HSE
+ * oscillator is off. The HSE has priority over the GPIO function.
+ *
+ * @endverbatim
+ *
+ ******************************************************************************
+ * @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 "stm32f2xx_gpio.h"
+#include "stm32f2xx_rcc.h"
+
+/** @addtogroup STM32F2xx_StdPeriph_Driver
+ * @{
+ */
+
+/** @defgroup GPIO
+ * @brief GPIO driver modules
+ * @{
+ */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+/** @defgroup GPIO_Private_Functions
+ * @{
+ */
+
+/** @defgroup GPIO_Group1 Initialization and Configuration
+ * @brief Initialization and Configuration
+ *
+@verbatim
+ ===============================================================================
+ Initialization and Configuration
+ ===============================================================================
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Deinitializes the GPIOx peripheral registers to their default reset values.
+ * @note By default, The GPIO pins are configured in input floating mode (except JTAG pins).
+ * @param GPIOx: where x can be (A..I) to select the GPIO peripheral.
+ * @retval None
+ */
+void GPIO_DeInit(GPIO_TypeDef* GPIOx)
+{
+ /* Check the parameters */
+ assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
+
+ if (GPIOx == GPIOA)
+ {
+ RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOA, ENABLE);
+ RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOA, DISABLE);
+ }
+ else if (GPIOx == GPIOB)
+ {
+ RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOB, ENABLE);
+ RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOB, DISABLE);
+ }
+ else if (GPIOx == GPIOC)
+ {
+ RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOC, ENABLE);
+ RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOC, DISABLE);
+ }
+ else if (GPIOx == GPIOD)
+ {
+ RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOD, ENABLE);
+ RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOD, DISABLE);
+ }
+ else if (GPIOx == GPIOE)
+ {
+ RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOE, ENABLE);
+ RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOE, DISABLE);
+ }
+ else if (GPIOx == GPIOF)
+ {
+ RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOF, ENABLE);
+ RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOF, DISABLE);
+ }
+ else if (GPIOx == GPIOG)
+ {
+ RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOG, ENABLE);
+ RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOG, DISABLE);
+ }
+ else if (GPIOx == GPIOH)
+ {
+ RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOH, ENABLE);
+ RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOH, DISABLE);
+ }
+ else
+ {
+ if (GPIOx == GPIOI)
+ {
+ RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOI, ENABLE);
+ RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOI, DISABLE);
+ }
+ }
+}
+
+/**
+ * @brief Initializes the GPIOx peripheral according to the specified parameters in the GPIO_InitStruct.
+ * @param GPIOx: where x can be (A..I) to select the GPIO peripheral.
+ * @param GPIO_InitStruct: pointer to a GPIO_InitTypeDef structure that contains
+ * the configuration information for the specified GPIO peripheral.
+ * @retval None
+ */
+void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)
+{
+ uint32_t pinpos = 0x00, pos = 0x00 , currentpin = 0x00;
+
+ /* Check the parameters */
+ assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
+ assert_param(IS_GPIO_PIN(GPIO_InitStruct->GPIO_Pin));
+ assert_param(IS_GPIO_MODE(GPIO_InitStruct->GPIO_Mode));
+ assert_param(IS_GPIO_PUPD(GPIO_InitStruct->GPIO_PuPd));
+
+ /* -------------------------Configure the port pins---------------- */
+ /*-- GPIO Mode Configuration --*/
+ for (pinpos = 0x00; pinpos < 0x10; pinpos++)
+ {
+ pos = ((uint32_t)0x01) << pinpos;
+ /* Get the port pins position */
+ currentpin = (GPIO_InitStruct->GPIO_Pin) & pos;
+
+ if (currentpin == pos)
+ {
+ GPIOx->MODER &= ~(GPIO_MODER_MODER0 << (pinpos * 2));
+ GPIOx->MODER |= (((uint32_t)GPIO_InitStruct->GPIO_Mode) << (pinpos * 2));
+
+ if ((GPIO_InitStruct->GPIO_Mode == GPIO_Mode_OUT) || (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_AF))
+ {
+ /* Check Speed mode parameters */
+ assert_param(IS_GPIO_SPEED(GPIO_InitStruct->GPIO_Speed));
+
+ /* Speed mode configuration */
+ GPIOx->OSPEEDR &= ~(GPIO_OSPEEDER_OSPEEDR0 << (pinpos * 2));
+ GPIOx->OSPEEDR |= ((uint32_t)(GPIO_InitStruct->GPIO_Speed) << (pinpos * 2));
+
+ /* Check Output mode parameters */
+ assert_param(IS_GPIO_OTYPE(GPIO_InitStruct->GPIO_OType));
+
+ /* Output mode configuration*/
+ GPIOx->OTYPER &= ~((GPIO_OTYPER_OT_0) << ((uint16_t)pinpos)) ;
+ GPIOx->OTYPER |= (uint16_t)(((uint16_t)GPIO_InitStruct->GPIO_OType) << ((uint16_t)pinpos));
+ }
+
+ /* Pull-up Pull down resistor configuration*/
+ GPIOx->PUPDR &= ~(GPIO_PUPDR_PUPDR0 << ((uint16_t)pinpos * 2));
+ GPIOx->PUPDR |= (((uint32_t)GPIO_InitStruct->GPIO_PuPd) << (pinpos * 2));
+ }
+ }
+}
+
+/**
+ * @brief Fills each GPIO_InitStruct member with its default value.
+ * @param GPIO_InitStruct : pointer to a GPIO_InitTypeDef structure which will be initialized.
+ * @retval None
+ */
+void GPIO_StructInit(GPIO_InitTypeDef* GPIO_InitStruct)
+{
+ /* Reset GPIO init structure parameters values */
+ GPIO_InitStruct->GPIO_Pin = GPIO_Pin_All;
+ GPIO_InitStruct->GPIO_Mode = GPIO_Mode_IN;
+ GPIO_InitStruct->GPIO_Speed = GPIO_Speed_2MHz;
+ GPIO_InitStruct->GPIO_OType = GPIO_OType_PP;
+ GPIO_InitStruct->GPIO_PuPd = GPIO_PuPd_NOPULL;
+}
+
+/**
+ * @brief Locks GPIO Pins configuration registers.
+ * @note The locked registers are GPIOx_MODER, GPIOx_OTYPER, GPIOx_OSPEEDR,
+ * GPIOx_PUPDR, GPIOx_AFRL and GPIOx_AFRH.
+ * @note The configuration of the locked GPIO pins can no longer be modified
+ * until the next reset.
+ * @param GPIOx: where x can be (A..I) to select the GPIO peripheral.
+ * @param GPIO_Pin: specifies the port bit to be locked.
+ * This parameter can be any combination of GPIO_Pin_x where x can be (0..15).
+ * @retval None
+ */
+void GPIO_PinLockConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
+{
+ __IO uint32_t tmp = 0x00010000;
+
+ /* Check the parameters */
+ assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
+ assert_param(IS_GPIO_PIN(GPIO_Pin));
+
+ tmp |= GPIO_Pin;
+ /* Set LCKK bit */
+ GPIOx->LCKR = tmp;
+ /* Reset LCKK bit */
+ GPIOx->LCKR = GPIO_Pin;
+ /* Set LCKK bit */
+ GPIOx->LCKR = tmp;
+ /* Read LCKK bit*/
+ tmp = GPIOx->LCKR;
+ /* Read LCKK bit*/
+ tmp = GPIOx->LCKR;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup GPIO_Group2 GPIO Read and Write
+ * @brief GPIO Read and Write
+ *
+@verbatim
+ ===============================================================================
+ GPIO Read and Write
+ ===============================================================================
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Reads the specified input port pin.
+ * @param GPIOx: where x can be (A..I) to select the GPIO peripheral.
+ * @param GPIO_Pin: specifies the port bit to read.
+ * This parameter can be GPIO_Pin_x where x can be (0..15).
+ * @retval The input port pin value.
+ */
+uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
+{
+ uint8_t bitstatus = 0x00;
+
+ /* Check the parameters */
+ assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
+ assert_param(IS_GET_GPIO_PIN(GPIO_Pin));
+
+ if ((GPIOx->IDR & GPIO_Pin) != (uint32_t)Bit_RESET)
+ {
+ bitstatus = (uint8_t)Bit_SET;
+ }
+ else
+ {
+ bitstatus = (uint8_t)Bit_RESET;
+ }
+ return bitstatus;
+}
+
+/**
+ * @brief Reads the specified GPIO input data port.
+ * @param GPIOx: where x can be (A..I) to select the GPIO peripheral.
+ * @retval GPIO input data port value.
+ */
+uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx)
+{
+ /* Check the parameters */
+ assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
+
+ return ((uint16_t)GPIOx->IDR);
+}
+
+/**
+ * @brief Reads the specified output data port bit.
+ * @param GPIOx: where x can be (A..I) to select the GPIO peripheral.
+ * @param GPIO_Pin: specifies the port bit to read.
+ * This parameter can be GPIO_Pin_x where x can be (0..15).
+ * @retval The output port pin value.
+ */
+uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
+{
+ uint8_t bitstatus = 0x00;
+
+ /* Check the parameters */
+ assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
+ assert_param(IS_GET_GPIO_PIN(GPIO_Pin));
+
+ if ((GPIOx->ODR & GPIO_Pin) != (uint32_t)Bit_RESET)
+ {
+ bitstatus = (uint8_t)Bit_SET;
+ }
+ else
+ {
+ bitstatus = (uint8_t)Bit_RESET;
+ }
+ return bitstatus;
+}
+
+/**
+ * @brief Reads the specified GPIO output data port.
+ * @param GPIOx: where x can be (A..I) to select the GPIO peripheral.
+ * @retval GPIO output data port value.
+ */
+uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx)
+{
+ /* Check the parameters */
+ assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
+
+ return ((uint16_t)GPIOx->ODR);
+}
+
+/**
+ * @brief Sets the selected data port bits.
+ * @note This functions uses GPIOx_BSRR register to allow atomic read/modify
+ * accesses. In this way, there is no risk of an IRQ occurring between
+ * the read and the modify access.
+ * @param GPIOx: where x can be (A..I) to select the GPIO peripheral.
+ * @param GPIO_Pin: specifies the port bits to be written.
+ * This parameter can be any combination of GPIO_Pin_x where x can be (0..15).
+ * @retval None
+ */
+void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
+{
+ /* Check the parameters */
+ assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
+ assert_param(IS_GPIO_PIN(GPIO_Pin));
+
+ GPIOx->BSRRL = GPIO_Pin;
+}
+
+/**
+ * @brief Clears the selected data port bits.
+ * @note This functions uses GPIOx_BSRR register to allow atomic read/modify
+ * accesses. In this way, there is no risk of an IRQ occurring between
+ * the read and the modify access.
+ * @param GPIOx: where x can be (A..I) to select the GPIO peripheral.
+ * @param GPIO_Pin: specifies the port bits to be written.
+ * This parameter can be any combination of GPIO_Pin_x where x can be (0..15).
+ * @retval None
+ */
+void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
+{
+ /* Check the parameters */
+ assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
+ assert_param(IS_GPIO_PIN(GPIO_Pin));
+
+ GPIOx->BSRRH = GPIO_Pin;
+}
+
+/**
+ * @brief Sets or clears the selected data port bit.
+ * @param GPIOx: where x can be (A..I) to select the GPIO peripheral.
+ * @param GPIO_Pin: specifies the port bit to be written.
+ * This parameter can be one of GPIO_Pin_x where x can be (0..15).
+ * @param BitVal: specifies the value to be written to the selected bit.
+ * This parameter can be one of the BitAction enum values:
+ * @arg Bit_RESET: to clear the port pin
+ * @arg Bit_SET: to set the port pin
+ * @retval None
+ */
+void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal)
+{
+ /* Check the parameters */
+ assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
+ assert_param(IS_GET_GPIO_PIN(GPIO_Pin));
+ assert_param(IS_GPIO_BIT_ACTION(BitVal));
+
+ if (BitVal != Bit_RESET)
+ {
+ GPIOx->BSRRL = GPIO_Pin;
+ }
+ else
+ {
+ GPIOx->BSRRH = GPIO_Pin ;
+ }
+}
+
+/**
+ * @brief Writes data to the specified GPIO data port.
+ * @param GPIOx: where x can be (A..I) to select the GPIO peripheral.
+ * @param PortVal: specifies the value to be written to the port output data register.
+ * @retval None
+ */
+void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal)
+{
+ /* Check the parameters */
+ assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
+
+ GPIOx->ODR = PortVal;
+}
+
+/**
+ * @brief Toggles the specified GPIO pins..
+ * @param GPIOx: where x can be (A..I) to select the GPIO peripheral.
+ * @param GPIO_Pin: Specifies the pins to be toggled.
+ * @retval None
+ */
+void GPIO_ToggleBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
+{
+ /* Check the parameters */
+ assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
+
+ GPIOx->ODR ^= GPIO_Pin;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup GPIO_Group3 GPIO Alternate functions configuration function
+ * @brief GPIO Alternate functions configuration function
+ *
+@verbatim
+ ===============================================================================
+ GPIO Alternate functions configuration function
+ ===============================================================================
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Changes the mapping of the specified pin.
+ * @param GPIOx: where x can be (A..I) to select the GPIO peripheral.
+ * @param GPIO_PinSource: specifies the pin for the Alternate function.
+ * This parameter can be GPIO_PinSourcex where x can be (0..15).
+ * @param GPIO_AFSelection: selects the pin to used as Alternate function.
+ * This parameter can be one of the following values:
+ * @arg GPIO_AF_RTC_50Hz: Connect RTC_50Hz pin to AF0 (default after reset)
+ * @arg GPIO_AF_MCO: Connect MCO pin (MCO1 and MCO2) to AF0 (default after reset)
+ * @arg GPIO_AF_TAMPER: Connect TAMPER pins (TAMPER_1 and TAMPER_2) to AF0 (default after reset)
+ * @arg GPIO_AF_SWJ: Connect SWJ pins (SWD and JTAG)to AF0 (default after reset)
+ * @arg GPIO_AF_TRACE: Connect TRACE pins to AF0 (default after reset)
+ * @arg GPIO_AF_TIM1: Connect TIM1 pins to AF1
+ * @arg GPIO_AF_TIM2: Connect TIM2 pins to AF1
+ * @arg GPIO_AF_TIM3: Connect TIM3 pins to AF2
+ * @arg GPIO_AF_TIM4: Connect TIM4 pins to AF2
+ * @arg GPIO_AF_TIM5: Connect TIM5 pins to AF2
+ * @arg GPIO_AF_TIM8: Connect TIM8 pins to AF3
+ * @arg GPIO_AF_TIM9: Connect TIM9 pins to AF3
+ * @arg GPIO_AF_TIM10: Connect TIM10 pins to AF3
+ * @arg GPIO_AF_TIM11: Connect TIM11 pins to AF3
+ * @arg GPIO_AF_I2C1: Connect I2C1 pins to AF4
+ * @arg GPIO_AF_I2C2: Connect I2C2 pins to AF4
+ * @arg GPIO_AF_I2C3: Connect I2C3 pins to AF4
+ * @arg GPIO_AF_SPI1: Connect SPI1 pins to AF5
+ * @arg GPIO_AF_SPI2: Connect SPI2/I2S2 pins to AF5
+ * @arg GPIO_AF_SPI3: Connect SPI3/I2S3 pins to AF6
+ * @arg GPIO_AF_USART1: Connect USART1 pins to AF7
+ * @arg GPIO_AF_USART2: Connect USART2 pins to AF7
+ * @arg GPIO_AF_USART3: Connect USART3 pins to AF7
+ * @arg GPIO_AF_UART4: Connect UART4 pins to AF8
+ * @arg GPIO_AF_UART5: Connect UART5 pins to AF8
+ * @arg GPIO_AF_USART6: Connect USART6 pins to AF8
+ * @arg GPIO_AF_CAN1: Connect CAN1 pins to AF9
+ * @arg GPIO_AF_CAN2: Connect CAN2 pins to AF9
+ * @arg GPIO_AF_TIM12: Connect TIM12 pins to AF9
+ * @arg GPIO_AF_TIM13: Connect TIM13 pins to AF9
+ * @arg GPIO_AF_TIM14: Connect TIM14 pins to AF9
+ * @arg GPIO_AF_OTG_FS: Connect OTG_FS pins to AF10
+ * @arg GPIO_AF_OTG_HS: Connect OTG_HS pins to AF10
+ * @arg GPIO_AF_ETH: Connect ETHERNET pins to AF11
+ * @arg GPIO_AF_FSMC: Connect FSMC pins to AF12
+ * @arg GPIO_AF_OTG_HS_FS: Connect OTG HS (configured in FS) pins to AF12
+ * @arg GPIO_AF_SDIO: Connect SDIO pins to AF12
+ * @arg GPIO_AF_DCMI: Connect DCMI pins to AF13
+ * @arg GPIO_AF_EVENTOUT: Connect EVENTOUT pins to AF15
+ * @retval None
+ */
+void GPIO_PinAFConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_PinSource, uint8_t GPIO_AF)
+{
+ uint32_t temp = 0x00;
+ uint32_t temp_2 = 0x00;
+
+ /* Check the parameters */
+ assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
+ assert_param(IS_GPIO_PIN_SOURCE(GPIO_PinSource));
+ assert_param(IS_GPIO_AF(GPIO_AF));
+
+ temp = ((uint32_t)(GPIO_AF) << ((uint32_t)((uint32_t)GPIO_PinSource & (uint32_t)0x07) * 4)) ;
+ GPIOx->AFR[GPIO_PinSource >> 0x03] &= ~((uint32_t)0xF << ((uint32_t)((uint32_t)GPIO_PinSource & (uint32_t)0x07) * 4)) ;
+ temp_2 = GPIOx->AFR[GPIO_PinSource >> 0x03] | temp;
+ GPIOx->AFR[GPIO_PinSource >> 0x03] = temp_2;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/src/stm32f2xx_hash.c b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/src/stm32f2xx_hash.c
new file mode 100644
index 0000000..c5c799b
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/src/stm32f2xx_hash.c
@@ -0,0 +1,706 @@
+/**
+ ******************************************************************************
+ * @file stm32f2xx_hash.c
+ * @author MCD Application Team
+ * @version V1.1.2
+ * @date 05-March-2012
+ * @brief This file provides firmware functions to manage the following
+ * functionalities of the HASH / HMAC Processor (HASH) peripheral:
+ * - Initialization and Configuration functions
+ * - Message Digest generation functions
+ * - context swapping functions
+ * - DMA interface function
+ * - Interrupts and flags management
+ *
+ * @verbatim
+ *
+ * ===================================================================
+ * How to use this driver
+ * ===================================================================
+ * HASH operation :
+ * ----------------
+ * 1. Enable the HASH controller clock using
+ * RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_HASH, ENABLE) function.
+ *
+ * 2. Initialise the HASH using HASH_Init() function.
+ *
+ * 3 . Reset the HASH processor core, so that the HASH will be ready
+ * to compute he message digest of a new message by using
+ * HASH_Reset() function.
+ *
+ * 4. Enable the HASH controller using the HASH_Cmd() function.
+ *
+ * 5. if using DMA for Data input transfer, Activate the DMA Request
+ * using HASH_DMACmd() function
+ *
+ * 6. if DMA is not used for data transfer, use HASH_DataIn() function
+ * to enter data to IN FIFO.
+ *
+ *
+ * 7. Configure the Number of valid bits in last word of the message
+ * using HASH_SetLastWordValidBitsNbr() function.
+ *
+ * 8. if the message length is not an exact multiple of 512 bits,
+ * then the function HASH_StartDigest() must be called to
+ * launch the computation of the final digest.
+ *
+ * 9. Once computed, the digest can be read using HASH_GetDigest()
+ * function.
+ *
+ * 10. To control HASH events you can use one of the following
+ * two methods:
+ * a- Check on HASH flags using the HASH_GetFlagStatus() function.
+ * b- Use HASH interrupts through the function HASH_ITConfig() at
+ * initialization phase and HASH_GetITStatus() function into
+ * interrupt routines in hashing phase.
+ * After checking on a flag you should clear it using HASH_ClearFlag()
+ * function. And after checking on an interrupt event you should
+ * clear it using HASH_ClearITPendingBit() function.
+ *
+ * 11. Save and restore hash processor context using
+ * HASH_SaveContext() and HASH_RestoreContext() functions.
+ *
+ *
+ *
+ * HMAC operation :
+ * ----------------
+ * The HMAC algorithm is used for message authentication, by
+ * irreversibly binding the message being processed to a key chosen
+ * by the user.
+ * For HMAC specifications, refer to "HMAC: keyed-hashing for message
+ * authentication, H. Krawczyk, M. Bellare, R. Canetti, February 1997"
+ *
+ * Basically, the HMAC algorithm consists of two nested hash operations:
+ * HMAC(message) = Hash[((key | pad) XOR 0x5C) | Hash(((key | pad) XOR 0x36) | message)]
+ * where:
+ * - "pad" is a sequence of zeroes needed to extend the key to the
+ * length of the underlying hash function data block (that is
+ * 512 bits for both the SHA-1 and MD5 hash algorithms)
+ * - "|" represents the concatenation operator
+ *
+ *
+ * To compute the HMAC, four different phases are required:
+ *
+ * 1. Initialise the HASH using HASH_Init() function to do HMAC
+ * operation.
+ *
+ * 2. The key (to be used for the inner hash function) is then given
+ * to the core. This operation follows the same mechanism as the
+ * one used to send the message in the hash operation (that is,
+ * by HASH_DataIn() function and, finally,
+ * HASH_StartDigest() function.
+ *
+ * 3. Once the last word has been entered and computation has started,
+ * the hash processor elaborates the key. It is then ready to
+ * accept the message text using the same mechanism as the one
+ * used to send the message in the hash operation.
+ *
+ * 4. After the first hash round, the hash processor returns "ready"
+ * to indicate that it is ready to receive the key to be used for
+ * the outer hash function (normally, this key is the same as the
+ * one used for the inner hash function). When the last word of
+ * the key is entered and computation starts, the HMAC result is
+ * made available using HASH_GetDigest() function.
+ *
+ *
+ * @endverbatim
+ *
+ ******************************************************************************
+ * @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 "stm32f2xx_hash.h"
+#include "stm32f2xx_rcc.h"
+
+/** @addtogroup STM32F2xx_StdPeriph_Driver
+ * @{
+ */
+
+/** @defgroup HASH
+ * @brief HASH driver modules
+ * @{
+ */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+/** @defgroup HASH_Private_Functions
+ * @{
+ */
+
+/** @defgroup HASH_Group1 Initialization and Configuration functions
+ * @brief Initialization and Configuration functions
+ *
+@verbatim
+ ===============================================================================
+ Initialization and Configuration functions
+ ===============================================================================
+ This section provides functions allowing to
+ - Initialize the HASH peripheral
+ - Configure the HASH Processor
+ - MD5/SHA1,
+ - HASH/HMAC,
+ - datatype
+ - HMAC Key (if mode = HMAC)
+ - Reset the HASH Processor
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Deinitializes the HASH peripheral registers to their default reset values
+ * @param None
+ * @retval None
+ */
+void HASH_DeInit(void)
+{
+ /* Enable HASH reset state */
+ RCC_AHB2PeriphResetCmd(RCC_AHB2Periph_HASH, ENABLE);
+ /* Release HASH from reset state */
+ RCC_AHB2PeriphResetCmd(RCC_AHB2Periph_HASH, DISABLE);
+}
+
+/**
+ * @brief Initializes the HASH peripheral according to the specified parameters
+ * in the HASH_InitStruct structure.
+ * @note the hash processor is reset when calling this function so that the
+ * HASH will be ready to compute the message digest of a new message.
+ * There is no need to call HASH_Reset() function.
+ * @param HASH_InitStruct: pointer to a HASH_InitTypeDef structure that contains
+ * the configuration information for the HASH peripheral.
+ * @note The field HASH_HMACKeyType in HASH_InitTypeDef must be filled only
+ * if the algorithm mode is HMAC.
+ * @retval None
+ */
+void HASH_Init(HASH_InitTypeDef* HASH_InitStruct)
+{
+ /* Check the parameters */
+ assert_param(IS_HASH_ALGOSELECTION(HASH_InitStruct->HASH_AlgoSelection));
+ assert_param(IS_HASH_DATATYPE(HASH_InitStruct->HASH_DataType));
+ assert_param(IS_HASH_ALGOMODE(HASH_InitStruct->HASH_AlgoMode));
+
+ /* Configure the Algorithm used, algorithm mode and the datatype */
+ HASH->CR &= ~ (HASH_CR_ALGO | HASH_CR_DATATYPE | HASH_CR_MODE);
+ HASH->CR |= (HASH_InitStruct->HASH_AlgoSelection | \
+ HASH_InitStruct->HASH_DataType | \
+ HASH_InitStruct->HASH_AlgoMode);
+
+ /* if algorithm mode is HMAC, set the Key */
+ if(HASH_InitStruct->HASH_AlgoMode == HASH_AlgoMode_HMAC)
+ {
+ assert_param(IS_HASH_HMAC_KEYTYPE(HASH_InitStruct->HASH_HMACKeyType));
+ HASH->CR &= ~HASH_CR_LKEY;
+ HASH->CR |= HASH_InitStruct->HASH_HMACKeyType;
+ }
+
+ /* Reset the HASH processor core, so that the HASH will be ready to compute
+ the message digest of a new message */
+ HASH->CR |= HASH_CR_INIT;
+}
+
+/**
+ * @brief Fills each HASH_InitStruct member with its default value.
+ * @param HASH_InitStruct : pointer to a HASH_InitTypeDef structure which will
+ * be initialized.
+ * @note The default values set are : Processor mode is HASH, Algorithm selected is SHA1,
+ * Data type selected is 32b and HMAC Key Type is short key.
+ * @retval None
+ */
+void HASH_StructInit(HASH_InitTypeDef* HASH_InitStruct)
+{
+ /* Initialize the HASH_AlgoSelection member */
+ HASH_InitStruct->HASH_AlgoSelection = HASH_AlgoSelection_SHA1;
+
+ /* Initialize the HASH_AlgoMode member */
+ HASH_InitStruct->HASH_AlgoMode = HASH_AlgoMode_HASH;
+
+ /* Initialize the HASH_DataType member */
+ HASH_InitStruct->HASH_DataType = HASH_DataType_32b;
+
+ /* Initialize the HASH_HMACKeyType member */
+ HASH_InitStruct->HASH_HMACKeyType = HASH_HMACKeyType_ShortKey;
+}
+
+/**
+ * @brief Resets the HASH processor core, so that the HASH will be ready
+ * to compute the message digest of a new message.
+ * @note Calling this function will clear the HASH_SR_DCIS (Digest calculation
+ * completion interrupt status) bit corresponding to HASH_IT_DCI
+ * interrupt and HASH_FLAG_DCIS flag.
+ * @param None
+ * @retval None
+ */
+void HASH_Reset(void)
+{
+ /* Reset the HASH processor core */
+ HASH->CR |= HASH_CR_INIT;
+}
+/**
+ * @}
+ */
+
+/** @defgroup HASH_Group2 Message Digest generation functions
+ * @brief Message Digest generation functions
+ *
+@verbatim
+ ===============================================================================
+ Message Digest generation functions
+ ===============================================================================
+ This section provides functions allowing the generation of message digest:
+ - Push data in the IN FIFO : using HASH_DataIn()
+ - Get the number of words set in IN FIFO, use HASH_GetInFIFOWordsNbr()
+ - set the last word valid bits number using HASH_SetLastWordValidBitsNbr()
+ - start digest calculation : using HASH_StartDigest()
+ - Get the Digest message : using HASH_GetDigest()
+
+@endverbatim
+ * @{
+ */
+
+
+/**
+ * @brief Configure the Number of valid bits in last word of the message
+ * @param ValidNumber: Number of valid bits in last word of the message.
+ * This parameter must be a number between 0 and 0x1F.
+ * - 0x00: All 32 bits of the last data written are valid
+ * - 0x01: Only bit [0] of the last data written is valid
+ * - 0x02: Only bits[1:0] of the last data written are valid
+ * - 0x03: Only bits[2:0] of the last data written are valid
+ * - ...
+ * - 0x1F: Only bits[30:0] of the last data written are valid
+ * @note The Number of valid bits must be set before to start the message
+ * digest competition (in Hash and HMAC) and key treatment(in HMAC).
+ * @retval None
+ */
+void HASH_SetLastWordValidBitsNbr(uint16_t ValidNumber)
+{
+ /* Check the parameters */
+ assert_param(IS_HASH_VALIDBITSNUMBER(ValidNumber));
+
+ /* Configure the Number of valid bits in last word of the message */
+ HASH->STR &= ~(HASH_STR_NBW);
+ HASH->STR |= ValidNumber;
+}
+
+/**
+ * @brief Writes data in the Data Input FIFO
+ * @param Data: new data of the message to be processed.
+ * @retval None
+ */
+void HASH_DataIn(uint32_t Data)
+{
+ /* Write in the DIN register a new data */
+ HASH->DIN = Data;
+}
+
+/**
+ * @brief Returns the number of words already pushed into the IN FIFO.
+ * @param None
+ * @retval The value of words already pushed into the IN FIFO.
+ */
+uint8_t HASH_GetInFIFOWordsNbr(void)
+{
+ /* Return the value of NBW bits */
+ return ((HASH->CR & HASH_CR_NBW) >> 8);
+}
+
+/**
+ * @brief Provides the message digest result.
+ * @note In MD5 mode, Data[4] filed of HASH_MsgDigest structure is not used
+ * and is read as zero.
+ * @param HASH_MessageDigest: pointer to a HASH_MsgDigest structure which will
+ * hold the message digest result
+ * @retval None
+ */
+void HASH_GetDigest(HASH_MsgDigest* HASH_MessageDigest)
+{
+ /* Get the data field */
+ HASH_MessageDigest->Data[0] = HASH->HR[0];
+ HASH_MessageDigest->Data[1] = HASH->HR[1];
+ HASH_MessageDigest->Data[2] = HASH->HR[2];
+ HASH_MessageDigest->Data[3] = HASH->HR[3];
+ HASH_MessageDigest->Data[4] = HASH->HR[4];
+}
+
+/**
+ * @brief Starts the message padding and calculation of the final message
+ * @param None
+ * @retval None
+ */
+void HASH_StartDigest(void)
+{
+ /* Start the Digest calculation */
+ HASH->STR |= HASH_STR_DCAL;
+}
+/**
+ * @}
+ */
+
+/** @defgroup HASH_Group3 Context swapping functions
+ * @brief Context swapping functions
+ *
+@verbatim
+ ===============================================================================
+ Context swapping functions
+ ===============================================================================
+
+ This section provides functions allowing to save and store HASH Context
+
+ It is possible to interrupt a HASH/HMAC process to perform another processing
+ with a higher priority, and to complete the interrupted process later on, when
+ the higher priority task is complete. To do so, the context of the interrupted
+ task must be saved from the HASH registers to memory, and then be restored
+ from memory to the HASH registers.
+
+ 1. To save the current context, use HASH_SaveContext() function
+ 2. To restore the saved context, use HASH_RestoreContext() function
+
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Save the Hash peripheral Context.
+ * @note The context can be saved only when no block is currently being
+ * processed. So user must wait for DINIS = 1 (the last block has been
+ * processed and the input FIFO is empty) or NBW != 0 (the FIFO is not
+ * full and no processing is ongoing).
+ * @param HASH_ContextSave: pointer to a HASH_Context structure that contains
+ * the repository for current context.
+ * @retval None
+ */
+void HASH_SaveContext(HASH_Context* HASH_ContextSave)
+{
+ uint8_t i = 0;
+
+ /* save context registers */
+ HASH_ContextSave->HASH_IMR = HASH->IMR;
+ HASH_ContextSave->HASH_STR = HASH->STR;
+ HASH_ContextSave->HASH_CR = HASH->CR;
+ for(i=0; i<=50;i++)
+ {
+ HASH_ContextSave->HASH_CSR[i] = HASH->CSR[i];
+ }
+}
+
+/**
+ * @brief Restore the Hash peripheral Context.
+ * @note After calling this function, user can restart the processing from the
+ * point where it has been interrupted.
+ * @param HASH_ContextRestore: pointer to a HASH_Context structure that contains
+ * the repository for saved context.
+ * @retval None
+ */
+void HASH_RestoreContext(HASH_Context* HASH_ContextRestore)
+{
+ uint8_t i = 0;
+
+ /* restore context registers */
+ HASH->IMR = HASH_ContextRestore->HASH_IMR;
+ HASH->STR = HASH_ContextRestore->HASH_STR;
+ HASH->CR = HASH_ContextRestore->HASH_CR;
+
+ /* Initialize the hash processor */
+ HASH->CR |= HASH_CR_INIT;
+
+ /* continue restoring context registers */
+ for(i=0; i<=50;i++)
+ {
+ HASH->CSR[i] = HASH_ContextRestore->HASH_CSR[i];
+ }
+}
+/**
+ * @}
+ */
+
+/** @defgroup HASH_Group4 HASH's DMA interface Configuration function
+ * @brief HASH's DMA interface Configuration function
+ *
+@verbatim
+ ===============================================================================
+ HASH's DMA interface Configuration function
+ ===============================================================================
+
+ This section provides functions allowing to configure the DMA interface for
+ HASH/ HMAC data input transfer.
+
+ When the DMA mode is enabled (using the HASH_DMACmd() function), data can be
+ sent to the IN FIFO using the DMA peripheral.
+
+
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Enables or disables the HASH DMA interface.
+ * @note The DMA is disabled by hardware after the end of transfer.
+ * @param NewState: new state of the selected HASH DMA transfer request.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void HASH_DMACmd(FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the HASH DMA request */
+ HASH->CR |= HASH_CR_DMAE;
+ }
+ else
+ {
+ /* Disable the HASH DMA request */
+ HASH->CR &= ~HASH_CR_DMAE;
+ }
+}
+/**
+ * @}
+ */
+
+/** @defgroup HASH_Group5 Interrupts and flags management functions
+ * @brief Interrupts and flags management functions
+ *
+@verbatim
+ ===============================================================================
+ Interrupts and flags management functions
+ ===============================================================================
+
+ This section provides functions allowing to configure the HASH Interrupts and
+ to get the status and clear flags and Interrupts pending bits.
+
+ The HASH provides 2 Interrupts sources and 5 Flags:
+
+ Flags :
+ ----------
+ 1. HASH_FLAG_DINIS : set when 16 locations are free in the Data IN FIFO
+ which means that a new block (512 bit) can be entered
+ into the input buffer.
+
+ 2. HASH_FLAG_DCIS : set when Digest calculation is complete
+
+ 3. HASH_FLAG_DMAS : set when HASH's DMA interface is enabled (DMAE=1) or
+ a transfer is ongoing.
+ This Flag is cleared only by hardware.
+
+ 4. HASH_FLAG_BUSY : set when The hash core is processing a block of data
+ This Flag is cleared only by hardware.
+
+ 5. HASH_FLAG_DINNE : set when Data IN FIFO is not empty which means that
+ the Data IN FIFO contains at least one word of data.
+ This Flag is cleared only by hardware.
+
+ Interrupts :
+ ------------
+
+ 1. HASH_IT_DINI : if enabled, this interrupt source is pending when 16
+ locations are free in the Data IN FIFO which means that
+ a new block (512 bit) can be entered into the input buffer.
+ This interrupt source is cleared using
+ HASH_ClearITPendingBit(HASH_IT_DINI) function.
+
+ 2. HASH_IT_DCI : if enabled, this interrupt source is pending when Digest
+ calculation is complete.
+ This interrupt source is cleared using
+ HASH_ClearITPendingBit(HASH_IT_DCI) function.
+
+ Managing the HASH controller events :
+ ------------------------------------
+ The user should identify which mode will be used in his application to manage
+ the HASH controller events: Polling mode or Interrupt mode.
+
+ 1. In the Polling Mode it is advised to use the following functions:
+ - HASH_GetFlagStatus() : to check if flags events occur.
+ - HASH_ClearFlag() : to clear the flags events.
+
+ 2. In the Interrupt Mode it is advised to use the following functions:
+ - HASH_ITConfig() : to enable or disable the interrupt source.
+ - HASH_GetITStatus() : to check if Interrupt occurs.
+ - HASH_ClearITPendingBit() : to clear the Interrupt pending Bit
+ (corresponding Flag).
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Enables or disables the specified HASH interrupts.
+ * @param HASH_IT: specifies the HASH interrupt source to be enabled or disabled.
+ * This parameter can be any combination of the following values:
+ * @arg HASH_IT_DINI: Data Input interrupt
+ * @arg HASH_IT_DCI: Digest Calculation Completion Interrupt
+ * @param NewState: new state of the specified HASH interrupt.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void HASH_ITConfig(uint8_t HASH_IT, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_HASH_IT(HASH_IT));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the selected HASH interrupt */
+ HASH->IMR |= HASH_IT;
+ }
+ else
+ {
+ /* Disable the selected HASH interrupt */
+ HASH->IMR &= (uint8_t) ~HASH_IT;
+ }
+}
+
+/**
+ * @brief Checks whether the specified HASH flag is set or not.
+ * @param HASH_FLAG: specifies the HASH flag to check.
+ * This parameter can be one of the following values:
+ * @arg HASH_FLAG_DINIS: Data input interrupt status flag
+ * @arg HASH_FLAG_DCIS: Digest calculation completion interrupt status flag
+ * @arg HASH_FLAG_BUSY: Busy flag
+ * @arg HASH_FLAG_DMAS: DMAS Status flag
+ * @arg HASH_FLAG_DINNE: Data Input register (DIN) not empty status flag
+ * @retval The new state of HASH_FLAG (SET or RESET)
+ */
+FlagStatus HASH_GetFlagStatus(uint16_t HASH_FLAG)
+{
+ FlagStatus bitstatus = RESET;
+ uint32_t tempreg = 0;
+
+ /* Check the parameters */
+ assert_param(IS_HASH_GET_FLAG(HASH_FLAG));
+
+ /* check if the FLAG is in CR register */
+ if ((HASH_FLAG & HASH_FLAG_DINNE) != (uint16_t)RESET )
+ {
+ tempreg = HASH->CR;
+ }
+ else /* The FLAG is in SR register */
+ {
+ tempreg = HASH->SR;
+ }
+
+ /* Check the status of the specified HASH flag */
+ if ((tempreg & HASH_FLAG) != (uint16_t)RESET)
+ {
+ /* HASH is set */
+ bitstatus = SET;
+ }
+ else
+ {
+ /* HASH_FLAG is reset */
+ bitstatus = RESET;
+ }
+
+ /* Return the HASH_FLAG status */
+ return bitstatus;
+}
+/**
+ * @brief Clears the HASH flags.
+ * @param HASH_FLAG: specifies the flag to clear.
+ * This parameter can be any combination of the following values:
+ * @arg HASH_FLAG_DINIS: Data Input Flag
+ * @arg HASH_FLAG_DCIS: Digest Calculation Completion Flag
+ * @retval None
+ */
+void HASH_ClearFlag(uint16_t HASH_FLAG)
+{
+ /* Check the parameters */
+ assert_param(IS_HASH_CLEAR_FLAG(HASH_FLAG));
+
+ /* Clear the selected HASH flags */
+ HASH->SR = ~(uint32_t)HASH_FLAG;
+}
+/**
+ * @brief Checks whether the specified HASH interrupt has occurred or not.
+ * @param HASH_IT: specifies the HASH interrupt source to check.
+ * This parameter can be one of the following values:
+ * @arg HASH_IT_DINI: Data Input interrupt
+ * @arg HASH_IT_DCI: Digest Calculation Completion Interrupt
+ * @retval The new state of HASH_IT (SET or RESET).
+ */
+ITStatus HASH_GetITStatus(uint8_t HASH_IT)
+{
+ ITStatus bitstatus = RESET;
+ uint32_t tmpreg = 0;
+
+ /* Check the parameters */
+ assert_param(IS_HASH_GET_IT(HASH_IT));
+
+
+ /* Check the status of the specified HASH interrupt */
+ tmpreg = HASH->SR;
+
+ if (((HASH->IMR & tmpreg) & HASH_IT) != RESET)
+ {
+ /* HASH_IT is set */
+ bitstatus = SET;
+ }
+ else
+ {
+ /* HASH_IT is reset */
+ bitstatus = RESET;
+ }
+ /* Return the HASH_IT status */
+ return bitstatus;
+}
+
+/**
+ * @brief Clears the HASH interrupt pending bit(s).
+ * @param HASH_IT: specifies the HASH interrupt pending bit(s) to clear.
+ * This parameter can be any combination of the following values:
+ * @arg HASH_IT_DINI: Data Input interrupt
+ * @arg HASH_IT_DCI: Digest Calculation Completion Interrupt
+ * @retval None
+ */
+void HASH_ClearITPendingBit(uint8_t HASH_IT)
+{
+ /* Check the parameters */
+ assert_param(IS_HASH_IT(HASH_IT));
+
+ /* Clear the selected HASH interrupt pending bit */
+ HASH->SR = (uint8_t)~HASH_IT;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/src/stm32f2xx_hash_md5.c b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/src/stm32f2xx_hash_md5.c
new file mode 100644
index 0000000..21b929f
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/src/stm32f2xx_hash_md5.c
@@ -0,0 +1,320 @@
+/**
+ ******************************************************************************
+ * @file stm32f2xx_hash_md5.c
+ * @author MCD Application Team
+ * @version V1.1.2
+ * @date 05-March-2012
+ * @brief This file provides high level functions to compute the HASH MD5 and
+ * HMAC MD5 Digest of an input message.
+ * It uses the stm32f2xx_hash.c/.h drivers to access the STM32F2xx HASH
+ * peripheral.
+ *
+ * @verbatim
+ *
+ * ===================================================================
+ * How to use this driver
+ * ===================================================================
+ * 1. Enable The HASH controller clock using
+ * RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_HASH, ENABLE); function.
+ *
+ * 2. Calculate the HASH MD5 Digest using HASH_MD5() function.
+ *
+ * 3. Calculate the HMAC MD5 Digest using HMAC_MD5() function.
+ *
+ * @endverbatim
+ *
+ ******************************************************************************
+ * @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 "stm32f2xx_hash.h"
+
+/** @addtogroup STM32F2xx_StdPeriph_Driver
+ * @{
+ */
+
+/** @defgroup HASH
+ * @brief HASH driver modules
+ * @{
+ */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+#define MD5BUSY_TIMEOUT ((uint32_t) 0x00010000)
+
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+/** @defgroup HASH_Private_Functions
+ * @{
+ */
+
+/** @defgroup HASH_Group7 High Level MD5 functions
+ * @brief High Level MD5 Hash and HMAC functions
+ *
+@verbatim
+ ===============================================================================
+ High Level MD5 Hash and HMAC functions
+ ===============================================================================
+
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Compute the HASH MD5 digest.
+ * @param Input: pointer to the Input buffer to be treated.
+ * @param Ilen: length of the Input buffer.
+ * @param Output: the returned digest
+ * @retval An ErrorStatus enumeration value:
+ * - SUCCESS: digest computation done
+ * - ERROR: digest computation failed
+ */
+ErrorStatus HASH_MD5(uint8_t *Input, uint32_t Ilen, uint8_t Output[16])
+{
+ HASH_InitTypeDef MD5_HASH_InitStructure;
+ HASH_MsgDigest MD5_MessageDigest;
+ __IO uint16_t nbvalidbitsdata = 0;
+ uint32_t i = 0;
+ __IO uint32_t counter = 0;
+ uint32_t busystatus = 0;
+ ErrorStatus status = SUCCESS;
+ uint32_t inputaddr = (uint32_t)Input;
+ uint32_t outputaddr = (uint32_t)Output;
+
+
+ /* Number of valid bits in last word of the Input data */
+ nbvalidbitsdata = 8 * (Ilen % 4);
+
+ /* HASH peripheral initialization */
+ HASH_DeInit();
+
+ /* HASH Configuration */
+ MD5_HASH_InitStructure.HASH_AlgoSelection = HASH_AlgoSelection_MD5;
+ MD5_HASH_InitStructure.HASH_AlgoMode = HASH_AlgoMode_HASH;
+ MD5_HASH_InitStructure.HASH_DataType = HASH_DataType_8b;
+ HASH_Init(&MD5_HASH_InitStructure);
+
+ /* Configure the number of valid bits in last word of the data */
+ HASH_SetLastWordValidBitsNbr(nbvalidbitsdata);
+
+ /* Write the Input block in the IN FIFO */
+ for(i=0; i 64)
+ {
+ /* HMAC long Key */
+ MD5_HASH_InitStructure.HASH_HMACKeyType = HASH_HMACKeyType_LongKey;
+ }
+ else
+ {
+ /* HMAC short Key */
+ MD5_HASH_InitStructure.HASH_HMACKeyType = HASH_HMACKeyType_ShortKey;
+ }
+ HASH_Init(&MD5_HASH_InitStructure);
+
+ /* Configure the number of valid bits in last word of the Key */
+ HASH_SetLastWordValidBitsNbr(nbvalidbitskey);
+
+ /* Write the Key */
+ for(i=0; i© 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 "stm32f2xx_hash.h"
+
+/** @addtogroup STM32F2xx_StdPeriph_Driver
+ * @{
+ */
+
+/** @defgroup HASH
+ * @brief HASH driver modules
+ * @{
+ */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+#define SHA1BUSY_TIMEOUT ((uint32_t) 0x00010000)
+
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+/** @defgroup HASH_Private_Functions
+ * @{
+ */
+
+/** @defgroup HASH_Group6 High Level SHA1 functions
+ * @brief High Level SHA1 Hash and HMAC functions
+ *
+@verbatim
+ ===============================================================================
+ High Level SHA1 Hash and HMAC functions
+ ===============================================================================
+
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Compute the HASH SHA1 digest.
+ * @param Input: pointer to the Input buffer to be treated.
+ * @param Ilen: length of the Input buffer.
+ * @param Output: the returned digest
+ * @retval An ErrorStatus enumeration value:
+ * - SUCCESS: digest computation done
+ * - ERROR: digest computation failed
+ */
+ErrorStatus HASH_SHA1(uint8_t *Input, uint32_t Ilen, uint8_t Output[20])
+{
+ HASH_InitTypeDef SHA1_HASH_InitStructure;
+ HASH_MsgDigest SHA1_MessageDigest;
+ __IO uint16_t nbvalidbitsdata = 0;
+ uint32_t i = 0;
+ __IO uint32_t counter = 0;
+ uint32_t busystatus = 0;
+ ErrorStatus status = SUCCESS;
+ uint32_t inputaddr = (uint32_t)Input;
+ uint32_t outputaddr = (uint32_t)Output;
+
+ /* Number of valid bits in last word of the Input data */
+ nbvalidbitsdata = 8 * (Ilen % 4);
+
+ /* HASH peripheral initialization */
+ HASH_DeInit();
+
+ /* HASH Configuration */
+ SHA1_HASH_InitStructure.HASH_AlgoSelection = HASH_AlgoSelection_SHA1;
+ SHA1_HASH_InitStructure.HASH_AlgoMode = HASH_AlgoMode_HASH;
+ SHA1_HASH_InitStructure.HASH_DataType = HASH_DataType_8b;
+ HASH_Init(&SHA1_HASH_InitStructure);
+
+ /* Configure the number of valid bits in last word of the data */
+ HASH_SetLastWordValidBitsNbr(nbvalidbitsdata);
+
+ /* Write the Input block in the IN FIFO */
+ for(i=0; i 64)
+ {
+ /* HMAC long Key */
+ SHA1_HASH_InitStructure.HASH_HMACKeyType = HASH_HMACKeyType_LongKey;
+ }
+ else
+ {
+ /* HMAC short Key */
+ SHA1_HASH_InitStructure.HASH_HMACKeyType = HASH_HMACKeyType_ShortKey;
+ }
+ HASH_Init(&SHA1_HASH_InitStructure);
+
+ /* Configure the number of valid bits in last word of the Key */
+ HASH_SetLastWordValidBitsNbr(nbvalidbitskey);
+
+ /* Write the Key */
+ for(i=0; iGPIO_Mode = GPIO_Mode_AF
+ * - Select the type, pull-up/pull-down and output speed via
+ * GPIO_PuPd, GPIO_OType and GPIO_Speed members
+ * - Call GPIO_Init() function
+ * Recommended configuration is Push-Pull, Pull-up, Open-Drain.
+ * Add an external pull up if necessary (typically 4.7 KOhm).
+ *
+ * 4. Program the Mode, duty cycle , Own address, Ack, Speed and Acknowledged
+ * Address using the I2C_Init() function.
+ *
+ * 5. Optionally you can enable/configure the following parameters without
+ * re-initialization (i.e there is no need to call again I2C_Init() function):
+ * - Enable the acknowledge feature using I2C_AcknowledgeConfig() function
+ * - Enable the dual addressing mode using I2C_DualAddressCmd() function
+ * - Enable the general call using the I2C_GeneralCallCmd() function
+ * - Enable the clock stretching using I2C_StretchClockCmd() function
+ * - Enable the fast mode duty cycle using the I2C_FastModeDutyCycleConfig()
+ * function.
+ * - Configure the NACK position for Master Receiver mode in case of
+ * 2 bytes reception using the function I2C_NACKPositionConfig().
+ * - Enable the PEC Calculation using I2C_CalculatePEC() function
+ * - For SMBus Mode:
+ * - Enable the Address Resolution Protocol (ARP) using I2C_ARPCmd() function
+ * - Configure the SMBusAlert pin using I2C_SMBusAlertConfig() function
+ *
+ * 6. Enable the NVIC and the corresponding interrupt using the function
+ * I2C_ITConfig() if you need to use interrupt mode.
+ *
+ * 7. When using the DMA mode
+ * - Configure the DMA using DMA_Init() function
+ * - Active the needed channel Request using I2C_DMACmd() or
+ * I2C_DMALastTransferCmd() function.
+ * @note When using DMA mode, I2C interrupts may be used at the same time to
+ * control the communication flow (Start/Stop/Ack... events and errors).
+ *
+ * 8. Enable the I2C using the I2C_Cmd() function.
+ *
+ * 9. Enable the DMA using the DMA_Cmd() function when using DMA mode in the
+ * transfers.
+ *
+ * @endverbatim
+ *
+ ******************************************************************************
+ * @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 "stm32f2xx_i2c.h"
+#include "stm32f2xx_rcc.h"
+
+/** @addtogroup STM32F2xx_StdPeriph_Driver
+ * @{
+ */
+
+/** @defgroup I2C
+ * @brief I2C driver modules
+ * @{
+ */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+
+#define CR1_CLEAR_MASK ((uint16_t)0xFBF5) /*I2C_ClockSpeed));
+ assert_param(IS_I2C_MODE(I2C_InitStruct->I2C_Mode));
+ assert_param(IS_I2C_DUTY_CYCLE(I2C_InitStruct->I2C_DutyCycle));
+ assert_param(IS_I2C_OWN_ADDRESS1(I2C_InitStruct->I2C_OwnAddress1));
+ assert_param(IS_I2C_ACK_STATE(I2C_InitStruct->I2C_Ack));
+ assert_param(IS_I2C_ACKNOWLEDGE_ADDRESS(I2C_InitStruct->I2C_AcknowledgedAddress));
+
+/*---------------------------- I2Cx CR2 Configuration ------------------------*/
+ /* Get the I2Cx CR2 value */
+ tmpreg = I2Cx->CR2;
+ /* Clear frequency FREQ[5:0] bits */
+ tmpreg &= (uint16_t)~((uint16_t)I2C_CR2_FREQ);
+ /* Get pclk1 frequency value */
+ RCC_GetClocksFreq(&rcc_clocks);
+ pclk1 = rcc_clocks.PCLK1_Frequency;
+ /* Set frequency bits depending on pclk1 value */
+ freqrange = (uint16_t)(pclk1 / 1000000);
+ tmpreg |= freqrange;
+ /* Write to I2Cx CR2 */
+ I2Cx->CR2 = tmpreg;
+
+/*---------------------------- I2Cx CCR Configuration ------------------------*/
+ /* Disable the selected I2C peripheral to configure TRISE */
+ I2Cx->CR1 &= (uint16_t)~((uint16_t)I2C_CR1_PE);
+ /* Reset tmpreg value */
+ /* Clear F/S, DUTY and CCR[11:0] bits */
+ tmpreg = 0;
+
+ /* Configure speed in standard mode */
+ if (I2C_InitStruct->I2C_ClockSpeed <= 100000)
+ {
+ /* Standard mode speed calculate */
+ result = (uint16_t)(pclk1 / (I2C_InitStruct->I2C_ClockSpeed << 1));
+ /* Test if CCR value is under 0x4*/
+ if (result < 0x04)
+ {
+ /* Set minimum allowed value */
+ result = 0x04;
+ }
+ /* Set speed value for standard mode */
+ tmpreg |= result;
+ /* Set Maximum Rise Time for standard mode */
+ I2Cx->TRISE = freqrange + 1;
+ }
+ /* Configure speed in fast mode */
+ /* To use the I2C at 400 KHz (in fast mode), the PCLK1 frequency (I2C peripheral
+ input clock) must be a multiple of 10 MHz */
+ else /*(I2C_InitStruct->I2C_ClockSpeed <= 400000)*/
+ {
+ if (I2C_InitStruct->I2C_DutyCycle == I2C_DutyCycle_2)
+ {
+ /* Fast mode speed calculate: Tlow/Thigh = 2 */
+ result = (uint16_t)(pclk1 / (I2C_InitStruct->I2C_ClockSpeed * 3));
+ }
+ else /*I2C_InitStruct->I2C_DutyCycle == I2C_DutyCycle_16_9*/
+ {
+ /* Fast mode speed calculate: Tlow/Thigh = 16/9 */
+ result = (uint16_t)(pclk1 / (I2C_InitStruct->I2C_ClockSpeed * 25));
+ /* Set DUTY bit */
+ result |= I2C_DutyCycle_16_9;
+ }
+
+ /* Test if CCR value is under 0x1*/
+ if ((result & I2C_CCR_CCR) == 0)
+ {
+ /* Set minimum allowed value */
+ result |= (uint16_t)0x0001;
+ }
+ /* Set speed value and set F/S bit for fast mode */
+ tmpreg |= (uint16_t)(result | I2C_CCR_FS);
+ /* Set Maximum Rise Time for fast mode */
+ I2Cx->TRISE = (uint16_t)(((freqrange * (uint16_t)300) / (uint16_t)1000) + (uint16_t)1);
+ }
+
+ /* Write to I2Cx CCR */
+ I2Cx->CCR = tmpreg;
+ /* Enable the selected I2C peripheral */
+ I2Cx->CR1 |= I2C_CR1_PE;
+
+/*---------------------------- I2Cx CR1 Configuration ------------------------*/
+ /* Get the I2Cx CR1 value */
+ tmpreg = I2Cx->CR1;
+ /* Clear ACK, SMBTYPE and SMBUS bits */
+ tmpreg &= CR1_CLEAR_MASK;
+ /* Configure I2Cx: mode and acknowledgement */
+ /* Set SMBTYPE and SMBUS bits according to I2C_Mode value */
+ /* Set ACK bit according to I2C_Ack value */
+ tmpreg |= (uint16_t)((uint32_t)I2C_InitStruct->I2C_Mode | I2C_InitStruct->I2C_Ack);
+ /* Write to I2Cx CR1 */
+ I2Cx->CR1 = tmpreg;
+
+/*---------------------------- I2Cx OAR1 Configuration -----------------------*/
+ /* Set I2Cx Own Address1 and acknowledged address */
+ I2Cx->OAR1 = (I2C_InitStruct->I2C_AcknowledgedAddress | I2C_InitStruct->I2C_OwnAddress1);
+}
+
+/**
+ * @brief Fills each I2C_InitStruct member with its default value.
+ * @param I2C_InitStruct: pointer to an I2C_InitTypeDef structure which will be initialized.
+ * @retval None
+ */
+void I2C_StructInit(I2C_InitTypeDef* I2C_InitStruct)
+{
+/*---------------- Reset I2C init structure parameters values ----------------*/
+ /* initialize the I2C_ClockSpeed member */
+ I2C_InitStruct->I2C_ClockSpeed = 5000;
+ /* Initialize the I2C_Mode member */
+ I2C_InitStruct->I2C_Mode = I2C_Mode_I2C;
+ /* Initialize the I2C_DutyCycle member */
+ I2C_InitStruct->I2C_DutyCycle = I2C_DutyCycle_2;
+ /* Initialize the I2C_OwnAddress1 member */
+ I2C_InitStruct->I2C_OwnAddress1 = 0;
+ /* Initialize the I2C_Ack member */
+ I2C_InitStruct->I2C_Ack = I2C_Ack_Disable;
+ /* Initialize the I2C_AcknowledgedAddress member */
+ I2C_InitStruct->I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
+}
+
+/**
+ * @brief Enables or disables the specified I2C peripheral.
+ * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral.
+ * @param NewState: new state of the I2Cx peripheral.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void I2C_Cmd(I2C_TypeDef* I2Cx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ if (NewState != DISABLE)
+ {
+ /* Enable the selected I2C peripheral */
+ I2Cx->CR1 |= I2C_CR1_PE;
+ }
+ else
+ {
+ /* Disable the selected I2C peripheral */
+ I2Cx->CR1 &= (uint16_t)~((uint16_t)I2C_CR1_PE);
+ }
+}
+
+/**
+ * @brief Generates I2Cx communication START condition.
+ * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral.
+ * @param NewState: new state of the I2C START condition generation.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None.
+ */
+void I2C_GenerateSTART(I2C_TypeDef* I2Cx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ if (NewState != DISABLE)
+ {
+ /* Generate a START condition */
+ I2Cx->CR1 |= I2C_CR1_START;
+ }
+ else
+ {
+ /* Disable the START condition generation */
+ I2Cx->CR1 &= (uint16_t)~((uint16_t)I2C_CR1_START);
+ }
+}
+
+/**
+ * @brief Generates I2Cx communication STOP condition.
+ * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral.
+ * @param NewState: new state of the I2C STOP condition generation.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None.
+ */
+void I2C_GenerateSTOP(I2C_TypeDef* I2Cx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ if (NewState != DISABLE)
+ {
+ /* Generate a STOP condition */
+ I2Cx->CR1 |= I2C_CR1_STOP;
+ }
+ else
+ {
+ /* Disable the STOP condition generation */
+ I2Cx->CR1 &= (uint16_t)~((uint16_t)I2C_CR1_STOP);
+ }
+}
+
+/**
+ * @brief Transmits the address byte to select the slave device.
+ * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral.
+ * @param Address: specifies the slave address which will be transmitted
+ * @param I2C_Direction: specifies whether the I2C device will be a Transmitter
+ * or a Receiver.
+ * This parameter can be one of the following values
+ * @arg I2C_Direction_Transmitter: Transmitter mode
+ * @arg I2C_Direction_Receiver: Receiver mode
+ * @retval None.
+ */
+void I2C_Send7bitAddress(I2C_TypeDef* I2Cx, uint8_t Address, uint8_t I2C_Direction)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(IS_I2C_DIRECTION(I2C_Direction));
+ /* Test on the direction to set/reset the read/write bit */
+ if (I2C_Direction != I2C_Direction_Transmitter)
+ {
+ /* Set the address bit0 for read */
+ Address |= I2C_OAR1_ADD0;
+ }
+ else
+ {
+ /* Reset the address bit0 for write */
+ Address &= (uint8_t)~((uint8_t)I2C_OAR1_ADD0);
+ }
+ /* Send the address */
+ I2Cx->DR = Address;
+}
+
+/**
+ * @brief Enables or disables the specified I2C acknowledge feature.
+ * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral.
+ * @param NewState: new state of the I2C Acknowledgement.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None.
+ */
+void I2C_AcknowledgeConfig(I2C_TypeDef* I2Cx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ if (NewState != DISABLE)
+ {
+ /* Enable the acknowledgement */
+ I2Cx->CR1 |= I2C_CR1_ACK;
+ }
+ else
+ {
+ /* Disable the acknowledgement */
+ I2Cx->CR1 &= (uint16_t)~((uint16_t)I2C_CR1_ACK);
+ }
+}
+
+/**
+ * @brief Configures the specified I2C own address2.
+ * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral.
+ * @param Address: specifies the 7bit I2C own address2.
+ * @retval None.
+ */
+void I2C_OwnAddress2Config(I2C_TypeDef* I2Cx, uint8_t Address)
+{
+ uint16_t tmpreg = 0;
+
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+
+ /* Get the old register value */
+ tmpreg = I2Cx->OAR2;
+
+ /* Reset I2Cx Own address2 bit [7:1] */
+ tmpreg &= (uint16_t)~((uint16_t)I2C_OAR2_ADD2);
+
+ /* Set I2Cx Own address2 */
+ tmpreg |= (uint16_t)((uint16_t)Address & (uint16_t)0x00FE);
+
+ /* Store the new register value */
+ I2Cx->OAR2 = tmpreg;
+}
+
+/**
+ * @brief Enables or disables the specified I2C dual addressing mode.
+ * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral.
+ * @param NewState: new state of the I2C dual addressing mode.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void I2C_DualAddressCmd(I2C_TypeDef* I2Cx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ if (NewState != DISABLE)
+ {
+ /* Enable dual addressing mode */
+ I2Cx->OAR2 |= I2C_OAR2_ENDUAL;
+ }
+ else
+ {
+ /* Disable dual addressing mode */
+ I2Cx->OAR2 &= (uint16_t)~((uint16_t)I2C_OAR2_ENDUAL);
+ }
+}
+
+/**
+ * @brief Enables or disables the specified I2C general call feature.
+ * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral.
+ * @param NewState: new state of the I2C General call.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void I2C_GeneralCallCmd(I2C_TypeDef* I2Cx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ if (NewState != DISABLE)
+ {
+ /* Enable generall call */
+ I2Cx->CR1 |= I2C_CR1_ENGC;
+ }
+ else
+ {
+ /* Disable generall call */
+ I2Cx->CR1 &= (uint16_t)~((uint16_t)I2C_CR1_ENGC);
+ }
+}
+
+/**
+ * @brief Enables or disables the specified I2C software reset.
+ * @note When software reset is enabled, the I2C IOs are released (this can
+ * be useful to recover from bus errors).
+ * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral.
+ * @param NewState: new state of the I2C software reset.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void I2C_SoftwareResetCmd(I2C_TypeDef* I2Cx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ if (NewState != DISABLE)
+ {
+ /* Peripheral under reset */
+ I2Cx->CR1 |= I2C_CR1_SWRST;
+ }
+ else
+ {
+ /* Peripheral not under reset */
+ I2Cx->CR1 &= (uint16_t)~((uint16_t)I2C_CR1_SWRST);
+ }
+}
+
+/**
+ * @brief Enables or disables the specified I2C Clock stretching.
+ * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral.
+ * @param NewState: new state of the I2Cx Clock stretching.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void I2C_StretchClockCmd(I2C_TypeDef* I2Cx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ if (NewState == DISABLE)
+ {
+ /* Enable the selected I2C Clock stretching */
+ I2Cx->CR1 |= I2C_CR1_NOSTRETCH;
+ }
+ else
+ {
+ /* Disable the selected I2C Clock stretching */
+ I2Cx->CR1 &= (uint16_t)~((uint16_t)I2C_CR1_NOSTRETCH);
+ }
+}
+
+/**
+ * @brief Selects the specified I2C fast mode duty cycle.
+ * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral.
+ * @param I2C_DutyCycle: specifies the fast mode duty cycle.
+ * This parameter can be one of the following values:
+ * @arg I2C_DutyCycle_2: I2C fast mode Tlow/Thigh = 2
+ * @arg I2C_DutyCycle_16_9: I2C fast mode Tlow/Thigh = 16/9
+ * @retval None
+ */
+void I2C_FastModeDutyCycleConfig(I2C_TypeDef* I2Cx, uint16_t I2C_DutyCycle)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(IS_I2C_DUTY_CYCLE(I2C_DutyCycle));
+ if (I2C_DutyCycle != I2C_DutyCycle_16_9)
+ {
+ /* I2C fast mode Tlow/Thigh=2 */
+ I2Cx->CCR &= I2C_DutyCycle_2;
+ }
+ else
+ {
+ /* I2C fast mode Tlow/Thigh=16/9 */
+ I2Cx->CCR |= I2C_DutyCycle_16_9;
+ }
+}
+
+/**
+ * @brief Selects the specified I2C NACK position in master receiver mode.
+ * @note This function is useful in I2C Master Receiver mode when the number
+ * of data to be received is equal to 2. In this case, this function
+ * should be called (with parameter I2C_NACKPosition_Next) before data
+ * reception starts,as described in the 2-byte reception procedure
+ * recommended in Reference Manual in Section: Master receiver.
+ * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral.
+ * @param I2C_NACKPosition: specifies the NACK position.
+ * This parameter can be one of the following values:
+ * @arg I2C_NACKPosition_Next: indicates that the next byte will be the last
+ * received byte.
+ * @arg I2C_NACKPosition_Current: indicates that current byte is the last
+ * received byte.
+ *
+ * @note This function configures the same bit (POS) as I2C_PECPositionConfig()
+ * but is intended to be used in I2C mode while I2C_PECPositionConfig()
+ * is intended to used in SMBUS mode.
+ *
+ * @retval None
+ */
+void I2C_NACKPositionConfig(I2C_TypeDef* I2Cx, uint16_t I2C_NACKPosition)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(IS_I2C_NACK_POSITION(I2C_NACKPosition));
+
+ /* Check the input parameter */
+ if (I2C_NACKPosition == I2C_NACKPosition_Next)
+ {
+ /* Next byte in shift register is the last received byte */
+ I2Cx->CR1 |= I2C_NACKPosition_Next;
+ }
+ else
+ {
+ /* Current byte in shift register is the last received byte */
+ I2Cx->CR1 &= I2C_NACKPosition_Current;
+ }
+}
+
+/**
+ * @brief Drives the SMBusAlert pin high or low for the specified I2C.
+ * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral.
+ * @param I2C_SMBusAlert: specifies SMBAlert pin level.
+ * This parameter can be one of the following values:
+ * @arg I2C_SMBusAlert_Low: SMBAlert pin driven low
+ * @arg I2C_SMBusAlert_High: SMBAlert pin driven high
+ * @retval None
+ */
+void I2C_SMBusAlertConfig(I2C_TypeDef* I2Cx, uint16_t I2C_SMBusAlert)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(IS_I2C_SMBUS_ALERT(I2C_SMBusAlert));
+ if (I2C_SMBusAlert == I2C_SMBusAlert_Low)
+ {
+ /* Drive the SMBusAlert pin Low */
+ I2Cx->CR1 |= I2C_SMBusAlert_Low;
+ }
+ else
+ {
+ /* Drive the SMBusAlert pin High */
+ I2Cx->CR1 &= I2C_SMBusAlert_High;
+ }
+}
+
+/**
+ * @brief Enables or disables the specified I2C ARP.
+ * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral.
+ * @param NewState: new state of the I2Cx ARP.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void I2C_ARPCmd(I2C_TypeDef* I2Cx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ if (NewState != DISABLE)
+ {
+ /* Enable the selected I2C ARP */
+ I2Cx->CR1 |= I2C_CR1_ENARP;
+ }
+ else
+ {
+ /* Disable the selected I2C ARP */
+ I2Cx->CR1 &= (uint16_t)~((uint16_t)I2C_CR1_ENARP);
+ }
+}
+/**
+ * @}
+ */
+
+/** @defgroup I2C_Group2 Data transfers functions
+ * @brief Data transfers functions
+ *
+@verbatim
+ ===============================================================================
+ Data transfers functions
+ ===============================================================================
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Sends a data byte through the I2Cx peripheral.
+ * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral.
+ * @param Data: Byte to be transmitted..
+ * @retval None
+ */
+void I2C_SendData(I2C_TypeDef* I2Cx, uint8_t Data)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ /* Write in the DR register the data to be sent */
+ I2Cx->DR = Data;
+}
+
+/**
+ * @brief Returns the most recent received data by the I2Cx peripheral.
+ * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral.
+ * @retval The value of the received data.
+ */
+uint8_t I2C_ReceiveData(I2C_TypeDef* I2Cx)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ /* Return the data in the DR register */
+ return (uint8_t)I2Cx->DR;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup I2C_Group3 PEC management functions
+ * @brief PEC management functions
+ *
+@verbatim
+ ===============================================================================
+ PEC management functions
+ ===============================================================================
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Enables or disables the specified I2C PEC transfer.
+ * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral.
+ * @param NewState: new state of the I2C PEC transmission.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void I2C_TransmitPEC(I2C_TypeDef* I2Cx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ if (NewState != DISABLE)
+ {
+ /* Enable the selected I2C PEC transmission */
+ I2Cx->CR1 |= I2C_CR1_PEC;
+ }
+ else
+ {
+ /* Disable the selected I2C PEC transmission */
+ I2Cx->CR1 &= (uint16_t)~((uint16_t)I2C_CR1_PEC);
+ }
+}
+
+/**
+ * @brief Selects the specified I2C PEC position.
+ * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral.
+ * @param I2C_PECPosition: specifies the PEC position.
+ * This parameter can be one of the following values:
+ * @arg I2C_PECPosition_Next: indicates that the next byte is PEC
+ * @arg I2C_PECPosition_Current: indicates that current byte is PEC
+ *
+ * @note This function configures the same bit (POS) as I2C_NACKPositionConfig()
+ * but is intended to be used in SMBUS mode while I2C_NACKPositionConfig()
+ * is intended to used in I2C mode.
+ *
+ * @retval None
+ */
+void I2C_PECPositionConfig(I2C_TypeDef* I2Cx, uint16_t I2C_PECPosition)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(IS_I2C_PEC_POSITION(I2C_PECPosition));
+ if (I2C_PECPosition == I2C_PECPosition_Next)
+ {
+ /* Next byte in shift register is PEC */
+ I2Cx->CR1 |= I2C_PECPosition_Next;
+ }
+ else
+ {
+ /* Current byte in shift register is PEC */
+ I2Cx->CR1 &= I2C_PECPosition_Current;
+ }
+}
+
+/**
+ * @brief Enables or disables the PEC value calculation of the transferred bytes.
+ * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral.
+ * @param NewState: new state of the I2Cx PEC value calculation.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void I2C_CalculatePEC(I2C_TypeDef* I2Cx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ if (NewState != DISABLE)
+ {
+ /* Enable the selected I2C PEC calculation */
+ I2Cx->CR1 |= I2C_CR1_ENPEC;
+ }
+ else
+ {
+ /* Disable the selected I2C PEC calculation */
+ I2Cx->CR1 &= (uint16_t)~((uint16_t)I2C_CR1_ENPEC);
+ }
+}
+
+/**
+ * @brief Returns the PEC value for the specified I2C.
+ * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral.
+ * @retval The PEC value.
+ */
+uint8_t I2C_GetPEC(I2C_TypeDef* I2Cx)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ /* Return the selected I2C PEC value */
+ return ((I2Cx->SR2) >> 8);
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup I2C_Group4 DMA transfers management functions
+ * @brief DMA transfers management functions
+ *
+@verbatim
+ ===============================================================================
+ DMA transfers management functions
+ ===============================================================================
+ This section provides functions allowing to configure the I2C DMA channels
+ requests.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Enables or disables the specified I2C DMA requests.
+ * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral.
+ * @param NewState: new state of the I2C DMA transfer.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void I2C_DMACmd(I2C_TypeDef* I2Cx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ if (NewState != DISABLE)
+ {
+ /* Enable the selected I2C DMA requests */
+ I2Cx->CR2 |= I2C_CR2_DMAEN;
+ }
+ else
+ {
+ /* Disable the selected I2C DMA requests */
+ I2Cx->CR2 &= (uint16_t)~((uint16_t)I2C_CR2_DMAEN);
+ }
+}
+
+/**
+ * @brief Specifies that the next DMA transfer is the last one.
+ * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral.
+ * @param NewState: new state of the I2C DMA last transfer.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void I2C_DMALastTransferCmd(I2C_TypeDef* I2Cx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ if (NewState != DISABLE)
+ {
+ /* Next DMA transfer is the last transfer */
+ I2Cx->CR2 |= I2C_CR2_LAST;
+ }
+ else
+ {
+ /* Next DMA transfer is not the last transfer */
+ I2Cx->CR2 &= (uint16_t)~((uint16_t)I2C_CR2_LAST);
+ }
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup I2C_Group5 Interrupts events and flags management functions
+ * @brief Interrupts, events and flags management functions
+ *
+@verbatim
+ ===============================================================================
+ Interrupts, events and flags management functions
+ ===============================================================================
+ This section provides functions allowing to configure the I2C Interrupts
+ sources and check or clear the flags or pending bits status.
+ The user should identify which mode will be used in his application to manage
+ the communication: Polling mode, Interrupt mode or DMA mode.
+
+ ===============================================================================
+ I2C State Monitoring Functions
+ ===============================================================================
+ This I2C driver provides three different ways for I2C state monitoring
+ depending on the application requirements and constraints:
+
+
+ 1. Basic state monitoring (Using I2C_CheckEvent() function)
+ -----------------------------------------------------------
+ It compares the status registers (SR1 and SR2) content to a given event
+ (can be the combination of one or more flags).
+ It returns SUCCESS if the current status includes the given flags
+ and returns ERROR if one or more flags are missing in the current status.
+
+ - When to use
+ - This function is suitable for most applications as well as for startup
+ activity since the events are fully described in the product reference
+ manual (RM0033).
+ - It is also suitable for users who need to define their own events.
+
+ - Limitations
+ - If an error occurs (ie. error flags are set besides to the monitored
+ flags), the I2C_CheckEvent() function may return SUCCESS despite
+ the communication hold or corrupted real state.
+ In this case, it is advised to use error interrupts to monitor
+ the error events and handle them in the interrupt IRQ handler.
+
+ @note
+ For error management, it is advised to use the following functions:
+ - I2C_ITConfig() to configure and enable the error interrupts (I2C_IT_ERR).
+ - I2Cx_ER_IRQHandler() which is called when the error interrupt occurs.
+ Where x is the peripheral instance (I2C1, I2C2 ...)
+ - I2C_GetFlagStatus() or I2C_GetITStatus() to be called into the
+ I2Cx_ER_IRQHandler() function in order to determine which error occurred.
+ - I2C_ClearFlag() or I2C_ClearITPendingBit() and/or I2C_SoftwareResetCmd()
+ and/or I2C_GenerateStop() in order to clear the error flag and source
+ and return to correct communication status.
+
+
+ 2. Advanced state monitoring (Using the function I2C_GetLastEvent())
+ --------------------------------------------------------------------
+ Using the function I2C_GetLastEvent() which returns the image of both status
+ registers in a single word (uint32_t) (Status Register 2 value is shifted left
+ by 16 bits and concatenated to Status Register 1).
+
+ - When to use
+ - This function is suitable for the same applications above but it
+ allows to overcome the mentioned limitation of I2C_GetFlagStatus()
+ function.
+ - The returned value could be compared to events already defined in
+ the library (stm32f2xx_i2c.h) or to custom values defined by user.
+ This function is suitable when multiple flags are monitored at the
+ same time.
+ - At the opposite of I2C_CheckEvent() function, this function allows
+ user to choose when an event is accepted (when all events flags are
+ set and no other flags are set or just when the needed flags are set
+ like I2C_CheckEvent() function.
+
+ - Limitations
+ - User may need to define his own events.
+ - Same remark concerning the error management is applicable for this
+ function if user decides to check only regular communication flags
+ (and ignores error flags).
+
+
+ 3. Flag-based state monitoring (Using the function I2C_GetFlagStatus())
+ -----------------------------------------------------------------------
+
+ Using the function I2C_GetFlagStatus() which simply returns the status of
+ one single flag (ie. I2C_FLAG_RXNE ...).
+
+ - When to use
+ - This function could be used for specific applications or in debug
+ phase.
+ - It is suitable when only one flag checking is needed (most I2C
+ events are monitored through multiple flags).
+ - Limitations:
+ - When calling this function, the Status register is accessed.
+ Some flags are cleared when the status register is accessed.
+ So checking the status of one Flag, may clear other ones.
+ - Function may need to be called twice or more in order to monitor
+ one single event.
+
+ For detailed description of Events, please refer to section I2C_Events in
+ stm32f2xx_i2c.h file.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Reads the specified I2C register and returns its value.
+ * @param I2C_Register: specifies the register to read.
+ * This parameter can be one of the following values:
+ * @arg I2C_Register_CR1: CR1 register.
+ * @arg I2C_Register_CR2: CR2 register.
+ * @arg I2C_Register_OAR1: OAR1 register.
+ * @arg I2C_Register_OAR2: OAR2 register.
+ * @arg I2C_Register_DR: DR register.
+ * @arg I2C_Register_SR1: SR1 register.
+ * @arg I2C_Register_SR2: SR2 register.
+ * @arg I2C_Register_CCR: CCR register.
+ * @arg I2C_Register_TRISE: TRISE register.
+ * @retval The value of the read register.
+ */
+uint16_t I2C_ReadRegister(I2C_TypeDef* I2Cx, uint8_t I2C_Register)
+{
+ __IO uint32_t tmp = 0;
+
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(IS_I2C_REGISTER(I2C_Register));
+
+ tmp = (uint32_t) I2Cx;
+ tmp += I2C_Register;
+
+ /* Return the selected register value */
+ return (*(__IO uint16_t *) tmp);
+}
+
+/**
+ * @brief Enables or disables the specified I2C interrupts.
+ * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral.
+ * @param I2C_IT: specifies the I2C interrupts sources to be enabled or disabled.
+ * This parameter can be any combination of the following values:
+ * @arg I2C_IT_BUF: Buffer interrupt mask
+ * @arg I2C_IT_EVT: Event interrupt mask
+ * @arg I2C_IT_ERR: Error interrupt mask
+ * @param NewState: new state of the specified I2C interrupts.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void I2C_ITConfig(I2C_TypeDef* I2Cx, uint16_t I2C_IT, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ assert_param(IS_I2C_CONFIG_IT(I2C_IT));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the selected I2C interrupts */
+ I2Cx->CR2 |= I2C_IT;
+ }
+ else
+ {
+ /* Disable the selected I2C interrupts */
+ I2Cx->CR2 &= (uint16_t)~I2C_IT;
+ }
+}
+
+/*
+ ===============================================================================
+ 1. Basic state monitoring
+ ===============================================================================
+ */
+
+/**
+ * @brief Checks whether the last I2Cx Event is equal to the one passed
+ * as parameter.
+ * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral.
+ * @param I2C_EVENT: specifies the event to be checked.
+ * This parameter can be one of the following values:
+ * @arg I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED: EV1
+ * @arg I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED: EV1
+ * @arg I2C_EVENT_SLAVE_TRANSMITTER_SECONDADDRESS_MATCHED: EV1
+ * @arg I2C_EVENT_SLAVE_RECEIVER_SECONDADDRESS_MATCHED: EV1
+ * @arg I2C_EVENT_SLAVE_GENERALCALLADDRESS_MATCHED: EV1
+ * @arg I2C_EVENT_SLAVE_BYTE_RECEIVED: EV2
+ * @arg (I2C_EVENT_SLAVE_BYTE_RECEIVED | I2C_FLAG_DUALF): EV2
+ * @arg (I2C_EVENT_SLAVE_BYTE_RECEIVED | I2C_FLAG_GENCALL): EV2
+ * @arg I2C_EVENT_SLAVE_BYTE_TRANSMITTED: EV3
+ * @arg (I2C_EVENT_SLAVE_BYTE_TRANSMITTED | I2C_FLAG_DUALF): EV3
+ * @arg (I2C_EVENT_SLAVE_BYTE_TRANSMITTED | I2C_FLAG_GENCALL): EV3
+ * @arg I2C_EVENT_SLAVE_ACK_FAILURE: EV3_2
+ * @arg I2C_EVENT_SLAVE_STOP_DETECTED: EV4
+ * @arg I2C_EVENT_MASTER_MODE_SELECT: EV5
+ * @arg I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED: EV6
+ * @arg I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED: EV6
+ * @arg I2C_EVENT_MASTER_BYTE_RECEIVED: EV7
+ * @arg I2C_EVENT_MASTER_BYTE_TRANSMITTING: EV8
+ * @arg I2C_EVENT_MASTER_BYTE_TRANSMITTED: EV8_2
+ * @arg I2C_EVENT_MASTER_MODE_ADDRESS10: EV9
+ *
+ * @note For detailed description of Events, please refer to section I2C_Events
+ * in stm32f2xx_i2c.h file.
+ *
+ * @retval An ErrorStatus enumeration value:
+ * - SUCCESS: Last event is equal to the I2C_EVENT
+ * - ERROR: Last event is different from the I2C_EVENT
+ */
+ErrorStatus I2C_CheckEvent(I2C_TypeDef* I2Cx, uint32_t I2C_EVENT)
+{
+ uint32_t lastevent = 0;
+ uint32_t flag1 = 0, flag2 = 0;
+ ErrorStatus status = ERROR;
+
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(IS_I2C_EVENT(I2C_EVENT));
+
+ /* Read the I2Cx status register */
+ flag1 = I2Cx->SR1;
+ flag2 = I2Cx->SR2;
+ flag2 = flag2 << 16;
+
+ /* Get the last event value from I2C status register */
+ lastevent = (flag1 | flag2) & FLAG_MASK;
+
+ /* Check whether the last event contains the I2C_EVENT */
+ if ((lastevent & I2C_EVENT) == I2C_EVENT)
+ {
+ /* SUCCESS: last event is equal to I2C_EVENT */
+ status = SUCCESS;
+ }
+ else
+ {
+ /* ERROR: last event is different from I2C_EVENT */
+ status = ERROR;
+ }
+ /* Return status */
+ return status;
+}
+
+/*
+ ===============================================================================
+ 2. Advanced state monitoring
+ ===============================================================================
+ */
+
+/**
+ * @brief Returns the last I2Cx Event.
+ * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral.
+ *
+ * @note For detailed description of Events, please refer to section I2C_Events
+ * in stm32f2xx_i2c.h file.
+ *
+ * @retval The last event
+ */
+uint32_t I2C_GetLastEvent(I2C_TypeDef* I2Cx)
+{
+ uint32_t lastevent = 0;
+ uint32_t flag1 = 0, flag2 = 0;
+
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+
+ /* Read the I2Cx status register */
+ flag1 = I2Cx->SR1;
+ flag2 = I2Cx->SR2;
+ flag2 = flag2 << 16;
+
+ /* Get the last event value from I2C status register */
+ lastevent = (flag1 | flag2) & FLAG_MASK;
+
+ /* Return status */
+ return lastevent;
+}
+
+/*
+ ===============================================================================
+ 3. Flag-based state monitoring
+ ===============================================================================
+ */
+
+/**
+ * @brief Checks whether the specified I2C flag is set or not.
+ * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral.
+ * @param I2C_FLAG: specifies the flag to check.
+ * This parameter can be one of the following values:
+ * @arg I2C_FLAG_DUALF: Dual flag (Slave mode)
+ * @arg I2C_FLAG_SMBHOST: SMBus host header (Slave mode)
+ * @arg I2C_FLAG_SMBDEFAULT: SMBus default header (Slave mode)
+ * @arg I2C_FLAG_GENCALL: General call header flag (Slave mode)
+ * @arg I2C_FLAG_TRA: Transmitter/Receiver flag
+ * @arg I2C_FLAG_BUSY: Bus busy flag
+ * @arg I2C_FLAG_MSL: Master/Slave flag
+ * @arg I2C_FLAG_SMBALERT: SMBus Alert flag
+ * @arg I2C_FLAG_TIMEOUT: Timeout or Tlow error flag
+ * @arg I2C_FLAG_PECERR: PEC error in reception flag
+ * @arg I2C_FLAG_OVR: Overrun/Underrun flag (Slave mode)
+ * @arg I2C_FLAG_AF: Acknowledge failure flag
+ * @arg I2C_FLAG_ARLO: Arbitration lost flag (Master mode)
+ * @arg I2C_FLAG_BERR: Bus error flag
+ * @arg I2C_FLAG_TXE: Data register empty flag (Transmitter)
+ * @arg I2C_FLAG_RXNE: Data register not empty (Receiver) flag
+ * @arg I2C_FLAG_STOPF: Stop detection flag (Slave mode)
+ * @arg I2C_FLAG_ADD10: 10-bit header sent flag (Master mode)
+ * @arg I2C_FLAG_BTF: Byte transfer finished flag
+ * @arg I2C_FLAG_ADDR: Address sent flag (Master mode) "ADSL"
+ * Address matched flag (Slave mode)"ENDAD"
+ * @arg I2C_FLAG_SB: Start bit flag (Master mode)
+ * @retval The new state of I2C_FLAG (SET or RESET).
+ */
+FlagStatus I2C_GetFlagStatus(I2C_TypeDef* I2Cx, uint32_t I2C_FLAG)
+{
+ FlagStatus bitstatus = RESET;
+ __IO uint32_t i2creg = 0, i2cxbase = 0;
+
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(IS_I2C_GET_FLAG(I2C_FLAG));
+
+ /* Get the I2Cx peripheral base address */
+ i2cxbase = (uint32_t)I2Cx;
+
+ /* Read flag register index */
+ i2creg = I2C_FLAG >> 28;
+
+ /* Get bit[23:0] of the flag */
+ I2C_FLAG &= FLAG_MASK;
+
+ if(i2creg != 0)
+ {
+ /* Get the I2Cx SR1 register address */
+ i2cxbase += 0x14;
+ }
+ else
+ {
+ /* Flag in I2Cx SR2 Register */
+ I2C_FLAG = (uint32_t)(I2C_FLAG >> 16);
+ /* Get the I2Cx SR2 register address */
+ i2cxbase += 0x18;
+ }
+
+ if(((*(__IO uint32_t *)i2cxbase) & I2C_FLAG) != (uint32_t)RESET)
+ {
+ /* I2C_FLAG is set */
+ bitstatus = SET;
+ }
+ else
+ {
+ /* I2C_FLAG is reset */
+ bitstatus = RESET;
+ }
+
+ /* Return the I2C_FLAG status */
+ return bitstatus;
+}
+
+/**
+ * @brief Clears the I2Cx's pending flags.
+ * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral.
+ * @param I2C_FLAG: specifies the flag to clear.
+ * This parameter can be any combination of the following values:
+ * @arg I2C_FLAG_SMBALERT: SMBus Alert flag
+ * @arg I2C_FLAG_TIMEOUT: Timeout or Tlow error flag
+ * @arg I2C_FLAG_PECERR: PEC error in reception flag
+ * @arg I2C_FLAG_OVR: Overrun/Underrun flag (Slave mode)
+ * @arg I2C_FLAG_AF: Acknowledge failure flag
+ * @arg I2C_FLAG_ARLO: Arbitration lost flag (Master mode)
+ * @arg I2C_FLAG_BERR: Bus error flag
+ *
+ * @note STOPF (STOP detection) is cleared by software sequence: a read operation
+ * to I2C_SR1 register (I2C_GetFlagStatus()) followed by a write operation
+ * to I2C_CR1 register (I2C_Cmd() to re-enable the I2C peripheral).
+ * @note ADD10 (10-bit header sent) is cleared by software sequence: a read
+ * operation to I2C_SR1 (I2C_GetFlagStatus()) followed by writing the
+ * second byte of the address in DR register.
+ * @note BTF (Byte Transfer Finished) is cleared by software sequence: a read
+ * operation to I2C_SR1 register (I2C_GetFlagStatus()) followed by a
+ * read/write to I2C_DR register (I2C_SendData()).
+ * @note ADDR (Address sent) is cleared by software sequence: a read operation to
+ * I2C_SR1 register (I2C_GetFlagStatus()) followed by a read operation to
+ * I2C_SR2 register ((void)(I2Cx->SR2)).
+ * @note SB (Start Bit) is cleared software sequence: a read operation to I2C_SR1
+ * register (I2C_GetFlagStatus()) followed by a write operation to I2C_DR
+ * register (I2C_SendData()).
+ *
+ * @retval None
+ */
+void I2C_ClearFlag(I2C_TypeDef* I2Cx, uint32_t I2C_FLAG)
+{
+ uint32_t flagpos = 0;
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(IS_I2C_CLEAR_FLAG(I2C_FLAG));
+ /* Get the I2C flag position */
+ flagpos = I2C_FLAG & FLAG_MASK;
+ /* Clear the selected I2C flag */
+ I2Cx->SR1 = (uint16_t)~flagpos;
+}
+
+/**
+ * @brief Checks whether the specified I2C interrupt has occurred or not.
+ * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral.
+ * @param I2C_IT: specifies the interrupt source to check.
+ * This parameter can be one of the following values:
+ * @arg I2C_IT_SMBALERT: SMBus Alert flag
+ * @arg I2C_IT_TIMEOUT: Timeout or Tlow error flag
+ * @arg I2C_IT_PECERR: PEC error in reception flag
+ * @arg I2C_IT_OVR: Overrun/Underrun flag (Slave mode)
+ * @arg I2C_IT_AF: Acknowledge failure flag
+ * @arg I2C_IT_ARLO: Arbitration lost flag (Master mode)
+ * @arg I2C_IT_BERR: Bus error flag
+ * @arg I2C_IT_TXE: Data register empty flag (Transmitter)
+ * @arg I2C_IT_RXNE: Data register not empty (Receiver) flag
+ * @arg I2C_IT_STOPF: Stop detection flag (Slave mode)
+ * @arg I2C_IT_ADD10: 10-bit header sent flag (Master mode)
+ * @arg I2C_IT_BTF: Byte transfer finished flag
+ * @arg I2C_IT_ADDR: Address sent flag (Master mode) "ADSL"
+ * Address matched flag (Slave mode)"ENDAD"
+ * @arg I2C_IT_SB: Start bit flag (Master mode)
+ * @retval The new state of I2C_IT (SET or RESET).
+ */
+ITStatus I2C_GetITStatus(I2C_TypeDef* I2Cx, uint32_t I2C_IT)
+{
+ ITStatus bitstatus = RESET;
+ uint32_t enablestatus = 0;
+
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(IS_I2C_GET_IT(I2C_IT));
+
+ /* Check if the interrupt source is enabled or not */
+ enablestatus = (uint32_t)(((I2C_IT & ITEN_MASK) >> 16) & (I2Cx->CR2)) ;
+
+ /* Get bit[23:0] of the flag */
+ I2C_IT &= FLAG_MASK;
+
+ /* Check the status of the specified I2C flag */
+ if (((I2Cx->SR1 & I2C_IT) != (uint32_t)RESET) && enablestatus)
+ {
+ /* I2C_IT is set */
+ bitstatus = SET;
+ }
+ else
+ {
+ /* I2C_IT is reset */
+ bitstatus = RESET;
+ }
+ /* Return the I2C_IT status */
+ return bitstatus;
+}
+
+/**
+ * @brief Clears the I2Cx's interrupt pending bits.
+ * @param I2Cx: where x can be 1, 2 or 3 to select the I2C peripheral.
+ * @param I2C_IT: specifies the interrupt pending bit to clear.
+ * This parameter can be any combination of the following values:
+ * @arg I2C_IT_SMBALERT: SMBus Alert interrupt
+ * @arg I2C_IT_TIMEOUT: Timeout or Tlow error interrupt
+ * @arg I2C_IT_PECERR: PEC error in reception interrupt
+ * @arg I2C_IT_OVR: Overrun/Underrun interrupt (Slave mode)
+ * @arg I2C_IT_AF: Acknowledge failure interrupt
+ * @arg I2C_IT_ARLO: Arbitration lost interrupt (Master mode)
+ * @arg I2C_IT_BERR: Bus error interrupt
+ *
+ * @note STOPF (STOP detection) is cleared by software sequence: a read operation
+ * to I2C_SR1 register (I2C_GetITStatus()) followed by a write operation to
+ * I2C_CR1 register (I2C_Cmd() to re-enable the I2C peripheral).
+ * @note ADD10 (10-bit header sent) is cleared by software sequence: a read
+ * operation to I2C_SR1 (I2C_GetITStatus()) followed by writing the second
+ * byte of the address in I2C_DR register.
+ * @note BTF (Byte Transfer Finished) is cleared by software sequence: a read
+ * operation to I2C_SR1 register (I2C_GetITStatus()) followed by a
+ * read/write to I2C_DR register (I2C_SendData()).
+ * @note ADDR (Address sent) is cleared by software sequence: a read operation to
+ * I2C_SR1 register (I2C_GetITStatus()) followed by a read operation to
+ * I2C_SR2 register ((void)(I2Cx->SR2)).
+ * @note SB (Start Bit) is cleared by software sequence: a read operation to
+ * I2C_SR1 register (I2C_GetITStatus()) followed by a write operation to
+ * I2C_DR register (I2C_SendData()).
+ * @retval None
+ */
+void I2C_ClearITPendingBit(I2C_TypeDef* I2Cx, uint32_t I2C_IT)
+{
+ uint32_t flagpos = 0;
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(IS_I2C_CLEAR_IT(I2C_IT));
+
+ /* Get the I2C flag position */
+ flagpos = I2C_IT & FLAG_MASK;
+
+ /* Clear the selected I2C flag */
+ I2Cx->SR1 = (uint16_t)~flagpos;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/src/stm32f2xx_iwdg.c b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/src/stm32f2xx_iwdg.c
new file mode 100644
index 0000000..3939a17
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/src/stm32f2xx_iwdg.c
@@ -0,0 +1,269 @@
+/**
+ ******************************************************************************
+ * @file stm32f2xx_iwdg.c
+ * @author MCD Application Team
+ * @version V1.1.2
+ * @date 05-March-2012
+ * @brief This file provides firmware functions to manage the following
+ * functionalities of the Independent watchdog (IWDG) peripheral:
+ * - Prescaler and Counter configuration
+ * - IWDG activation
+ * - Flag management
+ *
+ * @verbatim
+ *
+ * ===================================================================
+ * IWDG features
+ * ===================================================================
+ *
+ * The IWDG can be started by either software or hardware (configurable
+ * through option byte).
+ *
+ * The IWDG is clocked by its own dedicated low-speed clock (LSI) and
+ * thus stays active even if the main clock fails.
+ * Once the IWDG is started, the LSI is forced ON and cannot be disabled
+ * (LSI cannot be disabled too), and the counter starts counting down from
+ * the reset value of 0xFFF. When it reaches the end of count value (0x000)
+ * a system reset is generated.
+ * The IWDG counter should be reloaded at regular intervals to prevent
+ * an MCU reset.
+ *
+ * The IWDG is implemented in the VDD voltage domain that is still functional
+ * in STOP and STANDBY mode (IWDG reset can wake-up from STANDBY).
+ *
+ * IWDGRST flag in RCC_CSR register can be used to inform when a IWDG
+ * reset occurs.
+ *
+ * Min-max timeout value @32KHz (LSI): ~125us / ~32.7s
+ * The IWDG timeout may vary due to LSI frequency dispersion. STM32F2xx
+ * devices provide the capability to measure the LSI frequency (LSI clock
+ * connected internally to TIM5 CH4 input capture). The measured value
+ * can be used to have an IWDG timeout with an acceptable accuracy.
+ * For more information, please refer to the STM32F2xx Reference manual
+ *
+ *
+ * ===================================================================
+ * How to use this driver
+ * ===================================================================
+ * 1. Enable write access to IWDG_PR and IWDG_RLR registers using
+ * IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable) function
+ *
+ * 2. Configure the IWDG prescaler using IWDG_SetPrescaler() function
+ *
+ * 3. Configure the IWDG counter value using IWDG_SetReload() function.
+ * This value will be loaded in the IWDG counter each time the counter
+ * is reloaded, then the IWDG will start counting down from this value.
+ *
+ * 4. Start the IWDG using IWDG_Enable() function, when the IWDG is used
+ * in software mode (no need to enable the LSI, it will be enabled
+ * by hardware)
+ *
+ * 5. Then the application program must reload the IWDG counter at regular
+ * intervals during normal operation to prevent an MCU reset, using
+ * IWDG_ReloadCounter() function.
+ *
+ * @endverbatim
+ *
+ ******************************************************************************
+ * @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 "stm32f2xx_iwdg.h"
+
+/** @addtogroup STM32F2xx_StdPeriph_Driver
+ * @{
+ */
+
+/** @defgroup IWDG
+ * @brief IWDG driver modules
+ * @{
+ */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+
+/* KR register bit mask */
+#define KR_KEY_RELOAD ((uint16_t)0xAAAA)
+#define KR_KEY_ENABLE ((uint16_t)0xCCCC)
+
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+/** @defgroup IWDG_Private_Functions
+ * @{
+ */
+
+/** @defgroup IWDG_Group1 Prescaler and Counter configuration functions
+ * @brief Prescaler and Counter configuration functions
+ *
+@verbatim
+ ===============================================================================
+ Prescaler and Counter configuration functions
+ ===============================================================================
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Enables or disables write access to IWDG_PR and IWDG_RLR registers.
+ * @param IWDG_WriteAccess: new state of write access to IWDG_PR and IWDG_RLR registers.
+ * This parameter can be one of the following values:
+ * @arg IWDG_WriteAccess_Enable: Enable write access to IWDG_PR and IWDG_RLR registers
+ * @arg IWDG_WriteAccess_Disable: Disable write access to IWDG_PR and IWDG_RLR registers
+ * @retval None
+ */
+void IWDG_WriteAccessCmd(uint16_t IWDG_WriteAccess)
+{
+ /* Check the parameters */
+ assert_param(IS_IWDG_WRITE_ACCESS(IWDG_WriteAccess));
+ IWDG->KR = IWDG_WriteAccess;
+}
+
+/**
+ * @brief Sets IWDG Prescaler value.
+ * @param IWDG_Prescaler: specifies the IWDG Prescaler value.
+ * This parameter can be one of the following values:
+ * @arg IWDG_Prescaler_4: IWDG prescaler set to 4
+ * @arg IWDG_Prescaler_8: IWDG prescaler set to 8
+ * @arg IWDG_Prescaler_16: IWDG prescaler set to 16
+ * @arg IWDG_Prescaler_32: IWDG prescaler set to 32
+ * @arg IWDG_Prescaler_64: IWDG prescaler set to 64
+ * @arg IWDG_Prescaler_128: IWDG prescaler set to 128
+ * @arg IWDG_Prescaler_256: IWDG prescaler set to 256
+ * @retval None
+ */
+void IWDG_SetPrescaler(uint8_t IWDG_Prescaler)
+{
+ /* Check the parameters */
+ assert_param(IS_IWDG_PRESCALER(IWDG_Prescaler));
+ IWDG->PR = IWDG_Prescaler;
+}
+
+/**
+ * @brief Sets IWDG Reload value.
+ * @param Reload: specifies the IWDG Reload value.
+ * This parameter must be a number between 0 and 0x0FFF.
+ * @retval None
+ */
+void IWDG_SetReload(uint16_t Reload)
+{
+ /* Check the parameters */
+ assert_param(IS_IWDG_RELOAD(Reload));
+ IWDG->RLR = Reload;
+}
+
+/**
+ * @brief Reloads IWDG counter with value defined in the reload register
+ * (write access to IWDG_PR and IWDG_RLR registers disabled).
+ * @param None
+ * @retval None
+ */
+void IWDG_ReloadCounter(void)
+{
+ IWDG->KR = KR_KEY_RELOAD;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup IWDG_Group2 IWDG activation function
+ * @brief IWDG activation function
+ *
+@verbatim
+ ===============================================================================
+ IWDG activation function
+ ===============================================================================
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Enables IWDG (write access to IWDG_PR and IWDG_RLR registers disabled).
+ * @param None
+ * @retval None
+ */
+void IWDG_Enable(void)
+{
+ IWDG->KR = KR_KEY_ENABLE;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup IWDG_Group3 Flag management function
+ * @brief Flag management function
+ *
+@verbatim
+ ===============================================================================
+ Flag management function
+ ===============================================================================
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Checks whether the specified IWDG flag is set or not.
+ * @param IWDG_FLAG: specifies the flag to check.
+ * This parameter can be one of the following values:
+ * @arg IWDG_FLAG_PVU: Prescaler Value Update on going
+ * @arg IWDG_FLAG_RVU: Reload Value Update on going
+ * @retval The new state of IWDG_FLAG (SET or RESET).
+ */
+FlagStatus IWDG_GetFlagStatus(uint16_t IWDG_FLAG)
+{
+ FlagStatus bitstatus = RESET;
+ /* Check the parameters */
+ assert_param(IS_IWDG_FLAG(IWDG_FLAG));
+ if ((IWDG->SR & IWDG_FLAG) != (uint32_t)RESET)
+ {
+ bitstatus = SET;
+ }
+ else
+ {
+ bitstatus = RESET;
+ }
+ /* Return the flag status */
+ return bitstatus;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/src/stm32f2xx_pwr.c b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/src/stm32f2xx_pwr.c
new file mode 100644
index 0000000..99ad2dc
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/src/stm32f2xx_pwr.c
@@ -0,0 +1,620 @@
+/**
+ ******************************************************************************
+ * @file stm32f2xx_pwr.c
+ * @author MCD Application Team
+ * @version V1.1.2
+ * @date 05-March-2012
+ * @brief This file provides firmware functions to manage the following
+ * functionalities of the Power Controller (PWR) peripheral:
+ * - Backup Domain Access
+ * - PVD configuration
+ * - WakeUp pin configuration
+ * - Backup Regulator configuration
+ * - FLASH Power Down configuration
+ * - Low Power modes configuration
+ * - Flags management
+ *
+ ******************************************************************************
+ * @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 "stm32f2xx_pwr.h"
+#include "stm32f2xx_rcc.h"
+
+/** @addtogroup STM32F2xx_StdPeriph_Driver
+ * @{
+ */
+
+/** @defgroup PWR
+ * @brief PWR driver modules
+ * @{
+ */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* --------- PWR registers bit address in the alias region ---------- */
+#define PWR_OFFSET (PWR_BASE - PERIPH_BASE)
+
+/* --- CR Register ---*/
+
+/* Alias word address of DBP bit */
+#define CR_OFFSET (PWR_OFFSET + 0x00)
+#define DBP_BitNumber 0x08
+#define CR_DBP_BB (PERIPH_BB_BASE + (CR_OFFSET * 32) + (DBP_BitNumber * 4))
+
+/* Alias word address of PVDE bit */
+#define PVDE_BitNumber 0x04
+#define CR_PVDE_BB (PERIPH_BB_BASE + (CR_OFFSET * 32) + (PVDE_BitNumber * 4))
+
+/* Alias word address of FPDS bit */
+#define FPDS_BitNumber 0x09
+#define CR_FPDS_BB (PERIPH_BB_BASE + (CR_OFFSET * 32) + (FPDS_BitNumber * 4))
+
+/* --- CSR Register ---*/
+
+/* Alias word address of EWUP bit */
+#define CSR_OFFSET (PWR_OFFSET + 0x04)
+#define EWUP_BitNumber 0x08
+#define CSR_EWUP_BB (PERIPH_BB_BASE + (CSR_OFFSET * 32) + (EWUP_BitNumber * 4))
+
+/* Alias word address of BRE bit */
+#define BRE_BitNumber 0x09
+#define CSR_BRE_BB (PERIPH_BB_BASE + (CSR_OFFSET * 32) + (BRE_BitNumber * 4))
+
+/* ------------------ PWR registers bit mask ------------------------ */
+
+/* CR register bit mask */
+#define CR_DS_MASK ((uint32_t)0xFFFFFFFC)
+#define CR_PLS_MASK ((uint32_t)0xFFFFFF1F)
+
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+/** @defgroup PWR_Private_Functions
+ * @{
+ */
+
+/** @defgroup PWR_Group1 Backup Domain Access function
+ * @brief Backup Domain Access function
+ *
+@verbatim
+ ===============================================================================
+ Backup Domain Access function
+ ===============================================================================
+
+ After reset, the backup domain (RTC registers, RTC backup data
+ registers and backup SRAM) is protected against possible unwanted
+ write accesses.
+ To enable access to the RTC Domain and RTC registers, proceed as follows:
+ - Enable the Power Controller (PWR) APB1 interface clock using the
+ RCC_APB1PeriphClockCmd() function.
+ - Enable access to RTC domain using the PWR_BackupAccessCmd() function.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Deinitializes the PWR peripheral registers to their default reset values.
+ * @param None
+ * @retval None
+ */
+void PWR_DeInit(void)
+{
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_PWR, ENABLE);
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_PWR, DISABLE);
+}
+
+/**
+ * @brief Enables or disables access to the backup domain (RTC registers, RTC
+ * backup data registers and backup SRAM).
+ * @note If the HSE divided by 2, 3, ..31 is used as the RTC clock, the
+ * Backup Domain Access should be kept enabled.
+ * @param NewState: new state of the access to the backup domain.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void PWR_BackupAccessCmd(FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ *(__IO uint32_t *) CR_DBP_BB = (uint32_t)NewState;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup PWR_Group2 PVD configuration functions
+ * @brief PVD configuration functions
+ *
+@verbatim
+ ===============================================================================
+ PVD configuration functions
+ ===============================================================================
+
+ - The PVD is used to monitor the VDD power supply by comparing it to a threshold
+ selected by the PVD Level (PLS[2:0] bits in the PWR_CR).
+ - A PVDO flag is available to indicate if VDD/VDDA is higher or lower than the
+ PVD threshold. This event is internally connected to the EXTI line16
+ and can generate an interrupt if enabled through the EXTI registers.
+ - The PVD is stopped in Standby mode.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Configures the voltage threshold detected by the Power Voltage Detector(PVD).
+ * @param PWR_PVDLevel: specifies the PVD detection level
+ * This parameter can be one of the following values:
+ * @arg PWR_PVDLevel_0
+ * @arg PWR_PVDLevel_1
+ * @arg PWR_PVDLevel_2
+ * @arg PWR_PVDLevel_3
+ * @arg PWR_PVDLevel_4
+ * @arg PWR_PVDLevel_5
+ * @arg PWR_PVDLevel_6
+ * @arg PWR_PVDLevel_7
+ * @note Refer to the electrical characteristics of your device datasheet for
+ * more details about the voltage threshold corresponding to each
+ * detection level.
+ * @retval None
+ */
+void PWR_PVDLevelConfig(uint32_t PWR_PVDLevel)
+{
+ uint32_t tmpreg = 0;
+
+ /* Check the parameters */
+ assert_param(IS_PWR_PVD_LEVEL(PWR_PVDLevel));
+
+ tmpreg = PWR->CR;
+
+ /* Clear PLS[7:5] bits */
+ tmpreg &= CR_PLS_MASK;
+
+ /* Set PLS[7:5] bits according to PWR_PVDLevel value */
+ tmpreg |= PWR_PVDLevel;
+
+ /* Store the new value */
+ PWR->CR = tmpreg;
+}
+
+/**
+ * @brief Enables or disables the Power Voltage Detector(PVD).
+ * @param NewState: new state of the PVD.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void PWR_PVDCmd(FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ *(__IO uint32_t *) CR_PVDE_BB = (uint32_t)NewState;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup PWR_Group3 WakeUp pin configuration functions
+ * @brief WakeUp pin configuration functions
+ *
+@verbatim
+ ===============================================================================
+ WakeUp pin configuration functions
+ ===============================================================================
+
+ - WakeUp pin is used to wakeup the system from Standby mode. This pin is
+ forced in input pull down configuration and is active on rising edges.
+ - There is only one WakeUp pin: WakeUp Pin 1 on PA.00.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Enables or disables the WakeUp Pin functionality.
+ * @param NewState: new state of the WakeUp Pin functionality.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void PWR_WakeUpPinCmd(FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ *(__IO uint32_t *) CSR_EWUP_BB = (uint32_t)NewState;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup PWR_Group4 Backup Regulator configuration functions
+ * @brief Backup Regulator configuration functions
+ *
+@verbatim
+ ===============================================================================
+ Backup Regulator configuration functions
+ ===============================================================================
+
+ - The backup domain includes 4 Kbytes of backup SRAM accessible only from the
+ CPU, and address in 32-bit, 16-bit or 8-bit mode. Its content is retained
+ even in Standby or VBAT mode when the low power backup regulator is enabled.
+ It can be considered as an internal EEPROM when VBAT is always present.
+ You can use the PWR_BackupRegulatorCmd() function to enable the low power
+ backup regulator and use the PWR_GetFlagStatus(PWR_FLAG_BRR) to check if it is
+ ready or not.
+
+ - When the backup domain is supplied by VDD (analog switch connected to VDD)
+ the backup SRAM is powered from VDD which replaces the VBAT power supply to
+ save battery life.
+
+ - The backup SRAM is not mass erased by an tamper event. It is read protected
+ to prevent confidential data, such as cryptographic private key, from being
+ accessed. The backup SRAM can be erased only through the Flash interface when
+ a protection level change from level 1 to level 0 is requested.
+ Refer to the description of Read protection (RDP) in the Flash programming manual.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Enables or disables the Backup Regulator.
+ * @param NewState: new state of the Backup Regulator.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void PWR_BackupRegulatorCmd(FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ *(__IO uint32_t *) CSR_BRE_BB = (uint32_t)NewState;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup PWR_Group5 FLASH Power Down configuration functions
+ * @brief FLASH Power Down configuration functions
+ *
+@verbatim
+ ===============================================================================
+ FLASH Power Down configuration functions
+ ===============================================================================
+
+ - By setting the FPDS bit in the PWR_CR register by using the PWR_FlashPowerDownCmd()
+ function, the Flash memory also enters power down mode when the device enters
+ Stop mode. When the Flash memory is in power down mode, an additional startup
+ delay is incurred when waking up from Stop mode.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Enables or disables the Flash Power Down in STOP mode.
+ * @param NewState: new state of the Flash power mode.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void PWR_FlashPowerDownCmd(FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ *(__IO uint32_t *) CR_FPDS_BB = (uint32_t)NewState;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup PWR_Group6 Low Power modes configuration functions
+ * @brief Low Power modes configuration functions
+ *
+@verbatim
+ ===============================================================================
+ Low Power modes configuration functions
+ ===============================================================================
+
+ The devices feature 3 low-power modes:
+ - Sleep mode: Cortex-M3 core stopped, peripherals kept running.
+ - Stop mode: all clocks are stopped, regulator running, regulator in low power mode
+ - Standby mode: 1.2V domain powered off.
+
+ Sleep mode
+ ===========
+ - Entry:
+ - The Sleep mode is entered by using the __WFI() or __WFE() functions.
+ - Exit:
+ - Any peripheral interrupt acknowledged by the nested vectored interrupt
+ controller (NVIC) can wake up the device from Sleep mode.
+
+ Stop mode
+ ==========
+ In Stop mode, all clocks in the 1.2V domain are stopped, the PLL, the HSI,
+ and the HSE RC oscillators are disabled. Internal SRAM and register contents
+ are preserved.
+ The voltage regulator can be configured either in normal or low-power mode.
+ To minimize the consumption In Stop mode, FLASH can be powered off before
+ entering the Stop mode. It can be switched on again by software after exiting
+ the Stop mode using the PWR_FlashPowerDownCmd() function.
+
+ - Entry:
+ - The Stop mode is entered using the PWR_EnterSTOPMode(PWR_Regulator_LowPower,)
+ function with regulator in LowPower or with Regulator ON.
+ - Exit:
+ - Any EXTI Line (Internal or External) configured in Interrupt/Event mode.
+
+ Standby mode
+ ============
+ The Standby mode allows to achieve the lowest power consumption. It is based
+ on the Cortex-M3 deepsleep mode, with the voltage regulator disabled.
+ The 1.2V domain is consequently powered off. The PLL, the HSI oscillator and
+ the HSE oscillator are also switched off. SRAM and register contents are lost
+ except for the RTC registers, RTC backup registers, backup SRAM and Standby
+ circuitry.
+
+ The voltage regulator is OFF.
+
+ - Entry:
+ - The Standby mode is entered using the PWR_EnterSTANDBYMode() function.
+ - Exit:
+ - WKUP pin rising edge, RTC alarm (Alarm A and Alarm B), RTC wakeup,
+ tamper event, time-stamp event, external reset in NRST pin, IWDG reset.
+
+ Auto-wakeup (AWU) from low-power mode
+ =====================================
+ The MCU can be woken up from low-power mode by an RTC Alarm event, an RTC
+ Wakeup event, a tamper event, a time-stamp event, or a comparator event,
+ without depending on an external interrupt (Auto-wakeup mode).
+
+ - RTC auto-wakeup (AWU) from the Stop mode
+ ----------------------------------------
+
+ - To wake up from the Stop mode with an RTC alarm event, it is necessary to:
+ - Configure the EXTI Line 17 to be sensitive to rising edges (Interrupt
+ or Event modes) using the EXTI_Init() function.
+ - Enable the RTC Alarm Interrupt using the RTC_ITConfig() function
+ - Configure the RTC to generate the RTC alarm using the RTC_SetAlarm()
+ and RTC_AlarmCmd() functions.
+ - To wake up from the Stop mode with an RTC Tamper or time stamp event, it
+ is necessary to:
+ - Configure the EXTI Line 21 to be sensitive to rising edges (Interrupt
+ or Event modes) using the EXTI_Init() function.
+ - Enable the RTC Tamper or time stamp Interrupt using the RTC_ITConfig()
+ function
+ - Configure the RTC to detect the tamper or time stamp event using the
+ RTC_TimeStampConfig(), RTC_TamperTriggerConfig() and RTC_TamperCmd()
+ functions.
+ - To wake up from the Stop mode with an RTC WakeUp event, it is necessary to:
+ - Configure the EXTI Line 22 to be sensitive to rising edges (Interrupt
+ or Event modes) using the EXTI_Init() function.
+ - Enable the RTC WakeUp Interrupt using the RTC_ITConfig() function
+ - Configure the RTC to generate the RTC WakeUp event using the RTC_WakeUpClockConfig(),
+ RTC_SetWakeUpCounter() and RTC_WakeUpCmd() functions.
+
+ - RTC auto-wakeup (AWU) from the Standby mode
+ -------------------------------------------
+ - To wake up from the Standby mode with an RTC alarm event, it is necessary to:
+ - Enable the RTC Alarm Interrupt using the RTC_ITConfig() function
+ - Configure the RTC to generate the RTC alarm using the RTC_SetAlarm()
+ and RTC_AlarmCmd() functions.
+ - To wake up from the Standby mode with an RTC Tamper or time stamp event, it
+ is necessary to:
+ - Enable the RTC Tamper or time stamp Interrupt using the RTC_ITConfig()
+ function
+ - Configure the RTC to detect the tamper or time stamp event using the
+ RTC_TimeStampConfig(), RTC_TamperTriggerConfig() and RTC_TamperCmd()
+ functions.
+ - To wake up from the Standby mode with an RTC WakeUp event, it is necessary to:
+ - Enable the RTC WakeUp Interrupt using the RTC_ITConfig() function
+ - Configure the RTC to generate the RTC WakeUp event using the RTC_WakeUpClockConfig(),
+ RTC_SetWakeUpCounter() and RTC_WakeUpCmd() functions.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Enters STOP mode.
+ *
+ * @note In Stop mode, all I/O pins keep the same state as in Run mode.
+ * @note When exiting Stop mode by issuing an interrupt or a wakeup event,
+ * the HSI RC oscillator is selected as system clock.
+ * @note When the voltage regulator operates in low power mode, an additional
+ * startup delay is incurred when waking up from Stop mode.
+ * By keeping the internal regulator ON during Stop mode, the consumption
+ * is higher although the startup time is reduced.
+ *
+ * @param PWR_Regulator: specifies the regulator state in STOP mode.
+ * This parameter can be one of the following values:
+ * @arg PWR_Regulator_ON: STOP mode with regulator ON
+ * @arg PWR_Regulator_LowPower: STOP mode with regulator in low power mode
+ * @param PWR_STOPEntry: specifies if STOP mode in entered with WFI or WFE instruction.
+ * This parameter can be one of the following values:
+ * @arg PWR_STOPEntry_WFI: enter STOP mode with WFI instruction
+ * @arg PWR_STOPEntry_WFE: enter STOP mode with WFE instruction
+ * @retval None
+ */
+void PWR_EnterSTOPMode(uint32_t PWR_Regulator, uint8_t PWR_STOPEntry)
+{
+ uint32_t tmpreg = 0;
+
+ /* Check the parameters */
+ assert_param(IS_PWR_REGULATOR(PWR_Regulator));
+ assert_param(IS_PWR_STOP_ENTRY(PWR_STOPEntry));
+
+ /* Select the regulator state in STOP mode ---------------------------------*/
+ tmpreg = PWR->CR;
+ /* Clear PDDS and LPDSR bits */
+ tmpreg &= CR_DS_MASK;
+
+ /* Set LPDSR bit according to PWR_Regulator value */
+ tmpreg |= PWR_Regulator;
+
+ /* Store the new value */
+ PWR->CR = tmpreg;
+
+ /* Set SLEEPDEEP bit of Cortex System Control Register */
+ SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
+
+ /* Select STOP mode entry --------------------------------------------------*/
+ if(PWR_STOPEntry == PWR_STOPEntry_WFI)
+ {
+ /* Request Wait For Interrupt */
+ __WFI();
+ }
+ else
+ {
+ /* Request Wait For Event */
+ __WFE();
+ }
+ /* Reset SLEEPDEEP bit of Cortex System Control Register */
+ SCB->SCR &= (uint32_t)~((uint32_t)SCB_SCR_SLEEPDEEP_Msk);
+}
+
+/**
+ * @brief Enters STANDBY mode.
+ * @note In Standby mode, all I/O pins are high impedance except for:
+ * - Reset pad (still available)
+ * - RTC_AF1 pin (PC13) if configured for tamper, time-stamp, RTC
+ * Alarm out, or RTC clock calibration out.
+ * - RTC_AF2 pin (PI8) if configured for tamper or time-stamp.
+ * - WKUP pin 1 (PA0) if enabled.
+ * @param None
+ * @retval None
+ */
+void PWR_EnterSTANDBYMode(void)
+{
+ /* Clear Wakeup flag */
+ PWR->CR |= PWR_CR_CWUF;
+
+ /* Select STANDBY mode */
+ PWR->CR |= PWR_CR_PDDS;
+
+ /* Set SLEEPDEEP bit of Cortex System Control Register */
+ SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
+
+/* This option is used to ensure that store operations are completed */
+#if defined ( __CC_ARM )
+ __force_stores();
+#endif
+ /* Request Wait For Interrupt */
+ __WFI();
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup PWR_Group7 Flags management functions
+ * @brief Flags management functions
+ *
+@verbatim
+ ===============================================================================
+ Flags management functions
+ ===============================================================================
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Checks whether the specified PWR flag is set or not.
+ * @param PWR_FLAG: specifies the flag to check.
+ * This parameter can be one of the following values:
+ * @arg PWR_FLAG_WU: Wake Up flag. This flag indicates that a wakeup event
+ * was received from the WKUP pin or from the RTC alarm (Alarm A
+ * or Alarm B), RTC Tamper event, RTC TimeStamp event or RTC Wakeup.
+ * An additional wakeup event is detected if the WKUP pin is enabled
+ * (by setting the EWUP bit) when the WKUP pin level is already high.
+ * @arg PWR_FLAG_SB: StandBy flag. This flag indicates that the system was
+ * resumed from StandBy mode.
+ * @arg PWR_FLAG_PVDO: PVD Output. This flag is valid only if PVD is enabled
+ * by the PWR_PVDCmd() function. The PVD is stopped by Standby mode
+ * For this reason, this bit is equal to 0 after Standby or reset
+ * until the PVDE bit is set.
+ * @arg PWR_FLAG_BRR: Backup regulator ready flag. This bit is not reset
+ * when the device wakes up from Standby mode or by a system reset
+ * or power reset.
+ * @retval The new state of PWR_FLAG (SET or RESET).
+ */
+FlagStatus PWR_GetFlagStatus(uint32_t PWR_FLAG)
+{
+ FlagStatus bitstatus = RESET;
+
+ /* Check the parameters */
+ assert_param(IS_PWR_GET_FLAG(PWR_FLAG));
+
+ if ((PWR->CSR & PWR_FLAG) != (uint32_t)RESET)
+ {
+ bitstatus = SET;
+ }
+ else
+ {
+ bitstatus = RESET;
+ }
+ /* Return the flag status */
+ return bitstatus;
+}
+
+/**
+ * @brief Clears the PWR's pending flags.
+ * @param PWR_FLAG: specifies the flag to clear.
+ * This parameter can be one of the following values:
+ * @arg PWR_FLAG_WU: Wake Up flag
+ * @arg PWR_FLAG_SB: StandBy flag
+ * @retval None
+ */
+void PWR_ClearFlag(uint32_t PWR_FLAG)
+{
+ /* Check the parameters */
+ assert_param(IS_PWR_CLEAR_FLAG(PWR_FLAG));
+
+ PWR->CR |= PWR_FLAG << 2;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/src/stm32f2xx_rcc.c b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/src/stm32f2xx_rcc.c
new file mode 100644
index 0000000..0376f7f
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/src/stm32f2xx_rcc.c
@@ -0,0 +1,1817 @@
+/**
+ ******************************************************************************
+ * @file stm32f2xx_rcc.c
+ * @author MCD Application Team
+ * @version V1.1.2
+ * @date 05-March-2012
+ * @brief This file provides firmware functions to manage the following
+ * functionalities of the Reset and clock control (RCC) peripheral:
+ * - Internal/external clocks, PLL, CSS and MCO configuration
+ * - System, AHB and APB busses clocks configuration
+ * - Peripheral clocks configuration
+ * - Interrupts and flags management
+ *
+ * @verbatim
+ *
+ * ===================================================================
+ * RCC specific features
+ * ===================================================================
+ *
+ * After reset the device is running from Internal High Speed oscillator
+ * (HSI 16MHz) with Flash 0 wait state, Flash prefetch buffer, D-Cache
+ * and I-Cache are disabled, and all peripherals are off except internal
+ * SRAM, Flash and JTAG.
+ * - There is no prescaler on High speed (AHB) and Low speed (APB) busses;
+ * all peripherals mapped on these busses are running at HSI speed.
+ * - The clock for all peripherals is switched off, except the SRAM and FLASH.
+ * - All GPIOs are in input floating state, except the JTAG pins which
+ * are assigned to be used for debug purpose.
+ *
+ * Once the device started from reset, the user application has to:
+ * - Configure the clock source to be used to drive the System clock
+ * (if the application needs higher frequency/performance)
+ * - Configure the System clock frequency and Flash settings
+ * - Configure the AHB and APB busses prescalers
+ * - Enable the clock for the peripheral(s) to be used
+ * - Configure the clock source(s) for peripherals which clocks are not
+ * derived from the System clock (I2S, RTC, ADC, USB OTG FS/SDIO/RNG)
+ *
+ * @endverbatim
+ *
+ ******************************************************************************
+ * @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 "stm32f2xx_rcc.h"
+
+/** @addtogroup STM32F2xx_StdPeriph_Driver
+ * @{
+ */
+
+/** @defgroup RCC
+ * @brief RCC driver modules
+ * @{
+ */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* ------------ RCC registers bit address in the alias region ----------- */
+#define RCC_OFFSET (RCC_BASE - PERIPH_BASE)
+/* --- CR Register ---*/
+/* Alias word address of HSION bit */
+#define CR_OFFSET (RCC_OFFSET + 0x00)
+#define HSION_BitNumber 0x00
+#define CR_HSION_BB (PERIPH_BB_BASE + (CR_OFFSET * 32) + (HSION_BitNumber * 4))
+/* Alias word address of CSSON bit */
+#define CSSON_BitNumber 0x13
+#define CR_CSSON_BB (PERIPH_BB_BASE + (CR_OFFSET * 32) + (CSSON_BitNumber * 4))
+/* Alias word address of PLLON bit */
+#define PLLON_BitNumber 0x18
+#define CR_PLLON_BB (PERIPH_BB_BASE + (CR_OFFSET * 32) + (PLLON_BitNumber * 4))
+/* Alias word address of PLLI2SON bit */
+#define PLLI2SON_BitNumber 0x1A
+#define CR_PLLI2SON_BB (PERIPH_BB_BASE + (CR_OFFSET * 32) + (PLLI2SON_BitNumber * 4))
+
+/* --- CFGR Register ---*/
+/* Alias word address of I2SSRC bit */
+#define CFGR_OFFSET (RCC_OFFSET + 0x08)
+#define I2SSRC_BitNumber 0x17
+#define CFGR_I2SSRC_BB (PERIPH_BB_BASE + (CFGR_OFFSET * 32) + (I2SSRC_BitNumber * 4))
+
+/* --- BDCR Register ---*/
+/* Alias word address of RTCEN bit */
+#define BDCR_OFFSET (RCC_OFFSET + 0x70)
+#define RTCEN_BitNumber 0x0F
+#define BDCR_RTCEN_BB (PERIPH_BB_BASE + (BDCR_OFFSET * 32) + (RTCEN_BitNumber * 4))
+/* Alias word address of BDRST bit */
+#define BDRST_BitNumber 0x10
+#define BDCR_BDRST_BB (PERIPH_BB_BASE + (BDCR_OFFSET * 32) + (BDRST_BitNumber * 4))
+/* --- CSR Register ---*/
+/* Alias word address of LSION bit */
+#define CSR_OFFSET (RCC_OFFSET + 0x74)
+#define LSION_BitNumber 0x00
+#define CSR_LSION_BB (PERIPH_BB_BASE + (CSR_OFFSET * 32) + (LSION_BitNumber * 4))
+/* ---------------------- RCC registers bit mask ------------------------ */
+/* CFGR register bit mask */
+#define CFGR_MCO2_RESET_MASK ((uint32_t)0x07FFFFFF)
+#define CFGR_MCO1_RESET_MASK ((uint32_t)0xF89FFFFF)
+
+/* RCC Flag Mask */
+#define FLAG_MASK ((uint8_t)0x1F)
+
+/* CR register byte 3 (Bits[23:16]) base address */
+#define CR_BYTE3_ADDRESS ((uint32_t)0x40023802)
+
+/* CIR register byte 2 (Bits[15:8]) base address */
+#define CIR_BYTE2_ADDRESS ((uint32_t)(RCC_BASE + 0x0C + 0x01))
+
+/* CIR register byte 3 (Bits[23:16]) base address */
+#define CIR_BYTE3_ADDRESS ((uint32_t)(RCC_BASE + 0x0C + 0x02))
+
+/* BDCR register base address */
+#define BDCR_ADDRESS (PERIPH_BASE + BDCR_OFFSET)
+
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+static __I uint8_t APBAHBPrescTable[16] = {0, 0, 0, 0, 1, 2, 3, 4, 1, 2, 3, 4, 6, 7, 8, 9};
+
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+/** @defgroup RCC_Private_Functions
+ * @{
+ */
+
+/** @defgroup RCC_Group1 Internal and external clocks, PLL, CSS and MCO configuration functions
+ * @brief Internal and external clocks, PLL, CSS and MCO configuration functions
+ *
+@verbatim
+ ===============================================================================
+ Internal/external clocks, PLL, CSS and MCO configuration functions
+ ===============================================================================
+
+ This section provide functions allowing to configure the internal/external clocks,
+ PLLs, CSS and MCO pins.
+
+ 1. HSI (high-speed internal), 16 MHz factory-trimmed RC used directly or through
+ the PLL as System clock source.
+
+ 2. LSI (low-speed internal), 32 KHz low consumption RC used as IWDG and/or RTC
+ clock source.
+
+ 3. HSE (high-speed external), 4 to 26 MHz crystal oscillator used directly or
+ through the PLL as System clock source. Can be used also as RTC clock source.
+
+ 4. LSE (low-speed external), 32 KHz oscillator used as RTC clock source.
+
+ 5. PLL (clocked by HSI or HSE), featuring two different output clocks:
+ - The first output is used to generate the high speed system clock (up to 120 MHz)
+ - The second output is used to generate the clock for the USB OTG FS (48 MHz),
+ the random analog generator (<=48 MHz) and the SDIO (<= 48 MHz).
+
+ 6. PLLI2S (clocked by HSI or HSE), used to generate an accurate clock to achieve
+ high-quality audio performance on the I2S interface.
+
+ 7. CSS (Clock security system), once enable and if a HSE clock failure occurs
+ (HSE used directly or through PLL as System clock source), the System clock
+ is automatically switched to HSI and an interrupt is generated if enabled.
+ The interrupt is linked to the Cortex-M3 NMI (Non-Maskable Interrupt)
+ exception vector.
+
+ 8. MCO1 (microcontroller clock output), used to output HSI, LSE, HSE or PLL
+ clock (through a configurable prescaler) on PA8 pin.
+
+ 9. MCO2 (microcontroller clock output), used to output HSE, PLL, SYSCLK or PLLI2S
+ clock (through a configurable prescaler) on PC9 pin.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Resets the RCC clock configuration to the default reset state.
+ * @note The default reset state of the clock configuration is given below:
+ * - HSI ON and used as system clock source
+ * - HSE, PLL and PLLI2S OFF
+ * - AHB, APB1 and APB2 prescaler set to 1.
+ * - CSS, MCO1 and MCO2 OFF
+ * - All interrupts disabled
+ * @note This function doesn't modify the configuration of the
+ * - Peripheral clocks
+ * - LSI, LSE and RTC clocks
+ * @param None
+ * @retval None
+ */
+void RCC_DeInit(void)
+{
+ /* 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;
+}
+
+/**
+ * @brief Configures the External High Speed oscillator (HSE).
+ * @note After enabling the HSE (RCC_HSE_ON or RCC_HSE_Bypass), the application
+ * software should wait on HSERDY flag to be set indicating that HSE clock
+ * is stable and can be used to clock the PLL and/or system clock.
+ * @note HSE state can not be changed if it is used directly or through the
+ * PLL as system clock. In this case, you have to select another source
+ * of the system clock then change the HSE state (ex. disable it).
+ * @note The HSE is stopped by hardware when entering STOP and STANDBY modes.
+ * @note This function reset the CSSON bit, so if the Clock security system(CSS)
+ * was previously enabled you have to enable it again after calling this
+ * function.
+ * @param RCC_HSE: specifies the new state of the HSE.
+ * This parameter can be one of the following values:
+ * @arg RCC_HSE_OFF: turn OFF the HSE oscillator, HSERDY flag goes low after
+ * 6 HSE oscillator clock cycles.
+ * @arg RCC_HSE_ON: turn ON the HSE oscillator
+ * @arg RCC_HSE_Bypass: HSE oscillator bypassed with external clock
+ * @retval None
+ */
+void RCC_HSEConfig(uint8_t RCC_HSE)
+{
+ /* Check the parameters */
+ assert_param(IS_RCC_HSE(RCC_HSE));
+
+ /* Reset HSEON and HSEBYP bits before configuring the HSE ------------------*/
+ *(__IO uint8_t *) CR_BYTE3_ADDRESS = RCC_HSE_OFF;
+
+ /* Set the new HSE configuration -------------------------------------------*/
+ *(__IO uint8_t *) CR_BYTE3_ADDRESS = RCC_HSE;
+}
+
+/**
+ * @brief Waits for HSE start-up.
+ * @note This functions waits on HSERDY flag to be set and return SUCCESS if
+ * this flag is set, otherwise returns ERROR if the timeout is reached
+ * and this flag is not set. The timeout value is defined by the constant
+ * HSE_STARTUP_TIMEOUT in stm32f2xx.h file. You can tailor it depending
+ * on the HSE crystal used in your application.
+ * @param None
+ * @retval An ErrorStatus enumeration value:
+ * - SUCCESS: HSE oscillator is stable and ready to use
+ * - ERROR: HSE oscillator not yet ready
+ */
+ErrorStatus RCC_WaitForHSEStartUp(void)
+{
+ __IO uint32_t startupcounter = 0;
+ ErrorStatus status = ERROR;
+ FlagStatus hsestatus = RESET;
+ /* Wait till HSE is ready and if Time out is reached exit */
+ do
+ {
+ hsestatus = RCC_GetFlagStatus(RCC_FLAG_HSERDY);
+ startupcounter++;
+ } while((startupcounter != HSE_STARTUP_TIMEOUT) && (hsestatus == RESET));
+
+ if (RCC_GetFlagStatus(RCC_FLAG_HSERDY) != RESET)
+ {
+ status = SUCCESS;
+ }
+ else
+ {
+ status = ERROR;
+ }
+ return (status);
+}
+
+/**
+ * @brief Adjusts the Internal High Speed oscillator (HSI) calibration value.
+ * @note The calibration is used to compensate for the variations in voltage
+ * and temperature that influence the frequency of the internal HSI RC.
+ * @param HSICalibrationValue: specifies the calibration trimming value.
+ * This parameter must be a number between 0 and 0x1F.
+ * @retval None
+ */
+void RCC_AdjustHSICalibrationValue(uint8_t HSICalibrationValue)
+{
+ uint32_t tmpreg = 0;
+ /* Check the parameters */
+ assert_param(IS_RCC_CALIBRATION_VALUE(HSICalibrationValue));
+
+ tmpreg = RCC->CR;
+
+ /* Clear HSITRIM[4:0] bits */
+ tmpreg &= ~RCC_CR_HSITRIM;
+
+ /* Set the HSITRIM[4:0] bits according to HSICalibrationValue value */
+ tmpreg |= (uint32_t)HSICalibrationValue << 3;
+
+ /* Store the new value */
+ RCC->CR = tmpreg;
+}
+
+/**
+ * @brief Enables or disables the Internal High Speed oscillator (HSI).
+ * @note The HSI is stopped by hardware when entering STOP and STANDBY modes.
+ * It is used (enabled by hardware) as system clock source after startup
+ * from Reset, wakeup from STOP and STANDBY mode, or in case of failure
+ * of the HSE used directly or indirectly as system clock (if the Clock
+ * Security System CSS is enabled).
+ * @note HSI can not be stopped if it is used as system clock source. In this case,
+ * you have to select another source of the system clock then stop the HSI.
+ * @note After enabling the HSI, the application software should wait on HSIRDY
+ * flag to be set indicating that HSI clock is stable and can be used as
+ * system clock source.
+ * @param NewState: new state of the HSI.
+ * This parameter can be: ENABLE or DISABLE.
+ * @note When the HSI is stopped, HSIRDY flag goes low after 6 HSI oscillator
+ * clock cycles.
+ * @retval None
+ */
+void RCC_HSICmd(FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ *(__IO uint32_t *) CR_HSION_BB = (uint32_t)NewState;
+}
+
+/**
+ * @brief Configures the External Low Speed oscillator (LSE).
+ * @note As the LSE is in the Backup domain and write access is denied to
+ * this domain after reset, you have to enable write access using
+ * PWR_BackupAccessCmd(ENABLE) function before to configure the LSE
+ * (to be done once after reset).
+ * @note After enabling the LSE (RCC_LSE_ON or RCC_LSE_Bypass), the application
+ * software should wait on LSERDY flag to be set indicating that LSE clock
+ * is stable and can be used to clock the RTC.
+ * @param RCC_LSE: specifies the new state of the LSE.
+ * This parameter can be one of the following values:
+ * @arg RCC_LSE_OFF: turn OFF the LSE oscillator, LSERDY flag goes low after
+ * 6 LSE oscillator clock cycles.
+ * @arg RCC_LSE_ON: turn ON the LSE oscillator
+ * @arg RCC_LSE_Bypass: LSE oscillator bypassed with external clock
+ * @retval None
+ */
+void RCC_LSEConfig(uint8_t RCC_LSE)
+{
+ /* Check the parameters */
+ assert_param(IS_RCC_LSE(RCC_LSE));
+
+ /* Reset LSEON and LSEBYP bits before configuring the LSE ------------------*/
+ /* Reset LSEON bit */
+ *(__IO uint8_t *) BDCR_ADDRESS = RCC_LSE_OFF;
+
+ /* Reset LSEBYP bit */
+ *(__IO uint8_t *) BDCR_ADDRESS = RCC_LSE_OFF;
+
+ /* Configure LSE (RCC_LSE_OFF is already covered by the code section above) */
+ switch (RCC_LSE)
+ {
+ case RCC_LSE_ON:
+ /* Set LSEON bit */
+ *(__IO uint8_t *) BDCR_ADDRESS = RCC_LSE_ON;
+ break;
+ case RCC_LSE_Bypass:
+ /* Set LSEBYP and LSEON bits */
+ *(__IO uint8_t *) BDCR_ADDRESS = RCC_LSE_Bypass | RCC_LSE_ON;
+ break;
+ default:
+ break;
+ }
+}
+
+/**
+ * @brief Enables or disables the Internal Low Speed oscillator (LSI).
+ * @note After enabling the LSI, the application software should wait on
+ * LSIRDY flag to be set indicating that LSI clock is stable and can
+ * be used to clock the IWDG and/or the RTC.
+ * @note LSI can not be disabled if the IWDG is running.
+ * @param NewState: new state of the LSI.
+ * This parameter can be: ENABLE or DISABLE.
+ * @note When the LSI is stopped, LSIRDY flag goes low after 6 LSI oscillator
+ * clock cycles.
+ * @retval None
+ */
+void RCC_LSICmd(FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ *(__IO uint32_t *) CSR_LSION_BB = (uint32_t)NewState;
+}
+
+/**
+ * @brief Configures the main PLL clock source, multiplication and division factors.
+ * @note This function must be used only when the main PLL is disabled.
+ *
+ * @param RCC_PLLSource: specifies the PLL entry clock source.
+ * This parameter can be one of the following values:
+ * @arg RCC_PLLSource_HSI: HSI oscillator clock selected as PLL clock entry
+ * @arg RCC_PLLSource_HSE: HSE oscillator clock selected as PLL clock entry
+ * @note This clock source (RCC_PLLSource) is common for the main PLL and PLLI2S.
+ *
+ * @param PLLM: specifies the division factor for PLL VCO input clock
+ * This parameter must be a number between 0 and 63.
+ * @note You have to set the PLLM parameter correctly to ensure that the VCO input
+ * frequency ranges from 1 to 2 MHz. It is recommended to select a frequency
+ * of 2 MHz to limit PLL jitter.
+ *
+ * @param PLLN: specifies the multiplication factor for PLL VCO output clock
+ * This parameter must be a number between 192 and 432.
+ * @note You have to set the PLLN parameter correctly to ensure that the VCO
+ * output frequency is between 192 and 432 MHz.
+ *
+ * @param PLLP: specifies the division factor for main system clock (SYSCLK)
+ * This parameter must be a number in the range {2, 4, 6, or 8}.
+ * @note You have to set the PLLP parameter correctly to not exceed 120 MHz on
+ * the System clock frequency.
+ *
+ * @param PLLQ: specifies the division factor for OTG FS, SDIO and RNG clocks
+ * This parameter must be a number between 4 and 15.
+ * @note If the USB OTG FS is used in your application, you have to set the
+ * PLLQ parameter correctly to have 48 MHz clock for the USB. However,
+ * the SDIO and RNG need a frequency lower than or equal to 48 MHz to work
+ * correctly.
+ *
+ * @retval None
+ */
+void RCC_PLLConfig(uint32_t RCC_PLLSource, uint32_t PLLM, uint32_t PLLN, uint32_t PLLP, uint32_t PLLQ)
+{
+ /* Check the parameters */
+ assert_param(IS_RCC_PLL_SOURCE(RCC_PLLSource));
+ assert_param(IS_RCC_PLLM_VALUE(PLLM));
+ assert_param(IS_RCC_PLLN_VALUE(PLLN));
+ assert_param(IS_RCC_PLLP_VALUE(PLLP));
+ assert_param(IS_RCC_PLLQ_VALUE(PLLQ));
+
+ RCC->PLLCFGR = PLLM | (PLLN << 6) | (((PLLP >> 1) -1) << 16) | (RCC_PLLSource) |
+ (PLLQ << 24);
+}
+
+/**
+ * @brief Enables or disables the main PLL.
+ * @note After enabling the main PLL, the application software should wait on
+ * PLLRDY flag to be set indicating that PLL clock is stable and can
+ * be used as system clock source.
+ * @note The main PLL can not be disabled if it is used as system clock source
+ * @note The main PLL is disabled by hardware when entering STOP and STANDBY modes.
+ * @param NewState: new state of the main PLL. This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void RCC_PLLCmd(FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ *(__IO uint32_t *) CR_PLLON_BB = (uint32_t)NewState;
+}
+
+/**
+ * @brief Configures the PLLI2S clock multiplication and division factors.
+ *
+ * @note PLLI2S is available only in Silicon RevisionB and RevisionY.
+ * @note This function must be used only when the PLLI2S is disabled.
+ * @note PLLI2S clock source is common with the main PLL (configured in
+ * RCC_PLLConfig function )
+ *
+ * @param PLLI2SN: specifies the multiplication factor for PLLI2S VCO output clock
+ * This parameter must be a number between 192 and 432.
+ * @note You have to set the PLLI2SN parameter correctly to ensure that the VCO
+ * output frequency is between 192 and 432 MHz.
+ *
+ * @param PLLI2SR: specifies the division factor for I2S clock
+ * This parameter must be a number between 2 and 7.
+ * @note You have to set the PLLI2SR parameter correctly to not exceed 192 MHz
+ * on the I2S clock frequency.
+ *
+ * @retval None
+ */
+void RCC_PLLI2SConfig(uint32_t PLLI2SN, uint32_t PLLI2SR)
+{
+ /* Check the parameters */
+ assert_param(IS_RCC_PLLI2SN_VALUE(PLLI2SN));
+ assert_param(IS_RCC_PLLI2SR_VALUE(PLLI2SR));
+
+ RCC->PLLI2SCFGR = (PLLI2SN << 6) | (PLLI2SR << 28);
+}
+
+/**
+ * @brief Enables or disables the PLLI2S.
+ * @note PLLI2S is available only in RevisionB and RevisionY
+ * @note The PLLI2S is disabled by hardware when entering STOP and STANDBY modes.
+ * @param NewState: new state of the PLLI2S. This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void RCC_PLLI2SCmd(FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ *(__IO uint32_t *) CR_PLLI2SON_BB = (uint32_t)NewState;
+}
+
+/**
+ * @brief Enables or disables the Clock Security System.
+ * @note If a failure is detected on the HSE oscillator clock, this oscillator
+ * is automatically disabled and an interrupt is generated to inform the
+ * software about the failure (Clock Security System Interrupt, CSSI),
+ * allowing the MCU to perform rescue operations. The CSSI is linked to
+ * the Cortex-M3 NMI (Non-Maskable Interrupt) exception vector.
+ * @param NewState: new state of the Clock Security System.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void RCC_ClockSecuritySystemCmd(FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ *(__IO uint32_t *) CR_CSSON_BB = (uint32_t)NewState;
+}
+
+/**
+ * @brief Selects the clock source to output on MCO1 pin(PA8).
+ * @note PA8 should be configured in alternate function mode.
+ * @param RCC_MCO1Source: specifies the clock source to output.
+ * This parameter can be one of the following values:
+ * @arg RCC_MCO1Source_HSI: HSI clock selected as MCO1 source
+ * @arg RCC_MCO1Source_LSE: LSE clock selected as MCO1 source
+ * @arg RCC_MCO1Source_HSE: HSE clock selected as MCO1 source
+ * @arg RCC_MCO1Source_PLLCLK: main PLL clock selected as MCO1 source
+ * @param RCC_MCO1Div: specifies the MCO1 prescaler.
+ * This parameter can be one of the following values:
+ * @arg RCC_MCO1Div_1: no division applied to MCO1 clock
+ * @arg RCC_MCO1Div_2: division by 2 applied to MCO1 clock
+ * @arg RCC_MCO1Div_3: division by 3 applied to MCO1 clock
+ * @arg RCC_MCO1Div_4: division by 4 applied to MCO1 clock
+ * @arg RCC_MCO1Div_5: division by 5 applied to MCO1 clock
+ * @retval None
+ */
+void RCC_MCO1Config(uint32_t RCC_MCO1Source, uint32_t RCC_MCO1Div)
+{
+ uint32_t tmpreg = 0;
+
+ /* Check the parameters */
+ assert_param(IS_RCC_MCO1SOURCE(RCC_MCO1Source));
+ assert_param(IS_RCC_MCO1DIV(RCC_MCO1Div));
+
+ tmpreg = RCC->CFGR;
+
+ /* Clear MCO1[1:0] and MCO1PRE[2:0] bits */
+ tmpreg &= CFGR_MCO1_RESET_MASK;
+
+ /* Select MCO1 clock source and prescaler */
+ tmpreg |= RCC_MCO1Source | RCC_MCO1Div;
+
+ /* Store the new value */
+ RCC->CFGR = tmpreg;
+}
+
+/**
+ * @brief Selects the clock source to output on MCO2 pin(PC9).
+ * @note PC9 should be configured in alternate function mode.
+ * @param RCC_MCO2Source: specifies the clock source to output.
+ * This parameter can be one of the following values:
+ * @arg RCC_MCO2Source_SYSCLK: System clock (SYSCLK) selected as MCO2 source
+ * @arg RCC_MCO2Source_PLLI2SCLK: PLLI2S clock selected as MCO2 source
+ * @arg RCC_MCO2Source_HSE: HSE clock selected as MCO2 source
+ * @arg RCC_MCO2Source_PLLCLK: main PLL clock selected as MCO2 source
+ * @param RCC_MCO2Div: specifies the MCO2 prescaler.
+ * This parameter can be one of the following values:
+ * @arg RCC_MCO2Div_1: no division applied to MCO2 clock
+ * @arg RCC_MCO2Div_2: division by 2 applied to MCO2 clock
+ * @arg RCC_MCO2Div_3: division by 3 applied to MCO2 clock
+ * @arg RCC_MCO2Div_4: division by 4 applied to MCO2 clock
+ * @arg RCC_MCO2Div_5: division by 5 applied to MCO2 clock
+ * @retval None
+ */
+void RCC_MCO2Config(uint32_t RCC_MCO2Source, uint32_t RCC_MCO2Div)
+{
+ uint32_t tmpreg = 0;
+
+ /* Check the parameters */
+ assert_param(IS_RCC_MCO2SOURCE(RCC_MCO2Source));
+ assert_param(IS_RCC_MCO2DIV(RCC_MCO2Div));
+
+ tmpreg = RCC->CFGR;
+
+ /* Clear MCO2 and MCO2PRE[2:0] bits */
+ tmpreg &= CFGR_MCO2_RESET_MASK;
+
+ /* Select MCO2 clock source and prescaler */
+ tmpreg |= RCC_MCO2Source | RCC_MCO2Div;
+
+ /* Store the new value */
+ RCC->CFGR = tmpreg;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup RCC_Group2 System AHB and APB busses clocks configuration functions
+ * @brief System, AHB and APB busses clocks configuration functions
+ *
+@verbatim
+ ===============================================================================
+ System, AHB and APB busses clocks configuration functions
+ ===============================================================================
+
+ This section provide functions allowing to configure the System, AHB, APB1 and
+ APB2 busses clocks.
+
+ 1. Several clock sources can be used to drive the System clock (SYSCLK): HSI,
+ HSE and PLL.
+ The AHB clock (HCLK) is derived from System clock through configurable prescaler
+ and used to clock the CPU, memory and peripherals mapped on AHB bus (DMA, GPIO...).
+ APB1 (PCLK1) and APB2 (PCLK2) clocks are derived from AHB clock through
+ configurable prescalers and used to clock the peripherals mapped on these busses.
+ You can use "RCC_GetClocksFreq()" function to retrieve the frequencies of these clocks.
+
+@note All the peripheral clocks are derived from the System clock (SYSCLK) except:
+ - I2S: the I2S clock can be derived either from a specific PLL (PLLI2S) or
+ from an external clock mapped on the I2S_CKIN pin.
+ You have to use RCC_I2SCLKConfig() function to configure this clock.
+ - RTC: the RTC clock can be derived either from the LSI, LSE or HSE clock
+ divided by 2 to 31. You have to use RCC_RTCCLKConfig() and RCC_RTCCLKCmd()
+ functions to configure this clock.
+ - USB OTG FS, SDIO and RTC: USB OTG FS require a frequency equal to 48 MHz
+ to work correctly, while the SDIO require a frequency equal or lower than
+ to 48. This clock is derived of the main PLL through PLLQ divider.
+ - IWDG clock which is always the LSI clock.
+
+ 2. The maximum frequency of the SYSCLK and HCLK is 120 MHz, PCLK2 60 MHz and PCLK1 30 MHz.
+ Depending on the device voltage range, the maximum frequency should be
+ adapted accordingly:
+ +-------------------------------------------------------------------------------------+
+ | Latency | HCLK clock frequency (MHz) |
+ | |---------------------------------------------------------------------|
+ | | voltage range | voltage range | voltage range | voltage range |
+ | | 2.7 V - 3.6 V | 2.4 V - 2.7 V | 2.1 V - 2.4 V | 1.8 V - 2.1 V |
+ |---------------|----------------|----------------|-----------------|-----------------|
+ |0WS(1CPU cycle)|0 < HCLK <= 30 |0 < HCLK <= 24 |0 < HCLK <= 18 |0 < HCLK <= 16 |
+ |---------------|----------------|----------------|-----------------|-----------------|
+ |1WS(2CPU cycle)|30 < HCLK <= 60 |24 < HCLK <= 48 |18 < HCLK <= 36 |16 < HCLK <= 32 |
+ |---------------|----------------|----------------|-----------------|-----------------|
+ |2WS(3CPU cycle)|60 < HCLK <= 90 |48 < HCLK <= 72 |36 < HCLK <= 54 |32 < HCLK <= 48 |
+ |---------------|----------------|----------------|-----------------|-----------------|
+ |3WS(4CPU cycle)|90 < HCLK <= 120|72 < HCLK <= 96 |54 < HCLK <= 72 |48 < HCLK <= 64 |
+ |---------------|----------------|----------------|-----------------|-----------------|
+ |4WS(5CPU cycle)| NA |96 < HCLK <= 120|72 < HCLK <= 90 |64 < HCLK <= 80 |
+ |---------------|----------------|----------------|-----------------|-----------------|
+ |5WS(6CPU cycle)| NA | NA |90 < HCLK <= 108 |80 < HCLK <= 96 |
+ |---------------|----------------|----------------|-----------------|-----------------|
+ |6WS(7CPU cycle)| NA | NA |108 < HCLK <= 120|96 < HCLK <= 112 |
+ |---------------|----------------|----------------|-----------------|-----------------|
+ |7WS(8CPU cycle)| NA | NA | NA |112 < HCLK <= 120|
+ +-------------------------------------------------------------------------------------+
+
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Configures the system clock (SYSCLK).
+ * @note The HSI is used (enabled by hardware) as system clock source after
+ * startup from Reset, wake-up from STOP and STANDBY mode, or in case
+ * of failure of the HSE used directly or indirectly as system clock
+ * (if the Clock Security System CSS is enabled).
+ * @note A switch from one clock source to another occurs only if the target
+ * clock source is ready (clock stable after startup delay or PLL locked).
+ * If a clock source which is not yet ready is selected, the switch will
+ * occur when the clock source will be ready.
+ * You can use RCC_GetSYSCLKSource() function to know which clock is
+ * currently used as system clock source.
+ * @param RCC_SYSCLKSource: specifies the clock source used as system clock.
+ * This parameter can be one of the following values:
+ * @arg RCC_SYSCLKSource_HSI: HSI selected as system clock source
+ * @arg RCC_SYSCLKSource_HSE: HSE selected as system clock source
+ * @arg RCC_SYSCLKSource_PLLCLK: PLL selected as system clock source
+ * @retval None
+ */
+void RCC_SYSCLKConfig(uint32_t RCC_SYSCLKSource)
+{
+ uint32_t tmpreg = 0;
+
+ /* Check the parameters */
+ assert_param(IS_RCC_SYSCLK_SOURCE(RCC_SYSCLKSource));
+
+ tmpreg = RCC->CFGR;
+
+ /* Clear SW[1:0] bits */
+ tmpreg &= ~RCC_CFGR_SW;
+
+ /* Set SW[1:0] bits according to RCC_SYSCLKSource value */
+ tmpreg |= RCC_SYSCLKSource;
+
+ /* Store the new value */
+ RCC->CFGR = tmpreg;
+}
+
+/**
+ * @brief Returns the clock source used as system clock.
+ * @param None
+ * @retval The clock source used as system clock. The returned value can be one
+ * of the following:
+ * - 0x00: HSI used as system clock
+ * - 0x04: HSE used as system clock
+ * - 0x08: PLL used as system clock
+ */
+uint8_t RCC_GetSYSCLKSource(void)
+{
+ return ((uint8_t)(RCC->CFGR & RCC_CFGR_SWS));
+}
+
+/**
+ * @brief Configures the AHB clock (HCLK).
+ * @note Depending on the device voltage range, the software has to set correctly
+ * these bits to ensure that HCLK not exceed the maximum allowed frequency
+ * (for more details refer to section above
+ * "CPU, AHB and APB busses clocks configuration functions")
+ * @param RCC_SYSCLK: defines the AHB clock divider. This clock is derived from
+ * the system clock (SYSCLK).
+ * This parameter can be one of the following values:
+ * @arg RCC_SYSCLK_Div1: AHB clock = SYSCLK
+ * @arg RCC_SYSCLK_Div2: AHB clock = SYSCLK/2
+ * @arg RCC_SYSCLK_Div4: AHB clock = SYSCLK/4
+ * @arg RCC_SYSCLK_Div8: AHB clock = SYSCLK/8
+ * @arg RCC_SYSCLK_Div16: AHB clock = SYSCLK/16
+ * @arg RCC_SYSCLK_Div64: AHB clock = SYSCLK/64
+ * @arg RCC_SYSCLK_Div128: AHB clock = SYSCLK/128
+ * @arg RCC_SYSCLK_Div256: AHB clock = SYSCLK/256
+ * @arg RCC_SYSCLK_Div512: AHB clock = SYSCLK/512
+ * @retval None
+ */
+void RCC_HCLKConfig(uint32_t RCC_SYSCLK)
+{
+ uint32_t tmpreg = 0;
+
+ /* Check the parameters */
+ assert_param(IS_RCC_HCLK(RCC_SYSCLK));
+
+ tmpreg = RCC->CFGR;
+
+ /* Clear HPRE[3:0] bits */
+ tmpreg &= ~RCC_CFGR_HPRE;
+
+ /* Set HPRE[3:0] bits according to RCC_SYSCLK value */
+ tmpreg |= RCC_SYSCLK;
+
+ /* Store the new value */
+ RCC->CFGR = tmpreg;
+}
+
+
+/**
+ * @brief Configures the Low Speed APB clock (PCLK1).
+ * @param RCC_HCLK: defines the APB1 clock divider. This clock is derived from
+ * the AHB clock (HCLK).
+ * This parameter can be one of the following values:
+ * @arg RCC_HCLK_Div1: APB1 clock = HCLK
+ * @arg RCC_HCLK_Div2: APB1 clock = HCLK/2
+ * @arg RCC_HCLK_Div4: APB1 clock = HCLK/4
+ * @arg RCC_HCLK_Div8: APB1 clock = HCLK/8
+ * @arg RCC_HCLK_Div16: APB1 clock = HCLK/16
+ * @retval None
+ */
+void RCC_PCLK1Config(uint32_t RCC_HCLK)
+{
+ uint32_t tmpreg = 0;
+
+ /* Check the parameters */
+ assert_param(IS_RCC_PCLK(RCC_HCLK));
+
+ tmpreg = RCC->CFGR;
+
+ /* Clear PPRE1[2:0] bits */
+ tmpreg &= ~RCC_CFGR_PPRE1;
+
+ /* Set PPRE1[2:0] bits according to RCC_HCLK value */
+ tmpreg |= RCC_HCLK;
+
+ /* Store the new value */
+ RCC->CFGR = tmpreg;
+}
+
+/**
+ * @brief Configures the High Speed APB clock (PCLK2).
+ * @param RCC_HCLK: defines the APB2 clock divider. This clock is derived from
+ * the AHB clock (HCLK).
+ * This parameter can be one of the following values:
+ * @arg RCC_HCLK_Div1: APB2 clock = HCLK
+ * @arg RCC_HCLK_Div2: APB2 clock = HCLK/2
+ * @arg RCC_HCLK_Div4: APB2 clock = HCLK/4
+ * @arg RCC_HCLK_Div8: APB2 clock = HCLK/8
+ * @arg RCC_HCLK_Div16: APB2 clock = HCLK/16
+ * @retval None
+ */
+void RCC_PCLK2Config(uint32_t RCC_HCLK)
+{
+ uint32_t tmpreg = 0;
+
+ /* Check the parameters */
+ assert_param(IS_RCC_PCLK(RCC_HCLK));
+
+ tmpreg = RCC->CFGR;
+
+ /* Clear PPRE2[2:0] bits */
+ tmpreg &= ~RCC_CFGR_PPRE2;
+
+ /* Set PPRE2[2:0] bits according to RCC_HCLK value */
+ tmpreg |= RCC_HCLK << 3;
+
+ /* Store the new value */
+ RCC->CFGR = tmpreg;
+}
+
+/**
+ * @brief Returns the frequencies of different on chip clocks; SYSCLK, HCLK,
+ * PCLK1 and PCLK2.
+ *
+ * @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:
+ * @note If SYSCLK source is HSI, function returns values based on HSI_VALUE(*)
+ * @note If SYSCLK source is HSE, function returns values based on HSE_VALUE(**)
+ * @note If SYSCLK source is PLL, function returns values based on HSE_VALUE(**)
+ * or HSI_VALUE(*) multiplied/divided by the PLL factors.
+ * @note (*) HSI_VALUE is a constant defined in stm32f2xx.h file (default value
+ * 16 MHz) but the real value may vary depending on the variations
+ * in voltage and temperature.
+ * @note (**) HSE_VALUE is a constant defined in stm32f2xx.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.
+ *
+ * @note The result of this function could be not correct when using fractional
+ * value for HSE crystal.
+ *
+ * @param RCC_Clocks: pointer to a RCC_ClocksTypeDef structure which will hold
+ * the clocks frequencies.
+ *
+ * @note This function can be used by the user application to compute the
+ * baudrate for the communication peripherals or configure other parameters.
+ * @note Each time SYSCLK, HCLK, PCLK1 and/or PCLK2 clock changes, this function
+ * must be called to update the structure's field. Otherwise, any
+ * configuration based on this function will be incorrect.
+ *
+ * @retval None
+ */
+void RCC_GetClocksFreq(RCC_ClocksTypeDef* RCC_Clocks)
+{
+ uint32_t tmp = 0, presc = 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 */
+ RCC_Clocks->SYSCLK_Frequency = HSI_VALUE;
+ break;
+ case 0x04: /* HSE used as system clock source */
+ RCC_Clocks->SYSCLK_Frequency = HSE_VALUE;
+ break;
+ case 0x08: /* PLL used as system clock source */
+
+ /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLLM) * PLLN
+ SYSCLK = PLL_VCO / PLLP
+ */
+ 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;
+ RCC_Clocks->SYSCLK_Frequency = pllvco/pllp;
+ break;
+ default:
+ RCC_Clocks->SYSCLK_Frequency = HSI_VALUE;
+ break;
+ }
+ /* Compute HCLK, PCLK1 and PCLK2 clocks frequencies ------------------------*/
+
+ /* Get HCLK prescaler */
+ tmp = RCC->CFGR & RCC_CFGR_HPRE;
+ tmp = tmp >> 4;
+ presc = APBAHBPrescTable[tmp];
+ /* HCLK clock frequency */
+ RCC_Clocks->HCLK_Frequency = RCC_Clocks->SYSCLK_Frequency >> presc;
+
+ /* Get PCLK1 prescaler */
+ tmp = RCC->CFGR & RCC_CFGR_PPRE1;
+ tmp = tmp >> 10;
+ presc = APBAHBPrescTable[tmp];
+ /* PCLK1 clock frequency */
+ RCC_Clocks->PCLK1_Frequency = RCC_Clocks->HCLK_Frequency >> presc;
+
+ /* Get PCLK2 prescaler */
+ tmp = RCC->CFGR & RCC_CFGR_PPRE2;
+ tmp = tmp >> 13;
+ presc = APBAHBPrescTable[tmp];
+ /* PCLK2 clock frequency */
+ RCC_Clocks->PCLK2_Frequency = RCC_Clocks->HCLK_Frequency >> presc;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup RCC_Group3 Peripheral clocks configuration functions
+ * @brief Peripheral clocks configuration functions
+ *
+@verbatim
+ ===============================================================================
+ Peripheral clocks configuration functions
+ ===============================================================================
+
+ This section provide functions allowing to configure the Peripheral clocks.
+
+ 1. The RTC clock which is derived from the LSI, LSE or HSE clock divided by 2 to 31.
+
+ 2. After restart from Reset or wakeup from STANDBY, all peripherals are off
+ except internal SRAM, Flash and JTAG. Before to start using a peripheral you
+ have to enable its interface clock. You can do this using RCC_AHBPeriphClockCmd()
+ , RCC_APB2PeriphClockCmd() and RCC_APB1PeriphClockCmd() functions.
+
+ 3. To reset the peripherals configuration (to the default state after device reset)
+ you can use RCC_AHBPeriphResetCmd(), RCC_APB2PeriphResetCmd() and
+ RCC_APB1PeriphResetCmd() functions.
+
+ 4. To further reduce power consumption in SLEEP mode the peripheral clocks can
+ be disabled prior to executing the WFI or WFE instructions. You can do this
+ using RCC_AHBPeriphClockLPModeCmd(), RCC_APB2PeriphClockLPModeCmd() and
+ RCC_APB1PeriphClockLPModeCmd() functions.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Configures the RTC clock (RTCCLK).
+ * @note As the RTC clock configuration bits are in the Backup domain and write
+ * access is denied to this domain after reset, you have to enable write
+ * access using PWR_BackupAccessCmd(ENABLE) function before to configure
+ * the RTC clock source (to be done once after reset).
+ * @note Once the RTC clock is configured it can't be changed unless the
+ * Backup domain is reset using RCC_BackupResetCmd() function, or by
+ * a Power On Reset (POR).
+ *
+ * @param RCC_RTCCLKSource: specifies the RTC clock source.
+ * This parameter can be one of the following values:
+ * @arg RCC_RTCCLKSource_LSE: LSE selected as RTC clock
+ * @arg RCC_RTCCLKSource_LSI: LSI selected as RTC clock
+ * @arg RCC_RTCCLKSource_HSE_Divx: HSE clock divided by x selected
+ * as RTC clock, where x:[2,31]
+ *
+ * @note If the LSE or LSI is used as RTC clock source, the RTC continues to
+ * work in STOP and STANDBY modes, and can be used as wakeup source.
+ * However, when the HSE clock is used as RTC clock source, the RTC
+ * cannot be used in STOP and STANDBY modes.
+ * @note The maximum input clock frequency for RTC is 1MHz (when using HSE as
+ * RTC clock source).
+ *
+ * @retval None
+ */
+void RCC_RTCCLKConfig(uint32_t RCC_RTCCLKSource)
+{
+ uint32_t tmpreg = 0;
+
+ /* Check the parameters */
+ assert_param(IS_RCC_RTCCLK_SOURCE(RCC_RTCCLKSource));
+
+ if ((RCC_RTCCLKSource & 0x00000300) == 0x00000300)
+ { /* If HSE is selected as RTC clock source, configure HSE division factor for RTC clock */
+ tmpreg = RCC->CFGR;
+
+ /* Clear RTCPRE[4:0] bits */
+ tmpreg &= ~RCC_CFGR_RTCPRE;
+
+ /* Configure HSE division factor for RTC clock */
+ tmpreg |= (RCC_RTCCLKSource & 0xFFFFCFF);
+
+ /* Store the new value */
+ RCC->CFGR = tmpreg;
+ }
+
+ /* Select the RTC clock source */
+ RCC->BDCR |= (RCC_RTCCLKSource & 0x00000FFF);
+}
+
+/**
+ * @brief Enables or disables the RTC clock.
+ * @note This function must be used only after the RTC clock source was selected
+ * using the RCC_RTCCLKConfig function.
+ * @param NewState: new state of the RTC clock. This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void RCC_RTCCLKCmd(FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ *(__IO uint32_t *) BDCR_RTCEN_BB = (uint32_t)NewState;
+}
+
+/**
+ * @brief Forces or releases the Backup domain reset.
+ * @note This function resets the RTC peripheral (including the backup registers)
+ * and the RTC clock source selection in RCC_CSR register.
+ * @note The BKPSRAM is not affected by this reset.
+ * @param NewState: new state of the Backup domain reset.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void RCC_BackupResetCmd(FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ *(__IO uint32_t *) BDCR_BDRST_BB = (uint32_t)NewState;
+}
+
+/**
+ * @brief Configures the I2S clock source (I2SCLK).
+ *
+ * @note This function must be called before enabling the I2S APB clock.
+ * @note This function applies only to Silicon RevisionB and RevisionY.
+ *
+ * @param RCC_I2SCLKSource: specifies the I2S clock source.
+ * This parameter can be one of the following values:
+ * @arg RCC_I2S2CLKSource_PLLI2S: PLLI2S clock used as I2S clock source
+ * @arg RCC_I2S2CLKSource_Ext: External clock mapped on the I2S_CKIN pin
+ * used as I2S clock source
+ * @retval None
+ */
+void RCC_I2SCLKConfig(uint32_t RCC_I2SCLKSource)
+{
+ /* Check the parameters */
+ assert_param(IS_RCC_I2SCLK_SOURCE(RCC_I2SCLKSource));
+
+ *(__IO uint32_t *) CFGR_I2SSRC_BB = RCC_I2SCLKSource;
+}
+
+/**
+ * @brief Enables or disables the AHB1 peripheral clock.
+ * @note After reset, the peripheral clock (used for registers read/write access)
+ * is disabled and the application software has to enable this clock before
+ * using it.
+ * @param RCC_AHBPeriph: specifies the AHB1 peripheral to gates its clock.
+ * This parameter can be any combination of the following values:
+ * @arg RCC_AHB1Periph_GPIOA: GPIOA clock
+ * @arg RCC_AHB1Periph_GPIOB: GPIOB clock
+ * @arg RCC_AHB1Periph_GPIOC: GPIOC clock
+ * @arg RCC_AHB1Periph_GPIOD: GPIOD clock
+ * @arg RCC_AHB1Periph_GPIOE: GPIOE clock
+ * @arg RCC_AHB1Periph_GPIOF: GPIOF clock
+ * @arg RCC_AHB1Periph_GPIOG: GPIOG clock
+ * @arg RCC_AHB1Periph_GPIOG: GPIOG clock
+ * @arg RCC_AHB1Periph_GPIOI: GPIOI clock
+ * @arg RCC_AHB1Periph_CRC: CRC clock
+ * @arg RCC_AHB1Periph_BKPSRAM: BKPSRAM interface clock
+ * @arg RCC_AHB1Periph_DMA1: DMA1 clock
+ * @arg RCC_AHB1Periph_DMA2: DMA2 clock
+ * @arg RCC_AHB1Periph_ETH_MAC: Ethernet MAC clock
+ * @arg RCC_AHB1Periph_ETH_MAC_Tx: Ethernet Transmission clock
+ * @arg RCC_AHB1Periph_ETH_MAC_Rx: Ethernet Reception clock
+ * @arg RCC_AHB1Periph_ETH_MAC_PTP: Ethernet PTP clock
+ * @arg RCC_AHB1Periph_OTG_HS: USB OTG HS clock
+ * @arg RCC_AHB1Periph_OTG_HS_ULPI: USB OTG HS ULPI clock
+ * @param NewState: new state of the specified peripheral clock.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void RCC_AHB1PeriphClockCmd(uint32_t RCC_AHB1Periph, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_RCC_AHB1_CLOCK_PERIPH(RCC_AHB1Periph));
+
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ if (NewState != DISABLE)
+ {
+ RCC->AHB1ENR |= RCC_AHB1Periph;
+ }
+ else
+ {
+ RCC->AHB1ENR &= ~RCC_AHB1Periph;
+ }
+}
+
+/**
+ * @brief Enables or disables the AHB2 peripheral clock.
+ * @note After reset, the peripheral clock (used for registers read/write access)
+ * is disabled and the application software has to enable this clock before
+ * using it.
+ * @param RCC_AHBPeriph: specifies the AHB2 peripheral to gates its clock.
+ * This parameter can be any combination of the following values:
+ * @arg RCC_AHB2Periph_DCMI: DCMI clock
+ * @arg RCC_AHB2Periph_CRYP: CRYP clock
+ * @arg RCC_AHB2Periph_HASH: HASH clock
+ * @arg RCC_AHB2Periph_RNG: RNG clock
+ * @arg RCC_AHB2Periph_OTG_FS: USB OTG FS clock
+ * @param NewState: new state of the specified peripheral clock.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void RCC_AHB2PeriphClockCmd(uint32_t RCC_AHB2Periph, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_RCC_AHB2_PERIPH(RCC_AHB2Periph));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ RCC->AHB2ENR |= RCC_AHB2Periph;
+ }
+ else
+ {
+ RCC->AHB2ENR &= ~RCC_AHB2Periph;
+ }
+}
+
+/**
+ * @brief Enables or disables the AHB3 peripheral clock.
+ * @note After reset, the peripheral clock (used for registers read/write access)
+ * is disabled and the application software has to enable this clock before
+ * using it.
+ * @param RCC_AHBPeriph: specifies the AHB3 peripheral to gates its clock.
+ * This parameter must be: RCC_AHB3Periph_FSMC
+ * @param NewState: new state of the specified peripheral clock.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void RCC_AHB3PeriphClockCmd(uint32_t RCC_AHB3Periph, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_RCC_AHB3_PERIPH(RCC_AHB3Periph));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ RCC->AHB3ENR |= RCC_AHB3Periph;
+ }
+ else
+ {
+ RCC->AHB3ENR &= ~RCC_AHB3Periph;
+ }
+}
+
+/**
+ * @brief Enables or disables the Low Speed APB (APB1) peripheral clock.
+ * @note After reset, the peripheral clock (used for registers read/write access)
+ * is disabled and the application software has to enable this clock before
+ * using it.
+ * @param RCC_APB1Periph: specifies the APB1 peripheral to gates its clock.
+ * This parameter can be any combination of the following values:
+ * @arg RCC_APB1Periph_TIM2: TIM2 clock
+ * @arg RCC_APB1Periph_TIM3: TIM3 clock
+ * @arg RCC_APB1Periph_TIM4: TIM4 clock
+ * @arg RCC_APB1Periph_TIM5: TIM5 clock
+ * @arg RCC_APB1Periph_TIM6: TIM6 clock
+ * @arg RCC_APB1Periph_TIM7: TIM7 clock
+ * @arg RCC_APB1Periph_TIM12: TIM12 clock
+ * @arg RCC_APB1Periph_TIM13: TIM13 clock
+ * @arg RCC_APB1Periph_TIM14: TIM14 clock
+ * @arg RCC_APB1Periph_WWDG: WWDG clock
+ * @arg RCC_APB1Periph_SPI2: SPI2 clock
+ * @arg RCC_APB1Periph_SPI3: SPI3 clock
+ * @arg RCC_APB1Periph_USART2: USART2 clock
+ * @arg RCC_APB1Periph_USART3: USART3 clock
+ * @arg RCC_APB1Periph_UART4: UART4 clock
+ * @arg RCC_APB1Periph_UART5: UART5 clock
+ * @arg RCC_APB1Periph_I2C1: I2C1 clock
+ * @arg RCC_APB1Periph_I2C2: I2C2 clock
+ * @arg RCC_APB1Periph_I2C3: I2C3 clock
+ * @arg RCC_APB1Periph_CAN1: CAN1 clock
+ * @arg RCC_APB1Periph_CAN2: CAN2 clock
+ * @arg RCC_APB1Periph_PWR: PWR clock
+ * @arg RCC_APB1Periph_DAC: DAC clock
+ * @param NewState: new state of the specified peripheral clock.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void RCC_APB1PeriphClockCmd(uint32_t RCC_APB1Periph, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_RCC_APB1_PERIPH(RCC_APB1Periph));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ RCC->APB1ENR |= RCC_APB1Periph;
+ }
+ else
+ {
+ RCC->APB1ENR &= ~RCC_APB1Periph;
+ }
+}
+
+/**
+ * @brief Enables or disables the High Speed APB (APB2) peripheral clock.
+ * @note After reset, the peripheral clock (used for registers read/write access)
+ * is disabled and the application software has to enable this clock before
+ * using it.
+ * @param RCC_APB2Periph: specifies the APB2 peripheral to gates its clock.
+ * This parameter can be any combination of the following values:
+ * @arg RCC_APB2Periph_TIM1: TIM1 clock
+ * @arg RCC_APB2Periph_TIM8: TIM8 clock
+ * @arg RCC_APB2Periph_USART1: USART1 clock
+ * @arg RCC_APB2Periph_USART6: USART6 clock
+ * @arg RCC_APB2Periph_ADC1: ADC1 clock
+ * @arg RCC_APB2Periph_ADC2: ADC2 clock
+ * @arg RCC_APB2Periph_ADC3: ADC3 clock
+ * @arg RCC_APB2Periph_SDIO: SDIO clock
+ * @arg RCC_APB2Periph_SPI1: SPI1 clock
+ * @arg RCC_APB2Periph_SYSCFG: SYSCFG clock
+ * @arg RCC_APB2Periph_TIM9: TIM9 clock
+ * @arg RCC_APB2Periph_TIM10: TIM10 clock
+ * @arg RCC_APB2Periph_TIM11: TIM11 clock
+ * @param NewState: new state of the specified peripheral clock.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_RCC_APB2_PERIPH(RCC_APB2Periph));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ RCC->APB2ENR |= RCC_APB2Periph;
+ }
+ else
+ {
+ RCC->APB2ENR &= ~RCC_APB2Periph;
+ }
+}
+
+/**
+ * @brief Forces or releases AHB1 peripheral reset.
+ * @param RCC_AHB1Periph: specifies the AHB1 peripheral to reset.
+ * This parameter can be any combination of the following values:
+ * @arg RCC_AHB1Periph_GPIOA: GPIOA clock
+ * @arg RCC_AHB1Periph_GPIOB: GPIOB clock
+ * @arg RCC_AHB1Periph_GPIOC: GPIOC clock
+ * @arg RCC_AHB1Periph_GPIOD: GPIOD clock
+ * @arg RCC_AHB1Periph_GPIOE: GPIOE clock
+ * @arg RCC_AHB1Periph_GPIOF: GPIOF clock
+ * @arg RCC_AHB1Periph_GPIOG: GPIOG clock
+ * @arg RCC_AHB1Periph_GPIOG: GPIOG clock
+ * @arg RCC_AHB1Periph_GPIOI: GPIOI clock
+ * @arg RCC_AHB1Periph_CRC: CRC clock
+ * @arg RCC_AHB1Periph_DMA1: DMA1 clock
+ * @arg RCC_AHB1Periph_DMA2: DMA2 clock
+ * @arg RCC_AHB1Periph_ETH_MAC: Ethernet MAC clock
+ * @arg RCC_AHB1Periph_OTG_HS: USB OTG HS clock
+ *
+ * @param NewState: new state of the specified peripheral reset.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void RCC_AHB1PeriphResetCmd(uint32_t RCC_AHB1Periph, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_RCC_AHB1_RESET_PERIPH(RCC_AHB1Periph));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ RCC->AHB1RSTR |= RCC_AHB1Periph;
+ }
+ else
+ {
+ RCC->AHB1RSTR &= ~RCC_AHB1Periph;
+ }
+}
+
+/**
+ * @brief Forces or releases AHB2 peripheral reset.
+ * @param RCC_AHB2Periph: specifies the AHB2 peripheral to reset.
+ * This parameter can be any combination of the following values:
+ * @arg RCC_AHB2Periph_DCMI: DCMI clock
+ * @arg RCC_AHB2Periph_CRYP: CRYP clock
+ * @arg RCC_AHB2Periph_HASH: HASH clock
+ * @arg RCC_AHB2Periph_RNG: RNG clock
+ * @arg RCC_AHB2Periph_OTG_FS: USB OTG FS clock
+ * @param NewState: new state of the specified peripheral reset.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void RCC_AHB2PeriphResetCmd(uint32_t RCC_AHB2Periph, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_RCC_AHB2_PERIPH(RCC_AHB2Periph));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ RCC->AHB2RSTR |= RCC_AHB2Periph;
+ }
+ else
+ {
+ RCC->AHB2RSTR &= ~RCC_AHB2Periph;
+ }
+}
+
+/**
+ * @brief Forces or releases AHB3 peripheral reset.
+ * @param RCC_AHB3Periph: specifies the AHB3 peripheral to reset.
+ * This parameter must be: RCC_AHB3Periph_FSMC
+ * @param NewState: new state of the specified peripheral reset.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void RCC_AHB3PeriphResetCmd(uint32_t RCC_AHB3Periph, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_RCC_AHB3_PERIPH(RCC_AHB3Periph));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ RCC->AHB3RSTR |= RCC_AHB3Periph;
+ }
+ else
+ {
+ RCC->AHB3RSTR &= ~RCC_AHB3Periph;
+ }
+}
+
+/**
+ * @brief Forces or releases Low Speed APB (APB1) peripheral reset.
+ * @param RCC_APB1Periph: specifies the APB1 peripheral to reset.
+ * This parameter can be any combination of the following values:
+ * @arg RCC_APB1Periph_TIM2: TIM2 clock
+ * @arg RCC_APB1Periph_TIM3: TIM3 clock
+ * @arg RCC_APB1Periph_TIM4: TIM4 clock
+ * @arg RCC_APB1Periph_TIM5: TIM5 clock
+ * @arg RCC_APB1Periph_TIM6: TIM6 clock
+ * @arg RCC_APB1Periph_TIM7: TIM7 clock
+ * @arg RCC_APB1Periph_TIM12: TIM12 clock
+ * @arg RCC_APB1Periph_TIM13: TIM13 clock
+ * @arg RCC_APB1Periph_TIM14: TIM14 clock
+ * @arg RCC_APB1Periph_WWDG: WWDG clock
+ * @arg RCC_APB1Periph_SPI2: SPI2 clock
+ * @arg RCC_APB1Periph_SPI3: SPI3 clock
+ * @arg RCC_APB1Periph_USART2: USART2 clock
+ * @arg RCC_APB1Periph_USART3: USART3 clock
+ * @arg RCC_APB1Periph_UART4: UART4 clock
+ * @arg RCC_APB1Periph_UART5: UART5 clock
+ * @arg RCC_APB1Periph_I2C1: I2C1 clock
+ * @arg RCC_APB1Periph_I2C2: I2C2 clock
+ * @arg RCC_APB1Periph_I2C3: I2C3 clock
+ * @arg RCC_APB1Periph_CAN1: CAN1 clock
+ * @arg RCC_APB1Periph_CAN2: CAN2 clock
+ * @arg RCC_APB1Periph_PWR: PWR clock
+ * @arg RCC_APB1Periph_DAC: DAC clock
+ * @param NewState: new state of the specified peripheral reset.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void RCC_APB1PeriphResetCmd(uint32_t RCC_APB1Periph, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_RCC_APB1_PERIPH(RCC_APB1Periph));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ if (NewState != DISABLE)
+ {
+ RCC->APB1RSTR |= RCC_APB1Periph;
+ }
+ else
+ {
+ RCC->APB1RSTR &= ~RCC_APB1Periph;
+ }
+}
+
+/**
+ * @brief Forces or releases High Speed APB (APB2) peripheral reset.
+ * @param RCC_APB2Periph: specifies the APB2 peripheral to reset.
+ * This parameter can be any combination of the following values:
+ * @arg RCC_APB2Periph_TIM1: TIM1 clock
+ * @arg RCC_APB2Periph_TIM8: TIM8 clock
+ * @arg RCC_APB2Periph_USART1: USART1 clock
+ * @arg RCC_APB2Periph_USART6: USART6 clock
+ * @arg RCC_APB2Periph_ADC1: ADC1 clock
+ * @arg RCC_APB2Periph_ADC2: ADC2 clock
+ * @arg RCC_APB2Periph_ADC3: ADC3 clock
+ * @arg RCC_APB2Periph_SDIO: SDIO clock
+ * @arg RCC_APB2Periph_SPI1: SPI1 clock
+ * @arg RCC_APB2Periph_SYSCFG: SYSCFG clock
+ * @arg RCC_APB2Periph_TIM9: TIM9 clock
+ * @arg RCC_APB2Periph_TIM10: TIM10 clock
+ * @arg RCC_APB2Periph_TIM11: TIM11 clock
+ * @param NewState: new state of the specified peripheral reset.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void RCC_APB2PeriphResetCmd(uint32_t RCC_APB2Periph, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_RCC_APB2_RESET_PERIPH(RCC_APB2Periph));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ if (NewState != DISABLE)
+ {
+ RCC->APB2RSTR |= RCC_APB2Periph;
+ }
+ else
+ {
+ RCC->APB2RSTR &= ~RCC_APB2Periph;
+ }
+}
+
+/**
+ * @brief Enables or disables the AHB1 peripheral clock during Low Power (Sleep) mode.
+ * @note Peripheral clock gating in SLEEP mode can be used to further reduce
+ * power consumption.
+ * @note After wakeup from SLEEP mode, the peripheral clock is enabled again.
+ * @note By default, all peripheral clocks are enabled during SLEEP mode.
+ * @param RCC_AHBPeriph: specifies the AHB1 peripheral to gates its clock.
+ * This parameter can be any combination of the following values:
+ * @arg RCC_AHB1Periph_GPIOA: GPIOA clock
+ * @arg RCC_AHB1Periph_GPIOB: GPIOB clock
+ * @arg RCC_AHB1Periph_GPIOC: GPIOC clock
+ * @arg RCC_AHB1Periph_GPIOD: GPIOD clock
+ * @arg RCC_AHB1Periph_GPIOE: GPIOE clock
+ * @arg RCC_AHB1Periph_GPIOF: GPIOF clock
+ * @arg RCC_AHB1Periph_GPIOG: GPIOG clock
+ * @arg RCC_AHB1Periph_GPIOG: GPIOG clock
+ * @arg RCC_AHB1Periph_GPIOI: GPIOI clock
+ * @arg RCC_AHB1Periph_CRC: CRC clock
+ * @arg RCC_AHB1Periph_BKPSRAM: BKPSRAM interface clock
+ * @arg RCC_AHB1Periph_DMA1: DMA1 clock
+ * @arg RCC_AHB1Periph_DMA2: DMA2 clock
+ * @arg RCC_AHB1Periph_ETH_MAC: Ethernet MAC clock
+ * @arg RCC_AHB1Periph_ETH_MAC_Tx: Ethernet Transmission clock
+ * @arg RCC_AHB1Periph_ETH_MAC_Rx: Ethernet Reception clock
+ * @arg RCC_AHB1Periph_ETH_MAC_PTP: Ethernet PTP clock
+ * @arg RCC_AHB1Periph_OTG_HS: USB OTG HS clock
+ * @arg RCC_AHB1Periph_OTG_HS_ULPI: USB OTG HS ULPI clock
+ * @param NewState: new state of the specified peripheral clock.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void RCC_AHB1PeriphClockLPModeCmd(uint32_t RCC_AHB1Periph, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_RCC_AHB1_LPMODE_PERIPH(RCC_AHB1Periph));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ if (NewState != DISABLE)
+ {
+ RCC->AHB1LPENR |= RCC_AHB1Periph;
+ }
+ else
+ {
+ RCC->AHB1LPENR &= ~RCC_AHB1Periph;
+ }
+}
+
+/**
+ * @brief Enables or disables the AHB2 peripheral clock during Low Power (Sleep) mode.
+ * @note Peripheral clock gating in SLEEP mode can be used to further reduce
+ * power consumption.
+ * @note After wakeup from SLEEP mode, the peripheral clock is enabled again.
+ * @note By default, all peripheral clocks are enabled during SLEEP mode.
+ * @param RCC_AHBPeriph: specifies the AHB2 peripheral to gates its clock.
+ * This parameter can be any combination of the following values:
+ * @arg RCC_AHB2Periph_DCMI: DCMI clock
+ * @arg RCC_AHB2Periph_CRYP: CRYP clock
+ * @arg RCC_AHB2Periph_HASH: HASH clock
+ * @arg RCC_AHB2Periph_RNG: RNG clock
+ * @arg RCC_AHB2Periph_OTG_FS: USB OTG FS clock
+ * @param NewState: new state of the specified peripheral clock.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void RCC_AHB2PeriphClockLPModeCmd(uint32_t RCC_AHB2Periph, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_RCC_AHB2_PERIPH(RCC_AHB2Periph));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ if (NewState != DISABLE)
+ {
+ RCC->AHB2LPENR |= RCC_AHB2Periph;
+ }
+ else
+ {
+ RCC->AHB2LPENR &= ~RCC_AHB2Periph;
+ }
+}
+
+/**
+ * @brief Enables or disables the AHB3 peripheral clock during Low Power (Sleep) mode.
+ * @note Peripheral clock gating in SLEEP mode can be used to further reduce
+ * power consumption.
+ * @note After wakeup from SLEEP mode, the peripheral clock is enabled again.
+ * @note By default, all peripheral clocks are enabled during SLEEP mode.
+ * @param RCC_AHBPeriph: specifies the AHB3 peripheral to gates its clock.
+ * This parameter must be: RCC_AHB3Periph_FSMC
+ * @param NewState: new state of the specified peripheral clock.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void RCC_AHB3PeriphClockLPModeCmd(uint32_t RCC_AHB3Periph, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_RCC_AHB3_PERIPH(RCC_AHB3Periph));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ if (NewState != DISABLE)
+ {
+ RCC->AHB3LPENR |= RCC_AHB3Periph;
+ }
+ else
+ {
+ RCC->AHB3LPENR &= ~RCC_AHB3Periph;
+ }
+}
+
+/**
+ * @brief Enables or disables the APB1 peripheral clock during Low Power (Sleep) mode.
+ * @note Peripheral clock gating in SLEEP mode can be used to further reduce
+ * power consumption.
+ * @note After wakeup from SLEEP mode, the peripheral clock is enabled again.
+ * @note By default, all peripheral clocks are enabled during SLEEP mode.
+ * @param RCC_APB1Periph: specifies the APB1 peripheral to gates its clock.
+ * This parameter can be any combination of the following values:
+ * @arg RCC_APB1Periph_TIM2: TIM2 clock
+ * @arg RCC_APB1Periph_TIM3: TIM3 clock
+ * @arg RCC_APB1Periph_TIM4: TIM4 clock
+ * @arg RCC_APB1Periph_TIM5: TIM5 clock
+ * @arg RCC_APB1Periph_TIM6: TIM6 clock
+ * @arg RCC_APB1Periph_TIM7: TIM7 clock
+ * @arg RCC_APB1Periph_TIM12: TIM12 clock
+ * @arg RCC_APB1Periph_TIM13: TIM13 clock
+ * @arg RCC_APB1Periph_TIM14: TIM14 clock
+ * @arg RCC_APB1Periph_WWDG: WWDG clock
+ * @arg RCC_APB1Periph_SPI2: SPI2 clock
+ * @arg RCC_APB1Periph_SPI3: SPI3 clock
+ * @arg RCC_APB1Periph_USART2: USART2 clock
+ * @arg RCC_APB1Periph_USART3: USART3 clock
+ * @arg RCC_APB1Periph_UART4: UART4 clock
+ * @arg RCC_APB1Periph_UART5: UART5 clock
+ * @arg RCC_APB1Periph_I2C1: I2C1 clock
+ * @arg RCC_APB1Periph_I2C2: I2C2 clock
+ * @arg RCC_APB1Periph_I2C3: I2C3 clock
+ * @arg RCC_APB1Periph_CAN1: CAN1 clock
+ * @arg RCC_APB1Periph_CAN2: CAN2 clock
+ * @arg RCC_APB1Periph_PWR: PWR clock
+ * @arg RCC_APB1Periph_DAC: DAC clock
+ * @param NewState: new state of the specified peripheral clock.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void RCC_APB1PeriphClockLPModeCmd(uint32_t RCC_APB1Periph, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_RCC_APB1_PERIPH(RCC_APB1Periph));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ if (NewState != DISABLE)
+ {
+ RCC->APB1LPENR |= RCC_APB1Periph;
+ }
+ else
+ {
+ RCC->APB1LPENR &= ~RCC_APB1Periph;
+ }
+}
+
+/**
+ * @brief Enables or disables the APB2 peripheral clock during Low Power (Sleep) mode.
+ * @note Peripheral clock gating in SLEEP mode can be used to further reduce
+ * power consumption.
+ * @note After wakeup from SLEEP mode, the peripheral clock is enabled again.
+ * @note By default, all peripheral clocks are enabled during SLEEP mode.
+ * @param RCC_APB2Periph: specifies the APB2 peripheral to gates its clock.
+ * This parameter can be any combination of the following values:
+ * @arg RCC_APB2Periph_TIM1: TIM1 clock
+ * @arg RCC_APB2Periph_TIM8: TIM8 clock
+ * @arg RCC_APB2Periph_USART1: USART1 clock
+ * @arg RCC_APB2Periph_USART6: USART6 clock
+ * @arg RCC_APB2Periph_ADC1: ADC1 clock
+ * @arg RCC_APB2Periph_ADC2: ADC2 clock
+ * @arg RCC_APB2Periph_ADC3: ADC3 clock
+ * @arg RCC_APB2Periph_SDIO: SDIO clock
+ * @arg RCC_APB2Periph_SPI1: SPI1 clock
+ * @arg RCC_APB2Periph_SYSCFG: SYSCFG clock
+ * @arg RCC_APB2Periph_TIM9: TIM9 clock
+ * @arg RCC_APB2Periph_TIM10: TIM10 clock
+ * @arg RCC_APB2Periph_TIM11: TIM11 clock
+ * @param NewState: new state of the specified peripheral clock.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void RCC_APB2PeriphClockLPModeCmd(uint32_t RCC_APB2Periph, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_RCC_APB2_PERIPH(RCC_APB2Periph));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ if (NewState != DISABLE)
+ {
+ RCC->APB2LPENR |= RCC_APB2Periph;
+ }
+ else
+ {
+ RCC->APB2LPENR &= ~RCC_APB2Periph;
+ }
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup RCC_Group4 Interrupts and flags management functions
+ * @brief Interrupts and flags management functions
+ *
+@verbatim
+ ===============================================================================
+ Interrupts and flags management functions
+ ===============================================================================
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Enables or disables the specified RCC interrupts.
+ * @param RCC_IT: specifies the RCC interrupt sources to be enabled or disabled.
+ * This parameter can be any combination of the following values:
+ * @arg RCC_IT_LSIRDY: LSI ready interrupt
+ * @arg RCC_IT_LSERDY: LSE ready interrupt
+ * @arg RCC_IT_HSIRDY: HSI ready interrupt
+ * @arg RCC_IT_HSERDY: HSE ready interrupt
+ * @arg RCC_IT_PLLRDY: main PLL ready interrupt
+ * @arg RCC_IT_PLLI2SRDY: PLLI2S ready interrupt
+ * @param NewState: new state of the specified RCC interrupts.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void RCC_ITConfig(uint8_t RCC_IT, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_RCC_IT(RCC_IT));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ if (NewState != DISABLE)
+ {
+ /* Perform Byte access to RCC_CIR[14:8] bits to enable the selected interrupts */
+ *(__IO uint8_t *) CIR_BYTE2_ADDRESS |= RCC_IT;
+ }
+ else
+ {
+ /* Perform Byte access to RCC_CIR[14:8] bits to disable the selected interrupts */
+ *(__IO uint8_t *) CIR_BYTE2_ADDRESS &= (uint8_t)~RCC_IT;
+ }
+}
+
+/**
+ * @brief Checks whether the specified RCC flag is set or not.
+ * @param RCC_FLAG: specifies the flag to check.
+ * This parameter can be one of the following values:
+ * @arg RCC_FLAG_HSIRDY: HSI oscillator clock ready
+ * @arg RCC_FLAG_HSERDY: HSE oscillator clock ready
+ * @arg RCC_FLAG_PLLRDY: main PLL clock ready
+ * @arg RCC_FLAG_PLLI2SRDY: PLLI2S clock ready
+ * @arg RCC_FLAG_LSERDY: LSE oscillator clock ready
+ * @arg RCC_FLAG_LSIRDY: LSI oscillator clock ready
+ * @arg RCC_FLAG_BORRST: POR/PDR or BOR reset
+ * @arg RCC_FLAG_PINRST: Pin reset
+ * @arg RCC_FLAG_PORRST: POR/PDR reset
+ * @arg RCC_FLAG_SFTRST: Software reset
+ * @arg RCC_FLAG_IWDGRST: Independent Watchdog reset
+ * @arg RCC_FLAG_WWDGRST: Window Watchdog reset
+ * @arg RCC_FLAG_LPWRRST: Low Power reset
+ * @retval The new state of RCC_FLAG (SET or RESET).
+ */
+FlagStatus RCC_GetFlagStatus(uint8_t RCC_FLAG)
+{
+ uint32_t tmp = 0;
+ uint32_t statusreg = 0;
+ FlagStatus bitstatus = RESET;
+
+ /* Check the parameters */
+ assert_param(IS_RCC_FLAG(RCC_FLAG));
+
+ /* Get the RCC register index */
+ tmp = RCC_FLAG >> 5;
+ if (tmp == 1) /* The flag to check is in CR register */
+ {
+ statusreg = RCC->CR;
+ }
+ else if (tmp == 2) /* The flag to check is in BDCR register */
+ {
+ statusreg = RCC->BDCR;
+ }
+ else /* The flag to check is in CSR register */
+ {
+ statusreg = RCC->CSR;
+ }
+
+ /* Get the flag position */
+ tmp = RCC_FLAG & FLAG_MASK;
+ if ((statusreg & ((uint32_t)1 << tmp)) != (uint32_t)RESET)
+ {
+ bitstatus = SET;
+ }
+ else
+ {
+ bitstatus = RESET;
+ }
+ /* Return the flag status */
+ return bitstatus;
+}
+
+/**
+ * @brief Clears the RCC reset flags.
+ * The reset flags are: RCC_FLAG_PINRST, RCC_FLAG_PORRST, RCC_FLAG_SFTRST,
+ * RCC_FLAG_IWDGRST, RCC_FLAG_WWDGRST, RCC_FLAG_LPWRRST
+ * @param None
+ * @retval None
+ */
+void RCC_ClearFlag(void)
+{
+ /* Set RMVF bit to clear the reset flags */
+ RCC->CSR |= RCC_CSR_RMVF;
+}
+
+/**
+ * @brief Checks whether the specified RCC interrupt has occurred or not.
+ * @param RCC_IT: specifies the RCC interrupt source to check.
+ * This parameter can be one of the following values:
+ * @arg RCC_IT_LSIRDY: LSI ready interrupt
+ * @arg RCC_IT_LSERDY: LSE ready interrupt
+ * @arg RCC_IT_HSIRDY: HSI ready interrupt
+ * @arg RCC_IT_HSERDY: HSE ready interrupt
+ * @arg RCC_IT_PLLRDY: main PLL ready interrupt
+ * @arg RCC_IT_PLLI2SRDY: PLLI2S ready interrupt
+ * @arg RCC_IT_CSS: Clock Security System interrupt
+ * @retval The new state of RCC_IT (SET or RESET).
+ */
+ITStatus RCC_GetITStatus(uint8_t RCC_IT)
+{
+ ITStatus bitstatus = RESET;
+
+ /* Check the parameters */
+ assert_param(IS_RCC_GET_IT(RCC_IT));
+
+ /* Check the status of the specified RCC interrupt */
+ if ((RCC->CIR & RCC_IT) != (uint32_t)RESET)
+ {
+ bitstatus = SET;
+ }
+ else
+ {
+ bitstatus = RESET;
+ }
+ /* Return the RCC_IT status */
+ return bitstatus;
+}
+
+/**
+ * @brief Clears the RCC's interrupt pending bits.
+ * @param RCC_IT: specifies the interrupt pending bit to clear.
+ * This parameter can be any combination of the following values:
+ * @arg RCC_IT_LSIRDY: LSI ready interrupt
+ * @arg RCC_IT_LSERDY: LSE ready interrupt
+ * @arg RCC_IT_HSIRDY: HSI ready interrupt
+ * @arg RCC_IT_HSERDY: HSE ready interrupt
+ * @arg RCC_IT_PLLRDY: main PLL ready interrupt
+ * @arg RCC_IT_PLLI2SRDY: PLLI2S ready interrupt
+ * @arg RCC_IT_CSS: Clock Security System interrupt
+ * @retval None
+ */
+void RCC_ClearITPendingBit(uint8_t RCC_IT)
+{
+ /* Check the parameters */
+ assert_param(IS_RCC_CLEAR_IT(RCC_IT));
+
+ /* Perform Byte access to RCC_CIR[23:16] bits to clear the selected interrupt
+ pending bits */
+ *(__IO uint8_t *) CIR_BYTE3_ADDRESS = RCC_IT;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/src/stm32f2xx_rng.c b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/src/stm32f2xx_rng.c
new file mode 100644
index 0000000..9f0d6c2
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/src/stm32f2xx_rng.c
@@ -0,0 +1,405 @@
+/**
+ ******************************************************************************
+ * @file stm32f2xx_rng.c
+ * @author MCD Application Team
+ * @version V1.1.2
+ * @date 05-March-2012
+ * @brief This file provides firmware functions to manage the following
+ * functionalities of the Random Number Generator (RNG) peripheral:
+ * - Initialization and Configuration
+ * - Get 32 bit Random number
+ * - Interrupts and flags management
+ *
+ * @verbatim
+ *
+ * ===================================================================
+ * How to use this driver
+ * ===================================================================
+ * 1. Enable The RNG controller clock using
+ * RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_RNG, ENABLE) function.
+ *
+ * 2. Activate the RNG peripheral using RNG_Cmd() function.
+ *
+ * 3. Wait until the 32 bit Random number Generator contains a valid
+ * random data (using polling/interrupt mode). For more details,
+ * refer to "Interrupts and flags management functions" module
+ * description.
+ *
+ * 4. Get the 32 bit Random number using RNG_GetRandomNumber() function
+ *
+ * 5. To get another 32 bit Random number, go to step 3.
+ *
+ *
+ *
+ * @endverbatim
+ *
+ ******************************************************************************
+ * @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 "stm32f2xx_rng.h"
+#include "stm32f2xx_rcc.h"
+
+/** @addtogroup STM32F2xx_StdPeriph_Driver
+ * @{
+ */
+
+/** @defgroup RNG
+ * @brief RNG driver modules
+ * @{
+ */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+/** @defgroup RNG_Private_Functions
+ * @{
+ */
+
+/** @defgroup RNG_Group1 Initialization and Configuration functions
+ * @brief Initialization and Configuration functions
+ *
+@verbatim
+ ===============================================================================
+ Initialization and Configuration functions
+ ===============================================================================
+ This section provides functions allowing to
+ - Initialize the RNG peripheral
+ - Enable or disable the RNG peripheral
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Deinitializes the RNG peripheral registers to their default reset values.
+ * @param None
+ * @retval None
+ */
+void RNG_DeInit(void)
+{
+ /* Enable RNG reset state */
+ RCC_AHB2PeriphResetCmd(RCC_AHB2Periph_RNG, ENABLE);
+
+ /* Release RNG from reset state */
+ RCC_AHB2PeriphResetCmd(RCC_AHB2Periph_RNG, DISABLE);
+}
+
+/**
+ * @brief Enables or disables the RNG peripheral.
+ * @param NewState: new state of the RNG peripheral.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void RNG_Cmd(FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the RNG */
+ RNG->CR |= RNG_CR_RNGEN;
+ }
+ else
+ {
+ /* Disable the RNG */
+ RNG->CR &= ~RNG_CR_RNGEN;
+ }
+}
+/**
+ * @}
+ */
+
+/** @defgroup RNG_Group2 Get 32 bit Random number function
+ * @brief Get 32 bit Random number function
+ *
+
+@verbatim
+ ===============================================================================
+ Get 32 bit Random number function
+ ===============================================================================
+ This section provides a function allowing to get the 32 bit Random number
+
+ @note Before to call this function you have to wait till DRDY flag is set,
+ using RNG_GetFlagStatus(RNG_FLAG_DRDY) function.
+
+@endverbatim
+ * @{
+ */
+
+
+/**
+ * @brief Returns a 32-bit random number.
+ *
+ * @note Before to call this function you have to wait till DRDY (data ready)
+ * flag is set, using RNG_GetFlagStatus(RNG_FLAG_DRDY) function.
+ * @note Each time the the Random number data is read (using RNG_GetRandomNumber()
+ * function), the RNG_FLAG_DRDY flag is automatically cleared.
+ * @note In the case of a seed error, the generation of random numbers is
+ * interrupted for as long as the SECS bit is '1'. If a number is
+ * available in the RNG_DR register, it must not be used because it may
+ * not have enough entropy. In this case, it is recommended to clear the
+ * SEIS bit(using RNG_ClearFlag(RNG_FLAG_SECS) function), then disable
+ * and enable the RNG peripheral (using RNG_Cmd() function) to
+ * reinitialize and restart the RNG.
+ * @note In the case of a clock error, the RNG is no more able to generate
+ * random numbers because the PLL48CLK clock is not correct. User have
+ * to check that the clock controller is correctly configured to provide
+ * the RNG clock and clear the CEIS bit (using RNG_ClearFlag(RNG_FLAG_CECS)
+ * function) . The clock error has no impact on the previously generated
+ * random numbers, and the RNG_DR register contents can be used.
+ *
+ * @param None
+ * @retval 32-bit random number.
+ */
+uint32_t RNG_GetRandomNumber(void)
+{
+ /* Return the 32 bit random number from the DR register */
+ return RNG->DR;
+}
+
+
+/**
+ * @}
+ */
+
+/** @defgroup RNG_Group3 Interrupts and flags management functions
+ * @brief Interrupts and flags management functions
+ *
+@verbatim
+ ===============================================================================
+ Interrupts and flags management functions
+ ===============================================================================
+
+ This section provides functions allowing to configure the RNG Interrupts and
+ to get the status and clear flags and Interrupts pending bits.
+
+ The RNG provides 3 Interrupts sources and 3 Flags:
+
+ Flags :
+ ----------
+ 1. RNG_FLAG_DRDY : In the case of the RNG_DR register contains valid
+ random data. it is cleared by reading the valid data
+ (using RNG_GetRandomNumber() function).
+
+ 2. RNG_FLAG_CECS : In the case of a seed error detection.
+
+ 3. RNG_FLAG_SECS : In the case of a clock error detection.
+
+
+ Interrupts :
+ ------------
+ if enabled, an RNG interrupt is pending :
+
+ 1. In the case of the RNG_DR register contains valid random data.
+ This interrupt source is cleared once the RNG_DR register has been read
+ (using RNG_GetRandomNumber() function) until a new valid value is
+ computed.
+
+ or
+ 2. In the case of a seed error : One of the following faulty sequences has
+ been detected:
+ - More than 64 consecutive bits at the same value (0 or 1)
+ - More than 32 consecutive alternance of 0 and 1 (0101010101...01)
+ This interrupt source is cleared using RNG_ClearITPendingBit(RNG_IT_SEI)
+ function.
+
+ or
+ 3. In the case of a clock error : the PLL48CLK (RNG peripheral clock source)
+ was not correctly detected (fPLL48CLK< fHCLK/16).
+ This interrupt source is cleared using RNG_ClearITPendingBit(RNG_IT_CEI)
+ function.
+ @note In this case, User have to check that the clock controller is
+ correctly configured to provide the RNG clock.
+
+ Managing the RNG controller events :
+ ------------------------------------
+ The user should identify which mode will be used in his application to manage
+ the RNG controller events: Polling mode or Interrupt mode.
+
+ 1. In the Polling Mode it is advised to use the following functions:
+ - RNG_GetFlagStatus() : to check if flags events occur.
+ - RNG_ClearFlag() : to clear the flags events.
+
+ @note RNG_FLAG_DRDY can not be cleared by RNG_ClearFlag(). it is cleared only
+ by reading the Random number data.
+
+ 2. In the Interrupt Mode it is advised to use the following functions:
+ - RNG_ITConfig() : to enable or disable the interrupt source.
+ - RNG_GetITStatus() : to check if Interrupt occurs.
+ - RNG_ClearITPendingBit() : to clear the Interrupt pending Bit
+ (corresponding Flag).
+
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Enables or disables the RNG interrupt.
+ * @note The RNG provides 3 interrupt sources,
+ * - Computed data is ready event (DRDY), and
+ * - Seed error Interrupt (SEI) and
+ * - Clock error Interrupt (CEI),
+ * all these interrupts sources are enabled by setting the IE bit in
+ * CR register. However, each interrupt have its specific status bit
+ * (see RNG_GetITStatus() function) and clear bit except the DRDY event
+ * (see RNG_ClearITPendingBit() function).
+ * @param NewState: new state of the RNG interrupt.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void RNG_ITConfig(FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the RNG interrupt */
+ RNG->CR |= RNG_CR_IE;
+ }
+ else
+ {
+ /* Disable the RNG interrupt */
+ RNG->CR &= ~RNG_CR_IE;
+ }
+}
+
+/**
+ * @brief Checks whether the specified RNG flag is set or not.
+ * @param RNG_FLAG: specifies the RNG flag to check.
+ * This parameter can be one of the following values:
+ * @arg RNG_FLAG_DRDY: Data Ready flag.
+ * @arg RNG_FLAG_CECS: Clock Error Current flag.
+ * @arg RNG_FLAG_SECS: Seed Error Current flag.
+ * @retval The new state of RNG_FLAG (SET or RESET).
+ */
+FlagStatus RNG_GetFlagStatus(uint8_t RNG_FLAG)
+{
+ FlagStatus bitstatus = RESET;
+ /* Check the parameters */
+ assert_param(IS_RNG_GET_FLAG(RNG_FLAG));
+
+ /* Check the status of the specified RNG flag */
+ if ((RNG->SR & RNG_FLAG) != (uint8_t)RESET)
+ {
+ /* RNG_FLAG is set */
+ bitstatus = SET;
+ }
+ else
+ {
+ /* RNG_FLAG is reset */
+ bitstatus = RESET;
+ }
+ /* Return the RNG_FLAG status */
+ return bitstatus;
+}
+
+
+/**
+ * @brief Clears the RNG flags.
+ * @param RNG_FLAG: specifies the flag to clear.
+ * This parameter can be any combination of the following values:
+ * @arg RNG_FLAG_CECS: Clock Error Current flag.
+ * @arg RNG_FLAG_SECS: Seed Error Current flag.
+ * @note RNG_FLAG_DRDY can not be cleared by RNG_ClearFlag() function.
+ * This flag is cleared only by reading the Random number data (using
+ * RNG_GetRandomNumber() function).
+ * @retval None
+ */
+void RNG_ClearFlag(uint8_t RNG_FLAG)
+{
+ /* Check the parameters */
+ assert_param(IS_RNG_CLEAR_FLAG(RNG_FLAG));
+ /* Clear the selected RNG flags */
+ RNG->SR = ~(uint32_t)(((uint32_t)RNG_FLAG) << 4);
+}
+
+/**
+ * @brief Checks whether the specified RNG interrupt has occurred or not.
+ * @param RNG_IT: specifies the RNG interrupt source to check.
+ * This parameter can be one of the following values:
+ * @arg RNG_IT_CEI: Clock Error Interrupt.
+ * @arg RNG_IT_SEI: Seed Error Interrupt.
+ * @retval The new state of RNG_IT (SET or RESET).
+ */
+ITStatus RNG_GetITStatus(uint8_t RNG_IT)
+{
+ ITStatus bitstatus = RESET;
+ /* Check the parameters */
+ assert_param(IS_RNG_GET_IT(RNG_IT));
+
+ /* Check the status of the specified RNG interrupt */
+ if ((RNG->SR & RNG_IT) != (uint8_t)RESET)
+ {
+ /* RNG_IT is set */
+ bitstatus = SET;
+ }
+ else
+ {
+ /* RNG_IT is reset */
+ bitstatus = RESET;
+ }
+ /* Return the RNG_IT status */
+ return bitstatus;
+}
+
+
+/**
+ * @brief Clears the RNG interrupt pending bit(s).
+ * @param RNG_IT: specifies the RNG interrupt pending bit(s) to clear.
+ * This parameter can be any combination of the following values:
+ * @arg RNG_IT_CEI: Clock Error Interrupt.
+ * @arg RNG_IT_SEI: Seed Error Interrupt.
+ * @retval None
+ */
+void RNG_ClearITPendingBit(uint8_t RNG_IT)
+{
+ /* Check the parameters */
+ assert_param(IS_RNG_IT(RNG_IT));
+
+ /* Clear the selected RNG interrupt pending bit */
+ RNG->SR = (uint8_t)~RNG_IT;
+}
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+
+/**
+ * @}
+ */
+
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/src/stm32f2xx_rtc.c b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/src/stm32f2xx_rtc.c
new file mode 100644
index 0000000..00c6aa6
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/src/stm32f2xx_rtc.c
@@ -0,0 +1,2244 @@
+/**
+ ******************************************************************************
+ * @file stm32f2xx_rtc.c
+ * @author MCD Application Team
+ * @version V1.1.2
+ * @date 05-March-2012
+ * @brief This file provides firmware functions to manage the following
+ * functionalities of the Real-Time Clock (RTC) peripheral:
+ * - Initialization
+ * - Calendar (Time and Date) configuration
+ * - Alarms (Alarm A and Alarm B) configuration
+ * - WakeUp Timer configuration
+ * - Daylight Saving configuration
+ * - Output pin Configuration
+ * - Coarse Calibration configuration
+ * - TimeStamp configuration
+ * - Tampers configuration
+ * - Backup Data Registers configuration
+ * - RTC Tamper and TimeStamp Pins Selection and Output Type Config configuration
+ * - Interrupts and flags management
+ *
+ * @verbatim
+ *
+ * ===================================================================
+ * Backup Domain Operating Condition
+ * ===================================================================
+ * The real-time clock (RTC), the RTC backup registers, and the backup
+ * SRAM (BKP SRAM) can be powered from the VBAT voltage when the main
+ * VDD supply is powered off.
+ * To retain the content of the RTC backup registers, backup SRAM,
+ * and supply the RTC when VDD is turned off, VBAT pin can be connected
+ * to an optional standby voltage supplied by a battery or by another
+ * source.
+ *
+ * To allow the RTC to operate even when the main digital supply (VDD)
+ * is turned off, the VBAT pin powers the following blocks:
+ * 1 - The RTC
+ * 2 - The LSE oscillator
+ * 3 - The backup SRAM when the low power backup regulator is enabled
+ * 4 - PC13 to PC15 I/Os, plus PI8 I/O (when available)
+ *
+ * When the backup domain is supplied by VDD (analog switch connected
+ * to VDD), the following functions are available:
+ * 1 - PC14 and PC15 can be used as either GPIO or LSE pins
+ * 2 - PC13 can be used as a GPIO or as the RTC_AF1 pin
+ * 3 - PI8 can be used as a GPIO or as the RTC_AF2 pin
+ *
+ * When the backup domain is supplied by VBAT (analog switch connected
+ * to VBAT because VDD is not present), the following functions are available:
+ * 1 - PC14 and PC15 can be used as LSE pins only
+ * 2 - PC13 can be used as the RTC_AF1 pin
+ * 3 - PI8 can be used as the RTC_AF2 pin
+ *
+ * ===================================================================
+ * Backup Domain Reset
+ * ===================================================================
+ * The backup domain reset sets all RTC registers and the RCC_BDCR
+ * register to their reset values. The BKPSRAM is not affected by this
+ * reset. The only way of resetting the BKPSRAM is through the Flash
+ * interface by requesting a protection level change from 1 to 0.
+ * A backup domain reset is generated when one of the following events
+ * occurs:
+ * 1 - Software reset, triggered by setting the BDRST bit in the
+ * RCC Backup domain control register (RCC_BDCR). You can use the
+ * RCC_BackupResetCmd().
+ * 2 - VDD or VBAT power on, if both supplies have previously been
+ * powered off.
+ *
+ * ===================================================================
+ * Backup Domain Access
+ * ===================================================================
+ * After reset, the backup domain (RTC registers, RTC backup data
+ * registers and backup SRAM) is protected against possible unwanted
+ * write accesses.
+ * To enable access to the RTC Domain and RTC registers, proceed as follows:
+ * - Enable the Power Controller (PWR) APB1 interface clock using the
+ * RCC_APB1PeriphClockCmd() function.
+ * - Enable access to RTC domain using the PWR_BackupAccessCmd() function.
+ * - Select the RTC clock source using the RCC_RTCCLKConfig() function.
+ * - Enable RTC Clock using the RCC_RTCCLKCmd() function.
+ *
+ * ===================================================================
+ * RTC Driver: how to use it
+ * ===================================================================
+ * - Enable the RTC domain access (see description in the section above)
+ * - Configure the RTC Prescaler (Asynchronous and Synchronous) and
+ * RTC hour format using the RTC_Init() function.
+ *
+ * Time and Date configuration
+ * ===========================
+ * - To configure the RTC Calendar (Time and Date) use the RTC_SetTime()
+ * and RTC_SetDate() functions.
+ * - To read the RTC Calendar, use the RTC_GetTime() and RTC_GetDate()
+ * functions.
+ * - Use the RTC_DayLightSavingConfig() function to add or sub one
+ * hour to the RTC Calendar.
+ *
+ * Alarm configuration
+ * ===================
+ * - To configure the RTC Alarm use the RTC_SetAlarm() function.
+ * - Enable the selected RTC Alarm using the RTC_AlarmCmd() function
+ * - To read the RTC Alarm, use the RTC_GetAlarm() function.
+ *
+ * RTC Wakeup configuration
+ * ========================
+ * - Configure the RTC Wakeup Clock source use the RTC_WakeUpClockConfig()
+ * function.
+ * - Configure the RTC WakeUp Counter using the RTC_SetWakeUpCounter()
+ * function
+ * - Enable the RTC WakeUp using the RTC_WakeUpCmd() function
+ * - To read the RTC WakeUp Counter register, use the RTC_GetWakeUpCounter()
+ * function.
+ *
+ * Outputs configuration
+ * =====================
+ * The RTC has 2 different outputs:
+ * - AFO_ALARM: this output is used to manage the RTC Alarm A, Alarm B
+ * and WaKeUp signals.
+ * To output the selected RTC signal on RTC_AF1 pin, use the
+ * RTC_OutputConfig() function.
+ * - AFO_CALIB: this output is used to manage the RTC Clock divided
+ * by 64 (512Hz) signal.
+ * To output the RTC Clock on RTC_AF1 pin, use the RTC_CalibOutputCmd()
+ * function.
+ *
+ * Coarse Calibration configuration
+ * =================================
+ * - Configure the RTC Coarse Calibration Value and the corresponding
+ * sign using the RTC_CoarseCalibConfig() function.
+ * - Enable the RTC Coarse Calibration using the RTC_CoarseCalibCmd()
+ * function
+ *
+ * TimeStamp configuration
+ * =======================
+ * - Configure the RTC_AF1 trigger and enables the RTC TimeStamp
+ * using the RTC_TimeStampCmd() function.
+ * - To read the RTC TimeStamp Time and Date register, use the
+ * RTC_GetTimeStamp() function.
+ * - The TAMPER1 alternate function can be mapped either to RTC_AF1(PC13)
+ * or RTC_AF2 (PI8) depending on the value of TAMP1INSEL bit in
+ * RTC_TAFCR register. You can use the RTC_TamperPinSelection()
+ * function to select the corresponding pin.
+ *
+ * Tamper configuration
+ * ====================
+ * - Configure the RTC Tamper trigger using the RTC_TamperConfig()
+ * function.
+ * - Enable the RTC Tamper using the RTC_TamperCmd() function.
+ * - The TIMESTAMP alternate function can be mapped to either RTC_AF1
+ * or RTC_AF2 depending on the value of the TSINSEL bit in the
+ * RTC_TAFCR register. You can use the RTC_TimeStampPinSelection()
+ * function to select the corresponding pin.
+ *
+ * Backup Data Registers configuration
+ * ===================================
+ * - To write to the RTC Backup Data registers, use the RTC_WriteBackupRegister()
+ * function.
+ * - To read the RTC Backup Data registers, use the RTC_ReadBackupRegister()
+ * function.
+ *
+ * ===================================================================
+ * RTC and low power modes
+ * ===================================================================
+ * The MCU can be woken up from a low power mode by an RTC alternate
+ * function.
+ * The RTC alternate functions are the RTC alarms (Alarm A and Alarm B),
+ * RTC wakeup, RTC tamper event detection and RTC time stamp event detection.
+ * These RTC alternate functions can wake up the system from the Stop
+ * and Standby lowpower modes.
+ * The system can also wake up from low power modes without depending
+ * on an external interrupt (Auto-wakeup mode), by using the RTC alarm
+ * or the RTC wakeup events.
+ * The RTC provides a programmable time base for waking up from the
+ * Stop or Standby mode at regular intervals.
+ * Wakeup from STOP and Standby modes is possible only when the RTC
+ * clock source is LSE or LSI.
+ *
+ * ===================================================================
+ * Selection of RTC_AF1 alternate functions
+ * ===================================================================
+ * The RTC_AF1 pin (PC13) can be used for the following purposes:
+ * - AFO_ALARM output
+ * - AFO_CALIB output
+ * - AFI_TAMPER
+ * - AFI_TIMESTAMP
+ *
+ * +-------------------------------------------------------------------------------------------------------------+
+ * | Pin |AFO_ALARM |AFO_CALIB |AFI_TAMPER |AFI_TIMESTAMP | TAMP1INSEL | TSINSEL |ALARMOUTTYPE |
+ * | configuration | ENABLED | ENABLED | ENABLED | ENABLED |TAMPER1 pin |TIMESTAMP pin | AFO_ALARM |
+ * | and function | | | | | selection | selection |Configuration |
+ * |-----------------|----------|----------|-----------|--------------|------------|--------------|--------------|
+ * | Alarm out | | | | | Don't | Don't | |
+ * | output OD | 1 |Don't care|Don't care | Don't care | care | care | 0 |
+ * |-----------------|----------|----------|-----------|--------------|------------|--------------|--------------|
+ * | Alarm out | | | | | Don't | Don't | |
+ * | output PP | 1 |Don't care|Don't care | Don't care | care | care | 1 |
+ * |-----------------|----------|----------|-----------|--------------|------------|--------------|--------------|
+ * | Calibration out | | | | | Don't | Don't | |
+ * | output PP | 0 | 1 |Don't care | Don't care | care | care | Don't care |
+ * |-----------------|----------|----------|-----------|--------------|------------|--------------|--------------|
+ * | TAMPER input | | | | | | Don't | |
+ * | floating | 0 | 0 | 1 | 0 | 0 | care | Don't care |
+ * |-----------------|----------|----------|-----------|--------------|------------|--------------|--------------|
+ * | TIMESTAMP and | | | | | | | |
+ * | TAMPER input | 0 | 0 | 1 | 1 | 0 | 0 | Don't care |
+ * | floating | | | | | | | |
+ * |-----------------|----------|----------|-----------|--------------|------------|--------------|--------------|
+ * | TIMESTAMP input | | | | | Don't | | |
+ * | floating | 0 | 0 | 0 | 1 | care | 0 | Don't care |
+ * |-----------------|----------|----------|-----------|--------------|------------|--------------|--------------|
+ * | Standard GPIO | 0 | 0 | 0 | 0 | Don't care | Don't care | Don't care |
+ * +-------------------------------------------------------------------------------------------------------------+
+ *
+ *
+ * ===================================================================
+ * Selection of RTC_AF2 alternate functions
+ * ===================================================================
+ * The RTC_AF2 pin (PI8) can be used for the following purposes:
+ * - AFI_TAMPER
+ * - AFI_TIMESTAMP
+ *
+ * +---------------------------------------------------------------------------------------+
+ * | Pin |AFI_TAMPER |AFI_TIMESTAMP | TAMP1INSEL | TSINSEL |ALARMOUTTYPE |
+ * | configuration | ENABLED | ENABLED |TAMPER1 pin |TIMESTAMP pin | AFO_ALARM |
+ * | and function | | | selection | selection |Configuration |
+ * |-----------------|-----------|--------------|------------|--------------|--------------|
+ * | TAMPER input | | | | Don't | |
+ * | floating | 1 | 0 | 1 | care | Don't care |
+ * |-----------------|-----------|--------------|------------|--------------|--------------|
+ * | TIMESTAMP and | | | | | |
+ * | TAMPER input | 1 | 1 | 1 | 1 | Don't care |
+ * | floating | | | | | |
+ * |-----------------|-----------|--------------|------------|--------------|--------------|
+ * | TIMESTAMP input | | | Don't | | |
+ * | floating | 0 | 1 | care | 1 | Don't care |
+ * |-----------------|-----------|--------------|------------|--------------|--------------|
+ * | Standard GPIO | 0 | 0 | Don't care | Don't care | Don't care |
+ * +---------------------------------------------------------------------------------------+
+ *
+ *
+ * @endverbatim
+ *
+ ******************************************************************************
+ * @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 "stm32f2xx_rtc.h"
+#include "stm32f2xx_rcc.h"
+
+/** @addtogroup STM32F2xx_StdPeriph_Driver
+ * @{
+ */
+
+/** @defgroup RTC
+ * @brief RTC driver modules
+ * @{
+ */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+
+/* Masks Definition */
+#define RTC_TR_RESERVED_MASK ((uint32_t)0x007F7F7F)
+#define RTC_DR_RESERVED_MASK ((uint32_t)0x00FFFF3F)
+#define RTC_INIT_MASK ((uint32_t)0xFFFFFFFF)
+#define RTC_RSF_MASK ((uint32_t)0xFFFFFF5F)
+#define RTC_FLAGS_MASK ((uint32_t)(RTC_FLAG_TSOVF | RTC_FLAG_TSF | RTC_FLAG_WUTF | \
+ RTC_FLAG_ALRBF | RTC_FLAG_ALRAF | RTC_FLAG_INITF | \
+ RTC_FLAG_RSF | RTC_FLAG_INITS | RTC_FLAG_WUTWF | \
+ RTC_FLAG_ALRBWF | RTC_FLAG_ALRAWF | RTC_FLAG_TAMP1F ))
+
+#define INITMODE_TIMEOUT ((uint32_t) 0x00010000)
+#define SYNCHRO_TIMEOUT ((uint32_t) 0x00008000)
+
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+static uint8_t RTC_ByteToBcd2(uint8_t Value);
+static uint8_t RTC_Bcd2ToByte(uint8_t Value);
+
+/* Private functions ---------------------------------------------------------*/
+
+/** @defgroup RTC_Private_Functions
+ * @{
+ */
+
+/** @defgroup RTC_Group1 Initialization and Configuration functions
+ * @brief Initialization and Configuration functions
+ *
+@verbatim
+ ===============================================================================
+ Initialization and Configuration functions
+ ===============================================================================
+
+ This section provide functions allowing to initialize and configure the RTC
+ Prescaler (Synchronous and Asynchronous), RTC Hour format, disable RTC registers
+ Write protection, enter and exit the RTC initialization mode, RTC registers
+ synchronization check and reference clock detection enable.
+
+ 1. The RTC Prescaler is programmed to generate the RTC 1Hz time base. It is
+ split into 2 programmable prescalers to minimize power consumption.
+ - A 7-bit asynchronous prescaler and A 13-bit synchronous prescaler.
+ - When both prescalers are used, it is recommended to configure the asynchronous
+ prescaler to a high value to minimize consumption.
+
+ 2. All RTC registers are Write protected. Writing to the RTC registers
+ is enabled by writing a key into the Write Protection register, RTC_WPR.
+
+ 3. To Configure the RTC Calendar, user application should enter initialization
+ mode. In this mode, the calendar counter is stopped and its value can be
+ updated. When the initialization sequence is complete, the calendar restarts
+ counting after 4 RTCCLK cycles.
+
+ 4. To read the calendar through the shadow registers after Calendar initialization,
+ calendar update or after wakeup from low power modes the software must first
+ clear the RSF flag. The software must then wait until it is set again before
+ reading the calendar, which means that the calendar registers have been
+ correctly copied into the RTC_TR and RTC_DR shadow registers.
+ The RTC_WaitForSynchro() function implements the above software sequence
+ (RSF clear and RSF check).
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Deinitializes the RTC registers to their default reset values.
+ * @note This function doesn't reset the RTC Clock source and RTC Backup Data
+ * registers.
+ * @param None
+ * @retval An ErrorStatus enumeration value:
+ * - SUCCESS: RTC registers are deinitialized
+ * - ERROR: RTC registers are not deinitialized
+ */
+ErrorStatus RTC_DeInit(void)
+{
+ __IO uint32_t wutcounter = 0x00;
+ uint32_t wutwfstatus = 0x00;
+ ErrorStatus status = ERROR;
+
+ /* Disable the write protection for RTC registers */
+ RTC->WPR = 0xCA;
+ RTC->WPR = 0x53;
+
+ /* Set Initialization mode */
+ if (RTC_EnterInitMode() == ERROR)
+ {
+ status = ERROR;
+ }
+ else
+ {
+ /* Reset TR, DR and CR registers */
+ RTC->TR = (uint32_t)0x00000000;
+ RTC->DR = (uint32_t)0x00002101;
+ /* Reset All CR bits except CR[2:0] */
+ RTC->CR &= (uint32_t)0x00000007;
+
+ /* Wait till RTC WUTWF flag is set and if Time out is reached exit */
+ do
+ {
+ wutwfstatus = RTC->ISR & RTC_ISR_WUTWF;
+ wutcounter++;
+ } while((wutcounter != INITMODE_TIMEOUT) && (wutwfstatus == 0x00));
+
+ if ((RTC->ISR & RTC_ISR_WUTWF) == RESET)
+ {
+ status = ERROR;
+ }
+ else
+ {
+ /* Reset all RTC CR register bits */
+ RTC->CR &= (uint32_t)0x00000000;
+ RTC->WUTR = (uint32_t)0x0000FFFF;
+ RTC->PRER = (uint32_t)0x007F00FF;
+ RTC->CALIBR = (uint32_t)0x00000000;
+ RTC->ALRMAR = (uint32_t)0x00000000;
+ RTC->ALRMBR = (uint32_t)0x00000000;
+
+ /* Reset ISR register and exit initialization mode */
+ RTC->ISR = (uint32_t)0x00000000;
+
+ /* Reset Tamper and alternate functions configuration register */
+ RTC->TAFCR = 0x00000000;
+
+ if(RTC_WaitForSynchro() == ERROR)
+ {
+ status = ERROR;
+ }
+ else
+ {
+ status = SUCCESS;
+ }
+ }
+ }
+
+ /* Enable the write protection for RTC registers */
+ RTC->WPR = 0xFF;
+
+ return status;
+}
+
+/**
+ * @brief Initializes the RTC registers according to the specified parameters
+ * in RTC_InitStruct.
+ * @param RTC_InitStruct: pointer to a RTC_InitTypeDef structure that contains
+ * the configuration information for the RTC peripheral.
+ * @note The RTC Prescaler register is write protected and can be written in
+ * initialization mode only.
+ * @retval An ErrorStatus enumeration value:
+ * - SUCCESS: RTC registers are initialized
+ * - ERROR: RTC registers are not initialized
+ */
+ErrorStatus RTC_Init(RTC_InitTypeDef* RTC_InitStruct)
+{
+ ErrorStatus status = ERROR;
+
+ /* Check the parameters */
+ assert_param(IS_RTC_HOUR_FORMAT(RTC_InitStruct->RTC_HourFormat));
+ assert_param(IS_RTC_ASYNCH_PREDIV(RTC_InitStruct->RTC_AsynchPrediv));
+ assert_param(IS_RTC_SYNCH_PREDIV(RTC_InitStruct->RTC_SynchPrediv));
+
+ /* Disable the write protection for RTC registers */
+ RTC->WPR = 0xCA;
+ RTC->WPR = 0x53;
+
+ /* Set Initialization mode */
+ if (RTC_EnterInitMode() == ERROR)
+ {
+ status = ERROR;
+ }
+ else
+ {
+ /* Clear RTC CR FMT Bit */
+ RTC->CR &= ((uint32_t)~(RTC_CR_FMT));
+ /* Set RTC_CR register */
+ RTC->CR |= ((uint32_t)(RTC_InitStruct->RTC_HourFormat));
+
+ /* Configure the RTC PRER */
+ RTC->PRER = (uint32_t)(RTC_InitStruct->RTC_SynchPrediv);
+ RTC->PRER |= (uint32_t)(RTC_InitStruct->RTC_AsynchPrediv << 16);
+
+ /* Exit Initialization mode */
+ RTC_ExitInitMode();
+
+ status = SUCCESS;
+ }
+ /* Enable the write protection for RTC registers */
+ RTC->WPR = 0xFF;
+
+ return status;
+}
+
+/**
+ * @brief Fills each RTC_InitStruct member with its default value.
+ * @param RTC_InitStruct: pointer to a RTC_InitTypeDef structure which will be
+ * initialized.
+ * @retval None
+ */
+void RTC_StructInit(RTC_InitTypeDef* RTC_InitStruct)
+{
+ /* Initialize the RTC_HourFormat member */
+ RTC_InitStruct->RTC_HourFormat = RTC_HourFormat_24;
+
+ /* Initialize the RTC_AsynchPrediv member */
+ RTC_InitStruct->RTC_AsynchPrediv = (uint32_t)0x7F;
+
+ /* Initialize the RTC_SynchPrediv member */
+ RTC_InitStruct->RTC_SynchPrediv = (uint32_t)0xFF;
+}
+
+/**
+ * @brief Enables or disables the RTC registers write protection.
+ * @note All the RTC registers are write protected except for RTC_ISR[13:8],
+ * RTC_TAFCR and RTC_BKPxR.
+ * @note Writing a wrong key reactivates the write protection.
+ * @note The protection mechanism is not affected by system reset.
+ * @param NewState: new state of the write protection.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void RTC_WriteProtectionCmd(FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the write protection for RTC registers */
+ RTC->WPR = 0xFF;
+ }
+ else
+ {
+ /* Disable the write protection for RTC registers */
+ RTC->WPR = 0xCA;
+ RTC->WPR = 0x53;
+ }
+}
+
+/**
+ * @brief Enters the RTC Initialization mode.
+ * @note The RTC Initialization mode is write protected, use the
+ * RTC_WriteProtectionCmd(DISABLE) before calling this function.
+ * @param None
+ * @retval An ErrorStatus enumeration value:
+ * - SUCCESS: RTC is in Init mode
+ * - ERROR: RTC is not in Init mode
+ */
+ErrorStatus RTC_EnterInitMode(void)
+{
+ __IO uint32_t initcounter = 0x00;
+ ErrorStatus status = ERROR;
+ uint32_t initstatus = 0x00;
+
+ /* Check if the Initialization mode is set */
+ if ((RTC->ISR & RTC_ISR_INITF) == (uint32_t)RESET)
+ {
+ /* Set the Initialization mode */
+ RTC->ISR = (uint32_t)RTC_INIT_MASK;
+
+ /* Wait till RTC is in INIT state and if Time out is reached exit */
+ do
+ {
+ initstatus = RTC->ISR & RTC_ISR_INITF;
+ initcounter++;
+ } while((initcounter != INITMODE_TIMEOUT) && (initstatus == 0x00));
+
+ if ((RTC->ISR & RTC_ISR_INITF) != RESET)
+ {
+ status = SUCCESS;
+ }
+ else
+ {
+ status = ERROR;
+ }
+ }
+ else
+ {
+ status = SUCCESS;
+ }
+
+ return (status);
+}
+
+/**
+ * @brief Exits the RTC Initialization mode.
+ * @note When the initialization sequence is complete, the calendar restarts
+ * counting after 4 RTCCLK cycles.
+ * @note The RTC Initialization mode is write protected, use the
+ * RTC_WriteProtectionCmd(DISABLE) before calling this function.
+ * @param None
+ * @retval None
+ */
+void RTC_ExitInitMode(void)
+{
+ /* Exit Initialization mode */
+ RTC->ISR &= (uint32_t)~RTC_ISR_INIT;
+}
+
+/**
+ * @brief Waits until the RTC Time and Date registers (RTC_TR and RTC_DR) are
+ * synchronized with RTC APB clock.
+ * @note The RTC Resynchronization mode is write protected, use the
+ * RTC_WriteProtectionCmd(DISABLE) before calling this function.
+ * @note To read the calendar through the shadow registers after Calendar
+ * initialization, calendar update or after wakeup from low power modes
+ * the software must first clear the RSF flag.
+ * The software must then wait until it is set again before reading
+ * the calendar, which means that the calendar registers have been
+ * correctly copied into the RTC_TR and RTC_DR shadow registers.
+ * @param None
+ * @retval An ErrorStatus enumeration value:
+ * - SUCCESS: RTC registers are synchronised
+ * - ERROR: RTC registers are not synchronised
+ */
+ErrorStatus RTC_WaitForSynchro(void)
+{
+ __IO uint32_t synchrocounter = 0;
+ ErrorStatus status = ERROR;
+ uint32_t synchrostatus = 0x00;
+
+ /* Disable the write protection for RTC registers */
+ RTC->WPR = 0xCA;
+ RTC->WPR = 0x53;
+
+ /* Clear RSF flag */
+ RTC->ISR &= (uint32_t)RTC_RSF_MASK;
+
+ /* Wait the registers to be synchronised */
+ do
+ {
+ synchrostatus = RTC->ISR & RTC_ISR_RSF;
+ synchrocounter++;
+ } while((synchrocounter != SYNCHRO_TIMEOUT) && (synchrostatus == 0x00));
+
+ if ((RTC->ISR & RTC_ISR_RSF) != RESET)
+ {
+ status = SUCCESS;
+ }
+ else
+ {
+ status = ERROR;
+ }
+
+ /* Enable the write protection for RTC registers */
+ RTC->WPR = 0xFF;
+
+ return (status);
+}
+
+/**
+ * @brief Enables or disables the RTC reference clock detection.
+ * @param NewState: new state of the RTC reference clock.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval An ErrorStatus enumeration value:
+ * - SUCCESS: RTC reference clock detection is enabled
+ * - ERROR: RTC reference clock detection is disabled
+ */
+ErrorStatus RTC_RefClockCmd(FunctionalState NewState)
+{
+ ErrorStatus status = ERROR;
+
+ /* Check the parameters */
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ /* Disable the write protection for RTC registers */
+ RTC->WPR = 0xCA;
+ RTC->WPR = 0x53;
+
+ /* Set Initialization mode */
+ if (RTC_EnterInitMode() == ERROR)
+ {
+ status = ERROR;
+ }
+ else
+ {
+ if (NewState != DISABLE)
+ {
+ /* Enable the RTC reference clock detection */
+ RTC->CR |= RTC_CR_REFCKON;
+ }
+ else
+ {
+ /* Disable the RTC reference clock detection */
+ RTC->CR &= ~RTC_CR_REFCKON;
+ }
+ /* Exit Initialization mode */
+ RTC_ExitInitMode();
+
+ status = SUCCESS;
+ }
+
+ /* Enable the write protection for RTC registers */
+ RTC->WPR = 0xFF;
+
+ return status;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup RTC_Group2 Time and Date configuration functions
+ * @brief Time and Date configuration functions
+ *
+@verbatim
+ ===============================================================================
+ Time and Date configuration functions
+ ===============================================================================
+
+ This section provide functions allowing to program and read the RTC Calendar
+ (Time and Date).
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Set the RTC current time.
+ * @param RTC_Format: specifies the format of the entered parameters.
+ * This parameter can be one of the following values:
+ * @arg RTC_Format_BIN: Binary data format
+ * @arg RTC_Format_BCD: BCD data format
+ * @param RTC_TimeStruct: pointer to a RTC_TimeTypeDef structure that contains
+ * the time configuration information for the RTC.
+ * @retval An ErrorStatus enumeration value:
+ * - SUCCESS: RTC Time register is configured
+ * - ERROR: RTC Time register is not configured
+ */
+ErrorStatus RTC_SetTime(uint32_t RTC_Format, RTC_TimeTypeDef* RTC_TimeStruct)
+{
+ uint32_t tmpreg = 0;
+ ErrorStatus status = ERROR;
+
+ /* Check the parameters */
+ assert_param(IS_RTC_FORMAT(RTC_Format));
+
+ if (RTC_Format == RTC_Format_BIN)
+ {
+ if ((RTC->CR & RTC_CR_FMT) != (uint32_t)RESET)
+ {
+ assert_param(IS_RTC_HOUR12(RTC_TimeStruct->RTC_Hours));
+ assert_param(IS_RTC_H12(RTC_TimeStruct->RTC_H12));
+ }
+ else
+ {
+ RTC_TimeStruct->RTC_H12 = 0x00;
+ assert_param(IS_RTC_HOUR24(RTC_TimeStruct->RTC_Hours));
+ }
+ assert_param(IS_RTC_MINUTES(RTC_TimeStruct->RTC_Minutes));
+ assert_param(IS_RTC_SECONDS(RTC_TimeStruct->RTC_Seconds));
+ }
+ else
+ {
+ if ((RTC->CR & RTC_CR_FMT) != (uint32_t)RESET)
+ {
+ tmpreg = RTC_Bcd2ToByte(RTC_TimeStruct->RTC_Hours);
+ assert_param(IS_RTC_HOUR12(tmpreg));
+ assert_param(IS_RTC_H12(RTC_TimeStruct->RTC_H12));
+ }
+ else
+ {
+ RTC_TimeStruct->RTC_H12 = 0x00;
+ assert_param(IS_RTC_HOUR24(RTC_Bcd2ToByte(RTC_TimeStruct->RTC_Hours)));
+ }
+ assert_param(IS_RTC_MINUTES(RTC_Bcd2ToByte(RTC_TimeStruct->RTC_Minutes)));
+ assert_param(IS_RTC_SECONDS(RTC_Bcd2ToByte(RTC_TimeStruct->RTC_Seconds)));
+ }
+
+ /* Check the input parameters format */
+ if (RTC_Format != RTC_Format_BIN)
+ {
+ tmpreg = (((uint32_t)(RTC_TimeStruct->RTC_Hours) << 16) | \
+ ((uint32_t)(RTC_TimeStruct->RTC_Minutes) << 8) | \
+ ((uint32_t)RTC_TimeStruct->RTC_Seconds) | \
+ ((uint32_t)(RTC_TimeStruct->RTC_H12) << 16));
+ }
+ else
+ {
+ tmpreg = (uint32_t)(((uint32_t)RTC_ByteToBcd2(RTC_TimeStruct->RTC_Hours) << 16) | \
+ ((uint32_t)RTC_ByteToBcd2(RTC_TimeStruct->RTC_Minutes) << 8) | \
+ ((uint32_t)RTC_ByteToBcd2(RTC_TimeStruct->RTC_Seconds)) | \
+ (((uint32_t)RTC_TimeStruct->RTC_H12) << 16));
+ }
+
+ /* Disable the write protection for RTC registers */
+ RTC->WPR = 0xCA;
+ RTC->WPR = 0x53;
+
+ /* Set Initialization mode */
+ if (RTC_EnterInitMode() == ERROR)
+ {
+ status = ERROR;
+ }
+ else
+ {
+ /* Set the RTC_TR register */
+ RTC->TR = (uint32_t)(tmpreg & RTC_TR_RESERVED_MASK);
+
+ /* Exit Initialization mode */
+ RTC_ExitInitMode();
+
+ if(RTC_WaitForSynchro() == ERROR)
+ {
+ status = ERROR;
+ }
+ else
+ {
+ status = SUCCESS;
+ }
+
+ }
+ /* Enable the write protection for RTC registers */
+ RTC->WPR = 0xFF;
+
+ return status;
+}
+
+/**
+ * @brief Fills each RTC_TimeStruct member with its default value
+ * (Time = 00h:00min:00sec).
+ * @param RTC_TimeStruct: pointer to a RTC_TimeTypeDef structure which will be
+ * initialized.
+ * @retval None
+ */
+void RTC_TimeStructInit(RTC_TimeTypeDef* RTC_TimeStruct)
+{
+ /* Time = 00h:00min:00sec */
+ RTC_TimeStruct->RTC_H12 = RTC_H12_AM;
+ RTC_TimeStruct->RTC_Hours = 0;
+ RTC_TimeStruct->RTC_Minutes = 0;
+ RTC_TimeStruct->RTC_Seconds = 0;
+}
+
+/**
+ * @brief Get the RTC current Time.
+ * @param RTC_Format: specifies the format of the returned parameters.
+ * This parameter can be one of the following values:
+ * @arg RTC_Format_BIN: Binary data format
+ * @arg RTC_Format_BCD: BCD data format
+ * @param RTC_TimeStruct: pointer to a RTC_TimeTypeDef structure that will
+ * contain the returned current time configuration.
+ * @retval None
+ */
+void RTC_GetTime(uint32_t RTC_Format, RTC_TimeTypeDef* RTC_TimeStruct)
+{
+ uint32_t tmpreg = 0;
+
+ /* Check the parameters */
+ assert_param(IS_RTC_FORMAT(RTC_Format));
+
+ /* Get the RTC_TR register */
+ tmpreg = (uint32_t)(RTC->TR & RTC_TR_RESERVED_MASK);
+
+ /* Fill the structure fields with the read parameters */
+ RTC_TimeStruct->RTC_Hours = (uint8_t)((tmpreg & (RTC_TR_HT | RTC_TR_HU)) >> 16);
+ RTC_TimeStruct->RTC_Minutes = (uint8_t)((tmpreg & (RTC_TR_MNT | RTC_TR_MNU)) >>8);
+ RTC_TimeStruct->RTC_Seconds = (uint8_t)(tmpreg & (RTC_TR_ST | RTC_TR_SU));
+ RTC_TimeStruct->RTC_H12 = (uint8_t)((tmpreg & (RTC_TR_PM)) >> 16);
+
+ /* Check the input parameters format */
+ if (RTC_Format == RTC_Format_BIN)
+ {
+ /* Convert the structure parameters to Binary format */
+ RTC_TimeStruct->RTC_Hours = (uint8_t)RTC_Bcd2ToByte(RTC_TimeStruct->RTC_Hours);
+ RTC_TimeStruct->RTC_Minutes = (uint8_t)RTC_Bcd2ToByte(RTC_TimeStruct->RTC_Minutes);
+ RTC_TimeStruct->RTC_Seconds = (uint8_t)RTC_Bcd2ToByte(RTC_TimeStruct->RTC_Seconds);
+ }
+}
+
+/**
+ * @brief Set the RTC current date.
+ * @param RTC_Format: specifies the format of the entered parameters.
+ * This parameter can be one of the following values:
+ * @arg RTC_Format_BIN: Binary data format
+ * @arg RTC_Format_BCD: BCD data format
+ * @param RTC_DateStruct: pointer to a RTC_DateTypeDef structure that contains
+ * the date configuration information for the RTC.
+ * @retval An ErrorStatus enumeration value:
+ * - SUCCESS: RTC Date register is configured
+ * - ERROR: RTC Date register is not configured
+ */
+ErrorStatus RTC_SetDate(uint32_t RTC_Format, RTC_DateTypeDef* RTC_DateStruct)
+{
+ uint32_t tmpreg = 0;
+ ErrorStatus status = ERROR;
+
+ /* Check the parameters */
+ assert_param(IS_RTC_FORMAT(RTC_Format));
+
+ if ((RTC_Format == RTC_Format_BIN) && ((RTC_DateStruct->RTC_Month & 0x10) == 0x10))
+ {
+ RTC_DateStruct->RTC_Month = (RTC_DateStruct->RTC_Month & (uint32_t)~(0x10)) + 0x0A;
+ }
+ if (RTC_Format == RTC_Format_BIN)
+ {
+ assert_param(IS_RTC_YEAR(RTC_DateStruct->RTC_Year));
+ assert_param(IS_RTC_MONTH(RTC_DateStruct->RTC_Month));
+ assert_param(IS_RTC_DATE(RTC_DateStruct->RTC_Date));
+ }
+ else
+ {
+ assert_param(IS_RTC_YEAR(RTC_Bcd2ToByte(RTC_DateStruct->RTC_Year)));
+ tmpreg = RTC_Bcd2ToByte(RTC_DateStruct->RTC_Month);
+ assert_param(IS_RTC_MONTH(tmpreg));
+ tmpreg = RTC_Bcd2ToByte(RTC_DateStruct->RTC_Date);
+ assert_param(IS_RTC_DATE(tmpreg));
+ }
+ assert_param(IS_RTC_WEEKDAY(RTC_DateStruct->RTC_WeekDay));
+
+ /* Check the input parameters format */
+ if (RTC_Format != RTC_Format_BIN)
+ {
+ tmpreg = ((((uint32_t)RTC_DateStruct->RTC_Year) << 16) | \
+ (((uint32_t)RTC_DateStruct->RTC_Month) << 8) | \
+ ((uint32_t)RTC_DateStruct->RTC_Date) | \
+ (((uint32_t)RTC_DateStruct->RTC_WeekDay) << 13));
+ }
+ else
+ {
+ tmpreg = (((uint32_t)RTC_ByteToBcd2(RTC_DateStruct->RTC_Year) << 16) | \
+ ((uint32_t)RTC_ByteToBcd2(RTC_DateStruct->RTC_Month) << 8) | \
+ ((uint32_t)RTC_ByteToBcd2(RTC_DateStruct->RTC_Date)) | \
+ ((uint32_t)RTC_DateStruct->RTC_WeekDay << 13));
+ }
+
+ /* Disable the write protection for RTC registers */
+ RTC->WPR = 0xCA;
+ RTC->WPR = 0x53;
+
+ /* Set Initialization mode */
+ if (RTC_EnterInitMode() == ERROR)
+ {
+ status = ERROR;
+ }
+ else
+ {
+ /* Set the RTC_DR register */
+ RTC->DR = (uint32_t)(tmpreg & RTC_DR_RESERVED_MASK);
+
+ /* Exit Initialization mode */
+ RTC_ExitInitMode();
+
+ if(RTC_WaitForSynchro() == ERROR)
+ {
+ status = ERROR;
+ }
+ else
+ {
+ status = SUCCESS;
+ }
+ }
+ /* Enable the write protection for RTC registers */
+ RTC->WPR = 0xFF;
+
+ return status;
+}
+
+/**
+ * @brief Fills each RTC_DateStruct member with its default value
+ * (Monday, January 01 xx00).
+ * @param RTC_DateStruct: pointer to a RTC_DateTypeDef structure which will be
+ * initialized.
+ * @retval None
+ */
+void RTC_DateStructInit(RTC_DateTypeDef* RTC_DateStruct)
+{
+ /* Monday, January 01 xx00 */
+ RTC_DateStruct->RTC_WeekDay = RTC_Weekday_Monday;
+ RTC_DateStruct->RTC_Date = 1;
+ RTC_DateStruct->RTC_Month = RTC_Month_January;
+ RTC_DateStruct->RTC_Year = 0;
+}
+
+/**
+ * @brief Get the RTC current date.
+ * @param RTC_Format: specifies the format of the returned parameters.
+ * This parameter can be one of the following values:
+ * @arg RTC_Format_BIN: Binary data format
+ * @arg RTC_Format_BCD: BCD data format
+ * @param RTC_DateStruct: pointer to a RTC_DateTypeDef structure that will
+ * contain the returned current date configuration.
+ * @retval None
+ */
+void RTC_GetDate(uint32_t RTC_Format, RTC_DateTypeDef* RTC_DateStruct)
+{
+ uint32_t tmpreg = 0;
+
+ /* Check the parameters */
+ assert_param(IS_RTC_FORMAT(RTC_Format));
+
+ /* Get the RTC_TR register */
+ tmpreg = (uint32_t)(RTC->DR & RTC_DR_RESERVED_MASK);
+
+ /* Fill the structure fields with the read parameters */
+ RTC_DateStruct->RTC_Year = (uint8_t)((tmpreg & (RTC_DR_YT | RTC_DR_YU)) >> 16);
+ RTC_DateStruct->RTC_Month = (uint8_t)((tmpreg & (RTC_DR_MT | RTC_DR_MU)) >> 8);
+ RTC_DateStruct->RTC_Date = (uint8_t)(tmpreg & (RTC_DR_DT | RTC_DR_DU));
+ RTC_DateStruct->RTC_WeekDay = (uint8_t)((tmpreg & (RTC_DR_WDU)) >> 13);
+
+ /* Check the input parameters format */
+ if (RTC_Format == RTC_Format_BIN)
+ {
+ /* Convert the structure parameters to Binary format */
+ RTC_DateStruct->RTC_Year = (uint8_t)RTC_Bcd2ToByte(RTC_DateStruct->RTC_Year);
+ RTC_DateStruct->RTC_Month = (uint8_t)RTC_Bcd2ToByte(RTC_DateStruct->RTC_Month);
+ RTC_DateStruct->RTC_Date = (uint8_t)RTC_Bcd2ToByte(RTC_DateStruct->RTC_Date);
+ }
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup RTC_Group3 Alarms configuration functions
+ * @brief Alarms (Alarm A and Alarm B) configuration functions
+ *
+@verbatim
+ ===============================================================================
+ Alarms (Alarm A and Alarm B) configuration functions
+ ===============================================================================
+
+ This section provide functions allowing to program and read the RTC Alarms.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Set the specified RTC Alarm.
+ * @note The Alarm register can only be written when the corresponding Alarm
+ * is disabled (Use the RTC_AlarmCmd(DISABLE)).
+ * @param RTC_Format: specifies the format of the returned parameters.
+ * This parameter can be one of the following values:
+ * @arg RTC_Format_BIN: Binary data format
+ * @arg RTC_Format_BCD: BCD data format
+ * @param RTC_Alarm: specifies the alarm to be configured.
+ * This parameter can be one of the following values:
+ * @arg RTC_Alarm_A: to select Alarm A
+ * @arg RTC_Alarm_B: to select Alarm B
+ * @param RTC_AlarmStruct: pointer to a RTC_AlarmTypeDef structure that
+ * contains the alarm configuration parameters.
+ * @retval None
+ */
+void RTC_SetAlarm(uint32_t RTC_Format, uint32_t RTC_Alarm, RTC_AlarmTypeDef* RTC_AlarmStruct)
+{
+ uint32_t tmpreg = 0;
+
+ /* Check the parameters */
+ assert_param(IS_RTC_FORMAT(RTC_Format));
+ assert_param(IS_RTC_ALARM(RTC_Alarm));
+ assert_param(IS_ALARM_MASK(RTC_AlarmStruct->RTC_AlarmMask));
+ assert_param(IS_RTC_ALARM_DATE_WEEKDAY_SEL(RTC_AlarmStruct->RTC_AlarmDateWeekDaySel));
+
+ if (RTC_Format == RTC_Format_BIN)
+ {
+ if ((RTC->CR & RTC_CR_FMT) != (uint32_t)RESET)
+ {
+ assert_param(IS_RTC_HOUR12(RTC_AlarmStruct->RTC_AlarmTime.RTC_Hours));
+ assert_param(IS_RTC_H12(RTC_AlarmStruct->RTC_AlarmTime.RTC_H12));
+ }
+ else
+ {
+ RTC_AlarmStruct->RTC_AlarmTime.RTC_H12 = 0x00;
+ assert_param(IS_RTC_HOUR24(RTC_AlarmStruct->RTC_AlarmTime.RTC_Hours));
+ }
+ assert_param(IS_RTC_MINUTES(RTC_AlarmStruct->RTC_AlarmTime.RTC_Minutes));
+ assert_param(IS_RTC_SECONDS(RTC_AlarmStruct->RTC_AlarmTime.RTC_Seconds));
+
+ if(RTC_AlarmStruct->RTC_AlarmDateWeekDaySel == RTC_AlarmDateWeekDaySel_Date)
+ {
+ assert_param(IS_RTC_ALARM_DATE_WEEKDAY_DATE(RTC_AlarmStruct->RTC_AlarmDateWeekDay));
+ }
+ else
+ {
+ assert_param(IS_RTC_ALARM_DATE_WEEKDAY_WEEKDAY(RTC_AlarmStruct->RTC_AlarmDateWeekDay));
+ }
+ }
+ else
+ {
+ if ((RTC->CR & RTC_CR_FMT) != (uint32_t)RESET)
+ {
+ tmpreg = RTC_Bcd2ToByte(RTC_AlarmStruct->RTC_AlarmTime.RTC_Hours);
+ assert_param(IS_RTC_HOUR12(tmpreg));
+ assert_param(IS_RTC_H12(RTC_AlarmStruct->RTC_AlarmTime.RTC_H12));
+ }
+ else
+ {
+ RTC_AlarmStruct->RTC_AlarmTime.RTC_H12 = 0x00;
+ assert_param(IS_RTC_HOUR24(RTC_Bcd2ToByte(RTC_AlarmStruct->RTC_AlarmTime.RTC_Hours)));
+ }
+
+ assert_param(IS_RTC_MINUTES(RTC_Bcd2ToByte(RTC_AlarmStruct->RTC_AlarmTime.RTC_Minutes)));
+ assert_param(IS_RTC_SECONDS(RTC_Bcd2ToByte(RTC_AlarmStruct->RTC_AlarmTime.RTC_Seconds)));
+
+ if(RTC_AlarmStruct->RTC_AlarmDateWeekDaySel == RTC_AlarmDateWeekDaySel_Date)
+ {
+ tmpreg = RTC_Bcd2ToByte(RTC_AlarmStruct->RTC_AlarmDateWeekDay);
+ assert_param(IS_RTC_ALARM_DATE_WEEKDAY_DATE(tmpreg));
+ }
+ else
+ {
+ tmpreg = RTC_Bcd2ToByte(RTC_AlarmStruct->RTC_AlarmDateWeekDay);
+ assert_param(IS_RTC_ALARM_DATE_WEEKDAY_WEEKDAY(tmpreg));
+ }
+ }
+
+ /* Check the input parameters format */
+ if (RTC_Format != RTC_Format_BIN)
+ {
+ tmpreg = (((uint32_t)(RTC_AlarmStruct->RTC_AlarmTime.RTC_Hours) << 16) | \
+ ((uint32_t)(RTC_AlarmStruct->RTC_AlarmTime.RTC_Minutes) << 8) | \
+ ((uint32_t)RTC_AlarmStruct->RTC_AlarmTime.RTC_Seconds) | \
+ ((uint32_t)(RTC_AlarmStruct->RTC_AlarmTime.RTC_H12) << 16) | \
+ ((uint32_t)(RTC_AlarmStruct->RTC_AlarmDateWeekDay) << 24) | \
+ ((uint32_t)RTC_AlarmStruct->RTC_AlarmDateWeekDaySel) | \
+ ((uint32_t)RTC_AlarmStruct->RTC_AlarmMask));
+ }
+ else
+ {
+ tmpreg = (((uint32_t)RTC_ByteToBcd2(RTC_AlarmStruct->RTC_AlarmTime.RTC_Hours) << 16) | \
+ ((uint32_t)RTC_ByteToBcd2(RTC_AlarmStruct->RTC_AlarmTime.RTC_Minutes) << 8) | \
+ ((uint32_t)RTC_ByteToBcd2(RTC_AlarmStruct->RTC_AlarmTime.RTC_Seconds)) | \
+ ((uint32_t)(RTC_AlarmStruct->RTC_AlarmTime.RTC_H12) << 16) | \
+ ((uint32_t)RTC_ByteToBcd2(RTC_AlarmStruct->RTC_AlarmDateWeekDay) << 24) | \
+ ((uint32_t)RTC_AlarmStruct->RTC_AlarmDateWeekDaySel) | \
+ ((uint32_t)RTC_AlarmStruct->RTC_AlarmMask));
+ }
+
+ /* Disable the write protection for RTC registers */
+ RTC->WPR = 0xCA;
+ RTC->WPR = 0x53;
+
+ /* Configure the Alarm register */
+ if (RTC_Alarm == RTC_Alarm_A)
+ {
+ RTC->ALRMAR = (uint32_t)tmpreg;
+ }
+ else
+ {
+ RTC->ALRMBR = (uint32_t)tmpreg;
+ }
+
+ /* Enable the write protection for RTC registers */
+ RTC->WPR = 0xFF;
+}
+
+/**
+ * @brief Fills each RTC_AlarmStruct member with its default value
+ * (Time = 00h:00mn:00sec / Date = 1st day of the month/Mask =
+ * all fields are masked).
+ * @param RTC_AlarmStruct: pointer to a @ref RTC_AlarmTypeDef structure which
+ * will be initialized.
+ * @retval None
+ */
+void RTC_AlarmStructInit(RTC_AlarmTypeDef* RTC_AlarmStruct)
+{
+ /* Alarm Time Settings : Time = 00h:00mn:00sec */
+ RTC_AlarmStruct->RTC_AlarmTime.RTC_H12 = RTC_H12_AM;
+ RTC_AlarmStruct->RTC_AlarmTime.RTC_Hours = 0;
+ RTC_AlarmStruct->RTC_AlarmTime.RTC_Minutes = 0;
+ RTC_AlarmStruct->RTC_AlarmTime.RTC_Seconds = 0;
+
+ /* Alarm Date Settings : Date = 1st day of the month */
+ RTC_AlarmStruct->RTC_AlarmDateWeekDaySel = RTC_AlarmDateWeekDaySel_Date;
+ RTC_AlarmStruct->RTC_AlarmDateWeekDay = 1;
+
+ /* Alarm Masks Settings : Mask = all fields are not masked */
+ RTC_AlarmStruct->RTC_AlarmMask = RTC_AlarmMask_None;
+}
+
+/**
+ * @brief Get the RTC Alarm value and masks.
+ * @param RTC_Format: specifies the format of the output parameters.
+ * This parameter can be one of the following values:
+ * @arg RTC_Format_BIN: Binary data format
+ * @arg RTC_Format_BCD: BCD data format
+ * @param RTC_Alarm: specifies the alarm to be read.
+ * This parameter can be one of the following values:
+ * @arg RTC_Alarm_A: to select Alarm A
+ * @arg RTC_Alarm_B: to select Alarm B
+ * @param RTC_AlarmStruct: pointer to a RTC_AlarmTypeDef structure that will
+ * contains the output alarm configuration values.
+ * @retval None
+ */
+void RTC_GetAlarm(uint32_t RTC_Format, uint32_t RTC_Alarm, RTC_AlarmTypeDef* RTC_AlarmStruct)
+{
+ uint32_t tmpreg = 0;
+
+ /* Check the parameters */
+ assert_param(IS_RTC_FORMAT(RTC_Format));
+ assert_param(IS_RTC_ALARM(RTC_Alarm));
+
+ /* Get the RTC_ALRMxR register */
+ if (RTC_Alarm == RTC_Alarm_A)
+ {
+ tmpreg = (uint32_t)(RTC->ALRMAR);
+ }
+ else
+ {
+ tmpreg = (uint32_t)(RTC->ALRMBR);
+ }
+
+ /* Fill the structure with the read parameters */
+ RTC_AlarmStruct->RTC_AlarmTime.RTC_Hours = (uint32_t)((tmpreg & (RTC_ALRMAR_HT | \
+ RTC_ALRMAR_HU)) >> 16);
+ RTC_AlarmStruct->RTC_AlarmTime.RTC_Minutes = (uint32_t)((tmpreg & (RTC_ALRMAR_MNT | \
+ RTC_ALRMAR_MNU)) >> 8);
+ RTC_AlarmStruct->RTC_AlarmTime.RTC_Seconds = (uint32_t)(tmpreg & (RTC_ALRMAR_ST | \
+ RTC_ALRMAR_SU));
+ RTC_AlarmStruct->RTC_AlarmTime.RTC_H12 = (uint32_t)((tmpreg & RTC_ALRMAR_PM) >> 16);
+ RTC_AlarmStruct->RTC_AlarmDateWeekDay = (uint32_t)((tmpreg & (RTC_ALRMAR_DT | RTC_ALRMAR_DU)) >> 24);
+ RTC_AlarmStruct->RTC_AlarmDateWeekDaySel = (uint32_t)(tmpreg & RTC_ALRMAR_WDSEL);
+ RTC_AlarmStruct->RTC_AlarmMask = (uint32_t)(tmpreg & RTC_AlarmMask_All);
+
+ if (RTC_Format == RTC_Format_BIN)
+ {
+ RTC_AlarmStruct->RTC_AlarmTime.RTC_Hours = RTC_Bcd2ToByte(RTC_AlarmStruct-> \
+ RTC_AlarmTime.RTC_Hours);
+ RTC_AlarmStruct->RTC_AlarmTime.RTC_Minutes = RTC_Bcd2ToByte(RTC_AlarmStruct-> \
+ RTC_AlarmTime.RTC_Minutes);
+ RTC_AlarmStruct->RTC_AlarmTime.RTC_Seconds = RTC_Bcd2ToByte(RTC_AlarmStruct-> \
+ RTC_AlarmTime.RTC_Seconds);
+ RTC_AlarmStruct->RTC_AlarmDateWeekDay = RTC_Bcd2ToByte(RTC_AlarmStruct->RTC_AlarmDateWeekDay);
+ }
+}
+
+/**
+ * @brief Enables or disables the specified RTC Alarm.
+ * @param RTC_Alarm: specifies the alarm to be configured.
+ * This parameter can be any combination of the following values:
+ * @arg RTC_Alarm_A: to select Alarm A
+ * @arg RTC_Alarm_B: to select Alarm B
+ * @param NewState: new state of the specified alarm.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval An ErrorStatus enumeration value:
+ * - SUCCESS: RTC Alarm is enabled/disabled
+ * - ERROR: RTC Alarm is not enabled/disabled
+ */
+ErrorStatus RTC_AlarmCmd(uint32_t RTC_Alarm, FunctionalState NewState)
+{
+ __IO uint32_t alarmcounter = 0x00;
+ uint32_t alarmstatus = 0x00;
+ ErrorStatus status = ERROR;
+
+ /* Check the parameters */
+ assert_param(IS_RTC_CMD_ALARM(RTC_Alarm));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ /* Disable the write protection for RTC registers */
+ RTC->WPR = 0xCA;
+ RTC->WPR = 0x53;
+
+ /* Configure the Alarm state */
+ if (NewState != DISABLE)
+ {
+ RTC->CR |= (uint32_t)RTC_Alarm;
+
+ status = SUCCESS;
+ }
+ else
+ {
+ /* Disable the Alarm in RTC_CR register */
+ RTC->CR &= (uint32_t)~RTC_Alarm;
+
+ /* Wait till RTC ALRxWF flag is set and if Time out is reached exit */
+ do
+ {
+ alarmstatus = RTC->ISR & (RTC_Alarm >> 8);
+ alarmcounter++;
+ } while((alarmcounter != INITMODE_TIMEOUT) && (alarmstatus == 0x00));
+
+ if ((RTC->ISR & (RTC_Alarm >> 8)) == RESET)
+ {
+ status = ERROR;
+ }
+ else
+ {
+ status = SUCCESS;
+ }
+ }
+
+ /* Enable the write protection for RTC registers */
+ RTC->WPR = 0xFF;
+
+ return status;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup RTC_Group4 WakeUp Timer configuration functions
+ * @brief WakeUp Timer configuration functions
+ *
+@verbatim
+ ===============================================================================
+ WakeUp Timer configuration functions
+ ===============================================================================
+
+ This section provide functions allowing to program and read the RTC WakeUp.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Configures the RTC Wakeup clock source.
+ * @note The WakeUp Clock source can only be changed when the RTC WakeUp
+ * is disabled (Use the RTC_WakeUpCmd(DISABLE)).
+ * @param RTC_WakeUpClock: Wakeup Clock source.
+ * This parameter can be one of the following values:
+ * @arg RTC_WakeUpClock_RTCCLK_Div16: RTC Wakeup Counter Clock = RTCCLK/16
+ * @arg RTC_WakeUpClock_RTCCLK_Div8: RTC Wakeup Counter Clock = RTCCLK/8
+ * @arg RTC_WakeUpClock_RTCCLK_Div4: RTC Wakeup Counter Clock = RTCCLK/4
+ * @arg RTC_WakeUpClock_RTCCLK_Div2: RTC Wakeup Counter Clock = RTCCLK/2
+ * @arg RTC_WakeUpClock_CK_SPRE_16bits: RTC Wakeup Counter Clock = CK_SPRE
+ * @arg RTC_WakeUpClock_CK_SPRE_17bits: RTC Wakeup Counter Clock = CK_SPRE
+ * @retval None
+ */
+void RTC_WakeUpClockConfig(uint32_t RTC_WakeUpClock)
+{
+ /* Check the parameters */
+ assert_param(IS_RTC_WAKEUP_CLOCK(RTC_WakeUpClock));
+
+ /* Disable the write protection for RTC registers */
+ RTC->WPR = 0xCA;
+ RTC->WPR = 0x53;
+
+ /* Clear the Wakeup Timer clock source bits in CR register */
+ RTC->CR &= (uint32_t)~RTC_CR_WUCKSEL;
+
+ /* Configure the clock source */
+ RTC->CR |= (uint32_t)RTC_WakeUpClock;
+
+ /* Enable the write protection for RTC registers */
+ RTC->WPR = 0xFF;
+}
+
+/**
+ * @brief Configures the RTC Wakeup counter.
+ * @note The RTC WakeUp counter can only be written when the RTC WakeUp
+ * is disabled (Use the RTC_WakeUpCmd(DISABLE)).
+ * @param RTC_WakeUpCounter: specifies the WakeUp counter.
+ * This parameter can be a value from 0x0000 to 0xFFFF.
+ * @retval None
+ */
+void RTC_SetWakeUpCounter(uint32_t RTC_WakeUpCounter)
+{
+ /* Check the parameters */
+ assert_param(IS_RTC_WAKEUP_COUNTER(RTC_WakeUpCounter));
+
+ /* Disable the write protection for RTC registers */
+ RTC->WPR = 0xCA;
+ RTC->WPR = 0x53;
+
+ /* Configure the Wakeup Timer counter */
+ RTC->WUTR = (uint32_t)RTC_WakeUpCounter;
+
+ /* Enable the write protection for RTC registers */
+ RTC->WPR = 0xFF;
+}
+
+/**
+ * @brief Returns the RTC WakeUp timer counter value.
+ * @param None
+ * @retval The RTC WakeUp Counter value.
+ */
+uint32_t RTC_GetWakeUpCounter(void)
+{
+ /* Get the counter value */
+ return ((uint32_t)(RTC->WUTR & RTC_WUTR_WUT));
+}
+
+/**
+ * @brief Enables or Disables the RTC WakeUp timer.
+ * @param NewState: new state of the WakeUp timer.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+ErrorStatus RTC_WakeUpCmd(FunctionalState NewState)
+{
+ __IO uint32_t wutcounter = 0x00;
+ uint32_t wutwfstatus = 0x00;
+ ErrorStatus status = ERROR;
+
+ /* Check the parameters */
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ /* Disable the write protection for RTC registers */
+ RTC->WPR = 0xCA;
+ RTC->WPR = 0x53;
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the Wakeup Timer */
+ RTC->CR |= (uint32_t)RTC_CR_WUTE;
+ status = SUCCESS;
+ }
+ else
+ {
+ /* Disable the Wakeup Timer */
+ RTC->CR &= (uint32_t)~RTC_CR_WUTE;
+ /* Wait till RTC WUTWF flag is set and if Time out is reached exit */
+ do
+ {
+ wutwfstatus = RTC->ISR & RTC_ISR_WUTWF;
+ wutcounter++;
+ } while((wutcounter != INITMODE_TIMEOUT) && (wutwfstatus == 0x00));
+
+ if ((RTC->ISR & RTC_ISR_WUTWF) == RESET)
+ {
+ status = ERROR;
+ }
+ else
+ {
+ status = SUCCESS;
+ }
+ }
+
+ /* Enable the write protection for RTC registers */
+ RTC->WPR = 0xFF;
+
+ return status;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup RTC_Group5 Daylight Saving configuration functions
+ * @brief Daylight Saving configuration functions
+ *
+@verbatim
+ ===============================================================================
+ Daylight Saving configuration functions
+ ===============================================================================
+
+ This section provide functions allowing to configure the RTC DayLight Saving.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Adds or substract one hour from the current time.
+ * @param RTC_DayLightSaveOperation: the value of hour adjustment.
+ * This parameter can be one of the following values:
+ * @arg RTC_DayLightSaving_SUB1H: Substract one hour (winter time)
+ * @arg RTC_DayLightSaving_ADD1H: Add one hour (summer time)
+ * @param RTC_StoreOperation: Specifies the value to be written in the BCK bit
+ * in CR register to store the operation.
+ * This parameter can be one of the following values:
+ * @arg RTC_StoreOperation_Reset: BCK Bit Reset
+ * @arg RTC_StoreOperation_Set: BCK Bit Set
+ * @retval None
+ */
+void RTC_DayLightSavingConfig(uint32_t RTC_DayLightSaving, uint32_t RTC_StoreOperation)
+{
+ /* Check the parameters */
+ assert_param(IS_RTC_DAYLIGHT_SAVING(RTC_DayLightSaving));
+ assert_param(IS_RTC_STORE_OPERATION(RTC_StoreOperation));
+
+ /* Disable the write protection for RTC registers */
+ RTC->WPR = 0xCA;
+ RTC->WPR = 0x53;
+
+ /* Clear the bits to be configured */
+ RTC->CR &= (uint32_t)~(RTC_CR_BCK);
+
+ /* Configure the RTC_CR register */
+ RTC->CR |= (uint32_t)(RTC_DayLightSaving | RTC_StoreOperation);
+
+ /* Enable the write protection for RTC registers */
+ RTC->WPR = 0xFF;
+}
+
+/**
+ * @brief Returns the RTC Day Light Saving stored operation.
+ * @param None
+ * @retval RTC Day Light Saving stored operation.
+ * - RTC_StoreOperation_Reset
+ * - RTC_StoreOperation_Set
+ */
+uint32_t RTC_GetStoreOperation(void)
+{
+ return (RTC->CR & RTC_CR_BCK);
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup RTC_Group6 Output pin Configuration function
+ * @brief Output pin Configuration function
+ *
+@verbatim
+ ===============================================================================
+ Output pin Configuration function
+ ===============================================================================
+
+ This section provide functions allowing to configure the RTC Output source.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Configures the RTC output source (AFO_ALARM).
+ * @param RTC_Output: Specifies which signal will be routed to the RTC output.
+ * This parameter can be one of the following values:
+ * @arg RTC_Output_Disable: No output selected
+ * @arg RTC_Output_AlarmA: signal of AlarmA mapped to output
+ * @arg RTC_Output_AlarmB: signal of AlarmB mapped to output
+ * @arg RTC_Output_WakeUp: signal of WakeUp mapped to output
+ * @param RTC_OutputPolarity: Specifies the polarity of the output signal.
+ * This parameter can be one of the following:
+ * @arg RTC_OutputPolarity_High: The output pin is high when the
+ * ALRAF/ALRBF/WUTF is high (depending on OSEL)
+ * @arg RTC_OutputPolarity_Low: The output pin is low when the
+ * ALRAF/ALRBF/WUTF is high (depending on OSEL)
+ * @retval None
+ */
+void RTC_OutputConfig(uint32_t RTC_Output, uint32_t RTC_OutputPolarity)
+{
+ /* Check the parameters */
+ assert_param(IS_RTC_OUTPUT(RTC_Output));
+ assert_param(IS_RTC_OUTPUT_POL(RTC_OutputPolarity));
+
+ /* Disable the write protection for RTC registers */
+ RTC->WPR = 0xCA;
+ RTC->WPR = 0x53;
+
+ /* Clear the bits to be configured */
+ RTC->CR &= (uint32_t)~(RTC_CR_OSEL | RTC_CR_POL);
+
+ /* Configure the output selection and polarity */
+ RTC->CR |= (uint32_t)(RTC_Output | RTC_OutputPolarity);
+
+ /* Enable the write protection for RTC registers */
+ RTC->WPR = 0xFF;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup RTC_Group7 Coarse Calibration configuration functions
+ * @brief Coarse Calibration configuration functions
+ *
+@verbatim
+ ===============================================================================
+ Coarse Calibration configuration functions
+ ===============================================================================
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Configures the Coarse calibration parameters.
+ * @param RTC_CalibSign: specifies the sign of the coarse calibration value.
+ * This parameter can be one of the following values:
+ * @arg RTC_CalibSign_Positive: The value sign is positive
+ * @arg RTC_CalibSign_Negative: The value sign is negative
+ * @param Value: value of coarse calibration expressed in ppm (coded on 5 bits).
+ *
+ * @note This Calibration value should be between 0 and 63 when using negative
+ * sign with a 2-ppm step.
+ *
+ * @note This Calibration value should be between 0 and 126 when using positive
+ * sign with a 4-ppm step.
+ *
+ * @retval An ErrorStatus enumeration value:
+ * - SUCCESS: RTC Coarse calibration are initialized
+ * - ERROR: RTC Coarse calibration are not initialized
+ */
+ErrorStatus RTC_CoarseCalibConfig(uint32_t RTC_CalibSign, uint32_t Value)
+{
+ ErrorStatus status = ERROR;
+
+ /* Check the parameters */
+ assert_param(IS_RTC_CALIB_SIGN(RTC_CalibSign));
+ assert_param(IS_RTC_CALIB_VALUE(Value));
+
+ /* Disable the write protection for RTC registers */
+ RTC->WPR = 0xCA;
+ RTC->WPR = 0x53;
+
+ /* Set Initialization mode */
+ if (RTC_EnterInitMode() == ERROR)
+ {
+ status = ERROR;
+ }
+ else
+ {
+ /* Set the coarse calibration value */
+ RTC->CALIBR = (uint32_t)(RTC_CalibSign | Value);
+ /* Exit Initialization mode */
+ RTC_ExitInitMode();
+
+ status = SUCCESS;
+ }
+
+ /* Enable the write protection for RTC registers */
+ RTC->WPR = 0xFF;
+
+ return status;
+}
+
+/**
+ * @brief Enables or disables the Coarse calibration process.
+ * @param NewState: new state of the Coarse calibration.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval An ErrorStatus enumeration value:
+ * - SUCCESS: RTC Coarse calibration are enabled/disabled
+ * - ERROR: RTC Coarse calibration are not enabled/disabled
+ */
+ErrorStatus RTC_CoarseCalibCmd(FunctionalState NewState)
+{
+ ErrorStatus status = ERROR;
+
+ /* Check the parameters */
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ /* Disable the write protection for RTC registers */
+ RTC->WPR = 0xCA;
+ RTC->WPR = 0x53;
+
+ /* Set Initialization mode */
+ if (RTC_EnterInitMode() == ERROR)
+ {
+ status = ERROR;
+ }
+ else
+ {
+ if (NewState != DISABLE)
+ {
+ /* Enable the Coarse Calibration */
+ RTC->CR |= (uint32_t)RTC_CR_DCE;
+ }
+ else
+ {
+ /* Disable the Coarse Calibration */
+ RTC->CR &= (uint32_t)~RTC_CR_DCE;
+ }
+ /* Exit Initialization mode */
+ RTC_ExitInitMode();
+
+ status = SUCCESS;
+ }
+
+ /* Enable the write protection for RTC registers */
+ RTC->WPR = 0xFF;
+
+ return status;
+}
+
+/**
+ * @brief Enables or disables the RTC clock to be output through the relative pin.
+ * @param NewState: new state of the digital calibration Output.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void RTC_CalibOutputCmd(FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ /* Disable the write protection for RTC registers */
+ RTC->WPR = 0xCA;
+ RTC->WPR = 0x53;
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the RTC clock output */
+ RTC->CR |= (uint32_t)RTC_CR_COE;
+ }
+ else
+ {
+ /* Disable the RTC clock output */
+ RTC->CR &= (uint32_t)~RTC_CR_COE;
+ }
+
+ /* Enable the write protection for RTC registers */
+ RTC->WPR = 0xFF;
+}
+
+/**
+ * @}
+ */
+
+
+/** @defgroup RTC_Group8 TimeStamp configuration functions
+ * @brief TimeStamp configuration functions
+ *
+@verbatim
+ ===============================================================================
+ TimeStamp configuration functions
+ ===============================================================================
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Enables or Disables the RTC TimeStamp functionality with the
+ * specified time stamp pin stimulating edge.
+ * @param RTC_TimeStampEdge: Specifies the pin edge on which the TimeStamp is
+ * activated.
+ * This parameter can be one of the following:
+ * @arg RTC_TimeStampEdge_Rising: the Time stamp event occurs on the rising
+ * edge of the related pin.
+ * @arg RTC_TimeStampEdge_Falling: the Time stamp event occurs on the
+ * falling edge of the related pin.
+ * @param NewState: new state of the TimeStamp.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void RTC_TimeStampCmd(uint32_t RTC_TimeStampEdge, FunctionalState NewState)
+{
+ uint32_t tmpreg = 0;
+
+ /* Check the parameters */
+ assert_param(IS_RTC_TIMESTAMP_EDGE(RTC_TimeStampEdge));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ /* Get the RTC_CR register and clear the bits to be configured */
+ tmpreg = (uint32_t)(RTC->CR & (uint32_t)~(RTC_CR_TSEDGE | RTC_CR_TSE));
+
+ /* Get the new configuration */
+ if (NewState != DISABLE)
+ {
+ tmpreg |= (uint32_t)(RTC_TimeStampEdge | RTC_CR_TSE);
+ }
+ else
+ {
+ tmpreg |= (uint32_t)(RTC_TimeStampEdge);
+ }
+
+ /* Disable the write protection for RTC registers */
+ RTC->WPR = 0xCA;
+ RTC->WPR = 0x53;
+
+ /* Configure the Time Stamp TSEDGE and Enable bits */
+ RTC->CR = (uint32_t)tmpreg;
+
+ /* Enable the write protection for RTC registers */
+ RTC->WPR = 0xFF;
+}
+
+/**
+ * @brief Get the RTC TimeStamp value and masks.
+ * @param RTC_Format: specifies the format of the output parameters.
+ * This parameter can be one of the following values:
+ * @arg RTC_Format_BIN: Binary data format
+ * @arg RTC_Format_BCD: BCD data format
+ * @param RTC_StampTimeStruct: pointer to a RTC_TimeTypeDef structure that will
+ * contains the TimeStamp time values.
+ * @param RTC_StampDateStruct: pointer to a RTC_DateTypeDef structure that will
+ * contains the TimeStamp date values.
+ * @retval None
+ */
+void RTC_GetTimeStamp(uint32_t RTC_Format, RTC_TimeTypeDef* RTC_StampTimeStruct,
+ RTC_DateTypeDef* RTC_StampDateStruct)
+{
+ uint32_t tmptime = 0, tmpdate = 0;
+
+ /* Check the parameters */
+ assert_param(IS_RTC_FORMAT(RTC_Format));
+
+ /* Get the TimeStamp time and date registers values */
+ tmptime = (uint32_t)(RTC->TSTR & RTC_TR_RESERVED_MASK);
+ tmpdate = (uint32_t)(RTC->TSDR & RTC_DR_RESERVED_MASK);
+
+ /* Fill the Time structure fields with the read parameters */
+ RTC_StampTimeStruct->RTC_Hours = (uint8_t)((tmptime & (RTC_TR_HT | RTC_TR_HU)) >> 16);
+ RTC_StampTimeStruct->RTC_Minutes = (uint8_t)((tmptime & (RTC_TR_MNT | RTC_TR_MNU)) >> 8);
+ RTC_StampTimeStruct->RTC_Seconds = (uint8_t)(tmptime & (RTC_TR_ST | RTC_TR_SU));
+ RTC_StampTimeStruct->RTC_H12 = (uint8_t)((tmptime & (RTC_TR_PM)) >> 16);
+
+ /* Fill the Date structure fields with the read parameters */
+ RTC_StampDateStruct->RTC_Year = 0;
+ RTC_StampDateStruct->RTC_Month = (uint8_t)((tmpdate & (RTC_DR_MT | RTC_DR_MU)) >> 8);
+ RTC_StampDateStruct->RTC_Date = (uint8_t)(tmpdate & (RTC_DR_DT | RTC_DR_DU));
+ RTC_StampDateStruct->RTC_WeekDay = (uint8_t)((tmpdate & (RTC_DR_WDU)) >> 13);
+
+ /* Check the input parameters format */
+ if (RTC_Format == RTC_Format_BIN)
+ {
+ /* Convert the Time structure parameters to Binary format */
+ RTC_StampTimeStruct->RTC_Hours = (uint8_t)RTC_Bcd2ToByte(RTC_StampTimeStruct->RTC_Hours);
+ RTC_StampTimeStruct->RTC_Minutes = (uint8_t)RTC_Bcd2ToByte(RTC_StampTimeStruct->RTC_Minutes);
+ RTC_StampTimeStruct->RTC_Seconds = (uint8_t)RTC_Bcd2ToByte(RTC_StampTimeStruct->RTC_Seconds);
+
+ /* Convert the Date structure parameters to Binary format */
+ RTC_StampDateStruct->RTC_Month = (uint8_t)RTC_Bcd2ToByte(RTC_StampDateStruct->RTC_Month);
+ RTC_StampDateStruct->RTC_Date = (uint8_t)RTC_Bcd2ToByte(RTC_StampDateStruct->RTC_Date);
+ RTC_StampDateStruct->RTC_WeekDay = (uint8_t)RTC_Bcd2ToByte(RTC_StampDateStruct->RTC_WeekDay);
+ }
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup RTC_Group9 Tampers configuration functions
+ * @brief Tampers configuration functions
+ *
+@verbatim
+ ===============================================================================
+ Tampers configuration functions
+ ===============================================================================
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Configures the select Tamper pin edge.
+ * @param RTC_Tamper: Selected tamper pin.
+ * This parameter can be RTC_Tamper_1.
+ * @param RTC_TamperTrigger: Specifies the trigger on the tamper pin that
+ * stimulates tamper event.
+ * This parameter can be one of the following values:
+ * @arg RTC_TamperTrigger_RisingEdge: Rising Edge of the tamper pin causes tamper event.
+ * @arg RTC_TamperTrigger_FallingEdge: Falling Edge of the tamper pin causes tamper event.
+ * @retval None
+ */
+void RTC_TamperTriggerConfig(uint32_t RTC_Tamper, uint32_t RTC_TamperTrigger)
+{
+ /* Check the parameters */
+ assert_param(IS_RTC_TAMPER(RTC_Tamper));
+ assert_param(IS_RTC_TAMPER_TRIGGER(RTC_TamperTrigger));
+
+ if (RTC_TamperTrigger == RTC_TamperTrigger_RisingEdge)
+ {
+ /* Configure the RTC_TAFCR register */
+ RTC->TAFCR &= (uint32_t)((uint32_t)~(RTC_Tamper << 1));
+ }
+ else
+ {
+ /* Configure the RTC_TAFCR register */
+ RTC->TAFCR |= (uint32_t)(RTC_Tamper << 1);
+ }
+}
+
+/**
+ * @brief Enables or Disables the Tamper detection.
+ * @param RTC_Tamper: Selected tamper pin.
+ * This parameter can be RTC_Tamper_1.
+ * @param NewState: new state of the tamper pin.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void RTC_TamperCmd(uint32_t RTC_Tamper, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_RTC_TAMPER(RTC_Tamper));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the selected Tamper pin */
+ RTC->TAFCR |= (uint32_t)RTC_Tamper;
+ }
+ else
+ {
+ /* Disable the selected Tamper pin */
+ RTC->TAFCR &= (uint32_t)~RTC_Tamper;
+ }
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup RTC_Group10 Backup Data Registers configuration functions
+ * @brief Backup Data Registers configuration functions
+ *
+@verbatim
+ ===============================================================================
+ Backup Data Registers configuration functions
+ ===============================================================================
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Writes a data in a specified RTC Backup data register.
+ * @param RTC_BKP_DR: RTC Backup data Register number.
+ * This parameter can be: RTC_BKP_DRx where x can be from 0 to 19 to
+ * specify the register.
+ * @param Data: Data to be written in the specified RTC Backup data register.
+ * @retval None
+ */
+void RTC_WriteBackupRegister(uint32_t RTC_BKP_DR, uint32_t Data)
+{
+ __IO uint32_t tmp = 0;
+
+ /* Check the parameters */
+ assert_param(IS_RTC_BKP(RTC_BKP_DR));
+
+ tmp = RTC_BASE + 0x50;
+ tmp += (RTC_BKP_DR * 4);
+
+ /* Write the specified register */
+ *(__IO uint32_t *)tmp = (uint32_t)Data;
+}
+
+/**
+ * @brief Reads data from the specified RTC Backup data Register.
+ * @param RTC_BKP_DR: RTC Backup data Register number.
+ * This parameter can be: RTC_BKP_DRx where x can be from 0 to 19 to
+ * specify the register.
+ * @retval None
+ */
+uint32_t RTC_ReadBackupRegister(uint32_t RTC_BKP_DR)
+{
+ __IO uint32_t tmp = 0;
+
+ /* Check the parameters */
+ assert_param(IS_RTC_BKP(RTC_BKP_DR));
+
+ tmp = RTC_BASE + 0x50;
+ tmp += (RTC_BKP_DR * 4);
+
+ /* Read the specified register */
+ return (*(__IO uint32_t *)tmp);
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup RTC_Group11 RTC Tamper and TimeStamp Pins Selection and Output Type Config configuration functions
+ * @brief RTC Tamper and TimeStamp Pins Selection and Output Type Config
+ * configuration functions
+ *
+@verbatim
+ ===============================================================================
+ RTC Tamper and TimeStamp Pins Selection and Output Type Config configuration
+ functions
+ ===============================================================================
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Selects the RTC Tamper Pin.
+ * @param RTC_TamperPin: specifies the RTC Tamper Pin.
+ * This parameter can be one of the following values:
+ * @arg RTC_TamperPin_PC13: PC13 is selected as RTC Tamper Pin.
+ * @arg RTC_TamperPin_PI8: PI8 is selected as RTC Tamper Pin.
+ * @retval None
+ */
+void RTC_TamperPinSelection(uint32_t RTC_TamperPin)
+{
+ /* Check the parameters */
+ assert_param(IS_RTC_TAMPER_PIN(RTC_TamperPin));
+
+ RTC->TAFCR &= (uint32_t)~(RTC_TAFCR_TAMPINSEL);
+ RTC->TAFCR |= (uint32_t)(RTC_TamperPin);
+}
+
+/**
+ * @brief Selects the RTC TimeStamp Pin.
+ * @param RTC_TimeStampPin: specifies the RTC TimeStamp Pin.
+ * This parameter can be one of the following values:
+ * @arg RTC_TimeStampPin_PC13: PC13 is selected as RTC TimeStamp Pin.
+ * @arg RTC_TimeStampPin_PI8: PI8 is selected as RTC TimeStamp Pin.
+ * @retval None
+ */
+void RTC_TimeStampPinSelection(uint32_t RTC_TimeStampPin)
+{
+ /* Check the parameters */
+ assert_param(IS_RTC_TIMESTAMP_PIN(RTC_TimeStampPin));
+
+ RTC->TAFCR &= (uint32_t)~(RTC_TAFCR_TSINSEL);
+ RTC->TAFCR |= (uint32_t)(RTC_TimeStampPin);
+}
+
+/**
+ * @brief Configures the RTC Output Pin mode.
+ * @param RTC_OutputType: specifies the RTC Output (PC13) pin mode.
+ * This parameter can be one of the following values:
+ * @arg RTC_OutputType_OpenDrain: RTC Output (PC13) is configured in
+ * Open Drain mode.
+ * @arg RTC_OutputType_PushPull: RTC Output (PC13) is configured in
+ * Push Pull mode.
+ * @retval None
+ */
+void RTC_OutputTypeConfig(uint32_t RTC_OutputType)
+{
+ /* Check the parameters */
+ assert_param(IS_RTC_OUTPUT_TYPE(RTC_OutputType));
+
+ RTC->TAFCR &= (uint32_t)~(RTC_TAFCR_ALARMOUTTYPE);
+ RTC->TAFCR |= (uint32_t)(RTC_OutputType);
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup RTC_Group12 Interrupts and flags management functions
+ * @brief Interrupts and flags management functions
+ *
+@verbatim
+ ===============================================================================
+ Interrupts and flags management functions
+ ===============================================================================
+ All RTC interrupts are connected to the EXTI controller.
+
+ - To enable the RTC Alarm interrupt, the following sequence is required:
+ - Configure and enable the EXTI Line 17 in interrupt mode and select the rising
+ edge sensitivity using the EXTI_Init() function.
+ - Configure and enable the RTC_Alarm IRQ channel in the NVIC using the NVIC_Init()
+ function.
+ - Configure the RTC to generate RTC alarms (Alarm A and/or Alarm B) using
+ the RTC_SetAlarm() and RTC_AlarmCmd() functions.
+
+ - To enable the RTC Wakeup interrupt, the following sequence is required:
+ - Configure and enable the EXTI Line 22 in interrupt mode and select the rising
+ edge sensitivity using the EXTI_Init() function.
+ - Configure and enable the RTC_WKUP IRQ channel in the NVIC using the NVIC_Init()
+ function.
+ - Configure the RTC to generate the RTC wakeup timer event using the
+ RTC_WakeUpClockConfig(), RTC_SetWakeUpCounter() and RTC_WakeUpCmd() functions.
+
+ - To enable the RTC Tamper interrupt, the following sequence is required:
+ - Configure and enable the EXTI Line 21 in interrupt mode and select the rising
+ edge sensitivity using the EXTI_Init() function.
+ - Configure and enable the TAMP_STAMP IRQ channel in the NVIC using the NVIC_Init()
+ function.
+ - Configure the RTC to detect the RTC tamper event using the
+ RTC_TamperTriggerConfig() and RTC_TamperCmd() functions.
+
+ - To enable the RTC TimeStamp interrupt, the following sequence is required:
+ - Configure and enable the EXTI Line 21 in interrupt mode and select the rising
+ edge sensitivity using the EXTI_Init() function.
+ - Configure and enable the TAMP_STAMP IRQ channel in the NVIC using the NVIC_Init()
+ function.
+ - Configure the RTC to detect the RTC time-stamp event using the
+ RTC_TimeStampCmd() functions.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Enables or disables the specified RTC interrupts.
+ * @param RTC_IT: specifies the RTC interrupt sources to be enabled or disabled.
+ * This parameter can be any combination of the following values:
+ * @arg RTC_IT_TS: Time Stamp interrupt mask
+ * @arg RTC_IT_WUT: WakeUp Timer interrupt mask
+ * @arg RTC_IT_ALRB: Alarm B interrupt mask
+ * @arg RTC_IT_ALRA: Alarm A interrupt mask
+ * @arg RTC_IT_TAMP: Tamper event interrupt mask
+ * @param NewState: new state of the specified RTC interrupts.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void RTC_ITConfig(uint32_t RTC_IT, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_RTC_CONFIG_IT(RTC_IT));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ /* Disable the write protection for RTC registers */
+ RTC->WPR = 0xCA;
+ RTC->WPR = 0x53;
+
+ if (NewState != DISABLE)
+ {
+ /* Configure the Interrupts in the RTC_CR register */
+ RTC->CR |= (uint32_t)(RTC_IT & ~RTC_TAFCR_TAMPIE);
+ /* Configure the Tamper Interrupt in the RTC_TAFCR */
+ RTC->TAFCR |= (uint32_t)(RTC_IT & RTC_TAFCR_TAMPIE);
+ }
+ else
+ {
+ /* Configure the Interrupts in the RTC_CR register */
+ RTC->CR &= (uint32_t)~(RTC_IT & (uint32_t)~RTC_TAFCR_TAMPIE);
+ /* Configure the Tamper Interrupt in the RTC_TAFCR */
+ RTC->TAFCR &= (uint32_t)~(RTC_IT & RTC_TAFCR_TAMPIE);
+ }
+ /* Enable the write protection for RTC registers */
+ RTC->WPR = 0xFF;
+}
+
+/**
+ * @brief Checks whether the specified RTC flag is set or not.
+ * @param RTC_FLAG: specifies the flag to check.
+ * This parameter can be one of the following values:
+ * @arg RTC_FLAG_TAMP1F: Tamper 1 event flag
+ * @arg RTC_FLAG_TSOVF: Time Stamp OverFlow flag
+ * @arg RTC_FLAG_TSF: Time Stamp event flag
+ * @arg RTC_FLAG_WUTF: WakeUp Timer flag
+ * @arg RTC_FLAG_ALRBF: Alarm B flag
+ * @arg RTC_FLAG_ALRAF: Alarm A flag
+ * @arg RTC_FLAG_INITF: Initialization mode flag
+ * @arg RTC_FLAG_RSF: Registers Synchronized flag
+ * @arg RTC_FLAG_INITS: Registers Configured flag
+ * @arg RTC_FLAG_WUTWF: WakeUp Timer Write flag
+ * @arg RTC_FLAG_ALRBWF: Alarm B Write flag
+ * @arg RTC_FLAG_ALRAWF: Alarm A write flag
+ * @retval The new state of RTC_FLAG (SET or RESET).
+ */
+FlagStatus RTC_GetFlagStatus(uint32_t RTC_FLAG)
+{
+ FlagStatus bitstatus = RESET;
+ uint32_t tmpreg = 0;
+
+ /* Check the parameters */
+ assert_param(IS_RTC_GET_FLAG(RTC_FLAG));
+
+ /* Get all the flags */
+ tmpreg = (uint32_t)(RTC->ISR & RTC_FLAGS_MASK);
+
+ /* Return the status of the flag */
+ if ((tmpreg & RTC_FLAG) != (uint32_t)RESET)
+ {
+ bitstatus = SET;
+ }
+ else
+ {
+ bitstatus = RESET;
+ }
+ return bitstatus;
+}
+
+/**
+ * @brief Clears the RTC's pending flags.
+ * @param RTC_FLAG: specifies the RTC flag to clear.
+ * This parameter can be any combination of the following values:
+ * @arg RTC_FLAG_TAMP1F: Tamper 1 event flag
+ * @arg RTC_FLAG_TSOVF: Time Stamp Overflow flag
+ * @arg RTC_FLAG_TSF: Time Stamp event flag
+ * @arg RTC_FLAG_WUTF: WakeUp Timer flag
+ * @arg RTC_FLAG_ALRBF: Alarm B flag
+ * @arg RTC_FLAG_ALRAF: Alarm A flag
+ * @arg RTC_FLAG_RSF: Registers Synchronized flag
+ * @retval None
+ */
+void RTC_ClearFlag(uint32_t RTC_FLAG)
+{
+ /* Check the parameters */
+ assert_param(IS_RTC_CLEAR_FLAG(RTC_FLAG));
+
+ /* Clear the Flags in the RTC_ISR register */
+ RTC->ISR = (uint32_t)((uint32_t)(~((RTC_FLAG | RTC_ISR_INIT)& 0x0000FFFF) | (uint32_t)(RTC->ISR & RTC_ISR_INIT)));
+}
+
+/**
+ * @brief Checks whether the specified RTC interrupt has occurred or not.
+ * @param RTC_IT: specifies the RTC interrupt source to check.
+ * This parameter can be one of the following values:
+ * @arg RTC_IT_TS: Time Stamp interrupt
+ * @arg RTC_IT_WUT: WakeUp Timer interrupt
+ * @arg RTC_IT_ALRB: Alarm B interrupt
+ * @arg RTC_IT_ALRA: Alarm A interrupt
+ * @arg RTC_IT_TAMP1: Tamper 1 event interrupt
+ * @retval The new state of RTC_IT (SET or RESET).
+ */
+ITStatus RTC_GetITStatus(uint32_t RTC_IT)
+{
+ ITStatus bitstatus = RESET;
+ uint32_t tmpreg = 0, enablestatus = 0;
+
+ /* Check the parameters */
+ assert_param(IS_RTC_GET_IT(RTC_IT));
+
+ /* Get the TAMPER Interrupt enable bit and pending bit */
+ tmpreg = (uint32_t)(RTC->TAFCR & (RTC_TAFCR_TAMPIE));
+
+ /* Get the Interrupt enable Status */
+ enablestatus = (uint32_t)((RTC->CR & RTC_IT) | (tmpreg & (RTC_IT >> 15)));
+
+ /* Get the Interrupt pending bit */
+ tmpreg = (uint32_t)((RTC->ISR & (uint32_t)(RTC_IT >> 4)));
+
+ /* Get the status of the Interrupt */
+ if ((enablestatus != (uint32_t)RESET) && ((tmpreg & 0x0000FFFF) != (uint32_t)RESET))
+ {
+ bitstatus = SET;
+ }
+ else
+ {
+ bitstatus = RESET;
+ }
+ return bitstatus;
+}
+
+/**
+ * @brief Clears the RTC's interrupt pending bits.
+ * @param RTC_IT: specifies the RTC interrupt pending bit to clear.
+ * This parameter can be any combination of the following values:
+ * @arg RTC_IT_TS: Time Stamp interrupt
+ * @arg RTC_IT_WUT: WakeUp Timer interrupt
+ * @arg RTC_IT_ALRB: Alarm B interrupt
+ * @arg RTC_IT_ALRA: Alarm A interrupt
+ * @arg RTC_IT_TAMP1: Tamper 1 event interrupt
+ * @retval None
+ */
+void RTC_ClearITPendingBit(uint32_t RTC_IT)
+{
+ uint32_t tmpreg = 0;
+
+ /* Check the parameters */
+ assert_param(IS_RTC_CLEAR_IT(RTC_IT));
+
+ /* Get the RTC_ISR Interrupt pending bits mask */
+ tmpreg = (uint32_t)(RTC_IT >> 4);
+
+ /* Clear the interrupt pending bits in the RTC_ISR register */
+ RTC->ISR = (uint32_t)((uint32_t)(~((tmpreg | RTC_ISR_INIT)& 0x0000FFFF) | (uint32_t)(RTC->ISR & RTC_ISR_INIT)));
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @brief Converts a 2 digit decimal to BCD format.
+ * @param Value: Byte to be converted.
+ * @retval Converted byte
+ */
+static uint8_t RTC_ByteToBcd2(uint8_t Value)
+{
+ uint8_t bcdhigh = 0;
+
+ while (Value >= 10)
+ {
+ bcdhigh++;
+ Value -= 10;
+ }
+
+ return ((uint8_t)(bcdhigh << 4) | Value);
+}
+
+/**
+ * @brief Convert from 2 digit BCD to Binary.
+ * @param Value: BCD value to be converted.
+ * @retval Converted word
+ */
+static uint8_t RTC_Bcd2ToByte(uint8_t Value)
+{
+ uint8_t tmp = 0;
+ tmp = ((uint8_t)(Value & (uint8_t)0xF0) >> (uint8_t)0x4) * 10;
+ return (tmp + (Value & (uint8_t)0x0F));
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/src/stm32f2xx_sdio.c b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/src/stm32f2xx_sdio.c
new file mode 100644
index 0000000..a4fafe5
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/src/stm32f2xx_sdio.c
@@ -0,0 +1,1010 @@
+/**
+ ******************************************************************************
+ * @file stm32f2xx_sdio.c
+ * @author MCD Application Team
+ * @version V1.1.2
+ * @date 05-March-2012
+ * @brief This file provides firmware functions to manage the following
+ * functionalities of the Secure digital input/output interface (SDIO)
+ * peripheral:
+ * - Initialization and Configuration
+ * - Command path state machine (CPSM) management
+ * - Data path state machine (DPSM) management
+ * - SDIO IO Cards mode management
+ * - CE-ATA mode management
+ * - DMA transfers management
+ * - Interrupts and flags management
+ *
+ * @verbatim
+ *
+ *
+ * ===================================================================
+ * How to use this driver
+ * ===================================================================
+ * 1. The SDIO clock (SDIOCLK = 48 MHz) is coming from a specific output
+ * of PLL (PLL48CLK). Before to start working with SDIO peripheral
+ * make sure that the PLL is well configured.
+ * The SDIO peripheral uses two clock signals:
+ * - SDIO adapter clock (SDIOCLK = 48 MHz)
+ * - APB2 bus clock (PCLK2)
+ * PCLK2 and SDIO_CK clock frequencies must respect the following condition:
+ * Frequenc(PCLK2) >= (3 / 8 x Frequency(SDIO_CK))
+ *
+ * 2. Enable peripheral clock using RCC_APB2PeriphClockCmd(RCC_APB2Periph_SDIO, ENABLE).
+ *
+ * 3. According to the SDIO mode, enable the GPIO clocks using
+ * RCC_AHB1PeriphClockCmd() function.
+ * The I/O can be one of the following configurations:
+ * - 1-bit data length: SDIO_CMD, SDIO_CK and D0.
+ * - 4-bit data length: SDIO_CMD, SDIO_CK and D[3:0].
+ * - 8-bit data length: SDIO_CMD, SDIO_CK and D[7:0].
+ *
+ * 4. Peripheral's alternate function:
+ * - Connect the pin to the desired peripherals' Alternate
+ * Function (AF) using GPIO_PinAFConfig() function
+ * - Configure the desired pin in alternate function by:
+ * GPIO_InitStruct->GPIO_Mode = GPIO_Mode_AF
+ * - Select the type, pull-up/pull-down and output speed via
+ * GPIO_PuPd, GPIO_OType and GPIO_Speed members
+ * - Call GPIO_Init() function
+ *
+ * 5. Program the Clock Edge, Clock Bypass, Clock Power Save, Bus Wide,
+ * hardware, flow control and the Clock Divider using the SDIO_Init()
+ * function.
+ *
+ * 6. Enable the Power ON State using the SDIO_SetPowerState(SDIO_PowerState_ON)
+ * function.
+ *
+ * 7. Enable the clock using the SDIO_ClockCmd() function.
+ *
+ * 8. Enable the NVIC and the corresponding interrupt using the function
+ * SDIO_ITConfig() if you need to use interrupt mode.
+ *
+ * 9. When using the DMA mode
+ * - Configure the DMA using DMA_Init() function
+ * - Active the needed channel Request using SDIO_DMACmd() function
+ *
+ * 10. Enable the DMA using the DMA_Cmd() function, when using DMA mode.
+ *
+ * 11. To control the CPSM (Command Path State Machine) and send
+ * commands to the card use the SDIO_SendCommand(),
+ * SDIO_GetCommandResponse() and SDIO_GetResponse() functions.
+ * First, user has to fill the command structure (pointer to
+ * SDIO_CmdInitTypeDef) according to the selected command to be sent.
+ * The parameters that should be filled are:
+ * - Command Argument
+ * - Command Index
+ * - Command Response type
+ * - Command Wait
+ * - CPSM Status (Enable or Disable)
+ *
+ * To check if the command is well received, read the SDIO_CMDRESP
+ * register using the SDIO_GetCommandResponse().
+ * The SDIO responses registers (SDIO_RESP1 to SDIO_RESP2), use the
+ * SDIO_GetResponse() function.
+ *
+ * 12. To control the DPSM (Data Path State Machine) and send/receive
+ * data to/from the card use the SDIO_DataConfig(), SDIO_GetDataCounter(),
+ * SDIO_ReadData(), SDIO_WriteData() and SDIO_GetFIFOCount() functions.
+ *
+ * Read Operations
+ * ---------------
+ * a) First, user has to fill the data structure (pointer to
+ * SDIO_DataInitTypeDef) according to the selected data type to
+ * be received.
+ * The parameters that should be filled are:
+ * - Data TimeOut
+ * - Data Length
+ * - Data Block size
+ * - Data Transfer direction: should be from card (To SDIO)
+ * - Data Transfer mode
+ * - DPSM Status (Enable or Disable)
+ *
+ * b) Configure the SDIO resources to receive the data from the card
+ * according to selected transfer mode (Refer to Step 8, 9 and 10).
+ *
+ * c) Send the selected Read command (refer to step 11).
+ *
+ * d) Use the SDIO flags/interrupts to check the transfer status.
+ *
+ * Write Operations
+ * ---------------
+ * a) First, user has to fill the data structure (pointer to
+ * SDIO_DataInitTypeDef) according to the selected data type to
+ * be received.
+ * The parameters that should be filled are:
+ * - Data TimeOut
+ * - Data Length
+ * - Data Block size
+ * - Data Transfer direction: should be to card (To CARD)
+ * - Data Transfer mode
+ * - DPSM Status (Enable or Disable)
+ *
+ * b) Configure the SDIO resources to send the data to the card
+ * according to selected transfer mode (Refer to Step 8, 9 and 10).
+ *
+ * c) Send the selected Write command (refer to step 11).
+ *
+ * d) Use the SDIO flags/interrupts to check the transfer status.
+ *
+ *
+ * @endverbatim
+ *
+ *
+ ******************************************************************************
+ * @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 "stm32f2xx_sdio.h"
+#include "stm32f2xx_rcc.h"
+
+/** @addtogroup STM32F2xx_StdPeriph_Driver
+ * @{
+ */
+
+/** @defgroup SDIO
+ * @brief SDIO driver modules
+ * @{
+ */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+
+/* ------------ SDIO registers bit address in the alias region ----------- */
+#define SDIO_OFFSET (SDIO_BASE - PERIPH_BASE)
+
+/* --- CLKCR Register ---*/
+/* Alias word address of CLKEN bit */
+#define CLKCR_OFFSET (SDIO_OFFSET + 0x04)
+#define CLKEN_BitNumber 0x08
+#define CLKCR_CLKEN_BB (PERIPH_BB_BASE + (CLKCR_OFFSET * 32) + (CLKEN_BitNumber * 4))
+
+/* --- CMD Register ---*/
+/* Alias word address of SDIOSUSPEND bit */
+#define CMD_OFFSET (SDIO_OFFSET + 0x0C)
+#define SDIOSUSPEND_BitNumber 0x0B
+#define CMD_SDIOSUSPEND_BB (PERIPH_BB_BASE + (CMD_OFFSET * 32) + (SDIOSUSPEND_BitNumber * 4))
+
+/* Alias word address of ENCMDCOMPL bit */
+#define ENCMDCOMPL_BitNumber 0x0C
+#define CMD_ENCMDCOMPL_BB (PERIPH_BB_BASE + (CMD_OFFSET * 32) + (ENCMDCOMPL_BitNumber * 4))
+
+/* Alias word address of NIEN bit */
+#define NIEN_BitNumber 0x0D
+#define CMD_NIEN_BB (PERIPH_BB_BASE + (CMD_OFFSET * 32) + (NIEN_BitNumber * 4))
+
+/* Alias word address of ATACMD bit */
+#define ATACMD_BitNumber 0x0E
+#define CMD_ATACMD_BB (PERIPH_BB_BASE + (CMD_OFFSET * 32) + (ATACMD_BitNumber * 4))
+
+/* --- DCTRL Register ---*/
+/* Alias word address of DMAEN bit */
+#define DCTRL_OFFSET (SDIO_OFFSET + 0x2C)
+#define DMAEN_BitNumber 0x03
+#define DCTRL_DMAEN_BB (PERIPH_BB_BASE + (DCTRL_OFFSET * 32) + (DMAEN_BitNumber * 4))
+
+/* Alias word address of RWSTART bit */
+#define RWSTART_BitNumber 0x08
+#define DCTRL_RWSTART_BB (PERIPH_BB_BASE + (DCTRL_OFFSET * 32) + (RWSTART_BitNumber * 4))
+
+/* Alias word address of RWSTOP bit */
+#define RWSTOP_BitNumber 0x09
+#define DCTRL_RWSTOP_BB (PERIPH_BB_BASE + (DCTRL_OFFSET * 32) + (RWSTOP_BitNumber * 4))
+
+/* Alias word address of RWMOD bit */
+#define RWMOD_BitNumber 0x0A
+#define DCTRL_RWMOD_BB (PERIPH_BB_BASE + (DCTRL_OFFSET * 32) + (RWMOD_BitNumber * 4))
+
+/* Alias word address of SDIOEN bit */
+#define SDIOEN_BitNumber 0x0B
+#define DCTRL_SDIOEN_BB (PERIPH_BB_BASE + (DCTRL_OFFSET * 32) + (SDIOEN_BitNumber * 4))
+
+/* ---------------------- SDIO registers bit mask ------------------------ */
+/* --- CLKCR Register ---*/
+/* CLKCR register clear mask */
+#define CLKCR_CLEAR_MASK ((uint32_t)0xFFFF8100)
+
+/* --- PWRCTRL Register ---*/
+/* SDIO PWRCTRL Mask */
+#define PWR_PWRCTRL_MASK ((uint32_t)0xFFFFFFFC)
+
+/* --- DCTRL Register ---*/
+/* SDIO DCTRL Clear Mask */
+#define DCTRL_CLEAR_MASK ((uint32_t)0xFFFFFF08)
+
+/* --- CMD Register ---*/
+/* CMD Register clear mask */
+#define CMD_CLEAR_MASK ((uint32_t)0xFFFFF800)
+
+/* SDIO RESP Registers Address */
+#define SDIO_RESP_ADDR ((uint32_t)(SDIO_BASE + 0x14))
+
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+/** @defgroup SDIO_Private_Functions
+ * @{
+ */
+
+/** @defgroup SDIO_Group1 Initialization and Configuration functions
+ * @brief Initialization and Configuration functions
+ *
+@verbatim
+ ===============================================================================
+ Initialization and Configuration functions
+ ===============================================================================
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Deinitializes the SDIO peripheral registers to their default reset values.
+ * @param None
+ * @retval None
+ */
+void SDIO_DeInit(void)
+{
+ RCC_APB2PeriphResetCmd(RCC_APB2Periph_SDIO, ENABLE);
+ RCC_APB2PeriphResetCmd(RCC_APB2Periph_SDIO, DISABLE);
+}
+
+/**
+ * @brief Initializes the SDIO peripheral according to the specified
+ * parameters in the SDIO_InitStruct.
+ * @param SDIO_InitStruct : pointer to a SDIO_InitTypeDef structure
+ * that contains the configuration information for the SDIO peripheral.
+ * @retval None
+ */
+void SDIO_Init(SDIO_InitTypeDef* SDIO_InitStruct)
+{
+ uint32_t tmpreg = 0;
+
+ /* Check the parameters */
+ assert_param(IS_SDIO_CLOCK_EDGE(SDIO_InitStruct->SDIO_ClockEdge));
+ assert_param(IS_SDIO_CLOCK_BYPASS(SDIO_InitStruct->SDIO_ClockBypass));
+ assert_param(IS_SDIO_CLOCK_POWER_SAVE(SDIO_InitStruct->SDIO_ClockPowerSave));
+ assert_param(IS_SDIO_BUS_WIDE(SDIO_InitStruct->SDIO_BusWide));
+ assert_param(IS_SDIO_HARDWARE_FLOW_CONTROL(SDIO_InitStruct->SDIO_HardwareFlowControl));
+
+/*---------------------------- SDIO CLKCR Configuration ------------------------*/
+ /* Get the SDIO CLKCR value */
+ tmpreg = SDIO->CLKCR;
+
+ /* Clear CLKDIV, PWRSAV, BYPASS, WIDBUS, NEGEDGE, HWFC_EN bits */
+ tmpreg &= CLKCR_CLEAR_MASK;
+
+ /* Set CLKDIV bits according to SDIO_ClockDiv value */
+ /* Set PWRSAV bit according to SDIO_ClockPowerSave value */
+ /* Set BYPASS bit according to SDIO_ClockBypass value */
+ /* Set WIDBUS bits according to SDIO_BusWide value */
+ /* Set NEGEDGE bits according to SDIO_ClockEdge value */
+ /* Set HWFC_EN bits according to SDIO_HardwareFlowControl value */
+ tmpreg |= (SDIO_InitStruct->SDIO_ClockDiv | SDIO_InitStruct->SDIO_ClockPowerSave |
+ SDIO_InitStruct->SDIO_ClockBypass | SDIO_InitStruct->SDIO_BusWide |
+ SDIO_InitStruct->SDIO_ClockEdge | SDIO_InitStruct->SDIO_HardwareFlowControl);
+
+ /* Write to SDIO CLKCR */
+ SDIO->CLKCR = tmpreg;
+}
+
+/**
+ * @brief Fills each SDIO_InitStruct member with its default value.
+ * @param SDIO_InitStruct: pointer to an SDIO_InitTypeDef structure which
+ * will be initialized.
+ * @retval None
+ */
+void SDIO_StructInit(SDIO_InitTypeDef* SDIO_InitStruct)
+{
+ /* SDIO_InitStruct members default value */
+ SDIO_InitStruct->SDIO_ClockDiv = 0x00;
+ SDIO_InitStruct->SDIO_ClockEdge = SDIO_ClockEdge_Rising;
+ SDIO_InitStruct->SDIO_ClockBypass = SDIO_ClockBypass_Disable;
+ SDIO_InitStruct->SDIO_ClockPowerSave = SDIO_ClockPowerSave_Disable;
+ SDIO_InitStruct->SDIO_BusWide = SDIO_BusWide_1b;
+ SDIO_InitStruct->SDIO_HardwareFlowControl = SDIO_HardwareFlowControl_Disable;
+}
+
+/**
+ * @brief Enables or disables the SDIO Clock.
+ * @param NewState: new state of the SDIO Clock.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void SDIO_ClockCmd(FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ *(__IO uint32_t *) CLKCR_CLKEN_BB = (uint32_t)NewState;
+}
+
+/**
+ * @brief Sets the power status of the controller.
+ * @param SDIO_PowerState: new state of the Power state.
+ * This parameter can be one of the following values:
+ * @arg SDIO_PowerState_OFF: SDIO Power OFF
+ * @arg SDIO_PowerState_ON: SDIO Power ON
+ * @retval None
+ */
+void SDIO_SetPowerState(uint32_t SDIO_PowerState)
+{
+ /* Check the parameters */
+ assert_param(IS_SDIO_POWER_STATE(SDIO_PowerState));
+
+ SDIO->POWER = SDIO_PowerState;
+}
+
+/**
+ * @brief Gets the power status of the controller.
+ * @param None
+ * @retval Power status of the controller. The returned value can be one of the
+ * following values:
+ * - 0x00: Power OFF
+ * - 0x02: Power UP
+ * - 0x03: Power ON
+ */
+uint32_t SDIO_GetPowerState(void)
+{
+ return (SDIO->POWER & (~PWR_PWRCTRL_MASK));
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup SDIO_Group2 Command path state machine (CPSM) management functions
+ * @brief Command path state machine (CPSM) management functions
+ *
+@verbatim
+ ===============================================================================
+ Command path state machine (CPSM) management functions
+ ===============================================================================
+
+ This section provide functions allowing to program and read the Command path
+ state machine (CPSM).
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Initializes the SDIO Command according to the specified
+ * parameters in the SDIO_CmdInitStruct and send the command.
+ * @param SDIO_CmdInitStruct : pointer to a SDIO_CmdInitTypeDef
+ * structure that contains the configuration information for the SDIO
+ * command.
+ * @retval None
+ */
+void SDIO_SendCommand(SDIO_CmdInitTypeDef *SDIO_CmdInitStruct)
+{
+ uint32_t tmpreg = 0;
+
+ /* Check the parameters */
+ assert_param(IS_SDIO_CMD_INDEX(SDIO_CmdInitStruct->SDIO_CmdIndex));
+ assert_param(IS_SDIO_RESPONSE(SDIO_CmdInitStruct->SDIO_Response));
+ assert_param(IS_SDIO_WAIT(SDIO_CmdInitStruct->SDIO_Wait));
+ assert_param(IS_SDIO_CPSM(SDIO_CmdInitStruct->SDIO_CPSM));
+
+/*---------------------------- SDIO ARG Configuration ------------------------*/
+ /* Set the SDIO Argument value */
+ SDIO->ARG = SDIO_CmdInitStruct->SDIO_Argument;
+
+/*---------------------------- SDIO CMD Configuration ------------------------*/
+ /* Get the SDIO CMD value */
+ tmpreg = SDIO->CMD;
+ /* Clear CMDINDEX, WAITRESP, WAITINT, WAITPEND, CPSMEN bits */
+ tmpreg &= CMD_CLEAR_MASK;
+ /* Set CMDINDEX bits according to SDIO_CmdIndex value */
+ /* Set WAITRESP bits according to SDIO_Response value */
+ /* Set WAITINT and WAITPEND bits according to SDIO_Wait value */
+ /* Set CPSMEN bits according to SDIO_CPSM value */
+ tmpreg |= (uint32_t)SDIO_CmdInitStruct->SDIO_CmdIndex | SDIO_CmdInitStruct->SDIO_Response
+ | SDIO_CmdInitStruct->SDIO_Wait | SDIO_CmdInitStruct->SDIO_CPSM;
+
+ /* Write to SDIO CMD */
+ SDIO->CMD = tmpreg;
+}
+
+/**
+ * @brief Fills each SDIO_CmdInitStruct member with its default value.
+ * @param SDIO_CmdInitStruct: pointer to an SDIO_CmdInitTypeDef
+ * structure which will be initialized.
+ * @retval None
+ */
+void SDIO_CmdStructInit(SDIO_CmdInitTypeDef* SDIO_CmdInitStruct)
+{
+ /* SDIO_CmdInitStruct members default value */
+ SDIO_CmdInitStruct->SDIO_Argument = 0x00;
+ SDIO_CmdInitStruct->SDIO_CmdIndex = 0x00;
+ SDIO_CmdInitStruct->SDIO_Response = SDIO_Response_No;
+ SDIO_CmdInitStruct->SDIO_Wait = SDIO_Wait_No;
+ SDIO_CmdInitStruct->SDIO_CPSM = SDIO_CPSM_Disable;
+}
+
+/**
+ * @brief Returns command index of last command for which response received.
+ * @param None
+ * @retval Returns the command index of the last command response received.
+ */
+uint8_t SDIO_GetCommandResponse(void)
+{
+ return (uint8_t)(SDIO->RESPCMD);
+}
+
+/**
+ * @brief Returns response received from the card for the last command.
+ * @param SDIO_RESP: Specifies the SDIO response register.
+ * This parameter can be one of the following values:
+ * @arg SDIO_RESP1: Response Register 1
+ * @arg SDIO_RESP2: Response Register 2
+ * @arg SDIO_RESP3: Response Register 3
+ * @arg SDIO_RESP4: Response Register 4
+ * @retval The Corresponding response register value.
+ */
+uint32_t SDIO_GetResponse(uint32_t SDIO_RESP)
+{
+ __IO uint32_t tmp = 0;
+
+ /* Check the parameters */
+ assert_param(IS_SDIO_RESP(SDIO_RESP));
+
+ tmp = SDIO_RESP_ADDR + SDIO_RESP;
+
+ return (*(__IO uint32_t *) tmp);
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup SDIO_Group3 Data path state machine (DPSM) management functions
+ * @brief Data path state machine (DPSM) management functions
+ *
+@verbatim
+ ===============================================================================
+ Data path state machine (DPSM) management functions
+ ===============================================================================
+
+ This section provide functions allowing to program and read the Data path
+ state machine (DPSM).
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Initializes the SDIO data path according to the specified
+ * parameters in the SDIO_DataInitStruct.
+ * @param SDIO_DataInitStruct : pointer to a SDIO_DataInitTypeDef structure
+ * that contains the configuration information for the SDIO command.
+ * @retval None
+ */
+void SDIO_DataConfig(SDIO_DataInitTypeDef* SDIO_DataInitStruct)
+{
+ uint32_t tmpreg = 0;
+
+ /* Check the parameters */
+ assert_param(IS_SDIO_DATA_LENGTH(SDIO_DataInitStruct->SDIO_DataLength));
+ assert_param(IS_SDIO_BLOCK_SIZE(SDIO_DataInitStruct->SDIO_DataBlockSize));
+ assert_param(IS_SDIO_TRANSFER_DIR(SDIO_DataInitStruct->SDIO_TransferDir));
+ assert_param(IS_SDIO_TRANSFER_MODE(SDIO_DataInitStruct->SDIO_TransferMode));
+ assert_param(IS_SDIO_DPSM(SDIO_DataInitStruct->SDIO_DPSM));
+
+/*---------------------------- SDIO DTIMER Configuration ---------------------*/
+ /* Set the SDIO Data TimeOut value */
+ SDIO->DTIMER = SDIO_DataInitStruct->SDIO_DataTimeOut;
+
+/*---------------------------- SDIO DLEN Configuration -----------------------*/
+ /* Set the SDIO DataLength value */
+ SDIO->DLEN = SDIO_DataInitStruct->SDIO_DataLength;
+
+/*---------------------------- SDIO DCTRL Configuration ----------------------*/
+ /* Get the SDIO DCTRL value */
+ tmpreg = SDIO->DCTRL;
+ /* Clear DEN, DTMODE, DTDIR and DBCKSIZE bits */
+ tmpreg &= DCTRL_CLEAR_MASK;
+ /* Set DEN bit according to SDIO_DPSM value */
+ /* Set DTMODE bit according to SDIO_TransferMode value */
+ /* Set DTDIR bit according to SDIO_TransferDir value */
+ /* Set DBCKSIZE bits according to SDIO_DataBlockSize value */
+ tmpreg |= (uint32_t)SDIO_DataInitStruct->SDIO_DataBlockSize | SDIO_DataInitStruct->SDIO_TransferDir
+ | SDIO_DataInitStruct->SDIO_TransferMode | SDIO_DataInitStruct->SDIO_DPSM;
+
+ /* Write to SDIO DCTRL */
+ SDIO->DCTRL = tmpreg;
+}
+
+/**
+ * @brief Fills each SDIO_DataInitStruct member with its default value.
+ * @param SDIO_DataInitStruct: pointer to an SDIO_DataInitTypeDef structure
+ * which will be initialized.
+ * @retval None
+ */
+void SDIO_DataStructInit(SDIO_DataInitTypeDef* SDIO_DataInitStruct)
+{
+ /* SDIO_DataInitStruct members default value */
+ SDIO_DataInitStruct->SDIO_DataTimeOut = 0xFFFFFFFF;
+ SDIO_DataInitStruct->SDIO_DataLength = 0x00;
+ SDIO_DataInitStruct->SDIO_DataBlockSize = SDIO_DataBlockSize_1b;
+ SDIO_DataInitStruct->SDIO_TransferDir = SDIO_TransferDir_ToCard;
+ SDIO_DataInitStruct->SDIO_TransferMode = SDIO_TransferMode_Block;
+ SDIO_DataInitStruct->SDIO_DPSM = SDIO_DPSM_Disable;
+}
+
+/**
+ * @brief Returns number of remaining data bytes to be transferred.
+ * @param None
+ * @retval Number of remaining data bytes to be transferred
+ */
+uint32_t SDIO_GetDataCounter(void)
+{
+ return SDIO->DCOUNT;
+}
+
+/**
+ * @brief Read one data word from Rx FIFO.
+ * @param None
+ * @retval Data received
+ */
+uint32_t SDIO_ReadData(void)
+{
+ return SDIO->FIFO;
+}
+
+/**
+ * @brief Write one data word to Tx FIFO.
+ * @param Data: 32-bit data word to write.
+ * @retval None
+ */
+void SDIO_WriteData(uint32_t Data)
+{
+ SDIO->FIFO = Data;
+}
+
+/**
+ * @brief Returns the number of words left to be written to or read from FIFO.
+ * @param None
+ * @retval Remaining number of words.
+ */
+uint32_t SDIO_GetFIFOCount(void)
+{
+ return SDIO->FIFOCNT;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup SDIO_Group4 SDIO IO Cards mode management functions
+ * @brief SDIO IO Cards mode management functions
+ *
+@verbatim
+ ===============================================================================
+ SDIO IO Cards mode management functions
+ ===============================================================================
+
+ This section provide functions allowing to program and read the SDIO IO Cards.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Starts the SD I/O Read Wait operation.
+ * @param NewState: new state of the Start SDIO Read Wait operation.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void SDIO_StartSDIOReadWait(FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ *(__IO uint32_t *) DCTRL_RWSTART_BB = (uint32_t) NewState;
+}
+
+/**
+ * @brief Stops the SD I/O Read Wait operation.
+ * @param NewState: new state of the Stop SDIO Read Wait operation.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void SDIO_StopSDIOReadWait(FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ *(__IO uint32_t *) DCTRL_RWSTOP_BB = (uint32_t) NewState;
+}
+
+/**
+ * @brief Sets one of the two options of inserting read wait interval.
+ * @param SDIO_ReadWaitMode: SD I/O Read Wait operation mode.
+ * This parameter can be:
+ * @arg SDIO_ReadWaitMode_CLK: Read Wait control by stopping SDIOCLK
+ * @arg SDIO_ReadWaitMode_DATA2: Read Wait control using SDIO_DATA2
+ * @retval None
+ */
+void SDIO_SetSDIOReadWaitMode(uint32_t SDIO_ReadWaitMode)
+{
+ /* Check the parameters */
+ assert_param(IS_SDIO_READWAIT_MODE(SDIO_ReadWaitMode));
+
+ *(__IO uint32_t *) DCTRL_RWMOD_BB = SDIO_ReadWaitMode;
+}
+
+/**
+ * @brief Enables or disables the SD I/O Mode Operation.
+ * @param NewState: new state of SDIO specific operation.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void SDIO_SetSDIOOperation(FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ *(__IO uint32_t *) DCTRL_SDIOEN_BB = (uint32_t)NewState;
+}
+
+/**
+ * @brief Enables or disables the SD I/O Mode suspend command sending.
+ * @param NewState: new state of the SD I/O Mode suspend command.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void SDIO_SendSDIOSuspendCmd(FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ *(__IO uint32_t *) CMD_SDIOSUSPEND_BB = (uint32_t)NewState;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup SDIO_Group5 CE-ATA mode management functions
+ * @brief CE-ATA mode management functions
+ *
+@verbatim
+ ===============================================================================
+ CE-ATA mode management functions
+ ===============================================================================
+
+ This section provide functions allowing to program and read the CE-ATA card.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Enables or disables the command completion signal.
+ * @param NewState: new state of command completion signal.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void SDIO_CommandCompletionCmd(FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ *(__IO uint32_t *) CMD_ENCMDCOMPL_BB = (uint32_t)NewState;
+}
+
+/**
+ * @brief Enables or disables the CE-ATA interrupt.
+ * @param NewState: new state of CE-ATA interrupt.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void SDIO_CEATAITCmd(FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ *(__IO uint32_t *) CMD_NIEN_BB = (uint32_t)((~((uint32_t)NewState)) & ((uint32_t)0x1));
+}
+
+/**
+ * @brief Sends CE-ATA command (CMD61).
+ * @param NewState: new state of CE-ATA command.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void SDIO_SendCEATACmd(FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ *(__IO uint32_t *) CMD_ATACMD_BB = (uint32_t)NewState;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup SDIO_Group6 DMA transfers management functions
+ * @brief DMA transfers management functions
+ *
+@verbatim
+ ===============================================================================
+ DMA transfers management functions
+ ===============================================================================
+
+ This section provide functions allowing to program SDIO DMA transfer.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Enables or disables the SDIO DMA request.
+ * @param NewState: new state of the selected SDIO DMA request.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void SDIO_DMACmd(FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ *(__IO uint32_t *) DCTRL_DMAEN_BB = (uint32_t)NewState;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup SDIO_Group7 Interrupts and flags management functions
+ * @brief Interrupts and flags management functions
+ *
+@verbatim
+ ===============================================================================
+ Interrupts and flags management functions
+ ===============================================================================
+
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Enables or disables the SDIO interrupts.
+ * @param SDIO_IT: specifies the SDIO interrupt sources to be enabled or disabled.
+ * This parameter can be one or a combination of the following values:
+ * @arg SDIO_IT_CCRCFAIL: Command response received (CRC check failed) interrupt
+ * @arg SDIO_IT_DCRCFAIL: Data block sent/received (CRC check failed) interrupt
+ * @arg SDIO_IT_CTIMEOUT: Command response timeout interrupt
+ * @arg SDIO_IT_DTIMEOUT: Data timeout interrupt
+ * @arg SDIO_IT_TXUNDERR: Transmit FIFO underrun error interrupt
+ * @arg SDIO_IT_RXOVERR: Received FIFO overrun error interrupt
+ * @arg SDIO_IT_CMDREND: Command response received (CRC check passed) interrupt
+ * @arg SDIO_IT_CMDSENT: Command sent (no response required) interrupt
+ * @arg SDIO_IT_DATAEND: Data end (data counter, SDIDCOUNT, is zero) interrupt
+ * @arg SDIO_IT_STBITERR: Start bit not detected on all data signals in wide
+ * bus mode interrupt
+ * @arg SDIO_IT_DBCKEND: Data block sent/received (CRC check passed) interrupt
+ * @arg SDIO_IT_CMDACT: Command transfer in progress interrupt
+ * @arg SDIO_IT_TXACT: Data transmit in progress interrupt
+ * @arg SDIO_IT_RXACT: Data receive in progress interrupt
+ * @arg SDIO_IT_TXFIFOHE: Transmit FIFO Half Empty interrupt
+ * @arg SDIO_IT_RXFIFOHF: Receive FIFO Half Full interrupt
+ * @arg SDIO_IT_TXFIFOF: Transmit FIFO full interrupt
+ * @arg SDIO_IT_RXFIFOF: Receive FIFO full interrupt
+ * @arg SDIO_IT_TXFIFOE: Transmit FIFO empty interrupt
+ * @arg SDIO_IT_RXFIFOE: Receive FIFO empty interrupt
+ * @arg SDIO_IT_TXDAVL: Data available in transmit FIFO interrupt
+ * @arg SDIO_IT_RXDAVL: Data available in receive FIFO interrupt
+ * @arg SDIO_IT_SDIOIT: SD I/O interrupt received interrupt
+ * @arg SDIO_IT_CEATAEND: CE-ATA command completion signal received for CMD61 interrupt
+ * @param NewState: new state of the specified SDIO interrupts.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void SDIO_ITConfig(uint32_t SDIO_IT, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_SDIO_IT(SDIO_IT));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the SDIO interrupts */
+ SDIO->MASK |= SDIO_IT;
+ }
+ else
+ {
+ /* Disable the SDIO interrupts */
+ SDIO->MASK &= ~SDIO_IT;
+ }
+}
+
+/**
+ * @brief Checks whether the specified SDIO flag is set or not.
+ * @param SDIO_FLAG: specifies the flag to check.
+ * This parameter can be one of the following values:
+ * @arg SDIO_FLAG_CCRCFAIL: Command response received (CRC check failed)
+ * @arg SDIO_FLAG_DCRCFAIL: Data block sent/received (CRC check failed)
+ * @arg SDIO_FLAG_CTIMEOUT: Command response timeout
+ * @arg SDIO_FLAG_DTIMEOUT: Data timeout
+ * @arg SDIO_FLAG_TXUNDERR: Transmit FIFO underrun error
+ * @arg SDIO_FLAG_RXOVERR: Received FIFO overrun error
+ * @arg SDIO_FLAG_CMDREND: Command response received (CRC check passed)
+ * @arg SDIO_FLAG_CMDSENT: Command sent (no response required)
+ * @arg SDIO_FLAG_DATAEND: Data end (data counter, SDIDCOUNT, is zero)
+ * @arg SDIO_FLAG_STBITERR: Start bit not detected on all data signals in wide bus mode.
+ * @arg SDIO_FLAG_DBCKEND: Data block sent/received (CRC check passed)
+ * @arg SDIO_FLAG_CMDACT: Command transfer in progress
+ * @arg SDIO_FLAG_TXACT: Data transmit in progress
+ * @arg SDIO_FLAG_RXACT: Data receive in progress
+ * @arg SDIO_FLAG_TXFIFOHE: Transmit FIFO Half Empty
+ * @arg SDIO_FLAG_RXFIFOHF: Receive FIFO Half Full
+ * @arg SDIO_FLAG_TXFIFOF: Transmit FIFO full
+ * @arg SDIO_FLAG_RXFIFOF: Receive FIFO full
+ * @arg SDIO_FLAG_TXFIFOE: Transmit FIFO empty
+ * @arg SDIO_FLAG_RXFIFOE: Receive FIFO empty
+ * @arg SDIO_FLAG_TXDAVL: Data available in transmit FIFO
+ * @arg SDIO_FLAG_RXDAVL: Data available in receive FIFO
+ * @arg SDIO_FLAG_SDIOIT: SD I/O interrupt received
+ * @arg SDIO_FLAG_CEATAEND: CE-ATA command completion signal received for CMD61
+ * @retval The new state of SDIO_FLAG (SET or RESET).
+ */
+FlagStatus SDIO_GetFlagStatus(uint32_t SDIO_FLAG)
+{
+ FlagStatus bitstatus = RESET;
+
+ /* Check the parameters */
+ assert_param(IS_SDIO_FLAG(SDIO_FLAG));
+
+ if ((SDIO->STA & SDIO_FLAG) != (uint32_t)RESET)
+ {
+ bitstatus = SET;
+ }
+ else
+ {
+ bitstatus = RESET;
+ }
+ return bitstatus;
+}
+
+/**
+ * @brief Clears the SDIO's pending flags.
+ * @param SDIO_FLAG: specifies the flag to clear.
+ * This parameter can be one or a combination of the following values:
+ * @arg SDIO_FLAG_CCRCFAIL: Command response received (CRC check failed)
+ * @arg SDIO_FLAG_DCRCFAIL: Data block sent/received (CRC check failed)
+ * @arg SDIO_FLAG_CTIMEOUT: Command response timeout
+ * @arg SDIO_FLAG_DTIMEOUT: Data timeout
+ * @arg SDIO_FLAG_TXUNDERR: Transmit FIFO underrun error
+ * @arg SDIO_FLAG_RXOVERR: Received FIFO overrun error
+ * @arg SDIO_FLAG_CMDREND: Command response received (CRC check passed)
+ * @arg SDIO_FLAG_CMDSENT: Command sent (no response required)
+ * @arg SDIO_FLAG_DATAEND: Data end (data counter, SDIDCOUNT, is zero)
+ * @arg SDIO_FLAG_STBITERR: Start bit not detected on all data signals in wide bus mode
+ * @arg SDIO_FLAG_DBCKEND: Data block sent/received (CRC check passed)
+ * @arg SDIO_FLAG_SDIOIT: SD I/O interrupt received
+ * @arg SDIO_FLAG_CEATAEND: CE-ATA command completion signal received for CMD61
+ * @retval None
+ */
+void SDIO_ClearFlag(uint32_t SDIO_FLAG)
+{
+ /* Check the parameters */
+ assert_param(IS_SDIO_CLEAR_FLAG(SDIO_FLAG));
+
+ SDIO->ICR = SDIO_FLAG;
+}
+
+/**
+ * @brief Checks whether the specified SDIO interrupt has occurred or not.
+ * @param SDIO_IT: specifies the SDIO interrupt source to check.
+ * This parameter can be one of the following values:
+ * @arg SDIO_IT_CCRCFAIL: Command response received (CRC check failed) interrupt
+ * @arg SDIO_IT_DCRCFAIL: Data block sent/received (CRC check failed) interrupt
+ * @arg SDIO_IT_CTIMEOUT: Command response timeout interrupt
+ * @arg SDIO_IT_DTIMEOUT: Data timeout interrupt
+ * @arg SDIO_IT_TXUNDERR: Transmit FIFO underrun error interrupt
+ * @arg SDIO_IT_RXOVERR: Received FIFO overrun error interrupt
+ * @arg SDIO_IT_CMDREND: Command response received (CRC check passed) interrupt
+ * @arg SDIO_IT_CMDSENT: Command sent (no response required) interrupt
+ * @arg SDIO_IT_DATAEND: Data end (data counter, SDIDCOUNT, is zero) interrupt
+ * @arg SDIO_IT_STBITERR: Start bit not detected on all data signals in wide
+ * bus mode interrupt
+ * @arg SDIO_IT_DBCKEND: Data block sent/received (CRC check passed) interrupt
+ * @arg SDIO_IT_CMDACT: Command transfer in progress interrupt
+ * @arg SDIO_IT_TXACT: Data transmit in progress interrupt
+ * @arg SDIO_IT_RXACT: Data receive in progress interrupt
+ * @arg SDIO_IT_TXFIFOHE: Transmit FIFO Half Empty interrupt
+ * @arg SDIO_IT_RXFIFOHF: Receive FIFO Half Full interrupt
+ * @arg SDIO_IT_TXFIFOF: Transmit FIFO full interrupt
+ * @arg SDIO_IT_RXFIFOF: Receive FIFO full interrupt
+ * @arg SDIO_IT_TXFIFOE: Transmit FIFO empty interrupt
+ * @arg SDIO_IT_RXFIFOE: Receive FIFO empty interrupt
+ * @arg SDIO_IT_TXDAVL: Data available in transmit FIFO interrupt
+ * @arg SDIO_IT_RXDAVL: Data available in receive FIFO interrupt
+ * @arg SDIO_IT_SDIOIT: SD I/O interrupt received interrupt
+ * @arg SDIO_IT_CEATAEND: CE-ATA command completion signal received for CMD61 interrupt
+ * @retval The new state of SDIO_IT (SET or RESET).
+ */
+ITStatus SDIO_GetITStatus(uint32_t SDIO_IT)
+{
+ ITStatus bitstatus = RESET;
+
+ /* Check the parameters */
+ assert_param(IS_SDIO_GET_IT(SDIO_IT));
+ if ((SDIO->STA & SDIO_IT) != (uint32_t)RESET)
+ {
+ bitstatus = SET;
+ }
+ else
+ {
+ bitstatus = RESET;
+ }
+ return bitstatus;
+}
+
+/**
+ * @brief Clears the SDIO's interrupt pending bits.
+ * @param SDIO_IT: specifies the interrupt pending bit to clear.
+ * This parameter can be one or a combination of the following values:
+ * @arg SDIO_IT_CCRCFAIL: Command response received (CRC check failed) interrupt
+ * @arg SDIO_IT_DCRCFAIL: Data block sent/received (CRC check failed) interrupt
+ * @arg SDIO_IT_CTIMEOUT: Command response timeout interrupt
+ * @arg SDIO_IT_DTIMEOUT: Data timeout interrupt
+ * @arg SDIO_IT_TXUNDERR: Transmit FIFO underrun error interrupt
+ * @arg SDIO_IT_RXOVERR: Received FIFO overrun error interrupt
+ * @arg SDIO_IT_CMDREND: Command response received (CRC check passed) interrupt
+ * @arg SDIO_IT_CMDSENT: Command sent (no response required) interrupt
+ * @arg SDIO_IT_DATAEND: Data end (data counter, SDIO_DCOUNT, is zero) interrupt
+ * @arg SDIO_IT_STBITERR: Start bit not detected on all data signals in wide
+ * bus mode interrupt
+ * @arg SDIO_IT_SDIOIT: SD I/O interrupt received interrupt
+ * @arg SDIO_IT_CEATAEND: CE-ATA command completion signal received for CMD61
+ * @retval None
+ */
+void SDIO_ClearITPendingBit(uint32_t SDIO_IT)
+{
+ /* Check the parameters */
+ assert_param(IS_SDIO_CLEAR_IT(SDIO_IT));
+
+ SDIO->ICR = SDIO_IT;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/src/stm32f2xx_spi.c b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/src/stm32f2xx_spi.c
new file mode 100644
index 0000000..fe46ffd
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/src/stm32f2xx_spi.c
@@ -0,0 +1,1183 @@
+/**
+ ******************************************************************************
+ * @file stm32f2xx_spi.c
+ * @author MCD Application Team
+ * @version V1.1.2
+ * @date 05-March-2012
+ * @brief This file provides firmware functions to manage the following
+ * functionalities of the Serial peripheral interface (SPI):
+ * - Initialization and Configuration
+ * - Data transfers functions
+ * - Hardware CRC Calculation
+ * - DMA transfers management
+ * - Interrupts and flags management
+ *
+ * @verbatim
+ *
+ *
+ * ===================================================================
+ * How to use this driver
+ * ===================================================================
+ * 1. Enable peripheral clock using the following functions
+ * RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE) for SPI1
+ * RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE) for SPI2
+ * RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI3, ENABLE) for SPI3.
+ *
+ * 2. Enable SCK, MOSI, MISO and NSS GPIO clocks using RCC_AHB1PeriphClockCmd()
+ * function.
+ * In I2S mode, if an external clock source is used then the I2S CKIN pin GPIO
+ * clock should also be enabled.
+ *
+ * 3. Peripherals alternate function:
+ * - Connect the pin to the desired peripherals' Alternate
+ * Function (AF) using GPIO_PinAFConfig() function
+ * - Configure the desired pin in alternate function by:
+ * GPIO_InitStruct->GPIO_Mode = GPIO_Mode_AF
+ * - Select the type, pull-up/pull-down and output speed via
+ * GPIO_PuPd, GPIO_OType and GPIO_Speed members
+ * - Call GPIO_Init() function
+ * In I2S mode, if an external clock source is used then the I2S CKIN pin
+ * should be also configured in Alternate function Push-pull pull-up mode.
+ *
+ * 4. Program the Polarity, Phase, First Data, Baud Rate Prescaler, Slave
+ * Management, Peripheral Mode and CRC Polynomial values using the SPI_Init()
+ * function.
+ * In I2S mode, program the Mode, Standard, Data Format, MCLK Output, Audio
+ * frequency and Polarity using I2S_Init() function.
+ * For I2S mode, make sure that either:
+ * - I2S PLL is configured using the functions RCC_I2SCLKConfig(RCC_I2S2CLKSource_PLLI2S),
+ * RCC_PLLI2SCmd(ENABLE) and RCC_GetFlagStatus(RCC_FLAG_PLLI2SRDY).
+ * or
+ * - External clock source is configured using the function
+ * RCC_I2SCLKConfig(RCC_I2S2CLKSource_Ext) and after setting correctly the define constant
+ * I2S_EXTERNAL_CLOCK_VAL in the stm32f2xx_conf.h file.
+ *
+ * 5. Enable the NVIC and the corresponding interrupt using the function
+ * SPI_ITConfig() if you need to use interrupt mode.
+ *
+ * 6. When using the DMA mode
+ * - Configure the DMA using DMA_Init() function
+ * - Active the needed channel Request using SPI_I2S_DMACmd() function
+ *
+ * 7. Enable the SPI using the SPI_Cmd() function or enable the I2S using
+ * I2S_Cmd().
+ *
+ * 8. Enable the DMA using the DMA_Cmd() function when using DMA mode.
+ *
+ * 9. Optionally, you can enable/configure the following parameters without
+ * re-initialization (i.e there is no need to call again SPI_Init() function):
+ * - When bidirectional mode (SPI_Direction_1Line_Rx or SPI_Direction_1Line_Tx)
+ * is programmed as Data direction parameter using the SPI_Init() function
+ * it can be possible to switch between SPI_Direction_Tx or SPI_Direction_Rx
+ * using the SPI_BiDirectionalLineConfig() function.
+ * - When SPI_NSS_Soft is selected as Slave Select Management parameter
+ * using the SPI_Init() function it can be possible to manage the
+ * NSS internal signal using the SPI_NSSInternalSoftwareConfig() function.
+ * - Reconfigure the data size using the SPI_DataSizeConfig() function
+ * - Enable or disable the SS output using the SPI_SSOutputCmd() function
+ *
+ * 10. To use the CRC Hardware calculation feature refer to the Peripheral
+ * CRC hardware Calculation subsection.
+ *
+ *
+ * @note This driver supports only the I2S clock scheme available in Silicon
+ * RevisionB and RevisionY.
+ *
+ * @note In I2S mode: if an external clock is used as source clock for the I2S,
+ * then the define I2S_EXTERNAL_CLOCK_VAL in file stm32f2xx_conf.h should
+ * be enabled and set to the value of the source clock frequency (in Hz).
+ *
+ * @note In SPI mode: To use the SPI TI mode, call the function SPI_TIModeCmd()
+ * just after calling the function SPI_Init().
+ *
+ * @endverbatim
+ *
+ ******************************************************************************
+ * @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 "stm32f2xx_spi.h"
+#include "stm32f2xx_rcc.h"
+
+/** @addtogroup STM32F2xx_StdPeriph_Driver
+ * @{
+ */
+
+/** @defgroup SPI
+ * @brief SPI driver modules
+ * @{
+ */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+
+/* SPI registers Masks */
+#define CR1_CLEAR_MASK ((uint16_t)0x3040)
+#define I2SCFGR_CLEAR_MASK ((uint16_t)0xF040)
+
+/* RCC PLLs masks */
+#define PLLCFGR_PPLR_MASK ((uint32_t)0x70000000)
+#define PLLCFGR_PPLN_MASK ((uint32_t)0x00007FC0)
+
+#define SPI_CR2_FRF ((uint16_t)0x0010)
+#define SPI_SR_TIFRFE ((uint16_t)0x0100)
+
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+/** @defgroup SPI_Private_Functions
+ * @{
+ */
+
+/** @defgroup SPI_Group1 Initialization and Configuration functions
+ * @brief Initialization and Configuration functions
+ *
+@verbatim
+ ===============================================================================
+ Initialization and Configuration functions
+ ===============================================================================
+
+ This section provides a set of functions allowing to initialize the SPI Direction,
+ SPI Mode, SPI Data Size, SPI Polarity, SPI Phase, SPI NSS Management, SPI Baud
+ Rate Prescaler, SPI First Bit and SPI CRC Polynomial.
+
+ The SPI_Init() function follows the SPI configuration procedures for Master mode
+ and Slave mode (details for these procedures are available in reference manual
+ (RM0033)).
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Deinitialize the SPIx peripheral registers to their default reset values.
+ * @param SPIx: To select the SPIx/I2Sx peripheral, where x can be: 1, 2 or 3
+ * in SPI mode or 2 or 3 in I2S mode.
+ * @retval None
+ */
+void SPI_I2S_DeInit(SPI_TypeDef* SPIx)
+{
+ /* Check the parameters */
+ assert_param(IS_SPI_ALL_PERIPH(SPIx));
+
+ if (SPIx == SPI1)
+ {
+ /* Enable SPI1 reset state */
+ RCC_APB2PeriphResetCmd(RCC_APB2Periph_SPI1, ENABLE);
+ /* Release SPI1 from reset state */
+ RCC_APB2PeriphResetCmd(RCC_APB2Periph_SPI1, DISABLE);
+ }
+ else if (SPIx == SPI2)
+ {
+ /* Enable SPI2 reset state */
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI2, ENABLE);
+ /* Release SPI2 from reset state */
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI2, DISABLE);
+ }
+ else
+ {
+ if (SPIx == SPI3)
+ {
+ /* Enable SPI3 reset state */
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI3, ENABLE);
+ /* Release SPI3 from reset state */
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI3, DISABLE);
+ }
+ }
+}
+
+/**
+ * @brief Initializes the SPIx peripheral according to the specified
+ * parameters in the SPI_InitStruct.
+ * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
+ * @param SPI_InitStruct: pointer to a SPI_InitTypeDef structure that
+ * contains the configuration information for the specified SPI peripheral.
+ * @retval None
+ */
+void SPI_Init(SPI_TypeDef* SPIx, SPI_InitTypeDef* SPI_InitStruct)
+{
+ uint16_t tmpreg = 0;
+
+ /* check the parameters */
+ assert_param(IS_SPI_ALL_PERIPH(SPIx));
+
+ /* Check the SPI parameters */
+ assert_param(IS_SPI_DIRECTION_MODE(SPI_InitStruct->SPI_Direction));
+ assert_param(IS_SPI_MODE(SPI_InitStruct->SPI_Mode));
+ assert_param(IS_SPI_DATASIZE(SPI_InitStruct->SPI_DataSize));
+ assert_param(IS_SPI_CPOL(SPI_InitStruct->SPI_CPOL));
+ assert_param(IS_SPI_CPHA(SPI_InitStruct->SPI_CPHA));
+ assert_param(IS_SPI_NSS(SPI_InitStruct->SPI_NSS));
+ assert_param(IS_SPI_BAUDRATE_PRESCALER(SPI_InitStruct->SPI_BaudRatePrescaler));
+ assert_param(IS_SPI_FIRST_BIT(SPI_InitStruct->SPI_FirstBit));
+ assert_param(IS_SPI_CRC_POLYNOMIAL(SPI_InitStruct->SPI_CRCPolynomial));
+
+/*---------------------------- SPIx CR1 Configuration ------------------------*/
+ /* Get the SPIx CR1 value */
+ tmpreg = SPIx->CR1;
+ /* Clear BIDIMode, BIDIOE, RxONLY, SSM, SSI, LSBFirst, BR, MSTR, CPOL and CPHA bits */
+ tmpreg &= CR1_CLEAR_MASK;
+ /* Configure SPIx: direction, NSS management, first transmitted bit, BaudRate prescaler
+ master/salve mode, CPOL and CPHA */
+ /* Set BIDImode, BIDIOE and RxONLY bits according to SPI_Direction value */
+ /* Set SSM, SSI and MSTR bits according to SPI_Mode and SPI_NSS values */
+ /* Set LSBFirst bit according to SPI_FirstBit value */
+ /* Set BR bits according to SPI_BaudRatePrescaler value */
+ /* Set CPOL bit according to SPI_CPOL value */
+ /* Set CPHA bit according to SPI_CPHA value */
+ tmpreg |= (uint16_t)((uint32_t)SPI_InitStruct->SPI_Direction | SPI_InitStruct->SPI_Mode |
+ SPI_InitStruct->SPI_DataSize | SPI_InitStruct->SPI_CPOL |
+ SPI_InitStruct->SPI_CPHA | SPI_InitStruct->SPI_NSS |
+ SPI_InitStruct->SPI_BaudRatePrescaler | SPI_InitStruct->SPI_FirstBit);
+ /* Write to SPIx CR1 */
+ SPIx->CR1 = tmpreg;
+
+ /* Activate the SPI mode (Reset I2SMOD bit in I2SCFGR register) */
+ SPIx->I2SCFGR &= (uint16_t)~((uint16_t)SPI_I2SCFGR_I2SMOD);
+/*---------------------------- SPIx CRCPOLY Configuration --------------------*/
+ /* Write to SPIx CRCPOLY */
+ SPIx->CRCPR = SPI_InitStruct->SPI_CRCPolynomial;
+}
+
+/**
+ * @brief Initializes the SPIx peripheral according to the specified
+ * parameters in the I2S_InitStruct.
+ * @param SPIx: where x can be 2 or 3 to select the SPI peripheral (configured in I2S mode).
+ * @param I2S_InitStruct: pointer to an I2S_InitTypeDef structure that
+ * contains the configuration information for the specified SPI peripheral
+ * configured in I2S mode.
+ *
+ * @note The function calculates the optimal prescaler needed to obtain the most
+ * accurate audio frequency (depending on the I2S clock source, the PLL values
+ * and the product configuration). But in case the prescaler value is greater
+ * than 511, the default value (0x02) will be configured instead.
+ *
+ * @note if an external clock is used as source clock for the I2S, then the define
+ * I2S_EXTERNAL_CLOCK_VAL in file stm32f2xx_conf.h should be enabled and set
+ * to the value of the the source clock frequency (in Hz).
+ *
+ * @retval None
+ */
+void I2S_Init(SPI_TypeDef* SPIx, I2S_InitTypeDef* I2S_InitStruct)
+{
+ uint16_t tmpreg = 0, i2sdiv = 2, i2sodd = 0, packetlength = 1;
+ uint32_t tmp = 0, i2sclk = 0;
+#ifndef I2S_EXTERNAL_CLOCK_VAL
+ uint32_t pllm = 0, plln = 0, pllr = 0;
+#endif /* I2S_EXTERNAL_CLOCK_VAL */
+
+ /* Check the I2S parameters */
+ assert_param(IS_SPI_23_PERIPH(SPIx));
+ assert_param(IS_I2S_MODE(I2S_InitStruct->I2S_Mode));
+ assert_param(IS_I2S_STANDARD(I2S_InitStruct->I2S_Standard));
+ assert_param(IS_I2S_DATA_FORMAT(I2S_InitStruct->I2S_DataFormat));
+ assert_param(IS_I2S_MCLK_OUTPUT(I2S_InitStruct->I2S_MCLKOutput));
+ assert_param(IS_I2S_AUDIO_FREQ(I2S_InitStruct->I2S_AudioFreq));
+ assert_param(IS_I2S_CPOL(I2S_InitStruct->I2S_CPOL));
+
+/*----------------------- SPIx I2SCFGR & I2SPR Configuration -----------------*/
+ /* Clear I2SMOD, I2SE, I2SCFG, PCMSYNC, I2SSTD, CKPOL, DATLEN and CHLEN bits */
+ SPIx->I2SCFGR &= I2SCFGR_CLEAR_MASK;
+ SPIx->I2SPR = 0x0002;
+
+ /* Get the I2SCFGR register value */
+ tmpreg = SPIx->I2SCFGR;
+
+ /* If the default value has to be written, reinitialize i2sdiv and i2sodd*/
+ if(I2S_InitStruct->I2S_AudioFreq == I2S_AudioFreq_Default)
+ {
+ i2sodd = (uint16_t)0;
+ i2sdiv = (uint16_t)2;
+ }
+ /* If the requested audio frequency is not the default, compute the prescaler */
+ else
+ {
+ /* Check the frame length (For the Prescaler computing) *******************/
+ if(I2S_InitStruct->I2S_DataFormat == I2S_DataFormat_16b)
+ {
+ /* Packet length is 16 bits */
+ packetlength = 1;
+ }
+ else
+ {
+ /* Packet length is 32 bits */
+ packetlength = 2;
+ }
+
+ /* Get I2S source Clock frequency (only in Silicon RevisionB and RevisionY) */
+
+ /* If an external I2S clock has to be used, this define should be set
+ in the project configuration or in the stm32f2xx_conf.h file */
+ #ifdef I2S_EXTERNAL_CLOCK_VAL
+ /* Set external clock as I2S clock source */
+ if ((RCC->CFGR & RCC_CFGR_I2SSRC) == 0)
+ {
+ RCC->CFGR |= (uint32_t)RCC_CFGR_I2SSRC;
+ }
+
+ /* Set the I2S clock to the external clock value */
+ i2sclk = I2S_EXTERNAL_CLOCK_VAL;
+
+ #else /* There is no define for External I2S clock source */
+ /* Set PLLI2S as I2S clock source */
+ if ((RCC->CFGR & RCC_CFGR_I2SSRC) != 0)
+ {
+ RCC->CFGR &= ~(uint32_t)RCC_CFGR_I2SSRC;
+ }
+
+ /* Get the PLLI2SN value */
+ plln = (uint32_t)(((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> 6) & \
+ (RCC_PLLI2SCFGR_PLLI2SN >> 6));
+
+ /* Get the PLLI2SR value */
+ pllr = (uint32_t)(((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> 28) & \
+ (RCC_PLLI2SCFGR_PLLI2SR >> 28));
+
+ /* Get the PLLM value */
+ pllm = (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM);
+
+ /* Get the I2S source clock value */
+ i2sclk = (uint32_t)(((HSE_VALUE / pllm) * plln) / pllr);
+ #endif /* I2S_EXTERNAL_CLOCK_VAL */
+
+ /* Compute the Real divider depending on the MCLK output state, with a floating point */
+ if(I2S_InitStruct->I2S_MCLKOutput == I2S_MCLKOutput_Enable)
+ {
+ /* MCLK output is enabled */
+ tmp = (uint16_t)(((((i2sclk / 256) * 10) / I2S_InitStruct->I2S_AudioFreq)) + 5);
+ }
+ else
+ {
+ /* MCLK output is disabled */
+ tmp = (uint16_t)(((((i2sclk / (32 * packetlength)) *10 ) / I2S_InitStruct->I2S_AudioFreq)) + 5);
+ }
+
+ /* Remove the flatting point */
+ tmp = tmp / 10;
+
+ /* Check the parity of the divider */
+ i2sodd = (uint16_t)(tmp & (uint16_t)0x0001);
+
+ /* Compute the i2sdiv prescaler */
+ i2sdiv = (uint16_t)((tmp - i2sodd) / 2);
+
+ /* Get the Mask for the Odd bit (SPI_I2SPR[8]) register */
+ i2sodd = (uint16_t) (i2sodd << 8);
+ }
+
+ /* Test if the divider is 1 or 0 or greater than 0xFF */
+ if ((i2sdiv < 2) || (i2sdiv > 0xFF))
+ {
+ /* Set the default values */
+ i2sdiv = 2;
+ i2sodd = 0;
+ }
+
+ /* Write to SPIx I2SPR register the computed value */
+ SPIx->I2SPR = (uint16_t)((uint16_t)i2sdiv | (uint16_t)(i2sodd | (uint16_t)I2S_InitStruct->I2S_MCLKOutput));
+
+ /* Configure the I2S with the SPI_InitStruct values */
+ tmpreg |= (uint16_t)((uint16_t)SPI_I2SCFGR_I2SMOD | (uint16_t)(I2S_InitStruct->I2S_Mode | \
+ (uint16_t)(I2S_InitStruct->I2S_Standard | (uint16_t)(I2S_InitStruct->I2S_DataFormat | \
+ (uint16_t)I2S_InitStruct->I2S_CPOL))));
+
+ /* Write to SPIx I2SCFGR */
+ SPIx->I2SCFGR = tmpreg;
+}
+
+/**
+ * @brief Fills each SPI_InitStruct member with its default value.
+ * @param SPI_InitStruct: pointer to a SPI_InitTypeDef structure which will be initialized.
+ * @retval None
+ */
+void SPI_StructInit(SPI_InitTypeDef* SPI_InitStruct)
+{
+/*--------------- Reset SPI init structure parameters values -----------------*/
+ /* Initialize the SPI_Direction member */
+ SPI_InitStruct->SPI_Direction = SPI_Direction_2Lines_FullDuplex;
+ /* initialize the SPI_Mode member */
+ SPI_InitStruct->SPI_Mode = SPI_Mode_Slave;
+ /* initialize the SPI_DataSize member */
+ SPI_InitStruct->SPI_DataSize = SPI_DataSize_8b;
+ /* Initialize the SPI_CPOL member */
+ SPI_InitStruct->SPI_CPOL = SPI_CPOL_Low;
+ /* Initialize the SPI_CPHA member */
+ SPI_InitStruct->SPI_CPHA = SPI_CPHA_1Edge;
+ /* Initialize the SPI_NSS member */
+ SPI_InitStruct->SPI_NSS = SPI_NSS_Hard;
+ /* Initialize the SPI_BaudRatePrescaler member */
+ SPI_InitStruct->SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;
+ /* Initialize the SPI_FirstBit member */
+ SPI_InitStruct->SPI_FirstBit = SPI_FirstBit_MSB;
+ /* Initialize the SPI_CRCPolynomial member */
+ SPI_InitStruct->SPI_CRCPolynomial = 7;
+}
+
+/**
+ * @brief Fills each I2S_InitStruct member with its default value.
+ * @param I2S_InitStruct: pointer to a I2S_InitTypeDef structure which will be initialized.
+ * @retval None
+ */
+void I2S_StructInit(I2S_InitTypeDef* I2S_InitStruct)
+{
+/*--------------- Reset I2S init structure parameters values -----------------*/
+ /* Initialize the I2S_Mode member */
+ I2S_InitStruct->I2S_Mode = I2S_Mode_SlaveTx;
+
+ /* Initialize the I2S_Standard member */
+ I2S_InitStruct->I2S_Standard = I2S_Standard_Phillips;
+
+ /* Initialize the I2S_DataFormat member */
+ I2S_InitStruct->I2S_DataFormat = I2S_DataFormat_16b;
+
+ /* Initialize the I2S_MCLKOutput member */
+ I2S_InitStruct->I2S_MCLKOutput = I2S_MCLKOutput_Disable;
+
+ /* Initialize the I2S_AudioFreq member */
+ I2S_InitStruct->I2S_AudioFreq = I2S_AudioFreq_Default;
+
+ /* Initialize the I2S_CPOL member */
+ I2S_InitStruct->I2S_CPOL = I2S_CPOL_Low;
+}
+
+/**
+ * @brief Enables or disables the specified SPI peripheral.
+ * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
+ * @param NewState: new state of the SPIx peripheral.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void SPI_Cmd(SPI_TypeDef* SPIx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_SPI_ALL_PERIPH(SPIx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ if (NewState != DISABLE)
+ {
+ /* Enable the selected SPI peripheral */
+ SPIx->CR1 |= SPI_CR1_SPE;
+ }
+ else
+ {
+ /* Disable the selected SPI peripheral */
+ SPIx->CR1 &= (uint16_t)~((uint16_t)SPI_CR1_SPE);
+ }
+}
+
+/**
+ * @brief Enables or disables the specified SPI peripheral (in I2S mode).
+ * @param SPIx: where x can be 2 or 3 to select the SPI peripheral.
+ * @param NewState: new state of the SPIx peripheral.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void I2S_Cmd(SPI_TypeDef* SPIx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_SPI_23_PERIPH(SPIx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the selected SPI peripheral (in I2S mode) */
+ SPIx->I2SCFGR |= SPI_I2SCFGR_I2SE;
+ }
+ else
+ {
+ /* Disable the selected SPI peripheral in I2S mode */
+ SPIx->I2SCFGR &= (uint16_t)~((uint16_t)SPI_I2SCFGR_I2SE);
+ }
+}
+
+/**
+ * @brief Configures the data size for the selected SPI.
+ * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
+ * @param SPI_DataSize: specifies the SPI data size.
+ * This parameter can be one of the following values:
+ * @arg SPI_DataSize_16b: Set data frame format to 16bit
+ * @arg SPI_DataSize_8b: Set data frame format to 8bit
+ * @retval None
+ */
+void SPI_DataSizeConfig(SPI_TypeDef* SPIx, uint16_t SPI_DataSize)
+{
+ /* Check the parameters */
+ assert_param(IS_SPI_ALL_PERIPH(SPIx));
+ assert_param(IS_SPI_DATASIZE(SPI_DataSize));
+ /* Clear DFF bit */
+ SPIx->CR1 &= (uint16_t)~SPI_DataSize_16b;
+ /* Set new DFF bit value */
+ SPIx->CR1 |= SPI_DataSize;
+}
+
+/**
+ * @brief Selects the data transfer direction in bidirectional mode for the specified SPI.
+ * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
+ * @param SPI_Direction: specifies the data transfer direction in bidirectional mode.
+ * This parameter can be one of the following values:
+ * @arg SPI_Direction_Tx: Selects Tx transmission direction
+ * @arg SPI_Direction_Rx: Selects Rx receive direction
+ * @retval None
+ */
+void SPI_BiDirectionalLineConfig(SPI_TypeDef* SPIx, uint16_t SPI_Direction)
+{
+ /* Check the parameters */
+ assert_param(IS_SPI_ALL_PERIPH(SPIx));
+ assert_param(IS_SPI_DIRECTION(SPI_Direction));
+ if (SPI_Direction == SPI_Direction_Tx)
+ {
+ /* Set the Tx only mode */
+ SPIx->CR1 |= SPI_Direction_Tx;
+ }
+ else
+ {
+ /* Set the Rx only mode */
+ SPIx->CR1 &= SPI_Direction_Rx;
+ }
+}
+
+/**
+ * @brief Configures internally by software the NSS pin for the selected SPI.
+ * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
+ * @param SPI_NSSInternalSoft: specifies the SPI NSS internal state.
+ * This parameter can be one of the following values:
+ * @arg SPI_NSSInternalSoft_Set: Set NSS pin internally
+ * @arg SPI_NSSInternalSoft_Reset: Reset NSS pin internally
+ * @retval None
+ */
+void SPI_NSSInternalSoftwareConfig(SPI_TypeDef* SPIx, uint16_t SPI_NSSInternalSoft)
+{
+ /* Check the parameters */
+ assert_param(IS_SPI_ALL_PERIPH(SPIx));
+ assert_param(IS_SPI_NSS_INTERNAL(SPI_NSSInternalSoft));
+ if (SPI_NSSInternalSoft != SPI_NSSInternalSoft_Reset)
+ {
+ /* Set NSS pin internally by software */
+ SPIx->CR1 |= SPI_NSSInternalSoft_Set;
+ }
+ else
+ {
+ /* Reset NSS pin internally by software */
+ SPIx->CR1 &= SPI_NSSInternalSoft_Reset;
+ }
+}
+
+/**
+ * @brief Enables or disables the SS output for the selected SPI.
+ * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
+ * @param NewState: new state of the SPIx SS output.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void SPI_SSOutputCmd(SPI_TypeDef* SPIx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_SPI_ALL_PERIPH(SPIx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ if (NewState != DISABLE)
+ {
+ /* Enable the selected SPI SS output */
+ SPIx->CR2 |= (uint16_t)SPI_CR2_SSOE;
+ }
+ else
+ {
+ /* Disable the selected SPI SS output */
+ SPIx->CR2 &= (uint16_t)~((uint16_t)SPI_CR2_SSOE);
+ }
+}
+
+/**
+ * @brief Enables or disables the SPIx/I2Sx DMA interface.
+ *
+ * @note This function can be called only after the SPI_Init() function has
+ * been called.
+ * @note When TI mode is selected, the control bits SSM, SSI, CPOL and CPHA
+ * are not taken into consideration and are configured by hardware
+ * respectively to the TI mode requirements.
+ *
+ * @param SPIx: where x can be 1, 2 or 3
+ * @param NewState: new state of the selected SPI TI communication mode.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void SPI_TIModeCmd(SPI_TypeDef* SPIx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_SPI_ALL_PERIPH(SPIx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the TI mode for the selected SPI peripheral */
+ SPIx->CR2 |= SPI_CR2_FRF;
+ }
+ else
+ {
+ /* Disable the TI mode for the selected SPI peripheral */
+ SPIx->CR2 &= (uint16_t)~SPI_CR2_FRF;
+ }
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup SPI_Group2 Data transfers functions
+ * @brief Data transfers functions
+ *
+@verbatim
+ ===============================================================================
+ Data transfers functions
+ ===============================================================================
+
+ This section provides a set of functions allowing to manage the SPI data transfers
+
+ In reception, data are received and then stored into an internal Rx buffer while
+ In transmission, data are first stored into an internal Tx buffer before being
+ transmitted.
+
+ The read access of the SPI_DR register can be done using the SPI_I2S_ReceiveData()
+ function and returns the Rx buffered value. Whereas a write access to the SPI_DR
+ can be done using SPI_I2S_SendData() function and stores the written data into
+ Tx buffer.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Returns the most recent received data by the SPIx/I2Sx peripheral.
+ * @param SPIx: To select the SPIx/I2Sx peripheral, where x can be: 1, 2 or 3
+ * in SPI mode or 2 or 3 in I2S mode.
+ * @retval The value of the received data.
+ */
+uint16_t SPI_I2S_ReceiveData(SPI_TypeDef* SPIx)
+{
+ /* Check the parameters */
+ assert_param(IS_SPI_ALL_PERIPH(SPIx));
+
+ /* Return the data in the DR register */
+ return SPIx->DR;
+}
+
+/**
+ * @brief Transmits a Data through the SPIx/I2Sx peripheral.
+ * @param SPIx: To select the SPIx/I2Sx peripheral, where x can be: 1, 2 or 3
+ * in SPI mode or 2 or 3 in I2S mode.
+ * @param Data: Data to be transmitted.
+ * @retval None
+ */
+void SPI_I2S_SendData(SPI_TypeDef* SPIx, uint16_t Data)
+{
+ /* Check the parameters */
+ assert_param(IS_SPI_ALL_PERIPH(SPIx));
+
+ /* Write in the DR register the data to be sent */
+ SPIx->DR = Data;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup SPI_Group3 Hardware CRC Calculation functions
+ * @brief Hardware CRC Calculation functions
+ *
+@verbatim
+ ===============================================================================
+ Hardware CRC Calculation functions
+ ===============================================================================
+
+ This section provides a set of functions allowing to manage the SPI CRC hardware
+ calculation
+
+ SPI communication using CRC is possible through the following procedure:
+ 1. Program the Data direction, Polarity, Phase, First Data, Baud Rate Prescaler,
+ Slave Management, Peripheral Mode and CRC Polynomial values using the SPI_Init()
+ function.
+ 2. Enable the CRC calculation using the SPI_CalculateCRC() function.
+ 3. Enable the SPI using the SPI_Cmd() function
+ 4. Before writing the last data to the TX buffer, set the CRCNext bit using the
+ SPI_TransmitCRC() function to indicate that after transmission of the last
+ data, the CRC should be transmitted.
+ 5. After transmitting the last data, the SPI transmits the CRC. The SPI_CR1_CRCNEXT
+ bit is reset. The CRC is also received and compared against the SPI_RXCRCR
+ value.
+ If the value does not match, the SPI_FLAG_CRCERR flag is set and an interrupt
+ can be generated when the SPI_I2S_IT_ERR interrupt is enabled.
+
+@note It is advised not to read the calculated CRC values during the communication.
+
+@note When the SPI is in slave mode, be careful to enable CRC calculation only
+ when the clock is stable, that is, when the clock is in the steady state.
+ If not, a wrong CRC calculation may be done. In fact, the CRC is sensitive
+ to the SCK slave input clock as soon as CRCEN is set, and this, whatever
+ the value of the SPE bit.
+
+@note With high bitrate frequencies, be careful when transmitting the CRC.
+ As the number of used CPU cycles has to be as low as possible in the CRC
+ transfer phase, it is forbidden to call software functions in the CRC
+ transmission sequence to avoid errors in the last data and CRC reception.
+ In fact, CRCNEXT bit has to be written before the end of the transmission/reception
+ of the last data.
+
+@note For high bit rate frequencies, it is advised to use the DMA mode to avoid the
+ degradation of the SPI speed performance due to CPU accesses impacting the
+ SPI bandwidth.
+
+@note When the STM32F2xx is configured as slave and the NSS hardware mode is
+ used, the NSS pin needs to be kept low between the data phase and the CRC
+ phase.
+
+@note When the SPI is configured in slave mode with the CRC feature enabled, CRC
+ calculation takes place even if a high level is applied on the NSS pin.
+ This may happen for example in case of a multi-slave environment where the
+ communication master addresses slaves alternately.
+
+@note Between a slave de-selection (high level on NSS) and a new slave selection
+ (low level on NSS), the CRC value should be cleared on both master and slave
+ sides in order to resynchronize the master and slave for their respective
+ CRC calculation.
+
+@note To clear the CRC, follow the procedure below:
+ 1. Disable SPI using the SPI_Cmd() function
+ 2. Disable the CRC calculation using the SPI_CalculateCRC() function.
+ 3. Enable the CRC calculation using the SPI_CalculateCRC() function.
+ 4. Enable SPI using the SPI_Cmd() function.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Enables or disables the CRC value calculation of the transferred bytes.
+ * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
+ * @param NewState: new state of the SPIx CRC value calculation.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void SPI_CalculateCRC(SPI_TypeDef* SPIx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_SPI_ALL_PERIPH(SPIx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ if (NewState != DISABLE)
+ {
+ /* Enable the selected SPI CRC calculation */
+ SPIx->CR1 |= SPI_CR1_CRCEN;
+ }
+ else
+ {
+ /* Disable the selected SPI CRC calculation */
+ SPIx->CR1 &= (uint16_t)~((uint16_t)SPI_CR1_CRCEN);
+ }
+}
+
+/**
+ * @brief Transmit the SPIx CRC value.
+ * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
+ * @retval None
+ */
+void SPI_TransmitCRC(SPI_TypeDef* SPIx)
+{
+ /* Check the parameters */
+ assert_param(IS_SPI_ALL_PERIPH(SPIx));
+
+ /* Enable the selected SPI CRC transmission */
+ SPIx->CR1 |= SPI_CR1_CRCNEXT;
+}
+
+/**
+ * @brief Returns the transmit or the receive CRC register value for the specified SPI.
+ * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
+ * @param SPI_CRC: specifies the CRC register to be read.
+ * This parameter can be one of the following values:
+ * @arg SPI_CRC_Tx: Selects Tx CRC register
+ * @arg SPI_CRC_Rx: Selects Rx CRC register
+ * @retval The selected CRC register value..
+ */
+uint16_t SPI_GetCRC(SPI_TypeDef* SPIx, uint8_t SPI_CRC)
+{
+ uint16_t crcreg = 0;
+ /* Check the parameters */
+ assert_param(IS_SPI_ALL_PERIPH(SPIx));
+ assert_param(IS_SPI_CRC(SPI_CRC));
+ if (SPI_CRC != SPI_CRC_Rx)
+ {
+ /* Get the Tx CRC register */
+ crcreg = SPIx->TXCRCR;
+ }
+ else
+ {
+ /* Get the Rx CRC register */
+ crcreg = SPIx->RXCRCR;
+ }
+ /* Return the selected CRC register */
+ return crcreg;
+}
+
+/**
+ * @brief Returns the CRC Polynomial register value for the specified SPI.
+ * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
+ * @retval The CRC Polynomial register value.
+ */
+uint16_t SPI_GetCRCPolynomial(SPI_TypeDef* SPIx)
+{
+ /* Check the parameters */
+ assert_param(IS_SPI_ALL_PERIPH(SPIx));
+
+ /* Return the CRC polynomial register */
+ return SPIx->CRCPR;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup SPI_Group4 DMA transfers management functions
+ * @brief DMA transfers management functions
+ *
+@verbatim
+ ===============================================================================
+ DMA transfers management functions
+ ===============================================================================
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Enables or disables the SPIx/I2Sx DMA interface.
+ * @param SPIx: To select the SPIx/I2Sx peripheral, where x can be: 1, 2 or 3
+ * in SPI mode or 2 or 3 in I2S mode.
+ * @param SPI_I2S_DMAReq: specifies the SPI DMA transfer request to be enabled or disabled.
+ * This parameter can be any combination of the following values:
+ * @arg SPI_I2S_DMAReq_Tx: Tx buffer DMA transfer request
+ * @arg SPI_I2S_DMAReq_Rx: Rx buffer DMA transfer request
+ * @param NewState: new state of the selected SPI DMA transfer request.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void SPI_I2S_DMACmd(SPI_TypeDef* SPIx, uint16_t SPI_I2S_DMAReq, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_SPI_ALL_PERIPH(SPIx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ assert_param(IS_SPI_I2S_DMAREQ(SPI_I2S_DMAReq));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the selected SPI DMA requests */
+ SPIx->CR2 |= SPI_I2S_DMAReq;
+ }
+ else
+ {
+ /* Disable the selected SPI DMA requests */
+ SPIx->CR2 &= (uint16_t)~SPI_I2S_DMAReq;
+ }
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup SPI_Group5 Interrupts and flags management functions
+ * @brief Interrupts and flags management functions
+ *
+@verbatim
+ ===============================================================================
+ Interrupts and flags management functions
+ ===============================================================================
+
+ This section provides a set of functions allowing to configure the SPI Interrupts
+ sources and check or clear the flags or pending bits status.
+ The user should identify which mode will be used in his application to manage
+ the communication: Polling mode, Interrupt mode or DMA mode.
+
+ Polling Mode
+ =============
+ In Polling Mode, the SPI/I2S communication can be managed by 9 flags:
+ 1. SPI_I2S_FLAG_TXE : to indicate the status of the transmit buffer register
+ 2. SPI_I2S_FLAG_RXNE : to indicate the status of the receive buffer register
+ 3. SPI_I2S_FLAG_BSY : to indicate the state of the communication layer of the SPI.
+ 4. SPI_FLAG_CRCERR : to indicate if a CRC Calculation error occur
+ 5. SPI_FLAG_MODF : to indicate if a Mode Fault error occur
+ 6. SPI_I2S_FLAG_OVR : to indicate if an Overrun error occur
+ 7. I2S_FLAG_TIFRFE: to indicate a Frame Format error occurs.
+ 8. I2S_FLAG_UDR: to indicate an Underrun error occurs.
+ 9. I2S_FLAG_CHSIDE: to indicate Channel Side.
+
+@note Do not use the BSY flag to handle each data transmission or reception. It is
+ better to use the TXE and RXNE flags instead.
+
+ In this Mode it is advised to use the following functions:
+ - FlagStatus SPI_I2S_GetFlagStatus(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG);
+ - void SPI_I2S_ClearFlag(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG);
+
+ Interrupt Mode
+ ===============
+ In Interrupt Mode, the SPI communication can be managed by 3 interrupt sources
+ and 7 pending bits:
+ Pending Bits:
+ -------------
+ 1. SPI_I2S_IT_TXE : to indicate the status of the transmit buffer register
+ 2. SPI_I2S_IT_RXNE : to indicate the status of the receive buffer register
+ 3. SPI_IT_CRCERR : to indicate if a CRC Calculation error occur (available in SPI mode only)
+ 4. SPI_IT_MODF : to indicate if a Mode Fault error occur (available in SPI mode only)
+ 5. SPI_I2S_IT_OVR : to indicate if an Overrun error occur
+ 6. I2S_IT_UDR : to indicate an Underrun Error occurs (available in I2S mode only).
+ 7. I2S_FLAG_TIFRFE : to indicate a Frame Format error occurs (available in TI mode only).
+
+ Interrupt Source:
+ -----------------
+ 1. SPI_I2S_IT_TXE: specifies the interrupt source for the Tx buffer empty
+ interrupt.
+ 2. SPI_I2S_IT_RXNE : specifies the interrupt source for the Rx buffer not
+ empty interrupt.
+ 3. SPI_I2S_IT_ERR : specifies the interrupt source for the errors interrupt.
+
+ In this Mode it is advised to use the following functions:
+ - void SPI_I2S_ITConfig(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT, FunctionalState NewState);
+ - ITStatus SPI_I2S_GetITStatus(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT);
+ - void SPI_I2S_ClearITPendingBit(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT);
+
+ DMA Mode
+ ========
+ In DMA Mode, the SPI communication can be managed by 2 DMA Channel requests:
+ 1. SPI_I2S_DMAReq_Tx: specifies the Tx buffer DMA transfer request
+ 2. SPI_I2S_DMAReq_Rx: specifies the Rx buffer DMA transfer request
+
+ In this Mode it is advised to use the following function:
+ - void SPI_I2S_DMACmd(SPI_TypeDef* SPIx, uint16_t SPI_I2S_DMAReq, FunctionalState NewState);
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Enables or disables the specified SPI/I2S interrupts.
+ * @param SPIx: To select the SPIx/I2Sx peripheral, where x can be: 1, 2 or 3
+ * in SPI mode or 2 or 3 in I2S mode.
+ * @param SPI_I2S_IT: specifies the SPI interrupt source to be enabled or disabled.
+ * This parameter can be one of the following values:
+ * @arg SPI_I2S_IT_TXE: Tx buffer empty interrupt mask
+ * @arg SPI_I2S_IT_RXNE: Rx buffer not empty interrupt mask
+ * @arg SPI_I2S_IT_ERR: Error interrupt mask
+ * @param NewState: new state of the specified SPI interrupt.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void SPI_I2S_ITConfig(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT, FunctionalState NewState)
+{
+ uint16_t itpos = 0, itmask = 0 ;
+
+ /* Check the parameters */
+ assert_param(IS_SPI_ALL_PERIPH(SPIx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ assert_param(IS_SPI_I2S_CONFIG_IT(SPI_I2S_IT));
+
+ /* Get the SPI IT index */
+ itpos = SPI_I2S_IT >> 4;
+
+ /* Set the IT mask */
+ itmask = (uint16_t)1 << (uint16_t)itpos;
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the selected SPI interrupt */
+ SPIx->CR2 |= itmask;
+ }
+ else
+ {
+ /* Disable the selected SPI interrupt */
+ SPIx->CR2 &= (uint16_t)~itmask;
+ }
+}
+
+/**
+ * @brief Checks whether the specified SPIx/I2Sx flag is set or not.
+ * @param SPIx: To select the SPIx/I2Sx peripheral, where x can be: 1, 2 or 3
+ * in SPI mode or 2 or 3 in I2S mode.
+ * @param SPI_I2S_FLAG: specifies the SPI flag to check.
+ * This parameter can be one of the following values:
+ * @arg SPI_I2S_FLAG_TXE: Transmit buffer empty flag.
+ * @arg SPI_I2S_FLAG_RXNE: Receive buffer not empty flag.
+ * @arg SPI_I2S_FLAG_BSY: Busy flag.
+ * @arg SPI_I2S_FLAG_OVR: Overrun flag.
+ * @arg SPI_FLAG_MODF: Mode Fault flag.
+ * @arg SPI_FLAG_CRCERR: CRC Error flag.
+ * @arg SPI_I2S_FLAG_TIFRFE: Format Error.
+ * @arg I2S_FLAG_UDR: Underrun Error flag.
+ * @arg I2S_FLAG_CHSIDE: Channel Side flag.
+ * @retval The new state of SPI_I2S_FLAG (SET or RESET).
+ */
+FlagStatus SPI_I2S_GetFlagStatus(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG)
+{
+ FlagStatus bitstatus = RESET;
+ /* Check the parameters */
+ assert_param(IS_SPI_ALL_PERIPH(SPIx));
+ assert_param(IS_SPI_I2S_GET_FLAG(SPI_I2S_FLAG));
+
+ /* Check the status of the specified SPI flag */
+ if ((SPIx->SR & SPI_I2S_FLAG) != (uint16_t)RESET)
+ {
+ /* SPI_I2S_FLAG is set */
+ bitstatus = SET;
+ }
+ else
+ {
+ /* SPI_I2S_FLAG is reset */
+ bitstatus = RESET;
+ }
+ /* Return the SPI_I2S_FLAG status */
+ return bitstatus;
+}
+
+/**
+ * @brief Clears the SPIx CRC Error (CRCERR) flag.
+ * @param SPIx: To select the SPIx/I2Sx peripheral, where x can be: 1, 2 or 3
+ * in SPI mode or 2 or 3 in I2S mode.
+ * @param SPI_I2S_FLAG: specifies the SPI flag to clear.
+ * This function clears only CRCERR flag.
+ * @arg SPI_FLAG_CRCERR: CRC Error flag.
+ *
+ * @note OVR (OverRun error) flag is cleared by software sequence: a read
+ * operation to SPI_DR register (SPI_I2S_ReceiveData()) followed by a read
+ * operation to SPI_SR register (SPI_I2S_GetFlagStatus()).
+ * @note UDR (UnderRun error) flag is cleared by a read operation to
+ * SPI_SR register (SPI_I2S_GetFlagStatus()).
+ * @note MODF (Mode Fault) flag is cleared by software sequence: a read/write
+ * operation to SPI_SR register (SPI_I2S_GetFlagStatus()) followed by a
+ * write operation to SPI_CR1 register (SPI_Cmd() to enable the SPI).
+ *
+ * @retval None
+ */
+void SPI_I2S_ClearFlag(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG)
+{
+ /* Check the parameters */
+ assert_param(IS_SPI_ALL_PERIPH(SPIx));
+ assert_param(IS_SPI_I2S_CLEAR_FLAG(SPI_I2S_FLAG));
+
+ /* Clear the selected SPI CRC Error (CRCERR) flag */
+ SPIx->SR = (uint16_t)~SPI_I2S_FLAG;
+}
+
+/**
+ * @brief Checks whether the specified SPIx/I2Sx interrupt has occurred or not.
+ * @param SPIx: To select the SPIx/I2Sx peripheral, where x can be: 1, 2 or 3
+ * in SPI mode or 2 or 3 in I2S mode.
+ * @param SPI_I2S_IT: specifies the SPI interrupt source to check.
+ * This parameter can be one of the following values:
+ * @arg SPI_I2S_IT_TXE: Transmit buffer empty interrupt.
+ * @arg SPI_I2S_IT_RXNE: Receive buffer not empty interrupt.
+ * @arg SPI_I2S_IT_OVR: Overrun interrupt.
+ * @arg SPI_IT_MODF: Mode Fault interrupt.
+ * @arg SPI_IT_CRCERR: CRC Error interrupt.
+ * @arg I2S_IT_UDR: Underrun interrupt.
+ * @arg SPI_I2S_IT_TIFRFE: Format Error interrupt.
+ * @retval The new state of SPI_I2S_IT (SET or RESET).
+ */
+ITStatus SPI_I2S_GetITStatus(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT)
+{
+ ITStatus bitstatus = RESET;
+ uint16_t itpos = 0, itmask = 0, enablestatus = 0;
+
+ /* Check the parameters */
+ assert_param(IS_SPI_ALL_PERIPH(SPIx));
+ assert_param(IS_SPI_I2S_GET_IT(SPI_I2S_IT));
+
+ /* Get the SPI_I2S_IT index */
+ itpos = 0x01 << (SPI_I2S_IT & 0x0F);
+
+ /* Get the SPI_I2S_IT IT mask */
+ itmask = SPI_I2S_IT >> 4;
+
+ /* Set the IT mask */
+ itmask = 0x01 << itmask;
+
+ /* Get the SPI_I2S_IT enable bit status */
+ enablestatus = (SPIx->CR2 & itmask) ;
+
+ /* Check the status of the specified SPI interrupt */
+ if (((SPIx->SR & itpos) != (uint16_t)RESET) && enablestatus)
+ {
+ /* SPI_I2S_IT is set */
+ bitstatus = SET;
+ }
+ else
+ {
+ /* SPI_I2S_IT is reset */
+ bitstatus = RESET;
+ }
+ /* Return the SPI_I2S_IT status */
+ return bitstatus;
+}
+
+/**
+ * @brief Clears the SPIx CRC Error (CRCERR) interrupt pending bit.
+ * @param SPIx: To select the SPIx/I2Sx peripheral, where x can be: 1, 2 or 3
+ * in SPI mode or 2 or 3 in I2S mode.
+ * @param SPI_I2S_IT: specifies the SPI interrupt pending bit to clear.
+ * This function clears only CRCERR interrupt pending bit.
+ * @arg SPI_IT_CRCERR: CRC Error interrupt.
+ *
+ * @note OVR (OverRun Error) interrupt pending bit is cleared by software
+ * sequence: a read operation to SPI_DR register (SPI_I2S_ReceiveData())
+ * followed by a read operation to SPI_SR register (SPI_I2S_GetITStatus()).
+ * @note UDR (UnderRun Error) interrupt pending bit is cleared by a read
+ * operation to SPI_SR register (SPI_I2S_GetITStatus()).
+ * @note MODF (Mode Fault) interrupt pending bit is cleared by software sequence:
+ * a read/write operation to SPI_SR register (SPI_I2S_GetITStatus())
+ * followed by a write operation to SPI_CR1 register (SPI_Cmd() to enable
+ * the SPI).
+ * @retval None
+ */
+void SPI_I2S_ClearITPendingBit(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT)
+{
+ uint16_t itpos = 0;
+ /* Check the parameters */
+ assert_param(IS_SPI_ALL_PERIPH(SPIx));
+ assert_param(IS_SPI_I2S_CLEAR_IT(SPI_I2S_IT));
+
+ /* Get the SPI_I2S IT index */
+ itpos = 0x01 << (SPI_I2S_IT & 0x0F);
+
+ /* Clear the selected SPI CRC Error (CRCERR) interrupt pending bit */
+ SPIx->SR = (uint16_t)~itpos;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/src/stm32f2xx_syscfg.c b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/src/stm32f2xx_syscfg.c
new file mode 100644
index 0000000..ba87ffa
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/src/stm32f2xx_syscfg.c
@@ -0,0 +1,210 @@
+/**
+ ******************************************************************************
+ * @file stm32f2xx_syscfg.c
+ * @author MCD Application Team
+ * @version V1.1.2
+ * @date 05-March-2012
+ * @brief This file provides firmware functions to manage the SYSCFG peripheral.
+ *
+ * @verbatim
+ *
+ * ===================================================================
+ * How to use this driver
+ * ===================================================================
+ *
+ * This driver provides functions for:
+ *
+ * 1. Remapping the memory accessible in the code area using SYSCFG_MemoryRemapConfig()
+ *
+ * 2. Manage the EXTI lines connection to the GPIOs using SYSCFG_EXTILineConfig()
+ *
+ * 3. Select the ETHERNET media interface (RMII/RII) using SYSCFG_ETH_MediaInterfaceConfig()
+ *
+ * @note SYSCFG APB clock must be enabled to get write access to SYSCFG registers,
+ * using RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
+ *
+ * @endverbatim
+ *
+ ******************************************************************************
+ * @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 "stm32f2xx_syscfg.h"
+#include "stm32f2xx_rcc.h"
+
+/** @addtogroup STM32F2xx_StdPeriph_Driver
+ * @{
+ */
+
+/** @defgroup SYSCFG
+ * @brief SYSCFG driver modules
+ * @{
+ */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* ------------ RCC registers bit address in the alias region ----------- */
+#define SYSCFG_OFFSET (SYSCFG_BASE - PERIPH_BASE)
+/* --- PMC Register ---*/
+/* Alias word address of MII_RMII_SEL bit */
+#define PMC_OFFSET (SYSCFG_OFFSET + 0x04)
+#define MII_RMII_SEL_BitNumber ((uint8_t)0x17)
+#define PMC_MII_RMII_SEL_BB (PERIPH_BB_BASE + (PMC_OFFSET * 32) + (MII_RMII_SEL_BitNumber * 4))
+
+/* --- CMPCR Register ---*/
+/* Alias word address of CMP_PD bit */
+#define CMPCR_OFFSET (SYSCFG_OFFSET + 0x20)
+#define CMP_PD_BitNumber ((uint8_t)0x00)
+#define CMPCR_CMP_PD_BB (PERIPH_BB_BASE + (CMPCR_OFFSET * 32) + (CMP_PD_BitNumber * 4))
+
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+/** @defgroup SYSCFG_Private_Functions
+ * @{
+ */
+
+/**
+ * @brief Deinitializes the Alternate Functions (remap and EXTI configuration)
+ * registers to their default reset values.
+ * @param None
+ * @retval None
+ */
+void SYSCFG_DeInit(void)
+{
+ RCC_APB2PeriphResetCmd(RCC_APB2Periph_SYSCFG, ENABLE);
+ RCC_APB2PeriphResetCmd(RCC_APB2Periph_SYSCFG, DISABLE);
+}
+
+/**
+ * @brief Changes the mapping of the specified pin.
+ * @param SYSCFG_Memory: selects the memory remapping.
+ * This parameter can be one of the following values:
+ * @arg SYSCFG_MemoryRemap_Flash: Main Flash memory mapped at 0x00000000
+ * @arg SYSCFG_MemoryRemap_SystemFlash: System Flash memory mapped at 0x00000000
+ * @arg SYSCFG_MemoryRemap_FSMC: FSMC (Bank1 (NOR/PSRAM 1 and 2) mapped at 0x00000000
+ * @arg SYSCFG_MemoryRemap_SRAM: Embedded SRAM (112kB) mapped at 0x00000000
+ *
+ * @note In remap mode, the FSMC addressing is fixed to the remap address area only
+ * (Bank1 NOR/PSRAM 1 and NOR/PSRAM 2) and FSMC control registers are not
+ * accessible. The FSMC remap function must be disabled to allows addressing
+ * other memory devices through the FSMC and/or to access FSMC control
+ * registers.
+ *
+ * @retval None
+ */
+void SYSCFG_MemoryRemapConfig(uint8_t SYSCFG_MemoryRemap)
+{
+ /* Check the parameters */
+ assert_param(IS_SYSCFG_MEMORY_REMAP_CONFING(SYSCFG_MemoryRemap));
+
+ SYSCFG->MEMRMP = SYSCFG_MemoryRemap;
+}
+
+/**
+ * @brief Selects the GPIO pin used as EXTI Line.
+ * @param EXTI_PortSourceGPIOx : selects the GPIO port to be used as source for
+ * EXTI lines where x can be (A..I).
+ * @param EXTI_PinSourcex: specifies the EXTI line to be configured.
+ * This parameter can be EXTI_PinSourcex where x can be (0..15, except
+ * for EXTI_PortSourceGPIOI x can be (0..11).
+ * @retval None
+ */
+void SYSCFG_EXTILineConfig(uint8_t EXTI_PortSourceGPIOx, uint8_t EXTI_PinSourcex)
+{
+ uint32_t tmp = 0x00;
+
+ /* Check the parameters */
+ assert_param(IS_EXTI_PORT_SOURCE(EXTI_PortSourceGPIOx));
+ assert_param(IS_EXTI_PIN_SOURCE(EXTI_PinSourcex));
+
+ tmp = ((uint32_t)0x0F) << (0x04 * (EXTI_PinSourcex & (uint8_t)0x03));
+ SYSCFG->EXTICR[EXTI_PinSourcex >> 0x02] &= ~tmp;
+ SYSCFG->EXTICR[EXTI_PinSourcex >> 0x02] |= (((uint32_t)EXTI_PortSourceGPIOx) << (0x04 * (EXTI_PinSourcex & (uint8_t)0x03)));
+}
+
+/**
+ * @brief Selects the ETHERNET media interface
+ * @param SYSCFG_ETH_MediaInterface: specifies the Media Interface mode.
+ * This parameter can be one of the following values:
+ * @arg SYSCFG_ETH_MediaInterface_MII: MII mode selected
+ * @arg SYSCFG_ETH_MediaInterface_RMII: RMII mode selected
+ * @retval None
+ */
+void SYSCFG_ETH_MediaInterfaceConfig(uint32_t SYSCFG_ETH_MediaInterface)
+{
+ assert_param(IS_SYSCFG_ETH_MEDIA_INTERFACE(SYSCFG_ETH_MediaInterface));
+ /* Configure MII_RMII selection bit */
+ *(__IO uint32_t *) PMC_MII_RMII_SEL_BB = SYSCFG_ETH_MediaInterface;
+}
+
+/**
+ * @brief Enables or disables the I/O Compensation Cell.
+ * @note The I/O compensation cell can be used only when the device supply
+ * voltage ranges from 2.4 to 3.6 V.
+ * @param NewState: new state of the I/O Compensation Cell.
+ * This parameter can be one of the following values:
+ * @arg ENABLE: I/O compensation cell enabled
+ * @arg DISABLE: I/O compensation cell power-down mode
+ * @retval None
+ */
+void SYSCFG_CompensationCellCmd(FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ *(__IO uint32_t *) CMPCR_CMP_PD_BB = (uint32_t)NewState;
+}
+
+/**
+ * @brief Checks whether the I/O Compensation Cell ready flag is set or not.
+ * @param None
+ * @retval The new state of the I/O Compensation Cell ready flag (SET or RESET)
+ */
+FlagStatus SYSCFG_GetCompensationCellStatus(void)
+{
+ FlagStatus bitstatus = RESET;
+
+ if ((SYSCFG->CMPCR & SYSCFG_CMPCR_READY ) != (uint32_t)RESET)
+ {
+ bitstatus = SET;
+ }
+ else
+ {
+ bitstatus = RESET;
+ }
+ return bitstatus;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/src/stm32f2xx_tim.c b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/src/stm32f2xx_tim.c
new file mode 100644
index 0000000..f160770
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/src/stm32f2xx_tim.c
@@ -0,0 +1,3358 @@
+/**
+ ******************************************************************************
+ * @file stm32f2xx_tim.c
+ * @author MCD Application Team
+ * @version V1.1.2
+ * @date 05-March-2012
+ * @brief This file provides firmware functions to manage the following
+ * functionalities of the TIM peripheral:
+ * - TimeBase management
+ * - Output Compare management
+ * - Input Capture management
+ * - Advanced-control timers (TIM1 and TIM8) specific features
+ * - Interrupts, DMA and flags management
+ * - Clocks management
+ * - Synchronization management
+ * - Specific interface management
+ * - Specific remapping management
+ *
+ * @verbatim
+ *
+ * ===================================================================
+ * How to use this driver
+ * ===================================================================
+ * This driver provides functions to configure and program the TIM
+ * of all STM32F2xx devices.
+ * These functions are split in 9 groups:
+ *
+ * 1. TIM TimeBase management: this group includes all needed functions
+ * to configure the TM Timebase unit:
+ * - Set/Get Prescaler
+ * - Set/Get Autoreload
+ * - Counter modes configuration
+ * - Set Clock division
+ * - Select the One Pulse mode
+ * - Update Request Configuration
+ * - Update Disable Configuration
+ * - Auto-Preload Configuration
+ * - Enable/Disable the counter
+ *
+ * 2. TIM Output Compare management: this group includes all needed
+ * functions to configure the Capture/Compare unit used in Output
+ * compare mode:
+ * - Configure each channel, independently, in Output Compare mode
+ * - Select the output compare modes
+ * - Select the Polarities of each channel
+ * - Set/Get the Capture/Compare register values
+ * - Select the Output Compare Fast mode
+ * - Select the Output Compare Forced mode
+ * - Output Compare-Preload Configuration
+ * - Clear Output Compare Reference
+ * - Select the OCREF Clear signal
+ * - Enable/Disable the Capture/Compare Channels
+ *
+ * 3. TIM Input Capture management: this group includes all needed
+ * functions to configure the Capture/Compare unit used in
+ * Input Capture mode:
+ * - Configure each channel in input capture mode
+ * - Configure Channel1/2 in PWM Input mode
+ * - Set the Input Capture Prescaler
+ * - Get the Capture/Compare values
+ *
+ * 4. Advanced-control timers (TIM1 and TIM8) specific features
+ * - Configures the Break input, dead time, Lock level, the OSSI,
+ * the OSSR State and the AOE(automatic output enable)
+ * - Enable/Disable the TIM peripheral Main Outputs
+ * - Select the Commutation event
+ * - Set/Reset the Capture Compare Preload Control bit
+ *
+ * 5. TIM interrupts, DMA and flags management
+ * - Enable/Disable interrupt sources
+ * - Get flags status
+ * - Clear flags/ Pending bits
+ * - Enable/Disable DMA requests
+ * - Configure DMA burst mode
+ * - Select CaptureCompare DMA request
+ *
+ * 6. TIM clocks management: this group includes all needed functions
+ * to configure the clock controller unit:
+ * - Select internal/External clock
+ * - Select the external clock mode: ETR(Mode1/Mode2), TIx or ITRx
+ *
+ * 7. TIM synchronization management: this group includes all needed
+ * functions to configure the Synchronization unit:
+ * - Select Input Trigger
+ * - Select Output Trigger
+ * - Select Master Slave Mode
+ * - ETR Configuration when used as external trigger
+ *
+ * 8. TIM specific interface management, this group includes all
+ * needed functions to use the specific TIM interface:
+ * - Encoder Interface Configuration
+ * - Select Hall Sensor
+ *
+ * 9. TIM specific remapping management includes the Remapping
+ * configuration of specific timers
+ *
+ * @endverbatim
+ *
+ ******************************************************************************
+ * @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 "stm32f2xx_tim.h"
+#include "stm32f2xx_rcc.h"
+
+/** @addtogroup STM32F2xx_StdPeriph_Driver
+ * @{
+ */
+
+/** @defgroup TIM
+ * @brief TIM driver modules
+ * @{
+ */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+
+/* ---------------------- TIM registers bit mask ------------------------ */
+#define SMCR_ETR_MASK ((uint16_t)0x00FF)
+#define CCMR_OFFSET ((uint16_t)0x0018)
+#define CCER_CCE_SET ((uint16_t)0x0001)
+#define CCER_CCNE_SET ((uint16_t)0x0004)
+#define CCMR_OC13M_MASK ((uint16_t)0xFF8F)
+#define CCMR_OC24M_MASK ((uint16_t)0x8FFF)
+
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+static void TI1_Config(TIM_TypeDef* TIMx, uint16_t TIM_ICPolarity, uint16_t TIM_ICSelection,
+ uint16_t TIM_ICFilter);
+static void TI2_Config(TIM_TypeDef* TIMx, uint16_t TIM_ICPolarity, uint16_t TIM_ICSelection,
+ uint16_t TIM_ICFilter);
+static void TI3_Config(TIM_TypeDef* TIMx, uint16_t TIM_ICPolarity, uint16_t TIM_ICSelection,
+ uint16_t TIM_ICFilter);
+static void TI4_Config(TIM_TypeDef* TIMx, uint16_t TIM_ICPolarity, uint16_t TIM_ICSelection,
+ uint16_t TIM_ICFilter);
+
+/* Private functions ---------------------------------------------------------*/
+
+/** @defgroup TIM_Private_Functions
+ * @{
+ */
+
+/** @defgroup TIM_Group1 TimeBase management functions
+ * @brief TimeBase management functions
+ *
+@verbatim
+ ===============================================================================
+ TimeBase management functions
+ ===============================================================================
+
+ ===================================================================
+ TIM Driver: how to use it in Timing(Time base) Mode
+ ===================================================================
+ To use the Timer in Timing(Time base) mode, the following steps are mandatory:
+
+ 1. Enable TIM clock using RCC_APBxPeriphClockCmd(RCC_APBxPeriph_TIMx, ENABLE) function
+
+ 2. Fill the TIM_TimeBaseInitStruct with the desired parameters.
+
+ 3. Call TIM_TimeBaseInit(TIMx, &TIM_TimeBaseInitStruct) to configure the Time Base unit
+ with the corresponding configuration
+
+ 4. Enable the NVIC if you need to generate the update interrupt.
+
+ 5. Enable the corresponding interrupt using the function TIM_ITConfig(TIMx, TIM_IT_Update)
+
+ 6. Call the TIM_Cmd(ENABLE) function to enable the TIM counter.
+
+ Note1: All other functions can be used separately to modify, if needed,
+ a specific feature of the Timer.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Deinitializes the TIMx peripheral registers to their default reset values.
+ * @param TIMx: where x can be 1 to 14 to select the TIM peripheral.
+ * @retval None
+
+ */
+void TIM_DeInit(TIM_TypeDef* TIMx)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_ALL_PERIPH(TIMx));
+
+ if (TIMx == TIM1)
+ {
+ RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM1, ENABLE);
+ RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM1, DISABLE);
+ }
+ else if (TIMx == TIM2)
+ {
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM2, ENABLE);
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM2, DISABLE);
+ }
+ else if (TIMx == TIM3)
+ {
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM3, ENABLE);
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM3, DISABLE);
+ }
+ else if (TIMx == TIM4)
+ {
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM4, ENABLE);
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM4, DISABLE);
+ }
+ else if (TIMx == TIM5)
+ {
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM5, ENABLE);
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM5, DISABLE);
+ }
+ else if (TIMx == TIM6)
+ {
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM6, ENABLE);
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM6, DISABLE);
+ }
+ else if (TIMx == TIM7)
+ {
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM7, ENABLE);
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM7, DISABLE);
+ }
+ else if (TIMx == TIM8)
+ {
+ RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM8, ENABLE);
+ RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM8, DISABLE);
+ }
+ else if (TIMx == TIM9)
+ {
+ RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM9, ENABLE);
+ RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM9, DISABLE);
+ }
+ else if (TIMx == TIM10)
+ {
+ RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM10, ENABLE);
+ RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM10, DISABLE);
+ }
+ else if (TIMx == TIM11)
+ {
+ RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM11, ENABLE);
+ RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM11, DISABLE);
+ }
+ else if (TIMx == TIM12)
+ {
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM12, ENABLE);
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM12, DISABLE);
+ }
+ else if (TIMx == TIM13)
+ {
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM13, ENABLE);
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM13, DISABLE);
+ }
+ else
+ {
+ if (TIMx == TIM14)
+ {
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM14, ENABLE);
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM14, DISABLE);
+ }
+ }
+}
+
+/**
+ * @brief Initializes the TIMx Time Base Unit peripheral according to
+ * the specified parameters in the TIM_TimeBaseInitStruct.
+ * @param TIMx: where x can be 1 to 14 to select the TIM peripheral.
+ * @param TIM_TimeBaseInitStruct: pointer to a TIM_TimeBaseInitTypeDef structure
+ * that contains the configuration information for the specified TIM peripheral.
+ * @retval None
+ */
+void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct)
+{
+ uint16_t tmpcr1 = 0;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_ALL_PERIPH(TIMx));
+ assert_param(IS_TIM_COUNTER_MODE(TIM_TimeBaseInitStruct->TIM_CounterMode));
+ assert_param(IS_TIM_CKD_DIV(TIM_TimeBaseInitStruct->TIM_ClockDivision));
+
+ tmpcr1 = TIMx->CR1;
+
+ if((TIMx == TIM1) || (TIMx == TIM8)||
+ (TIMx == TIM2) || (TIMx == TIM3)||
+ (TIMx == TIM4) || (TIMx == TIM5))
+ {
+ /* Select the Counter Mode */
+ tmpcr1 &= (uint16_t)(~(TIM_CR1_DIR | TIM_CR1_CMS));
+ tmpcr1 |= (uint32_t)TIM_TimeBaseInitStruct->TIM_CounterMode;
+ }
+
+ if((TIMx != TIM6) && (TIMx != TIM7))
+ {
+ /* Set the clock division */
+ tmpcr1 &= (uint16_t)(~TIM_CR1_CKD);
+ tmpcr1 |= (uint32_t)TIM_TimeBaseInitStruct->TIM_ClockDivision;
+ }
+
+ TIMx->CR1 = tmpcr1;
+
+ /* Set the Autoreload value */
+ TIMx->ARR = TIM_TimeBaseInitStruct->TIM_Period ;
+
+ /* Set the Prescaler value */
+ TIMx->PSC = TIM_TimeBaseInitStruct->TIM_Prescaler;
+
+ if ((TIMx == TIM1) || (TIMx == TIM8))
+ {
+ /* Set the Repetition Counter value */
+ TIMx->RCR = TIM_TimeBaseInitStruct->TIM_RepetitionCounter;
+ }
+
+ /* Generate an update event to reload the Prescaler
+ and the repetition counter(only for TIM1 and TIM8) value immediatly */
+ TIMx->EGR = TIM_PSCReloadMode_Immediate;
+}
+
+/**
+ * @brief Fills each TIM_TimeBaseInitStruct member with its default value.
+ * @param TIM_TimeBaseInitStruct : pointer to a TIM_TimeBaseInitTypeDef
+ * structure which will be initialized.
+ * @retval None
+ */
+void TIM_TimeBaseStructInit(TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct)
+{
+ /* Set the default configuration */
+ TIM_TimeBaseInitStruct->TIM_Period = 0xFFFFFFFF;
+ TIM_TimeBaseInitStruct->TIM_Prescaler = 0x0000;
+ TIM_TimeBaseInitStruct->TIM_ClockDivision = TIM_CKD_DIV1;
+ TIM_TimeBaseInitStruct->TIM_CounterMode = TIM_CounterMode_Up;
+ TIM_TimeBaseInitStruct->TIM_RepetitionCounter = 0x0000;
+}
+
+/**
+ * @brief Configures the TIMx Prescaler.
+ * @param TIMx: where x can be 1 to 14 to select the TIM peripheral.
+ * @param Prescaler: specifies the Prescaler Register value
+ * @param TIM_PSCReloadMode: specifies the TIM Prescaler Reload mode
+ * This parameter can be one of the following values:
+ * @arg TIM_PSCReloadMode_Update: The Prescaler is loaded at the update event.
+ * @arg TIM_PSCReloadMode_Immediate: The Prescaler is loaded immediatly.
+ * @retval None
+ */
+void TIM_PrescalerConfig(TIM_TypeDef* TIMx, uint16_t Prescaler, uint16_t TIM_PSCReloadMode)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_ALL_PERIPH(TIMx));
+ assert_param(IS_TIM_PRESCALER_RELOAD(TIM_PSCReloadMode));
+ /* Set the Prescaler value */
+ TIMx->PSC = Prescaler;
+ /* Set or reset the UG Bit */
+ TIMx->EGR = TIM_PSCReloadMode;
+}
+
+/**
+ * @brief Specifies the TIMx Counter Mode to be used.
+ * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral.
+ * @param TIM_CounterMode: specifies the Counter Mode to be used
+ * This parameter can be one of the following values:
+ * @arg TIM_CounterMode_Up: TIM Up Counting Mode
+ * @arg TIM_CounterMode_Down: TIM Down Counting Mode
+ * @arg TIM_CounterMode_CenterAligned1: TIM Center Aligned Mode1
+ * @arg TIM_CounterMode_CenterAligned2: TIM Center Aligned Mode2
+ * @arg TIM_CounterMode_CenterAligned3: TIM Center Aligned Mode3
+ * @retval None
+ */
+void TIM_CounterModeConfig(TIM_TypeDef* TIMx, uint16_t TIM_CounterMode)
+{
+ uint16_t tmpcr1 = 0;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+ assert_param(IS_TIM_COUNTER_MODE(TIM_CounterMode));
+
+ tmpcr1 = TIMx->CR1;
+
+ /* Reset the CMS and DIR Bits */
+ tmpcr1 &= (uint16_t)~(TIM_CR1_DIR | TIM_CR1_CMS);
+
+ /* Set the Counter Mode */
+ tmpcr1 |= TIM_CounterMode;
+
+ /* Write to TIMx CR1 register */
+ TIMx->CR1 = tmpcr1;
+}
+
+/**
+ * @brief Sets the TIMx Counter Register value
+ * @param TIMx: where x can be 1 to 14 to select the TIM peripheral.
+ * @param Counter: specifies the Counter register new value.
+ * @retval None
+ */
+void TIM_SetCounter(TIM_TypeDef* TIMx, uint32_t Counter)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_ALL_PERIPH(TIMx));
+
+ /* Set the Counter Register value */
+ TIMx->CNT = Counter;
+}
+
+/**
+ * @brief Sets the TIMx Autoreload Register value
+ * @param TIMx: where x can be 1 to 14 to select the TIM peripheral.
+ * @param Autoreload: specifies the Autoreload register new value.
+ * @retval None
+ */
+void TIM_SetAutoreload(TIM_TypeDef* TIMx, uint32_t Autoreload)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_ALL_PERIPH(TIMx));
+
+ /* Set the Autoreload Register value */
+ TIMx->ARR = Autoreload;
+}
+
+/**
+ * @brief Gets the TIMx Counter value.
+ * @param TIMx: where x can be 1 to 14 to select the TIM peripheral.
+ * @retval Counter Register value
+ */
+uint32_t TIM_GetCounter(TIM_TypeDef* TIMx)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_ALL_PERIPH(TIMx));
+
+ /* Get the Counter Register value */
+ return TIMx->CNT;
+}
+
+/**
+ * @brief Gets the TIMx Prescaler value.
+ * @param TIMx: where x can be 1 to 14 to select the TIM peripheral.
+ * @retval Prescaler Register value.
+ */
+uint16_t TIM_GetPrescaler(TIM_TypeDef* TIMx)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_ALL_PERIPH(TIMx));
+
+ /* Get the Prescaler Register value */
+ return TIMx->PSC;
+}
+
+/**
+ * @brief Enables or Disables the TIMx Update event.
+ * @param TIMx: where x can be 1 to 14 to select the TIM peripheral.
+ * @param NewState: new state of the TIMx UDIS bit
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void TIM_UpdateDisableConfig(TIM_TypeDef* TIMx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_ALL_PERIPH(TIMx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Set the Update Disable Bit */
+ TIMx->CR1 |= TIM_CR1_UDIS;
+ }
+ else
+ {
+ /* Reset the Update Disable Bit */
+ TIMx->CR1 &= (uint16_t)~TIM_CR1_UDIS;
+ }
+}
+
+/**
+ * @brief Configures the TIMx Update Request Interrupt source.
+ * @param TIMx: where x can be 1 to 14 to select the TIM peripheral.
+ * @param TIM_UpdateSource: specifies the Update source.
+ * This parameter can be one of the following values:
+ * @arg TIM_UpdateSource_Global: Source of update is the counter
+ * overflow/underflow or the setting of UG bit, or an update
+ * generation through the slave mode controller.
+ * @arg TIM_UpdateSource_Regular: Source of update is counter overflow/underflow.
+ * @retval None
+ */
+void TIM_UpdateRequestConfig(TIM_TypeDef* TIMx, uint16_t TIM_UpdateSource)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_ALL_PERIPH(TIMx));
+ assert_param(IS_TIM_UPDATE_SOURCE(TIM_UpdateSource));
+
+ if (TIM_UpdateSource != TIM_UpdateSource_Global)
+ {
+ /* Set the URS Bit */
+ TIMx->CR1 |= TIM_CR1_URS;
+ }
+ else
+ {
+ /* Reset the URS Bit */
+ TIMx->CR1 &= (uint16_t)~TIM_CR1_URS;
+ }
+}
+
+/**
+ * @brief Enables or disables TIMx peripheral Preload register on ARR.
+ * @param TIMx: where x can be 1 to 14 to select the TIM peripheral.
+ * @param NewState: new state of the TIMx peripheral Preload register
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void TIM_ARRPreloadConfig(TIM_TypeDef* TIMx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_ALL_PERIPH(TIMx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Set the ARR Preload Bit */
+ TIMx->CR1 |= TIM_CR1_ARPE;
+ }
+ else
+ {
+ /* Reset the ARR Preload Bit */
+ TIMx->CR1 &= (uint16_t)~TIM_CR1_ARPE;
+ }
+}
+
+/**
+ * @brief Selects the TIMx's One Pulse Mode.
+ * @param TIMx: where x can be 1 to 14 to select the TIM peripheral.
+ * @param TIM_OPMode: specifies the OPM Mode to be used.
+ * This parameter can be one of the following values:
+ * @arg TIM_OPMode_Single
+ * @arg TIM_OPMode_Repetitive
+ * @retval None
+ */
+void TIM_SelectOnePulseMode(TIM_TypeDef* TIMx, uint16_t TIM_OPMode)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_ALL_PERIPH(TIMx));
+ assert_param(IS_TIM_OPM_MODE(TIM_OPMode));
+
+ /* Reset the OPM Bit */
+ TIMx->CR1 &= (uint16_t)~TIM_CR1_OPM;
+
+ /* Configure the OPM Mode */
+ TIMx->CR1 |= TIM_OPMode;
+}
+
+/**
+ * @brief Sets the TIMx Clock Division value.
+ * @param TIMx: where x can be 1 to 14 except 6 and 7, to select the TIM peripheral.
+ * @param TIM_CKD: specifies the clock division value.
+ * This parameter can be one of the following value:
+ * @arg TIM_CKD_DIV1: TDTS = Tck_tim
+ * @arg TIM_CKD_DIV2: TDTS = 2*Tck_tim
+ * @arg TIM_CKD_DIV4: TDTS = 4*Tck_tim
+ * @retval None
+ */
+void TIM_SetClockDivision(TIM_TypeDef* TIMx, uint16_t TIM_CKD)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST1_PERIPH(TIMx));
+ assert_param(IS_TIM_CKD_DIV(TIM_CKD));
+
+ /* Reset the CKD Bits */
+ TIMx->CR1 &= (uint16_t)(~TIM_CR1_CKD);
+
+ /* Set the CKD value */
+ TIMx->CR1 |= TIM_CKD;
+}
+
+/**
+ * @brief Enables or disables the specified TIM peripheral.
+ * @param TIMx: where x can be 1 to 14 to select the TIMx peripheral.
+ * @param NewState: new state of the TIMx peripheral.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_ALL_PERIPH(TIMx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the TIM Counter */
+ TIMx->CR1 |= TIM_CR1_CEN;
+ }
+ else
+ {
+ /* Disable the TIM Counter */
+ TIMx->CR1 &= (uint16_t)~TIM_CR1_CEN;
+ }
+}
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Group2 Output Compare management functions
+ * @brief Output Compare management functions
+ *
+@verbatim
+ ===============================================================================
+ Output Compare management functions
+ ===============================================================================
+
+ ===================================================================
+ TIM Driver: how to use it in Output Compare Mode
+ ===================================================================
+ To use the Timer in Output Compare mode, the following steps are mandatory:
+
+ 1. Enable TIM clock using RCC_APBxPeriphClockCmd(RCC_APBxPeriph_TIMx, ENABLE) function
+
+ 2. Configure the TIM pins by configuring the corresponding GPIO pins
+
+ 2. Configure the Time base unit as described in the first part of this driver,
+ if needed, else the Timer will run with the default configuration:
+ - Autoreload value = 0xFFFF
+ - Prescaler value = 0x0000
+ - Counter mode = Up counting
+ - Clock Division = TIM_CKD_DIV1
+
+ 3. Fill the TIM_OCInitStruct with the desired parameters including:
+ - The TIM Output Compare mode: TIM_OCMode
+ - TIM Output State: TIM_OutputState
+ - TIM Pulse value: TIM_Pulse
+ - TIM Output Compare Polarity : TIM_OCPolarity
+
+ 4. Call TIM_OCxInit(TIMx, &TIM_OCInitStruct) to configure the desired channel with the
+ corresponding configuration
+
+ 5. Call the TIM_Cmd(ENABLE) function to enable the TIM counter.
+
+ Note1: All other functions can be used separately to modify, if needed,
+ a specific feature of the Timer.
+
+ Note2: In case of PWM mode, this function is mandatory:
+ TIM_OCxPreloadConfig(TIMx, TIM_OCPreload_ENABLE);
+
+ Note3: If the corresponding interrupt or DMA request are needed, the user should:
+ 1. Enable the NVIC (or the DMA) to use the TIM interrupts (or DMA requests).
+ 2. Enable the corresponding interrupt (or DMA request) using the function
+ TIM_ITConfig(TIMx, TIM_IT_CCx) (or TIM_DMA_Cmd(TIMx, TIM_DMA_CCx))
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Initializes the TIMx Channel1 according to the specified parameters in
+ * the TIM_OCInitStruct.
+ * @param TIMx: where x can be 1 to 14 except 6 and 7, to select the TIM peripheral.
+ * @param TIM_OCInitStruct: pointer to a TIM_OCInitTypeDef structure that contains
+ * the configuration information for the specified TIM peripheral.
+ * @retval None
+ */
+void TIM_OC1Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct)
+{
+ uint16_t tmpccmrx = 0, tmpccer = 0, tmpcr2 = 0;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST1_PERIPH(TIMx));
+ assert_param(IS_TIM_OC_MODE(TIM_OCInitStruct->TIM_OCMode));
+ assert_param(IS_TIM_OUTPUT_STATE(TIM_OCInitStruct->TIM_OutputState));
+ assert_param(IS_TIM_OC_POLARITY(TIM_OCInitStruct->TIM_OCPolarity));
+
+ /* Disable the Channel 1: Reset the CC1E Bit */
+ TIMx->CCER &= (uint16_t)~TIM_CCER_CC1E;
+
+ /* Get the TIMx CCER register value */
+ tmpccer = TIMx->CCER;
+ /* Get the TIMx CR2 register value */
+ tmpcr2 = TIMx->CR2;
+
+ /* Get the TIMx CCMR1 register value */
+ tmpccmrx = TIMx->CCMR1;
+
+ /* Reset the Output Compare Mode Bits */
+ tmpccmrx &= (uint16_t)~TIM_CCMR1_OC1M;
+ tmpccmrx &= (uint16_t)~TIM_CCMR1_CC1S;
+ /* Select the Output Compare Mode */
+ tmpccmrx |= TIM_OCInitStruct->TIM_OCMode;
+
+ /* Reset the Output Polarity level */
+ tmpccer &= (uint16_t)~TIM_CCER_CC1P;
+ /* Set the Output Compare Polarity */
+ tmpccer |= TIM_OCInitStruct->TIM_OCPolarity;
+
+ /* Set the Output State */
+ tmpccer |= TIM_OCInitStruct->TIM_OutputState;
+
+ if((TIMx == TIM1) || (TIMx == TIM8))
+ {
+ assert_param(IS_TIM_OUTPUTN_STATE(TIM_OCInitStruct->TIM_OutputNState));
+ assert_param(IS_TIM_OCN_POLARITY(TIM_OCInitStruct->TIM_OCNPolarity));
+ assert_param(IS_TIM_OCNIDLE_STATE(TIM_OCInitStruct->TIM_OCNIdleState));
+ assert_param(IS_TIM_OCIDLE_STATE(TIM_OCInitStruct->TIM_OCIdleState));
+
+ /* Reset the Output N Polarity level */
+ tmpccer &= (uint16_t)~TIM_CCER_CC1NP;
+ /* Set the Output N Polarity */
+ tmpccer |= TIM_OCInitStruct->TIM_OCNPolarity;
+ /* Reset the Output N State */
+ tmpccer &= (uint16_t)~TIM_CCER_CC1NE;
+
+ /* Set the Output N State */
+ tmpccer |= TIM_OCInitStruct->TIM_OutputNState;
+ /* Reset the Output Compare and Output Compare N IDLE State */
+ tmpcr2 &= (uint16_t)~TIM_CR2_OIS1;
+ tmpcr2 &= (uint16_t)~TIM_CR2_OIS1N;
+ /* Set the Output Idle state */
+ tmpcr2 |= TIM_OCInitStruct->TIM_OCIdleState;
+ /* Set the Output N Idle state */
+ tmpcr2 |= TIM_OCInitStruct->TIM_OCNIdleState;
+ }
+ /* Write to TIMx CR2 */
+ TIMx->CR2 = tmpcr2;
+
+ /* Write to TIMx CCMR1 */
+ TIMx->CCMR1 = tmpccmrx;
+
+ /* Set the Capture Compare Register value */
+ TIMx->CCR1 = TIM_OCInitStruct->TIM_Pulse;
+
+ /* Write to TIMx CCER */
+ TIMx->CCER = tmpccer;
+}
+
+/**
+ * @brief Initializes the TIMx Channel2 according to the specified parameters
+ * in the TIM_OCInitStruct.
+ * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9 or 12 to select the TIM
+ * peripheral.
+ * @param TIM_OCInitStruct: pointer to a TIM_OCInitTypeDef structure that contains
+ * the configuration information for the specified TIM peripheral.
+ * @retval None
+ */
+void TIM_OC2Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct)
+{
+ uint16_t tmpccmrx = 0, tmpccer = 0, tmpcr2 = 0;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST2_PERIPH(TIMx));
+ assert_param(IS_TIM_OC_MODE(TIM_OCInitStruct->TIM_OCMode));
+ assert_param(IS_TIM_OUTPUT_STATE(TIM_OCInitStruct->TIM_OutputState));
+ assert_param(IS_TIM_OC_POLARITY(TIM_OCInitStruct->TIM_OCPolarity));
+
+ /* Disable the Channel 2: Reset the CC2E Bit */
+ TIMx->CCER &= (uint16_t)~TIM_CCER_CC2E;
+
+ /* Get the TIMx CCER register value */
+ tmpccer = TIMx->CCER;
+ /* Get the TIMx CR2 register value */
+ tmpcr2 = TIMx->CR2;
+
+ /* Get the TIMx CCMR1 register value */
+ tmpccmrx = TIMx->CCMR1;
+
+ /* Reset the Output Compare mode and Capture/Compare selection Bits */
+ tmpccmrx &= (uint16_t)~TIM_CCMR1_OC2M;
+ tmpccmrx &= (uint16_t)~TIM_CCMR1_CC2S;
+
+ /* Select the Output Compare Mode */
+ tmpccmrx |= (uint16_t)(TIM_OCInitStruct->TIM_OCMode << 8);
+
+ /* Reset the Output Polarity level */
+ tmpccer &= (uint16_t)~TIM_CCER_CC2P;
+ /* Set the Output Compare Polarity */
+ tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OCPolarity << 4);
+
+ /* Set the Output State */
+ tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OutputState << 4);
+
+ if((TIMx == TIM1) || (TIMx == TIM8))
+ {
+ assert_param(IS_TIM_OUTPUTN_STATE(TIM_OCInitStruct->TIM_OutputNState));
+ assert_param(IS_TIM_OCN_POLARITY(TIM_OCInitStruct->TIM_OCNPolarity));
+ assert_param(IS_TIM_OCNIDLE_STATE(TIM_OCInitStruct->TIM_OCNIdleState));
+ assert_param(IS_TIM_OCIDLE_STATE(TIM_OCInitStruct->TIM_OCIdleState));
+
+ /* Reset the Output N Polarity level */
+ tmpccer &= (uint16_t)~TIM_CCER_CC2NP;
+ /* Set the Output N Polarity */
+ tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OCNPolarity << 4);
+ /* Reset the Output N State */
+ tmpccer &= (uint16_t)~TIM_CCER_CC2NE;
+
+ /* Set the Output N State */
+ tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OutputNState << 4);
+ /* Reset the Output Compare and Output Compare N IDLE State */
+ tmpcr2 &= (uint16_t)~TIM_CR2_OIS2;
+ tmpcr2 &= (uint16_t)~TIM_CR2_OIS2N;
+ /* Set the Output Idle state */
+ tmpcr2 |= (uint16_t)(TIM_OCInitStruct->TIM_OCIdleState << 2);
+ /* Set the Output N Idle state */
+ tmpcr2 |= (uint16_t)(TIM_OCInitStruct->TIM_OCNIdleState << 2);
+ }
+ /* Write to TIMx CR2 */
+ TIMx->CR2 = tmpcr2;
+
+ /* Write to TIMx CCMR1 */
+ TIMx->CCMR1 = tmpccmrx;
+
+ /* Set the Capture Compare Register value */
+ TIMx->CCR2 = TIM_OCInitStruct->TIM_Pulse;
+
+ /* Write to TIMx CCER */
+ TIMx->CCER = tmpccer;
+}
+
+/**
+ * @brief Initializes the TIMx Channel3 according to the specified parameters
+ * in the TIM_OCInitStruct.
+ * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral.
+ * @param TIM_OCInitStruct: pointer to a TIM_OCInitTypeDef structure that contains
+ * the configuration information for the specified TIM peripheral.
+ * @retval None
+ */
+void TIM_OC3Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct)
+{
+ uint16_t tmpccmrx = 0, tmpccer = 0, tmpcr2 = 0;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+ assert_param(IS_TIM_OC_MODE(TIM_OCInitStruct->TIM_OCMode));
+ assert_param(IS_TIM_OUTPUT_STATE(TIM_OCInitStruct->TIM_OutputState));
+ assert_param(IS_TIM_OC_POLARITY(TIM_OCInitStruct->TIM_OCPolarity));
+
+ /* Disable the Channel 3: Reset the CC2E Bit */
+ TIMx->CCER &= (uint16_t)~TIM_CCER_CC3E;
+
+ /* Get the TIMx CCER register value */
+ tmpccer = TIMx->CCER;
+ /* Get the TIMx CR2 register value */
+ tmpcr2 = TIMx->CR2;
+
+ /* Get the TIMx CCMR2 register value */
+ tmpccmrx = TIMx->CCMR2;
+
+ /* Reset the Output Compare mode and Capture/Compare selection Bits */
+ tmpccmrx &= (uint16_t)~TIM_CCMR2_OC3M;
+ tmpccmrx &= (uint16_t)~TIM_CCMR2_CC3S;
+ /* Select the Output Compare Mode */
+ tmpccmrx |= TIM_OCInitStruct->TIM_OCMode;
+
+ /* Reset the Output Polarity level */
+ tmpccer &= (uint16_t)~TIM_CCER_CC3P;
+ /* Set the Output Compare Polarity */
+ tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OCPolarity << 8);
+
+ /* Set the Output State */
+ tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OutputState << 8);
+
+ if((TIMx == TIM1) || (TIMx == TIM8))
+ {
+ assert_param(IS_TIM_OUTPUTN_STATE(TIM_OCInitStruct->TIM_OutputNState));
+ assert_param(IS_TIM_OCN_POLARITY(TIM_OCInitStruct->TIM_OCNPolarity));
+ assert_param(IS_TIM_OCNIDLE_STATE(TIM_OCInitStruct->TIM_OCNIdleState));
+ assert_param(IS_TIM_OCIDLE_STATE(TIM_OCInitStruct->TIM_OCIdleState));
+
+ /* Reset the Output N Polarity level */
+ tmpccer &= (uint16_t)~TIM_CCER_CC3NP;
+ /* Set the Output N Polarity */
+ tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OCNPolarity << 8);
+ /* Reset the Output N State */
+ tmpccer &= (uint16_t)~TIM_CCER_CC3NE;
+
+ /* Set the Output N State */
+ tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OutputNState << 8);
+ /* Reset the Output Compare and Output Compare N IDLE State */
+ tmpcr2 &= (uint16_t)~TIM_CR2_OIS3;
+ tmpcr2 &= (uint16_t)~TIM_CR2_OIS3N;
+ /* Set the Output Idle state */
+ tmpcr2 |= (uint16_t)(TIM_OCInitStruct->TIM_OCIdleState << 4);
+ /* Set the Output N Idle state */
+ tmpcr2 |= (uint16_t)(TIM_OCInitStruct->TIM_OCNIdleState << 4);
+ }
+ /* Write to TIMx CR2 */
+ TIMx->CR2 = tmpcr2;
+
+ /* Write to TIMx CCMR2 */
+ TIMx->CCMR2 = tmpccmrx;
+
+ /* Set the Capture Compare Register value */
+ TIMx->CCR3 = TIM_OCInitStruct->TIM_Pulse;
+
+ /* Write to TIMx CCER */
+ TIMx->CCER = tmpccer;
+}
+
+/**
+ * @brief Initializes the TIMx Channel4 according to the specified parameters
+ * in the TIM_OCInitStruct.
+ * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral.
+ * @param TIM_OCInitStruct: pointer to a TIM_OCInitTypeDef structure that contains
+ * the configuration information for the specified TIM peripheral.
+ * @retval None
+ */
+void TIM_OC4Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct)
+{
+ uint16_t tmpccmrx = 0, tmpccer = 0, tmpcr2 = 0;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+ assert_param(IS_TIM_OC_MODE(TIM_OCInitStruct->TIM_OCMode));
+ assert_param(IS_TIM_OUTPUT_STATE(TIM_OCInitStruct->TIM_OutputState));
+ assert_param(IS_TIM_OC_POLARITY(TIM_OCInitStruct->TIM_OCPolarity));
+
+ /* Disable the Channel 4: Reset the CC4E Bit */
+ TIMx->CCER &= (uint16_t)~TIM_CCER_CC4E;
+
+ /* Get the TIMx CCER register value */
+ tmpccer = TIMx->CCER;
+ /* Get the TIMx CR2 register value */
+ tmpcr2 = TIMx->CR2;
+
+ /* Get the TIMx CCMR2 register value */
+ tmpccmrx = TIMx->CCMR2;
+
+ /* Reset the Output Compare mode and Capture/Compare selection Bits */
+ tmpccmrx &= (uint16_t)~TIM_CCMR2_OC4M;
+ tmpccmrx &= (uint16_t)~TIM_CCMR2_CC4S;
+
+ /* Select the Output Compare Mode */
+ tmpccmrx |= (uint16_t)(TIM_OCInitStruct->TIM_OCMode << 8);
+
+ /* Reset the Output Polarity level */
+ tmpccer &= (uint16_t)~TIM_CCER_CC4P;
+ /* Set the Output Compare Polarity */
+ tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OCPolarity << 12);
+
+ /* Set the Output State */
+ tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OutputState << 12);
+
+ if((TIMx == TIM1) || (TIMx == TIM8))
+ {
+ assert_param(IS_TIM_OCIDLE_STATE(TIM_OCInitStruct->TIM_OCIdleState));
+ /* Reset the Output Compare IDLE State */
+ tmpcr2 &=(uint16_t) ~TIM_CR2_OIS4;
+ /* Set the Output Idle state */
+ tmpcr2 |= (uint16_t)(TIM_OCInitStruct->TIM_OCIdleState << 6);
+ }
+ /* Write to TIMx CR2 */
+ TIMx->CR2 = tmpcr2;
+
+ /* Write to TIMx CCMR2 */
+ TIMx->CCMR2 = tmpccmrx;
+
+ /* Set the Capture Compare Register value */
+ TIMx->CCR4 = TIM_OCInitStruct->TIM_Pulse;
+
+ /* Write to TIMx CCER */
+ TIMx->CCER = tmpccer;
+}
+
+/**
+ * @brief Fills each TIM_OCInitStruct member with its default value.
+ * @param TIM_OCInitStruct: pointer to a TIM_OCInitTypeDef structure which will
+ * be initialized.
+ * @retval None
+ */
+void TIM_OCStructInit(TIM_OCInitTypeDef* TIM_OCInitStruct)
+{
+ /* Set the default configuration */
+ TIM_OCInitStruct->TIM_OCMode = TIM_OCMode_Timing;
+ TIM_OCInitStruct->TIM_OutputState = TIM_OutputState_Disable;
+ TIM_OCInitStruct->TIM_OutputNState = TIM_OutputNState_Disable;
+ TIM_OCInitStruct->TIM_Pulse = 0x00000000;
+ TIM_OCInitStruct->TIM_OCPolarity = TIM_OCPolarity_High;
+ TIM_OCInitStruct->TIM_OCNPolarity = TIM_OCPolarity_High;
+ TIM_OCInitStruct->TIM_OCIdleState = TIM_OCIdleState_Reset;
+ TIM_OCInitStruct->TIM_OCNIdleState = TIM_OCNIdleState_Reset;
+}
+
+/**
+ * @brief Selects the TIM Output Compare Mode.
+ * @note This function disables the selected channel before changing the Output
+ * Compare Mode. If needed, user has to enable this channel using
+ * TIM_CCxCmd() and TIM_CCxNCmd() functions.
+ * @param TIMx: where x can be 1 to 14 except 6 and 7, to select the TIM peripheral.
+ * @param TIM_Channel: specifies the TIM Channel
+ * This parameter can be one of the following values:
+ * @arg TIM_Channel_1: TIM Channel 1
+ * @arg TIM_Channel_2: TIM Channel 2
+ * @arg TIM_Channel_3: TIM Channel 3
+ * @arg TIM_Channel_4: TIM Channel 4
+ * @param TIM_OCMode: specifies the TIM Output Compare Mode.
+ * This parameter can be one of the following values:
+ * @arg TIM_OCMode_Timing
+ * @arg TIM_OCMode_Active
+ * @arg TIM_OCMode_Toggle
+ * @arg TIM_OCMode_PWM1
+ * @arg TIM_OCMode_PWM2
+ * @arg TIM_ForcedAction_Active
+ * @arg TIM_ForcedAction_InActive
+ * @retval None
+ */
+void TIM_SelectOCxM(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_OCMode)
+{
+ uint32_t tmp = 0;
+ uint16_t tmp1 = 0;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST1_PERIPH(TIMx));
+ assert_param(IS_TIM_CHANNEL(TIM_Channel));
+ assert_param(IS_TIM_OCM(TIM_OCMode));
+
+ tmp = (uint32_t) TIMx;
+ tmp += CCMR_OFFSET;
+
+ tmp1 = CCER_CCE_SET << (uint16_t)TIM_Channel;
+
+ /* Disable the Channel: Reset the CCxE Bit */
+ TIMx->CCER &= (uint16_t) ~tmp1;
+
+ if((TIM_Channel == TIM_Channel_1) ||(TIM_Channel == TIM_Channel_3))
+ {
+ tmp += (TIM_Channel>>1);
+
+ /* Reset the OCxM bits in the CCMRx register */
+ *(__IO uint32_t *) tmp &= CCMR_OC13M_MASK;
+
+ /* Configure the OCxM bits in the CCMRx register */
+ *(__IO uint32_t *) tmp |= TIM_OCMode;
+ }
+ else
+ {
+ tmp += (uint16_t)(TIM_Channel - (uint16_t)4)>> (uint16_t)1;
+
+ /* Reset the OCxM bits in the CCMRx register */
+ *(__IO uint32_t *) tmp &= CCMR_OC24M_MASK;
+
+ /* Configure the OCxM bits in the CCMRx register */
+ *(__IO uint32_t *) tmp |= (uint16_t)(TIM_OCMode << 8);
+ }
+}
+
+/**
+ * @brief Sets the TIMx Capture Compare1 Register value
+ * @param TIMx: where x can be 1 to 14 except 6 and 7, to select the TIM peripheral.
+ * @param Compare1: specifies the Capture Compare1 register new value.
+ * @retval None
+ */
+void TIM_SetCompare1(TIM_TypeDef* TIMx, uint32_t Compare1)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST1_PERIPH(TIMx));
+
+ /* Set the Capture Compare1 Register value */
+ TIMx->CCR1 = Compare1;
+}
+
+/**
+ * @brief Sets the TIMx Capture Compare2 Register value
+ * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9 or 12 to select the TIM
+ * peripheral.
+ * @param Compare2: specifies the Capture Compare2 register new value.
+ * @retval None
+ */
+void TIM_SetCompare2(TIM_TypeDef* TIMx, uint32_t Compare2)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST2_PERIPH(TIMx));
+
+ /* Set the Capture Compare2 Register value */
+ TIMx->CCR2 = Compare2;
+}
+
+/**
+ * @brief Sets the TIMx Capture Compare3 Register value
+ * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral.
+ * @param Compare3: specifies the Capture Compare3 register new value.
+ * @retval None
+ */
+void TIM_SetCompare3(TIM_TypeDef* TIMx, uint32_t Compare3)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+
+ /* Set the Capture Compare3 Register value */
+ TIMx->CCR3 = Compare3;
+}
+
+/**
+ * @brief Sets the TIMx Capture Compare4 Register value
+ * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral.
+ * @param Compare4: specifies the Capture Compare4 register new value.
+ * @retval None
+ */
+void TIM_SetCompare4(TIM_TypeDef* TIMx, uint32_t Compare4)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+
+ /* Set the Capture Compare4 Register value */
+ TIMx->CCR4 = Compare4;
+}
+
+/**
+ * @brief Forces the TIMx output 1 waveform to active or inactive level.
+ * @param TIMx: where x can be 1 to 14 except 6 and 7, to select the TIM peripheral.
+ * @param TIM_ForcedAction: specifies the forced Action to be set to the output waveform.
+ * This parameter can be one of the following values:
+ * @arg TIM_ForcedAction_Active: Force active level on OC1REF
+ * @arg TIM_ForcedAction_InActive: Force inactive level on OC1REF.
+ * @retval None
+ */
+void TIM_ForcedOC1Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction)
+{
+ uint16_t tmpccmr1 = 0;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST1_PERIPH(TIMx));
+ assert_param(IS_TIM_FORCED_ACTION(TIM_ForcedAction));
+ tmpccmr1 = TIMx->CCMR1;
+
+ /* Reset the OC1M Bits */
+ tmpccmr1 &= (uint16_t)~TIM_CCMR1_OC1M;
+
+ /* Configure The Forced output Mode */
+ tmpccmr1 |= TIM_ForcedAction;
+
+ /* Write to TIMx CCMR1 register */
+ TIMx->CCMR1 = tmpccmr1;
+}
+
+/**
+ * @brief Forces the TIMx output 2 waveform to active or inactive level.
+ * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9 or 12 to select the TIM
+ * peripheral.
+ * @param TIM_ForcedAction: specifies the forced Action to be set to the output waveform.
+ * This parameter can be one of the following values:
+ * @arg TIM_ForcedAction_Active: Force active level on OC2REF
+ * @arg TIM_ForcedAction_InActive: Force inactive level on OC2REF.
+ * @retval None
+ */
+void TIM_ForcedOC2Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction)
+{
+ uint16_t tmpccmr1 = 0;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST2_PERIPH(TIMx));
+ assert_param(IS_TIM_FORCED_ACTION(TIM_ForcedAction));
+ tmpccmr1 = TIMx->CCMR1;
+
+ /* Reset the OC2M Bits */
+ tmpccmr1 &= (uint16_t)~TIM_CCMR1_OC2M;
+
+ /* Configure The Forced output Mode */
+ tmpccmr1 |= (uint16_t)(TIM_ForcedAction << 8);
+
+ /* Write to TIMx CCMR1 register */
+ TIMx->CCMR1 = tmpccmr1;
+}
+
+/**
+ * @brief Forces the TIMx output 3 waveform to active or inactive level.
+ * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral.
+ * @param TIM_ForcedAction: specifies the forced Action to be set to the output waveform.
+ * This parameter can be one of the following values:
+ * @arg TIM_ForcedAction_Active: Force active level on OC3REF
+ * @arg TIM_ForcedAction_InActive: Force inactive level on OC3REF.
+ * @retval None
+ */
+void TIM_ForcedOC3Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction)
+{
+ uint16_t tmpccmr2 = 0;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+ assert_param(IS_TIM_FORCED_ACTION(TIM_ForcedAction));
+
+ tmpccmr2 = TIMx->CCMR2;
+
+ /* Reset the OC1M Bits */
+ tmpccmr2 &= (uint16_t)~TIM_CCMR2_OC3M;
+
+ /* Configure The Forced output Mode */
+ tmpccmr2 |= TIM_ForcedAction;
+
+ /* Write to TIMx CCMR2 register */
+ TIMx->CCMR2 = tmpccmr2;
+}
+
+/**
+ * @brief Forces the TIMx output 4 waveform to active or inactive level.
+ * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral.
+ * @param TIM_ForcedAction: specifies the forced Action to be set to the output waveform.
+ * This parameter can be one of the following values:
+ * @arg TIM_ForcedAction_Active: Force active level on OC4REF
+ * @arg TIM_ForcedAction_InActive: Force inactive level on OC4REF.
+ * @retval None
+ */
+void TIM_ForcedOC4Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction)
+{
+ uint16_t tmpccmr2 = 0;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+ assert_param(IS_TIM_FORCED_ACTION(TIM_ForcedAction));
+ tmpccmr2 = TIMx->CCMR2;
+
+ /* Reset the OC2M Bits */
+ tmpccmr2 &= (uint16_t)~TIM_CCMR2_OC4M;
+
+ /* Configure The Forced output Mode */
+ tmpccmr2 |= (uint16_t)(TIM_ForcedAction << 8);
+
+ /* Write to TIMx CCMR2 register */
+ TIMx->CCMR2 = tmpccmr2;
+}
+
+/**
+ * @brief Enables or disables the TIMx peripheral Preload register on CCR1.
+ * @param TIMx: where x can be 1 to 14 except 6 and 7, to select the TIM peripheral.
+ * @param TIM_OCPreload: new state of the TIMx peripheral Preload register
+ * This parameter can be one of the following values:
+ * @arg TIM_OCPreload_Enable
+ * @arg TIM_OCPreload_Disable
+ * @retval None
+ */
+void TIM_OC1PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload)
+{
+ uint16_t tmpccmr1 = 0;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST1_PERIPH(TIMx));
+ assert_param(IS_TIM_OCPRELOAD_STATE(TIM_OCPreload));
+
+ tmpccmr1 = TIMx->CCMR1;
+
+ /* Reset the OC1PE Bit */
+ tmpccmr1 &= (uint16_t)(~TIM_CCMR1_OC1PE);
+
+ /* Enable or Disable the Output Compare Preload feature */
+ tmpccmr1 |= TIM_OCPreload;
+
+ /* Write to TIMx CCMR1 register */
+ TIMx->CCMR1 = tmpccmr1;
+}
+
+/**
+ * @brief Enables or disables the TIMx peripheral Preload register on CCR2.
+ * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9 or 12 to select the TIM
+ * peripheral.
+ * @param TIM_OCPreload: new state of the TIMx peripheral Preload register
+ * This parameter can be one of the following values:
+ * @arg TIM_OCPreload_Enable
+ * @arg TIM_OCPreload_Disable
+ * @retval None
+ */
+void TIM_OC2PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload)
+{
+ uint16_t tmpccmr1 = 0;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST2_PERIPH(TIMx));
+ assert_param(IS_TIM_OCPRELOAD_STATE(TIM_OCPreload));
+
+ tmpccmr1 = TIMx->CCMR1;
+
+ /* Reset the OC2PE Bit */
+ tmpccmr1 &= (uint16_t)(~TIM_CCMR1_OC2PE);
+
+ /* Enable or Disable the Output Compare Preload feature */
+ tmpccmr1 |= (uint16_t)(TIM_OCPreload << 8);
+
+ /* Write to TIMx CCMR1 register */
+ TIMx->CCMR1 = tmpccmr1;
+}
+
+/**
+ * @brief Enables or disables the TIMx peripheral Preload register on CCR3.
+ * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral.
+ * @param TIM_OCPreload: new state of the TIMx peripheral Preload register
+ * This parameter can be one of the following values:
+ * @arg TIM_OCPreload_Enable
+ * @arg TIM_OCPreload_Disable
+ * @retval None
+ */
+void TIM_OC3PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload)
+{
+ uint16_t tmpccmr2 = 0;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+ assert_param(IS_TIM_OCPRELOAD_STATE(TIM_OCPreload));
+
+ tmpccmr2 = TIMx->CCMR2;
+
+ /* Reset the OC3PE Bit */
+ tmpccmr2 &= (uint16_t)(~TIM_CCMR2_OC3PE);
+
+ /* Enable or Disable the Output Compare Preload feature */
+ tmpccmr2 |= TIM_OCPreload;
+
+ /* Write to TIMx CCMR2 register */
+ TIMx->CCMR2 = tmpccmr2;
+}
+
+/**
+ * @brief Enables or disables the TIMx peripheral Preload register on CCR4.
+ * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral.
+ * @param TIM_OCPreload: new state of the TIMx peripheral Preload register
+ * This parameter can be one of the following values:
+ * @arg TIM_OCPreload_Enable
+ * @arg TIM_OCPreload_Disable
+ * @retval None
+ */
+void TIM_OC4PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload)
+{
+ uint16_t tmpccmr2 = 0;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+ assert_param(IS_TIM_OCPRELOAD_STATE(TIM_OCPreload));
+
+ tmpccmr2 = TIMx->CCMR2;
+
+ /* Reset the OC4PE Bit */
+ tmpccmr2 &= (uint16_t)(~TIM_CCMR2_OC4PE);
+
+ /* Enable or Disable the Output Compare Preload feature */
+ tmpccmr2 |= (uint16_t)(TIM_OCPreload << 8);
+
+ /* Write to TIMx CCMR2 register */
+ TIMx->CCMR2 = tmpccmr2;
+}
+
+/**
+ * @brief Configures the TIMx Output Compare 1 Fast feature.
+ * @param TIMx: where x can be 1 to 14 except 6 and 7, to select the TIM peripheral.
+ * @param TIM_OCFast: new state of the Output Compare Fast Enable Bit.
+ * This parameter can be one of the following values:
+ * @arg TIM_OCFast_Enable: TIM output compare fast enable
+ * @arg TIM_OCFast_Disable: TIM output compare fast disable
+ * @retval None
+ */
+void TIM_OC1FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast)
+{
+ uint16_t tmpccmr1 = 0;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST1_PERIPH(TIMx));
+ assert_param(IS_TIM_OCFAST_STATE(TIM_OCFast));
+
+ /* Get the TIMx CCMR1 register value */
+ tmpccmr1 = TIMx->CCMR1;
+
+ /* Reset the OC1FE Bit */
+ tmpccmr1 &= (uint16_t)~TIM_CCMR1_OC1FE;
+
+ /* Enable or Disable the Output Compare Fast Bit */
+ tmpccmr1 |= TIM_OCFast;
+
+ /* Write to TIMx CCMR1 */
+ TIMx->CCMR1 = tmpccmr1;
+}
+
+/**
+ * @brief Configures the TIMx Output Compare 2 Fast feature.
+ * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9 or 12 to select the TIM
+ * peripheral.
+ * @param TIM_OCFast: new state of the Output Compare Fast Enable Bit.
+ * This parameter can be one of the following values:
+ * @arg TIM_OCFast_Enable: TIM output compare fast enable
+ * @arg TIM_OCFast_Disable: TIM output compare fast disable
+ * @retval None
+ */
+void TIM_OC2FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast)
+{
+ uint16_t tmpccmr1 = 0;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST2_PERIPH(TIMx));
+ assert_param(IS_TIM_OCFAST_STATE(TIM_OCFast));
+
+ /* Get the TIMx CCMR1 register value */
+ tmpccmr1 = TIMx->CCMR1;
+
+ /* Reset the OC2FE Bit */
+ tmpccmr1 &= (uint16_t)(~TIM_CCMR1_OC2FE);
+
+ /* Enable or Disable the Output Compare Fast Bit */
+ tmpccmr1 |= (uint16_t)(TIM_OCFast << 8);
+
+ /* Write to TIMx CCMR1 */
+ TIMx->CCMR1 = tmpccmr1;
+}
+
+/**
+ * @brief Configures the TIMx Output Compare 3 Fast feature.
+ * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral.
+ * @param TIM_OCFast: new state of the Output Compare Fast Enable Bit.
+ * This parameter can be one of the following values:
+ * @arg TIM_OCFast_Enable: TIM output compare fast enable
+ * @arg TIM_OCFast_Disable: TIM output compare fast disable
+ * @retval None
+ */
+void TIM_OC3FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast)
+{
+ uint16_t tmpccmr2 = 0;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+ assert_param(IS_TIM_OCFAST_STATE(TIM_OCFast));
+
+ /* Get the TIMx CCMR2 register value */
+ tmpccmr2 = TIMx->CCMR2;
+
+ /* Reset the OC3FE Bit */
+ tmpccmr2 &= (uint16_t)~TIM_CCMR2_OC3FE;
+
+ /* Enable or Disable the Output Compare Fast Bit */
+ tmpccmr2 |= TIM_OCFast;
+
+ /* Write to TIMx CCMR2 */
+ TIMx->CCMR2 = tmpccmr2;
+}
+
+/**
+ * @brief Configures the TIMx Output Compare 4 Fast feature.
+ * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral.
+ * @param TIM_OCFast: new state of the Output Compare Fast Enable Bit.
+ * This parameter can be one of the following values:
+ * @arg TIM_OCFast_Enable: TIM output compare fast enable
+ * @arg TIM_OCFast_Disable: TIM output compare fast disable
+ * @retval None
+ */
+void TIM_OC4FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast)
+{
+ uint16_t tmpccmr2 = 0;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+ assert_param(IS_TIM_OCFAST_STATE(TIM_OCFast));
+
+ /* Get the TIMx CCMR2 register value */
+ tmpccmr2 = TIMx->CCMR2;
+
+ /* Reset the OC4FE Bit */
+ tmpccmr2 &= (uint16_t)(~TIM_CCMR2_OC4FE);
+
+ /* Enable or Disable the Output Compare Fast Bit */
+ tmpccmr2 |= (uint16_t)(TIM_OCFast << 8);
+
+ /* Write to TIMx CCMR2 */
+ TIMx->CCMR2 = tmpccmr2;
+}
+
+/**
+ * @brief Clears or safeguards the OCREF1 signal on an external event
+ * @param TIMx: where x can be 1 to 14 except 6 and 7, to select the TIM peripheral.
+ * @param TIM_OCClear: new state of the Output Compare Clear Enable Bit.
+ * This parameter can be one of the following values:
+ * @arg TIM_OCClear_Enable: TIM Output clear enable
+ * @arg TIM_OCClear_Disable: TIM Output clear disable
+ * @retval None
+ */
+void TIM_ClearOC1Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear)
+{
+ uint16_t tmpccmr1 = 0;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST1_PERIPH(TIMx));
+ assert_param(IS_TIM_OCCLEAR_STATE(TIM_OCClear));
+
+ tmpccmr1 = TIMx->CCMR1;
+
+ /* Reset the OC1CE Bit */
+ tmpccmr1 &= (uint16_t)~TIM_CCMR1_OC1CE;
+
+ /* Enable or Disable the Output Compare Clear Bit */
+ tmpccmr1 |= TIM_OCClear;
+
+ /* Write to TIMx CCMR1 register */
+ TIMx->CCMR1 = tmpccmr1;
+}
+
+/**
+ * @brief Clears or safeguards the OCREF2 signal on an external event
+ * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9 or 12 to select the TIM
+ * peripheral.
+ * @param TIM_OCClear: new state of the Output Compare Clear Enable Bit.
+ * This parameter can be one of the following values:
+ * @arg TIM_OCClear_Enable: TIM Output clear enable
+ * @arg TIM_OCClear_Disable: TIM Output clear disable
+ * @retval None
+ */
+void TIM_ClearOC2Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear)
+{
+ uint16_t tmpccmr1 = 0;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST2_PERIPH(TIMx));
+ assert_param(IS_TIM_OCCLEAR_STATE(TIM_OCClear));
+
+ tmpccmr1 = TIMx->CCMR1;
+
+ /* Reset the OC2CE Bit */
+ tmpccmr1 &= (uint16_t)~TIM_CCMR1_OC2CE;
+
+ /* Enable or Disable the Output Compare Clear Bit */
+ tmpccmr1 |= (uint16_t)(TIM_OCClear << 8);
+
+ /* Write to TIMx CCMR1 register */
+ TIMx->CCMR1 = tmpccmr1;
+}
+
+/**
+ * @brief Clears or safeguards the OCREF3 signal on an external event
+ * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral.
+ * @param TIM_OCClear: new state of the Output Compare Clear Enable Bit.
+ * This parameter can be one of the following values:
+ * @arg TIM_OCClear_Enable: TIM Output clear enable
+ * @arg TIM_OCClear_Disable: TIM Output clear disable
+ * @retval None
+ */
+void TIM_ClearOC3Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear)
+{
+ uint16_t tmpccmr2 = 0;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+ assert_param(IS_TIM_OCCLEAR_STATE(TIM_OCClear));
+
+ tmpccmr2 = TIMx->CCMR2;
+
+ /* Reset the OC3CE Bit */
+ tmpccmr2 &= (uint16_t)~TIM_CCMR2_OC3CE;
+
+ /* Enable or Disable the Output Compare Clear Bit */
+ tmpccmr2 |= TIM_OCClear;
+
+ /* Write to TIMx CCMR2 register */
+ TIMx->CCMR2 = tmpccmr2;
+}
+
+/**
+ * @brief Clears or safeguards the OCREF4 signal on an external event
+ * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral.
+ * @param TIM_OCClear: new state of the Output Compare Clear Enable Bit.
+ * This parameter can be one of the following values:
+ * @arg TIM_OCClear_Enable: TIM Output clear enable
+ * @arg TIM_OCClear_Disable: TIM Output clear disable
+ * @retval None
+ */
+void TIM_ClearOC4Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear)
+{
+ uint16_t tmpccmr2 = 0;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+ assert_param(IS_TIM_OCCLEAR_STATE(TIM_OCClear));
+
+ tmpccmr2 = TIMx->CCMR2;
+
+ /* Reset the OC4CE Bit */
+ tmpccmr2 &= (uint16_t)~TIM_CCMR2_OC4CE;
+
+ /* Enable or Disable the Output Compare Clear Bit */
+ tmpccmr2 |= (uint16_t)(TIM_OCClear << 8);
+
+ /* Write to TIMx CCMR2 register */
+ TIMx->CCMR2 = tmpccmr2;
+}
+
+/**
+ * @brief Configures the TIMx channel 1 polarity.
+ * @param TIMx: where x can be 1 to 14 except 6 and 7, to select the TIM peripheral.
+ * @param TIM_OCPolarity: specifies the OC1 Polarity
+ * This parameter can be one of the following values:
+ * @arg TIM_OCPolarity_High: Output Compare active high
+ * @arg TIM_OCPolarity_Low: Output Compare active low
+ * @retval None
+ */
+void TIM_OC1PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity)
+{
+ uint16_t tmpccer = 0;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST1_PERIPH(TIMx));
+ assert_param(IS_TIM_OC_POLARITY(TIM_OCPolarity));
+
+ tmpccer = TIMx->CCER;
+
+ /* Set or Reset the CC1P Bit */
+ tmpccer &= (uint16_t)(~TIM_CCER_CC1P);
+ tmpccer |= TIM_OCPolarity;
+
+ /* Write to TIMx CCER register */
+ TIMx->CCER = tmpccer;
+}
+
+/**
+ * @brief Configures the TIMx Channel 1N polarity.
+ * @param TIMx: where x can be 1 or 8 to select the TIM peripheral.
+ * @param TIM_OCNPolarity: specifies the OC1N Polarity
+ * This parameter can be one of the following values:
+ * @arg TIM_OCNPolarity_High: Output Compare active high
+ * @arg TIM_OCNPolarity_Low: Output Compare active low
+ * @retval None
+ */
+void TIM_OC1NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity)
+{
+ uint16_t tmpccer = 0;
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST4_PERIPH(TIMx));
+ assert_param(IS_TIM_OCN_POLARITY(TIM_OCNPolarity));
+
+ tmpccer = TIMx->CCER;
+
+ /* Set or Reset the CC1NP Bit */
+ tmpccer &= (uint16_t)~TIM_CCER_CC1NP;
+ tmpccer |= TIM_OCNPolarity;
+
+ /* Write to TIMx CCER register */
+ TIMx->CCER = tmpccer;
+}
+
+/**
+ * @brief Configures the TIMx channel 2 polarity.
+ * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9 or 12 to select the TIM
+ * peripheral.
+ * @param TIM_OCPolarity: specifies the OC2 Polarity
+ * This parameter can be one of the following values:
+ * @arg TIM_OCPolarity_High: Output Compare active high
+ * @arg TIM_OCPolarity_Low: Output Compare active low
+ * @retval None
+ */
+void TIM_OC2PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity)
+{
+ uint16_t tmpccer = 0;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST2_PERIPH(TIMx));
+ assert_param(IS_TIM_OC_POLARITY(TIM_OCPolarity));
+
+ tmpccer = TIMx->CCER;
+
+ /* Set or Reset the CC2P Bit */
+ tmpccer &= (uint16_t)(~TIM_CCER_CC2P);
+ tmpccer |= (uint16_t)(TIM_OCPolarity << 4);
+
+ /* Write to TIMx CCER register */
+ TIMx->CCER = tmpccer;
+}
+
+/**
+ * @brief Configures the TIMx Channel 2N polarity.
+ * @param TIMx: where x can be 1 or 8 to select the TIM peripheral.
+ * @param TIM_OCNPolarity: specifies the OC2N Polarity
+ * This parameter can be one of the following values:
+ * @arg TIM_OCNPolarity_High: Output Compare active high
+ * @arg TIM_OCNPolarity_Low: Output Compare active low
+ * @retval None
+ */
+void TIM_OC2NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity)
+{
+ uint16_t tmpccer = 0;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST4_PERIPH(TIMx));
+ assert_param(IS_TIM_OCN_POLARITY(TIM_OCNPolarity));
+
+ tmpccer = TIMx->CCER;
+
+ /* Set or Reset the CC2NP Bit */
+ tmpccer &= (uint16_t)~TIM_CCER_CC2NP;
+ tmpccer |= (uint16_t)(TIM_OCNPolarity << 4);
+
+ /* Write to TIMx CCER register */
+ TIMx->CCER = tmpccer;
+}
+
+/**
+ * @brief Configures the TIMx channel 3 polarity.
+ * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral.
+ * @param TIM_OCPolarity: specifies the OC3 Polarity
+ * This parameter can be one of the following values:
+ * @arg TIM_OCPolarity_High: Output Compare active high
+ * @arg TIM_OCPolarity_Low: Output Compare active low
+ * @retval None
+ */
+void TIM_OC3PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity)
+{
+ uint16_t tmpccer = 0;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+ assert_param(IS_TIM_OC_POLARITY(TIM_OCPolarity));
+
+ tmpccer = TIMx->CCER;
+
+ /* Set or Reset the CC3P Bit */
+ tmpccer &= (uint16_t)~TIM_CCER_CC3P;
+ tmpccer |= (uint16_t)(TIM_OCPolarity << 8);
+
+ /* Write to TIMx CCER register */
+ TIMx->CCER = tmpccer;
+}
+
+/**
+ * @brief Configures the TIMx Channel 3N polarity.
+ * @param TIMx: where x can be 1 or 8 to select the TIM peripheral.
+ * @param TIM_OCNPolarity: specifies the OC3N Polarity
+ * This parameter can be one of the following values:
+ * @arg TIM_OCNPolarity_High: Output Compare active high
+ * @arg TIM_OCNPolarity_Low: Output Compare active low
+ * @retval None
+ */
+void TIM_OC3NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity)
+{
+ uint16_t tmpccer = 0;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST4_PERIPH(TIMx));
+ assert_param(IS_TIM_OCN_POLARITY(TIM_OCNPolarity));
+
+ tmpccer = TIMx->CCER;
+
+ /* Set or Reset the CC3NP Bit */
+ tmpccer &= (uint16_t)~TIM_CCER_CC3NP;
+ tmpccer |= (uint16_t)(TIM_OCNPolarity << 8);
+
+ /* Write to TIMx CCER register */
+ TIMx->CCER = tmpccer;
+}
+
+/**
+ * @brief Configures the TIMx channel 4 polarity.
+ * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral.
+ * @param TIM_OCPolarity: specifies the OC4 Polarity
+ * This parameter can be one of the following values:
+ * @arg TIM_OCPolarity_High: Output Compare active high
+ * @arg TIM_OCPolarity_Low: Output Compare active low
+ * @retval None
+ */
+void TIM_OC4PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity)
+{
+ uint16_t tmpccer = 0;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+ assert_param(IS_TIM_OC_POLARITY(TIM_OCPolarity));
+
+ tmpccer = TIMx->CCER;
+
+ /* Set or Reset the CC4P Bit */
+ tmpccer &= (uint16_t)~TIM_CCER_CC4P;
+ tmpccer |= (uint16_t)(TIM_OCPolarity << 12);
+
+ /* Write to TIMx CCER register */
+ TIMx->CCER = tmpccer;
+}
+
+/**
+ * @brief Enables or disables the TIM Capture Compare Channel x.
+ * @param TIMx: where x can be 1 to 14 except 6 and 7, to select the TIM peripheral.
+ * @param TIM_Channel: specifies the TIM Channel
+ * This parameter can be one of the following values:
+ * @arg TIM_Channel_1: TIM Channel 1
+ * @arg TIM_Channel_2: TIM Channel 2
+ * @arg TIM_Channel_3: TIM Channel 3
+ * @arg TIM_Channel_4: TIM Channel 4
+ * @param TIM_CCx: specifies the TIM Channel CCxE bit new state.
+ * This parameter can be: TIM_CCx_Enable or TIM_CCx_Disable.
+ * @retval None
+ */
+void TIM_CCxCmd(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_CCx)
+{
+ uint16_t tmp = 0;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST1_PERIPH(TIMx));
+ assert_param(IS_TIM_CHANNEL(TIM_Channel));
+ assert_param(IS_TIM_CCX(TIM_CCx));
+
+ tmp = CCER_CCE_SET << TIM_Channel;
+
+ /* Reset the CCxE Bit */
+ TIMx->CCER &= (uint16_t)~ tmp;
+
+ /* Set or reset the CCxE Bit */
+ TIMx->CCER |= (uint16_t)(TIM_CCx << TIM_Channel);
+}
+
+/**
+ * @brief Enables or disables the TIM Capture Compare Channel xN.
+ * @param TIMx: where x can be 1 or 8 to select the TIM peripheral.
+ * @param TIM_Channel: specifies the TIM Channel
+ * This parameter can be one of the following values:
+ * @arg TIM_Channel_1: TIM Channel 1
+ * @arg TIM_Channel_2: TIM Channel 2
+ * @arg TIM_Channel_3: TIM Channel 3
+ * @param TIM_CCxN: specifies the TIM Channel CCxNE bit new state.
+ * This parameter can be: TIM_CCxN_Enable or TIM_CCxN_Disable.
+ * @retval None
+ */
+void TIM_CCxNCmd(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_CCxN)
+{
+ uint16_t tmp = 0;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST4_PERIPH(TIMx));
+ assert_param(IS_TIM_COMPLEMENTARY_CHANNEL(TIM_Channel));
+ assert_param(IS_TIM_CCXN(TIM_CCxN));
+
+ tmp = CCER_CCNE_SET << TIM_Channel;
+
+ /* Reset the CCxNE Bit */
+ TIMx->CCER &= (uint16_t) ~tmp;
+
+ /* Set or reset the CCxNE Bit */
+ TIMx->CCER |= (uint16_t)(TIM_CCxN << TIM_Channel);
+}
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Group3 Input Capture management functions
+ * @brief Input Capture management functions
+ *
+@verbatim
+ ===============================================================================
+ Input Capture management functions
+ ===============================================================================
+
+ ===================================================================
+ TIM Driver: how to use it in Input Capture Mode
+ ===================================================================
+ To use the Timer in Input Capture mode, the following steps are mandatory:
+
+ 1. Enable TIM clock using RCC_APBxPeriphClockCmd(RCC_APBxPeriph_TIMx, ENABLE) function
+
+ 2. Configure the TIM pins by configuring the corresponding GPIO pins
+
+ 2. Configure the Time base unit as described in the first part of this driver,
+ if needed, else the Timer will run with the default configuration:
+ - Autoreload value = 0xFFFF
+ - Prescaler value = 0x0000
+ - Counter mode = Up counting
+ - Clock Division = TIM_CKD_DIV1
+
+ 3. Fill the TIM_ICInitStruct with the desired parameters including:
+ - TIM Channel: TIM_Channel
+ - TIM Input Capture polarity: TIM_ICPolarity
+ - TIM Input Capture selection: TIM_ICSelection
+ - TIM Input Capture Prescaler: TIM_ICPrescaler
+ - TIM Input CApture filter value: TIM_ICFilter
+
+ 4. Call TIM_ICInit(TIMx, &TIM_ICInitStruct) to configure the desired channel with the
+ corresponding configuration and to measure only frequency or duty cycle of the input signal,
+ or,
+ Call TIM_PWMIConfig(TIMx, &TIM_ICInitStruct) to configure the desired channels with the
+ corresponding configuration and to measure the frequency and the duty cycle of the input signal
+
+ 5. Enable the NVIC or the DMA to read the measured frequency.
+
+ 6. Enable the corresponding interrupt (or DMA request) to read the Captured value,
+ using the function TIM_ITConfig(TIMx, TIM_IT_CCx) (or TIM_DMA_Cmd(TIMx, TIM_DMA_CCx))
+
+ 7. Call the TIM_Cmd(ENABLE) function to enable the TIM counter.
+
+ 8. Use TIM_GetCapturex(TIMx); to read the captured value.
+
+ Note1: All other functions can be used separately to modify, if needed,
+ a specific feature of the Timer.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Initializes the TIM peripheral according to the specified parameters
+ * in the TIM_ICInitStruct.
+ * @param TIMx: where x can be 1 to 14 except 6 and 7, to select the TIM peripheral.
+ * @param TIM_ICInitStruct: pointer to a TIM_ICInitTypeDef structure that contains
+ * the configuration information for the specified TIM peripheral.
+ * @retval None
+ */
+void TIM_ICInit(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST1_PERIPH(TIMx));
+ assert_param(IS_TIM_IC_POLARITY(TIM_ICInitStruct->TIM_ICPolarity));
+ assert_param(IS_TIM_IC_SELECTION(TIM_ICInitStruct->TIM_ICSelection));
+ assert_param(IS_TIM_IC_PRESCALER(TIM_ICInitStruct->TIM_ICPrescaler));
+ assert_param(IS_TIM_IC_FILTER(TIM_ICInitStruct->TIM_ICFilter));
+
+ if (TIM_ICInitStruct->TIM_Channel == TIM_Channel_1)
+ {
+ /* TI1 Configuration */
+ TI1_Config(TIMx, TIM_ICInitStruct->TIM_ICPolarity,
+ TIM_ICInitStruct->TIM_ICSelection,
+ TIM_ICInitStruct->TIM_ICFilter);
+ /* Set the Input Capture Prescaler value */
+ TIM_SetIC1Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler);
+ }
+ else if (TIM_ICInitStruct->TIM_Channel == TIM_Channel_2)
+ {
+ /* TI2 Configuration */
+ assert_param(IS_TIM_LIST2_PERIPH(TIMx));
+ TI2_Config(TIMx, TIM_ICInitStruct->TIM_ICPolarity,
+ TIM_ICInitStruct->TIM_ICSelection,
+ TIM_ICInitStruct->TIM_ICFilter);
+ /* Set the Input Capture Prescaler value */
+ TIM_SetIC2Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler);
+ }
+ else if (TIM_ICInitStruct->TIM_Channel == TIM_Channel_3)
+ {
+ /* TI3 Configuration */
+ assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+ TI3_Config(TIMx, TIM_ICInitStruct->TIM_ICPolarity,
+ TIM_ICInitStruct->TIM_ICSelection,
+ TIM_ICInitStruct->TIM_ICFilter);
+ /* Set the Input Capture Prescaler value */
+ TIM_SetIC3Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler);
+ }
+ else
+ {
+ /* TI4 Configuration */
+ assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+ TI4_Config(TIMx, TIM_ICInitStruct->TIM_ICPolarity,
+ TIM_ICInitStruct->TIM_ICSelection,
+ TIM_ICInitStruct->TIM_ICFilter);
+ /* Set the Input Capture Prescaler value */
+ TIM_SetIC4Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler);
+ }
+}
+
+/**
+ * @brief Fills each TIM_ICInitStruct member with its default value.
+ * @param TIM_ICInitStruct: pointer to a TIM_ICInitTypeDef structure which will
+ * be initialized.
+ * @retval None
+ */
+void TIM_ICStructInit(TIM_ICInitTypeDef* TIM_ICInitStruct)
+{
+ /* Set the default configuration */
+ TIM_ICInitStruct->TIM_Channel = TIM_Channel_1;
+ TIM_ICInitStruct->TIM_ICPolarity = TIM_ICPolarity_Rising;
+ TIM_ICInitStruct->TIM_ICSelection = TIM_ICSelection_DirectTI;
+ TIM_ICInitStruct->TIM_ICPrescaler = TIM_ICPSC_DIV1;
+ TIM_ICInitStruct->TIM_ICFilter = 0x00;
+}
+
+/**
+ * @brief Configures the TIM peripheral according to the specified parameters
+ * in the TIM_ICInitStruct to measure an external PWM signal.
+ * @param TIMx: where x can be 1, 2, 3, 4, 5,8, 9 or 12 to select the TIM
+ * peripheral.
+ * @param TIM_ICInitStruct: pointer to a TIM_ICInitTypeDef structure that contains
+ * the configuration information for the specified TIM peripheral.
+ * @retval None
+ */
+void TIM_PWMIConfig(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct)
+{
+ uint16_t icoppositepolarity = TIM_ICPolarity_Rising;
+ uint16_t icoppositeselection = TIM_ICSelection_DirectTI;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST2_PERIPH(TIMx));
+
+ /* Select the Opposite Input Polarity */
+ if (TIM_ICInitStruct->TIM_ICPolarity == TIM_ICPolarity_Rising)
+ {
+ icoppositepolarity = TIM_ICPolarity_Falling;
+ }
+ else
+ {
+ icoppositepolarity = TIM_ICPolarity_Rising;
+ }
+ /* Select the Opposite Input */
+ if (TIM_ICInitStruct->TIM_ICSelection == TIM_ICSelection_DirectTI)
+ {
+ icoppositeselection = TIM_ICSelection_IndirectTI;
+ }
+ else
+ {
+ icoppositeselection = TIM_ICSelection_DirectTI;
+ }
+ if (TIM_ICInitStruct->TIM_Channel == TIM_Channel_1)
+ {
+ /* TI1 Configuration */
+ TI1_Config(TIMx, TIM_ICInitStruct->TIM_ICPolarity, TIM_ICInitStruct->TIM_ICSelection,
+ TIM_ICInitStruct->TIM_ICFilter);
+ /* Set the Input Capture Prescaler value */
+ TIM_SetIC1Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler);
+ /* TI2 Configuration */
+ TI2_Config(TIMx, icoppositepolarity, icoppositeselection, TIM_ICInitStruct->TIM_ICFilter);
+ /* Set the Input Capture Prescaler value */
+ TIM_SetIC2Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler);
+ }
+ else
+ {
+ /* TI2 Configuration */
+ TI2_Config(TIMx, TIM_ICInitStruct->TIM_ICPolarity, TIM_ICInitStruct->TIM_ICSelection,
+ TIM_ICInitStruct->TIM_ICFilter);
+ /* Set the Input Capture Prescaler value */
+ TIM_SetIC2Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler);
+ /* TI1 Configuration */
+ TI1_Config(TIMx, icoppositepolarity, icoppositeselection, TIM_ICInitStruct->TIM_ICFilter);
+ /* Set the Input Capture Prescaler value */
+ TIM_SetIC1Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler);
+ }
+}
+
+/**
+ * @brief Gets the TIMx Input Capture 1 value.
+ * @param TIMx: where x can be 1 to 14 except 6 and 7, to select the TIM peripheral.
+ * @retval Capture Compare 1 Register value.
+ */
+uint32_t TIM_GetCapture1(TIM_TypeDef* TIMx)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST1_PERIPH(TIMx));
+
+ /* Get the Capture 1 Register value */
+ return TIMx->CCR1;
+}
+
+/**
+ * @brief Gets the TIMx Input Capture 2 value.
+ * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9 or 12 to select the TIM
+ * peripheral.
+ * @retval Capture Compare 2 Register value.
+ */
+uint32_t TIM_GetCapture2(TIM_TypeDef* TIMx)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST2_PERIPH(TIMx));
+
+ /* Get the Capture 2 Register value */
+ return TIMx->CCR2;
+}
+
+/**
+ * @brief Gets the TIMx Input Capture 3 value.
+ * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral.
+ * @retval Capture Compare 3 Register value.
+ */
+uint32_t TIM_GetCapture3(TIM_TypeDef* TIMx)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+
+ /* Get the Capture 3 Register value */
+ return TIMx->CCR3;
+}
+
+/**
+ * @brief Gets the TIMx Input Capture 4 value.
+ * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral.
+ * @retval Capture Compare 4 Register value.
+ */
+uint32_t TIM_GetCapture4(TIM_TypeDef* TIMx)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+
+ /* Get the Capture 4 Register value */
+ return TIMx->CCR4;
+}
+
+/**
+ * @brief Sets the TIMx Input Capture 1 prescaler.
+ * @param TIMx: where x can be 1 to 14 except 6 and 7, to select the TIM peripheral.
+ * @param TIM_ICPSC: specifies the Input Capture1 prescaler new value.
+ * This parameter can be one of the following values:
+ * @arg TIM_ICPSC_DIV1: no prescaler
+ * @arg TIM_ICPSC_DIV2: capture is done once every 2 events
+ * @arg TIM_ICPSC_DIV4: capture is done once every 4 events
+ * @arg TIM_ICPSC_DIV8: capture is done once every 8 events
+ * @retval None
+ */
+void TIM_SetIC1Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST1_PERIPH(TIMx));
+ assert_param(IS_TIM_IC_PRESCALER(TIM_ICPSC));
+
+ /* Reset the IC1PSC Bits */
+ TIMx->CCMR1 &= (uint16_t)~TIM_CCMR1_IC1PSC;
+
+ /* Set the IC1PSC value */
+ TIMx->CCMR1 |= TIM_ICPSC;
+}
+
+/**
+ * @brief Sets the TIMx Input Capture 2 prescaler.
+ * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9 or 12 to select the TIM
+ * peripheral.
+ * @param TIM_ICPSC: specifies the Input Capture2 prescaler new value.
+ * This parameter can be one of the following values:
+ * @arg TIM_ICPSC_DIV1: no prescaler
+ * @arg TIM_ICPSC_DIV2: capture is done once every 2 events
+ * @arg TIM_ICPSC_DIV4: capture is done once every 4 events
+ * @arg TIM_ICPSC_DIV8: capture is done once every 8 events
+ * @retval None
+ */
+void TIM_SetIC2Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST2_PERIPH(TIMx));
+ assert_param(IS_TIM_IC_PRESCALER(TIM_ICPSC));
+
+ /* Reset the IC2PSC Bits */
+ TIMx->CCMR1 &= (uint16_t)~TIM_CCMR1_IC2PSC;
+
+ /* Set the IC2PSC value */
+ TIMx->CCMR1 |= (uint16_t)(TIM_ICPSC << 8);
+}
+
+/**
+ * @brief Sets the TIMx Input Capture 3 prescaler.
+ * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral.
+ * @param TIM_ICPSC: specifies the Input Capture3 prescaler new value.
+ * This parameter can be one of the following values:
+ * @arg TIM_ICPSC_DIV1: no prescaler
+ * @arg TIM_ICPSC_DIV2: capture is done once every 2 events
+ * @arg TIM_ICPSC_DIV4: capture is done once every 4 events
+ * @arg TIM_ICPSC_DIV8: capture is done once every 8 events
+ * @retval None
+ */
+void TIM_SetIC3Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+ assert_param(IS_TIM_IC_PRESCALER(TIM_ICPSC));
+
+ /* Reset the IC3PSC Bits */
+ TIMx->CCMR2 &= (uint16_t)~TIM_CCMR2_IC3PSC;
+
+ /* Set the IC3PSC value */
+ TIMx->CCMR2 |= TIM_ICPSC;
+}
+
+/**
+ * @brief Sets the TIMx Input Capture 4 prescaler.
+ * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral.
+ * @param TIM_ICPSC: specifies the Input Capture4 prescaler new value.
+ * This parameter can be one of the following values:
+ * @arg TIM_ICPSC_DIV1: no prescaler
+ * @arg TIM_ICPSC_DIV2: capture is done once every 2 events
+ * @arg TIM_ICPSC_DIV4: capture is done once every 4 events
+ * @arg TIM_ICPSC_DIV8: capture is done once every 8 events
+ * @retval None
+ */
+void TIM_SetIC4Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+ assert_param(IS_TIM_IC_PRESCALER(TIM_ICPSC));
+
+ /* Reset the IC4PSC Bits */
+ TIMx->CCMR2 &= (uint16_t)~TIM_CCMR2_IC4PSC;
+
+ /* Set the IC4PSC value */
+ TIMx->CCMR2 |= (uint16_t)(TIM_ICPSC << 8);
+}
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Group4 Advanced-control timers (TIM1 and TIM8) specific features
+ * @brief Advanced-control timers (TIM1 and TIM8) specific features
+ *
+@verbatim
+ ===============================================================================
+ Advanced-control timers (TIM1 and TIM8) specific features
+ ===============================================================================
+
+ ===================================================================
+ TIM Driver: how to use the Break feature
+ ===================================================================
+ After configuring the Timer channel(s) in the appropriate Output Compare mode:
+
+ 1. Fill the TIM_BDTRInitStruct with the desired parameters for the Timer
+ Break Polarity, dead time, Lock level, the OSSI/OSSR State and the
+ AOE(automatic output enable).
+
+ 2. Call TIM_BDTRConfig(TIMx, &TIM_BDTRInitStruct) to configure the Timer
+
+ 3. Enable the Main Output using TIM_CtrlPWMOutputs(TIM1, ENABLE)
+
+ 4. Once the break even occurs, the Timer's output signals are put in reset
+ state or in a known state (according to the configuration made in
+ TIM_BDTRConfig() function).
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Configures the Break feature, dead time, Lock level, OSSI/OSSR State
+ * and the AOE(automatic output enable).
+ * @param TIMx: where x can be 1 or 8 to select the TIM
+ * @param TIM_BDTRInitStruct: pointer to a TIM_BDTRInitTypeDef structure that
+ * contains the BDTR Register configuration information for the TIM peripheral.
+ * @retval None
+ */
+void TIM_BDTRConfig(TIM_TypeDef* TIMx, TIM_BDTRInitTypeDef *TIM_BDTRInitStruct)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST4_PERIPH(TIMx));
+ assert_param(IS_TIM_OSSR_STATE(TIM_BDTRInitStruct->TIM_OSSRState));
+ assert_param(IS_TIM_OSSI_STATE(TIM_BDTRInitStruct->TIM_OSSIState));
+ assert_param(IS_TIM_LOCK_LEVEL(TIM_BDTRInitStruct->TIM_LOCKLevel));
+ assert_param(IS_TIM_BREAK_STATE(TIM_BDTRInitStruct->TIM_Break));
+ assert_param(IS_TIM_BREAK_POLARITY(TIM_BDTRInitStruct->TIM_BreakPolarity));
+ assert_param(IS_TIM_AUTOMATIC_OUTPUT_STATE(TIM_BDTRInitStruct->TIM_AutomaticOutput));
+
+ /* Set the Lock level, the Break enable Bit and the Polarity, the OSSR State,
+ the OSSI State, the dead time value and the Automatic Output Enable Bit */
+ TIMx->BDTR = (uint32_t)TIM_BDTRInitStruct->TIM_OSSRState | TIM_BDTRInitStruct->TIM_OSSIState |
+ TIM_BDTRInitStruct->TIM_LOCKLevel | TIM_BDTRInitStruct->TIM_DeadTime |
+ TIM_BDTRInitStruct->TIM_Break | TIM_BDTRInitStruct->TIM_BreakPolarity |
+ TIM_BDTRInitStruct->TIM_AutomaticOutput;
+}
+
+/**
+ * @brief Fills each TIM_BDTRInitStruct member with its default value.
+ * @param TIM_BDTRInitStruct: pointer to a TIM_BDTRInitTypeDef structure which
+ * will be initialized.
+ * @retval None
+ */
+void TIM_BDTRStructInit(TIM_BDTRInitTypeDef* TIM_BDTRInitStruct)
+{
+ /* Set the default configuration */
+ TIM_BDTRInitStruct->TIM_OSSRState = TIM_OSSRState_Disable;
+ TIM_BDTRInitStruct->TIM_OSSIState = TIM_OSSIState_Disable;
+ TIM_BDTRInitStruct->TIM_LOCKLevel = TIM_LOCKLevel_OFF;
+ TIM_BDTRInitStruct->TIM_DeadTime = 0x00;
+ TIM_BDTRInitStruct->TIM_Break = TIM_Break_Disable;
+ TIM_BDTRInitStruct->TIM_BreakPolarity = TIM_BreakPolarity_Low;
+ TIM_BDTRInitStruct->TIM_AutomaticOutput = TIM_AutomaticOutput_Disable;
+}
+
+/**
+ * @brief Enables or disables the TIM peripheral Main Outputs.
+ * @param TIMx: where x can be 1 or 8 to select the TIMx peripheral.
+ * @param NewState: new state of the TIM peripheral Main Outputs.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void TIM_CtrlPWMOutputs(TIM_TypeDef* TIMx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST4_PERIPH(TIMx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the TIM Main Output */
+ TIMx->BDTR |= TIM_BDTR_MOE;
+ }
+ else
+ {
+ /* Disable the TIM Main Output */
+ TIMx->BDTR &= (uint16_t)~TIM_BDTR_MOE;
+ }
+}
+
+/**
+ * @brief Selects the TIM peripheral Commutation event.
+ * @param TIMx: where x can be 1 or 8 to select the TIMx peripheral
+ * @param NewState: new state of the Commutation event.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void TIM_SelectCOM(TIM_TypeDef* TIMx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST4_PERIPH(TIMx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Set the COM Bit */
+ TIMx->CR2 |= TIM_CR2_CCUS;
+ }
+ else
+ {
+ /* Reset the COM Bit */
+ TIMx->CR2 &= (uint16_t)~TIM_CR2_CCUS;
+ }
+}
+
+/**
+ * @brief Sets or Resets the TIM peripheral Capture Compare Preload Control bit.
+ * @param TIMx: where x can be 1 or 8 to select the TIMx peripheral
+ * @param NewState: new state of the Capture Compare Preload Control bit
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void TIM_CCPreloadControl(TIM_TypeDef* TIMx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST4_PERIPH(TIMx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ if (NewState != DISABLE)
+ {
+ /* Set the CCPC Bit */
+ TIMx->CR2 |= TIM_CR2_CCPC;
+ }
+ else
+ {
+ /* Reset the CCPC Bit */
+ TIMx->CR2 &= (uint16_t)~TIM_CR2_CCPC;
+ }
+}
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Group5 Interrupts DMA and flags management functions
+ * @brief Interrupts, DMA and flags management functions
+ *
+@verbatim
+ ===============================================================================
+ Interrupts, DMA and flags management functions
+ ===============================================================================
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Enables or disables the specified TIM interrupts.
+ * @param TIMx: where x can be 1 to 14 to select the TIMx peripheral.
+ * @param TIM_IT: specifies the TIM interrupts sources to be enabled or disabled.
+ * This parameter can be any combination of the following values:
+ * @arg TIM_IT_Update: TIM update Interrupt source
+ * @arg TIM_IT_CC1: TIM Capture Compare 1 Interrupt source
+ * @arg TIM_IT_CC2: TIM Capture Compare 2 Interrupt source
+ * @arg TIM_IT_CC3: TIM Capture Compare 3 Interrupt source
+ * @arg TIM_IT_CC4: TIM Capture Compare 4 Interrupt source
+ * @arg TIM_IT_COM: TIM Commutation Interrupt source
+ * @arg TIM_IT_Trigger: TIM Trigger Interrupt source
+ * @arg TIM_IT_Break: TIM Break Interrupt source
+ *
+ * @note For TIM6 and TIM7 only the parameter TIM_IT_Update can be used
+ * @note For TIM9 and TIM12 only one of the following parameters can be used: TIM_IT_Update,
+ * TIM_IT_CC1, TIM_IT_CC2 or TIM_IT_Trigger.
+ * @note For TIM10, TIM11, TIM13 and TIM14 only one of the following parameters can
+ * be used: TIM_IT_Update or TIM_IT_CC1
+ * @note TIM_IT_COM and TIM_IT_Break can be used only with TIM1 and TIM8
+ *
+ * @param NewState: new state of the TIM interrupts.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_ALL_PERIPH(TIMx));
+ assert_param(IS_TIM_IT(TIM_IT));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the Interrupt sources */
+ TIMx->DIER |= TIM_IT;
+ }
+ else
+ {
+ /* Disable the Interrupt sources */
+ TIMx->DIER &= (uint16_t)~TIM_IT;
+ }
+}
+
+/**
+ * @brief Configures the TIMx event to be generate by software.
+ * @param TIMx: where x can be 1 to 14 to select the TIM peripheral.
+ * @param TIM_EventSource: specifies the event source.
+ * This parameter can be one or more of the following values:
+ * @arg TIM_EventSource_Update: Timer update Event source
+ * @arg TIM_EventSource_CC1: Timer Capture Compare 1 Event source
+ * @arg TIM_EventSource_CC2: Timer Capture Compare 2 Event source
+ * @arg TIM_EventSource_CC3: Timer Capture Compare 3 Event source
+ * @arg TIM_EventSource_CC4: Timer Capture Compare 4 Event source
+ * @arg TIM_EventSource_COM: Timer COM event source
+ * @arg TIM_EventSource_Trigger: Timer Trigger Event source
+ * @arg TIM_EventSource_Break: Timer Break event source
+ *
+ * @note TIM6 and TIM7 can only generate an update event.
+ * @note TIM_EventSource_COM and TIM_EventSource_Break are used only with TIM1 and TIM8.
+ *
+ * @retval None
+ */
+void TIM_GenerateEvent(TIM_TypeDef* TIMx, uint16_t TIM_EventSource)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_ALL_PERIPH(TIMx));
+ assert_param(IS_TIM_EVENT_SOURCE(TIM_EventSource));
+
+ /* Set the event sources */
+ TIMx->EGR = TIM_EventSource;
+}
+
+/**
+ * @brief Checks whether the specified TIM flag is set or not.
+ * @param TIMx: where x can be 1 to 14 to select the TIM peripheral.
+ * @param TIM_FLAG: specifies the flag to check.
+ * This parameter can be one of the following values:
+ * @arg TIM_FLAG_Update: TIM update Flag
+ * @arg TIM_FLAG_CC1: TIM Capture Compare 1 Flag
+ * @arg TIM_FLAG_CC2: TIM Capture Compare 2 Flag
+ * @arg TIM_FLAG_CC3: TIM Capture Compare 3 Flag
+ * @arg TIM_FLAG_CC4: TIM Capture Compare 4 Flag
+ * @arg TIM_FLAG_COM: TIM Commutation Flag
+ * @arg TIM_FLAG_Trigger: TIM Trigger Flag
+ * @arg TIM_FLAG_Break: TIM Break Flag
+ * @arg TIM_FLAG_CC1OF: TIM Capture Compare 1 over capture Flag
+ * @arg TIM_FLAG_CC2OF: TIM Capture Compare 2 over capture Flag
+ * @arg TIM_FLAG_CC3OF: TIM Capture Compare 3 over capture Flag
+ * @arg TIM_FLAG_CC4OF: TIM Capture Compare 4 over capture Flag
+ *
+ * @note TIM6 and TIM7 can have only one update flag.
+ * @note TIM_FLAG_COM and TIM_FLAG_Break are used only with TIM1 and TIM8.
+ *
+ * @retval The new state of TIM_FLAG (SET or RESET).
+ */
+FlagStatus TIM_GetFlagStatus(TIM_TypeDef* TIMx, uint16_t TIM_FLAG)
+{
+ ITStatus bitstatus = RESET;
+ /* Check the parameters */
+ assert_param(IS_TIM_ALL_PERIPH(TIMx));
+ assert_param(IS_TIM_GET_FLAG(TIM_FLAG));
+
+
+ if ((TIMx->SR & TIM_FLAG) != (uint16_t)RESET)
+ {
+ bitstatus = SET;
+ }
+ else
+ {
+ bitstatus = RESET;
+ }
+ return bitstatus;
+}
+
+/**
+ * @brief Clears the TIMx's pending flags.
+ * @param TIMx: where x can be 1 to 14 to select the TIM peripheral.
+ * @param TIM_FLAG: specifies the flag bit to clear.
+ * This parameter can be any combination of the following values:
+ * @arg TIM_FLAG_Update: TIM update Flag
+ * @arg TIM_FLAG_CC1: TIM Capture Compare 1 Flag
+ * @arg TIM_FLAG_CC2: TIM Capture Compare 2 Flag
+ * @arg TIM_FLAG_CC3: TIM Capture Compare 3 Flag
+ * @arg TIM_FLAG_CC4: TIM Capture Compare 4 Flag
+ * @arg TIM_FLAG_COM: TIM Commutation Flag
+ * @arg TIM_FLAG_Trigger: TIM Trigger Flag
+ * @arg TIM_FLAG_Break: TIM Break Flag
+ * @arg TIM_FLAG_CC1OF: TIM Capture Compare 1 over capture Flag
+ * @arg TIM_FLAG_CC2OF: TIM Capture Compare 2 over capture Flag
+ * @arg TIM_FLAG_CC3OF: TIM Capture Compare 3 over capture Flag
+ * @arg TIM_FLAG_CC4OF: TIM Capture Compare 4 over capture Flag
+ *
+ * @note TIM6 and TIM7 can have only one update flag.
+ * @note TIM_FLAG_COM and TIM_FLAG_Break are used only with TIM1 and TIM8.
+ *
+ * @retval None
+ */
+void TIM_ClearFlag(TIM_TypeDef* TIMx, uint16_t TIM_FLAG)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_ALL_PERIPH(TIMx));
+
+ /* Clear the flags */
+ TIMx->SR = (uint16_t)~TIM_FLAG;
+}
+
+/**
+ * @brief Checks whether the TIM interrupt has occurred or not.
+ * @param TIMx: where x can be 1 to 14 to select the TIM peripheral.
+ * @param TIM_IT: specifies the TIM interrupt source to check.
+ * This parameter can be one of the following values:
+ * @arg TIM_IT_Update: TIM update Interrupt source
+ * @arg TIM_IT_CC1: TIM Capture Compare 1 Interrupt source
+ * @arg TIM_IT_CC2: TIM Capture Compare 2 Interrupt source
+ * @arg TIM_IT_CC3: TIM Capture Compare 3 Interrupt source
+ * @arg TIM_IT_CC4: TIM Capture Compare 4 Interrupt source
+ * @arg TIM_IT_COM: TIM Commutation Interrupt source
+ * @arg TIM_IT_Trigger: TIM Trigger Interrupt source
+ * @arg TIM_IT_Break: TIM Break Interrupt source
+ *
+ * @note TIM6 and TIM7 can generate only an update interrupt.
+ * @note TIM_IT_COM and TIM_IT_Break are used only with TIM1 and TIM8.
+ *
+ * @retval The new state of the TIM_IT(SET or RESET).
+ */
+ITStatus TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t TIM_IT)
+{
+ ITStatus bitstatus = RESET;
+ uint16_t itstatus = 0x0, itenable = 0x0;
+ /* Check the parameters */
+ assert_param(IS_TIM_ALL_PERIPH(TIMx));
+ assert_param(IS_TIM_GET_IT(TIM_IT));
+
+ itstatus = TIMx->SR & TIM_IT;
+
+ itenable = TIMx->DIER & TIM_IT;
+ if ((itstatus != (uint16_t)RESET) && (itenable != (uint16_t)RESET))
+ {
+ bitstatus = SET;
+ }
+ else
+ {
+ bitstatus = RESET;
+ }
+ return bitstatus;
+}
+
+/**
+ * @brief Clears the TIMx's interrupt pending bits.
+ * @param TIMx: where x can be 1 to 14 to select the TIM peripheral.
+ * @param TIM_IT: specifies the pending bit to clear.
+ * This parameter can be any combination of the following values:
+ * @arg TIM_IT_Update: TIM1 update Interrupt source
+ * @arg TIM_IT_CC1: TIM Capture Compare 1 Interrupt source
+ * @arg TIM_IT_CC2: TIM Capture Compare 2 Interrupt source
+ * @arg TIM_IT_CC3: TIM Capture Compare 3 Interrupt source
+ * @arg TIM_IT_CC4: TIM Capture Compare 4 Interrupt source
+ * @arg TIM_IT_COM: TIM Commutation Interrupt source
+ * @arg TIM_IT_Trigger: TIM Trigger Interrupt source
+ * @arg TIM_IT_Break: TIM Break Interrupt source
+ *
+ * @note TIM6 and TIM7 can generate only an update interrupt.
+ * @note TIM_IT_COM and TIM_IT_Break are used only with TIM1 and TIM8.
+ *
+ * @retval None
+ */
+void TIM_ClearITPendingBit(TIM_TypeDef* TIMx, uint16_t TIM_IT)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_ALL_PERIPH(TIMx));
+
+ /* Clear the IT pending Bit */
+ TIMx->SR = (uint16_t)~TIM_IT;
+}
+
+/**
+ * @brief Configures the TIMx's DMA interface.
+ * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral.
+ * @param TIM_DMABase: DMA Base address.
+ * This parameter can be one of the following values:
+ * @arg TIM_DMABase_CR1
+ * @arg TIM_DMABase_CR2
+ * @arg TIM_DMABase_SMCR
+ * @arg TIM_DMABase_DIER
+ * @arg TIM1_DMABase_SR
+ * @arg TIM_DMABase_EGR
+ * @arg TIM_DMABase_CCMR1
+ * @arg TIM_DMABase_CCMR2
+ * @arg TIM_DMABase_CCER
+ * @arg TIM_DMABase_CNT
+ * @arg TIM_DMABase_PSC
+ * @arg TIM_DMABase_ARR
+ * @arg TIM_DMABase_RCR
+ * @arg TIM_DMABase_CCR1
+ * @arg TIM_DMABase_CCR2
+ * @arg TIM_DMABase_CCR3
+ * @arg TIM_DMABase_CCR4
+ * @arg TIM_DMABase_BDTR
+ * @arg TIM_DMABase_DCR
+ * @param TIM_DMABurstLength: DMA Burst length. This parameter can be one value
+ * between: TIM_DMABurstLength_1Transfer and TIM_DMABurstLength_18Transfers.
+ * @retval None
+ */
+void TIM_DMAConfig(TIM_TypeDef* TIMx, uint16_t TIM_DMABase, uint16_t TIM_DMABurstLength)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+ assert_param(IS_TIM_DMA_BASE(TIM_DMABase));
+ assert_param(IS_TIM_DMA_LENGTH(TIM_DMABurstLength));
+
+ /* Set the DMA Base and the DMA Burst Length */
+ TIMx->DCR = TIM_DMABase | TIM_DMABurstLength;
+}
+
+/**
+ * @brief Enables or disables the TIMx's DMA Requests.
+ * @param TIMx: where x can be 1, 2, 3, 4, 5, 6, 7 or 8 to select the TIM peripheral.
+ * @param TIM_DMASource: specifies the DMA Request sources.
+ * This parameter can be any combination of the following values:
+ * @arg TIM_DMA_Update: TIM update Interrupt source
+ * @arg TIM_DMA_CC1: TIM Capture Compare 1 DMA source
+ * @arg TIM_DMA_CC2: TIM Capture Compare 2 DMA source
+ * @arg TIM_DMA_CC3: TIM Capture Compare 3 DMA source
+ * @arg TIM_DMA_CC4: TIM Capture Compare 4 DMA source
+ * @arg TIM_DMA_COM: TIM Commutation DMA source
+ * @arg TIM_DMA_Trigger: TIM Trigger DMA source
+ * @param NewState: new state of the DMA Request sources.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void TIM_DMACmd(TIM_TypeDef* TIMx, uint16_t TIM_DMASource, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST5_PERIPH(TIMx));
+ assert_param(IS_TIM_DMA_SOURCE(TIM_DMASource));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the DMA sources */
+ TIMx->DIER |= TIM_DMASource;
+ }
+ else
+ {
+ /* Disable the DMA sources */
+ TIMx->DIER &= (uint16_t)~TIM_DMASource;
+ }
+}
+
+/**
+ * @brief Selects the TIMx peripheral Capture Compare DMA source.
+ * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral.
+ * @param NewState: new state of the Capture Compare DMA source
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void TIM_SelectCCDMA(TIM_TypeDef* TIMx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Set the CCDS Bit */
+ TIMx->CR2 |= TIM_CR2_CCDS;
+ }
+ else
+ {
+ /* Reset the CCDS Bit */
+ TIMx->CR2 &= (uint16_t)~TIM_CR2_CCDS;
+ }
+}
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Group6 Clocks management functions
+ * @brief Clocks management functions
+ *
+@verbatim
+ ===============================================================================
+ Clocks management functions
+ ===============================================================================
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Configures the TIMx internal Clock
+ * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9 or 12 to select the TIM
+ * peripheral.
+ * @retval None
+ */
+void TIM_InternalClockConfig(TIM_TypeDef* TIMx)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST2_PERIPH(TIMx));
+
+ /* Disable slave mode to clock the prescaler directly with the internal clock */
+ TIMx->SMCR &= (uint16_t)~TIM_SMCR_SMS;
+}
+
+/**
+ * @brief Configures the TIMx Internal Trigger as External Clock
+ * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9 or 12 to select the TIM
+ * peripheral.
+ * @param TIM_InputTriggerSource: Trigger source.
+ * This parameter can be one of the following values:
+ * @arg TIM_TS_ITR0: Internal Trigger 0
+ * @arg TIM_TS_ITR1: Internal Trigger 1
+ * @arg TIM_TS_ITR2: Internal Trigger 2
+ * @arg TIM_TS_ITR3: Internal Trigger 3
+ * @retval None
+ */
+void TIM_ITRxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST2_PERIPH(TIMx));
+ assert_param(IS_TIM_INTERNAL_TRIGGER_SELECTION(TIM_InputTriggerSource));
+
+ /* Select the Internal Trigger */
+ TIM_SelectInputTrigger(TIMx, TIM_InputTriggerSource);
+
+ /* Select the External clock mode1 */
+ TIMx->SMCR |= TIM_SlaveMode_External1;
+}
+
+/**
+ * @brief Configures the TIMx Trigger as External Clock
+ * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9, 10, 11, 12, 13 or 14
+ * to select the TIM peripheral.
+ * @param TIM_TIxExternalCLKSource: Trigger source.
+ * This parameter can be one of the following values:
+ * @arg TIM_TIxExternalCLK1Source_TI1ED: TI1 Edge Detector
+ * @arg TIM_TIxExternalCLK1Source_TI1: Filtered Timer Input 1
+ * @arg TIM_TIxExternalCLK1Source_TI2: Filtered Timer Input 2
+ * @param TIM_ICPolarity: specifies the TIx Polarity.
+ * This parameter can be one of the following values:
+ * @arg TIM_ICPolarity_Rising
+ * @arg TIM_ICPolarity_Falling
+ * @param ICFilter: specifies the filter value.
+ * This parameter must be a value between 0x0 and 0xF.
+ * @retval None
+ */
+void TIM_TIxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_TIxExternalCLKSource,
+ uint16_t TIM_ICPolarity, uint16_t ICFilter)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST1_PERIPH(TIMx));
+ assert_param(IS_TIM_IC_POLARITY(TIM_ICPolarity));
+ assert_param(IS_TIM_IC_FILTER(ICFilter));
+
+ /* Configure the Timer Input Clock Source */
+ if (TIM_TIxExternalCLKSource == TIM_TIxExternalCLK1Source_TI2)
+ {
+ TI2_Config(TIMx, TIM_ICPolarity, TIM_ICSelection_DirectTI, ICFilter);
+ }
+ else
+ {
+ TI1_Config(TIMx, TIM_ICPolarity, TIM_ICSelection_DirectTI, ICFilter);
+ }
+ /* Select the Trigger source */
+ TIM_SelectInputTrigger(TIMx, TIM_TIxExternalCLKSource);
+ /* Select the External clock mode1 */
+ TIMx->SMCR |= TIM_SlaveMode_External1;
+}
+
+/**
+ * @brief Configures the External clock Mode1
+ * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral.
+ * @param TIM_ExtTRGPrescaler: The external Trigger Prescaler.
+ * This parameter can be one of the following values:
+ * @arg TIM_ExtTRGPSC_OFF: ETRP Prescaler OFF.
+ * @arg TIM_ExtTRGPSC_DIV2: ETRP frequency divided by 2.
+ * @arg TIM_ExtTRGPSC_DIV4: ETRP frequency divided by 4.
+ * @arg TIM_ExtTRGPSC_DIV8: ETRP frequency divided by 8.
+ * @param TIM_ExtTRGPolarity: The external Trigger Polarity.
+ * This parameter can be one of the following values:
+ * @arg TIM_ExtTRGPolarity_Inverted: active low or falling edge active.
+ * @arg TIM_ExtTRGPolarity_NonInverted: active high or rising edge active.
+ * @param ExtTRGFilter: External Trigger Filter.
+ * This parameter must be a value between 0x00 and 0x0F
+ * @retval None
+ */
+void TIM_ETRClockMode1Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler,
+ uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter)
+{
+ uint16_t tmpsmcr = 0;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+ assert_param(IS_TIM_EXT_PRESCALER(TIM_ExtTRGPrescaler));
+ assert_param(IS_TIM_EXT_POLARITY(TIM_ExtTRGPolarity));
+ assert_param(IS_TIM_EXT_FILTER(ExtTRGFilter));
+ /* Configure the ETR Clock source */
+ TIM_ETRConfig(TIMx, TIM_ExtTRGPrescaler, TIM_ExtTRGPolarity, ExtTRGFilter);
+
+ /* Get the TIMx SMCR register value */
+ tmpsmcr = TIMx->SMCR;
+
+ /* Reset the SMS Bits */
+ tmpsmcr &= (uint16_t)~TIM_SMCR_SMS;
+
+ /* Select the External clock mode1 */
+ tmpsmcr |= TIM_SlaveMode_External1;
+
+ /* Select the Trigger selection : ETRF */
+ tmpsmcr &= (uint16_t)~TIM_SMCR_TS;
+ tmpsmcr |= TIM_TS_ETRF;
+
+ /* Write to TIMx SMCR */
+ TIMx->SMCR = tmpsmcr;
+}
+
+/**
+ * @brief Configures the External clock Mode2
+ * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral.
+ * @param TIM_ExtTRGPrescaler: The external Trigger Prescaler.
+ * This parameter can be one of the following values:
+ * @arg TIM_ExtTRGPSC_OFF: ETRP Prescaler OFF.
+ * @arg TIM_ExtTRGPSC_DIV2: ETRP frequency divided by 2.
+ * @arg TIM_ExtTRGPSC_DIV4: ETRP frequency divided by 4.
+ * @arg TIM_ExtTRGPSC_DIV8: ETRP frequency divided by 8.
+ * @param TIM_ExtTRGPolarity: The external Trigger Polarity.
+ * This parameter can be one of the following values:
+ * @arg TIM_ExtTRGPolarity_Inverted: active low or falling edge active.
+ * @arg TIM_ExtTRGPolarity_NonInverted: active high or rising edge active.
+ * @param ExtTRGFilter: External Trigger Filter.
+ * This parameter must be a value between 0x00 and 0x0F
+ * @retval None
+ */
+void TIM_ETRClockMode2Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler,
+ uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+ assert_param(IS_TIM_EXT_PRESCALER(TIM_ExtTRGPrescaler));
+ assert_param(IS_TIM_EXT_POLARITY(TIM_ExtTRGPolarity));
+ assert_param(IS_TIM_EXT_FILTER(ExtTRGFilter));
+
+ /* Configure the ETR Clock source */
+ TIM_ETRConfig(TIMx, TIM_ExtTRGPrescaler, TIM_ExtTRGPolarity, ExtTRGFilter);
+
+ /* Enable the External clock mode2 */
+ TIMx->SMCR |= TIM_SMCR_ECE;
+}
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Group7 Synchronization management functions
+ * @brief Synchronization management functions
+ *
+@verbatim
+ ===============================================================================
+ Synchronization management functions
+ ===============================================================================
+
+ ===================================================================
+ TIM Driver: how to use it in synchronization Mode
+ ===================================================================
+ Case of two/several Timers
+ **************************
+ 1. Configure the Master Timers using the following functions:
+ - void TIM_SelectOutputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_TRGOSource);
+ - void TIM_SelectMasterSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_MasterSlaveMode);
+ 2. Configure the Slave Timers using the following functions:
+ - void TIM_SelectInputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource);
+ - void TIM_SelectSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_SlaveMode);
+
+ Case of Timers and external trigger(ETR pin)
+ ********************************************
+ 1. Configure the External trigger using this function:
+ - void TIM_ETRConfig(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity,
+ uint16_t ExtTRGFilter);
+ 2. Configure the Slave Timers using the following functions:
+ - void TIM_SelectInputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource);
+ - void TIM_SelectSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_SlaveMode);
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Selects the Input Trigger source
+ * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9, 10, 11, 12, 13 or 14
+ * to select the TIM peripheral.
+ * @param TIM_InputTriggerSource: The Input Trigger source.
+ * This parameter can be one of the following values:
+ * @arg TIM_TS_ITR0: Internal Trigger 0
+ * @arg TIM_TS_ITR1: Internal Trigger 1
+ * @arg TIM_TS_ITR2: Internal Trigger 2
+ * @arg TIM_TS_ITR3: Internal Trigger 3
+ * @arg TIM_TS_TI1F_ED: TI1 Edge Detector
+ * @arg TIM_TS_TI1FP1: Filtered Timer Input 1
+ * @arg TIM_TS_TI2FP2: Filtered Timer Input 2
+ * @arg TIM_TS_ETRF: External Trigger input
+ * @retval None
+ */
+void TIM_SelectInputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource)
+{
+ uint16_t tmpsmcr = 0;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST1_PERIPH(TIMx));
+ assert_param(IS_TIM_TRIGGER_SELECTION(TIM_InputTriggerSource));
+
+ /* Get the TIMx SMCR register value */
+ tmpsmcr = TIMx->SMCR;
+
+ /* Reset the TS Bits */
+ tmpsmcr &= (uint16_t)~TIM_SMCR_TS;
+
+ /* Set the Input Trigger source */
+ tmpsmcr |= TIM_InputTriggerSource;
+
+ /* Write to TIMx SMCR */
+ TIMx->SMCR = tmpsmcr;
+}
+
+/**
+ * @brief Selects the TIMx Trigger Output Mode.
+ * @param TIMx: where x can be 1, 2, 3, 4, 5, 6, 7 or 8 to select the TIM peripheral.
+ *
+ * @param TIM_TRGOSource: specifies the Trigger Output source.
+ * This parameter can be one of the following values:
+ *
+ * - For all TIMx
+ * @arg TIM_TRGOSource_Reset: The UG bit in the TIM_EGR register is used as the trigger output(TRGO)
+ * @arg TIM_TRGOSource_Enable: The Counter Enable CEN is used as the trigger output(TRGO)
+ * @arg TIM_TRGOSource_Update: The update event is selected as the trigger output(TRGO)
+ *
+ * - For all TIMx except TIM6 and TIM7
+ * @arg TIM_TRGOSource_OC1: The trigger output sends a positive pulse when the CC1IF flag
+ * is to be set, as soon as a capture or compare match occurs(TRGO)
+ * @arg TIM_TRGOSource_OC1Ref: OC1REF signal is used as the trigger output(TRGO)
+ * @arg TIM_TRGOSource_OC2Ref: OC2REF signal is used as the trigger output(TRGO)
+ * @arg TIM_TRGOSource_OC3Ref: OC3REF signal is used as the trigger output(TRGO)
+ * @arg TIM_TRGOSource_OC4Ref: OC4REF signal is used as the trigger output(TRGO)
+ *
+ * @retval None
+ */
+void TIM_SelectOutputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_TRGOSource)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST5_PERIPH(TIMx));
+ assert_param(IS_TIM_TRGO_SOURCE(TIM_TRGOSource));
+
+ /* Reset the MMS Bits */
+ TIMx->CR2 &= (uint16_t)~TIM_CR2_MMS;
+ /* Select the TRGO source */
+ TIMx->CR2 |= TIM_TRGOSource;
+}
+
+/**
+ * @brief Selects the TIMx Slave Mode.
+ * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9 or 12 to select the TIM peripheral.
+ * @param TIM_SlaveMode: specifies the Timer Slave Mode.
+ * This parameter can be one of the following values:
+ * @arg TIM_SlaveMode_Reset: Rising edge of the selected trigger signal(TRGI) reinitialize
+ * the counter and triggers an update of the registers
+ * @arg TIM_SlaveMode_Gated: The counter clock is enabled when the trigger signal (TRGI) is high
+ * @arg TIM_SlaveMode_Trigger: The counter starts at a rising edge of the trigger TRGI
+ * @arg TIM_SlaveMode_External1: Rising edges of the selected trigger (TRGI) clock the counter
+ * @retval None
+ */
+void TIM_SelectSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_SlaveMode)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST2_PERIPH(TIMx));
+ assert_param(IS_TIM_SLAVE_MODE(TIM_SlaveMode));
+
+ /* Reset the SMS Bits */
+ TIMx->SMCR &= (uint16_t)~TIM_SMCR_SMS;
+
+ /* Select the Slave Mode */
+ TIMx->SMCR |= TIM_SlaveMode;
+}
+
+/**
+ * @brief Sets or Resets the TIMx Master/Slave Mode.
+ * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9 or 12 to select the TIM peripheral.
+ * @param TIM_MasterSlaveMode: specifies the Timer Master Slave Mode.
+ * This parameter can be one of the following values:
+ * @arg TIM_MasterSlaveMode_Enable: synchronization between the current timer
+ * and its slaves (through TRGO)
+ * @arg TIM_MasterSlaveMode_Disable: No action
+ * @retval None
+ */
+void TIM_SelectMasterSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_MasterSlaveMode)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST2_PERIPH(TIMx));
+ assert_param(IS_TIM_MSM_STATE(TIM_MasterSlaveMode));
+
+ /* Reset the MSM Bit */
+ TIMx->SMCR &= (uint16_t)~TIM_SMCR_MSM;
+
+ /* Set or Reset the MSM Bit */
+ TIMx->SMCR |= TIM_MasterSlaveMode;
+}
+
+/**
+ * @brief Configures the TIMx External Trigger (ETR).
+ * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral.
+ * @param TIM_ExtTRGPrescaler: The external Trigger Prescaler.
+ * This parameter can be one of the following values:
+ * @arg TIM_ExtTRGPSC_OFF: ETRP Prescaler OFF.
+ * @arg TIM_ExtTRGPSC_DIV2: ETRP frequency divided by 2.
+ * @arg TIM_ExtTRGPSC_DIV4: ETRP frequency divided by 4.
+ * @arg TIM_ExtTRGPSC_DIV8: ETRP frequency divided by 8.
+ * @param TIM_ExtTRGPolarity: The external Trigger Polarity.
+ * This parameter can be one of the following values:
+ * @arg TIM_ExtTRGPolarity_Inverted: active low or falling edge active.
+ * @arg TIM_ExtTRGPolarity_NonInverted: active high or rising edge active.
+ * @param ExtTRGFilter: External Trigger Filter.
+ * This parameter must be a value between 0x00 and 0x0F
+ * @retval None
+ */
+void TIM_ETRConfig(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler,
+ uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter)
+{
+ uint16_t tmpsmcr = 0;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST3_PERIPH(TIMx));
+ assert_param(IS_TIM_EXT_PRESCALER(TIM_ExtTRGPrescaler));
+ assert_param(IS_TIM_EXT_POLARITY(TIM_ExtTRGPolarity));
+ assert_param(IS_TIM_EXT_FILTER(ExtTRGFilter));
+
+ tmpsmcr = TIMx->SMCR;
+
+ /* Reset the ETR Bits */
+ tmpsmcr &= SMCR_ETR_MASK;
+
+ /* Set the Prescaler, the Filter value and the Polarity */
+ tmpsmcr |= (uint16_t)(TIM_ExtTRGPrescaler | (uint16_t)(TIM_ExtTRGPolarity | (uint16_t)(ExtTRGFilter << (uint16_t)8)));
+
+ /* Write to TIMx SMCR */
+ TIMx->SMCR = tmpsmcr;
+}
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Group8 Specific interface management functions
+ * @brief Specific interface management functions
+ *
+@verbatim
+ ===============================================================================
+ Specific interface management functions
+ ===============================================================================
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Configures the TIMx Encoder Interface.
+ * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9 or 12 to select the TIM
+ * peripheral.
+ * @param TIM_EncoderMode: specifies the TIMx Encoder Mode.
+ * This parameter can be one of the following values:
+ * @arg TIM_EncoderMode_TI1: Counter counts on TI1FP1 edge depending on TI2FP2 level.
+ * @arg TIM_EncoderMode_TI2: Counter counts on TI2FP2 edge depending on TI1FP1 level.
+ * @arg TIM_EncoderMode_TI12: Counter counts on both TI1FP1 and TI2FP2 edges depending
+ * on the level of the other input.
+ * @param TIM_IC1Polarity: specifies the IC1 Polarity
+ * This parameter can be one of the following values:
+ * @arg TIM_ICPolarity_Falling: IC Falling edge.
+ * @arg TIM_ICPolarity_Rising: IC Rising edge.
+ * @param TIM_IC2Polarity: specifies the IC2 Polarity
+ * This parameter can be one of the following values:
+ * @arg TIM_ICPolarity_Falling: IC Falling edge.
+ * @arg TIM_ICPolarity_Rising: IC Rising edge.
+ * @retval None
+ */
+void TIM_EncoderInterfaceConfig(TIM_TypeDef* TIMx, uint16_t TIM_EncoderMode,
+ uint16_t TIM_IC1Polarity, uint16_t TIM_IC2Polarity)
+{
+ uint16_t tmpsmcr = 0;
+ uint16_t tmpccmr1 = 0;
+ uint16_t tmpccer = 0;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST2_PERIPH(TIMx));
+ assert_param(IS_TIM_ENCODER_MODE(TIM_EncoderMode));
+ assert_param(IS_TIM_IC_POLARITY(TIM_IC1Polarity));
+ assert_param(IS_TIM_IC_POLARITY(TIM_IC2Polarity));
+
+ /* Get the TIMx SMCR register value */
+ tmpsmcr = TIMx->SMCR;
+
+ /* Get the TIMx CCMR1 register value */
+ tmpccmr1 = TIMx->CCMR1;
+
+ /* Get the TIMx CCER register value */
+ tmpccer = TIMx->CCER;
+
+ /* Set the encoder Mode */
+ tmpsmcr &= (uint16_t)~TIM_SMCR_SMS;
+ tmpsmcr |= TIM_EncoderMode;
+
+ /* Select the Capture Compare 1 and the Capture Compare 2 as input */
+ tmpccmr1 &= ((uint16_t)~TIM_CCMR1_CC1S) & ((uint16_t)~TIM_CCMR1_CC2S);
+ tmpccmr1 |= TIM_CCMR1_CC1S_0 | TIM_CCMR1_CC2S_0;
+
+ /* Set the TI1 and the TI2 Polarities */
+ tmpccer &= ((uint16_t)~TIM_CCER_CC1P) & ((uint16_t)~TIM_CCER_CC2P);
+ tmpccer |= (uint16_t)(TIM_IC1Polarity | (uint16_t)(TIM_IC2Polarity << (uint16_t)4));
+
+ /* Write to TIMx SMCR */
+ TIMx->SMCR = tmpsmcr;
+
+ /* Write to TIMx CCMR1 */
+ TIMx->CCMR1 = tmpccmr1;
+
+ /* Write to TIMx CCER */
+ TIMx->CCER = tmpccer;
+}
+
+/**
+ * @brief Enables or disables the TIMx's Hall sensor interface.
+ * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9 or 12 to select the TIM
+ * peripheral.
+ * @param NewState: new state of the TIMx Hall sensor interface.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void TIM_SelectHallSensor(TIM_TypeDef* TIMx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST2_PERIPH(TIMx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Set the TI1S Bit */
+ TIMx->CR2 |= TIM_CR2_TI1S;
+ }
+ else
+ {
+ /* Reset the TI1S Bit */
+ TIMx->CR2 &= (uint16_t)~TIM_CR2_TI1S;
+ }
+}
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Group9 Specific remapping management function
+ * @brief Specific remapping management function
+ *
+@verbatim
+ ===============================================================================
+ Specific remapping management function
+ ===============================================================================
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Configures the TIM2, TIM5 and TIM11 Remapping input capabilities.
+ * @param TIMx: where x can be 2, 5 or 11 to select the TIM peripheral.
+ * @param TIM_Remap: specifies the TIM input remapping source.
+ * This parameter can be one of the following values:
+ * @arg TIM2_TIM8_TRGO: TIM2 ITR1 input is connected to TIM8 Trigger output(default)
+ * @arg TIM2_ETH_PTP: TIM2 ITR1 input is connected to ETH PTP trogger output.
+ * @arg TIM2_USBFS_SOF: TIM2 ITR1 input is connected to USB FS SOF.
+ * @arg TIM2_USBHS_SOF: TIM2 ITR1 input is connected to USB HS SOF.
+ * @arg TIM5_GPIO: TIM5 CH4 input is connected to dedicated Timer pin(default)
+ * @arg TIM5_LSI: TIM5 CH4 input is connected to LSI clock.
+ * @arg TIM5_LSE: TIM5 CH4 input is connected to LSE clock.
+ * @arg TIM5_RTC: TIM5 CH4 input is connected to RTC Output event.
+ * @arg TIM11_GPIO: TIM11 CH4 input is connected to dedicated Timer pin(default)
+ * @arg TIM11_HSE: TIM11 CH4 input is connected to HSE_RTC clock
+ * (HSE divided by a programmable prescaler)
+ * @retval None
+ */
+void TIM_RemapConfig(TIM_TypeDef* TIMx, uint16_t TIM_Remap)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_LIST6_PERIPH(TIMx));
+ assert_param(IS_TIM_REMAP(TIM_Remap));
+
+ /* Set the Timer remapping configuration */
+ TIMx->OR = TIM_Remap;
+}
+/**
+ * @}
+ */
+
+/**
+ * @brief Configure the TI1 as Input.
+ * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9, 10, 11, 12, 13 or 14
+ * to select the TIM peripheral.
+ * @param TIM_ICPolarity : The Input Polarity.
+ * This parameter can be one of the following values:
+ * @arg TIM_ICPolarity_Rising
+ * @arg TIM_ICPolarity_Falling
+ * @arg TIM_ICPolarity_BothEdge
+ * @param TIM_ICSelection: specifies the input to be used.
+ * This parameter can be one of the following values:
+ * @arg TIM_ICSelection_DirectTI: TIM Input 1 is selected to be connected to IC1.
+ * @arg TIM_ICSelection_IndirectTI: TIM Input 1 is selected to be connected to IC2.
+ * @arg TIM_ICSelection_TRC: TIM Input 1 is selected to be connected to TRC.
+ * @param TIM_ICFilter: Specifies the Input Capture Filter.
+ * This parameter must be a value between 0x00 and 0x0F.
+ * @retval None
+ */
+static void TI1_Config(TIM_TypeDef* TIMx, uint16_t TIM_ICPolarity, uint16_t TIM_ICSelection,
+ uint16_t TIM_ICFilter)
+{
+ uint16_t tmpccmr1 = 0, tmpccer = 0;
+
+ /* Disable the Channel 1: Reset the CC1E Bit */
+ TIMx->CCER &= (uint16_t)~TIM_CCER_CC1E;
+ tmpccmr1 = TIMx->CCMR1;
+ tmpccer = TIMx->CCER;
+
+ /* Select the Input and set the filter */
+ tmpccmr1 &= ((uint16_t)~TIM_CCMR1_CC1S) & ((uint16_t)~TIM_CCMR1_IC1F);
+ tmpccmr1 |= (uint16_t)(TIM_ICSelection | (uint16_t)(TIM_ICFilter << (uint16_t)4));
+
+ /* Select the Polarity and set the CC1E Bit */
+ tmpccer &= (uint16_t)~(TIM_CCER_CC1P | TIM_CCER_CC1NP);
+ tmpccer |= (uint16_t)(TIM_ICPolarity | (uint16_t)TIM_CCER_CC1E);
+
+ /* Write to TIMx CCMR1 and CCER registers */
+ TIMx->CCMR1 = tmpccmr1;
+ TIMx->CCER = tmpccer;
+}
+
+/**
+ * @brief Configure the TI2 as Input.
+ * @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9 or 12 to select the TIM
+ * peripheral.
+ * @param TIM_ICPolarity : The Input Polarity.
+ * This parameter can be one of the following values:
+ * @arg TIM_ICPolarity_Rising
+ * @arg TIM_ICPolarity_Falling
+ * @arg TIM_ICPolarity_BothEdge
+ * @param TIM_ICSelection: specifies the input to be used.
+ * This parameter can be one of the following values:
+ * @arg TIM_ICSelection_DirectTI: TIM Input 2 is selected to be connected to IC2.
+ * @arg TIM_ICSelection_IndirectTI: TIM Input 2 is selected to be connected to IC1.
+ * @arg TIM_ICSelection_TRC: TIM Input 2 is selected to be connected to TRC.
+ * @param TIM_ICFilter: Specifies the Input Capture Filter.
+ * This parameter must be a value between 0x00 and 0x0F.
+ * @retval None
+ */
+static void TI2_Config(TIM_TypeDef* TIMx, uint16_t TIM_ICPolarity, uint16_t TIM_ICSelection,
+ uint16_t TIM_ICFilter)
+{
+ uint16_t tmpccmr1 = 0, tmpccer = 0, tmp = 0;
+
+ /* Disable the Channel 2: Reset the CC2E Bit */
+ TIMx->CCER &= (uint16_t)~TIM_CCER_CC2E;
+ tmpccmr1 = TIMx->CCMR1;
+ tmpccer = TIMx->CCER;
+ tmp = (uint16_t)(TIM_ICPolarity << 4);
+
+ /* Select the Input and set the filter */
+ tmpccmr1 &= ((uint16_t)~TIM_CCMR1_CC2S) & ((uint16_t)~TIM_CCMR1_IC2F);
+ tmpccmr1 |= (uint16_t)(TIM_ICFilter << 12);
+ tmpccmr1 |= (uint16_t)(TIM_ICSelection << 8);
+
+ /* Select the Polarity and set the CC2E Bit */
+ tmpccer &= (uint16_t)~(TIM_CCER_CC2P | TIM_CCER_CC2NP);
+ tmpccer |= (uint16_t)(tmp | (uint16_t)TIM_CCER_CC2E);
+
+ /* Write to TIMx CCMR1 and CCER registers */
+ TIMx->CCMR1 = tmpccmr1 ;
+ TIMx->CCER = tmpccer;
+}
+
+/**
+ * @brief Configure the TI3 as Input.
+ * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral.
+ * @param TIM_ICPolarity : The Input Polarity.
+ * This parameter can be one of the following values:
+ * @arg TIM_ICPolarity_Rising
+ * @arg TIM_ICPolarity_Falling
+ * @arg TIM_ICPolarity_BothEdge
+ * @param TIM_ICSelection: specifies the input to be used.
+ * This parameter can be one of the following values:
+ * @arg TIM_ICSelection_DirectTI: TIM Input 3 is selected to be connected to IC3.
+ * @arg TIM_ICSelection_IndirectTI: TIM Input 3 is selected to be connected to IC4.
+ * @arg TIM_ICSelection_TRC: TIM Input 3 is selected to be connected to TRC.
+ * @param TIM_ICFilter: Specifies the Input Capture Filter.
+ * This parameter must be a value between 0x00 and 0x0F.
+ * @retval None
+ */
+static void TI3_Config(TIM_TypeDef* TIMx, uint16_t TIM_ICPolarity, uint16_t TIM_ICSelection,
+ uint16_t TIM_ICFilter)
+{
+ uint16_t tmpccmr2 = 0, tmpccer = 0, tmp = 0;
+
+ /* Disable the Channel 3: Reset the CC3E Bit */
+ TIMx->CCER &= (uint16_t)~TIM_CCER_CC3E;
+ tmpccmr2 = TIMx->CCMR2;
+ tmpccer = TIMx->CCER;
+ tmp = (uint16_t)(TIM_ICPolarity << 8);
+
+ /* Select the Input and set the filter */
+ tmpccmr2 &= ((uint16_t)~TIM_CCMR1_CC1S) & ((uint16_t)~TIM_CCMR2_IC3F);
+ tmpccmr2 |= (uint16_t)(TIM_ICSelection | (uint16_t)(TIM_ICFilter << (uint16_t)4));
+
+ /* Select the Polarity and set the CC3E Bit */
+ tmpccer &= (uint16_t)~(TIM_CCER_CC3P | TIM_CCER_CC3NP);
+ tmpccer |= (uint16_t)(tmp | (uint16_t)TIM_CCER_CC3E);
+
+ /* Write to TIMx CCMR2 and CCER registers */
+ TIMx->CCMR2 = tmpccmr2;
+ TIMx->CCER = tmpccer;
+}
+
+/**
+ * @brief Configure the TI4 as Input.
+ * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral.
+ * @param TIM_ICPolarity : The Input Polarity.
+ * This parameter can be one of the following values:
+ * @arg TIM_ICPolarity_Rising
+ * @arg TIM_ICPolarity_Falling
+ * @arg TIM_ICPolarity_BothEdge
+ * @param TIM_ICSelection: specifies the input to be used.
+ * This parameter can be one of the following values:
+ * @arg TIM_ICSelection_DirectTI: TIM Input 4 is selected to be connected to IC4.
+ * @arg TIM_ICSelection_IndirectTI: TIM Input 4 is selected to be connected to IC3.
+ * @arg TIM_ICSelection_TRC: TIM Input 4 is selected to be connected to TRC.
+ * @param TIM_ICFilter: Specifies the Input Capture Filter.
+ * This parameter must be a value between 0x00 and 0x0F.
+ * @retval None
+ */
+static void TI4_Config(TIM_TypeDef* TIMx, uint16_t TIM_ICPolarity, uint16_t TIM_ICSelection,
+ uint16_t TIM_ICFilter)
+{
+ uint16_t tmpccmr2 = 0, tmpccer = 0, tmp = 0;
+
+ /* Disable the Channel 4: Reset the CC4E Bit */
+ TIMx->CCER &= (uint16_t)~TIM_CCER_CC4E;
+ tmpccmr2 = TIMx->CCMR2;
+ tmpccer = TIMx->CCER;
+ tmp = (uint16_t)(TIM_ICPolarity << 12);
+
+ /* Select the Input and set the filter */
+ tmpccmr2 &= ((uint16_t)~TIM_CCMR1_CC2S) & ((uint16_t)~TIM_CCMR1_IC2F);
+ tmpccmr2 |= (uint16_t)(TIM_ICSelection << 8);
+ tmpccmr2 |= (uint16_t)(TIM_ICFilter << 12);
+
+ /* Select the Polarity and set the CC4E Bit */
+ tmpccer &= (uint16_t)~(TIM_CCER_CC4P | TIM_CCER_CC4NP);
+ tmpccer |= (uint16_t)(tmp | (uint16_t)TIM_CCER_CC4E);
+
+ /* Write to TIMx CCMR2 and CCER registers */
+ TIMx->CCMR2 = tmpccmr2;
+ TIMx->CCER = tmpccer ;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/src/stm32f2xx_usart.c b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/src/stm32f2xx_usart.c
new file mode 100644
index 0000000..8f41b58
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/src/stm32f2xx_usart.c
@@ -0,0 +1,1469 @@
+/**
+ ******************************************************************************
+ * @file stm32f2xx_usart.c
+ * @author MCD Application Team
+ * @version V1.1.2
+ * @date 05-March-2012
+ * @brief This file provides firmware functions to manage the following
+ * functionalities of the Universal synchronous asynchronous receiver
+ * transmitter (USART):
+ * - Initialization and Configuration
+ * - Data transfers
+ * - Multi-Processor Communication
+ * - LIN mode
+ * - Half-duplex mode
+ * - Smartcard mode
+ * - IrDA mode
+ * - DMA transfers management
+ * - Interrupts and flags management
+ *
+ * @verbatim
+ *
+ * ===================================================================
+ * How to use this driver
+ * ===================================================================
+ * 1. Enable peripheral clock using the follwoing functions
+ * RCC_APB2PeriphClockCmd(RCC_APB2Periph_USARTx, ENABLE) for USART1 and USART6
+ * RCC_APB1PeriphClockCmd(RCC_APB1Periph_USARTx, ENABLE) for USART2, USART3, UART4 or UART5.
+ *
+ * 2. According to the USART mode, enable the GPIO clocks using
+ * RCC_AHB1PeriphClockCmd() function. (The I/O can be TX, RX, CTS,
+ * or/and SCLK).
+ *
+ * 3. Peripheral's alternate function:
+ * - Connect the pin to the desired peripherals' Alternate
+ * Function (AF) using GPIO_PinAFConfig() function
+ * - Configure the desired pin in alternate function by:
+ * GPIO_InitStruct->GPIO_Mode = GPIO_Mode_AF
+ * - Select the type, pull-up/pull-down and output speed via
+ * GPIO_PuPd, GPIO_OType and GPIO_Speed members
+ * - Call GPIO_Init() function
+ *
+ * 4. Program the Baud Rate, Word Length , Stop Bit, Parity, Hardware
+ * flow control and Mode(Receiver/Transmitter) using the USART_Init()
+ * function.
+ *
+ * 5. For synchronous mode, enable the clock and program the polarity,
+ * phase and last bit using the USART_ClockInit() function.
+ *
+ * 5. Enable the NVIC and the corresponding interrupt using the function
+ * USART_ITConfig() if you need to use interrupt mode.
+ *
+ * 6. When using the DMA mode
+ * - Configure the DMA using DMA_Init() function
+ * - Active the needed channel Request using USART_DMACmd() function
+ *
+ * 7. Enable the USART using the USART_Cmd() function.
+ *
+ * 8. Enable the DMA using the DMA_Cmd() function, when using DMA mode.
+ *
+ * Refer to Multi-Processor, LIN, half-duplex, Smartcard, IrDA sub-sections
+ * for more details
+ *
+ * In order to reach higher communication baudrates, it is possible to
+ * enable the oversampling by 8 mode using the function USART_OverSampling8Cmd().
+ * This function should be called after enabling the USART clock (RCC_APBxPeriphClockCmd())
+ * and before calling the function USART_Init().
+ *
+ * @endverbatim
+ *
+ ******************************************************************************
+ * @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 "stm32f2xx_usart.h"
+#include "stm32f2xx_rcc.h"
+
+/** @addtogroup STM32F2xx_StdPeriph_Driver
+ * @{
+ */
+
+/** @defgroup USART
+ * @brief USART driver modules
+ * @{
+ */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+
+/*!< USART CR1 register clear Mask ((~(uint16_t)0xE9F3)) */
+#define CR1_CLEAR_MASK ((uint16_t)(USART_CR1_M | USART_CR1_PCE | \
+ USART_CR1_PS | USART_CR1_TE | \
+ USART_CR1_RE))
+
+/*!< USART CR2 register clock bits clear Mask ((~(uint16_t)0xF0FF)) */
+#define CR2_CLOCK_CLEAR_MASK ((uint16_t)(USART_CR2_CLKEN | USART_CR2_CPOL | \
+ USART_CR2_CPHA | USART_CR2_LBCL))
+
+/*!< USART CR3 register clear Mask ((~(uint16_t)0xFCFF)) */
+#define CR3_CLEAR_MASK ((uint16_t)(USART_CR3_RTSE | USART_CR3_CTSE))
+
+/*!< USART Interrupts mask */
+#define IT_MASK ((uint16_t)0x001F)
+
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+/** @defgroup USART_Private_Functions
+ * @{
+ */
+
+/** @defgroup USART_Group1 Initialization and Configuration functions
+ * @brief Initialization and Configuration functions
+ *
+@verbatim
+ ===============================================================================
+ Initialization and Configuration functions
+ ===============================================================================
+
+ This subsection provides a set of functions allowing to initialize the USART
+ in asynchronous and in synchronous modes.
+ - For the asynchronous mode only these parameters can be configured:
+ - Baud Rate
+ - Word Length
+ - Stop Bit
+ - Parity: If the parity is enabled, then the MSB bit of the data written
+ in the data register is transmitted but is changed by the parity bit.
+ Depending on the frame length defined by the M bit (8-bits or 9-bits),
+ the possible USART frame formats are as listed in the following table:
+ +-------------------------------------------------------------+
+ | M bit | PCE bit | USART frame |
+ |---------------------|---------------------------------------|
+ | 0 | 0 | | SB | 8 bit data | STB | |
+ |---------|-----------|---------------------------------------|
+ | 0 | 1 | | SB | 7 bit data | PB | STB | |
+ |---------|-----------|---------------------------------------|
+ | 1 | 0 | | SB | 9 bit data | STB | |
+ |---------|-----------|---------------------------------------|
+ | 1 | 1 | | SB | 8 bit data | PB | STB | |
+ +-------------------------------------------------------------+
+ - Hardware flow control
+ - Receiver/transmitter modes
+
+ The USART_Init() function follows the USART asynchronous configuration procedure
+ (details for the procedure are available in reference manual (RM0033)).
+
+ - For the synchronous mode in addition to the asynchronous mode parameters these
+ parameters should be also configured:
+ - USART Clock Enabled
+ - USART polarity
+ - USART phase
+ - USART LastBit
+
+ These parameters can be configured using the USART_ClockInit() function.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Deinitializes the USARTx peripheral registers to their default reset values.
+ * @param USARTx: where x can be 1, 2, 3, 4, 5 or 6 to select the USART or
+ * UART peripheral.
+ * @retval None
+ */
+void USART_DeInit(USART_TypeDef* USARTx)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+
+ if (USARTx == USART1)
+ {
+ RCC_APB2PeriphResetCmd(RCC_APB2Periph_USART1, ENABLE);
+ RCC_APB2PeriphResetCmd(RCC_APB2Periph_USART1, DISABLE);
+ }
+ else if (USARTx == USART2)
+ {
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART2, ENABLE);
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART2, DISABLE);
+ }
+ else if (USARTx == USART3)
+ {
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART3, ENABLE);
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART3, DISABLE);
+ }
+ else if (USARTx == UART4)
+ {
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_UART4, ENABLE);
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_UART4, DISABLE);
+ }
+ else if (USARTx == UART5)
+ {
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_UART5, ENABLE);
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_UART5, DISABLE);
+ }
+ else
+ {
+ if (USARTx == USART6)
+ {
+ RCC_APB2PeriphResetCmd(RCC_APB2Periph_USART6, ENABLE);
+ RCC_APB2PeriphResetCmd(RCC_APB2Periph_USART6, DISABLE);
+ }
+ }
+}
+
+/**
+ * @brief Initializes the USARTx peripheral according to the specified
+ * parameters in the USART_InitStruct .
+ * @param USARTx: where x can be 1, 2, 3, 4, 5 or 6 to select the USART or
+ * UART peripheral.
+ * @param USART_InitStruct: pointer to a USART_InitTypeDef structure that contains
+ * the configuration information for the specified USART peripheral.
+ * @retval None
+ */
+void USART_Init(USART_TypeDef* USARTx, USART_InitTypeDef* USART_InitStruct)
+{
+ uint32_t tmpreg = 0x00, apbclock = 0x00;
+ uint32_t integerdivider = 0x00;
+ uint32_t fractionaldivider = 0x00;
+ RCC_ClocksTypeDef RCC_ClocksStatus;
+
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+ assert_param(IS_USART_BAUDRATE(USART_InitStruct->USART_BaudRate));
+ assert_param(IS_USART_WORD_LENGTH(USART_InitStruct->USART_WordLength));
+ assert_param(IS_USART_STOPBITS(USART_InitStruct->USART_StopBits));
+ assert_param(IS_USART_PARITY(USART_InitStruct->USART_Parity));
+ assert_param(IS_USART_MODE(USART_InitStruct->USART_Mode));
+ assert_param(IS_USART_HARDWARE_FLOW_CONTROL(USART_InitStruct->USART_HardwareFlowControl));
+
+ /* The hardware flow control is available only for USART1, USART2, USART3 and USART6 */
+ if (USART_InitStruct->USART_HardwareFlowControl != USART_HardwareFlowControl_None)
+ {
+ assert_param(IS_USART_1236_PERIPH(USARTx));
+ }
+
+/*---------------------------- USART CR2 Configuration -----------------------*/
+ tmpreg = USARTx->CR2;
+
+ /* Clear STOP[13:12] bits */
+ tmpreg &= (uint32_t)~((uint32_t)USART_CR2_STOP);
+
+ /* Configure the USART Stop Bits, Clock, CPOL, CPHA and LastBit :
+ Set STOP[13:12] bits according to USART_StopBits value */
+ tmpreg |= (uint32_t)USART_InitStruct->USART_StopBits;
+
+ /* Write to USART CR2 */
+ USARTx->CR2 = (uint16_t)tmpreg;
+
+/*---------------------------- USART CR1 Configuration -----------------------*/
+ tmpreg = USARTx->CR1;
+
+ /* Clear M, PCE, PS, TE and RE bits */
+ tmpreg &= (uint32_t)~((uint32_t)CR1_CLEAR_MASK);
+
+ /* Configure the USART Word Length, Parity and mode:
+ Set the M bits according to USART_WordLength value
+ Set PCE and PS bits according to USART_Parity value
+ Set TE and RE bits according to USART_Mode value */
+ tmpreg |= (uint32_t)USART_InitStruct->USART_WordLength | USART_InitStruct->USART_Parity |
+ USART_InitStruct->USART_Mode;
+
+ /* Write to USART CR1 */
+ USARTx->CR1 = (uint16_t)tmpreg;
+
+/*---------------------------- USART CR3 Configuration -----------------------*/
+ tmpreg = USARTx->CR3;
+
+ /* Clear CTSE and RTSE bits */
+ tmpreg &= (uint32_t)~((uint32_t)CR3_CLEAR_MASK);
+
+ /* Configure the USART HFC :
+ Set CTSE and RTSE bits according to USART_HardwareFlowControl value */
+ tmpreg |= USART_InitStruct->USART_HardwareFlowControl;
+
+ /* Write to USART CR3 */
+ USARTx->CR3 = (uint16_t)tmpreg;
+
+/*---------------------------- USART BRR Configuration -----------------------*/
+ /* Configure the USART Baud Rate */
+ RCC_GetClocksFreq(&RCC_ClocksStatus);
+
+ if ((USARTx == USART1) || (USARTx == USART6))
+ {
+ apbclock = RCC_ClocksStatus.PCLK2_Frequency;
+ }
+ else
+ {
+ apbclock = RCC_ClocksStatus.PCLK1_Frequency;
+ }
+
+ /* Determine the integer part */
+ if ((USARTx->CR1 & USART_CR1_OVER8) != 0)
+ {
+ /* Integer part computing in case Oversampling mode is 8 Samples */
+ integerdivider = ((25 * apbclock) / (2 * (USART_InitStruct->USART_BaudRate)));
+ }
+ else /* if ((USARTx->CR1 & USART_CR1_OVER8) == 0) */
+ {
+ /* Integer part computing in case Oversampling mode is 16 Samples */
+ integerdivider = ((25 * apbclock) / (4 * (USART_InitStruct->USART_BaudRate)));
+ }
+ tmpreg = (integerdivider / 100) << 4;
+
+ /* Determine the fractional part */
+ fractionaldivider = integerdivider - (100 * (tmpreg >> 4));
+
+ /* Implement the fractional part in the register */
+ if ((USARTx->CR1 & USART_CR1_OVER8) != 0)
+ {
+ tmpreg |= ((((fractionaldivider * 8) + 50) / 100)) & ((uint8_t)0x07);
+ }
+ else /* if ((USARTx->CR1 & USART_CR1_OVER8) == 0) */
+ {
+ tmpreg |= ((((fractionaldivider * 16) + 50) / 100)) & ((uint8_t)0x0F);
+ }
+
+ /* Write to USART BRR register */
+ USARTx->BRR = (uint16_t)tmpreg;
+}
+
+/**
+ * @brief Fills each USART_InitStruct member with its default value.
+ * @param USART_InitStruct: pointer to a USART_InitTypeDef structure which will
+ * be initialized.
+ * @retval None
+ */
+void USART_StructInit(USART_InitTypeDef* USART_InitStruct)
+{
+ /* USART_InitStruct members default value */
+ USART_InitStruct->USART_BaudRate = 9600;
+ USART_InitStruct->USART_WordLength = USART_WordLength_8b;
+ USART_InitStruct->USART_StopBits = USART_StopBits_1;
+ USART_InitStruct->USART_Parity = USART_Parity_No ;
+ USART_InitStruct->USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
+ USART_InitStruct->USART_HardwareFlowControl = USART_HardwareFlowControl_None;
+}
+
+/**
+ * @brief Initializes the USARTx peripheral Clock according to the
+ * specified parameters in the USART_ClockInitStruct .
+ * @param USARTx: where x can be 1, 2, 3 or 6 to select the USART peripheral.
+ * @param USART_ClockInitStruct: pointer to a USART_ClockInitTypeDef structure that
+ * contains the configuration information for the specified USART peripheral.
+ * @note The Smart Card and Synchronous modes are not available for UART4 and UART5.
+ * @retval None
+ */
+void USART_ClockInit(USART_TypeDef* USARTx, USART_ClockInitTypeDef* USART_ClockInitStruct)
+{
+ uint32_t tmpreg = 0x00;
+ /* Check the parameters */
+ assert_param(IS_USART_1236_PERIPH(USARTx));
+ assert_param(IS_USART_CLOCK(USART_ClockInitStruct->USART_Clock));
+ assert_param(IS_USART_CPOL(USART_ClockInitStruct->USART_CPOL));
+ assert_param(IS_USART_CPHA(USART_ClockInitStruct->USART_CPHA));
+ assert_param(IS_USART_LASTBIT(USART_ClockInitStruct->USART_LastBit));
+
+/*---------------------------- USART CR2 Configuration -----------------------*/
+ tmpreg = USARTx->CR2;
+ /* Clear CLKEN, CPOL, CPHA and LBCL bits */
+ tmpreg &= (uint32_t)~((uint32_t)CR2_CLOCK_CLEAR_MASK);
+ /* Configure the USART Clock, CPOL, CPHA and LastBit ------------*/
+ /* Set CLKEN bit according to USART_Clock value */
+ /* Set CPOL bit according to USART_CPOL value */
+ /* Set CPHA bit according to USART_CPHA value */
+ /* Set LBCL bit according to USART_LastBit value */
+ tmpreg |= (uint32_t)USART_ClockInitStruct->USART_Clock | USART_ClockInitStruct->USART_CPOL |
+ USART_ClockInitStruct->USART_CPHA | USART_ClockInitStruct->USART_LastBit;
+ /* Write to USART CR2 */
+ USARTx->CR2 = (uint16_t)tmpreg;
+}
+
+/**
+ * @brief Fills each USART_ClockInitStruct member with its default value.
+ * @param USART_ClockInitStruct: pointer to a USART_ClockInitTypeDef structure
+ * which will be initialized.
+ * @retval None
+ */
+void USART_ClockStructInit(USART_ClockInitTypeDef* USART_ClockInitStruct)
+{
+ /* USART_ClockInitStruct members default value */
+ USART_ClockInitStruct->USART_Clock = USART_Clock_Disable;
+ USART_ClockInitStruct->USART_CPOL = USART_CPOL_Low;
+ USART_ClockInitStruct->USART_CPHA = USART_CPHA_1Edge;
+ USART_ClockInitStruct->USART_LastBit = USART_LastBit_Disable;
+}
+
+/**
+ * @brief Enables or disables the specified USART peripheral.
+ * @param USARTx: where x can be 1, 2, 3, 4, 5 or 6 to select the USART or
+ * UART peripheral.
+ * @param NewState: new state of the USARTx peripheral.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void USART_Cmd(USART_TypeDef* USARTx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the selected USART by setting the UE bit in the CR1 register */
+ USARTx->CR1 |= USART_CR1_UE;
+ }
+ else
+ {
+ /* Disable the selected USART by clearing the UE bit in the CR1 register */
+ USARTx->CR1 &= (uint16_t)~((uint16_t)USART_CR1_UE);
+ }
+}
+
+/**
+ * @brief Sets the system clock prescaler.
+ * @param USARTx: where x can be 1, 2, 3, 4, 5 or 6 to select the USART or
+ * UART peripheral.
+ * @param USART_Prescaler: specifies the prescaler clock.
+ * @note The function is used for IrDA mode with UART4 and UART5.
+ * @retval None
+ */
+void USART_SetPrescaler(USART_TypeDef* USARTx, uint8_t USART_Prescaler)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+
+ /* Clear the USART prescaler */
+ USARTx->GTPR &= USART_GTPR_GT;
+ /* Set the USART prescaler */
+ USARTx->GTPR |= USART_Prescaler;
+}
+
+/**
+ * @brief Enables or disables the USART's 8x oversampling mode.
+ * @note This function has to be called before calling USART_Init() function
+ * in order to have correct baudrate Divider value.
+ * @param USARTx: where x can be 1, 2, 3, 4, 5 or 6 to select the USART or
+ * UART peripheral.
+ * @param NewState: new state of the USART 8x oversampling mode.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void USART_OverSampling8Cmd(USART_TypeDef* USARTx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the 8x Oversampling mode by setting the OVER8 bit in the CR1 register */
+ USARTx->CR1 |= USART_CR1_OVER8;
+ }
+ else
+ {
+ /* Disable the 8x Oversampling mode by clearing the OVER8 bit in the CR1 register */
+ USARTx->CR1 &= (uint16_t)~((uint16_t)USART_CR1_OVER8);
+ }
+}
+
+/**
+ * @brief Enables or disables the USART's one bit sampling method.
+ * @param USARTx: where x can be 1, 2, 3, 4, 5 or 6 to select the USART or
+ * UART peripheral.
+ * @param NewState: new state of the USART one bit sampling method.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void USART_OneBitMethodCmd(USART_TypeDef* USARTx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the one bit method by setting the ONEBITE bit in the CR3 register */
+ USARTx->CR3 |= USART_CR3_ONEBIT;
+ }
+ else
+ {
+ /* Disable the one bit method by clearing the ONEBITE bit in the CR3 register */
+ USARTx->CR3 &= (uint16_t)~((uint16_t)USART_CR3_ONEBIT);
+ }
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup USART_Group2 Data transfers functions
+ * @brief Data transfers functions
+ *
+@verbatim
+ ===============================================================================
+ Data transfers functions
+ ===============================================================================
+
+ This subsection provides a set of functions allowing to manage the USART data
+ transfers.
+
+ During an USART reception, data shifts in least significant bit first through
+ the RX pin. In this mode, the USART_DR register consists of a buffer (RDR)
+ between the internal bus and the received shift register.
+
+ When a transmission is taking place, a write instruction to the USART_DR register
+ stores the data in the TDR register and which is copied in the shift register
+ at the end of the current transmission.
+
+ The read access of the USART_DR register can be done using the USART_ReceiveData()
+ function and returns the RDR buffered value. Whereas a write access to the USART_DR
+ can be done using USART_SendData() function and stores the written data into
+ TDR buffer.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Transmits single data through the USARTx peripheral.
+ * @param USARTx: where x can be 1, 2, 3, 4, 5 or 6 to select the USART or
+ * UART peripheral.
+ * @param Data: the data to transmit.
+ * @retval None
+ */
+void USART_SendData(USART_TypeDef* USARTx, uint16_t Data)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+ assert_param(IS_USART_DATA(Data));
+
+ /* Transmit Data */
+ USARTx->DR = (Data & (uint16_t)0x01FF);
+}
+
+/**
+ * @brief Returns the most recent received data by the USARTx peripheral.
+ * @param USARTx: where x can be 1, 2, 3, 4, 5 or 6 to select the USART or
+ * UART peripheral.
+ * @retval The received data.
+ */
+uint16_t USART_ReceiveData(USART_TypeDef* USARTx)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+
+ /* Receive Data */
+ return (uint16_t)(USARTx->DR & (uint16_t)0x01FF);
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup USART_Group3 MultiProcessor Communication functions
+ * @brief Multi-Processor Communication functions
+ *
+@verbatim
+ ===============================================================================
+ Multi-Processor Communication functions
+ ===============================================================================
+
+ This subsection provides a set of functions allowing to manage the USART
+ multiprocessor communication.
+
+ For instance one of the USARTs can be the master, its TX output is connected to
+ the RX input of the other USART. The others are slaves, their respective TX outputs
+ are logically ANDed together and connected to the RX input of the master.
+
+ USART multiprocessor communication is possible through the following procedure:
+ 1. Program the Baud rate, Word length = 9 bits, Stop bits, Parity, Mode transmitter
+ or Mode receiver and hardware flow control values using the USART_Init()
+ function.
+ 2. Configures the USART address using the USART_SetAddress() function.
+ 3. Configures the wake up method (USART_WakeUp_IdleLine or USART_WakeUp_AddressMark)
+ using USART_WakeUpConfig() function only for the slaves.
+ 4. Enable the USART using the USART_Cmd() function.
+ 5. Enter the USART slaves in mute mode using USART_ReceiverWakeUpCmd() function.
+
+ The USART Slave exit from mute mode when receive the wake up condition.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Sets the address of the USART node.
+ * @param USARTx: where x can be 1, 2, 3, 4, 5 or 6 to select the USART or
+ * UART peripheral.
+ * @param USART_Address: Indicates the address of the USART node.
+ * @retval None
+ */
+void USART_SetAddress(USART_TypeDef* USARTx, uint8_t USART_Address)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+ assert_param(IS_USART_ADDRESS(USART_Address));
+
+ /* Clear the USART address */
+ USARTx->CR2 &= (uint16_t)~((uint16_t)USART_CR2_ADD);
+ /* Set the USART address node */
+ USARTx->CR2 |= USART_Address;
+}
+
+/**
+ * @brief Determines if the USART is in mute mode or not.
+ * @param USARTx: where x can be 1, 2, 3, 4, 5 or 6 to select the USART or
+ * UART peripheral.
+ * @param NewState: new state of the USART mute mode.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void USART_ReceiverWakeUpCmd(USART_TypeDef* USARTx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the USART mute mode by setting the RWU bit in the CR1 register */
+ USARTx->CR1 |= USART_CR1_RWU;
+ }
+ else
+ {
+ /* Disable the USART mute mode by clearing the RWU bit in the CR1 register */
+ USARTx->CR1 &= (uint16_t)~((uint16_t)USART_CR1_RWU);
+ }
+}
+/**
+ * @brief Selects the USART WakeUp method.
+ * @param USARTx: where x can be 1, 2, 3, 4, 5 or 6 to select the USART or
+ * UART peripheral.
+ * @param USART_WakeUp: specifies the USART wakeup method.
+ * This parameter can be one of the following values:
+ * @arg USART_WakeUp_IdleLine: WakeUp by an idle line detection
+ * @arg USART_WakeUp_AddressMark: WakeUp by an address mark
+ * @retval None
+ */
+void USART_WakeUpConfig(USART_TypeDef* USARTx, uint16_t USART_WakeUp)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+ assert_param(IS_USART_WAKEUP(USART_WakeUp));
+
+ USARTx->CR1 &= (uint16_t)~((uint16_t)USART_CR1_WAKE);
+ USARTx->CR1 |= USART_WakeUp;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup USART_Group4 LIN mode functions
+ * @brief LIN mode functions
+ *
+@verbatim
+ ===============================================================================
+ LIN mode functions
+ ===============================================================================
+
+ This subsection provides a set of functions allowing to manage the USART LIN
+ Mode communication.
+
+ In LIN mode, 8-bit data format with 1 stop bit is required in accordance with
+ the LIN standard.
+
+ Only this LIN Feature is supported by the USART IP:
+ - LIN Master Synchronous Break send capability and LIN slave break detection
+ capability : 13-bit break generation and 10/11 bit break detection
+
+
+ USART LIN Master transmitter communication is possible through the following procedure:
+ 1. Program the Baud rate, Word length = 8bits, Stop bits = 1bit, Parity,
+ Mode transmitter or Mode receiver and hardware flow control values using
+ the USART_Init() function.
+ 2. Enable the USART using the USART_Cmd() function.
+ 3. Enable the LIN mode using the USART_LINCmd() function.
+ 4. Send the break character using USART_SendBreak() function.
+
+ USART LIN Master receiver communication is possible through the following procedure:
+ 1. Program the Baud rate, Word length = 8bits, Stop bits = 1bit, Parity,
+ Mode transmitter or Mode receiver and hardware flow control values using
+ the USART_Init() function.
+ 2. Enable the USART using the USART_Cmd() function.
+ 3. Configures the break detection length using the USART_LINBreakDetectLengthConfig()
+ function.
+ 4. Enable the LIN mode using the USART_LINCmd() function.
+
+
+@note In LIN mode, the following bits must be kept cleared:
+ - CLKEN in the USART_CR2 register,
+ - STOP[1:0], SCEN, HDSEL and IREN in the USART_CR3 register.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Sets the USART LIN Break detection length.
+ * @param USARTx: where x can be 1, 2, 3, 4, 5 or 6 to select the USART or
+ * UART peripheral.
+ * @param USART_LINBreakDetectLength: specifies the LIN break detection length.
+ * This parameter can be one of the following values:
+ * @arg USART_LINBreakDetectLength_10b: 10-bit break detection
+ * @arg USART_LINBreakDetectLength_11b: 11-bit break detection
+ * @retval None
+ */
+void USART_LINBreakDetectLengthConfig(USART_TypeDef* USARTx, uint16_t USART_LINBreakDetectLength)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+ assert_param(IS_USART_LIN_BREAK_DETECT_LENGTH(USART_LINBreakDetectLength));
+
+ USARTx->CR2 &= (uint16_t)~((uint16_t)USART_CR2_LBDL);
+ USARTx->CR2 |= USART_LINBreakDetectLength;
+}
+
+/**
+ * @brief Enables or disables the USART's LIN mode.
+ * @param USARTx: where x can be 1, 2, 3, 4, 5 or 6 to select the USART or
+ * UART peripheral.
+ * @param NewState: new state of the USART LIN mode.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void USART_LINCmd(USART_TypeDef* USARTx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the LIN mode by setting the LINEN bit in the CR2 register */
+ USARTx->CR2 |= USART_CR2_LINEN;
+ }
+ else
+ {
+ /* Disable the LIN mode by clearing the LINEN bit in the CR2 register */
+ USARTx->CR2 &= (uint16_t)~((uint16_t)USART_CR2_LINEN);
+ }
+}
+
+/**
+ * @brief Transmits break characters.
+ * @param USARTx: where x can be 1, 2, 3, 4, 5 or 6 to select the USART or
+ * UART peripheral.
+ * @retval None
+ */
+void USART_SendBreak(USART_TypeDef* USARTx)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+
+ /* Send break characters */
+ USARTx->CR1 |= USART_CR1_SBK;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup USART_Group5 Halfduplex mode function
+ * @brief Half-duplex mode function
+ *
+@verbatim
+ ===============================================================================
+ Half-duplex mode function
+ ===============================================================================
+
+ This subsection provides a set of functions allowing to manage the USART
+ Half-duplex communication.
+
+ The USART can be configured to follow a single-wire half-duplex protocol where
+ the TX and RX lines are internally connected.
+
+ USART Half duplex communication is possible through the following procedure:
+ 1. Program the Baud rate, Word length, Stop bits, Parity, Mode transmitter
+ or Mode receiver and hardware flow control values using the USART_Init()
+ function.
+ 2. Configures the USART address using the USART_SetAddress() function.
+ 3. Enable the USART using the USART_Cmd() function.
+ 4. Enable the half duplex mode using USART_HalfDuplexCmd() function.
+
+
+@note The RX pin is no longer used
+@note In Half-duplex mode the following bits must be kept cleared:
+ - LINEN and CLKEN bits in the USART_CR2 register.
+ - SCEN and IREN bits in the USART_CR3 register.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Enables or disables the USART's Half Duplex communication.
+ * @param USARTx: where x can be 1, 2, 3, 4, 5 or 6 to select the USART or
+ * UART peripheral.
+ * @param NewState: new state of the USART Communication.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void USART_HalfDuplexCmd(USART_TypeDef* USARTx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the Half-Duplex mode by setting the HDSEL bit in the CR3 register */
+ USARTx->CR3 |= USART_CR3_HDSEL;
+ }
+ else
+ {
+ /* Disable the Half-Duplex mode by clearing the HDSEL bit in the CR3 register */
+ USARTx->CR3 &= (uint16_t)~((uint16_t)USART_CR3_HDSEL);
+ }
+}
+
+/**
+ * @}
+ */
+
+
+/** @defgroup USART_Group6 Smartcard mode functions
+ * @brief Smartcard mode functions
+ *
+@verbatim
+ ===============================================================================
+ Smartcard mode functions
+ ===============================================================================
+
+ This subsection provides a set of functions allowing to manage the USART
+ Smartcard communication.
+
+ The Smartcard interface is designed to support asynchronous protocol Smartcards as
+ defined in the ISO 7816-3 standard.
+
+ The USART can provide a clock to the smartcard through the SCLK output.
+ In smartcard mode, SCLK is not associated to the communication but is simply derived
+ from the internal peripheral input clock through a 5-bit prescaler.
+
+ Smartcard communication is possible through the following procedure:
+ 1. Configures the Smartcard Prescaler using the USART_SetPrescaler() function.
+ 2. Configures the Smartcard Guard Time using the USART_SetGuardTime() function.
+ 3. Program the USART clock using the USART_ClockInit() function as following:
+ - USART Clock enabled
+ - USART CPOL Low
+ - USART CPHA on first edge
+ - USART Last Bit Clock Enabled
+ 4. Program the Smartcard interface using the USART_Init() function as following:
+ - Word Length = 9 Bits
+ - 1.5 Stop Bit
+ - Even parity
+ - BaudRate = 12096 baud
+ - Hardware flow control disabled (RTS and CTS signals)
+ - Tx and Rx enabled
+ 5. Optionally you can enable the parity error interrupt using the USART_ITConfig()
+ function
+ 6. Enable the USART using the USART_Cmd() function.
+ 7. Enable the Smartcard NACK using the USART_SmartCardNACKCmd() function.
+ 8. Enable the Smartcard interface using the USART_SmartCardCmd() function.
+
+ Please refer to the ISO 7816-3 specification for more details.
+
+
+@note It is also possible to choose 0.5 stop bit for receiving but it is recommended
+ to use 1.5 stop bits for both transmitting and receiving to avoid switching
+ between the two configurations.
+@note In smartcard mode, the following bits must be kept cleared:
+ - LINEN bit in the USART_CR2 register.
+ - HDSEL and IREN bits in the USART_CR3 register.
+@note Smartcard mode is available on USART peripherals only (not available on UART4
+ and UART5 peripherals).
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Sets the specified USART guard time.
+ * @param USARTx: where x can be 1, 2, 3 or 6 to select the USART or
+ * UART peripheral.
+ * @param USART_GuardTime: specifies the guard time.
+ * @retval None
+ */
+void USART_SetGuardTime(USART_TypeDef* USARTx, uint8_t USART_GuardTime)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_1236_PERIPH(USARTx));
+
+ /* Clear the USART Guard time */
+ USARTx->GTPR &= USART_GTPR_PSC;
+ /* Set the USART guard time */
+ USARTx->GTPR |= (uint16_t)((uint16_t)USART_GuardTime << 0x08);
+}
+
+/**
+ * @brief Enables or disables the USART's Smart Card mode.
+ * @param USARTx: where x can be 1, 2, 3 or 6 to select the USART or
+ * UART peripheral.
+ * @param NewState: new state of the Smart Card mode.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void USART_SmartCardCmd(USART_TypeDef* USARTx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_1236_PERIPH(USARTx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ if (NewState != DISABLE)
+ {
+ /* Enable the SC mode by setting the SCEN bit in the CR3 register */
+ USARTx->CR3 |= USART_CR3_SCEN;
+ }
+ else
+ {
+ /* Disable the SC mode by clearing the SCEN bit in the CR3 register */
+ USARTx->CR3 &= (uint16_t)~((uint16_t)USART_CR3_SCEN);
+ }
+}
+
+/**
+ * @brief Enables or disables NACK transmission.
+ * @param USARTx: where x can be 1, 2, 3 or 6 to select the USART or
+ * UART peripheral.
+ * @param NewState: new state of the NACK transmission.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void USART_SmartCardNACKCmd(USART_TypeDef* USARTx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_1236_PERIPH(USARTx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ if (NewState != DISABLE)
+ {
+ /* Enable the NACK transmission by setting the NACK bit in the CR3 register */
+ USARTx->CR3 |= USART_CR3_NACK;
+ }
+ else
+ {
+ /* Disable the NACK transmission by clearing the NACK bit in the CR3 register */
+ USARTx->CR3 &= (uint16_t)~((uint16_t)USART_CR3_NACK);
+ }
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup USART_Group7 IrDA mode functions
+ * @brief IrDA mode functions
+ *
+@verbatim
+ ===============================================================================
+ IrDA mode functions
+ ===============================================================================
+
+ This subsection provides a set of functions allowing to manage the USART
+ IrDA communication.
+
+ IrDA is a half duplex communication protocol. If the Transmitter is busy, any data
+ on the IrDA receive line will be ignored by the IrDA decoder and if the Receiver
+ is busy, data on the TX from the USART to IrDA will not be encoded by IrDA.
+ While receiving data, transmission should be avoided as the data to be transmitted
+ could be corrupted.
+
+ IrDA communication is possible through the following procedure:
+ 1. Program the Baud rate, Word length = 8 bits, Stop bits, Parity, Transmitter/Receiver
+ modes and hardware flow control values using the USART_Init() function.
+ 2. Enable the USART using the USART_Cmd() function.
+ 3. Configures the IrDA pulse width by configuring the prescaler using
+ the USART_SetPrescaler() function.
+ 4. Configures the IrDA USART_IrDAMode_LowPower or USART_IrDAMode_Normal mode
+ using the USART_IrDAConfig() function.
+ 5. Enable the IrDA using the USART_IrDACmd() function.
+
+@note A pulse of width less than two and greater than one PSC period(s) may or may
+ not be rejected.
+@note The receiver set up time should be managed by software. The IrDA physical layer
+ specification specifies a minimum of 10 ms delay between transmission and
+ reception (IrDA is a half duplex protocol).
+@note In IrDA mode, the following bits must be kept cleared:
+ - LINEN, STOP and CLKEN bits in the USART_CR2 register.
+ - SCEN and HDSEL bits in the USART_CR3 register.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Configures the USART's IrDA interface.
+ * @param USARTx: where x can be 1, 2, 3, 4, 5 or 6 to select the USART or
+ * UART peripheral.
+ * @param USART_IrDAMode: specifies the IrDA mode.
+ * This parameter can be one of the following values:
+ * @arg USART_IrDAMode_LowPower
+ * @arg USART_IrDAMode_Normal
+ * @retval None
+ */
+void USART_IrDAConfig(USART_TypeDef* USARTx, uint16_t USART_IrDAMode)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+ assert_param(IS_USART_IRDA_MODE(USART_IrDAMode));
+
+ USARTx->CR3 &= (uint16_t)~((uint16_t)USART_CR3_IRLP);
+ USARTx->CR3 |= USART_IrDAMode;
+}
+
+/**
+ * @brief Enables or disables the USART's IrDA interface.
+ * @param USARTx: where x can be 1, 2, 3, 4, 5 or 6 to select the USART or
+ * UART peripheral.
+ * @param NewState: new state of the IrDA mode.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void USART_IrDACmd(USART_TypeDef* USARTx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the IrDA mode by setting the IREN bit in the CR3 register */
+ USARTx->CR3 |= USART_CR3_IREN;
+ }
+ else
+ {
+ /* Disable the IrDA mode by clearing the IREN bit in the CR3 register */
+ USARTx->CR3 &= (uint16_t)~((uint16_t)USART_CR3_IREN);
+ }
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup USART_Group8 DMA transfers management functions
+ * @brief DMA transfers management functions
+ *
+@verbatim
+ ===============================================================================
+ DMA transfers management functions
+ ===============================================================================
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Enables or disables the USART's DMA interface.
+ * @param USARTx: where x can be 1, 2, 3, 4, 5 or 6 to select the USART or
+ * UART peripheral.
+ * @param USART_DMAReq: specifies the DMA request.
+ * This parameter can be any combination of the following values:
+ * @arg USART_DMAReq_Tx: USART DMA transmit request
+ * @arg USART_DMAReq_Rx: USART DMA receive request
+ * @param NewState: new state of the DMA Request sources.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void USART_DMACmd(USART_TypeDef* USARTx, uint16_t USART_DMAReq, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+ assert_param(IS_USART_DMAREQ(USART_DMAReq));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the DMA transfer for selected requests by setting the DMAT and/or
+ DMAR bits in the USART CR3 register */
+ USARTx->CR3 |= USART_DMAReq;
+ }
+ else
+ {
+ /* Disable the DMA transfer for selected requests by clearing the DMAT and/or
+ DMAR bits in the USART CR3 register */
+ USARTx->CR3 &= (uint16_t)~USART_DMAReq;
+ }
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup USART_Group9 Interrupts and flags management functions
+ * @brief Interrupts and flags management functions
+ *
+@verbatim
+ ===============================================================================
+ Interrupts and flags management functions
+ ===============================================================================
+
+ This subsection provides a set of functions allowing to configure the USART
+ Interrupts sources, DMA channels requests and check or clear the flags or
+ pending bits status.
+ The user should identify which mode will be used in his application to manage
+ the communication: Polling mode, Interrupt mode or DMA mode.
+
+ Polling Mode
+ =============
+ In Polling Mode, the SPI communication can be managed by 10 flags:
+ 1. USART_FLAG_TXE : to indicate the status of the transmit buffer register
+ 2. USART_FLAG_RXNE : to indicate the status of the receive buffer register
+ 3. USART_FLAG_TC : to indicate the status of the transmit operation
+ 4. USART_FLAG_IDLE : to indicate the status of the Idle Line
+ 5. USART_FLAG_CTS : to indicate the status of the nCTS input
+ 6. USART_FLAG_LBD : to indicate the status of the LIN break detection
+ 7. USART_FLAG_NE : to indicate if a noise error occur
+ 8. USART_FLAG_FE : to indicate if a frame error occur
+ 9. USART_FLAG_PE : to indicate if a parity error occur
+ 10. USART_FLAG_ORE : to indicate if an Overrun error occur
+
+ In this Mode it is advised to use the following functions:
+ - FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG);
+ - void USART_ClearFlag(USART_TypeDef* USARTx, uint16_t USART_FLAG);
+
+ Interrupt Mode
+ ===============
+ In Interrupt Mode, the USART communication can be managed by 8 interrupt sources
+ and 10 pending bits:
+
+ Pending Bits:
+ -------------
+ 1. USART_IT_TXE : to indicate the status of the transmit buffer register
+ 2. USART_IT_RXNE : to indicate the status of the receive buffer register
+ 3. USART_IT_TC : to indicate the status of the transmit operation
+ 4. USART_IT_IDLE : to indicate the status of the Idle Line
+ 5. USART_IT_CTS : to indicate the status of the nCTS input
+ 6. USART_IT_LBD : to indicate the status of the LIN break detection
+ 7. USART_IT_NE : to indicate if a noise error occur
+ 8. USART_IT_FE : to indicate if a frame error occur
+ 9. USART_IT_PE : to indicate if a parity error occur
+ 10. USART_IT_ORE : to indicate if an Overrun error occur
+
+ Interrupt Source:
+ -----------------
+ 1. USART_IT_TXE : specifies the interrupt source for the Tx buffer empty
+ interrupt.
+ 2. USART_IT_RXNE : specifies the interrupt source for the Rx buffer not
+ empty interrupt.
+ 3. USART_IT_TC : specifies the interrupt source for the Transmit complete
+ interrupt.
+ 4. USART_IT_IDLE : specifies the interrupt source for the Idle Line interrupt.
+ 5. USART_IT_CTS : specifies the interrupt source for the CTS interrupt.
+ 6. USART_IT_LBD : specifies the interrupt source for the LIN break detection
+ interrupt.
+ 7. USART_IT_PE : specifies the interrupt source for the parity error interrupt.
+ 8. USART_IT_ERR : specifies the interrupt source for the errors interrupt.
+
+@note Some parameters are coded in order to use them as interrupt source or as pending bits.
+
+ In this Mode it is advised to use the following functions:
+ - void USART_ITConfig(USART_TypeDef* USARTx, uint16_t USART_IT, FunctionalState NewState);
+ - ITStatus USART_GetITStatus(USART_TypeDef* USARTx, uint16_t USART_IT);
+ - void USART_ClearITPendingBit(USART_TypeDef* USARTx, uint16_t USART_IT);
+
+ DMA Mode
+ ========
+ In DMA Mode, the USART communication can be managed by 2 DMA Channel requests:
+ 1. USART_DMAReq_Tx: specifies the Tx buffer DMA transfer request
+ 2. USART_DMAReq_Rx: specifies the Rx buffer DMA transfer request
+
+ In this Mode it is advised to use the following function:
+ - void USART_DMACmd(USART_TypeDef* USARTx, uint16_t USART_DMAReq, FunctionalState NewState);
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Enables or disables the specified USART interrupts.
+ * @param USARTx: where x can be 1, 2, 3, 4, 5 or 6 to select the USART or
+ * UART peripheral.
+ * @param USART_IT: specifies the USART interrupt sources to be enabled or disabled.
+ * This parameter can be one of the following values:
+ * @arg USART_IT_CTS: CTS change interrupt
+ * @arg USART_IT_LBD: LIN Break detection interrupt
+ * @arg USART_IT_TXE: Transmit Data Register empty interrupt
+ * @arg USART_IT_TC: Transmission complete interrupt
+ * @arg USART_IT_RXNE: Receive Data register not empty interrupt
+ * @arg USART_IT_IDLE: Idle line detection interrupt
+ * @arg USART_IT_PE: Parity Error interrupt
+ * @arg USART_IT_ERR: Error interrupt(Frame error, noise error, overrun error)
+ * @param NewState: new state of the specified USARTx interrupts.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void USART_ITConfig(USART_TypeDef* USARTx, uint16_t USART_IT, FunctionalState NewState)
+{
+ uint32_t usartreg = 0x00, itpos = 0x00, itmask = 0x00;
+ uint32_t usartxbase = 0x00;
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+ assert_param(IS_USART_CONFIG_IT(USART_IT));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ /* The CTS interrupt is not available for UART4 and UART5 */
+ if (USART_IT == USART_IT_CTS)
+ {
+ assert_param(IS_USART_1236_PERIPH(USARTx));
+ }
+
+ usartxbase = (uint32_t)USARTx;
+
+ /* Get the USART register index */
+ usartreg = (((uint8_t)USART_IT) >> 0x05);
+
+ /* Get the interrupt position */
+ itpos = USART_IT & IT_MASK;
+ itmask = (((uint32_t)0x01) << itpos);
+
+ if (usartreg == 0x01) /* The IT is in CR1 register */
+ {
+ usartxbase += 0x0C;
+ }
+ else if (usartreg == 0x02) /* The IT is in CR2 register */
+ {
+ usartxbase += 0x10;
+ }
+ else /* The IT is in CR3 register */
+ {
+ usartxbase += 0x14;
+ }
+ if (NewState != DISABLE)
+ {
+ *(__IO uint32_t*)usartxbase |= itmask;
+ }
+ else
+ {
+ *(__IO uint32_t*)usartxbase &= ~itmask;
+ }
+}
+
+/**
+ * @brief Checks whether the specified USART flag is set or not.
+ * @param USARTx: where x can be 1, 2, 3, 4, 5 or 6 to select the USART or
+ * UART peripheral.
+ * @param USART_FLAG: specifies the flag to check.
+ * This parameter can be one of the following values:
+ * @arg USART_FLAG_CTS: CTS Change flag (not available for UART4 and UART5)
+ * @arg USART_FLAG_LBD: LIN Break detection flag
+ * @arg USART_FLAG_TXE: Transmit data register empty flag
+ * @arg USART_FLAG_TC: Transmission Complete flag
+ * @arg USART_FLAG_RXNE: Receive data register not empty flag
+ * @arg USART_FLAG_IDLE: Idle Line detection flag
+ * @arg USART_FLAG_ORE: OverRun Error flag
+ * @arg USART_FLAG_NE: Noise Error flag
+ * @arg USART_FLAG_FE: Framing Error flag
+ * @arg USART_FLAG_PE: Parity Error flag
+ * @retval The new state of USART_FLAG (SET or RESET).
+ */
+FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG)
+{
+ FlagStatus bitstatus = RESET;
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+ assert_param(IS_USART_FLAG(USART_FLAG));
+
+ /* The CTS flag is not available for UART4 and UART5 */
+ if (USART_FLAG == USART_FLAG_CTS)
+ {
+ assert_param(IS_USART_1236_PERIPH(USARTx));
+ }
+
+ if ((USARTx->SR & USART_FLAG) != (uint16_t)RESET)
+ {
+ bitstatus = SET;
+ }
+ else
+ {
+ bitstatus = RESET;
+ }
+ return bitstatus;
+}
+
+/**
+ * @brief Clears the USARTx's pending flags.
+ * @param USARTx: where x can be 1, 2, 3, 4, 5 or 6 to select the USART or
+ * UART peripheral.
+ * @param USART_FLAG: specifies the flag to clear.
+ * This parameter can be any combination of the following values:
+ * @arg USART_FLAG_CTS: CTS Change flag (not available for UART4 and UART5).
+ * @arg USART_FLAG_LBD: LIN Break detection flag.
+ * @arg USART_FLAG_TC: Transmission Complete flag.
+ * @arg USART_FLAG_RXNE: Receive data register not empty flag.
+ *
+ * @note PE (Parity error), FE (Framing error), NE (Noise error), ORE (OverRun
+ * error) and IDLE (Idle line detected) flags are cleared by software
+ * sequence: a read operation to USART_SR register (USART_GetFlagStatus())
+ * followed by a read operation to USART_DR register (USART_ReceiveData()).
+ * @note RXNE flag can be also cleared by a read to the USART_DR register
+ * (USART_ReceiveData()).
+ * @note TC flag can be also cleared by software sequence: a read operation to
+ * USART_SR register (USART_GetFlagStatus()) followed by a write operation
+ * to USART_DR register (USART_SendData()).
+ * @note TXE flag is cleared only by a write to the USART_DR register
+ * (USART_SendData()).
+ *
+ * @retval None
+ */
+void USART_ClearFlag(USART_TypeDef* USARTx, uint16_t USART_FLAG)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+ assert_param(IS_USART_CLEAR_FLAG(USART_FLAG));
+
+ /* The CTS flag is not available for UART4 and UART5 */
+ if ((USART_FLAG & USART_FLAG_CTS) == USART_FLAG_CTS)
+ {
+ assert_param(IS_USART_1236_PERIPH(USARTx));
+ }
+
+ USARTx->SR = (uint16_t)~USART_FLAG;
+}
+
+/**
+ * @brief Checks whether the specified USART interrupt has occurred or not.
+ * @param USARTx: where x can be 1, 2, 3, 4, 5 or 6 to select the USART or
+ * UART peripheral.
+ * @param USART_IT: specifies the USART interrupt source to check.
+ * This parameter can be one of the following values:
+ * @arg USART_IT_CTS : CTS change interrupt (not available for UART4 and UART5)
+ * @arg USART_IT_LBD : LIN Break detection interrupt
+ * @arg USART_IT_TXE : Transmit Data Register empty interrupt
+ * @arg USART_IT_TC : Transmission complete interrupt
+ * @arg USART_IT_RXNE : Receive Data register not empty interrupt
+ * @arg USART_IT_IDLE : Idle line detection interrupt
+ * @arg USART_IT_ORE_RX : OverRun Error interrupt if the RXNEIE bit is set
+ * @arg USART_IT_ORE_ER : OverRun Error interrupt if the EIE bit is set
+ * @arg USART_IT_NE : Noise Error interrupt
+ * @arg USART_IT_FE : Framing Error interrupt
+ * @arg USART_IT_PE : Parity Error interrupt
+ * @retval The new state of USART_IT (SET or RESET).
+ */
+ITStatus USART_GetITStatus(USART_TypeDef* USARTx, uint16_t USART_IT)
+{
+ uint32_t bitpos = 0x00, itmask = 0x00, usartreg = 0x00;
+ ITStatus bitstatus = RESET;
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+ assert_param(IS_USART_GET_IT(USART_IT));
+
+ /* The CTS interrupt is not available for UART4 and UART5 */
+ if (USART_IT == USART_IT_CTS)
+ {
+ assert_param(IS_USART_1236_PERIPH(USARTx));
+ }
+
+ /* Get the USART register index */
+ usartreg = (((uint8_t)USART_IT) >> 0x05);
+ /* Get the interrupt position */
+ itmask = USART_IT & IT_MASK;
+ itmask = (uint32_t)0x01 << itmask;
+
+ if (usartreg == 0x01) /* The IT is in CR1 register */
+ {
+ itmask &= USARTx->CR1;
+ }
+ else if (usartreg == 0x02) /* The IT is in CR2 register */
+ {
+ itmask &= USARTx->CR2;
+ }
+ else /* The IT is in CR3 register */
+ {
+ itmask &= USARTx->CR3;
+ }
+
+ bitpos = USART_IT >> 0x08;
+ bitpos = (uint32_t)0x01 << bitpos;
+ bitpos &= USARTx->SR;
+ if ((itmask != (uint16_t)RESET)&&(bitpos != (uint16_t)RESET))
+ {
+ bitstatus = SET;
+ }
+ else
+ {
+ bitstatus = RESET;
+ }
+
+ return bitstatus;
+}
+
+/**
+ * @brief Clears the USARTx's interrupt pending bits.
+ * @param USARTx: where x can be 1, 2, 3, 4, 5 or 6 to select the USART or
+ * UART peripheral.
+ * @param USART_IT: specifies the interrupt pending bit to clear.
+ * This parameter can be one of the following values:
+ * @arg USART_IT_CTS: CTS change interrupt (not available for UART4 and UART5)
+ * @arg USART_IT_LBD: LIN Break detection interrupt
+ * @arg USART_IT_TC: Transmission complete interrupt.
+ * @arg USART_IT_RXNE: Receive Data register not empty interrupt.
+ *
+ * @note PE (Parity error), FE (Framing error), NE (Noise error), ORE (OverRun
+ * error) and IDLE (Idle line detected) pending bits are cleared by
+ * software sequence: a read operation to USART_SR register
+ * (USART_GetITStatus()) followed by a read operation to USART_DR register
+ * (USART_ReceiveData()).
+ * @note RXNE pending bit can be also cleared by a read to the USART_DR register
+ * (USART_ReceiveData()).
+ * @note TC pending bit can be also cleared by software sequence: a read
+ * operation to USART_SR register (USART_GetITStatus()) followed by a write
+ * operation to USART_DR register (USART_SendData()).
+ * @note TXE pending bit is cleared only by a write to the USART_DR register
+ * (USART_SendData()).
+ *
+ * @retval None
+ */
+void USART_ClearITPendingBit(USART_TypeDef* USARTx, uint16_t USART_IT)
+{
+ uint16_t bitpos = 0x00, itmask = 0x00;
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+ assert_param(IS_USART_CLEAR_IT(USART_IT));
+
+ /* The CTS interrupt is not available for UART4 and UART5 */
+ if (USART_IT == USART_IT_CTS)
+ {
+ assert_param(IS_USART_1236_PERIPH(USARTx));
+ }
+
+ bitpos = USART_IT >> 0x08;
+ itmask = ((uint16_t)0x01 << (uint16_t)bitpos);
+ USARTx->SR = (uint16_t)~itmask;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/src/stm32f2xx_wwdg.c b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/src/stm32f2xx_wwdg.c
new file mode 100644
index 0000000..4d715dc
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32F2xx_StdPeriph_Driver/src/stm32f2xx_wwdg.c
@@ -0,0 +1,309 @@
+/**
+ ******************************************************************************
+ * @file stm32f2xx_wwdg.c
+ * @author MCD Application Team
+ * @version V1.1.2
+ * @date 05-March-2012
+ * @brief This file provides firmware functions to manage the following
+ * functionalities of the Window watchdog (WWDG) peripheral:
+ * - Prescaler, Refresh window and Counter configuration
+ * - WWDG activation
+ * - Interrupts and flags management
+ *
+ * @verbatim
+ *
+ * ===================================================================
+ * WWDG features
+ * ===================================================================
+ *
+ * Once enabled the WWDG generates a system reset on expiry of a programmed
+ * time period, unless the program refreshes the counter (downcounter)
+ * before to reach 0x3F value (i.e. a reset is generated when the counter
+ * value rolls over from 0x40 to 0x3F).
+ * An MCU reset is also generated if the counter value is refreshed
+ * before the counter has reached the refresh window value. This
+ * implies that the counter must be refreshed in a limited window.
+ *
+ * Once enabled the WWDG cannot be disabled except by a system reset.
+ *
+ * WWDGRST flag in RCC_CSR register can be used to inform when a WWDG
+ * reset occurs.
+ *
+ * The WWDG counter input clock is derived from the APB clock divided
+ * by a programmable prescaler.
+ *
+ * WWDG counter clock = PCLK1 / Prescaler
+ * WWDG timeout = (WWDG counter clock) * (counter value)
+ *
+ * Min-max timeout value @30 MHz(PCLK1): ~136.5 us / ~69.9 ms
+ *
+ * ===================================================================
+ * How to use this driver
+ * ===================================================================
+ * 1. Enable WWDG clock using RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE) function
+ *
+ * 2. Configure the WWDG prescaler using WWDG_SetPrescaler() function
+ *
+ * 3. Configure the WWDG refresh window using WWDG_SetWindowValue() function
+ *
+ * 4. Set the WWDG counter value and start it using WWDG_Enable() function.
+ * When the WWDG is enabled the counter value should be configured to
+ * a value greater than 0x40 to prevent generating an immediate reset.
+ *
+ * 5. Optionally you can enable the Early wakeup interrupt which is
+ * generated when the counter reach 0x40.
+ * Once enabled this interrupt cannot be disabled except by a system reset.
+ *
+ * 6. Then the application program must refresh the WWDG counter at regular
+ * intervals during normal operation to prevent an MCU reset, using
+ * WWDG_SetCounter() function. This operation must occur only when
+ * the counter value is lower than the refresh window value,
+ * programmed using WWDG_SetWindowValue().
+ *
+ * @endverbatim
+ *
+ ******************************************************************************
+ * @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 "stm32f2xx_wwdg.h"
+#include "stm32f2xx_rcc.h"
+
+/** @addtogroup STM32F2xx_StdPeriph_Driver
+ * @{
+ */
+
+/** @defgroup WWDG
+ * @brief WWDG driver modules
+ * @{
+ */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+
+/* ----------- WWDG registers bit address in the alias region ----------- */
+#define WWDG_OFFSET (WWDG_BASE - PERIPH_BASE)
+/* Alias word address of EWI bit */
+#define CFR_OFFSET (WWDG_OFFSET + 0x04)
+#define EWI_BitNumber 0x09
+#define CFR_EWI_BB (PERIPH_BB_BASE + (CFR_OFFSET * 32) + (EWI_BitNumber * 4))
+
+/* --------------------- WWDG registers bit mask ------------------------ */
+/* CFR register bit mask */
+#define CFR_WDGTB_MASK ((uint32_t)0xFFFFFE7F)
+#define CFR_W_MASK ((uint32_t)0xFFFFFF80)
+#define BIT_MASK ((uint8_t)0x7F)
+
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+/** @defgroup WWDG_Private_Functions
+ * @{
+ */
+
+/** @defgroup WWDG_Group1 Prescaler, Refresh window and Counter configuration functions
+ * @brief Prescaler, Refresh window and Counter configuration functions
+ *
+@verbatim
+ ===============================================================================
+ Prescaler, Refresh window and Counter configuration functions
+ ===============================================================================
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Deinitializes the WWDG peripheral registers to their default reset values.
+ * @param None
+ * @retval None
+ */
+void WWDG_DeInit(void)
+{
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_WWDG, ENABLE);
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_WWDG, DISABLE);
+}
+
+/**
+ * @brief Sets the WWDG Prescaler.
+ * @param WWDG_Prescaler: specifies the WWDG Prescaler.
+ * This parameter can be one of the following values:
+ * @arg WWDG_Prescaler_1: WWDG counter clock = (PCLK1/4096)/1
+ * @arg WWDG_Prescaler_2: WWDG counter clock = (PCLK1/4096)/2
+ * @arg WWDG_Prescaler_4: WWDG counter clock = (PCLK1/4096)/4
+ * @arg WWDG_Prescaler_8: WWDG counter clock = (PCLK1/4096)/8
+ * @retval None
+ */
+void WWDG_SetPrescaler(uint32_t WWDG_Prescaler)
+{
+ uint32_t tmpreg = 0;
+ /* Check the parameters */
+ assert_param(IS_WWDG_PRESCALER(WWDG_Prescaler));
+ /* Clear WDGTB[1:0] bits */
+ tmpreg = WWDG->CFR & CFR_WDGTB_MASK;
+ /* Set WDGTB[1:0] bits according to WWDG_Prescaler value */
+ tmpreg |= WWDG_Prescaler;
+ /* Store the new value */
+ WWDG->CFR = tmpreg;
+}
+
+/**
+ * @brief Sets the WWDG window value.
+ * @param WindowValue: specifies the window value to be compared to the downcounter.
+ * This parameter value must be lower than 0x80.
+ * @retval None
+ */
+void WWDG_SetWindowValue(uint8_t WindowValue)
+{
+ __IO uint32_t tmpreg = 0;
+
+ /* Check the parameters */
+ assert_param(IS_WWDG_WINDOW_VALUE(WindowValue));
+ /* Clear W[6:0] bits */
+
+ tmpreg = WWDG->CFR & CFR_W_MASK;
+
+ /* Set W[6:0] bits according to WindowValue value */
+ tmpreg |= WindowValue & (uint32_t) BIT_MASK;
+
+ /* Store the new value */
+ WWDG->CFR = tmpreg;
+}
+
+/**
+ * @brief Enables the WWDG Early Wakeup interrupt(EWI).
+ * @note Once enabled this interrupt cannot be disabled except by a system reset.
+ * @param None
+ * @retval None
+ */
+void WWDG_EnableIT(void)
+{
+ *(__IO uint32_t *) CFR_EWI_BB = (uint32_t)ENABLE;
+}
+
+/**
+ * @brief Sets the WWDG counter value.
+ * @param Counter: specifies the watchdog counter value.
+ * This parameter must be a number between 0x40 and 0x7F (to prevent generating
+ * an immediate reset)
+ * @retval None
+ */
+void WWDG_SetCounter(uint8_t Counter)
+{
+ /* Check the parameters */
+ assert_param(IS_WWDG_COUNTER(Counter));
+ /* Write to T[6:0] bits to configure the counter value, no need to do
+ a read-modify-write; writing a 0 to WDGA bit does nothing */
+ WWDG->CR = Counter & BIT_MASK;
+}
+/**
+ * @}
+ */
+
+/** @defgroup WWDG_Group2 WWDG activation functions
+ * @brief WWDG activation functions
+ *
+@verbatim
+ ===============================================================================
+ WWDG activation function
+ ===============================================================================
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Enables WWDG and load the counter value.
+ * @param Counter: specifies the watchdog counter value.
+ * This parameter must be a number between 0x40 and 0x7F (to prevent generating
+ * an immediate reset)
+ * @retval None
+ */
+void WWDG_Enable(uint8_t Counter)
+{
+ /* Check the parameters */
+ assert_param(IS_WWDG_COUNTER(Counter));
+ WWDG->CR = WWDG_CR_WDGA | Counter;
+}
+/**
+ * @}
+ */
+
+/** @defgroup WWDG_Group3 Interrupts and flags management functions
+ * @brief Interrupts and flags management functions
+ *
+@verbatim
+ ===============================================================================
+ Interrupts and flags management functions
+ ===============================================================================
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Checks whether the Early Wakeup interrupt flag is set or not.
+ * @param None
+ * @retval The new state of the Early Wakeup interrupt flag (SET or RESET)
+ */
+FlagStatus WWDG_GetFlagStatus(void)
+{
+ FlagStatus bitstatus = RESET;
+
+ if ((WWDG->SR) != (uint32_t)RESET)
+ {
+ bitstatus = SET;
+ }
+ else
+ {
+ bitstatus = RESET;
+ }
+ return bitstatus;
+}
+
+/**
+ * @brief Clears Early Wakeup interrupt flag.
+ * @param None
+ * @retval None
+ */
+void WWDG_ClearFlag(void)
+{
+ WWDG->SR = (uint32_t)RESET;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/audio/inc/usbd_audio_core.h b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/audio/inc/usbd_audio_core.h
new file mode 100644
index 0000000..a0547eb
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/audio/inc/usbd_audio_core.h
@@ -0,0 +1,164 @@
+/**
+ ******************************************************************************
+ * @file usbd_audio_core.h
+ * @author MCD Application Team
+ * @version V1.1.0
+ * @date 19-March-2012
+ * @brief header file for the usbd_audio_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_AUDIO_CORE_H_
+#define __USB_AUDIO_CORE_H_
+
+#include "usbd_ioreq.h"
+#include "usbd_req.h"
+#include "usbd_desc.h"
+
+
+
+
+/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
+ * @{
+ */
+
+/** @defgroup usbd_audio
+ * @brief This file is the Header file for USBD_audio.c
+ * @{
+ */
+
+
+/** @defgroup usbd_audio_Exported_Defines
+ * @{
+ */
+
+/* AudioFreq * DataSize (2 bytes) * NumChannels (Stereo: 2) */
+#define AUDIO_OUT_PACKET (uint32_t)(((USBD_AUDIO_FREQ * 2 * 2) /1000))
+
+/* Number of sub-packets in the audio transfer buffer. You can modify this value but always make sure
+ that it is an even number and higher than 3 */
+#define OUT_PACKET_NUM 4
+/* Total size of the audio transfer buffer */
+#define TOTAL_OUT_BUF_SIZE ((uint32_t)(AUDIO_OUT_PACKET * OUT_PACKET_NUM))
+
+#define AUDIO_CONFIG_DESC_SIZE 109
+#define AUDIO_INTERFACE_DESC_SIZE 9
+#define USB_AUDIO_DESC_SIZ 0x09
+#define AUDIO_STANDARD_ENDPOINT_DESC_SIZE 0x09
+#define AUDIO_STREAMING_ENDPOINT_DESC_SIZE 0x07
+
+#define AUDIO_DESCRIPTOR_TYPE 0x21
+#define USB_DEVICE_CLASS_AUDIO 0x01
+#define AUDIO_SUBCLASS_AUDIOCONTROL 0x01
+#define AUDIO_SUBCLASS_AUDIOSTREAMING 0x02
+#define AUDIO_PROTOCOL_UNDEFINED 0x00
+#define AUDIO_STREAMING_GENERAL 0x01
+#define AUDIO_STREAMING_FORMAT_TYPE 0x02
+
+/* Audio Descriptor Types */
+#define AUDIO_INTERFACE_DESCRIPTOR_TYPE 0x24
+#define AUDIO_ENDPOINT_DESCRIPTOR_TYPE 0x25
+
+/* Audio Control Interface Descriptor Subtypes */
+#define AUDIO_CONTROL_HEADER 0x01
+#define AUDIO_CONTROL_INPUT_TERMINAL 0x02
+#define AUDIO_CONTROL_OUTPUT_TERMINAL 0x03
+#define AUDIO_CONTROL_FEATURE_UNIT 0x06
+
+#define AUDIO_INPUT_TERMINAL_DESC_SIZE 0x0C
+#define AUDIO_OUTPUT_TERMINAL_DESC_SIZE 0x09
+#define AUDIO_STREAMING_INTERFACE_DESC_SIZE 0x07
+
+#define AUDIO_CONTROL_MUTE 0x0001
+
+#define AUDIO_FORMAT_TYPE_I 0x01
+#define AUDIO_FORMAT_TYPE_III 0x03
+
+#define USB_ENDPOINT_TYPE_ISOCHRONOUS 0x01
+#define AUDIO_ENDPOINT_GENERAL 0x01
+
+#define AUDIO_REQ_GET_CUR 0x81
+#define AUDIO_REQ_SET_CUR 0x01
+
+#define AUDIO_OUT_STREAMING_CTRL 0x02
+
+/**
+ * @}
+ */
+
+
+/** @defgroup USBD_CORE_Exported_TypesDefinitions
+ * @{
+ */
+typedef struct _Audio_Fops
+{
+ uint8_t (*Init) (uint32_t AudioFreq, uint32_t Volume, uint32_t options);
+ uint8_t (*DeInit) (uint32_t options);
+ uint8_t (*AudioCmd) (uint8_t* pbuf, uint32_t size, uint8_t cmd);
+ uint8_t (*VolumeCtl) (uint8_t vol);
+ uint8_t (*MuteCtl) (uint8_t cmd);
+ uint8_t (*PeriodicTC) (uint8_t cmd);
+ uint8_t (*GetState) (void);
+}AUDIO_FOPS_TypeDef;
+/**
+ * @}
+ */
+
+
+
+/** @defgroup USBD_CORE_Exported_Macros
+ * @{
+ */
+#define AUDIO_PACKET_SZE(frq) (uint8_t)(((frq * 2 * 2)/1000) & 0xFF), \
+ (uint8_t)((((frq * 2 * 2)/1000) >> 8) & 0xFF)
+#define SAMPLE_FREQ(frq) (uint8_t)(frq), (uint8_t)((frq >> 8)), (uint8_t)((frq >> 16))
+/**
+ * @}
+ */
+
+/** @defgroup USBD_CORE_Exported_Variables
+ * @{
+ */
+
+extern USBD_Class_cb_TypeDef AUDIO_cb;
+
+/**
+ * @}
+ */
+
+/** @defgroup USB_CORE_Exported_Functions
+ * @{
+ */
+/**
+ * @}
+ */
+
+#endif // __USB_AUDIO_CORE_H_
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/audio/inc/usbd_audio_out_if.h b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/audio/inc/usbd_audio_out_if.h
new file mode 100644
index 0000000..8b4fd4a
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/audio/inc/usbd_audio_out_if.h
@@ -0,0 +1,125 @@
+/**
+ ******************************************************************************
+ * @file usbd_audio_out_if.h
+ * @author MCD Application Team
+ * @version V1.1.0
+ * @date 19-March-2012
+ * @brief header file for the usbd_audio_out_if.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_AUDIO_OUT_IF_H_
+#define __USB_AUDIO_OUT_IF_H_
+
+#ifdef STM32F2XX
+ #include "stm322xg_usb_audio_codec.h"
+#elif defined(STM32F4XX)
+ #include "stm324xg_usb_audio_codec.h"
+#elif defined(STM32F10X_CL)
+ #include "stm3210c_usb_audio_codec.h"
+#endif /* STM32F2XX */
+
+/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
+ * @{
+ */
+
+/** @defgroup usbd_audio
+ * @brief This file is the Header file for USBD_audio.c
+ * @{
+ */
+
+
+/** @defgroup usbd_audio_Exported_Defines
+ * @{
+ */
+/* Audio Commands enmueration */
+typedef enum
+{
+ AUDIO_CMD_PLAY = 1,
+ AUDIO_CMD_PAUSE,
+ AUDIO_CMD_STOP,
+}AUDIO_CMD_TypeDef;
+
+/* Mute commands */
+#define AUDIO_MUTE 0x01
+#define AUDIO_UNMUTE 0x00
+
+/* Functions return value */
+#define AUDIO_OK 0x00
+#define AUDIO_FAIL 0xFF
+
+/* Audio Machine States */
+#define AUDIO_STATE_INACTIVE 0x00
+#define AUDIO_STATE_ACTIVE 0x01
+#define AUDIO_STATE_PLAYING 0x02
+#define AUDIO_STATE_PAUSED 0x03
+#define AUDIO_STATE_STOPPED 0x04
+#define AUDIO_STATE_ERROR 0x05
+
+/**
+ * @}
+ */
+
+
+/** @defgroup USBD_CORE_Exported_TypesDefinitions
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+
+/** @defgroup USBD_CORE_Exported_Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USBD_CORE_Exported_Variables
+ * @{
+ */
+
+extern AUDIO_FOPS_TypeDef AUDIO_OUT_fops;
+
+/**
+ * @}
+ */
+
+/** @defgroup USB_CORE_Exported_Functions
+ * @{
+ */
+/**
+ * @}
+ */
+
+#endif /* __USB_AUDIO_OUT_IF_H_ */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/audio/src/usbd_audio_core.c b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/audio/src/usbd_audio_core.c
new file mode 100644
index 0000000..b74bf3f
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/audio/src/usbd_audio_core.c
@@ -0,0 +1,671 @@
+/**
+ ******************************************************************************
+ * @file usbd_audio_core.c
+ * @author MCD Application Team
+ * @version V1.1.0
+ * @date 19-March-2012
+ * @brief This file provides the high layer firmware functions to manage the
+ * following functionalities of the USB Audio Class:
+ * - Initialization and Configuration of high and low layer
+ * - Enumeration as Audio Streaming Device
+ * - Audio Streaming data transfer
+ * - AudioControl requests management
+ * - Error management
+ *
+ * @verbatim
+ *
+ * ===================================================================
+ * Audio Class Driver Description
+ * ===================================================================
+ * This driver manages the Audio Class 1.0 following the "USB Device Class Definition for
+ * Audio Devices V1.0 Mar 18, 98".
+ * This driver implements the following aspects of the specification:
+ * - Device descriptor management
+ * - Configuration descriptor management
+ * - Standard AC Interface Descriptor management
+ * - 1 Audio Streaming Interface (with single channel, PCM, Stereo mode)
+ * - 1 Audio Streaming Endpoint
+ * - 1 Audio Terminal Input (1 channel)
+ * - Audio Class-Specific AC Interfaces
+ * - Audio Class-Specific AS Interfaces
+ * - AudioControl Requests: only SET_CUR and GET_CUR requests are supported (for Mute)
+ * - Audio Feature Unit (limited to Mute control)
+ * - Audio Synchronization type: Asynchronous
+ * - Single fixed audio sampling rate (configurable in usbd_conf.h file)
+ *
+ * @note
+ * The Audio Class 1.0 is based on USB Specification 1.0 and thus supports only
+ * Low and Full speed modes and does not allow High Speed transfers.
+ * Please refer to "USB Device Class Definition for Audio Devices V1.0 Mar 18, 98"
+ * for more details.
+ *
+ * These aspects may be enriched or modified for a specific user application.
+ *
+ * This driver doesn't implement the following aspects of the specification
+ * (but it is possible to manage these features with some modifications on this driver):
+ * - AudioControl Endpoint management
+ * - AudioControl requsests other than SET_CUR and GET_CUR
+ * - Abstraction layer for AudioControl requests (only Mute functionality is managed)
+ * - Audio Synchronization type: Adaptive
+ * - Audio Compression modules and interfaces
+ * - MIDI interfaces and modules
+ * - Mixer/Selector/Processing/Extension Units (Feature unit is limited to Mute control)
+ * - Any other application-specific modules
+ * - Multiple and Variable audio sampling rates
+ * - Out Streaming Endpoint/Interface (microphone)
+ *
+ * @endverbatim
+ *
+ ******************************************************************************
+ * @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_audio_core.h"
+#include "usbd_audio_out_if.h"
+
+/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
+ * @{
+ */
+
+
+/** @defgroup usbd_audio
+ * @brief usbd core module
+ * @{
+ */
+
+/** @defgroup usbd_audio_Private_TypesDefinitions
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup usbd_audio_Private_Defines
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup usbd_audio_Private_Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup usbd_audio_Private_FunctionPrototypes
+ * @{
+ */
+
+/*********************************************
+ AUDIO Device library callbacks
+ *********************************************/
+static uint8_t usbd_audio_Init (void *pdev, uint8_t cfgidx);
+static uint8_t usbd_audio_DeInit (void *pdev, uint8_t cfgidx);
+static uint8_t usbd_audio_Setup (void *pdev, USB_SETUP_REQ *req);
+static uint8_t usbd_audio_EP0_RxReady(void *pdev);
+static uint8_t usbd_audio_DataIn (void *pdev, uint8_t epnum);
+static uint8_t usbd_audio_DataOut (void *pdev, uint8_t epnum);
+static uint8_t usbd_audio_SOF (void *pdev);
+static uint8_t usbd_audio_OUT_Incplt (void *pdev);
+
+/*********************************************
+ AUDIO Requests management functions
+ *********************************************/
+static void AUDIO_Req_GetCurrent(void *pdev, USB_SETUP_REQ *req);
+static void AUDIO_Req_SetCurrent(void *pdev, USB_SETUP_REQ *req);
+static uint8_t *USBD_audio_GetCfgDesc (uint8_t speed, uint16_t *length);
+/**
+ * @}
+ */
+
+/** @defgroup usbd_audio_Private_Variables
+ * @{
+ */
+/* Main Buffer for Audio Data Out transfers and its relative pointers */
+uint8_t IsocOutBuff [TOTAL_OUT_BUF_SIZE * 2];
+uint8_t* IsocOutWrPtr = IsocOutBuff;
+uint8_t* IsocOutRdPtr = IsocOutBuff;
+
+/* Main Buffer for Audio Control Rrequests transfers and its relative variables */
+uint8_t AudioCtl[64];
+uint8_t AudioCtlCmd = 0;
+uint32_t AudioCtlLen = 0;
+uint8_t AudioCtlUnit = 0;
+
+static uint32_t PlayFlag = 0;
+
+static __IO uint32_t usbd_audio_AltSet = 0;
+static uint8_t usbd_audio_CfgDesc[AUDIO_CONFIG_DESC_SIZE];
+
+/* AUDIO interface class callbacks structure */
+USBD_Class_cb_TypeDef AUDIO_cb =
+{
+ usbd_audio_Init,
+ usbd_audio_DeInit,
+ usbd_audio_Setup,
+ NULL, /* EP0_TxSent */
+ usbd_audio_EP0_RxReady,
+ usbd_audio_DataIn,
+ usbd_audio_DataOut,
+ usbd_audio_SOF,
+ NULL,
+ usbd_audio_OUT_Incplt,
+ USBD_audio_GetCfgDesc,
+#ifdef USB_OTG_HS_CORE
+ USBD_audio_GetCfgDesc, /* use same config as per FS */
+#endif
+};
+
+/* USB AUDIO device Configuration Descriptor */
+static uint8_t usbd_audio_CfgDesc[AUDIO_CONFIG_DESC_SIZE] =
+{
+ /* Configuration 1 */
+ 0x09, /* bLength */
+ USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType */
+ LOBYTE(AUDIO_CONFIG_DESC_SIZE), /* wTotalLength 109 bytes*/
+ HIBYTE(AUDIO_CONFIG_DESC_SIZE),
+ 0x02, /* bNumInterfaces */
+ 0x01, /* bConfigurationValue */
+ 0x00, /* iConfiguration */
+ 0xC0, /* bmAttributes BUS Powred*/
+ 0x32, /* bMaxPower = 100 mA*/
+ /* 09 byte*/
+
+ /* USB Speaker Standard interface descriptor */
+ AUDIO_INTERFACE_DESC_SIZE, /* bLength */
+ USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
+ 0x00, /* bInterfaceNumber */
+ 0x00, /* bAlternateSetting */
+ 0x00, /* bNumEndpoints */
+ USB_DEVICE_CLASS_AUDIO, /* bInterfaceClass */
+ AUDIO_SUBCLASS_AUDIOCONTROL, /* bInterfaceSubClass */
+ AUDIO_PROTOCOL_UNDEFINED, /* bInterfaceProtocol */
+ 0x00, /* iInterface */
+ /* 09 byte*/
+
+ /* USB Speaker Class-specific AC Interface Descriptor */
+ AUDIO_INTERFACE_DESC_SIZE, /* bLength */
+ AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
+ AUDIO_CONTROL_HEADER, /* bDescriptorSubtype */
+ 0x00, /* 1.00 */ /* bcdADC */
+ 0x01,
+ 0x27, /* wTotalLength = 39*/
+ 0x00,
+ 0x01, /* bInCollection */
+ 0x01, /* baInterfaceNr */
+ /* 09 byte*/
+
+ /* USB Speaker Input Terminal Descriptor */
+ AUDIO_INPUT_TERMINAL_DESC_SIZE, /* bLength */
+ AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
+ AUDIO_CONTROL_INPUT_TERMINAL, /* bDescriptorSubtype */
+ 0x01, /* bTerminalID */
+ 0x01, /* wTerminalType AUDIO_TERMINAL_USB_STREAMING 0x0101 */
+ 0x01,
+ 0x00, /* bAssocTerminal */
+ 0x01, /* bNrChannels */
+ 0x00, /* wChannelConfig 0x0000 Mono */
+ 0x00,
+ 0x00, /* iChannelNames */
+ 0x00, /* iTerminal */
+ /* 12 byte*/
+
+ /* USB Speaker Audio Feature Unit Descriptor */
+ 0x09, /* bLength */
+ AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
+ AUDIO_CONTROL_FEATURE_UNIT, /* bDescriptorSubtype */
+ AUDIO_OUT_STREAMING_CTRL, /* bUnitID */
+ 0x01, /* bSourceID */
+ 0x01, /* bControlSize */
+ AUDIO_CONTROL_MUTE, /* bmaControls(0) */
+ 0x00, /* bmaControls(1) */
+ 0x00, /* iTerminal */
+ /* 09 byte*/
+
+ /*USB Speaker Output Terminal Descriptor */
+ 0x09, /* bLength */
+ AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
+ AUDIO_CONTROL_OUTPUT_TERMINAL, /* bDescriptorSubtype */
+ 0x03, /* bTerminalID */
+ 0x01, /* wTerminalType 0x0301*/
+ 0x03,
+ 0x00, /* bAssocTerminal */
+ 0x02, /* bSourceID */
+ 0x00, /* iTerminal */
+ /* 09 byte*/
+
+ /* USB Speaker Standard AS Interface Descriptor - Audio Streaming Zero Bandwith */
+ /* Interface 1, Alternate Setting 0 */
+ AUDIO_INTERFACE_DESC_SIZE, /* bLength */
+ USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
+ 0x01, /* bInterfaceNumber */
+ 0x00, /* bAlternateSetting */
+ 0x00, /* bNumEndpoints */
+ USB_DEVICE_CLASS_AUDIO, /* bInterfaceClass */
+ AUDIO_SUBCLASS_AUDIOSTREAMING, /* bInterfaceSubClass */
+ AUDIO_PROTOCOL_UNDEFINED, /* bInterfaceProtocol */
+ 0x00, /* iInterface */
+ /* 09 byte*/
+
+ /* USB Speaker Standard AS Interface Descriptor - Audio Streaming Operational */
+ /* Interface 1, Alternate Setting 1 */
+ AUDIO_INTERFACE_DESC_SIZE, /* bLength */
+ USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
+ 0x01, /* bInterfaceNumber */
+ 0x01, /* bAlternateSetting */
+ 0x01, /* bNumEndpoints */
+ USB_DEVICE_CLASS_AUDIO, /* bInterfaceClass */
+ AUDIO_SUBCLASS_AUDIOSTREAMING, /* bInterfaceSubClass */
+ AUDIO_PROTOCOL_UNDEFINED, /* bInterfaceProtocol */
+ 0x00, /* iInterface */
+ /* 09 byte*/
+
+ /* USB Speaker Audio Streaming Interface Descriptor */
+ AUDIO_STREAMING_INTERFACE_DESC_SIZE, /* bLength */
+ AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
+ AUDIO_STREAMING_GENERAL, /* bDescriptorSubtype */
+ 0x01, /* bTerminalLink */
+ 0x01, /* bDelay */
+ 0x01, /* wFormatTag AUDIO_FORMAT_PCM 0x0001*/
+ 0x00,
+ /* 07 byte*/
+
+ /* USB Speaker Audio Type III Format Interface Descriptor */
+ 0x0B, /* bLength */
+ AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
+ AUDIO_STREAMING_FORMAT_TYPE, /* bDescriptorSubtype */
+ AUDIO_FORMAT_TYPE_III, /* bFormatType */
+ 0x02, /* bNrChannels */
+ 0x02, /* bSubFrameSize : 2 Bytes per frame (16bits) */
+ 16, /* bBitResolution (16-bits per sample) */
+ 0x01, /* bSamFreqType only one frequency supported */
+ SAMPLE_FREQ(USBD_AUDIO_FREQ), /* Audio sampling frequency coded on 3 bytes */
+ /* 11 byte*/
+
+ /* Endpoint 1 - Standard Descriptor */
+ AUDIO_STANDARD_ENDPOINT_DESC_SIZE, /* bLength */
+ USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */
+ AUDIO_OUT_EP, /* bEndpointAddress 1 out endpoint*/
+ USB_ENDPOINT_TYPE_ISOCHRONOUS, /* bmAttributes */
+ AUDIO_PACKET_SZE(USBD_AUDIO_FREQ), /* wMaxPacketSize in Bytes (Freq(Samples)*2(Stereo)*2(HalfWord)) */
+ 0x01, /* bInterval */
+ 0x00, /* bRefresh */
+ 0x00, /* bSynchAddress */
+ /* 09 byte*/
+
+ /* Endpoint - Audio Streaming Descriptor*/
+ AUDIO_STREAMING_ENDPOINT_DESC_SIZE, /* bLength */
+ AUDIO_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */
+ AUDIO_ENDPOINT_GENERAL, /* bDescriptor */
+ 0x00, /* bmAttributes */
+ 0x00, /* bLockDelayUnits */
+ 0x00, /* wLockDelay */
+ 0x00,
+ /* 07 byte*/
+} ;
+
+/**
+ * @}
+ */
+
+/** @defgroup usbd_audio_Private_Functions
+ * @{
+ */
+
+/**
+* @brief usbd_audio_Init
+* Initilaizes the AUDIO interface.
+* @param pdev: device instance
+* @param cfgidx: Configuration index
+* @retval status
+*/
+static uint8_t usbd_audio_Init (void *pdev,
+ uint8_t cfgidx)
+{
+ /* Open EP OUT */
+ DCD_EP_Open(pdev,
+ AUDIO_OUT_EP,
+ AUDIO_OUT_PACKET,
+ USB_OTG_EP_ISOC);
+
+ /* Initialize the Audio output Hardware layer */
+ if (AUDIO_OUT_fops.Init(USBD_AUDIO_FREQ, DEFAULT_VOLUME, 0) != USBD_OK)
+ {
+ return USBD_FAIL;
+ }
+
+ /* Prepare Out endpoint to receive audio data */
+ DCD_EP_PrepareRx(pdev,
+ AUDIO_OUT_EP,
+ (uint8_t*)IsocOutBuff,
+ AUDIO_OUT_PACKET);
+
+ return USBD_OK;
+}
+
+/**
+* @brief usbd_audio_Init
+* DeInitializes the AUDIO layer.
+* @param pdev: device instance
+* @param cfgidx: Configuration index
+* @retval status
+*/
+static uint8_t usbd_audio_DeInit (void *pdev,
+ uint8_t cfgidx)
+{
+ DCD_EP_Close (pdev , AUDIO_OUT_EP);
+
+ /* DeInitialize the Audio output Hardware layer */
+ if (AUDIO_OUT_fops.DeInit(0) != USBD_OK)
+ {
+ return USBD_FAIL;
+ }
+
+ return USBD_OK;
+}
+
+/**
+ * @brief usbd_audio_Setup
+ * Handles the Audio control request parsing.
+ * @param pdev: instance
+ * @param req: usb requests
+ * @retval status
+ */
+static uint8_t usbd_audio_Setup (void *pdev,
+ USB_SETUP_REQ *req)
+{
+ uint16_t len=USB_AUDIO_DESC_SIZ;
+ uint8_t *pbuf=usbd_audio_CfgDesc + 18;
+
+ switch (req->bmRequest & USB_REQ_TYPE_MASK)
+ {
+ /* AUDIO Class Requests -------------------------------*/
+ case USB_REQ_TYPE_CLASS :
+ switch (req->bRequest)
+ {
+ case AUDIO_REQ_GET_CUR:
+ AUDIO_Req_GetCurrent(pdev, req);
+ break;
+
+ case AUDIO_REQ_SET_CUR:
+ AUDIO_Req_SetCurrent(pdev, req);
+ break;
+
+ default:
+ USBD_CtlError (pdev, req);
+ return USBD_FAIL;
+ }
+ break;
+
+ /* Standard Requests -------------------------------*/
+ case USB_REQ_TYPE_STANDARD:
+ switch (req->bRequest)
+ {
+ case USB_REQ_GET_DESCRIPTOR:
+ if( (req->wValue >> 8) == AUDIO_DESCRIPTOR_TYPE)
+ {
+#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
+ pbuf = usbd_audio_Desc;
+#else
+ pbuf = usbd_audio_CfgDesc + 18;
+#endif
+ len = MIN(USB_AUDIO_DESC_SIZ , req->wLength);
+ }
+
+ USBD_CtlSendData (pdev,
+ pbuf,
+ len);
+ break;
+
+ case USB_REQ_GET_INTERFACE :
+ USBD_CtlSendData (pdev,
+ (uint8_t *)&usbd_audio_AltSet,
+ 1);
+ break;
+
+ case USB_REQ_SET_INTERFACE :
+ if ((uint8_t)(req->wValue) < AUDIO_TOTAL_IF_NUM)
+ {
+ usbd_audio_AltSet = (uint8_t)(req->wValue);
+ }
+ else
+ {
+ /* Call the error management function (command will be nacked */
+ USBD_CtlError (pdev, req);
+ }
+ break;
+ }
+ }
+ return USBD_OK;
+}
+
+/**
+ * @brief usbd_audio_EP0_RxReady
+ * Handles audio control requests data.
+ * @param pdev: device device instance
+ * @retval status
+ */
+static uint8_t usbd_audio_EP0_RxReady (void *pdev)
+{
+ /* Check if an AudioControl request has been issued */
+ if (AudioCtlCmd == AUDIO_REQ_SET_CUR)
+ {/* In this driver, to simplify code, only SET_CUR request is managed */
+ /* Check for which addressed unit the AudioControl request has been issued */
+ if (AudioCtlUnit == AUDIO_OUT_STREAMING_CTRL)
+ {/* In this driver, to simplify code, only one unit is manage */
+ /* Call the audio interface mute function */
+ AUDIO_OUT_fops.MuteCtl(AudioCtl[0]);
+
+ /* Reset the AudioCtlCmd variable to prevent re-entering this function */
+ AudioCtlCmd = 0;
+ AudioCtlLen = 0;
+ }
+ }
+
+ return USBD_OK;
+}
+
+/**
+ * @brief usbd_audio_DataIn
+ * Handles the audio IN data stage.
+ * @param pdev: instance
+ * @param epnum: endpoint number
+ * @retval status
+ */
+static uint8_t usbd_audio_DataIn (void *pdev, uint8_t epnum)
+{
+ return USBD_OK;
+}
+
+/**
+ * @brief usbd_audio_DataOut
+ * Handles the Audio Out data stage.
+ * @param pdev: instance
+ * @param epnum: endpoint number
+ * @retval status
+ */
+static uint8_t usbd_audio_DataOut (void *pdev, uint8_t epnum)
+{
+ if (epnum == AUDIO_OUT_EP)
+ {
+ /* Increment the Buffer pointer or roll it back when all buffers are full */
+ if (IsocOutWrPtr >= (IsocOutBuff + (AUDIO_OUT_PACKET * OUT_PACKET_NUM)))
+ {/* All buffers are full: roll back */
+ IsocOutWrPtr = IsocOutBuff;
+ }
+ else
+ {/* Increment the buffer pointer */
+ IsocOutWrPtr += AUDIO_OUT_PACKET;
+ }
+
+ /* Toggle the frame index */
+ ((USB_OTG_CORE_HANDLE*)pdev)->dev.out_ep[epnum].even_odd_frame =
+ (((USB_OTG_CORE_HANDLE*)pdev)->dev.out_ep[epnum].even_odd_frame)? 0:1;
+
+ /* Prepare Out endpoint to receive next audio packet */
+ DCD_EP_PrepareRx(pdev,
+ AUDIO_OUT_EP,
+ (uint8_t*)(IsocOutWrPtr),
+ AUDIO_OUT_PACKET);
+
+ /* Trigger the start of streaming only when half buffer is full */
+ if ((PlayFlag == 0) && (IsocOutWrPtr >= (IsocOutBuff + ((AUDIO_OUT_PACKET * OUT_PACKET_NUM) / 2))))
+ {
+ /* Enable start of Streaming */
+ PlayFlag = 1;
+ }
+ }
+
+ return USBD_OK;
+}
+
+/**
+ * @brief usbd_audio_SOF
+ * Handles the SOF event (data buffer update and synchronization).
+ * @param pdev: instance
+ * @param epnum: endpoint number
+ * @retval status
+ */
+static uint8_t usbd_audio_SOF (void *pdev)
+{
+ /* Check if there are available data in stream buffer.
+ In this function, a single variable (PlayFlag) is used to avoid software delays.
+ The play operation must be executed as soon as possible after the SOF detection. */
+ if (PlayFlag)
+ {
+ /* Start playing received packet */
+ AUDIO_OUT_fops.AudioCmd((uint8_t*)(IsocOutRdPtr), /* Samples buffer pointer */
+ AUDIO_OUT_PACKET, /* Number of samples in Bytes */
+ AUDIO_CMD_PLAY); /* Command to be processed */
+
+ /* Increment the Buffer pointer or roll it back when all buffers all full */
+ if (IsocOutRdPtr >= (IsocOutBuff + (AUDIO_OUT_PACKET * OUT_PACKET_NUM)))
+ {/* Roll back to the start of buffer */
+ IsocOutRdPtr = IsocOutBuff;
+ }
+ else
+ {/* Increment to the next sub-buffer */
+ IsocOutRdPtr += AUDIO_OUT_PACKET;
+ }
+
+ /* If all available buffers have been consumed, stop playing */
+ if (IsocOutRdPtr == IsocOutWrPtr)
+ {
+ /* Pause the audio stream */
+ AUDIO_OUT_fops.AudioCmd((uint8_t*)(IsocOutBuff), /* Samples buffer pointer */
+ AUDIO_OUT_PACKET, /* Number of samples in Bytes */
+ AUDIO_CMD_PAUSE); /* Command to be processed */
+
+ /* Stop entering play loop */
+ PlayFlag = 0;
+
+ /* Reset buffer pointers */
+ IsocOutRdPtr = IsocOutBuff;
+ IsocOutWrPtr = IsocOutBuff;
+ }
+ }
+
+ return USBD_OK;
+}
+
+/**
+ * @brief usbd_audio_OUT_Incplt
+ * Handles the iso out incomplete event.
+ * @param pdev: instance
+ * @retval status
+ */
+static uint8_t usbd_audio_OUT_Incplt (void *pdev)
+{
+ return USBD_OK;
+}
+
+/******************************************************************************
+ AUDIO Class requests management
+******************************************************************************/
+/**
+ * @brief AUDIO_Req_GetCurrent
+ * Handles the GET_CUR Audio control request.
+ * @param pdev: instance
+ * @param req: setup class request
+ * @retval status
+ */
+static void AUDIO_Req_GetCurrent(void *pdev, USB_SETUP_REQ *req)
+{
+ /* Send the current mute state */
+ USBD_CtlSendData (pdev,
+ AudioCtl,
+ req->wLength);
+}
+
+/**
+ * @brief AUDIO_Req_SetCurrent
+ * Handles the SET_CUR Audio control request.
+ * @param pdev: instance
+ * @param req: setup class request
+ * @retval status
+ */
+static void AUDIO_Req_SetCurrent(void *pdev, USB_SETUP_REQ *req)
+{
+ if (req->wLength)
+ {
+ /* Prepare the reception of the buffer over EP0 */
+ USBD_CtlPrepareRx (pdev,
+ AudioCtl,
+ req->wLength);
+
+ /* Set the global variables indicating current request and its length
+ to the function usbd_audio_EP0_RxReady() which will process the request */
+ AudioCtlCmd = AUDIO_REQ_SET_CUR; /* Set the request value */
+ AudioCtlLen = req->wLength; /* Set the request data length */
+ AudioCtlUnit = HIBYTE(req->wIndex); /* Set the request target unit */
+ }
+}
+
+/**
+ * @brief USBD_audio_GetCfgDesc
+ * Returns configuration descriptor.
+ * @param speed : current device speed
+ * @param length : pointer data length
+ * @retval pointer to descriptor buffer
+ */
+static uint8_t *USBD_audio_GetCfgDesc (uint8_t speed, uint16_t *length)
+{
+ *length = sizeof (usbd_audio_CfgDesc);
+ return usbd_audio_CfgDesc;
+}
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/audio/src/usbd_audio_out_if.c b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/audio/src/usbd_audio_out_if.c
new file mode 100644
index 0000000..b004ddf
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/audio/src/usbd_audio_out_if.c
@@ -0,0 +1,321 @@
+/**
+ ******************************************************************************
+ * @file usbd_audio_out_if.c
+ * @author MCD Application Team
+ * @version V1.1.0
+ * @date 19-March-2012
+ * @brief This file provides the Audio Out (palyback) interface API.
+ ******************************************************************************
+ * @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_audio_core.h"
+#include "usbd_audio_out_if.h"
+
+/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
+ * @{
+ */
+
+
+/** @defgroup usbd_audio_out_if
+ * @brief usbd out interface module
+ * @{
+ */
+
+/** @defgroup usbd_audio_out_if_Private_TypesDefinitions
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup usbd_audio_out_if_Private_Defines
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup usbd_audio_out_if_Private_Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup usbd_audio_out_if_Private_FunctionPrototypes
+ * @{
+ */
+static uint8_t Init (uint32_t AudioFreq, uint32_t Volume, uint32_t options);
+static uint8_t DeInit (uint32_t options);
+static uint8_t AudioCmd (uint8_t* pbuf, uint32_t size, uint8_t cmd);
+static uint8_t VolumeCtl (uint8_t vol);
+static uint8_t MuteCtl (uint8_t cmd);
+static uint8_t PeriodicTC (uint8_t cmd);
+static uint8_t GetState (void);
+
+/**
+ * @}
+ */
+
+/** @defgroup usbd_audio_out_if_Private_Variables
+ * @{
+ */
+AUDIO_FOPS_TypeDef AUDIO_OUT_fops =
+{
+ Init,
+ DeInit,
+ AudioCmd,
+ VolumeCtl,
+ MuteCtl,
+ PeriodicTC,
+ GetState
+};
+
+static uint8_t AudioState = AUDIO_STATE_INACTIVE;
+
+/**
+ * @}
+ */
+
+/** @defgroup usbd_audio_out_if_Private_Functions
+ * @{
+ */
+
+/**
+ * @brief Init
+ * Initialize and configures all required resources for audio play function.
+ * @param AudioFreq: Statrtup audio frequency.
+ * @param Volume: Startup volume to be set.
+ * @param options: specific options passed to low layer function.
+ * @retval AUDIO_OK if all operations succeed, AUDIO_FAIL else.
+ */
+static uint8_t Init (uint32_t AudioFreq,
+ uint32_t Volume,
+ uint32_t options)
+{
+ static uint32_t Initialized = 0;
+
+ /* Check if the low layer has already been initialized */
+ if (Initialized == 0)
+ {
+ /* Call low layer function */
+ if (EVAL_AUDIO_Init(OUTPUT_DEVICE_AUTO, Volume, AudioFreq) != 0)
+ {
+ AudioState = AUDIO_STATE_ERROR;
+ return AUDIO_FAIL;
+ }
+
+ /* Set the Initialization flag to prevent reinitializing the interface again */
+ Initialized = 1;
+ }
+
+ /* Update the Audio state machine */
+ AudioState = AUDIO_STATE_ACTIVE;
+
+ return AUDIO_OK;
+}
+
+/**
+ * @brief DeInit
+ * Free all resources used by low layer and stops audio-play function.
+ * @param options: options passed to low layer function.
+ * @retval AUDIO_OK if all operations succeed, AUDIO_FAIL else.
+ */
+static uint8_t DeInit (uint32_t options)
+{
+ /* Update the Audio state machine */
+ AudioState = AUDIO_STATE_INACTIVE;
+
+ return AUDIO_OK;
+}
+
+/**
+ * @brief AudioCmd
+ * Play, Stop, Pause or Resume current file.
+ * @param pbuf: address from which file shoud be played.
+ * @param size: size of the current buffer/file.
+ * @param cmd: command to be executed, can be AUDIO_CMD_PLAY , AUDIO_CMD_PAUSE,
+ * AUDIO_CMD_RESUME or AUDIO_CMD_STOP.
+ * @retval AUDIO_OK if all operations succeed, AUDIO_FAIL else.
+ */
+static uint8_t AudioCmd(uint8_t* pbuf,
+ uint32_t size,
+ uint8_t cmd)
+{
+ /* Check the current state */
+ if ((AudioState == AUDIO_STATE_INACTIVE) || (AudioState == AUDIO_STATE_ERROR))
+ {
+ AudioState = AUDIO_STATE_ERROR;
+ return AUDIO_FAIL;
+ }
+
+ switch (cmd)
+ {
+ /* Process the PLAY command ----------------------------*/
+ case AUDIO_CMD_PLAY:
+ /* If current state is Active or Stopped */
+ if ((AudioState == AUDIO_STATE_ACTIVE) || \
+ (AudioState == AUDIO_STATE_STOPPED) || \
+ (AudioState == AUDIO_STATE_PLAYING))
+ {
+ Audio_MAL_Play((uint32_t)pbuf, (size/2));
+ AudioState = AUDIO_STATE_PLAYING;
+ return AUDIO_OK;
+ }
+ /* If current state is Paused */
+ else if (AudioState == AUDIO_STATE_PAUSED)
+ {
+ if (EVAL_AUDIO_PauseResume(AUDIO_RESUME, (uint32_t)pbuf, (size/2)) != 0)
+ {
+ AudioState = AUDIO_STATE_ERROR;
+ return AUDIO_FAIL;
+ }
+ else
+ {
+ AudioState = AUDIO_STATE_PLAYING;
+ return AUDIO_OK;
+ }
+ }
+ else /* Not allowed command */
+ {
+ return AUDIO_FAIL;
+ }
+
+ /* Process the STOP command ----------------------------*/
+ case AUDIO_CMD_STOP:
+ if (AudioState != AUDIO_STATE_PLAYING)
+ {
+ /* Unsupported command */
+ return AUDIO_FAIL;
+ }
+ else if (EVAL_AUDIO_Stop(CODEC_PDWN_SW) != 0)
+ {
+ AudioState = AUDIO_STATE_ERROR;
+ return AUDIO_FAIL;
+ }
+ else
+ {
+ AudioState = AUDIO_STATE_STOPPED;
+ return AUDIO_OK;
+ }
+
+ /* Process the PAUSE command ---------------------------*/
+ case AUDIO_CMD_PAUSE:
+ if (AudioState != AUDIO_STATE_PLAYING)
+ {
+ /* Unsupported command */
+ return AUDIO_FAIL;
+ }
+ else if (EVAL_AUDIO_PauseResume(AUDIO_PAUSE, (uint32_t)pbuf, (size/2)) != 0)
+ {
+ AudioState = AUDIO_STATE_ERROR;
+ return AUDIO_FAIL;
+ }
+ else
+ {
+ AudioState = AUDIO_STATE_PAUSED;
+ return AUDIO_OK;
+ }
+
+ /* Unsupported command ---------------------------------*/
+ default:
+ return AUDIO_FAIL;
+ }
+}
+
+/**
+ * @brief VolumeCtl
+ * Set the volume level in %
+ * @param vol: volume level to be set in % (from 0% to 100%)
+ * @retval AUDIO_OK if all operations succeed, AUDIO_FAIL else.
+ */
+static uint8_t VolumeCtl (uint8_t vol)
+{
+ /* Call low layer volume setting function */
+ if (EVAL_AUDIO_VolumeCtl(vol) != 0)
+ {
+ AudioState = AUDIO_STATE_ERROR;
+ return AUDIO_FAIL;
+ }
+
+ return AUDIO_OK;
+}
+
+/**
+ * @brief MuteCtl
+ * Mute or Unmute the audio current output
+ * @param cmd: can be 0 to unmute, or 1 to mute.
+ * @retval AUDIO_OK if all operations succeed, AUDIO_FAIL else.
+ */
+static uint8_t MuteCtl (uint8_t cmd)
+{
+ /* Call low layer mute setting function */
+ if (EVAL_AUDIO_Mute(cmd) != 0)
+ {
+ AudioState = AUDIO_STATE_ERROR;
+ return AUDIO_FAIL;
+ }
+
+ return AUDIO_OK;
+}
+
+/**
+ * @brief
+ *
+ * @param
+ * @param
+ * @retval AUDIO_OK if all operations succeed, AUDIO_FAIL else.
+ */
+static uint8_t PeriodicTC (uint8_t cmd)
+{
+
+
+ return AUDIO_OK;
+}
+
+
+/**
+ * @brief GetState
+ * Return the current state of the audio machine
+ * @param None
+ * @retval Current State.
+ */
+static uint8_t GetState (void)
+{
+ return AudioState;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/cdc/inc/usbd_cdc_core.h b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/cdc/inc/usbd_cdc_core.h
new file mode 100644
index 0000000..0c0c3bd
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/cdc/inc/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/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/cdc/inc/usbd_cdc_if_template.h b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/cdc/inc/usbd_cdc_if_template.h
new file mode 100644
index 0000000..2acd55d
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/cdc/inc/usbd_cdc_if_template.h
@@ -0,0 +1,46 @@
+/**
+ ******************************************************************************
+ * @file usbd_cdc_if_template.h
+ * @author MCD Application Team
+ * @version V1.1.0
+ * @date 19-March-2012
+ * @brief Header for dfu_mal.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_CDC_IF_TEMPLATE_H
+#define __USBD_CDC_IF_TEMPLATE_H
+
+/* Includes ------------------------------------------------------------------*/
+#include "usb_conf.h"
+#include "usbd_conf.h"
+#include "usbd_cdc_core.h"
+
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+
+extern CDC_IF_Prop_TypeDef TEMPLATE_fops;
+
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions ------------------------------------------------------- */
+#endif /* __USBD_CDC_IF_TEMPLATE_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/cdc/src/usbd_cdc_core.c b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/cdc/src/usbd_cdc_core.c
new file mode 100644
index 0000000..9d67b95
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/cdc/src/usbd_cdc_core.c
@@ -0,0 +1,817 @@
+/**
+ ******************************************************************************
+ * @file usbd_cdc_core.c
+ * @author MCD Application Team
+ * @version V1.1.0
+ * @date 19-March-2012
+ * @brief This file provides the high layer firmware functions to manage the
+ * following functionalities of the USB CDC Class:
+ * - Initialization and Configuration of high and low layer
+ * - Enumeration as CDC Device (and enumeration for each implemented memory interface)
+ * - OUT/IN data transfer
+ * - Command IN transfer (class requests management)
+ * - Error management
+ *
+ * @verbatim
+ *
+ * ===================================================================
+ * CDC Class Driver Description
+ * ===================================================================
+ * This driver manages the "Universal Serial Bus Class Definitions for Communications Devices
+ * Revision 1.2 November 16, 2007" and the sub-protocol specification of "Universal Serial Bus
+ * Communications Class Subclass Specification for PSTN Devices Revision 1.2 February 9, 2007"
+ * This driver implements the following aspects of the specification:
+ * - Device descriptor management
+ * - Configuration descriptor management
+ * - Enumeration as CDC device with 2 data endpoints (IN and OUT) and 1 command endpoint (IN)
+ * - Requests management (as described in section 6.2 in specification)
+ * - Abstract Control Model compliant
+ * - Union Functional collection (using 1 IN endpoint for control)
+ * - Data interface class
+
+ * @note
+ * For the Abstract Control Model, this core allows only transmitting the requests to
+ * lower layer dispatcher (ie. usbd_cdc_vcp.c/.h) which should manage each request and
+ * perform relative actions.
+ *
+ * These aspects may be enriched or modified for a specific user application.
+ *
+ * This driver doesn't implement the following aspects of the specification
+ * (but it is possible to manage these features with some modifications on this driver):
+ * - Any class-specific aspect relative to communication classes should be managed by user application.
+ * - All communication classes other than PSTN are not managed
+ *
+ * @endverbatim
+ *
+ ******************************************************************************
+ * @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_cdc_core.h"
+#include "usbd_desc.h"
+#include "usbd_req.h"
+
+
+/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
+ * @{
+ */
+
+
+/** @defgroup usbd_cdc
+ * @brief usbd core module
+ * @{
+ */
+
+/** @defgroup usbd_cdc_Private_TypesDefinitions
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup usbd_cdc_Private_Defines
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup usbd_cdc_Private_Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup usbd_cdc_Private_FunctionPrototypes
+ * @{
+ */
+
+/*********************************************
+ CDC Device library 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);
+
+/*********************************************
+ CDC specific management functions
+ *********************************************/
+static void Handle_USBAsynchXfer (void *pdev);
+static uint8_t *USBD_cdc_GetCfgDesc (uint8_t speed, uint16_t *length);
+#ifdef USE_USB_OTG_HS
+static uint8_t *USBD_cdc_GetOtherCfgDesc (uint8_t speed, uint16_t *length);
+#endif
+/**
+ * @}
+ */
+
+/** @defgroup usbd_cdc_Private_Variables
+ * @{
+ */
+extern CDC_IF_Prop_TypeDef APP_FOPS;
+extern uint8_t USBD_DeviceDesc [USB_SIZ_DEVICE_DESC];
+
+#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_cdc_CfgDesc [USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END ;
+
+#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_cdc_OtherCfgDesc [USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END ;
+
+#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 static __IO uint32_t usbd_cdc_AltSet __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 USB_Rx_Buffer [CDC_DATA_MAX_PACKET_SIZE] __ALIGN_END ;
+
+#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 APP_Rx_Buffer [APP_RX_DATA_SIZE] __ALIGN_END ;
+
+
+#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 CmdBuff[CDC_CMD_PACKET_SZE] __ALIGN_END ;
+
+uint32_t APP_Rx_ptr_in = 0;
+uint32_t APP_Rx_ptr_out = 0;
+uint32_t APP_Rx_length = 0;
+
+uint8_t USB_Tx_State = 0;
+
+static uint32_t cdcCmd = 0xFF;
+static uint32_t cdcLen = 0;
+
+/* CDC interface class callbacks structure */
+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,
+#ifdef USE_USB_OTG_HS
+ USBD_cdc_GetOtherCfgDesc, /* use same cobfig as per FS */
+#endif /* USE_USB_OTG_HS */
+};
+
+#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
+ #if defined ( __ICCARM__ ) /*!< IAR Compiler */
+ #pragma data_alignment=4
+ #endif
+#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
+/* USB CDC device Configuration Descriptor */
+__ALIGN_BEGIN uint8_t usbd_cdc_CfgDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END =
+{
+ /*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),
+#ifdef USE_USB_OTG_HS
+ 0x10, /* bInterval: */
+#else
+ 0xFF, /* bInterval: */
+#endif /* USE_USB_OTG_HS */
+
+ /*---------------------------------------------------------------------------*/
+
+ /*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 */
+} ;
+
+#ifdef USE_USB_OTG_HS
+#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_cdc_OtherCfgDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END =
+{
+ 0x09, /* bLength: Configuation Descriptor size */
+ USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION,
+ USB_CDC_CONFIG_DESC_SIZ,
+ 0x00,
+ 0x02, /* bNumInterfaces: 2 interfaces */
+ 0x01, /* bConfigurationValue: */
+ 0x04, /* iConfiguration: */
+ 0xC0, /* bmAttributes: */
+ 0x32, /* MaxPower 100 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),
+ 0xFF, /* 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 */
+ 0x40, /* wMaxPacketSize: */
+ 0x00,
+ 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 */
+ 0x40, /* wMaxPacketSize: */
+ 0x00,
+ 0x00 /* bInterval */
+};
+#endif /* USE_USB_OTG_HS */
+
+/**
+ * @}
+ */
+
+/** @defgroup usbd_cdc_Private_Functions
+ * @{
+ */
+
+/**
+ * @brief usbd_cdc_Init
+ * Initilaize the CDC interface
+ * @param pdev: device instance
+ * @param cfgidx: Configuration index
+ * @retval status
+ */
+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;
+
+ /* Initialize the Interface physical components */
+ APP_FOPS.pIf_Init();
+
+ /* Prepare Out endpoint to receive next packet */
+ DCD_EP_PrepareRx(pdev,
+ CDC_OUT_EP,
+ (uint8_t*)(USB_Rx_Buffer),
+ CDC_DATA_OUT_PACKET_SIZE);
+
+ return USBD_OK;
+}
+
+/**
+ * @brief usbd_cdc_Init
+ * DeInitialize the CDC layer
+ * @param pdev: device instance
+ * @param cfgidx: Configuration index
+ * @retval status
+ */
+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);
+
+ /* Restore default state of the Interface physical components */
+ APP_FOPS.pIf_DeInit();
+
+ return USBD_OK;
+}
+
+/**
+ * @brief usbd_cdc_Setup
+ * Handle the CDC specific requests
+ * @param pdev: instance
+ * @param req: usb requests
+ * @retval status
+ */
+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 */
+ APP_FOPS.pIf_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 */
+ APP_FOPS.pIf_Ctrl(req->bRequest, NULL, 0);
+ }
+
+ return USBD_OK;
+
+ default:
+ USBD_CtlError (pdev, req);
+ return USBD_FAIL;
+
+
+
+ /* Standard Requests -------------------------------*/
+ case USB_REQ_TYPE_STANDARD:
+ switch (req->bRequest)
+ {
+ case USB_REQ_GET_DESCRIPTOR:
+ if( (req->wValue >> 8) == CDC_DESCRIPTOR_TYPE)
+ {
+#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
+ pbuf = usbd_cdc_Desc;
+#else
+ pbuf = usbd_cdc_CfgDesc + 9 + (9 * USBD_ITF_MAX_NUM);
+#endif
+ 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;
+}
+
+/**
+ * @brief usbd_cdc_EP0_RxReady
+ * Data received on control endpoint
+ * @param pdev: device device instance
+ * @retval status
+ */
+static uint8_t usbd_cdc_EP0_RxReady (void *pdev)
+{
+ if (cdcCmd != NO_CMD)
+ {
+ /* Process the data */
+ APP_FOPS.pIf_Ctrl(cdcCmd, CmdBuff, cdcLen);
+
+ /* Reset the command variable to default value */
+ cdcCmd = NO_CMD;
+ }
+
+ return USBD_OK;
+}
+
+/**
+ * @brief usbd_audio_DataIn
+ * Data sent on non-control IN endpoint
+ * @param pdev: device instance
+ * @param epnum: endpoint number
+ * @retval status
+ */
+static uint8_t usbd_cdc_DataIn (void *pdev, uint8_t epnum)
+{
+ uint16_t USB_Tx_ptr;
+ uint16_t USB_Tx_length;
+
+ if (USB_Tx_State == 1)
+ {
+ if (APP_Rx_length == 0)
+ {
+ USB_Tx_State = 0;
+ }
+ else
+ {
+ if (APP_Rx_length > CDC_DATA_IN_PACKET_SIZE){
+ USB_Tx_ptr = APP_Rx_ptr_out;
+ USB_Tx_length = CDC_DATA_IN_PACKET_SIZE;
+
+ APP_Rx_ptr_out += CDC_DATA_IN_PACKET_SIZE;
+ APP_Rx_length -= CDC_DATA_IN_PACKET_SIZE;
+ }
+ else
+ {
+ USB_Tx_ptr = APP_Rx_ptr_out;
+ USB_Tx_length = APP_Rx_length;
+
+ APP_Rx_ptr_out += APP_Rx_length;
+ APP_Rx_length = 0;
+ }
+
+ /* Prepare the available data buffer to be sent on IN endpoint */
+ DCD_EP_Tx (pdev,
+ CDC_IN_EP,
+ (uint8_t*)&APP_Rx_Buffer[USB_Tx_ptr],
+ USB_Tx_length);
+ }
+ }
+
+ return USBD_OK;
+}
+
+/**
+ * @brief usbd_cdc_DataOut
+ * Data received on non-control Out endpoint
+ * @param pdev: device instance
+ * @param epnum: endpoint number
+ * @retval status
+ */
+static uint8_t usbd_cdc_DataOut (void *pdev, uint8_t epnum)
+{
+ uint16_t USB_Rx_Cnt;
+
+ /* Get the received data buffer and update the counter */
+ USB_Rx_Cnt = ((USB_OTG_CORE_HANDLE*)pdev)->dev.out_ep[epnum].xfer_count;
+
+ /* USB data will be immediately processed, this allow next USB traffic being
+ NAKed till the end of the application Xfer */
+ APP_FOPS.pIf_DataRx(USB_Rx_Buffer, USB_Rx_Cnt);
+
+ /* Prepare Out endpoint to receive next packet */
+ DCD_EP_PrepareRx(pdev,
+ CDC_OUT_EP,
+ (uint8_t*)(USB_Rx_Buffer),
+ CDC_DATA_OUT_PACKET_SIZE);
+
+ return USBD_OK;
+}
+
+/**
+ * @brief usbd_audio_SOF
+ * Start Of Frame event management
+ * @param pdev: instance
+ * @param epnum: endpoint number
+ * @retval status
+ */
+static uint8_t usbd_cdc_SOF (void *pdev)
+{
+ static uint32_t FrameCount = 0;
+
+ if (FrameCount++ == CDC_IN_FRAME_INTERVAL)
+ {
+ /* Reset the frame counter */
+ FrameCount = 0;
+
+ /* Check the data to be sent through IN pipe */
+ Handle_USBAsynchXfer(pdev);
+ }
+
+ return USBD_OK;
+}
+
+/**
+ * @brief Handle_USBAsynchXfer
+ * Send data to USB
+ * @param pdev: instance
+ * @retval None
+ */
+static void Handle_USBAsynchXfer (void *pdev)
+{
+ uint16_t USB_Tx_ptr;
+ uint16_t USB_Tx_length;
+
+ if(USB_Tx_State != 1)
+ {
+ if (APP_Rx_ptr_out == APP_RX_DATA_SIZE)
+ {
+ APP_Rx_ptr_out = 0;
+ }
+
+ if(APP_Rx_ptr_out == APP_Rx_ptr_in)
+ {
+ USB_Tx_State = 0;
+ return;
+ }
+
+ if(APP_Rx_ptr_out > APP_Rx_ptr_in) /* rollback */
+ {
+ APP_Rx_length = APP_RX_DATA_SIZE - APP_Rx_ptr_out;
+
+ }
+ else
+ {
+ APP_Rx_length = APP_Rx_ptr_in - APP_Rx_ptr_out;
+
+ }
+#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
+ APP_Rx_length &= ~0x03;
+#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
+
+ if (APP_Rx_length > CDC_DATA_IN_PACKET_SIZE)
+ {
+ USB_Tx_ptr = APP_Rx_ptr_out;
+ USB_Tx_length = CDC_DATA_IN_PACKET_SIZE;
+
+ APP_Rx_ptr_out += CDC_DATA_IN_PACKET_SIZE;
+ APP_Rx_length -= CDC_DATA_IN_PACKET_SIZE;
+ }
+ else
+ {
+ USB_Tx_ptr = APP_Rx_ptr_out;
+ USB_Tx_length = APP_Rx_length;
+
+ APP_Rx_ptr_out += APP_Rx_length;
+ APP_Rx_length = 0;
+ }
+ USB_Tx_State = 1;
+
+ DCD_EP_Tx (pdev,
+ CDC_IN_EP,
+ (uint8_t*)&APP_Rx_Buffer[USB_Tx_ptr],
+ USB_Tx_length);
+ }
+
+}
+
+/**
+ * @brief USBD_cdc_GetCfgDesc
+ * Return configuration descriptor
+ * @param speed : current device speed
+ * @param length : pointer data length
+ * @retval pointer to descriptor buffer
+ */
+static uint8_t *USBD_cdc_GetCfgDesc (uint8_t speed, uint16_t *length)
+{
+ *length = sizeof (usbd_cdc_CfgDesc);
+ return usbd_cdc_CfgDesc;
+}
+
+/**
+ * @brief USBD_cdc_GetCfgDesc
+ * Return configuration descriptor
+ * @param speed : current device speed
+ * @param length : pointer data length
+ * @retval pointer to descriptor buffer
+ */
+#ifdef USE_USB_OTG_HS
+static uint8_t *USBD_cdc_GetOtherCfgDesc (uint8_t speed, uint16_t *length)
+{
+ *length = sizeof (usbd_cdc_OtherCfgDesc);
+ return usbd_cdc_OtherCfgDesc;
+}
+#endif
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/cdc/src/usbd_cdc_if_template.c b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/cdc/src/usbd_cdc_if_template.c
new file mode 100644
index 0000000..f2d14f3
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/cdc/src/usbd_cdc_if_template.c
@@ -0,0 +1,207 @@
+/**
+ ******************************************************************************
+ * @file usbd_cdc_if_template.c
+ * @author MCD Application Team
+ * @version V1.1.0
+ * @date 19-March-2012
+ * @brief Generic media access 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.
+ *
+ ******************************************************************************
+ */
+
+#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
+#pragma data_alignment = 4
+#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_cdc_if_template.h"
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* These are external variables imported from CDC core to be used for IN
+ transfer management. */
+extern uint8_t APP_Rx_Buffer []; /* Write CDC received data in this buffer.
+ These data will be sent over USB IN endpoint
+ in the CDC core functions. */
+extern uint32_t APP_Rx_ptr_in; /* Increment this pointer or roll it back to
+ start address when writing received data
+ in the buffer APP_Rx_Buffer. */
+
+/* Private function prototypes -----------------------------------------------*/
+static uint16_t TEMPLATE_Init (void);
+static uint16_t TEMPLATE_DeInit (void);
+static uint16_t TEMPLATE_Ctrl (uint32_t Cmd, uint8_t* Buf, uint32_t Len);
+static uint16_t TEMPLATE_DataTx (uint8_t* Buf, uint32_t Len);
+static uint16_t TEMPLATE_DataRx (uint8_t* Buf, uint32_t Len);
+
+CDC_IF_Prop_TypeDef TEMPLATE_fops =
+{
+ TEMPLATE_Init,
+ TEMPLATE_DeInit,
+ TEMPLATE_Ctrl,
+ TEMPLATE_DataTx,
+ TEMPLATE_DataRx
+};
+
+/* Private functions ---------------------------------------------------------*/
+
+/**
+ * @brief TEMPLATE_Init
+ * Initializes the CDC media low layer
+ * @param None
+ * @retval Result of the opeartion: USBD_OK if all operations are OK else USBD_FAIL
+ */
+static uint16_t TEMPLATE_Init(void)
+{
+ /*
+ Add your initialization code here
+ */
+ return USBD_OK;
+}
+
+/**
+ * @brief TEMPLATE_DeInit
+ * DeInitializes the CDC media low layer
+ * @param None
+ * @retval Result of the opeartion: USBD_OK if all operations are OK else USBD_FAIL
+ */
+static uint16_t TEMPLATE_DeInit(void)
+{
+ /*
+ Add your deinitialization code here
+ */
+ return USBD_OK;
+}
+
+
+/**
+ * @brief TEMPLATE_Ctrl
+ * Manage the CDC class requests
+ * @param Cmd: Command code
+ * @param Buf: Buffer containing command data (request parameters)
+ * @param Len: Number of data to be sent (in bytes)
+ * @retval Result of the opeartion: USBD_OK if all operations are OK else USBD_FAIL
+ */
+static uint16_t TEMPLATE_Ctrl (uint32_t Cmd, uint8_t* Buf, uint32_t Len)
+{
+ switch (Cmd)
+ {
+ case SEND_ENCAPSULATED_COMMAND:
+ /* Add your code here */
+ break;
+
+ case GET_ENCAPSULATED_RESPONSE:
+ /* Add your code here */
+ break;
+
+ case SET_COMM_FEATURE:
+ /* Add your code here */
+ break;
+
+ case GET_COMM_FEATURE:
+ /* Add your code here */
+ break;
+
+ case CLEAR_COMM_FEATURE:
+ /* Add your code here */
+ break;
+
+ case SET_LINE_CODING:
+ /* Add your code here */
+ break;
+
+ case GET_LINE_CODING:
+ /* Add your code here */
+ break;
+
+ case SET_CONTROL_LINE_STATE:
+ /* Add your code here */
+ break;
+
+ case SEND_BREAK:
+ /* Add your code here */
+ break;
+
+ default:
+ break;
+ }
+
+ return USBD_OK;
+}
+
+/**
+ * @brief TEMPLATE_DataTx
+ * CDC received data to be send over USB IN endpoint are managed in
+ * this function.
+ * @param Buf: Buffer of data to be sent
+ * @param Len: Number of data to be sent (in bytes)
+ * @retval Result of the opeartion: USBD_OK if all operations are OK else USBD_FAIL
+ */
+static uint16_t TEMPLATE_DataTx (uint8_t* Buf, uint32_t Len)
+{
+
+ /* Get the data to be sent */
+ for (i = 0; i < Len; i++)
+ {
+ /* APP_Rx_Buffer[APP_Rx_ptr_in] = XXX_ReceiveData(XXX); */
+ }
+
+ /* Increment the in pointer */
+ APP_Rx_ptr_in++;
+
+ /* To avoid buffer overflow */
+ if(APP_Rx_ptr_in == APP_RX_DATA_SIZE)
+ {
+ APP_Rx_ptr_in = 0;
+ }
+
+ return USBD_OK;
+}
+
+/**
+ * @brief TEMPLATE_DataRx
+ * Data received over USB OUT endpoint are sent over CDC interface
+ * through this function.
+ *
+ * @note
+ * This function will block any OUT packet reception on USB endpoint
+ * untill exiting this function. If you exit this function before transfer
+ * is complete on CDC interface (ie. using DMA controller) it will result
+ * in receiving more data while previous ones are still not sent.
+ *
+ * @param Buf: Buffer of data to be received
+ * @param Len: Number of data received (in bytes)
+ * @retval Result of the opeartion: USBD_OK if all operations are OK else USBD_FAIL
+ */
+static uint16_t TEMPLATE_DataRx (uint8_t* Buf, uint32_t Len)
+{
+ uint32_t i;
+
+ /* Send the received buffer */
+ for (i = 0; i < Len; i++)
+ {
+ /* XXXX_SendData(XXXX, *(Buf + i) ); */
+ }
+
+ return USBD_OK;
+}
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/dfu/inc/usbd_dfu_core.h b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/dfu/inc/usbd_dfu_core.h
new file mode 100644
index 0000000..3f7b03e
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/dfu/inc/usbd_dfu_core.h
@@ -0,0 +1,193 @@
+/**
+ ******************************************************************************
+ * @file usbd_dfu_core.h
+ * @author MCD Application Team
+ * @version V1.1.0
+ * @date 19-March-2012
+ * @brief header file for the usbd_dfu_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_DFU_CORE_H_
+#define __USB_DFU_CORE_H_
+
+#include "usbd_ioreq.h"
+#include "usbd_dfu_mal.h"
+
+/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
+ * @{
+ */
+
+/** @defgroup usbd_dfu
+ * @brief This file is the Header file for USBD_dfu.c
+ * @{
+ */
+
+
+/** @defgroup usbd_dfu_Exported_Defines
+ * @{
+ */
+#define USB_DFU_CONFIG_DESC_SIZ (18 + (9 * USBD_ITF_MAX_NUM))
+#define USB_DFU_DESC_SIZ 9
+
+#define DFU_DESCRIPTOR_TYPE 0x21
+
+
+/*---------------------------------------------------------------------*/
+/* DFU definitions */
+/*---------------------------------------------------------------------*/
+
+
+
+/**************************************************/
+/* DFU Requests DFU states */
+/**************************************************/
+
+
+#define STATE_appIDLE 0
+#define STATE_appDETACH 1
+#define STATE_dfuIDLE 2
+#define STATE_dfuDNLOAD_SYNC 3
+#define STATE_dfuDNBUSY 4
+#define STATE_dfuDNLOAD_IDLE 5
+#define STATE_dfuMANIFEST_SYNC 6
+#define STATE_dfuMANIFEST 7
+#define STATE_dfuMANIFEST_WAIT_RESET 8
+#define STATE_dfuUPLOAD_IDLE 9
+#define STATE_dfuERROR 10
+
+/**************************************************/
+/* DFU Requests DFU status */
+/**************************************************/
+
+#define STATUS_OK 0x00
+#define STATUS_ERRTARGET 0x01
+#define STATUS_ERRFILE 0x02
+#define STATUS_ERRWRITE 0x03
+#define STATUS_ERRERASE 0x04
+#define STATUS_ERRCHECK_ERASED 0x05
+#define STATUS_ERRPROG 0x06
+#define STATUS_ERRVERIFY 0x07
+#define STATUS_ERRADDRESS 0x08
+#define STATUS_ERRNOTDONE 0x09
+#define STATUS_ERRFIRMWARE 0x0A
+#define STATUS_ERRVENDOR 0x0B
+#define STATUS_ERRUSBR 0x0C
+#define STATUS_ERRPOR 0x0D
+#define STATUS_ERRUNKNOWN 0x0E
+#define STATUS_ERRSTALLEDPKT 0x0F
+
+/**************************************************/
+/* DFU Requests DFU states Manifestation State */
+/**************************************************/
+
+#define Manifest_complete 0x00
+#define Manifest_In_Progress 0x01
+
+
+/**************************************************/
+/* Special Commands with Download Request */
+/**************************************************/
+
+#define CMD_GETCOMMANDS 0x00
+#define CMD_SETADDRESSPOINTER 0x21
+#define CMD_ERASE 0x41
+
+/**************************************************/
+/* Other defines */
+/**************************************************/
+/* Bit Detach capable = bit 3 in bmAttributes field */
+#define DFU_DETACH_MASK (uint8_t)(1 << 4)
+/**
+ * @}
+ */
+
+
+/** @defgroup USBD_CORE_Exported_TypesDefinitions
+ * @{
+ */
+/**************************************************/
+/* DFU Requests */
+/**************************************************/
+
+typedef enum _DFU_REQUESTS {
+ DFU_DETACH = 0,
+ DFU_DNLOAD = 1,
+ DFU_UPLOAD,
+ DFU_GETSTATUS,
+ DFU_CLRSTATUS,
+ DFU_GETSTATE,
+ DFU_ABORT
+} DFU_REQUESTS;
+
+typedef void (*pFunction)(void);
+/**
+ * @}
+ */
+
+
+
+/** @defgroup USBD_CORE_Exported_Macros
+ * @{
+ */
+/********** Descriptor of DFU interface 0 Alternate setting n ****************/
+#define USBD_DFU_IF_DESC(n) 0x09, /* bLength: Interface Descriptor size */ \
+ USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ \
+ 0x00, /* bInterfaceNumber: Number of Interface */ \
+ (n), /* bAlternateSetting: Alternate setting */ \
+ 0x00, /* bNumEndpoints*/ \
+ 0xFE, /* bInterfaceClass: Application Specific Class Code */ \
+ 0x01, /* bInterfaceSubClass : Device Firmware Upgrade Code */ \
+ 0x02, /* nInterfaceProtocol: DFU mode protocol */ \
+ USBD_IDX_INTERFACE_STR + (n) + 1 /* iInterface: Index of string descriptor */ \
+ /* 18 */
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_CORE_Exported_Variables
+ * @{
+ */
+
+extern USBD_Class_cb_TypeDef DFU_cb;
+/**
+ * @}
+ */
+
+/** @defgroup USB_CORE_Exported_Functions
+ * @{
+ */
+/**
+ * @}
+ */
+
+#endif // __USB_DFU_CORE_H_
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/dfu/inc/usbd_dfu_mal.h b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/dfu/inc/usbd_dfu_mal.h
new file mode 100644
index 0000000..66dcf9e
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/dfu/inc/usbd_dfu_mal.h
@@ -0,0 +1,81 @@
+/**
+ ******************************************************************************
+ * @file usbd_dfu_mal.h
+ * @author MCD Application Team
+ * @version V1.1.0
+ * @date 19-March-2012
+ * @brief Header for usbd_dfu_mal.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 __DFU_MAL_H
+#define __DFU_MAL_H
+
+/* Includes ------------------------------------------------------------------*/
+#include "usb_conf.h"
+
+#include "usbd_conf.h"
+#include "usbd_dfu_core.h"
+
+/* Exported types ------------------------------------------------------------*/
+typedef struct _DFU_MAL_PROP
+{
+ const uint8_t* pStrDesc;
+ uint16_t (*pMAL_Init) (void);
+ uint16_t (*pMAL_DeInit) (void);
+ uint16_t (*pMAL_Erase) (uint32_t Add);
+ uint16_t (*pMAL_Write) (uint32_t Add, uint32_t Len);
+ uint8_t *(*pMAL_Read) (uint32_t Add, uint32_t Len);
+ uint16_t (*pMAL_CheckAdd) (uint32_t Add);
+ const uint32_t EraseTiming;
+ const uint32_t WriteTiming;
+}
+DFU_MAL_Prop_TypeDef;
+
+
+/* Exported constants --------------------------------------------------------*/
+#define MAL_OK 0
+#define MAL_FAIL 1
+
+/* utils macro ---------------------------------------------------------------*/
+#define _1st_BYTE(x) (uint8_t)((x)&0xFF) /* 1st addressing cycle */
+#define _2nd_BYTE(x) (uint8_t)(((x)&0xFF00)>>8) /* 2nd addressing cycle */
+#define _3rd_BYTE(x) (uint8_t)(((x)&0xFF0000)>>16) /* 3rd addressing cycle */
+#define _4th_BYTE(x) (uint8_t)(((x)&0xFF000000)>>24) /* 4th addressing cycle */
+
+/* Exported macro ------------------------------------------------------------*/
+#define SET_POLLING_TIMING(x) buffer[1] = _1st_BYTE(x);\
+ buffer[2] = _2nd_BYTE(x);\
+ buffer[3] = _3rd_BYTE(x);
+
+/* Exported functions ------------------------------------------------------- */
+
+uint16_t MAL_Init (void);
+uint16_t MAL_DeInit (void);
+uint16_t MAL_Erase (uint32_t SectorAddress);
+uint16_t MAL_Write (uint32_t SectorAddress, uint32_t DataLength);
+uint8_t *MAL_Read (uint32_t SectorAddress, uint32_t DataLength);
+uint16_t MAL_GetStatus(uint32_t SectorAddress ,uint8_t Cmd, uint8_t *buffer);
+
+extern uint8_t MAL_Buffer[XFERSIZE]; /* RAM Buffer for Downloaded Data */
+#endif /* __DFU_MAL_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/dfu/inc/usbd_flash_if.h b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/dfu/inc/usbd_flash_if.h
new file mode 100644
index 0000000..d79adbc
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/dfu/inc/usbd_flash_if.h
@@ -0,0 +1,58 @@
+/**
+ ******************************************************************************
+ * @file usbd_flash_if.h
+ * @author MCD Application Team
+ * @version V1.1.0
+ * @date 19-March-2012
+ * @brief Header for usbd_flash_if.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 __FLASH_IF_MAL_H
+#define __FLASH_IF_MAL_H
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_dfu_mal.h"
+
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+#define FLASH_START_ADD 0x08000000
+
+#ifdef STM32F2XX
+ #define FLASH_END_ADD 0x08100000
+ #define FLASH_IF_STRING "@Internal Flash /0x08000000/03*016Ka,01*016Kg,01*064Kg,07*128Kg"
+#elif defined(STM32F4XX)
+ #define FLASH_END_ADD 0x08100000
+ #define FLASH_IF_STRING "@Internal Flash /0x08000000/03*016Ka,01*016Kg,01*064Kg,07*128Kg"
+#elif defined(STM32F10X_CL)
+ #define FLASH_END_ADD 0x08040000
+ #define FLASH_IF_STRING "@Internal Flash /0x08000000/06*002Ka,122*002Kg"
+#endif /* STM32F2XX */
+
+
+extern DFU_MAL_Prop_TypeDef DFU_Flash_cb;
+
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions ------------------------------------------------------- */
+
+#endif /* __FLASH_IF_MAL_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/dfu/inc/usbd_mem_if_template.h b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/dfu/inc/usbd_mem_if_template.h
new file mode 100644
index 0000000..a59b9ac
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/dfu/inc/usbd_mem_if_template.h
@@ -0,0 +1,51 @@
+/**
+ ******************************************************************************
+ * @file usbd_mem_if_template.h
+ * @author MCD Application Team
+ * @version V1.1.0
+ * @date 19-March-2012
+ * @brief Header for usbd_mem_if_template.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 __MEM_IF_MAL_H
+#define __MEM_IF_MAL_H
+
+/* Includes ------------------------------------------------------------------*/
+#include "usb_conf.h"
+
+#include "usbd_dfu_mal.h"
+
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+#define MEM_START_ADD 0x00000000 /* Dummy start address */
+#define MEM_END_ADD (uint32_t)(MEM_START_ADD + (5 * 1024)) /* Dummy Size = 5KB */
+
+#define MEM_IF_STRING "@Dummy Memory /0x00000000/01*002Kg,03*001Kg"
+
+extern DFU_MAL_Prop_TypeDef DFU_Mem_cb;
+
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions ------------------------------------------------------- */
+
+#endif /* __MEM_IF_MAL_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/dfu/inc/usbd_otp_if.h b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/dfu/inc/usbd_otp_if.h
new file mode 100644
index 0000000..b5de502
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/dfu/inc/usbd_otp_if.h
@@ -0,0 +1,49 @@
+/**
+ ******************************************************************************
+ * @file usbd_otp_if.h
+ * @author MCD Application Team
+ * @version V1.1.0
+ * @date 19-March-2012
+ * @brief Header for usbd_otp_if.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 __OTP_IF_MAL_H
+#define __OTP_IF_MAL_H
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_dfu_mal.h"
+
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+#define OTP_START_ADD 0x1FFF7800
+#define OTP_END_ADD (uint32_t)(OTP_START_ADD + 528)
+
+#define OTP_IF_STRING "@OTP Area /0x1FFF7800/01*512 g,01*016 g"
+
+extern DFU_MAL_Prop_TypeDef DFU_Otp_cb;
+
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions ------------------------------------------------------- */
+
+#endif /* __OTP_IF_MAL_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/dfu/src/usbd_dfu_core.c b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/dfu/src/usbd_dfu_core.c
new file mode 100644
index 0000000..af8ca9d
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/dfu/src/usbd_dfu_core.c
@@ -0,0 +1,1052 @@
+/**
+ ******************************************************************************
+ * @file usbd_dfu_core.c
+ * @author MCD Application Team
+ * @version V1.1.0
+ * @date 19-March-2012
+ * @brief This file provides the high layer firmware functions to manage the
+ * following functionalities of the USB DFU Class:
+ * - Initialization and Configuration of high and low layer
+ * - Enumeration as DFU Device (and enumeration for each implemented memory interface)
+ * - Transfers to/from memory interfaces
+ * - Easy-to-customize "plug-in-like" modules for adding/removing memory interfaces.
+ * - Error management
+ *
+ * @verbatim
+ *
+ * ===================================================================
+ * DFU Class Driver Description
+ * ===================================================================
+ * This driver manages the DFU class V1.1 following the "Device Class Specification for
+ * Device Firmware Upgrade Version 1.1 Aug 5, 2004".
+ * This driver implements the following aspects of the specification:
+ * - Device descriptor management
+ * - Configuration descriptor management
+ * - Enumeration as DFU device (in DFU mode only)
+ * - Requests management (supporting ST DFU sub-protocol)
+ * - Memory operations management (Download/Upload/Erase/Detach/GetState/GetStatus)
+ * - DFU state machine implementation.
+ *
+ * @note
+ * ST DFU sub-protocol is compliant with DFU protocol and use sub-requests to manage
+ * memory addressing, commands processing, specific memories operations (ie. Erase) ...
+ * As required by the DFU specification, only endpoint 0 is used in this application.
+ * Other endpoints and functions may be added to the application (ie. DFU ...)
+ *
+ * These aspects may be enriched or modified for a specific user application.
+ *
+ * This driver doesn't implement the following aspects of the specification
+ * (but it is possible to manage these features with some modifications on this driver):
+ * - Manifestation Tolerant mode
+ *
+ * @endverbatim
+ *
+ ******************************************************************************
+ * @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_dfu_core.h"
+#include "usbd_desc.h"
+#include "usbd_req.h"
+#include "usb_bsp.h"
+
+
+/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
+ * @{
+ */
+
+
+/** @defgroup usbd_dfu
+ * @brief usbd core module
+ * @{
+ */
+
+/** @defgroup usbd_dfu_Private_TypesDefinitions
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup usbd_dfu_Private_Defines
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup usbd_dfu_Private_Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup usbd_dfu_Private_FunctionPrototypes
+ * @{
+ */
+
+/*********************************************
+ DFU Device library callbacks
+ *********************************************/
+static uint8_t usbd_dfu_Init (void *pdev,
+ uint8_t cfgidx);
+
+static uint8_t usbd_dfu_DeInit (void *pdev,
+ uint8_t cfgidx);
+
+static uint8_t usbd_dfu_Setup (void *pdev,
+ USB_SETUP_REQ *req);
+
+static uint8_t EP0_TxSent (void *pdev);
+
+static uint8_t EP0_RxReady (void *pdev);
+
+
+static uint8_t *USBD_DFU_GetCfgDesc (uint8_t speed,
+ uint16_t *length);
+
+
+#ifdef USB_OTG_HS_CORE
+static uint8_t *USBD_DFU_GetOtherCfgDesc (uint8_t speed,
+ uint16_t *length);
+#endif
+
+static uint8_t* USBD_DFU_GetUsrStringDesc (uint8_t speed,
+ uint8_t index ,
+ uint16_t *length);
+
+/*********************************************
+ DFU Requests management functions
+ *********************************************/
+static void DFU_Req_DETACH (void *pdev,
+ USB_SETUP_REQ *req);
+
+static void DFU_Req_DNLOAD (void *pdev,
+ USB_SETUP_REQ *req);
+
+static void DFU_Req_UPLOAD (void *pdev,
+ USB_SETUP_REQ *req);
+
+static void DFU_Req_GETSTATUS (void *pdev);
+
+static void DFU_Req_CLRSTATUS (void *pdev);
+
+static void DFU_Req_GETSTATE (void *pdev);
+
+static void DFU_Req_ABORT (void *pdev);
+
+static void DFU_LeaveDFUMode (void *pdev);
+
+/**
+ * @}
+ */
+
+/** @defgroup usbd_dfu_Private_Variables
+ * @{
+ */
+#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_dfu_CfgDesc[USB_DFU_CONFIG_DESC_SIZ] __ALIGN_END ;
+
+
+#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_dfu_OtherCfgDesc[USB_DFU_CONFIG_DESC_SIZ] __ALIGN_END ;
+
+/* The list of Interface String descriptor pointers is defined in usbd_dfu_mal.c
+ file. This list can be updated whenever a memory has to be added or removed */
+extern const uint8_t* usbd_dfu_StringDesc[];
+
+/* State Machine variables */
+uint8_t DeviceState;
+uint8_t DeviceStatus[6];
+uint32_t Manifest_State = Manifest_complete;
+/* Data Management variables */
+static uint32_t wBlockNum = 0, wlength = 0;
+static uint32_t Pointer = APP_DEFAULT_ADD; /* Base Address to Erase, Program or Read */
+static __IO uint32_t usbd_dfu_AltSet = 0;
+
+extern uint8_t MAL_Buffer[];
+
+/* DFU interface class callbacks structure */
+USBD_Class_cb_TypeDef DFU_cb =
+{
+ usbd_dfu_Init,
+ usbd_dfu_DeInit,
+ usbd_dfu_Setup,
+ EP0_TxSent,
+ EP0_RxReady,
+ NULL, /* DataIn, */
+ NULL, /* DataOut, */
+ NULL, /*SOF */
+ NULL,
+ NULL,
+ USBD_DFU_GetCfgDesc,
+#ifdef USB_OTG_HS_CORE
+ USBD_DFU_GetOtherCfgDesc, /* use same cobfig as per FS */
+#endif
+ USBD_DFU_GetUsrStringDesc,
+};
+
+#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
+ #if defined ( __ICCARM__ ) /*!< IAR Compiler */
+ #pragma data_alignment=4
+ #endif
+#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
+/* USB DFU device Configuration Descriptor */
+__ALIGN_BEGIN uint8_t usbd_dfu_CfgDesc[USB_DFU_CONFIG_DESC_SIZ] __ALIGN_END =
+{
+ 0x09, /* bLength: Configuation Descriptor size */
+ USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType: Configuration */
+ USB_DFU_CONFIG_DESC_SIZ,
+ /* wTotalLength: Bytes returned */
+ 0x00,
+ 0x01, /*bNumInterfaces: 1 interface*/
+ 0x01, /*bConfigurationValue: Configuration value*/
+ 0x02, /*iConfiguration: Index of string descriptor describing the configuration*/
+ 0xC0, /*bmAttributes: bus powered and Supprts Remote Wakeup */
+ 0x32, /*MaxPower 100 mA: this current is used for detecting Vbus*/
+ /* 09 */
+
+ /********** Descriptor of DFU interface 0 Alternate setting 0 **************/
+ USBD_DFU_IF_DESC(0), /* This interface is mandatory for all devices */
+
+#if (USBD_ITF_MAX_NUM > 1)
+ /********** Descriptor of DFU interface 0 Alternate setting 1 **************/
+ USBD_DFU_IF_DESC(1),
+#endif /* (USBD_ITF_MAX_NUM > 1) */
+
+#if (USBD_ITF_MAX_NUM > 2)
+ /********** Descriptor of DFU interface 0 Alternate setting 2 **************/
+ USBD_DFU_IF_DESC(2),
+#endif /* (USBD_ITF_MAX_NUM > 2) */
+
+#if (USBD_ITF_MAX_NUM > 3)
+ /********** Descriptor of DFU interface 0 Alternate setting 3 **************/
+ USBD_DFU_IF_DESC(3),
+#endif /* (USBD_ITF_MAX_NUM > 3) */
+
+#if (USBD_ITF_MAX_NUM > 4)
+ /********** Descriptor of DFU interface 0 Alternate setting 4 **************/
+ USBD_DFU_IF_DESC(4),
+#endif /* (USBD_ITF_MAX_NUM > 4) */
+
+#if (USBD_ITF_MAX_NUM > 5)
+ /********** Descriptor of DFU interface 0 Alternate setting 5 **************/
+ USBD_DFU_IF_DESC(5),
+#endif /* (USBD_ITF_MAX_NUM > 5) */
+
+#if (USBD_ITF_MAX_NUM > 6)
+#error "ERROR: usbd_dfu_core.c: Modify the file to support more descriptors!"
+#endif /* (USBD_ITF_MAX_NUM > 6) */
+
+ /******************** DFU Functional Descriptor********************/
+ 0x09, /*blength = 9 Bytes*/
+ DFU_DESCRIPTOR_TYPE, /* DFU Functional Descriptor*/
+ 0x0B, /*bmAttribute
+ bitCanDnload = 1 (bit 0)
+ bitCanUpload = 1 (bit 1)
+ bitManifestationTolerant = 0 (bit 2)
+ bitWillDetach = 1 (bit 3)
+ Reserved (bit4-6)
+ bitAcceleratedST = 0 (bit 7)*/
+ 0xFF, /*DetachTimeOut= 255 ms*/
+ 0x00,
+ /*WARNING: In DMA mode the multiple MPS packets feature is still not supported
+ ==> In this case, when using DMA XFERSIZE should be set to 64 in usbd_conf.h */
+ TRANSFER_SIZE_BYTES(XFERSIZE), /* TransferSize = 1024 Byte*/
+ 0x1A, /* bcdDFUVersion*/
+ 0x01
+ /***********************************************************/
+ /* 9*/
+} ;
+
+#ifdef USE_USB_OTG_HS
+#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_dfu_OtherCfgDesc[USB_DFU_CONFIG_DESC_SIZ] __ALIGN_END =
+{
+ 0x09, /* bLength: Configuation Descriptor size */
+ USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION, /* bDescriptorType: Configuration */
+ USB_DFU_CONFIG_DESC_SIZ,
+ /* wTotalLength: Bytes returned */
+ 0x00,
+ 0x01, /*bNumInterfaces: 1 interface*/
+ 0x01, /*bConfigurationValue: Configuration value*/
+ 0x02, /*iConfiguration: Index of string descriptor describing the configuration*/
+ 0xC0, /*bmAttributes: bus powered and Supprts Remote Wakeup */
+ 0x32, /*MaxPower 100 mA: this current is used for detecting Vbus*/
+ /* 09 */
+
+ /********** Descriptor of DFU interface 0 Alternate setting 0 **************/
+ USBD_DFU_IF_DESC(0), /* This interface is mandatory for all devices */
+
+#if (USBD_ITF_MAX_NUM > 1)
+ /********** Descriptor of DFU interface 0 Alternate setting 1 **************/
+ USBD_DFU_IF_DESC(1),
+#endif /* (USBD_ITF_MAX_NUM > 1) */
+
+#if (USBD_ITF_MAX_NUM > 2)
+ /********** Descriptor of DFU interface 0 Alternate setting 2 **************/
+ USBD_DFU_IF_DESC(2),
+#endif /* (USBD_ITF_MAX_NUM > 2) */
+
+#if (USBD_ITF_MAX_NUM > 3)
+ /********** Descriptor of DFU interface 0 Alternate setting 3 **************/
+ USBD_DFU_IF_DESC(3),
+#endif /* (USBD_ITF_MAX_NUM > 3) */
+
+#if (USBD_ITF_MAX_NUM > 4)
+ /********** Descriptor of DFU interface 0 Alternate setting 4 **************/
+ USBD_DFU_IF_DESC(4),
+#endif /* (USBD_ITF_MAX_NUM > 4) */
+
+#if (USBD_ITF_MAX_NUM > 5)
+ /********** Descriptor of DFU interface 0 Alternate setting 5 **************/
+ USBD_DFU_IF_DESC(5),
+#endif /* (USBD_ITF_MAX_NUM > 5) */
+
+#if (USBD_ITF_MAX_NUM > 6)
+#error "ERROR: usbd_dfu_core.c: Modify the file to support more descriptors!"
+#endif /* (USBD_ITF_MAX_NUM > 6) */
+
+ /******************** DFU Functional Descriptor********************/
+ 0x09, /*blength = 9 Bytes*/
+ DFU_DESCRIPTOR_TYPE, /* DFU Functional Descriptor*/
+ 0x0B, /*bmAttribute
+ bitCanDnload = 1 (bit 0)
+ bitCanUpload = 1 (bit 1)
+ bitManifestationTolerant = 0 (bit 2)
+ bitWillDetach = 1 (bit 3)
+ Reserved (bit4-6)
+ bitAcceleratedST = 0 (bit 7)*/
+ 0xFF, /*DetachTimeOut= 255 ms*/
+ 0x00,
+ /*WARNING: In DMA mode the multiple MPS packets feature is still not supported
+ ==> In this case, when using DMA XFERSIZE should be set to 64 in usbd_conf.h */
+ TRANSFER_SIZE_BYTES(XFERSIZE), /* TransferSize = 1024 Byte*/
+ 0x1A, /* bcdDFUVersion*/
+ 0x01
+ /***********************************************************/
+ /* 9*/
+};
+#endif /* USE_USB_OTG_HS */
+
+#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
+ #if defined ( __ICCARM__ ) /*!< IAR Compiler */
+ #pragma data_alignment=4
+ #endif
+
+__ALIGN_BEGIN static uint8_t usbd_dfu_Desc[USB_DFU_DESC_SIZ] __ALIGN_END =
+{
+ 0x09, /*blength = 9 Bytes*/
+ DFU_DESCRIPTOR_TYPE, /* DFU Functional Descriptor*/
+ 0x0B, /*bmAttribute
+ bitCanDnload = 1 (bit 0)
+ bitCanUpload = 1 (bit 1)
+ bitManifestationTolerant = 0 (bit 2)
+ bitWillDetach = 1 (bit 3)
+ Reserved (bit4-6)
+ bitAcceleratedST = 0 (bit 7)*/
+ 0xFF, /*DetachTimeOut= 255 ms*/
+ 0x00,
+ /*WARNING: In DMA mode the multiple MPS packets feature is still not supported
+ ==> In this case, when using DMA XFERSIZE should be set to 64 in usbd_conf.h */
+ TRANSFER_SIZE_BYTES(XFERSIZE), /* TransferSize = 1024 Byte*/
+ 0x1A, /* bcdDFUVersion*/
+ 0x01
+};
+#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
+
+/**
+ * @}
+ */
+
+/** @defgroup usbd_dfu_Private_Functions
+ * @{
+ */
+
+/**
+ * @brief usbd_dfu_Init
+ * Initializes the DFU interface.
+ * @param pdev: device instance
+ * @param cfgidx: Configuration index
+ * @retval status
+ */
+static uint8_t usbd_dfu_Init (void *pdev,
+ uint8_t cfgidx)
+{
+ /* Initilialize the MAL(Media Access Layer) */
+ MAL_Init();
+
+ /* Initialize the state of the DFU interface */
+ DeviceState = STATE_dfuIDLE;
+ DeviceStatus[0] = STATUS_OK;
+ DeviceStatus[4] = DeviceState;
+
+ return USBD_OK;
+}
+
+/**
+ * @brief usbd_dfu_Init
+ * De-initializes the DFU layer.
+ * @param pdev: device instance
+ * @param cfgidx: Configuration index
+ * @retval status
+ */
+static uint8_t usbd_dfu_DeInit (void *pdev,
+ uint8_t cfgidx)
+{
+ /* Restore default state */
+ DeviceState = STATE_dfuIDLE;
+ DeviceStatus[0] = STATUS_OK;
+ DeviceStatus[4] = DeviceState;
+ wBlockNum = 0;
+ wlength = 0;
+
+ /* DeInitilialize the MAL(Media Access Layer) */
+ MAL_DeInit();
+
+ return USBD_OK;
+}
+
+/**
+ * @brief usbd_dfu_Setup
+ * Handles the DFU request parsing.
+ * @param pdev: instance
+ * @param req: usb requests
+ * @retval status
+ */
+static uint8_t usbd_dfu_Setup (void *pdev,
+ USB_SETUP_REQ *req)
+{
+ uint16_t len = 0;
+ uint8_t *pbuf = NULL;
+
+ switch (req->bmRequest & USB_REQ_TYPE_MASK)
+ {
+ /* DFU Class Requests -------------------------------*/
+ case USB_REQ_TYPE_CLASS :
+ switch (req->bRequest)
+ {
+ case DFU_DNLOAD:
+ DFU_Req_DNLOAD(pdev, req);
+ break;
+
+ case DFU_UPLOAD:
+ DFU_Req_UPLOAD(pdev, req);
+ break;
+
+ case DFU_GETSTATUS:
+ DFU_Req_GETSTATUS(pdev);
+ break;
+
+ case DFU_CLRSTATUS:
+ DFU_Req_CLRSTATUS(pdev);
+ break;
+
+ case DFU_GETSTATE:
+ DFU_Req_GETSTATE(pdev);
+ break;
+
+ case DFU_ABORT:
+ DFU_Req_ABORT(pdev);
+ break;
+
+ case DFU_DETACH:
+ DFU_Req_DETACH(pdev, req);
+ break;
+
+ default:
+ USBD_CtlError (pdev, req);
+ return USBD_FAIL;
+ }
+ break;
+
+ /* Standard Requests -------------------------------*/
+ case USB_REQ_TYPE_STANDARD:
+ switch (req->bRequest)
+ {
+ case USB_REQ_GET_DESCRIPTOR:
+ if( (req->wValue >> 8) == DFU_DESCRIPTOR_TYPE)
+ {
+#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
+ pbuf = usbd_dfu_Desc;
+#else
+ pbuf = usbd_dfu_CfgDesc + 9 + (9 * USBD_ITF_MAX_NUM);
+#endif
+ len = MIN(USB_DFU_DESC_SIZ , req->wLength);
+ }
+
+ USBD_CtlSendData (pdev,
+ pbuf,
+ len);
+ break;
+
+ case USB_REQ_GET_INTERFACE :
+ USBD_CtlSendData (pdev,
+ (uint8_t *)&usbd_dfu_AltSet,
+ 1);
+ break;
+
+ case USB_REQ_SET_INTERFACE :
+ if ((uint8_t)(req->wValue) < USBD_ITF_MAX_NUM)
+ {
+ usbd_dfu_AltSet = (uint8_t)(req->wValue);
+ }
+ else
+ {
+ /* Call the error management function (command will be nacked */
+ USBD_CtlError (pdev, req);
+ }
+ break;
+ }
+ }
+ return USBD_OK;
+}
+
+/**
+ * @brief EP0_TxSent
+ * Handles the DFU control endpoint data IN stage.
+ * @param pdev: device instance
+ * @retval status
+ */
+static uint8_t EP0_TxSent (void *pdev)
+{
+ uint32_t Addr;
+ USB_SETUP_REQ req;
+
+ if (DeviceState == STATE_dfuDNBUSY)
+ {
+ /* Decode the Special Command*/
+ if (wBlockNum == 0)
+ {
+ if ((MAL_Buffer[0] == CMD_GETCOMMANDS) && (wlength == 1))
+ {}
+ else if (( MAL_Buffer[0] == CMD_SETADDRESSPOINTER ) && (wlength == 5))
+ {
+ Pointer = MAL_Buffer[1];
+ Pointer += MAL_Buffer[2] << 8;
+ Pointer += MAL_Buffer[3] << 16;
+ Pointer += MAL_Buffer[4] << 24;
+ }
+ else if (( MAL_Buffer[0] == CMD_ERASE ) && (wlength == 5))
+ {
+ Pointer = MAL_Buffer[1];
+ Pointer += MAL_Buffer[2] << 8;
+ Pointer += MAL_Buffer[3] << 16;
+ Pointer += MAL_Buffer[4] << 24;
+ MAL_Erase(Pointer);
+ }
+ else
+ {
+ /* Reset the global length and block number */
+ wlength = 0;
+ wBlockNum = 0;
+ /* Call the error management function (command will be nacked) */
+ req.bmRequest = 0;
+ req.wLength = 1;
+ USBD_CtlError (pdev, &req);
+ }
+ }
+ /* Regular Download Command */
+ else if (wBlockNum > 1)
+ {
+ /* Decode the required address */
+ Addr = ((wBlockNum - 2) * XFERSIZE) + Pointer;
+
+ /* Preform the write operation */
+ MAL_Write(Addr, wlength);
+ }
+ /* Reset the global lenght and block number */
+ wlength = 0;
+ wBlockNum = 0;
+
+ /* Update the state machine */
+ DeviceState = STATE_dfuDNLOAD_SYNC;
+ DeviceStatus[4] = DeviceState;
+ DeviceStatus[1] = 0;
+ DeviceStatus[2] = 0;
+ DeviceStatus[3] = 0;
+ return USBD_OK;
+ }
+ else if (DeviceState == STATE_dfuMANIFEST)/* Manifestation in progress*/
+ {
+ /* Start leaving DFU mode */
+ DFU_LeaveDFUMode(pdev);
+ }
+
+ return USBD_OK;
+}
+
+/**
+ * @brief EP0_RxReady
+ * Handles the DFU control endpoint data OUT stage.
+ * @param pdev: device instance
+ * @retval status
+ */
+static uint8_t EP0_RxReady (void *pdev)
+{
+ return USBD_OK;
+}
+
+
+/******************************************************************************
+ DFU Class requests management
+******************************************************************************/
+/**
+ * @brief DFU_Req_DETACH
+ * Handles the DFU DETACH request.
+ * @param pdev: device instance
+ * @param req: pointer to the request structure.
+ * @retval None.
+ */
+static void DFU_Req_DETACH(void *pdev, USB_SETUP_REQ *req)
+{
+ if (DeviceState == STATE_dfuIDLE || DeviceState == STATE_dfuDNLOAD_SYNC
+ || DeviceState == STATE_dfuDNLOAD_IDLE || DeviceState == STATE_dfuMANIFEST_SYNC
+ || DeviceState == STATE_dfuUPLOAD_IDLE )
+ {
+ /* Update the state machine */
+ DeviceState = STATE_dfuIDLE;
+ DeviceStatus[0] = STATUS_OK;
+ DeviceStatus[1] = 0;
+ DeviceStatus[2] = 0;
+ DeviceStatus[3] = 0; /*bwPollTimeout=0ms*/
+ DeviceStatus[4] = DeviceState;
+ DeviceStatus[5] = 0; /*iString*/
+ wBlockNum = 0;
+ wlength = 0;
+ }
+
+ /* Check the detach capability in the DFU functional descriptor */
+ if ((usbd_dfu_CfgDesc[12 + (9 * USBD_ITF_MAX_NUM)]) & DFU_DETACH_MASK)
+ {
+ /* Perform an Attach-Detach operation on USB bus */
+ DCD_DevDisconnect (pdev);
+ DCD_DevConnect (pdev);
+ }
+ else
+ {
+ /* Wait for the period of time specified in Detach request */
+ USB_OTG_BSP_mDelay (req->wValue);
+ }
+}
+
+/**
+ * @brief DFU_Req_DNLOAD
+ * Handles the DFU DNLOAD request.
+ * @param pdev: device instance
+ * @param req: pointer to the request structure
+ * @retval None
+ */
+static void DFU_Req_DNLOAD(void *pdev, USB_SETUP_REQ *req)
+{
+ /* Data setup request */
+ if (req->wLength > 0)
+ {
+ if ((DeviceState == STATE_dfuIDLE) || (DeviceState == STATE_dfuDNLOAD_IDLE))
+ {
+ /* Update the global length and block number */
+ wBlockNum = req->wValue;
+ wlength = req->wLength;
+
+ /* Update the state machine */
+ DeviceState = STATE_dfuDNLOAD_SYNC;
+ DeviceStatus[4] = DeviceState;
+
+ /* Prepare the reception of the buffer over EP0 */
+ USBD_CtlPrepareRx (pdev,
+ (uint8_t*)MAL_Buffer,
+ wlength);
+ }
+ /* Unsupported state */
+ else
+ {
+ /* Call the error management function (command will be nacked */
+ USBD_CtlError (pdev, req);
+ }
+ }
+ /* 0 Data DNLOAD request */
+ else
+ {
+ /* End of DNLOAD operation*/
+ if (DeviceState == STATE_dfuDNLOAD_IDLE || DeviceState == STATE_dfuIDLE )
+ {
+ Manifest_State = Manifest_In_Progress;
+ DeviceState = STATE_dfuMANIFEST_SYNC;
+ DeviceStatus[1] = 0;
+ DeviceStatus[2] = 0;
+ DeviceStatus[3] = 0;
+ DeviceStatus[4] = DeviceState;
+ }
+ else
+ {
+ /* Call the error management function (command will be nacked */
+ USBD_CtlError (pdev, req);
+ }
+ }
+}
+
+/**
+ * @brief DFU_Req_UPLOAD
+ * Handles the DFU UPLOAD request.
+ * @param pdev: instance
+ * @param req: pointer to the request structure
+ * @retval status
+ */
+static void DFU_Req_UPLOAD(void *pdev, USB_SETUP_REQ *req)
+{
+ uint8_t *Phy_Addr = NULL;
+ uint32_t Addr = 0;
+
+ /* Data setup request */
+ if (req->wLength > 0)
+ {
+ if ((DeviceState == STATE_dfuIDLE) || (DeviceState == STATE_dfuUPLOAD_IDLE))
+ {
+ /* Update the global langth and block number */
+ wBlockNum = req->wValue;
+ wlength = req->wLength;
+
+ /* DFU Get Command */
+ if (wBlockNum == 0)
+ {
+ /* Update the state machine */
+ DeviceState = (wlength > 3)? STATE_dfuIDLE:STATE_dfuUPLOAD_IDLE;
+ DeviceStatus[4] = DeviceState;
+ DeviceStatus[1] = 0;
+ DeviceStatus[2] = 0;
+ DeviceStatus[3] = 0;
+
+ /* Store the values of all supported commands */
+ MAL_Buffer[0] = CMD_GETCOMMANDS;
+ MAL_Buffer[1] = CMD_SETADDRESSPOINTER;
+ MAL_Buffer[2] = CMD_ERASE;
+
+ /* Send the status data over EP0 */
+ USBD_CtlSendData (pdev,
+ (uint8_t *)(&(MAL_Buffer[0])),
+ 3);
+ }
+ else if (wBlockNum > 1)
+ {
+ DeviceState = STATE_dfuUPLOAD_IDLE ;
+ DeviceStatus[4] = DeviceState;
+ DeviceStatus[1] = 0;
+ DeviceStatus[2] = 0;
+ DeviceStatus[3] = 0;
+ Addr = ((wBlockNum - 2) * XFERSIZE) + Pointer; /* Change is Accelerated*/
+
+ /* Return the physical address where data are stored */
+ Phy_Addr = MAL_Read(Addr, wlength);
+
+ /* Send the status data over EP0 */
+ USBD_CtlSendData (pdev,
+ Phy_Addr,
+ wlength);
+ }
+ else /* unsupported wBlockNum */
+ {
+ DeviceState = STATUS_ERRSTALLEDPKT;
+ DeviceStatus[4] = DeviceState;
+ DeviceStatus[1] = 0;
+ DeviceStatus[2] = 0;
+ DeviceStatus[3] = 0;
+
+ /* Call the error management function (command will be nacked */
+ USBD_CtlError (pdev, req);
+ }
+ }
+ /* Unsupported state */
+ else
+ {
+ wlength = 0;
+ wBlockNum = 0;
+ /* Call the error management function (command will be nacked */
+ USBD_CtlError (pdev, req);
+ }
+ }
+ /* No Data setup request */
+ else
+ {
+ DeviceState = STATE_dfuIDLE;
+ DeviceStatus[1] = 0;
+ DeviceStatus[2] = 0;
+ DeviceStatus[3] = 0;
+ DeviceStatus[4] = DeviceState;
+ }
+}
+
+/**
+ * @brief DFU_Req_GETSTATUS
+ * Handles the DFU GETSTATUS request.
+ * @param pdev: instance
+ * @retval status
+ */
+static void DFU_Req_GETSTATUS(void *pdev)
+{
+ switch (DeviceState)
+ {
+ case STATE_dfuDNLOAD_SYNC:
+ if (wlength != 0)
+ {
+ DeviceState = STATE_dfuDNBUSY;
+ DeviceStatus[4] = DeviceState;
+ if ((wBlockNum == 0) && (MAL_Buffer[0] == CMD_ERASE))
+ {
+ MAL_GetStatus(Pointer, 0, DeviceStatus);
+ }
+ else
+ {
+ MAL_GetStatus(Pointer, 1, DeviceStatus);
+ }
+ }
+ else /* (wlength==0)*/
+ {
+ DeviceState = STATE_dfuDNLOAD_IDLE;
+ DeviceStatus[4] = DeviceState;
+ DeviceStatus[1] = 0;
+ DeviceStatus[2] = 0;
+ DeviceStatus[3] = 0;
+ }
+ break;
+
+ case STATE_dfuMANIFEST_SYNC :
+ if (Manifest_State == Manifest_In_Progress)
+ {
+ DeviceState = STATE_dfuMANIFEST;
+ DeviceStatus[4] = DeviceState;
+ DeviceStatus[1] = 1; /*bwPollTimeout = 1ms*/
+ DeviceStatus[2] = 0;
+ DeviceStatus[3] = 0;
+ //break;
+ }
+ else if ((Manifest_State == Manifest_complete) && \
+ ((usbd_dfu_CfgDesc[(11 + (9 * USBD_ITF_MAX_NUM))]) & 0x04))
+ {
+ DeviceState = STATE_dfuIDLE;
+ DeviceStatus[4] = DeviceState;
+ DeviceStatus[1] = 0;
+ DeviceStatus[2] = 0;
+ DeviceStatus[3] = 0;
+ //break;
+ }
+ break;
+
+ default :
+ break;
+ }
+
+ /* Send the status data over EP0 */
+ USBD_CtlSendData (pdev,
+ (uint8_t *)(&(DeviceStatus[0])),
+ 6);
+}
+
+/**
+ * @brief DFU_Req_CLRSTATUS
+ * Handles the DFU CLRSTATUS request.
+ * @param pdev: device instance
+ * @retval status
+ */
+static void DFU_Req_CLRSTATUS(void *pdev)
+{
+ if (DeviceState == STATE_dfuERROR)
+ {
+ DeviceState = STATE_dfuIDLE;
+ DeviceStatus[0] = STATUS_OK;/*bStatus*/
+ DeviceStatus[1] = 0;
+ DeviceStatus[2] = 0;
+ DeviceStatus[3] = 0; /*bwPollTimeout=0ms*/
+ DeviceStatus[4] = DeviceState;/*bState*/
+ DeviceStatus[5] = 0;/*iString*/
+ }
+ else
+ { /*State Error*/
+ DeviceState = STATE_dfuERROR;
+ DeviceStatus[0] = STATUS_ERRUNKNOWN;/*bStatus*/
+ DeviceStatus[1] = 0;
+ DeviceStatus[2] = 0;
+ DeviceStatus[3] = 0; /*bwPollTimeout=0ms*/
+ DeviceStatus[4] = DeviceState;/*bState*/
+ DeviceStatus[5] = 0;/*iString*/
+ }
+}
+
+/**
+ * @brief DFU_Req_GETSTATE
+ * Handles the DFU GETSTATE request.
+ * @param pdev: device instance
+ * @retval None
+ */
+static void DFU_Req_GETSTATE(void *pdev)
+{
+ /* Return the current state of the DFU interface */
+ USBD_CtlSendData (pdev,
+ &DeviceState,
+ 1);
+}
+
+/**
+ * @brief DFU_Req_ABORT
+ * Handles the DFU ABORT request.
+ * @param pdev: device instance
+ * @retval None
+ */
+static void DFU_Req_ABORT(void *pdev)
+{
+ if (DeviceState == STATE_dfuIDLE || DeviceState == STATE_dfuDNLOAD_SYNC
+ || DeviceState == STATE_dfuDNLOAD_IDLE || DeviceState == STATE_dfuMANIFEST_SYNC
+ || DeviceState == STATE_dfuUPLOAD_IDLE )
+ {
+ DeviceState = STATE_dfuIDLE;
+ DeviceStatus[0] = STATUS_OK;
+ DeviceStatus[1] = 0;
+ DeviceStatus[2] = 0;
+ DeviceStatus[3] = 0; /*bwPollTimeout=0ms*/
+ DeviceStatus[4] = DeviceState;
+ DeviceStatus[5] = 0; /*iString*/
+ wBlockNum = 0;
+ wlength = 0;
+ }
+}
+
+/**
+ * @brief DFU_LeaveDFUMode
+ * Handles the sub-protocol DFU leave DFU mode request (leaves DFU mode
+ * and resets device to jump to user loaded code).
+ * @param pdev: device instance
+ * @retval None
+ */
+void DFU_LeaveDFUMode(void *pdev)
+{
+ Manifest_State = Manifest_complete;
+
+ if ((usbd_dfu_CfgDesc[(11 + (9 * USBD_ITF_MAX_NUM))]) & 0x04)
+ {
+ DeviceState = STATE_dfuMANIFEST_SYNC;
+ DeviceStatus[4] = DeviceState;
+ DeviceStatus[1] = 0;
+ DeviceStatus[2] = 0;
+ DeviceStatus[3] = 0;
+ return;
+ }
+ else
+ {
+ DeviceState = STATE_dfuMANIFEST_WAIT_RESET;
+ DeviceStatus[4] = DeviceState;
+ DeviceStatus[1] = 0;
+ DeviceStatus[2] = 0;
+ DeviceStatus[3] = 0;
+
+ /* Disconnect the USB device */
+ DCD_DevDisconnect (pdev);
+
+ /* DeInitilialize the MAL(Media Access Layer) */
+ MAL_DeInit();
+
+ /* Generate system reset to allow jumping to the user code */
+ NVIC_SystemReset();
+
+ /* This instruction will not be reached (system reset) */
+ return;
+ }
+}
+
+/**
+ * @brief USBD_DFU_GetCfgDesc
+ * Returns configuration descriptor
+ * @param speed : current device speed
+ * @param length : pointer data length
+ * @retval pointer to descriptor buffer
+ */
+static uint8_t *USBD_DFU_GetCfgDesc (uint8_t speed, uint16_t *length)
+{
+ *length = sizeof (usbd_dfu_CfgDesc);
+ return usbd_dfu_CfgDesc;
+}
+
+#ifdef USB_OTG_HS_CORE
+/**
+ * @brief USBD_DFU_GetOtherCfgDesc
+ * Returns other speed configuration descriptor.
+ * @param speed : current device speed
+ * @param length : pointer data length
+ * @retval pointer to descriptor buffer
+ */
+static uint8_t *USBD_DFU_GetOtherCfgDesc (uint8_t speed, uint16_t *length)
+{
+ *length = sizeof (usbd_dfu_OtherCfgDesc);
+ return usbd_dfu_OtherCfgDesc;
+}
+#endif
+
+/**
+ * @brief USBD_DFU_GetUsrStringDesc
+ * Manages the transfer of memory interfaces string descriptors.
+ * @param speed : current device speed
+ * @param index: desciptor index
+ * @param length : pointer data length
+ * @retval pointer to the descriptor table or NULL if the descriptor is not supported.
+ */
+static uint8_t* USBD_DFU_GetUsrStringDesc (uint8_t speed, uint8_t index , uint16_t *length)
+{
+ /* Check if the requested string interface is supported */
+ if (index <= (USBD_IDX_INTERFACE_STR + USBD_ITF_MAX_NUM))
+ {
+
+
+ USBD_GetString ((uint8_t *)usbd_dfu_StringDesc[index - USBD_IDX_INTERFACE_STR - 1], USBD_StrDesc, length);
+ return USBD_StrDesc;
+ }
+ /* Not supported Interface Descriptor index */
+ else
+ {
+ return NULL;
+ }
+}
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/dfu/src/usbd_dfu_mal.c b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/dfu/src/usbd_dfu_mal.c
new file mode 100644
index 0000000..280ac7a
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/dfu/src/usbd_dfu_mal.c
@@ -0,0 +1,287 @@
+/**
+ ******************************************************************************
+ * @file usbd_dfu_mal.c
+ * @author MCD Application Team
+ * @version V1.1.0
+ * @date 19-March-2012
+ * @brief Generic media access 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_dfu_mal.h"
+
+#include "usbd_flash_if.h"
+
+#ifdef DFU_MAL_SUPPORT_OTP
+ #include "usbd_otp_if.h"
+#endif
+
+#ifdef DFU_MAL_SUPPORT_MEM
+ #include "usbd_mem_if_template.h"
+#endif
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+
+/* Global Memories callback and string descriptors reference tables.
+ To add a new memory, modify the value of MAX_USED_MEDIA in usbd_dfu_mal.h
+ and add the pointer to the callback structure in this table.
+ Then add the pointer to the memory string descriptor in usbd_dfu_StringDesc table.
+ No other operation is required. */
+DFU_MAL_Prop_TypeDef* tMALTab[MAX_USED_MEDIA] = {
+ &DFU_Flash_cb
+#ifdef DFU_MAL_SUPPORT_OTP
+ , &DFU_Otp_cb
+#endif
+#ifdef DFU_MAL_SUPPORT_MEM
+ , &DFU_Mem_cb
+#endif
+};
+
+#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 const uint8_t* usbd_dfu_StringDesc[MAX_USED_MEDIA] __ALIGN_END = {
+ FLASH_IF_STRING
+#ifdef DFU_MAL_SUPPORT_OTP
+ , OTP_IF_STRING
+#endif
+#ifdef DFU_MAL_SUPPORT_MEM
+ , MEM_IF_STRING
+#endif
+};
+
+#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
+ #if defined ( __ICCARM__ ) /*!< IAR Compiler */
+ #pragma data_alignment=4
+ #endif
+#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
+/* RAM Buffer for Downloaded Data */
+__ALIGN_BEGIN uint8_t MAL_Buffer[XFERSIZE] __ALIGN_END ;
+
+/* Private function prototypes -----------------------------------------------*/
+static uint8_t MAL_CheckAdd (uint32_t Add);
+/* Private functions ---------------------------------------------------------*/
+
+/**
+ * @brief MAL_Init
+ * Initializes the Media on the STM32
+ * @param None
+ * @retval Result of the opeartion (MAL_OK in all cases)
+ */
+uint16_t MAL_Init(void)
+{
+ uint32_t memIdx = 0;
+
+ /* Init all supported memories */
+ for(memIdx = 0; memIdx < MAX_USED_MEDIA; memIdx++)
+ {
+ /* If the check addres is positive, exit with the memory index */
+ if (tMALTab[memIdx]->pMAL_Init != NULL)
+ {
+ tMALTab[memIdx]->pMAL_Init();
+ }
+ }
+
+ return MAL_OK;
+}
+
+/**
+ * @brief MAL_DeInit
+ * DeInitializes the Media on the STM32
+ * @param None
+ * @retval Result of the opeartion (MAL_OK in all cases)
+ */
+uint16_t MAL_DeInit(void)
+{
+ uint32_t memIdx = 0;
+
+ /* Init all supported memories */
+ for(memIdx = 0; memIdx < MAX_USED_MEDIA; memIdx++)
+ {
+ /* Check if the command is supported */
+ if (tMALTab[memIdx]->pMAL_DeInit != NULL)
+ {
+ tMALTab[memIdx]->pMAL_DeInit();
+ }
+ }
+
+ return MAL_OK;
+}
+
+/**
+ * @brief MAL_Erase
+ * Erase a sector of memory.
+ * @param Add: Sector address/code
+ * @retval Result of the opeartion: MAL_OK if all operations are OK else MAL_FAIL
+ */
+uint16_t MAL_Erase(uint32_t Add)
+{
+ uint32_t memIdx = MAL_CheckAdd(Add);
+
+ /* Check if the area is protected */
+ if (DFU_MAL_IS_PROTECTED_AREA(Add))
+ {
+ return MAL_FAIL;
+ }
+
+ if (memIdx < MAX_USED_MEDIA)
+ {
+ /* Check if the command is supported */
+ if (tMALTab[memIdx]->pMAL_Erase != NULL)
+ {
+ return tMALTab[memIdx]->pMAL_Erase(Add);
+ }
+ else
+ {
+ return MAL_FAIL;
+ }
+ }
+ else
+ {
+ return MAL_FAIL;
+ }
+}
+
+/**
+ * @brief MAL_Write
+ * Write sectors of memory.
+ * @param Add: Sector address/code
+ * @param Len: Number of data to be written (in bytes)
+ * @retval Result of the opeartion: MAL_OK if all operations are OK else MAL_FAIL
+ */
+uint16_t MAL_Write (uint32_t Add, uint32_t Len)
+{
+ uint32_t memIdx = MAL_CheckAdd(Add);
+
+ /* Check if the area is protected */
+ if (DFU_MAL_IS_PROTECTED_AREA(Add))
+ {
+ return MAL_FAIL;
+ }
+
+ if (memIdx < MAX_USED_MEDIA)
+ {
+ /* Check if the command is supported */
+ if (tMALTab[memIdx]->pMAL_Write != NULL)
+ {
+ return tMALTab[memIdx]->pMAL_Write(Add, Len);
+ }
+ else
+ {
+ return MAL_FAIL;
+ }
+ }
+ else
+ {
+ return MAL_FAIL;
+ }
+}
+
+/**
+ * @brief MAL_Read
+ * Read sectors of memory.
+ * @param Add: Sector address/code
+ * @param Len: Number of data to be written (in bytes)
+ * @retval Buffer pointer
+ */
+uint8_t *MAL_Read (uint32_t Add, uint32_t Len)
+{
+ uint32_t memIdx = MAL_CheckAdd(Add);
+
+ if (memIdx < MAX_USED_MEDIA)
+ {
+ /* Check if the command is supported */
+ if (tMALTab[memIdx]->pMAL_Read != NULL)
+ {
+ return tMALTab[memIdx]->pMAL_Read(Add, Len);
+ }
+ else
+ {
+ return MAL_Buffer;
+ }
+ }
+ else
+ {
+ return MAL_Buffer;
+ }
+}
+
+/**
+ * @brief MAL_GetStatus
+ * Get the status of a given memory.
+ * @param Add: Sector address/code (allow to determine which memory will be addressed)
+ * @param Cmd: 0 for erase and 1 for write
+ * @param buffer: pointer to the buffer where the status data will be stored.
+ * @retval Buffer pointer
+ */
+uint16_t MAL_GetStatus(uint32_t Add , uint8_t Cmd, uint8_t *buffer)
+{
+ uint32_t memIdx = MAL_CheckAdd(Add);
+
+ if (memIdx < MAX_USED_MEDIA)
+ {
+ if (Cmd & 0x01)
+ {
+ SET_POLLING_TIMING(tMALTab[memIdx]->EraseTiming);
+ }
+ else
+ {
+ SET_POLLING_TIMING(tMALTab[memIdx]->WriteTiming);
+ }
+
+ return MAL_OK;
+ }
+ else
+ {
+ return MAL_FAIL;
+ }
+}
+
+/**
+ * @brief MAL_CheckAdd
+ * Determine which memory should be managed.
+ * @param Add: Sector address/code (allow to determine which memory will be addressed)
+ * @retval Index of the addressed memory.
+ */
+static uint8_t MAL_CheckAdd(uint32_t Add)
+{
+ uint32_t memIdx = 0;
+
+ /* Check with all supported memories */
+ for(memIdx = 0; memIdx < MAX_USED_MEDIA; memIdx++)
+ {
+ /* If the check addres is positive, exit with the memory index */
+ if (tMALTab[memIdx]->pMAL_CheckAdd(Add) == MAL_OK)
+ {
+ return memIdx;
+ }
+ }
+ /* If no memory found, return MAX_USED_MEDIA */
+ return (MAX_USED_MEDIA);
+}
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/dfu/src/usbd_flash_if.c b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/dfu/src/usbd_flash_if.c
new file mode 100644
index 0000000..3d649d8
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/dfu/src/usbd_flash_if.c
@@ -0,0 +1,227 @@
+/**
+ ******************************************************************************
+ * @file usbd_flash_if.c
+ * @author MCD Application Team
+ * @version V1.1.0
+ * @date 19-March-2012
+ * @brief Specific media access Layer for internal flash.
+ ******************************************************************************
+ * @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_flash_if.h"
+#include "usbd_dfu_mal.h"
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+
+/* Private function prototypes -----------------------------------------------*/
+uint16_t FLASH_If_Init(void);
+uint16_t FLASH_If_Erase (uint32_t Add);
+uint16_t FLASH_If_Write (uint32_t Add, uint32_t Len);
+uint8_t *FLASH_If_Read (uint32_t Add, uint32_t Len);
+uint16_t FLASH_If_DeInit(void);
+uint16_t FLASH_If_CheckAdd(uint32_t Add);
+
+
+/* Private variables ---------------------------------------------------------*/
+DFU_MAL_Prop_TypeDef DFU_Flash_cb =
+ {
+ FLASH_IF_STRING,
+ FLASH_If_Init,
+ FLASH_If_DeInit,
+ FLASH_If_Erase,
+ FLASH_If_Write,
+ FLASH_If_Read,
+ FLASH_If_CheckAdd,
+ 50, /* Erase Time in ms */
+ 50 /* Programming Time in ms */
+ };
+
+/* Private functions ---------------------------------------------------------*/
+
+/**
+ * @brief FLASH_If_Init
+ * Memory initialization routine.
+ * @param None
+ * @retval MAL_OK if operation is successeful, MAL_FAIL else.
+ */
+uint16_t FLASH_If_Init(void)
+{
+ /* Unlock the internal flash */
+ FLASH_Unlock();
+
+ return MAL_OK;
+}
+
+/**
+ * @brief FLASH_If_DeInit
+ * Memory deinitialization routine.
+ * @param None
+ * @retval MAL_OK if operation is successeful, MAL_FAIL else.
+ */
+uint16_t FLASH_If_DeInit(void)
+{
+ /* Lock the internal flash */
+ FLASH_Lock();
+
+ return MAL_OK;
+}
+
+/*******************************************************************************
+* Function Name : FLASH_If_Erase
+* Description : Erase sector
+* Input : None
+* Output : None
+* Return : None
+*******************************************************************************/
+uint16_t FLASH_If_Erase(uint32_t Add)
+{
+#if defined (STM32F2XX) || defined (STM32F4XX)
+ /* Check which sector has to be erased */
+ if (Add < 0x08004000)
+ {
+ FLASH_EraseSector(FLASH_Sector_0, VoltageRange_3);
+ }
+ else if (Add < 0x08008000)
+ {
+ FLASH_EraseSector(FLASH_Sector_1, VoltageRange_3);
+ }
+ else if (Add < 0x0800C000)
+ {
+ FLASH_EraseSector(FLASH_Sector_2, VoltageRange_3);
+ }
+ else if (Add < 0x08010000)
+ {
+ FLASH_EraseSector(FLASH_Sector_3, VoltageRange_3);
+ }
+ else if (Add < 0x08020000)
+ {
+ FLASH_EraseSector(FLASH_Sector_4, VoltageRange_3);
+ }
+ else if (Add < 0x08040000)
+ {
+ FLASH_EraseSector(FLASH_Sector_5, VoltageRange_3);
+ }
+ else if (Add < 0x08060000)
+ {
+ FLASH_EraseSector(FLASH_Sector_6, VoltageRange_3);
+ }
+ else if (Add < 0x08080000)
+ {
+ FLASH_EraseSector(FLASH_Sector_7, VoltageRange_3);
+ }
+ else if (Add < 0x080A0000)
+ {
+ FLASH_EraseSector(FLASH_Sector_8, VoltageRange_3);
+ }
+ else if (Add < 0x080C0000)
+ {
+ FLASH_EraseSector(FLASH_Sector_9, VoltageRange_3);
+ }
+ else if (Add < 0x080E0000)
+ {
+ FLASH_EraseSector(FLASH_Sector_10, VoltageRange_3);
+ }
+ else if (Add < 0x08100000)
+ {
+ FLASH_EraseSector(FLASH_Sector_11, VoltageRange_3);
+ }
+ else
+ {
+ return MAL_FAIL;
+ }
+#elif defined(STM32F10X_CL)
+ /* Call the standard Flash erase function */
+ FLASH_ErasePage(Add);
+#endif /* STM32F2XX */
+
+ return MAL_OK;
+}
+
+/**
+ * @brief FLASH_If_Write
+ * Memory write routine.
+ * @param Add: Address to be written to.
+ * @param Len: Number of data to be written (in bytes).
+ * @retval MAL_OK if operation is successeful, MAL_FAIL else.
+ */
+uint16_t FLASH_If_Write(uint32_t Add, uint32_t Len)
+{
+ uint32_t idx = 0;
+
+ if (Len & 0x3) /* Not an aligned data */
+ {
+ for (idx = Len; idx < ((Len & 0xFFFC) + 4); idx++)
+ {
+ MAL_Buffer[idx] = 0xFF;
+ }
+ }
+
+ /* Data received are Word multiple */
+ for (idx = 0; idx < Len; idx = idx + 4)
+ {
+ FLASH_ProgramWord(Add, *(uint32_t *)(MAL_Buffer + idx));
+ Add += 4;
+ }
+ return MAL_OK;
+}
+
+/**
+ * @brief FLASH_If_Read
+ * Memory read routine.
+ * @param Add: Address to be read from.
+ * @param Len: Number of data to be read (in bytes).
+ * @retval Pointer to the phyisical address where data should be read.
+ */
+uint8_t *FLASH_If_Read (uint32_t Add, uint32_t Len)
+{
+#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
+ uint32_t idx = 0;
+ for (idx = 0; idx < Len; idx += 4)
+ {
+ *(uint32_t*)(MAL_Buffer + idx) = *(uint32_t *)(Add + idx);
+ }
+ return (uint8_t*)(MAL_Buffer);
+#else
+ return (uint8_t *)(Add);
+#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
+}
+
+/**
+ * @brief FLASH_If_CheckAdd
+ * Check if the address is an allowed address for this memory.
+ * @param Add: Address to be checked.
+ * @param Len: Number of data to be read (in bytes).
+ * @retval MAL_OK if the address is allowed, MAL_FAIL else.
+ */
+uint16_t FLASH_If_CheckAdd(uint32_t Add)
+{
+ if ((Add >= FLASH_START_ADD) && (Add < FLASH_END_ADD))
+ {
+ return MAL_OK;
+ }
+ else
+ {
+ return MAL_FAIL;
+ }
+}
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/dfu/src/usbd_mem_if_template.c b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/dfu/src/usbd_mem_if_template.c
new file mode 100644
index 0000000..7aa4228
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/dfu/src/usbd_mem_if_template.c
@@ -0,0 +1,139 @@
+/**
+ ******************************************************************************
+ * @file usbd_mem_if_template.c
+ * @author MCD Application Team
+ * @version V1.1.0
+ * @date 19-March-2012
+ * @brief Specific media access Layer for a template memory. This file is
+ provided as template example showing how to implement a new memory
+ interface based on pre-defined API.
+ ******************************************************************************
+ * @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_mem_if_template.h"
+#include "usbd_dfu_mal.h"
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+
+/* Private function prototypes -----------------------------------------------*/
+uint16_t MEM_If_Init(void);
+uint16_t MEM_If_Erase (uint32_t Add);
+uint16_t MEM_If_Write (uint32_t Add, uint32_t Len);
+uint8_t *MEM_If_Read (uint32_t Add, uint32_t Len);
+uint16_t MEM_If_DeInit(void);
+uint16_t MEM_If_CheckAdd(uint32_t Add);
+
+
+/* Private variables ---------------------------------------------------------*/
+DFU_MAL_Prop_TypeDef DFU_Mem_cb =
+ {
+ MEM_IF_STRING,
+ MEM_If_Init,
+ MEM_If_DeInit,
+ MEM_If_Erase,
+ MEM_If_Write,
+ MEM_If_Read,
+ MEM_If_CheckAdd,
+ 10, /* Erase Time in ms */
+ 10 /* Programming Time in ms */
+ };
+
+/* Private functions ---------------------------------------------------------*/
+
+/**
+ * @brief MEM_If_Init
+ * Memory initialization routine.
+ * @param None
+ * @retval MAL_OK if operation is successeful, MAL_FAIL else.
+ */
+uint16_t MEM_If_Init(void)
+{
+ return MAL_OK;
+}
+
+/**
+ * @brief MEM_If_DeInit
+ * Memory deinitialization routine.
+ * @param None
+ * @retval MAL_OK if operation is successeful, MAL_FAIL else.
+ */
+uint16_t MEM_If_DeInit(void)
+{
+ return MAL_OK;
+}
+
+/**
+ * @brief MEM_If_Erase
+ * Erase sector.
+ * @param Add: Address of sector to be erased.
+ * @retval MAL_OK if operation is successeful, MAL_FAIL else.
+ */
+uint16_t MEM_If_Erase(uint32_t Add)
+{
+ return MAL_OK;
+}
+
+/**
+ * @brief MEM_If_Write
+ * Memory write routine.
+ * @param Add: Address to be written to.
+ * @param Len: Number of data to be written (in bytes).
+ * @retval MAL_OK if operation is successeful, MAL_FAIL else.
+ */
+uint16_t MEM_If_Write(uint32_t Add, uint32_t Len)
+{
+ return MAL_OK;
+}
+
+/**
+ * @brief MEM_If_Read
+ * Memory read routine.
+ * @param Add: Address to be read from.
+ * @param Len: Number of data to be read (in bytes).
+ * @retval Pointer to the phyisical address where data should be read.
+ */
+uint8_t *MEM_If_Read (uint32_t Add, uint32_t Len)
+{
+ /* Return a valid address to avoid HardFault */
+ return (uint8_t*)(MAL_Buffer);
+}
+
+/**
+ * @brief MEM_If_CheckAdd
+ * Check if the address is an allowed address for this memory.
+ * @param Add: Address to be checked.
+ * @param Len: Number of data to be read (in bytes).
+ * @retval MAL_OK if the address is allowed, MAL_FAIL else.
+ */
+uint16_t MEM_If_CheckAdd(uint32_t Add)
+{
+ if ((Add >= MEM_START_ADD) && (Add < MEM_END_ADD))
+ {
+ return MAL_OK;
+ }
+ else
+ {
+ return MAL_FAIL;
+ }
+}
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/dfu/src/usbd_otp_if.c b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/dfu/src/usbd_otp_if.c
new file mode 100644
index 0000000..d9fba28
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/dfu/src/usbd_otp_if.c
@@ -0,0 +1,126 @@
+/**
+ ******************************************************************************
+ * @file usbd_otp_if.c
+ * @author MCD Application Team
+ * @version V1.1.0
+ * @date 19-March-2012
+ * @brief Specific media access Layer for OTP (One Time Programming) memory.
+ ******************************************************************************
+ * @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_otp_if.h"
+#include "usbd_dfu_mal.h"
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+
+/* Private function prototypes -----------------------------------------------*/
+uint16_t OTP_If_Write (uint32_t Add, uint32_t Len);
+uint8_t *OTP_If_Read (uint32_t Add, uint32_t Len);
+uint16_t OTP_If_DeInit(void);
+uint16_t OTP_If_CheckAdd(uint32_t Add);
+
+
+/* Private variables ---------------------------------------------------------*/
+DFU_MAL_Prop_TypeDef DFU_Otp_cb =
+ {
+ OTP_IF_STRING,
+ NULL, /* Init not supported*/
+ NULL, /* DeInit not supported */
+ NULL, /* Erase not supported */
+ OTP_If_Write,
+ OTP_If_Read,
+ OTP_If_CheckAdd,
+ 1, /* Erase Time in ms */
+ 10 /* Programming Time in ms */
+ };
+
+/* Private functions ---------------------------------------------------------*/
+
+/**
+ * @brief OTP_If_Write
+ * Memory write routine.
+ * @param Add: Address to be written to.
+ * @param Len: Number of data to be written (in bytes).
+ * @retval MAL_OK if operation is successeful, MAL_FAIL else.
+ */
+uint16_t OTP_If_Write(uint32_t Add, uint32_t Len)
+{
+ uint32_t idx = 0;
+
+ if (Len & 0x3) /* Not an aligned data */
+ {
+ for (idx = Len; idx < ((Len & 0xFFFC) + 4); idx++)
+ {
+ MAL_Buffer[idx] = 0xFF;
+ }
+ }
+
+ /* Data received are Word multiple */
+ for (idx = 0; idx < Len; idx = idx + 4)
+ {
+ FLASH_ProgramWord(Add, *(uint32_t *)(MAL_Buffer + idx));
+ Add += 4;
+ }
+ return MAL_OK;
+}
+
+/**
+ * @brief OTP_If_Read
+ * Memory read routine.
+ * @param Add: Address to be read from.
+ * @param Len: Number of data to be read (in bytes).
+ * @retval Pointer to the phyisical address where data should be read.
+ */
+uint8_t *OTP_If_Read (uint32_t Add, uint32_t Len)
+{
+#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
+ uint32_t idx = 0;
+ for (idx = 0; idx < Len; idx += 4)
+ {
+ *(uint32_t*)(MAL_Buffer + idx) = *(uint32_t *)(Add + idx);
+ }
+ return (uint8_t*)(MAL_Buffer);
+#else
+ return (uint8_t*)(Add);
+#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
+}
+
+/**
+ * @brief OTP_If_CheckAdd
+ * Check if the address is an allowed address for this memory.
+ * @param Add: Address to be checked.
+ * @param Len: Number of data to be read (in bytes).
+ * @retval MAL_OK if the address is allowed, MAL_FAIL else.
+ */
+uint16_t OTP_If_CheckAdd(uint32_t Add)
+{
+ if ((Add >= OTP_START_ADD) && (Add < OTP_END_ADD))
+ {
+ return MAL_OK;
+ }
+ else
+ {
+ return MAL_FAIL;
+ }
+}
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/hid/inc/usbd_hid_core.h b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/hid/inc/usbd_hid_core.h
new file mode 100644
index 0000000..ddde21d
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/hid/inc/usbd_hid_core.h
@@ -0,0 +1,116 @@
+/**
+ ******************************************************************************
+ * @file usbd_hid_core.h
+ * @author MCD Application Team
+ * @version V1.1.0
+ * @date 19-March-2012
+ * @brief header file for the usbd_hid_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_HID_CORE_H_
+#define __USB_HID_CORE_H_
+
+#include "usbd_ioreq.h"
+
+/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
+ * @{
+ */
+
+/** @defgroup USBD_HID
+ * @brief This file is the Header file for USBD_msc.c
+ * @{
+ */
+
+
+/** @defgroup USBD_HID_Exported_Defines
+ * @{
+ */
+#define USB_HID_CONFIG_DESC_SIZ 34
+#define USB_HID_DESC_SIZ 9
+#define HID_MOUSE_REPORT_DESC_SIZE 74
+
+#define HID_DESCRIPTOR_TYPE 0x21
+#define HID_REPORT_DESC 0x22
+
+
+#define HID_REQ_SET_PROTOCOL 0x0B
+#define HID_REQ_GET_PROTOCOL 0x03
+
+#define HID_REQ_SET_IDLE 0x0A
+#define HID_REQ_GET_IDLE 0x02
+
+#define HID_REQ_SET_REPORT 0x09
+#define HID_REQ_GET_REPORT 0x01
+/**
+ * @}
+ */
+
+
+/** @defgroup USBD_CORE_Exported_TypesDefinitions
+ * @{
+ */
+
+
+/**
+ * @}
+ */
+
+
+
+/** @defgroup USBD_CORE_Exported_Macros
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_CORE_Exported_Variables
+ * @{
+ */
+
+extern USBD_Class_cb_TypeDef USBD_HID_cb;
+/**
+ * @}
+ */
+
+/** @defgroup USB_CORE_Exported_Functions
+ * @{
+ */
+uint8_t USBD_HID_SendReport (USB_OTG_CORE_HANDLE *pdev,
+ uint8_t *report,
+ uint16_t len);
+/**
+ * @}
+ */
+
+#endif // __USB_HID_CORE_H_
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/hid/src/usbd_hid_core.c b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/hid/src/usbd_hid_core.c
new file mode 100644
index 0000000..e54cbb3
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/hid/src/usbd_hid_core.c
@@ -0,0 +1,487 @@
+/**
+ ******************************************************************************
+ * @file usbd_hid_core.c
+ * @author MCD Application Team
+ * @version V1.1.0
+ * @date 19-March-2012
+ * @brief This file provides the HID core functions.
+ *
+ * @verbatim
+ *
+ * ===================================================================
+ * HID Class Description
+ * ===================================================================
+ * This module manages the HID class V1.11 following the "Device Class Definition
+ * for Human Interface Devices (HID) Version 1.11 Jun 27, 2001".
+ * This driver implements the following aspects of the specification:
+ * - The Boot Interface Subclass
+ * - The Mouse protocol
+ * - Usage Page : Generic Desktop
+ * - Usage : Joystick)
+ * - Collection : Application
+ *
+ * @note In HS mode and when the DMA is used, all variables and data structures
+ * dealing with the DMA during the transaction process should be 32-bit aligned.
+ *
+ *
+ * @endverbatim
+ *
+ ******************************************************************************
+ * @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_hid_core.h"
+#include "usbd_desc.h"
+#include "usbd_req.h"
+
+
+/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
+ * @{
+ */
+
+
+/** @defgroup USBD_HID
+ * @brief usbd core module
+ * @{
+ */
+
+/** @defgroup USBD_HID_Private_TypesDefinitions
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup USBD_HID_Private_Defines
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+
+/** @defgroup USBD_HID_Private_Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+
+
+/** @defgroup USBD_HID_Private_FunctionPrototypes
+ * @{
+ */
+
+
+static uint8_t USBD_HID_Init (void *pdev,
+ uint8_t cfgidx);
+
+static uint8_t USBD_HID_DeInit (void *pdev,
+ uint8_t cfgidx);
+
+static uint8_t USBD_HID_Setup (void *pdev,
+ USB_SETUP_REQ *req);
+
+static uint8_t *USBD_HID_GetCfgDesc (uint8_t speed, uint16_t *length);
+
+static uint8_t USBD_HID_DataIn (void *pdev, uint8_t epnum);
+/**
+ * @}
+ */
+
+/** @defgroup USBD_HID_Private_Variables
+ * @{
+ */
+
+USBD_Class_cb_TypeDef USBD_HID_cb =
+{
+ USBD_HID_Init,
+ USBD_HID_DeInit,
+ USBD_HID_Setup,
+ NULL, /*EP0_TxSent*/
+ NULL, /*EP0_RxReady*/
+ USBD_HID_DataIn, /*DataIn*/
+ NULL, /*DataOut*/
+ NULL, /*SOF */
+ NULL,
+ NULL,
+ USBD_HID_GetCfgDesc,
+#ifdef USB_OTG_HS_CORE
+ USBD_HID_GetCfgDesc, /* use same config as per FS */
+#endif
+};
+
+#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 static uint32_t USBD_HID_AltSet __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 static uint32_t USBD_HID_Protocol __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 static uint32_t USBD_HID_IdleState __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 */
+/* USB HID device Configuration Descriptor */
+__ALIGN_BEGIN static uint8_t USBD_HID_CfgDesc[USB_HID_CONFIG_DESC_SIZ] __ALIGN_END =
+{
+ 0x09, /* bLength: Configuration Descriptor size */
+ USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType: Configuration */
+ USB_HID_CONFIG_DESC_SIZ,
+ /* wTotalLength: Bytes returned */
+ 0x00,
+ 0x01, /*bNumInterfaces: 1 interface*/
+ 0x01, /*bConfigurationValue: Configuration value*/
+ 0x00, /*iConfiguration: Index of string descriptor describing
+ the configuration*/
+ 0xE0, /*bmAttributes: bus powered and Support Remote Wake-up */
+ 0x32, /*MaxPower 100 mA: this current is used for detecting Vbus*/
+
+ /************** Descriptor of Joystick Mouse interface ****************/
+ /* 09 */
+ 0x09, /*bLength: Interface Descriptor size*/
+ USB_INTERFACE_DESCRIPTOR_TYPE,/*bDescriptorType: Interface descriptor type*/
+ 0x00, /*bInterfaceNumber: Number of Interface*/
+ 0x00, /*bAlternateSetting: Alternate setting*/
+ 0x01, /*bNumEndpoints*/
+ 0x03, /*bInterfaceClass: HID*/
+ 0x01, /*bInterfaceSubClass : 1=BOOT, 0=no boot*/
+ 0x02, /*nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse*/
+ 0, /*iInterface: Index of string descriptor*/
+ /******************** Descriptor of Joystick Mouse HID ********************/
+ /* 18 */
+ 0x09, /*bLength: HID Descriptor size*/
+ HID_DESCRIPTOR_TYPE, /*bDescriptorType: HID*/
+ 0x11, /*bcdHID: HID Class Spec release number*/
+ 0x01,
+ 0x00, /*bCountryCode: Hardware target country*/
+ 0x01, /*bNumDescriptors: Number of HID class descriptors to follow*/
+ 0x22, /*bDescriptorType*/
+ HID_MOUSE_REPORT_DESC_SIZE,/*wItemLength: Total length of Report descriptor*/
+ 0x00,
+ /******************** Descriptor of Mouse endpoint ********************/
+ /* 27 */
+ 0x07, /*bLength: Endpoint Descriptor size*/
+ USB_ENDPOINT_DESCRIPTOR_TYPE, /*bDescriptorType:*/
+
+ HID_IN_EP, /*bEndpointAddress: Endpoint Address (IN)*/
+ 0x03, /*bmAttributes: Interrupt endpoint*/
+ HID_IN_PACKET, /*wMaxPacketSize: 4 Byte max */
+ 0x00,
+ 0x0A, /*bInterval: Polling Interval (10 ms)*/
+ /* 34 */
+} ;
+
+#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
+ #if defined ( __ICCARM__ ) /*!< IAR Compiler */
+ #pragma data_alignment=4
+ #endif
+/* USB HID device Configuration Descriptor */
+__ALIGN_BEGIN static uint8_t USBD_HID_Desc[USB_HID_DESC_SIZ] __ALIGN_END=
+{
+ /* 18 */
+ 0x09, /*bLength: HID Descriptor size*/
+ HID_DESCRIPTOR_TYPE, /*bDescriptorType: HID*/
+ 0x11, /*bcdHID: HID Class Spec release number*/
+ 0x01,
+ 0x00, /*bCountryCode: Hardware target country*/
+ 0x01, /*bNumDescriptors: Number of HID class descriptors to follow*/
+ 0x22, /*bDescriptorType*/
+ HID_MOUSE_REPORT_DESC_SIZE,/*wItemLength: Total length of Report descriptor*/
+ 0x00,
+};
+#endif
+
+
+#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 static uint8_t HID_MOUSE_ReportDesc[HID_MOUSE_REPORT_DESC_SIZE] __ALIGN_END =
+{
+ 0x05, 0x01,
+ 0x09, 0x02,
+ 0xA1, 0x01,
+ 0x09, 0x01,
+
+ 0xA1, 0x00,
+ 0x05, 0x09,
+ 0x19, 0x01,
+ 0x29, 0x03,
+
+ 0x15, 0x00,
+ 0x25, 0x01,
+ 0x95, 0x03,
+ 0x75, 0x01,
+
+ 0x81, 0x02,
+ 0x95, 0x01,
+ 0x75, 0x05,
+ 0x81, 0x01,
+
+ 0x05, 0x01,
+ 0x09, 0x30,
+ 0x09, 0x31,
+ 0x09, 0x38,
+
+ 0x15, 0x81,
+ 0x25, 0x7F,
+ 0x75, 0x08,
+ 0x95, 0x03,
+
+ 0x81, 0x06,
+ 0xC0, 0x09,
+ 0x3c, 0x05,
+ 0xff, 0x09,
+
+ 0x01, 0x15,
+ 0x00, 0x25,
+ 0x01, 0x75,
+ 0x01, 0x95,
+
+ 0x02, 0xb1,
+ 0x22, 0x75,
+ 0x06, 0x95,
+ 0x01, 0xb1,
+
+ 0x01, 0xc0
+};
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_HID_Private_Functions
+ * @{
+ */
+
+/**
+ * @brief USBD_HID_Init
+ * Initialize the HID interface
+ * @param pdev: device instance
+ * @param cfgidx: Configuration index
+ * @retval status
+ */
+static uint8_t USBD_HID_Init (void *pdev,
+ uint8_t cfgidx)
+{
+
+ /* Open EP IN */
+ DCD_EP_Open(pdev,
+ HID_IN_EP,
+ HID_IN_PACKET,
+ USB_OTG_EP_INT);
+
+ /* Open EP OUT */
+ DCD_EP_Open(pdev,
+ HID_OUT_EP,
+ HID_OUT_PACKET,
+ USB_OTG_EP_INT);
+
+ return USBD_OK;
+}
+
+/**
+ * @brief USBD_HID_Init
+ * DeInitialize the HID layer
+ * @param pdev: device instance
+ * @param cfgidx: Configuration index
+ * @retval status
+ */
+static uint8_t USBD_HID_DeInit (void *pdev,
+ uint8_t cfgidx)
+{
+ /* Close HID EPs */
+ DCD_EP_Close (pdev , HID_IN_EP);
+ DCD_EP_Close (pdev , HID_OUT_EP);
+
+
+ return USBD_OK;
+}
+
+/**
+ * @brief USBD_HID_Setup
+ * Handle the HID specific requests
+ * @param pdev: instance
+ * @param req: usb requests
+ * @retval status
+ */
+static uint8_t USBD_HID_Setup (void *pdev,
+ USB_SETUP_REQ *req)
+{
+ uint16_t len = 0;
+ uint8_t *pbuf = NULL;
+
+ switch (req->bmRequest & USB_REQ_TYPE_MASK)
+ {
+ case USB_REQ_TYPE_CLASS :
+ switch (req->bRequest)
+ {
+
+
+ case HID_REQ_SET_PROTOCOL:
+ USBD_HID_Protocol = (uint8_t)(req->wValue);
+ break;
+
+ case HID_REQ_GET_PROTOCOL:
+ USBD_CtlSendData (pdev,
+ (uint8_t *)&USBD_HID_Protocol,
+ 1);
+ break;
+
+ case HID_REQ_SET_IDLE:
+ USBD_HID_IdleState = (uint8_t)(req->wValue >> 8);
+ break;
+
+ case HID_REQ_GET_IDLE:
+ USBD_CtlSendData (pdev,
+ (uint8_t *)&USBD_HID_IdleState,
+ 1);
+ break;
+
+ default:
+ USBD_CtlError (pdev, req);
+ return USBD_FAIL;
+ }
+ break;
+
+ case USB_REQ_TYPE_STANDARD:
+ switch (req->bRequest)
+ {
+ case USB_REQ_GET_DESCRIPTOR:
+ if( req->wValue >> 8 == HID_REPORT_DESC)
+ {
+ len = MIN(HID_MOUSE_REPORT_DESC_SIZE , req->wLength);
+ pbuf = HID_MOUSE_ReportDesc;
+ }
+ else if( req->wValue >> 8 == HID_DESCRIPTOR_TYPE)
+ {
+
+#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
+ pbuf = USBD_HID_Desc;
+#else
+ pbuf = USBD_HID_CfgDesc + 0x12;
+#endif
+ len = MIN(USB_HID_DESC_SIZ , req->wLength);
+ }
+
+ USBD_CtlSendData (pdev,
+ pbuf,
+ len);
+
+ break;
+
+ case USB_REQ_GET_INTERFACE :
+ USBD_CtlSendData (pdev,
+ (uint8_t *)&USBD_HID_AltSet,
+ 1);
+ break;
+
+ case USB_REQ_SET_INTERFACE :
+ USBD_HID_AltSet = (uint8_t)(req->wValue);
+ break;
+ }
+ }
+ return USBD_OK;
+}
+
+/**
+ * @brief USBD_HID_SendReport
+ * Send HID Report
+ * @param pdev: device instance
+ * @param buff: pointer to report
+ * @retval status
+ */
+uint8_t USBD_HID_SendReport (USB_OTG_CORE_HANDLE *pdev,
+ uint8_t *report,
+ uint16_t len)
+{
+ if (pdev->dev.device_status == USB_OTG_CONFIGURED )
+ {
+ DCD_EP_Tx (pdev, HID_IN_EP, report, len);
+ }
+ return USBD_OK;
+}
+
+/**
+ * @brief USBD_HID_GetCfgDesc
+ * return configuration descriptor
+ * @param speed : current device speed
+ * @param length : pointer data length
+ * @retval pointer to descriptor buffer
+ */
+static uint8_t *USBD_HID_GetCfgDesc (uint8_t speed, uint16_t *length)
+{
+ *length = sizeof (USBD_HID_CfgDesc);
+ return USBD_HID_CfgDesc;
+}
+
+/**
+ * @brief USBD_HID_DataIn
+ * handle data IN Stage
+ * @param pdev: device instance
+ * @param epnum: endpoint index
+ * @retval status
+ */
+static uint8_t USBD_HID_DataIn (void *pdev,
+ uint8_t epnum)
+{
+
+ /* Ensure that the FIFO is empty before a new transfer, this condition could
+ be caused by a new transfer before the end of the previous transfer */
+ DCD_EP_Flush(pdev, HID_IN_EP);
+ return USBD_OK;
+}
+
+/**
+ * @}
+ */
+
+
+/**
+ * @}
+ */
+
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/msc/inc/usbd_msc_bot.h b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/msc/inc/usbd_msc_bot.h
new file mode 100644
index 0000000..fe85b51
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/msc/inc/usbd_msc_bot.h
@@ -0,0 +1,153 @@
+/**
+ ******************************************************************************
+ * @file usbd_msc_bot.h
+ * @author MCD Application Team
+ * @version V1.1.0
+ * @date 19-March-2012
+ * @brief header for the usbd_msc_bot.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 -------------------------------------*/
+
+#include "usbd_core.h"
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USBD_MSC_BOT_H
+#define __USBD_MSC_BOT_H
+
+/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
+ * @{
+ */
+
+/** @defgroup MSC_BOT
+ * @brief This file is the Header file for usbd_bot.c
+ * @{
+ */
+
+
+/** @defgroup USBD_CORE_Exported_Defines
+ * @{
+ */
+#define BOT_IDLE 0 /* Idle state */
+#define BOT_DATA_OUT 1 /* Data Out state */
+#define BOT_DATA_IN 2 /* Data In state */
+#define BOT_LAST_DATA_IN 3 /* Last Data In Last */
+#define BOT_SEND_DATA 4 /* Send Immediate data */
+
+#define BOT_CBW_SIGNATURE 0x43425355
+#define BOT_CSW_SIGNATURE 0x53425355
+#define BOT_CBW_LENGTH 31
+#define BOT_CSW_LENGTH 13
+
+/* CSW Status Definitions */
+#define CSW_CMD_PASSED 0x00
+#define CSW_CMD_FAILED 0x01
+#define CSW_PHASE_ERROR 0x02
+
+/* BOT Status */
+#define BOT_STATE_NORMAL 0
+#define BOT_STATE_RECOVERY 1
+#define BOT_STATE_ERROR 2
+
+
+#define DIR_IN 0
+#define DIR_OUT 1
+#define BOTH_DIR 2
+
+/**
+ * @}
+ */
+
+/** @defgroup MSC_CORE_Private_TypesDefinitions
+ * @{
+ */
+
+typedef struct _MSC_BOT_CBW
+{
+ uint32_t dSignature;
+ uint32_t dTag;
+ uint32_t dDataLength;
+ uint8_t bmFlags;
+ uint8_t bLUN;
+ uint8_t bCBLength;
+ uint8_t CB[16];
+}
+MSC_BOT_CBW_TypeDef;
+
+
+typedef struct _MSC_BOT_CSW
+{
+ uint32_t dSignature;
+ uint32_t dTag;
+ uint32_t dDataResidue;
+ uint8_t bStatus;
+}
+MSC_BOT_CSW_TypeDef;
+
+/**
+ * @}
+ */
+
+
+/** @defgroup USBD_CORE_Exported_Types
+ * @{
+ */
+
+extern uint8_t MSC_BOT_Data[];
+extern uint16_t MSC_BOT_DataLen;
+extern uint8_t MSC_BOT_State;
+extern uint8_t MSC_BOT_BurstMode;
+extern MSC_BOT_CBW_TypeDef MSC_BOT_cbw;
+extern MSC_BOT_CSW_TypeDef MSC_BOT_csw;
+/**
+ * @}
+ */
+/** @defgroup USBD_CORE_Exported_FunctionsPrototypes
+ * @{
+ */
+void MSC_BOT_Init (USB_OTG_CORE_HANDLE *pdev);
+void MSC_BOT_Reset (USB_OTG_CORE_HANDLE *pdev);
+void MSC_BOT_DeInit (USB_OTG_CORE_HANDLE *pdev);
+void MSC_BOT_DataIn (USB_OTG_CORE_HANDLE *pdev,
+ uint8_t epnum);
+
+void MSC_BOT_DataOut (USB_OTG_CORE_HANDLE *pdev,
+ uint8_t epnum);
+
+void MSC_BOT_SendCSW (USB_OTG_CORE_HANDLE *pdev,
+ uint8_t CSW_Status);
+
+void MSC_BOT_CplClrFeature (USB_OTG_CORE_HANDLE *pdev,
+ uint8_t epnum);
+/**
+ * @}
+ */
+
+#endif /* __USBD_MSC_BOT_H */
+/**
+ * @}
+ */
+
+/**
+* @}
+*/
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/msc/inc/usbd_msc_core.h b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/msc/inc/usbd_msc_core.h
new file mode 100644
index 0000000..5662465
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/msc/inc/usbd_msc_core.h
@@ -0,0 +1,77 @@
+/**
+ ******************************************************************************
+ * @file usbd_msc_core.h
+ * @author MCD Application Team
+ * @version V1.1.0
+ * @date 19-March-2012
+ * @brief header for the usbd_msc_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.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef _USB_MSC_CORE_H_
+#define _USB_MSC_CORE_H_
+
+#include "usbd_ioreq.h"
+
+/** @addtogroup USBD_MSC_BOT
+ * @{
+ */
+
+/** @defgroup USBD_MSC
+ * @brief This file is the Header file for USBD_msc.c
+ * @{
+ */
+
+
+/** @defgroup USBD_BOT_Exported_Defines
+ * @{
+ */
+
+
+#define BOT_GET_MAX_LUN 0xFE
+#define BOT_RESET 0xFF
+#define USB_MSC_CONFIG_DESC_SIZ 32
+
+#define MSC_EPIN_SIZE MSC_MAX_PACKET
+#define MSC_EPOUT_SIZE MSC_MAX_PACKET
+
+/**
+ * @}
+ */
+
+/** @defgroup USB_CORE_Exported_Types
+ * @{
+ */
+
+extern USBD_Class_cb_TypeDef USBD_MSC_cb;
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+#endif // _USB_MSC_CORE_H_
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/msc/inc/usbd_msc_data.h b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/msc/inc/usbd_msc_data.h
new file mode 100644
index 0000000..3fb2118
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/msc/inc/usbd_msc_data.h
@@ -0,0 +1,104 @@
+/**
+ ******************************************************************************
+ * @file usbd_msc_data.h
+ * @author MCD Application Team
+ * @version V1.1.0
+ * @date 19-March-2012
+ * @brief header for the usbd_msc_data.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_MSC_DATA_H_
+#define _USBD_MSC_DATA_H_
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_conf.h"
+
+/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
+ * @{
+ */
+
+/** @defgroup USB_INFO
+ * @brief general defines for the usb device library file
+ * @{
+ */
+
+/** @defgroup USB_INFO_Exported_Defines
+ * @{
+ */
+#define MODE_SENSE6_LEN 8
+#define MODE_SENSE10_LEN 8
+#define LENGTH_INQUIRY_PAGE00 7
+#define LENGTH_FORMAT_CAPACITIES 20
+
+/**
+ * @}
+ */
+
+
+/** @defgroup USBD_INFO_Exported_TypesDefinitions
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+
+/** @defgroup USBD_INFO_Exported_Macros
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_INFO_Exported_Variables
+ * @{
+ */
+extern const uint8_t MSC_Page00_Inquiry_Data[];
+extern const uint8_t MSC_Mode_Sense6_data[];
+extern const uint8_t MSC_Mode_Sense10_data[] ;
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_INFO_Exported_FunctionsPrototype
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+#endif /* _USBD_MSC_DATA_H_ */
+
+/**
+ * @}
+ */
+
+/**
+* @}
+*/
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/msc/inc/usbd_msc_mem.h b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/msc/inc/usbd_msc_mem.h
new file mode 100644
index 0000000..6b1378f
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/msc/inc/usbd_msc_mem.h
@@ -0,0 +1,112 @@
+/**
+ ******************************************************************************
+ * @file usbd_msc_mem.h
+ * @author MCD Application Team
+ * @version V1.1.0
+ * @date 19-March-2012
+ * @brief header for the STORAGE DISK file 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_MEM_H
+#define __USBD_MEM_H
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_def.h"
+
+
+/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
+ * @{
+ */
+
+/** @defgroup USBD_MEM
+ * @brief header file for the storage disk file
+ * @{
+ */
+
+/** @defgroup USBD_MEM_Exported_Defines
+ * @{
+ */
+#define USBD_STD_INQUIRY_LENGTH 36
+/**
+ * @}
+ */
+
+
+/** @defgroup USBD_MEM_Exported_TypesDefinitions
+ * @{
+ */
+
+typedef struct _USBD_STORAGE
+{
+ int8_t (* Init) (uint8_t lun);
+ int8_t (* GetCapacity) (uint8_t lun, uint32_t *block_num, uint32_t *block_size);
+ int8_t (* IsReady) (uint8_t lun);
+ int8_t (* IsWriteProtected) (uint8_t lun);
+ int8_t (* Read) (uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len);
+ int8_t (* Write)(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len);
+ int8_t (* GetMaxLun)(void);
+ int8_t *pInquiry;
+
+}USBD_STORAGE_cb_TypeDef;
+/**
+ * @}
+ */
+
+
+
+/** @defgroup USBD_MEM_Exported_Macros
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_MEM_Exported_Variables
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_MEM_Exported_FunctionsPrototype
+ * @{
+ */
+extern USBD_STORAGE_cb_TypeDef *USBD_STORAGE_fops;
+/**
+ * @}
+ */
+
+#endif /* __USBD_MEM_H */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+* @}
+*/
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/msc/inc/usbd_msc_scsi.h b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/msc/inc/usbd_msc_scsi.h
new file mode 100644
index 0000000..71b8250
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/msc/inc/usbd_msc_scsi.h
@@ -0,0 +1,195 @@
+/**
+ ******************************************************************************
+ * @file usbd_msc_scsi.h
+ * @author MCD Application Team
+ * @version V1.1.0
+ * @date 19-March-2012
+ * @brief header for the usbd_msc_scsi.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_MSC_SCSI_H
+#define __USBD_MSC_SCSI_H
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_def.h"
+
+/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
+ * @{
+ */
+
+/** @defgroup USBD_SCSI
+ * @brief header file for the storage disk file
+ * @{
+ */
+
+/** @defgroup USBD_SCSI_Exported_Defines
+ * @{
+ */
+
+#define SENSE_LIST_DEEPTH 4
+
+/* SCSI Commands */
+#define SCSI_FORMAT_UNIT 0x04
+#define SCSI_INQUIRY 0x12
+#define SCSI_MODE_SELECT6 0x15
+#define SCSI_MODE_SELECT10 0x55
+#define SCSI_MODE_SENSE6 0x1A
+#define SCSI_MODE_SENSE10 0x5A
+#define SCSI_ALLOW_MEDIUM_REMOVAL 0x1E
+#define SCSI_READ6 0x08
+#define SCSI_READ10 0x28
+#define SCSI_READ12 0xA8
+#define SCSI_READ16 0x88
+
+#define SCSI_READ_CAPACITY10 0x25
+#define SCSI_READ_CAPACITY16 0x9E
+
+#define SCSI_REQUEST_SENSE 0x03
+#define SCSI_START_STOP_UNIT 0x1B
+#define SCSI_TEST_UNIT_READY 0x00
+#define SCSI_WRITE6 0x0A
+#define SCSI_WRITE10 0x2A
+#define SCSI_WRITE12 0xAA
+#define SCSI_WRITE16 0x8A
+
+#define SCSI_VERIFY10 0x2F
+#define SCSI_VERIFY12 0xAF
+#define SCSI_VERIFY16 0x8F
+
+#define SCSI_SEND_DIAGNOSTIC 0x1D
+#define SCSI_READ_FORMAT_CAPACITIES 0x23
+
+#define NO_SENSE 0
+#define RECOVERED_ERROR 1
+#define NOT_READY 2
+#define MEDIUM_ERROR 3
+#define HARDWARE_ERROR 4
+#define ILLEGAL_REQUEST 5
+#define UNIT_ATTENTION 6
+#define DATA_PROTECT 7
+#define BLANK_CHECK 8
+#define VENDOR_SPECIFIC 9
+#define COPY_ABORTED 10
+#define ABORTED_COMMAND 11
+#define VOLUME_OVERFLOW 13
+#define MISCOMPARE 14
+
+
+#define INVALID_CDB 0x20
+#define INVALID_FIELED_IN_COMMAND 0x24
+#define PARAMETER_LIST_LENGTH_ERROR 0x1A
+#define INVALID_FIELD_IN_PARAMETER_LIST 0x26
+#define ADDRESS_OUT_OF_RANGE 0x21
+#define MEDIUM_NOT_PRESENT 0x3A
+#define MEDIUM_HAVE_CHANGED 0x28
+#define WRITE_PROTECTED 0x27
+#define UNRECOVERED_READ_ERROR 0x11
+#define WRITE_FAULT 0x03
+
+#define READ_FORMAT_CAPACITY_DATA_LEN 0x0C
+#define READ_CAPACITY10_DATA_LEN 0x08
+#define MODE_SENSE10_DATA_LEN 0x08
+#define MODE_SENSE6_DATA_LEN 0x04
+#define REQUEST_SENSE_DATA_LEN 0x12
+#define STANDARD_INQUIRY_DATA_LEN 0x24
+#define BLKVFY 0x04
+
+extern uint8_t Page00_Inquiry_Data[];
+extern uint8_t Standard_Inquiry_Data[];
+extern uint8_t Standard_Inquiry_Data2[];
+extern uint8_t Mode_Sense6_data[];
+extern uint8_t Mode_Sense10_data[];
+extern uint8_t Scsi_Sense_Data[];
+extern uint8_t ReadCapacity10_Data[];
+extern uint8_t ReadFormatCapacity_Data [];
+/**
+ * @}
+ */
+
+
+/** @defgroup USBD_SCSI_Exported_TypesDefinitions
+ * @{
+ */
+
+typedef struct _SENSE_ITEM {
+ char Skey;
+ union {
+ struct _ASCs {
+ char ASC;
+ char ASCQ;
+ }b;
+ unsigned int ASC;
+ char *pData;
+ } w;
+} SCSI_Sense_TypeDef;
+/**
+ * @}
+ */
+
+/** @defgroup USBD_SCSI_Exported_Macros
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_SCSI_Exported_Variables
+ * @{
+ */
+extern SCSI_Sense_TypeDef SCSI_Sense [SENSE_LIST_DEEPTH];
+extern uint8_t SCSI_Sense_Head;
+extern uint8_t SCSI_Sense_Tail;
+
+/**
+ * @}
+ */
+/** @defgroup USBD_SCSI_Exported_FunctionsPrototype
+ * @{
+ */
+int8_t SCSI_ProcessCmd(USB_OTG_CORE_HANDLE *pdev,
+ uint8_t lun,
+ uint8_t *cmd);
+
+void SCSI_SenseCode(uint8_t lun,
+ uint8_t sKey,
+ uint8_t ASC);
+
+/**
+ * @}
+ */
+
+#endif /* __USBD_MSC_SCSI_H */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+* @}
+*/
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/msc/src/usbd_msc_bot.c b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/msc/src/usbd_msc_bot.c
new file mode 100644
index 0000000..227aa6e
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/msc/src/usbd_msc_bot.c
@@ -0,0 +1,400 @@
+/**
+ ******************************************************************************
+ * @file usbd_msc_bot.c
+ * @author MCD Application Team
+ * @version V1.1.0
+ * @date 19-March-2012
+ * @brief This file provides all the BOT protocol 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_msc_bot.h"
+#include "usbd_msc_scsi.h"
+#include "usbd_ioreq.h"
+#include "usbd_msc_mem.h"
+
+/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
+ * @{
+ */
+
+
+/** @defgroup MSC_BOT
+ * @brief BOT protocol module
+ * @{
+ */
+
+/** @defgroup MSC_BOT_Private_TypesDefinitions
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup MSC_BOT_Private_Defines
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+
+/** @defgroup MSC_BOT_Private_Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup MSC_BOT_Private_Variables
+ * @{
+ */
+uint16_t MSC_BOT_DataLen;
+uint8_t MSC_BOT_State;
+uint8_t MSC_BOT_Status;
+
+#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 MSC_BOT_Data[MSC_MEDIA_PACKET] __ALIGN_END ;
+
+#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 MSC_BOT_CBW_TypeDef MSC_BOT_cbw __ALIGN_END ;
+
+#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 MSC_BOT_CSW_TypeDef MSC_BOT_csw __ALIGN_END ;
+/**
+ * @}
+ */
+
+
+/** @defgroup MSC_BOT_Private_FunctionPrototypes
+ * @{
+ */
+static void MSC_BOT_CBW_Decode (USB_OTG_CORE_HANDLE *pdev);
+
+static void MSC_BOT_SendData (USB_OTG_CORE_HANDLE *pdev,
+ uint8_t* pbuf,
+ uint16_t len);
+
+static void MSC_BOT_Abort(USB_OTG_CORE_HANDLE *pdev);
+/**
+ * @}
+ */
+
+
+/** @defgroup MSC_BOT_Private_Functions
+ * @{
+ */
+
+
+
+/**
+* @brief MSC_BOT_Init
+* Initialize the BOT Process
+* @param pdev: device instance
+* @retval None
+*/
+void MSC_BOT_Init (USB_OTG_CORE_HANDLE *pdev)
+{
+ MSC_BOT_State = BOT_IDLE;
+ MSC_BOT_Status = BOT_STATE_NORMAL;
+ USBD_STORAGE_fops->Init(0);
+
+ DCD_EP_Flush(pdev, MSC_OUT_EP);
+ DCD_EP_Flush(pdev, MSC_IN_EP);
+ /* Prapare EP to Receive First BOT Cmd */
+ DCD_EP_PrepareRx (pdev,
+ MSC_OUT_EP,
+ (uint8_t *)&MSC_BOT_cbw,
+ BOT_CBW_LENGTH);
+}
+
+/**
+* @brief MSC_BOT_Reset
+* Reset the BOT Machine
+* @param pdev: device instance
+* @retval None
+*/
+void MSC_BOT_Reset (USB_OTG_CORE_HANDLE *pdev)
+{
+ MSC_BOT_State = BOT_IDLE;
+ MSC_BOT_Status = BOT_STATE_RECOVERY;
+ /* Prapare EP to Receive First BOT Cmd */
+ DCD_EP_PrepareRx (pdev,
+ MSC_OUT_EP,
+ (uint8_t *)&MSC_BOT_cbw,
+ BOT_CBW_LENGTH);
+}
+
+/**
+* @brief MSC_BOT_DeInit
+* Uninitialize the BOT Machine
+* @param pdev: device instance
+* @retval None
+*/
+void MSC_BOT_DeInit (USB_OTG_CORE_HANDLE *pdev)
+{
+ MSC_BOT_State = BOT_IDLE;
+}
+
+/**
+* @brief MSC_BOT_DataIn
+* Handle BOT IN data stage
+* @param pdev: device instance
+* @param epnum: endpoint index
+* @retval None
+*/
+void MSC_BOT_DataIn (USB_OTG_CORE_HANDLE *pdev,
+ uint8_t epnum)
+{
+
+ switch (MSC_BOT_State)
+ {
+ case BOT_DATA_IN:
+ if(SCSI_ProcessCmd(pdev,
+ MSC_BOT_cbw.bLUN,
+ &MSC_BOT_cbw.CB[0]) < 0)
+ {
+ MSC_BOT_SendCSW (pdev, CSW_CMD_FAILED);
+ }
+ break;
+
+ case BOT_SEND_DATA:
+ case BOT_LAST_DATA_IN:
+ MSC_BOT_SendCSW (pdev, CSW_CMD_PASSED);
+
+ break;
+
+ default:
+ break;
+ }
+}
+/**
+* @brief MSC_BOT_DataOut
+* Proccess MSC OUT data
+* @param pdev: device instance
+* @param epnum: endpoint index
+* @retval None
+*/
+void MSC_BOT_DataOut (USB_OTG_CORE_HANDLE *pdev,
+ uint8_t epnum)
+{
+ switch (MSC_BOT_State)
+ {
+ case BOT_IDLE:
+ MSC_BOT_CBW_Decode(pdev);
+ break;
+
+ case BOT_DATA_OUT:
+
+ if(SCSI_ProcessCmd(pdev,
+ MSC_BOT_cbw.bLUN,
+ &MSC_BOT_cbw.CB[0]) < 0)
+ {
+ MSC_BOT_SendCSW (pdev, CSW_CMD_FAILED);
+ }
+
+ break;
+
+ default:
+ break;
+ }
+
+}
+
+/**
+* @brief MSC_BOT_CBW_Decode
+* Decode the CBW command and set the BOT state machine accordingtly
+* @param pdev: device instance
+* @retval None
+*/
+static void MSC_BOT_CBW_Decode (USB_OTG_CORE_HANDLE *pdev)
+{
+
+ MSC_BOT_csw.dTag = MSC_BOT_cbw.dTag;
+ MSC_BOT_csw.dDataResidue = MSC_BOT_cbw.dDataLength;
+
+ if ((USBD_GetRxCount (pdev ,MSC_OUT_EP) != BOT_CBW_LENGTH) ||
+ (MSC_BOT_cbw.dSignature != BOT_CBW_SIGNATURE)||
+ (MSC_BOT_cbw.bLUN > 1) ||
+ (MSC_BOT_cbw.bCBLength < 1) ||
+ (MSC_BOT_cbw.bCBLength > 16))
+ {
+
+ SCSI_SenseCode(MSC_BOT_cbw.bLUN,
+ ILLEGAL_REQUEST,
+ INVALID_CDB);
+ MSC_BOT_Status = BOT_STATE_ERROR;
+ MSC_BOT_Abort(pdev);
+
+ }
+ else
+ {
+ if(SCSI_ProcessCmd(pdev,
+ MSC_BOT_cbw.bLUN,
+ &MSC_BOT_cbw.CB[0]) < 0)
+ {
+ MSC_BOT_Abort(pdev);
+ }
+ /*Burst xfer handled internally*/
+ else if ((MSC_BOT_State != BOT_DATA_IN) &&
+ (MSC_BOT_State != BOT_DATA_OUT) &&
+ (MSC_BOT_State != BOT_LAST_DATA_IN))
+ {
+ if (MSC_BOT_DataLen > 0)
+ {
+ MSC_BOT_SendData(pdev,
+ MSC_BOT_Data,
+ MSC_BOT_DataLen);
+ }
+ else if (MSC_BOT_DataLen == 0)
+ {
+ MSC_BOT_SendCSW (pdev,
+ CSW_CMD_PASSED);
+ }
+ }
+ }
+}
+
+/**
+* @brief MSC_BOT_SendData
+* Send the requested data
+* @param pdev: device instance
+* @param buf: pointer to data buffer
+* @param len: Data Length
+* @retval None
+*/
+static void MSC_BOT_SendData(USB_OTG_CORE_HANDLE *pdev,
+ uint8_t* buf,
+ uint16_t len)
+{
+
+ len = MIN (MSC_BOT_cbw.dDataLength, len);
+ MSC_BOT_csw.dDataResidue -= len;
+ MSC_BOT_csw.bStatus = CSW_CMD_PASSED;
+ MSC_BOT_State = BOT_SEND_DATA;
+
+ DCD_EP_Tx (pdev, MSC_IN_EP, buf, len);
+}
+
+/**
+* @brief MSC_BOT_SendCSW
+* Send the Command Status Wrapper
+* @param pdev: device instance
+* @param status : CSW status
+* @retval None
+*/
+void MSC_BOT_SendCSW (USB_OTG_CORE_HANDLE *pdev,
+ uint8_t CSW_Status)
+{
+ MSC_BOT_csw.dSignature = BOT_CSW_SIGNATURE;
+ MSC_BOT_csw.bStatus = CSW_Status;
+ MSC_BOT_State = BOT_IDLE;
+
+ DCD_EP_Tx (pdev,
+ MSC_IN_EP,
+ (uint8_t *)&MSC_BOT_csw,
+ BOT_CSW_LENGTH);
+
+ /* Prapare EP to Receive next Cmd */
+ DCD_EP_PrepareRx (pdev,
+ MSC_OUT_EP,
+ (uint8_t *)&MSC_BOT_cbw,
+ BOT_CBW_LENGTH);
+
+}
+
+/**
+* @brief MSC_BOT_Abort
+* Abort the current transfer
+* @param pdev: device instance
+* @retval status
+*/
+
+static void MSC_BOT_Abort (USB_OTG_CORE_HANDLE *pdev)
+{
+
+ if ((MSC_BOT_cbw.bmFlags == 0) &&
+ (MSC_BOT_cbw.dDataLength != 0) &&
+ (MSC_BOT_Status == BOT_STATE_NORMAL) )
+ {
+ DCD_EP_Stall(pdev, MSC_OUT_EP );
+ }
+ DCD_EP_Stall(pdev, MSC_IN_EP);
+
+ if(MSC_BOT_Status == BOT_STATE_ERROR)
+ {
+ DCD_EP_PrepareRx (pdev,
+ MSC_OUT_EP,
+ (uint8_t *)&MSC_BOT_cbw,
+ BOT_CBW_LENGTH);
+ }
+}
+
+/**
+* @brief MSC_BOT_CplClrFeature
+* Complete the clear feature request
+* @param pdev: device instance
+* @param epnum: endpoint index
+* @retval None
+*/
+
+void MSC_BOT_CplClrFeature (USB_OTG_CORE_HANDLE *pdev, uint8_t epnum)
+{
+ if(MSC_BOT_Status == BOT_STATE_ERROR )/* Bad CBW Signature */
+ {
+ DCD_EP_Stall(pdev, MSC_IN_EP);
+ MSC_BOT_Status = BOT_STATE_NORMAL;
+ }
+ else if(((epnum & 0x80) == 0x80) && ( MSC_BOT_Status != BOT_STATE_RECOVERY))
+ {
+ MSC_BOT_SendCSW (pdev, CSW_CMD_FAILED);
+ }
+
+}
+/**
+ * @}
+ */
+
+
+/**
+ * @}
+ */
+
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/msc/src/usbd_msc_core.c b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/msc/src/usbd_msc_core.c
new file mode 100644
index 0000000..5d8d4e8
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/msc/src/usbd_msc_core.c
@@ -0,0 +1,496 @@
+/**
+ ******************************************************************************
+ * @file usbd_msc_core.c
+ * @author MCD Application Team
+ * @version V1.1.0
+ * @date 19-March-2012
+ * @brief This file provides all the MSC core functions.
+ *
+ * @verbatim
+ *
+ * ===================================================================
+ * MSC Class Description
+ * ===================================================================
+ * This module manages the MSC class V1.0 following the "Universal
+ * Serial Bus Mass Storage Class (MSC) Bulk-Only Transport (BOT) Version 1.0
+ * Sep. 31, 1999".
+ * This driver implements the following aspects of the specification:
+ * - Bulk-Only Transport protocol
+ * - Subclass : SCSI transparent command set (ref. SCSI Primary Commands - 3 (SPC-3))
+ *
+ * @endverbatim
+ *
+ ******************************************************************************
+ * @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_msc_mem.h"
+#include "usbd_msc_core.h"
+#include "usbd_msc_bot.h"
+#include "usbd_req.h"
+
+
+/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
+ * @{
+ */
+
+
+/** @defgroup MSC_CORE
+ * @brief Mass storage core module
+ * @{
+ */
+
+/** @defgroup MSC_CORE_Private_TypesDefinitions
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup MSC_CORE_Private_Defines
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+
+/** @defgroup MSC_CORE_Private_Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup MSC_CORE_Private_FunctionPrototypes
+ * @{
+ */
+uint8_t USBD_MSC_Init (void *pdev,
+ uint8_t cfgidx);
+
+uint8_t USBD_MSC_DeInit (void *pdev,
+ uint8_t cfgidx);
+
+uint8_t USBD_MSC_Setup (void *pdev,
+ USB_SETUP_REQ *req);
+
+uint8_t USBD_MSC_DataIn (void *pdev,
+ uint8_t epnum);
+
+
+uint8_t USBD_MSC_DataOut (void *pdev,
+ uint8_t epnum);
+
+uint8_t *USBD_MSC_GetCfgDesc (uint8_t speed,
+ uint16_t *length);
+
+#ifdef USB_OTG_HS_CORE
+uint8_t *USBD_MSC_GetOtherCfgDesc (uint8_t speed,
+ uint16_t *length);
+#endif
+
+
+uint8_t USBD_MSC_CfgDesc[USB_MSC_CONFIG_DESC_SIZ];
+
+
+
+
+/**
+ * @}
+ */
+
+
+/** @defgroup MSC_CORE_Private_Variables
+ * @{
+ */
+
+
+USBD_Class_cb_TypeDef USBD_MSC_cb =
+{
+ USBD_MSC_Init,
+ USBD_MSC_DeInit,
+ USBD_MSC_Setup,
+ NULL, /*EP0_TxSent*/
+ NULL, /*EP0_RxReady*/
+ USBD_MSC_DataIn,
+ USBD_MSC_DataOut,
+ NULL, /*SOF */
+ NULL,
+ NULL,
+ USBD_MSC_GetCfgDesc,
+#ifdef USB_OTG_HS_CORE
+ USBD_MSC_GetOtherCfgDesc,
+#endif
+};
+
+#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
+ #if defined ( __ICCARM__ ) /*!< IAR Compiler */
+ #pragma data_alignment=4
+ #endif
+#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
+/* USB Mass storage device Configuration Descriptor */
+/* All Descriptors (Configuration, Interface, Endpoint, Class, Vendor */
+__ALIGN_BEGIN uint8_t USBD_MSC_CfgDesc[USB_MSC_CONFIG_DESC_SIZ] __ALIGN_END =
+{
+
+ 0x09, /* bLength: Configuation Descriptor size */
+ USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
+ USB_MSC_CONFIG_DESC_SIZ,
+
+ 0x00,
+ 0x01, /* bNumInterfaces: 1 interface */
+ 0x01, /* bConfigurationValue: */
+ 0x04, /* iConfiguration: */
+ 0xC0, /* bmAttributes: */
+ 0x32, /* MaxPower 100 mA */
+
+ /******************** Mass Storage interface ********************/
+ 0x09, /* bLength: Interface Descriptor size */
+ 0x04, /* bDescriptorType: */
+ 0x00, /* bInterfaceNumber: Number of Interface */
+ 0x00, /* bAlternateSetting: Alternate setting */
+ 0x02, /* bNumEndpoints*/
+ 0x08, /* bInterfaceClass: MSC Class */
+ 0x06, /* bInterfaceSubClass : SCSI transparent*/
+ 0x50, /* nInterfaceProtocol */
+ 0x05, /* iInterface: */
+ /******************** Mass Storage Endpoints ********************/
+ 0x07, /*Endpoint descriptor length = 7*/
+ 0x05, /*Endpoint descriptor type */
+ MSC_IN_EP, /*Endpoint address (IN, address 1) */
+ 0x02, /*Bulk endpoint type */
+ LOBYTE(MSC_MAX_PACKET),
+ HIBYTE(MSC_MAX_PACKET),
+ 0x00, /*Polling interval in milliseconds */
+
+ 0x07, /*Endpoint descriptor length = 7 */
+ 0x05, /*Endpoint descriptor type */
+ MSC_OUT_EP, /*Endpoint address (OUT, address 1) */
+ 0x02, /*Bulk endpoint type */
+ LOBYTE(MSC_MAX_PACKET),
+ HIBYTE(MSC_MAX_PACKET),
+ 0x00 /*Polling interval in milliseconds*/
+};
+#ifdef USB_OTG_HS_CORE
+ #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_MSC_OtherCfgDesc[USB_MSC_CONFIG_DESC_SIZ] __ALIGN_END =
+{
+
+ 0x09, /* bLength: Configuation Descriptor size */
+ USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION,
+ USB_MSC_CONFIG_DESC_SIZ,
+
+ 0x00,
+ 0x01, /* bNumInterfaces: 1 interface */
+ 0x01, /* bConfigurationValue: */
+ 0x04, /* iConfiguration: */
+ 0xC0, /* bmAttributes: */
+ 0x32, /* MaxPower 100 mA */
+
+ /******************** Mass Storage interface ********************/
+ 0x09, /* bLength: Interface Descriptor size */
+ 0x04, /* bDescriptorType: */
+ 0x00, /* bInterfaceNumber: Number of Interface */
+ 0x00, /* bAlternateSetting: Alternate setting */
+ 0x02, /* bNumEndpoints*/
+ 0x08, /* bInterfaceClass: MSC Class */
+ 0x06, /* bInterfaceSubClass : SCSI transparent command set*/
+ 0x50, /* nInterfaceProtocol */
+ 0x05, /* iInterface: */
+ /******************** Mass Storage Endpoints ********************/
+ 0x07, /*Endpoint descriptor length = 7*/
+ 0x05, /*Endpoint descriptor type */
+ MSC_IN_EP, /*Endpoint address (IN, address 1) */
+ 0x02, /*Bulk endpoint type */
+ 0x40,
+ 0x00,
+ 0x00, /*Polling interval in milliseconds */
+
+ 0x07, /*Endpoint descriptor length = 7 */
+ 0x05, /*Endpoint descriptor type */
+ MSC_OUT_EP, /*Endpoint address (OUT, address 1) */
+ 0x02, /*Bulk endpoint type */
+ 0x40,
+ 0x00,
+ 0x00 /*Polling interval in milliseconds*/
+};
+#endif
+
+#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 static uint8_t USBD_MSC_MaxLun __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 static uint8_t USBD_MSC_AltSet __ALIGN_END = 0;
+
+/**
+ * @}
+ */
+
+
+/** @defgroup MSC_CORE_Private_Functions
+ * @{
+ */
+
+/**
+* @brief USBD_MSC_Init
+* Initialize the mass storage configuration
+* @param pdev: device instance
+* @param cfgidx: configuration index
+* @retval status
+*/
+uint8_t USBD_MSC_Init (void *pdev,
+ uint8_t cfgidx)
+{
+ USBD_MSC_DeInit(pdev , cfgidx );
+
+ /* Open EP IN */
+ DCD_EP_Open(pdev,
+ MSC_IN_EP,
+ MSC_EPIN_SIZE,
+ USB_OTG_EP_BULK);
+
+ /* Open EP OUT */
+ DCD_EP_Open(pdev,
+ MSC_OUT_EP,
+ MSC_EPOUT_SIZE,
+ USB_OTG_EP_BULK);
+
+ /* Init the BOT layer */
+ MSC_BOT_Init(pdev);
+
+ return USBD_OK;
+}
+
+/**
+* @brief USBD_MSC_DeInit
+* DeInitilaize the mass storage configuration
+* @param pdev: device instance
+* @param cfgidx: configuration index
+* @retval status
+*/
+uint8_t USBD_MSC_DeInit (void *pdev,
+ uint8_t cfgidx)
+{
+ /* Close MSC EPs */
+ DCD_EP_Close (pdev , MSC_IN_EP);
+ DCD_EP_Close (pdev , MSC_OUT_EP);
+
+ /* Un Init the BOT layer */
+ MSC_BOT_DeInit(pdev);
+ return USBD_OK;
+}
+/**
+* @brief USBD_MSC_Setup
+* Handle the MSC specific requests
+* @param pdev: device instance
+* @param req: USB request
+* @retval status
+*/
+uint8_t USBD_MSC_Setup (void *pdev, USB_SETUP_REQ *req)
+{
+
+ switch (req->bmRequest & USB_REQ_TYPE_MASK)
+ {
+
+ /* Class request */
+ case USB_REQ_TYPE_CLASS :
+ switch (req->bRequest)
+ {
+ case BOT_GET_MAX_LUN :
+
+ if((req->wValue == 0) &&
+ (req->wLength == 1) &&
+ ((req->bmRequest & 0x80) == 0x80))
+ {
+ USBD_MSC_MaxLun = USBD_STORAGE_fops->GetMaxLun();
+ if(USBD_MSC_MaxLun > 0)
+ {
+ USBD_CtlSendData (pdev,
+ &USBD_MSC_MaxLun,
+ 1);
+ }
+ else
+ {
+ USBD_CtlError(pdev , req);
+ return USBD_FAIL;
+
+ }
+ }
+ else
+ {
+ USBD_CtlError(pdev , req);
+ return USBD_FAIL;
+ }
+ break;
+
+ case BOT_RESET :
+ if((req->wValue == 0) &&
+ (req->wLength == 0) &&
+ ((req->bmRequest & 0x80) != 0x80))
+ {
+ MSC_BOT_Reset(pdev);
+ }
+ else
+ {
+ USBD_CtlError(pdev , req);
+ return USBD_FAIL;
+ }
+ break;
+
+ default:
+ USBD_CtlError(pdev , req);
+ return USBD_FAIL;
+ }
+ break;
+ /* Interface & Endpoint request */
+ case USB_REQ_TYPE_STANDARD:
+ switch (req->bRequest)
+ {
+ case USB_REQ_GET_INTERFACE :
+ USBD_CtlSendData (pdev,
+ &USBD_MSC_AltSet,
+ 1);
+ break;
+
+ case USB_REQ_SET_INTERFACE :
+ USBD_MSC_AltSet = (uint8_t)(req->wValue);
+ break;
+
+ case USB_REQ_CLEAR_FEATURE:
+
+ /* Flush the FIFO and Clear the stall status */
+ DCD_EP_Flush(pdev, (uint8_t)req->wIndex);
+
+ /* Re-activate the EP */
+ DCD_EP_Close (pdev , (uint8_t)req->wIndex);
+ if((((uint8_t)req->wIndex) & 0x80) == 0x80)
+ {
+ DCD_EP_Open(pdev,
+ ((uint8_t)req->wIndex),
+ MSC_EPIN_SIZE,
+ USB_OTG_EP_BULK);
+ }
+ else
+ {
+ DCD_EP_Open(pdev,
+ ((uint8_t)req->wIndex),
+ MSC_EPOUT_SIZE,
+ USB_OTG_EP_BULK);
+ }
+
+ /* Handle BOT error */
+ MSC_BOT_CplClrFeature(pdev, (uint8_t)req->wIndex);
+ break;
+
+ }
+ break;
+
+ default:
+ break;
+ }
+ return USBD_OK;
+}
+
+/**
+* @brief USBD_MSC_DataIn
+* handle data IN Stage
+* @param pdev: device instance
+* @param epnum: endpoint index
+* @retval status
+*/
+uint8_t USBD_MSC_DataIn (void *pdev,
+ uint8_t epnum)
+{
+ MSC_BOT_DataIn(pdev , epnum);
+ return USBD_OK;
+}
+
+/**
+* @brief USBD_MSC_DataOut
+* handle data OUT Stage
+* @param pdev: device instance
+* @param epnum: endpoint index
+* @retval status
+*/
+uint8_t USBD_MSC_DataOut (void *pdev,
+ uint8_t epnum)
+{
+ MSC_BOT_DataOut(pdev , epnum);
+ return USBD_OK;
+}
+
+/**
+* @brief USBD_MSC_GetCfgDesc
+* return configuration descriptor
+* @param speed : current device speed
+* @param length : pointer data length
+* @retval pointer to descriptor buffer
+*/
+uint8_t *USBD_MSC_GetCfgDesc (uint8_t speed, uint16_t *length)
+{
+ *length = sizeof (USBD_MSC_CfgDesc);
+ return USBD_MSC_CfgDesc;
+}
+
+/**
+* @brief USBD_MSC_GetOtherCfgDesc
+* return other speed configuration descriptor
+* @param speed : current device speed
+* @param length : pointer data length
+* @retval pointer to descriptor buffer
+*/
+#ifdef USB_OTG_HS_CORE
+uint8_t *USBD_MSC_GetOtherCfgDesc (uint8_t speed,
+ uint16_t *length)
+{
+ *length = sizeof (USBD_MSC_OtherCfgDesc);
+ return USBD_MSC_OtherCfgDesc;
+}
+#endif
+/**
+ * @}
+ */
+
+
+/**
+ * @}
+ */
+
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/msc/src/usbd_msc_data.c b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/msc/src/usbd_msc_data.c
new file mode 100644
index 0000000..d65f058
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/msc/src/usbd_msc_data.c
@@ -0,0 +1,134 @@
+/**
+ ******************************************************************************
+ * @file usbd_msc_data.c
+ * @author MCD Application Team
+ * @version V1.1.0
+ * @date 19-March-2012
+ * @brief This file provides all the vital inquiry pages and sense data.
+ ******************************************************************************
+ * @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_msc_data.h"
+
+
+/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
+ * @{
+ */
+
+
+/** @defgroup MSC_DATA
+ * @brief Mass storage info/data module
+ * @{
+ */
+
+/** @defgroup MSC_DATA_Private_TypesDefinitions
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup MSC_DATA_Private_Defines
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup MSC_DATA_Private_Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup MSC_DATA_Private_Variables
+ * @{
+ */
+
+
+/* USB Mass storage Page 0 Inquiry Data */
+const uint8_t MSC_Page00_Inquiry_Data[] = {//7
+ 0x00,
+ 0x00,
+ 0x00,
+ (LENGTH_INQUIRY_PAGE00 - 4),
+ 0x00,
+ 0x80,
+ 0x83
+};
+/* USB Mass storage sense 6 Data */
+const uint8_t MSC_Mode_Sense6_data[] = {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00
+};
+/* USB Mass storage sense 10 Data */
+const uint8_t MSC_Mode_Sense10_data[] = {
+ 0x00,
+ 0x06,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00
+};
+/**
+ * @}
+ */
+
+
+/** @defgroup MSC_DATA_Private_FunctionPrototypes
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup MSC_DATA_Private_Functions
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+
+/**
+ * @}
+ */
+
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/msc/src/usbd_msc_scsi.c b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/msc/src/usbd_msc_scsi.c
new file mode 100644
index 0000000..4d15d0c
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/msc/src/usbd_msc_scsi.c
@@ -0,0 +1,728 @@
+/**
+ ******************************************************************************
+ * @file usbd_msc_scsi.c
+ * @author MCD Application Team
+ * @version V1.1.0
+ * @date 19-March-2012
+ * @brief This file provides all the USBD SCSI layer 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_msc_bot.h"
+#include "usbd_msc_scsi.h"
+#include "usbd_msc_mem.h"
+#include "usbd_msc_data.h"
+
+
+
+/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
+ * @{
+ */
+
+
+/** @defgroup MSC_SCSI
+ * @brief Mass storage SCSI layer module
+ * @{
+ */
+
+/** @defgroup MSC_SCSI_Private_TypesDefinitions
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup MSC_SCSI_Private_Defines
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+
+/** @defgroup MSC_SCSI_Private_Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup MSC_SCSI_Private_Variables
+ * @{
+ */
+
+SCSI_Sense_TypeDef SCSI_Sense [SENSE_LIST_DEEPTH];
+uint8_t SCSI_Sense_Head;
+uint8_t SCSI_Sense_Tail;
+
+uint32_t SCSI_blk_size;
+uint32_t SCSI_blk_nbr;
+
+uint32_t SCSI_blk_addr;
+uint32_t SCSI_blk_len;
+
+USB_OTG_CORE_HANDLE *cdev;
+/**
+ * @}
+ */
+
+
+/** @defgroup MSC_SCSI_Private_FunctionPrototypes
+ * @{
+ */
+static int8_t SCSI_TestUnitReady(uint8_t lun, uint8_t *params);
+static int8_t SCSI_Inquiry(uint8_t lun, uint8_t *params);
+static int8_t SCSI_ReadFormatCapacity(uint8_t lun, uint8_t *params);
+static int8_t SCSI_ReadCapacity10(uint8_t lun, uint8_t *params);
+static int8_t SCSI_RequestSense (uint8_t lun, uint8_t *params);
+static int8_t SCSI_StartStopUnit(uint8_t lun, uint8_t *params);
+static int8_t SCSI_ModeSense6 (uint8_t lun, uint8_t *params);
+static int8_t SCSI_ModeSense10 (uint8_t lun, uint8_t *params);
+static int8_t SCSI_Write10(uint8_t lun , uint8_t *params);
+static int8_t SCSI_Read10(uint8_t lun , uint8_t *params);
+static int8_t SCSI_Verify10(uint8_t lun, uint8_t *params);
+static int8_t SCSI_CheckAddressRange (uint8_t lun ,
+ uint32_t blk_offset ,
+ uint16_t blk_nbr);
+static int8_t SCSI_ProcessRead (uint8_t lun);
+
+static int8_t SCSI_ProcessWrite (uint8_t lun);
+/**
+ * @}
+ */
+
+
+/** @defgroup MSC_SCSI_Private_Functions
+ * @{
+ */
+
+
+/**
+* @brief SCSI_ProcessCmd
+* Process SCSI commands
+* @param pdev: device instance
+* @param lun: Logical unit number
+* @param params: Command parameters
+* @retval status
+*/
+int8_t SCSI_ProcessCmd(USB_OTG_CORE_HANDLE *pdev,
+ uint8_t lun,
+ uint8_t *params)
+{
+ cdev = pdev;
+
+ switch (params[0])
+ {
+ case SCSI_TEST_UNIT_READY:
+ return SCSI_TestUnitReady(lun, params);
+
+ case SCSI_REQUEST_SENSE:
+ return SCSI_RequestSense (lun, params);
+ case SCSI_INQUIRY:
+ return SCSI_Inquiry(lun, params);
+
+ case SCSI_START_STOP_UNIT:
+ return SCSI_StartStopUnit(lun, params);
+
+ case SCSI_ALLOW_MEDIUM_REMOVAL:
+ return SCSI_StartStopUnit(lun, params);
+
+ case SCSI_MODE_SENSE6:
+ return SCSI_ModeSense6 (lun, params);
+
+ case SCSI_MODE_SENSE10:
+ return SCSI_ModeSense10 (lun, params);
+
+ case SCSI_READ_FORMAT_CAPACITIES:
+ return SCSI_ReadFormatCapacity(lun, params);
+
+ case SCSI_READ_CAPACITY10:
+ return SCSI_ReadCapacity10(lun, params);
+
+ case SCSI_READ10:
+ return SCSI_Read10(lun, params);
+
+ case SCSI_WRITE10:
+ return SCSI_Write10(lun, params);
+
+ case SCSI_VERIFY10:
+ return SCSI_Verify10(lun, params);
+
+ default:
+ SCSI_SenseCode(lun,
+ ILLEGAL_REQUEST,
+ INVALID_CDB);
+ return -1;
+ }
+}
+
+
+/**
+* @brief SCSI_TestUnitReady
+* Process SCSI Test Unit Ready Command
+* @param lun: Logical unit number
+* @param params: Command parameters
+* @retval status
+*/
+static int8_t SCSI_TestUnitReady(uint8_t lun, uint8_t *params)
+{
+
+ /* case 9 : Hi > D0 */
+ if (MSC_BOT_cbw.dDataLength != 0)
+ {
+ SCSI_SenseCode(MSC_BOT_cbw.bLUN,
+ ILLEGAL_REQUEST,
+ INVALID_CDB);
+ return -1;
+ }
+
+ if(USBD_STORAGE_fops->IsReady(lun) !=0 )
+ {
+ SCSI_SenseCode(lun,
+ NOT_READY,
+ MEDIUM_NOT_PRESENT);
+ return -1;
+ }
+ MSC_BOT_DataLen = 0;
+ return 0;
+}
+
+/**
+* @brief SCSI_Inquiry
+* Process Inquiry command
+* @param lun: Logical unit number
+* @param params: Command parameters
+* @retval status
+*/
+static int8_t SCSI_Inquiry(uint8_t lun, uint8_t *params)
+{
+ uint8_t* pPage;
+ uint16_t len;
+
+ if (params[1] & 0x01)/*Evpd is set*/
+ {
+ pPage = (uint8_t *)MSC_Page00_Inquiry_Data;
+ len = LENGTH_INQUIRY_PAGE00;
+ }
+ else
+ {
+
+ pPage = (uint8_t *)&USBD_STORAGE_fops->pInquiry[lun * USBD_STD_INQUIRY_LENGTH];
+ len = pPage[4] + 5;
+
+ if (params[4] <= len)
+ {
+ len = params[4];
+ }
+ }
+ MSC_BOT_DataLen = len;
+
+ while (len)
+ {
+ len--;
+ MSC_BOT_Data[len] = pPage[len];
+ }
+ return 0;
+}
+
+/**
+* @brief SCSI_ReadCapacity10
+* Process Read Capacity 10 command
+* @param lun: Logical unit number
+* @param params: Command parameters
+* @retval status
+*/
+static int8_t SCSI_ReadCapacity10(uint8_t lun, uint8_t *params)
+{
+
+ if(USBD_STORAGE_fops->GetCapacity(lun, &SCSI_blk_nbr, &SCSI_blk_size) != 0)
+ {
+ SCSI_SenseCode(lun,
+ NOT_READY,
+ MEDIUM_NOT_PRESENT);
+ return -1;
+ }
+ else
+ {
+
+ MSC_BOT_Data[0] = (uint8_t)(SCSI_blk_nbr - 1 >> 24);
+ MSC_BOT_Data[1] = (uint8_t)(SCSI_blk_nbr - 1 >> 16);
+ MSC_BOT_Data[2] = (uint8_t)(SCSI_blk_nbr - 1 >> 8);
+ MSC_BOT_Data[3] = (uint8_t)(SCSI_blk_nbr - 1);
+
+ MSC_BOT_Data[4] = (uint8_t)(SCSI_blk_size >> 24);
+ MSC_BOT_Data[5] = (uint8_t)(SCSI_blk_size >> 16);
+ MSC_BOT_Data[6] = (uint8_t)(SCSI_blk_size >> 8);
+ MSC_BOT_Data[7] = (uint8_t)(SCSI_blk_size);
+
+ MSC_BOT_DataLen = 8;
+ return 0;
+ }
+}
+/**
+* @brief SCSI_ReadFormatCapacity
+* Process Read Format Capacity command
+* @param lun: Logical unit number
+* @param params: Command parameters
+* @retval status
+*/
+static int8_t SCSI_ReadFormatCapacity(uint8_t lun, uint8_t *params)
+{
+
+ uint32_t blk_size;
+ uint32_t blk_nbr;
+ uint16_t i;
+
+ for(i=0 ; i < 12 ; i++)
+ {
+ MSC_BOT_Data[i] = 0;
+ }
+
+ if(USBD_STORAGE_fops->GetCapacity(lun, &blk_nbr, &blk_size) != 0)
+ {
+ SCSI_SenseCode(lun,
+ NOT_READY,
+ MEDIUM_NOT_PRESENT);
+ return -1;
+ }
+ else
+ {
+ MSC_BOT_Data[3] = 0x08;
+ MSC_BOT_Data[4] = (uint8_t)(blk_nbr - 1 >> 24);
+ MSC_BOT_Data[5] = (uint8_t)(blk_nbr - 1 >> 16);
+ MSC_BOT_Data[6] = (uint8_t)(blk_nbr - 1 >> 8);
+ MSC_BOT_Data[7] = (uint8_t)(blk_nbr - 1);
+
+ MSC_BOT_Data[8] = 0x02;
+ MSC_BOT_Data[9] = (uint8_t)(blk_size >> 16);
+ MSC_BOT_Data[10] = (uint8_t)(blk_size >> 8);
+ MSC_BOT_Data[11] = (uint8_t)(blk_size);
+
+ MSC_BOT_DataLen = 12;
+ return 0;
+ }
+}
+/**
+* @brief SCSI_ModeSense6
+* Process Mode Sense6 command
+* @param lun: Logical unit number
+* @param params: Command parameters
+* @retval status
+*/
+static int8_t SCSI_ModeSense6 (uint8_t lun, uint8_t *params)
+{
+
+ uint16_t len = 8 ;
+ MSC_BOT_DataLen = len;
+
+ while (len)
+ {
+ len--;
+ MSC_BOT_Data[len] = MSC_Mode_Sense6_data[len];
+ }
+ return 0;
+}
+
+/**
+* @brief SCSI_ModeSense10
+* Process Mode Sense10 command
+* @param lun: Logical unit number
+* @param params: Command parameters
+* @retval status
+*/
+static int8_t SCSI_ModeSense10 (uint8_t lun, uint8_t *params)
+{
+ uint16_t len = 8;
+
+ MSC_BOT_DataLen = len;
+
+ while (len)
+ {
+ len--;
+ MSC_BOT_Data[len] = MSC_Mode_Sense10_data[len];
+ }
+ return 0;
+}
+
+/**
+* @brief SCSI_RequestSense
+* Process Request Sense command
+* @param lun: Logical unit number
+* @param params: Command parameters
+* @retval status
+*/
+
+static int8_t SCSI_RequestSense (uint8_t lun, uint8_t *params)
+{
+ uint8_t i;
+
+ for(i=0 ; i < REQUEST_SENSE_DATA_LEN ; i++)
+ {
+ MSC_BOT_Data[i] = 0;
+ }
+
+ MSC_BOT_Data[0] = 0x70;
+ MSC_BOT_Data[7] = REQUEST_SENSE_DATA_LEN - 6;
+
+ if((SCSI_Sense_Head != SCSI_Sense_Tail)) {
+
+ MSC_BOT_Data[2] = SCSI_Sense[SCSI_Sense_Head].Skey;
+ MSC_BOT_Data[12] = SCSI_Sense[SCSI_Sense_Head].w.b.ASCQ;
+ MSC_BOT_Data[13] = SCSI_Sense[SCSI_Sense_Head].w.b.ASC;
+ SCSI_Sense_Head++;
+
+ if (SCSI_Sense_Head == SENSE_LIST_DEEPTH)
+ {
+ SCSI_Sense_Head = 0;
+ }
+ }
+ MSC_BOT_DataLen = REQUEST_SENSE_DATA_LEN;
+
+ if (params[4] <= REQUEST_SENSE_DATA_LEN)
+ {
+ MSC_BOT_DataLen = params[4];
+ }
+ return 0;
+}
+
+/**
+* @brief SCSI_SenseCode
+* Load the last error code in the error list
+* @param lun: Logical unit number
+* @param sKey: Sense Key
+* @param ASC: Additional Sense Key
+* @retval none
+
+*/
+void SCSI_SenseCode(uint8_t lun, uint8_t sKey, uint8_t ASC)
+{
+ SCSI_Sense[SCSI_Sense_Tail].Skey = sKey;
+ SCSI_Sense[SCSI_Sense_Tail].w.ASC = ASC << 8;
+ SCSI_Sense_Tail++;
+ if (SCSI_Sense_Tail == SENSE_LIST_DEEPTH)
+ {
+ SCSI_Sense_Tail = 0;
+ }
+}
+/**
+* @brief SCSI_StartStopUnit
+* Process Start Stop Unit command
+* @param lun: Logical unit number
+* @param params: Command parameters
+* @retval status
+*/
+static int8_t SCSI_StartStopUnit(uint8_t lun, uint8_t *params)
+{
+ MSC_BOT_DataLen = 0;
+ return 0;
+}
+
+/**
+* @brief SCSI_Read10
+* Process Read10 command
+* @param lun: Logical unit number
+* @param params: Command parameters
+* @retval status
+*/
+static int8_t SCSI_Read10(uint8_t lun , uint8_t *params)
+{
+ if(MSC_BOT_State == BOT_IDLE) /* Idle */
+ {
+
+ /* case 10 : Ho <> Di */
+
+ if ((MSC_BOT_cbw.bmFlags & 0x80) != 0x80)
+ {
+ SCSI_SenseCode(MSC_BOT_cbw.bLUN,
+ ILLEGAL_REQUEST,
+ INVALID_CDB);
+ return -1;
+ }
+
+ if(USBD_STORAGE_fops->IsReady(lun) !=0 )
+ {
+ SCSI_SenseCode(lun,
+ NOT_READY,
+ MEDIUM_NOT_PRESENT);
+ return -1;
+ }
+
+ SCSI_blk_addr = (params[2] << 24) | \
+ (params[3] << 16) | \
+ (params[4] << 8) | \
+ params[5];
+
+ SCSI_blk_len = (params[7] << 8) | \
+ params[8];
+
+
+
+ if( SCSI_CheckAddressRange(lun, SCSI_blk_addr, SCSI_blk_len) < 0)
+ {
+ return -1; /* error */
+ }
+
+ MSC_BOT_State = BOT_DATA_IN;
+ SCSI_blk_addr *= SCSI_blk_size;
+ SCSI_blk_len *= SCSI_blk_size;
+
+ /* cases 4,5 : Hi <> Dn */
+ if (MSC_BOT_cbw.dDataLength != SCSI_blk_len)
+ {
+ SCSI_SenseCode(MSC_BOT_cbw.bLUN,
+ ILLEGAL_REQUEST,
+ INVALID_CDB);
+ return -1;
+ }
+ }
+ MSC_BOT_DataLen = MSC_MEDIA_PACKET;
+
+ return SCSI_ProcessRead(lun);
+}
+
+/**
+* @brief SCSI_Write10
+* Process Write10 command
+* @param lun: Logical unit number
+* @param params: Command parameters
+* @retval status
+*/
+
+static int8_t SCSI_Write10 (uint8_t lun , uint8_t *params)
+{
+ if (MSC_BOT_State == BOT_IDLE) /* Idle */
+ {
+
+ /* case 8 : Hi <> Do */
+
+ if ((MSC_BOT_cbw.bmFlags & 0x80) == 0x80)
+ {
+ SCSI_SenseCode(MSC_BOT_cbw.bLUN,
+ ILLEGAL_REQUEST,
+ INVALID_CDB);
+ return -1;
+ }
+
+ /* Check whether Media is ready */
+ if(USBD_STORAGE_fops->IsReady(lun) !=0 )
+ {
+ SCSI_SenseCode(lun,
+ NOT_READY,
+ MEDIUM_NOT_PRESENT);
+ return -1;
+ }
+
+ /* Check If media is write-protected */
+ if(USBD_STORAGE_fops->IsWriteProtected(lun) !=0 )
+ {
+ SCSI_SenseCode(lun,
+ NOT_READY,
+ WRITE_PROTECTED);
+ return -1;
+ }
+
+
+ SCSI_blk_addr = (params[2] << 24) | \
+ (params[3] << 16) | \
+ (params[4] << 8) | \
+ params[5];
+ SCSI_blk_len = (params[7] << 8) | \
+ params[8];
+
+ /* check if LBA address is in the right range */
+ if(SCSI_CheckAddressRange(lun, SCSI_blk_addr, SCSI_blk_len) < 0)
+ {
+ return -1; /* error */
+ }
+
+ SCSI_blk_addr *= SCSI_blk_size;
+ SCSI_blk_len *= SCSI_blk_size;
+
+ /* cases 3,11,13 : Hn,Ho <> D0 */
+ if (MSC_BOT_cbw.dDataLength != SCSI_blk_len)
+ {
+ SCSI_SenseCode(MSC_BOT_cbw.bLUN,
+ ILLEGAL_REQUEST,
+ INVALID_CDB);
+ return -1;
+ }
+
+ /* Prepare EP to receive first data packet */
+ MSC_BOT_State = BOT_DATA_OUT;
+ DCD_EP_PrepareRx (cdev,
+ MSC_OUT_EP,
+ MSC_BOT_Data,
+ MIN (SCSI_blk_len, MSC_MEDIA_PACKET));
+ }
+ else /* Write Process ongoing */
+ {
+ return SCSI_ProcessWrite(lun);
+ }
+ return 0;
+}
+
+
+/**
+* @brief SCSI_Verify10
+* Process Verify10 command
+* @param lun: Logical unit number
+* @param params: Command parameters
+* @retval status
+*/
+
+static int8_t SCSI_Verify10(uint8_t lun , uint8_t *params){
+ if ((params[1]& 0x02) == 0x02)
+ {
+ SCSI_SenseCode (lun, ILLEGAL_REQUEST, INVALID_FIELED_IN_COMMAND);
+ return -1; /* Error, Verify Mode Not supported*/
+ }
+
+ if(SCSI_CheckAddressRange(lun, SCSI_blk_addr, SCSI_blk_len) < 0)
+ {
+ return -1; /* error */
+ }
+ MSC_BOT_DataLen = 0;
+ return 0;
+}
+
+/**
+* @brief SCSI_CheckAddressRange
+* Check address range
+* @param lun: Logical unit number
+* @param blk_offset: first block address
+* @param blk_nbr: number of block to be processed
+* @retval status
+*/
+static int8_t SCSI_CheckAddressRange (uint8_t lun , uint32_t blk_offset , uint16_t blk_nbr)
+{
+
+ if ((blk_offset + blk_nbr) > SCSI_blk_nbr )
+ {
+ SCSI_SenseCode(lun, ILLEGAL_REQUEST, ADDRESS_OUT_OF_RANGE);
+ return -1;
+ }
+ return 0;
+}
+
+/**
+* @brief SCSI_ProcessRead
+* Handle Read Process
+* @param lun: Logical unit number
+* @retval status
+*/
+static int8_t SCSI_ProcessRead (uint8_t lun)
+{
+ uint32_t len;
+
+ len = MIN(SCSI_blk_len , MSC_MEDIA_PACKET);
+
+ if( USBD_STORAGE_fops->Read(lun ,
+ MSC_BOT_Data,
+ SCSI_blk_addr / SCSI_blk_size,
+ len / SCSI_blk_size) < 0)
+ {
+
+ SCSI_SenseCode(lun, HARDWARE_ERROR, UNRECOVERED_READ_ERROR);
+ return -1;
+ }
+
+
+ DCD_EP_Tx (cdev,
+ MSC_IN_EP,
+ MSC_BOT_Data,
+ len);
+
+
+ SCSI_blk_addr += len;
+ SCSI_blk_len -= len;
+
+ /* case 6 : Hi = Di */
+ MSC_BOT_csw.dDataResidue -= len;
+
+ if (SCSI_blk_len == 0)
+ {
+ MSC_BOT_State = BOT_LAST_DATA_IN;
+ }
+ return 0;
+}
+
+/**
+* @brief SCSI_ProcessWrite
+* Handle Write Process
+* @param lun: Logical unit number
+* @retval status
+*/
+
+static int8_t SCSI_ProcessWrite (uint8_t lun)
+{
+ uint32_t len;
+
+ len = MIN(SCSI_blk_len , MSC_MEDIA_PACKET);
+
+ if(USBD_STORAGE_fops->Write(lun ,
+ MSC_BOT_Data,
+ SCSI_blk_addr / SCSI_blk_size,
+ len / SCSI_blk_size) < 0)
+ {
+ SCSI_SenseCode(lun, HARDWARE_ERROR, WRITE_FAULT);
+ return -1;
+ }
+
+
+ SCSI_blk_addr += len;
+ SCSI_blk_len -= len;
+
+ /* case 12 : Ho = Do */
+ MSC_BOT_csw.dDataResidue -= len;
+
+ if (SCSI_blk_len == 0)
+ {
+ MSC_BOT_SendCSW (cdev, CSW_CMD_PASSED);
+ }
+ else
+ {
+ /* Prapare EP to Receive next packet */
+ DCD_EP_PrepareRx (cdev,
+ MSC_OUT_EP,
+ MSC_BOT_Data,
+ MIN (SCSI_blk_len, MSC_MEDIA_PACKET));
+ }
+
+ return 0;
+}
+/**
+ * @}
+ */
+
+
+/**
+ * @}
+ */
+
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/msc/src/usbd_storage_template.c b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/msc/src/usbd_storage_template.c
new file mode 100644
index 0000000..850e98e
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Class/msc/src/usbd_storage_template.c
@@ -0,0 +1,185 @@
+/**
+ ******************************************************************************
+ * @file usbd_storage_template.c
+ * @author MCD Application Team
+ * @version V1.1.0
+ * @date 19-March-2012
+ * @brief Memory management 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_msc_mem.h"
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Extern function prototypes ------------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+#define STORAGE_LUN_NBR 1
+
+int8_t STORAGE_Init (uint8_t lun);
+
+int8_t STORAGE_GetCapacity (uint8_t lun,
+ uint32_t *block_num,
+ uint16_t *block_size);
+
+int8_t STORAGE_IsReady (uint8_t lun);
+
+int8_t STORAGE_IsWriteProtected (uint8_t lun);
+
+int8_t STORAGE_Read (uint8_t lun,
+ uint8_t *buf,
+ uint32_t blk_addr,
+ uint16_t blk_len);
+
+int8_t STORAGE_Write (uint8_t lun,
+ uint8_t *buf,
+ uint32_t blk_addr,
+ uint16_t blk_len);
+
+int8_t STORAGE_GetMaxLun (void);
+
+/* USB Mass storage Standard Inquiry Data */
+const int8_t STORAGE_Inquirydata[] = {//36
+
+ /* LUN 0 */
+ 0x00,
+ 0x80,
+ 0x02,
+ 0x02,
+ (USBD_STD_INQUIRY_LENGTH - 5),
+ 0x00,
+ 0x00,
+ 0x00,
+ 'S', 'T', 'M', ' ', ' ', ' ', ' ', ' ', /* Manufacturer : 8 bytes */
+ 'P', 'r', 'o', 'd', 'u', 't', ' ', ' ', /* Product : 16 Bytes */
+ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
+ '0', '.', '0' ,'1', /* Version : 4 Bytes */
+};
+
+USBD_STORAGE_cb_TypeDef USBD_MICRO_SDIO_fops =
+{
+ STORAGE_Init,
+ STORAGE_GetCapacity,
+ STORAGE_IsReady,
+ STORAGE_IsWriteProtected,
+ STORAGE_Read,
+ STORAGE_Write,
+ STORAGE_GetMaxLun,
+ STORAGE_Inquirydata,
+
+};
+
+USBD_STORAGE_cb_TypeDef *USBD_STORAGE_fops = &USBD_MICRO_SDIO_fops;
+/*******************************************************************************
+* Function Name : Read_Memory
+* Description : Handle the Read operation from the microSD card.
+* Input : None.
+* Output : None.
+* Return : None.
+*******************************************************************************/
+int8_t STORAGE_Init (uint8_t lun)
+{
+ return (0);
+}
+
+/*******************************************************************************
+* Function Name : Read_Memory
+* Description : Handle the Read operation from the STORAGE card.
+* Input : None.
+* Output : None.
+* Return : None.
+*******************************************************************************/
+int8_t STORAGE_GetCapacity (uint8_t lun, uint32_t *block_num, uint16_t *block_size)
+{
+ return (0);
+}
+
+/*******************************************************************************
+* Function Name : Read_Memory
+* Description : Handle the Read operation from the STORAGE card.
+* Input : None.
+* Output : None.
+* Return : None.
+*******************************************************************************/
+int8_t STORAGE_IsReady (uint8_t lun)
+{
+ return (0);
+}
+
+/*******************************************************************************
+* Function Name : Read_Memory
+* Description : Handle the Read operation from the STORAGE card.
+* Input : None.
+* Output : None.
+* Return : None.
+*******************************************************************************/
+int8_t STORAGE_IsWriteProtected (uint8_t lun)
+{
+ return 0;
+}
+
+/*******************************************************************************
+* Function Name : Read_Memory
+* Description : Handle the Read operation from the STORAGE card.
+* Input : None.
+* Output : None.
+* Return : None.
+*******************************************************************************/
+int8_t STORAGE_Read (uint8_t lun,
+ uint8_t *buf,
+ uint32_t blk_addr,
+ uint16_t blk_len)
+{
+ return 0;
+}
+/*******************************************************************************
+* Function Name : Write_Memory
+* Description : Handle the Write operation to the STORAGE card.
+* Input : None.
+* Output : None.
+* Return : None.
+*******************************************************************************/
+int8_t STORAGE_Write (uint8_t lun,
+ uint8_t *buf,
+ uint32_t blk_addr,
+ uint16_t blk_len)
+{
+ return (0);
+}
+/*******************************************************************************
+* Function Name : Write_Memory
+* Description : Handle the Write operation to the STORAGE card.
+* Input : None.
+* Output : None.
+* Return : None.
+*******************************************************************************/
+int8_t STORAGE_GetMaxLun (void)
+{
+ return (STORAGE_LUN_NBR - 1);
+}
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Core/inc/usbd_conf_template.h b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Core/inc/usbd_conf_template.h
new file mode 100644
index 0000000..ea97b6b
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Core/inc/usbd_conf_template.h
@@ -0,0 +1,82 @@
+/**
+ ******************************************************************************
+ * @file usbd_conf_template.h
+ * @author MCD Application Team
+ * @version V1.1.0
+ * @date 19-March-2012
+ * @brief usb device configuration template 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 USE_USB_OTG_HS
+
+#define USBD_CFG_MAX_NUM 1
+#define USB_MAX_STR_DESC_SIZ 64
+#define USBD_EP0_MAX_PACKET_SIZE 64
+
+/**
+ * @}
+ */
+
+
+/** @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/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Core/inc/usbd_core.h b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Core/inc/usbd_core.h
new file mode 100644
index 0000000..1ba845c
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Core/inc/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/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Core/inc/usbd_def.h b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Core/inc/usbd_def.h
new file mode 100644
index 0000000..2aa1325
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Core/inc/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/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Core/inc/usbd_ioreq.h b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Core/inc/usbd_ioreq.h
new file mode 100644
index 0000000..b385b31
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Core/inc/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/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Core/inc/usbd_req.h b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Core/inc/usbd_req.h
new file mode 100644
index 0000000..e165937
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Core/inc/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/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Core/inc/usbd_usr.h b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Core/inc/usbd_usr.h
new file mode 100644
index 0000000..428cf68
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Core/inc/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/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Core/src/usbd_core.c b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Core/src/usbd_core.c
new file mode 100644
index 0000000..c09028e
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Core/src/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/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Core/src/usbd_ioreq.c b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Core/src/usbd_ioreq.c
new file mode 100644
index 0000000..139a86a
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Core/src/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/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Core/src/usbd_req.c b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Core/src/usbd_req.c
new file mode 100644
index 0000000..63c1167
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_Device_Library/Core/src/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/SPARK_Platform/MCU/STM32F2xx/STM32_USB_HOST_Library/Class/HID/inc/usbh_hid_core.h b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_HOST_Library/Class/HID/inc/usbh_hid_core.h
new file mode 100644
index 0000000..9b87cf6
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_HOST_Library/Class/HID/inc/usbh_hid_core.h
@@ -0,0 +1,203 @@
+/**
+ ******************************************************************************
+ * @file usbh_hid_core.h
+ * @author MCD Application Team
+ * @version V2.1.0
+ * @date 19-March-2012
+ * @brief This file contains all the prototypes for the usbh_hid_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 ----------------------------------------------*/
+#ifndef __USBH_HID_CORE_H
+#define __USBH_HID_CORE_H
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbh_core.h"
+#include "usbh_stdreq.h"
+#include "usb_bsp.h"
+#include "usbh_ioreq.h"
+#include "usbh_hcs.h"
+
+/** @addtogroup USBH_LIB
+ * @{
+ */
+
+/** @addtogroup USBH_CLASS
+ * @{
+ */
+
+/** @addtogroup USBH_HID_CLASS
+ * @{
+ */
+
+/** @defgroup USBH_HID_CORE
+ * @brief This file is the Header file for USBH_HID_CORE.c
+ * @{
+ */
+
+
+/** @defgroup USBH_HID_CORE_Exported_Types
+ * @{
+ */
+
+#define HID_MIN_POLL 10
+
+/* States for HID State Machine */
+typedef enum
+{
+ HID_IDLE= 0,
+ HID_SEND_DATA,
+ HID_BUSY,
+ HID_GET_DATA,
+ HID_SYNC,
+ HID_POLL,
+ HID_ERROR,
+}
+HID_State;
+
+typedef enum
+{
+ HID_REQ_IDLE = 0,
+ HID_REQ_GET_REPORT_DESC,
+ HID_REQ_GET_HID_DESC,
+ HID_REQ_SET_IDLE,
+ HID_REQ_SET_PROTOCOL,
+ HID_REQ_SET_REPORT,
+
+}
+HID_CtlState;
+
+typedef struct HID_cb
+{
+ void (*Init) (void);
+ void (*Decode) (uint8_t *data);
+
+} HID_cb_TypeDef;
+
+typedef struct _HID_Report
+{
+ uint8_t ReportID;
+ uint8_t ReportType;
+ uint16_t UsagePage;
+ uint32_t Usage[2];
+ uint32_t NbrUsage;
+ uint32_t UsageMin;
+ uint32_t UsageMax;
+ int32_t LogMin;
+ int32_t LogMax;
+ int32_t PhyMin;
+ int32_t PhyMax;
+ int32_t UnitExp;
+ uint32_t Unit;
+ uint32_t ReportSize;
+ uint32_t ReportCnt;
+ uint32_t Flag;
+ uint32_t PhyUsage;
+ uint32_t AppUsage;
+ uint32_t LogUsage;
+}
+HID_Report_TypeDef;
+
+/* Structure for HID process */
+typedef struct _HID_Process
+{
+ uint8_t buff[64];
+ uint8_t hc_num_in;
+ uint8_t hc_num_out;
+ HID_State state;
+ uint8_t HIDIntOutEp;
+ uint8_t HIDIntInEp;
+ HID_CtlState ctl_state;
+ uint16_t length;
+ uint8_t ep_addr;
+ uint16_t poll;
+ __IO uint16_t timer;
+ HID_cb_TypeDef *cb;
+}
+HID_Machine_TypeDef;
+
+/**
+ * @}
+ */
+
+/** @defgroup USBH_HID_CORE_Exported_Defines
+ * @{
+ */
+
+#define USB_HID_REQ_GET_REPORT 0x01
+#define USB_HID_GET_IDLE 0x02
+#define USB_HID_GET_PROTOCOL 0x03
+#define USB_HID_SET_REPORT 0x09
+#define USB_HID_SET_IDLE 0x0A
+#define USB_HID_SET_PROTOCOL 0x0B
+/**
+ * @}
+ */
+
+/** @defgroup USBH_HID_CORE_Exported_Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USBH_HID_CORE_Exported_Variables
+ * @{
+ */
+extern USBH_Class_cb_TypeDef HID_cb;
+/**
+ * @}
+ */
+
+/** @defgroup USBH_HID_CORE_Exported_FunctionsPrototype
+ * @{
+ */
+
+USBH_Status USBH_Set_Report (USB_OTG_CORE_HANDLE *pdev,
+ USBH_HOST *phost,
+ uint8_t reportType,
+ uint8_t reportId,
+ uint8_t reportLen,
+ uint8_t* reportBuff);
+/**
+ * @}
+ */
+
+
+#endif /* __USBH_HID_CORE_H */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32_USB_HOST_Library/Class/HID/inc/usbh_hid_keybd.h b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_HOST_Library/Class/HID/inc/usbh_hid_keybd.h
new file mode 100644
index 0000000..a81b2b0
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_HOST_Library/Class/HID/inc/usbh_hid_keybd.h
@@ -0,0 +1,128 @@
+/**
+ ******************************************************************************
+ * @file usbh_hid_keybd.h
+ * @author MCD Application Team
+ * @version V2.1.0
+ * @date 19-March-2012
+ * @brief This file contains all the prototypes for the usbh_hid_keybd.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 -----------------------------------------------*/
+#ifndef __USBH_HID_KEYBD_H
+#define __USBH_HID_KEYBD_H
+
+/* Includes ------------------------------------------------------------------*/
+#include "usb_conf.h"
+#include "usbh_hid_core.h"
+
+/** @addtogroup USBH_LIB
+ * @{
+ */
+
+/** @addtogroup USBH_CLASS
+ * @{
+ */
+
+/** @addtogroup USBH_HID_CLASS
+ * @{
+ */
+
+/** @defgroup USBH_HID_KEYBD
+ * @brief This file is the Header file for USBH_HID_KEYBD.c
+ * @{
+ */
+
+
+/** @defgroup USBH_HID_KEYBD_Exported_Types
+ * @{
+ */
+
+
+/**
+ * @}
+ */
+
+/** @defgroup USBH_HID_KEYBD_Exported_Defines
+ * @{
+ */
+//#define QWERTY_KEYBOARD
+#define AZERTY_KEYBOARD
+
+#define KBD_LEFT_CTRL 0x01
+#define KBD_LEFT_SHIFT 0x02
+#define KBD_LEFT_ALT 0x04
+#define KBD_LEFT_GUI 0x08
+#define KBD_RIGHT_CTRL 0x10
+#define KBD_RIGHT_SHIFT 0x20
+#define KBD_RIGHT_ALT 0x40
+#define KBD_RIGHT_GUI 0x80
+
+#define KBR_MAX_NBR_PRESSED 6
+
+/**
+ * @}
+ */
+
+/** @defgroup USBH_HID_KEYBD_Exported_Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USBH_HID_KEYBD_Exported_Variables
+ * @{
+ */
+
+extern HID_cb_TypeDef HID_KEYBRD_cb;
+/**
+ * @}
+ */
+
+/** @defgroup USBH_HID_KEYBD_Exported_FunctionsPrototype
+ * @{
+ */
+void USR_KEYBRD_Init (void);
+void USR_KEYBRD_ProcessData (uint8_t pbuf);
+/**
+ * @}
+ */
+
+#endif /* __USBH_HID_KEYBD_H */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32_USB_HOST_Library/Class/HID/inc/usbh_hid_mouse.h b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_HOST_Library/Class/HID/inc/usbh_hid_mouse.h
new file mode 100644
index 0000000..bd94bf1
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_HOST_Library/Class/HID/inc/usbh_hid_mouse.h
@@ -0,0 +1,120 @@
+/**
+ ******************************************************************************
+ * @file usbh_hid_mouse.h
+ * @author MCD Application Team
+ * @version V2.1.0
+ * @date 19-March-2012
+ * @brief This file contains all the prototypes for the usbh_hid_mouse.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 ----------------------------------------------*/
+#ifndef __USBH_HID_MOUSE_H
+#define __USBH_HID_MOUSE_H
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbh_hid_core.h"
+
+/** @addtogroup USBH_LIB
+ * @{
+ */
+
+/** @addtogroup USBH_CLASS
+ * @{
+ */
+
+/** @addtogroup USBH_HID_CLASS
+ * @{
+ */
+
+/** @defgroup USBH_HID_MOUSE
+ * @brief This file is the Header file for USBH_HID_MOUSE.c
+ * @{
+ */
+
+
+/** @defgroup USBH_HID_MOUSE_Exported_Types
+ * @{
+ */
+typedef struct _HID_MOUSE_Data
+{
+ uint8_t x;
+ uint8_t y;
+ uint8_t z; /* Not Supported */
+ uint8_t button;
+}
+HID_MOUSE_Data_TypeDef;
+
+/**
+ * @}
+ */
+
+/** @defgroup USBH_HID_MOUSE_Exported_Defines
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USBH_HID_MOUSE_Exported_Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USBH_HID_MOUSE_Exported_Variables
+ * @{
+ */
+
+extern HID_cb_TypeDef HID_MOUSE_cb;
+extern HID_MOUSE_Data_TypeDef HID_MOUSE_Data;
+/**
+ * @}
+ */
+
+/** @defgroup USBH_HID_MOUSE_Exported_FunctionsPrototype
+ * @{
+ */
+void USR_MOUSE_Init (void);
+void USR_MOUSE_ProcessData (HID_MOUSE_Data_TypeDef *data);
+/**
+ * @}
+ */
+
+#endif /* __USBH_HID_MOUSE_H */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32_USB_HOST_Library/Class/HID/src/usbh_hid_core.c b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_HOST_Library/Class/HID/src/usbh_hid_core.c
new file mode 100644
index 0000000..bf3d41c
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_HOST_Library/Class/HID/src/usbh_hid_core.c
@@ -0,0 +1,657 @@
+/**
+ ******************************************************************************
+ * @file usbh_hid_core.c
+ * @author MCD Application Team
+ * @version V2.1.0
+ * @date 19-March-2012
+ * @brief This file is the HID Layer Handlers for USB Host HID class.
+ *
+ * @verbatim
+ *
+ * ===================================================================
+ * HID Class Description
+ * ===================================================================
+ * This module manages the MSC class V1.11 following the "Device Class Definition
+ * for Human Interface Devices (HID) Version 1.11 Jun 27, 2001".
+ * This driver implements the following aspects of the specification:
+ * - The Boot Interface Subclass
+ * - The Mouse and Keyboard protocols
+ *
+ * @endverbatim
+ *
+ ******************************************************************************
+ * @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 "usbh_hid_core.h"
+#include "usbh_hid_mouse.h"
+#include "usbh_hid_keybd.h"
+
+/** @addtogroup USBH_LIB
+* @{
+*/
+
+/** @addtogroup USBH_CLASS
+* @{
+*/
+
+/** @addtogroup USBH_HID_CLASS
+* @{
+*/
+
+/** @defgroup USBH_HID_CORE
+* @brief This file includes HID Layer Handlers for USB Host HID class.
+* @{
+*/
+
+/** @defgroup USBH_HID_CORE_Private_TypesDefinitions
+* @{
+*/
+/**
+* @}
+*/
+
+
+/** @defgroup USBH_HID_CORE_Private_Defines
+* @{
+*/
+/**
+* @}
+*/
+
+
+/** @defgroup USBH_HID_CORE_Private_Macros
+* @{
+*/
+/**
+* @}
+*/
+
+
+/** @defgroup USBH_HID_CORE_Private_Variables
+* @{
+*/
+#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 HID_Machine_TypeDef HID_Machine __ALIGN_END ;
+
+#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 HID_Report_TypeDef HID_Report __ALIGN_END ;
+
+#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 USB_Setup_TypeDef HID_Setup __ALIGN_END ;
+
+#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 USBH_HIDDesc_TypeDef HID_Desc __ALIGN_END ;
+
+__IO uint8_t start_toggle = 0;
+/**
+* @}
+*/
+
+
+/** @defgroup USBH_HID_CORE_Private_FunctionPrototypes
+* @{
+*/
+
+static USBH_Status USBH_HID_InterfaceInit (USB_OTG_CORE_HANDLE *pdev ,
+ void *phost);
+
+static void USBH_ParseHIDDesc (USBH_HIDDesc_TypeDef *desc, uint8_t *buf);
+
+static void USBH_HID_InterfaceDeInit (USB_OTG_CORE_HANDLE *pdev ,
+ void *phost);
+
+static USBH_Status USBH_HID_Handle(USB_OTG_CORE_HANDLE *pdev ,
+ void *phost);
+
+static USBH_Status USBH_HID_ClassRequest(USB_OTG_CORE_HANDLE *pdev ,
+ void *phost);
+
+static USBH_Status USBH_Get_HID_ReportDescriptor (USB_OTG_CORE_HANDLE *pdev,
+ USBH_HOST *phost,
+ uint16_t length);
+
+static USBH_Status USBH_Get_HID_Descriptor (USB_OTG_CORE_HANDLE *pdev,\
+ USBH_HOST *phost,
+ uint16_t length);
+
+static USBH_Status USBH_Set_Idle (USB_OTG_CORE_HANDLE *pdev,
+ USBH_HOST *phost,
+ uint8_t duration,
+ uint8_t reportId);
+
+static USBH_Status USBH_Set_Protocol (USB_OTG_CORE_HANDLE *pdev,
+ USBH_HOST *phost,
+ uint8_t protocol);
+
+
+USBH_Class_cb_TypeDef HID_cb =
+{
+ USBH_HID_InterfaceInit,
+ USBH_HID_InterfaceDeInit,
+ USBH_HID_ClassRequest,
+ USBH_HID_Handle
+};
+/**
+* @}
+*/
+
+
+/** @defgroup USBH_HID_CORE_Private_Functions
+* @{
+*/
+
+/**
+* @brief USBH_HID_InterfaceInit
+* The function init the HID class.
+* @param pdev: Selected device
+* @param hdev: Selected device property
+* @retval USBH_Status :Response for USB HID driver intialization
+*/
+static USBH_Status USBH_HID_InterfaceInit ( USB_OTG_CORE_HANDLE *pdev,
+ void *phost)
+{
+ uint8_t maxEP;
+ USBH_HOST *pphost = phost;
+
+ uint8_t num =0;
+ USBH_Status status = USBH_BUSY ;
+ HID_Machine.state = HID_ERROR;
+
+
+ if(pphost->device_prop.Itf_Desc[0].bInterfaceSubClass == HID_BOOT_CODE)
+ {
+ /*Decode Bootclass Protocl: Mouse or Keyboard*/
+ if(pphost->device_prop.Itf_Desc[0].bInterfaceProtocol == HID_KEYBRD_BOOT_CODE)
+ {
+ HID_Machine.cb = &HID_KEYBRD_cb;
+ }
+ else if(pphost->device_prop.Itf_Desc[0].bInterfaceProtocol == HID_MOUSE_BOOT_CODE)
+ {
+ HID_Machine.cb = &HID_MOUSE_cb;
+ }
+
+ HID_Machine.state = HID_IDLE;
+ HID_Machine.ctl_state = HID_REQ_IDLE;
+ HID_Machine.ep_addr = pphost->device_prop.Ep_Desc[0][0].bEndpointAddress;
+ HID_Machine.length = pphost->device_prop.Ep_Desc[0][0].wMaxPacketSize;
+ HID_Machine.poll = pphost->device_prop.Ep_Desc[0][0].bInterval ;
+
+ if (HID_Machine.poll < HID_MIN_POLL)
+ {
+ HID_Machine.poll = HID_MIN_POLL;
+ }
+
+
+ /* Check fo available number of endpoints */
+ /* Find the number of EPs in the Interface Descriptor */
+ /* Choose the lower number in order not to overrun the buffer allocated */
+ maxEP = ( (pphost->device_prop.Itf_Desc[0].bNumEndpoints <= USBH_MAX_NUM_ENDPOINTS) ?
+ pphost->device_prop.Itf_Desc[0].bNumEndpoints :
+ USBH_MAX_NUM_ENDPOINTS);
+
+
+ /* Decode endpoint IN and OUT address from interface descriptor */
+ for (num=0; num < maxEP; num++)
+ {
+ if(pphost->device_prop.Ep_Desc[0][num].bEndpointAddress & 0x80)
+ {
+ HID_Machine.HIDIntInEp = (pphost->device_prop.Ep_Desc[0][num].bEndpointAddress);
+ HID_Machine.hc_num_in =\
+ USBH_Alloc_Channel(pdev,
+ pphost->device_prop.Ep_Desc[0][num].bEndpointAddress);
+
+ /* Open channel for IN endpoint */
+ USBH_Open_Channel (pdev,
+ HID_Machine.hc_num_in,
+ pphost->device_prop.address,
+ pphost->device_prop.speed,
+ EP_TYPE_INTR,
+ HID_Machine.length);
+ }
+ else
+ {
+ HID_Machine.HIDIntOutEp = (pphost->device_prop.Ep_Desc[0][num].bEndpointAddress);
+ HID_Machine.hc_num_out =\
+ USBH_Alloc_Channel(pdev,
+ pphost->device_prop.Ep_Desc[0][num].bEndpointAddress);
+
+ /* Open channel for OUT endpoint */
+ USBH_Open_Channel (pdev,
+ HID_Machine.hc_num_out,
+ pphost->device_prop.address,
+ pphost->device_prop.speed,
+ EP_TYPE_INTR,
+ HID_Machine.length);
+ }
+
+ }
+
+ start_toggle =0;
+ status = USBH_OK;
+ }
+ else
+ {
+ pphost->usr_cb->DeviceNotSupported();
+ }
+
+ return status;
+
+}
+
+
+
+/**
+* @brief USBH_HID_InterfaceDeInit
+* The function DeInit the Host Channels used for the HID class.
+* @param pdev: Selected device
+* @param hdev: Selected device property
+* @retval None
+*/
+void USBH_HID_InterfaceDeInit ( USB_OTG_CORE_HANDLE *pdev,
+ void *phost)
+{
+ //USBH_HOST *pphost = phost;
+
+ if(HID_Machine.hc_num_in != 0x00)
+ {
+ USB_OTG_HC_Halt(pdev, HID_Machine.hc_num_in);
+ USBH_Free_Channel (pdev, HID_Machine.hc_num_in);
+ HID_Machine.hc_num_in = 0; /* Reset the Channel as Free */
+ }
+
+ if(HID_Machine.hc_num_out != 0x00)
+ {
+ USB_OTG_HC_Halt(pdev, HID_Machine.hc_num_out);
+ USBH_Free_Channel (pdev, HID_Machine.hc_num_out);
+ HID_Machine.hc_num_out = 0; /* Reset the Channel as Free */
+ }
+
+ start_toggle = 0;
+}
+
+/**
+* @brief USBH_HID_ClassRequest
+* The function is responsible for handling HID Class requests
+* for HID class.
+* @param pdev: Selected device
+* @param hdev: Selected device property
+* @retval USBH_Status :Response for USB Set Protocol request
+*/
+static USBH_Status USBH_HID_ClassRequest(USB_OTG_CORE_HANDLE *pdev ,
+ void *phost)
+{
+ USBH_HOST *pphost = phost;
+
+ USBH_Status status = USBH_BUSY;
+ USBH_Status classReqStatus = USBH_BUSY;
+
+
+ /* Switch HID state machine */
+ switch (HID_Machine.ctl_state)
+ {
+ case HID_IDLE:
+ case HID_REQ_GET_HID_DESC:
+
+ /* Get HID Desc */
+ if (USBH_Get_HID_Descriptor (pdev, pphost, USB_HID_DESC_SIZE)== USBH_OK)
+ {
+
+ USBH_ParseHIDDesc(&HID_Desc, pdev->host.Rx_Buffer);
+ HID_Machine.ctl_state = HID_REQ_GET_REPORT_DESC;
+ }
+
+ break;
+ case HID_REQ_GET_REPORT_DESC:
+
+
+ /* Get Report Desc */
+ if (USBH_Get_HID_ReportDescriptor(pdev , pphost, HID_Desc.wItemLength) == USBH_OK)
+ {
+ HID_Machine.ctl_state = HID_REQ_SET_IDLE;
+ }
+
+ break;
+
+ case HID_REQ_SET_IDLE:
+
+ classReqStatus = USBH_Set_Idle (pdev, pphost, 0, 0);
+
+ /* set Idle */
+ if (classReqStatus == USBH_OK)
+ {
+ HID_Machine.ctl_state = HID_REQ_SET_PROTOCOL;
+ }
+ else if(classReqStatus == USBH_NOT_SUPPORTED)
+ {
+ HID_Machine.ctl_state = HID_REQ_SET_PROTOCOL;
+ }
+ break;
+
+ case HID_REQ_SET_PROTOCOL:
+ /* set protocol */
+ if (USBH_Set_Protocol (pdev ,pphost, 0) == USBH_OK)
+ {
+ HID_Machine.ctl_state = HID_REQ_IDLE;
+
+ /* all requests performed*/
+ status = USBH_OK;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return status;
+}
+
+
+/**
+* @brief USBH_HID_Handle
+* The function is for managing state machine for HID data transfers
+* @param pdev: Selected device
+* @param hdev: Selected device property
+* @retval USBH_Status
+*/
+static USBH_Status USBH_HID_Handle(USB_OTG_CORE_HANDLE *pdev ,
+ void *phost)
+{
+ USBH_HOST *pphost = phost;
+ USBH_Status status = USBH_OK;
+
+ switch (HID_Machine.state)
+ {
+
+ case HID_IDLE:
+ HID_Machine.cb->Init();
+ HID_Machine.state = HID_SYNC;
+
+ case HID_SYNC:
+
+ /* Sync with start of Even Frame */
+ if(USB_OTG_IsEvenFrame(pdev) == TRUE)
+ {
+ HID_Machine.state = HID_GET_DATA;
+ }
+ break;
+
+ case HID_GET_DATA:
+
+ USBH_InterruptReceiveData(pdev,
+ HID_Machine.buff,
+ HID_Machine.length,
+ HID_Machine.hc_num_in);
+ start_toggle = 1;
+
+ HID_Machine.state = HID_POLL;
+ HID_Machine.timer = HCD_GetCurrentFrame(pdev);
+ break;
+
+ case HID_POLL:
+ if(( HCD_GetCurrentFrame(pdev) - HID_Machine.timer) >= HID_Machine.poll)
+ {
+ HID_Machine.state = HID_GET_DATA;
+ }
+ else if(HCD_GetURB_State(pdev , HID_Machine.hc_num_in) == URB_DONE)
+ {
+ if(start_toggle == 1) /* handle data once */
+ {
+ start_toggle = 0;
+ HID_Machine.cb->Decode(HID_Machine.buff);
+ }
+ }
+ else if(HCD_GetURB_State(pdev, HID_Machine.hc_num_in) == URB_STALL) /* IN Endpoint Stalled */
+ {
+
+ /* Issue Clear Feature on interrupt IN endpoint */
+ if( (USBH_ClrFeature(pdev,
+ pphost,
+ HID_Machine.ep_addr,
+ HID_Machine.hc_num_in)) == USBH_OK)
+ {
+ /* Change state to issue next IN token */
+ HID_Machine.state = HID_GET_DATA;
+
+ }
+
+ }
+ break;
+
+ default:
+ break;
+ }
+ return status;
+}
+
+
+/**
+* @brief USBH_Get_HID_ReportDescriptor
+* Issue report Descriptor command to the device. Once the response
+* received, parse the report descriptor and update the status.
+* @param pdev : Selected device
+* @param Length : HID Report Descriptor Length
+* @retval USBH_Status : Response for USB HID Get Report Descriptor Request
+*/
+static USBH_Status USBH_Get_HID_ReportDescriptor (USB_OTG_CORE_HANDLE *pdev,
+ USBH_HOST *phost,
+ uint16_t length)
+{
+
+ USBH_Status status;
+
+ status = USBH_GetDescriptor(pdev,
+ phost,
+ USB_REQ_RECIPIENT_INTERFACE
+ | USB_REQ_TYPE_STANDARD,
+ USB_DESC_HID_REPORT,
+ pdev->host.Rx_Buffer,
+ length);
+
+ /* HID report descriptor is available in pdev->host.Rx_Buffer.
+ In case of USB Boot Mode devices for In report handling ,
+ HID report descriptor parsing is not required.
+ In case, for supporting Non-Boot Protocol devices and output reports,
+ user may parse the report descriptor*/
+
+
+ return status;
+}
+
+/**
+* @brief USBH_Get_HID_Descriptor
+* Issue HID Descriptor command to the device. Once the response
+* received, parse the report descriptor and update the status.
+* @param pdev : Selected device
+* @param Length : HID Descriptor Length
+* @retval USBH_Status : Response for USB HID Get Report Descriptor Request
+*/
+static USBH_Status USBH_Get_HID_Descriptor (USB_OTG_CORE_HANDLE *pdev,
+ USBH_HOST *phost,
+ uint16_t length)
+{
+
+ USBH_Status status;
+
+ status = USBH_GetDescriptor(pdev,
+ phost,
+ USB_REQ_RECIPIENT_INTERFACE
+ | USB_REQ_TYPE_STANDARD,
+ USB_DESC_HID,
+ pdev->host.Rx_Buffer,
+ length);
+
+ return status;
+}
+
+/**
+* @brief USBH_Set_Idle
+* Set Idle State.
+* @param pdev: Selected device
+* @param duration: Duration for HID Idle request
+* @param reportID : Targetted report ID for Set Idle request
+* @retval USBH_Status : Response for USB Set Idle request
+*/
+static USBH_Status USBH_Set_Idle (USB_OTG_CORE_HANDLE *pdev,
+ USBH_HOST *phost,
+ uint8_t duration,
+ uint8_t reportId)
+{
+
+ phost->Control.setup.b.bmRequestType = USB_H2D | USB_REQ_RECIPIENT_INTERFACE |\
+ USB_REQ_TYPE_CLASS;
+
+
+ phost->Control.setup.b.bRequest = USB_HID_SET_IDLE;
+ phost->Control.setup.b.wValue.w = (duration << 8 ) | reportId;
+
+ phost->Control.setup.b.wIndex.w = 0;
+ phost->Control.setup.b.wLength.w = 0;
+
+ return USBH_CtlReq(pdev, phost, 0 , 0 );
+}
+
+
+/**
+* @brief USBH_Set_Report
+* Issues Set Report
+* @param pdev: Selected device
+* @param reportType : Report type to be sent
+* @param reportID : Targetted report ID for Set Report request
+* @param reportLen : Length of data report to be send
+* @param reportBuff : Report Buffer
+* @retval USBH_Status : Response for USB Set Idle request
+*/
+USBH_Status USBH_Set_Report (USB_OTG_CORE_HANDLE *pdev,
+ USBH_HOST *phost,
+ uint8_t reportType,
+ uint8_t reportId,
+ uint8_t reportLen,
+ uint8_t* reportBuff)
+{
+
+ phost->Control.setup.b.bmRequestType = USB_H2D | USB_REQ_RECIPIENT_INTERFACE |\
+ USB_REQ_TYPE_CLASS;
+
+
+ phost->Control.setup.b.bRequest = USB_HID_SET_REPORT;
+ phost->Control.setup.b.wValue.w = (reportType << 8 ) | reportId;
+
+ phost->Control.setup.b.wIndex.w = 0;
+ phost->Control.setup.b.wLength.w = reportLen;
+
+ return USBH_CtlReq(pdev, phost, reportBuff , reportLen );
+}
+
+
+/**
+* @brief USBH_Set_Protocol
+* Set protocol State.
+* @param pdev: Selected device
+* @param protocol : Set Protocol for HID : boot/report protocol
+* @retval USBH_Status : Response for USB Set Protocol request
+*/
+static USBH_Status USBH_Set_Protocol(USB_OTG_CORE_HANDLE *pdev,
+ USBH_HOST *phost,
+ uint8_t protocol)
+{
+
+
+ phost->Control.setup.b.bmRequestType = USB_H2D | USB_REQ_RECIPIENT_INTERFACE |\
+ USB_REQ_TYPE_CLASS;
+
+
+ phost->Control.setup.b.bRequest = USB_HID_SET_PROTOCOL;
+
+ if(protocol != 0)
+ {
+ /* Boot Protocol */
+ phost->Control.setup.b.wValue.w = 0;
+ }
+ else
+ {
+ /*Report Protocol*/
+ phost->Control.setup.b.wValue.w = 1;
+ }
+
+ phost->Control.setup.b.wIndex.w = 0;
+ phost->Control.setup.b.wLength.w = 0;
+
+ return USBH_CtlReq(pdev, phost, 0 , 0 );
+
+}
+
+/**
+* @brief USBH_ParseHIDDesc
+* This function Parse the HID descriptor
+* @param buf: Buffer where the source descriptor is available
+* @retval None
+*/
+static void USBH_ParseHIDDesc (USBH_HIDDesc_TypeDef *desc, uint8_t *buf)
+{
+
+ desc->bLength = *(uint8_t *) (buf + 0);
+ desc->bDescriptorType = *(uint8_t *) (buf + 1);
+ desc->bcdHID = LE16 (buf + 2);
+ desc->bCountryCode = *(uint8_t *) (buf + 4);
+ desc->bNumDescriptors = *(uint8_t *) (buf + 5);
+ desc->bReportDescriptorType = *(uint8_t *) (buf + 6);
+ desc->wItemLength = LE16 (buf + 7);
+
+}
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+
+/**
+* @}
+*/
+
+
+/**
+* @}
+*/
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32_USB_HOST_Library/Class/HID/src/usbh_hid_keybd.c b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_HOST_Library/Class/HID/src/usbh_hid_keybd.c
new file mode 100644
index 0000000..6ee072c
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_HOST_Library/Class/HID/src/usbh_hid_keybd.c
@@ -0,0 +1,344 @@
+/**
+ ******************************************************************************
+ * @file usbh_hid_keybd.c
+ * @author MCD Application Team
+ * @version V2.1.0
+ * @date 19-March-2012
+ * @brief This file is the application layer for USB Host HID Keyboard handling
+ * QWERTY and AZERTY Keyboard are supported as per the selection in
+ * usbh_hid_keybd.h
+ ******************************************************************************
+ * @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 "usbh_hid_keybd.h"
+
+/** @addtogroup USBH_LIB
+* @{
+*/
+
+/** @addtogroup USBH_CLASS
+* @{
+*/
+
+/** @addtogroup USBH_HID_CLASS
+* @{
+*/
+
+/** @defgroup USBH_HID_KEYBD
+* @brief This file includes HID Layer Handlers for USB Host HID class.
+* @{
+*/
+
+/** @defgroup USBH_HID_KEYBD_Private_TypesDefinitions
+* @{
+*/
+/**
+* @}
+*/
+
+
+/** @defgroup USBH_HID_KEYBD_Private_Defines
+* @{
+*/
+/**
+* @}
+*/
+
+
+/** @defgroup USBH_HID_KEYBD_Private_Macros
+* @{
+*/
+/**
+* @}
+*/
+
+/** @defgroup USBH_HID_KEYBD_Private_FunctionPrototypes
+* @{
+*/
+static void KEYBRD_Init (void);
+static void KEYBRD_Decode(uint8_t *data);
+
+/**
+* @}
+*/
+
+#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
+ #if defined (__CC_ARM) /*!< ARM Compiler */
+ __align(4)
+ #elif defined ( __ICCARM__ ) /*!< IAR Compiler */
+ #pragma data_alignment=4
+ #elif defined (__GNUC__) /*!< GNU Compiler */
+ #pragma pack(4)
+ #elif defined (__TASKING__) /*!< TASKING Compiler */
+ __align(4)
+ #endif /* __CC_ARM */
+#endif
+
+/** @defgroup USBH_HID_KEYBD_Private_Variables
+* @{
+*/
+HID_cb_TypeDef HID_KEYBRD_cb=
+{
+ KEYBRD_Init,
+ KEYBRD_Decode
+};
+
+/*
+*******************************************************************************
+* LOCAL CONSTANTS
+*******************************************************************************
+*/
+
+static const uint8_t HID_KEYBRD_Codes[] = {
+ 0, 0, 0, 0, 31, 50, 48, 33,
+ 19, 34, 35, 36, 24, 37, 38, 39, /* 0x00 - 0x0F */
+ 52, 51, 25, 26, 17, 20, 32, 21,
+ 23, 49, 18, 47, 22, 46, 2, 3, /* 0x10 - 0x1F */
+ 4, 5, 6, 7, 8, 9, 10, 11,
+ 43, 110, 15, 16, 61, 12, 13, 27, /* 0x20 - 0x2F */
+ 28, 29, 42, 40, 41, 1, 53, 54,
+ 55, 30, 112, 113, 114, 115, 116, 117, /* 0x30 - 0x3F */
+ 118, 119, 120, 121, 122, 123, 124, 125,
+ 126, 75, 80, 85, 76, 81, 86, 89, /* 0x40 - 0x4F */
+ 79, 84, 83, 90, 95, 100, 105, 106,
+ 108, 93, 98, 103, 92, 97, 102, 91, /* 0x50 - 0x5F */
+ 96, 101, 99, 104, 45, 129, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, /* 0x60 - 0x6F */
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, /* 0x70 - 0x7F */
+ 0, 0, 0, 0, 0, 107, 0, 56,
+ 0, 0, 0, 0, 0, 0, 0, 0, /* 0x80 - 0x8F */
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90 - 0x9F */
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, /* 0xA0 - 0xAF */
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, /* 0xB0 - 0xBF */
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, /* 0xC0 - 0xCF */
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, /* 0xD0 - 0xDF */
+ 58, 44, 60, 127, 64, 57, 62, 128 /* 0xE0 - 0xE7 */
+};
+
+#ifdef QWERTY_KEYBOARD
+static const int8_t HID_KEYBRD_Key[] = {
+ '\0', '`', '1', '2', '3', '4', '5', '6',
+ '7', '8', '9', '0', '-', '=', '\0', '\r',
+ '\t', 'q', 'w', 'e', 'r', 't', 'y', 'u',
+ 'i', 'o', 'p', '[', ']', '\\',
+ '\0', 'a', 's', 'd', 'f', 'g', 'h', 'j',
+ 'k', 'l', ';', '\'', '\0', '\n',
+ '\0', '\0', 'z', 'x', 'c', 'v', 'b', 'n',
+ 'm', ',', '.', '/', '\0', '\0',
+ '\0', '\0', '\0', ' ', '\0', '\0', '\0', '\0',
+ '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
+ '\0', '\0', '\0', '\0', '\0', '\r', '\0', '\0',
+ '\0', '\0', '\0', '\0', '\0', '\0',
+ '\0', '\0', '7', '4', '1',
+ '\0', '/', '8', '5', '2',
+ '0', '*', '9', '6', '3',
+ '.', '-', '+', '\0', '\n', '\0', '\0', '\0', '\0', '\0', '\0',
+ '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
+ '\0', '\0', '\0', '\0'
+};
+
+static const int8_t HID_KEYBRD_ShiftKey[] = {
+ '\0', '~', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')',
+ '_', '+', '\0', '\0', '\0', 'Q', 'W', 'E', 'R', 'T', 'Y', 'U',
+ 'I', 'O', 'P', '{', '}', '|', '\0', 'A', 'S', 'D', 'F', 'G',
+ 'H', 'J', 'K', 'L', ':', '"', '\0', '\n', '\0', '\0', 'Z', 'X',
+ 'C', 'V', 'B', 'N', 'M', '<', '>', '?', '\0', '\0', '\0', '\0',
+ '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
+ '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
+ '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
+ '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
+ '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
+ '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0'
+};
+
+#else
+
+static const int8_t HID_KEYBRD_Key[] = {
+ '\0', '`', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0',
+ '-', '=', '\0', '\r', '\t', 'a', 'z', 'e', 'r', 't', 'y', 'u',
+ 'i', 'o', 'p', '[', ']', '\\', '\0', 'q', 's', 'd', 'f', 'g',
+ 'h', 'j', 'k', 'l', 'm', '\0', '\0', '\n', '\0', '\0', 'w', 'x',
+ 'c', 'v', 'b', 'n', ',', ';', ':', '!', '\0', '\0', '\0', '\0',
+ '\0', ' ', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
+ '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\r', '\0', '\0', '\0',
+ '\0', '\0', '\0', '\0', '\0', '\0', '\0', '7', '4', '1','\0', '/',
+ '8', '5', '2', '0', '*', '9', '6', '3', '.', '-', '+', '\0',
+ '\n', '\0', '\0', '\0', '\0', '\0', '\0','\0', '\0', '\0', '\0', '\0', '\0',
+ '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0'
+};
+
+static const int8_t HID_KEYBRD_ShiftKey[] = {
+ '\0', '~', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_',
+ '+', '\0', '\0', '\0', 'A', 'Z', 'E', 'R', 'T', 'Y', 'U', 'I', 'O',
+ 'P', '{', '}', '*', '\0', 'Q', 'S', 'D', 'F', 'G', 'H', 'J', 'K',
+ 'L', 'M', '%', '\0', '\n', '\0', '\0', 'W', 'X', 'C', 'V', 'B', 'N',
+ '?', '.', '/', '\0', '\0', '\0','\0', '\0', '\0', '\0', '\0', '\0', '\0',
+ '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
+ '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
+ '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
+ '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
+ '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0'
+};
+#endif
+
+/**
+* @}
+*/
+
+
+/** @defgroup USBH_HID_KEYBD_Private_Functions
+* @{
+*/
+
+
+/**
+* @brief KEYBRD_Init.
+* Initialize the keyboard function.
+* @param None
+* @retval None
+*/
+static void KEYBRD_Init (void)
+{
+ /* Call User Init*/
+ USR_KEYBRD_Init();
+}
+
+/**
+* @brief KEYBRD_ProcessData.
+* The function is to decode the pressed keys.
+* @param pbuf : Pointer to the HID IN report data buffer
+* @retval None
+*/
+
+static void KEYBRD_Decode(uint8_t *pbuf)
+{
+ static uint8_t shift;
+ static uint8_t keys[KBR_MAX_NBR_PRESSED];
+ static uint8_t keys_new[KBR_MAX_NBR_PRESSED];
+ static uint8_t keys_last[KBR_MAX_NBR_PRESSED];
+ static uint8_t key_newest;
+ static uint8_t nbr_keys;
+ static uint8_t nbr_keys_new;
+ static uint8_t nbr_keys_last;
+ uint8_t ix;
+ uint8_t jx;
+ uint8_t error;
+ uint8_t output;
+
+ nbr_keys = 0;
+ nbr_keys_new = 0;
+ nbr_keys_last = 0;
+ key_newest = 0x00;
+
+
+ /* Check if Shift key is pressed */
+ if ((pbuf[0] == KBD_LEFT_SHIFT) || (pbuf[0] == KBD_RIGHT_SHIFT)) {
+ shift = TRUE;
+ } else {
+ shift = FALSE;
+ }
+
+ error = FALSE;
+
+ /* Check for the value of pressed key */
+ for (ix = 2; ix < 2 + KBR_MAX_NBR_PRESSED; ix++) {
+ if ((pbuf[ix] == 0x01) ||
+ (pbuf[ix] == 0x02) ||
+ (pbuf[ix] == 0x03)) {
+ error = TRUE;
+ }
+ }
+
+ if (error == TRUE) {
+ return;
+ }
+
+ nbr_keys = 0;
+ nbr_keys_new = 0;
+ for (ix = 2; ix < 2 + KBR_MAX_NBR_PRESSED; ix++) {
+ if (pbuf[ix] != 0) {
+ keys[nbr_keys] = pbuf[ix];
+ nbr_keys++;
+ for (jx = 0; jx < nbr_keys_last; jx++) {
+ if (pbuf[ix] == keys_last[jx]) {
+ break;
+ }
+ }
+
+ if (jx == nbr_keys_last) {
+ keys_new[nbr_keys_new] = pbuf[ix];
+ nbr_keys_new++;
+ }
+ }
+ }
+
+ if (nbr_keys_new == 1) {
+ key_newest = keys_new[0];
+
+ if (shift == TRUE) {
+ output = HID_KEYBRD_ShiftKey[HID_KEYBRD_Codes[key_newest]];
+ } else {
+ output = HID_KEYBRD_Key[HID_KEYBRD_Codes[key_newest]];
+ }
+
+ /* call user process handle */
+ USR_KEYBRD_ProcessData(output);
+ } else {
+ key_newest = 0x00;
+ }
+
+
+ nbr_keys_last = nbr_keys;
+ for (ix = 0; ix < KBR_MAX_NBR_PRESSED; ix++) {
+ keys_last[ix] = keys[ix];
+ }
+}
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+
+/**
+* @}
+*/
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32_USB_HOST_Library/Class/HID/src/usbh_hid_mouse.c b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_HOST_Library/Class/HID/src/usbh_hid_mouse.c
new file mode 100644
index 0000000..fd3e97c
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_HOST_Library/Class/HID/src/usbh_hid_mouse.c
@@ -0,0 +1,161 @@
+/**
+ ******************************************************************************
+ * @file usbh_hid_mouse.c
+ * @author MCD Application Team
+ * @version V2.1.0
+ * @date 19-March-2012
+ * @brief This file is the application layer for USB Host HID Mouse Handling.
+ ******************************************************************************
+ * @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 "usbh_hid_mouse.h"
+
+
+/** @addtogroup USBH_LIB
+ * @{
+ */
+
+/** @addtogroup USBH_CLASS
+ * @{
+ */
+
+/** @addtogroup USBH_HID_CLASS
+ * @{
+ */
+
+/** @defgroup USBH_HID_MOUSE
+ * @brief This file includes HID Layer Handlers for USB Host HID class.
+ * @{
+ */
+
+/** @defgroup USBH_HID_MOUSE_Private_TypesDefinitions
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup USBH_HID_MOUSE_Private_Defines
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup USBH_HID_MOUSE_Private_Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USBH_HID_MOUSE_Private_FunctionPrototypes
+ * @{
+ */
+static void MOUSE_Init (void);
+static void MOUSE_Decode(uint8_t *data);
+/**
+ * @}
+ */
+
+
+/** @defgroup USBH_HID_MOUSE_Private_Variables
+ * @{
+ */
+#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
+ #if defined (__CC_ARM) /*!< ARM Compiler */
+ __align(4)
+ #elif defined ( __ICCARM__ ) /*!< IAR Compiler */
+ #pragma data_alignment=4
+ #elif defined (__GNUC__) /*!< GNU Compiler */
+ #pragma pack(4)
+ #elif defined (__TASKING__) /*!< TASKING Compiler */
+ __align(4)
+ #endif /* __CC_ARM */
+#endif
+
+
+HID_MOUSE_Data_TypeDef HID_MOUSE_Data;
+HID_cb_TypeDef HID_MOUSE_cb =
+{
+ MOUSE_Init,
+ MOUSE_Decode,
+};
+/**
+ * @}
+ */
+
+
+/** @defgroup USBH_HID_MOUSE_Private_Functions
+ * @{
+ */
+
+/**
+* @brief MOUSE_Init
+* Init Mouse State.
+* @param None
+* @retval None
+*/
+static void MOUSE_Init ( void)
+{
+ /* Call User Init*/
+ USR_MOUSE_Init();
+}
+
+/**
+* @brief MOUSE_Decode
+* Decode Mouse data
+* @param data : Pointer to Mouse HID data buffer
+* @retval None
+*/
+static void MOUSE_Decode(uint8_t *data)
+{
+ HID_MOUSE_Data.button = data[0];
+
+ HID_MOUSE_Data.x = data[1];
+ HID_MOUSE_Data.y = data[2];
+
+ USR_MOUSE_ProcessData(&HID_MOUSE_Data);
+
+}
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+
+/**
+ * @}
+ */
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32_USB_HOST_Library/Class/MSC/inc/usbh_msc_bot.h b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_HOST_Library/Class/MSC/inc/usbh_msc_bot.h
new file mode 100644
index 0000000..3c05ba5
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_HOST_Library/Class/MSC/inc/usbh_msc_bot.h
@@ -0,0 +1,227 @@
+/**
+ ******************************************************************************
+ * @file usbh_msc_bot.h
+ * @author MCD Application Team
+ * @version V2.1.0
+ * @date 19-March-2012
+ * @brief Header file for usbh_msc_bot.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 ----------------------------------------------*/
+#ifndef __USBH_MSC_BOT_H__
+#define __USBH_MSC_BOT_H__
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbh_stdreq.h"
+
+
+/** @addtogroup USBH_LIB
+ * @{
+ */
+
+/** @addtogroup USBH_CLASS
+ * @{
+ */
+
+/** @addtogroup USBH_MSC_CLASS
+ * @{
+ */
+
+/** @defgroup USBH_MSC_BOT
+ * @brief This file is the Header file for usbh_msc_core.c
+ * @{
+ */
+
+
+/** @defgroup USBH_MSC_BOT_Exported_Types
+ * @{
+ */
+
+typedef union _USBH_CBW_Block
+{
+ struct __CBW
+ {
+ uint32_t CBWSignature;
+ uint32_t CBWTag;
+ uint32_t CBWTransferLength;
+ uint8_t CBWFlags;
+ uint8_t CBWLUN;
+ uint8_t CBWLength;
+ uint8_t CBWCB[16];
+}field;
+ uint8_t CBWArray[31];
+}HostCBWPkt_TypeDef;
+
+typedef enum
+{
+ USBH_MSC_BOT_INIT_STATE = 0,
+ USBH_MSC_BOT_RESET,
+ USBH_MSC_GET_MAX_LUN,
+ USBH_MSC_TEST_UNIT_READY,
+ USBH_MSC_READ_CAPACITY10,
+ USBH_MSC_MODE_SENSE6,
+ USBH_MSC_REQUEST_SENSE,
+ USBH_MSC_BOT_USB_TRANSFERS,
+ USBH_MSC_DEFAULT_APPLI_STATE,
+ USBH_MSC_CTRL_ERROR_STATE,
+ USBH_MSC_UNRECOVERED_STATE
+}
+MSCState;
+
+
+typedef struct _BOTXfer
+{
+uint8_t MSCState;
+uint8_t MSCStateBkp;
+uint8_t MSCStateCurrent;
+uint8_t CmdStateMachine;
+uint8_t BOTState;
+uint8_t BOTStateBkp;
+uint8_t* pRxTxBuff;
+uint16_t DataLength;
+uint8_t BOTXferErrorCount;
+uint8_t BOTXferStatus;
+} USBH_BOTXfer_TypeDef;
+
+
+typedef union _USBH_CSW_Block
+{
+ struct __CSW
+ {
+ uint32_t CSWSignature;
+ uint32_t CSWTag;
+ uint32_t CSWDataResidue;
+ uint8_t CSWStatus;
+ }field;
+ uint8_t CSWArray[13];
+}HostCSWPkt_TypeDef;
+
+/**
+ * @}
+ */
+
+
+
+/** @defgroup USBH_MSC_BOT_Exported_Defines
+ * @{
+ */
+#define USBH_MSC_SEND_CBW 1
+#define USBH_MSC_SENT_CBW 2
+#define USBH_MSC_BOT_DATAIN_STATE 3
+#define USBH_MSC_BOT_DATAOUT_STATE 4
+#define USBH_MSC_RECEIVE_CSW_STATE 5
+#define USBH_MSC_DECODE_CSW 6
+#define USBH_MSC_BOT_ERROR_IN 7
+#define USBH_MSC_BOT_ERROR_OUT 8
+
+
+#define USBH_MSC_BOT_CBW_SIGNATURE 0x43425355
+#define USBH_MSC_BOT_CBW_TAG 0x20304050
+#define USBH_MSC_BOT_CSW_SIGNATURE 0x53425355
+#define USBH_MSC_CSW_DATA_LENGTH 0x000D
+#define USBH_MSC_BOT_CBW_PACKET_LENGTH 31
+#define USBH_MSC_CSW_LENGTH 13
+#define USBH_MSC_CSW_MAX_LENGTH 63
+
+/* CSW Status Definitions */
+#define USBH_MSC_CSW_CMD_PASSED 0x00
+#define USBH_MSC_CSW_CMD_FAILED 0x01
+#define USBH_MSC_CSW_PHASE_ERROR 0x02
+
+#define USBH_MSC_SEND_CSW_DISABLE 0
+#define USBH_MSC_SEND_CSW_ENABLE 1
+
+#define USBH_MSC_DIR_IN 0
+#define USBH_MSC_DIR_OUT 1
+#define USBH_MSC_BOTH_DIR 2
+
+//#define USBH_MSC_PAGE_LENGTH 0x40
+#define USBH_MSC_PAGE_LENGTH 512
+
+
+#define CBW_CB_LENGTH 16
+#define CBW_LENGTH 10
+#define CBW_LENGTH_TEST_UNIT_READY 6
+
+#define USB_REQ_BOT_RESET 0xFF
+#define USB_REQ_GET_MAX_LUN 0xFE
+
+#define MAX_BULK_STALL_COUNT_LIMIT 0x04 /* If STALL is seen on Bulk
+ Endpoint continously, this means
+ that device and Host has phase error
+ Hence a Reset is needed */
+
+/**
+ * @}
+ */
+
+/** @defgroup USBH_MSC_BOT_Exported_Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USBH_MSC_BOT_Exported_Variables
+ * @{
+ */
+extern USBH_BOTXfer_TypeDef USBH_MSC_BOTXferParam;
+extern HostCBWPkt_TypeDef USBH_MSC_CBWData;
+extern HostCSWPkt_TypeDef USBH_MSC_CSWData;
+/**
+ * @}
+ */
+
+/** @defgroup USBH_MSC_BOT_Exported_FunctionsPrototype
+ * @{
+ */
+void USBH_MSC_HandleBOTXfer(USB_OTG_CORE_HANDLE *pdev,
+ USBH_HOST *phost);
+uint8_t USBH_MSC_DecodeCSW(USB_OTG_CORE_HANDLE *pdev,
+ USBH_HOST *phost);
+void USBH_MSC_Init(USB_OTG_CORE_HANDLE *pdev);
+USBH_Status USBH_MSC_BOT_Abort(USB_OTG_CORE_HANDLE *pdev,
+ USBH_HOST *phost,
+ uint8_t direction);
+/**
+ * @}
+ */
+
+#endif //__USBH_MSC_BOT_H__
+
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32_USB_HOST_Library/Class/MSC/inc/usbh_msc_core.h b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_HOST_Library/Class/MSC/inc/usbh_msc_core.h
new file mode 100644
index 0000000..8b61c77
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_HOST_Library/Class/MSC/inc/usbh_msc_core.h
@@ -0,0 +1,147 @@
+/**
+ ******************************************************************************
+ * @file usbh_msc_core.h
+ * @author MCD Application Team
+ * @version V2.1.0
+ * @date 19-March-2012
+ * @brief This file contains all the prototypes for the usbh_msc_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 ----------------------------------------------*/
+#ifndef __USBH_MSC_CORE_H
+#define __USBH_MSC_CORE_H
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbh_core.h"
+#include "usbh_stdreq.h"
+#include "usb_bsp.h"
+#include "usbh_ioreq.h"
+#include "usbh_hcs.h"
+#include "usbh_msc_core.h"
+#include "usbh_msc_scsi.h"
+#include "usbh_msc_bot.h"
+
+/** @addtogroup USBH_LIB
+ * @{
+ */
+
+/** @addtogroup USBH_CLASS
+ * @{
+ */
+
+/** @addtogroup USBH_MSC_CLASS
+ * @{
+ */
+
+/** @defgroup USBH_MSC_CORE
+ * @brief This file is the Header file for usbh_msc_core.c
+ * @{
+ */
+
+
+/** @defgroup USBH_MSC_CORE_Exported_Types
+ * @{
+ */
+
+
+/* Structure for MSC process */
+typedef struct _MSC_Process
+{
+ uint8_t hc_num_in;
+ uint8_t hc_num_out;
+ uint8_t MSBulkOutEp;
+ uint8_t MSBulkInEp;
+ uint16_t MSBulkInEpSize;
+ uint16_t MSBulkOutEpSize;
+ uint8_t buff[USBH_MSC_MPS_SIZE];
+ uint8_t maxLun;
+}
+MSC_Machine_TypeDef;
+
+
+/**
+ * @}
+ */
+
+
+
+/** @defgroup USBH_MSC_CORE_Exported_Defines
+ * @{
+ */
+
+#define USB_REQ_BOT_RESET 0xFF
+#define USB_REQ_GET_MAX_LUN 0xFE
+
+
+/**
+ * @}
+ */
+
+/** @defgroup USBH_MSC_CORE_Exported_Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USBH_MSC_CORE_Exported_Variables
+ * @{
+ */
+extern USBH_Class_cb_TypeDef USBH_MSC_cb;
+extern MSC_Machine_TypeDef MSC_Machine;
+extern uint8_t MSCErrorCount;
+
+/**
+ * @}
+ */
+
+/** @defgroup USBH_MSC_CORE_Exported_FunctionsPrototype
+ * @{
+ */
+
+
+
+/**
+ * @}
+ */
+
+#endif /* __USBH_MSC_CORE_H */
+
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
+
+
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32_USB_HOST_Library/Class/MSC/inc/usbh_msc_scsi.h b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_HOST_Library/Class/MSC/inc/usbh_msc_scsi.h
new file mode 100644
index 0000000..464541d
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_HOST_Library/Class/MSC/inc/usbh_msc_scsi.h
@@ -0,0 +1,169 @@
+/**
+ ******************************************************************************
+ * @file usbh_msc_scsi.h
+ * @author MCD Application Team
+ * @version V2.1.0
+ * @date 19-March-2012
+ * @brief Header file for usbh_msc_scsi.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 ----------------------------------------------*/
+#ifndef __USBH_MSC_SCSI_H__
+#define __USBH_MSC_SCSI_H__
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbh_stdreq.h"
+
+
+/** @addtogroup USBH_LIB
+ * @{
+ */
+
+/** @addtogroup USBH_CLASS
+ * @{
+ */
+
+/** @addtogroup USBH_MSC_CLASS
+ * @{
+ */
+
+/** @defgroup USBH_MSC_SCSI
+ * @brief This file is the Header file for usbh_msc_scsi.c
+ * @{
+ */
+
+
+/** @defgroup USBH_MSC_SCSI_Exported_Types
+ * @{
+ */
+typedef enum {
+ USBH_MSC_OK = 0,
+ USBH_MSC_FAIL = 1,
+ USBH_MSC_PHASE_ERROR = 2,
+ USBH_MSC_BUSY = 3
+}USBH_MSC_Status_TypeDef;
+
+typedef enum {
+ CMD_UNINITIALIZED_STATE =0,
+ CMD_SEND_STATE,
+ CMD_WAIT_STATUS
+} CMD_STATES_TypeDef;
+
+
+
+typedef struct __MassStorageParameter
+{
+ uint32_t MSCapacity;
+ uint32_t MSSenseKey;
+ uint16_t MSPageLength;
+ uint8_t MSBulkOutEp;
+ uint8_t MSBulkInEp;
+ uint8_t MSWriteProtect;
+} MassStorageParameter_TypeDef;
+/**
+ * @}
+ */
+
+
+
+/** @defgroup USBH_MSC_SCSI_Exported_Defines
+ * @{
+ */
+
+
+
+#define OPCODE_TEST_UNIT_READY 0X00
+#define OPCODE_READ_CAPACITY10 0x25
+#define OPCODE_MODE_SENSE6 0x1A
+#define OPCODE_READ10 0x28
+#define OPCODE_WRITE10 0x2A
+#define OPCODE_REQUEST_SENSE 0x03
+
+#define DESC_REQUEST_SENSE 0X00
+#define ALLOCATION_LENGTH_REQUEST_SENSE 63
+#define XFER_LEN_READ_CAPACITY10 8
+#define XFER_LEN_MODE_SENSE6 63
+
+#define MASK_MODE_SENSE_WRITE_PROTECT 0x80
+#define MODE_SENSE_PAGE_CONTROL_FIELD 0x00
+#define MODE_SENSE_PAGE_CODE 0x3F
+#define DISK_WRITE_PROTECTED 0x01
+/**
+ * @}
+ */
+
+/** @defgroup USBH_MSC_SCSI_Exported_Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup _Exported_Variables
+ * @{
+ */
+extern MassStorageParameter_TypeDef USBH_MSC_Param;
+/**
+ * @}
+ */
+
+/** @defgroup USBH_MSC_SCSI_Exported_FunctionsPrototype
+ * @{
+ */
+uint8_t USBH_MSC_TestUnitReady(USB_OTG_CORE_HANDLE *pdev);
+uint8_t USBH_MSC_ReadCapacity10(USB_OTG_CORE_HANDLE *pdev);
+uint8_t USBH_MSC_ModeSense6(USB_OTG_CORE_HANDLE *pdev);
+uint8_t USBH_MSC_RequestSense(USB_OTG_CORE_HANDLE *pdev);
+uint8_t USBH_MSC_Write10(USB_OTG_CORE_HANDLE *pdev,
+ uint8_t *,
+ uint32_t ,
+ uint32_t );
+uint8_t USBH_MSC_Read10(USB_OTG_CORE_HANDLE *pdev,
+ uint8_t *,
+ uint32_t ,
+ uint32_t );
+void USBH_MSC_StateMachine(USB_OTG_CORE_HANDLE *pdev);
+
+/**
+ * @}
+ */
+
+#endif //__USBH_MSC_SCSI_H__
+
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32_USB_HOST_Library/Class/MSC/src/usbh_msc_bot.c b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_HOST_Library/Class/MSC/src/usbh_msc_bot.c
new file mode 100644
index 0000000..39af8d2
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_HOST_Library/Class/MSC/src/usbh_msc_bot.c
@@ -0,0 +1,632 @@
+/**
+ ******************************************************************************
+ * @file usbh_msc_bot.c
+ * @author MCD Application Team
+ * @version V2.1.0
+ * @date 19-March-2012
+ * @brief This file includes the mass storage related 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 "usbh_msc_core.h"
+#include "usbh_msc_scsi.h"
+#include "usbh_msc_bot.h"
+#include "usbh_ioreq.h"
+#include "usbh_def.h"
+#include "usb_hcd_int.h"
+
+
+/** @addtogroup USBH_LIB
+* @{
+*/
+
+/** @addtogroup USBH_CLASS
+* @{
+*/
+
+/** @addtogroup USBH_MSC_CLASS
+* @{
+*/
+
+/** @defgroup USBH_MSC_BOT
+* @brief This file includes the mass storage related functions
+* @{
+*/
+
+
+/** @defgroup USBH_MSC_BOT_Private_TypesDefinitions
+* @{
+*/
+/**
+* @}
+*/
+
+/** @defgroup USBH_MSC_BOT_Private_Defines
+* @{
+*/
+/**
+* @}
+*/
+
+/** @defgroup USBH_MSC_BOT_Private_Macros
+* @{
+*/
+/**
+* @}
+*/
+
+
+/** @defgroup USBH_MSC_BOT_Private_Variables
+* @{
+*/
+
+#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 HostCBWPkt_TypeDef USBH_MSC_CBWData __ALIGN_END ;
+
+#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 HostCSWPkt_TypeDef USBH_MSC_CSWData __ALIGN_END ;
+
+
+static uint32_t BOTStallErrorCount; /* Keeps count of STALL Error Cases*/
+
+/**
+* @}
+*/
+
+
+/** @defgroup USBH_MSC_BOT_Private_FunctionPrototypes
+* @{
+*/
+/**
+* @}
+*/
+
+
+/** @defgroup USBH_MSC_BOT_Exported_Variables
+* @{
+*/
+USBH_BOTXfer_TypeDef USBH_MSC_BOTXferParam;
+/**
+* @}
+*/
+
+
+/** @defgroup USBH_MSC_BOT_Private_Functions
+* @{
+*/
+
+
+/**
+* @brief USBH_MSC_Init
+* Initializes the mass storage parameters
+* @param None
+* @retval None
+*/
+void USBH_MSC_Init(USB_OTG_CORE_HANDLE *pdev )
+{
+ if(HCD_IsDeviceConnected(pdev))
+ {
+ USBH_MSC_CBWData.field.CBWSignature = USBH_MSC_BOT_CBW_SIGNATURE;
+ USBH_MSC_CBWData.field.CBWTag = USBH_MSC_BOT_CBW_TAG;
+ USBH_MSC_CBWData.field.CBWLUN = 0; /*Only one LUN is supported*/
+ USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE;
+ }
+
+ BOTStallErrorCount = 0;
+ MSCErrorCount = 0;
+}
+
+/**
+* @brief USBH_MSC_HandleBOTXfer
+* This function manages the different states of BOT transfer and
+* updates the status to upper layer.
+* @param None
+* @retval None
+*
+*/
+void USBH_MSC_HandleBOTXfer (USB_OTG_CORE_HANDLE *pdev ,USBH_HOST *phost)
+{
+ uint8_t xferDirection, index;
+ static uint32_t remainingDataLength;
+ static uint8_t *datapointer , *datapointer_prev;
+ static uint8_t error_direction;
+ USBH_Status status;
+
+ URB_STATE URB_Status = URB_IDLE;
+
+ if(HCD_IsDeviceConnected(pdev))
+ {
+
+ switch (USBH_MSC_BOTXferParam.BOTState)
+ {
+ case USBH_MSC_SEND_CBW:
+ /* send CBW */
+ USBH_BulkSendData (pdev,
+ &USBH_MSC_CBWData.CBWArray[0],
+ USBH_MSC_BOT_CBW_PACKET_LENGTH ,
+ MSC_Machine.hc_num_out);
+
+ USBH_MSC_BOTXferParam.BOTStateBkp = USBH_MSC_SEND_CBW;
+ USBH_MSC_BOTXferParam.BOTState = USBH_MSC_SENT_CBW;
+
+ break;
+
+ case USBH_MSC_SENT_CBW:
+ URB_Status = HCD_GetURB_State(pdev , MSC_Machine.hc_num_out);
+
+ if(URB_Status == URB_DONE)
+ {
+ BOTStallErrorCount = 0;
+ USBH_MSC_BOTXferParam.BOTStateBkp = USBH_MSC_SENT_CBW;
+
+ /* If the CBW Pkt is sent successful, then change the state */
+ xferDirection = (USBH_MSC_CBWData.field.CBWFlags & USB_REQ_DIR_MASK);
+
+ if ( USBH_MSC_CBWData.field.CBWTransferLength != 0 )
+ {
+ remainingDataLength = USBH_MSC_CBWData.field.CBWTransferLength ;
+ datapointer = USBH_MSC_BOTXferParam.pRxTxBuff;
+ datapointer_prev = datapointer;
+
+ /* If there is Data Transfer Stage */
+ if (xferDirection == USB_D2H)
+ {
+ /* Data Direction is IN */
+ USBH_MSC_BOTXferParam.BOTState = USBH_MSC_BOT_DATAIN_STATE;
+ }
+ else
+ {
+ /* Data Direction is OUT */
+ USBH_MSC_BOTXferParam.BOTState = USBH_MSC_BOT_DATAOUT_STATE;
+ }
+ }
+
+ else
+ {/* If there is NO Data Transfer Stage */
+ USBH_MSC_BOTXferParam.BOTState = USBH_MSC_RECEIVE_CSW_STATE;
+ }
+
+ }
+ else if(URB_Status == URB_NOTREADY)
+ {
+ USBH_MSC_BOTXferParam.BOTState = USBH_MSC_BOTXferParam.BOTStateBkp;
+ }
+ else if(URB_Status == URB_STALL)
+ {
+ error_direction = USBH_MSC_DIR_OUT;
+ USBH_MSC_BOTXferParam.BOTState = USBH_MSC_BOT_ERROR_OUT;
+ }
+ break;
+
+ case USBH_MSC_BOT_DATAIN_STATE:
+
+ URB_Status = HCD_GetURB_State(pdev , MSC_Machine.hc_num_in);
+ /* BOT DATA IN stage */
+ if((URB_Status == URB_DONE) ||(USBH_MSC_BOTXferParam.BOTStateBkp != USBH_MSC_BOT_DATAIN_STATE))
+ {
+ BOTStallErrorCount = 0;
+ USBH_MSC_BOTXferParam.BOTStateBkp = USBH_MSC_BOT_DATAIN_STATE;
+
+ if(remainingDataLength > MSC_Machine.MSBulkInEpSize)
+ {
+ USBH_BulkReceiveData (pdev,
+ datapointer,
+ MSC_Machine.MSBulkInEpSize ,
+ MSC_Machine.hc_num_in);
+
+ remainingDataLength -= MSC_Machine.MSBulkInEpSize;
+ datapointer = datapointer + MSC_Machine.MSBulkInEpSize;
+ }
+ else if ( remainingDataLength == 0)
+ {
+ /* If value was 0, and successful transfer, then change the state */
+ USBH_MSC_BOTXferParam.BOTState = USBH_MSC_RECEIVE_CSW_STATE;
+ }
+ else
+ {
+ USBH_BulkReceiveData (pdev,
+ datapointer,
+ remainingDataLength ,
+ MSC_Machine.hc_num_in);
+
+ remainingDataLength = 0; /* Reset this value and keep in same state */
+ }
+ }
+ else if(URB_Status == URB_STALL)
+ {
+ /* This is Data Stage STALL Condition */
+
+ error_direction = USBH_MSC_DIR_IN;
+ USBH_MSC_BOTXferParam.BOTState = USBH_MSC_BOT_ERROR_IN;
+
+ /* Refer to USB Mass-Storage Class : BOT (www.usb.org)
+ 6.7.2 Host expects to receive data from the device
+ 3. On a STALL condition receiving data, then:
+ The host shall accept the data received.
+ The host shall clear the Bulk-In pipe.
+ 4. The host shall attempt to receive a CSW.
+
+ USBH_MSC_BOTXferParam.BOTStateBkp is used to switch to the Original
+ state after the ClearFeature Command is issued.
+ */
+ USBH_MSC_BOTXferParam.BOTStateBkp = USBH_MSC_RECEIVE_CSW_STATE;
+
+ }
+ break;
+
+
+ case USBH_MSC_BOT_DATAOUT_STATE:
+ /* BOT DATA OUT stage */
+ URB_Status = HCD_GetURB_State(pdev , MSC_Machine.hc_num_out);
+ if(URB_Status == URB_DONE)
+ {
+ BOTStallErrorCount = 0;
+ USBH_MSC_BOTXferParam.BOTStateBkp = USBH_MSC_BOT_DATAOUT_STATE;
+ if(remainingDataLength > MSC_Machine.MSBulkOutEpSize)
+ {
+ USBH_BulkSendData (pdev,
+ datapointer,
+ MSC_Machine.MSBulkOutEpSize ,
+ MSC_Machine.hc_num_out);
+ datapointer_prev = datapointer;
+ datapointer = datapointer + MSC_Machine.MSBulkOutEpSize;
+
+ remainingDataLength = remainingDataLength - MSC_Machine.MSBulkOutEpSize;
+ }
+ else if ( remainingDataLength == 0)
+ {
+ /* If value was 0, and successful transfer, then change the state */
+ USBH_MSC_BOTXferParam.BOTState = USBH_MSC_RECEIVE_CSW_STATE;
+ }
+ else
+ {
+ USBH_BulkSendData (pdev,
+ datapointer,
+ remainingDataLength ,
+ MSC_Machine.hc_num_out);
+
+ remainingDataLength = 0; /* Reset this value and keep in same state */
+ }
+ }
+
+ else if(URB_Status == URB_NOTREADY)
+ {
+ if(datapointer != datapointer_prev)
+ {
+ USBH_BulkSendData (pdev,
+ (datapointer - MSC_Machine.MSBulkOutEpSize),
+ MSC_Machine.MSBulkOutEpSize ,
+ MSC_Machine.hc_num_out);
+ }
+ else
+ {
+ USBH_BulkSendData (pdev,
+ datapointer,
+ MSC_Machine.MSBulkOutEpSize ,
+ MSC_Machine.hc_num_out);
+ }
+ }
+
+ else if(URB_Status == URB_STALL)
+ {
+ error_direction = USBH_MSC_DIR_OUT;
+ USBH_MSC_BOTXferParam.BOTState = USBH_MSC_BOT_ERROR_OUT;
+
+ /* Refer to USB Mass-Storage Class : BOT (www.usb.org)
+ 6.7.3 Ho - Host expects to send data to the device
+ 3. On a STALL condition sending data, then:
+ " The host shall clear the Bulk-Out pipe.
+ 4. The host shall attempt to receive a CSW.
+
+ The Above statement will do the clear the Bulk-Out pipe.
+ The Below statement will help in Getting the CSW.
+
+ USBH_MSC_BOTXferParam.BOTStateBkp is used to switch to the Original
+ state after the ClearFeature Command is issued.
+ */
+
+ USBH_MSC_BOTXferParam.BOTStateBkp = USBH_MSC_RECEIVE_CSW_STATE;
+
+ }
+ break;
+
+ case USBH_MSC_RECEIVE_CSW_STATE:
+ /* BOT CSW stage */
+ /* NOTE: We cannot reset the BOTStallErrorCount here as it may come from
+ the clearFeature from previous command */
+
+ USBH_MSC_BOTXferParam.BOTStateBkp = USBH_MSC_RECEIVE_CSW_STATE;
+
+ USBH_MSC_BOTXferParam.pRxTxBuff = USBH_MSC_CSWData.CSWArray;
+ USBH_MSC_BOTXferParam.DataLength = USBH_MSC_CSW_MAX_LENGTH;
+
+ for(index = USBH_MSC_CSW_LENGTH; index != 0; index--)
+ {
+ USBH_MSC_CSWData.CSWArray[index] = 0;
+ }
+
+ USBH_MSC_CSWData.CSWArray[0] = 0;
+
+ USBH_BulkReceiveData (pdev,
+ USBH_MSC_BOTXferParam.pRxTxBuff,
+ USBH_MSC_CSW_MAX_LENGTH ,
+ MSC_Machine.hc_num_in);
+ USBH_MSC_BOTXferParam.BOTState = USBH_MSC_DECODE_CSW;
+
+ break;
+
+ case USBH_MSC_DECODE_CSW:
+ URB_Status = HCD_GetURB_State(pdev , MSC_Machine.hc_num_in);
+ /* Decode CSW */
+ if(URB_Status == URB_DONE)
+ {
+ BOTStallErrorCount = 0;
+ USBH_MSC_BOTXferParam.BOTStateBkp = USBH_MSC_RECEIVE_CSW_STATE;
+
+ USBH_MSC_BOTXferParam.MSCState = USBH_MSC_BOTXferParam.MSCStateCurrent ;
+
+ USBH_MSC_BOTXferParam.BOTXferStatus = USBH_MSC_DecodeCSW(pdev , phost);
+ }
+ else if(URB_Status == URB_STALL)
+ {
+ error_direction = USBH_MSC_DIR_IN;
+ USBH_MSC_BOTXferParam.BOTState = USBH_MSC_BOT_ERROR_IN;
+ }
+ break;
+
+ case USBH_MSC_BOT_ERROR_IN:
+ status = USBH_MSC_BOT_Abort(pdev, phost, USBH_MSC_DIR_IN);
+ if (status == USBH_OK)
+ {
+ /* Check if the error was due in Both the directions */
+ if (error_direction == USBH_MSC_BOTH_DIR)
+ {/* If Both directions are Needed, Switch to OUT Direction */
+ USBH_MSC_BOTXferParam.BOTState = USBH_MSC_BOT_ERROR_OUT;
+ }
+ else
+ {
+ /* Switch Back to the Original State, In many cases this will be
+ USBH_MSC_RECEIVE_CSW_STATE state */
+ USBH_MSC_BOTXferParam.BOTState = USBH_MSC_BOTXferParam.BOTStateBkp;
+ }
+ }
+ else if (status == USBH_UNRECOVERED_ERROR)
+ {
+ /* This means that there is a STALL Error limit, Do Reset Recovery */
+ USBH_MSC_BOTXferParam.BOTXferStatus = USBH_MSC_PHASE_ERROR;
+ }
+ break;
+
+ case USBH_MSC_BOT_ERROR_OUT:
+ status = USBH_MSC_BOT_Abort(pdev, phost, USBH_MSC_DIR_OUT);
+ if ( status == USBH_OK)
+ { /* Switch Back to the Original State */
+ USBH_MSC_BOTXferParam.BOTState = USBH_MSC_BOTXferParam.BOTStateBkp;
+ }
+ else if (status == USBH_UNRECOVERED_ERROR)
+ {
+ /* This means that there is a STALL Error limit, Do Reset Recovery */
+ USBH_MSC_BOTXferParam.BOTXferStatus = USBH_MSC_PHASE_ERROR;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+}
+
+/**
+* @brief USBH_MSC_BOT_Abort
+* This function manages the different Error handling for STALL
+* @param direction : IN / OUT
+* @retval None
+*/
+USBH_Status USBH_MSC_BOT_Abort(USB_OTG_CORE_HANDLE *pdev,
+ USBH_HOST *phost,
+ uint8_t direction)
+{
+ USBH_Status status;
+
+ status = USBH_BUSY;
+
+ switch (direction)
+ {
+ case USBH_MSC_DIR_IN :
+ /* send ClrFeture on Bulk IN endpoint */
+ status = USBH_ClrFeature(pdev,
+ phost,
+ MSC_Machine.MSBulkInEp,
+ MSC_Machine.hc_num_in);
+
+ break;
+
+ case USBH_MSC_DIR_OUT :
+ /*send ClrFeature on Bulk OUT endpoint */
+ status = USBH_ClrFeature(pdev,
+ phost,
+ MSC_Machine.MSBulkOutEp,
+ MSC_Machine.hc_num_out);
+ break;
+
+ default:
+ break;
+ }
+
+ BOTStallErrorCount++; /* Check Continous Number of times, STALL has Occured */
+ if (BOTStallErrorCount > MAX_BULK_STALL_COUNT_LIMIT )
+ {
+ status = USBH_UNRECOVERED_ERROR;
+ }
+
+ return status;
+}
+
+/**
+* @brief USBH_MSC_DecodeCSW
+* This function decodes the CSW received by the device and updates the
+* same to upper layer.
+* @param None
+* @retval On success USBH_MSC_OK, on failure USBH_MSC_FAIL
+* @notes
+* Refer to USB Mass-Storage Class : BOT (www.usb.org)
+* 6.3.1 Valid CSW Conditions :
+* The host shall consider the CSW valid when:
+* 1. dCSWSignature is equal to 53425355h
+* 2. the CSW is 13 (Dh) bytes in length,
+* 3. dCSWTag matches the dCBWTag from the corresponding CBW.
+*/
+
+uint8_t USBH_MSC_DecodeCSW(USB_OTG_CORE_HANDLE *pdev , USBH_HOST *phost)
+{
+ uint8_t status;
+ uint32_t dataXferCount = 0;
+ status = USBH_MSC_FAIL;
+
+ if(HCD_IsDeviceConnected(pdev))
+ {
+ /*Checking if the transfer length is diffrent than 13*/
+ dataXferCount = HCD_GetXferCnt(pdev, MSC_Machine.hc_num_in);
+
+ if(dataXferCount != USBH_MSC_CSW_LENGTH)
+ {
+ /*(4) Hi > Dn (Host expects to receive data from the device,
+ Device intends to transfer no data)
+ (5) Hi > Di (Host expects to receive data from the device,
+ Device intends to send data to the host)
+ (9) Ho > Dn (Host expects to send data to the device,
+ Device intends to transfer no data)
+ (11) Ho > Do (Host expects to send data to the device,
+ Device intends to receive data from the host)*/
+
+
+ status = USBH_MSC_PHASE_ERROR;
+ }
+ else
+ { /* CSW length is Correct */
+
+ /* Check validity of the CSW Signature and CSWStatus */
+ if(USBH_MSC_CSWData.field.CSWSignature == USBH_MSC_BOT_CSW_SIGNATURE)
+ {/* Check Condition 1. dCSWSignature is equal to 53425355h */
+
+ if(USBH_MSC_CSWData.field.CSWTag == USBH_MSC_CBWData.field.CBWTag)
+ {
+ /* Check Condition 3. dCSWTag matches the dCBWTag from the
+ corresponding CBW */
+
+ if(USBH_MSC_CSWData.field.CSWStatus == USBH_MSC_OK)
+ {
+ /* Refer to USB Mass-Storage Class : BOT (www.usb.org)
+
+ Hn Host expects no data transfers
+ Hi Host expects to receive data from the device
+ Ho Host expects to send data to the device
+
+ Dn Device intends to transfer no data
+ Di Device intends to send data to the host
+ Do Device intends to receive data from the host
+
+ Section 6.7
+ (1) Hn = Dn (Host expects no data transfers,
+ Device intends to transfer no data)
+ (6) Hi = Di (Host expects to receive data from the device,
+ Device intends to send data to the host)
+ (12) Ho = Do (Host expects to send data to the device,
+ Device intends to receive data from the host)
+
+ */
+
+ status = USBH_MSC_OK;
+ }
+ else if(USBH_MSC_CSWData.field.CSWStatus == USBH_MSC_FAIL)
+ {
+ status = USBH_MSC_FAIL;
+ }
+
+ else if(USBH_MSC_CSWData.field.CSWStatus == USBH_MSC_PHASE_ERROR)
+ {
+ /* Refer to USB Mass-Storage Class : BOT (www.usb.org)
+ Section 6.7
+ (2) Hn < Di ( Host expects no data transfers,
+ Device intends to send data to the host)
+ (3) Hn < Do ( Host expects no data transfers,
+ Device intends to receive data from the host)
+ (7) Hi < Di ( Host expects to receive data from the device,
+ Device intends to send data to the host)
+ (8) Hi <> Do ( Host expects to receive data from the device,
+ Device intends to receive data from the host)
+ (10) Ho <> Di (Host expects to send data to the device,
+ Di Device intends to send data to the host)
+ (13) Ho < Do (Host expects to send data to the device,
+ Device intends to receive data from the host)
+ */
+
+ status = USBH_MSC_PHASE_ERROR;
+ }
+ } /* CSW Tag Matching is Checked */
+ } /* CSW Signature Correct Checking */
+ else
+ {
+ /* If the CSW Signature is not valid, We sall return the Phase Error to
+ Upper Layers for Reset Recovery */
+
+ status = USBH_MSC_PHASE_ERROR;
+ }
+ } /* CSW Length Check*/
+ }
+
+ USBH_MSC_BOTXferParam.BOTXferStatus = status;
+ return status;
+}
+
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
+
+
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32_USB_HOST_Library/Class/MSC/src/usbh_msc_core.c b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_HOST_Library/Class/MSC/src/usbh_msc_core.c
new file mode 100644
index 0000000..f88632a
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_HOST_Library/Class/MSC/src/usbh_msc_core.c
@@ -0,0 +1,566 @@
+/**
+ ******************************************************************************
+ * @file usbh_msc_core.c
+ * @author MCD Application Team
+ * @version V2.1.0
+ * @date 19-March-2012
+ * @brief This file implements the MSC class driver functions
+ * ===================================================================
+ * MSC Class Description
+ * ===================================================================
+ * This module manages the MSC class V1.0 following the "Universal
+ * Serial Bus Mass Storage Class (MSC) Bulk-Only Transport (BOT) Version 1.0
+ * Sep. 31, 1999".
+ * This driver implements the following aspects of the specification:
+ * - Bulk-Only Transport protocol
+ * - Subclass : SCSI transparent command set (ref. SCSI Primary Commands - 3 (SPC-3))
+ *
+ * @endverbatim
+ *
+ ******************************************************************************
+ * @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 "usbh_msc_core.h"
+#include "usbh_msc_scsi.h"
+#include "usbh_msc_bot.h"
+#include "usbh_core.h"
+
+
+/** @addtogroup USBH_LIB
+ * @{
+ */
+
+/** @addtogroup USBH_CLASS
+ * @{
+ */
+
+/** @addtogroup USBH_MSC_CLASS
+ * @{
+ */
+
+/** @defgroup USBH_MSC_CORE
+ * @brief This file includes the mass storage related functions
+ * @{
+ */
+
+
+/** @defgroup USBH_MSC_CORE_Private_TypesDefinitions
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USBH_MSC_CORE_Private_Defines
+ * @{
+ */
+#define USBH_MSC_ERROR_RETRY_LIMIT 10
+/**
+ * @}
+ */
+
+/** @defgroup USBH_MSC_CORE_Private_Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup USBH_MSC_CORE_Private_Variables
+ * @{
+ */
+#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 MSC_Machine_TypeDef MSC_Machine __ALIGN_END ;
+
+#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 USB_Setup_TypeDef MSC_Setup __ALIGN_END ;
+uint8_t MSCErrorCount = 0;
+
+
+/**
+ * @}
+ */
+
+
+/** @defgroup USBH_MSC_CORE_Private_FunctionPrototypes
+ * @{
+ */
+
+static USBH_Status USBH_MSC_InterfaceInit (USB_OTG_CORE_HANDLE *pdev ,
+ void *phost);
+
+static void USBH_MSC_InterfaceDeInit (USB_OTG_CORE_HANDLE *pdev ,
+ void *phost);
+
+static USBH_Status USBH_MSC_Handle(USB_OTG_CORE_HANDLE *pdev ,
+ void *phost);
+
+static USBH_Status USBH_MSC_ClassRequest(USB_OTG_CORE_HANDLE *pdev ,
+ void *phost);
+
+static USBH_Status USBH_MSC_BOTReset(USB_OTG_CORE_HANDLE *pdev,
+ USBH_HOST *phost);
+static USBH_Status USBH_MSC_GETMaxLUN(USB_OTG_CORE_HANDLE *pdev,
+ USBH_HOST *phost);
+
+
+USBH_Class_cb_TypeDef USBH_MSC_cb =
+{
+ USBH_MSC_InterfaceInit,
+ USBH_MSC_InterfaceDeInit,
+ USBH_MSC_ClassRequest,
+ USBH_MSC_Handle,
+};
+
+void USBH_MSC_ErrorHandle(uint8_t status);
+
+/**
+ * @}
+ */
+
+
+/** @defgroup USBH_MSC_CORE_Exported_Variables
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+
+/** @defgroup USBH_MSC_CORE_Private_Functions
+ * @{
+ */
+
+
+/**
+ * @brief USBH_MSC_InterfaceInit
+ * Interface initialization for MSC class.
+ * @param pdev: Selected device
+ * @param hdev: Selected device property
+ * @retval USBH_Status : Status of class request handled.
+ */
+static USBH_Status USBH_MSC_InterfaceInit ( USB_OTG_CORE_HANDLE *pdev,
+ void *phost)
+{
+ USBH_HOST *pphost = phost;
+
+ if((pphost->device_prop.Itf_Desc[0].bInterfaceClass == MSC_CLASS) && \
+ (pphost->device_prop.Itf_Desc[0].bInterfaceProtocol == MSC_PROTOCOL))
+ {
+ if(pphost->device_prop.Ep_Desc[0][0].bEndpointAddress & 0x80)
+ {
+ MSC_Machine.MSBulkInEp = (pphost->device_prop.Ep_Desc[0][0].bEndpointAddress);
+ MSC_Machine.MSBulkInEpSize = pphost->device_prop.Ep_Desc[0][0].wMaxPacketSize;
+ }
+ else
+ {
+ MSC_Machine.MSBulkOutEp = (pphost->device_prop.Ep_Desc[0][0].bEndpointAddress);
+ MSC_Machine.MSBulkOutEpSize = pphost->device_prop.Ep_Desc[0] [0].wMaxPacketSize;
+ }
+
+ if(pphost->device_prop.Ep_Desc[0][1].bEndpointAddress & 0x80)
+ {
+ MSC_Machine.MSBulkInEp = (pphost->device_prop.Ep_Desc[0][1].bEndpointAddress);
+ MSC_Machine.MSBulkInEpSize = pphost->device_prop.Ep_Desc[0][1].wMaxPacketSize;
+ }
+ else
+ {
+ MSC_Machine.MSBulkOutEp = (pphost->device_prop.Ep_Desc[0][1].bEndpointAddress);
+ MSC_Machine.MSBulkOutEpSize = pphost->device_prop.Ep_Desc[0][1].wMaxPacketSize;
+ }
+
+ MSC_Machine.hc_num_out = USBH_Alloc_Channel(pdev,
+ MSC_Machine.MSBulkOutEp);
+ MSC_Machine.hc_num_in = USBH_Alloc_Channel(pdev,
+ MSC_Machine.MSBulkInEp);
+
+ /* Open the new channels */
+ USBH_Open_Channel (pdev,
+ MSC_Machine.hc_num_out,
+ pphost->device_prop.address,
+ pphost->device_prop.speed,
+ EP_TYPE_BULK,
+ MSC_Machine.MSBulkOutEpSize);
+
+ USBH_Open_Channel (pdev,
+ MSC_Machine.hc_num_in,
+ pphost->device_prop.address,
+ pphost->device_prop.speed,
+ EP_TYPE_BULK,
+ MSC_Machine.MSBulkInEpSize);
+
+ }
+
+ else
+ {
+ pphost->usr_cb->DeviceNotSupported();
+ }
+
+ return USBH_OK ;
+
+}
+
+
+/**
+ * @brief USBH_MSC_InterfaceDeInit
+ * De-Initialize interface by freeing host channels allocated to interface
+ * @param pdev: Selected device
+ * @param hdev: Selected device property
+ * @retval None
+ */
+void USBH_MSC_InterfaceDeInit ( USB_OTG_CORE_HANDLE *pdev,
+ void *phost)
+{
+ if ( MSC_Machine.hc_num_out)
+ {
+ USB_OTG_HC_Halt(pdev, MSC_Machine.hc_num_out);
+ USBH_Free_Channel (pdev, MSC_Machine.hc_num_out);
+ MSC_Machine.hc_num_out = 0; /* Reset the Channel as Free */
+ }
+
+ if ( MSC_Machine.hc_num_in)
+ {
+ USB_OTG_HC_Halt(pdev, MSC_Machine.hc_num_in);
+ USBH_Free_Channel (pdev, MSC_Machine.hc_num_in);
+ MSC_Machine.hc_num_in = 0; /* Reset the Channel as Free */
+ }
+}
+
+/**
+ * @brief USBH_MSC_ClassRequest
+ * This function will only initialize the MSC state machine
+ * @param pdev: Selected device
+ * @param hdev: Selected device property
+ * @retval USBH_Status : Status of class request handled.
+ */
+
+static USBH_Status USBH_MSC_ClassRequest(USB_OTG_CORE_HANDLE *pdev ,
+ void *phost)
+{
+
+ USBH_Status status = USBH_OK ;
+ USBH_MSC_BOTXferParam.MSCState = USBH_MSC_BOT_INIT_STATE;
+
+ return status;
+}
+
+
+/**
+ * @brief USBH_MSC_Handle
+ * MSC state machine handler
+ * @param pdev: Selected device
+ * @param hdev: Selected device property
+ * @retval USBH_Status
+ */
+
+static USBH_Status USBH_MSC_Handle(USB_OTG_CORE_HANDLE *pdev ,
+ void *phost)
+{
+ USBH_HOST *pphost = phost;
+
+ USBH_Status status = USBH_BUSY;
+ uint8_t mscStatus = USBH_MSC_BUSY;
+ uint8_t appliStatus = 0;
+
+ static uint8_t maxLunExceed = FALSE;
+
+
+ if(HCD_IsDeviceConnected(pdev))
+ {
+ switch(USBH_MSC_BOTXferParam.MSCState)
+ {
+ case USBH_MSC_BOT_INIT_STATE:
+ USBH_MSC_Init(pdev);
+ USBH_MSC_BOTXferParam.MSCState = USBH_MSC_BOT_RESET;
+ break;
+
+ case USBH_MSC_BOT_RESET:
+ /* Issue BOT RESET request */
+ status = USBH_MSC_BOTReset(pdev, phost);
+ if(status == USBH_OK )
+ {
+ USBH_MSC_BOTXferParam.MSCState = USBH_MSC_GET_MAX_LUN;
+ }
+
+ if(status == USBH_NOT_SUPPORTED )
+ {
+ /* If the Command has failed, then we need to move to Next State, after
+ STALL condition is cleared by Control-Transfer */
+ USBH_MSC_BOTXferParam.MSCStateBkp = USBH_MSC_GET_MAX_LUN;
+
+ /* a Clear Feature should be issued here */
+ USBH_MSC_BOTXferParam.MSCState = USBH_MSC_CTRL_ERROR_STATE;
+ }
+ break;
+
+ case USBH_MSC_GET_MAX_LUN:
+ /* Issue GetMaxLUN request */
+ status = USBH_MSC_GETMaxLUN(pdev, phost);
+
+ if(status == USBH_OK )
+ {
+ MSC_Machine.maxLun = *(MSC_Machine.buff) ;
+
+ /* If device has more that one logical unit then it is not supported */
+ if((MSC_Machine.maxLun > 0) && (maxLunExceed == FALSE))
+ {
+ maxLunExceed = TRUE;
+ pphost->usr_cb->DeviceNotSupported();
+
+ break;
+ }
+ USBH_MSC_BOTXferParam.MSCState = USBH_MSC_TEST_UNIT_READY;
+ }
+
+ if(status == USBH_NOT_SUPPORTED )
+ {
+ /* If the Command has failed, then we need to move to Next State, after
+ STALL condition is cleared by Control-Transfer */
+ USBH_MSC_BOTXferParam.MSCStateBkp = USBH_MSC_TEST_UNIT_READY;
+
+ /* a Clear Feature should be issued here */
+ USBH_MSC_BOTXferParam.MSCState = USBH_MSC_CTRL_ERROR_STATE;
+ }
+ break;
+
+ case USBH_MSC_CTRL_ERROR_STATE:
+ /* Issue Clearfeature request */
+ status = USBH_ClrFeature(pdev,
+ phost,
+ 0x00,
+ pphost->Control.hc_num_out);
+ if(status == USBH_OK )
+ {
+ /* If GetMaxLun Request not support, assume Single LUN configuration */
+ MSC_Machine.maxLun = 0;
+
+ USBH_MSC_BOTXferParam.MSCState = USBH_MSC_BOTXferParam.MSCStateBkp;
+ }
+ break;
+
+ case USBH_MSC_TEST_UNIT_READY:
+ /* Issue SCSI command TestUnitReady */
+ mscStatus = USBH_MSC_TestUnitReady(pdev);
+
+ if(mscStatus == USBH_MSC_OK )
+ {
+ USBH_MSC_BOTXferParam.MSCState = USBH_MSC_READ_CAPACITY10;
+ MSCErrorCount = 0;
+ status = USBH_OK;
+ }
+ else
+ {
+ USBH_MSC_ErrorHandle(mscStatus);
+ }
+ break;
+
+ case USBH_MSC_READ_CAPACITY10:
+ /* Issue READ_CAPACITY10 SCSI command */
+ mscStatus = USBH_MSC_ReadCapacity10(pdev);
+ if(mscStatus == USBH_MSC_OK )
+ {
+ USBH_MSC_BOTXferParam.MSCState = USBH_MSC_MODE_SENSE6;
+ MSCErrorCount = 0;
+ status = USBH_OK;
+ }
+ else
+ {
+ USBH_MSC_ErrorHandle(mscStatus);
+ }
+ break;
+
+ case USBH_MSC_MODE_SENSE6:
+ /* Issue ModeSense6 SCSI command for detecting if device is write-protected */
+ mscStatus = USBH_MSC_ModeSense6(pdev);
+ if(mscStatus == USBH_MSC_OK )
+ {
+ USBH_MSC_BOTXferParam.MSCState = USBH_MSC_DEFAULT_APPLI_STATE;
+ MSCErrorCount = 0;
+ status = USBH_OK;
+ }
+ else
+ {
+ USBH_MSC_ErrorHandle(mscStatus);
+ }
+ break;
+
+ case USBH_MSC_REQUEST_SENSE:
+ /* Issue RequestSense SCSI command for retreiving error code */
+ mscStatus = USBH_MSC_RequestSense(pdev);
+ if(mscStatus == USBH_MSC_OK )
+ {
+ USBH_MSC_BOTXferParam.MSCState = USBH_MSC_BOTXferParam.MSCStateBkp;
+ status = USBH_OK;
+ }
+ else
+ {
+ USBH_MSC_ErrorHandle(mscStatus);
+ }
+ break;
+
+ case USBH_MSC_BOT_USB_TRANSFERS:
+ /* Process the BOT state machine */
+ USBH_MSC_HandleBOTXfer(pdev , phost);
+ break;
+
+ case USBH_MSC_DEFAULT_APPLI_STATE:
+ /* Process Application callback for MSC */
+ appliStatus = pphost->usr_cb->UserApplication();
+ if(appliStatus == 0)
+ {
+ USBH_MSC_BOTXferParam.MSCState = USBH_MSC_DEFAULT_APPLI_STATE;
+ }
+ else if (appliStatus == 1)
+ {
+ /* De-init requested from application layer */
+ status = USBH_APPLY_DEINIT;
+ }
+ break;
+
+ case USBH_MSC_UNRECOVERED_STATE:
+
+ status = USBH_UNRECOVERED_ERROR;
+
+ break;
+
+ default:
+ break;
+
+ }
+ }
+ return status;
+}
+
+
+
+/**
+ * @brief USBH_MSC_BOTReset
+ * This request is used to reset the mass storage device and its
+ * associated interface. This class-specific request shall ready the
+ * device for the next CBW from the host.
+ * @param pdev: Selected device
+ * @retval USBH_Status : Status of class request handled.
+ */
+static USBH_Status USBH_MSC_BOTReset(USB_OTG_CORE_HANDLE *pdev,
+ USBH_HOST *phost)
+{
+
+ phost->Control.setup.b.bmRequestType = USB_H2D | USB_REQ_TYPE_CLASS | \
+ USB_REQ_RECIPIENT_INTERFACE;
+
+ phost->Control.setup.b.bRequest = USB_REQ_BOT_RESET;
+ phost->Control.setup.b.wValue.w = 0;
+ phost->Control.setup.b.wIndex.w = 0;
+ phost->Control.setup.b.wLength.w = 0;
+
+ return USBH_CtlReq(pdev, phost, 0 , 0 );
+}
+
+
+/**
+ * @brief USBH_MSC_GETMaxLUN
+ * This request is used to reset the mass storage device and its
+ * associated interface. This class-specific request shall ready the
+ * device for the next CBW from the host.
+ * @param pdev: Selected device
+ * @retval USBH_Status : USB ctl xfer status
+ */
+static USBH_Status USBH_MSC_GETMaxLUN(USB_OTG_CORE_HANDLE *pdev , USBH_HOST *phost)
+{
+ phost->Control.setup.b.bmRequestType = USB_D2H | USB_REQ_TYPE_CLASS | \
+ USB_REQ_RECIPIENT_INTERFACE;
+
+ phost->Control.setup.b.bRequest = USB_REQ_GET_MAX_LUN;
+ phost->Control.setup.b.wValue.w = 0;
+ phost->Control.setup.b.wIndex.w = 0;
+ phost->Control.setup.b.wLength.w = 1;
+
+ return USBH_CtlReq(pdev, phost, MSC_Machine.buff , 1 );
+}
+
+/**
+ * @brief USBH_MSC_ErrorHandle
+ * The function is for handling errors occuring during the MSC
+ * state machine
+ * @param status
+ * @retval None
+ */
+
+void USBH_MSC_ErrorHandle(uint8_t status)
+{
+ if(status == USBH_MSC_FAIL)
+ {
+ MSCErrorCount++;
+ if(MSCErrorCount < USBH_MSC_ERROR_RETRY_LIMIT)
+ { /* Try MSC level error recovery, Issue the request Sense to get
+ Drive error reason */
+ USBH_MSC_BOTXferParam.MSCState = USBH_MSC_REQUEST_SENSE;
+ USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE;
+ }
+ else
+ {
+ /* Error trials exceeded the limit, go to unrecovered state */
+ USBH_MSC_BOTXferParam.MSCState = USBH_MSC_UNRECOVERED_STATE;
+ }
+ }
+ else if(status == USBH_MSC_PHASE_ERROR)
+ {
+ /* Phase error, Go to Unrecoovered state */
+ USBH_MSC_BOTXferParam.MSCState = USBH_MSC_UNRECOVERED_STATE;
+ }
+ else if(status == USBH_MSC_BUSY)
+ {
+ /*No change in state*/
+ }
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32_USB_HOST_Library/Class/MSC/src/usbh_msc_fatfs.c b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_HOST_Library/Class/MSC/src/usbh_msc_fatfs.c
new file mode 100644
index 0000000..7c217c1
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_HOST_Library/Class/MSC/src/usbh_msc_fatfs.c
@@ -0,0 +1,186 @@
+
+#include "usb_conf.h"
+#include "diskio.h"
+#include "usbh_msc_core.h"
+/*--------------------------------------------------------------------------
+
+Module Private Functions and Variables
+
+---------------------------------------------------------------------------*/
+
+static volatile DSTATUS Stat = STA_NOINIT; /* Disk status */
+
+extern USB_OTG_CORE_HANDLE USB_OTG_Core;
+extern USBH_HOST USB_Host;
+
+/*-----------------------------------------------------------------------*/
+/* Initialize Disk Drive */
+/*-----------------------------------------------------------------------*/
+
+DSTATUS disk_initialize (
+ BYTE drv /* Physical drive number (0) */
+ )
+{
+
+ if(HCD_IsDeviceConnected(&USB_OTG_Core))
+ {
+ Stat &= ~STA_NOINIT;
+ }
+
+ return Stat;
+
+
+}
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Get Disk Status */
+/*-----------------------------------------------------------------------*/
+
+DSTATUS disk_status (
+ BYTE drv /* Physical drive number (0) */
+ )
+{
+ if (drv) return STA_NOINIT; /* Supports only single drive */
+ return Stat;
+}
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Read Sector(s) */
+/*-----------------------------------------------------------------------*/
+
+DRESULT disk_read (
+ BYTE drv, /* Physical drive number (0) */
+ BYTE *buff, /* Pointer to the data buffer to store read data */
+ DWORD sector, /* Start sector number (LBA) */
+ BYTE count /* Sector count (1..255) */
+ )
+{
+ BYTE status = USBH_MSC_OK;
+
+ if (drv || !count) return RES_PARERR;
+ if (Stat & STA_NOINIT) return RES_NOTRDY;
+
+
+ if(HCD_IsDeviceConnected(&USB_OTG_Core))
+ {
+
+ do
+ {
+ status = USBH_MSC_Read10(&USB_OTG_Core, buff,sector,512 * count);
+ USBH_MSC_HandleBOTXfer(&USB_OTG_Core ,&USB_Host);
+
+ if(!HCD_IsDeviceConnected(&USB_OTG_Core))
+ {
+ return RES_ERROR;
+ }
+ }
+ while(status == USBH_MSC_BUSY );
+ }
+
+ if(status == USBH_MSC_OK)
+ return RES_OK;
+ return RES_ERROR;
+
+}
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Write Sector(s) */
+/*-----------------------------------------------------------------------*/
+
+#if _READONLY == 0
+DRESULT disk_write (
+ BYTE drv, /* Physical drive number (0) */
+ const BYTE *buff, /* Pointer to the data to be written */
+ DWORD sector, /* Start sector number (LBA) */
+ BYTE count /* Sector count (1..255) */
+ )
+{
+ BYTE status = USBH_MSC_OK;
+ if (drv || !count) return RES_PARERR;
+ if (Stat & STA_NOINIT) return RES_NOTRDY;
+ if (Stat & STA_PROTECT) return RES_WRPRT;
+
+
+ if(HCD_IsDeviceConnected(&USB_OTG_Core))
+ {
+ do
+ {
+ status = USBH_MSC_Write10(&USB_OTG_Core,(BYTE*)buff,sector,512 * count);
+ USBH_MSC_HandleBOTXfer(&USB_OTG_Core, &USB_Host);
+
+ if(!HCD_IsDeviceConnected(&USB_OTG_Core))
+ {
+ return RES_ERROR;
+ }
+ }
+
+ while(status == USBH_MSC_BUSY );
+
+ }
+
+ if(status == USBH_MSC_OK)
+ return RES_OK;
+ return RES_ERROR;
+}
+#endif /* _READONLY == 0 */
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Miscellaneous Functions */
+/*-----------------------------------------------------------------------*/
+
+#if _USE_IOCTL != 0
+DRESULT disk_ioctl (
+ BYTE drv, /* Physical drive number (0) */
+ BYTE ctrl, /* Control code */
+ void *buff /* Buffer to send/receive control data */
+ )
+{
+ DRESULT res = RES_OK;
+
+ if (drv) return RES_PARERR;
+
+ res = RES_ERROR;
+
+ if (Stat & STA_NOINIT) return RES_NOTRDY;
+
+ switch (ctrl) {
+ case CTRL_SYNC : /* Make sure that no pending write process */
+
+ res = RES_OK;
+ break;
+
+ case GET_SECTOR_COUNT : /* Get number of sectors on the disk (DWORD) */
+
+ *(DWORD*)buff = (DWORD) USBH_MSC_Param.MSCapacity;
+ res = RES_OK;
+ break;
+
+ case GET_SECTOR_SIZE : /* Get R/W sector size (WORD) */
+ *(WORD*)buff = 512;
+ res = RES_OK;
+ break;
+
+ case GET_BLOCK_SIZE : /* Get erase block size in unit of sector (DWORD) */
+
+ *(DWORD*)buff = 512;
+
+ break;
+
+
+ default:
+ res = RES_PARERR;
+ }
+
+
+
+ return res;
+}
+#endif /* _USE_IOCTL != 0 */
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32_USB_HOST_Library/Class/MSC/src/usbh_msc_scsi.c b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_HOST_Library/Class/MSC/src/usbh_msc_scsi.c
new file mode 100644
index 0000000..bb49659
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_HOST_Library/Class/MSC/src/usbh_msc_scsi.c
@@ -0,0 +1,680 @@
+/**
+ ******************************************************************************
+ * @file usbh_msc_scsi.c
+ * @author MCD Application Team
+ * @version V2.1.0
+ * @date 19-March-2012
+ * @brief This file implements the SCSI commands
+ ******************************************************************************
+ * @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 "usbh_msc_core.h"
+#include "usbh_msc_scsi.h"
+#include "usbh_msc_bot.h"
+#include "usbh_ioreq.h"
+#include "usbh_def.h"
+
+
+/** @addtogroup USBH_LIB
+ * @{
+ */
+
+/** @addtogroup USBH_CLASS
+ * @{
+ */
+
+/** @addtogroup USBH_MSC_CLASS
+ * @{
+ */
+
+/** @defgroup USBH_MSC_SCSI
+ * @brief This file includes the mass storage related functions
+ * @{
+ */
+
+
+/** @defgroup USBH_MSC_SCSI_Private_TypesDefinitions
+ * @{
+ */
+
+MassStorageParameter_TypeDef USBH_MSC_Param;
+/**
+ * @}
+ */
+
+/** @defgroup USBH_MSC_SCSI_Private_Defines
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USBH_MSC_SCSI_Private_Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup USBH_MSC_SCSI_Private_Variables
+ * @{
+ */
+
+#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 USBH_DataInBuffer[512] __ALIGN_END ;
+
+#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 USBH_DataOutBuffer[512] __ALIGN_END ;
+/**
+ * @}
+ */
+
+
+/** @defgroup USBH_MSC_SCSI_Private_FunctionPrototypes
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup USBH_MSC_SCSI_Exported_Variables
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+
+/** @defgroup USBH_MSC_SCSI_Private_Functions
+ * @{
+ */
+
+
+
+
+/**
+ * @brief USBH_MSC_TestUnitReady
+ * Issues 'Test unit ready' command to the device. Once the response
+ * received, it updates the status to upper layer.
+ * @param None
+ * @retval Status
+ */
+uint8_t USBH_MSC_TestUnitReady (USB_OTG_CORE_HANDLE *pdev)
+{
+ uint8_t index;
+ USBH_MSC_Status_TypeDef status = USBH_MSC_BUSY;
+
+ if(HCD_IsDeviceConnected(pdev))
+ {
+ switch(USBH_MSC_BOTXferParam.CmdStateMachine)
+ {
+ case CMD_SEND_STATE:
+ /*Prepare the CBW and relevent field*/
+ USBH_MSC_CBWData.field.CBWTransferLength = 0; /* No Data Transfer */
+ USBH_MSC_CBWData.field.CBWFlags = USB_EP_DIR_OUT;
+ USBH_MSC_CBWData.field.CBWLength = CBW_LENGTH_TEST_UNIT_READY;
+ USBH_MSC_BOTXferParam.pRxTxBuff = USBH_MSC_CSWData.CSWArray;
+ USBH_MSC_BOTXferParam.DataLength = USBH_MSC_CSW_MAX_LENGTH;
+ USBH_MSC_BOTXferParam.MSCStateCurrent = USBH_MSC_TEST_UNIT_READY;
+
+ for(index = CBW_CB_LENGTH; index != 0; index--)
+ {
+ USBH_MSC_CBWData.field.CBWCB[index] = 0x00;
+ }
+
+ USBH_MSC_CBWData.field.CBWCB[0] = OPCODE_TEST_UNIT_READY;
+ USBH_MSC_BOTXferParam.BOTState = USBH_MSC_SEND_CBW;
+ /* Start the transfer, then let the state
+ machine magage the other transactions */
+ USBH_MSC_BOTXferParam.MSCState = USBH_MSC_BOT_USB_TRANSFERS;
+ USBH_MSC_BOTXferParam.BOTXferStatus = USBH_MSC_BUSY;
+ USBH_MSC_BOTXferParam.CmdStateMachine = CMD_WAIT_STATUS;
+
+ status = USBH_MSC_BUSY;
+ break;
+
+ case CMD_WAIT_STATUS:
+ if(USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_OK)
+ {
+ /* Commands successfully sent and Response Received */
+ USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE;
+
+ status = USBH_MSC_OK;
+ }
+ else if ( USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_FAIL )
+ {
+ /* Failure Mode */
+ USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE;
+ status = USBH_MSC_FAIL;
+ }
+
+ else if ( USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_PHASE_ERROR )
+ {
+ /* Failure Mode */
+ USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE;
+ status = USBH_MSC_PHASE_ERROR;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ return status;
+}
+
+
+/**
+ * @brief USBH_MSC_ReadCapacity10
+ * Issue the read capacity command to the device. Once the response
+ * received, it updates the status to upper layer
+ * @param None
+ * @retval Status
+ */
+uint8_t USBH_MSC_ReadCapacity10(USB_OTG_CORE_HANDLE *pdev)
+{
+ uint8_t index;
+ USBH_MSC_Status_TypeDef status = USBH_MSC_BUSY;
+
+ if(HCD_IsDeviceConnected(pdev))
+ {
+ switch(USBH_MSC_BOTXferParam.CmdStateMachine)
+ {
+ case CMD_SEND_STATE:
+ /*Prepare the CBW and relevent field*/
+ USBH_MSC_CBWData.field.CBWTransferLength = XFER_LEN_READ_CAPACITY10;
+ USBH_MSC_CBWData.field.CBWFlags = USB_EP_DIR_IN;
+ USBH_MSC_CBWData.field.CBWLength = CBW_LENGTH;
+
+ USBH_MSC_BOTXferParam.pRxTxBuff = USBH_DataInBuffer;
+ USBH_MSC_BOTXferParam.MSCStateCurrent = USBH_MSC_READ_CAPACITY10;
+
+ for(index = CBW_CB_LENGTH; index != 0; index--)
+ {
+ USBH_MSC_CBWData.field.CBWCB[index] = 0x00;
+ }
+
+ USBH_MSC_CBWData.field.CBWCB[0] = OPCODE_READ_CAPACITY10;
+ USBH_MSC_BOTXferParam.BOTState = USBH_MSC_SEND_CBW;
+
+ /* Start the transfer, then let the state machine manage the other
+ transactions */
+ USBH_MSC_BOTXferParam.MSCState = USBH_MSC_BOT_USB_TRANSFERS;
+ USBH_MSC_BOTXferParam.BOTXferStatus = USBH_MSC_BUSY;
+ USBH_MSC_BOTXferParam.CmdStateMachine = CMD_WAIT_STATUS;
+
+ status = USBH_MSC_BUSY;
+ break;
+
+ case CMD_WAIT_STATUS:
+ if(USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_OK)
+ {
+ /*assign the capacity*/
+ (((uint8_t*)&USBH_MSC_Param.MSCapacity )[3]) = USBH_DataInBuffer[0];
+ (((uint8_t*)&USBH_MSC_Param.MSCapacity )[2]) = USBH_DataInBuffer[1];
+ (((uint8_t*)&USBH_MSC_Param.MSCapacity )[1]) = USBH_DataInBuffer[2];
+ (((uint8_t*)&USBH_MSC_Param.MSCapacity )[0]) = USBH_DataInBuffer[3];
+
+ /*assign the page length*/
+ (((uint8_t*)&USBH_MSC_Param.MSPageLength )[1]) = USBH_DataInBuffer[6];
+ (((uint8_t*)&USBH_MSC_Param.MSPageLength )[0]) = USBH_DataInBuffer[7];
+
+ /* Commands successfully sent and Response Received */
+ USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE;
+ status = USBH_MSC_OK;
+ }
+ else if ( USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_FAIL )
+ {
+ /* Failure Mode */
+ USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE;
+ status = USBH_MSC_FAIL;
+ }
+ else if ( USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_PHASE_ERROR )
+ {
+ /* Failure Mode */
+ USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE;
+ status = USBH_MSC_PHASE_ERROR;
+ }
+ else
+ {
+ /* Wait for the Commands to get Completed */
+ /* NO Change in state Machine */
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ return status;
+}
+
+
+/**
+ * @brief USBH_MSC_ModeSense6
+ * Issue the Mode Sense6 Command to the device. This function is used
+ * for reading the WriteProtect Status of the Mass-Storage device.
+ * @param None
+ * @retval Status
+ */
+uint8_t USBH_MSC_ModeSense6(USB_OTG_CORE_HANDLE *pdev)
+{
+ uint8_t index;
+ USBH_MSC_Status_TypeDef status = USBH_MSC_BUSY;
+
+ if(HCD_IsDeviceConnected(pdev))
+ {
+ switch(USBH_MSC_BOTXferParam.CmdStateMachine)
+ {
+ case CMD_SEND_STATE:
+ /*Prepare the CBW and relevent field*/
+ USBH_MSC_CBWData.field.CBWTransferLength = XFER_LEN_MODE_SENSE6;
+ USBH_MSC_CBWData.field.CBWFlags = USB_EP_DIR_IN;
+ USBH_MSC_CBWData.field.CBWLength = CBW_LENGTH;
+
+ USBH_MSC_BOTXferParam.pRxTxBuff = USBH_DataInBuffer;
+ USBH_MSC_BOTXferParam.MSCStateCurrent = USBH_MSC_MODE_SENSE6;
+
+ for(index = CBW_CB_LENGTH; index != 0; index--)
+ {
+ USBH_MSC_CBWData.field.CBWCB[index] = 0x00;
+ }
+
+ USBH_MSC_CBWData.field.CBWCB[0] = OPCODE_MODE_SENSE6;
+ USBH_MSC_CBWData.field.CBWCB[2] = MODE_SENSE_PAGE_CONTROL_FIELD | \
+ MODE_SENSE_PAGE_CODE;
+
+ USBH_MSC_CBWData.field.CBWCB[4] = XFER_LEN_MODE_SENSE6;
+
+ USBH_MSC_BOTXferParam.BOTState = USBH_MSC_SEND_CBW;
+
+ /* Start the transfer, then let the state machine manage the other
+ transactions */
+ USBH_MSC_BOTXferParam.MSCState = USBH_MSC_BOT_USB_TRANSFERS;
+ USBH_MSC_BOTXferParam.BOTXferStatus = USBH_MSC_BUSY;
+ USBH_MSC_BOTXferParam.CmdStateMachine = CMD_WAIT_STATUS;
+
+ status = USBH_MSC_BUSY;
+ break;
+
+ case CMD_WAIT_STATUS:
+ if(USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_OK)
+ {
+ /* Assign the Write Protect status */
+ /* If WriteProtect = 0, Writing is allowed
+ If WriteProtect != 0, Disk is Write Protected */
+ if ( USBH_DataInBuffer[2] & MASK_MODE_SENSE_WRITE_PROTECT)
+ {
+ USBH_MSC_Param.MSWriteProtect = DISK_WRITE_PROTECTED;
+ }
+ else
+ {
+ USBH_MSC_Param.MSWriteProtect = 0;
+ }
+
+ /* Commands successfully sent and Response Received */
+ USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE;
+ status = USBH_MSC_OK;
+ }
+ else if ( USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_FAIL )
+ {
+ /* Failure Mode */
+ USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE;
+ status = USBH_MSC_FAIL;
+ }
+ else if ( USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_PHASE_ERROR )
+ {
+ /* Failure Mode */
+ USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE;
+ status = USBH_MSC_PHASE_ERROR;
+ }
+ else
+ {
+ /* Wait for the Commands to get Completed */
+ /* NO Change in state Machine */
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ return status;
+}
+
+/**
+ * @brief USBH_MSC_RequestSense
+ * Issues the Request Sense command to the device. Once the response
+ * received, it updates the status to upper layer
+ * @param None
+ * @retval Status
+ */
+uint8_t USBH_MSC_RequestSense(USB_OTG_CORE_HANDLE *pdev)
+{
+ USBH_MSC_Status_TypeDef status = USBH_MSC_BUSY;
+
+ uint8_t index;
+
+
+ if(HCD_IsDeviceConnected(pdev))
+ {
+ switch(USBH_MSC_BOTXferParam.CmdStateMachine)
+ {
+ case CMD_SEND_STATE:
+
+ /*Prepare the CBW and relevent field*/
+ USBH_MSC_CBWData.field.CBWTransferLength = \
+ ALLOCATION_LENGTH_REQUEST_SENSE;
+ USBH_MSC_CBWData.field.CBWFlags = USB_EP_DIR_IN;
+ USBH_MSC_CBWData.field.CBWLength = CBW_LENGTH;
+
+ USBH_MSC_BOTXferParam.pRxTxBuff = USBH_DataInBuffer;
+ USBH_MSC_BOTXferParam.MSCStateBkp = USBH_MSC_BOTXferParam.MSCStateCurrent;
+ USBH_MSC_BOTXferParam.MSCStateCurrent = USBH_MSC_REQUEST_SENSE;
+
+
+ for(index = CBW_CB_LENGTH; index != 0; index--)
+ {
+ USBH_MSC_CBWData.field.CBWCB[index] = 0x00;
+ }
+
+ USBH_MSC_CBWData.field.CBWCB[0] = OPCODE_REQUEST_SENSE;
+ USBH_MSC_CBWData.field.CBWCB[1] = DESC_REQUEST_SENSE;
+ USBH_MSC_CBWData.field.CBWCB[4] = ALLOCATION_LENGTH_REQUEST_SENSE;
+
+ USBH_MSC_BOTXferParam.BOTState = USBH_MSC_SEND_CBW;
+ /* Start the transfer, then let the state machine magage
+ the other transactions */
+ USBH_MSC_BOTXferParam.MSCState = USBH_MSC_BOT_USB_TRANSFERS;
+ USBH_MSC_BOTXferParam.BOTXferStatus = USBH_MSC_BUSY;
+ USBH_MSC_BOTXferParam.CmdStateMachine = CMD_WAIT_STATUS;
+
+ status = USBH_MSC_BUSY;
+
+ break;
+
+ case CMD_WAIT_STATUS:
+
+ if(USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_OK)
+ {
+ /* Get Sense data*/
+ (((uint8_t*)&USBH_MSC_Param.MSSenseKey )[3]) = USBH_DataInBuffer[0];
+ (((uint8_t*)&USBH_MSC_Param.MSSenseKey )[2]) = USBH_DataInBuffer[1];
+ (((uint8_t*)&USBH_MSC_Param.MSSenseKey )[1]) = USBH_DataInBuffer[2];
+ (((uint8_t*)&USBH_MSC_Param.MSSenseKey )[0]) = USBH_DataInBuffer[3];
+
+ /* Commands successfully sent and Response Received */
+ USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE;
+ status = USBH_MSC_OK;
+ }
+ else if ( USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_FAIL )
+ {
+ /* Failure Mode */
+ USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE;
+ status = USBH_MSC_FAIL;
+ }
+
+ else if ( USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_PHASE_ERROR )
+ {
+ /* Failure Mode */
+ USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE;
+ status = USBH_MSC_PHASE_ERROR;
+ }
+
+ else
+ {
+ /* Wait for the Commands to get Completed */
+ /* NO Change in state Machine */
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ return status;
+}
+
+
+/**
+ * @brief USBH_MSC_Write10
+ * Issue the write command to the device. Once the response received,
+ * it updates the status to upper layer
+ * @param dataBuffer : DataBuffer contains the data to write
+ * @param address : Address to which the data will be written
+ * @param nbOfbytes : NbOfbytes to be written
+ * @retval Status
+ */
+uint8_t USBH_MSC_Write10(USB_OTG_CORE_HANDLE *pdev,
+ uint8_t *dataBuffer,
+ uint32_t address,
+ uint32_t nbOfbytes)
+{
+ uint8_t index;
+ USBH_MSC_Status_TypeDef status = USBH_MSC_BUSY;
+ uint16_t nbOfPages;
+
+ if(HCD_IsDeviceConnected(pdev))
+ {
+ switch(USBH_MSC_BOTXferParam.CmdStateMachine)
+ {
+ case CMD_SEND_STATE:
+ USBH_MSC_CBWData.field.CBWTransferLength = nbOfbytes;
+ USBH_MSC_CBWData.field.CBWFlags = USB_EP_DIR_OUT;
+ USBH_MSC_CBWData.field.CBWLength = CBW_LENGTH;
+ USBH_MSC_BOTXferParam.pRxTxBuff = dataBuffer;
+
+
+ for(index = CBW_CB_LENGTH; index != 0; index--)
+ {
+ USBH_MSC_CBWData.field.CBWCB[index] = 0x00;
+ }
+
+ USBH_MSC_CBWData.field.CBWCB[0] = OPCODE_WRITE10;
+
+ /*logical block address*/
+ USBH_MSC_CBWData.field.CBWCB[2] = (((uint8_t*)&address)[3]) ;
+ USBH_MSC_CBWData.field.CBWCB[3] = (((uint8_t*)&address)[2]);
+ USBH_MSC_CBWData.field.CBWCB[4] = (((uint8_t*)&address)[1]);
+ USBH_MSC_CBWData.field.CBWCB[5] = (((uint8_t*)&address)[0]);
+
+ /*USBH_MSC_PAGE_LENGTH = 512*/
+ nbOfPages = nbOfbytes/ USBH_MSC_PAGE_LENGTH;
+
+ /*Tranfer length */
+ USBH_MSC_CBWData.field.CBWCB[7] = (((uint8_t *)&nbOfPages)[1]) ;
+ USBH_MSC_CBWData.field.CBWCB[8] = (((uint8_t *)&nbOfPages)[0]) ;
+
+ USBH_MSC_BOTXferParam.BOTState = USBH_MSC_SEND_CBW;
+ /* Start the transfer, then let the state machine
+ magage the other transactions */
+ USBH_MSC_BOTXferParam.MSCState = USBH_MSC_BOT_USB_TRANSFERS;
+ USBH_MSC_BOTXferParam.BOTXferStatus = USBH_MSC_BUSY;
+ USBH_MSC_BOTXferParam.CmdStateMachine = CMD_WAIT_STATUS;
+
+ status = USBH_MSC_BUSY;
+
+ break;
+
+ case CMD_WAIT_STATUS:
+ if(USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_OK)
+ {
+ /* Commands successfully sent and Response Received */
+ USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE;
+ status = USBH_MSC_OK;
+ }
+ else if ( USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_FAIL )
+ {
+ /* Failure Mode */
+ USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE;
+ }
+
+ else if ( USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_PHASE_ERROR )
+ {
+ /* Failure Mode */
+ USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE;
+ status = USBH_MSC_PHASE_ERROR;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ return status;
+}
+
+/**
+ * @brief USBH_MSC_Read10
+ * Issue the read command to the device. Once the response received,
+ * it updates the status to upper layer
+ * @param dataBuffer : DataBuffer will contain the data to be read
+ * @param address : Address from which the data will be read
+ * @param nbOfbytes : NbOfbytes to be read
+ * @retval Status
+ */
+uint8_t USBH_MSC_Read10(USB_OTG_CORE_HANDLE *pdev,
+ uint8_t *dataBuffer,
+ uint32_t address,
+ uint32_t nbOfbytes)
+{
+ uint8_t index;
+ static USBH_MSC_Status_TypeDef status = USBH_MSC_BUSY;
+ uint16_t nbOfPages;
+ status = USBH_MSC_BUSY;
+
+ if(HCD_IsDeviceConnected(pdev))
+ {
+ switch(USBH_MSC_BOTXferParam.CmdStateMachine)
+ {
+ case CMD_SEND_STATE:
+ /*Prepare the CBW and relevent field*/
+ USBH_MSC_CBWData.field.CBWTransferLength = nbOfbytes;
+ USBH_MSC_CBWData.field.CBWFlags = USB_EP_DIR_IN;
+ USBH_MSC_CBWData.field.CBWLength = CBW_LENGTH;
+
+ USBH_MSC_BOTXferParam.pRxTxBuff = dataBuffer;
+
+ for(index = CBW_CB_LENGTH; index != 0; index--)
+ {
+ USBH_MSC_CBWData.field.CBWCB[index] = 0x00;
+ }
+
+ USBH_MSC_CBWData.field.CBWCB[0] = OPCODE_READ10;
+
+ /*logical block address*/
+
+ USBH_MSC_CBWData.field.CBWCB[2] = (((uint8_t*)&address)[3]);
+ USBH_MSC_CBWData.field.CBWCB[3] = (((uint8_t*)&address)[2]);
+ USBH_MSC_CBWData.field.CBWCB[4] = (((uint8_t*)&address)[1]);
+ USBH_MSC_CBWData.field.CBWCB[5] = (((uint8_t*)&address)[0]);
+
+ /*USBH_MSC_PAGE_LENGTH = 512*/
+ nbOfPages = nbOfbytes/ USBH_MSC_PAGE_LENGTH;
+
+ /*Tranfer length */
+ USBH_MSC_CBWData.field.CBWCB[7] = (((uint8_t *)&nbOfPages)[1]) ;
+ USBH_MSC_CBWData.field.CBWCB[8] = (((uint8_t *)&nbOfPages)[0]) ;
+
+
+ USBH_MSC_BOTXferParam.BOTState = USBH_MSC_SEND_CBW;
+ /* Start the transfer, then let the state machine
+ magage the other transactions */
+ USBH_MSC_BOTXferParam.MSCState = USBH_MSC_BOT_USB_TRANSFERS;
+ USBH_MSC_BOTXferParam.BOTXferStatus = USBH_MSC_BUSY;
+ USBH_MSC_BOTXferParam.CmdStateMachine = CMD_WAIT_STATUS;
+
+ status = USBH_MSC_BUSY;
+
+ break;
+
+ case CMD_WAIT_STATUS:
+
+ if((USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_OK) && \
+ (HCD_IsDeviceConnected(pdev)))
+ {
+ /* Commands successfully sent and Response Received */
+ USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE;
+ status = USBH_MSC_OK;
+ }
+ else if (( USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_FAIL ) && \
+ (HCD_IsDeviceConnected(pdev)))
+ {
+ /* Failure Mode */
+ USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE;
+ }
+
+ else if ( USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_PHASE_ERROR )
+ {
+ /* Failure Mode */
+ USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE;
+ status = USBH_MSC_PHASE_ERROR;
+ }
+ else
+ {
+ /* Wait for the Commands to get Completed */
+ /* NO Change in state Machine */
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ return status;
+}
+
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
+
+
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32_USB_HOST_Library/Core/inc/usbh_conf_template.h b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_HOST_Library/Core/inc/usbh_conf_template.h
new file mode 100644
index 0000000..9e7f8ff
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_HOST_Library/Core/inc/usbh_conf_template.h
@@ -0,0 +1,101 @@
+/**
+ ******************************************************************************
+ * @file usbh_conf_template
+ * @author MCD Application Team
+ * @version V2.1.0
+ * @date 19-March-2012
+ * @brief General USB Host library 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 __USBH_CONF__H__
+#define __USBH_CONF__H__
+
+/* Includes ------------------------------------------------------------------*/
+
+/** @addtogroup USBH_OTG_DRIVER
+ * @{
+ */
+
+/** @defgroup USBH_CONF
+ * @brief usb otg low level driver configuration file
+ * @{
+ */
+
+/** @defgroup USBH_CONF_Exported_Defines
+ * @{
+ */
+
+#define USBH_MAX_NUM_ENDPOINTS 2
+#define USBH_MAX_NUM_INTERFACES 2
+#ifdef USE_USB_OTG_FS
+#define USBH_MSC_MPS_SIZE 0x40
+#else
+#define USBH_MSC_MPS_SIZE 0x200
+#endif
+
+/**
+ * @}
+ */
+
+
+/** @defgroup USBH_CONF_Exported_Types
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup USBH_CONF_Exported_Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USBH_CONF_Exported_Variables
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USBH_CONF_Exported_FunctionsPrototype
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+#endif //__USBH_CONF__H__
+
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32_USB_HOST_Library/Core/inc/usbh_core.h b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_HOST_Library/Core/inc/usbh_core.h
new file mode 100644
index 0000000..97a7c9b
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_HOST_Library/Core/inc/usbh_core.h
@@ -0,0 +1,295 @@
+/**
+ ******************************************************************************
+ * @file usbh_core.h
+ * @author MCD Application Team
+ * @version V2.1.0
+ * @date 19-March-2012
+ * @brief Header file for usbh_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 ----------------------------------------------*/
+#ifndef __USBH_CORE_H
+#define __USBH_CORE_H
+
+/* Includes ------------------------------------------------------------------*/
+#include "usb_hcd.h"
+#include "usbh_def.h"
+#include "usbh_conf.h"
+
+/** @addtogroup USBH_LIB
+ * @{
+ */
+
+/** @addtogroup USBH_LIB_CORE
+* @{
+*/
+
+/** @defgroup USBH_CORE
+ * @brief This file is the Header file for usbh_core.c
+ * @{
+ */
+
+
+/** @defgroup USBH_CORE_Exported_Defines
+ * @{
+ */
+
+#define MSC_CLASS 0x08
+#define HID_CLASS 0x03
+#define MSC_PROTOCOL 0x50
+#define CBI_PROTOCOL 0x01
+
+
+#define USBH_MAX_ERROR_COUNT 2
+#define USBH_DEVICE_ADDRESS_DEFAULT 0
+#define USBH_DEVICE_ADDRESS 1
+
+
+/**
+ * @}
+ */
+
+
+/** @defgroup USBH_CORE_Exported_Types
+ * @{
+ */
+
+typedef enum {
+ USBH_OK = 0,
+ USBH_BUSY,
+ USBH_FAIL,
+ USBH_NOT_SUPPORTED,
+ USBH_UNRECOVERED_ERROR,
+ USBH_ERROR_SPEED_UNKNOWN,
+ USBH_APPLY_DEINIT
+}USBH_Status;
+
+/* Following states are used for gState */
+typedef enum {
+ HOST_IDLE =0,
+ HOST_DEV_ATTACHED,
+ HOST_DEV_DISCONNECTED,
+ HOST_DETECT_DEVICE_SPEED,
+ HOST_ENUMERATION,
+ HOST_CLASS_REQUEST,
+ HOST_CLASS,
+ HOST_CTRL_XFER,
+ HOST_USR_INPUT,
+ HOST_SUSPENDED,
+ HOST_ERROR_STATE
+}HOST_State;
+
+/* Following states are used for EnumerationState */
+typedef enum {
+ ENUM_IDLE = 0,
+ ENUM_GET_FULL_DEV_DESC,
+ ENUM_SET_ADDR,
+ ENUM_GET_CFG_DESC,
+ ENUM_GET_FULL_CFG_DESC,
+ ENUM_GET_MFC_STRING_DESC,
+ ENUM_GET_PRODUCT_STRING_DESC,
+ ENUM_GET_SERIALNUM_STRING_DESC,
+ ENUM_SET_CONFIGURATION,
+ ENUM_DEV_CONFIGURED
+} ENUM_State;
+
+
+
+/* Following states are used for CtrlXferStateMachine */
+typedef enum {
+ CTRL_IDLE =0,
+ CTRL_SETUP,
+ CTRL_SETUP_WAIT,
+ CTRL_DATA_IN,
+ CTRL_DATA_IN_WAIT,
+ CTRL_DATA_OUT,
+ CTRL_DATA_OUT_WAIT,
+ CTRL_STATUS_IN,
+ CTRL_STATUS_IN_WAIT,
+ CTRL_STATUS_OUT,
+ CTRL_STATUS_OUT_WAIT,
+ CTRL_ERROR,
+ CTRL_STALLED,
+ CTRL_COMPLETE
+}
+CTRL_State;
+
+typedef enum {
+ USBH_USR_NO_RESP = 0,
+ USBH_USR_RESP_OK = 1,
+}
+USBH_USR_Status;
+
+/* Following states are used for RequestState */
+typedef enum {
+ CMD_IDLE =0,
+ CMD_SEND,
+ CMD_WAIT
+} CMD_State;
+
+
+
+typedef struct _Ctrl
+{
+ uint8_t hc_num_in;
+ uint8_t hc_num_out;
+ uint8_t ep0size;
+ uint8_t *buff;
+ uint16_t length;
+ uint8_t errorcount;
+ uint16_t timer;
+ CTRL_STATUS status;
+ USB_Setup_TypeDef setup;
+ CTRL_State state;
+
+} USBH_Ctrl_TypeDef;
+
+
+
+typedef struct _DeviceProp
+{
+
+ uint8_t address;
+ uint8_t speed;
+ USBH_DevDesc_TypeDef Dev_Desc;
+ USBH_CfgDesc_TypeDef Cfg_Desc;
+ USBH_InterfaceDesc_TypeDef Itf_Desc[USBH_MAX_NUM_INTERFACES];
+ USBH_EpDesc_TypeDef Ep_Desc[USBH_MAX_NUM_INTERFACES][USBH_MAX_NUM_ENDPOINTS];
+ USBH_HIDDesc_TypeDef HID_Desc;
+
+}USBH_Device_TypeDef;
+
+typedef struct _USBH_Class_cb
+{
+ USBH_Status (*Init)\
+ (USB_OTG_CORE_HANDLE *pdev , void *phost);
+ void (*DeInit)\
+ (USB_OTG_CORE_HANDLE *pdev , void *phost);
+ USBH_Status (*Requests)\
+ (USB_OTG_CORE_HANDLE *pdev , void *phost);
+ USBH_Status (*Machine)\
+ (USB_OTG_CORE_HANDLE *pdev , void *phost);
+
+} USBH_Class_cb_TypeDef;
+
+
+typedef struct _USBH_USR_PROP
+{
+ void (*Init)(void); /* HostLibInitialized */
+ void (*DeInit)(void); /* HostLibInitialized */
+ void (*DeviceAttached)(void); /* DeviceAttached */
+ void (*ResetDevice)(void);
+ void (*DeviceDisconnected)(void);
+ void (*OverCurrentDetected)(void);
+ void (*DeviceSpeedDetected)(uint8_t DeviceSpeed); /* DeviceSpeed */
+ void (*DeviceDescAvailable)(void *); /* DeviceDescriptor is available */
+ void (*DeviceAddressAssigned)(void); /* Address is assigned to USB Device */
+ void (*ConfigurationDescAvailable)(USBH_CfgDesc_TypeDef *,
+ USBH_InterfaceDesc_TypeDef *,
+ USBH_EpDesc_TypeDef *);
+ /* Configuration Descriptor available */
+ void (*ManufacturerString)(void *); /* ManufacturerString*/
+ void (*ProductString)(void *); /* ProductString*/
+ void (*SerialNumString)(void *); /* SerialNubString*/
+ void (*EnumerationDone)(void); /* Enumeration finished */
+ USBH_USR_Status (*UserInput)(void);
+ int (*UserApplication) (void);
+ void (*DeviceNotSupported)(void); /* Device is not supported*/
+ void (*UnrecoveredError)(void);
+
+}
+USBH_Usr_cb_TypeDef;
+
+typedef struct _Host_TypeDef
+{
+ HOST_State gState; /* Host State Machine Value */
+ HOST_State gStateBkp; /* backup of previous State machine value */
+ ENUM_State EnumState; /* Enumeration state Machine */
+ CMD_State RequestState;
+ USBH_Ctrl_TypeDef Control;
+
+ USBH_Device_TypeDef device_prop;
+
+ USBH_Class_cb_TypeDef *class_cb;
+ USBH_Usr_cb_TypeDef *usr_cb;
+
+
+} USBH_HOST, *pUSBH_HOST;
+
+/**
+ * @}
+ */
+
+
+
+/** @defgroup USBH_CORE_Exported_Macros
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup USBH_CORE_Exported_Variables
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup USBH_CORE_Exported_FunctionsPrototype
+ * @{
+ */
+void USBH_Init(USB_OTG_CORE_HANDLE *pdev,
+ USB_OTG_CORE_ID_TypeDef coreID,
+ USBH_HOST *phost,
+ USBH_Class_cb_TypeDef *class_cb,
+ USBH_Usr_cb_TypeDef *usr_cb);
+
+USBH_Status USBH_DeInit(USB_OTG_CORE_HANDLE *pdev,
+ USBH_HOST *phost);
+void USBH_Process(USB_OTG_CORE_HANDLE *pdev ,
+ USBH_HOST *phost);
+void USBH_ErrorHandle(USBH_HOST *phost,
+ USBH_Status errType);
+
+/**
+ * @}
+ */
+
+#endif /* __USBH_CORE_H */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+* @}
+*/
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
+
+
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32_USB_HOST_Library/Core/inc/usbh_def.h b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_HOST_Library/Core/inc/usbh_def.h
new file mode 100644
index 0000000..19ad7b0
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_HOST_Library/Core/inc/usbh_def.h
@@ -0,0 +1,288 @@
+/**
+ ******************************************************************************
+ * @file usbh_def.h
+ * @author MCD Application Team
+ * @version V2.1.0
+ * @date 19-March-2012
+ * @brief Definitions used in the USB host 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.
+ *
+ ******************************************************************************
+ */
+
+/** @addtogroup USBH_LIB
+ * @{
+ */
+
+/** @addtogroup USBH_LIB_CORE
+* @{
+*/
+
+/** @defgroup USBH_DEF
+ * @brief This file is includes USB descriptors
+ * @{
+ */
+
+#ifndef USBH_DEF_H
+#define USBH_DEF_H
+
+#ifndef USBH_NULL
+#define USBH_NULL ((void *)0)
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+
+#define ValBit(VAR,POS) (VAR & (1 << POS))
+#define SetBit(VAR,POS) (VAR |= (1 << POS))
+#define ClrBit(VAR,POS) (VAR &= ((1 << POS)^255))
+
+#define LE16(addr) (((u16)(*((u8 *)(addr))))\
+ + (((u16)(*(((u8 *)(addr)) + 1))) << 8))
+
+#define USB_LEN_DESC_HDR 0x02
+#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 USB_LEN_SETUP_PKT 0x08
+
+/* bmRequestType :D7 Data Phase Transfer Direction */
+#define USB_REQ_DIR_MASK 0x80
+#define USB_H2D 0x00
+#define USB_D2H 0x80
+
+/* bmRequestType D6..5 Type */
+#define USB_REQ_TYPE_STANDARD 0x00
+#define USB_REQ_TYPE_CLASS 0x20
+#define USB_REQ_TYPE_VENDOR 0x40
+#define USB_REQ_TYPE_RESERVED 0x60
+
+/* bmRequestType D4..0 Recipient */
+#define USB_REQ_RECIPIENT_DEVICE 0x00
+#define USB_REQ_RECIPIENT_INTERFACE 0x01
+#define USB_REQ_RECIPIENT_ENDPOINT 0x02
+#define USB_REQ_RECIPIENT_OTHER 0x03
+
+/* Table 9-4. Standard Request Codes */
+/* bRequest , Value */
+#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
+
+/* Table 9-5. Descriptor Types of USB Specifications */
+#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_DESC_TYPE_INTERFACE_POWER 8
+#define USB_DESC_TYPE_HID 0x21
+#define USB_DESC_TYPE_HID_REPORT 0x22
+
+
+#define USB_DEVICE_DESC_SIZE 18
+#define USB_CONFIGURATION_DESC_SIZE 9
+#define USB_HID_DESC_SIZE 9
+#define USB_INTERFACE_DESC_SIZE 9
+#define USB_ENDPOINT_DESC_SIZE 7
+
+/* Descriptor Type and Descriptor Index */
+/* Use the following values when calling the function USBH_GetDescriptor */
+#define USB_DESC_DEVICE ((USB_DESC_TYPE_DEVICE << 8) & 0xFF00)
+#define USB_DESC_CONFIGURATION ((USB_DESC_TYPE_CONFIGURATION << 8) & 0xFF00)
+#define USB_DESC_STRING ((USB_DESC_TYPE_STRING << 8) & 0xFF00)
+#define USB_DESC_INTERFACE ((USB_DESC_TYPE_INTERFACE << 8) & 0xFF00)
+#define USB_DESC_ENDPOINT ((USB_DESC_TYPE_INTERFACE << 8) & 0xFF00)
+#define USB_DESC_DEVICE_QUALIFIER ((USB_DESC_TYPE_DEVICE_QUALIFIER << 8) & 0xFF00)
+#define USB_DESC_OTHER_SPEED_CONFIGURATION ((USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION << 8) & 0xFF00)
+#define USB_DESC_INTERFACE_POWER ((USB_DESC_TYPE_INTERFACE_POWER << 8) & 0xFF00)
+#define USB_DESC_HID_REPORT ((USB_DESC_TYPE_HID_REPORT << 8) & 0xFF00)
+#define USB_DESC_HID ((USB_DESC_TYPE_HID << 8) & 0xFF00)
+
+
+#define USB_EP_TYPE_CTRL 0x00
+#define USB_EP_TYPE_ISOC 0x01
+#define USB_EP_TYPE_BULK 0x02
+#define USB_EP_TYPE_INTR 0x03
+
+#define USB_EP_DIR_OUT 0x00
+#define USB_EP_DIR_IN 0x80
+#define USB_EP_DIR_MSK 0x80
+
+/* supported classes */
+#define USB_MSC_CLASS 0x08
+#define USB_HID_CLASS 0x03
+
+/* Interface Descriptor field values for HID Boot Protocol */
+#define HID_BOOT_CODE 0x01
+#define HID_KEYBRD_BOOT_CODE 0x01
+#define HID_MOUSE_BOOT_CODE 0x02
+
+/* As per USB specs 9.2.6.4 :Standard request with data request timeout: 5sec
+ Standard request with no data stage timeout : 50ms */
+#define DATA_STAGE_TIMEOUT 5000
+#define NODATA_STAGE_TIMEOUT 50
+
+/**
+ * @}
+ */
+
+
+#define USBH_CONFIGURATION_DESCRIPTOR_SIZE (USB_CONFIGURATION_DESC_SIZE \
+ + USB_INTERFACE_DESC_SIZE\
+ + (USBH_MAX_NUM_ENDPOINTS * USB_ENDPOINT_DESC_SIZE))
+
+
+#define CONFIG_DESC_wTOTAL_LENGTH (ConfigurationDescriptorData.ConfigDescfield.\
+ ConfigurationDescriptor.wTotalLength)
+
+
+/* This Union is copied from usb_core.h */
+typedef union
+{
+ uint16_t w;
+ struct BW
+ {
+ uint8_t msb;
+ uint8_t lsb;
+ }
+ bw;
+}
+uint16_t_uint8_t;
+
+
+typedef union _USB_Setup
+{
+ uint8_t d8[8];
+
+ struct _SetupPkt_Struc
+ {
+ uint8_t bmRequestType;
+ uint8_t bRequest;
+ uint16_t_uint8_t wValue;
+ uint16_t_uint8_t wIndex;
+ uint16_t_uint8_t wLength;
+ } b;
+}
+USB_Setup_TypeDef;
+
+typedef struct _DescHeader
+{
+ uint8_t bLength;
+ uint8_t bDescriptorType;
+}
+USBH_DescHeader_t;
+
+typedef struct _DeviceDescriptor
+{
+ uint8_t bLength;
+ uint8_t bDescriptorType;
+ uint16_t bcdUSB; /* USB Specification Number which device complies too */
+ uint8_t bDeviceClass;
+ uint8_t bDeviceSubClass;
+ uint8_t bDeviceProtocol;
+ /* If equal to Zero, each interface specifies its own class
+ code if equal to 0xFF, the class code is vendor specified.
+ Otherwise field is valid Class Code.*/
+ uint8_t bMaxPacketSize;
+ uint16_t idVendor; /* Vendor ID (Assigned by USB Org) */
+ uint16_t idProduct; /* Product ID (Assigned by Manufacturer) */
+ uint16_t bcdDevice; /* Device Release Number */
+ uint8_t iManufacturer; /* Index of Manufacturer String Descriptor */
+ uint8_t iProduct; /* Index of Product String Descriptor */
+ uint8_t iSerialNumber; /* Index of Serial Number String Descriptor */
+ uint8_t bNumConfigurations; /* Number of Possible Configurations */
+}
+USBH_DevDesc_TypeDef;
+
+
+typedef struct _ConfigurationDescriptor
+{
+ uint8_t bLength;
+ uint8_t bDescriptorType;
+ uint16_t wTotalLength; /* Total Length of Data Returned */
+ uint8_t bNumInterfaces; /* Number of Interfaces */
+ uint8_t bConfigurationValue; /* Value to use as an argument to select this configuration*/
+ uint8_t iConfiguration; /*Index of String Descriptor Describing this configuration */
+ uint8_t bmAttributes; /* D7 Bus Powered , D6 Self Powered, D5 Remote Wakeup , D4..0 Reserved (0)*/
+ uint8_t bMaxPower; /*Maximum Power Consumption */
+}
+USBH_CfgDesc_TypeDef;
+
+
+typedef struct _HIDDescriptor
+{
+ uint8_t bLength;
+ uint8_t bDescriptorType;
+ uint16_t bcdHID; /* indicates what endpoint this descriptor is describing */
+ uint8_t bCountryCode; /* specifies the transfer type. */
+ uint8_t bNumDescriptors; /* specifies the transfer type. */
+ uint8_t bReportDescriptorType; /* Maximum Packet Size this endpoint is capable of sending or receiving */
+ uint16_t wItemLength; /* is used to specify the polling interval of certain transfers. */
+}
+USBH_HIDDesc_TypeDef;
+
+
+typedef struct _InterfaceDescriptor
+{
+ uint8_t bLength;
+ uint8_t bDescriptorType;
+ uint8_t bInterfaceNumber;
+ uint8_t bAlternateSetting; /* Value used to select alternative setting */
+ uint8_t bNumEndpoints; /* Number of Endpoints used for this interface */
+ uint8_t bInterfaceClass; /* Class Code (Assigned by USB Org) */
+ uint8_t bInterfaceSubClass; /* Subclass Code (Assigned by USB Org) */
+ uint8_t bInterfaceProtocol; /* Protocol Code */
+ uint8_t iInterface; /* Index of String Descriptor Describing this interface */
+
+}
+USBH_InterfaceDesc_TypeDef;
+
+
+typedef struct _EndpointDescriptor
+{
+ uint8_t bLength;
+ uint8_t bDescriptorType;
+ uint8_t bEndpointAddress; /* indicates what endpoint this descriptor is describing */
+ uint8_t bmAttributes; /* specifies the transfer type. */
+ uint16_t wMaxPacketSize; /* Maximum Packet Size this endpoint is capable of sending or receiving */
+ uint8_t bInterval; /* is used to specify the polling interval of certain transfers. */
+}
+USBH_EpDesc_TypeDef;
+#endif
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32_USB_HOST_Library/Core/inc/usbh_hcs.h b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_HOST_Library/Core/inc/usbh_hcs.h
new file mode 100644
index 0000000..b50609f
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_HOST_Library/Core/inc/usbh_hcs.h
@@ -0,0 +1,129 @@
+/**
+ ******************************************************************************
+ * @file usbh_hcs.h
+ * @author MCD Application Team
+ * @version V2.1.0
+ * @date 19-March-2012
+ * @brief Header file for usbh_hcs.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 ----------------------------------------------*/
+#ifndef __USBH_HCS_H
+#define __USBH_HCS_H
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbh_core.h"
+
+/** @addtogroup USBH_LIB
+ * @{
+ */
+
+/** @addtogroup USBH_LIB_CORE
+* @{
+*/
+
+/** @defgroup USBH_HCS
+ * @brief This file is the header file for usbh_hcs.c
+ * @{
+ */
+
+/** @defgroup USBH_HCS_Exported_Defines
+ * @{
+ */
+#define HC_MAX 8
+
+#define HC_OK 0x0000
+#define HC_USED 0x8000
+#define HC_ERROR 0xFFFF
+#define HC_USED_MASK 0x7FFF
+/**
+ * @}
+ */
+
+/** @defgroup USBH_HCS_Exported_Types
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup USBH_HCS_Exported_Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USBH_HCS_Exported_Variables
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USBH_HCS_Exported_FunctionsPrototype
+ * @{
+ */
+
+uint8_t USBH_Alloc_Channel(USB_OTG_CORE_HANDLE *pdev, uint8_t ep_addr);
+
+uint8_t USBH_Free_Channel (USB_OTG_CORE_HANDLE *pdev, uint8_t idx);
+
+uint8_t USBH_DeAllocate_AllChannel (USB_OTG_CORE_HANDLE *pdev);
+
+uint8_t USBH_Open_Channel (USB_OTG_CORE_HANDLE *pdev,
+ uint8_t ch_num,
+ uint8_t dev_address,
+ uint8_t speed,
+ uint8_t ep_type,
+ uint16_t mps);
+
+uint8_t USBH_Modify_Channel (USB_OTG_CORE_HANDLE *pdev,
+ uint8_t hc_num,
+ uint8_t dev_address,
+ uint8_t speed,
+ uint8_t ep_type,
+ uint16_t mps);
+/**
+ * @}
+ */
+
+
+
+#endif /* __USBH_HCS_H */
+
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+* @}
+*/
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
+
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32_USB_HOST_Library/Core/inc/usbh_ioreq.h b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_HOST_Library/Core/inc/usbh_ioreq.h
new file mode 100644
index 0000000..d56ef43
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_HOST_Library/Core/inc/usbh_ioreq.h
@@ -0,0 +1,156 @@
+/**
+ ******************************************************************************
+ * @file usbh_ioreq.h
+ * @author MCD Application Team
+ * @version V2.1.0
+ * @date 19-March-2012
+ * @brief Header file for usbh_ioreq.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 ----------------------------------------------*/
+#ifndef __USBH_IOREQ_H
+#define __USBH_IOREQ_H
+
+/* Includes ------------------------------------------------------------------*/
+#include "usb_conf.h"
+#include "usbh_core.h"
+#include "usbh_def.h"
+
+/** @addtogroup USBH_LIB
+ * @{
+ */
+
+/** @addtogroup USBH_LIB_CORE
+* @{
+*/
+
+/** @defgroup USBH_IOREQ
+ * @brief This file is the header file for usbh_ioreq.c
+ * @{
+ */
+
+
+/** @defgroup USBH_IOREQ_Exported_Defines
+ * @{
+ */
+#define USBH_SETUP_PKT_SIZE 8
+#define USBH_EP0_EP_NUM 0
+#define USBH_MAX_PACKET_SIZE 0x40
+/**
+ * @}
+ */
+
+
+/** @defgroup USBH_IOREQ_Exported_Types
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup USBH_IOREQ_Exported_Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USBH_IOREQ_Exported_Variables
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USBH_IOREQ_Exported_FunctionsPrototype
+ * @{
+ */
+USBH_Status USBH_CtlSendSetup ( USB_OTG_CORE_HANDLE *pdev,
+ uint8_t *buff,
+ uint8_t hc_num);
+
+USBH_Status USBH_CtlSendData ( USB_OTG_CORE_HANDLE *pdev,
+ uint8_t *buff,
+ uint16_t length,
+ uint8_t hc_num);
+
+USBH_Status USBH_CtlReceiveData( USB_OTG_CORE_HANDLE *pdev,
+ uint8_t *buff,
+ uint16_t length,
+ uint8_t hc_num);
+
+USBH_Status USBH_BulkReceiveData( USB_OTG_CORE_HANDLE *pdev,
+ uint8_t *buff,
+ uint16_t length,
+ uint8_t hc_num);
+
+USBH_Status USBH_BulkSendData ( USB_OTG_CORE_HANDLE *pdev,
+ uint8_t *buff,
+ uint16_t length,
+ uint8_t hc_num);
+
+USBH_Status USBH_InterruptReceiveData( USB_OTG_CORE_HANDLE *pdev,
+ uint8_t *buff,
+ uint8_t length,
+ uint8_t hc_num);
+
+USBH_Status USBH_InterruptSendData( USB_OTG_CORE_HANDLE *pdev,
+ uint8_t *buff,
+ uint8_t length,
+ uint8_t hc_num);
+
+USBH_Status USBH_CtlReq (USB_OTG_CORE_HANDLE *pdev,
+ USBH_HOST *phost,
+ uint8_t *buff,
+ uint16_t length);
+
+USBH_Status USBH_IsocReceiveData( USB_OTG_CORE_HANDLE *pdev,
+ uint8_t *buff,
+ uint32_t length,
+ uint8_t hc_num);
+
+
+USBH_Status USBH_IsocSendData( USB_OTG_CORE_HANDLE *pdev,
+ uint8_t *buff,
+ uint32_t length,
+ uint8_t hc_num);
+/**
+ * @}
+ */
+
+#endif /* __USBH_IOREQ_H */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+* @}
+*/
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
+
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32_USB_HOST_Library/Core/inc/usbh_stdreq.h b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_HOST_Library/Core/inc/usbh_stdreq.h
new file mode 100644
index 0000000..0ad1fde
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_HOST_Library/Core/inc/usbh_stdreq.h
@@ -0,0 +1,161 @@
+/**
+ ******************************************************************************
+ * @file usbh_stdreq.h
+ * @author MCD Application Team
+ * @version V2.1.0
+ * @date 19-March-2012
+ * @brief Header file for usbh_stdreq.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 ----------------------------------------------*/
+#ifndef __USBH_STDREQ_H
+#define __USBH_STDREQ_H
+
+/* Includes ------------------------------------------------------------------*/
+#include "usb_conf.h"
+#include "usb_hcd.h"
+#include "usbh_core.h"
+#include "usbh_def.h"
+
+/** @addtogroup USBH_LIB
+ * @{
+ */
+
+/** @addtogroup USBH_LIB_CORE
+* @{
+*/
+
+/** @defgroup USBH_STDREQ
+ * @brief This file is the
+ * @{
+ */
+
+
+/** @defgroup USBH_STDREQ_Exported_Defines
+ * @{
+ */
+/*Standard Feature Selector for clear feature command*/
+#define FEATURE_SELECTOR_ENDPOINT 0X00
+#define FEATURE_SELECTOR_DEVICE 0X01
+
+
+#define INTERFACE_DESC_TYPE 0x04
+#define ENDPOINT_DESC_TYPE 0x05
+#define INTERFACE_DESC_SIZE 0x09
+
+
+#define USBH_HID_CLASS 0x03
+
+/**
+ * @}
+ */
+
+
+/** @defgroup USBH_STDREQ_Exported_Types
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup USBH_STDREQ_Exported_Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USBH_STDREQ_Exported_Variables
+ * @{
+ */
+extern uint8_t USBH_CfgDesc[512];
+/**
+ * @}
+ */
+
+/** @defgroup USBH_STDREQ_Exported_FunctionsPrototype
+ * @{
+ */
+USBH_Status USBH_GetDescriptor(USB_OTG_CORE_HANDLE *pdev,
+ USBH_HOST *phost,
+ uint8_t req_type,
+ uint16_t value_idx,
+ uint8_t* buff,
+ uint16_t length );
+
+USBH_Status USBH_Get_DevDesc(USB_OTG_CORE_HANDLE *pdev,
+ USBH_HOST *phost,
+ uint8_t length);
+
+USBH_Status USBH_Get_StringDesc(USB_OTG_CORE_HANDLE *pdev,
+ USBH_HOST *phost,
+ uint8_t string_index,
+ uint8_t *buff,
+ uint16_t length);
+
+USBH_Status USBH_SetCfg(USB_OTG_CORE_HANDLE *pdev,
+ USBH_HOST *phost,
+ uint16_t configuration_value);
+
+USBH_Status USBH_Get_CfgDesc(USB_OTG_CORE_HANDLE *pdev,
+ USBH_HOST *phost,
+ uint16_t length);
+
+USBH_Status USBH_SetAddress(USB_OTG_CORE_HANDLE *pdev,
+ USBH_HOST *phost,
+ uint8_t DeviceAddress);
+
+USBH_Status USBH_ClrFeature(USB_OTG_CORE_HANDLE *pdev,
+ USBH_HOST *phost,
+ uint8_t ep_num, uint8_t hc_num);
+
+USBH_Status USBH_SetInterface(USB_OTG_CORE_HANDLE *pdev,
+ USBH_HOST *phost,
+ uint8_t ep_num, uint8_t altSetting);
+
+USBH_Status USBH_Issue_ClrFeature(USB_OTG_CORE_HANDLE *pdev,
+ USBH_HOST *phost,
+ uint8_t ep_num);
+
+USBH_DescHeader_t *USBH_GetNextDesc (uint8_t *pbuf,
+ uint16_t *ptr);
+/**
+ * @}
+ */
+
+#endif /* __USBH_STDREQ_H */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+* @}
+*/
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
+
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32_USB_HOST_Library/Core/src/usbh_core.c b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_HOST_Library/Core/src/usbh_core.c
new file mode 100644
index 0000000..8048969
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_HOST_Library/Core/src/usbh_core.c
@@ -0,0 +1,857 @@
+/**
+ ******************************************************************************
+ * @file usbh_core.c
+ * @author MCD Application Team
+ * @version V2.1.0
+ * @date 19-March-2012
+ * @brief This file implements the functions for the core state machine process
+ * the enumeration and the control transfer process
+ ******************************************************************************
+ * @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 "usbh_ioreq.h"
+#include "usb_bsp.h"
+#include "usbh_hcs.h"
+#include "usbh_stdreq.h"
+#include "usbh_core.h"
+#include "usb_hcd_int.h"
+
+
+/** @addtogroup USBH_LIB
+ * @{
+ */
+
+/** @addtogroup USBH_LIB_CORE
+* @{
+*/
+
+/** @defgroup USBH_CORE
+ * @brief TThis file handles the basic enumaration when a device is connected
+ * to the host.
+ * @{
+ */
+
+/** @defgroup USBH_CORE_Private_TypesDefinitions
+ * @{
+ */
+uint8_t USBH_Disconnected (USB_OTG_CORE_HANDLE *pdev);
+uint8_t USBH_Connected (USB_OTG_CORE_HANDLE *pdev);
+uint8_t USBH_SOF (USB_OTG_CORE_HANDLE *pdev);
+
+USBH_HCD_INT_cb_TypeDef USBH_HCD_INT_cb =
+{
+ USBH_SOF,
+ USBH_Connected,
+ USBH_Disconnected,
+};
+
+USBH_HCD_INT_cb_TypeDef *USBH_HCD_INT_fops = &USBH_HCD_INT_cb;
+/**
+ * @}
+ */
+
+
+/** @defgroup USBH_CORE_Private_Defines
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup USBH_CORE_Private_Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup USBH_CORE_Private_Variables
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup USBH_CORE_Private_FunctionPrototypes
+ * @{
+ */
+static USBH_Status USBH_HandleEnum(USB_OTG_CORE_HANDLE *pdev, USBH_HOST *phost);
+USBH_Status USBH_HandleControl (USB_OTG_CORE_HANDLE *pdev, USBH_HOST *phost);
+
+/**
+ * @}
+ */
+
+
+/** @defgroup USBH_CORE_Private_Functions
+ * @{
+ */
+
+
+/**
+ * @brief USBH_Connected
+ * USB Connect callback function from the Interrupt.
+ * @param selected device
+ * @retval Status
+*/
+uint8_t USBH_Connected (USB_OTG_CORE_HANDLE *pdev)
+{
+ pdev->host.ConnSts = 1;
+ return 0;
+}
+
+/**
+* @brief USBH_Disconnected
+* USB Disconnect callback function from the Interrupt.
+* @param selected device
+* @retval Status
+*/
+
+uint8_t USBH_Disconnected (USB_OTG_CORE_HANDLE *pdev)
+{
+ pdev->host.ConnSts = 0;
+ return 0;
+}
+
+/**
+ * @brief USBH_SOF
+ * USB SOF callback function from the Interrupt.
+ * @param selected device
+ * @retval Status
+ */
+
+uint8_t USBH_SOF (USB_OTG_CORE_HANDLE *pdev)
+{
+ /* This callback could be used to implement a scheduler process */
+ return 0;
+}
+/**
+ * @brief USBH_Init
+ * Host hardware and stack initializations
+ * @param class_cb: Class callback structure address
+ * @param usr_cb: User callback structure address
+ * @retval None
+ */
+void USBH_Init(USB_OTG_CORE_HANDLE *pdev,
+ USB_OTG_CORE_ID_TypeDef coreID,
+ USBH_HOST *phost,
+ USBH_Class_cb_TypeDef *class_cb,
+ USBH_Usr_cb_TypeDef *usr_cb)
+{
+
+ /* Hardware Init */
+ USB_OTG_BSP_Init(pdev);
+
+ /* configure GPIO pin used for switching VBUS power */
+ USB_OTG_BSP_ConfigVBUS(0);
+
+
+ /* Host de-initializations */
+ USBH_DeInit(pdev, phost);
+
+ /*Register class and user callbacks */
+ phost->class_cb = class_cb;
+ phost->usr_cb = usr_cb;
+
+ /* Start the USB OTG core */
+ HCD_Init(pdev , coreID);
+
+ /* Upon Init call usr call back */
+ phost->usr_cb->Init();
+
+ /* Enable Interrupts */
+ USB_OTG_BSP_EnableInterrupt(pdev);
+}
+
+/**
+ * @brief USBH_DeInit
+ * Re-Initialize Host
+ * @param None
+ * @retval status: USBH_Status
+ */
+USBH_Status USBH_DeInit(USB_OTG_CORE_HANDLE *pdev, USBH_HOST *phost)
+{
+ /* Software Init */
+
+ phost->gState = HOST_IDLE;
+ phost->gStateBkp = HOST_IDLE;
+ phost->EnumState = ENUM_IDLE;
+ phost->RequestState = CMD_SEND;
+
+ phost->Control.state = CTRL_SETUP;
+ phost->Control.ep0size = USB_OTG_MAX_EP0_SIZE;
+
+ phost->device_prop.address = USBH_DEVICE_ADDRESS_DEFAULT;
+ phost->device_prop.speed = HPRT0_PRTSPD_FULL_SPEED;
+
+ USBH_Free_Channel (pdev, phost->Control.hc_num_in);
+ USBH_Free_Channel (pdev, phost->Control.hc_num_out);
+ return USBH_OK;
+}
+
+/**
+* @brief USBH_Process
+* USB Host core main state machine process
+* @param None
+* @retval None
+*/
+void USBH_Process(USB_OTG_CORE_HANDLE *pdev , USBH_HOST *phost)
+{
+ volatile USBH_Status status = USBH_FAIL;
+
+
+ /* check for Host port events */
+ if ((HCD_IsDeviceConnected(pdev) == 0)&& (phost->gState != HOST_IDLE))
+ {
+ if(phost->gState != HOST_DEV_DISCONNECTED)
+ {
+ phost->gState = HOST_DEV_DISCONNECTED;
+ }
+ }
+
+ switch (phost->gState)
+ {
+
+ case HOST_IDLE :
+
+ if (HCD_IsDeviceConnected(pdev))
+ {
+ phost->gState = HOST_DEV_ATTACHED;
+ USB_OTG_BSP_mDelay(100);
+ }
+ break;
+
+ case HOST_DEV_ATTACHED :
+
+ phost->usr_cb->DeviceAttached();
+ phost->Control.hc_num_out = USBH_Alloc_Channel(pdev, 0x00);
+ phost->Control.hc_num_in = USBH_Alloc_Channel(pdev, 0x80);
+
+ /* Reset USB Device */
+ if ( HCD_ResetPort(pdev) == 0)
+ {
+ phost->usr_cb->ResetDevice();
+ /* Wait for USB USBH_ISR_PrtEnDisableChange()
+ Host is Now ready to start the Enumeration
+ */
+
+ phost->device_prop.speed = HCD_GetCurrentSpeed(pdev);
+
+ phost->gState = HOST_ENUMERATION;
+ phost->usr_cb->DeviceSpeedDetected(phost->device_prop.speed);
+
+ /* Open Control pipes */
+ USBH_Open_Channel (pdev,
+ phost->Control.hc_num_in,
+ phost->device_prop.address,
+ phost->device_prop.speed,
+ EP_TYPE_CTRL,
+ phost->Control.ep0size);
+
+ /* Open Control pipes */
+ USBH_Open_Channel (pdev,
+ phost->Control.hc_num_out,
+ phost->device_prop.address,
+ phost->device_prop.speed,
+ EP_TYPE_CTRL,
+ phost->Control.ep0size);
+ }
+ break;
+
+ case HOST_ENUMERATION:
+ /* Check for enumeration status */
+ if ( USBH_HandleEnum(pdev , phost) == USBH_OK)
+ {
+ /* The function shall return USBH_OK when full enumeration is complete */
+
+ /* user callback for end of device basic enumeration */
+ phost->usr_cb->EnumerationDone();
+
+ phost->gState = HOST_USR_INPUT;
+ }
+ break;
+
+ case HOST_USR_INPUT:
+ /*The function should return user response true to move to class state */
+ if ( phost->usr_cb->UserInput() == USBH_USR_RESP_OK)
+ {
+ if((phost->class_cb->Init(pdev, phost))\
+ == USBH_OK)
+ {
+ phost->gState = HOST_CLASS_REQUEST;
+ }
+ }
+ break;
+
+ case HOST_CLASS_REQUEST:
+ /* process class standard contol requests state machine */
+ status = phost->class_cb->Requests(pdev, phost);
+
+ if(status == USBH_OK)
+ {
+ phost->gState = HOST_CLASS;
+ }
+
+ else
+ {
+ USBH_ErrorHandle(phost, status);
+ }
+
+
+ break;
+ case HOST_CLASS:
+ /* process class state machine */
+ status = phost->class_cb->Machine(pdev, phost);
+ USBH_ErrorHandle(phost, status);
+ break;
+
+ case HOST_CTRL_XFER:
+ /* process control transfer state machine */
+ USBH_HandleControl(pdev, phost);
+ break;
+
+ case HOST_SUSPENDED:
+ break;
+
+ case HOST_ERROR_STATE:
+ /* Re-Initilaize Host for new Enumeration */
+ USBH_DeInit(pdev, phost);
+ phost->usr_cb->DeInit();
+ phost->class_cb->DeInit(pdev, &phost->device_prop);
+ break;
+
+ case HOST_DEV_DISCONNECTED :
+
+ /* Manage User disconnect operations*/
+ phost->usr_cb->DeviceDisconnected();
+
+ /* Re-Initilaize Host for new Enumeration */
+ USBH_DeInit(pdev, phost);
+ phost->usr_cb->DeInit();
+ phost->class_cb->DeInit(pdev, &phost->device_prop);
+ USBH_DeAllocate_AllChannel(pdev);
+ phost->gState = HOST_IDLE;
+
+ break;
+
+ default :
+ break;
+ }
+
+}
+
+
+/**
+ * @brief USBH_ErrorHandle
+ * This function handles the Error on Host side.
+ * @param errType : Type of Error or Busy/OK state
+ * @retval None
+ */
+void USBH_ErrorHandle(USBH_HOST *phost, USBH_Status errType)
+{
+ /* Error unrecovered or not supported device speed */
+ if ( (errType == USBH_ERROR_SPEED_UNKNOWN) ||
+ (errType == USBH_UNRECOVERED_ERROR) )
+ {
+ phost->usr_cb->UnrecoveredError();
+ phost->gState = HOST_ERROR_STATE;
+ }
+ /* USB host restart requested from application layer */
+ else if(errType == USBH_APPLY_DEINIT)
+ {
+ phost->gState = HOST_ERROR_STATE;
+ /* user callback for initalization */
+ phost->usr_cb->Init();
+ }
+}
+
+
+/**
+ * @brief USBH_HandleEnum
+ * This function includes the complete enumeration process
+ * @param pdev: Selected device
+ * @retval USBH_Status
+ */
+static USBH_Status USBH_HandleEnum(USB_OTG_CORE_HANDLE *pdev, USBH_HOST *phost)
+{
+ USBH_Status Status = USBH_BUSY;
+ uint8_t Local_Buffer[64];
+
+ switch (phost->EnumState)
+ {
+ case ENUM_IDLE:
+ /* Get Device Desc for only 1st 8 bytes : To get EP0 MaxPacketSize */
+ if ( USBH_Get_DevDesc(pdev , phost, 8) == USBH_OK)
+ {
+ phost->Control.ep0size = phost->device_prop.Dev_Desc.bMaxPacketSize;
+
+ /* Issue Reset */
+ HCD_ResetPort(pdev);
+ phost->EnumState = ENUM_GET_FULL_DEV_DESC;
+
+ /* modify control channels configuration for MaxPacket size */
+ USBH_Modify_Channel (pdev,
+ phost->Control.hc_num_out,
+ 0,
+ 0,
+ 0,
+ phost->Control.ep0size);
+
+ USBH_Modify_Channel (pdev,
+ phost->Control.hc_num_in,
+ 0,
+ 0,
+ 0,
+ phost->Control.ep0size);
+ }
+ break;
+
+ case ENUM_GET_FULL_DEV_DESC:
+ /* Get FULL Device Desc */
+ if ( USBH_Get_DevDesc(pdev, phost, USB_DEVICE_DESC_SIZE)\
+ == USBH_OK)
+ {
+ /* user callback for device descriptor available */
+ phost->usr_cb->DeviceDescAvailable(&phost->device_prop.Dev_Desc);
+ phost->EnumState = ENUM_SET_ADDR;
+ }
+ break;
+
+ case ENUM_SET_ADDR:
+ /* set address */
+ if ( USBH_SetAddress(pdev, phost, USBH_DEVICE_ADDRESS) == USBH_OK)
+ {
+ USB_OTG_BSP_mDelay(2);
+ phost->device_prop.address = USBH_DEVICE_ADDRESS;
+
+ /* user callback for device address assigned */
+ phost->usr_cb->DeviceAddressAssigned();
+ phost->EnumState = ENUM_GET_CFG_DESC;
+
+ /* modify control channels to update device address */
+ USBH_Modify_Channel (pdev,
+ phost->Control.hc_num_in,
+ phost->device_prop.address,
+ 0,
+ 0,
+ 0);
+
+ USBH_Modify_Channel (pdev,
+ phost->Control.hc_num_out,
+ phost->device_prop.address,
+ 0,
+ 0,
+ 0);
+ }
+ break;
+
+ case ENUM_GET_CFG_DESC:
+ /* get standard configuration descriptor */
+ if ( USBH_Get_CfgDesc(pdev,
+ phost,
+ USB_CONFIGURATION_DESC_SIZE) == USBH_OK)
+ {
+ phost->EnumState = ENUM_GET_FULL_CFG_DESC;
+ }
+ break;
+
+ case ENUM_GET_FULL_CFG_DESC:
+ /* get FULL config descriptor (config, interface, endpoints) */
+ if (USBH_Get_CfgDesc(pdev,
+ phost,
+ phost->device_prop.Cfg_Desc.wTotalLength) == USBH_OK)
+ {
+ /* User callback for configuration descriptors available */
+ phost->usr_cb->ConfigurationDescAvailable(&phost->device_prop.Cfg_Desc,
+ phost->device_prop.Itf_Desc,
+ phost->device_prop.Ep_Desc[0]);
+
+ phost->EnumState = ENUM_GET_MFC_STRING_DESC;
+ }
+ break;
+
+ case ENUM_GET_MFC_STRING_DESC:
+ if (phost->device_prop.Dev_Desc.iManufacturer != 0)
+ { /* Check that Manufacturer String is available */
+
+ if ( USBH_Get_StringDesc(pdev,
+ phost,
+ phost->device_prop.Dev_Desc.iManufacturer,
+ Local_Buffer ,
+ 0xff) == USBH_OK)
+ {
+ /* User callback for Manufacturing string */
+ phost->usr_cb->ManufacturerString(Local_Buffer);
+ phost->EnumState = ENUM_GET_PRODUCT_STRING_DESC;
+ }
+ }
+ else
+ {
+ phost->usr_cb->ManufacturerString("N/A");
+ phost->EnumState = ENUM_GET_PRODUCT_STRING_DESC;
+ }
+ break;
+
+ case ENUM_GET_PRODUCT_STRING_DESC:
+ if (phost->device_prop.Dev_Desc.iProduct != 0)
+ { /* Check that Product string is available */
+ if ( USBH_Get_StringDesc(pdev,
+ phost,
+ phost->device_prop.Dev_Desc.iProduct,
+ Local_Buffer,
+ 0xff) == USBH_OK)
+ {
+ /* User callback for Product string */
+ phost->usr_cb->ProductString(Local_Buffer);
+ phost->EnumState = ENUM_GET_SERIALNUM_STRING_DESC;
+ }
+ }
+ else
+ {
+ phost->usr_cb->ProductString("N/A");
+ phost->EnumState = ENUM_GET_SERIALNUM_STRING_DESC;
+ }
+ break;
+
+ case ENUM_GET_SERIALNUM_STRING_DESC:
+ if (phost->device_prop.Dev_Desc.iSerialNumber != 0)
+ { /* Check that Serial number string is available */
+ if ( USBH_Get_StringDesc(pdev,
+ phost,
+ phost->device_prop.Dev_Desc.iSerialNumber,
+ Local_Buffer,
+ 0xff) == USBH_OK)
+ {
+ /* User callback for Serial number string */
+ phost->usr_cb->SerialNumString(Local_Buffer);
+ phost->EnumState = ENUM_SET_CONFIGURATION;
+ }
+ }
+ else
+ {
+ phost->usr_cb->SerialNumString("N/A");
+ phost->EnumState = ENUM_SET_CONFIGURATION;
+ }
+ break;
+
+ case ENUM_SET_CONFIGURATION:
+ /* set configuration (default config) */
+ if (USBH_SetCfg(pdev,
+ phost,
+ phost->device_prop.Cfg_Desc.bConfigurationValue) == USBH_OK)
+ {
+ phost->EnumState = ENUM_DEV_CONFIGURED;
+ }
+ break;
+
+
+ case ENUM_DEV_CONFIGURED:
+ /* user callback for enumeration done */
+ Status = USBH_OK;
+ break;
+
+ default:
+ break;
+ }
+ return Status;
+}
+
+
+/**
+ * @brief USBH_HandleControl
+ * Handles the USB control transfer state machine
+ * @param pdev: Selected device
+ * @retval Status
+ */
+USBH_Status USBH_HandleControl (USB_OTG_CORE_HANDLE *pdev, USBH_HOST *phost)
+{
+ uint8_t direction;
+ static uint16_t timeout = 0;
+ USBH_Status status = USBH_OK;
+ URB_STATE URB_Status = URB_IDLE;
+
+ phost->Control.status = CTRL_START;
+
+
+ switch (phost->Control.state)
+ {
+ case CTRL_SETUP:
+ /* send a SETUP packet */
+ USBH_CtlSendSetup (pdev,
+ phost->Control.setup.d8 ,
+ phost->Control.hc_num_out);
+ phost->Control.state = CTRL_SETUP_WAIT;
+ break;
+
+ case CTRL_SETUP_WAIT:
+
+ URB_Status = HCD_GetURB_State(pdev , phost->Control.hc_num_out);
+ /* case SETUP packet sent successfully */
+ if(URB_Status == URB_DONE)
+ {
+ direction = (phost->Control.setup.b.bmRequestType & USB_REQ_DIR_MASK);
+
+ /* check if there is a data stage */
+ if (phost->Control.setup.b.wLength.w != 0 )
+ {
+ timeout = DATA_STAGE_TIMEOUT;
+ if (direction == USB_D2H)
+ {
+ /* Data Direction is IN */
+ phost->Control.state = CTRL_DATA_IN;
+ }
+ else
+ {
+ /* Data Direction is OUT */
+ phost->Control.state = CTRL_DATA_OUT;
+ }
+ }
+ /* No DATA stage */
+ else
+ {
+ timeout = NODATA_STAGE_TIMEOUT;
+
+ /* If there is No Data Transfer Stage */
+ if (direction == USB_D2H)
+ {
+ /* Data Direction is IN */
+ phost->Control.state = CTRL_STATUS_OUT;
+ }
+ else
+ {
+ /* Data Direction is OUT */
+ phost->Control.state = CTRL_STATUS_IN;
+ }
+ }
+ /* Set the delay timer to enable timeout for data stage completion */
+ phost->Control.timer = HCD_GetCurrentFrame(pdev);
+ }
+ else if(URB_Status == URB_ERROR)
+ {
+ phost->Control.state = CTRL_ERROR;
+ phost->Control.status = CTRL_XACTERR;
+ }
+ break;
+
+ case CTRL_DATA_IN:
+ /* Issue an IN token */
+ USBH_CtlReceiveData(pdev,
+ phost->Control.buff,
+ phost->Control.length,
+ phost->Control.hc_num_in);
+
+ phost->Control.state = CTRL_DATA_IN_WAIT;
+ break;
+
+ case CTRL_DATA_IN_WAIT:
+
+ URB_Status = HCD_GetURB_State(pdev , phost->Control.hc_num_in);
+
+ /* check is DATA packet transfered successfully */
+ if (URB_Status == URB_DONE)
+ {
+ phost->Control.state = CTRL_STATUS_OUT;
+ }
+
+ /* manage error cases*/
+ if (URB_Status == URB_STALL)
+ {
+ /* In stall case, return to previous machine state*/
+ phost->gState = phost->gStateBkp;
+ }
+ else if (URB_Status == URB_ERROR)
+ {
+ /* Device error */
+ phost->Control.state = CTRL_ERROR;
+ }
+ else if ((HCD_GetCurrentFrame(pdev)- phost->Control.timer) > timeout)
+ {
+ /* timeout for IN transfer */
+ phost->Control.state = CTRL_ERROR;
+ }
+ break;
+
+ case CTRL_DATA_OUT:
+ /* Start DATA out transfer (only one DATA packet)*/
+ pdev->host.hc[phost->Control.hc_num_out].toggle_out = 1;
+
+ USBH_CtlSendData (pdev,
+ phost->Control.buff,
+ phost->Control.length ,
+ phost->Control.hc_num_out);
+
+
+
+
+
+ phost->Control.state = CTRL_DATA_OUT_WAIT;
+ break;
+
+ case CTRL_DATA_OUT_WAIT:
+
+ URB_Status = HCD_GetURB_State(pdev , phost->Control.hc_num_out);
+ if (URB_Status == URB_DONE)
+ { /* If the Setup Pkt is sent successful, then change the state */
+ phost->Control.state = CTRL_STATUS_IN;
+ }
+
+ /* handle error cases */
+ else if (URB_Status == URB_STALL)
+ {
+ /* In stall case, return to previous machine state*/
+ phost->gState = phost->gStateBkp;
+ phost->Control.state = CTRL_STALLED;
+ }
+ else if (URB_Status == URB_NOTREADY)
+ {
+ /* Nack received from device */
+ phost->Control.state = CTRL_DATA_OUT;
+ }
+ else if (URB_Status == URB_ERROR)
+ {
+ /* device error */
+ phost->Control.state = CTRL_ERROR;
+ }
+ break;
+
+
+ case CTRL_STATUS_IN:
+ /* Send 0 bytes out packet */
+ USBH_CtlReceiveData (pdev,
+ 0,
+ 0,
+ phost->Control.hc_num_in);
+
+ phost->Control.state = CTRL_STATUS_IN_WAIT;
+
+ break;
+
+ case CTRL_STATUS_IN_WAIT:
+
+ URB_Status = HCD_GetURB_State(pdev , phost->Control.hc_num_in);
+
+ if ( URB_Status == URB_DONE)
+ { /* Control transfers completed, Exit the State Machine */
+ phost->gState = phost->gStateBkp;
+ phost->Control.state = CTRL_COMPLETE;
+ }
+
+ else if (URB_Status == URB_ERROR)
+ {
+ phost->Control.state = CTRL_ERROR;
+ }
+
+ else if((HCD_GetCurrentFrame(pdev)\
+ - phost->Control.timer) > timeout)
+ {
+ phost->Control.state = CTRL_ERROR;
+ }
+ else if(URB_Status == URB_STALL)
+ {
+ /* Control transfers completed, Exit the State Machine */
+ phost->gState = phost->gStateBkp;
+ phost->Control.status = CTRL_STALL;
+ status = USBH_NOT_SUPPORTED;
+ }
+ break;
+
+ case CTRL_STATUS_OUT:
+ pdev->host.hc[phost->Control.hc_num_out].toggle_out ^= 1;
+ USBH_CtlSendData (pdev,
+ 0,
+ 0,
+ phost->Control.hc_num_out);
+
+ phost->Control.state = CTRL_STATUS_OUT_WAIT;
+ break;
+
+ case CTRL_STATUS_OUT_WAIT:
+
+ URB_Status = HCD_GetURB_State(pdev , phost->Control.hc_num_out);
+ if (URB_Status == URB_DONE)
+ {
+ phost->gState = phost->gStateBkp;
+ phost->Control.state = CTRL_COMPLETE;
+ }
+ else if (URB_Status == URB_NOTREADY)
+ {
+ phost->Control.state = CTRL_STATUS_OUT;
+ }
+ else if (URB_Status == URB_ERROR)
+ {
+ phost->Control.state = CTRL_ERROR;
+ }
+ break;
+
+ case CTRL_ERROR:
+ /*
+ After a halt condition is encountered or an error is detected by the
+ host, a control endpoint is allowed to recover by accepting the next Setup
+ PID; i.e., recovery actions via some other pipe are not required for control
+ endpoints. For the Default Control Pipe, a device reset will ultimately be
+ required to clear the halt or error condition if the next Setup PID is not
+ accepted.
+ */
+ if (++ phost->Control.errorcount <= USBH_MAX_ERROR_COUNT)
+ {
+ /* Do the transmission again, starting from SETUP Packet */
+ phost->Control.state = CTRL_SETUP;
+ }
+ else
+ {
+ phost->Control.status = CTRL_FAIL;
+ phost->gState = phost->gStateBkp;
+
+ status = USBH_FAIL;
+ }
+ break;
+
+ default:
+ break;
+ }
+ return status;
+}
+
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
+
+
+
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32_USB_HOST_Library/Core/src/usbh_hcs.c b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_HOST_Library/Core/src/usbh_hcs.c
new file mode 100644
index 0000000..3a5d5f4
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_HOST_Library/Core/src/usbh_hcs.c
@@ -0,0 +1,259 @@
+/**
+ ******************************************************************************
+ * @file usbh_hcs.c
+ * @author MCD Application Team
+ * @version V2.1.0
+ * @date 19-March-2012
+ * @brief This file implements functions for opening and closing host channels
+ ******************************************************************************
+ * @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 "usbh_hcs.h"
+
+/** @addtogroup USBH_LIB
+ * @{
+ */
+
+/** @addtogroup USBH_LIB_CORE
+* @{
+*/
+
+/** @defgroup USBH_HCS
+ * @brief This file includes opening and closing host channels
+ * @{
+ */
+
+/** @defgroup USBH_HCS_Private_Defines
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USBH_HCS_Private_TypesDefinitions
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup USBH_HCS_Private_Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup USBH_HCS_Private_Variables
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+
+/** @defgroup USBH_HCS_Private_FunctionPrototypes
+ * @{
+ */
+static uint16_t USBH_GetFreeChannel (USB_OTG_CORE_HANDLE *pdev);
+/**
+ * @}
+ */
+
+
+/** @defgroup USBH_HCS_Private_Functions
+ * @{
+ */
+
+
+
+/**
+ * @brief USBH_Open_Channel
+ * Open a pipe
+ * @param pdev : Selected device
+ * @param hc_num: Host channel Number
+ * @param dev_address: USB Device address allocated to attached device
+ * @param speed : USB device speed (Full/Low)
+ * @param ep_type: end point type (Bulk/int/ctl)
+ * @param mps: max pkt size
+ * @retval Status
+ */
+uint8_t USBH_Open_Channel (USB_OTG_CORE_HANDLE *pdev,
+ uint8_t hc_num,
+ uint8_t dev_address,
+ uint8_t speed,
+ uint8_t ep_type,
+ uint16_t mps)
+{
+
+ pdev->host.hc[hc_num].ep_num = pdev->host.channel[hc_num]& 0x7F;
+ pdev->host.hc[hc_num].ep_is_in = (pdev->host.channel[hc_num] & 0x80 ) == 0x80;
+ pdev->host.hc[hc_num].dev_addr = dev_address;
+ pdev->host.hc[hc_num].ep_type = ep_type;
+ pdev->host.hc[hc_num].max_packet = mps;
+ pdev->host.hc[hc_num].speed = speed;
+ pdev->host.hc[hc_num].toggle_in = 0;
+ pdev->host.hc[hc_num].toggle_out = 0;
+ if(speed == HPRT0_PRTSPD_HIGH_SPEED)
+ {
+ pdev->host.hc[hc_num].do_ping = 1;
+ }
+
+ USB_OTG_HC_Init(pdev, hc_num) ;
+
+ return HC_OK;
+
+}
+
+/**
+ * @brief USBH_Modify_Channel
+ * Modify a pipe
+ * @param pdev : Selected device
+ * @param hc_num: Host channel Number
+ * @param dev_address: USB Device address allocated to attached device
+ * @param speed : USB device speed (Full/Low)
+ * @param ep_type: end point type (Bulk/int/ctl)
+ * @param mps: max pkt size
+ * @retval Status
+ */
+uint8_t USBH_Modify_Channel (USB_OTG_CORE_HANDLE *pdev,
+ uint8_t hc_num,
+ uint8_t dev_address,
+ uint8_t speed,
+ uint8_t ep_type,
+ uint16_t mps)
+{
+
+ if(dev_address != 0)
+ {
+ pdev->host.hc[hc_num].dev_addr = dev_address;
+ }
+
+ if((pdev->host.hc[hc_num].max_packet != mps) && (mps != 0))
+ {
+ pdev->host.hc[hc_num].max_packet = mps;
+ }
+
+ if((pdev->host.hc[hc_num].speed != speed ) && (speed != 0 ))
+ {
+ pdev->host.hc[hc_num].speed = speed;
+ }
+
+ USB_OTG_HC_Init(pdev, hc_num);
+ return HC_OK;
+
+}
+
+/**
+ * @brief USBH_Alloc_Channel
+ * Allocate a new channel for the pipe
+ * @param ep_addr: End point for which the channel to be allocated
+ * @retval hc_num: Host channel number
+ */
+uint8_t USBH_Alloc_Channel (USB_OTG_CORE_HANDLE *pdev, uint8_t ep_addr)
+{
+ uint16_t hc_num;
+
+ hc_num = USBH_GetFreeChannel(pdev);
+
+ if (hc_num != HC_ERROR)
+ {
+ pdev->host.channel[hc_num] = HC_USED | ep_addr;
+ }
+ return hc_num;
+}
+
+/**
+ * @brief USBH_Free_Pipe
+ * Free the USB host channel
+ * @param idx: Channel number to be freed
+ * @retval Status
+ */
+uint8_t USBH_Free_Channel (USB_OTG_CORE_HANDLE *pdev, uint8_t idx)
+{
+ if(idx < HC_MAX)
+ {
+ pdev->host.channel[idx] &= HC_USED_MASK;
+ }
+ return USBH_OK;
+}
+
+
+/**
+ * @brief USBH_DeAllocate_AllChannel
+ * Free all USB host channel
+* @param pdev : core instance
+ * @retval Status
+ */
+uint8_t USBH_DeAllocate_AllChannel (USB_OTG_CORE_HANDLE *pdev)
+{
+ uint8_t idx;
+
+ for (idx = 2; idx < HC_MAX ; idx ++)
+ {
+ pdev->host.channel[idx] = 0;
+ }
+ return USBH_OK;
+}
+
+/**
+ * @brief USBH_GetFreeChannel
+ * Get a free channel number for allocation to a device endpoint
+ * @param None
+ * @retval idx: Free Channel number
+ */
+static uint16_t USBH_GetFreeChannel (USB_OTG_CORE_HANDLE *pdev)
+{
+ uint8_t idx = 0;
+
+ for (idx = 0 ; idx < HC_MAX ; idx++)
+ {
+ if ((pdev->host.channel[idx] & HC_USED) == 0)
+ {
+ return idx;
+ }
+ }
+ return HC_ERROR;
+}
+
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
+
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32_USB_HOST_Library/Core/src/usbh_ioreq.c b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_HOST_Library/Core/src/usbh_ioreq.c
new file mode 100644
index 0000000..23d8307
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_HOST_Library/Core/src/usbh_ioreq.c
@@ -0,0 +1,474 @@
+/**
+ ******************************************************************************
+ * @file usbh_ioreq.c
+ * @author MCD Application Team
+ * @version V2.1.0
+ * @date 19-March-2012
+ * @brief This file handles the issuing of the USB transactions
+ ******************************************************************************
+ * @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 "usbh_ioreq.h"
+
+/** @addtogroup USBH_LIB
+ * @{
+ */
+
+/** @addtogroup USBH_LIB_CORE
+* @{
+*/
+
+/** @defgroup USBH_IOREQ
+ * @brief This file handles the standard protocol processing (USB v2.0)
+ * @{
+ */
+
+
+/** @defgroup USBH_IOREQ_Private_Defines
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup USBH_IOREQ_Private_TypesDefinitions
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+
+/** @defgroup USBH_IOREQ_Private_Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup USBH_IOREQ_Private_Variables
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup USBH_IOREQ_Private_FunctionPrototypes
+ * @{
+ */
+static USBH_Status USBH_SubmitSetupRequest(USBH_HOST *phost,
+ uint8_t* buff,
+ uint16_t length);
+
+/**
+ * @}
+ */
+
+
+/** @defgroup USBH_IOREQ_Private_Functions
+ * @{
+ */
+
+
+/**
+ * @brief USBH_CtlReq
+ * USBH_CtlReq sends a control request and provide the status after
+ * completion of the request
+ * @param pdev: Selected device
+ * @param req: Setup Request Structure
+ * @param buff: data buffer address to store the response
+ * @param length: length of the response
+ * @retval Status
+ */
+USBH_Status USBH_CtlReq (USB_OTG_CORE_HANDLE *pdev,
+ USBH_HOST *phost,
+ uint8_t *buff,
+ uint16_t length)
+{
+ USBH_Status status;
+ status = USBH_BUSY;
+
+ switch (phost->RequestState)
+ {
+ case CMD_SEND:
+ /* Start a SETUP transfer */
+ USBH_SubmitSetupRequest(phost, buff, length);
+ phost->RequestState = CMD_WAIT;
+ status = USBH_BUSY;
+ break;
+
+ case CMD_WAIT:
+ if (phost->Control.state == CTRL_COMPLETE )
+ {
+ /* Commands successfully sent and Response Received */
+ phost->RequestState = CMD_SEND;
+ phost->Control.state =CTRL_IDLE;
+ status = USBH_OK;
+ }
+ else if (phost->Control.state == CTRL_ERROR)
+ {
+ /* Failure Mode */
+ phost->RequestState = CMD_SEND;
+ status = USBH_FAIL;
+ }
+ else if (phost->Control.state == CTRL_STALLED )
+ {
+ /* Commands successfully sent and Response Received */
+ phost->RequestState = CMD_SEND;
+ status = USBH_NOT_SUPPORTED;
+ }
+ break;
+
+ default:
+ break;
+ }
+ return status;
+}
+
+/**
+ * @brief USBH_CtlSendSetup
+ * Sends the Setup Packet to the Device
+ * @param pdev: Selected device
+ * @param buff: Buffer pointer from which the Data will be send to Device
+ * @param hc_num: Host channel Number
+ * @retval Status
+ */
+USBH_Status USBH_CtlSendSetup ( USB_OTG_CORE_HANDLE *pdev,
+ uint8_t *buff,
+ uint8_t hc_num){
+ pdev->host.hc[hc_num].ep_is_in = 0;
+ pdev->host.hc[hc_num].data_pid = HC_PID_SETUP;
+ pdev->host.hc[hc_num].xfer_buff = buff;
+ pdev->host.hc[hc_num].xfer_len = USBH_SETUP_PKT_SIZE;
+
+ return (USBH_Status)HCD_SubmitRequest (pdev , hc_num);
+}
+
+
+/**
+ * @brief USBH_CtlSendData
+ * Sends a data Packet to the Device
+ * @param pdev: Selected device
+ * @param buff: Buffer pointer from which the Data will be sent to Device
+ * @param length: Length of the data to be sent
+ * @param hc_num: Host channel Number
+ * @retval Status
+ */
+USBH_Status USBH_CtlSendData ( USB_OTG_CORE_HANDLE *pdev,
+ uint8_t *buff,
+ uint16_t length,
+ uint8_t hc_num)
+{
+ pdev->host.hc[hc_num].ep_is_in = 0;
+ pdev->host.hc[hc_num].xfer_buff = buff;
+ pdev->host.hc[hc_num].xfer_len = length;
+
+ if ( length == 0 )
+ { /* For Status OUT stage, Length==0, Status Out PID = 1 */
+ pdev->host.hc[hc_num].toggle_out = 1;
+ }
+
+ /* Set the Data Toggle bit as per the Flag */
+ if ( pdev->host.hc[hc_num].toggle_out == 0)
+ { /* Put the PID 0 */
+ pdev->host.hc[hc_num].data_pid = HC_PID_DATA0;
+ }
+ else
+ { /* Put the PID 1 */
+ pdev->host.hc[hc_num].data_pid = HC_PID_DATA1 ;
+ }
+
+ HCD_SubmitRequest (pdev , hc_num);
+
+ return USBH_OK;
+}
+
+
+/**
+ * @brief USBH_CtlReceiveData
+ * Receives the Device Response to the Setup Packet
+ * @param pdev: Selected device
+ * @param buff: Buffer pointer in which the response needs to be copied
+ * @param length: Length of the data to be received
+ * @param hc_num: Host channel Number
+ * @retval Status.
+ */
+USBH_Status USBH_CtlReceiveData(USB_OTG_CORE_HANDLE *pdev,
+ uint8_t* buff,
+ uint16_t length,
+ uint8_t hc_num)
+{
+
+ pdev->host.hc[hc_num].ep_is_in = 1;
+ pdev->host.hc[hc_num].data_pid = HC_PID_DATA1;
+ pdev->host.hc[hc_num].xfer_buff = buff;
+ pdev->host.hc[hc_num].xfer_len = length;
+
+ HCD_SubmitRequest (pdev , hc_num);
+
+ return USBH_OK;
+
+}
+
+
+/**
+ * @brief USBH_BulkSendData
+ * Sends the Bulk Packet to the device
+ * @param pdev: Selected device
+ * @param buff: Buffer pointer from which the Data will be sent to Device
+ * @param length: Length of the data to be sent
+ * @param hc_num: Host channel Number
+ * @retval Status
+ */
+USBH_Status USBH_BulkSendData ( USB_OTG_CORE_HANDLE *pdev,
+ uint8_t *buff,
+ uint16_t length,
+ uint8_t hc_num)
+{
+ pdev->host.hc[hc_num].ep_is_in = 0;
+ pdev->host.hc[hc_num].xfer_buff = buff;
+ pdev->host.hc[hc_num].xfer_len = length;
+
+ /* Set the Data Toggle bit as per the Flag */
+ if ( pdev->host.hc[hc_num].toggle_out == 0)
+ { /* Put the PID 0 */
+ pdev->host.hc[hc_num].data_pid = HC_PID_DATA0;
+ }
+ else
+ { /* Put the PID 1 */
+ pdev->host.hc[hc_num].data_pid = HC_PID_DATA1 ;
+ }
+
+ HCD_SubmitRequest (pdev , hc_num);
+ return USBH_OK;
+}
+
+
+/**
+ * @brief USBH_BulkReceiveData
+ * Receives IN bulk packet from device
+ * @param pdev: Selected device
+ * @param buff: Buffer pointer in which the received data packet to be copied
+ * @param length: Length of the data to be received
+ * @param hc_num: Host channel Number
+ * @retval Status.
+ */
+USBH_Status USBH_BulkReceiveData( USB_OTG_CORE_HANDLE *pdev,
+ uint8_t *buff,
+ uint16_t length,
+ uint8_t hc_num)
+{
+ pdev->host.hc[hc_num].ep_is_in = 1;
+ pdev->host.hc[hc_num].xfer_buff = buff;
+ pdev->host.hc[hc_num].xfer_len = length;
+
+
+ if( pdev->host.hc[hc_num].toggle_in == 0)
+ {
+ pdev->host.hc[hc_num].data_pid = HC_PID_DATA0;
+ }
+ else
+ {
+ pdev->host.hc[hc_num].data_pid = HC_PID_DATA1;
+ }
+
+ HCD_SubmitRequest (pdev , hc_num);
+ return USBH_OK;
+}
+
+
+/**
+ * @brief USBH_InterruptReceiveData
+ * Receives the Device Response to the Interrupt IN token
+ * @param pdev: Selected device
+ * @param buff: Buffer pointer in which the response needs to be copied
+ * @param length: Length of the data to be received
+ * @param hc_num: Host channel Number
+ * @retval Status.
+ */
+USBH_Status USBH_InterruptReceiveData( USB_OTG_CORE_HANDLE *pdev,
+ uint8_t *buff,
+ uint8_t length,
+ uint8_t hc_num)
+{
+
+ pdev->host.hc[hc_num].ep_is_in = 1;
+ pdev->host.hc[hc_num].xfer_buff = buff;
+ pdev->host.hc[hc_num].xfer_len = length;
+
+
+
+ if(pdev->host.hc[hc_num].toggle_in == 0)
+ {
+ pdev->host.hc[hc_num].data_pid = HC_PID_DATA0;
+ }
+ else
+ {
+ pdev->host.hc[hc_num].data_pid = HC_PID_DATA1;
+ }
+
+ /* toggle DATA PID */
+ pdev->host.hc[hc_num].toggle_in ^= 1;
+
+ HCD_SubmitRequest (pdev , hc_num);
+
+ return USBH_OK;
+}
+
+/**
+ * @brief USBH_InterruptSendData
+ * Sends the data on Interrupt OUT Endpoint
+ * @param pdev: Selected device
+ * @param buff: Buffer pointer from where the data needs to be copied
+ * @param length: Length of the data to be sent
+ * @param hc_num: Host channel Number
+ * @retval Status.
+ */
+USBH_Status USBH_InterruptSendData( USB_OTG_CORE_HANDLE *pdev,
+ uint8_t *buff,
+ uint8_t length,
+ uint8_t hc_num)
+{
+
+ pdev->host.hc[hc_num].ep_is_in = 0;
+ pdev->host.hc[hc_num].xfer_buff = buff;
+ pdev->host.hc[hc_num].xfer_len = length;
+
+ if(pdev->host.hc[hc_num].toggle_in == 0)
+ {
+ pdev->host.hc[hc_num].data_pid = HC_PID_DATA0;
+ }
+ else
+ {
+ pdev->host.hc[hc_num].data_pid = HC_PID_DATA1;
+ }
+
+ pdev->host.hc[hc_num].toggle_in ^= 1;
+
+ HCD_SubmitRequest (pdev , hc_num);
+
+ return USBH_OK;
+}
+
+
+/**
+ * @brief USBH_SubmitSetupRequest
+ * Start a setup transfer by changing the state-machine and
+ * initializing the required variables needed for the Control Transfer
+ * @param pdev: Selected device
+ * @param setup: Setup Request Structure
+ * @param buff: Buffer used for setup request
+ * @param length: Length of the data
+ * @retval Status.
+*/
+static USBH_Status USBH_SubmitSetupRequest(USBH_HOST *phost,
+ uint8_t* buff,
+ uint16_t length)
+{
+
+ /* Save Global State */
+ phost->gStateBkp = phost->gState;
+
+ /* Prepare the Transactions */
+ phost->gState = HOST_CTRL_XFER;
+ phost->Control.buff = buff;
+ phost->Control.length = length;
+ phost->Control.state = CTRL_SETUP;
+
+ return USBH_OK;
+}
+
+
+/**
+ * @brief USBH_IsocReceiveData
+ * Receives the Device Response to the Isochronous IN token
+ * @param pdev: Selected device
+ * @param buff: Buffer pointer in which the response needs to be copied
+ * @param length: Length of the data to be received
+ * @param hc_num: Host channel Number
+ * @retval Status.
+ */
+USBH_Status USBH_IsocReceiveData( USB_OTG_CORE_HANDLE *pdev,
+ uint8_t *buff,
+ uint32_t length,
+ uint8_t hc_num)
+{
+
+ pdev->host.hc[hc_num].ep_is_in = 1;
+ pdev->host.hc[hc_num].xfer_buff = buff;
+ pdev->host.hc[hc_num].xfer_len = length;
+ pdev->host.hc[hc_num].data_pid = HC_PID_DATA0;
+
+
+ HCD_SubmitRequest (pdev , hc_num);
+
+ return USBH_OK;
+}
+
+/**
+ * @brief USBH_IsocSendData
+ * Sends the data on Isochronous OUT Endpoint
+ * @param pdev: Selected device
+ * @param buff: Buffer pointer from where the data needs to be copied
+ * @param length: Length of the data to be sent
+ * @param hc_num: Host channel Number
+ * @retval Status.
+ */
+USBH_Status USBH_IsocSendData( USB_OTG_CORE_HANDLE *pdev,
+ uint8_t *buff,
+ uint32_t length,
+ uint8_t hc_num)
+{
+
+ pdev->host.hc[hc_num].ep_is_in = 0;
+ pdev->host.hc[hc_num].xfer_buff = buff;
+ pdev->host.hc[hc_num].xfer_len = length;
+ pdev->host.hc[hc_num].data_pid = HC_PID_DATA0;
+
+ HCD_SubmitRequest (pdev , hc_num);
+
+ return USBH_OK;
+}
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
+
+
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32_USB_HOST_Library/Core/src/usbh_stdreq.c b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_HOST_Library/Core/src/usbh_stdreq.c
new file mode 100644
index 0000000..5ee46d5
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_HOST_Library/Core/src/usbh_stdreq.c
@@ -0,0 +1,607 @@
+/**
+ ******************************************************************************
+ * @file usbh_stdreq.c
+ * @author MCD Application Team
+ * @version V2.1.0
+ * @date 19-March-2012
+ * @brief This file implements the standard requests for device enumeration
+ ******************************************************************************
+ * @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 "usbh_ioreq.h"
+#include "usbh_stdreq.h"
+
+/** @addtogroup USBH_LIB
+* @{
+*/
+
+/** @addtogroup USBH_LIB_CORE
+* @{
+*/
+
+/** @defgroup USBH_STDREQ
+* @brief This file implements the standard requests for device enumeration
+* @{
+*/
+
+
+/** @defgroup USBH_STDREQ_Private_Defines
+* @{
+*/
+/**
+* @}
+*/
+
+
+/** @defgroup USBH_STDREQ_Private_TypesDefinitions
+* @{
+*/
+/**
+* @}
+*/
+
+
+
+/** @defgroup USBH_STDREQ_Private_Macros
+* @{
+*/
+/**
+* @}
+*/
+
+
+/** @defgroup USBH_STDREQ_Private_Variables
+* @{
+*/
+/**
+* @}
+*/
+#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 USBH_CfgDesc[512] __ALIGN_END ;
+
+
+/** @defgroup USBH_STDREQ_Private_FunctionPrototypes
+* @{
+*/
+static void USBH_ParseDevDesc (USBH_DevDesc_TypeDef* , uint8_t *buf, uint16_t length);
+
+static void USBH_ParseCfgDesc (USBH_CfgDesc_TypeDef* cfg_desc,
+ USBH_InterfaceDesc_TypeDef* itf_desc,
+ USBH_EpDesc_TypeDef ep_desc[][USBH_MAX_NUM_ENDPOINTS],
+ uint8_t *buf,
+ uint16_t length);
+
+
+static void USBH_ParseInterfaceDesc (USBH_InterfaceDesc_TypeDef *if_descriptor, uint8_t *buf);
+static void USBH_ParseEPDesc (USBH_EpDesc_TypeDef *ep_descriptor, uint8_t *buf);
+
+static void USBH_ParseStringDesc (uint8_t* psrc, uint8_t* pdest, uint16_t length);
+/**
+* @}
+*/
+
+
+/** @defgroup USBH_STDREQ_Private_Functions
+* @{
+*/
+
+
+/**
+* @brief USBH_Get_DevDesc
+* Issue Get Device Descriptor command to the device. Once the response
+* received, it parses the device descriptor and updates the status.
+* @param pdev: Selected device
+* @param dev_desc: Device Descriptor buffer address
+* @param pdev->host.Rx_Buffer: Receive Buffer address
+* @param length: Length of the descriptor
+* @retval Status
+*/
+USBH_Status USBH_Get_DevDesc(USB_OTG_CORE_HANDLE *pdev,
+ USBH_HOST *phost,
+ uint8_t length)
+{
+
+ USBH_Status status;
+
+ if((status = USBH_GetDescriptor(pdev,
+ phost,
+ USB_REQ_RECIPIENT_DEVICE | USB_REQ_TYPE_STANDARD,
+ USB_DESC_DEVICE,
+ pdev->host.Rx_Buffer,
+ length)) == USBH_OK)
+ {
+ /* Commands successfully sent and Response Received */
+ USBH_ParseDevDesc(&phost->device_prop.Dev_Desc, pdev->host.Rx_Buffer, length);
+ }
+ return status;
+}
+
+/**
+* @brief USBH_Get_CfgDesc
+* Issues Configuration Descriptor to the device. Once the response
+* received, it parses the configuartion descriptor and updates the
+* status.
+* @param pdev: Selected device
+* @param cfg_desc: Configuration Descriptor address
+* @param itf_desc: Interface Descriptor address
+* @param ep_desc: Endpoint Descriptor address
+* @param length: Length of the descriptor
+* @retval Status
+*/
+USBH_Status USBH_Get_CfgDesc(USB_OTG_CORE_HANDLE *pdev,
+ USBH_HOST *phost,
+ uint16_t length)
+
+{
+ USBH_Status status;
+ uint16_t index = 0;
+
+ if((status = USBH_GetDescriptor(pdev,
+ phost,
+ USB_REQ_RECIPIENT_DEVICE | USB_REQ_TYPE_STANDARD,
+ USB_DESC_CONFIGURATION,
+ pdev->host.Rx_Buffer,
+ length)) == USBH_OK)
+ {
+ /*save Cfg descriptor for class parsing usage */
+ for( ; index < length ; index ++)
+ {
+ USBH_CfgDesc[index] = pdev->host.Rx_Buffer[index];
+ }
+
+ /* Commands successfully sent and Response Received */
+ USBH_ParseCfgDesc (&phost->device_prop.Cfg_Desc,
+ phost->device_prop.Itf_Desc,
+ phost->device_prop.Ep_Desc,
+ pdev->host.Rx_Buffer,
+ length);
+
+ }
+ return status;
+}
+
+
+/**
+* @brief USBH_Get_StringDesc
+* Issues string Descriptor command to the device. Once the response
+* received, it parses the string descriptor and updates the status.
+* @param pdev: Selected device
+* @param string_index: String index for the descriptor
+* @param buff: Buffer address for the descriptor
+* @param length: Length of the descriptor
+* @retval Status
+*/
+USBH_Status USBH_Get_StringDesc(USB_OTG_CORE_HANDLE *pdev,
+ USBH_HOST *phost,
+ uint8_t string_index,
+ uint8_t *buff,
+ uint16_t length)
+{
+ USBH_Status status;
+
+ if((status = USBH_GetDescriptor(pdev,
+ phost,
+ USB_REQ_RECIPIENT_DEVICE | USB_REQ_TYPE_STANDARD,
+ USB_DESC_STRING | string_index,
+ pdev->host.Rx_Buffer,
+ length)) == USBH_OK)
+ {
+ /* Commands successfully sent and Response Received */
+ USBH_ParseStringDesc(pdev->host.Rx_Buffer,buff, length);
+ }
+ return status;
+}
+
+/**
+* @brief USBH_GetDescriptor
+* Issues Descriptor command to the device. Once the response received,
+* it parses the descriptor and updates the status.
+* @param pdev: Selected device
+* @param req_type: Descriptor type
+* @param value_idx: wValue for the GetDescriptr request
+* @param buff: Buffer to store the descriptor
+* @param length: Length of the descriptor
+* @retval Status
+*/
+USBH_Status USBH_GetDescriptor(USB_OTG_CORE_HANDLE *pdev,
+ USBH_HOST *phost,
+ uint8_t req_type,
+ uint16_t value_idx,
+ uint8_t* buff,
+ uint16_t length )
+{
+ phost->Control.setup.b.bmRequestType = USB_D2H | req_type;
+ phost->Control.setup.b.bRequest = USB_REQ_GET_DESCRIPTOR;
+ phost->Control.setup.b.wValue.w = value_idx;
+
+ if ((value_idx & 0xff00) == USB_DESC_STRING)
+ {
+ phost->Control.setup.b.wIndex.w = 0x0409;
+ }
+ else
+ {
+ phost->Control.setup.b.wIndex.w = 0;
+ }
+ phost->Control.setup.b.wLength.w = length;
+ return USBH_CtlReq(pdev, phost, buff , length );
+}
+
+/**
+* @brief USBH_SetAddress
+* This command sets the address to the connected device
+* @param pdev: Selected device
+* @param DeviceAddress: Device address to assign
+* @retval Status
+*/
+USBH_Status USBH_SetAddress(USB_OTG_CORE_HANDLE *pdev,
+ USBH_HOST *phost,
+ uint8_t DeviceAddress)
+{
+ phost->Control.setup.b.bmRequestType = USB_H2D | USB_REQ_RECIPIENT_DEVICE | \
+ USB_REQ_TYPE_STANDARD;
+
+ phost->Control.setup.b.bRequest = USB_REQ_SET_ADDRESS;
+
+ phost->Control.setup.b.wValue.w = (uint16_t)DeviceAddress;
+ phost->Control.setup.b.wIndex.w = 0;
+ phost->Control.setup.b.wLength.w = 0;
+
+ return USBH_CtlReq(pdev, phost, 0 , 0 );
+}
+
+/**
+* @brief USBH_SetCfg
+* The command sets the configuration value to the connected device
+* @param pdev: Selected device
+* @param cfg_idx: Configuration value
+* @retval Status
+*/
+USBH_Status USBH_SetCfg(USB_OTG_CORE_HANDLE *pdev,
+ USBH_HOST *phost,
+ uint16_t cfg_idx)
+{
+
+ phost->Control.setup.b.bmRequestType = USB_H2D | USB_REQ_RECIPIENT_DEVICE |\
+ USB_REQ_TYPE_STANDARD;
+ phost->Control.setup.b.bRequest = USB_REQ_SET_CONFIGURATION;
+ phost->Control.setup.b.wValue.w = cfg_idx;
+ phost->Control.setup.b.wIndex.w = 0;
+ phost->Control.setup.b.wLength.w = 0;
+
+ return USBH_CtlReq(pdev, phost, 0 , 0 );
+}
+
+/**
+* @brief USBH_SetInterface
+* The command sets the Interface value to the connected device
+* @param pdev: Selected device
+* @param itf_idx: Interface value
+* @retval Status
+*/
+USBH_Status USBH_SetInterface(USB_OTG_CORE_HANDLE *pdev,
+ USBH_HOST *phost,
+ uint8_t ep_num, uint8_t altSetting)
+{
+
+
+ phost->Control.setup.b.bmRequestType = USB_H2D | USB_REQ_RECIPIENT_INTERFACE | \
+ USB_REQ_TYPE_STANDARD;
+
+ phost->Control.setup.b.bRequest = USB_REQ_SET_INTERFACE;
+ phost->Control.setup.b.wValue.w = altSetting;
+ phost->Control.setup.b.wIndex.w = ep_num;
+ phost->Control.setup.b.wLength.w = 0;
+
+ return USBH_CtlReq(pdev, phost, 0 , 0 );
+}
+/**
+* @brief USBH_ClrFeature
+* This request is used to clear or disable a specific feature.
+
+* @param pdev: Selected device
+* @param ep_num: endpoint number
+* @param hc_num: Host channel number
+* @retval Status
+*/
+USBH_Status USBH_ClrFeature(USB_OTG_CORE_HANDLE *pdev,
+ USBH_HOST *phost,
+ uint8_t ep_num,
+ uint8_t hc_num)
+{
+
+ phost->Control.setup.b.bmRequestType = USB_H2D |
+ USB_REQ_RECIPIENT_ENDPOINT |
+ USB_REQ_TYPE_STANDARD;
+
+ phost->Control.setup.b.bRequest = USB_REQ_CLEAR_FEATURE;
+ phost->Control.setup.b.wValue.w = FEATURE_SELECTOR_ENDPOINT;
+ phost->Control.setup.b.wIndex.w = ep_num;
+ phost->Control.setup.b.wLength.w = 0;
+
+ if ((ep_num & USB_REQ_DIR_MASK ) == USB_D2H)
+ { /* EP Type is IN */
+ pdev->host.hc[hc_num].toggle_in = 0;
+ }
+ else
+ {/* EP Type is OUT */
+ pdev->host.hc[hc_num].toggle_out = 0;
+ }
+
+ return USBH_CtlReq(pdev, phost, 0 , 0 );
+}
+
+/**
+* @brief USBH_ParseDevDesc
+* This function Parses the device descriptor
+* @param dev_desc: device_descriptor destinaton address
+* @param buf: Buffer where the source descriptor is available
+* @param length: Length of the descriptor
+* @retval None
+*/
+static void USBH_ParseDevDesc (USBH_DevDesc_TypeDef* dev_desc,
+ uint8_t *buf,
+ uint16_t length)
+{
+ dev_desc->bLength = *(uint8_t *) (buf + 0);
+ dev_desc->bDescriptorType = *(uint8_t *) (buf + 1);
+ dev_desc->bcdUSB = LE16 (buf + 2);
+ dev_desc->bDeviceClass = *(uint8_t *) (buf + 4);
+ dev_desc->bDeviceSubClass = *(uint8_t *) (buf + 5);
+ dev_desc->bDeviceProtocol = *(uint8_t *) (buf + 6);
+ dev_desc->bMaxPacketSize = *(uint8_t *) (buf + 7);
+
+ if (length > 8)
+ { /* For 1st time after device connection, Host may issue only 8 bytes for
+ Device Descriptor Length */
+ dev_desc->idVendor = LE16 (buf + 8);
+ dev_desc->idProduct = LE16 (buf + 10);
+ dev_desc->bcdDevice = LE16 (buf + 12);
+ dev_desc->iManufacturer = *(uint8_t *) (buf + 14);
+ dev_desc->iProduct = *(uint8_t *) (buf + 15);
+ dev_desc->iSerialNumber = *(uint8_t *) (buf + 16);
+ dev_desc->bNumConfigurations = *(uint8_t *) (buf + 17);
+ }
+}
+
+/**
+* @brief USBH_ParseCfgDesc
+* This function Parses the configuration descriptor
+* @param cfg_desc: Configuration Descriptor address
+* @param itf_desc: Interface Descriptor address
+* @param ep_desc: Endpoint Descriptor address
+* @param buf: Buffer where the source descriptor is available
+* @param length: Length of the descriptor
+* @retval None
+*/
+static void USBH_ParseCfgDesc (USBH_CfgDesc_TypeDef* cfg_desc,
+ USBH_InterfaceDesc_TypeDef* itf_desc,
+ USBH_EpDesc_TypeDef ep_desc[][USBH_MAX_NUM_ENDPOINTS],
+ uint8_t *buf,
+ uint16_t length)
+{
+ USBH_InterfaceDesc_TypeDef *pif ;
+ USBH_InterfaceDesc_TypeDef temp_pif ;
+ USBH_EpDesc_TypeDef *pep;
+ USBH_DescHeader_t *pdesc = (USBH_DescHeader_t *)buf;
+ uint16_t ptr;
+ int8_t if_ix = 0;
+ int8_t ep_ix = 0;
+ static uint16_t prev_ep_size = 0;
+ static uint8_t prev_itf = 0;
+
+
+ pdesc = (USBH_DescHeader_t *)buf;
+
+ /* Parse configuration descriptor */
+ cfg_desc->bLength = *(uint8_t *) (buf + 0);
+ cfg_desc->bDescriptorType = *(uint8_t *) (buf + 1);
+ cfg_desc->wTotalLength = LE16 (buf + 2);
+ cfg_desc->bNumInterfaces = *(uint8_t *) (buf + 4);
+ cfg_desc->bConfigurationValue = *(uint8_t *) (buf + 5);
+ cfg_desc->iConfiguration = *(uint8_t *) (buf + 6);
+ cfg_desc->bmAttributes = *(uint8_t *) (buf + 7);
+ cfg_desc->bMaxPower = *(uint8_t *) (buf + 8);
+
+
+ if (length > USB_CONFIGURATION_DESC_SIZE)
+ {
+ ptr = USB_LEN_CFG_DESC;
+
+ if ( cfg_desc->bNumInterfaces <= USBH_MAX_NUM_INTERFACES)
+ {
+ pif = (USBH_InterfaceDesc_TypeDef *)0;
+
+ while (ptr < cfg_desc->wTotalLength )
+ {
+ pdesc = USBH_GetNextDesc((uint8_t *)pdesc, &ptr);
+ if (pdesc->bDescriptorType == USB_DESC_TYPE_INTERFACE)
+ {
+ if_ix = *(((uint8_t *)pdesc ) + 2);
+ pif = &itf_desc[if_ix];
+
+ if((*((uint8_t *)pdesc + 3)) < 3)
+ {
+ USBH_ParseInterfaceDesc (&temp_pif, (uint8_t *)pdesc);
+ ep_ix = 0;
+
+ /* Parse Ep descriptors relative to the current interface */
+ if(temp_pif.bNumEndpoints <= USBH_MAX_NUM_ENDPOINTS)
+ {
+ while (ep_ix < temp_pif.bNumEndpoints)
+ {
+ pdesc = USBH_GetNextDesc((void* )pdesc, &ptr);
+ if (pdesc->bDescriptorType == USB_DESC_TYPE_ENDPOINT)
+ {
+ pep = &ep_desc[if_ix][ep_ix];
+
+ if(prev_itf != if_ix)
+ {
+ prev_itf = if_ix;
+ USBH_ParseInterfaceDesc (pif, (uint8_t *)&temp_pif);
+ }
+ else
+ {
+ if(prev_ep_size > LE16((uint8_t *)pdesc + 4))
+ {
+ break;
+ }
+ else
+ {
+ USBH_ParseInterfaceDesc (pif, (uint8_t *)&temp_pif);
+ }
+ }
+ USBH_ParseEPDesc (pep, (uint8_t *)pdesc);
+ prev_ep_size = LE16((uint8_t *)pdesc + 4);
+ ep_ix++;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ prev_ep_size = 0;
+ prev_itf = 0;
+ }
+}
+
+
+/**
+* @brief USBH_ParseInterfaceDesc
+* This function Parses the interface descriptor
+* @param if_descriptor : Interface descriptor destination
+* @param buf: Buffer where the descriptor data is available
+* @retval None
+*/
+static void USBH_ParseInterfaceDesc (USBH_InterfaceDesc_TypeDef *if_descriptor,
+ uint8_t *buf)
+{
+ if_descriptor->bLength = *(uint8_t *) (buf + 0);
+ if_descriptor->bDescriptorType = *(uint8_t *) (buf + 1);
+ if_descriptor->bInterfaceNumber = *(uint8_t *) (buf + 2);
+ if_descriptor->bAlternateSetting = *(uint8_t *) (buf + 3);
+ if_descriptor->bNumEndpoints = *(uint8_t *) (buf + 4);
+ if_descriptor->bInterfaceClass = *(uint8_t *) (buf + 5);
+ if_descriptor->bInterfaceSubClass = *(uint8_t *) (buf + 6);
+ if_descriptor->bInterfaceProtocol = *(uint8_t *) (buf + 7);
+ if_descriptor->iInterface = *(uint8_t *) (buf + 8);
+}
+
+/**
+* @brief USBH_ParseEPDesc
+* This function Parses the endpoint descriptor
+* @param ep_descriptor: Endpoint descriptor destination address
+* @param buf: Buffer where the parsed descriptor stored
+* @retval None
+*/
+static void USBH_ParseEPDesc (USBH_EpDesc_TypeDef *ep_descriptor,
+ uint8_t *buf)
+{
+
+ ep_descriptor->bLength = *(uint8_t *) (buf + 0);
+ ep_descriptor->bDescriptorType = *(uint8_t *) (buf + 1);
+ ep_descriptor->bEndpointAddress = *(uint8_t *) (buf + 2);
+ ep_descriptor->bmAttributes = *(uint8_t *) (buf + 3);
+ ep_descriptor->wMaxPacketSize = LE16 (buf + 4);
+ ep_descriptor->bInterval = *(uint8_t *) (buf + 6);
+}
+
+/**
+* @brief USBH_ParseStringDesc
+* This function Parses the string descriptor
+* @param psrc: Source pointer containing the descriptor data
+* @param pdest: Destination address pointer
+* @param length: Length of the descriptor
+* @retval None
+*/
+static void USBH_ParseStringDesc (uint8_t* psrc,
+ uint8_t* pdest,
+ uint16_t length)
+{
+ uint16_t strlength;
+ uint16_t idx;
+
+ /* The UNICODE string descriptor is not NULL-terminated. The string length is
+ computed by substracting two from the value of the first byte of the descriptor.
+ */
+
+ /* Check which is lower size, the Size of string or the length of bytes read
+ from the device */
+
+ if ( psrc[1] == USB_DESC_TYPE_STRING)
+ { /* Make sure the Descriptor is String Type */
+
+ /* psrc[0] contains Size of Descriptor, subtract 2 to get the length of string */
+ strlength = ( ( (psrc[0]-2) <= length) ? (psrc[0]-2) :length);
+ psrc += 2; /* Adjust the offset ignoring the String Len and Descriptor type */
+
+ for (idx = 0; idx < strlength; idx+=2 )
+ {/* Copy Only the string and ignore the UNICODE ID, hence add the src */
+ *pdest = psrc[idx];
+ pdest++;
+ }
+ *pdest = 0; /* mark end of string */
+ }
+}
+
+/**
+* @brief USBH_GetNextDesc
+* This function return the next descriptor header
+* @param buf: Buffer where the cfg descriptor is available
+* @param ptr: data popinter inside the cfg descriptor
+* @retval next header
+*/
+USBH_DescHeader_t *USBH_GetNextDesc (uint8_t *pbuf, uint16_t *ptr)
+{
+ USBH_DescHeader_t *pnext;
+
+ *ptr += ((USBH_DescHeader_t *)pbuf)->bLength;
+ pnext = (USBH_DescHeader_t *)((uint8_t *)pbuf + \
+ ((USBH_DescHeader_t *)pbuf)->bLength);
+
+ return(pnext);
+}
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
+
+
+
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32_USB_OTG_Driver/inc/usb_bsp.h b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_OTG_Driver/inc/usb_bsp.h
new file mode 100644
index 0000000..a23cd36
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_OTG_Driver/inc/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/SPARK_Platform/MCU/STM32F2xx/STM32_USB_OTG_Driver/inc/usb_conf_template.h b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_OTG_Driver/inc/usb_conf_template.h
new file mode 100644
index 0000000..dcb6730
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_OTG_Driver/inc/usb_conf_template.h
@@ -0,0 +1,306 @@
+/**
+ ******************************************************************************
+ * @file usb_conf.h
+ * @author MCD Application Team
+ * @version V2.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 "usb_conf.h"
+
+/** @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
+ //#define USE_USB_OTG_FS
+#endif /* USE_USB_OTG_FS */
+
+#ifdef USE_USB_OTG_FS
+ #define USB_OTG_FS_CORE
+#endif
+
+/****************** 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.
+*******************************************************************************/
+
+/*******************************************************************************
+* FIFO Size Configuration in Host mode
+*
+* (i) Receive data FIFO size = (Largest Packet Size / 4) + 1 or
+* 2x (Largest Packet Size / 4) + 1, If a
+* high-bandwidth channel or multiple isochronous
+* channels are enabled
+*
+* (ii) For the host nonperiodic Transmit FIFO is the largest maximum packet size
+* for all supported nonperiodic OUT channels. Typically, a space
+* corresponding to two Largest Packet Size is recommended.
+*
+* (iii) The minimum amount of RAM required for Host periodic Transmit FIFO is
+* the largest maximum packet size for all supported periodic OUT channels.
+* If there is at least one High Bandwidth Isochronous OUT endpoint,
+* then the space must be at least two times the maximum packet size for
+* that channel.
+*******************************************************************************/
+
+/****************** USB OTG HS CONFIGURATION **********************************/
+#ifdef USB_OTG_HS_CORE
+ #define RX_FIFO_HS_SIZE 512
+ #define TX0_FIFO_HS_SIZE 512
+ #define TX1_FIFO_HS_SIZE 512
+ #define TX2_FIFO_HS_SIZE 0
+ #define TX3_FIFO_HS_SIZE 0
+ #define TX4_FIFO_HS_SIZE 0
+ #define TX5_FIFO_HS_SIZE 0
+ #define TXH_NP_HS_FIFOSIZ 96
+ #define TXH_P_HS_FIFOSIZ 96
+
+// #define USB_OTG_HS_LOW_PWR_MGMT_SUPPORT
+// #define USB_OTG_HS_SOF_OUTPUT_ENABLED
+
+// #define USB_OTG_INTERNAL_VBUS_ENABLED
+ #define USB_OTG_EXTERNAL_VBUS_ENABLED
+
+ #ifdef USE_ULPI_PHY
+ #define USB_OTG_ULPI_PHY_ENABLED
+ #endif
+ #ifdef USE_EMBEDDED_PHY
+ #define USB_OTG_EMBEDDED_PHY_ENABLED
+ #endif
+ #define USB_OTG_HS_INTERNAL_DMA_ENABLED
+ #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 64
+ #define TX1_FIFO_FS_SIZE 128
+ #define TX2_FIFO_FS_SIZE 0
+ #define TX3_FIFO_FS_SIZE 0
+ #define TXH_NP_HS_FIFOSIZ 96
+ #define TXH_P_HS_FIFOSIZ 96
+
+// #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
+
+/****************** C Compilers dependant keywords ****************************/
+/* In HS mode and when the DMA is used, all variables and data structures dealing
+ with the DMA during the transaction process should be 4-bytes aligned */
+#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
+ #if defined (__GNUC__) /* GNU Compiler */
+ #define __ALIGN_END __attribute__ ((aligned (4)))
+ #define __ALIGN_BEGIN
+ #else
+ #define __ALIGN_END
+ #if defined (__CC_ARM) /* ARM Compiler */
+ #define __ALIGN_BEGIN __align(4)
+ #elif defined (__ICCARM__) /* IAR Compiler */
+ #define __ALIGN_BEGIN
+ #elif defined (__TASKING__) /* TASKING Compiler */
+ #define __ALIGN_BEGIN __align(4)
+ #endif /* __CC_ARM */
+ #endif /* __GNUC__ */
+#else
+ #define __ALIGN_BEGIN
+ #define __ALIGN_END
+#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
+
+/* __packed keyword used to decrease the data type alignment to 1-byte */
+#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/SPARK_Platform/MCU/STM32F2xx/STM32_USB_OTG_Driver/inc/usb_core.h b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_OTG_Driver/inc/usb_core.h
new file mode 100644
index 0000000..55e0fca
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_OTG_Driver/inc/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/SPARK_Platform/MCU/STM32F2xx/STM32_USB_OTG_Driver/inc/usb_dcd.h b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_OTG_Driver/inc/usb_dcd.h
new file mode 100644
index 0000000..7b42804
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_OTG_Driver/inc/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/SPARK_Platform/MCU/STM32F2xx/STM32_USB_OTG_Driver/inc/usb_dcd_int.h b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_OTG_Driver/inc/usb_dcd_int.h
new file mode 100644
index 0000000..69e525a
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_OTG_Driver/inc/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/SPARK_Platform/MCU/STM32F2xx/STM32_USB_OTG_Driver/inc/usb_defines.h b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_OTG_Driver/inc/usb_defines.h
new file mode 100644
index 0000000..333aeed
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_OTG_Driver/inc/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/SPARK_Platform/MCU/STM32F2xx/STM32_USB_OTG_Driver/inc/usb_hcd.h b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_OTG_Driver/inc/usb_hcd.h
new file mode 100644
index 0000000..0f46d17
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_OTG_Driver/inc/usb_hcd.h
@@ -0,0 +1,108 @@
+/**
+ ******************************************************************************
+ * @file usb_hcd.h
+ * @author MCD Application Team
+ * @version V2.1.0
+ * @date 19-March-2012
+ * @brief Host layer 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 __USB_HCD_H__
+#define __USB_HCD_H__
+
+/* Includes ------------------------------------------------------------------*/
+#include "usb_regs.h"
+#include "usb_core.h"
+
+
+/** @addtogroup USB_OTG_DRIVER
+ * @{
+ */
+
+/** @defgroup USB_HCD
+ * @brief This file is the
+ * @{
+ */
+
+
+/** @defgroup USB_HCD_Exported_Defines
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup USB_HCD_Exported_Types
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup USB_HCD_Exported_Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USB_HCD_Exported_Variables
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USB_HCD_Exported_FunctionsPrototype
+ * @{
+ */
+uint32_t HCD_Init (USB_OTG_CORE_HANDLE *pdev ,
+ USB_OTG_CORE_ID_TypeDef coreID);
+uint32_t HCD_HC_Init (USB_OTG_CORE_HANDLE *pdev ,
+ uint8_t hc_num);
+uint32_t HCD_SubmitRequest (USB_OTG_CORE_HANDLE *pdev ,
+ uint8_t hc_num) ;
+uint32_t HCD_GetCurrentSpeed (USB_OTG_CORE_HANDLE *pdev);
+uint32_t HCD_ResetPort (USB_OTG_CORE_HANDLE *pdev);
+uint32_t HCD_IsDeviceConnected (USB_OTG_CORE_HANDLE *pdev);
+uint32_t HCD_GetCurrentFrame (USB_OTG_CORE_HANDLE *pdev) ;
+URB_STATE HCD_GetURB_State (USB_OTG_CORE_HANDLE *pdev, uint8_t ch_num);
+uint32_t HCD_GetXferCnt (USB_OTG_CORE_HANDLE *pdev, uint8_t ch_num);
+HC_STATUS HCD_GetHCState (USB_OTG_CORE_HANDLE *pdev, uint8_t ch_num) ;
+/**
+ * @}
+ */
+
+#endif //__USB_HCD_H__
+
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32_USB_OTG_Driver/inc/usb_hcd_int.h b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_OTG_Driver/inc/usb_hcd_int.h
new file mode 100644
index 0000000..fc2c649
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_OTG_Driver/inc/usb_hcd_int.h
@@ -0,0 +1,141 @@
+/**
+ ******************************************************************************
+ * @file usb_hcd_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 __HCD_INT_H__
+#define __HCD_INT_H__
+
+/* Includes ------------------------------------------------------------------*/
+#include "usb_hcd.h"
+
+
+/** @addtogroup USB_OTG_DRIVER
+ * @{
+ */
+
+/** @defgroup USB_HCD_INT
+ * @brief This file is the
+ * @{
+ */
+
+
+/** @defgroup USB_HCD_INT_Exported_Defines
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup USB_HCD_INT_Exported_Types
+ * @{
+ */
+
+typedef struct _USBH_HCD_INT
+{
+ uint8_t (* SOF) (USB_OTG_CORE_HANDLE *pdev);
+ uint8_t (* DevConnected) (USB_OTG_CORE_HANDLE *pdev);
+ uint8_t (* DevDisconnected) (USB_OTG_CORE_HANDLE *pdev);
+
+}USBH_HCD_INT_cb_TypeDef;
+
+extern USBH_HCD_INT_cb_TypeDef *USBH_HCD_INT_fops;
+/**
+ * @}
+ */
+
+
+/** @defgroup USB_HCD_INT_Exported_Macros
+ * @{
+ */
+
+#define CLEAR_HC_INT(HC_REGS, intr) \
+ {\
+ USB_OTG_HCINTn_TypeDef hcint_clear; \
+ hcint_clear.d32 = 0; \
+ hcint_clear.b.intr = 1; \
+ USB_OTG_WRITE_REG32(&((HC_REGS)->HCINT), hcint_clear.d32);\
+ }\
+
+#define MASK_HOST_INT_CHH(hc_num) { USB_OTG_HCINTMSK_TypeDef INTMSK; \
+ INTMSK.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[hc_num]->HCINTMSK); \
+ INTMSK.b.chhltd = 0; \
+ USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCINTMSK, INTMSK.d32);}
+
+#define UNMASK_HOST_INT_CHH(hc_num) { USB_OTG_HCINTMSK_TypeDef INTMSK; \
+ INTMSK.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[hc_num]->HCINTMSK); \
+ INTMSK.b.chhltd = 1; \
+ USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCINTMSK, INTMSK.d32);}
+
+#define MASK_HOST_INT_ACK(hc_num) { USB_OTG_HCINTMSK_TypeDef INTMSK; \
+ INTMSK.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[hc_num]->HCINTMSK); \
+ INTMSK.b.ack = 0; \
+ USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCINTMSK, GINTMSK.d32);}
+
+#define UNMASK_HOST_INT_ACK(hc_num) { USB_OTG_HCGINTMSK_TypeDef INTMSK; \
+ INTMSK.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[hc_num]->HCINTMSK); \
+ INTMSK.b.ack = 1; \
+ USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCINTMSK, INTMSK.d32);}
+
+/**
+ * @}
+ */
+
+/** @defgroup USB_HCD_INT_Exported_Variables
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USB_HCD_INT_Exported_FunctionsPrototype
+ * @{
+ */
+/* Callbacks handler */
+void ConnectCallback_Handler(USB_OTG_CORE_HANDLE *pdev);
+void Disconnect_Callback_Handler(USB_OTG_CORE_HANDLE *pdev);
+void Overcurrent_Callback_Handler(USB_OTG_CORE_HANDLE *pdev);
+uint32_t USBH_OTG_ISR_Handler (USB_OTG_CORE_HANDLE *pdev);
+
+/**
+ * @}
+ */
+
+
+
+#endif //__HCD_INT_H__
+
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32_USB_OTG_Driver/inc/usb_otg.h b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_OTG_Driver/inc/usb_otg.h
new file mode 100644
index 0000000..9f6054c
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_OTG_Driver/inc/usb_otg.h
@@ -0,0 +1,99 @@
+/**
+ ******************************************************************************
+ * @file usb_otg.h
+ * @author MCD Application Team
+ * @version V2.1.0
+ * @date 19-March-2012
+ * @brief OTG Core Header
+ ******************************************************************************
+ * @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__
+#define __USB_OTG__
+
+
+/** @addtogroup USB_OTG_DRIVER
+ * @{
+ */
+
+/** @defgroup USB_OTG
+ * @brief This file is the
+ * @{
+ */
+
+
+/** @defgroup USB_OTG_Exported_Defines
+ * @{
+ */
+
+
+void USB_OTG_InitiateSRP(void);
+void USB_OTG_InitiateHNP(uint8_t state , uint8_t mode);
+void USB_OTG_Switchback (USB_OTG_CORE_DEVICE *pdev);
+uint32_t USB_OTG_GetCurrentState (USB_OTG_CORE_DEVICE *pdev);
+
+/**
+ * @}
+ */
+
+
+/** @defgroup USB_OTG_Exported_Types
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup USB_OTG_Exported_Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USB_OTG_Exported_Variables
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USB_OTG_Exported_FunctionsPrototype
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+#endif //__USB_OTG__
+
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32_USB_OTG_Driver/inc/usb_regs.h b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_OTG_Driver/inc/usb_regs.h
new file mode 100644
index 0000000..7befb51
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_OTG_Driver/inc/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/SPARK_Platform/MCU/STM32F2xx/STM32_USB_OTG_Driver/src/usb_bsp_template.c b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_OTG_Driver/src/usb_bsp_template.c
new file mode 100644
index 0000000..ee9c3be
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_OTG_Driver/src/usb_bsp_template.c
@@ -0,0 +1,206 @@
+/**
+ ******************************************************************************
+ * @file usb_bsp.c
+ * @author MCD Application Team
+ * @version V2.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"
+
+/** @addtogroup USB_OTG_DRIVER
+* @{
+*/
+
+/** @defgroup USB_BSP
+ * @brief This file is responsible to offer board support package
+ * @{
+ */
+
+/** @defgroup USB_BSP_Private_Defines
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup USB_BSP_Private_TypesDefinitions
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+
+
+
+/** @defgroup USB_BSP_Private_Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USBH_BSP_Private_Variables
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup USBH_BSP_Private_FunctionPrototypes
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USB_BSP_Private_Functions
+ * @{
+ */
+
+
+/**
+ * @brief USB_OTG_BSP_Init
+ * Initilizes BSP configurations
+ * @param None
+ * @retval None
+ */
+
+void USB_OTG_BSP_Init(void)
+{
+
+}
+/**
+ * @brief USB_OTG_BSP_EnableInterrupt
+ * Enabele USB Global interrupt
+ * @param None
+ * @retval None
+ */
+void USB_OTG_BSP_EnableInterrupt(void)
+{
+
+}
+
+/**
+ * @brief BSP_Drive_VBUS
+ * Drives the Vbus signal through IO
+ * @param speed : Full, Low
+ * @param state : VBUS states
+ * @retval None
+ */
+
+void USB_OTG_BSP_DriveVBUS(uint32_t speed, uint8_t state)
+{
+
+}
+
+/**
+ * @brief USB_OTG_BSP_ConfigVBUS
+ * Configures the IO for the Vbus and OverCurrent
+ * @param Speed : Full, Low
+ * @retval None
+ */
+
+void USB_OTG_BSP_ConfigVBUS(uint32_t speed)
+{
+
+}
+
+/**
+ * @brief USB_OTG_BSP_TimeInit
+ * Initialises delay unit Systick timer /Timer2
+ * @param None
+ * @retval None
+ */
+void USB_OTG_BSP_TimeInit ( void )
+{
+
+}
+
+/**
+ * @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);
+
+}
+
+
+/**
+ * @brief USB_OTG_BSP_TimerIRQ
+ * Time base IRQ
+ * @param None
+ * @retval None
+ */
+
+void USB_OTG_BSP_TimerIRQ (void)
+{
+
+}
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32_USB_OTG_Driver/src/usb_core.c b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_OTG_Driver/src/usb_core.c
new file mode 100644
index 0000000..12a207d
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_OTG_Driver/src/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/SPARK_Platform/MCU/STM32F2xx/STM32_USB_OTG_Driver/src/usb_dcd.c b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_OTG_Driver/src/usb_dcd.c
new file mode 100644
index 0000000..36428e2
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_OTG_Driver/src/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/SPARK_Platform/MCU/STM32F2xx/STM32_USB_OTG_Driver/src/usb_dcd_int.c b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_OTG_Driver/src/usb_dcd_int.c
new file mode 100644
index 0000000..359d569
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_OTG_Driver/src/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/SPARK_Platform/MCU/STM32F2xx/STM32_USB_OTG_Driver/src/usb_hcd.c b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_OTG_Driver/src/usb_hcd.c
new file mode 100644
index 0000000..d983cd2
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_OTG_Driver/src/usb_hcd.c
@@ -0,0 +1,262 @@
+/**
+ ******************************************************************************
+ * @file usb_hcd.c
+ * @author MCD Application Team
+ * @version V2.1.0
+ * @date 19-March-2012
+ * @brief Host 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_core.h"
+#include "usb_hcd.h"
+#include "usb_conf.h"
+#include "usb_bsp.h"
+
+
+/** @addtogroup USB_OTG_DRIVER
+ * @{
+ */
+
+/** @defgroup USB_HCD
+ * @brief This file is the interface between EFSL ans Host mass-storage class
+ * @{
+ */
+
+
+/** @defgroup USB_HCD_Private_Defines
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup USB_HCD_Private_TypesDefinitions
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+
+/** @defgroup USB_HCD_Private_Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup USB_HCD_Private_Variables
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup USB_HCD_Private_FunctionPrototypes
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup USB_HCD_Private_Functions
+ * @{
+ */
+
+/**
+ * @brief HCD_Init
+ * Initialize the HOST portion of the driver.
+ * @param pdev: Selected device
+ * @param base_address: OTG base address
+ * @retval Status
+ */
+uint32_t HCD_Init(USB_OTG_CORE_HANDLE *pdev ,
+ USB_OTG_CORE_ID_TypeDef coreID)
+{
+ uint8_t i = 0;
+ pdev->host.ConnSts = 0;
+
+ for (i= 0; i< USB_OTG_MAX_TX_FIFOS; i++)
+ {
+ pdev->host.ErrCnt[i] = 0;
+ pdev->host.XferCnt[i] = 0;
+ pdev->host.HC_Status[i] = HC_IDLE;
+ }
+ pdev->host.hc[0].max_packet = 8;
+
+ USB_OTG_SelectCore(pdev, coreID);
+#ifndef DUAL_ROLE_MODE_ENABLED
+ USB_OTG_DisableGlobalInt(pdev);
+ USB_OTG_CoreInit(pdev);
+
+ /* Force Host Mode*/
+ USB_OTG_SetCurrentMode(pdev , HOST_MODE);
+ USB_OTG_CoreInitHost(pdev);
+ USB_OTG_EnableGlobalInt(pdev);
+#endif
+
+ return 0;
+}
+
+
+/**
+ * @brief HCD_GetCurrentSpeed
+ * Get Current device Speed.
+ * @param pdev : Selected device
+ * @retval Status
+ */
+
+uint32_t HCD_GetCurrentSpeed (USB_OTG_CORE_HANDLE *pdev)
+{
+ USB_OTG_HPRT0_TypeDef HPRT0;
+ HPRT0.d32 = USB_OTG_READ_REG32(pdev->regs.HPRT0);
+
+ return HPRT0.b.prtspd;
+}
+
+/**
+ * @brief HCD_ResetPort
+ * Issues the reset command to device
+ * @param pdev : Selected device
+ * @retval Status
+ */
+uint32_t HCD_ResetPort(USB_OTG_CORE_HANDLE *pdev)
+{
+ /*
+ Before starting to drive a USB reset, the application waits for the OTG
+ interrupt triggered by the debounce done bit (DBCDNE bit in OTG_FS_GOTGINT),
+ which indicates that the bus is stable again after the electrical debounce
+ caused by the attachment of a pull-up resistor on DP (FS) or DM (LS).
+ */
+
+ USB_OTG_ResetPort(pdev);
+ return 0;
+}
+
+/**
+ * @brief HCD_IsDeviceConnected
+ * Check if the device is connected.
+ * @param pdev : Selected device
+ * @retval Device connection status. 1 -> connected and 0 -> disconnected
+ *
+ */
+uint32_t HCD_IsDeviceConnected(USB_OTG_CORE_HANDLE *pdev)
+{
+ return (pdev->host.ConnSts);
+}
+
+/**
+ * @brief HCD_GetCurrentFrame
+ * This function returns the frame number for sof packet
+ * @param pdev : Selected device
+ * @retval Frame number
+ *
+ */
+uint32_t HCD_GetCurrentFrame (USB_OTG_CORE_HANDLE *pdev)
+{
+ return (USB_OTG_READ_REG32(&pdev->regs.HREGS->HFNUM) & 0xFFFF) ;
+}
+
+/**
+ * @brief HCD_GetURB_State
+ * This function returns the last URBstate
+ * @param pdev: Selected device
+ * @retval URB_STATE
+ *
+ */
+URB_STATE HCD_GetURB_State (USB_OTG_CORE_HANDLE *pdev , uint8_t ch_num)
+{
+ return pdev->host.URB_State[ch_num] ;
+}
+
+/**
+ * @brief HCD_GetXferCnt
+ * This function returns the last URBstate
+ * @param pdev: Selected device
+ * @retval No. of data bytes transferred
+ *
+ */
+uint32_t HCD_GetXferCnt (USB_OTG_CORE_HANDLE *pdev, uint8_t ch_num)
+{
+ return pdev->host.XferCnt[ch_num] ;
+}
+
+
+
+/**
+ * @brief HCD_GetHCState
+ * This function returns the HC Status
+ * @param pdev: Selected device
+ * @retval HC_STATUS
+ *
+ */
+HC_STATUS HCD_GetHCState (USB_OTG_CORE_HANDLE *pdev , uint8_t ch_num)
+{
+ return pdev->host.HC_Status[ch_num] ;
+}
+
+/**
+ * @brief HCD_HC_Init
+ * This function prepare a HC and start a transfer
+ * @param pdev: Selected device
+ * @param hc_num: Channel number
+ * @retval status
+ */
+uint32_t HCD_HC_Init (USB_OTG_CORE_HANDLE *pdev , uint8_t hc_num)
+{
+ return USB_OTG_HC_Init(pdev, hc_num);
+}
+
+/**
+ * @brief HCD_SubmitRequest
+ * This function prepare a HC and start a transfer
+ * @param pdev: Selected device
+ * @param hc_num: Channel number
+ * @retval status
+ */
+uint32_t HCD_SubmitRequest (USB_OTG_CORE_HANDLE *pdev , uint8_t hc_num)
+{
+
+ pdev->host.URB_State[hc_num] = URB_IDLE;
+ pdev->host.hc[hc_num].xfer_count = 0 ;
+ return USB_OTG_HC_StartXfer(pdev, hc_num);
+}
+
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32_USB_OTG_Driver/src/usb_hcd_int.c b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_OTG_Driver/src/usb_hcd_int.c
new file mode 100644
index 0000000..df83344
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_OTG_Driver/src/usb_hcd_int.c
@@ -0,0 +1,858 @@
+/**
+ ******************************************************************************
+ * @file usb_hcd_int.c
+ * @author MCD Application Team
+ * @version V2.1.0
+ * @date 19-March-2012
+ * @brief Host driver 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_core.h"
+#include "usb_defines.h"
+#include "usb_hcd_int.h"
+
+#if defined (__CC_ARM) /*!< ARM Compiler */
+#pragma O0
+#elif defined (__GNUC__) /*!< GNU Compiler */
+#pragma GCC optimize ("O0")
+#elif defined (__TASKING__) /*!< TASKING Compiler */
+#pragma optimize=0
+
+#endif /* __CC_ARM */
+
+/** @addtogroup USB_OTG_DRIVER
+* @{
+*/
+
+/** @defgroup USB_HCD_INT
+* @brief This file contains the interrupt subroutines for the Host mode.
+* @{
+*/
+
+
+/** @defgroup USB_HCD_INT_Private_Defines
+* @{
+*/
+/**
+* @}
+*/
+
+
+/** @defgroup USB_HCD_INT_Private_TypesDefinitions
+* @{
+*/
+/**
+* @}
+*/
+
+
+
+/** @defgroup USB_HCD_INT_Private_Macros
+* @{
+*/
+/**
+* @}
+*/
+
+
+/** @defgroup USB_HCD_INT_Private_Variables
+* @{
+*/
+/**
+* @}
+*/
+
+
+/** @defgroup USB_HCD_INT_Private_FunctionPrototypes
+* @{
+*/
+
+static uint32_t USB_OTG_USBH_handle_sof_ISR(USB_OTG_CORE_HANDLE *pdev);
+static uint32_t USB_OTG_USBH_handle_port_ISR(USB_OTG_CORE_HANDLE *pdev);
+static uint32_t USB_OTG_USBH_handle_hc_ISR (USB_OTG_CORE_HANDLE *pdev);
+static uint32_t USB_OTG_USBH_handle_hc_n_In_ISR (USB_OTG_CORE_HANDLE *pdev ,
+ uint32_t num);
+static uint32_t USB_OTG_USBH_handle_hc_n_Out_ISR (USB_OTG_CORE_HANDLE *pdev ,
+ uint32_t num);
+static uint32_t USB_OTG_USBH_handle_rx_qlvl_ISR (USB_OTG_CORE_HANDLE *pdev);
+static uint32_t USB_OTG_USBH_handle_nptxfempty_ISR (USB_OTG_CORE_HANDLE *pdev);
+static uint32_t USB_OTG_USBH_handle_ptxfempty_ISR (USB_OTG_CORE_HANDLE *pdev);
+static uint32_t USB_OTG_USBH_handle_Disconnect_ISR (USB_OTG_CORE_HANDLE *pdev);
+static uint32_t USB_OTG_USBH_handle_IncompletePeriodicXfer_ISR (USB_OTG_CORE_HANDLE *pdev);
+
+/**
+* @}
+*/
+
+
+/** @defgroup USB_HCD_INT_Private_Functions
+* @{
+*/
+
+/**
+* @brief HOST_Handle_ISR
+* This function handles all USB Host Interrupts
+* @param pdev: Selected device
+* @retval status
+*/
+
+uint32_t USBH_OTG_ISR_Handler (USB_OTG_CORE_HANDLE *pdev)
+{
+ USB_OTG_GINTSTS_TypeDef gintsts;
+ uint32_t retval = 0;
+
+ gintsts.d32 = 0;
+
+ /* Check if HOST Mode */
+ if (USB_OTG_IsHostMode(pdev))
+ {
+ gintsts.d32 = USB_OTG_ReadCoreItr(pdev);
+ if (!gintsts.d32)
+ {
+ return 0;
+ }
+
+ if (gintsts.b.sofintr)
+ {
+ retval |= USB_OTG_USBH_handle_sof_ISR (pdev);
+ }
+
+ if (gintsts.b.rxstsqlvl)
+ {
+ retval |= USB_OTG_USBH_handle_rx_qlvl_ISR (pdev);
+ }
+
+ if (gintsts.b.nptxfempty)
+ {
+ retval |= USB_OTG_USBH_handle_nptxfempty_ISR (pdev);
+ }
+
+ if (gintsts.b.ptxfempty)
+ {
+ retval |= USB_OTG_USBH_handle_ptxfempty_ISR (pdev);
+ }
+
+ if (gintsts.b.hcintr)
+ {
+ retval |= USB_OTG_USBH_handle_hc_ISR (pdev);
+ }
+
+ if (gintsts.b.portintr)
+ {
+ retval |= USB_OTG_USBH_handle_port_ISR (pdev);
+ }
+
+ if (gintsts.b.disconnect)
+ {
+ retval |= USB_OTG_USBH_handle_Disconnect_ISR (pdev);
+
+ }
+
+ if (gintsts.b.incomplisoout)
+ {
+ retval |= USB_OTG_USBH_handle_IncompletePeriodicXfer_ISR (pdev);
+ }
+
+
+ }
+ return retval;
+}
+
+/**
+* @brief USB_OTG_USBH_handle_hc_ISR
+* This function indicates that one or more host channels has a pending
+* @param pdev: Selected device
+* @retval status
+*/
+static uint32_t USB_OTG_USBH_handle_hc_ISR (USB_OTG_CORE_HANDLE *pdev)
+{
+ USB_OTG_HAINT_TypeDef haint;
+ USB_OTG_HCCHAR_TypeDef hcchar;
+ uint32_t i = 0;
+ uint32_t retval = 0;
+
+ /* Clear appropriate bits in HCINTn to clear the interrupt bit in
+ * GINTSTS */
+
+ haint.d32 = USB_OTG_ReadHostAllChannels_intr(pdev);
+
+ for (i = 0; i < pdev->cfg.host_channels ; i++)
+ {
+ if (haint.b.chint & (1 << i))
+ {
+ hcchar.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[i]->HCCHAR);
+
+ if (hcchar.b.epdir)
+ {
+ retval |= USB_OTG_USBH_handle_hc_n_In_ISR (pdev, i);
+ }
+ else
+ {
+ retval |= USB_OTG_USBH_handle_hc_n_Out_ISR (pdev, i);
+ }
+ }
+ }
+
+ return retval;
+}
+
+/**
+* @brief USB_OTG_otg_hcd_handle_sof_intr
+* Handles the start-of-frame interrupt in host mode.
+* @param pdev: Selected device
+* @retval status
+*/
+static uint32_t USB_OTG_USBH_handle_sof_ISR (USB_OTG_CORE_HANDLE *pdev)
+{
+ USB_OTG_GINTSTS_TypeDef gintsts;
+ gintsts.d32 = 0;
+
+ USBH_HCD_INT_fops->SOF(pdev);
+
+ /* Clear interrupt */
+ gintsts.b.sofintr = 1;
+ USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GINTSTS, gintsts.d32);
+
+ return 1;
+}
+
+/**
+* @brief USB_OTG_USBH_handle_Disconnect_ISR
+* Handles disconnect event.
+* @param pdev: Selected device
+* @retval status
+*/
+static uint32_t USB_OTG_USBH_handle_Disconnect_ISR (USB_OTG_CORE_HANDLE *pdev)
+{
+ USB_OTG_GINTSTS_TypeDef gintsts;
+
+ gintsts.d32 = 0;
+
+ USBH_HCD_INT_fops->DevDisconnected(pdev);
+
+ /* Clear interrupt */
+ gintsts.b.disconnect = 1;
+ USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GINTSTS, gintsts.d32);
+
+ return 1;
+}
+#if defined ( __ICCARM__ ) /*!< IAR Compiler */
+#pragma optimize = none
+#endif /* __CC_ARM */
+/**
+* @brief USB_OTG_USBH_handle_nptxfempty_ISR
+* Handles non periodic tx fifo empty.
+* @param pdev: Selected device
+* @retval status
+*/
+static uint32_t USB_OTG_USBH_handle_nptxfempty_ISR (USB_OTG_CORE_HANDLE *pdev)
+{
+ USB_OTG_GINTMSK_TypeDef intmsk;
+ USB_OTG_HNPTXSTS_TypeDef hnptxsts;
+ uint16_t len_words , len;
+
+ hnptxsts.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->HNPTXSTS);
+
+ len_words = (pdev->host.hc[hnptxsts.b.nptxqtop.chnum].xfer_len + 3) / 4;
+
+ while ((hnptxsts.b.nptxfspcavail > len_words)&&
+ (pdev->host.hc[hnptxsts.b.nptxqtop.chnum].xfer_len != 0))
+ {
+
+ len = hnptxsts.b.nptxfspcavail * 4;
+
+ if (len > pdev->host.hc[hnptxsts.b.nptxqtop.chnum].xfer_len)
+ {
+ /* Last packet */
+ len = pdev->host.hc[hnptxsts.b.nptxqtop.chnum].xfer_len;
+
+ intmsk.d32 = 0;
+ intmsk.b.nptxfempty = 1;
+ USB_OTG_MODIFY_REG32( &pdev->regs.GREGS->GINTMSK, intmsk.d32, 0);
+ }
+
+ len_words = (pdev->host.hc[hnptxsts.b.nptxqtop.chnum].xfer_len + 3) / 4;
+
+ USB_OTG_WritePacket (pdev , pdev->host.hc[hnptxsts.b.nptxqtop.chnum].xfer_buff, hnptxsts.b.nptxqtop.chnum, len);
+
+ pdev->host.hc[hnptxsts.b.nptxqtop.chnum].xfer_buff += len;
+ pdev->host.hc[hnptxsts.b.nptxqtop.chnum].xfer_len -= len;
+ pdev->host.hc[hnptxsts.b.nptxqtop.chnum].xfer_count += len;
+
+ hnptxsts.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->HNPTXSTS);
+ }
+
+ return 1;
+}
+#if defined ( __ICCARM__ ) /*!< IAR Compiler */
+#pragma optimize = none
+#endif /* __CC_ARM */
+/**
+* @brief USB_OTG_USBH_handle_ptxfempty_ISR
+* Handles periodic tx fifo empty
+* @param pdev: Selected device
+* @retval status
+*/
+static uint32_t USB_OTG_USBH_handle_ptxfempty_ISR (USB_OTG_CORE_HANDLE *pdev)
+{
+ USB_OTG_GINTMSK_TypeDef intmsk;
+ USB_OTG_HPTXSTS_TypeDef hptxsts;
+ uint16_t len_words , len;
+
+ hptxsts.d32 = USB_OTG_READ_REG32(&pdev->regs.HREGS->HPTXSTS);
+
+ len_words = (pdev->host.hc[hptxsts.b.ptxqtop.chnum].xfer_len + 3) / 4;
+
+ while ((hptxsts.b.ptxfspcavail > len_words)&&
+ (pdev->host.hc[hptxsts.b.ptxqtop.chnum].xfer_len != 0))
+ {
+
+ len = hptxsts.b.ptxfspcavail * 4;
+
+ if (len > pdev->host.hc[hptxsts.b.ptxqtop.chnum].xfer_len)
+ {
+ len = pdev->host.hc[hptxsts.b.ptxqtop.chnum].xfer_len;
+ /* Last packet */
+ intmsk.d32 = 0;
+ intmsk.b.ptxfempty = 1;
+ USB_OTG_MODIFY_REG32( &pdev->regs.GREGS->GINTMSK, intmsk.d32, 0);
+ }
+
+ len_words = (pdev->host.hc[hptxsts.b.ptxqtop.chnum].xfer_len + 3) / 4;
+
+ USB_OTG_WritePacket (pdev , pdev->host.hc[hptxsts.b.ptxqtop.chnum].xfer_buff, hptxsts.b.ptxqtop.chnum, len);
+
+ pdev->host.hc[hptxsts.b.ptxqtop.chnum].xfer_buff += len;
+ pdev->host.hc[hptxsts.b.ptxqtop.chnum].xfer_len -= len;
+ pdev->host.hc[hptxsts.b.ptxqtop.chnum].xfer_count += len;
+
+ hptxsts.d32 = USB_OTG_READ_REG32(&pdev->regs.HREGS->HPTXSTS);
+ }
+
+ return 1;
+}
+
+/**
+* @brief USB_OTG_USBH_handle_port_ISR
+* This function determines which interrupt conditions have occurred
+* @param pdev: Selected device
+* @retval status
+*/
+#if defined ( __ICCARM__ ) /*!< IAR Compiler */
+#pragma optimize = none
+#endif /* __CC_ARM */
+static uint32_t USB_OTG_USBH_handle_port_ISR (USB_OTG_CORE_HANDLE *pdev)
+{
+ USB_OTG_HPRT0_TypeDef hprt0;
+ USB_OTG_HPRT0_TypeDef hprt0_dup;
+ USB_OTG_HCFG_TypeDef hcfg;
+ uint32_t do_reset = 0;
+ uint32_t retval = 0;
+
+ hcfg.d32 = 0;
+ hprt0.d32 = 0;
+ hprt0_dup.d32 = 0;
+
+ hprt0.d32 = USB_OTG_READ_REG32(pdev->regs.HPRT0);
+ hprt0_dup.d32 = USB_OTG_READ_REG32(pdev->regs.HPRT0);
+
+ /* Clear the interrupt bits in GINTSTS */
+
+ hprt0_dup.b.prtena = 0;
+ hprt0_dup.b.prtconndet = 0;
+ hprt0_dup.b.prtenchng = 0;
+ hprt0_dup.b.prtovrcurrchng = 0;
+
+ /* Port Connect Detected */
+ if (hprt0.b.prtconndet)
+ {
+
+ hprt0_dup.b.prtconndet = 1;
+ USBH_HCD_INT_fops->DevConnected(pdev);
+ retval |= 1;
+ }
+
+ /* Port Enable Changed */
+ if (hprt0.b.prtenchng)
+ {
+ hprt0_dup.b.prtenchng = 1;
+
+ if (hprt0.b.prtena == 1)
+ {
+
+ USBH_HCD_INT_fops->DevConnected(pdev);
+
+ if ((hprt0.b.prtspd == HPRT0_PRTSPD_LOW_SPEED) ||
+ (hprt0.b.prtspd == HPRT0_PRTSPD_FULL_SPEED))
+ {
+
+ hcfg.d32 = USB_OTG_READ_REG32(&pdev->regs.HREGS->HCFG);
+
+ if (hprt0.b.prtspd == HPRT0_PRTSPD_LOW_SPEED)
+ {
+ USB_OTG_WRITE_REG32(&pdev->regs.HREGS->HFIR, 6000 );
+ if (hcfg.b.fslspclksel != HCFG_6_MHZ)
+ {
+ if(pdev->cfg.phy_itface == USB_OTG_EMBEDDED_PHY)
+ {
+ USB_OTG_InitFSLSPClkSel(pdev ,HCFG_6_MHZ );
+ }
+ do_reset = 1;
+ }
+ }
+ else
+ {
+
+ USB_OTG_WRITE_REG32(&pdev->regs.HREGS->HFIR, 48000 );
+ if (hcfg.b.fslspclksel != HCFG_48_MHZ)
+ {
+ USB_OTG_InitFSLSPClkSel(pdev ,HCFG_48_MHZ );
+ do_reset = 1;
+ }
+ }
+ }
+ else
+ {
+ do_reset = 1;
+ }
+ }
+ }
+ /* Overcurrent Change Interrupt */
+ if (hprt0.b.prtovrcurrchng)
+ {
+ hprt0_dup.b.prtovrcurrchng = 1;
+ retval |= 1;
+ }
+ if (do_reset)
+ {
+ USB_OTG_ResetPort(pdev);
+ }
+ /* Clear Port Interrupts */
+ USB_OTG_WRITE_REG32(pdev->regs.HPRT0, hprt0_dup.d32);
+
+ return retval;
+}
+#if defined ( __ICCARM__ ) /*!< IAR Compiler */
+#pragma optimize = none
+#endif /* __CC_ARM */
+/**
+* @brief USB_OTG_USBH_handle_hc_n_Out_ISR
+* Handles interrupt for a specific Host Channel
+* @param pdev: Selected device
+* @param hc_num: Channel number
+* @retval status
+*/
+uint32_t USB_OTG_USBH_handle_hc_n_Out_ISR (USB_OTG_CORE_HANDLE *pdev , uint32_t num)
+{
+
+ USB_OTG_HCINTn_TypeDef hcint;
+ USB_OTG_HCINTMSK_TypeDef hcintmsk;
+ USB_OTG_HC_REGS *hcreg;
+ USB_OTG_HCCHAR_TypeDef hcchar;
+
+ hcreg = pdev->regs.HC_REGS[num];
+ hcint.d32 = USB_OTG_READ_REG32(&hcreg->HCINT);
+ hcintmsk.d32 = USB_OTG_READ_REG32(&hcreg->HCINTMSK);
+ hcint.d32 = hcint.d32 & hcintmsk.d32;
+
+ hcchar.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[num]->HCCHAR);
+
+ if (hcint.b.ahberr)
+ {
+ CLEAR_HC_INT(hcreg ,ahberr);
+ UNMASK_HOST_INT_CHH (num);
+ }
+ else if (hcint.b.ack)
+ {
+ CLEAR_HC_INT(hcreg , ack);
+ }
+ else if (hcint.b.frmovrun)
+ {
+ UNMASK_HOST_INT_CHH (num);
+ USB_OTG_HC_Halt(pdev, num);
+ CLEAR_HC_INT(hcreg ,frmovrun);
+ }
+ else if (hcint.b.xfercompl)
+ {
+ pdev->host.ErrCnt[num] = 0;
+ UNMASK_HOST_INT_CHH (num);
+ USB_OTG_HC_Halt(pdev, num);
+ CLEAR_HC_INT(hcreg , xfercompl);
+ pdev->host.HC_Status[num] = HC_XFRC;
+ }
+
+ else if (hcint.b.stall)
+ {
+ CLEAR_HC_INT(hcreg , stall);
+ UNMASK_HOST_INT_CHH (num);
+ USB_OTG_HC_Halt(pdev, num);
+ pdev->host.HC_Status[num] = HC_STALL;
+ }
+
+ else if (hcint.b.nak)
+ {
+ pdev->host.ErrCnt[num] = 0;
+ UNMASK_HOST_INT_CHH (num);
+ USB_OTG_HC_Halt(pdev, num);
+ CLEAR_HC_INT(hcreg , nak);
+ pdev->host.HC_Status[num] = HC_NAK;
+ }
+
+ else if (hcint.b.xacterr)
+ {
+ UNMASK_HOST_INT_CHH (num);
+ USB_OTG_HC_Halt(pdev, num);
+ pdev->host.ErrCnt[num] ++;
+ pdev->host.HC_Status[num] = HC_XACTERR;
+ CLEAR_HC_INT(hcreg , xacterr);
+ }
+ else if (hcint.b.nyet)
+ {
+ pdev->host.ErrCnt[num] = 0;
+ UNMASK_HOST_INT_CHH (num);
+ USB_OTG_HC_Halt(pdev, num);
+ CLEAR_HC_INT(hcreg , nyet);
+ pdev->host.HC_Status[num] = HC_NYET;
+ }
+ else if (hcint.b.datatglerr)
+ {
+
+ UNMASK_HOST_INT_CHH (num);
+ USB_OTG_HC_Halt(pdev, num);
+ CLEAR_HC_INT(hcreg , nak);
+ pdev->host.HC_Status[num] = HC_DATATGLERR;
+
+ CLEAR_HC_INT(hcreg , datatglerr);
+ }
+ else if (hcint.b.chhltd)
+ {
+ MASK_HOST_INT_CHH (num);
+
+ if(pdev->host.HC_Status[num] == HC_XFRC)
+ {
+ pdev->host.URB_State[num] = URB_DONE;
+
+ if (hcchar.b.eptype == EP_TYPE_BULK)
+ {
+ pdev->host.hc[num].toggle_out ^= 1;
+ }
+ }
+ else if(pdev->host.HC_Status[num] == HC_NAK)
+ {
+ pdev->host.URB_State[num] = URB_NOTREADY;
+ }
+ else if(pdev->host.HC_Status[num] == HC_NYET)
+ {
+ if(pdev->host.hc[num].do_ping == 1)
+ {
+ USB_OTG_HC_DoPing(pdev, num);
+ }
+ pdev->host.URB_State[num] = URB_NOTREADY;
+ }
+ else if(pdev->host.HC_Status[num] == HC_STALL)
+ {
+ pdev->host.URB_State[num] = URB_STALL;
+ }
+ else if(pdev->host.HC_Status[num] == HC_XACTERR)
+ {
+ if (pdev->host.ErrCnt[num] == 3)
+ {
+ pdev->host.URB_State[num] = URB_ERROR;
+ pdev->host.ErrCnt[num] = 0;
+ }
+ }
+ CLEAR_HC_INT(hcreg , chhltd);
+ }
+
+
+ return 1;
+}
+#if defined ( __ICCARM__ ) /*!< IAR Compiler */
+#pragma optimize = none
+#endif /* __CC_ARM */
+/**
+* @brief USB_OTG_USBH_handle_hc_n_In_ISR
+* Handles interrupt for a specific Host Channel
+* @param pdev: Selected device
+* @param hc_num: Channel number
+* @retval status
+*/
+uint32_t USB_OTG_USBH_handle_hc_n_In_ISR (USB_OTG_CORE_HANDLE *pdev , uint32_t num)
+{
+ USB_OTG_HCINTn_TypeDef hcint;
+ USB_OTG_HCINTMSK_TypeDef hcintmsk;
+ USB_OTG_HCCHAR_TypeDef hcchar;
+ USB_OTG_HCTSIZn_TypeDef hctsiz;
+ USB_OTG_HC_REGS *hcreg;
+
+
+ hcreg = pdev->regs.HC_REGS[num];
+ hcint.d32 = USB_OTG_READ_REG32(&hcreg->HCINT);
+ hcintmsk.d32 = USB_OTG_READ_REG32(&hcreg->HCINTMSK);
+ hcint.d32 = hcint.d32 & hcintmsk.d32;
+ hcchar.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[num]->HCCHAR);
+ hcintmsk.d32 = 0;
+
+
+ if (hcint.b.ahberr)
+ {
+ CLEAR_HC_INT(hcreg ,ahberr);
+ UNMASK_HOST_INT_CHH (num);
+ }
+ else if (hcint.b.ack)
+ {
+ CLEAR_HC_INT(hcreg ,ack);
+ }
+
+ else if (hcint.b.stall)
+ {
+ UNMASK_HOST_INT_CHH (num);
+ pdev->host.HC_Status[num] = HC_STALL;
+ CLEAR_HC_INT(hcreg , nak); /* Clear the NAK Condition */
+ CLEAR_HC_INT(hcreg , stall); /* Clear the STALL Condition */
+ hcint.b.nak = 0; /* NOTE: When there is a 'stall', reset also nak,
+ else, the pdev->host.HC_Status = HC_STALL
+ will be overwritten by 'nak' in code below */
+ USB_OTG_HC_Halt(pdev, num);
+ }
+ else if (hcint.b.datatglerr)
+ {
+
+ UNMASK_HOST_INT_CHH (num);
+ USB_OTG_HC_Halt(pdev, num);
+ CLEAR_HC_INT(hcreg , nak);
+ pdev->host.HC_Status[num] = HC_DATATGLERR;
+ CLEAR_HC_INT(hcreg , datatglerr);
+ }
+
+ if (hcint.b.frmovrun)
+ {
+ UNMASK_HOST_INT_CHH (num);
+ USB_OTG_HC_Halt(pdev, num);
+ CLEAR_HC_INT(hcreg ,frmovrun);
+ }
+
+ else if (hcint.b.xfercompl)
+ {
+
+ if (pdev->cfg.dma_enable == 1)
+ {
+ hctsiz.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[num]->HCTSIZ);
+ pdev->host.XferCnt[num] = pdev->host.hc[num].xfer_len - hctsiz.b.xfersize;
+ }
+
+ pdev->host.HC_Status[num] = HC_XFRC;
+ pdev->host.ErrCnt [num]= 0;
+ CLEAR_HC_INT(hcreg , xfercompl);
+
+ if ((hcchar.b.eptype == EP_TYPE_CTRL)||
+ (hcchar.b.eptype == EP_TYPE_BULK))
+ {
+ UNMASK_HOST_INT_CHH (num);
+ USB_OTG_HC_Halt(pdev, num);
+ CLEAR_HC_INT(hcreg , nak);
+ pdev->host.hc[num].toggle_in ^= 1;
+
+ }
+ else if(hcchar.b.eptype == EP_TYPE_INTR)
+ {
+ hcchar.b.oddfrm = 1;
+ USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[num]->HCCHAR, hcchar.d32);
+ pdev->host.URB_State[num] = URB_DONE;
+ }
+
+ }
+ else if (hcint.b.chhltd)
+ {
+ MASK_HOST_INT_CHH (num);
+
+ if(pdev->host.HC_Status[num] == HC_XFRC)
+ {
+ pdev->host.URB_State[num] = URB_DONE;
+ }
+
+ else if (pdev->host.HC_Status[num] == HC_STALL)
+ {
+ pdev->host.URB_State[num] = URB_STALL;
+ }
+
+ else if((pdev->host.HC_Status[num] == HC_XACTERR) ||
+ (pdev->host.HC_Status[num] == HC_DATATGLERR))
+ {
+ pdev->host.ErrCnt[num] = 0;
+ pdev->host.URB_State[num] = URB_ERROR;
+
+ }
+ else if(hcchar.b.eptype == EP_TYPE_INTR)
+ {
+ pdev->host.hc[num].toggle_in ^= 1;
+ }
+
+ CLEAR_HC_INT(hcreg , chhltd);
+
+ }
+ else if (hcint.b.xacterr)
+ {
+ UNMASK_HOST_INT_CHH (num);
+ pdev->host.ErrCnt[num] ++;
+ pdev->host.HC_Status[num] = HC_XACTERR;
+ USB_OTG_HC_Halt(pdev, num);
+ CLEAR_HC_INT(hcreg , xacterr);
+
+ }
+ else if (hcint.b.nak)
+ {
+ if(hcchar.b.eptype == EP_TYPE_INTR)
+ {
+ UNMASK_HOST_INT_CHH (num);
+ USB_OTG_HC_Halt(pdev, num);
+ }
+ else if ((hcchar.b.eptype == EP_TYPE_CTRL)||
+ (hcchar.b.eptype == EP_TYPE_BULK))
+ {
+ /* re-activate the channel */
+ hcchar.b.chen = 1;
+ hcchar.b.chdis = 0;
+ USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[num]->HCCHAR, hcchar.d32);
+ }
+ pdev->host.HC_Status[num] = HC_NAK;
+ CLEAR_HC_INT(hcreg , nak);
+ }
+
+
+ return 1;
+
+}
+
+/**
+* @brief USB_OTG_USBH_handle_rx_qlvl_ISR
+* Handles the Rx Status Queue Level Interrupt
+* @param pdev: Selected device
+* @retval status
+*/
+#if defined ( __ICCARM__ ) /*!< IAR Compiler */
+#pragma optimize = none
+#endif /* __CC_ARM */
+static uint32_t USB_OTG_USBH_handle_rx_qlvl_ISR (USB_OTG_CORE_HANDLE *pdev)
+{
+ USB_OTG_GRXFSTS_TypeDef grxsts;
+ USB_OTG_GINTMSK_TypeDef intmsk;
+ USB_OTG_HCTSIZn_TypeDef hctsiz;
+ USB_OTG_HCCHAR_TypeDef hcchar;
+ __IO uint8_t channelnum =0;
+ uint32_t count;
+
+ /* Disable the Rx Status Queue Level interrupt */
+ intmsk.d32 = 0;
+ intmsk.b.rxstsqlvl = 1;
+ USB_OTG_MODIFY_REG32( &pdev->regs.GREGS->GINTMSK, intmsk.d32, 0);
+
+ grxsts.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GRXSTSP);
+ channelnum = grxsts.b.chnum;
+ hcchar.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[channelnum]->HCCHAR);
+
+ switch (grxsts.b.pktsts)
+ {
+ case GRXSTS_PKTSTS_IN:
+ /* Read the data into the host buffer. */
+ if ((grxsts.b.bcnt > 0) && (pdev->host.hc[channelnum].xfer_buff != (void *)0))
+ {
+
+ USB_OTG_ReadPacket(pdev, pdev->host.hc[channelnum].xfer_buff, grxsts.b.bcnt);
+ /*manage multiple Xfer */
+ pdev->host.hc[grxsts.b.chnum].xfer_buff += grxsts.b.bcnt;
+ pdev->host.hc[grxsts.b.chnum].xfer_count += grxsts.b.bcnt;
+
+
+ count = pdev->host.hc[channelnum].xfer_count;
+ pdev->host.XferCnt[channelnum] = count;
+
+ hctsiz.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[channelnum]->HCTSIZ);
+ if(hctsiz.b.pktcnt > 0)
+ {
+ /* re-activate the channel when more packets are expected */
+ hcchar.b.chen = 1;
+ hcchar.b.chdis = 0;
+ USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[channelnum]->HCCHAR, hcchar.d32);
+ }
+ }
+ break;
+
+ case GRXSTS_PKTSTS_IN_XFER_COMP:
+
+ case GRXSTS_PKTSTS_DATA_TOGGLE_ERR:
+ case GRXSTS_PKTSTS_CH_HALTED:
+ default:
+ break;
+ }
+
+ /* Enable the Rx Status Queue Level interrupt */
+ intmsk.b.rxstsqlvl = 1;
+ USB_OTG_MODIFY_REG32(&pdev->regs.GREGS->GINTMSK, 0, intmsk.d32);
+ return 1;
+}
+
+/**
+* @brief USB_OTG_USBH_handle_IncompletePeriodicXfer_ISR
+* Handles the incomplete Periodic transfer Interrupt
+* @param pdev: Selected device
+* @retval status
+*/
+#if defined ( __ICCARM__ ) /*!< IAR Compiler */
+#pragma optimize = none
+#endif /* __CC_ARM */
+static uint32_t USB_OTG_USBH_handle_IncompletePeriodicXfer_ISR (USB_OTG_CORE_HANDLE *pdev)
+{
+
+ USB_OTG_GINTSTS_TypeDef gintsts;
+ USB_OTG_HCCHAR_TypeDef hcchar;
+
+
+
+
+ hcchar.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[0]->HCCHAR);
+ hcchar.b.chen = 1;
+ hcchar.b.chdis = 1;
+ USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[0]->HCCHAR, hcchar.d32);
+
+ gintsts.d32 = 0;
+ /* Clear interrupt */
+ gintsts.b.incomplisoout = 1;
+ USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GINTSTS, gintsts.d32);
+
+ return 1;
+}
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
diff --git a/SPARK_Platform/MCU/STM32F2xx/STM32_USB_OTG_Driver/src/usb_otg.c b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_OTG_Driver/src/usb_otg.c
new file mode 100644
index 0000000..3bd1e6d
--- /dev/null
+++ b/SPARK_Platform/MCU/STM32F2xx/STM32_USB_OTG_Driver/src/usb_otg.c
@@ -0,0 +1,418 @@
+/**
+ ******************************************************************************
+ * @file usb_otg.c
+ * @author MCD Application Team
+ * @version V2.1.0
+ * @date 19-March-2012
+ * @brief 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_defines.h"
+#include "usb_regs.h"
+#include "usb_core.h"
+#include "usb_otg.h"
+
+/** @addtogroup USB_OTG_DRIVER
+ * @{
+ */
+
+/** @defgroup USB_OTG
+ * @brief This file is the interface between EFSL ans Host mass-storage class
+ * @{
+ */
+
+
+/** @defgroup USB_OTG_Private_Defines
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup USB_OTG_Private_TypesDefinitions
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+
+/** @defgroup USB_OTG_Private_Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup USB_OTG_Private_Variables
+ * @{
+ */
+/**
+ * @}
+ */
+
+
+/** @defgroup USB_OTG_Private_FunctionPrototypes
+ * @{
+ */
+
+uint32_t USB_OTG_HandleOTG_ISR(USB_OTG_CORE_HANDLE *pdev);
+
+static uint32_t USB_OTG_HandleConnectorIDStatusChange_ISR(USB_OTG_CORE_HANDLE *pdev);
+static uint32_t USB_OTG_HandleSessionRequest_ISR(USB_OTG_CORE_HANDLE *pdev);
+static uint32_t USB_OTG_Read_itr(USB_OTG_CORE_HANDLE *pdev);
+
+/**
+ * @}
+ */
+
+
+/** @defgroup USB_OTG_Private_Functions
+ * @{
+ */
+
+
+/* OTG Interrupt Handler */
+
+
+/**
+ * @brief STM32_USBO_OTG_ISR_Handler
+ *
+ * @param None
+ * @retval : None
+ */
+uint32_t STM32_USBO_OTG_ISR_Handler(USB_OTG_CORE_HANDLE *pdev)
+{
+ uint32_t retval = 0;
+ USB_OTG_GINTSTS_TypeDef gintsts ;
+ gintsts.d32 = 0;
+
+ gintsts.d32 = USB_OTG_Read_itr(pdev);
+ if (gintsts.d32 == 0)
+ {
+ return 0;
+ }
+ if (gintsts.b.otgintr)
+ {
+ retval |= USB_OTG_HandleOTG_ISR(pdev);
+ }
+ if (gintsts.b.conidstschng)
+ {
+ retval |= USB_OTG_HandleConnectorIDStatusChange_ISR(pdev);
+ }
+ if (gintsts.b.sessreqintr)
+ {
+ retval |= USB_OTG_HandleSessionRequest_ISR(pdev);
+ }
+ return retval;
+}
+
+
+/**
+ * @brief USB_OTG_Read_itr
+ * returns the Core Interrupt register
+ * @param None
+ * @retval : status
+ */
+static uint32_t USB_OTG_Read_itr(USB_OTG_CORE_HANDLE *pdev)
+{
+ USB_OTG_GINTSTS_TypeDef gintsts;
+ USB_OTG_GINTMSK_TypeDef gintmsk;
+ USB_OTG_GINTMSK_TypeDef gintmsk_common;
+
+
+ gintsts.d32 = 0;
+ gintmsk.d32 = 0;
+ gintmsk_common.d32 = 0;
+
+ /* OTG interrupts */
+ gintmsk_common.b.sessreqintr = 1;
+ gintmsk_common.b.conidstschng = 1;
+ gintmsk_common.b.otgintr = 1;
+
+ gintsts.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GINTSTS);
+ gintmsk.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GINTMSK);
+ return ((gintsts.d32 & gintmsk.d32 ) & gintmsk_common.d32);
+}
+
+
+/**
+ * @brief USB_OTG_HandleOTG_ISR
+ * handles the OTG Interrupts
+ * @param None
+ * @retval : status
+ */
+static uint32_t USB_OTG_HandleOTG_ISR(USB_OTG_CORE_HANDLE *pdev)
+{
+ USB_OTG_GOTGINT_TypeDef gotgint;
+ USB_OTG_GOTGCTL_TypeDef gotgctl;
+
+
+ gotgint.d32 = 0;
+ gotgctl.d32 = 0;
+
+ gotgint.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GOTGINT);
+ gotgctl.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GOTGCTL);
+
+ if (gotgint.b.sesenddet)
+ {
+ gotgctl.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GOTGCTL);
+
+
+ if (USB_OTG_IsDeviceMode(pdev))
+ {
+
+ }
+ else if (USB_OTG_IsHostMode(pdev))
+ {
+
+ }
+ }
+
+ /* ----> SRP SUCCESS or FAILURE INTERRUPT <---- */
+ if (gotgint.b.sesreqsucstschng)
+ {
+ gotgctl.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GOTGCTL);
+ if (gotgctl.b.sesreqscs) /* Session request success */
+ {
+ if (USB_OTG_IsDeviceMode(pdev))
+ {
+
+ }
+ /* Clear Session Request */
+ gotgctl.d32 = 0;
+ gotgctl.b.sesreq = 1;
+ USB_OTG_MODIFY_REG32(&pdev->regs.GREGS->GOTGCTL, gotgctl.d32, 0);
+ }
+ else /* Session request failure */
+ {
+ if (USB_OTG_IsDeviceMode(pdev))
+ {
+
+ }
+ }
+ }
+ /* ----> HNP SUCCESS or FAILURE INTERRUPT <---- */
+ if (gotgint.b.hstnegsucstschng)
+ {
+ gotgctl.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GOTGCTL);
+
+ if (gotgctl.b.hstnegscs) /* Host negotiation success */
+ {
+ if (USB_OTG_IsHostMode(pdev)) /* The core AUTOMATICALLY sets the Host mode */
+ {
+
+ }
+ }
+ else /* Host negotiation failure */
+ {
+
+ }
+ gotgint.b.hstnegsucstschng = 1; /* Ack "Host Negotiation Success Status Change" interrupt. */
+ }
+ /* ----> HOST NEGOTIATION DETECTED INTERRUPT <---- */
+ if (gotgint.b.hstnegdet)
+ {
+ if (USB_OTG_IsDeviceMode(pdev)) /* The core AUTOMATICALLY sets the Host mode */
+ {
+
+ }
+ else
+ {
+
+ }
+ }
+ if (gotgint.b.adevtoutchng)
+ {}
+ if (gotgint.b.debdone)
+ {
+ USB_OTG_ResetPort(pdev);
+ }
+ /* Clear OTG INT */
+ USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GOTGINT, gotgint.d32);
+ return 1;
+}
+
+
+/**
+ * @brief USB_OTG_HandleConnectorIDStatusChange_ISR
+ * handles the Connector ID Status Change Interrupt
+ * @param None
+ * @retval : status
+ */
+static uint32_t USB_OTG_HandleConnectorIDStatusChange_ISR(USB_OTG_CORE_HANDLE *pdev)
+{
+ USB_OTG_GINTMSK_TypeDef gintmsk;
+ USB_OTG_GOTGCTL_TypeDef gotgctl;
+ USB_OTG_GINTSTS_TypeDef gintsts;
+
+ gintsts.d32 = 0 ;
+ gintmsk.d32 = 0 ;
+ gotgctl.d32 = 0 ;
+ gintmsk.b.sofintr = 1;
+
+ USB_OTG_MODIFY_REG32(&pdev->regs.GREGS->GINTMSK, gintmsk.d32, 0);
+ gotgctl.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GOTGCTL);
+
+ /* B-Device connector (Device Mode) */
+ if (gotgctl.b.conidsts)
+ {
+ USB_OTG_DisableGlobalInt(pdev);
+ USB_OTG_CoreInitDev(pdev);
+ USB_OTG_EnableGlobalInt(pdev);
+ pdev->otg.OTG_State = B_PERIPHERAL;
+ }
+ else
+ {
+ USB_OTG_DisableGlobalInt(pdev);
+ USB_OTG_CoreInitHost(pdev);
+ USB_OTG_EnableGlobalInt(pdev);
+ pdev->otg.OTG_State = A_HOST;
+ }
+ /* Set flag and clear interrupt */
+ gintsts.b.conidstschng = 1;
+ USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GINTSTS, gintsts.d32);
+ return 1;
+}
+
+
+/**
+ * @brief USB_OTG_HandleSessionRequest_ISR
+ * Initiating the Session Request Protocol
+ * @param None
+ * @retval : status
+ */
+static uint32_t USB_OTG_HandleSessionRequest_ISR(USB_OTG_CORE_HANDLE *pdev)
+{
+ USB_OTG_GINTSTS_TypeDef gintsts;
+ USB_OTG_GOTGCTL_TypeDef gotgctl;
+
+
+ gotgctl.d32 = 0;
+ gintsts.d32 = 0;
+
+ gotgctl.d32 = USB_OTG_READ_REG32( &pdev->regs.GREGS->GOTGCTL );
+ if (USB_OTG_IsDeviceMode(pdev) && (gotgctl.b.bsesvld))
+ {
+
+ }
+ else if (gotgctl.b.asesvld)
+ {
+ }
+ /* Clear interrupt */
+ gintsts.d32 = 0;
+ gintsts.b.sessreqintr = 1;
+ USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GINTSTS, gintsts.d32);
+ return 1;
+}
+
+
+/**
+ * @brief USB_OTG_InitiateSRP
+ * Initiate an srp session
+ * @param None
+ * @retval : None
+ */
+void USB_OTG_InitiateSRP(USB_OTG_CORE_HANDLE *pdev)
+{
+ USB_OTG_GOTGCTL_TypeDef otgctl;
+
+ otgctl.d32 = 0;
+
+ otgctl.d32 = USB_OTG_READ_REG32( &pdev->regs.GREGS->GOTGCTL );
+ if (otgctl.b.sesreq)
+ {
+ return; /* SRP in progress */
+ }
+ otgctl.b.sesreq = 1;
+ USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GOTGCTL, otgctl.d32);
+}
+
+
+/**
+ * @brief USB_OTG_InitiateHNP
+ * Initiate HNP
+ * @param None
+ * @retval : None
+ */
+void USB_OTG_InitiateHNP(USB_OTG_CORE_HANDLE *pdev , uint8_t state, uint8_t mode)
+{
+ USB_OTG_GOTGCTL_TypeDef otgctl;
+ USB_OTG_HPRT0_TypeDef hprt0;
+
+ otgctl.d32 = 0;
+ hprt0.d32 = 0;
+
+ otgctl.d32 = USB_OTG_READ_REG32( &pdev->regs.GREGS->GOTGCTL );
+ if (mode)
+ { /* Device mode */
+ if (state)
+ {
+
+ otgctl.b.devhnpen = 1; /* B-Dev has been enabled to perform HNP */
+ otgctl.b.hnpreq = 1; /* Initiate an HNP req. to the connected USB host*/
+ USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GOTGCTL, otgctl.d32);
+ }
+ }
+ else
+ { /* Host mode */
+ if (state)
+ {
+ otgctl.b.hstsethnpen = 1; /* A-Dev has enabled B-device for HNP */
+ USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GOTGCTL, otgctl.d32);
+ /* Suspend the bus so that B-dev will disconnect indicating the initial condition for HNP to DWC_Core */
+ hprt0.d32 = USB_OTG_ReadHPRT0(pdev);
+ hprt0.b.prtsusp = 1; /* The core clear this bit when disconnect interrupt generated (GINTSTS.DisconnInt = '1') */
+ USB_OTG_WRITE_REG32(pdev->regs.HPRT0, hprt0.d32);
+ }
+ }
+}
+
+
+/**
+ * @brief USB_OTG_GetCurrentState
+ * Return current OTG State
+ * @param None
+ * @retval : None
+ */
+uint32_t USB_OTG_GetCurrentState (USB_OTG_CORE_HANDLE *pdev)
+{
+ return pdev->otg.OTG_State;
+}
+
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/CC3000_Host_Driver/build.mk b/SPARK_Platform/WLAN/CC3000/CC3000_Host_Driver/build.mk
similarity index 92%
rename from CC3000_Host_Driver/build.mk
rename to SPARK_Platform/WLAN/CC3000/CC3000_Host_Driver/build.mk
index 7b6e985..0a2550a 100644
--- a/CC3000_Host_Driver/build.mk
+++ b/SPARK_Platform/WLAN/CC3000/CC3000_Host_Driver/build.mk
@@ -4,7 +4,7 @@
# Define the prefix to this directory.
# Note: The name must be unique within this build and should be
# based on the root of the project
-TARGET_CC3000_PATH = CC3000_Host_Driver
+TARGET_CC3000_PATH = SPARK_Platform/WLAN/CC3000/CC3000_Host_Driver
# Add tropicssl include to all objects built for this target
INCLUDE_DIRS += $(TARGET_CC3000_PATH)
diff --git a/CC3000_Host_Driver/cc3000_common.c b/SPARK_Platform/WLAN/CC3000/CC3000_Host_Driver/cc3000_common.c
similarity index 100%
rename from CC3000_Host_Driver/cc3000_common.c
rename to SPARK_Platform/WLAN/CC3000/CC3000_Host_Driver/cc3000_common.c
diff --git a/CC3000_Host_Driver/cc3000_common.h b/SPARK_Platform/WLAN/CC3000/CC3000_Host_Driver/cc3000_common.h
similarity index 100%
rename from CC3000_Host_Driver/cc3000_common.h
rename to SPARK_Platform/WLAN/CC3000/CC3000_Host_Driver/cc3000_common.h
diff --git a/CC3000_Host_Driver/data_types.h b/SPARK_Platform/WLAN/CC3000/CC3000_Host_Driver/data_types.h
similarity index 100%
rename from CC3000_Host_Driver/data_types.h
rename to SPARK_Platform/WLAN/CC3000/CC3000_Host_Driver/data_types.h
diff --git a/CC3000_Host_Driver/evnt_handler.c b/SPARK_Platform/WLAN/CC3000/CC3000_Host_Driver/evnt_handler.c
similarity index 100%
rename from CC3000_Host_Driver/evnt_handler.c
rename to SPARK_Platform/WLAN/CC3000/CC3000_Host_Driver/evnt_handler.c
diff --git a/CC3000_Host_Driver/evnt_handler.h b/SPARK_Platform/WLAN/CC3000/CC3000_Host_Driver/evnt_handler.h
similarity index 100%
rename from CC3000_Host_Driver/evnt_handler.h
rename to SPARK_Platform/WLAN/CC3000/CC3000_Host_Driver/evnt_handler.h
diff --git a/CC3000_Host_Driver/hci.c b/SPARK_Platform/WLAN/CC3000/CC3000_Host_Driver/hci.c
similarity index 100%
rename from CC3000_Host_Driver/hci.c
rename to SPARK_Platform/WLAN/CC3000/CC3000_Host_Driver/hci.c
diff --git a/CC3000_Host_Driver/hci.h b/SPARK_Platform/WLAN/CC3000/CC3000_Host_Driver/hci.h
similarity index 100%
rename from CC3000_Host_Driver/hci.h
rename to SPARK_Platform/WLAN/CC3000/CC3000_Host_Driver/hci.h
diff --git a/CC3000_Host_Driver/host_driver_version.h b/SPARK_Platform/WLAN/CC3000/CC3000_Host_Driver/host_driver_version.h
similarity index 100%
rename from CC3000_Host_Driver/host_driver_version.h
rename to SPARK_Platform/WLAN/CC3000/CC3000_Host_Driver/host_driver_version.h
diff --git a/CC3000_Host_Driver/netapp.c b/SPARK_Platform/WLAN/CC3000/CC3000_Host_Driver/netapp.c
similarity index 100%
rename from CC3000_Host_Driver/netapp.c
rename to SPARK_Platform/WLAN/CC3000/CC3000_Host_Driver/netapp.c
diff --git a/CC3000_Host_Driver/netapp.h b/SPARK_Platform/WLAN/CC3000/CC3000_Host_Driver/netapp.h
similarity index 100%
rename from CC3000_Host_Driver/netapp.h
rename to SPARK_Platform/WLAN/CC3000/CC3000_Host_Driver/netapp.h
diff --git a/CC3000_Host_Driver/nvmem.c b/SPARK_Platform/WLAN/CC3000/CC3000_Host_Driver/nvmem.c
similarity index 100%
rename from CC3000_Host_Driver/nvmem.c
rename to SPARK_Platform/WLAN/CC3000/CC3000_Host_Driver/nvmem.c
diff --git a/CC3000_Host_Driver/nvmem.h b/SPARK_Platform/WLAN/CC3000/CC3000_Host_Driver/nvmem.h
similarity index 100%
rename from CC3000_Host_Driver/nvmem.h
rename to SPARK_Platform/WLAN/CC3000/CC3000_Host_Driver/nvmem.h
diff --git a/CC3000_Host_Driver/security.c b/SPARK_Platform/WLAN/CC3000/CC3000_Host_Driver/security.c
similarity index 100%
rename from CC3000_Host_Driver/security.c
rename to SPARK_Platform/WLAN/CC3000/CC3000_Host_Driver/security.c
diff --git a/CC3000_Host_Driver/security.h b/SPARK_Platform/WLAN/CC3000/CC3000_Host_Driver/security.h
similarity index 100%
rename from CC3000_Host_Driver/security.h
rename to SPARK_Platform/WLAN/CC3000/CC3000_Host_Driver/security.h
diff --git a/CC3000_Host_Driver/socket.c b/SPARK_Platform/WLAN/CC3000/CC3000_Host_Driver/socket.c
similarity index 100%
rename from CC3000_Host_Driver/socket.c
rename to SPARK_Platform/WLAN/CC3000/CC3000_Host_Driver/socket.c
diff --git a/CC3000_Host_Driver/socket.h b/SPARK_Platform/WLAN/CC3000/CC3000_Host_Driver/socket.h
similarity index 100%
rename from CC3000_Host_Driver/socket.h
rename to SPARK_Platform/WLAN/CC3000/CC3000_Host_Driver/socket.h
diff --git a/CC3000_Host_Driver/wlan.c b/SPARK_Platform/WLAN/CC3000/CC3000_Host_Driver/wlan.c
similarity index 100%
rename from CC3000_Host_Driver/wlan.c
rename to SPARK_Platform/WLAN/CC3000/CC3000_Host_Driver/wlan.c
diff --git a/CC3000_Host_Driver/wlan.h b/SPARK_Platform/WLAN/CC3000/CC3000_Host_Driver/wlan.h
similarity index 100%
rename from CC3000_Host_Driver/wlan.h
rename to SPARK_Platform/WLAN/CC3000/CC3000_Host_Driver/wlan.h
diff --git a/SPARK_Services/inc/usb_hal.h b/SPARK_Services/inc/usb_hal.h
new file mode 100644
index 0000000..3f568f4
--- /dev/null
+++ b/SPARK_Services/inc/usb_hal.h
@@ -0,0 +1,77 @@
+/**
+ ******************************************************************************
+ * @file usb_hal.h
+ * @author Satish Nair
+ * @version V1.0.0
+ * @date 10-Sept-2014
+ * @brief USB HAL
+ ******************************************************************************
+ Copyright (c) 2013-14 Spark Labs, Inc. All rights reserved.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation, either
+ version 3 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see .
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USB_HAL_H
+#define __USB_HAL_H
+
+/* Includes ------------------------------------------------------------------*/
+#include "hw_config.h"
+#include "usb_conf.h"
+
+/* Exported types ------------------------------------------------------------*/
+
+/* Exported constants --------------------------------------------------------*/
+
+/* Exported macros ------------------------------------------------------------*/
+
+/* We are temporary defining this macro over here */
+/* This could also be passed via -D option in build script */
+#define SPARK_USB_SERIAL //Default is Virtual COM Port
+//#define SPARK_USB_MOUSE
+//#define SPARK_USB_KEYBOARD
+
+/* USB Config : IMR_MSK */
+/* mask defining which events has to be handled */
+/* by the device application software */
+#define IMR_MSK (CNTR_CTRM | \
+ CNTR_WKUPM | \
+ CNTR_SUSPM | \
+ CNTR_ERRM | \
+ CNTR_SOFM | \
+ CNTR_ESOFM | \
+ CNTR_RESETM \
+)
+
+#define USART_RX_DATA_SIZE 256
+
+/* Exported functions ------------------------------------------------------- */
+#if defined (USB_CDC_ENABLE) || defined (USB_HID_ENABLE)
+void SPARK_USB_Setup(void);
+void Get_SerialNum(void);
+#endif
+
+#ifdef USB_CDC_ENABLE
+void USB_USART_Init(uint32_t baudRate);
+uint8_t USB_USART_Available_Data(void);
+int32_t USB_USART_Receive_Data(void);
+void USB_USART_Send_Data(uint8_t Data);
+#endif
+
+#ifdef USB_HID_ENABLE
+void USB_HID_Send_Report(void *pHIDReport, size_t reportSize);
+#endif
+
+#endif /* __USB_HAL_H */
diff --git a/SPARK_Services/src/build.mk b/SPARK_Services/src/build.mk
index f164115..64935bc 100644
--- a/SPARK_Services/src/build.mk
+++ b/SPARK_Services/src/build.mk
@@ -10,6 +10,7 @@ TARGET_SPARK_SERVICES_SRC_PATH = $(TARGET_SPARK_SERVICES_PATH)/src
INCLUDE_DIRS += $(TARGET_SPARK_SERVICES_SRC_PATH)/inc
CSRC += $(TARGET_SPARK_SERVICES_SRC_PATH)/rgbled.c
+CSRC += $(TARGET_SPARK_SERVICES_SRC_PATH)/usb_hal.c
# C++ source files included in this build.
CPPSRC +=
diff --git a/SPARK_Services/src/usb_hal.c b/SPARK_Services/src/usb_hal.c
new file mode 100644
index 0000000..9854b0d
--- /dev/null
+++ b/SPARK_Services/src/usb_hal.c
@@ -0,0 +1,246 @@
+/**
+ ******************************************************************************
+ * @file usb_hal.c
+ * @author Satish Nair
+ * @version V1.0.0
+ * @date 10-Sept-2014
+ * @brief USB HAL
+ ******************************************************************************
+ Copyright (c) 2013-14 Spark Labs, Inc. All rights reserved.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this program; if not, see .
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "usb_hal.h"
+#include "usb_conf.h"
+#include "usb_lib.h"
+#include "usb_desc.h"
+#include "usb_pwr.h"
+#include "usb_prop.h"
+
+/* Private typedef -----------------------------------------------------------*/
+
+/* Private define ------------------------------------------------------------*/
+
+/* Private macro -------------------------------------------------------------*/
+
+/* Private variables ---------------------------------------------------------*/
+#ifdef USB_CDC_ENABLE
+uint8_t USART_Rx_Buffer[USART_RX_DATA_SIZE];
+uint32_t USART_Rx_ptr_in = 0;
+uint32_t USART_Rx_ptr_out = 0;
+uint32_t USART_Rx_length = 0;
+
+uint8_t USB_Rx_Buffer[CDC_DATA_SIZE];
+uint16_t USB_Rx_length = 0;
+uint16_t USB_Rx_ptr = 0;
+
+uint8_t USB_Tx_State = 0;
+uint8_t USB_Rx_State = 0;
+
+uint32_t USB_USART_BaudRate = 9600;
+
+__IO uint8_t PrevXferComplete;
+#endif
+
+/* Extern variables ----------------------------------------------------------*/
+extern LINE_CODING linecoding;
+
+/* Private function prototypes -----------------------------------------------*/
+static void IntToUnicode (uint32_t value , uint8_t *pbuf , uint8_t len);
+
+#if defined (USB_CDC_ENABLE) || defined (USB_HID_ENABLE)
+/*******************************************************************************
+ * Function Name : SPARK_USB_Setup
+ * Description : Spark USB Setup.
+ * Input : None.
+ * Return : None.
+ *******************************************************************************/
+void SPARK_USB_Setup(void)
+{
+ USB_Disconnect_Config();
+ USB_Cable_Config(DISABLE);
+ Delay_Microsecond(100000);
+ Set_USBClock();
+ USB_Interrupts_Config();
+ USB_Init();
+}
+
+/*******************************************************************************
+ * Function Name : Get_SerialNum.
+ * Description : Create the serial number string descriptor.
+ * Input : None.
+ * Output : None.
+ * Return : None.
+ *******************************************************************************/
+void Get_SerialNum(void)
+{
+ uint32_t Device_Serial0, Device_Serial1, Device_Serial2;
+
+ Device_Serial0 = *(uint32_t*)ID1;
+ Device_Serial1 = *(uint32_t*)ID2;
+ Device_Serial2 = *(uint32_t*)ID3;
+
+ Device_Serial0 += Device_Serial2;
+
+ if (Device_Serial0 != 0)
+ {
+ IntToUnicode (Device_Serial0, &USB_StringSerial[2] , 8);
+ IntToUnicode (Device_Serial1, &USB_StringSerial[18], 4);
+ }
+}
+#endif
+
+#ifdef USB_CDC_ENABLE
+/*******************************************************************************
+ * Function Name : USB_USART_Init
+ * Description : Start USB-USART protocol.
+ * Input : baudRate.
+ * Return : None.
+ *******************************************************************************/
+void USB_USART_Init(uint32_t baudRate)
+{
+ linecoding.bitrate = baudRate;
+ SPARK_USB_Setup();
+}
+
+/*******************************************************************************
+ * Function Name : USB_USART_Available_Data.
+ * Description : Return the length of available data received from USB.
+ * Input : None.
+ * Return : Length.
+ *******************************************************************************/
+uint8_t USB_USART_Available_Data(void)
+{
+ if(bDeviceState == CONFIGURED)
+ {
+ if(USB_Rx_State == 1)
+ {
+ return (USB_Rx_length - USB_Rx_ptr);
+ }
+ }
+
+ return 0;
+}
+
+/*******************************************************************************
+ * Function Name : USB_USART_Receive_Data.
+ * Description : Return data sent by USB Host.
+ * Input : None
+ * Return : Data.
+ *******************************************************************************/
+int32_t USB_USART_Receive_Data(void)
+{
+ if(bDeviceState == CONFIGURED)
+ {
+ if(USB_Rx_State == 1)
+ {
+ if((USB_Rx_length - USB_Rx_ptr) == 1)
+ {
+ USB_Rx_State = 0;
+
+ /* Enable the receive of data on EP3 */
+ SetEPRxValid(ENDP3);
+ }
+
+ return USB_Rx_Buffer[USB_Rx_ptr++];
+ }
+ }
+
+ return -1;
+}
+
+/*******************************************************************************
+ * Function Name : USB_USART_Send_Data.
+ * Description : Send Data from USB_USART to USB Host.
+ * Input : Data.
+ * Return : None.
+ *******************************************************************************/
+void USB_USART_Send_Data(uint8_t Data)
+{
+ if(bDeviceState == CONFIGURED)
+ {
+ USART_Rx_Buffer[USART_Rx_ptr_in] = Data;
+
+ USART_Rx_ptr_in++;
+
+ /* To avoid buffer overflow */
+ if(USART_Rx_ptr_in == USART_RX_DATA_SIZE)
+ {
+ USART_Rx_ptr_in = 0;
+ }
+
+ if(CC3000_Read_Interrupt_Pin())
+ {
+ //Delay 100us to avoid losing the data
+ Delay_Microsecond(100);
+ }
+ }
+}
+#endif
+
+#ifdef USB_HID_ENABLE
+/*******************************************************************************
+ * Function Name : USB_HID_Send_Report.
+ * Description : Send HID Report Info to Host.
+ * Input : pHIDReport and reportSize.
+ * Output : None.
+ * Return value : None.
+ *******************************************************************************/
+void USB_HID_Send_Report(void *pHIDReport, size_t reportSize)
+{
+ if (bDeviceState == CONFIGURED)
+ {
+ /* Reset the control token to inform upper layer that a transfer is ongoing */
+ PrevXferComplete = 0;
+
+ /* Copy HID Report to ENDP1 Tx Packet Memory Area*/
+ UserToPMABufferCopy((uint8_t *)pHIDReport, ENDP1_TXADDR, reportSize);
+ SetEPTxCount(ENDP1, reportSize);
+
+ /* Enable endpoint for transmission */
+ SetEPTxValid(ENDP1);
+ }
+}
+#endif
+
+/*******************************************************************************
+ * Function Name : HexToChar.
+ * Description : Convert Hex 32Bits value into char.
+ * Input : None.
+ * Output : None.
+ * Return : None.
+ *******************************************************************************/
+static void IntToUnicode (uint32_t value , uint8_t *pbuf , uint8_t len)
+{
+ uint8_t idx = 0;
+
+ for( idx = 0 ; idx < len ; idx ++)
+ {
+ if( ((value >> 28)) < 0xA )
+ {
+ pbuf[ 2* idx] = (value >> 28) + '0';
+ }
+ else
+ {
+ pbuf[2* idx] = (value >> 28) + 'A' - 10;
+ }
+
+ value = value << 4;
+
+ pbuf[ 2* idx + 1] = 0;
+ }
+}
diff --git a/build/makefile b/build/makefile
index 0ce95d1..fcd7071 100644
--- a/build/makefile
+++ b/build/makefile
@@ -37,8 +37,8 @@ SRC_MAKEFILES := $(call rwildcard,$(SRC_PATH)/,build.mk)
include $(SRC_MAKEFILES)
# Additional include directories, applied to objects built for this target.
-INCLUDE_DIRS += CMSIS/Include
-INCLUDE_DIRS += CMSIS/Device/ST/STM32F10x/Include
+INCLUDE_DIRS += SPARK_Platform/MCU/STM32F1xx/CMSIS/Include
+INCLUDE_DIRS += SPARK_Platform/MCU/STM32F1xx/CMSIS/Device/ST/STM32F10x/Include
# Compiler flags
CFLAGS = -g3 -gdwarf-2 -Os -mcpu=cortex-m3 -mthumb