aboutsummaryrefslogtreecommitdiff
path: root/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Libraries/STM32F37x_StdPeriph_Driver/src
diff options
context:
space:
mode:
authorTrygve Laugstøl <trygvis@inamo.no>2017-01-25 22:24:18 +0100
committerTrygve Laugstøl <trygvis@inamo.no>2017-01-25 22:29:25 +0100
commit40e04e3772726829d66c12e69f24b03920d79c67 (patch)
tree636811bad956798c9d5d22de9e7ba8c799b8d791 /thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Libraries/STM32F37x_StdPeriph_Driver/src
parent2fff65aed2477a503c72629d27e2a330d30c02d1 (diff)
downloadstm32f103-playground-40e04e3772726829d66c12e69f24b03920d79c67.tar.gz
stm32f103-playground-40e04e3772726829d66c12e69f24b03920d79c67.tar.bz2
stm32f103-playground-40e04e3772726829d66c12e69f24b03920d79c67.tar.xz
stm32f103-playground-40e04e3772726829d66c12e69f24b03920d79c67.zip
o Moving tinyprintf and stm libraries under thirdparty.
Diffstat (limited to 'thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Libraries/STM32F37x_StdPeriph_Driver/src')
-rw-r--r--thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Libraries/STM32F37x_StdPeriph_Driver/src/stm32f37x_adc.c1485
-rw-r--r--thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Libraries/STM32F37x_StdPeriph_Driver/src/stm32f37x_can.c1669
-rw-r--r--thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Libraries/STM32F37x_StdPeriph_Driver/src/stm32f37x_cec.c620
-rw-r--r--thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Libraries/STM32F37x_StdPeriph_Driver/src/stm32f37x_comp.c407
-rw-r--r--thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Libraries/STM32F37x_StdPeriph_Driver/src/stm32f37x_dac.c746
-rw-r--r--thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Libraries/STM32F37x_StdPeriph_Driver/src/stm32f37x_dma.c858
-rw-r--r--thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Libraries/STM32F37x_StdPeriph_Driver/src/stm32f37x_exti.c320
-rw-r--r--thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Libraries/STM32F37x_StdPeriph_Driver/src/stm32f37x_gpio.c528
-rw-r--r--thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Libraries/STM32F37x_StdPeriph_Driver/src/stm32f37x_i2c.c1585
-rw-r--r--thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Libraries/STM32F37x_StdPeriph_Driver/src/stm32f37x_iwdg.c295
-rw-r--r--thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Libraries/STM32F37x_StdPeriph_Driver/src/stm32f37x_pwr.c589
-rw-r--r--thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Libraries/STM32F37x_StdPeriph_Driver/src/stm32f37x_rcc.c1655
-rw-r--r--thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Libraries/STM32F37x_StdPeriph_Driver/src/stm32f37x_rtc.c2597
-rw-r--r--thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Libraries/STM32F37x_StdPeriph_Driver/src/stm32f37x_spi.c1302
-rw-r--r--thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Libraries/STM32F37x_StdPeriph_Driver/src/stm32f37x_syscfg.c378
-rw-r--r--thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Libraries/STM32F37x_StdPeriph_Driver/src/stm32f37x_usart.c2003
-rw-r--r--thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Libraries/STM32F37x_StdPeriph_Driver/src/stm32f37x_wwdg.c313
17 files changed, 17350 insertions, 0 deletions
diff --git a/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Libraries/STM32F37x_StdPeriph_Driver/src/stm32f37x_adc.c b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Libraries/STM32F37x_StdPeriph_Driver/src/stm32f37x_adc.c
new file mode 100644
index 0000000..2d4989e
--- /dev/null
+++ b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Libraries/STM32F37x_StdPeriph_Driver/src/stm32f37x_adc.c
@@ -0,0 +1,1485 @@
+/**
+ ******************************************************************************
+ * @file stm32f37x_adc.c
+ * @author MCD Application Team
+ * @version V1.0.0
+ * @date 20-September-2012
+ * @brief This file provides firmware functions to manage the following
+ * functionalities of the Analog to Digital Converter (ADC) peripheral:
+ * + Initialization and Configuration
+ * + Analog Watchdog configuration
+ * + Temperature Sensor, Vrefint (Internal Reference Voltage)
+ * and VBAT (Voltage battery) management
+ * + Regular Channels Configuration
+ * + Regular Channels DMA Configuration
+ * + Injected channels Configuration
+ * + Interrupts and flags management
+ *
+ * @verbatim
+================================================================================
+ ##### How to use this driver #####
+================================================================================
+ [..]
+ (#) Enable the ADC interface clock using
+ RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
+ (#) ADC pins configuration
+ (++) Enable the clock for the ADC GPIOs using the following function:
+ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOx, ENABLE);
+ (++) Configure these ADC pins in analog mode using GPIO_Init();
+ (#) Configure the data alignment using the ADC_Init() function.
+ (#) 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 configure and activate the Discontinuous mode, use the
+ ADC_DiscModeChannelCountConfig() and ADC_DiscModeCmd() functions.
+ (+) To read the ADC converted values, use the ADC_GetConversionValue()
+ function.
+
+ *** DMA for Regular channels group features configuration ***
+ =============================================================
+ [..]
+ (+) To enable the DMA mode for regular channels group, use the
+ ADC_DMACmd() function.
+
+ *** Injected channels group configuration ***
+ =============================================
+ [..]
+ (+) To configure the ADC Injected channels group features, use
+ ADC_InjectedChannelConfig() 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
+ *
+ * <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
+ *
+ * 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 "stm32f37x_adc.h"
+#include "stm32f37x_rcc.h"
+
+/** @addtogroup STM32F37x_StdPeriph_Driver
+ * @{
+ */
+
+/** @defgroup ADC
+ * @brief ADC driver modules
+ * @{
+ */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* CR2 register Mask */
+#define ADC_CR2_CLEAR_MASK ((uint32_t)0xFFF1F7FD)
+/* ADC SQRx mask */
+#define ADC_SQR_SQ_SET ((uint32_t)0x0000001F)
+/* ADC JSQRx mask */
+#define ADC_JSQR_JSQ_SET ((uint32_t)0x0000001F)
+/* ADC SMPRx mask */
+#define ADC_SMPR_SMP_SET ((uint32_t)0x00000007)
+/* ADC JDRx registers offset */
+#define ADC_JDR_OFFSET ((uint8_t)0x28)
+
+/* 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:
+ (+) 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
+ (+) Enable or disable the ADC peripheral
+ (+) Start/Reset the calibration
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Deinitializes the ADCx peripheral registers to their default reset values.
+ * @param ADCx: where x can be 1 to select the ADC peripheral.
+ * @retval None
+ */
+void ADC_DeInit(ADC_TypeDef* ADCx)
+{
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+
+ /* Enable ADC1 reset state */
+ RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1, ENABLE);
+ /* Release ADC1 from reset state */
+ RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1, DISABLE);
+}
+
+/**
+ * @brief Initializes the ADCx peripheral according to the specified parameters
+ * in the ADC_InitStruct.
+ * @param ADCx: where x can be 1 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_FUNCTIONAL_STATE(ADC_InitStruct->ADC_ScanConvMode));
+ assert_param(IS_FUNCTIONAL_STATE(ADC_InitStruct->ADC_ContinuousConvMode));
+ 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_NbrOfChannel));
+
+ /*---------------------------- ADCx CR1 Configuration -----------------*/
+ /* Get the ADCx CR1 value */
+ tmpreg1 = ADCx->CR1;
+ /* Clear SCAN bit */
+ tmpreg1 &= (uint32_t)(~ADC_CR1_SCAN);
+ /* Configure ADCx: scan conversion mode */
+ /* Set SCAN bit according to ADC_ScanConvMode value */
+ tmpreg1 |= (uint32_t)((uint32_t)ADC_InitStruct->ADC_ScanConvMode << 8);
+ /* Write to ADCx CR1 */
+ ADCx->CR1 = tmpreg1;
+
+ /*---------------------------- ADCx CR2 Configuration -----------------*/
+ /* Get the ADCx CR2 value */
+ tmpreg1 = ADCx->CR2;
+ /* Clear CONT, ALIGN and EXTSEL bits */
+ tmpreg1 &= ADC_CR2_CLEAR_MASK;
+ /* Configure ADCx: external trigger event and continuous conversion mode */
+ /* Set ALIGN bit according to ADC_DataAlign 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 |
+ ((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 &= (uint32_t) (~ADC_SQR1_L);
+ /* Configure ADCx: regular channel sequence length */
+ /* Set L bits according to ADC_NbrOfChannel value */
+ tmpreg2 |= (uint8_t) (ADC_InitStruct->ADC_NbrOfChannel - (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.
+ * @param ADC_InitStruct : pointer to an ADC_InitTypeDef structure which will be initialized.
+ * @retval None
+ */
+void ADC_StructInit(ADC_InitTypeDef* ADC_InitStruct)
+{
+ /* Reset ADC init structure parameters values */
+ /* initialize the ADC_ScanConvMode member */
+ ADC_InitStruct->ADC_ScanConvMode = DISABLE;
+ /* Initialize the ADC_ContinuousConvMode member */
+ ADC_InitStruct->ADC_ContinuousConvMode = DISABLE;
+ /* Initialize the ADC_ExternalTrigConv member */
+ ADC_InitStruct->ADC_ExternalTrigConv = ADC_ExternalTrigConv_T19_TRGO;
+ /* Initialize the ADC_DataAlign member */
+ ADC_InitStruct->ADC_DataAlign = ADC_DataAlign_Right;
+ /* Initialize the ADC_NbrOfChannel member */
+ ADC_InitStruct->ADC_NbrOfChannel = 1;
+}
+
+/**
+ * @brief Enables or disables the specified ADC peripheral.
+ * @param ADCx: where x can be 1 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 |= ADC_CR2_ADON;
+ }
+ else
+ {
+ /* Disable the selected ADC peripheral */
+ ADCx->CR2 &= (uint32_t)(~ADC_CR2_ADON);
+ }
+}
+
+/**
+ * @brief Starts the selected ADC calibration process.
+ * @param ADCx: where x can be 1 to select the ADC peripheral.
+ * @retval None
+ */
+void ADC_StartCalibration(ADC_TypeDef* ADCx)
+{
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+ /* Enable the selected ADC calibration process */
+ ADCx->CR2 |= ADC_CR2_CAL;
+}
+
+/**
+ * @brief Resets the selected ADC calibration registers.
+ * @param ADCx: where x can be 1 to select the ADC peripheral.
+ * @retval None
+ */
+void ADC_ResetCalibration(ADC_TypeDef* ADCx)
+{
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+ /* Resets the selected ADC calibration registers */
+ ADCx->CR2 |= ADC_CR2_RSTCAL;
+}
+
+/**
+ * @}
+ */
+
+/** @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 :
+ (#) The ADC guarded channel(s) is (are) selected using the
+ ADC_AnalogWatchdogSingleChannelConfig() function.
+ (#) The Analog watchdog lower and higher threshold are configured using
+ the ADC_AnalogWatchdogThresholdsConfig() function.
+ (#) 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 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, AWDENJ and AWDSGL bits */
+ tmpreg &= (uint32_t) (~(ADC_CR1_JAWDEN | ADC_CR1_AWDEN | ADC_CR1_AWDSGL));
+ /* 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 to select the ADC peripheral.
+ * @param HighThreshold: the ADC analog watchdog High threshold value.
+ * This parameter must be a 12bit value.
+ * @param LowThreshold: the ADC analog watchdog Low threshold value.
+ * This parameter must be a 12bit 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 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
+ * @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 &= (uint32_t)(~ADC_CR1_AWDCH);
+ /* Set the Analog watchdog channel */
+ tmpreg |= ADC_Channel;
+ /* Store the new register value */
+ ADCx->CR1 = tmpreg;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup ADC_Group3 Temperature Sensor- Vrefint (Internal Reference Voltage) and VBAT management function
+ * @brief Temperature Sensor- Vrefint (Internal Reference Voltage) and VBAT management function
+ *
+@verbatim
+ ===============================================================================
+ ##### Temperature Sensor, Vrefint and VBAT management function #####
+ ===============================================================================
+
+ [..] This section provides a function 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 :
+ (#) Enable the internal connection of Temperature sensor and Vrefint sources
+ with the ADC channels using ADC_TempSensorVrefintCmd() function.
+ Enable the internal connection of VBAT using SYSCFG_VBATMonitoringCmd(ENABLE);
+ (#) Select the ADC_Channel_TempSensor and/or ADC_Channel_Vrefint and/or
+ ADC_Channel_Vbat using ADC_RegularChannelConfig()
+ or ADC_InjectedChannelConfig() functions
+ (#) Get the voltage values, using ADC_GetConversionValue() or
+ ADC_GetInjectedConversionValue().
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Enables or disables the temperature sensor and Vrefint channel.
+ * @param NewState: new state of the temperature sensor.
+ * 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*/
+ ADC1->CR2 |= ADC_CR2_TSVREFE;
+ }
+ else
+ {
+ /* Disable the temperature sensor and Vrefint channel*/
+ ADC1->CR2 &= (uint32_t) (~ADC_CR2_TSVREFE);
+ }
+}
+
+/**
+ * @}
+ */
+
+/** @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 regular channels,
+ it is composed of 2 sub sections :
+
+ (#) 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 configured 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.
+
+ -@@- (*) and (**) are performing the same configuration
+
+ (#) 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.
+
+@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 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
+ * @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_1Cycles5: Sample time equal to 1.5 cycles
+ * @arg ADC_SampleTime_7Cycles5: Sample time equal to 7.5 cycles
+ * @arg ADC_SampleTime_13Cycles5: Sample time equal to 13.5 cycles
+ * @arg ADC_SampleTime_28Cycles5: Sample time equal to 28.5 cycles
+ * @arg ADC_SampleTime_41Cycles5: Sample time equal to 41.5 cycles
+ * @arg ADC_SampleTime_55Cycles5: Sample time equal to 55.5 cycles
+ * @arg ADC_SampleTime_71Cycles5: Sample time equal to 71.5 cycles
+ * @arg ADC_SampleTime_239Cycles5: Sample time equal to 239.5 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_17 is selected */
+ if (ADC_Channel > ADC_Channel_9)
+ {
+ /* Get the old register value */
+ tmpreg1 = ADCx->SMPR1;
+ /* Calculate the mask to clear */
+ tmpreg2 = ADC_SMPR_SMP_SET << (3 * (ADC_Channel - 10));
+ /* Clear the old channel sample time */
+ tmpreg1 &= ~tmpreg2;
+ /* Calculate the mask to set */
+ tmpreg2 = (uint32_t)ADC_SampleTime << (3 * (ADC_Channel - 10));
+ /* Set the new channel 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 = ADC_SMPR_SMP_SET << (3 * ADC_Channel);
+ /* Clear the old channel sample time */
+ tmpreg1 &= ~tmpreg2;
+ /* Calculate the mask to set */
+ tmpreg2 = (uint32_t)ADC_SampleTime << (3 * ADC_Channel);
+ /* Set the new channel 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 = ADC_SQR_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 = ADC_SQR_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 = ADC_SQR_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 or disables the ADCx conversion through external trigger.
+ * @param ADCx: where x can be 1 to select the ADC peripheral.
+ * @param NewState: new state of the selected ADC external trigger start of conversion.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void ADC_ExternalTrigConvCmd(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 conversion on external event */
+ ADCx->CR2 |= ADC_CR2_EXTTRIG;
+ }
+ else
+ {
+ /* Disable the selected ADC conversion on external event */
+ ADCx->CR2 &= (uint32_t) (~ADC_CR2_EXTTRIG);
+ }
+}
+
+/**
+ * @brief Enables or disables the selected ADC software start conversion .
+ * @param ADCx: where x can be 1 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 on external event and start the selected
+ ADC conversion */
+ ADCx->CR2 |= (uint32_t)(ADC_CR2_SWSTART | ADC_CR2_EXTTRIG);
+
+}
+
+/**
+ * @brief Gets the selected ADC Software start conversion Status.
+ * @param ADCx: where x can be 1 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_SWSTART) != (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 ADC continuous conversion mode
+ * @param ADCx: where x can be 1 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 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 &= (uint32_t)(~ADC_CR1_DISCNUM);
+ /* 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 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 |= 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 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;
+}
+
+/**
+ * @}
+ */
+
+/** @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.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Enables or disables the specified ADC DMA request.
+ * @param ADCx: where x can be 1 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_DMA_PERIPH(ADCx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ if (NewState != DISABLE)
+ {
+ /* Enable the selected ADC DMA request */
+ ADCx->CR2 |= ADC_CR2_DMA;
+ }
+ else
+ {
+ /* Disable the selected ADC DMA request */
+ ADCx->CR2 &= (uint32_t) (~ADC_CR2_DMA);
+ }
+}
+
+/**
+ * @}
+ */
+
+/** @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 :
+ (#) 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.
+
+ (#) 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 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
+ * @param Rank: The rank in the injected group sequencer. This parameter must be between 1 and 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_1Cycles5: Sample time equal to 1.5 cycles
+ * @arg ADC_SampleTime_7Cycles5: Sample time equal to 7.5 cycles
+ * @arg ADC_SampleTime_13Cycles5: Sample time equal to 13.5 cycles
+ * @arg ADC_SampleTime_28Cycles5: Sample time equal to 28.5 cycles
+ * @arg ADC_SampleTime_41Cycles5: Sample time equal to 41.5 cycles
+ * @arg ADC_SampleTime_55Cycles5: Sample time equal to 55.5 cycles
+ * @arg ADC_SampleTime_71Cycles5: Sample time equal to 71.5 cycles
+ * @arg ADC_SampleTime_239Cycles5: Sample time equal to 239.5 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_17 is selected */
+ if (ADC_Channel > ADC_Channel_9)
+ {
+ /* Get the old register value */
+ tmpreg1 = ADCx->SMPR1;
+ /* Calculate the mask to clear */
+ tmpreg2 = ADC_SMPR_SMP_SET << (3*(ADC_Channel - 10));
+ /* Clear the old channel sample time */
+ tmpreg1 &= ~tmpreg2;
+ /* Calculate the mask to set */
+ tmpreg2 = (uint32_t)ADC_SampleTime << (3*(ADC_Channel - 10));
+ /* Set the new channel 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 = ADC_SMPR_SMP_SET << (3 * ADC_Channel);
+ /* Clear the old channel sample time */
+ tmpreg1 &= ~tmpreg2;
+ /* Calculate the mask to set */
+ tmpreg2 = (uint32_t)ADC_SampleTime << (3 * ADC_Channel);
+ /* Set the new channel 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 & ADC_JSQR_JL)>> 20;
+ /* Calculate the mask to clear: ((Rank-1)+(4-JL-1)) */
+ tmpreg2 = ADC_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 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 &= (uint32_t)(~ADC_JSQR_JL);
+ /* 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 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 ADC_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 ADC_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(ADC_Offset));
+
+ tmp = (uint32_t)ADCx;
+ tmp += ADC_InjectedChannel;
+
+ /* Set the selected injected channel data offset */
+ *(__IO uint32_t *) tmp = (uint32_t)ADC_Offset;
+}
+
+/**
+ * @brief Configures the ADCx external trigger for injected channels conversion.
+ * @param ADCx: where x can be 1 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_TRGO: Timer1 TRGO event selected (for ADC1, ADC2 and ADC3)
+ * @arg ADC_ExternalTrigInjecConv_T1_CC4: Timer1 capture compare4 selected (for ADC1, ADC2 and ADC3)
+ * @arg ADC_ExternalTrigInjecConv_T2_TRGO: Timer2 TRGO event selected (for ADC1 and ADC2)
+ * @arg ADC_ExternalTrigInjecConv_T2_CC1: Timer2 capture compare1 selected (for ADC1 and ADC2)
+ * @arg ADC_ExternalTrigInjecConv_T3_CC4: Timer3 capture compare4 selected (for ADC1 and ADC2)
+ * @arg ADC_ExternalTrigInjecConv_T4_TRGO: Timer4 TRGO event selected (for ADC1 and ADC2)
+ * @arg ADC_ExternalTrigInjecConv_Ext_IT15_TIM8_CC4: External interrupt line 15 or Timer8
+ * capture compare4 event selected (for ADC1 and ADC2)
+ * @arg ADC_ExternalTrigInjecConv_T4_CC3: Timer4 capture compare3 selected (for ADC3 only)
+ * @arg ADC_ExternalTrigInjecConv_T8_CC2: Timer8 capture compare2 selected (for ADC3 only)
+ * @arg ADC_ExternalTrigInjecConv_T8_CC4: Timer8 capture compare4 selected (for ADC3 only)
+ * @arg ADC_ExternalTrigInjecConv_T5_TRGO: Timer5 TRGO event selected (for ADC3 only)
+ * @arg ADC_ExternalTrigInjecConv_T5_CC4: Timer5 capture compare4 selected (for ADC3 only)
+ * @arg ADC_ExternalTrigInjecConv_None: Injected conversion started by software and not
+ * by external trigger (for ADC1, ADC2 and ADC3)
+ * @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 &= (uint32_t) (~ADC_CR2_JEXTSEL);
+ /* Set the external event selection for injected group */
+ tmpreg |= ADC_ExternalTrigInjecConv;
+ /* Store the new register value */
+ ADCx->CR2 = tmpreg;
+}
+
+/**
+ * @brief Enables or disables the ADCx injected channels conversion through
+ * external trigger
+ * @param ADCx: where x can be 1 to select the ADC peripheral.
+ * @param NewState: new state of the selected ADC external trigger start of
+ * injected conversion.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void ADC_ExternalTrigInjectedConvCmd(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 external event selection for injected group */
+ ADCx->CR2 |= ADC_CR2_JEXTTRIG;
+ }
+ else
+ {
+ /* Disable the selected ADC external event selection for injected group */
+ ADCx->CR2 &= (uint32_t)(~ADC_CR2_JEXTTRIG);
+ }
+}
+
+/**
+ * @brief Enables or disables the selected ADC start of the injected
+ * channels conversion.
+ * @param ADCx: where x can be 1 to select the ADC peripheral.
+ * @param NewState: new state of the selected ADC software start injected conversion.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void ADC_SoftwareStartInjectedConvCmd(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 conversion for injected group on external event and start the selected
+ ADC injected conversion */
+ ADCx->CR2 |= (ADC_CR2_JSWSTART | ADC_CR2_JEXTTRIG);
+ }
+ else
+ {
+ /* Disable the selected ADC conversion on external event for injected group and stop the selected
+ ADC injected conversion */
+ ADCx->CR2 &= (uint32_t) ~(ADC_CR2_JSWSTART | ADC_CR2_JEXTTRIG);
+ }
+}
+
+/**
+ * @brief Gets the selected ADC Software start injected conversion Status.
+ * @param ADCx: where x can be 1 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 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 |= 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 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 |= 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 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 + ADC_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,
+ get the status and clear flags and Interrupts pending bits.
+
+ [..] The ADC provide 4 Interrupts sources and 9 Flags which can be divided
+ into 3 groups:
+
+ *** Flags and Interrupts for ADC regular channels ***
+ =====================================================
+ [..]
+ (+)Flags :
+ (##) ADC_FLAG_EOC : Regular channel end of conversion to indicate
+ the end of sequence of regular GROUP conversions
+ (##) ADC_FLAG_STRT: Regular channel start to indicate when regular
+ CHANNEL conversion starts.
+
+ (+)Interrupts :
+ (##) ADC_IT_EOC : specifies the interrupt source for Regular channel
+ end of conversion event.
+
+
+ *** Flags and Interrupts for ADC Injected channels ***
+ ======================================================
+ [..]
+ (+)Flags :
+ (##) ADC_FLAG_JEOC : Injected channel end of conversion to indicate
+ at the end of injected GROUP conversion
+ (##) ADC_FLAG_JSTRT : Injected channel start to indicate when injected
+ GROUP conversion starts.
+
+ (+)Interrupts :
+ (##) ADC_IT_JEOC : specifies the interrupt source for Injected channel
+ end of conversion event.
+
+ *** General Flags and Interrupts for the ADC ***
+ ================================================
+ [..]
+ (+)Flags :
+ (##) ADC_FLAG_AWD : Analog watchdog + to indicate if the converted voltage
+ crosses the programmed thresholds values.
+ (+)Interrupts :
+ (##) 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 to select the ADC peripheral.
+ * @param ADC_IT: specifies the ADC interrupt sources to be enabled or disabled.
+ * This parameter can be any combination 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
+ * @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)
+{
+ uint8_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;
+ 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 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
+ * @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 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
+ * @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 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
+ * @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_GET_IT(ADC_IT));
+ /* Get the ADC IT index */
+ itmask = ADC_IT >> 8;
+ /* Get the ADC_IT enable bit status */
+ enablestatus = (ADCx->CR1 & (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 to select the ADC peripheral.
+ * @param ADC_IT: specifies the ADC interrupt pending bit to clear.
+ * This parameter can be any combination 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
+ * @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;
+}
+
+/**
+ * @brief Gets the selected ADC calibration status.
+ * @param ADCx: where x can be 1 to select the ADC peripheral.
+ * @retval The new state of ADC calibration (SET or RESET).
+ */
+FlagStatus ADC_GetCalibrationStatus(ADC_TypeDef* ADCx)
+{
+ FlagStatus bitstatus = RESET;
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+ /* Check the status of CAL bit */
+ if ((ADCx->CR2 & ADC_CR2_CAL) != (uint32_t)RESET)
+ {
+ /* CAL bit is set: calibration on going */
+ bitstatus = SET;
+ }
+ else
+ {
+ /* CAL bit is reset: end of calibration */
+ bitstatus = RESET;
+ }
+ /* Return the CAL bit status */
+ return bitstatus;
+}
+
+/**
+ * @brief Gets the selected ADC reset calibration registers status.
+ * @param ADCx: where x can be 1 to select the ADC peripheral.
+ * @retval The new state of ADC reset calibration registers (SET or RESET).
+ */
+FlagStatus ADC_GetResetCalibrationStatus(ADC_TypeDef* ADCx)
+{
+ FlagStatus bitstatus = RESET;
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+ /* Check the status of RSTCAL bit */
+ if ((ADCx->CR2 & ADC_CR2_RSTCAL) != (uint32_t)RESET)
+ {
+ /* RSTCAL bit is set */
+ bitstatus = SET;
+ }
+ else
+ {
+ /* RSTCAL bit is reset */
+ bitstatus = RESET;
+ }
+ /* Return the RSTCAL bit status */
+ return bitstatus;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Libraries/STM32F37x_StdPeriph_Driver/src/stm32f37x_can.c b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Libraries/STM32F37x_StdPeriph_Driver/src/stm32f37x_can.c
new file mode 100644
index 0000000..e020584
--- /dev/null
+++ b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Libraries/STM32F37x_StdPeriph_Driver/src/stm32f37x_can.c
@@ -0,0 +1,1669 @@
+/**
+ ******************************************************************************
+ * @file stm32f37x_can.c
+ * @author MCD Application Team
+ * @version V1.0.0
+ * @date 20-September-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 #####
+================================================================================
+ [..]
+ (#) Enable the CAN controller interface clock using
+ RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE); for CAN1
+
+ (#) 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();
+ (#) Initialise and configure the CAN using CAN_Init() and
+ CAN_FilterInit() functions.
+
+ (#) Transmit the desired CAN frame using CAN_Transmit() function.
+
+ (#) Check the transmission of a CAN frame using CAN_TransmitStatus()
+ function.
+
+ (#) Cancel the transmission of a CAN frame using CAN_CancelTransmit()
+ function.
+
+ (#) Receive a CAN frame using CAN_Recieve() function.
+
+ (#) Release the receive FIFOs using CAN_FIFORelease() function.
+
+ (#) Return the number of pending received frames using
+ CAN_MessagePending() function.
+
+ (#) 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
+ *
+ * <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
+ *
+ * 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 "stm32f37x_can.h"
+#include "stm32f37x_rcc.h"
+
+/** @addtogroup STM32F37x_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.
+ (#) 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 to select the CAN1 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);
+ }
+}
+
+/**
+ * @brief Initializes the CAN peripheral according to the specified
+ * parameters in the CAN_InitStruct.
+ * @param CANx: where x can be 1 to select the CAN1 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 to select the CAN1 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 to select the CAN1 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 to select the CAN1 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 to select the CAN1 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 to select the CAN1 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_status.
+ * @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 to select the CAN1 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 to select the CAN1 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).
+ [..]
+ (@) If TEC is greater than 255, The CAN is in bus-off state.
+ (@) If REC or TEC are greater than 96, an Error warning flag occurs.
+ (@) 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 to select the CAN1 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:
+
+ (+)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.
+
+ (+)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.
+
+ (+)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.
+
+ (+)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:
+
+ (+)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.
+
+ (+)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.
+
+ (+)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.
+
+ (+)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.
+ (+)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.
+
+ (+)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).
+ -@@-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/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Libraries/STM32F37x_StdPeriph_Driver/src/stm32f37x_cec.c b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Libraries/STM32F37x_StdPeriph_Driver/src/stm32f37x_cec.c
new file mode 100644
index 0000000..1dd33b8
--- /dev/null
+++ b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Libraries/STM32F37x_StdPeriph_Driver/src/stm32f37x_cec.c
@@ -0,0 +1,620 @@
+/**
+ ******************************************************************************
+ * @file stm32f37x_cec.c
+ * @author MCD Application Team
+ * @version V1.0.0
+ * @date 20-September-2012
+ * @brief This file provides firmware functions to manage the following
+ * functionalities of the Consumer Electronics Control (CEC) peripheral:
+ * + Initialization and Configuration
+ * + Data transfers functions
+ * + Interrupts and flags management
+ *
+ * @verbatim
+ ==============================================================================
+ ##### CEC features #####
+ ==============================================================================
+ [..] This device provides some features:
+ (#) Supports HDMI-CEC specification 1.4.
+ (#) Supports two source clocks(HSI/244 or LSE).
+ (#) Works in stop mode(without APB clock, but with CEC clock 32KHz).
+ It can genarate an interrupt in the CEC clock domain that the CPU
+ wakes up from the low power mode.
+ (#) Configurable Signal Free Time before of transmission start. The
+ number of nominal data bit periods waited before transmission can be
+ ruled by Hardware or Software.
+ (#) Configurable Peripheral Address (multi-addressing configuration).
+ (#) Supports listen mode.The CEC Messages addressed to different destination
+ can be received without interfering with CEC bus when Listen mode option is enabled.
+ (#) Configurable Rx-Tolerance(Standard and Extended tolerance margin).
+ (#) Error detection with configurable error bit generation.
+ (#) Arbitration lost error in the case of two CEC devices starting at the same time.
+
+ ##### How to use this driver #####
+ ==============================================================================
+ [..] This driver provides functions to configure and program the CEC device,
+ follow steps below:
+ (#) The source clock can be configured using:
+ (++) RCC_CECCLKConfig(RCC_CECCLK_HSI_Div244) for HSI(Default)
+ (++) RCC_CECCLKConfig(RCC_CECCLK_LSE) for LSE.
+ (#) Enable CEC peripheral clock using RCC_APBPeriphClockCmd(RCC_APBPeriph_CEC, ENABLE).
+ (#) 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 open-drain and output speed via GPIO_OType
+ and GPIO_Speed members.
+ (++) Call GPIO_Init() function.
+ (#) Configure the Signal Free Time, Rx Tolerance, Stop reception generation
+ and Bit error generation using the CEC_Init() function.
+ The function CEC_Init() must be called when the CEC peripheral is disabled.
+ (#) Configure the CEC own address by calling the fuction CEC_OwnAddressConfig().
+ (#) Optionally, you can configure the Listen mode using the function CEC_ListenModeCmd().
+ (#) Enable the NVIC and the corresponding interrupt using the function
+ CEC_ITConfig() if you need to use interrupt mode.
+ CEC_ITConfig() must be called before enabling the CEC peripheral.
+ (#) Enable the CEC using the CEC_Cmd() function.
+ (#) Charge the first data byte in the TXDR register using CEC_SendDataByte().
+ (#) Enable the transmission of the Byte of a CEC message using CEC_StartOfMessage()
+ (#) Transmit single data through the CEC peripheral using CEC_SendDataByte()
+ and Receive the last transmitted byte using CEC_ReceiveDataByte().
+ (#) Enable the CEC_EndOfMessage() in order to indicate the last byte of the message.
+ [..]
+ (@) If the listen mode is enabled, Stop reception generation and Bit error generation
+ must be in reset state.
+ (@) If the CEC message consists of only 1 byte, the function CEC_EndOfMessage()
+ must be called before CEC_StartOfMessage().
+
+ @endverbatim
+ *
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
+ *
+ * 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 "stm32f37x_cec.h"
+#include "stm32f37x_rcc.h"
+
+/** @addtogroup STM32F37x_StdPeriph_Driver
+ * @{
+ */
+
+/** @defgroup CEC
+ * @brief CEC driver modules
+ * @{
+ */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+#define BROADCAST_ADDRESS ((uint32_t)0x0000F) /* Broadcast address */
+#define CFGR_CLEAR_MASK ((uint32_t)0x7000FE00) /* CFGR register Mask */
+
+/* ------------- CEC registers bit address in the alias region -------------- */
+#define CEC_OFFSET (CEC_BASE - PERIPH_BASE)
+
+/* --- CR Register ---*/
+/* Alias word address of CECEN bit */
+#define CR_OFFSET (CEC_OFFSET + 0x00)
+#define CECEN_BitNumber 0x00
+#define CR_CECEN_BB (PERIPH_BB_BASE + (CR_OFFSET * 32) + (CECEN_BitNumber * 4))
+
+/* Alias word address of TXSOM bit */
+#define TXSOM_BitNumber 0x01
+#define CR_TXSOM_BB (PERIPH_BB_BASE + (CR_OFFSET * 32) + (TXSOM_BitNumber * 4))
+
+/* Alias word address of TXEOM bit */
+#define TXEOM_BitNumber 0x02
+#define CR_TXEOM_BB (PERIPH_BB_BASE + (CR_OFFSET * 32) + (TXEOM_BitNumber * 4))
+
+/* --- CFGR Register ---*/
+/* Alias word address of LSTN bit */
+#define CFGR_OFFSET (CEC_OFFSET + 0x04)
+#define LSTN_BitNumber 0x1F
+#define CFGR_LSTN_BB (PERIPH_BB_BASE + (CFGR_OFFSET * 32) + (LSTN_BitNumber * 4))
+
+
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+/** @defgroup CEC_Private_Functions
+ * @{
+ */
+
+/** @defgroup CEC_Group1 Initialization and Configuration functions
+ * @brief Initialization and Configuration functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Initialization and Configuration functions #####
+ ===============================================================================
+ [..] This section provides functions allowing to initialize:
+ (+) CEC own addresses
+ (+) CEC Signal Free Time
+ (+) CEC Rx Tolerance
+ (+) CEC Stop Reception
+ (+) CEC Bit Rising Error
+ (+) CEC Long Bit Period Error
+ [..] This section provides also a function to configure the CEC peripheral in Listen Mode.
+ Messages addressed to different destination can be received when Listen mode is
+ enabled without interfering with CEC bus.
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Deinitializes all CEC peripheral registers to their default reset values.
+ * @param None
+ * @retval None
+ */
+void CEC_DeInit(void)
+{
+ /* Enable all CEC reset state */
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_CEC, ENABLE);
+
+ /* Release all CEC from reset state */
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_CEC, DISABLE);
+}
+
+/**
+ * @brief Initializes the CEC peripheral according to the specified
+ * parameters in the CEC_InitStruct.
+ * @note The CEC parameters must be configured before enabling the CEC peripheral.
+ * @param CEC_InitStruct: pointer to an CEC_InitTypeDef structure that
+ * contains the configuration information for the specified
+ * CEC peripheral.
+ * @retval None
+ */
+void CEC_Init(CEC_InitTypeDef* CEC_InitStruct)
+{
+ uint32_t tmpreg = 0;
+
+ /* Check the parameters */
+ assert_param(IS_CEC_SIGNAL_FREE_TIME(CEC_InitStruct->CEC_SignalFreeTime));
+ assert_param(IS_CEC_RX_TOLERANCE(CEC_InitStruct->CEC_RxTolerance));
+ assert_param(IS_CEC_STOP_RECEPTION(CEC_InitStruct->CEC_StopReception));
+ assert_param(IS_CEC_BIT_RISING_ERROR(CEC_InitStruct->CEC_BitRisingError));
+ assert_param(IS_CEC_LONG_BIT_PERIOD_ERROR(CEC_InitStruct->CEC_LongBitPeriodError));
+ assert_param(IS_CEC_BDR_NO_GEN_ERROR(CEC_InitStruct->CEC_BRDNoGen));
+ assert_param(IS_CEC_SFT_OPTION(CEC_InitStruct->CEC_SFTOption));
+
+ /*---------------------------- CEC CFGR Configuration ----------------------*/
+ /* Get the CEC CFGR value */
+ tmpreg = CEC->CFGR;
+
+ /* Clear CFGR bits */
+ tmpreg &= CFGR_CLEAR_MASK;
+
+ /* Configure the CEC peripheral */
+ tmpreg |= (CEC_InitStruct->CEC_SignalFreeTime | CEC_InitStruct->CEC_RxTolerance |
+ CEC_InitStruct->CEC_StopReception | CEC_InitStruct->CEC_BitRisingError |
+ CEC_InitStruct->CEC_LongBitPeriodError|CEC_InitStruct->CEC_BRDNoGen |
+ CEC_InitStruct->CEC_SFTOption);
+
+ /* Write to CEC CFGR register */
+ CEC->CFGR = tmpreg;
+}
+
+/**
+ * @brief Fills each CEC_InitStruct member with its default value.
+ * @param CEC_InitStruct: pointer to a CEC_InitTypeDef structure which will
+ * be initialized.
+ * @retval None
+ */
+void CEC_StructInit(CEC_InitTypeDef* CEC_InitStruct)
+{
+ CEC_InitStruct->CEC_SignalFreeTime = CEC_SignalFreeTime_Standard;
+ CEC_InitStruct->CEC_RxTolerance = CEC_RxTolerance_Standard;
+ CEC_InitStruct->CEC_StopReception = CEC_StopReception_Off;
+ CEC_InitStruct->CEC_BitRisingError = CEC_BitRisingError_Off;
+ CEC_InitStruct->CEC_LongBitPeriodError = CEC_LongBitPeriodError_Off;
+ CEC_InitStruct->CEC_BRDNoGen = CEC_BRDNoGen_Off;
+ CEC_InitStruct->CEC_SFTOption = CEC_SFTOption_Off;
+}
+
+/**
+ * @brief Enables or disables the CEC peripheral.
+ * @param NewState: new state of the CEC peripheral.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void CEC_Cmd(FunctionalState NewState)
+{
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ *(__IO uint32_t *) CR_CECEN_BB = (uint32_t)NewState;
+}
+
+/**
+ * @brief Enables or disables the CEC Listen Mode.
+ * @param NewState: new state of the Listen Mode.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void CEC_ListenModeCmd(FunctionalState NewState)
+{
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ *(__IO uint32_t *) CFGR_LSTN_BB = (uint32_t)NewState;
+}
+
+/**
+ * @brief Defines the Own Address of the CEC device.
+ * @param CEC_OwnAddress: The CEC own address.
+ * @retval None
+ */
+void CEC_OwnAddressConfig(uint8_t CEC_OwnAddress)
+{
+ uint32_t tmp =0x00;
+
+ /* Check the parameters */
+ assert_param(IS_CEC_ADDRESS(CEC_OwnAddress));
+ tmp = 1 <<(CEC_OwnAddress + 16);
+ /* Set the CEC own address */
+ CEC->CFGR |= tmp;
+}
+
+/**
+ * @brief Clears the Own Address of the CEC device.
+ * @param CEC_OwnAddress: The CEC own address.
+ * @retval None
+ */
+void CEC_OwnAddressClear(void)
+{
+ /* Set the CEC own address */
+ CEC->CFGR = 0x0;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup CEC_Group2 Data transfers functions
+ * @brief Data transfers functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Data transfers functions #####
+ ===============================================================================
+ [..] This section provides functions allowing the CEC data transfers.The read
+ access of the CEC_RXDR register can be done using the CEC_ReceiveData()function
+ and returns the Rx buffered value. Whereas a write access to the CEC_TXDR can be
+ done using CEC_SendData() function.
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Transmits single data through the CEC peripheral.
+ * @param Data: the data to transmit.
+ * @retval None
+ */
+void CEC_SendData(uint8_t Data)
+{
+ /* Transmit Data */
+ CEC->TXDR = Data;
+}
+
+/**
+ * @brief Returns the most recent received data by the CEC peripheral.
+ * @param None
+ * @retval The received data.
+ */
+uint8_t CEC_ReceiveData(void)
+{
+ /* Receive Data */
+ return (uint8_t)(CEC->RXDR);
+}
+
+/**
+ * @brief Starts a new message.
+ * @param None
+ * @retval None
+ */
+void CEC_StartOfMessage(void)
+{
+ /* Starts of new message */
+ *(__IO uint32_t *) CR_TXSOM_BB = (uint32_t)0x1;
+}
+
+/**
+ * @brief Transmits message with an EOM bit.
+ * @param None
+ * @retval None
+ */
+void CEC_EndOfMessage(void)
+{
+ /* The data byte will be transmitted with an EOM bit */
+ *(__IO uint32_t *) CR_TXEOM_BB = (uint32_t)0x1;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup CEC_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 CEC 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 or Interrupt mode.
+
+ [..] In polling mode, the CEC can be managed by the following flags:
+ (+) CEC_FLAG_TXACKE : to indicate a missing acknowledge in transmission mode.
+ (+) CEC_FLAG_TXERR : to indicate an error occurs during transmission mode.
+ The initiator detects low impedance in the CEC line.
+ (+) CEC_FLAG_TXUDR : to indicate if an underrun error occurs in transmission mode.
+ The transmission is enabled while the software has not yet
+ loaded any value into the TXDR register.
+ (+) CEC_FLAG_TXEND : to indicate the end of successful transmission.
+ (+) CEC_FLAG_TXBR : to indicate the next transmission data has to be written to TXDR.
+ (+) CEC_FLAG_ARBLST : to indicate arbitration lost in the case of two CEC devices
+ starting at the same time.
+ (+) CEC_FLAG_RXACKE : to indicate a missing acknowledge in receive mode.
+ (+) CEC_FLAG_LBPE : to indicate a long bit period error generated during receive mode.
+ (+) CEC_FLAG_SBPE : to indicate a short bit period error generated during receive mode.
+ (+) CEC_FLAG_BRE : to indicate a bit rising error generated during receive mode.
+ (+) CEC_FLAG_RXOVR : to indicate if an overrun error occur while receiving a CEC message.
+ A byte is not yet received while a new byte is stored in the RXDR register.
+ (+) CEC_FLAG_RXEND : to indicate the end Of reception
+ (+) CEC_FLAG_RXBR : to indicate a new byte has been received from the CEC line and
+ stored into the RXDR buffer.
+ [..]
+ (@)In this Mode, it is advised to use the following functions:
+ FlagStatus CEC_GetFlagStatus(uint16_t CEC_FLAG);
+ void CEC_ClearFlag(uint16_t CEC_FLAG);
+
+ [..] In Interrupt mode, the CEC can be managed by the following interrupt sources:
+ (+) CEC_IT_TXACKE : to indicate a TX Missing acknowledge
+ (+) CEC_IT_TXACKE : to indicate a missing acknowledge in transmission mode.
+ (+) CEC_IT_TXERR : to indicate an error occurs during transmission mode.
+ The initiator detects low impedance in the CEC line.
+ (+) CEC_IT_TXUDR : to indicate if an underrun error occurs in transmission mode.
+ The transmission is enabled while the software has not yet
+ loaded any value into the TXDR register.
+ (+) CEC_IT_TXEND : to indicate the end of successful transmission.
+ (+) CEC_IT_TXBR : to indicate the next transmission data has to be written to TXDR register.
+ (+) CEC_IT_ARBLST : to indicate arbitration lost in the case of two CEC devices
+ starting at the same time.
+ (+) CEC_IT_RXACKE : to indicate a missing acknowledge in receive mode.
+ (+) CEC_IT_LBPE : to indicate a long bit period error generated during receive mode.
+ (+) CEC_IT_SBPE : to indicate a short bit period error generated during receive mode.
+ (+) CEC_IT_BRE : to indicate a bit rising error generated during receive mode.
+ (+) CEC_IT_RXOVR : to indicate if an overrun error occur while receiving a CEC message.
+ A byte is not yet received while a new byte is stored in the RXDR register.
+ (+) CEC_IT_RXEND : to indicate the end Of reception
+ (+) CEC_IT_RXBR : to indicate a new byte has been received from the CEC line and
+ stored into the RXDR buffer.
+ [..]
+ (@)In this Mode it is advised to use the following functions:
+ void CEC_ITConfig( uint16_t CEC_IT, FunctionalState NewState);
+ ITStatus CEC_GetITStatus(uint16_t CEC_IT);
+ void CEC_ClearITPendingBit(uint16_t CEC_IT);
+
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Enables or disables the selected CEC interrupts.
+ * @param CEC_IT: specifies the CEC interrupt source to be enabled.
+ * This parameter can be any combination of the following values:
+ * @arg CEC_IT_TXACKE: Tx Missing acknowledge Error
+ * @arg CEC_IT_TXERR: Tx Error.
+ * @arg CEC_IT_TXUDR: Tx-Buffer Underrun.
+ * @arg CEC_IT_TXEND: End of Transmission (successful transmission of the last byte).
+ * @arg CEC_IT_TXBR: Tx-Byte Request.
+ * @arg CEC_IT_ARBLST: Arbitration Lost
+ * @arg CEC_IT_RXACKE: Rx-Missing Acknowledge
+ * @arg CEC_IT_LBPE: Rx Long period Error
+ * @arg CEC_IT_SBPE: Rx Short period Error
+ * @arg CEC_IT_BRE: Rx Bit Rising Error
+ * @arg CEC_IT_RXOVR: Rx Overrun.
+ * @arg CEC_IT_RXEND: End Of Reception
+ * @arg CEC_IT_RXBR: Rx-Byte Received
+ * @param NewState: new state of the selected CEC interrupts.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void CEC_ITConfig(uint16_t CEC_IT, FunctionalState NewState)
+{
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ assert_param(IS_CEC_IT(CEC_IT));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the selected CEC interrupt */
+ CEC->IER |= CEC_IT;
+ }
+ else
+ {
+ CEC_IT =~CEC_IT;
+ /* Disable the selected CEC interrupt */
+ CEC->IER &= CEC_IT;
+ }
+}
+
+/**
+ * @brief Gets the CEC flag status.
+ * @param CEC_FLAG: specifies the CEC flag to check.
+ * This parameter can be one of the following values:
+ * @arg CEC_FLAG_TXACKE: Tx Missing acknowledge Error
+ * @arg CEC_FLAG_TXERR: Tx Error.
+ * @arg CEC_FLAG_TXUDR: Tx-Buffer Underrun.
+ * @arg CEC_FLAG_TXEND: End of transmission (successful transmission of the last byte).
+ * @arg CEC_FLAG_TXBR: Tx-Byte Request.
+ * @arg CEC_FLAG_ARBLST: Arbitration Lost
+ * @arg CEC_FLAG_RXACKE: Rx-Missing Acknowledge
+ * @arg CEC_FLAG_LBPE: Rx Long period Error
+ * @arg CEC_FLAG_SBPE: Rx Short period Error
+ * @arg CEC_FLAG_BRE: Rx Bit Rissing Error
+ * @arg CEC_FLAG_RXOVR: Rx Overrun.
+ * @arg CEC_FLAG_RXEND: End Of Reception.
+ * @arg CEC_FLAG_RXBR: Rx-Byte Received.
+ * @retval The new state of CEC_FLAG (SET or RESET)
+ */
+FlagStatus CEC_GetFlagStatus(uint16_t CEC_FLAG)
+{
+ FlagStatus bitstatus = RESET;
+
+ assert_param(IS_CEC_GET_FLAG(CEC_FLAG));
+
+ /* Check the status of the specified CEC flag */
+ if ((CEC->ISR & CEC_FLAG) != (uint16_t)RESET)
+ {
+ /* CEC flag is set */
+ bitstatus = SET;
+ }
+ else
+ {
+ /* CEC flag is reset */
+ bitstatus = RESET;
+ }
+
+ /* Return the CEC flag status */
+ return bitstatus;
+}
+
+/**
+ * @brief Clears the CEC's pending flags.
+ * @param CEC_FLAG: specifies the flag to clear.
+ * This parameter can be any combination of the following values:
+ * @arg CEC_FLAG_TXACKE: Tx Missing acknowledge Error
+ * @arg CEC_FLAG_TXERR: Tx Error
+ * @arg CEC_FLAG_TXUDR: Tx-Buffer Underrun
+ * @arg CEC_FLAG_TXEND: End of transmission (successful transmission of the last byte).
+ * @arg CEC_FLAG_TXBR: Tx-Byte Request
+ * @arg CEC_FLAG_ARBLST: Arbitration Lost
+ * @arg CEC_FLAG_RXACKE: Rx Missing Acknowledge
+ * @arg CEC_FLAG_LBPE: Rx Long period Error
+ * @arg CEC_FLAG_SBPE: Rx Short period Error
+ * @arg CEC_FLAG_BRE: Rx Bit Rising Error
+ * @arg CEC_FLAG_RXOVR: Rx Overrun
+ * @arg CEC_FLAG_RXEND: End Of Reception
+ * @arg CEC_FLAG_RXBR: Rx-Byte Received
+ * @retval None
+ */
+void CEC_ClearFlag(uint16_t CEC_FLAG)
+{
+ assert_param(IS_CEC_CLEAR_FLAG(CEC_FLAG));
+
+ /* Clear the selected CEC flag */
+ CEC->ISR = CEC_FLAG;
+}
+
+/**
+ * @brief Checks whether the specified CEC interrupt has occurred or not.
+ * @param CEC_IT: specifies the CEC interrupt source to check.
+ * This parameter can be one of the following values:
+ * @arg CEC_IT_TXACKE: Tx Missing acknowledge Error
+ * @arg CEC_IT_TXERR: Tx Error.
+ * @arg CEC_IT_TXUDR: Tx-Buffer Underrun.
+ * @arg CEC_IT_TXEND: End of transmission (successful transmission of the last byte).
+ * @arg CEC_IT_TXBR: Tx-Byte Request.
+ * @arg CEC_IT_ARBLST: Arbitration Lost.
+ * @arg CEC_IT_RXACKE: Rx-Missing Acknowledge.
+ * @arg CEC_IT_LBPE: Rx Long period Error.
+ * @arg CEC_IT_SBPE: Rx Short period Error.
+ * @arg CEC_IT_BRE: Rx Bit Rising Error.
+ * @arg CEC_IT_RXOVR: Rx Overrun.
+ * @arg CEC_IT_RXEND: End Of Reception.
+ * @arg CEC_IT_RXBR: Rx-Byte Received
+ * @retval The new state of CEC_IT (SET or RESET).
+ */
+ITStatus CEC_GetITStatus(uint16_t CEC_IT)
+{
+ ITStatus bitstatus = RESET;
+ uint32_t enablestatus = 0;
+
+ /* Check the parameters */
+ assert_param(IS_CEC_GET_IT(CEC_IT));
+
+ /* Get the CEC IT enable bit status */
+ enablestatus = (CEC->IER & CEC_IT);
+
+ /* Check the status of the specified CEC interrupt */
+ if (((CEC->ISR & CEC_IT) != (uint32_t)RESET) && enablestatus)
+ {
+ /* CEC interrupt is set */
+ bitstatus = SET;
+ }
+ else
+ {
+ /* CEC interrupt is reset */
+ bitstatus = RESET;
+ }
+
+ /* Return the CEC interrupt status */
+ return bitstatus;
+
+}
+
+/**
+ * @brief Clears the CEC's interrupt pending bits.
+ * @param CEC_IT: specifies the CEC interrupt pending bit to clear.
+ * This parameter can be any combination of the following values:
+ * @arg CEC_IT_TXACKE: Tx Missing acknowledge Error
+ * @arg CEC_IT_TXERR: Tx Error
+ * @arg CEC_IT_TXUDR: Tx-Buffer Underrun
+ * @arg CEC_IT_TXEND: End of Transmission
+ * @arg CEC_IT_TXBR: Tx-Byte Request
+ * @arg CEC_IT_ARBLST: Arbitration Lost
+ * @arg CEC_IT_RXACKE: Rx-Missing Acknowledge
+ * @arg CEC_IT_LBPE: Rx Long period Error
+ * @arg CEC_IT_SBPE: Rx Short period Error
+ * @arg CEC_IT_BRE: Rx Bit Rising Error
+ * @arg CEC_IT_RXOVR: Rx Overrun
+ * @arg CEC_IT_RXEND: End Of Reception
+ * @arg CEC_IT_RXBR: Rx-Byte Received
+ * @retval None
+ */
+void CEC_ClearITPendingBit(uint16_t CEC_IT)
+{
+ assert_param(IS_CEC_IT(CEC_IT));
+
+ /* Clear the selected CEC interrupt pending bits */
+ CEC->ISR = CEC_IT;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Libraries/STM32F37x_StdPeriph_Driver/src/stm32f37x_comp.c b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Libraries/STM32F37x_StdPeriph_Driver/src/stm32f37x_comp.c
new file mode 100644
index 0000000..5360729
--- /dev/null
+++ b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Libraries/STM32F37x_StdPeriph_Driver/src/stm32f37x_comp.c
@@ -0,0 +1,407 @@
+/**
+ ******************************************************************************
+ * @file stm32f37x_comp.c
+ * @author MCD Application Team
+ * @version V1.0.0
+ * @date 20-September-2012
+ * @brief This file provides firmware functions to manage the following
+ * functionalities of the comparators (COMP1 and COMP2) peripheral:
+ * + Comparators configuration
+ * + Window mode control
+ *
+ * @verbatim
+ *
+ ===============================================================================
+ ##### How to use this driver #####
+ ===============================================================================
+ [..]
+ The device integrates two analog comparators COMP1 and COMP2:
+
+ (+) The non inverting input is set to PA1 for COMP1 and to PA3
+ for COMP2.
+
+ (+) The inverting input can be selected among: DAC_OUT1,
+ 1/4 VREFINT, 1/2 VERFINT, 3/4 VREFINT, VREFINT,
+ I/O (PA0 for COMP1 and PA2 for COMP2)
+
+ (+) The COMP output is internally is available using COMP_GetOutputLevel()
+ and can be set on GPIO pins: PA0, PA6, PA11 for COMP1
+ and PA2, PA7, PA12 for COMP2
+
+ (+) The COMP output can be redirected to embedded timers (TIM1, TIM2
+ and TIM3)
+
+ (+) The two comparators COMP1 and COMP2 can be combined in window
+ mode and only COMP1 non inverting (PA1) can be used as non-
+ inverting input.
+
+ (+) The two comparators COMP1 and COMP2 have interrupt capability
+ with wake-up from Sleep and Stop modes (through the EXTI controller).
+ COMP1 and COMP2 outputs are internally connected to EXTI Line 21
+ and EXTI Line 22 respectively.
+
+
+ ##### How to configure the comparator #####
+ ===============================================================================
+ [..]
+ This driver provides functions to configure and program the Comparators
+ of all STM32F37x devices.
+
+ [..] To use the comparator, perform the following steps:
+
+ (#) Enable the SYSCFG APB clock to get write access to comparator
+ register using RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
+
+ (#) Configure the comparator input in analog mode using GPIO_Init()
+
+ (#) Configure the comparator output in alternate function mode
+ using GPIO_Init() and use GPIO_PinAFConfig() function to map the
+ comparator output to the GPIO pin
+
+ (#) Configure the comparator using COMP_Init() function:
+ (++) Select the inverting input
+ (++) Select the output polarity
+ (++) Select the output redirection
+ (++) Select the hysteresis level
+ (++) Select the power mode
+
+ (#) Enable the comparator using COMP_Cmd() function
+
+ (#) If required enable the COMP interrupt by configuring and enabling
+ EXTI line in Interrupt mode and selecting the desired sensitivity
+ level using EXTI_Init() function. After that enable the comparator
+ interrupt vector using NVIC_Init() function.
+
+ @endverbatim
+ *
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
+ *
+ * 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 "stm32f37x_comp.h"
+
+/** @addtogroup STM32F37x_StdPeriph_Driver
+ * @{
+ */
+
+/** @defgroup COMP
+ * @brief COMP driver modules
+ * @{
+ */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* CSR register Mask */
+#define COMP_CSR_CLEAR_MASK ((uint32_t)0x00003FFE)
+
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+/** @defgroup COMP_Private_Functions
+ * @{
+ */
+
+/** @defgroup COMP_Group1 Initialization and Configuration functions
+ * @brief Initialization and Configuration functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Initialization and Configuration functions #####
+ ===============================================================================
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Deinitializes COMP peripheral registers to their default reset values.
+ * @note Deinitialization can't be performed if the COMP configuration is locked.
+ * To unlock the configuration, perform a system reset.
+ * @param None
+ * @retval None
+ */
+void COMP_DeInit(void)
+{
+ COMP->CSR = ((uint32_t)0x00000000); /*!< Set COMP_CSR register to reset value */
+}
+
+/**
+ * @brief Initializes the COMP peripheral according to the specified parameters
+ * in COMP_InitStruct
+ * @note If the selected comparator is locked, initialization can't be performed.
+ * To unlock the configuration, perform a system reset.
+ * @note By default, PA1 is selected as COMP1 non inverting input.
+ * To use PA4 as COMP1 non inverting input call COMP_SwitchCmd() after COMP_Init()
+ * @param COMP_Selection: the selected comparator.
+ * This parameter can be one of the following values:
+ * @arg COMP_Selection_COMP1: COMP1 selected
+ * @arg COMP_Selection_COMP2: COMP2 selected
+ * @param COMP_InitStruct: pointer to an COMP_InitTypeDef structure that contains
+ * the configuration information for the specified COMP peripheral.
+ * @retval None
+ */
+void COMP_Init(uint32_t COMP_Selection, COMP_InitTypeDef* COMP_InitStruct)
+{
+ uint32_t tmpreg = 0;
+
+ /* Check the parameters */
+ assert_param(IS_COMP_ALL_PERIPH(COMP_Selection));
+ assert_param(IS_COMP_INVERTING_INPUT(COMP_InitStruct->COMP_InvertingInput));
+ assert_param(IS_COMP_OUTPUT(COMP_InitStruct->COMP_Output));
+ assert_param(IS_COMP_OUTPUT_POL(COMP_InitStruct->COMP_OutputPol));
+ assert_param(IS_COMP_HYSTERESIS(COMP_InitStruct->COMP_Hysteresis));
+ assert_param(IS_COMP_MODE(COMP_InitStruct->COMP_Mode));
+
+ /*!< Get the COMP_CSR register value */
+ tmpreg = COMP->CSR;
+
+ /*!< Clear the COMP1SW1, COMPx_IN_SEL, COMPx_OUT_TIM_SEL, COMPx_POL, COMPx_HYST and COMPx_PWR_MODE bits */
+ tmpreg &= (uint32_t) ~(COMP_CSR_CLEAR_MASK<<COMP_Selection);
+
+ /*!< Configure COMP: inverting input, output redirection, hysteresis value and power mode */
+ /*!< Set COMPxINSEL bits according to COMP_InitStruct->COMP_InvertingInput value */
+ /*!< Set COMPxOUTSEL bits according to COMP_InitStruct->COMP_Output value */
+ /*!< Set COMPxPOL bit according to COMP_InitStruct->COMP_OutputPol value */
+ /*!< Set COMPxHYST bits according to COMP_InitStruct->COMP_Hysteresis value */
+ /*!< Set COMPxMODE bits according to COMP_InitStruct->COMP_Mode value */
+ tmpreg |= (uint32_t)((COMP_InitStruct->COMP_InvertingInput | COMP_InitStruct->COMP_Output |
+ COMP_InitStruct->COMP_OutputPol | COMP_InitStruct->COMP_Hysteresis |
+ COMP_InitStruct->COMP_Mode)<<COMP_Selection);
+
+ /*!< Write to COMP_CSR register */
+ COMP->CSR = tmpreg;
+}
+
+/**
+ * @brief Fills each COMP_InitStruct member with its default value.
+ * @param COMP_InitStruct: pointer to an COMP_InitTypeDef structure which will
+ * be initialized.
+ * @retval None
+ */
+void COMP_StructInit(COMP_InitTypeDef* COMP_InitStruct)
+{
+ COMP_InitStruct->COMP_InvertingInput = COMP_InvertingInput_1_4VREFINT;
+ COMP_InitStruct->COMP_Output = COMP_Output_None;
+ COMP_InitStruct->COMP_OutputPol = COMP_OutputPol_NonInverted;
+ COMP_InitStruct->COMP_Hysteresis = COMP_Hysteresis_No;
+ COMP_InitStruct->COMP_Mode = COMP_Mode_UltraLowPower;
+}
+
+/**
+ * @brief Enable or disable the COMP peripheral.
+ * @note If the selected comparator is locked, enable/disable can't be performed.
+ * To unlock the configuration, perform a system reset.
+ * @param COMP_Selection: the selected comparator.
+ * This parameter can be one of the following values:
+ * @arg COMP_Selection_COMP1: COMP1 selected
+ * @arg COMP_Selection_COMP2: COMP2 selected
+ * @param NewState: new state of the COMP peripheral.
+ * This parameter can be: ENABLE or DISABLE.
+ * @note When enabled, the comparator compares the non inverting input with
+ * the inverting input and the comparison result is available on comparator output.
+ * @note When disabled, the comparator doesn't perform comparison and the
+ * output level is low.
+ * @retval None
+ */
+void COMP_Cmd(uint32_t COMP_Selection, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_COMP_ALL_PERIPH(COMP_Selection));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the selected COMP peripheral */
+ COMP->CSR |= (uint32_t) (1<<COMP_Selection);
+ }
+ else
+ {
+ /* Disable the selected COMP peripheral */
+ COMP->CSR &= (uint32_t)(~((uint32_t)1<<COMP_Selection));
+ }
+}
+
+/**
+ * @brief Close or Open the SW1 switch.
+ * @note This switch is solely intended to redirect signals onto high
+ * impedance input, such as COMP1 non-inverting input (highly resistive switch)
+ * @param NewState: New state of the analog switch.
+ * This parameter can be: ENABLE or DISABLE.
+ * @note When enabled, the SW1 is closed; PA1 is connected to PA4
+ * @note When disabled, the SW1 switch is open; PA1 is disconnected from PA4
+ * @retval None
+ */
+void COMP_SwitchCmd(FunctionalState NewState)
+{
+ /* Check the parameter */
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Close SW1 switch */
+ COMP->CSR |= (uint32_t) (COMP_CSR_COMP1SW1);
+ }
+ else
+ {
+ /* Open SW1 switch */
+ COMP->CSR &= (uint32_t)(~COMP_CSR_COMP1SW1);
+ }
+}
+
+/**
+ * @brief Return the output level (high or low) of the selected comparator.
+ * @note The output level depends on the selected polarity.
+ * @note If the polarity is not inverted:
+ * - Comparator output is low when the non-inverting input is at a lower
+ * voltage than the inverting input
+ * - Comparator output is high when the non-inverting input is at a higher
+ * voltage than the inverting input
+ * @note If the polarity is inverted:
+ * - Comparator output is high when the non-inverting input is at a lower
+ * voltage than the inverting input
+ * - Comparator output is low when the non-inverting input is at a higher
+ * voltage than the inverting input
+ * @param COMP_Selection: the selected comparator.
+ * This parameter can be one of the following values:
+ * @arg COMP_Selection_COMP1: COMP1 selected
+ * @arg COMP_Selection_COMP2: COMP2 selected
+ * @retval Returns the selected comparator output level: low or high.
+ *
+ */
+uint32_t COMP_GetOutputLevel(uint32_t COMP_Selection)
+{
+ uint32_t compout = 0x0;
+
+ /* Check the parameters */
+ assert_param(IS_COMP_ALL_PERIPH(COMP_Selection));
+
+ /* Check if selected comparator output is high */
+ if ((COMP->CSR & (COMP_CSR_COMP1OUT<<COMP_Selection)) != 0)
+ {
+ compout = COMP_OutputLevel_High;
+ }
+ else
+ {
+ compout = COMP_OutputLevel_Low;
+ }
+
+ /* Return the comparator output level */
+ return (uint32_t)(compout);
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup COMP_Group2 Window mode control function
+ * @brief Window mode control function
+ *
+@verbatim
+ ===============================================================================
+ ##### Window mode control function #####
+ ===============================================================================
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Enables or disables the window mode.
+ * @note In window mode, COMP1 and COMP2 non inverting inputs are connected
+ * together and only COMP1 non inverting input (PA1) can be used.
+ * @param NewState: new state of the window mode.
+ * This parameter can be :
+ * @arg ENABLE: COMP1 and COMP2 non inverting inputs are connected together.
+ * @arg DISABLE: OMP1 and COMP2 non inverting inputs are disconnected.
+ * @retval None
+ */
+void COMP_WindowCmd(FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the window mode */
+ COMP->CSR |= (uint32_t) COMP_CSR_WNDWEN;
+ }
+ else
+ {
+ /* Disable the window mode */
+ COMP->CSR &= (uint32_t)(~COMP_CSR_WNDWEN);
+ }
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup COMP_Group3 COMP configuration locking function
+ * @brief COMP1 and COMP2 configuration locking function
+ * COMP1 and COMP2 configuration can be locked each separately.
+ * Unlocking is performed by system reset.
+ *
+@verbatim
+ ===============================================================================
+ ##### Configuration Lock function #####
+ ===============================================================================
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Lock the selected comparator (COMP1/COMP2) configuration.
+ * @note Locking the configuration means that all control bits are read-only.
+ * To unlock the comparator configuration, perform a system reset.
+ * @param COMP_Selection: selects the comparator to be locked
+ * This parameter can be a value of the following values:
+ * @arg COMP_Selection_COMP1: COMP1 configuration is locked.
+ * @arg COMP_Selection_COMP2: COMP2 configuration is locked.
+ * @retval None
+ */
+void COMP_LockConfig(uint32_t COMP_Selection)
+{
+ /* Check the parameter */
+ assert_param(IS_COMP_ALL_PERIPH(COMP_Selection));
+
+ /* Set the lock bit corresponding to selected comparator */
+ COMP->CSR |= (uint32_t) (COMP_CSR_COMP1LOCK<<COMP_Selection);
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Libraries/STM32F37x_StdPeriph_Driver/src/stm32f37x_dac.c b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Libraries/STM32F37x_StdPeriph_Driver/src/stm32f37x_dac.c
new file mode 100644
index 0000000..1563055
--- /dev/null
+++ b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Libraries/STM32F37x_StdPeriph_Driver/src/stm32f37x_dac.c
@@ -0,0 +1,746 @@
+/**
+ ******************************************************************************
+ * @file stm32f37x_dac.c
+ * @author MCD Application Team
+ * @version V1.0.0
+ * @date 20-September-2012
+ * @brief This file provides firmware functions to manage the following
+ * functionalities of the Digital-to-Analog Converter (DAC) peripheral:
+ * + DAC channels configuration: trigger, output buffer, data format
+ * + DMA management
+ * + Interrupts and flags management
+
+ * @verbatim
+ *
+ ===============================================================================
+ ##### DAC Peripheral features #####
+ ===============================================================================
+ [..] The device integrates three 12-bit Digital Analog Converters:
+ (#) DAC1 integrates two DAC channels:
+ (++) DAC1 channel 1 with DAC1_OUT1 as output
+ (++) DAC1 channel 2 with DAC1_OUT2 as output
+ (++) The two channels can be used independently or simultaneously (dual mode)
+
+ (#) DAC2 integrates only one channel DAC2 channel 1 with DAC2_OUT1 as output
+
+ [..] The Digital to Analog conversion can be non-triggered using DAC_Trigger_None
+ and DACx_OUTy is available once writing to DHRx register using
+ DAC_SetChannel1Data()/DAC_SetChannel2Data.
+
+ [..] Digital to Analog conversion can be triggered by:
+ (#) External event: EXTI Line 9 (any GPIOx_Pin9) using DAC_Trigger_Ext_IT9.
+ The used pin (GPIOx_Pin9) must be configured in input mode.
+
+ (#) Timers TRGO: TIM2, TIM3, TIM4, TIM5, TIM6, TIM7 and TIM18
+ (DAC_Trigger_T2_TRGO, DAC_Trigger_T4_TRGO...)
+ The timer TRGO event should be selected using TIM_SelectOutputTrigger()
+ (++) TIM5 is applicable only for DAC1
+ (++) TIM18 is applicable only for DAC2
+
+ (#) Software using DAC_Trigger_Software
+
+ [..] Each DAC channel integrates an output buffer that can be used to
+ reduce the output impedance, and to drive external loads directly
+ without having to add an external operational amplifier.
+ To enable, the output buffer use
+ DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Enable;
+ before caliing DAC_Init() function
+
+ [..] Refer to the device datasheet for more details about output impedance
+ value with and without output buffer.
+
+ [..] Both DAC1 channels can be used to generate
+ (#) Noise wave using DAC_WaveGeneration_Noise
+ (#) Triangle wave using DAC_WaveGeneration_Triangle
+
+ [..] Wave generation can be disabled using DAC_WaveGeneration_None
+
+ [..] The DAC data format can be:
+ (#) 8-bit right alignment using DAC_Align_8b_R
+ (#) 12-bit left alignment using DAC_Align_12b_L
+ (#) 12-bit right alignment using DAC_Align_12b_R
+
+ [..] The analog output voltage on each DAC channel pin is determined
+ by the following equation: DAC_OUTx = VREF+ * DOR / 4095
+ with DOR is the Data Output Register
+ VEF+ is the input voltage reference (refer to the device datasheet)
+ e.g. To set DAC_OUT1 to 0.7V, use
+ DAC_SetChannel1Data(DAC_Align_12b_R, 868);
+ Assuming that VREF+ = 3.3, DAC_OUT1 = (3.3 * 868) / 4095 = 0.7V
+
+ [..] A DMA1 request can be generated when an external trigger (but not
+ a software trigger) occurs if DMA1 requests are enabled using
+ DAC_DMACmd()
+ DMA1 requests are mapped as following:
+ (+) DAC channel1 is mapped on DMA1 channel3 which must be already
+ configured
+ (+) DAC channel2 is mapped on DMA1 channel4 which must be already
+ configured
+
+ ##### How to use this driver #####
+ ===============================================================================
+ [..]
+ (+) Enable DAC APB1 clock to get write access to DAC registers
+ using RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE)
+
+ (+) Configure DACx_OUTy (DAC1_OUT1: PA4, DAC1_OUT2: PA5, DAC2_OUT1: PA6)
+ in analog mode.
+
+ (+) Configure the DAC channel using DAC_Init()
+
+ (+) Enable the DAC channel using DAC_Cmd()
+
+ @endverbatim
+ *
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
+ *
+ * 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 "stm32f37x_dac.h"
+#include "stm32f37x_rcc.h"
+
+/** @addtogroup STM32F37x_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(DAC_TypeDef* DACx)
+{
+ /* Check the parameters */
+ assert_param(IS_DAC_ALL_PERIPH(DACx));
+
+ if (DACx == DAC1)
+ {
+ /* Enable DAC1 reset state */
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_DAC1, ENABLE);
+ /* Release DAC1 from reset state */
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_DAC1, DISABLE);
+ }
+ else
+ {
+ /* Enable DAC2 reset state */
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_DAC2, ENABLE);
+ /* Release DAC2 from reset state */
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_DAC2, DISABLE);
+ }
+}
+
+/**
+ * @brief Initializes the DAC peripheral according to the specified
+ * parameters in the DAC_InitStruct.
+ * @param DACx: where x can be 1 or 2 to select the DAC peripheral.
+ * @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(DAC_TypeDef* DACx, uint32_t DAC_Channel, DAC_InitTypeDef* DAC_InitStruct)
+{
+ uint32_t tmpreg1 = 0, tmpreg2 = 0;
+
+ /* Check the DAC parameters */
+ assert_param(IS_DAC_ALL_PERIPH(DACx));
+ 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 = DACx->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 */
+ DACx->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 DACx: where x can be 1 or 2 to select the DAC peripheral.
+ * @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(DAC_TypeDef* DACx, uint32_t DAC_Channel, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_DAC_ALL_PERIPH(DACx));
+ assert_param(IS_DAC_CHANNEL(DAC_Channel));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the selected DAC channel */
+ DACx->CR |= (DAC_CR_EN1 << DAC_Channel);
+ }
+ else
+ {
+ /* Disable the selected DAC channel */
+ DACx->CR &= (~(DAC_CR_EN1 << DAC_Channel));
+ }
+}
+
+/**
+ * @brief Enables or disables the selected DAC channel software trigger.
+ * @param DACx: where x can be 1 or 2 to select the DAC peripheral.
+ * @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(DAC_TypeDef* DACx, uint32_t DAC_Channel, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_DAC_ALL_PERIPH(DACx));
+ assert_param(IS_DAC_CHANNEL(DAC_Channel));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable software trigger for the selected DAC channel */
+ DACx->SWTRIGR |= (uint32_t)DAC_SWTRIGR_SWTRIG1 << (DAC_Channel >> 4);
+ }
+ else
+ {
+ /* Disable software trigger for the selected DAC channel */
+ DACx->SWTRIGR &= ~((uint32_t)DAC_SWTRIGR_SWTRIG1 << (DAC_Channel >> 4));
+ }
+}
+
+/**
+ * @brief Enables or disables simultaneously the two DAC channels software
+ * triggers.
+ * @param DACx: where x can be 1 to select the DAC1 peripheral.
+ * @note Dual trigger is not applicable for DAC2 (DAC2 integrates one channel).
+ * @param NewState: new state of the DAC channels software triggers.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void DAC_DualSoftwareTriggerCmd(DAC_TypeDef* DACx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_DAC_LIST1_PERIPH(DACx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable software trigger for both DAC channels */
+ DACx->SWTRIGR |= DUAL_SWTRIG_SET;
+ }
+ else
+ {
+ /* Disable software trigger for both DAC channels */
+ DACx->SWTRIGR &= DUAL_SWTRIG_RESET;
+ }
+}
+
+/**
+ * @brief Enables or disables the selected DAC channel wave generation.
+ * @param DACx: where x can be 1 to select the DAC1 peripheral.
+ * @note Wave generation is not available in DAC2.
+ * @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.
+ * @note
+ * @retval None
+ */
+void DAC_WaveGenerationCmd(DAC_TypeDef* DACx, uint32_t DAC_Channel, uint32_t DAC_Wave, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_DAC_LIST1_PERIPH(DACx));
+ 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 */
+ DACx->CR |= DAC_Wave << DAC_Channel;
+ }
+ else
+ {
+ /* Disable the selected wave generation for the selected DAC channel */
+ DACx->CR &= ~(DAC_Wave << DAC_Channel);
+ }
+}
+
+/**
+ * @brief Set the specified data holding register value for DAC channel1.
+ * @param DACx: where x can be 1 or 2 to select the DAC peripheral.
+ * @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(DAC_TypeDef* DACx, uint32_t DAC_Align, uint16_t Data)
+{
+ __IO uint32_t tmp = 0;
+
+ /* Check the parameters */
+ assert_param(IS_DAC_ALL_PERIPH(DACx));
+ assert_param(IS_DAC_ALIGN(DAC_Align));
+ assert_param(IS_DAC_DATA(Data));
+
+ tmp = (uint32_t)DACx;
+ 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 DACx: where x can be 1 to select the DAC peripheral.
+ * @note This function is available only for DAC1.
+ * @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(DAC_TypeDef* DACx, uint32_t DAC_Align, uint16_t Data)
+{
+ __IO uint32_t tmp = 0;
+
+ /* Check the parameters */
+ assert_param(IS_DAC_LIST1_PERIPH(DACx));
+ assert_param(IS_DAC_ALIGN(DAC_Align));
+ assert_param(IS_DAC_DATA(Data));
+
+ tmp = (uint32_t)DACx;
+ 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 DACx: where x can be 1 to select the DAC peripheral.
+ * @note This function isn't applicable for DAC2.
+ * @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(DAC_TypeDef* DACx, uint32_t DAC_Align, uint16_t Data2, uint16_t Data1)
+{
+ uint32_t data = 0, tmp = 0;
+
+ /* Check the parameters */
+ assert_param(IS_DAC_LIST1_PERIPH(DACx));
+ 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)DACx;
+ 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 DACx: where x can be 1 or 2 to select the DAC peripheral.
+ * @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(DAC_TypeDef* DACx, uint32_t DAC_Channel)
+{
+ __IO uint32_t tmp = 0;
+
+ /* Check the parameters */
+ assert_param(IS_DAC_ALL_PERIPH(DACx));
+ assert_param(IS_DAC_CHANNEL(DAC_Channel));
+
+ tmp = (uint32_t) DACx;
+ 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.
+ * When enabled DMA1 is generated when an external trigger (EXTI Line9,
+ * TIM2, TIM4, TIM6, TIM7 or TIM9 but not a software trigger) occurs
+ * @param DACx: where x can be 1 or 2 to select the DAC peripheral.
+ * @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 (channel2) is mapped on DMA1 channel3 (channel4) which
+ * must be already configured.
+ * @retval None
+ */
+void DAC_DMACmd(DAC_TypeDef* DACx, uint32_t DAC_Channel, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_DAC_ALL_PERIPH(DACx));
+ assert_param(IS_DAC_CHANNEL(DAC_Channel));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the selected DAC channel DMA request */
+ DACx->CR |= (DAC_CR_DMAEN1 << DAC_Channel);
+ }
+ else
+ {
+ /* Disable the selected DAC channel DMA request */
+ DACx->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 DACx: where x can be 1 or 2 to select the DAC peripheral.
+ * @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:
+ * @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(DAC_TypeDef* DACx, uint32_t DAC_Channel, uint32_t DAC_IT, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_DAC_ALL_PERIPH(DACx));
+ 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 */
+ DACx->CR |= (DAC_IT << DAC_Channel);
+ }
+ else
+ {
+ /* Disable the selected DAC interrupts */
+ DACx->CR &= (~(uint32_t)(DAC_IT << DAC_Channel));
+ }
+}
+
+/**
+ * @brief Checks whether the specified DAC flag is set or not.
+ * @param DACx: where x can be 1 or 2 to select the DAC peripheral.
+ * @param DAC_Channel: thee 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:
+ * @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(DAC_TypeDef* DACx, uint32_t DAC_Channel, uint32_t DAC_FLAG)
+{
+ FlagStatus bitstatus = RESET;
+
+ /* Check the parameters */
+ assert_param(IS_DAC_ALL_PERIPH(DACx));
+ assert_param(IS_DAC_CHANNEL(DAC_Channel));
+ assert_param(IS_DAC_FLAG(DAC_FLAG));
+
+ /* Check the status of the specified DAC flag */
+ if ((DACx->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 DACx: where x can be 1 or 2 to select the DAC peripheral.
+ * @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:
+ * @arg DAC_FLAG_DMAUDR: DMA underrun flag
+ * @retval None
+ */
+void DAC_ClearFlag(DAC_TypeDef* DACx, uint32_t DAC_Channel, uint32_t DAC_FLAG)
+{
+ /* Check the parameters */
+ assert_param(IS_DAC_ALL_PERIPH(DACx));
+ assert_param(IS_DAC_CHANNEL(DAC_Channel));
+ assert_param(IS_DAC_FLAG(DAC_FLAG));
+
+ /* Clear the selected DAC flags */
+ DACx->SR = (DAC_FLAG << DAC_Channel);
+}
+
+/**
+ * @brief Checks whether the specified DAC interrupt has occurred or not.
+ * @param DACx: where x can be 1 or 2 to select the DAC peripheral.
+ * @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:
+ * @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(DAC_TypeDef* DACx, uint32_t DAC_Channel, uint32_t DAC_IT)
+{
+ ITStatus bitstatus = RESET;
+ uint32_t enablestatus = 0;
+
+ /* Check the parameters */
+ assert_param(IS_DAC_ALL_PERIPH(DACx));
+ assert_param(IS_DAC_CHANNEL(DAC_Channel));
+ assert_param(IS_DAC_IT(DAC_IT));
+
+ /* Get the DAC_IT enable bit status */
+ enablestatus = (DACx->CR & (DAC_IT << DAC_Channel)) ;
+
+ /* Check the status of the specified DAC interrupt */
+ if (((DACx->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 DACx: where x can be 1 or 2 to select the DAC peripheral.
+ * @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
+ * @retval None
+ */
+void DAC_ClearITPendingBit(DAC_TypeDef* DACx, uint32_t DAC_Channel, uint32_t DAC_IT)
+{
+ /* Check the parameters */
+ assert_param(IS_DAC_ALL_PERIPH(DACx));
+ assert_param(IS_DAC_CHANNEL(DAC_Channel));
+ assert_param(IS_DAC_IT(DAC_IT));
+
+ /* Clear the selected DAC interrupt pending bits */
+ DACx->SR = (DAC_IT << DAC_Channel);
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Libraries/STM32F37x_StdPeriph_Driver/src/stm32f37x_dma.c b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Libraries/STM32F37x_StdPeriph_Driver/src/stm32f37x_dma.c
new file mode 100644
index 0000000..911745e
--- /dev/null
+++ b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Libraries/STM32F37x_StdPeriph_Driver/src/stm32f37x_dma.c
@@ -0,0 +1,858 @@
+/**
+ ******************************************************************************
+ * @file stm32f37x_dma.c
+ * @author MCD Application Team
+ * @version V1.0.0
+ * @date 20-September-2012
+ * @brief This file provides firmware functions to manage the following
+ * functionalities of the Direct Memory Access controller (DMA):
+ * + Initialization and Configuration
+ * + Data Counter
+ * + Interrupts and flags management
+ *
+ * @verbatim
+ ==============================================================================
+ ##### How to use this driver #####
+ ==============================================================================
+ [..]
+ (#) Enable The DMA controller clock using
+ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE) function for DMA1 or
+ using RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE) function for DMA2.
+ (#) Enable and configure the peripheral to be connected to the DMA channel
+ (except for internal SRAM / FLASH memories: no initialization is necessary).
+ (#) For a given Channel, program the Source and Destination addresses,
+ the transfer Direction, the Buffer Size, the Peripheral and Memory
+ Incrementation mode and Data Size, the Circular or Normal mode,
+ the channel transfer Priority and the Memory-to-Memory transfer
+ mode (if needed) using the DMA_Init() function.
+ (#) Enable the NVIC and the corresponding interrupt(s) using the function
+ DMA_ITConfig() if you need to use DMA interrupts.
+ (#) Enable the DMA channel using the DMA_Cmd() function.
+ (#) Activate the needed channel 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).
+ (#) Optionally, you can configure the number of data to be transferred
+ when the channel 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 channel is
+ enabled and running).
+ (#) To control DMA events you can use one of the following two methods:
+ (##) Check on DMA channel flags using the function DMA_GetFlagStatus().
+ (##) 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.
+ @endverbatim
+ *
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
+ *
+ * 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 "stm32f37x_dma.h"
+
+/** @addtogroup STM32F37x_StdPeriph_Driver
+ * @{
+ */
+
+/** @defgroup DMA
+ * @brief DMA driver modules
+ * @{
+ */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+#define CCR_CLEAR_MASK ((uint32_t)0xFFFF800F) /* DMA Channel config registers Masks */
+#define FLAG_Mask ((uint32_t)0x10000000) /* DMA2 FLAG mask */
+
+
+/* DMA1 Channelx interrupt pending bit masks */
+#define DMA1_CHANNEL1_IT_MASK ((uint32_t)(DMA_ISR_GIF1 | DMA_ISR_TCIF1 | DMA_ISR_HTIF1 | DMA_ISR_TEIF1))
+#define DMA1_CHANNEL2_IT_MASK ((uint32_t)(DMA_ISR_GIF2 | DMA_ISR_TCIF2 | DMA_ISR_HTIF2 | DMA_ISR_TEIF2))
+#define DMA1_CHANNEL3_IT_MASK ((uint32_t)(DMA_ISR_GIF3 | DMA_ISR_TCIF3 | DMA_ISR_HTIF3 | DMA_ISR_TEIF3))
+#define DMA1_CHANNEL4_IT_MASK ((uint32_t)(DMA_ISR_GIF4 | DMA_ISR_TCIF4 | DMA_ISR_HTIF4 | DMA_ISR_TEIF4))
+#define DMA1_CHANNEL5_IT_MASK ((uint32_t)(DMA_ISR_GIF5 | DMA_ISR_TCIF5 | DMA_ISR_HTIF5 | DMA_ISR_TEIF5))
+#define DMA1_CHANNEL6_IT_MASK ((uint32_t)(DMA_ISR_GIF6 | DMA_ISR_TCIF6 | DMA_ISR_HTIF6 | DMA_ISR_TEIF6))
+#define DMA1_CHANNEL7_IT_MASK ((uint32_t)(DMA_ISR_GIF7 | DMA_ISR_TCIF7 | DMA_ISR_HTIF7 | DMA_ISR_TEIF7))
+
+/* DMA2 Channelx interrupt pending bit masks */
+#define DMA2_CHANNEL1_IT_MASK ((uint32_t)(DMA_ISR_GIF1 | DMA_ISR_TCIF1 | DMA_ISR_HTIF1 | DMA_ISR_TEIF1))
+#define DMA2_CHANNEL2_IT_MASK ((uint32_t)(DMA_ISR_GIF2 | DMA_ISR_TCIF2 | DMA_ISR_HTIF2 | DMA_ISR_TEIF2))
+#define DMA2_CHANNEL3_IT_MASK ((uint32_t)(DMA_ISR_GIF3 | DMA_ISR_TCIF3 | DMA_ISR_HTIF3 | DMA_ISR_TEIF3))
+#define DMA2_CHANNEL4_IT_MASK ((uint32_t)(DMA_ISR_GIF4 | DMA_ISR_TCIF4 | DMA_ISR_HTIF4 | DMA_ISR_TEIF4))
+#define DMA2_CHANNEL5_IT_MASK ((uint32_t)(DMA_ISR_GIF5 | DMA_ISR_TCIF5 | DMA_ISR_HTIF5 | DMA_ISR_TEIF5))
+
+/* 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 channel
+ source and destination addresses, incrementation and data sizes, transfer
+ direction, buffer size, circular/normal mode selection, memory-to-memory
+ mode selection and channel priority value.
+ [..] The DMA_Init() function follows the DMA configuration procedures as described
+ in reference manual (RM0313).
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Deinitializes the DMAy Channelx registers to their default reset
+ * values.
+ * @param DMAy_Channelx: where y can be 1 or 2 to select the DMA and
+ * x can be 1 to 7 for DMA1 and 1 to 5 for DMA2 to select the DMA Channel.
+ * @retval None
+ */
+void DMA_DeInit(DMA_Channel_TypeDef* DMAy_Channelx)
+{
+ /* Check the parameters */
+ assert_param(IS_DMA_ALL_PERIPH(DMAy_Channelx));
+
+ /* Disable the selected DMAy Channelx */
+ DMAy_Channelx->CCR &= (uint16_t)(~DMA_CCR_EN);
+
+ /* Reset DMAy Channelx control register */
+ DMAy_Channelx->CCR = 0;
+
+ /* Reset DMAy Channelx remaining bytes register */
+ DMAy_Channelx->CNDTR = 0;
+
+ /* Reset DMAy Channelx peripheral address register */
+ DMAy_Channelx->CPAR = 0;
+
+ /* Reset DMAy Channelx memory address register */
+ DMAy_Channelx->CMAR = 0;
+
+ if (DMAy_Channelx == DMA1_Channel1)
+ {
+ /* Reset interrupt pending bits for DMA1 Channel1 */
+ DMA1->IFCR |= DMA1_CHANNEL1_IT_MASK;
+ }
+ else if (DMAy_Channelx == DMA1_Channel2)
+ {
+ /* Reset interrupt pending bits for DMA1 Channel2 */
+ DMA1->IFCR |= DMA1_CHANNEL2_IT_MASK;
+ }
+ else if (DMAy_Channelx == DMA1_Channel3)
+ {
+ /* Reset interrupt pending bits for DMA1 Channel3 */
+ DMA1->IFCR |= DMA1_CHANNEL3_IT_MASK;
+ }
+ else if (DMAy_Channelx == DMA1_Channel4)
+ {
+ /* Reset interrupt pending bits for DMA1 Channel4 */
+ DMA1->IFCR |= DMA1_CHANNEL4_IT_MASK;
+ }
+ else if (DMAy_Channelx == DMA1_Channel5)
+ {
+ /* Reset interrupt pending bits for DMA1 Channel5 */
+ DMA1->IFCR |= DMA1_CHANNEL5_IT_MASK;
+ }
+ else if (DMAy_Channelx == DMA1_Channel6)
+ {
+ /* Reset interrupt pending bits for DMA1 Channel6 */
+ DMA1->IFCR |= DMA1_CHANNEL6_IT_MASK;
+ }
+ else if (DMAy_Channelx == DMA1_Channel7)
+ {
+ /* Reset interrupt pending bits for DMA1 Channel7 */
+ DMA1->IFCR |= DMA1_CHANNEL7_IT_MASK;
+ }
+ else if (DMAy_Channelx == DMA2_Channel1)
+ {
+ /* Reset interrupt pending bits for DMA2 Channel1 */
+ DMA2->IFCR |= DMA2_CHANNEL1_IT_MASK;
+ }
+ else if (DMAy_Channelx == DMA2_Channel2)
+ {
+ /* Reset interrupt pending bits for DMA2 Channel2 */
+ DMA2->IFCR |= DMA2_CHANNEL2_IT_MASK;
+ }
+ else if (DMAy_Channelx == DMA2_Channel3)
+ {
+ /* Reset interrupt pending bits for DMA2 Channel3 */
+ DMA2->IFCR |= DMA2_CHANNEL3_IT_MASK;
+ }
+ else if (DMAy_Channelx == DMA2_Channel4)
+ {
+ /* Reset interrupt pending bits for DMA2 Channel4 */
+ DMA2->IFCR |= DMA2_CHANNEL4_IT_MASK;
+ }
+ else
+ {
+ if (DMAy_Channelx == DMA2_Channel5)
+ {
+ /* Reset interrupt pending bits for DMA2 Channel5 */
+ DMA2->IFCR |= DMA2_CHANNEL5_IT_MASK;
+ }
+ }
+}
+
+/**
+ * @brief Initializes the DMAy Channelx according to the specified parameters
+ * in the DMA_InitStruct.
+ * @param DMAy_Channelx: where y can be 1 or 2 to select the DMA and
+ * x can be 1 to 7 for DMA1 and 1 to 5 for DMA2 to select the DMA Channel.
+ * @param DMA_InitStruct: pointer to a DMA_InitTypeDef structure that contains
+ * the configuration information for the specified DMA Channel.
+ * @retval None
+ */
+void DMA_Init(DMA_Channel_TypeDef* DMAy_Channelx, DMA_InitTypeDef* DMA_InitStruct)
+{
+ uint32_t tmpreg = 0;
+
+ /* Check the parameters */
+ assert_param(IS_DMA_ALL_PERIPH(DMAy_Channelx));
+ assert_param(IS_DMA_DIR(DMA_InitStruct->DMA_DIR));
+ 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_M2M_STATE(DMA_InitStruct->DMA_M2M));
+
+/*--------------------------- DMAy Channelx CCR Configuration ----------------*/
+ /* Get the DMAy_Channelx CCR value */
+ tmpreg = DMAy_Channelx->CCR;
+
+ /* Clear MEM2MEM, PL, MSIZE, PSIZE, MINC, PINC, CIRC and DIR bits */
+ tmpreg &= CCR_CLEAR_MASK;
+
+ /* Configure DMAy Channelx: data transfer, data size, priority level and mode */
+ /* Set DIR bit according to DMA_DIR value */
+ /* Set CIRC bit according to DMA_Mode 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 PL bits according to DMA_Priority value */
+ /* Set the MEM2MEM bit according to DMA_M2M value */
+ tmpreg |= DMA_InitStruct->DMA_DIR | DMA_InitStruct->DMA_Mode |
+ DMA_InitStruct->DMA_PeripheralInc | DMA_InitStruct->DMA_MemoryInc |
+ DMA_InitStruct->DMA_PeripheralDataSize | DMA_InitStruct->DMA_MemoryDataSize |
+ DMA_InitStruct->DMA_Priority | DMA_InitStruct->DMA_M2M;
+
+ /* Write to DMAy Channelx CCR */
+ DMAy_Channelx->CCR = tmpreg;
+
+/*--------------------------- DMAy Channelx CNDTR Configuration --------------*/
+ /* Write to DMAy Channelx CNDTR */
+ DMAy_Channelx->CNDTR = DMA_InitStruct->DMA_BufferSize;
+
+/*--------------------------- DMAy Channelx CPAR Configuration ---------------*/
+ /* Write to DMAy Channelx CPAR */
+ DMAy_Channelx->CPAR = DMA_InitStruct->DMA_PeripheralBaseAddr;
+
+/*--------------------------- DMAy Channelx CMAR Configuration ---------------*/
+ /* Write to DMAy Channelx CMAR */
+ DMAy_Channelx->CMAR = DMA_InitStruct->DMA_MemoryBaseAddr;
+}
+
+/**
+ * @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_PeripheralBaseAddr member */
+ DMA_InitStruct->DMA_PeripheralBaseAddr = 0;
+ /* Initialize the DMA_MemoryBaseAddr member */
+ DMA_InitStruct->DMA_MemoryBaseAddr = 0;
+ /* Initialize the DMA_DIR member */
+ DMA_InitStruct->DMA_DIR = DMA_DIR_PeripheralSRC;
+ /* 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_M2M member */
+ DMA_InitStruct->DMA_M2M = DMA_M2M_Disable;
+}
+
+/**
+ * @brief Enables or disables the specified DMAy Channelx.
+ * @param DMAy_Channelx: where y can be 1 or 2 to select the DMA and
+ * x can be 1 to 7 for DMA1 and 1 to 5 for DMA2 to select the DMA Channel.
+ * @param NewState: new state of the DMAy Channelx.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void DMA_Cmd(DMA_Channel_TypeDef* DMAy_Channelx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_DMA_ALL_PERIPH(DMAy_Channelx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the selected DMAy Channelx */
+ DMAy_Channelx->CCR |= DMA_CCR_EN;
+ }
+ else
+ {
+ /* Disable the selected DMAy Channelx */
+ DMAy_Channelx->CCR &= (uint16_t)(~DMA_CCR_EN);
+ }
+}
+
+/**
+ * @}
+ */
+
+/** @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 channel is disabled (ie. after transfer complete event).
+ [..] The following function can be used to write the Channel data counter value:
+ (+) void DMA_SetCurrDataCounter(DMA_Channel_TypeDef* DMAy_Channelx, uint16_t
+ DataNumber).
+ -@- It is advised to use this function rather than DMA_Init() in situations
+ where only the Data buffer needs to be reloaded.
+ [..] The DMA data counter can be read to indicate the number of remaining transfers
+ for the relative DMA channel. 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 channel).
+ [..] The following function can be used to read the Channel data counter value:
+ (+) uint16_t DMA_GetCurrDataCounter(DMA_Channel_TypeDef* DMAy_Channelx).
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Sets the number of data units in the current DMAy Channelx transfer.
+ * @param DMAy_Channelx: where y can be 1 or 2 to select the DMA and
+ * x can be 1 to 7 for DMA1 and 1 to 5 for DMA2 to select the DMA Channel.
+ * @param DataNumber: The number of data units in the current DMAy Channelx
+ * transfer.
+ * @note This function can only be used when the DMAy_Channelx is disabled.
+ * @retval None
+ */
+void DMA_SetCurrDataCounter(DMA_Channel_TypeDef* DMAy_Channelx, uint16_t DataNumber)
+{
+ /* Check the parameters */
+ assert_param(IS_DMA_ALL_PERIPH(DMAy_Channelx));
+
+/*--------------------------- DMAy Channelx CNDTR Configuration --------------*/
+ /* Write to DMAy Channelx CNDTR */
+ DMAy_Channelx->CNDTR = DataNumber;
+}
+
+/**
+ * @brief Returns the number of remaining data units in the current
+ * DMAy Channelx transfer.
+ * @param DMAy_Channelx: where y can be 1 or 2 to select the DMA and
+ * x can be 1 to 7 for DMA1 and 1 to 5 for DMA2 to select the DMA Channel.
+ * @retval The number of remaining data units in the current DMAy Channelx
+ * transfer.
+ */
+uint16_t DMA_GetCurrDataCounter(DMA_Channel_TypeDef* DMAy_Channelx)
+{
+ /* Check the parameters */
+ assert_param(IS_DMA_ALL_PERIPH(DMAy_Channelx));
+ /* Return the number of remaining data units for DMAy Channelx */
+ return ((uint16_t)(DMAy_Channelx->CNDTR));
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup DMA_Group3 Interrupts and flags management functions
+ * @brief Interrupts and flags management functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Interrupts and flags management functions #####
+ ===============================================================================
+ [..] This subsection provides functions allowing to configure the DMA 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 DMA controller events: Polling mode or Interrupt mode.
+ *** Polling Mode ***
+ ====================
+ [..] Each DMA channel can be managed through 4 event Flags:(y : DMA Controller
+ number x : DMA channel number ).
+ (#) DMAy_FLAG_TCx : to indicate that a Transfer Complete event occurred.
+ (#) DMAy_FLAG_HTx : to indicate that a Half-Transfer Complete event occurred.
+ (#) DMAy_FLAG_TEx : to indicate that a Transfer Error occurred.
+ (#) DMAy_FLAG_GLx : to indicate that at least one of the events described
+ above occurred.
+ -@- Clearing DMAy_FLAG_GLx results in clearing all other pending flags of the
+ same channel (DMAy_FLAG_TCx, DMAy_FLAG_HTx and DMAy_FLAG_TEx).
+ [..]In this Mode it is advised to use the following functions:
+ (+) FlagStatus DMA_GetFlagStatus(uint32_t DMA_FLAG);
+ (+) void DMA_ClearFlag(uint32_t DMA_FLAG);
+
+ *** Interrupt Mode ***
+ ======================
+ [..] Each DMA channel can be managed through 4 Interrupts:
+ (+) Interrupt Source
+ (##) DMA_IT_TC: specifies the interrupt source for the Transfer Complete
+ event.
+ (##) DMA_IT_HT : specifies the interrupt source for the Half-transfer Complete
+ event.
+ (##) DMA_IT_TE : specifies the interrupt source for the transfer errors event.
+ (##) DMA_IT_GL : to indicate that at least one of the interrupts described
+ above occurred.
+ -@@- Clearing DMA_IT_GL interrupt results in clearing all other interrupts of
+ the same channel (DMA_IT_TCx, DMA_IT_HT and DMA_IT_TE).
+ [..]In this Mode it is advised to use the following functions:
+ (+) void DMA_ITConfig(DMA_Channel_TypeDef* DMAy_Channelx, uint32_t DMA_IT,
+ FunctionalState NewState);
+ (+) ITStatus DMA_GetITStatus(uint32_t DMA_IT);
+ (+) void DMA_ClearITPendingBit(uint32_t DMA_IT);
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Enables or disables the specified DMAy Channelx interrupts.
+ * @param DMAy_Channelx: where y can be 1 or 2 to select the DMA and
+ * x can be 1 to 7 for DMA1 and 1 to 5 for DMA2 to select the DMA Channel.
+ * @param DMA_IT: specifies the DMA interrupts 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 interrupt mask
+ * @arg DMA_IT_TE: Transfer 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_Channel_TypeDef* DMAy_Channelx, uint32_t DMA_IT, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_DMA_ALL_PERIPH(DMAy_Channelx));
+ assert_param(IS_DMA_CONFIG_IT(DMA_IT));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the selected DMA interrupts */
+ DMAy_Channelx->CCR |= DMA_IT;
+ }
+ else
+ {
+ /* Disable the selected DMA interrupts */
+ DMAy_Channelx->CCR &= ~DMA_IT;
+ }
+}
+
+/**
+ * @brief Checks whether the specified DMAy Channelx flag is set or not.
+ * @param DMAy_FLAG: specifies the flag to check.
+ * This parameter can be one of the following values:
+ * @arg DMA1_FLAG_GL1: DMA1 Channel1 global flag.
+ * @arg DMA1_FLAG_TC1: DMA1 Channel1 transfer complete flag.
+ * @arg DMA1_FLAG_HT1: DMA1 Channel1 half transfer flag.
+ * @arg DMA1_FLAG_TE1: DMA1 Channel1 transfer error flag.
+ * @arg DMA1_FLAG_GL2: DMA1 Channel2 global flag.
+ * @arg DMA1_FLAG_TC2: DMA1 Channel2 transfer complete flag.
+ * @arg DMA1_FLAG_HT2: DMA1 Channel2 half transfer flag.
+ * @arg DMA1_FLAG_TE2: DMA1 Channel2 transfer error flag.
+ * @arg DMA1_FLAG_GL3: DMA1 Channel3 global flag.
+ * @arg DMA1_FLAG_TC3: DMA1 Channel3 transfer complete flag.
+ * @arg DMA1_FLAG_HT3: DMA1 Channel3 half transfer flag.
+ * @arg DMA1_FLAG_TE3: DMA1 Channel3 transfer error flag.
+ * @arg DMA1_FLAG_GL4: DMA1 Channel4 global flag.
+ * @arg DMA1_FLAG_TC4: DMA1 Channel4 transfer complete flag.
+ * @arg DMA1_FLAG_HT4: DMA1 Channel4 half transfer flag.
+ * @arg DMA1_FLAG_TE4: DMA1 Channel4 transfer error flag.
+ * @arg DMA1_FLAG_GL5: DMA1 Channel5 global flag.
+ * @arg DMA1_FLAG_TC5: DMA1 Channel5 transfer complete flag.
+ * @arg DMA1_FLAG_HT5: DMA1 Channel5 half transfer flag.
+ * @arg DMA1_FLAG_TE5: DMA1 Channel5 transfer error flag.
+ * @arg DMA1_FLAG_GL6: DMA1 Channel6 global flag.
+ * @arg DMA1_FLAG_TC6: DMA1 Channel6 transfer complete flag.
+ * @arg DMA1_FLAG_HT6: DMA1 Channel6 half transfer flag.
+ * @arg DMA1_FLAG_TE6: DMA1 Channel6 transfer error flag.
+ * @arg DMA1_FLAG_GL7: DMA1 Channel7 global flag.
+ * @arg DMA1_FLAG_TC7: DMA1 Channel7 transfer complete flag.
+ * @arg DMA1_FLAG_HT7: DMA1 Channel7 half transfer flag.
+ * @arg DMA1_FLAG_TE7: DMA1 Channel7 transfer error flag.
+ * @arg DMA2_FLAG_GL1: DMA2 Channel1 global flag.
+ * @arg DMA2_FLAG_TC1: DMA2 Channel1 transfer complete flag.
+ * @arg DMA2_FLAG_HT1: DMA2 Channel1 half transfer flag.
+ * @arg DMA2_FLAG_TE1: DMA2 Channel1 transfer error flag.
+ * @arg DMA2_FLAG_GL2: DMA2 Channel2 global flag.
+ * @arg DMA2_FLAG_TC2: DMA2 Channel2 transfer complete flag.
+ * @arg DMA2_FLAG_HT2: DMA2 Channel2 half transfer flag.
+ * @arg DMA2_FLAG_TE2: DMA2 Channel2 transfer error flag.
+ * @arg DMA2_FLAG_GL3: DMA2 Channel3 global flag.
+ * @arg DMA2_FLAG_TC3: DMA2 Channel3 transfer complete flag.
+ * @arg DMA2_FLAG_HT3: DMA2 Channel3 half transfer flag.
+ * @arg DMA2_FLAG_TE3: DMA2 Channel3 transfer error flag.
+ * @arg DMA2_FLAG_GL4: DMA2 Channel4 global flag.
+ * @arg DMA2_FLAG_TC4: DMA2 Channel4 transfer complete flag.
+ * @arg DMA2_FLAG_HT4: DMA2 Channel4 half transfer flag.
+ * @arg DMA2_FLAG_TE4: DMA2 Channel4 transfer error flag.
+ * @arg DMA2_FLAG_GL5: DMA2 Channel5 global flag.
+ * @arg DMA2_FLAG_TC5: DMA2 Channel5 transfer complete flag.
+ * @arg DMA2_FLAG_HT5: DMA2 Channel5 half transfer flag.
+ * @arg DMA2_FLAG_TE5: DMA2 Channel5 transfer error flag.
+ *
+ * @note The Global flag (DMAy_FLAG_GLx) is set whenever any of the other flags
+ * relative to the same channel is set (Transfer Complete, Half-transfer
+ * Complete or Transfer Error flags: DMAy_FLAG_TCx, DMAy_FLAG_HTx or
+ * DMAy_FLAG_TEx).
+ *
+ * @retval The new state of DMAy_FLAG (SET or RESET).
+ */
+FlagStatus DMA_GetFlagStatus(uint32_t DMAy_FLAG)
+{
+ FlagStatus bitstatus = RESET;
+ uint32_t tmpreg = 0;
+
+ /* Check the parameters */
+ assert_param(IS_DMA_GET_FLAG(DMAy_FLAG));
+
+ /* Calculate the used DMAy */
+ if ((DMAy_FLAG & FLAG_Mask) != (uint32_t)RESET)
+ {
+ /* Get DMA2 ISR register value */
+ tmpreg = DMA2->ISR ;
+ }
+ else
+ {
+ /* Get DMA1 ISR register value */
+ tmpreg = DMA1->ISR ;
+ }
+
+ /* Check the status of the specified DMAy flag */
+ if ((tmpreg & DMAy_FLAG) != (uint32_t)RESET)
+ {
+ /* DMAy_FLAG is set */
+ bitstatus = SET;
+ }
+ else
+ {
+ /* DMAy_FLAG is reset */
+ bitstatus = RESET;
+ }
+
+ /* Return the DMAy_FLAG status */
+ return bitstatus;
+}
+
+/**
+ * @brief Clears the DMAy Channelx's pending flags.
+ * @param DMAy_FLAG: specifies the flag to clear.
+ * This parameter can be any combination (for the same DMA) of the following values:
+ * @arg DMA1_FLAG_GL1: DMA1 Channel1 global flag.
+ * @arg DMA1_FLAG_TC1: DMA1 Channel1 transfer complete flag.
+ * @arg DMA1_FLAG_HT1: DMA1 Channel1 half transfer flag.
+ * @arg DMA1_FLAG_TE1: DMA1 Channel1 transfer error flag.
+ * @arg DMA1_FLAG_GL2: DMA1 Channel2 global flag.
+ * @arg DMA1_FLAG_TC2: DMA1 Channel2 transfer complete flag.
+ * @arg DMA1_FLAG_HT2: DMA1 Channel2 half transfer flag.
+ * @arg DMA1_FLAG_TE2: DMA1 Channel2 transfer error flag.
+ * @arg DMA1_FLAG_GL3: DMA1 Channel3 global flag.
+ * @arg DMA1_FLAG_TC3: DMA1 Channel3 transfer complete flag.
+ * @arg DMA1_FLAG_HT3: DMA1 Channel3 half transfer flag.
+ * @arg DMA1_FLAG_TE3: DMA1 Channel3 transfer error flag.
+ * @arg DMA1_FLAG_GL4: DMA1 Channel4 global flag.
+ * @arg DMA1_FLAG_TC4: DMA1 Channel4 transfer complete flag.
+ * @arg DMA1_FLAG_HT4: DMA1 Channel4 half transfer flag.
+ * @arg DMA1_FLAG_TE4: DMA1 Channel4 transfer error flag.
+ * @arg DMA1_FLAG_GL5: DMA1 Channel5 global flag.
+ * @arg DMA1_FLAG_TC5: DMA1 Channel5 transfer complete flag.
+ * @arg DMA1_FLAG_HT5: DMA1 Channel5 half transfer flag.
+ * @arg DMA1_FLAG_TE5: DMA1 Channel5 transfer error flag.
+ * @arg DMA1_FLAG_GL6: DMA1 Channel6 global flag.
+ * @arg DMA1_FLAG_TC6: DMA1 Channel6 transfer complete flag.
+ * @arg DMA1_FLAG_HT6: DMA1 Channel6 half transfer flag.
+ * @arg DMA1_FLAG_TE6: DMA1 Channel6 transfer error flag.
+ * @arg DMA1_FLAG_GL7: DMA1 Channel7 global flag.
+ * @arg DMA1_FLAG_TC7: DMA1 Channel7 transfer complete flag.
+ * @arg DMA1_FLAG_HT7: DMA1 Channel7 half transfer flag.
+ * @arg DMA1_FLAG_TE7: DMA1 Channel7 transfer error flag.
+ * @arg DMA2_FLAG_GL1: DMA2 Channel1 global flag.
+ * @arg DMA2_FLAG_TC1: DMA2 Channel1 transfer complete flag.
+ * @arg DMA2_FLAG_HT1: DMA2 Channel1 half transfer flag.
+ * @arg DMA2_FLAG_TE1: DMA2 Channel1 transfer error flag.
+ * @arg DMA2_FLAG_GL2: DMA2 Channel2 global flag.
+ * @arg DMA2_FLAG_TC2: DMA2 Channel2 transfer complete flag.
+ * @arg DMA2_FLAG_HT2: DMA2 Channel2 half transfer flag.
+ * @arg DMA2_FLAG_TE2: DMA2 Channel2 transfer error flag.
+ * @arg DMA2_FLAG_GL3: DMA2 Channel3 global flag.
+ * @arg DMA2_FLAG_TC3: DMA2 Channel3 transfer complete flag.
+ * @arg DMA2_FLAG_HT3: DMA2 Channel3 half transfer flag.
+ * @arg DMA2_FLAG_TE3: DMA2 Channel3 transfer error flag.
+ * @arg DMA2_FLAG_GL4: DMA2 Channel4 global flag.
+ * @arg DMA2_FLAG_TC4: DMA2 Channel4 transfer complete flag.
+ * @arg DMA2_FLAG_HT4: DMA2 Channel4 half transfer flag.
+ * @arg DMA2_FLAG_TE4: DMA2 Channel4 transfer error flag.
+ * @arg DMA2_FLAG_GL5: DMA2 Channel5 global flag.
+ * @arg DMA2_FLAG_TC5: DMA2 Channel5 transfer complete flag.
+ * @arg DMA2_FLAG_HT5: DMA2 Channel5 half transfer flag.
+ * @arg DMA2_FLAG_TE5: DMA2 Channel5 transfer error flag.
+ *
+ * @note Clearing the Global flag (DMAy_FLAG_GLx) results in clearing all other flags
+ * relative to the same channel (Transfer Complete, Half-transfer Complete and
+ * Transfer Error flags: DMAy_FLAG_TCx, DMAy_FLAG_HTx and DMAy_FLAG_TEx).
+ *
+ * @retval None
+ */
+void DMA_ClearFlag(uint32_t DMAy_FLAG)
+{
+ /* Check the parameters */
+ assert_param(IS_DMA_CLEAR_FLAG(DMAy_FLAG));
+
+/* Calculate the used DMAy */
+ if ((DMAy_FLAG & FLAG_Mask) != (uint32_t)RESET)
+ {
+ /* Clear the selected DMAy flags */
+ DMA2->IFCR = DMAy_FLAG;
+ }
+ else
+ {
+ /* Clear the selected DMAy flags */
+ DMA1->IFCR = DMAy_FLAG;
+ }
+}
+
+/**
+ * @brief Checks whether the specified DMAy Channelx interrupt has occurred or not.
+ * @param DMAy_IT: specifies the DMAy interrupt source to check.
+ * This parameter can be one of the following values:
+ * @arg DMA1_IT_GL1: DMA1 Channel1 global interrupt.
+ * @arg DMA1_IT_TC1: DMA1 Channel1 transfer complete interrupt.
+ * @arg DMA1_IT_HT1: DMA1 Channel1 half transfer interrupt.
+ * @arg DMA1_IT_TE1: DMA1 Channel1 transfer error interrupt.
+ * @arg DMA1_IT_GL2: DMA1 Channel2 global interrupt.
+ * @arg DMA1_IT_TC2: DMA1 Channel2 transfer complete interrupt.
+ * @arg DMA1_IT_HT2: DMA1 Channel2 half transfer interrupt.
+ * @arg DMA1_IT_TE2: DMA1 Channel2 transfer error interrupt.
+ * @arg DMA1_IT_GL3: DMA1 Channel3 global interrupt.
+ * @arg DMA1_IT_TC3: DMA1 Channel3 transfer complete interrupt.
+ * @arg DMA1_IT_HT3: DMA1 Channel3 half transfer interrupt.
+ * @arg DMA1_IT_TE3: DMA1 Channel3 transfer error interrupt.
+ * @arg DMA1_IT_GL4: DMA1 Channel4 global interrupt.
+ * @arg DMA1_IT_TC4: DMA1 Channel4 transfer complete interrupt.
+ * @arg DMA1_IT_HT4: DMA1 Channel4 half transfer interrupt.
+ * @arg DMA1_IT_TE4: DMA1 Channel4 transfer error interrupt.
+ * @arg DMA1_IT_GL5: DMA1 Channel5 global interrupt.
+ * @arg DMA1_IT_TC5: DMA1 Channel5 transfer complete interrupt.
+ * @arg DMA1_IT_HT5: DMA1 Channel5 half transfer interrupt.
+ * @arg DMA1_IT_TE5: DMA1 Channel5 transfer error interrupt.
+ * @arg DMA1_IT_GL6: DMA1 Channel6 global interrupt.
+ * @arg DMA1_IT_TC6: DMA1 Channel6 transfer complete interrupt.
+ * @arg DMA1_IT_HT6: DMA1 Channel6 half transfer interrupt.
+ * @arg DMA1_IT_TE6: DMA1 Channel6 transfer error interrupt.
+ * @arg DMA1_IT_GL7: DMA1 Channel7 global interrupt.
+ * @arg DMA1_IT_TC7: DMA1 Channel7 transfer complete interrupt.
+ * @arg DMA1_IT_HT7: DMA1 Channel7 half transfer interrupt.
+ * @arg DMA1_IT_TE7: DMA1 Channel7 transfer error interrupt.
+ * @arg DMA2_IT_GL1: DMA2 Channel1 global interrupt.
+ * @arg DMA2_IT_TC1: DMA2 Channel1 transfer complete interrupt.
+ * @arg DMA2_IT_HT1: DMA2 Channel1 half transfer interrupt.
+ * @arg DMA2_IT_TE1: DMA2 Channel1 transfer error interrupt.
+ * @arg DMA2_IT_GL2: DMA2 Channel2 global interrupt.
+ * @arg DMA2_IT_TC2: DMA2 Channel2 transfer complete interrupt.
+ * @arg DMA2_IT_HT2: DMA2 Channel2 half transfer interrupt.
+ * @arg DMA2_IT_TE2: DMA2 Channel2 transfer error interrupt.
+ * @arg DMA2_IT_GL3: DMA2 Channel3 global interrupt.
+ * @arg DMA2_IT_TC3: DMA2 Channel3 transfer complete interrupt.
+ * @arg DMA2_IT_HT3: DMA2 Channel3 half transfer interrupt.
+ * @arg DMA2_IT_TE3: DMA2 Channel3 transfer error interrupt.
+ * @arg DMA2_IT_GL4: DMA2 Channel4 global interrupt.
+ * @arg DMA2_IT_TC4: DMA2 Channel4 transfer complete interrupt.
+ * @arg DMA2_IT_HT4: DMA2 Channel4 half transfer interrupt.
+ * @arg DMA2_IT_TE4: DMA2 Channel4 transfer error interrupt.
+ * @arg DMA2_IT_GL5: DMA2 Channel5 global interrupt.
+ * @arg DMA2_IT_TC5: DMA2 Channel5 transfer complete interrupt.
+ * @arg DMA2_IT_HT5: DMA2 Channel5 half transfer interrupt.
+ * @arg DMA2_IT_TE5: DMA2 Channel5 transfer error interrupt.
+ *
+ * @note The Global interrupt (DMAy_FLAG_GLx) is set whenever any of the other
+ * interrupts relative to the same channel is set (Transfer Complete,
+ * Half-transfer Complete or Transfer Error interrupts: DMAy_IT_TCx,
+ * DMAy_IT_HTx or DMAy_IT_TEx).
+ *
+ * @retval The new state of DMAy_IT (SET or RESET).
+ */
+ITStatus DMA_GetITStatus(uint32_t DMAy_IT)
+{
+ ITStatus bitstatus = RESET;
+ uint32_t tmpreg = 0;
+
+ /* Check the parameters */
+ assert_param(IS_DMA_GET_IT(DMAy_IT));
+
+ /* Calculate the used DMA */
+ if ((DMAy_IT & FLAG_Mask) != (uint32_t)RESET)
+ {
+ /* Get DMA2 ISR register value */
+ tmpreg = DMA2->ISR;
+ }
+ else
+ {
+ /* Get DMA1 ISR register value */
+ tmpreg = DMA1->ISR;
+ }
+
+ /* Check the status of the specified DMAy interrupt */
+ if ((tmpreg & DMAy_IT) != (uint32_t)RESET)
+ {
+ /* DMAy_IT is set */
+ bitstatus = SET;
+ }
+ else
+ {
+ /* DMAy_IT is reset */
+ bitstatus = RESET;
+ }
+ /* Return the DMAy_IT status */
+ return bitstatus;
+}
+
+/**
+ * @brief Clears the DMAy Channelx's interrupt pending bits.
+ * @param DMAy_IT: specifies the DMAy interrupt pending bit to clear.
+ * This parameter can be any combination (for the same DMA) of the following values:
+ * @arg DMA1_IT_GL1: DMA1 Channel1 global interrupt.
+ * @arg DMA1_IT_TC1: DMA1 Channel1 transfer complete interrupt.
+ * @arg DMA1_IT_HT1: DMA1 Channel1 half transfer interrupt.
+ * @arg DMA1_IT_TE1: DMA1 Channel1 transfer error interrupt.
+ * @arg DMA1_IT_GL2: DMA1 Channel2 global interrupt.
+ * @arg DMA1_IT_TC2: DMA1 Channel2 transfer complete interrupt.
+ * @arg DMA1_IT_HT2: DMA1 Channel2 half transfer interrupt.
+ * @arg DMA1_IT_TE2: DMA1 Channel2 transfer error interrupt.
+ * @arg DMA1_IT_GL3: DMA1 Channel3 global interrupt.
+ * @arg DMA1_IT_TC3: DMA1 Channel3 transfer complete interrupt.
+ * @arg DMA1_IT_HT3: DMA1 Channel3 half transfer interrupt.
+ * @arg DMA1_IT_TE3: DMA1 Channel3 transfer error interrupt.
+ * @arg DMA1_IT_GL4: DMA1 Channel4 global interrupt.
+ * @arg DMA1_IT_TC4: DMA1 Channel4 transfer complete interrupt.
+ * @arg DMA1_IT_HT4: DMA1 Channel4 half transfer interrupt.
+ * @arg DMA1_IT_TE4: DMA1 Channel4 transfer error interrupt.
+ * @arg DMA1_IT_GL5: DMA1 Channel5 global interrupt.
+ * @arg DMA1_IT_TC5: DMA1 Channel5 transfer complete interrupt.
+ * @arg DMA1_IT_HT5: DMA1 Channel5 half transfer interrupt.
+ * @arg DMA1_IT_TE5: DMA1 Channel5 transfer error interrupt.
+ * @arg DMA1_IT_GL6: DMA1 Channel6 global interrupt.
+ * @arg DMA1_IT_TC6: DMA1 Channel6 transfer complete interrupt.
+ * @arg DMA1_IT_HT6: DMA1 Channel6 half transfer interrupt.
+ * @arg DMA1_IT_TE6: DMA1 Channel6 transfer error interrupt.
+ * @arg DMA1_IT_GL7: DMA1 Channel7 global interrupt.
+ * @arg DMA1_IT_TC7: DMA1 Channel7 transfer complete interrupt.
+ * @arg DMA1_IT_HT7: DMA1 Channel7 half transfer interrupt.
+ * @arg DMA1_IT_TE7: DMA1 Channel7 transfer error interrupt.
+ * @arg DMA2_IT_GL1: DMA2 Channel1 global interrupt.
+ * @arg DMA2_IT_TC1: DMA2 Channel1 transfer complete interrupt.
+ * @arg DMA2_IT_HT1: DMA2 Channel1 half transfer interrupt.
+ * @arg DMA2_IT_TE1: DMA2 Channel1 transfer error interrupt.
+ * @arg DMA2_IT_GL2: DMA2 Channel2 global interrupt.
+ * @arg DMA2_IT_TC2: DMA2 Channel2 transfer complete interrupt.
+ * @arg DMA2_IT_HT2: DMA2 Channel2 half transfer interrupt.
+ * @arg DMA2_IT_TE2: DMA2 Channel2 transfer error interrupt.
+ * @arg DMA2_IT_GL3: DMA2 Channel3 global interrupt.
+ * @arg DMA2_IT_TC3: DMA2 Channel3 transfer complete interrupt.
+ * @arg DMA2_IT_HT3: DMA2 Channel3 half transfer interrupt.
+ * @arg DMA2_IT_TE3: DMA2 Channel3 transfer error interrupt.
+ * @arg DMA2_IT_GL4: DMA2 Channel4 global interrupt.
+ * @arg DMA2_IT_TC4: DMA2 Channel4 transfer complete interrupt.
+ * @arg DMA2_IT_HT4: DMA2 Channel4 half transfer interrupt.
+ * @arg DMA2_IT_TE4: DMA2 Channel4 transfer error interrupt.
+ * @arg DMA2_IT_GL5: DMA2 Channel5 global interrupt.
+ * @arg DMA2_IT_TC5: DMA2 Channel5 transfer complete interrupt.
+ * @arg DMA2_IT_HT5: DMA2 Channel5 half transfer interrupt.
+ * @arg DMA2_IT_TE5: DMA2 Channel5 transfer error interrupt.
+ *
+ * @note Clearing the Global interrupt (DMAy_IT_GLx) results in clearing all other
+ * interrupts relative to the same channel (Transfer Complete, Half-transfer
+ * Complete and Transfer Error interrupts: DMAy_IT_TCx, DMAy_IT_HTx and
+ * DMAy_IT_TEx).
+ *
+ * @retval None
+ */
+void DMA_ClearITPendingBit(uint32_t DMAy_IT)
+{
+ /* Check the parameters */
+ assert_param(IS_DMA_CLEAR_IT(DMAy_IT));
+
+ /* Calculate the used DMAy */
+ if ((DMAy_IT & FLAG_Mask) != (uint32_t)RESET)
+ {
+ /* Clear the selected DMAy interrupt pending bits */
+ DMA2->IFCR = DMAy_IT;
+ }
+ else
+ {
+ /* Clear the selected DMAy interrupt pending bits */
+ DMA1->IFCR = DMAy_IT;
+ }
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Libraries/STM32F37x_StdPeriph_Driver/src/stm32f37x_exti.c b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Libraries/STM32F37x_StdPeriph_Driver/src/stm32f37x_exti.c
new file mode 100644
index 0000000..7427916
--- /dev/null
+++ b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Libraries/STM32F37x_StdPeriph_Driver/src/stm32f37x_exti.c
@@ -0,0 +1,320 @@
+/**
+ ******************************************************************************
+ * @file stm32f37x_exti.c
+ * @author MCD Application Team
+ * @version V1.0.0
+ * @date 20-September-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:
+ (#) All available GPIO pins are connected to the 16 external
+ interrupt/event lines from EXTI0 to EXTI15.
+ (#) EXTI line 16 is connected to the PVD output
+ (#) EXTI line 17 is connected to the RTC Alarm event
+ (#) EXTI line 18 is connected to USB Device wakeup event
+ (#) EXTI line 19 is connected to the RTC Tamper and TimeStamp events
+ (#) EXTI line 20 is connected to the RTC wakeup event
+ (#) EXTI line 21 is connected to the Comparator 1 wakeup event
+ (#) EXTI line 22 is connected to the Comparator 2 wakeup event
+ (#) EXTI line 23 is connected to the I2C1 wakeup event
+ (#) EXTI line 24 is connected to the I2C2 wakeup event
+ (#) EXTI line 25 is connected to the USART1 wakeup event
+ (#) EXTI line 26 is connected to the USART2 wakeup event
+ (#) EXTI line 27 is connected to the CEC wakeup event
+ (#) EXTI line 28 is connected to the USART3 wakeup event
+
+ ##### How to use this driver #####
+ ==============================================================================
+ [..] In order to use an I/O pin as an external interrupt source, follow
+ steps below:
+ (#) Configure the I/O in input mode using GPIO_Init()
+ (#) Select the input source pin for the EXTI line using
+ SYSCFG_EXTILineConfig().
+ (#) Select the mode(interrupt, event) and configure the trigger selection
+ (Rising, falling or both) using EXTI_Init(). For the internal interrupt,
+ the trigger selection is not needed( the active edge is always the rising one).
+ (#) Configure NVIC IRQ channel mapped to the EXTI line using NVIC_Init().
+ (#) Optionally, you can generate a software interrupt using the function EXTI_GenerateSWInterrupt().
+ [..]
+ (@) SYSCFG APB clock must be enabled to get write access to SYSCFG_EXTICRx
+ registers using RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
+ @endverbatim
+ *
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
+ *
+ * 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 "stm32f37x_exti.h"
+
+/** @addtogroup STM32F37x_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 = 0x1F800000;
+ EXTI->EMR = 0x00000000;
+ EXTI->RTSR = 0x00000000;
+ EXTI->FTSR = 0x00000000;
+ EXTI->PR = 0x01FFFFFF;
+}
+
+/**
+ * @brief Initializes the EXTI peripheral according to the specified
+ * parameters in the EXTI_InitStruct.
+ * - EXTI_Line specifies the EXTI line (EXTI0....EXTI28).
+ * - EXTI_Mode specifies which EXTI line is used as interrupt or an event.
+ * - EXTI_Trigger selects the trigger. When the trigger occurs, interrupt
+ * pending bit will be set.
+ * - EXTI_LineCmd controls (Enable/Disable) the EXTI line.
+ * @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 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..28).
+ * @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(0..28).
+ * @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..28).
+ * @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..28).
+ * @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..28).
+ * @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/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Libraries/STM32F37x_StdPeriph_Driver/src/stm32f37x_gpio.c b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Libraries/STM32F37x_StdPeriph_Driver/src/stm32f37x_gpio.c
new file mode 100644
index 0000000..6847a6b
--- /dev/null
+++ b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Libraries/STM32F37x_StdPeriph_Driver/src/stm32f37x_gpio.c
@@ -0,0 +1,528 @@
+/**
+ ******************************************************************************
+ * @file stm32f37x_gpio.c
+ * @author MCD Application Team
+ * @version V1.0.0
+ * @date 20-September-2012
+ * @brief This file provides firmware functions to manage the following
+ * functionalities of the GPIO peripheral:
+ * + Initialization and Configuration functions
+ * + GPIO Read and Write functions
+ * + GPIO Alternate functions configuration functions
+ *
+ * @verbatim
+ *
+ *
+ ===========================================================================
+ ##### How to use this driver #####
+ ===========================================================================
+ [..]
+ (#) Enable the GPIO AHB clock using RCC_AHBPeriphClockCmd()
+ (#) 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: Low, Medium, Fast or High.
+ (++) 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,
+ DAC output or comparator input.
+ (#) Peripherals alternate function:
+ (++) For ADC, DAC and comparators, 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. For PortC,
+ PortD and PortF, no configuration is needed.
+ (+++) 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
+ (#) To get the level of a pin configured in input mode use GPIO_ReadInputDataBit()
+ (#) To set/reset the level of a pin configured in output mode use
+ GPIO_SetBits()/GPIO_ResetBits()
+ (#) During and just after reset, the alternate functions are not active and
+ the GPIO pins are configured in input floating mode (except JTAG pins).
+ (#) 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.
+ (#) The HSE oscillator pins OSC_IN/OSC_OUT can be used as general-purpose
+ (PF0 and PF1 respectively) when the HSE oscillator is off. The HSE has
+ the priority over the GPIO function.
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
+ *
+ * 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 "stm32f37x_gpio.h"
+#include "stm32f37x_rcc.h"
+
+/** @addtogroup STM32F37x_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.
+ * @param GPIOx: where x can be (A, B, C, D, E or F) 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_AHBPeriphResetCmd(RCC_AHBPeriph_GPIOA, ENABLE);
+ RCC_AHBPeriphResetCmd(RCC_AHBPeriph_GPIOA, DISABLE);
+ }
+ else if(GPIOx == GPIOB)
+ {
+ RCC_AHBPeriphResetCmd(RCC_AHBPeriph_GPIOB, ENABLE);
+ RCC_AHBPeriphResetCmd(RCC_AHBPeriph_GPIOB, DISABLE);
+ }
+ else if(GPIOx == GPIOC)
+ {
+ RCC_AHBPeriphResetCmd(RCC_AHBPeriph_GPIOC, ENABLE);
+ RCC_AHBPeriphResetCmd(RCC_AHBPeriph_GPIOC, DISABLE);
+ }
+ else if(GPIOx == GPIOD)
+ {
+ RCC_AHBPeriphResetCmd(RCC_AHBPeriph_GPIOD, ENABLE);
+ RCC_AHBPeriphResetCmd(RCC_AHBPeriph_GPIOD, DISABLE);
+ }
+ else if(GPIOx == GPIOE)
+ {
+ RCC_AHBPeriphResetCmd(RCC_AHBPeriph_GPIOE, ENABLE);
+ RCC_AHBPeriphResetCmd(RCC_AHBPeriph_GPIOE, DISABLE);
+ }
+ else
+ {
+ if(GPIOx == GPIOF)
+ {
+ RCC_AHBPeriphResetCmd(RCC_AHBPeriph_GPIOF, ENABLE);
+ RCC_AHBPeriphResetCmd(RCC_AHBPeriph_GPIOF, DISABLE);
+ }
+ }
+}
+
+/**
+ * @brief Initializes the GPIOx peripheral according to the specified
+ * parameters in the GPIO_InitStruct.
+ * @param GPIOx: where x can be (A, B, C, D, E or F) to select the GPIO peripheral.
+ * @param GPIO_InitStruct: pointer to a GPIO_InitTypeDef structure that
+ * contains the configuration information for the specified GPIO
+ * peripheral.
+ * @note The configured pins can be:
+ * GPIO_Pin_0 -> GPIO_Pin_15 for GPIOA, GPIOC, GPIOD and GPIOE;
+ * GPIO_Pin_0 -> GPIO_Pin_10 and GPIO_Pin_14 -> GPIO_Pin_15 for GPIOB;
+ * GPIO_Pin_0 -> GPIO_Pin_2, GPIO_Pin_4, GPIO_Pin_6, GPIO_Pin_9 and GPIO_Pin_10
+ * for GPIOF.
+ * @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)
+ {
+ 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));
+ }
+
+ GPIOx->MODER &= ~(GPIO_MODER_MODER0 << (pinpos * 2));
+
+ GPIOx->MODER |= (((uint32_t)GPIO_InitStruct->GPIO_Mode) << (pinpos * 2));
+
+ /* 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_Level_2;
+ 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 device reset.
+ * @param GPIOx: where x can be (A or B or D) to select the GPIO peripheral.
+ * @param GPIO_Pin: specifies the port bit to be written.
+ * 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_LIST_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, B, C, D, E or F) to select the GPIO peripheral.
+ * @param GPIO_Pin: specifies the port bit to read.
+ * @note This parameter can be GPIO_Pin_x where x can be:
+ * (0..15) for GPIOA, GPIOC, GPIOD or GPIOE;
+ * (0..10 & 14..15) for GPIOB;
+ * (0..2, 4, 6, 9..10) for GPIOF.
+ * @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 input port pin.
+ * @param GPIOx: where x can be (A, B, C, D, E or F) to select the GPIO peripheral.
+ * @retval The input port pin 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, B, C, D, E or F) to select the GPIO peripheral.
+ * @param GPIO_Pin: Specifies the port bit to read.
+ * @note This parameter can be GPIO_Pin_x where x can be:
+ * (0..15) for GPIOA, GPIOC, GPIOD or GPIOE;
+ * (0..10 & 14..15) for GPIOB;
+ * (0..2, 4, 6, 9..10) for GPIOF.
+ * @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, B, C, D, E or F) 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.
+ * @param GPIOx: where x can be (A, B, C, D, E or F) to select the GPIO peripheral.
+ * @param GPIO_Pin: specifies the port bits to be written.
+ * @note This parameter can be GPIO_Pin_x where x can be:
+ * (0..15) for GPIOA, GPIOC, GPIOD or GPIOE;
+ * (0..10 & 14..15) for GPIOB;
+ * (0..2, 4, 6, 9..10) for GPIOF.
+ * @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->BSRR = GPIO_Pin;
+}
+
+/**
+ * @brief Clears the selected data port bits.
+ * @param GPIOx: where x can be (A, B, C, D, E or F) to select the GPIO peripheral.
+ * @param GPIO_Pin: specifies the port bits to be written.
+ * @note This parameter can be GPIO_Pin_x where x can be:
+ * (0..15) for GPIOA, GPIOC, GPIOD or GPIOE;
+ * (0..10 & 14..15) for GPIOB;
+ * (0..2, 4, 6, 9..10) for GPIOF.
+ * @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->BRR = GPIO_Pin;
+}
+
+/**
+ * @brief Sets or clears the selected data port bit.
+ * @param GPIOx: where x can be (A, B, C, D, E or F) to select the GPIO peripheral.
+ * @param GPIO_Pin: specifies the port bit to be written.
+ * @note This parameter can be GPIO_Pin_x where x can be:
+ * (0..15) for GPIOA, GPIOC, GPIOD or GPIOE;
+ * (0..10 & 14..15) for GPIOB;
+ * (0..2, 4, 6, 9..10) for GPIOF.
+ * @param BitVal: specifies the value to be written to the selected bit.
+ * This parameter can be one of the BitAction enumeration 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->BSRR = GPIO_Pin;
+ }
+ else
+ {
+ GPIOx->BRR = GPIO_Pin ;
+ }
+}
+
+/**
+ * @brief Writes data to the specified GPIO data port.
+ * @param GPIOx: where x can be (A, B, C, D, E or F) 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;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup GPIO_Group3 GPIO Alternate functions configuration functions
+ * @brief GPIO Alternate functions configuration functions
+ *
+@verbatim
+ ===============================================================================
+ ##### GPIO Alternate functions configuration functions #####
+ ===============================================================================
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Writes data to the specified GPIO data port.
+ * @param GPIOx: where x can be (A, B, C, D, E or F) 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_AF: selects the pin to be used as Alternate function.
+ * This parameter can be one of the following value:
+ * @arg GPIO_AF_0: MCO, JTMS-SWDAT, JTCK-SWCLK, JTDI,JTDO, JTRST, TRACECLK, TRACED, TRACEWO.
+ * @arg GPIO_AF_1: TIM2, TIM15, TIM16, TIM17, OUT.
+ * @arg GPIO_AF_2: TIM3, TIM4, TIM5, TIM13, TIM14, TIM19.
+ * @arg GPIO_AF_3: Touch Sence.
+ * @arg GPIO_AF_4: I2C1, I2C2.
+ * @arg GPIO_AF_5: SPI1, SPI2, IR_OUT.
+ * @arg GPIO_AF_6: SPI1, SPI3, CEC, IR_OUT.
+ * @arg GPIO_AF_7: USART1, USART2, USART3, CAN, CEC.
+ * @arg GPIO_AF_8: COMP1_OUT, COMP2_OUT.
+ * @arg GPIO_AF_9: CAN, TIM12, TIM13, TIM14, TIM15.
+ * @arg GPIO_AF_10: TIM2, TIM3, TIM4, TIM12, TIM17.
+ * @arg GPIO_AF_11: TIM19.
+ * @arg GPIO_AF_14: USBDM, USBDP.
+ * @arg GPIO_AF_15: OUT.
+ * @note The pin should already been configured in Alternate Function mode(AF)
+ * using GPIO_InitStruct->GPIO_Mode = GPIO_Mode_AF
+ * @note Refer to the Alternate function mapping table in the device datasheet
+ * for the detailed mapping of the system and peripherals'alternate
+ * function I/O pins.
+ * @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/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Libraries/STM32F37x_StdPeriph_Driver/src/stm32f37x_i2c.c b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Libraries/STM32F37x_StdPeriph_Driver/src/stm32f37x_i2c.c
new file mode 100644
index 0000000..1c2584b
--- /dev/null
+++ b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Libraries/STM32F37x_StdPeriph_Driver/src/stm32f37x_i2c.c
@@ -0,0 +1,1585 @@
+/**
+ ******************************************************************************
+ * @file stm32f37x_i2c.c
+ * @author MCD Application Team
+ * @version V1.0.0
+ * @date 20-September-2012
+ * @brief This file provides firmware functions to manage the following
+ * functionalities of the Inter-Integrated circuit (I2C):
+ * + Initialization and Configuration
+ * + Communications handling
+ * + SMBUS management
+ * + I2C registers management
+ * + Data transfers management
+ * + DMA transfers management
+ * + Interrupts and flags management
+ *
+ * @verbatim
+ ============================================================================
+ ##### How to use this driver #####
+ ============================================================================
+ [..]
+ (#) Enable peripheral clock using RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2Cx, ENABLE)
+ function for I2C1 or I2C2.
+ (#) Enable SDA, SCL and SMBA (when used) GPIO clocks using
+ RCC_AHBPeriphClockCmd() function.
+ (#) 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, OpenDrain and speed via
+ GPIO_PuPd, GPIO_OType and GPIO_Speed members
+ (++) Call GPIO_Init() function.
+ (#) Program the Mode, Timing , Own address, Ack and Acknowledged Address
+ using the I2C_Init() function.
+ (#) 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 PEC Calculation using I2C_CalculatePEC() function.
+ (++) For SMBus Mode:
+ (+++) Enable the SMBusAlert pin using I2C_SMBusAlertCmd() function.
+ (#) Enable the NVIC and the corresponding interrupt using the function
+ I2C_ITConfig() if you need to use interrupt mode.
+ (#) When using the DMA mode
+ (++) Configure the DMA using DMA_Init() function.
+ (++) Active the needed channel Request using I2C_DMACmd() function.
+ (#) Enable the I2C using the I2C_Cmd() function.
+ (#) Enable the DMA using the DMA_Cmd() function when using DMA mode in the
+ transfers.
+ [..]
+ (@) When using I2C in Fast Mode Plus, SCL and SDA pin 20mA current drive capability
+ must be enabled by setting the driving capability control bit in SYSCFG.
+
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
+ *
+ * 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 "stm32f37x_i2c.h"
+#include "stm32f37x_rcc.h"
+
+/** @addtogroup STM32F37x_StdPeriph_Driver
+ * @{
+ */
+
+/** @defgroup I2C
+ * @brief I2C driver modules
+ * @{
+ */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+
+#define CR1_CLEAR_MASK ((uint32_t)0x00CFE0FF) /*<! I2C CR1 clear register Mask */
+#define CR2_CLEAR_MASK ((uint32_t)0x07FF7FFF) /*<! I2C CR2 clear register Mask */
+#define TIMING_CLEAR_MASK ((uint32_t)0xF0FFFFFF) /*<! I2C TIMING clear register Mask */
+#define ERROR_IT_MASK ((uint32_t)0x00003F00) /*<! I2C Error interrupt register Mask */
+#define TC_IT_MASK ((uint32_t)0x000000C0) /*<! I2C TC interrupt register Mask */
+
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+/** @defgroup I2C_Private_Functions
+ * @{
+ */
+
+
+/** @defgroup I2C_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 I2C Mode,
+ I2C Timing, I2C filters, I2C Addressing mode, I2C OwnAddress1.
+
+ [..] The I2C_Init() function follows the I2C configuration procedures (these procedures
+ are available in reference manual).
+
+ [..] When the Software Reset is performed using I2C_SoftwareResetCmd() function, the internal
+ states machines are reset and communication control bits, as well as status bits come
+ back to their reset value.
+
+ [..] Before enabling Stop mode using I2C_StopModeCmd() I2C Clock source must be set to
+ HSI and Digital filters must be disabled.
+
+ [..] Before enabling Own Address 2 via I2C_DualAddressCmd() function, OA2 and mask should be
+ configured using I2C_OwnAddress2Config() function.
+
+ [..] I2C_SlaveByteControlCmd() enable Slave byte control that allow user to get control of
+ each byte in slave mode when NBYTES is set to 0x01.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Deinitializes the I2Cx peripheral registers to their default reset values.
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * @retval None
+ */
+void I2C_DeInit(I2C_TypeDef* I2Cx)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+
+ if (I2Cx == I2C1)
+ {
+ /* Enable I2C1 reset state */
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, ENABLE);
+ /* Release I2C1 from reset state */
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, DISABLE);
+ }
+ else
+ {
+ /* Enable I2C2 reset state */
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C2, ENABLE);
+ /* Release I2C2 from reset state */
+ RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C2, DISABLE);
+ }
+}
+
+/**
+ * @brief Initializes the I2Cx peripheral according to the specified
+ * parameters in the I2C_InitStruct.
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * @param I2C_InitStruct: pointer to a I2C_InitTypeDef structure that
+ * contains the configuration information for the specified I2C peripheral.
+ * @retval None
+ */
+void I2C_Init(I2C_TypeDef* I2Cx, I2C_InitTypeDef* I2C_InitStruct)
+{
+ uint32_t tmpreg = 0;
+
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(IS_I2C_ANALOG_FILTER(I2C_InitStruct->I2C_AnalogFilter));
+ assert_param(IS_I2C_DIGITAL_FILTER(I2C_InitStruct->I2C_DigitalFilter));
+ assert_param(IS_I2C_MODE(I2C_InitStruct->I2C_Mode));
+ assert_param(IS_I2C_OWN_ADDRESS1(I2C_InitStruct->I2C_OwnAddress1));
+ assert_param(IS_I2C_ACK(I2C_InitStruct->I2C_Ack));
+ assert_param(IS_I2C_ACKNOWLEDGE_ADDRESS(I2C_InitStruct->I2C_AcknowledgedAddress));
+
+ /* Disable I2Cx Peripheral */
+ I2Cx->CR1 &= (uint32_t)~((uint32_t)I2C_CR1_PE);
+
+ /*---------------------------- I2Cx FILTERS Configuration ------------------*/
+ /* Get the I2Cx CR1 value */
+ tmpreg = I2Cx->CR1;
+ /* Clear I2Cx CR1 register */
+ tmpreg &= CR1_CLEAR_MASK;
+ /* Configure I2Cx: analog and digital filter */
+ /* Set ANFOFF bit according to I2C_AnalogFilter value */
+ /* Set DFN bits according to I2C_DigitalFilter value */
+ tmpreg |= (uint32_t)I2C_InitStruct->I2C_AnalogFilter |(I2C_InitStruct->I2C_DigitalFilter << 8);
+
+ /* Write to I2Cx CR1 */
+ I2Cx->CR1 = tmpreg;
+
+ /*---------------------------- I2Cx TIMING Configuration -------------------*/
+ /* Configure I2Cx: Timing */
+ /* Set TIMINGR bits according to I2C_Timing */
+ /* Write to I2Cx TIMING */
+ I2Cx->TIMINGR = I2C_InitStruct->I2C_Timing & TIMING_CLEAR_MASK;
+
+ /* Enable I2Cx Peripheral */
+ I2Cx->CR1 |= I2C_CR1_PE;
+
+ /*---------------------------- I2Cx OAR1 Configuration ---------------------*/
+ /* Clear tmpreg local variable */
+ tmpreg = 0;
+ /* Clear OAR1 register */
+ I2Cx->OAR1 = (uint32_t)tmpreg;
+ /* Clear OAR2 register */
+ I2Cx->OAR2 = (uint32_t)tmpreg;
+ /* Configure I2Cx: Own Address1 and acknowledged address */
+ /* Set OA1MODE bit according to I2C_AcknowledgedAddress value */
+ /* Set OA1 bits according to I2C_OwnAddress1 value */
+ tmpreg = (uint32_t)((uint32_t)I2C_InitStruct->I2C_AcknowledgedAddress | \
+ (uint32_t)I2C_InitStruct->I2C_OwnAddress1);
+ /* Write to I2Cx OAR1 */
+ I2Cx->OAR1 = tmpreg;
+ /* Enable Own Address1 acknowledgement */
+ I2Cx->OAR1 |= I2C_OAR1_OA1EN;
+
+ /*---------------------------- I2Cx MODE Configuration ---------------------*/
+ /* Configure I2Cx: mode */
+ /* Set SMBDEN and SMBHEN bits according to I2C_Mode value */
+ tmpreg = I2C_InitStruct->I2C_Mode;
+ /* Write to I2Cx CR1 */
+ I2Cx->CR1 |= tmpreg;
+
+ /*---------------------------- I2Cx ACK Configuration ----------------------*/
+ /* Get the I2Cx CR2 value */
+ tmpreg = I2Cx->CR2;
+ /* Clear I2Cx CR2 register */
+ tmpreg &= CR2_CLEAR_MASK;
+ /* Configure I2Cx: acknowledgement */
+ /* Set NACK bit according to I2C_Ack value */
+ tmpreg |= I2C_InitStruct->I2C_Ack;
+ /* Write to I2Cx CR2 */
+ I2Cx->CR2 = tmpreg;
+}
+
+/**
+ * @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_Timing member */
+ I2C_InitStruct->I2C_Timing = 0;
+ /* Initialize the I2C_AnalogFilter member */
+ I2C_InitStruct->I2C_AnalogFilter = I2C_AnalogFilter_Enable;
+ /* Initialize the I2C_DigitalFilter member */
+ I2C_InitStruct->I2C_DigitalFilter = 0;
+ /* Initialize the I2C_Mode member */
+ I2C_InitStruct->I2C_Mode = I2C_Mode_I2C;
+ /* 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 or 2 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 &= (uint32_t)~((uint32_t)I2C_CR1_PE);
+ }
+}
+
+
+/**
+ * @brief Enables or disables the specified I2C software reset.
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * @retval None
+ */
+void I2C_SoftwareResetCmd(I2C_TypeDef* I2Cx)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+
+ /* Disable peripheral */
+ I2Cx->CR1 &= (uint32_t)~((uint32_t)I2C_CR1_PE);
+
+ /* Perform a dummy read to delay the disable of peripheral for minimum
+ 3 APB clock cycles to perform the software reset functionality */
+ *(__IO uint32_t *)(uint32_t)I2Cx;
+
+ /* Enable peripheral */
+ I2Cx->CR1 |= I2C_CR1_PE;
+}
+
+/**
+ * @brief Enables or disables the specified I2C interrupts.
+ * @param I2Cx: where x can be 1 or 2 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_ERRI: Error interrupt mask
+ * @arg I2C_IT_TCI: Transfer Complete interrupt mask
+ * @arg I2C_IT_STOPI: Stop Detection interrupt mask
+ * @arg I2C_IT_NACKI: Not Acknowledge received interrupt mask
+ * @arg I2C_IT_ADDRI: Address Match interrupt mask
+ * @arg I2C_IT_RXI: RX interrupt mask
+ * @arg I2C_IT_TXI: TX 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, uint32_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->CR1 |= I2C_IT;
+ }
+ else
+ {
+ /* Disable the selected I2C interrupts */
+ I2Cx->CR1 &= (uint32_t)~((uint32_t)I2C_IT);
+ }
+}
+
+/**
+ * @brief Enables or disables the I2C Clock stretching.
+ * @param I2Cx: where x can be 1 or 2 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 clock stretching */
+ I2Cx->CR1 &= (uint32_t)~((uint32_t)I2C_CR1_NOSTRETCH);
+ }
+ else
+ {
+ /* Disable clock stretching */
+ I2Cx->CR1 |= I2C_CR1_NOSTRETCH;
+ }
+}
+
+/**
+ * @brief Enables or disables I2C wakeup from stop mode.
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * @param NewState: new state of the I2Cx stop mode.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void I2C_StopModeCmd(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 wakeup from stop mode */
+ I2Cx->CR1 |= I2C_CR1_WUPEN;
+ }
+ else
+ {
+ /* Disable wakeup from stop mode */
+ I2Cx->CR1 &= (uint32_t)~((uint32_t)I2C_CR1_WUPEN);
+ }
+}
+
+/**
+ * @brief Enables or disables the I2C own address 2.
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * @param NewState: new state of the I2C own address 2.
+ * 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 own address 2 */
+ I2Cx->OAR2 |= I2C_OAR2_OA2EN;
+ }
+ else
+ {
+ /* Disable own address 2 */
+ I2Cx->OAR2 &= (uint32_t)~((uint32_t)I2C_OAR2_OA2EN);
+ }
+}
+
+/**
+ * @brief Configures the I2C slave own address 2 and mask.
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * @param Address: specifies the slave address to be programmed.
+ * @param Mask: specifies own address 2 mask to be programmed.
+ * This parameter can be one of the following values:
+ * @arg I2C_OA2_NoMask: no mask.
+ * @arg I2C_OA2_Mask01: OA2[1] is masked and don't care.
+ * @arg I2C_OA2_Mask02: OA2[2:1] are masked and don't care.
+ * @arg I2C_OA2_Mask03: OA2[3:1] are masked and don't care.
+ * @arg I2C_OA2_Mask04: OA2[4:1] are masked and don't care.
+ * @arg I2C_OA2_Mask05: OA2[5:1] are masked and don't care.
+ * @arg I2C_OA2_Mask06: OA2[6:1] are masked and don't care.
+ * @arg I2C_OA2_Mask07: OA2[7:1] are masked and don't care.
+ * @retval None
+ */
+void I2C_OwnAddress2Config(I2C_TypeDef* I2Cx, uint16_t Address, uint8_t Mask)
+{
+ uint32_t tmpreg = 0;
+
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(IS_I2C_OWN_ADDRESS2(Address));
+ assert_param(IS_I2C_OWN_ADDRESS2_MASK(Mask));
+
+ /* Get the old register value */
+ tmpreg = I2Cx->OAR2;
+
+ /* Reset I2Cx OA2 bit [7:1] and OA2MSK bit [1:0] */
+ tmpreg &= (uint32_t)~((uint32_t)(I2C_OAR2_OA2 | I2C_OAR2_OA2MSK));
+
+ /* Set I2Cx SADD */
+ tmpreg |= (uint32_t)(((uint32_t)Address & I2C_OAR2_OA2) | \
+ (((uint32_t)Mask << 8) & I2C_OAR2_OA2MSK)) ;
+
+ /* Store the new register value */
+ I2Cx->OAR2 = tmpreg;
+}
+
+/**
+ * @brief Enables or disables the I2C general call mode.
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * @param NewState: new state of the I2C general call mode.
+ * 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 general call mode */
+ I2Cx->CR1 |= I2C_CR1_GCEN;
+ }
+ else
+ {
+ /* Disable general call mode */
+ I2Cx->CR1 &= (uint32_t)~((uint32_t)I2C_CR1_GCEN);
+ }
+}
+
+/**
+ * @brief Enables or disables the I2C slave byte control.
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * @param NewState: new state of the I2C slave byte control.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void I2C_SlaveByteControlCmd(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 slave byte control */
+ I2Cx->CR1 |= I2C_CR1_SBC;
+ }
+ else
+ {
+ /* Disable slave byte control */
+ I2Cx->CR1 &= (uint32_t)~((uint32_t)I2C_CR1_SBC);
+ }
+}
+
+/**
+ * @brief Configures the slave address to be transmitted after start generation.
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * @param Address: specifies the slave address to be programmed.
+ * @note This function should be called before generating start condition.
+ * @retval None
+ */
+void I2C_SlaveAddressConfig(I2C_TypeDef* I2Cx, uint16_t Address)
+{
+ uint32_t tmpreg = 0;
+
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(IS_I2C_SLAVE_ADDRESS(Address));
+
+ /* Get the old register value */
+ tmpreg = I2Cx->CR2;
+
+ /* Reset I2Cx SADD bit [9:0] */
+ tmpreg &= (uint32_t)~((uint32_t)I2C_CR2_SADD);
+
+ /* Set I2Cx SADD */
+ tmpreg |= (uint32_t)((uint32_t)Address & I2C_CR2_SADD);
+
+ /* Store the new register value */
+ I2Cx->CR2 = tmpreg;
+}
+
+/**
+ * @brief Enables or disables the I2C 10-bit addressing mode for the master.
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * @param NewState: new state of the I2C 10-bit addressing mode.
+ * This parameter can be: ENABLE or DISABLE.
+ * @note This function should be called before generating start condition.
+ * @retval None
+ */
+void I2C_10BitAddressingModeCmd(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 10-bit addressing mode */
+ I2Cx->CR2 |= I2C_CR2_ADD10;
+ }
+ else
+ {
+ /* Disable 10-bit addressing mode */
+ I2Cx->CR2 &= (uint32_t)~((uint32_t)I2C_CR2_ADD10);
+ }
+}
+
+/**
+ * @}
+ */
+
+
+/** @defgroup I2C_Group2 Communications handling functions
+ * @brief Communications handling functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Communications handling functions #####
+ ===============================================================================
+ [..] This section provides a set of functions that handles I2C communication.
+
+ [..] Automatic End mode is enabled using I2C_AutoEndCmd() function. When Reload
+ mode is enabled via I2C_ReloadCmd() AutoEnd bit has no effect.
+
+ [..] I2C_NumberOfBytesConfig() function set the number of bytes to be transferred,
+ this configuration should be done before generating start condition in master
+ mode.
+
+ [..] When switching from master write operation to read operation in 10Bit addressing
+ mode, master can only sends the 1st 7 bits of the 10 bit address, followed by
+ Read direction by enabling HEADR bit using I2C_10BitAddressHeader() function.
+
+ [..] In master mode, when transferring more than 255 bytes Reload mode should be used
+ to handle communication. In the first phase of transfer, Nbytes should be set to
+ 255. After transferring these bytes TCR flag is set and I2C_TransferHandling()
+ function should be called to handle remaining communication.
+
+ [..] In master mode, when software end mode is selected when all data is transferred
+ TC flag is set I2C_TransferHandling() function should be called to generate STOP
+ or generate ReStart.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Enables or disables the I2C automatic end mode (stop condition is
+ * automatically sent when nbytes data are transferred).
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * @param NewState: new state of the I2C automatic end mode.
+ * This parameter can be: ENABLE or DISABLE.
+ * @note This function has effect if Reload mode is disabled.
+ * @retval None
+ */
+void I2C_AutoEndCmd(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 Auto end mode */
+ I2Cx->CR2 |= I2C_CR2_AUTOEND;
+ }
+ else
+ {
+ /* Disable Auto end mode */
+ I2Cx->CR2 &= (uint32_t)~((uint32_t)I2C_CR2_AUTOEND);
+ }
+}
+
+/**
+ * @brief Enables or disables the I2C nbytes reload mode.
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * @param NewState: new state of the nbytes reload mode.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void I2C_ReloadCmd(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 Auto Reload mode */
+ I2Cx->CR2 |= I2C_CR2_RELOAD;
+ }
+ else
+ {
+ /* Disable Auto Reload mode */
+ I2Cx->CR2 &= (uint32_t)~((uint32_t)I2C_CR2_RELOAD);
+ }
+}
+
+/**
+ * @brief Configures the number of bytes to be transmitted/received.
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * @param Number_Bytes: specifies the number of bytes to be programmed.
+ * @retval None
+ */
+void I2C_NumberOfBytesConfig(I2C_TypeDef* I2Cx, uint8_t Number_Bytes)
+{
+ uint32_t tmpreg = 0;
+
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+
+ /* Get the old register value */
+ tmpreg = I2Cx->CR2;
+
+ /* Reset I2Cx Nbytes bit [7:0] */
+ tmpreg &= (uint32_t)~((uint32_t)I2C_CR2_NBYTES);
+
+ /* Set I2Cx Nbytes */
+ tmpreg |= (uint32_t)(((uint32_t)Number_Bytes << 16 ) & I2C_CR2_NBYTES);
+
+ /* Store the new register value */
+ I2Cx->CR2 = tmpreg;
+}
+
+/**
+ * @brief Configures the type of transfer request for the master.
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * @param I2C_Direction: specifies the transfer request direction to be programmed.
+ * This parameter can be one of the following values:
+ * @arg I2C_Direction_Transmitter: Master request a write transfer
+ * @arg I2C_Direction_Receiver: Master request a read transfer
+ * @retval None
+ */
+void I2C_MasterRequestConfig(I2C_TypeDef* I2Cx, uint16_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)
+ {
+ /* Request a write Transfer */
+ I2Cx->CR2 &= (uint32_t)~((uint32_t)I2C_CR2_RD_WRN);
+ }
+ else
+ {
+ /* Request a read Transfer */
+ I2Cx->CR2 |= I2C_CR2_RD_WRN;
+ }
+}
+
+/**
+ * @brief Generates I2Cx communication START condition.
+ * @param I2Cx: where x can be 1 or 2 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->CR2 |= I2C_CR2_START;
+ }
+ else
+ {
+ /* Disable the START condition generation */
+ I2Cx->CR2 &= (uint32_t)~((uint32_t)I2C_CR2_START);
+ }
+}
+
+/**
+ * @brief Generates I2Cx communication STOP condition.
+ * @param I2Cx: where x can be 1 or 2 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->CR2 |= I2C_CR2_STOP;
+ }
+ else
+ {
+ /* Disable the STOP condition generation */
+ I2Cx->CR2 &= (uint32_t)~((uint32_t)I2C_CR2_STOP);
+ }
+}
+
+/**
+ * @brief Enables or disables the I2C 10-bit header only mode with read direction.
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * @param NewState: new state of the I2C 10-bit header only mode.
+ * This parameter can be: ENABLE or DISABLE.
+ * @note This mode can be used only when switching from master transmitter mode
+ * to master receiver mode.
+ * @retval None
+ */
+void I2C_10BitAddressHeaderCmd(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 10-bit header only mode */
+ I2Cx->CR2 |= I2C_CR2_HEAD10R;
+ }
+ else
+ {
+ /* Disable 10-bit header only mode */
+ I2Cx->CR2 &= (uint32_t)~((uint32_t)I2C_CR2_HEAD10R);
+ }
+}
+
+/**
+ * @brief Generates I2C communication Acknowledge.
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * @param NewState: new state of the Acknowledge.
+ * 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 ACK generation */
+ I2Cx->CR2 &= (uint32_t)~((uint32_t)I2C_CR2_NACK);
+ }
+ else
+ {
+ /* Enable NACK generation */
+ I2Cx->CR2 |= I2C_CR2_NACK;
+ }
+}
+
+/**
+ * @brief Returns the I2C slave matched address .
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * @retval The value of the slave matched address .
+ */
+uint8_t I2C_GetAddressMatched(I2C_TypeDef* I2Cx)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+
+ /* Return the slave matched address in the SR1 register */
+ return (uint8_t)(((uint32_t)I2Cx->ISR & I2C_ISR_ADDCODE) >> 16) ;
+}
+
+/**
+ * @brief Returns the I2C slave received request.
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * @retval The value of the received request.
+ */
+uint16_t I2C_GetTransferDirection(I2C_TypeDef* I2Cx)
+{
+ uint32_t tmpreg = 0;
+ uint16_t direction = 0;
+
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+
+ /* Return the slave matched address in the SR1 register */
+ tmpreg = (uint32_t)(I2Cx->ISR & I2C_ISR_DIR);
+
+ /* If write transfer is requested */
+ if (tmpreg == 0)
+ {
+ /* write transfer is requested */
+ direction = I2C_Direction_Transmitter;
+ }
+ else
+ {
+ /* Read transfer is requested */
+ direction = I2C_Direction_Receiver;
+ }
+ return direction;
+}
+
+/**
+ * @brief Handles I2Cx communication when starting transfer or during transfer (TC or TCR flag are set).
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * @param Address: specifies the slave address to be programmed.
+ * @param Number_Bytes: specifies the number of bytes to be programmed.
+ * This parameter must be a value between 0 and 255.
+ * @param ReloadEndMode: new state of the I2C START condition generation.
+ * This parameter can be one of the following values:
+ * @arg I2C_Reload_Mode: Enable Reload mode .
+ * @arg I2C_AutoEnd_Mode: Enable Automatic end mode.
+ * @arg I2C_SoftEnd_Mode: Enable Software end mode.
+ * @param StartStopMode: new state of the I2C START condition generation.
+ * This parameter can be one of the following values:
+ * @arg I2C_No_StartStop: Don't Generate stop and start condition.
+ * @arg I2C_Generate_Stop: Generate stop condition (Number_Bytes should be set to 0).
+ * @arg I2C_Generate_Start_Read: Generate Restart for read request.
+ * @arg I2C_Generate_Start_Write: Generate Restart for write request.
+ * @retval None
+ */
+void I2C_TransferHandling(I2C_TypeDef* I2Cx, uint16_t Address, uint8_t Number_Bytes, uint32_t ReloadEndMode, uint32_t StartStopMode)
+{
+ uint32_t tmpreg = 0;
+
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(IS_I2C_SLAVE_ADDRESS(Address));
+ assert_param(IS_RELOAD_END_MODE(ReloadEndMode));
+ assert_param(IS_START_STOP_MODE(StartStopMode));
+
+ /* Get the CR2 register value */
+ tmpreg = I2Cx->CR2;
+
+ /* clear tmpreg specific bits */
+ tmpreg &= (uint32_t)~((uint32_t)(I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RELOAD | I2C_CR2_AUTOEND | I2C_CR2_RD_WRN | I2C_CR2_START | I2C_CR2_STOP));
+
+ /* update tmpreg */
+ tmpreg |= (uint32_t)(((uint32_t)Address & I2C_CR2_SADD) | (((uint32_t)Number_Bytes << 16 ) & I2C_CR2_NBYTES) | \
+ (uint32_t)ReloadEndMode | (uint32_t)StartStopMode);
+
+ /* update CR2 register */
+ I2Cx->CR2 = tmpreg;
+}
+
+/**
+ * @}
+ */
+
+
+/** @defgroup I2C_Group3 SMBUS management functions
+ * @brief SMBUS management functions
+ *
+@verbatim
+ ===============================================================================
+ ##### SMBUS management functions #####
+ ===============================================================================
+ [..] This section provides a set of functions that handles SMBus communication
+ and timeouts detection.
+
+ [..] The SMBus Device default address (0b1100 001) is enabled by calling I2C_Init()
+ function and setting I2C_Mode member of I2C_InitTypeDef() structure to
+ I2C_Mode_SMBusDevice.
+
+ [..] The SMBus Host address (0b0001 000) is enabled by calling I2C_Init()
+ function and setting I2C_Mode member of I2C_InitTypeDef() structure to
+ I2C_Mode_SMBusHost.
+
+ [..] The Alert Response Address (0b0001 100) is enabled using I2C_SMBusAlertCmd()
+ function.
+
+ [..] To detect cumulative SCL stretch in master and slave mode, TIMEOUTB should be
+ configured (in accordance to SMBus specification) using I2C_TimeoutBConfig()
+ function then I2C_ExtendedClockTimeoutCmd() function should be called to enable
+ the detection.
+
+ [..] SCL low timeout is detected by configuring TIMEOUTB using I2C_TimeoutBConfig()
+ function followed by the call of I2C_ClockTimeoutCmd(). When adding to this
+ procedure the call of I2C_IdleClockTimeoutCmd() function, Bus Idle condition
+ (both SCL and SDA high) is detected also.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Enables or disables I2C SMBus alert.
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * @param NewState: new state of the I2Cx SMBus alert.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void I2C_SMBusAlertCmd(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 SMBus alert */
+ I2Cx->CR1 |= I2C_CR1_ALERTEN;
+ }
+ else
+ {
+ /* Disable SMBus alert */
+ I2Cx->CR1 &= (uint32_t)~((uint32_t)I2C_CR1_ALERTEN);
+ }
+}
+
+/**
+ * @brief Enables or disables I2C Clock Timeout (SCL Timeout detection).
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * @param NewState: new state of the I2Cx clock Timeout.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void I2C_ClockTimeoutCmd(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 Clock Timeout */
+ I2Cx->TIMEOUTR |= I2C_TIMEOUTR_TIMOUTEN;
+ }
+ else
+ {
+ /* Disable Clock Timeout */
+ I2Cx->TIMEOUTR &= (uint32_t)~((uint32_t)I2C_TIMEOUTR_TIMOUTEN);
+ }
+}
+
+/**
+ * @brief Enables or disables I2C Extended Clock Timeout (SCL cumulative Timeout detection).
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * @param NewState: new state of the I2Cx Extended clock Timeout.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void I2C_ExtendedClockTimeoutCmd(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 Clock Timeout */
+ I2Cx->TIMEOUTR |= I2C_TIMEOUTR_TEXTEN;
+ }
+ else
+ {
+ /* Disable Clock Timeout */
+ I2Cx->TIMEOUTR &= (uint32_t)~((uint32_t)I2C_TIMEOUTR_TEXTEN);
+ }
+}
+
+/**
+ * @brief Enables or disables I2C Idle Clock Timeout (Bus idle SCL and SDA
+ * high detection).
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * @param NewState: new state of the I2Cx Idle clock Timeout.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void I2C_IdleClockTimeoutCmd(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 Clock Timeout */
+ I2Cx->TIMEOUTR |= I2C_TIMEOUTR_TIDLE;
+ }
+ else
+ {
+ /* Disable Clock Timeout */
+ I2Cx->TIMEOUTR &= (uint32_t)~((uint32_t)I2C_TIMEOUTR_TIDLE);
+ }
+}
+
+/**
+ * @brief Configures the I2C Bus Timeout A (SCL Timeout when TIDLE = 0 or Bus
+ * idle SCL and SDA high when TIDLE = 1).
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * @param Timeout: specifies the TimeoutA to be programmed.
+ * @retval None
+ */
+void I2C_TimeoutAConfig(I2C_TypeDef* I2Cx, uint16_t Timeout)
+{
+ uint32_t tmpreg = 0;
+
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(IS_I2C_TIMEOUT(Timeout));
+
+ /* Get the old register value */
+ tmpreg = I2Cx->TIMEOUTR;
+
+ /* Reset I2Cx TIMEOUTA bit [11:0] */
+ tmpreg &= (uint32_t)~((uint32_t)I2C_TIMEOUTR_TIMEOUTA);
+
+ /* Set I2Cx TIMEOUTA */
+ tmpreg |= (uint32_t)((uint32_t)Timeout & I2C_TIMEOUTR_TIMEOUTA) ;
+
+ /* Store the new register value */
+ I2Cx->TIMEOUTR = tmpreg;
+}
+
+/**
+ * @brief Configures the I2C Bus Timeout B (SCL cumulative Timeout).
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * @param Timeout: specifies the TimeoutB to be programmed.
+ * @retval None
+ */
+void I2C_TimeoutBConfig(I2C_TypeDef* I2Cx, uint16_t Timeout)
+{
+ uint32_t tmpreg = 0;
+
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(IS_I2C_TIMEOUT(Timeout));
+
+ /* Get the old register value */
+ tmpreg = I2Cx->TIMEOUTR;
+
+ /* Reset I2Cx TIMEOUTB bit [11:0] */
+ tmpreg &= (uint32_t)~((uint32_t)I2C_TIMEOUTR_TIMEOUTB);
+
+ /* Set I2Cx TIMEOUTB */
+ tmpreg |= (uint32_t)(((uint32_t)Timeout << 16) & I2C_TIMEOUTR_TIMEOUTB) ;
+
+ /* Store the new register value */
+ I2Cx->TIMEOUTR = tmpreg;
+}
+
+/**
+ * @brief Enables or disables I2C PEC calculation.
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * @param NewState: new state of the I2Cx PEC 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 PEC calculation */
+ I2Cx->CR1 |= I2C_CR1_PECEN;
+ }
+ else
+ {
+ /* Disable PEC calculation */
+ I2Cx->CR1 &= (uint32_t)~((uint32_t)I2C_CR1_PECEN);
+ }
+}
+
+/**
+ * @brief Enables or disables I2C PEC transmission/reception request.
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * @param NewState: new state of the I2Cx PEC request.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void I2C_PECRequestCmd(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 PEC transmission/reception request */
+ I2Cx->CR1 |= I2C_CR2_PECBYTE;
+ }
+ else
+ {
+ /* Disable PEC transmission/reception request */
+ I2Cx->CR1 &= (uint32_t)~((uint32_t)I2C_CR2_PECBYTE);
+ }
+}
+
+/**
+ * @brief Returns the I2C PEC.
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * @retval The value of the PEC .
+ */
+uint8_t I2C_GetPEC(I2C_TypeDef* I2Cx)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+
+ /* Return the slave matched address in the SR1 register */
+ return (uint8_t)((uint32_t)I2Cx->PECR & I2C_PECR_PEC);
+}
+
+/**
+ * @}
+ */
+
+
+/** @defgroup I2C_Group4 I2C registers management functions
+ * @brief I2C registers management functions
+ *
+@verbatim
+ ===============================================================================
+ ##### I2C registers management functions #####
+ ===============================================================================
+ [..] This section provides a functions that allow user the management of
+ I2C registers.
+
+@endverbatim
+ * @{
+ */
+
+ /**
+ * @brief Reads the specified I2C register and returns its value.
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * @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_TIMINGR: TIMING register.
+ * @arg I2C_Register_TIMEOUTR: TIMEOUTR register.
+ * @arg I2C_Register_ISR: ISR register.
+ * @arg I2C_Register_ICR: ICR register.
+ * @arg I2C_Register_PECR: PECR register.
+ * @arg I2C_Register_RXDR: RXDR register.
+ * @arg I2C_Register_TXDR: TXDR register.
+ * @retval The value of the read register.
+ */
+uint32_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 uint32_t *) tmp);
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup I2C_Group5 Data transfers management functions
+ * @brief Data transfers management functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Data transfers management functions #####
+ ===============================================================================
+ [..] This subsection provides a set of functions allowing to manage
+ the I2C data transfers.
+
+ [..] The read access of the I2C_RXDR register can be done using
+ the I2C_ReceiveData() function and returns the received value.
+ Whereas a write access to the I2C_TXDR can be done using I2C_SendData()
+ function and stores the written data into TXDR.
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Sends a data byte through the I2Cx peripheral.
+ * @param I2Cx: where x can be 1 or 2 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->TXDR = (uint8_t)Data;
+}
+
+/**
+ * @brief Returns the most recent received data by the I2Cx peripheral.
+ * @param I2Cx: where x can be 1 or 2 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->RXDR;
+}
+
+/**
+ * @}
+ */
+
+
+/** @defgroup I2C_Group6 DMA transfers management functions
+ * @brief DMA transfers management functions
+ *
+@verbatim
+ ===============================================================================
+ ##### DMA transfers management functions #####
+ ===============================================================================
+ [..] This section provides two functions that can be used only in DMA mode.
+ [..] In DMA Mode, the I2C communication can be managed by 2 DMA Channel
+ requests:
+ (#) I2C_DMAReq_Tx: specifies the Tx buffer DMA transfer request.
+ (#) I2C_DMAReq_Rx: specifies the Rx buffer DMA transfer request.
+ [..] In this Mode it is advised to use the following function:
+ (+) I2C_DMACmd(I2C_TypeDef* I2Cx, uint32_t I2C_DMAReq, FunctionalState NewState);
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Enables or disables the I2C DMA interface.
+ * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
+ * @param I2C_DMAReq: specifies the I2C DMA transfer request to be enabled or disabled.
+ * This parameter can be any combination of the following values:
+ * @arg I2C_DMAReq_Tx: Tx DMA transfer request
+ * @arg I2C_DMAReq_Rx: Rx DMA transfer request
+ * @param NewState: new state of the selected I2C DMA transfer request.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void I2C_DMACmd(I2C_TypeDef* I2Cx, uint32_t I2C_DMAReq, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ assert_param(IS_I2C_DMA_REQ(I2C_DMAReq));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the selected I2C DMA requests */
+ I2Cx->CR1 |= I2C_DMAReq;
+ }
+ else
+ {
+ /* Disable the selected I2C DMA requests */
+ I2Cx->CR1 &= (uint32_t)~I2C_DMAReq;
+ }
+}
+/**
+ * @}
+ */
+
+
+/** @defgroup I2C_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 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(refer I2C_Group6).
+
+ *** Polling Mode ***
+ ====================
+ [..] In Polling Mode, the I2C communication can be managed by 15 flags:
+ (#) I2C_FLAG_TXE: to indicate the status of Transmit data register empty flag.
+ (#) I2C_FLAG_TXIS: to indicate the status of Transmit interrupt status flag .
+ (#) I2C_FLAG_RXNE: to indicate the status of Receive data register not empty flag.
+ (#) I2C_FLAG_ADDR: to indicate the status of Address matched flag (slave mode).
+ (#) I2C_FLAG_NACKF: to indicate the status of NACK received flag.
+ (#) I2C_FLAG_STOPF: to indicate the status of STOP detection flag.
+ (#) I2C_FLAG_TC: to indicate the status of Transfer complete flag(master mode).
+ (#) I2C_FLAG_TCR: to indicate the status of Transfer complete reload flag.
+ (#) I2C_FLAG_BERR: to indicate the status of Bus error flag.
+ (#) I2C_FLAG_ARLO: to indicate the status of Arbitration lost flag.
+ (#) I2C_FLAG_OVR: to indicate the status of Overrun/Underrun flag.
+ (#) I2C_FLAG_PECERR: to indicate the status of PEC error in reception flag.
+ (#) I2C_FLAG_TIMEOUT: to indicate the status of Timeout or Tlow detection flag.
+ (#) I2C_FLAG_ALERT: to indicate the status of SMBus Alert flag.
+ (#) I2C_FLAG_BUSY: to indicate the status of Bus busy flag.
+
+ [..] In this Mode it is advised to use the following functions:
+ (+) FlagStatus I2C_GetFlagStatus(I2C_TypeDef* I2Cx, uint32_t I2C_FLAG);
+ (+) void I2C_ClearFlag(I2C_TypeDef* I2Cx, uint32_t I2C_FLAG);
+
+ [..]
+ (@)Do not use the BUSY flag to handle each data transmission or reception.It is
+ better to use the TXIS and RXNE flags instead.
+
+ *** Interrupt Mode ***
+ ======================
+ [..] In Interrupt Mode, the I2C communication can be managed by 7 interrupt sources
+ and 15 pending bits:
+ [..] Interrupt Source:
+ (#) I2C_IT_ERRI: specifies the interrupt source for the Error interrupt.
+ (#) I2C_IT_TCI: specifies the interrupt source for the Transfer Complete interrupt.
+ (#) I2C_IT_STOPI: specifies the interrupt source for the Stop Detection interrupt.
+ (#) I2C_IT_NACKI: specifies the interrupt source for the Not Acknowledge received interrupt.
+ (#) I2C_IT_ADDRI: specifies the interrupt source for the Address Match interrupt.
+ (#) I2C_IT_RXI: specifies the interrupt source for the RX interrupt.
+ (#) I2C_IT_TXI: specifies the interrupt source for the TX interrupt.
+
+ [..] Pending Bits:
+ (#) I2C_IT_TXIS: to indicate the status of Transmit interrupt status flag.
+ (#) I2C_IT_RXNE: to indicate the status of Receive data register not empty flag.
+ (#) I2C_IT_ADDR: to indicate the status of Address matched flag (slave mode).
+ (#) I2C_IT_NACKF: to indicate the status of NACK received flag.
+ (#) I2C_IT_STOPF: to indicate the status of STOP detection flag.
+ (#) I2C_IT_TC: to indicate the status of Transfer complete flag (master mode).
+ (#) I2C_IT_TCR: to indicate the status of Transfer complete reload flag.
+ (#) I2C_IT_BERR: to indicate the status of Bus error flag.
+ (#) I2C_IT_ARLO: to indicate the status of Arbitration lost flag.
+ (#) I2C_IT_OVR: to indicate the status of Overrun/Underrun flag.
+ (#) I2C_IT_PECERR: to indicate the status of PEC error in reception flag.
+ (#) I2C_IT_TIMEOUT: to indicate the status of Timeout or Tlow detection flag.
+ (#) I2C_IT_ALERT: to indicate the status of SMBus Alert flag.
+
+ [..] In this Mode it is advised to use the following functions:
+ (+) void I2C_ClearITPendingBit(I2C_TypeDef* I2Cx, uint32_t I2C_IT);
+ (+) ITStatus I2C_GetITStatus(I2C_TypeDef* I2Cx, uint32_t I2C_IT);
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Checks whether the specified I2C flag is set or not.
+ * @param I2Cx: where x can be 1 or 2 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_TXE: Transmit data register empty
+ * @arg I2C_FLAG_TXIS: Transmit interrupt status
+ * @arg I2C_FLAG_RXNE: Receive data register not empty
+ * @arg I2C_FLAG_ADDR: Address matched (slave mode)
+ * @arg I2C_FLAG_NACKF: NACK received flag
+ * @arg I2C_FLAG_STOPF: STOP detection flag
+ * @arg I2C_FLAG_TC: Transfer complete (master mode)
+ * @arg I2C_FLAG_TCR: Transfer complete reload
+ * @arg I2C_FLAG_BERR: Bus error
+ * @arg I2C_FLAG_ARLO: Arbitration lost
+ * @arg I2C_FLAG_OVR: Overrun/Underrun
+ * @arg I2C_FLAG_PECERR: PEC error in reception
+ * @arg I2C_FLAG_TIMEOUT: Timeout or Tlow detection flag
+ * @arg I2C_FLAG_ALERT: SMBus Alert
+ * @arg I2C_FLAG_BUSY: Bus busy
+ * @retval The new state of I2C_FLAG (SET or RESET).
+ */
+FlagStatus I2C_GetFlagStatus(I2C_TypeDef* I2Cx, uint32_t I2C_FLAG)
+{
+ uint32_t tmpreg = 0;
+ FlagStatus bitstatus = RESET;
+
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(IS_I2C_GET_FLAG(I2C_FLAG));
+
+ /* Get the ISR register value */
+ tmpreg = I2Cx->ISR;
+
+ /* Get flag status */
+ tmpreg &= I2C_FLAG;
+
+ if(tmpreg != 0)
+ {
+ /* I2C_FLAG is set */
+ bitstatus = SET;
+ }
+ else
+ {
+ /* I2C_FLAG is reset */
+ bitstatus = RESET;
+ }
+ return bitstatus;
+}
+
+/**
+ * @brief Clears the I2Cx's pending flags.
+ * @param I2Cx: where x can be 1 or 2 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_ADDR: Address matched (slave mode)
+ * @arg I2C_FLAG_NACKF: NACK received flag
+ * @arg I2C_FLAG_STOPF: STOP detection flag
+ * @arg I2C_FLAG_BERR: Bus error
+ * @arg I2C_FLAG_ARLO: Arbitration lost
+ * @arg I2C_FLAG_OVR: Overrun/Underrun
+ * @arg I2C_FLAG_PECERR: PEC error in reception
+ * @arg I2C_FLAG_TIMEOUT: Timeout or Tlow detection flag
+ * @arg I2C_FLAG_ALERT: SMBus Alert
+ * @retval The new state of I2C_FLAG (SET or RESET).
+ */
+void I2C_ClearFlag(I2C_TypeDef* I2Cx, uint32_t I2C_FLAG)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(IS_I2C_CLEAR_FLAG(I2C_FLAG));
+
+ /* Clear the selected flag */
+ I2Cx->ICR = I2C_FLAG;
+ }
+
+/**
+ * @brief Checks whether the specified I2C interrupt has occurred or not.
+ * @param I2Cx: where x can be 1 or 2 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_TXIS: Transmit interrupt status
+ * @arg I2C_IT_RXNE: Receive data register not empty
+ * @arg I2C_IT_ADDR: Address matched (slave mode)
+ * @arg I2C_IT_NACKF: NACK received flag
+ * @arg I2C_IT_STOPF: STOP detection flag
+ * @arg I2C_IT_TC: Transfer complete (master mode)
+ * @arg I2C_IT_TCR: Transfer complete reload
+ * @arg I2C_IT_BERR: Bus error
+ * @arg I2C_IT_ARLO: Arbitration lost
+ * @arg I2C_IT_OVR: Overrun/Underrun
+ * @arg I2C_IT_PECERR: PEC error in reception
+ * @arg I2C_IT_TIMEOUT: Timeout or Tlow detection flag
+ * @arg I2C_IT_ALERT: SMBus Alert
+ * @retval The new state of I2C_IT (SET or RESET).
+ */
+ITStatus I2C_GetITStatus(I2C_TypeDef* I2Cx, uint32_t I2C_IT)
+{
+ uint32_t tmpreg = 0;
+ 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 */
+ /* If Error interrupt */
+ if ((uint32_t)(I2C_IT & ERROR_IT_MASK))
+ {
+ enablestatus = (uint32_t)((I2C_CR1_ERRIE) & (I2Cx->CR1));
+ }
+ /* If TC interrupt */
+ else if ((uint32_t)(I2C_IT & TC_IT_MASK))
+ {
+ enablestatus = (uint32_t)((I2C_CR1_TCIE) & (I2Cx->CR1));
+ }
+ else
+ {
+ enablestatus = (uint32_t)((I2C_IT) & (I2Cx->CR1));
+ }
+
+ /* Get the ISR register value */
+ tmpreg = I2Cx->ISR;
+
+ /* Get flag status */
+ tmpreg &= I2C_IT;
+
+ /* Check the status of the specified I2C flag */
+ if((tmpreg != 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 or 2 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_ADDR: Address matched (slave mode)
+ * @arg I2C_IT_NACKF: NACK received flag
+ * @arg I2C_IT_STOPF: STOP detection flag
+ * @arg I2C_IT_BERR: Bus error
+ * @arg I2C_IT_ARLO: Arbitration lost
+ * @arg I2C_IT_OVR: Overrun/Underrun
+ * @arg I2C_IT_PECERR: PEC error in reception
+ * @arg I2C_IT_TIMEOUT: Timeout or Tlow detection flag
+ * @arg I2C_IT_ALERT: SMBus Alert
+ * @retval The new state of I2C_IT (SET or RESET).
+ */
+void I2C_ClearITPendingBit(I2C_TypeDef* I2Cx, uint32_t I2C_IT)
+{
+ /* Check the parameters */
+ assert_param(IS_I2C_ALL_PERIPH(I2Cx));
+ assert_param(IS_I2C_CLEAR_IT(I2C_IT));
+
+ /* Clear the selected flag */
+ I2Cx->ICR = I2C_IT;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Libraries/STM32F37x_StdPeriph_Driver/src/stm32f37x_iwdg.c b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Libraries/STM32F37x_StdPeriph_Driver/src/stm32f37x_iwdg.c
new file mode 100644
index 0000000..aa07736
--- /dev/null
+++ b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Libraries/STM32F37x_StdPeriph_Driver/src/stm32f37x_iwdg.c
@@ -0,0 +1,295 @@
+/**
+ ******************************************************************************
+ * @file stm32f37x_iwdg.c
+ * @author MCD Application Team
+ * @version V1.0.0
+ * @date 20-September-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 @40KHz (LSI): ~0.1ms / ~28.3s
+ The IWDG timeout may vary due to LSI frequency dispersion. STM32F37x
+ devices provide the capability to measure the LSI frequency (LSI clock
+ should be seleted as RTC clock which is internally connected to TIM14 CH1
+ input capture). The measured value can be used to have an IWDG timeout with
+ an acceptable accuracy.
+ For more information, please refer to the STM32F37x Reference manual.
+
+ ##### How to use this driver #####
+ ==============================================================================
+ [..] This driver allows to use IWDG peripheral with either window option enabled
+ or disabled. To do so follow one of the two procedures below.
+ (#) Window option is enabled:
+ (++) 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).
+ (++) Enable write access to IWDG_PR and IWDG_RLR registers using
+ IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable) function.
+ (++) Configure the IWDG prescaler using IWDG_SetPrescaler() function.
+ (++) 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.
+ (++) Wait for the IWDG registers to be updated using IWDG_GetFlagStatus() function.
+ (++) Configure the IWDG refresh window using IWDG_SetWindowValue() function.
+
+ (#) Window option is disabled:
+ (++) Enable write access to IWDG_PR and IWDG_RLR registers using
+ IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable) function.
+ (++) Configure the IWDG prescaler using IWDG_SetPrescaler() function.
+ (++) 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.
+ (++) Wait for the IWDG registers to be updated using IWDG_GetFlagStatus() function.
+ (++) reload the IWDG counter at regular intervals during normal operation
+ to prevent an MCU reset, using IWDG_ReloadCounter() function.
+ (++) 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).
+
+ @endverbatim
+ *
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
+ *
+ * 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 "stm32f37x_iwdg.h"
+
+/** @addtogroup STM32F37x_StdPeriph_Driver
+ * @{
+ */
+
+/** @defgroup IWDG
+ * @brief IWDG driver modules
+ * @{
+ */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* ---------------------- IWDG registers bit mask ----------------------------*/
+/* 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;
+}
+
+
+/**
+ * @brief Sets the IWDG window value.
+ * @param WindowValue: specifies the window value to be compared to the downcounter.
+ * @retval None
+ */
+void IWDG_SetWindowValue(uint16_t WindowValue)
+{
+ /* Check the parameters */
+ assert_param(IS_IWDG_WINDOW_VALUE(WindowValue));
+ IWDG->WINR = WindowValue;
+}
+
+/**
+ * @}
+ */
+
+/** @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
+ * @arg IWDG_FLAG_WVU: Counter Window 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/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Libraries/STM32F37x_StdPeriph_Driver/src/stm32f37x_pwr.c b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Libraries/STM32F37x_StdPeriph_Driver/src/stm32f37x_pwr.c
new file mode 100644
index 0000000..3cc59f0
--- /dev/null
+++ b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Libraries/STM32F37x_StdPeriph_Driver/src/stm32f37x_pwr.c
@@ -0,0 +1,589 @@
+/**
+ ******************************************************************************
+ * @file stm32f37x_pwr.c
+ * @author MCD Application Team
+ * @version V1.0.0
+ * @date 20-September-2012
+ * @brief This file provides firmware functions to manage the following
+ * functionalities of the Power Controller (PWR) peripheral:
+ * + Backup Domain Access
+ * + PVD configuration
+ * + WakeUp pins configuration
+ * + SDADC Analog configuration
+ * + Low Power modes configuration
+ * + Flags management
+ *
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
+ *
+ * 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 "stm32f37x_pwr.h"
+#include "stm32f37x_rcc.h"
+
+/** @addtogroup STM32F37x_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))
+
+/* ------------------ 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 Registers (RCC BDCR Register, RTC registers
+ and RTC backup registers) are protected against possible stray write accesses.
+ [..] To enable access to Backup domain use the PWR_BackupAccessCmd(ENABLE) 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 registers.
+ * @note If the HSE divided by 32 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 registers.
+ * 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 pins configuration functions
+ * @brief WakeUp pins configuration functions
+ *
+@verbatim
+ ==============================================================================
+ ##### WakeUp pin configuration functions #####
+ ==============================================================================
+
+ (+) WakeUp pins are used to wakeup the system from Standby mode. These pins are
+ forced in input pull down configuration and are active on rising edges.
+ (+) There are three WakeUp pins: WakeUp Pin 1 on PA.00, WakeUp Pin 2 on PC.13 and
+ WakeUp Pin 3 on PE.06.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Enables or disables the WakeUp Pin functionality.
+ * @param PWR_WakeUpPin: specifies the WakeUpPin.
+ * This parameter can be: PWR_WakeUpPin_1, PWR_WakeUpPin_2 or PWR_WakeUpPin_3.
+ * @param NewState: new state of the WakeUp Pin functionality.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void PWR_WakeUpPinCmd(uint32_t PWR_WakeUpPin, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_PWR_WAKEUP_PIN(PWR_WakeUpPin));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the EWUPx pin */
+ PWR->CSR |= PWR_WakeUpPin;
+ }
+ else
+ {
+ /* Disable the EWUPx pin */
+ PWR->CSR &= ~PWR_WakeUpPin;
+ }
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup PWR_Group4 SDADC Analog part configuration function
+ * @brief SDADC Analog configuration function
+ *
+@verbatim
+
+ ==============================================================================
+ ##### SDADC analog configuration functions #####
+ ==============================================================================
+ [..]
+ (+) The SDADC peripherals are per default in deep power down mode, in order to
+ be used their analog part should be enabled and though by calling the
+ PWR_SDADCAnalogCmd() function.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Enables or disables the WakeUp Pin functionality.
+ * @param PWR_SDADCAnalog: specifies the SDADC.
+ * This parameter can be: PWR_SDADCAnalog_1, PWR_SDADCAnalog_2 or PWR_SDADCAnalog_3.
+ * @param NewState: new state of the SDADC Analog functionality.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void PWR_SDADCAnalogCmd(uint32_t PWR_SDADCAnalog, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_PWR_SDADC_ANALOG(PWR_SDADCAnalog));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the SDADCx analog */
+ PWR->CR |= PWR_SDADCAnalog;
+ }
+ else
+ {
+ /* Disable the SDADCx analog */
+ PWR->CR &= ~PWR_SDADCAnalog;
+ }
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup PWR_Group5 Low Power modes configuration functions
+ * @brief Low Power modes configuration functions
+ *
+@verbatim
+ ==============================================================================
+ ##### Low Power modes configuration functions #####
+ ==============================================================================
+
+ [..] The devices feature three low-power modes:
+ (+) Sleep mode: Cortex-M4 core stopped, peripherals kept running.
+ (+) Stop mode: all clocks are stopped, regulator running, regulator in low power mode
+ (+) Standby mode: VCORE domain powered off
+
+ *** Sleep mode ***
+ ==================
+ [..]
+ (+) Entry:
+ (++) The Sleep mode is entered by executing the WFE() or WFI() instructions.
+ (+) 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 VCORE domain are stopped, the PLL, the HSI,
+ the HSI14 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.
+
+ (+) 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
+ or any internal IPs (I2C, UASRT or CEC) wakeup event.
+
+ *** Standby mode ***
+ ====================
+ [..] The Standby mode allows to achieve the lowest power consumption. It is based
+ on the Cortex-M4 deepsleep mode, with the voltage regulator disabled.
+ The VCORE domain is consequently powered off. The PLL, the HSI, the HSI14
+ oscillator and the HSE oscillator are also switched off. SRAM and register
+ contents are lost except for the Backup domain (RTC registers, RTC backup
+ registers 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, 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 19 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.
+
+ (+) 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.
+
+ (+) Comparator auto-wakeup (AWU) from the Stop mode
+ (++) To wake up from the Stop mode with an comparator 1 or comparator 2 wakeup
+ event, it is necessary to:
+ (+++) Configure the EXTI Line 21 for comparator 1 or EXTI Line 22 for comparator 2
+ to be sensitive to to the selected edges (falling, rising or falling
+ and rising) (Interrupt or Event modes) using the EXTI_Init() function.
+ (+++) Configure the comparator to generate the event.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Enters Sleep mode.
+ * @note In Sleep mode, all I/O pins keep the same state as in Run mode.
+ * @param PWR_SLEEPEntry: specifies if SLEEP mode in entered with WFI or WFE instruction.
+ * This parameter can be one of the following values:
+ * @arg PWR_SLEEPEntry_WFI: enter SLEEP mode with WFI instruction
+ * @arg PWR_SLEEPEntry_WFE: enter SLEEP mode with WFE instruction
+ * @retval None
+ */
+void PWR_EnterSleepMode(uint8_t PWR_SLEEPEntry)
+{
+ /* Check the parameters */
+ assert_param(IS_PWR_SLEEP_ENTRY(PWR_SLEEPEntry));
+
+ /* Clear SLEEPDEEP bit of Cortex-M4 System Control Register */
+ SCB->SCR &= (uint32_t)~((uint32_t)SCB_SCR_SLEEPDEEP_Msk);
+
+ /* Select SLEEP mode entry -------------------------------------------------*/
+ if(PWR_SLEEPEntry == PWR_SLEEPEntry_WFI)
+ {
+ /* Request Wait For Interrupt */
+ __WFI();
+ }
+ else
+ {
+ /* Request Wait For Event */
+ __WFE();
+ }
+}
+
+/**
+ * @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 Wakeup pin 2 (WKUP2), tamper,
+ * time-stamp, RTC Alarm out, or RTC clock calibration out.
+ * - WKUP pin 1 (PA0) and WKUP pin 3 (PE6), 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-M4 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_Group6 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.
+ * @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.
+ * @arg PWR_FLAG_VREFINTRDY: Internal Voltage Reference Ready flag. This
+ * flag indicates the state of the internal voltage reference, VREFINT.
+ * @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/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Libraries/STM32F37x_StdPeriph_Driver/src/stm32f37x_rcc.c b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Libraries/STM32F37x_StdPeriph_Driver/src/stm32f37x_rcc.c
new file mode 100644
index 0000000..934352d
--- /dev/null
+++ b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Libraries/STM32F37x_StdPeriph_Driver/src/stm32f37x_rcc.c
@@ -0,0 +1,1655 @@
+/**
+ ******************************************************************************
+ * @file stm32f37x_rcc.c
+ * @author MCD Application Team
+ * @version V1.0.0
+ * @date 20-September-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 HSI (8 MHz) with Flash 0 WS,
+ all peripherals are off except internal SRAM, Flash and SWD.
+ (#) 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 SWD 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 (SDADC, CEC, I2C, USART, RTC and IWDG)
+
+ @endverbatim
+
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
+ *
+ * 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 "stm32f37x_rcc.h"
+
+/** @addtogroup STM32F37x_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 PLLON bit */
+#define PLLON_BitNumber 0x18
+#define CR_PLLON_BB (PERIPH_BB_BASE + (CR_OFFSET * 32) + (PLLON_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))
+
+/* --- CFGR Register ---*/
+/* Alias word address of USBPRE bit */
+#define CFGR_OFFSET (RCC_OFFSET + 0x04)
+#define USBPRE_BitNumber 0x16
+#define CFGR_USBPRE_BB (PERIPH_BB_BASE + (CFGR_OFFSET * 32) + (USBPRE_BitNumber * 4))
+
+/* --- BDCR Register ---*/
+
+/* Alias word address of RTCEN bit */
+#define BDCR_OFFSET (RCC_OFFSET + 0x20)
+#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 + 0x24)
+#define LSION_BitNumber 0x00
+#define CSR_LSION_BB (PERIPH_BB_BASE + (CSR_OFFSET * 32) + (LSION_BitNumber * 4))
+
+/* ---------------------- RCC registers bit mask ------------------------ */
+/* RCC Flag Mask */
+#define FLAG_MASK ((uint8_t)0x1F)
+
+/* CFGR register byte 3 (Bits[31:23]) base address */
+#define CFGR_BYTE3_ADDRESS ((uint32_t)0x40021007)
+
+/* CIR register byte 2 (Bits[15:8]) base address */
+#define CIR_BYTE2_ADDRESS ((uint32_t)0x40021009)
+
+/* CIR register byte 3 (Bits[23:16]) base address */
+#define CIR_BYTE3_ADDRESS ((uint32_t)0x4002100A)
+
+/* CR register byte 2 (Bits[23:16]) base address */
+#define CR_BYTE2_ADDRESS ((uint32_t)0x40021002)
+
+/* 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};
+static __I uint8_t ADCPrescTable[4] = {2, 4, 6, 8};
+static __I uint8_t SDADCPrescTable[16] = {2, 4, 6, 8, 10, 12, 14, 16, 20, 24, 28, 32, 36, 40, 44, 48};
+
+/* 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 provides functions allowing to configure the internal/external clocks,
+ PLL, CSS and MCO.
+ (#) HSI (high-speed internal), 8 MHz factory-trimmed RC used directly
+ or through the PLL as System clock source.
+ The HSI clock can be used also to clock the USART, I2C and CEC peripherals.
+ (#) LSI (low-speed internal), 40 KHz low consumption RC used as IWDG and/or RTC
+ clock source.
+ (#) HSE (high-speed external), 4 to 72 MHz crystal oscillator used directly or
+ through the PLL as System clock source. Can be used also as RTC clock source.
+ (#) LSE (low-speed external), 32 KHz oscillator used as RTC clock source.
+ LSE can be used also to clock the USART and CEC peripherals.
+ (#) PLL (clocked by HSI or HSE), for System clock.
+ (#) CSS (Clock security system), once enabled 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-M4 NMI (Non-Maskable Interrupt)
+ exception vector.
+ (#) MCO (microcontroller clock output), used to output SYSCLK, HSI, HSE, LSI, LSE,
+ PLL (divided by 2) clock on PA8 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:
+ * @note HSI ON and used as system clock source
+ * @note HSE and PLL OFF
+ * @note AHB, APB1 and APB2 prescalers set to 1.
+ * @note CSS and MCO OFF
+ * @note All interrupts disabled
+ * @note However, this function doesn't modify the configuration of the
+ * @note Peripheral clocks
+ * @note LSI, LSE and RTC clocks
+ * @param None
+ * @retval None
+ */
+void RCC_DeInit(void)
+{
+ /* Set HSION bit */
+ RCC->CR |= (uint32_t)0x00000001;
+
+ /* Reset SW[1:0], HPRE[3:0], PPRE[2:0], ADCPRE, SDADCPRE and MCOSEL[2:0] bits */
+ RCC->CFGR &= (uint32_t)0x00FF0000;
+
+ /* Reset HSEON, CSSON and PLLON bits */
+ RCC->CR &= (uint32_t)0xFEF6FFFF;
+
+ /* Reset HSEBYP bit */
+ RCC->CR &= (uint32_t)0xFFFBFFFF;
+
+ /* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE bits */
+ RCC->CFGR &= (uint32_t)0xFF80FFFF;
+
+ /* Reset PREDIV1[3:0] bits */
+ RCC->CFGR2 &= (uint32_t)0xFFFFFFF0;
+
+ /* Reset USARTSW[1:0], I2CSW and CECSW bits */
+ RCC->CFGR3 &= (uint32_t)0xFFF0F8C;
+
+ /* 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 resets 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_BYTE2_ADDRESS = RCC_HSE_OFF;
+
+ /* Set the new HSE configuration -------------------------------------------*/
+ *(__IO uint8_t *) CR_BYTE2_ADDRESS = RCC_HSE;
+
+}
+
+/**
+ * @brief Waits for HSE start-up.
+ * @note This function 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 stm32f37x.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 timeout 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 HSI 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_HSI_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 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 to clock the PLL and/or system clock.
+ * @note HSI can not be stopped 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 stop the HSI.
+ * @note The HSI is stopped by hardware when entering STOP and STANDBY modes.
+ * @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(uint32_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 */
+ RCC->BDCR &= ~(RCC_BDCR_LSEON);
+
+ /* Reset LSEBYP bit */
+ RCC->BDCR &= ~(RCC_BDCR_LSEBYP);
+
+ /* Configure LSE */
+ RCC->BDCR |= RCC_LSE;
+}
+
+/**
+ * @brief Configures the External Low Speed oscillator (LSE) drive capability.
+ * @param RCC_LSEDrive: specifies the new state of the LSE drive capability.
+ * This parameter can be one of the following values:
+ * @arg RCC_LSEDrive_Low: LSE oscillator low drive capability.
+ * @arg RCC_LSEDrive_MediumLow: LSE oscillator medium low drive capability.
+ * @arg RCC_LSEDrive_MediumHigh: LSE oscillator medium high drive capability.
+ * @arg RCC_LSEDrive_High: LSE oscillator high drive capability.
+ * @retval None
+ */
+void RCC_LSEDriveConfig(uint32_t RCC_LSEDrive)
+{
+ /* Check the parameters */
+ assert_param(IS_RCC_LSE_DRIVE(RCC_LSEDrive));
+
+ /* Clear LSEDRV[1:0] bits */
+ RCC->BDCR &= ~(RCC_BDCR_LSEDRV);
+
+ /* Set the LSE Drive */
+ RCC->BDCR |= RCC_LSEDrive;
+}
+
+/**
+ * @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 PLL clock source and multiplication factor.
+ * @note This function must be used only when the 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_Div2: HSI oscillator clock selected as PLL clock source
+ * @arg RCC_PLLSource_PREDIV1: PREDIV1 clock selected as PLL clock entry
+ * @note The minimum input clock frequency for PLL is 2 MHz (when using HSE as
+ * PLL source).
+ *
+ * @param RCC_PLLMul: specifies the PLL multiplication factor, which drive the PLLVCO clock
+ * This parameter can be RCC_PLLMul_x where x:[2,16]
+ *
+ * @retval None
+ */
+void RCC_PLLConfig(uint32_t RCC_PLLSource, uint32_t RCC_PLLMul)
+{
+ /* Check the parameters */
+ assert_param(IS_RCC_PLL_SOURCE(RCC_PLLSource));
+ assert_param(IS_RCC_PLL_MUL(RCC_PLLMul));
+
+ /* Clear PLL Source [16] and Multiplier [21:18] bits */
+ RCC->CFGR &= ~(RCC_CFGR_PLLMULL | RCC_CFGR_PLLSRC);
+
+ /* Set the PLL Source and Multiplier */
+ RCC->CFGR |= (uint32_t)(RCC_PLLSource | RCC_PLLMul);
+}
+
+/**
+ * @brief Enables or disables the PLL.
+ * @note After enabling the 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 PLL can not be disabled if it is used as system clock source
+ * @note The PLL is disabled by hardware when entering STOP and STANDBY modes.
+ * @param NewState: new state of the 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 PREDIV1 division factor.
+ * @note This function must be used only when the PLL is disabled.
+ * @param RCC_PREDIV1_Div: specifies the PREDIV1 clock division factor.
+ * This parameter can be RCC_PREDIV1_Divx where x:[1,16]
+ * @retval None
+ */
+void RCC_PREDIV1Config(uint32_t RCC_PREDIV1_Div)
+{
+ uint32_t tmpreg = 0;
+
+ /* Check the parameters */
+ assert_param(IS_RCC_PREDIV1(RCC_PREDIV1_Div));
+
+ tmpreg = RCC->CFGR2;
+ /* Clear PREDIV1[3:0] bits */
+ tmpreg &= ~(RCC_CFGR2_PREDIV1);
+
+ /* Set the PREDIV1 division factor */
+ tmpreg |= RCC_PREDIV1_Div;
+
+ /* Store the new value */
+ RCC->CFGR2 = tmpreg;
+}
+
+/**
+ * @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-M4 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 MCO pin (PA8).
+ * @note PA8 should be configured in alternate function mode.
+ * @param RCC_MCOSource: specifies the clock source to output.
+ * This parameter can be one of the following values:
+ * @arg RCC_MCOSource_NoClock: No clock selected.
+ * @arg RCC_MCOSource_LSI: LSI oscillator clock selected.
+ * @arg RCC_MCOSource_LSE: LSE oscillator clock selected.
+ * @arg RCC_MCOSource_SYSCLK: System clock selected.
+ * @arg RCC_MCOSource_HSI: HSI oscillator clock selected.
+ * @arg RCC_MCOSource_HSE: HSE oscillator clock selected.
+ * @arg RCC_MCOSource_PLLCLK_Div2: PLL clock divided by 2 selected.
+ * @retval None
+ */
+void RCC_MCOConfig(uint8_t RCC_MCOSource)
+{
+ /* Check the parameters */
+ assert_param(IS_RCC_MCO_SOURCE(RCC_MCOSource));
+
+ /* Select MCO clock source and prescaler */
+ *(__IO uint8_t *) CFGR_BYTE3_ADDRESS = RCC_MCOSource;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup RCC_Group2 System AHB, APB1 and APB2 busses clocks configuration functions
+ * @brief System, AHB and APB busses clocks configuration functions
+ *
+@verbatim
+ ===============================================================================
+ ##### System, AHB, APB1 and APB2 busses clocks configuration functions #####
+ ===============================================================================
+
+ [..] This section provide functions allowing to configure the System, AHB, APB1 and
+ APB2 busses clocks.
+ (#) 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 and 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.
+
+ -@- All the peripheral clocks are derived from the System clock (SYSCLK) except:
+ (+@) The FLASH program/erase clock which is always HSI 8MHz clock.
+ (+@) The USB 48 MHz clock which is derived from the PLL VCO clock.
+ (+@) The USART clock which can be derived as well from HSI 8MHz, LSI or LSE.
+ (+@) The I2C clock which can be derived as well from HSI 8MHz clock.
+ (+@) The CEC clock which can be derived from HSI 8MHz or LSE.
+ (+@) The RTC clock which is derived from the LSE, LSI or 1 MHz HSE_RTC (HSE
+ divided by a programmable prescaler).
+ The System clock (SYSCLK) frequency must be higher or equal to the RTC
+ clock frequency.
+ (+@) IWDG clock which is always the LSI clock.
+
+ (#) The maximum frequency of the SYSCLK, HCLK, PCLK1 and PCLK2 is 72 MHz.
+ Depending on the maximum frequency, the FLASH wait states (WS) should be
+ adapted accordingly:
+ +---------------------------------+
+ | Wait states | HCLK clock |
+ | (Latency) | frequency (MHz) |
+ |-------------- |-----------------|
+ |0WS(1CPU cycle)| 0 < HCLK <= 24 |
+ |---------------|-----------------|
+ |1WS(2CPU cycle)|24 < HCLK <=48 |
+ |---------------|-----------------|
+ |2WS(3CPU cycle)|48 < HCLK <= 72 |
+ +---------------------------------+
+
+ (#) After reset, the System clock source is the HSI (8 MHz) with 0 WS and
+ prefetch is disabled.
+ [..] It is recommended to use the following software sequences to tune the number
+ of wait states needed to access the Flash memory with the CPU frequency (HCLK).
+ (+) Increasing the CPU frequency
+ (++) Program the Flash Prefetch buffer, using "FLASH_PrefetchBufferCmd(ENABLE)"
+ function
+ (++) Check that Flash Prefetch buffer activation is taken into account by
+ reading FLASH_ACR using the FLASH_GetPrefetchBufferStatus() function
+ (++) Program Flash WS to 1 or 2, using "FLASH_SetLatency()" function
+ (++) Check that the new number of WS is taken into account by reading FLASH_ACR
+ (++) Modify the CPU clock source, using "RCC_SYSCLKConfig()" function
+ (++) If needed, modify the CPU clock prescaler by using "RCC_HCLKConfig()" function
+ (++) Check that the new CPU clock source is taken into account by reading
+ the clock source status, using "RCC_GetSYSCLKSource()" function
+ (+) Decreasing the CPU frequency
+ (++) Modify the CPU clock source, using "RCC_SYSCLKConfig()" function
+ (++) If needed, modify the CPU clock prescaler by using "RCC_HCLKConfig()" function
+ (++) Check that the new CPU clock source is taken into account by reading
+ the clock source status, using "RCC_GetSYSCLKSource()" function
+ (++) Program the new number of WS, using "FLASH_SetLatency()" function
+ (++) Check that the new number of WS is taken into account by reading FLASH_ACR
+ (++) Disable the Flash Prefetch buffer using "FLASH_PrefetchBufferCmd(DISABLE)"
+ function
+ (++) Check that Flash Prefetch buffer deactivation is taken into account by reading FLASH_ACR
+ using the FLASH_GetPrefetchBufferStatus() function.
+
+@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 source
+ * 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 values:
+ * - 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).
+ * @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 Configures the ADC clock (ADCCLK).
+ * @param RCC_PCLK2: defines the ADC clock divider. This clock is derived from
+ * the APB2 clock (PCLK2).
+ * This parameter can be one of the following values:
+ * @arg RCC_PCLK2_Div2: ADC clock = PCLK2/2
+ * @arg RCC_PCLK2_Div4: ADC clock = PCLK2/4
+ * @arg RCC_PCLK2_Div6: ADC clock = PCLK2/6
+ * @arg RCC_PCLK2_Div8: ADC clock = PCLK2/8
+ * @retval None
+ */
+void RCC_ADCCLKConfig(uint32_t RCC_PCLK2)
+{
+
+ /* Check the parameters */
+ assert_param(IS_RCC_ADCCLK(RCC_PCLK2));
+
+ /* Clear ADCPRE[1:0] bits */
+ RCC->CFGR &= ~RCC_CFGR_ADCPRE;
+
+ /* Set ADCPRE[1:0] bits according to RCC_PCLK2 value */
+ RCC->CFGR |= RCC_PCLK2;
+}
+
+/**
+ * @brief Configures the SDADC clock (SDADCCLK).
+ * @param RCC_PCLK2: defines the ADC clock divider. This clock is derived from
+ * the system clock (SYSCLK).
+ * This parameter can be one of the following values:
+ * @arg RCC_SDADCCLK_SYSCLK_Div2: SDADC clock = SYSCLK/2
+ * @arg RCC_SDADCCLK_SYSCLK_Div4: SDADC clock = SYSCLK/4
+ * @arg RCC_SDADCCLK_SYSCLK_Div6: SDADC clock = SYSCLK/6
+ * @arg RCC_SDADCCLK_SYSCLK_Div8: SDADC clock = SYSCLK/8
+ * @arg RCC_SDADCCLK_SYSCLK_Div10: SDADC clock = SYSCLK/10
+ * @arg RCC_SDADCCLK_SYSCLK_Div12: SDADC clock = SYSCLK/12
+ * @arg RCC_SDADCCLK_SYSCLK_Div14: SDADC clock = SYSCLK/14
+ * @arg RCC_SDADCCLK_SYSCLK_Div16: SDADC clock = SYSCLK/16
+ * @arg RCC_SDADCCLK_SYSCLK_Div20: SDADC clock = SYSCLK/20
+ * @arg RCC_SDADCCLK_SYSCLK_Div24: SDADC clock = SYSCLK/24
+ * @arg RCC_SDADCCLK_SYSCLK_Div28: SDADC clock = SYSCLK/28
+ * @arg RCC_SDADCCLK_SYSCLK_Div32: SDADC clock = SYSCLK/32
+ * @arg RCC_SDADCCLK_SYSCLK_Div36: SDADC clock = SYSCLK/36
+ * @arg RCC_SDADCCLK_SYSCLK_Div40: SDADC clock = SYSCLK/40
+ * @arg RCC_SDADCCLK_SYSCLK_Div44: SDADC clock = SYSCLK/44
+ * @arg RCC_SDADCCLK_SYSCLK_Div48: SDADC clock = SYSCLK/48
+ * @retval None
+ */
+void RCC_SDADCCLKConfig(uint32_t RCC_SDADCCLK)
+{
+ /* Check the parameters */
+ assert_param(IS_RCC_SDADCCLK(RCC_SDADCCLK));
+
+ /* Clear ADCPRE[1:0] bits */
+ RCC->CFGR &= ~RCC_CFGR_SDADCPRE;
+
+ /* Set SDADCPRE[4:0] bits according to RCC_PCLK2 value */
+ RCC->CFGR |= RCC_SDADCCLK;
+}
+
+/**
+ * @brief Configures the CEC clock (CECCLK).
+ * @param RCC_CECCLK: defines the CEC clock source. This clock is derived
+ * from the HSI or LSE clock.
+ * This parameter can be one of the following values:
+ * @arg RCC_CECCLK_HSI_Div244: CEC clock = HSI/244 (32768Hz)
+ * @arg RCC_CECCLK_LSE: CEC clock = LSE
+ * @retval None
+ */
+void RCC_CECCLKConfig(uint32_t RCC_CECCLK)
+{
+ /* Check the parameters */
+ assert_param(IS_RCC_CECCLK(RCC_CECCLK));
+
+ /* Clear CECSW bit */
+ RCC->CFGR3 &= ~RCC_CFGR3_CECSW;
+ /* Set CECSW bits according to RCC_CECCLK value */
+ RCC->CFGR3 |= RCC_CECCLK;
+}
+
+/**
+ * @brief Configures the I2C clock (I2CCLK).
+ * @param RCC_I2CCLK: defines the I2C clock source. This clock is derived
+ * from the HSI or System clock.
+ * This parameter can be one of the following values:
+ * @arg RCC_I2CxCLK_HSI: I2Cx clock = HSI
+ * @arg RCC_I2CxCLK_SYSCLK: I2Cx clock = System Clock
+ * @note x can be 1 or 2
+ * @retval None
+ */
+void RCC_I2CCLKConfig(uint32_t RCC_I2CCLK)
+{
+ uint32_t tmp = 0;
+
+ /* Check the parameters */
+ assert_param(IS_RCC_I2CCLK(RCC_I2CCLK));
+
+ tmp = (RCC_I2CCLK >> 28);
+
+ /* Clear I2CSW bit */
+ if (tmp == 0)
+ {
+ RCC->CFGR3 &= ~RCC_CFGR3_I2C1SW;
+ }
+ else
+ {
+ RCC->CFGR3 &= ~RCC_CFGR3_I2C2SW;
+ }
+ /* Set I2CSW bits according to RCC_I2CCLK value */
+ RCC->CFGR3 |= RCC_I2CCLK;
+}
+
+/**
+ * @brief Configures the USART clock (USARTCLK).
+ * @param RCC_USARTCLK: defines the USART clock source. This clock is derived
+ * from the HSI or System clock.
+ * This parameter can be one of the following values:
+ * @arg RCC_USARTxCLK_PCLK: USART clock = APB Clock (PCLK)
+ * @arg RCC_USARTxCLK_SYSCLK: USART clock = System Clock
+ * @arg RCC_USARTxCLK_LSE: USART clock = LSE Clock
+ * @arg RCC_USARTxCLK_HSI: USART clock = HSI Clock
+ * @note x can be 1, 2 or 3
+ * @retval None
+ */
+void RCC_USARTCLKConfig(uint32_t RCC_USARTCLK)
+{
+ uint32_t tmp = 0;
+
+ /* Check the parameters */
+ assert_param(IS_RCC_USARTCLK(RCC_USARTCLK));
+
+ tmp = (RCC_USARTCLK >> 28);
+
+ /* Clear USARTSW[1:0] bit */
+ switch (tmp)
+ {
+ case 0x01: /* clear USART1SW */
+ RCC->CFGR3 &= ~RCC_CFGR3_USART1SW;
+ break;
+ case 0x02: /* clear USART2SW */
+ RCC->CFGR3 &= ~RCC_CFGR3_USART2SW;
+ break;
+ case 0x03: /* clear USART3SW */
+ RCC->CFGR3 &= ~RCC_CFGR3_USART3SW;
+ break;
+ default:
+ break;
+ }
+
+ /* Set USARTSW bits according to RCC_USARTCLK value */
+ RCC->CFGR3 |= RCC_USARTCLK;
+}
+
+/**
+ * @brief Configures the USB clock (USBCLK).
+ * @param RCC_USBCLKSource: specifies the USB clock source. This clock is
+ * derived from the PLL output.
+ * This parameter can be one of the following values:
+ * @arg RCC_USBCLKSource_PLLCLK_1Div5: PLL clock divided by 1,5 selected as USB
+ * clock source
+ * @arg RCC_USBCLKSource_PLLCLK_Div1: PLL clock selected as USB clock source
+ * @retval None
+ */
+void RCC_USBCLKConfig(uint32_t RCC_USBCLKSource)
+{
+ /* Check the parameters */
+ assert_param(IS_RCC_USBCLK_SOURCE(RCC_USBCLKSource));
+
+ *(__IO uint32_t *) CFGR_USBPRE_BB = RCC_USBCLKSource;
+}
+
+/**
+ * @brief Returns the frequencies of the System, AHB, APB2 and APB1 busses clocks.
+ * @note The frequency returned by this function is not the real frequency
+ * in the chip. It is calculated based on the predefined constant and
+ * the source selected by RCC_SYSCLKConfig():
+ *
+ * @note If SYSCLK source is HSI, function returns constant HSI_VALUE(*)
+ *
+ * @note If SYSCLK source is HSE, function returns constant HSE_VALUE(**)
+ *
+ * @note If SYSCLK source is PLL, function returns constant HSE_VALUE(**)
+ * or HSI_VALUE(*) multiplied by the PLL factors.
+ *
+ * @note (*) HSI_VALUE is a constant defined in stm32f37x.h file (default value
+ * 8 MHz) but the real value may vary depending on the variations
+ * in voltage and temperature, refer to RCC_AdjustHSICalibrationValue().
+ *
+ * @note (**) HSE_VALUE is a constant defined in stm32f37x.h file (default value
+ * 8 MHz), user has to ensure that HSE_VALUE is same as the real
+ * frequency of the crystal used. Otherwise, this function may
+ * return 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, pllmull = 0, pllsource = 0, prediv1factor = 0, presc = 0;
+
+ /* Get SYSCLK source -------------------------------------------------------*/
+ tmp = RCC->CFGR & RCC_CFGR_SWS;
+
+ switch (tmp)
+ {
+ case 0x00: /* HSI used as system clock */
+ RCC_Clocks->SYSCLK_Frequency = HSI_VALUE;
+ break;
+ case 0x04: /* HSE used as system clock */
+ RCC_Clocks->SYSCLK_Frequency = HSE_VALUE;
+ break;
+ case 0x08: /* PLL used as system clock */
+ /* Get PLL clock source and multiplication factor ----------------------*/
+ pllmull = RCC->CFGR & RCC_CFGR_PLLMULL;
+ pllsource = RCC->CFGR & RCC_CFGR_PLLSRC;
+ pllmull = ( pllmull >> 18) + 2;
+
+ if (pllsource == 0x00)
+ {
+ /* HSI oscillator clock divided by 2 selected as PLL clock entry */
+ RCC_Clocks->SYSCLK_Frequency = (HSI_VALUE >> 1) * pllmull;
+ }
+ else
+ {
+ prediv1factor = (RCC->CFGR2 & RCC_CFGR2_PREDIV1) + 1;
+ /* HSE oscillator clock selected as PREDIV1 clock entry */
+ RCC_Clocks->SYSCLK_Frequency = (HSE_VALUE / prediv1factor) * pllmull;
+ }
+ break;
+ default: /* HSI used as system clock */
+ RCC_Clocks->SYSCLK_Frequency = HSI_VALUE;
+ break;
+ }
+ /* Compute HCLK, PCLK 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 >> 8;
+ 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 >> 11;
+ presc = APBAHBPrescTable[tmp];
+ /* PCLK2 clock frequency */
+ RCC_Clocks->PCLK2_Frequency = RCC_Clocks->HCLK_Frequency >> presc;
+
+ /* Get ADCCLK prescaler */
+ tmp = RCC->CFGR & RCC_CFGR_ADCPRE;
+ tmp = tmp >> 14;
+ presc = ADCPrescTable[tmp];
+ /* ADCCLK clock frequency */
+ RCC_Clocks->ADCCLK_Frequency = RCC_Clocks->PCLK2_Frequency / presc;
+
+ /* Get SDADCCLK prescaler */
+ tmp = RCC->CFGR & RCC_CFGR_SDADCPRE;
+ tmp = (tmp >> 27) & 0x0F;
+ presc = SDADCPrescTable[tmp];
+ /* ADCCLK clock frequency */
+ RCC_Clocks->SDADCCLK_Frequency = RCC_Clocks->SYSCLK_Frequency / presc;
+
+ /* CECCLK clock frequency */
+ if((RCC->CFGR3 & RCC_CFGR3_CECSW) != RCC_CFGR3_CECSW)
+ {
+ /* CEC Clock is HSI/244 */
+ RCC_Clocks->CECCLK_Frequency = HSI_VALUE / 244;
+ }
+ else
+ {
+ /* CECC Clock is LSE Osc. */
+ RCC_Clocks->CECCLK_Frequency = LSE_VALUE;
+ }
+
+ /* I2C1CLK clock frequency */
+ if((RCC->CFGR3 & RCC_CFGR3_I2C1SW) != RCC_CFGR3_I2C1SW)
+ {
+ /* I2C1 Clock is HSI Osc. */
+ RCC_Clocks->I2C1CLK_Frequency = HSI_VALUE;
+ }
+ else
+ {
+ /* I2C1 Clock is System Clock */
+ RCC_Clocks->I2C1CLK_Frequency = RCC_Clocks->SYSCLK_Frequency;
+ }
+
+ /* I2C2CLK clock frequency */
+ if((RCC->CFGR3 & RCC_CFGR3_I2C2SW) != RCC_CFGR3_I2C2SW)
+ {
+ /* I2C2 Clock is HSI Osc. */
+ RCC_Clocks->I2C2CLK_Frequency = HSI_VALUE;
+ }
+ else
+ {
+ /* I2C2 Clock is System Clock */
+ RCC_Clocks->I2C2CLK_Frequency = RCC_Clocks->SYSCLK_Frequency;
+ }
+
+ /* USART1CLK clock frequency */
+ if((RCC->CFGR3 & RCC_CFGR3_USART1SW) == 0x0)
+ {
+ /* USART Clock is PCLK */
+ RCC_Clocks->USART1CLK_Frequency = RCC_Clocks->PCLK2_Frequency;
+ }
+ else if((RCC->CFGR3 & RCC_CFGR3_USART1SW) == RCC_CFGR3_USART1SW_0)
+ {
+ /* USART Clock is System Clock */
+ RCC_Clocks->USART1CLK_Frequency = RCC_Clocks->SYSCLK_Frequency;
+ }
+ else if((RCC->CFGR3 & RCC_CFGR3_USART1SW) == RCC_CFGR3_USART1SW_1)
+ {
+ /* USART Clock is LSE Osc. */
+ RCC_Clocks->USART1CLK_Frequency = LSE_VALUE;
+ }
+ else if((RCC->CFGR3 & RCC_CFGR3_USART1SW) == RCC_CFGR3_USART1SW)
+ {
+ /* USART Clock is HSI Osc. */
+ RCC_Clocks->USART1CLK_Frequency = HSI_VALUE;
+ }
+
+ /* USART2CLK clock frequency */
+ if((RCC->CFGR3 & RCC_CFGR3_USART2SW) == 0x0)
+ {
+ /* USART Clock is PCLK */
+ RCC_Clocks->USART2CLK_Frequency = RCC_Clocks->PCLK1_Frequency;
+ }
+ else if((RCC->CFGR3 & RCC_CFGR3_USART2SW) == RCC_CFGR3_USART2SW_0)
+ {
+ /* USART Clock is System Clock */
+ RCC_Clocks->USART2CLK_Frequency = RCC_Clocks->SYSCLK_Frequency;
+ }
+ else if((RCC->CFGR3 & RCC_CFGR3_USART2SW) == RCC_CFGR3_USART2SW_1)
+ {
+ /* USART Clock is LSE Osc. */
+ RCC_Clocks->USART2CLK_Frequency = LSE_VALUE;
+ }
+ else if((RCC->CFGR3 & RCC_CFGR3_USART2SW) == RCC_CFGR3_USART2SW)
+ {
+ /* USART Clock is HSI Osc. */
+ RCC_Clocks->USART2CLK_Frequency = HSI_VALUE;
+ }
+
+ /* USART3CLK clock frequency */
+ if((RCC->CFGR3 & RCC_CFGR3_USART3SW) == 0x0)
+ {
+ /* USART Clock is PCLK */
+ RCC_Clocks->USART3CLK_Frequency = RCC_Clocks->PCLK1_Frequency;
+ }
+ else if((RCC->CFGR3 & RCC_CFGR3_USART3SW) == RCC_CFGR3_USART3SW_0)
+ {
+ /* USART Clock is System Clock */
+ RCC_Clocks->USART3CLK_Frequency = RCC_Clocks->SYSCLK_Frequency;
+ }
+ else if((RCC->CFGR3 & RCC_CFGR3_USART3SW) == RCC_CFGR3_USART3SW_1)
+ {
+ /* USART Clock is LSE Osc. */
+ RCC_Clocks->USART3CLK_Frequency = LSE_VALUE;
+ }
+ else if((RCC->CFGR3 & RCC_CFGR3_USART3SW) == RCC_CFGR3_USART3SW)
+ {
+ /* USART Clock is HSI Osc. */
+ RCC_Clocks->USART3CLK_Frequency = HSI_VALUE;
+ }
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup RCC_Group3 Peripheral clocks configuration functions
+ * @brief Peripheral clocks configuration functions
+ *
+@verbatim
+ ===============================================================================
+ #####Peripheral clocks configuration functions #####
+ ===============================================================================
+ [..] This section provides functions allowing to configure the Peripheral clocks.
+ (#) The RTC clock which is derived from the LSE, LSI or HSE_Div32 (HSE
+ divided by 32).
+ (#) After restart from Reset or wakeup from STANDBY, all peripherals are off
+ except internal SRAM, Flash and SWD. 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.
+ (#) To reset the peripherals configuration (to the default state after device reset)
+ you can use RCC_AHBPeriphResetCmd(), RCC_APB2PeriphResetCmd() and
+ RCC_APB1PeriphResetCmd() 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 RTC
+ * 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_Div32: HSE divided by 32 selected as RTC clock
+ *
+ * @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 2MHz (when using HSE as
+ * RTC clock source).
+ *
+ * @retval None
+ */
+void RCC_RTCCLKConfig(uint32_t RCC_RTCCLKSource)
+{
+ /* Check the parameters */
+ assert_param(IS_RCC_RTCCLK_SOURCE(RCC_RTCCLKSource));
+
+ /* Select the RTC clock source */
+ RCC->BDCR |= RCC_RTCCLKSource;
+}
+
+/**
+ * @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_BDCR register.
+ * @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 Enables or disables the AHB 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 AHB peripheral to gates its clock.
+ * This parameter can be any combination of the following values:
+ * @arg RCC_AHBPeriph_GPIOA: GPIOA clock
+ * @arg RCC_AHBPeriph_GPIOB: GPIOB clock
+ * @arg RCC_AHBPeriph_GPIOC: GPIOC clock
+ * @arg RCC_AHBPeriph_GPIOD: GPIOD clock
+ * @arg RCC_AHBPeriph_GPIOE: GPIOE clock
+ * @arg RCC_AHBPeriph_GPIOF: GPIOF clock
+ * @arg RCC_AHBPeriph_TS: TS clock
+ * @arg RCC_AHBPeriph_CRC: CRC clock
+ * @arg RCC_AHBPeriph_FLITF: (has effect only when the Flash memory is in power down mode)
+ * @arg RCC_AHBPeriph_SRAM: SRAM clock
+ * @arg RCC_AHBPeriph_DMA2: DMA2 clock
+ * @arg RCC_AHBPeriph_DMA1: DMA1 clock
+ * @param NewState: new state of the specified peripheral clock.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void RCC_AHBPeriphClockCmd(uint32_t RCC_AHBPeriph, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_RCC_AHB_PERIPH(RCC_AHBPeriph));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ RCC->AHBENR |= RCC_AHBPeriph;
+ }
+ else
+ {
+ RCC->AHBENR &= ~RCC_AHBPeriph;
+ }
+}
+
+/**
+ * @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_SYSCFG: SYSCFG clock
+ * @arg RCC_APB2Periph_ADC1: ADC1 clock
+ * @arg RCC_APB2Periph_SPI1: SPI1 clock
+ * @arg RCC_APB2Periph_USART1: USART1 clock
+ * @arg RCC_APB2Periph_TIM15: TIM15 clock
+ * @arg RCC_APB2Periph_TIM16: TIM16 clock
+ * @arg RCC_APB2Periph_TIM17: TIM17 clock
+ * @arg RCC_APB2Periph_TIM19: TIM19 clock
+ * @arg RCC_APB2Periph_SDADC1: SDADC1 clock
+ * @arg RCC_APB2Periph_SDADC2: SDADC2 clock
+ * @arg RCC_APB2Periph_SDADC3: SDADC3 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 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_TIM18: TIM18 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_I2C1: I2C1 clock
+ * @arg RCC_APB1Periph_I2C2: I2C2 clock
+ * @arg RCC_APB1Periph_USB: USB clock
+ * @arg RCC_APB1Periph_CAN1: CAN1 clock
+ * @arg RCC_APB1Periph_DAC2: DAC2 clock
+ * @arg RCC_APB1Periph_PWR: PWR clock
+ * @arg RCC_APB1Periph_DAC1: DAC1 clock
+ * @arg RCC_APB1Periph_CEC: CEC 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 Forces or releases AHB peripheral reset.
+ * @param RCC_AHBPeriph: specifies the AHB peripheral to reset.
+ * This parameter can be any combination of the following values:
+ * @arg RCC_AHBPeriph_GPIOA: GPIOA clock
+ * @arg RCC_AHBPeriph_GPIOB: GPIOB clock
+ * @arg RCC_AHBPeriph_GPIOC: GPIOC clock
+ * @arg RCC_AHBPeriph_GPIOD: GPIOD clock
+ * @arg RCC_AHBPeriph_GPIOE: GPIOE clock
+ * @arg RCC_AHBPeriph_GPIOF: GPIOF clock
+ * @arg RCC_AHBPeriph_TS: TS clock
+ * @param NewState: new state of the specified peripheral reset.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void RCC_AHBPeriphResetCmd(uint32_t RCC_AHBPeriph, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_RCC_AHB_RST_PERIPH(RCC_AHBPeriph));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ RCC->AHBRSTR |= RCC_AHBPeriph;
+ }
+ else
+ {
+ RCC->AHBRSTR &= ~RCC_AHBPeriph;
+ }
+}
+
+/**
+ * @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_SYSCFG: SYSCFG clock
+ * @arg RCC_APB2Periph_ADC1: ADC1 clock
+ * @arg RCC_APB2Periph_SPI1: SPI1 clock
+ * @arg RCC_APB2Periph_USART1: USART1 clock
+ * @arg RCC_APB2Periph_TIM15: TIM15 clock
+ * @arg RCC_APB2Periph_TIM16: TIM16 clock
+ * @arg RCC_APB2Periph_TIM17: TIM17 clock
+ * @arg RCC_APB2Periph_TIM19: TIM19 clock
+ * @arg RCC_APB2Periph_SDADC1: SDADC1 clock
+ * @arg RCC_APB2Periph_SDADC2: SDADC2 clock
+ * @arg RCC_APB2Periph_SDADC3: SDADC3 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_PERIPH(RCC_APB2Periph));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ RCC->APB2RSTR |= RCC_APB2Periph;
+ }
+ else
+ {
+ RCC->APB2RSTR &= ~RCC_APB2Periph;
+ }
+}
+
+/**
+ * @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_TIM18: TIM18 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_I2C1: I2C1 clock
+ * @arg RCC_APB1Periph_I2C2: I2C2 clock
+ * @arg RCC_APB1Periph_USB: USB clock
+ * @arg RCC_APB1Periph_CAN1: CAN1 clock
+ * @arg RCC_APB1Periph_DAC2: DAC2 clock
+ * @arg RCC_APB1Periph_PWR: PWR clock
+ * @arg RCC_APB1Periph_DAC1: DAC1 clock
+ * @arg RCC_APB1Periph_CEC: CEC clock
+ * @param NewState: new state of the specified peripheral clock.
+ * 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;
+ }
+}
+
+/**
+ * @}
+ */
+
+/** @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.
+ * @note The CSS interrupt doesn't have an enable bit; once the CSS is enabled
+ * and if the HSE clock fails, the CSS interrupt occurs and an NMI is
+ * automatically generated. The NMI will be executed indefinitely, and
+ * since NMI has higher priority than any other IRQ (and main program)
+ * the application will be stacked in the NMI ISR unless the CSS interrupt
+ * pending bit is cleared.
+ * @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: PLL 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[13:8] bits to enable the selected interrupts */
+ *(__IO uint8_t *) CIR_BYTE2_ADDRESS |= RCC_IT;
+ }
+ else
+ {
+ /* Perform Byte access to RCC_CIR[13: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: PLL clock ready
+ * @arg RCC_FLAG_LSERDY: LSE oscillator clock ready
+ * @arg RCC_FLAG_LSIRDY: LSI oscillator clock ready
+ * @arg RCC_FLAG_OBLRST: Option Byte Loader (OBL) reset
+ * @arg RCC_FLAG_PINRST: Pin reset
+ * @arg RCC_FLAG_V18PWRRSTF: Voltage regulator 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 == 0) /* The flag to check is in CR register */
+ {
+ statusreg = RCC->CR;
+ }
+ else if (tmp == 1) /* 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_OBLRST, RCC_FLAG_PINRST, RCC_FLAG_PORRST,
+ * RCC_FLAG_SFTRST, RCC_FLAG_IWDGRST, RCC_FLAG_WWDGRST, RCC_FLAG_LPWRRST, RCC_FLAG_V18PWRRSTF.
+ * @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: PLL 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: PLL 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/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Libraries/STM32F37x_StdPeriph_Driver/src/stm32f37x_rtc.c b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Libraries/STM32F37x_StdPeriph_Driver/src/stm32f37x_rtc.c
new file mode 100644
index 0000000..bc24893
--- /dev/null
+++ b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Libraries/STM32F37x_StdPeriph_Driver/src/stm32f37x_rtc.c
@@ -0,0 +1,2597 @@
+/**
+ ******************************************************************************
+ * @file stm32f37x_rtc.c
+ * @author MCD Application Team
+ * @version V1.0.0
+ * @date 20-September-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
+ * + Original Digital Calibration configuration
+ * + Digital Calibration configuration
+ * + TimeStamp configuration
+ * + Tampers configuration
+ * + Backup Data Registers configuration
+ * + Output Type Config configuration
+ * + Shift control synchronisation
+ * + Interrupts and flags management
+ *
+ @verbatim
+ ===============================================================================
+ ##### Backup Domain Operating Condition #####
+ ===============================================================================
+ [..] The real-time clock (RTC) and the RTC backup registers can be powered
+ from the VBAT voltage when the main VDD supply is powered off.
+ To retain the content of the RTC backup registers 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:
+ (#) The RTC
+ (#) The LSE oscillator
+ (#) PC13 to PC15 I/Os I/Os (when available)
+
+ [..] When the backup domain is supplied by VDD (analog switch connected
+ to VDD), the following functions are available:
+ (#) PC14 and PC15 can be used as either GPIO or LSE pins
+ (#) PC13 can be used as a GPIO or as the RTC_AF pin
+
+ [..] When the backup domain is supplied by VBAT (analog switch connected
+ to VBAT because VDD is not present), the following functions are available:
+ (#) PC14 and PC15 can be used as LSE pins only
+ (#) PC13 can be used as the RTC_AF pin
+
+ ##### Backup Domain Reset #####
+ ===============================================================================
+ [..] The backup domain reset sets all RTC registers and the RCC_BDCR
+ register to their reset values.
+ A backup domain reset is generated when one of the following events
+ occurs:
+ (#) Software reset, triggered by setting the BDRST bit in the
+ RCC Backup domain control register (RCC_BDCR). You can use the
+ RCC_BackupResetCmd().
+ (#) VDD or VBAT power on, if both supplies have previously been
+ powered off.
+
+ ##### Backup Domain Access #####
+ ===============================================================================
+ [..] After reset, the backup domain (RTC registers and RTC backup data
+ registers) is protected against possible unwanted write accesses.
+ [..] To enable access to the Backup Domain and RTC registers, proceed as follows:
+ (#) Enable the Power Controller (PWR) APB1 interface clock using the
+ RCC_APB1PeriphClockCmd() function.
+ (#) Enable access to Backup domain using the PWR_BackupAccessCmd() function.
+ (#) Select the RTC clock source using the RCC_RTCCLKConfig() function.
+ (#) Enable RTC Clock using the RCC_RTCCLKCmd() function.
+
+
+ ##### How to use this driver #####
+ ===============================================================================
+ [..]
+ (+) Enable the backup 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.
+ (+) To read the RTC subsecond, use the RTC_GetSubSecond() function.
+ (+) 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.
+ (+) To read the RTC alarm SubSecond, use the RTC_GetAlarmSubSecond() 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.
+ To output the selected RTC signal on RTC_AF pin, use the
+ RTC_OutputConfig() function.
+ (+) AFO_CALIB: this output is 512Hz signal or 1Hz .
+ To output the RTC Clock on RTC_AF pin, use the RTC_CalibOutputCmd()
+ function.
+
+ ***Original Digital Calibration configuration ***
+ =================================
+ [..] Configure the RTC Original Digital Calibration Value and the corresponding
+ calibration cycle period (32s,16s and 8s) using the RTC_SmoothCalibConfig()
+ function.
+
+ ***TimeStamp configuration ***
+ ==============================
+ [..]
+ (+) Configure the RTC_AF 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.
+ (+) To read the RTC TimeStamp SubSecond register, use the
+ RTC_GetTimeStampSubSecond() function.
+
+ ***Tamper configuration ***
+ ===========================
+ [..]
+ (+) Configure the Tamper filter count using RTC_TamperFilterConfig()
+ function.
+ (+) Configure the RTC Tamper trigger Edge or Level according to the Tamper
+ filter (if equal to 0 Edge else Level) value using the RTC_TamperConfig() function
+ (+) Configure the Tamper sampling frequency using RTC_TamperSamplingFreqConfig()
+ function.
+ (+) Configure the Tamper precharge or discharge duration using
+ RTC_TamperPinsPrechargeDuration() function.
+ (+) Enable the Tamper Pull-UP using RTC_TamperPullUpDisableCmd() function.
+ (+) Enable the RTC Tamper using the RTC_TamperCmd() function.
+ (+) Enable the Time stamp on Tamper detection event using
+ RTC_TSOnTamperDetecCmd() function.
+
+ ***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 alarm (Alarm A), 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 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_AF alternate functions #####
+ ===============================================================================
+ [..] The RTC_AF pin (PC13) can be used for the following purposes:
+ (+) Wakeup pin 2 (WKUP2) using the PWR_WakeUpPinCmd() function.
+ (+) AFO_ALARM output
+ (+) AFO_CALIB output
+ (+) AFI_TAMPER
+ (+) AFI_TIMESTAMP
+
+ +------------------------------------------------------------------------------------------+
+ | Pin |RTC ALARM |RTC CALIB |RTC TAMPER |RTC TIMESTAMP |PC13MODE| PC13VALUE |
+ | configuration | OUTPUT | OUTPUT | INPUT | INPUT | bit | bit |
+ | and function | ENABLED | ENABLED | ENABLED | ENABLED | | |
+ |-----------------|----------|----------|-----------|--------------|--------|--------------|
+ | Alarm out | | | | | Don't | |
+ | output OD | 1 |Don't care|Don't care | Don't care | care | 0 |
+ |-----------------|----------|----------|-----------|--------------|--------|--------------|
+ | Alarm out | | | | | Don't | |
+ | output PP | 1 |Don't care|Don't care | Don't care | care | 1 |
+ |-----------------|----------|----------|-----------|--------------|--------|--------------|
+ | Calibration out | | | | | Don't | |
+ | output PP | 0 | 1 |Don't care | Don't care | care | Don't care |
+ |-----------------|----------|----------|-----------|--------------|--------|--------------|
+ | TAMPER input | | | | | Don't | |
+ | floating | 0 | 0 | 1 | 0 | care | Don't care |
+ |-----------------|----------|----------|-----------|--------------|--------|--------------|
+ | TIMESTAMP and | | | | | Don't | |
+ | TAMPER input | 0 | 0 | 1 | 1 | care | Don't care |
+ | floating | | | | | | |
+ |-----------------|----------|----------|-----------|--------------|--------|--------------|
+ | TIMESTAMP input | | | | | Don't | |
+ | floating | 0 | 0 | 0 | 1 | care | Don't care |
+ |-----------------|----------|----------|-----------|--------------|--------|--------------|
+ | Output PP | 0 | 0 | 0 | 0 | 1 | PC13 output |
+ | Forced | | | | | | |
+ |-----------------|----------|----------|-----------|--------------|--------|--------------|
+ | Wakeup Pin or | 0 | 0 | 0 | 0 | 0 | Don't care |
+ | Standard GPIO | | | | | | |
+ +------------------------------------------------------------------------------------------+
+
+ @endverbatim
+
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
+ *
+ * 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 "stm32f37x_rtc.h"
+#include "stm32f37x_rcc.h"
+
+/** @addtogroup STM32F37x_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 | \
+ RTC_FLAG_TAMP2F | RTC_FLAG_TAMP3F | RTC_FLAG_RECALPF | \
+ RTC_FLAG_SHPF))
+
+#define INITMODE_TIMEOUT ((uint32_t) 0x00002000)
+#define SYNCHRO_TIMEOUT ((uint32_t) 0x00004000)
+#define RECALPF_TIMEOUT ((uint32_t) 0x00001000)
+#define SHPF_TIMEOUT ((uint32_t) 0x00001000)
+
+/* 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.
+
+ (#) 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.
+
+ (#) All RTC registers are Write protected. Writing to the RTC registers
+ is enabled by writing a key into the Write Protection register, RTC_WPR.
+
+ (#) 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.
+
+ (#) 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->ALRMAR = (uint32_t)0x00000000;
+ RTC->ALRMBR = (uint32_t)0x00000000;
+ RTC->SHIFTR = (uint32_t)0x00000000;
+ RTC->CALR = (uint32_t)0x00000000;
+ RTC->ALRMASSR = (uint32_t)0x00000000;
+ RTC->ALRMBSSR = (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;
+
+ /* Wait till the RTC RSF flag is set */
+ 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;
+}
+
+/**
+ * @brief Enables or Disables the Bypass Shadow feature.
+ * @note When the Bypass Shadow is enabled the calendar value are taken
+ * directly from the Calendar counter.
+ * @param NewState: new state of the Bypass Shadow feature.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+*/
+void RTC_BypassShadowCmd(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)
+ {
+ /* Set the BYPSHAD bit */
+ RTC->CR |= (uint8_t)RTC_CR_BYPSHAD;
+ }
+ else
+ {
+ /* Reset the BYPSHAD bit */
+ RTC->CR &= (uint8_t)~RTC_CR_BYPSHAD;
+ }
+
+ /* Enable the write protection for RTC registers */
+ RTC->WPR = 0xFF;
+}
+
+/**
+ * @}
+ */
+
+/** @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_CR_BYPSHAD bit = 0, wait for synchro else this check is not needed */
+ if ((RTC->CR & RTC_CR_BYPSHAD) == RESET)
+ {
+ if (RTC_WaitForSynchro() == ERROR)
+ {
+ status = ERROR;
+ }
+ else
+ {
+ status = SUCCESS;
+ }
+ }
+ 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 Gets the RTC current Calendar Subseconds value.
+ * @note This function freeze the Time and Date registers after reading the
+ * SSR register.
+ * @param None
+ * @retval RTC current Calendar Subseconds value.
+ */
+uint32_t RTC_GetSubSecond(void)
+{
+ uint32_t tmpreg = 0;
+
+ /* Get subseconds values from the correspondent registers*/
+ tmpreg = (uint32_t)(RTC->SSR);
+
+ /* Read DR register to unfroze calendar registers */
+ (void) (RTC->DR);
+
+ return (tmpreg);
+}
+
+/**
+ * @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_CR_BYPSHAD bit = 0, wait for synchro else this check is not needed */
+ if ((RTC->CR & RTC_CR_BYPSHAD) == RESET)
+ {
+ if (RTC_WaitForSynchro() == ERROR)
+ {
+ status = ERROR;
+ }
+ else
+ {
+ status = SUCCESS;
+ }
+ }
+ 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);
+ RTC_DateStruct->RTC_WeekDay = (uint8_t)(RTC_DateStruct->RTC_WeekDay);
+ }
+}
+
+/**
+ * @}
+ */
+
+/** @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;
+}
+
+/**
+ * @brief Configure the RTC AlarmA/B Subseconds value and mask.
+ * @note This function is performed only when the Alarm is disabled.
+ * @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_AlarmSubSecondValue: specifies the Subseconds value.
+ * This parameter can be a value from 0 to 0x00007FFF.
+ * @param RTC_AlarmSubSecondMask: specifies the Subseconds Mask.
+ * This parameter can be any combination of the following values:
+ * @arg RTC_AlarmSubSecondMask_All: All Alarm SS fields are masked.
+ * There is no comparison on sub seconds for Alarm.
+ * @arg RTC_AlarmSubSecondMask_SS14_1: SS[14:1] are don't care in Alarm comparison.
+ * Only SS[0] is compared
+ * @arg RTC_AlarmSubSecondMask_SS14_2: SS[14:2] are don't care in Alarm comparison.
+ * Only SS[1:0] are compared
+ * @arg RTC_AlarmSubSecondMask_SS14_3: SS[14:3] are don't care in Alarm comparison.
+ * Only SS[2:0] are compared
+ * @arg RTC_AlarmSubSecondMask_SS14_4: SS[14:4] are don't care in Alarm comparison.
+ * Only SS[3:0] are compared
+ * @arg RTC_AlarmSubSecondMask_SS14_5: SS[14:5] are don't care in Alarm comparison.
+ * Only SS[4:0] are compared
+ * @arg RTC_AlarmSubSecondMask_SS14_6: SS[14:6] are don't care in Alarm comparison.
+ * Only SS[5:0] are compared
+ * @arg RTC_AlarmSubSecondMask_SS14_7: SS[14:7] are don't care in Alarm comparison.
+ * Only SS[6:0] are compared
+ * @arg RTC_AlarmSubSecondMask_SS14_8: SS[14:8] are don't care in Alarm comparison.
+ * Only SS[7:0] are compared
+ * @arg RTC_AlarmSubSecondMask_SS14_9: SS[14:9] are don't care in Alarm comparison.
+ * Only SS[8:0] are compared
+ * @arg RTC_AlarmSubSecondMask_SS14_10: SS[14:10] are don't care in Alarm comparison.
+ * Only SS[9:0] are compared
+ * @arg RTC_AlarmSubSecondMask_SS14_11: SS[14:11] are don't care in Alarm comparison.
+ * Only SS[10:0] are compared
+ * @arg RTC_AlarmSubSecondMask_SS14_12: SS[14:12] are don't care in Alarm comparison.
+ * Only SS[11:0] are compared
+ * @arg RTC_AlarmSubSecondMask_SS14_13: SS[14:13] are don't care in Alarm comparison.
+ * Only SS[12:0] are compared
+ * @arg RTC_AlarmSubSecondMask_SS14: SS[14] is don't care in Alarm comparison.
+ * Only SS[13:0] are compared
+ * @arg RTC_AlarmSubSecondMask_None: SS[14:0] are compared and must match to activate alarm
+ * @retval None
+ */
+void RTC_AlarmSubSecondConfig(uint32_t RTC_Alarm, uint32_t RTC_AlarmSubSecondValue, uint32_t RTC_AlarmSubSecondMask)
+{
+ uint32_t tmpreg = 0;
+
+ /* Check the parameters */
+ assert_param(IS_RTC_ALARM(RTC_Alarm));
+ assert_param(IS_RTC_ALARM_SUB_SECOND_VALUE(RTC_AlarmSubSecondValue));
+ assert_param(IS_RTC_ALARM_SUB_SECOND_MASK(RTC_AlarmSubSecondMask));
+
+ /* Disable the write protection for RTC registers */
+ RTC->WPR = 0xCA;
+ RTC->WPR = 0x53;
+
+ /* Configure the Alarm A or Alarm B SubSecond registers */
+ tmpreg = (uint32_t) (uint32_t)(RTC_AlarmSubSecondValue) | (uint32_t)(RTC_AlarmSubSecondMask);
+
+ if (RTC_Alarm == RTC_Alarm_A)
+ {
+ /* Configure the AlarmA SubSecond register */
+ RTC->ALRMASSR = tmpreg;
+ }
+ else
+ {
+ /* Configure the Alarm B SubSecond register */
+ RTC->ALRMBSSR = tmpreg;
+ }
+
+ /* Enable the write protection for RTC registers */
+ RTC->WPR = 0xFF;
+
+}
+
+/**
+ * @brief Gets the RTC Alarm Subseconds value.
+ * @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 None
+ * @retval RTC Alarm Subseconds value.
+ */
+uint32_t RTC_GetAlarmSubSecond(uint32_t RTC_Alarm)
+{
+ uint32_t tmpreg = 0;
+
+ /* Get the RTC_ALRMxR register */
+ if (RTC_Alarm == RTC_Alarm_A)
+ {
+ tmpreg = (uint32_t)((RTC->ALRMASSR) & RTC_ALRMASSR_SS);
+ }
+ else
+ {
+ tmpreg = (uint32_t)((RTC->ALRMBSSR) & RTC_ALRMBSSR_SS);
+ }
+
+ return (tmpreg);
+}
+
+/**
+ * @}
+ */
+
+/** @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
+ * @arg RTC_WakeUpClock_RTCCLK_Div8
+ * @arg RTC_WakeUpClock_RTCCLK_Div4
+ * @arg RTC_WakeUpClock_RTCCLK_Div2
+ * @arg RTC_WakeUpClock_CK_SPRE_16bits
+ * @arg RTC_WakeUpClock_CK_SPRE_17bits
+ * @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 provides 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 provides 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 Digital Calibration configuration functions
+ * @brief Digital Calibration configuration functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Digital Calibration configuration functions #####
+ ===============================================================================
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @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;
+}
+
+/**
+ * @brief Configure the Calibration Pinout (RTC_CALIB) Selection (1Hz or 512Hz).
+ * @param RTC_CalibOutput: Select the Calibration output Selection .
+ * This parameter can be one of the following values:
+ * @arg RTC_CalibOutput_512Hz: A signal has a regular waveform at 512Hz.
+ * @arg RTC_CalibOutput_1Hz: A signal has a regular waveform at 1Hz.
+ * @retval None
+*/
+void RTC_CalibOutputConfig(uint32_t RTC_CalibOutput)
+{
+ /* Check the parameters */
+ assert_param(IS_RTC_CALIB_OUTPUT(RTC_CalibOutput));
+
+ /* Disable the write protection for RTC registers */
+ RTC->WPR = 0xCA;
+ RTC->WPR = 0x53;
+
+ /*clear flags before config*/
+ RTC->CR &= (uint32_t)~(RTC_CR_COSEL);
+
+ /* Configure the RTC_CR register */
+ RTC->CR |= (uint32_t)RTC_CalibOutput;
+
+ /* Enable the write protection for RTC registers */
+ RTC->WPR = 0xFF;
+}
+
+/**
+ * @brief Configures the Smooth Calibration Settings.
+ * @param RTC_SmoothCalibPeriod: Select the Smooth Calibration Period.
+ * This parameter can be can be one of the following values:
+ * @arg RTC_SmoothCalibPeriod_32sec: The smooth calibration periode is 32s.
+ * @arg RTC_SmoothCalibPeriod_16sec: The smooth calibration periode is 16s.
+ * @arg RTC_SmoothCalibPeriod_8sec: The smooth calibartion periode is 8s.
+ * @param RTC_SmoothCalibPlusPulses: Select to Set or reset the CALP bit.
+ * This parameter can be one of the following values:
+ * @arg RTC_SmoothCalibPlusPulses_Set: Add one RTCCLK puls every 2**11 pulses.
+ * @arg RTC_SmoothCalibPlusPulses_Reset: No RTCCLK pulses are added.
+ * @param RTC_SmouthCalibMinusPulsesValue: Select the value of CALM[8:0] bits.
+ * This parameter can be one any value from 0 to 0x000001FF.
+ * @retval An ErrorStatus enumeration value:
+ * - SUCCESS: RTC Calib registers are configured
+ * - ERROR: RTC Calib registers are not configured
+*/
+ErrorStatus RTC_SmoothCalibConfig(uint32_t RTC_SmoothCalibPeriod,
+ uint32_t RTC_SmoothCalibPlusPulses,
+ uint32_t RTC_SmouthCalibMinusPulsesValue)
+{
+ ErrorStatus status = ERROR;
+ uint32_t recalpfcount = 0;
+
+ /* Check the parameters */
+ assert_param(IS_RTC_SMOOTH_CALIB_PERIOD(RTC_SmoothCalibPeriod));
+ assert_param(IS_RTC_SMOOTH_CALIB_PLUS(RTC_SmoothCalibPlusPulses));
+ assert_param(IS_RTC_SMOOTH_CALIB_MINUS(RTC_SmouthCalibMinusPulsesValue));
+
+ /* Disable the write protection for RTC registers */
+ RTC->WPR = 0xCA;
+ RTC->WPR = 0x53;
+
+ /* check if a calibration is pending*/
+ if ((RTC->ISR & RTC_ISR_RECALPF) != RESET)
+ {
+ /* wait until the Calibration is completed*/
+ while (((RTC->ISR & RTC_ISR_RECALPF) != RESET) && (recalpfcount != RECALPF_TIMEOUT))
+ {
+ recalpfcount++;
+ }
+ }
+
+ /* check if the calibration pending is completed or if there is no calibration operation at all*/
+ if ((RTC->ISR & RTC_ISR_RECALPF) == RESET)
+ {
+ /* Configure the Smooth calibration settings */
+ RTC->CALR = (uint32_t)((uint32_t)RTC_SmoothCalibPeriod | (uint32_t)RTC_SmoothCalibPlusPulses | (uint32_t)RTC_SmouthCalibMinusPulsesValue);
+
+ status = SUCCESS;
+ }
+ else
+ {
+ status = ERROR;
+ }
+
+ /* Enable the write protection for RTC registers */
+ RTC->WPR = 0xFF;
+
+ return (ErrorStatus)(status);
+}
+
+/**
+ * @}
+ */
+
+
+/** @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);
+ }
+}
+
+/**
+ * @brief Get the RTC timestamp Subseconds value.
+ * @param None
+ * @retval RTC current timestamp Subseconds value.
+ */
+uint32_t RTC_GetTimeStampSubSecond(void)
+{
+ /* Get timestamp subseconds values from the correspondent registers */
+ return (uint32_t)(RTC->TSSSR);
+}
+
+/**
+ * @}
+ */
+
+/** @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 any combination of the following values:
+ * @arg RTC_Tamper_1: Select Tamper 1.
+ * @arg RTC_Tamper_2: Select Tamper 2.
+ * @arg RTC_Tamper_3: Select Tamper 3.
+ * @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.
+ * @arg RTC_TamperTrigger_LowLevel: Low Level of the tamper pin causes tamper event.
+ * @arg RTC_TamperTrigger_HighLevel: High Level 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));
+
+ /* Check if the active level for Tamper is rising edge (Low level)*/
+ 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 any combination of the following values:
+ * @arg RTC_Tamper_1: Select Tamper 1.
+ * @arg RTC_Tamper_2: Select Tamper 2.
+ * @arg RTC_Tamper_3: Select Tamper 3.
+ * @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;
+ }
+}
+
+/**
+ * @brief Configures the Tampers Filter.
+ * @param RTC_TamperFilter: Specifies the tampers filter.
+ * This parameter can be one of the following values:
+ * @arg RTC_TamperFilter_Disable: Tamper filter is disabled.
+ * @arg RTC_TamperFilter_2Sample: Tamper is activated after 2 consecutive
+ * samples at the active level
+ * @arg RTC_TamperFilter_4Sample: Tamper is activated after 4 consecutive
+ * samples at the active level
+ * @arg RTC_TamperFilter_8Sample: Tamper is activated after 8 consecutive
+ * samples at the active level
+ * @retval None
+ */
+void RTC_TamperFilterConfig(uint32_t RTC_TamperFilter)
+{
+ /* Check the parameters */
+ assert_param(IS_RTC_TAMPER_FILTER(RTC_TamperFilter));
+
+ /* Clear TAMPFLT[1:0] bits in the RTC_TAFCR register */
+ RTC->TAFCR &= (uint32_t)~(RTC_TAFCR_TAMPFLT);
+
+ /* Configure the RTC_TAFCR register */
+ RTC->TAFCR |= (uint32_t)RTC_TamperFilter;
+}
+
+/**
+ * @brief Configures the Tampers Sampling Frequency.
+ * @param RTC_TamperSamplingFreq: Specifies the tampers Sampling Frequency.
+ * This parameter can be one of the following values:
+ * @arg RTC_TamperSamplingFreq_RTCCLK_Div32768: Each of the tamper inputs are sampled
+ * with a frequency = RTCCLK / 32768
+ * @arg RTC_TamperSamplingFreq_RTCCLK_Div16384: Each of the tamper inputs are sampled
+ * with a frequency = RTCCLK / 16384
+ * @arg RTC_TamperSamplingFreq_RTCCLK_Div8192: Each of the tamper inputs are sampled
+ * with a frequency = RTCCLK / 8192
+ * @arg RTC_TamperSamplingFreq_RTCCLK_Div4096: Each of the tamper inputs are sampled
+ * with a frequency = RTCCLK / 4096
+ * @arg RTC_TamperSamplingFreq_RTCCLK_Div2048: Each of the tamper inputs are sampled
+ * with a frequency = RTCCLK / 2048
+ * @arg RTC_TamperSamplingFreq_RTCCLK_Div1024: Each of the tamper inputs are sampled
+ * with a frequency = RTCCLK / 1024
+ * @arg RTC_TamperSamplingFreq_RTCCLK_Div512: Each of the tamper inputs are sampled
+ * with a frequency = RTCCLK / 512
+ * @arg RTC_TamperSamplingFreq_RTCCLK_Div256: Each of the tamper inputs are sampled
+ * with a frequency = RTCCLK / 256
+ * @retval None
+ */
+void RTC_TamperSamplingFreqConfig(uint32_t RTC_TamperSamplingFreq)
+{
+ /* Check the parameters */
+ assert_param(IS_RTC_TAMPER_SAMPLING_FREQ(RTC_TamperSamplingFreq));
+
+ /* Clear TAMPFREQ[2:0] bits in the RTC_TAFCR register */
+ RTC->TAFCR &= (uint32_t)~(RTC_TAFCR_TAMPFREQ);
+
+ /* Configure the RTC_TAFCR register */
+ RTC->TAFCR |= (uint32_t)RTC_TamperSamplingFreq;
+}
+
+/**
+ * @brief Configures the Tampers Pins input Precharge Duration.
+ * @param RTC_TamperPrechargeDuration: Specifies the Tampers Pins input
+ * Precharge Duration.
+ * This parameter can be one of the following values:
+ * @arg RTC_TamperPrechargeDuration_1RTCCLK: Tamper pins are pre-charged before sampling during 1 RTCCLK cycle
+ * @arg RTC_TamperPrechargeDuration_2RTCCLK: Tamper pins are pre-charged before sampling during 2 RTCCLK cycle
+ * @arg RTC_TamperPrechargeDuration_4RTCCLK: Tamper pins are pre-charged before sampling during 4 RTCCLK cycle
+ * @arg RTC_TamperPrechargeDuration_8RTCCLK: Tamper pins are pre-charged before sampling during 8 RTCCLK cycle
+ * @retval None
+ */
+void RTC_TamperPinsPrechargeDuration(uint32_t RTC_TamperPrechargeDuration)
+{
+ /* Check the parameters */
+ assert_param(IS_RTC_TAMPER_PRECHARGE_DURATION(RTC_TamperPrechargeDuration));
+
+ /* Clear TAMPPRCH[1:0] bits in the RTC_TAFCR register */
+ RTC->TAFCR &= (uint32_t)~(RTC_TAFCR_TAMPPRCH);
+
+ /* Configure the RTC_TAFCR register */
+ RTC->TAFCR |= (uint32_t)RTC_TamperPrechargeDuration;
+}
+
+/**
+ * @brief Enables or Disables the TimeStamp on Tamper Detection Event.
+ * @note The timestamp is valid even the TSE bit in tamper control register
+ * is reset.
+ * @param NewState: new state of the timestamp on tamper event.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void RTC_TimeStampOnTamperDetectionCmd(FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Save timestamp on tamper detection event */
+ RTC->TAFCR |= (uint32_t)RTC_TAFCR_TAMPTS;
+ }
+ else
+ {
+ /* Tamper detection does not cause a timestamp to be saved */
+ RTC->TAFCR &= (uint32_t)~RTC_TAFCR_TAMPTS;
+ }
+}
+
+/**
+ * @brief Enables or Disables the Precharge of Tamper pin.
+ * @param NewState: new state of tamper pull up.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void RTC_TamperPullUpCmd(FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable precharge of the selected Tamper pin */
+ RTC->TAFCR &= (uint32_t)~RTC_TAFCR_TAMPPUDIS;
+ }
+ else
+ {
+ /* Disable precharge of the selected Tamper pin */
+ RTC->TAFCR |= (uint32_t)RTC_TAFCR_TAMPPUDIS;
+ }
+}
+
+/**
+ * @}
+ */
+
+/** @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 Output Type Config configuration functions
+ * @brief Output Type Config configuration functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Output Type Config configuration functions #####
+ ===============================================================================
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @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 Shift control synchronisation functions
+ * @brief Shift control synchronisation functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Shift control synchronisation functions #####
+ ===============================================================================
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Configures the Synchronization Shift Control Settings.
+ * @note When REFCKON is set, firmware must not write to Shift control register
+ * @param RTC_ShiftAdd1S: Select to add or not 1 second to the time Calendar.
+ * This parameter can be one of the following values :
+ * @arg RTC_ShiftAdd1S_Set: Add one second to the clock calendar.
+ * @arg RTC_ShiftAdd1S_Reset: No effect.
+ * @param RTC_ShiftSubFS: Select the number of Second Fractions to Substitute.
+ * This parameter can be one any value from 0 to 0x7FFF.
+ * @retval An ErrorStatus enumeration value:
+ * - SUCCESS: RTC Shift registers are configured
+ * - ERROR: RTC Shift registers are not configured
+*/
+ErrorStatus RTC_SynchroShiftConfig(uint32_t RTC_ShiftAdd1S, uint32_t RTC_ShiftSubFS)
+{
+ ErrorStatus status = ERROR;
+ uint32_t shpfcount = 0;
+
+ /* Check the parameters */
+ assert_param(IS_RTC_SHIFT_ADD1S(RTC_ShiftAdd1S));
+ assert_param(IS_RTC_SHIFT_SUBFS(RTC_ShiftSubFS));
+
+ /* Disable the write protection for RTC registers */
+ RTC->WPR = 0xCA;
+ RTC->WPR = 0x53;
+
+ /* Check if a Shift is pending*/
+ if ((RTC->ISR & RTC_ISR_SHPF) != RESET)
+ {
+ /* Wait until the shift is completed*/
+ while (((RTC->ISR & RTC_ISR_SHPF) != RESET) && (shpfcount != SHPF_TIMEOUT))
+ {
+ shpfcount++;
+ }
+ }
+
+ /* Check if the Shift pending is completed or if there is no Shift operation at all*/
+ if ((RTC->ISR & RTC_ISR_SHPF) == RESET)
+ {
+ /* check if the reference clock detection is disabled */
+ if((RTC->CR & RTC_CR_REFCKON) == RESET)
+ {
+ /* Configure the Shift settings */
+ RTC->SHIFTR = (uint32_t)(uint32_t)(RTC_ShiftSubFS) | (uint32_t)(RTC_ShiftAdd1S);
+
+ if(RTC_WaitForSynchro() == ERROR)
+ {
+ status = ERROR;
+ }
+ else
+ {
+ status = SUCCESS;
+ }
+ }
+ else
+ {
+ status = ERROR;
+ }
+ }
+ else
+ {
+ status = ERROR;
+ }
+
+ /* Enable the write protection for RTC registers */
+ RTC->WPR = 0xFF;
+
+ return (ErrorStatus)(status);
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup RTC_Group13 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 20 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 19 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 19 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() function.
+
+@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_RECALPF: RECALPF event flag
+ * @arg RTC_FLAG_TAMP3F: Tamper 3 event flag
+ * @arg RTC_FLAG_TAMP2F: Tamper 2 event flag
+ * @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
+ * @argRTC_FLAG_SHPF : Shift operation pending 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_TAMP3F: Tamper 3 event flag
+ * @arg RTC_FLAG_TAMP2F: Tamper 2 event flag
+ * @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)& 0x0001FFFF) | (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: Tamper1 event interrupt
+ * @arg RTC_IT_TAMP2: Tamper2 event interrupt
+ * @arg RTC_IT_TAMP3: Tamper3 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 >> (RTC_IT >> 18)) >> 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: Tamper1 event interrupt
+ * @arg RTC_IT_TAMP2: Tamper2 event interrupt
+ * @arg RTC_IT_TAMP3: Tamper3 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/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Libraries/STM32F37x_StdPeriph_Driver/src/stm32f37x_spi.c b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Libraries/STM32F37x_StdPeriph_Driver/src/stm32f37x_spi.c
new file mode 100644
index 0000000..5f1fda5
--- /dev/null
+++ b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Libraries/STM32F37x_StdPeriph_Driver/src/stm32f37x_spi.c
@@ -0,0 +1,1302 @@
+/**
+ ******************************************************************************
+ * @file stm32f37x_spi.c
+ * @author MCD Application Team
+ * @version V1.0.0
+ * @date 20-September-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 #####
+ ===============================================================================
+ [..]
+ (#) Enable peripheral clock using RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE)
+ function for SPI1 or using RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE)
+ function for SPI2 or using RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI3, ENABLE)
+ for SPI3.
+
+ (#) Enable SCK, MOSI, MISO and NSS GPIO clocks using
+ RCC_AHBPeriphClockCmd() function.
+
+ (#) 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.
+
+ (#) 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.
+
+ (#) Configure the FIFO threshold using SPI_RxFIFOThresholdConfig() to select
+ at which threshold the RXNE event is generated.
+
+ (#) Enable the NVIC and the corresponding interrupt using the function
+ SPI_ITConfig() if you need to use interrupt mode.
+
+ (#) When using the DMA mode
+ (++) Configure the DMA using DMA_Init() function.
+ (++) Active the needed channel Request using SPI_I2S_DMACmd() function.
+
+ (#) Enable the SPI using the SPI_Cmd() function or enable the I2S using
+ I2S_Cmd().
+
+ (#) Enable the DMA using the DMA_Cmd() function when using DMA mode.
+
+ (#) 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.
+
+ (#) To use the CRC Hardware calculation feature refer to the Peripheral
+ CRC hardware Calculation subsection.
+
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
+ *
+ * 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 "stm32f37x_spi.h"
+#include "stm32f37x_rcc.h"
+
+/** @addtogroup STM32F37x_StdPeriph_Driver
+ * @{
+ */
+
+/** @defgroup SPI
+ * @brief SPI driver modules
+ * @{
+ */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* SPI registers Masks */
+#define CR1_CLEAR_MASK ((uint16_t)0x3040)
+#define CR1_CLEAR_MASK2 ((uint16_t)0xFFFB)
+#define CR2_LDMA_MASK ((uint16_t)0x9FFF)
+
+#define I2SCFGR_CLEAR_Mask ((uint16_t)0xF040)
+
+/* 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).
+
+ [..] When the Software NSS management (SPI_InitStruct->SPI_NSS = SPI_NSS_Soft) is selected,
+ use the following function to manage the NSS bit:
+ void SPI_NSSInternalSoftwareConfig(SPI_TypeDef* SPIx, uint16_t SPI_NSSInternalSoft);
+
+ [..] In Master mode, when the Hardware NSS management (SPI_InitStruct->SPI_NSS = SPI_NSS_Hard)
+ is selected, use the follwoing function to enable the NSS output feature.
+ void SPI_SSOutputCmd(SPI_TypeDef* SPIx, FunctionalState NewState);
+
+ [..] The NSS pulse mode can be managed by the SPI TI mode when enabling it using the following function:
+ void SPI_TIModeCmd(SPI_TypeDef* SPIx, FunctionalState NewState);
+ And it can be managed by software in the SPI Motorola mode using this function:
+ void SPI_NSSPulseModeCmd(SPI_TypeDef* SPIx, FunctionalState NewState);
+
+ [..] This section provides also functions to initialize the I2S Mode, Standard,
+ Data Format, MCLK Output, Audio frequency and Polarity.
+
+ [..] The I2S_Init() function follows the I2S configuration procedures for Master mode
+ and Slave mode.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Deinitializes the SPIx peripheral registers to their default
+ * reset values.
+ * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
+ * @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 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 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_DATA_SIZE(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, CPOL and CPHA bits */
+ tmpreg &= CR1_CLEAR_MASK;
+ /* Configure SPIx: direction, NSS management, first transmitted bit, BaudRate prescaler
+ master/slave mode, CPOL and CPHA */
+ /* Set BIDImode, BIDIOE and RxONLY bits according to SPI_Direction value */
+ /* Set SSM, SSI bit according to 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_FirstBit |
+ SPI_InitStruct->SPI_CPOL | SPI_InitStruct->SPI_CPHA |
+ SPI_InitStruct->SPI_NSS | SPI_InitStruct->SPI_BaudRatePrescaler);
+ /* Write to SPIx CR1 */
+ SPIx->CR1 = tmpreg;
+ /*-------------------------Data Size Configuration -----------------------*/
+ /* Get the SPIx CR2 value */
+ tmpreg = SPIx->CR2;
+ /* Clear DS[3:0] bits */
+ tmpreg &=(uint16_t)~SPI_CR2_DS;
+ /* Configure SPIx: Data Size */
+ tmpreg |= (uint16_t)(SPI_InitStruct->SPI_DataSize);
+ /* Write to SPIx CR2 */
+ SPIx->CR2 = tmpreg;
+
+ /*---------------------------- SPIx CRCPOLY Configuration --------------------*/
+ /* Write to SPIx CRCPOLY */
+ SPIx->CRCPR = SPI_InitStruct->SPI_CRCPolynomial;
+
+ /*---------------------------- SPIx CR1 Configuration ------------------------*/
+ /* Get the SPIx CR1 value */
+ tmpreg = SPIx->CR1;
+ /* Clear MSTR bit */
+ tmpreg &= CR1_CLEAR_MASK2;
+ /* Configure SPIx: master/slave mode */
+ /* Set MSTR bit according to SPI_Mode */
+ tmpreg |= (uint16_t)((uint32_t)SPI_InitStruct->SPI_Mode);
+ /* 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);
+}
+
+/**
+ * @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 Initializes the SPIx peripheral according to the specified
+ * parameters in the I2S_InitStruct.
+ * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
+ * @param I2S_InitStruct: pointer to an I2S_InitTypeDef structure that
+ * contains the configuration information for the specified SPI peripheral
+ * configured in I2S mode.
+ * @note This 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.
+ * @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;
+ RCC_ClocksTypeDef RCC_Clocks;
+ uint32_t sourceclock = 0;
+
+ /* Check the I2S parameters */
+ assert_param(IS_SPI_ALL_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;
+ }
+
+ /* I2S Clock source is System clock: Get System Clock frequency */
+ RCC_GetClocksFreq(&RCC_Clocks);
+
+ /* Get the source clock value: based on System Clock value */
+ sourceclock = RCC_Clocks.SYSCLK_Frequency;
+
+ /* 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)(((((sourceclock / 256) * 10) / I2S_InitStruct->I2S_AudioFreq)) + 5);
+ }
+ else
+ {
+ /* MCLK output is disabled */
+ tmp = (uint16_t)(((((sourceclock / (32 * packetlength)) *10 ) / I2S_InitStruct->I2S_AudioFreq)) + 5);
+ }
+
+ /* Remove the floating 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)(i2sdiv | (uint16_t)(i2sodd | (uint16_t)I2S_InitStruct->I2S_MCLKOutput));
+
+ /* Configure the I2S with the SPI_InitStruct values */
+ tmpreg |= (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 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 TI Mode.
+ *
+ * @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 to select the SPI peripheral.
+ * @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)~((uint16_t)SPI_CR2_FRF);
+ }
+}
+
+/**
+ * @brief Enables or disables the specified SPI peripheral (in I2S mode).
+ * @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 I2S_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 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.
+ * For the SPIx peripheral this parameter can be one of the following values:
+ * @arg SPI_DataSize_4b: Set data size to 4 bits
+ * @arg SPI_DataSize_5b: Set data size to 5 bits
+ * @arg SPI_DataSize_6b: Set data size to 6 bits
+ * @arg SPI_DataSize_7b: Set data size to 7 bits
+ * @arg SPI_DataSize_8b: Set data size to 8 bits
+ * @arg SPI_DataSize_9b: Set data size to 9 bits
+ * @arg SPI_DataSize_10b: Set data size to 10 bits
+ * @arg SPI_DataSize_11b: Set data size to 11 bits
+ * @arg SPI_DataSize_12b: Set data size to 12 bits
+ * @arg SPI_DataSize_13b: Set data size to 13 bits
+ * @arg SPI_DataSize_14b: Set data size to 14 bits
+ * @arg SPI_DataSize_15b: Set data size to 15 bits
+ * @arg SPI_DataSize_16b: Set data size to 16 bits
+ * @retval None
+ */
+void SPI_DataSizeConfig(SPI_TypeDef* SPIx, uint16_t SPI_DataSize)
+{
+ uint16_t tmpreg = 0;
+
+ /* Check the parameters */
+ assert_param(IS_SPI_ALL_PERIPH(SPIx));
+ assert_param(IS_SPI_DATA_SIZE(SPI_DataSize));
+ /* Read the CR2 register */
+ tmpreg = SPIx->CR2;
+ /* Clear DS[3:0] bits */
+ tmpreg &= (uint16_t)~SPI_CR2_DS;
+ /* Set new DS[3:0] bits value */
+ tmpreg |= SPI_DataSize;
+ SPIx->CR2 = tmpreg;
+}
+
+/**
+ * @brief Configures the FIFO reception threshold for the selected SPI.
+ * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
+ * @param SPI_RxFIFOThreshold: specifies the FIFO reception threshold.
+ * This parameter can be one of the following values:
+ * @arg SPI_RxFIFOThreshold_HF: RXNE event is generated if the FIFO
+ * level is greater or equal to 1/2.
+ * @arg SPI_RxFIFOThreshold_QF: RXNE event is generated if the FIFO
+ * level is greater or equal to 1/4.
+ * @retval None
+ */
+void SPI_RxFIFOThresholdConfig(SPI_TypeDef* SPIx, uint16_t SPI_RxFIFOThreshold)
+{
+ /* Check the parameters */
+ assert_param(IS_SPI_ALL_PERIPH(SPIx));
+ assert_param(IS_SPI_RX_FIFO_THRESHOLD(SPI_RxFIFOThreshold));
+
+ /* Clear FRXTH bit */
+ SPIx->CR2 &= (uint16_t)~((uint16_t)SPI_CR2_FRXTH);
+
+ /* Set new FRXTH bit value */
+ SPIx->CR2 |= SPI_RxFIFOThreshold;
+}
+
+/**
+ * @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.
+ * @note This function can be called only after the SPI_Init() function has
+ * been called.
+ * @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.
+ * @note This function can be called only after the SPI_Init() function has
+ * been called and the NSS hardware management mode is selected.
+ * @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 |= SPI_CR2_SSOE;
+ }
+ else
+ {
+ /* Disable the selected SPI SS output */
+ SPIx->CR2 &= (uint16_t)~((uint16_t)SPI_CR2_SSOE);
+ }
+}
+
+/**
+ * @brief Enables or disables the NSS pulse management mode.
+ * @note This function can be called only after the SPI_Init() function has
+ * been called.
+ * @note When TI mode is selected, the control bits NSSP is 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 to select the SPI peripheral.
+ * @param NewState: new state of the NSS pulse management mode.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void SPI_NSSPulseModeCmd(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 NSS pulse management mode */
+ SPIx->CR2 |= SPI_CR2_NSSP;
+ }
+ else
+ {
+ /* Disable the NSS pulse management mode */
+ SPIx->CR2 &= (uint16_t)~((uint16_t)SPI_CR2_NSSP);
+ }
+}
+
+/**
+ * @}
+ */
+
+/** @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 or I2S
+ 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
+ SPI_ReceiveData8() (when data size is equal or inferior than 8bits) and.
+ SPI_I2S_ReceiveData16() (when data size is superior than 8bits)function
+ and returns the Rx buffered value. Whereas a write access to the SPI_DR
+ can be done using SPI_SendData8() (when data size is equal or inferior than 8bits)
+ and SPI_I2S_SendData16() (when data size is superior than 8bits) function
+ and stores the written data into Tx buffer.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Transmits a Data through the SPIx/I2Sx peripheral.
+ * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
+ * @param Data: Data to be transmitted.
+ * @retval None
+ */
+void SPI_SendData8(SPI_TypeDef* SPIx, uint8_t Data)
+{
+ uint32_t spixbase = 0x00;
+
+ /* Check the parameters */
+ assert_param(IS_SPI_ALL_PERIPH(SPIx));
+
+ spixbase = (uint32_t)SPIx;
+ spixbase += 0x0C;
+
+ *(__IO uint8_t *) spixbase = Data;
+}
+
+/**
+ * @brief Transmits a Data through the SPIx/I2Sx peripheral.
+ * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
+ * @param Data: Data to be transmitted.
+ * @retval None
+ */
+void SPI_I2S_SendData16(SPI_TypeDef* SPIx, uint16_t Data)
+{
+ /* Check the parameters */
+ assert_param(IS_SPI_ALL_PERIPH(SPIx));
+
+ SPIx->DR = (uint16_t)Data;
+}
+
+/**
+ * @brief Returns the most recent received data by the SPIx/I2Sx peripheral.
+ * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
+ * @retval The value of the received data.
+ */
+uint8_t SPI_ReceiveData8(SPI_TypeDef* SPIx)
+{
+ uint32_t spixbase = 0x00;
+
+ spixbase = (uint32_t)SPIx;
+ spixbase += 0x0C;
+
+ return *(__IO uint8_t *) spixbase;
+}
+
+/**
+ * @brief Returns the most recent received data by the SPIx peripheral.
+ * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
+ * @retval The value of the received data.
+ */
+uint16_t SPI_I2S_ReceiveData16(SPI_TypeDef* SPIx)
+{
+ return SPIx->DR;
+}
+/**
+ * @}
+ */
+
+/** @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:
+
+ (#) Program the Data direction, Polarity, Phase, First Data, Baud Rate Prescaler,
+ Slave Management, Peripheral Mode and CRC Polynomial values using the SPI_Init()
+ function.
+ (#) Enable the CRC calculation using the SPI_CalculateCRC() function.
+ (#) Enable the SPI using the SPI_Cmd() function
+ (#) 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.
+ (#) 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.
+
+ -@-
+ (+@) It is advised to don't read the calculate CRC values during the communication.
+ (+@) 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.
+ (+@) 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.
+ (+@) 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.
+ (+@) When the STM32F37x are configured as slaves and the NSS hardware mode is
+ used, the NSS pin needs to be kept low between the data phase and the CRC
+ phase.
+ (+@) 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 multislave environment where the
+ communication master addresses slaves alternately.
+ (+@) Between a slave deselection (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.
+
+ -@- To clear the CRC, follow the procedure below:
+ (#@) Disable SPI using the SPI_Cmd() function
+ (#@) Disable the CRC calculation using the SPI_CalculateCRC() function.
+ (#@) Enable the CRC calculation using the SPI_CalculateCRC() function.
+ (#@) Enable SPI using the SPI_Cmd() function.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Configures the CRC calculation length for the selected SPI.
+ * @note This function can be called only after the SPI_Init() function has
+ * been called.
+ * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
+ * @param SPI_CRCLength: specifies the SPI CRC calculation length.
+ * This parameter can be one of the following values:
+ * @arg SPI_CRCLength_8b: Set CRC Calculation to 8 bits
+ * @arg SPI_CRCLength_16b: Set CRC Calculation to 16 bits
+ * @retval None
+ */
+void SPI_CRCLengthConfig(SPI_TypeDef* SPIx, uint16_t SPI_CRCLength)
+{
+ /* Check the parameters */
+ assert_param(IS_SPI_ALL_PERIPH(SPIx));
+ assert_param(IS_SPI_CRC_LENGTH(SPI_CRCLength));
+
+ /* Clear CRCL bit */
+ SPIx->CR1 &= (uint16_t)~((uint16_t)SPI_CR1_CRCL);
+
+ /* Set new CRCL bit value */
+ SPIx->CR1 |= SPI_CRCLength;
+}
+
+/**
+ * @brief Enables or disables the CRC value calculation of the transferred bytes.
+ * @note This function can be called only after the SPI_Init() function has
+ * been called.
+ * @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 #####
+ ===============================================================================
+ [..] This section provides two functions that can be used only in DMA mode.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Enables or disables the SPIx/I2Sx DMA interface.
+ * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
+ * @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_DMA_REQ(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;
+ }
+}
+
+/**
+ * @brief Configures the number of data to transfer type(Even/Odd) for the DMA
+ * last transfers and for the selected SPI.
+ * @note This function have a meaning only if DMA mode is selected and if
+ * the packing mode is used (data length <= 8 and DMA transfer size halfword)
+ * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
+ * @param SPI_LastDMATransfer: specifies the SPI last DMA transfers state.
+ * This parameter can be one of the following values:
+ * @arg SPI_LastDMATransfer_TxEvenRxEven: Number of data for transmission Even
+ * and number of data for reception Even.
+ * @arg SPI_LastDMATransfer_TxOddRxEven: Number of data for transmission Odd
+ * and number of data for reception Even.
+ * @arg SPI_LastDMATransfer_TxEvenRxOdd: Number of data for transmission Even
+ * and number of data for reception Odd.
+ * @arg SPI_LastDMATransfer_TxOddRxOdd: Number of data for transmission Odd
+ * and number of data for reception Odd.
+ * @retval None
+ */
+void SPI_LastDMATransferCmd(SPI_TypeDef* SPIx, uint16_t SPI_LastDMATransfer)
+{
+ /* Check the parameters */
+ assert_param(IS_SPI_ALL_PERIPH(SPIx));
+ assert_param(IS_SPI_LAST_DMA_TRANSFER(SPI_LastDMATransfer));
+
+ /* Clear LDMA_TX and LDMA_RX bits */
+ SPIx->CR2 &= CR2_LDMA_MASK;
+
+ /* Set new LDMA_TX and LDMA_RX bits value */
+ SPIx->CR2 |= SPI_LastDMATransfer;
+}
+
+/**
+ * @}
+ */
+
+/** @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/I2S 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:
+ (#) SPI_I2S_FLAG_TXE : to indicate the status of the transmit buffer register
+ (#) SPI_I2S_FLAG_RXNE : to indicate the status of the receive buffer register
+ (#) SPI_I2S_FLAG_BSY : to indicate the state of the communication layer of the SPI.
+ (#) SPI_FLAG_CRCERR : to indicate if a CRC Calculation error occur
+ (#) SPI_FLAG_MODF : to indicate if a Mode Fault error occur
+ (#) SPI_I2S_FLAG_OVR : to indicate if an Overrun error occur
+ (#) SPI_I2S_FLAG_FRE: to indicate a Frame Format error occurs.
+ (#) I2S_FLAG_UDR: to indicate an Underrun error occurs.
+ (#) I2S_FLAG_CHSIDE: to indicate Channel Side.
+
+ [..]
+ (@)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/I2S communication can be managed by 3 interrupt sources
+ and 5 pending bits:
+ [..] Pending Bits:
+ (#) SPI_I2S_IT_TXE : to indicate the status of the transmit buffer register
+ (#) SPI_I2S_IT_RXNE : to indicate the status of the receive buffer register
+ (#) SPI_I2S_IT_OVR : to indicate if an Overrun error occur
+ (#) I2S_IT_UDR : to indicate an Underrun Error occurs.
+ (#) SPI_I2S_FLAG_FRE : to indicate a Frame Format error occurs.
+
+ [..] Interrupt Source:
+ (#) SPI_I2S_IT_TXE: specifies the interrupt source for the Tx buffer empty
+ interrupt.
+ (#) SPI_I2S_IT_RXNE : specifies the interrupt source for the Rx buffer not
+ empty interrupt.
+ (#) 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);
+
+ *** FIFO Status ***
+ ===================
+ [..] It is possible to monitor the FIFO status when a transfer is ongoing using the
+ following function:
+ (+) uint32_t SPI_GetFIFOStatus(uint8_t SPI_FIFO_Direction);
+
+ *** DMA Mode ***
+ ================
+ [..] In DMA Mode, the SPI communication can be managed by 2 DMA Channel
+ requests:
+ (#) SPI_I2S_DMAReq_Tx: specifies the Tx buffer DMA transfer request.
+ (#) 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: where x can be 1, 2 or 3 to select the SPI peripheral.
+ * @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 Returns the current SPIx Transmission FIFO filled level.
+ * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
+ * @retval The Transmission FIFO filling state.
+ * - SPI_TransmissionFIFOStatus_Empty: when FIFO is empty
+ * - SPI_TransmissionFIFOStatus_1QuarterFull: if more than 1 quarter-full.
+ * - SPI_TransmissionFIFOStatus_HalfFull: if more than 1 half-full.
+ * - SPI_TransmissionFIFOStatus_Full: when FIFO is full.
+ */
+uint16_t SPI_GetTransmissionFIFOStatus(SPI_TypeDef* SPIx)
+{
+ /* Get the SPIx Transmission FIFO level bits */
+ return (uint16_t)((SPIx->SR & SPI_SR_FTLVL));
+}
+
+/**
+ * @brief Returns the current SPIx Reception FIFO filled level.
+ * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
+ * @retval The Reception FIFO filling state.
+ * - SPI_ReceptionFIFOStatus_Empty: when FIFO is empty
+ * - SPI_ReceptionFIFOStatus_1QuarterFull: if more than 1 quarter-full.
+ * - SPI_ReceptionFIFOStatus_HalfFull: if more than 1 half-full.
+ * - SPI_ReceptionFIFOStatus_Full: when FIFO is full.
+ */
+uint16_t SPI_GetReceptionFIFOStatus(SPI_TypeDef* SPIx)
+{
+ /* Get the SPIx Reception FIFO level bits */
+ return (uint16_t)((SPIx->SR & SPI_SR_FRLVL));
+}
+
+/**
+ * @brief Checks whether the specified SPI flag is set or not.
+ * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
+ * @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_FRE: TI frame format error flag.
+ * @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: where x can be 1, 2 or 3 to select the SPI peripheral.
+ * @param SPI_I2S_FLAG: specifies the SPI flag to clear.
+ * This function clears only CRCERR 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 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_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 SPI/I2S interrupt has occurred or not.
+ * @param SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
+ * @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_IT_MODF: Mode Fault interrupt.
+ * @arg SPI_I2S_IT_OVR: Overrun interrupt.
+ * @arg I2S_IT_UDR: Underrun interrupt.
+ * @arg SPI_I2S_IT_FRE: 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;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Libraries/STM32F37x_StdPeriph_Driver/src/stm32f37x_syscfg.c b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Libraries/STM32F37x_StdPeriph_Driver/src/stm32f37x_syscfg.c
new file mode 100644
index 0000000..87ffb75
--- /dev/null
+++ b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Libraries/STM32F37x_StdPeriph_Driver/src/stm32f37x_syscfg.c
@@ -0,0 +1,378 @@
+/**
+ ******************************************************************************
+ * @file stm32f37x_syscfg.c
+ * @author MCD Application Team
+ * @version V1.0.0
+ * @date 20-September-2012
+ * @brief This file provides firmware functions to manage the following
+ * functionalities of the SYSCFG peripheral:
+ * + Remapping the memory mapped at 0x00000000
+ * + Remapping the DMA channels
+ * + Enabling I2C fast mode plus driving capability for I2C pins
+ * + Configuring the EXTI lines connection to the GPIO port
+ * + Configuring the CLASSB requirements
+ *
+ * @verbatim
+ ===============================================================================
+ ##### How to use this driver #####
+ ===============================================================================
+ [..]
+
+ The SYSCFG registers can be accessed only when the SYSCFG
+ interface APB clock is enabled.
+ To enable SYSCFG APB clock use:
+ RCC_APB2PeriphClockCmd(RCC_APBPeriph_SYSCFG, ENABLE).
+ * @endverbatim
+ *
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
+ *
+ * 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 "stm32f37x_syscfg.h"
+
+/** @addtogroup STM32F37x_StdPeriph_Driver
+ * @{
+ */
+
+/** @defgroup SYSCFG
+ * @brief SYSCFG driver modules
+ * @{
+ */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Reset value od SYSCFG_CFGR1 register */
+#define CFGR1_CLEAR_MASK ((uint32_t)0x7C000000)
+
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+/** @defgroup SYSCFG_Private_Functions
+ * @{
+ */
+
+/** @defgroup SYSCFG_Group1 SYSCFG Initialization and Configuration functions
+ * @brief SYSCFG Initialization and Configuration functions
+ *
+@verbatim
+ ===============================================================================
+ ##### SYSCFG Initialization and Configuration functions #####
+ ===============================================================================
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Deinitializes the SYSCFG registers to their default reset values.
+ * @param None
+ * @retval None
+ * @note MEM_MODE bits are not affected by APB reset.
+ * @note MEM_MODE bits took the value from the user option bytes.
+ * @note CFGR2 register is not affected by APB reset.
+ * @note CLASSB configuration bits are locked when set.
+ * @note To unlock the configuration, perform a system reset.
+ */
+void SYSCFG_DeInit(void)
+{
+ /* Set SYSCFG_CFGR1 register to reset value without affecting MEM_MODE bits */
+ SYSCFG->CFGR1 &= SYSCFG_CFGR1_MEM_MODE;
+
+ /* Set FPU Interrupt Enable bits to default value */
+ SYSCFG->CFGR1 |= 0x7C000000;
+
+ /* Set EXTICRx registers to reset value */
+ SYSCFG->EXTICR[0] = 0;
+ SYSCFG->EXTICR[1] = 0;
+ SYSCFG->EXTICR[2] = 0;
+ SYSCFG->EXTICR[3] = 0;
+
+ /* Set CFGR2 register to reset value */
+ SYSCFG->CFGR2 = 0;
+}
+
+/**
+ * @brief Configures the memory mapping at address 0x00000000.
+ * @param SYSCFG_MemoryRemap: 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_SystemMemory: System Flash memory mapped at 0x00000000
+ * @arg SYSCFG_MemoryRemap_SRAM: Embedded SRAM mapped at 0x00000000
+ * @retval None
+ */
+void SYSCFG_MemoryRemapConfig(uint32_t SYSCFG_MemoryRemap)
+{
+ uint32_t tmpctrl = 0;
+
+ /* Check the parameter */
+ assert_param(IS_SYSCFG_MEMORY_REMAP(SYSCFG_MemoryRemap));
+
+ /* Get CFGR1 register value */
+ tmpctrl = SYSCFG->CFGR1;
+
+ /* Clear MEM_MODE bits */
+ tmpctrl &= (uint32_t) (~SYSCFG_CFGR1_MEM_MODE);
+
+ /* Set the new MEM_MODE bits value */
+ tmpctrl |= (uint32_t) SYSCFG_MemoryRemap;
+
+ /* Set CFGR1 register with the new memory remap configuration */
+ SYSCFG->CFGR1 = tmpctrl;
+}
+
+/**
+ * @brief Configure the DMA channels remapping.
+ * @param SYSCFG_DMARemap: selects the DMA channels remap.
+ * This parameter can be one of the following values:
+ * @arg SYSCFG_DMARemap_TIM17: Remap TIM17 DMA1 requests from channel1 to channel2
+ * @arg SYSCFG_DMARemap_TIM16: Remap TIM16 DMA1 requests from channel3 to channel4
+ * @arg SYSCFG_DMARemap_TIM6DAC1Ch1: Remap TIM6/DAC1 channel1 DMA requests from DMA2 channel 3 to DMA1 channel 3
+ * @arg SYSCFG_DMARemap_TIM7DAC1Ch2: Remap TIM7/DAC1 channel2 DMA requests from DMA2 channel 4 to DMA1 channel 4
+ * @arg SYSCFG_DMARemap_TIM18DAC2Ch1: Remap TIM18/DAC2 channel1 DMA requests from DMA2 channel 5 to DMA1 channel 5
+ * @param NewState: new state of the DMA channel remapping.
+ * This parameter can be: ENABLE or DISABLE.
+ * @note When enabled, DMA channel of the selected peripheral is remapped
+ * @note When disabled, Default DMA channel is mapped to the selected peripheral
+ * @note By default TIM17 DMA requests is mapped to channel 1,
+ * use SYSCFG_DMAChannelRemapConfig(SYSCFG_DMARemap_TIM17, Enable) to remap
+ * TIM17 DMA requests to channel 2 and use
+ * SYSCFG_DMAChannelRemapConfig(SYSCFG_DMARemap_TIM17, Disable) to map
+ * TIM17 DMA requests to channel 1 (default mapping)
+ * @retval None
+ */
+void SYSCFG_DMAChannelRemapConfig(uint32_t SYSCFG_DMARemap, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_SYSCFG_DMA_REMAP(SYSCFG_DMARemap));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Remap the DMA channel */
+ SYSCFG->CFGR1 |= (uint32_t)SYSCFG_DMARemap;
+ }
+ else
+ {
+ /* use the default DMA channel mapping */
+ SYSCFG->CFGR1 &= (uint32_t)(~SYSCFG_DMARemap);
+ }
+}
+
+/**
+ * @brief Configure the I2C fast mode plus driving capability.
+ * @param SYSCFG_I2CFastModePlus: selects the pin.
+ * This parameter can be one of the following values:
+ * @arg SYSCFG_I2CFastModePlus_PB6: Configure fast mode plus driving capability for PB6
+ * @arg SYSCFG_I2CFastModePlus_PB7: Configure fast mode plus driving capability for PB7
+ * @arg SYSCFG_I2CFastModePlus_PB8: Configure fast mode plus driving capability for PB8
+ * @arg SYSCFG_I2CFastModePlus_PB9: Configure fast mode plus driving capability for PB9
+ * @arg SYSCFG_I2CFastModePlus_I2C1: Configure fast mode plus driving capability for I2C1 pins
+ * @arg SYSCFG_I2CFastModePlus_I2C2: Configure fast mode plus driving capability for I2C2 pins
+ * @param NewState: new state of the DMA channel remapping.
+ * This parameter can be: ENABLE or DISABLE.
+ * @note ENABLE: Enable fast mode plus driving capability for selected I2C pin
+ * @note DISABLE: Disable fast mode plus driving capability for selected I2C pin
+ * @note For I2C1, fast mode plus driving capability can be enabled on all selected
+ * I2C1 pins using SYSCFG_I2CFastModePlus_I2C1 parameter or independently
+ * on each one of the following pins PB6, PB7, PB8 and PB9.
+ * @note For remaining I2C1 pins (PA14, PA15...) fast mode plus driving capability
+ * can be enabled only by using SYSCFG_I2CFastModePlus_I2C1 parameter
+ * For all I2C2 pins fast mode plus driving capability can be enabled
+ * only by using SYSCFG_I2CFastModePlus_I2C2 parameter
+ * @retval None
+ */
+void SYSCFG_I2CFastModePlusConfig(uint32_t SYSCFG_I2CFastModePlus, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_SYSCFG_I2C_FMP(SYSCFG_I2CFastModePlus));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable fast mode plus driving capability for selected I2C pin */
+ SYSCFG->CFGR1 |= (uint32_t)SYSCFG_I2CFastModePlus;
+ }
+ else
+ {
+ /* Disable fast mode plus driving capability for selected I2C pin */
+ SYSCFG->CFGR1 &= (uint32_t)(~SYSCFG_I2CFastModePlus);
+ }
+}
+
+/**
+ * @brief Control the VBAT monitoring
+ * @param NewState: new state of the VBAT connection to ADC channel 18.
+ * This parameter can be: ENABLE or DISABLE.
+ * @note ENABLE: Enable VBAT monitoring by connecting internally VBAT to ADC channel 18
+ * @note DISABLE: Disable VBAT monitoring by disconnecting VBAT from ADC channel 18
+ * @retval None
+ */
+void SYSCFG_VBATMonitoringCmd(FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable VBAT monitoring */
+ SYSCFG->CFGR1 |= SYSCFG_CFGR1_VBAT;
+ }
+ else
+ {
+ /* Disable VBAT monitoring */
+ SYSCFG->CFGR1 &= ((uint32_t)~SYSCFG_CFGR1_VBAT);
+ }
+}
+
+/**
+ * @brief Enables or disables the selected SYSCFG interrupts.
+ * @param SYSCFG_IT: specifies the SYSCFG interrupt sources to be enabled or disabled.
+ * This parameter can be one of the following values:
+ * @arg SYSCFG_IT_IXC: Inexact Interrupt
+ * @arg SYSCFG_IT_IDC: Input denormal Interrupt
+ * @arg SYSCFG_IT_OFC: Overflow Interrupt
+ * @arg SYSCFG_IT_UFC: Underflow Interrupt
+ * @arg SYSCFG_IT_DZC: Divide-by-zero Interrupt
+ * @arg SYSCFG_IT_IOC: Invalid operation Interrupt
+ * @param NewState: new state of the specified SDADC interrupts.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void SYSCFG_ITConfig(uint32_t SYSCFG_IT, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ assert_param(IS_SYSCFG_IT(SYSCFG_IT));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the selected SYSCFG interrupts */
+ SYSCFG->CFGR1 |= SYSCFG_IT;
+ }
+ else
+ {
+ /* Disable the selected SYSCFG interrupts */
+ SYSCFG->CFGR1 &= ((uint32_t)~SYSCFG_IT);
+ }
+}
+
+/**
+ * @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, B, C, D, E or F).
+ * @param EXTI_PinSourcex: specifies the EXTI line to be configured.
+ * This parameter can be EXTI_PinSourcex where x can be (0..15)
+ * @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 Connect the selected parameter to the break input of TIM15/TIM16/TIM17.
+ * @note The selected configuration is locked and can be unlocked by system reset
+ * @param SYSCFG_Break: selects the configuration to be connected to break
+ * input of TIM15/TIM16/TIM17
+ * This parameter can be any combination of the following values:
+ * @arg SYSCFG_Break_PVD: Connects the PVD event to the Break Input of TIM15/TIM16/TIM17.
+ * @arg SYSCFG_Break_SRAMParity: Connects the SRAM_PARITY error signal to the Break Input of TIM15/TIM16/TIM17 .
+ * @arg SYSCFG_Break_Lockup: Connects Lockup output of CortexM4 to the break input of TIM15/TIM16/TIM17.
+ * @retval None
+ */
+void SYSCFG_BreakConfig(uint32_t SYSCFG_Break)
+{
+ /* Check the parameter */
+ assert_param(IS_SYSCFG_LOCK_CONFIG(SYSCFG_Break));
+
+ SYSCFG->CFGR2 |= (uint32_t) SYSCFG_Break;
+}
+
+/**
+ * @brief Checks whether the specified SYSCFG flag is set or not.
+ * @param SYSCFG_Flag: specifies the SYSCFG flag to check.
+ * This parameter can be one of the following values:
+ * @arg SYSCFG_FLAG_PE: SRAM parity error flag.
+ * @retval The new state of SYSCFG_Flag (SET or RESET).
+ */
+FlagStatus SYSCFG_GetFlagStatus(uint32_t SYSCFG_Flag)
+{
+ FlagStatus bitstatus = RESET;
+
+ /* Check the parameter */
+ assert_param(IS_SYSCFG_FLAG(SYSCFG_Flag));
+
+ /* Check the status of the specified SPI flag */
+ if ((SYSCFG->CFGR2 & SYSCFG_CFGR2_SRAM_PE) != (uint32_t)RESET)
+ {
+ /* SYSCFG_Flag is set */
+ bitstatus = SET;
+ }
+ else
+ {
+ /* SYSCFG_Flag is reset */
+ bitstatus = RESET;
+ }
+ /* Return the SYSCFG_Flag status */
+ return bitstatus;
+}
+
+/**
+ * @brief Clear the selected SYSCFG flag.
+ * @param SYSCFG_Flag: selects the flag to be cleared.
+ * This parameter can be any combination of the following values:
+ * @arg SYSCFG_FLAG_PE: SRAM parity error flag.
+ * @retval None
+ */
+void SYSCFG_ClearFlag(uint32_t SYSCFG_Flag)
+{
+ /* Check the parameter */
+ assert_param(IS_SYSCFG_FLAG(SYSCFG_Flag));
+
+ SYSCFG->CFGR2 |= (uint32_t) SYSCFG_Flag;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
diff --git a/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Libraries/STM32F37x_StdPeriph_Driver/src/stm32f37x_usart.c b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Libraries/STM32F37x_StdPeriph_Driver/src/stm32f37x_usart.c
new file mode 100644
index 0000000..f6b2f8a
--- /dev/null
+++ b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Libraries/STM32F37x_StdPeriph_Driver/src/stm32f37x_usart.c
@@ -0,0 +1,2003 @@
+/**
+ ******************************************************************************
+ * @file stm32f37x_usart.c
+ * @author MCD Application Team
+ * @version V1.0.0
+ * @date 20-September-2012
+ * @brief This file provides firmware functions to manage the following
+ * functionalities of the Universal synchronous asynchronous receiver
+ * transmitter (USART):
+ * + Initialization and Configuration
+ * + STOP Mode
+ * + AutoBaudRate
+ * + Data transfers
+ * + Multi-Processor Communication
+ * + LIN mode
+ * + Half-duplex mode
+ * + Smartcard mode
+ * + IrDA mode
+ * + RS485 mode
+ * + DMA transfers management
+ * + Interrupts and flags management
+ *
+ * @verbatim
+ ===============================================================================
+ ##### How to use this driver #####
+ ===============================================================================
+ [..]
+ (#) Enable peripheral clock using RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE)
+ function for USART1 or using RCC_APB1PeriphClockCmd(RCC_APB1Periph_USARTx, ENABLE)
+ function for USART2 and USART3.
+ (#) According to the USART mode, enable the GPIO clocks using
+ RCC_AHBPeriphClockCmd() function. (The I/O can be TX, RX, CTS,
+ or and SCLK).
+ (#) 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.
+ (#) Program the Baud Rate, Word Length , Stop Bit, Parity, Hardware
+ flow control and Mode(Receiver/Transmitter) using the SPI_Init()
+ function.
+ (#) For synchronous mode, enable the clock and program the polarity,
+ phase and last bit using the USART_ClockInit() function.
+ (#) Enable the NVIC and the corresponding interrupt using the function
+ USART_ITConfig() if you need to use interrupt mode.
+ (#) When using the DMA mode:
+ (++) Configure the DMA using DMA_Init() function.
+ (++) Active the needed channel Request using USART_DMACmd() function.
+ (#) Enable the USART using the USART_Cmd() function.
+ (#) 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.
+
+@endverbatim
+
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
+ *
+ * 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 "stm32f37x_usart.h"
+#include "stm32f37x_rcc.h"
+
+/** @addtogroup STM32F37x_StdPeriph_Driver
+ * @{
+ */
+
+/** @defgroup USART
+ * @brief USART driver modules
+ * @{
+ */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+
+/*!< USART CR1 register clear Mask ((~(uint32_t)0xFFFFE6F3)) */
+#define CR1_CLEAR_MASK ((uint32_t)(USART_CR1_M | USART_CR1_PCE | \
+ USART_CR1_PS | USART_CR1_TE | \
+ USART_CR1_RE))
+
+/*!< USART CR2 register clock bits clear Mask ((~(uint32_t)0xFFFFF0FF)) */
+#define CR2_CLOCK_CLEAR_MASK ((uint32_t)(USART_CR2_CLKEN | USART_CR2_CPOL | \
+ USART_CR2_CPHA | USART_CR2_LBCL))
+
+/*!< USART CR3 register clear Mask ((~(uint32_t)0xFFFFFCFF)) */
+#define CR3_CLEAR_MASK ((uint32_t)(USART_CR3_RTSE | USART_CR3_CTSE))
+
+/*!< USART Interrupts mask */
+#define IT_MASK ((uint32_t)0x000000FF)
+
+/* 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.
+ (+) 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 or 2 or 3 to select the USART 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);
+ }
+ }
+}
+
+/**
+ * @brief Initializes the USARTx peripheral according to the specified
+ * parameters in the USART_InitStruct .
+ * @param USARTx: where x can be 1 or 2 or 3 to select the USART 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 divider = 0, apbclock = 0, tmpreg = 0;
+ 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));
+
+ /* Disable USART */
+ USARTx->CR1 &= (uint32_t)~((uint32_t)USART_CR1_UE);
+
+/*---------------------------- 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 = 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 = 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 = tmpreg;
+
+ /*---------------------------- USART BRR Configuration -----------------------*/
+ /* Configure the USART Baud Rate -------------------------------------------*/
+ RCC_GetClocksFreq(&RCC_ClocksStatus);
+
+ if (USARTx == USART1)
+ {
+ apbclock = RCC_ClocksStatus.USART1CLK_Frequency;
+ }
+ else if (USARTx == USART2)
+ {
+ apbclock = RCC_ClocksStatus.USART2CLK_Frequency;
+ }
+ else
+ {
+ apbclock = RCC_ClocksStatus.USART3CLK_Frequency;
+ }
+
+ /* Determine the integer part */
+ if ((USARTx->CR1 & USART_CR1_OVER8) != 0)
+ {
+ /* (divider * 10) computing in case Oversampling mode is 8 Samples */
+ divider = (uint32_t)((2 * apbclock) / (USART_InitStruct->USART_BaudRate));
+ tmpreg = (uint32_t)((2 * apbclock) % (USART_InitStruct->USART_BaudRate));
+ }
+ else /* if ((USARTx->CR1 & CR1_OVER8_Set) == 0) */
+ {
+ /* (divider * 10) computing in case Oversampling mode is 16 Samples */
+ divider = (uint32_t)((apbclock) / (USART_InitStruct->USART_BaudRate));
+ tmpreg = (uint32_t)((apbclock) % (USART_InitStruct->USART_BaudRate));
+ }
+
+ /* round the divider : if fractional part i greater than 0.5 increment divider */
+ if (tmpreg >= (USART_InitStruct->USART_BaudRate) / 2)
+ {
+ divider++;
+ }
+
+ /* Implement the divider in case Oversampling mode is 8 Samples */
+ if ((USARTx->CR1 & USART_CR1_OVER8) != 0)
+ {
+ /* get the LSB of divider and shift it to the right by 1 bit */
+ tmpreg = (divider & (uint16_t)0x000F) >> 1;
+
+ /* update the divider value */
+ divider = (divider & (uint16_t)0xFFF0) | tmpreg;
+ }
+
+ /* Write to USART BRR */
+ USARTx->BRR = (uint16_t)divider;
+}
+
+/**
+ * @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 or 2 or 3 to select the USART peripheral.
+ * @param USART_ClockInitStruct: pointer to a USART_ClockInitTypeDef
+ * structure that contains the configuration information for the specified
+ * USART peripheral.
+ * @retval None
+ */
+void USART_ClockInit(USART_TypeDef* USARTx, USART_ClockInitTypeDef* USART_ClockInitStruct)
+{
+ uint32_t tmpreg = 0;
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_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, LBCL and SSM bits */
+ tmpreg &= (uint32_t)~((uint32_t)CR2_CLOCK_CLEAR_MASK);
+ /* Configure the USART Clock, CPOL, CPHA, LastBit and SSM ------------*/
+ /* 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 = 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 or 2 or 3 to select the USART 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 &= (uint32_t)~((uint32_t)USART_CR1_UE);
+ }
+}
+
+/**
+ * @brief Enables or disables the USART's transmitter or receiver.
+ * @param USARTx: where x can be 1 or 2 or 3 to select the USART peripheral.
+ * @param USART_Direction: specifies the USART direction.
+ * This parameter can be any combination of the following values:
+ * @arg USART_Mode_Tx: USART Transmitter
+ * @arg USART_Mode_Rx: USART Receiver
+ * @param NewState: new state of the USART transfer direction.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void USART_DirectionModeCmd(USART_TypeDef* USARTx, uint32_t USART_DirectionMode, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+ assert_param(IS_USART_MODE(USART_DirectionMode));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the USART's transfer interface by setting the TE and/or RE bits
+ in the USART CR1 register */
+ USARTx->CR1 |= USART_DirectionMode;
+ }
+ else
+ {
+ /* Disable the USART's transfer interface by clearing the TE and/or RE bits
+ in the USART CR3 register */
+ USARTx->CR1 &= (uint32_t)~USART_DirectionMode;
+ }
+}
+
+/**
+ * @brief Enables or disables the USART's 8x oversampling mode.
+ * @param USARTx: where x can be 1 or 2 or 3 to select the USART peripheral.
+ * @param NewState: new state of the USART 8x oversampling mode.
+ * This parameter can be: ENABLE or DISABLE.
+ * @note This function has to be called before calling USART_Init() function
+ * in order to have correct baudrate Divider value.
+ * @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 &= (uint32_t)~((uint32_t)USART_CR1_OVER8);
+ }
+}
+
+/**
+ * @brief Enables or disables the USART's one bit sampling method.
+ * @param USARTx: where x can be 1 or 2 or 3 to select the USART peripheral.
+ * @param NewState: new state of the USART one bit sampling method.
+ * This parameter can be: ENABLE or DISABLE.
+ * @note This function has to be called before calling USART_Cmd() function.
+ * @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 &= (uint32_t)~((uint32_t)USART_CR3_ONEBIT);
+ }
+}
+
+/**
+ * @brief Enables or disables the USART's most significant bit first
+ * transmitted/received following the start bit.
+ * @param USARTx: where x can be 1 or 2 or 3 to select the USART peripheral.
+ * @param NewState: new state of the USART most significant bit first
+ * transmitted/received following the start bit.
+ * This parameter can be: ENABLE or DISABLE.
+ * @note This function has to be called before calling USART_Cmd() function.
+ * @retval None
+ */
+void USART_MSBFirstCmd(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 most significant bit first transmitted/received following the
+ start bit by setting the MSBFIRST bit in the CR2 register */
+ USARTx->CR2 |= USART_CR2_MSBFIRST;
+ }
+ else
+ {
+ /* Disable the most significant bit first transmitted/received following the
+ start bit by clearing the MSBFIRST bit in the CR2 register */
+ USARTx->CR2 &= (uint32_t)~((uint32_t)USART_CR2_MSBFIRST);
+ }
+}
+
+/**
+ * @brief Enables or disables the binary data inversion.
+ * @param USARTx: where x can be 1 or 2 or 3 to select the USART peripheral.
+ * @param NewState: new defined levels for the USART data.
+ * This parameter can be:
+ * @arg ENABLE: Logical data from the data register are send/received in negative
+ * logic (1=L, 0=H). The parity bit is also inverted.
+ * @arg DISABLE: Logical data from the data register are send/received in positive
+ * logic (1=H, 0=L)
+ * @note This function has to be called before calling USART_Cmd() function.
+ * @retval None
+ */
+void USART_DataInvCmd(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 binary data inversion feature by setting the DATAINV bit in
+ the CR2 register */
+ USARTx->CR2 |= USART_CR2_DATAINV;
+ }
+ else
+ {
+ /* Disable the binary data inversion feature by clearing the DATAINV bit in
+ the CR2 register */
+ USARTx->CR2 &= (uint32_t)~((uint32_t)USART_CR2_DATAINV);
+ }
+}
+
+/**
+ * @brief Enables or disables the Pin(s) active level inversion.
+ * @param USARTx: where x can be 1 or 2 or 3 to select the USART peripheral.
+ * @param USART_InvPin: specifies the USART pin(s) to invert.
+ * This parameter can be any combination of the following values:
+ * @arg USART_InvPin_Tx: USART Tx pin active level inversion.
+ * @arg USART_InvPin_Rx: USART Rx pin active level inversion.
+ * @param NewState: new active level status for the USART pin(s).
+ * This parameter can be:
+ * @arg ENABLE: pin(s) signal values are inverted (Vdd =0, Gnd =1).
+ * @arg DISABLE: pin(s) signal works using the standard logic levels (Vdd =1, Gnd =0).
+ * @note This function has to be called before calling USART_Cmd() function.
+ * @retval None
+ */
+void USART_InvPinCmd(USART_TypeDef* USARTx, uint32_t USART_InvPin, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+ assert_param(IS_USART_INVERSTION_PIN(USART_InvPin));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the active level inversion for selected pins by setting the TXINV
+ and/or RXINV bits in the USART CR2 register */
+ USARTx->CR2 |= USART_InvPin;
+ }
+ else
+ {
+ /* Disable the active level inversion for selected requests by clearing the
+ TXINV and/or RXINV bits in the USART CR2 register */
+ USARTx->CR2 &= (uint32_t)~USART_InvPin;
+ }
+}
+
+/**
+ * @brief Enables or disables the swap Tx/Rx pins.
+ * @param USARTx: where x can be 1 or 2 or 3 to select the USART peripheral.
+ * @param NewState: new state of the USARTx TX/RX pins pinout.
+ * This parameter can be:
+ * @arg ENABLE: The TX and RX pins functions are swapped.
+ * @arg DISABLE: TX/RX pins are used as defined in standard pinout
+ * @note This function has to be called before calling USART_Cmd() function.
+ * @retval None
+ */
+void USART_SWAPPinCmd(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 SWAP feature by setting the SWAP bit in the CR2 register */
+ USARTx->CR2 |= USART_CR2_SWAP;
+ }
+ else
+ {
+ /* Disable the SWAP feature by clearing the SWAP bit in the CR2 register */
+ USARTx->CR2 &= (uint32_t)~((uint32_t)USART_CR2_SWAP);
+ }
+}
+
+/**
+ * @brief Enables or disables the receiver Time Out feature.
+ * @param USARTx: where x can be 1 or 2 or 3 to select the USART peripheral.
+ * @param NewState: new state of the USARTx receiver Time Out.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void USART_ReceiverTimeOutCmd(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 receiver time out feature by setting the RTOEN bit in the CR2
+ register */
+ USARTx->CR2 |= USART_CR2_RTOEN;
+ }
+ else
+ {
+ /* Disable the receiver time out feature by clearing the RTOEN bit in the CR2
+ register */
+ USARTx->CR2 &= (uint32_t)~((uint32_t)USART_CR2_RTOEN);
+ }
+}
+
+/**
+ * @brief Sets the receiver Time Out value.
+ * @param USARTx: where x can be 1 or 2 or 3 to select the USART peripheral.
+ * @param USART_ReceiverTimeOut: specifies the Receiver Time Out value.
+ * @retval None
+ */
+void USART_SetReceiverTimeOut(USART_TypeDef* USARTx, uint32_t USART_ReceiverTimeOut)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+ assert_param(IS_USART_TIMEOUT(USART_ReceiverTimeOut));
+
+ /* Clear the receiver Time Out value by clearing the RTO[23:0] bits in the RTOR
+ register */
+ USARTx->RTOR &= (uint32_t)~((uint32_t)USART_RTOR_RTO);
+ /* Set the receiver Time Out value by setting the RTO[23:0] bits in the RTOR
+ register */
+ USARTx->RTOR |= USART_ReceiverTimeOut;
+}
+
+/**
+ * @brief Sets the system clock prescaler.
+ * @param USARTx: where x can be 1 or 2 or 3 to select the USART peripheral.
+ * @param USART_Prescaler: specifies the prescaler clock.
+ * @note This function has to be called before calling USART_Cmd() function.
+ * @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;
+}
+
+/**
+ * @}
+ */
+
+
+/** @defgroup USART_Group2 STOP Mode functions
+ * @brief STOP Mode functions
+ *
+@verbatim
+ ===============================================================================
+ ##### STOP Mode functions #####
+ ===============================================================================
+ [..] This subsection provides a set of functions allowing to manage
+ WakeUp from STOP mode.
+
+ [..] The USART is able to WakeUp from Stop Mode if USART clock is set to HSI
+ or LSI.
+
+ [..] The WakeUp source is configured by calling USART_StopModeWakeUpSourceConfig()
+ function.
+
+ [..] After configuring the source of WakeUp and before entering in Stop Mode
+ USART_STOPModeCmd() function should be called to allow USART WakeUp.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Enables or disables the specified USART peripheral in STOP Mode.
+ * @param USARTx: where x can be 1 or 2 or 3 to select the USART peripheral.
+ * @param NewState: new state of the USARTx peripheral state in stop mode.
+ * This parameter can be: ENABLE or DISABLE.
+ * @note This function has to be called when USART clock is set to HSI or LSE.
+ * @retval None
+ */
+void USART_STOPModeCmd(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 in STOP mode by setting the UESM bit in the CR1
+ register */
+ USARTx->CR1 |= USART_CR1_UESM;
+ }
+ else
+ {
+ /* Disable the selected USART in STOP mode by clearing the UE bit in the CR1
+ register */
+ USARTx->CR1 &= (uint32_t)~((uint32_t)USART_CR1_UESM);
+ }
+}
+
+/**
+ * @brief Selects the USART WakeUp method form stop mode.
+ * @param USARTx: where x can be 1 or 2 or 3 to select the USART peripheral.
+ * @param USART_WakeUp: specifies the selected USART wakeup method.
+ * This parameter can be one of the following values:
+ * @arg USART_WakeUpSource_AddressMatch: WUF active on address match.
+ * @arg USART_WakeUpSource_StartBit: WUF active on Start bit detection.
+ * @arg USART_WakeUpSource_RXNE: WUF active on RXNE.
+ * @note This function has to be called before calling USART_Cmd() function.
+ * @retval None
+ */
+void USART_StopModeWakeUpSourceConfig(USART_TypeDef* USARTx, uint32_t USART_WakeUpSource)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+ assert_param(IS_USART_STOPMODE_WAKEUPSOURCE(USART_WakeUpSource));
+
+ USARTx->CR3 &= (uint32_t)~((uint32_t)USART_CR3_WUS);
+ USARTx->CR3 |= USART_WakeUpSource;
+}
+
+/**
+ * @}
+ */
+
+
+/** @defgroup USART_Group3 AutoBaudRate functions
+ * @brief AutoBaudRate functions
+ *
+@verbatim
+ ===============================================================================
+ ##### AutoBaudRate functions #####
+ ===============================================================================
+ [..] This subsection provides a set of functions allowing to manage
+ the AutoBaudRate detections.
+
+ [..] Before Enabling AutoBaudRate detection using USART_AutoBaudRateCmd ()
+ The character patterns used to calculate baudrate must be chosen by calling
+ USART_AutoBaudRateConfig() function. These function take as parameter :
+ (#)USART_AutoBaudRate_StartBit : any character starting with a bit 1.
+ (#)USART_AutoBaudRate_FallingEdge : any character starting with a 10xx bit pattern.
+
+ [..] At any later time, another request for AutoBaudRate detection can be performed
+ using USART_RequestCmd() function.
+
+ [..] The AutoBaudRate detection is monitored by the status of ABRF flag which indicate
+ that the AutoBaudRate detection is completed. In addition to ABRF flag, the ABRE flag
+ indicate that this procedure is completed without success. USART_GetFlagStatus ()
+ function should be used to monitor the status of these flags.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Enables or disables the Auto Baud Rate.
+ * @param USARTx: where x can be 1 or 2 or 3 to select the USART peripheral.
+ * @param NewState: new state of the USARTx auto baud rate.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void USART_AutoBaudRateCmd(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 auto baud rate feature by setting the ABREN bit in the CR2
+ register */
+ USARTx->CR2 |= USART_CR2_ABREN;
+ }
+ else
+ {
+ /* Disable the auto baud rate feature by clearing the ABREN bit in the CR2
+ register */
+ USARTx->CR2 &= (uint32_t)~((uint32_t)USART_CR2_ABREN);
+ }
+}
+
+/**
+ * @brief Selects the USART auto baud rate method.
+ * @param USARTx: where x can be 1 or 2 or 3 to select the USART peripheral.
+ * @param USART_AutoBaudRate: specifies the selected USART auto baud rate method.
+ * This parameter can be one of the following values:
+ * @arg USART_AutoBaudRate_StartBit: Start Bit duration measurement.
+ * @arg USART_AutoBaudRate_FallingEdge: Falling edge to falling edge measurement.
+ * @note This function has to be called before calling USART_Cmd() function.
+ * @retval None
+ */
+void USART_AutoBaudRateConfig(USART_TypeDef* USARTx, uint32_t USART_AutoBaudRate)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+ assert_param(IS_USART_AUTOBAUDRATE_MODE(USART_AutoBaudRate));
+
+ USARTx->CR2 &= (uint32_t)~((uint32_t)USART_CR2_ABRMODE);
+ USARTx->CR2 |= USART_AutoBaudRate;
+}
+
+/**
+ * @}
+ */
+
+
+/** @defgroup USART_Group4 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. When a transmission is taking place, a write instruction to
+ the USART_TDR register stores the data in the shift register.
+ [..] The read access of the USART_RDR register can be done using
+ the USART_ReceiveData() function and returns the RDR value.
+ Whereas a write access to the USART_TDR can be done using USART_SendData()
+ function and stores the written data into TDR.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Transmits single data through the USARTx peripheral.
+ * @param USARTx: where x can be 1 or 2 or 3 to select the USART 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->TDR = (Data & (uint16_t)0x01FF);
+}
+
+/**
+ * @brief Returns the most recent received data by the USARTx peripheral.
+ * @param USARTx: where x can be 1 or 2 or 3 to select the USART 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->RDR & (uint16_t)0x01FF);
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup USART_Group5 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:
+ (#) 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.
+ (#) Configures the USART address using the USART_SetAddress() function.
+ (#) Configures the wake up methode (USART_WakeUp_IdleLine or
+ USART_WakeUp_AddressMark) using USART_WakeUpConfig() function only
+ for the slaves.
+ (#) Enable the USART using the USART_Cmd() function.
+ (#) 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 or 2 or 3 to select the USART 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));
+
+ /* Clear the USART address */
+ USARTx->CR2 &= (uint32_t)~((uint32_t)USART_CR2_ADD);
+ /* Set the USART address node */
+ USARTx->CR2 |=((uint32_t)USART_Address << (uint32_t)0x18);
+}
+
+/**
+ * @brief Enables or disables the USART's mute mode.
+ * @param USARTx: where x can be 1 or 2 or 3 to select the USART peripheral.
+ * @param NewState: new state of the USART mute mode.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void USART_MuteModeCmd(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 MME bit in the CR1 register */
+ USARTx->CR1 |= USART_CR1_MME;
+ }
+ else
+ {
+ /* Disable the USART mute mode by clearing the MME bit in the CR1 register */
+ USARTx->CR1 &= (uint32_t)~((uint32_t)USART_CR1_MME);
+ }
+}
+
+/**
+ * @brief Selects the USART WakeUp method from mute mode.
+ * @param USARTx: where x can be 1 or 2 or 3 to select the USART 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_MuteModeWakeUpConfig(USART_TypeDef* USARTx, uint32_t USART_WakeUp)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+ assert_param(IS_USART_MUTEMODE_WAKEUP(USART_WakeUp));
+
+ USARTx->CR1 &= (uint32_t)~((uint32_t)USART_CR1_WAKE);
+ USARTx->CR1 |= USART_WakeUp;
+}
+
+/**
+ * @brief Configure the the USART Address detection length.
+ * @param USARTx: where x can be 1 or 2 or 3 to select the USART peripheral.
+ * @param USART_AddressLength: specifies the USART address length detection.
+ * This parameter can be one of the following values:
+ * @arg USART_AddressLength_4b: 4-bit address length detection
+ * @arg USART_AddressLength_7b: 7-bit address length detection
+ * @retval None
+ */
+void USART_AddressDetectionConfig(USART_TypeDef* USARTx, uint32_t USART_AddressLength)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+ assert_param(IS_USART_ADDRESS_DETECTION(USART_AddressLength));
+
+ USARTx->CR2 &= (uint32_t)~((uint32_t)USART_CR2_ADDM7);
+ USARTx->CR2 |= USART_AddressLength;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup USART_Group6 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:
+ (#) 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.
+ (#) Enable the LIN mode using the USART_LINCmd() function.
+ (#) Enable the USART using the USART_Cmd() function.
+ (#) Send the break character using USART_SendBreak() function.
+ [..] USART LIN Master receiver communication is possible through the
+ following procedure:
+ (#) 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.
+ (#) Configures the break detection length
+ using the USART_LINBreakDetectLengthConfig() function.
+ (#) Enable the LIN mode using the USART_LINCmd() function.
+ -@- 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.
+ (#) Enable the USART using the USART_Cmd() function.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Sets the USART LIN Break detection length.
+ * @param USARTx: where x can be 1 or 2 or 3 to select the USART 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, uint32_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 &= (uint32_t)~((uint32_t)USART_CR2_LBDL);
+ USARTx->CR2 |= USART_LINBreakDetectLength;
+}
+
+/**
+ * @brief Enables or disables the USART's LIN mode.
+ * @param USARTx: where x can be 1 or 2 or 3 to select the USART 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 &= (uint32_t)~((uint32_t)USART_CR2_LINEN);
+ }
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup USART_Group7 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:
+ (#) Program the Baud rate, Word length, Stop bits, Parity, Mode transmitter
+ or Mode receiver and hardware flow control values using the USART_Init()
+ function.
+ (#) Configures the USART address using the USART_SetAddress() function.
+ (#) Enable the half duplex mode using USART_HalfDuplexCmd() function.
+ (#) Enable the USART using the USART_Cmd() function.
+ -@- The RX pin is no longer used.
+ -@- 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 or 2 or 3 to select the USART 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 &= (uint32_t)~((uint32_t)USART_CR3_HDSEL);
+ }
+}
+
+/**
+ * @}
+ */
+
+
+/** @defgroup USART_Group8 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:
+ (#) Configures the Smartcard Prsecaler using the USART_SetPrescaler()
+ function.
+ (#) Configures the Smartcard Guard Time using the USART_SetGuardTime()
+ function.
+ (#) 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.
+ (#) 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
+ (#) Optionally you can enable the parity error interrupt using
+ the USART_ITConfig() function.
+ (#) Enable the Smartcard NACK using the USART_SmartCardNACKCmd() function.
+ (#) Enable the Smartcard interface using the USART_SmartCardCmd() function.
+ (#) Enable the USART using the USART_Cmd() function.
+ [..]
+ Please refer to the ISO 7816-3 specification for more details.
+ [..]
+ (@) 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.
+ (@) 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.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Sets the specified USART guard time.
+ * @param USARTx: where x can be 1 or 2 or 3 to select the USART 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_ALL_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 or 2 or 3 to select the USART 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_ALL_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 &= (uint32_t)~((uint32_t)USART_CR3_SCEN);
+ }
+}
+
+/**
+ * @brief Enables or disables NACK transmission.
+ * @param USARTx: where x can be 1 or 2 or 3 to select the USART 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_ALL_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 &= (uint32_t)~((uint32_t)USART_CR3_NACK);
+ }
+}
+
+/**
+ * @brief Sets the Smart Card number of retries in transmit and receive.
+ * @param USARTx: where x can be 1 or 2 or 3 to select the USART peripheral.
+ * @param USART_AutoCount: specifies the Smart Card auto retry count.
+ * @retval None
+ */
+void USART_SetAutoRetryCount(USART_TypeDef* USARTx, uint8_t USART_AutoCount)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+ assert_param(IS_USART_AUTO_RETRY_COUNTER(USART_AutoCount));
+ /* Clear the USART auto retry count */
+ USARTx->CR3 &= (uint32_t)~((uint32_t)USART_CR3_SCARCNT);
+ /* Set the USART auto retry count*/
+ USARTx->CR3 |= (uint32_t)((uint32_t)USART_AutoCount << 0x11);
+}
+
+/**
+ * @brief Sets the Smart Card Block length.
+ * @param USARTx: where x can be 1 or 2 or 3 to select the USART peripheral.
+ * @param USART_BlockLength: specifies the Smart Card block length.
+ * @retval None
+ */
+void USART_SetBlockLength(USART_TypeDef* USARTx, uint8_t USART_BlockLength)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+
+ /* Clear the Smart card block length */
+ USARTx->RTOR &= (uint32_t)~((uint32_t)USART_RTOR_BLEN);
+ /* Set the Smart Card block length */
+ USARTx->RTOR |= (uint32_t)((uint32_t)USART_BlockLength << 0x18);
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup USART_Group9 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:
+ (#) Program the Baud rate, Word length = 8 bits, Stop bits, Parity,
+ Transmitter/Receiver modes and hardware flow control values using
+ the USART_Init() function.
+ (#) Configures the IrDA pulse width by configuring the prescaler using
+ the USART_SetPrescaler() function.
+ (#) Configures the IrDA USART_IrDAMode_LowPower or USART_IrDAMode_Normal
+ mode using the USART_IrDAConfig() function.
+ (#) Enable the IrDA using the USART_IrDACmd() function.
+ (#) Enable the USART using the USART_Cmd() function.
+ [..]
+ (@) A pulse of width less than two and greater than one PSC period(s) may or
+ may not be rejected.
+ (@) 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).
+ (@) 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 or 2 or 3 to select the USART 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, uint32_t USART_IrDAMode)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+ assert_param(IS_USART_IRDA_MODE(USART_IrDAMode));
+
+ USARTx->CR3 &= (uint32_t)~((uint32_t)USART_CR3_IRLP);
+ USARTx->CR3 |= USART_IrDAMode;
+}
+
+/**
+ * @brief Enables or disables the USART's IrDA interface.
+ * @param USARTx: where x can be 1 or 2 or 3 to select the USART 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 &= (uint32_t)~((uint32_t)USART_CR3_IREN);
+ }
+}
+/**
+ * @}
+ */
+
+/** @defgroup USART_Group10 RS485 mode function
+ * @brief RS485 mode function
+ *
+@verbatim
+ ===============================================================================
+ ##### RS485 mode functions #####
+ ===============================================================================
+ [..] This subsection provides a set of functions allowing to manage the USART
+ RS485 flow control.
+ [..] RS485 flow control (Driver enable feature) handling is possible through
+ the following procedure:
+ (#) Program the Baud rate, Word length = 8 bits, Stop bits, Parity,
+ Transmitter/Receiver modes and hardware flow control values using
+ the USART_Init() function.
+ (#) Enable the Driver Enable using the USART_DECmd() function.
+ (#) Configures the Driver Enable polarity using the USART_DEPolarityConfig()
+ function.
+ (#) Configures the Driver Enable assertion time using USART_SetDEAssertionTime()
+ function and deassertion time using the USART_SetDEDeassertionTime()
+ function.
+ (#) Enable the USART using the USART_Cmd() function.
+ -@-
+ (+@) The assertion and dessertion times are expressed in sample time units (1/8 or
+ 1/16 bit time, depending on the oversampling rate).
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Enables or disables the USART's DE functionality.
+ * @param USARTx: where x can be 1 or 2 or 3 to select the USART peripheral.
+ * @param NewState: new state of the driver enable mode.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void USART_DECmd(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 DE functionality by setting the DEM bit in the CR3 register */
+ USARTx->CR3 |= USART_CR3_DEM;
+ }
+ else
+ {
+ /* Disable the DE functionality by clearing the DEM bit in the CR3 register */
+ USARTx->CR3 &= (uint32_t)~((uint32_t)USART_CR3_DEM);
+ }
+}
+
+/**
+ * @brief Configures the USART's DE polarity
+ * @param USARTx: where x can be 1 or 2 or 3 to select the USART peripheral.
+ * @param USART_DEPolarity: specifies the DE polarity.
+ * This parameter can be one of the following values:
+ * @arg USART_DEPolarity_Low
+ * @arg USART_DEPolarity_High
+ * @retval None
+ */
+void USART_DEPolarityConfig(USART_TypeDef* USARTx, uint32_t USART_DEPolarity)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+ assert_param(IS_USART_DE_POLARITY(USART_DEPolarity));
+
+ USARTx->CR3 &= (uint32_t)~((uint32_t)USART_CR3_DEP);
+ USARTx->CR3 |= USART_DEPolarity;
+}
+
+/**
+ * @brief Sets the specified RS485 DE assertion time
+ * @param USARTx: where x can be 1 or 2 or 3 to select the USART peripheral.
+ * @param USART_DEAssertionTime: specifies the time between the activation of
+ * the DE signal and the beginning of the start bit
+ * @retval None
+ */
+void USART_SetDEAssertionTime(USART_TypeDef* USARTx, uint32_t USART_DEAssertionTime)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+ assert_param(IS_USART_DE_ASSERTION_DEASSERTION_TIME(USART_DEAssertionTime));
+
+ /* Clear the DE assertion time */
+ USARTx->CR1 &= (uint32_t)~((uint32_t)USART_CR1_DEAT);
+ /* Set the new value for the DE assertion time */
+ USARTx->CR1 |=((uint32_t)USART_DEAssertionTime << (uint32_t)0x15);
+}
+
+/**
+ * @brief Sets the specified RS485 DE deassertion time
+ * @param USARTx: where x can be 1 or 2 or 3 to select the USART peripheral.
+ * @param USART_DeassertionTime: specifies the time between the middle of the last
+ * stop bit in a transmitted message and the de-activation of the DE signal
+ * @retval None
+ */
+void USART_SetDEDeassertionTime(USART_TypeDef* USARTx, uint32_t USART_DEDeassertionTime)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+ assert_param(IS_USART_DE_ASSERTION_DEASSERTION_TIME(USART_DEDeassertionTime));
+
+ /* Clear the DE deassertion time */
+ USARTx->CR1 &= (uint32_t)~((uint32_t)USART_CR1_DEDT);
+ /* Set the new value for the DE deassertion time */
+ USARTx->CR1 |=((uint32_t)USART_DEDeassertionTime << (uint32_t)0x10);
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup USART_Group11 DMA transfers management functions
+ * @brief DMA transfers management functions
+ *
+@verbatim
+ ===============================================================================
+ ##### DMA transfers management functions #####
+ ===============================================================================
+ [..] This section provides two functions that can be used only in DMA mode.
+ [..] In DMA Mode, the USART communication can be managed by 2 DMA Channel
+ requests:
+ (#) USART_DMAReq_Tx: specifies the Tx buffer DMA transfer request.
+ (#) 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 USART's DMA interface.
+ * @param USARTx: where x can be 1 or 2 or 3 to select the USART 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, uint32_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 &= (uint32_t)~USART_DMAReq;
+ }
+}
+
+/**
+ * @brief Enables or disables the USART's DMA interface when reception error occurs.
+ * @param USARTx: where x can be 1 or 2 or 3 to select the USART peripheral.
+ * @param USART_DMAOnError: specifies the DMA status in case of reception error.
+ * This parameter can be any combination of the following values:
+ * @arg USART_DMAOnError_Enable: DMA receive request enabled when the USART DMA
+ * reception error is asserted.
+ * @arg USART_DMAOnError_Disable: DMA receive request disabled when the USART DMA
+ * reception error is asserted.
+ * @retval None
+ */
+void USART_DMAReceptionErrorConfig(USART_TypeDef* USARTx, uint32_t USART_DMAOnError)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+ assert_param(IS_USART_DMAONERROR(USART_DMAOnError));
+
+ /* Clear the DMA Reception error detection bit */
+ USARTx->CR3 &= (uint32_t)~((uint32_t)USART_CR3_DDRE);
+ /* Set the new value for the DMA Reception error detection bit */
+ USARTx->CR3 |= USART_DMAOnError;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup USART_Group12 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, 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.
+
+ *** Polling Mode ***
+ ====================
+ [..] In Polling Mode, the SPI communication can be managed by these flags:
+ (#) USART_FLAG_REACK: to indicate the status of the Receive Enable
+ acknowledge flag
+ (#) USART_FLAG_TEACK: to indicate the status of the Transmit Enable
+ acknowledge flag.
+ (#) USART_FLAG_WU: to indicate the status of the Wake up flag.
+ (#) USART_FLAG_RWU: to indicate the status of the Receive Wake up flag.
+ (#) USART_FLAG_SBK: to indicate the status of the Send Break flag.
+ (#) USART_FLAG_CM: to indicate the status of the Character match flag.
+ (#) USART_FLAG_BUSY: to indicate the status of the Busy flag.
+ (#) USART_FLAG_ABRF: to indicate the status of the Auto baud rate flag.
+ (#) USART_FLAG_ABRE: to indicate the status of the Auto baud rate error flag.
+ (#) USART_FLAG_EOB: to indicate the status of the End of block flag.
+ (#) USART_FLAG_RTO: to indicate the status of the Receive time out flag.
+ (#) USART_FLAG_nCTSS: to indicate the status of the Inverted nCTS input
+ bit status.
+ (#) USART_FLAG_TXE: to indicate the status of the transmit buffer register.
+ (#) USART_FLAG_RXNE: to indicate the status of the receive buffer register.
+ (#) USART_FLAG_TC: to indicate the status of the transmit operation.
+ (#) USART_FLAG_IDLE: to indicate the status of the Idle Line.
+ (#) USART_FLAG_CTS: to indicate the status of the nCTS input.
+ (#) USART_FLAG_LBD: to indicate the status of the LIN break detection.
+ (#) USART_FLAG_NE: to indicate if a noise error occur.
+ (#) USART_FLAG_FE: to indicate if a frame error occur.
+ (#) USART_FLAG_PE: to indicate if a parity error occur.
+ (#) 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:
+ (##) USART_IT_WU: to indicate the status of the Wake up interrupt.
+ (##) USART_IT_CM: to indicate the status of Character match interrupt.
+ (##) USART_IT_EOB: to indicate the status of End of block interrupt.
+ (##) USART_IT_RTO: to indicate the status of Receive time out interrupt.
+ (##) USART_IT_CTS: to indicate the status of CTS change interrupt.
+ (##) USART_IT_LBD: to indicate the status of LIN Break detection interrupt.
+ (##) USART_IT_TC: to indicate the status of Transmission complete interrupt.
+ (##) USART_IT_IDLE: to indicate the status of IDLE line detected interrupt.
+ (##) USART_IT_ORE: to indicate the status of OverRun Error interrupt.
+ (##) USART_IT_NE: to indicate the status of Noise Error interrupt.
+ (##) USART_IT_FE: to indicate the status of Framing Error interrupt.
+ (##) USART_IT_PE: to indicate the status of Parity Error interrupt.
+
+ (+) Interrupt Source:
+ (##) USART_IT_WU: specifies the interrupt source for Wake up interrupt.
+ (##) USART_IT_CM: specifies the interrupt source for Character match
+ interrupt.
+ (##) USART_IT_EOB: specifies the interrupt source for End of block
+ interrupt.
+ (##) USART_IT_RTO: specifies the interrupt source for Receive time-out
+ interrupt.
+ (##) USART_IT_CTS: specifies the interrupt source for CTS change interrupt.
+ (##) USART_IT_LBD: specifies the interrupt source for LIN Break
+ detection interrupt.
+ (##) USART_IT_TXE: specifies the interrupt source for Tansmit Data
+ Register empty interrupt.
+ (##) USART_IT_TC: specifies the interrupt source for Transmission
+ complete interrupt.
+ (##) USART_IT_RXNE: specifies the interrupt source for Receive Data
+ register not empty interrupt.
+ (##) USART_IT_IDLE: specifies the interrupt source for Idle line
+ detection interrupt.
+ (##) USART_IT_PE: specifies the interrupt source for Parity Error interrupt.
+ (##) USART_IT_ERR: specifies the interrupt source for Error interrupt
+ (Frame error, noise error, overrun error)
+ -@@- 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).
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Enables or disables the specified USART interrupts.
+ * @param USARTx: where x can be 1 or 2 or 3 to select the USART 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_WU: Wake up interrupt.
+ * @arg USART_IT_CM: Character match interrupt.
+ * @arg USART_IT_EOB: End of block interrupt.
+ * @arg USART_IT_RTO: Receive time out interrupt.
+ * @arg USART_IT_CTS: CTS change interrupt.
+ * @arg USART_IT_LBD: LIN Break detection interrupt.
+ * @arg USART_IT_TXE: Tansmit 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, uint32_t USART_IT, FunctionalState NewState)
+{
+ uint32_t usartreg = 0, itpos = 0, itmask = 0;
+ uint32_t usartxbase = 0;
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+ assert_param(IS_USART_CONFIG_IT(USART_IT));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ usartxbase = (uint32_t)USARTx;
+
+ /* Get the USART register index */
+ usartreg = (((uint16_t)USART_IT) >> 0x08);
+
+ /* Get the interrupt position */
+ itpos = USART_IT & IT_MASK;
+ itmask = (((uint32_t)0x01) << itpos);
+
+ if (usartreg == 0x02) /* The IT is in CR2 register */
+ {
+ usartxbase += 0x04;
+ }
+ else if (usartreg == 0x03) /* The IT is in CR3 register */
+ {
+ usartxbase += 0x08;
+ }
+ else /* The IT is in CR1 register */
+ {
+ }
+ if (NewState != DISABLE)
+ {
+ *(__IO uint32_t*)usartxbase |= itmask;
+ }
+ else
+ {
+ *(__IO uint32_t*)usartxbase &= ~itmask;
+ }
+}
+
+/**
+ * @brief Enables the specified USART's Request.
+ * @param USARTx: where x can be 1 or 2 or 3 to select the USART peripheral.
+ * @param USART_Request: specifies the USART request.
+ * This parameter can be any combination of the following values:
+ * @arg USART_Request_TXFRQ: Transmit data flush ReQuest
+ * @arg USART_Request_RXFRQ: Receive data flush ReQuest
+ * @arg USART_Request_MMRQ: Mute Mode ReQuest
+ * @arg USART_Request_SBKRQ: Send Break ReQuest
+ * @arg USART_Request_ABRRQ: Auto Baud Rate ReQuest
+ * @param NewState: new state of the DMA interface when reception error occurs.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void USART_RequestCmd(USART_TypeDef* USARTx, uint32_t USART_Request, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+ assert_param(IS_USART_REQUEST(USART_Request));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the USART ReQuest by setting the dedicated request bit in the RQR
+ register.*/
+ USARTx->RQR |= USART_Request;
+ }
+ else
+ {
+ /* Disable the USART ReQuest by clearing the dedicated request bit in the RQR
+ register.*/
+ USARTx->RQR &= (uint32_t)~USART_Request;
+ }
+}
+
+/**
+ * @brief Enables or disables the USART's Overrun detection.
+ * @param USARTx: where x can be 1 or 2 or 3 to select the USART peripheral.
+ * @param USART_OVRDetection: specifies the OVR detection status in case of OVR error.
+ * This parameter can be any combination of the following values:
+ * @arg USART_OVRDetection_Enable: OVR error detection enabled when
+ * the USART OVR error is asserted.
+ * @arg USART_OVRDetection_Disable: OVR error detection disabled when
+ * the USART OVR error is asserted.
+ * @retval None
+ */
+void USART_OverrunDetectionConfig(USART_TypeDef* USARTx, uint32_t USART_OVRDetection)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+ assert_param(IS_USART_OVRDETECTION(USART_OVRDetection));
+
+ /* Clear the OVR detection bit */
+ USARTx->CR3 &= (uint32_t)~((uint32_t)USART_CR3_OVRDIS);
+ /* Set the new value for the OVR detection bit */
+ USARTx->CR3 |= USART_OVRDetection;
+}
+
+/**
+ * @brief Checks whether the specified USART flag is set or not.
+ * @param USARTx: where x can be 1 or 2 or 3 to select the USART peripheral.
+ * @param USART_FLAG: specifies the flag to check.
+ * This parameter can be one of the following values:
+ * @arg USART_FLAG_REACK: Receive Enable acknowledge flag.
+ * @arg USART_FLAG_TEACK: Transmit Enable acknowledge flag.
+ * @arg USART_FLAG_WU: Wake up flag.
+ * @arg USART_FLAG_RWU: Receive Wake up flag.
+ * @arg USART_FLAG_SBK: Send Break flag.
+ * @arg USART_FLAG_CM: Character match flag.
+ * @arg USART_FLAG_BUSY: Busy flag.
+ * @arg USART_FLAG_ABRF: Auto baud rate flag.
+ * @arg USART_FLAG_ABRE: Auto baud rate error flag.
+ * @arg USART_FLAG_EOB: End of block flag.
+ * @arg USART_FLAG_RTO: Receive time out flag.
+ * @arg USART_FLAG_nCTSS: Inverted nCTS input bit status.
+ * @arg USART_FLAG_CTS: CTS Change flag.
+ * @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, uint32_t USART_FLAG)
+{
+ FlagStatus bitstatus = RESET;
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+ assert_param(IS_USART_FLAG(USART_FLAG));
+
+ if ((USARTx->ISR & 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 or 2 or 3 to select the USART peripheral.
+ * @param USART_FLAG: specifies the flag to clear.
+ * This parameter can be any combination of the following values:
+ * @arg USART_FLAG_WU: Wake up flag.
+ * @arg USART_FLAG_CM: Character match flag.
+ * @arg USART_FLAG_EOB: End of block flag.
+ * @arg USART_FLAG_RTO: Receive time out flag.
+ * @arg USART_FLAG_CTS: CTS Change flag.
+ * @arg USART_FLAG_LBD: LIN Break detection flag.
+ * @arg USART_FLAG_TC: Transmission Complete flag.
+ * @arg USART_FLAG_IDLE: IDLE line detected 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 Errorflag.
+ *
+ * @note RXNE pending bit is cleared by a read to the USART_RDR register
+ * (USART_ReceiveData()) or by writing 1 to the RXFRQ in the register
+ * USART_RQR (USART_RequestCmd()).
+ * @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_TDR register (USART_SendData()).
+ * @note TXE flag is cleared by a write to the USART_TDR register (USART_SendData())
+ * or by writing 1 to the TXFRQ in the register USART_RQR (USART_RequestCmd()).
+ * @note SBKF flag is cleared by 1 to the SBKRQ in the register USART_RQR
+ * (USART_RequestCmd()).
+ * @retval None
+ */
+void USART_ClearFlag(USART_TypeDef* USARTx, uint32_t USART_FLAG)
+{
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+ assert_param(IS_USART_CLEAR_FLAG(USART_FLAG));
+
+ USARTx->ICR = USART_FLAG;
+}
+
+/**
+ * @brief Checks whether the specified USART interrupt has occurred or not.
+ * @param USARTx: where x can be 1 or 2 or 3 to select the USART peripheral.
+ * @param USART_IT: specifies the USART interrupt source to check.
+ * This parameter can be one of the following values:
+ * @arg USART_IT_WU: Wake up interrupt.
+ * @arg USART_IT_CM: Character match interrupt.
+ * @arg USART_IT_EOB: End of block interrupt.
+ * @arg USART_IT_RTO: Receive time out interrupt.
+ * @arg USART_IT_CTS: CTS change interrupt.
+ * @arg USART_IT_LBD: LIN Break detection interrupt.
+ * @arg USART_IT_TXE: Tansmit 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: OverRun Error interrupt.
+ * @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, uint32_t USART_IT)
+{
+ uint32_t bitpos = 0, itmask = 0, usartreg = 0;
+ ITStatus bitstatus = RESET;
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+ assert_param(IS_USART_GET_IT(USART_IT));
+
+ /* Get the USART register index */
+ usartreg = (((uint16_t)USART_IT) >> 0x08);
+ /* 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 >> 0x10;
+ bitpos = (uint32_t)0x01 << bitpos;
+ bitpos &= USARTx->ISR;
+ 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 or 2 or 3 to select the USART peripheral.
+ * @param USART_IT: specifies the interrupt pending bit to clear.
+ * This parameter can be one of the following values:
+ * @arg USART_IT_WU: Wake up interrupt.
+ * @arg USART_IT_CM: Character match interrupt.
+ * @arg USART_IT_EOB: End of block interrupt.
+ * @arg USART_IT_RTO: Receive time out interrupt.
+ * @arg USART_IT_CTS: CTS change interrupt.
+ * @arg USART_IT_LBD: LIN Break detection interrupt.
+ * @arg USART_IT_TC: Transmission complete interrupt.
+ * @arg USART_IT_IDLE: IDLE line detected interrupt.
+ * @arg USART_IT_ORE: OverRun Error interrupt.
+ * @arg USART_IT_NE: Noise Error interrupt.
+ * @arg USART_IT_FE: Framing Error interrupt.
+ * @arg USART_IT_PE: Parity Error interrupt.
+ *
+ * @note RXNE pending bit is cleared by a read to the USART_RDR register
+ * (USART_ReceiveData()) or by writing 1 to the RXFRQ in the register
+ * USART_RQR (USART_RequestCmd()).
+ * @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_TDR register (USART_SendData()).
+ * @note TXE pending bit is cleared by a write to the USART_TDR register
+ * (USART_SendData()) or by writing 1 to the TXFRQ in the register
+ * USART_RQR (USART_RequestCmd()).
+ * @retval None
+ */
+void USART_ClearITPendingBit(USART_TypeDef* USARTx, uint32_t USART_IT)
+{
+ uint32_t bitpos = 0, itmask = 0;
+ /* Check the parameters */
+ assert_param(IS_USART_ALL_PERIPH(USARTx));
+ assert_param(IS_USART_CLEAR_IT(USART_IT));
+
+ bitpos = USART_IT >> 0x10;
+ itmask = ((uint32_t)0x01 << (uint32_t)bitpos);
+ USARTx->ICR = (uint32_t)itmask;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Libraries/STM32F37x_StdPeriph_Driver/src/stm32f37x_wwdg.c b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Libraries/STM32F37x_StdPeriph_Driver/src/stm32f37x_wwdg.c
new file mode 100644
index 0000000..76fc17d
--- /dev/null
+++ b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Libraries/STM32F37x_StdPeriph_Driver/src/stm32f37x_wwdg.c
@@ -0,0 +1,313 @@
+/**
+ ******************************************************************************
+ * @file stm32f37x_wwdg.c
+ * @author MCD Application Team
+ * @version V1.0.0
+ * @date 20-September-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 @36MHz (PCLK1): ~114us / ~58.3ms.
+
+ ##### How to use this driver #####
+ ==============================================================================
+ [..]
+ (#) Enable WWDG clock using RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE)
+ function.
+
+ (#) Configure the WWDG prescaler using WWDG_SetPrescaler() function.
+
+ (#) Configure the WWDG refresh window using WWDG_SetWindowValue() function.
+
+ (#) 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.
+
+ (#) 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.
+
+ (#) 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
+ *
+ * <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
+ *
+ * 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 "stm32f37x_wwdg.h"
+#include "stm32f37x_rcc.h"
+
+/** @addtogroup STM32F37x_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****/