summaryrefslogtreecommitdiff
path: root/bsp/radio-controller-1/Drivers/STM32F1xx_HAL_Driver/Src
diff options
context:
space:
mode:
authorTrygve Laugstøl <trygvis@inamo.no>2017-05-27 10:55:23 +0200
committerTrygve Laugstøl <trygvis@inamo.no>2017-05-27 11:01:19 +0200
commita819d3cbddbb5294b98b2fd6590f9fff13491d85 (patch)
treea529b8260f7f8a8d589de3f4dcdb278fea08ab25 /bsp/radio-controller-1/Drivers/STM32F1xx_HAL_Driver/Src
parent46b7f97720293e098fa26eb5269b481c45819deb (diff)
downloadradio-controller-a819d3cbddbb5294b98b2fd6590f9fff13491d85.tar.gz
radio-controller-a819d3cbddbb5294b98b2fd6590f9fff13491d85.tar.bz2
radio-controller-a819d3cbddbb5294b98b2fd6590f9fff13491d85.tar.xz
radio-controller-a819d3cbddbb5294b98b2fd6590f9fff13491d85.zip
o Moving generated code to under bsp/. Renaming to match PCB.
Diffstat (limited to 'bsp/radio-controller-1/Drivers/STM32F1xx_HAL_Driver/Src')
-rw-r--r--bsp/radio-controller-1/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal.c526
-rw-r--r--bsp/radio-controller-1/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_cortex.c494
-rw-r--r--bsp/radio-controller-1/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_dma.c709
-rw-r--r--bsp/radio-controller-1/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_flash.c974
-rw-r--r--bsp/radio-controller-1/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_flash_ex.c1140
-rw-r--r--bsp/radio-controller-1/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio.c597
-rw-r--r--bsp/radio-controller-1/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio_ex.c145
-rw-r--r--bsp/radio-controller-1/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pcd.c1440
-rw-r--r--bsp/radio-controller-1/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pcd_ex.c252
-rw-r--r--bsp/radio-controller-1/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pwr.c636
-rw-r--r--bsp/radio-controller-1/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc.c1270
-rw-r--r--bsp/radio-controller-1/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc_ex.c870
-rw-r--r--bsp/radio-controller-1/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim.c5379
-rw-r--r--bsp/radio-controller-1/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim_ex.c1857
-rw-r--r--bsp/radio-controller-1/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_uart.c1921
-rw-r--r--bsp/radio-controller-1/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_usb.c2211
16 files changed, 20421 insertions, 0 deletions
diff --git a/bsp/radio-controller-1/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal.c b/bsp/radio-controller-1/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal.c
new file mode 100644
index 0000000..19a4699
--- /dev/null
+++ b/bsp/radio-controller-1/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal.c
@@ -0,0 +1,526 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal.c
+ * @author MCD Application Team
+ * @version V1.0.4
+ * @date 29-April-2016
+ * @brief HAL module driver.
+ * This is the common part of the HAL initialization
+ *
+ @verbatim
+ ==============================================================================
+ ##### How to use this driver #####
+ ==============================================================================
+ [..]
+ The common HAL driver contains a set of generic and common APIs that can be
+ used by the PPP peripheral drivers and the user to start using the HAL.
+ [..]
+ The HAL contains two APIs' categories:
+ (+) Common HAL APIs
+ (+) Services HAL APIs
+
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+/** @defgroup HAL HAL
+ * @brief HAL module driver.
+ * @{
+ */
+
+#ifdef HAL_MODULE_ENABLED
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+
+/** @defgroup HAL_Private_Constants HAL Private Constants
+ * @{
+ */
+
+/**
+ * @brief STM32F1xx HAL Driver version number
+ */
+#define __STM32F1xx_HAL_VERSION_MAIN (0x01) /*!< [31:24] main version */
+#define __STM32F1xx_HAL_VERSION_SUB1 (0x00) /*!< [23:16] sub1 version */
+#define __STM32F1xx_HAL_VERSION_SUB2 (0x04) /*!< [15:8] sub2 version */
+#define __STM32F1xx_HAL_VERSION_RC (0x00) /*!< [7:0] release candidate */
+#define __STM32F1xx_HAL_VERSION ((__STM32F1xx_HAL_VERSION_MAIN << 24)\
+ |(__STM32F1xx_HAL_VERSION_SUB1 << 16)\
+ |(__STM32F1xx_HAL_VERSION_SUB2 << 8 )\
+ |(__STM32F1xx_HAL_VERSION_RC))
+
+#define IDCODE_DEVID_MASK ((uint32_t)0x00000FFF)
+
+/**
+ * @}
+ */
+
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+
+/** @defgroup HAL_Private_Variables HAL Private Variables
+ * @{
+ */
+
+static __IO uint32_t uwTick;
+
+/**
+ * @}
+ */
+
+/* Private function prototypes -----------------------------------------------*/
+/* Exported functions ---------------------------------------------------------*/
+
+/** @defgroup HAL_Exported_Functions HAL Exported Functions
+ * @{
+ */
+
+/** @defgroup HAL_Exported_Functions_Group1 Initialization and de-initialization Functions
+ * @brief Initialization and de-initialization functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Initialization and de-initialization functions #####
+ ===============================================================================
+ [..] This section provides functions allowing to:
+ (+) Initializes the Flash interface, the NVIC allocation and initial clock
+ configuration. It initializes the source of time base also when timeout
+ is needed and the backup domain when enabled.
+ (+) de-Initializes common part of the HAL.
+ (+) Configure The time base source to have 1ms time base with a dedicated
+ Tick interrupt priority.
+ (++) Systick timer is used by default as source of time base, but user
+ can eventually implement his proper time base source (a general purpose
+ timer for example or other time source), keeping in mind that Time base
+ duration should be kept 1ms since PPP_TIMEOUT_VALUEs are defined and
+ handled in milliseconds basis.
+ (++) Time base configuration function (HAL_InitTick ()) is called automatically
+ at the beginning of the program after reset by HAL_Init() or at any time
+ when clock is configured, by HAL_RCC_ClockConfig().
+ (++) Source of time base is configured to generate interrupts at regular
+ time intervals. Care must be taken if HAL_Delay() is called from a
+ peripheral ISR process, the Tick interrupt line must have higher priority
+ (numerically lower) than the peripheral interrupt. Otherwise the caller
+ ISR process will be blocked.
+ (++) functions affecting time base configurations are declared as __Weak
+ to make override possible in case of other implementations in user file.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief This function configures the Flash prefetch,
+ * Configures time base source, NVIC and Low level hardware
+ * @note This function is called at the beginning of program after reset and before
+ * the clock configuration
+ * @note The time base configuration is based on MSI clock when exiting from Reset.
+ * Once done, time base tick start incrementing.
+ * In the default implementation,Systick is used as source of time base.
+ * The tick variable is incremented each 1ms in its ISR.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_Init(void)
+{
+ /* Configure Flash prefetch */
+#if (PREFETCH_ENABLE != 0)
+#if defined(STM32F101x6) || defined(STM32F101xB) || defined(STM32F101xE) || defined(STM32F101xG) || \
+ defined(STM32F102x6) || defined(STM32F102xB) || \
+ defined(STM32F103x6) || defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG) || \
+ defined(STM32F105xC) || defined(STM32F107xC)
+
+ /* Prefetch buffer is not available on value line devices */
+ __HAL_FLASH_PREFETCH_BUFFER_ENABLE();
+#endif
+#endif /* PREFETCH_ENABLE */
+
+ /* Set Interrupt Group Priority */
+ HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);
+
+ /* Use systick as time base source and configure 1ms tick (default clock after Reset is MSI) */
+ HAL_InitTick(TICK_INT_PRIORITY);
+
+ /* Init the low level hardware */
+ HAL_MspInit();
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief This function de-Initializes common part of the HAL and stops the source
+ * of time base.
+ * @note This function is optional.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_DeInit(void)
+{
+ /* Reset of all peripherals */
+ __HAL_RCC_APB1_FORCE_RESET();
+ __HAL_RCC_APB1_RELEASE_RESET();
+
+ __HAL_RCC_APB2_FORCE_RESET();
+ __HAL_RCC_APB2_RELEASE_RESET();
+
+#if defined(STM32F105xC) || defined(STM32F107xC)
+ __HAL_RCC_AHB_FORCE_RESET();
+ __HAL_RCC_AHB_RELEASE_RESET();
+#endif
+
+ /* De-Init the low level hardware */
+ HAL_MspDeInit();
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Initializes the MSP.
+ * @retval None
+ */
+__weak void HAL_MspInit(void)
+{
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_MspInit could be implemented in the user file
+ */
+}
+
+/**
+ * @brief DeInitializes the MSP.
+ * @retval None
+ */
+__weak void HAL_MspDeInit(void)
+{
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_MspDeInit could be implemented in the user file
+ */
+}
+
+/**
+ * @brief This function configures the source of the time base.
+ * The time source is configured to have 1ms time base with a dedicated
+ * Tick interrupt priority.
+ * @note This function is called automatically at the beginning of program after
+ * reset by HAL_Init() or at any time when clock is reconfigured by HAL_RCC_ClockConfig().
+ * @note In the default implementation, SysTick timer is the source of time base.
+ * It is used to generate interrupts at regular time intervals.
+ * Care must be taken if HAL_Delay() is called from a peripheral ISR process,
+ * The the SysTick interrupt must have higher priority (numerically lower)
+ * than the peripheral interrupt. Otherwise the caller ISR process will be blocked.
+ * The function is declared as __Weak to be overwritten in case of other
+ * implementation in user file.
+ * @param TickPriority: Tick interrupt priority.
+ * @retval HAL status
+ */
+__weak HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)
+{
+ /*Configure the SysTick to have interrupt in 1ms time basis*/
+ HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
+
+ /*Configure the SysTick IRQ priority */
+ HAL_NVIC_SetPriority(SysTick_IRQn, TickPriority ,0);
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup HAL_Exported_Functions_Group2 HAL Control functions
+ * @brief HAL Control functions
+ *
+@verbatim
+ ===============================================================================
+ ##### HAL Control functions #####
+ ===============================================================================
+ [..] This section provides functions allowing to:
+ (+) Provide a tick value in millisecond
+ (+) Provide a blocking delay in millisecond
+ (+) Suspend the time base source interrupt
+ (+) Resume the time base source interrupt
+ (+) Get the HAL API driver version
+ (+) Get the device identifier
+ (+) Get the device revision identifier
+ (+) Enable/Disable Debug module during Sleep mode
+ (+) Enable/Disable Debug module during STOP mode
+ (+) Enable/Disable Debug module during STANDBY mode
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief This function is called to increment a global variable "uwTick"
+ * used as application time base.
+ * @note In the default implementation, this variable is incremented each 1ms
+ * in Systick ISR.
+ * @note This function is declared as __weak to be overwritten in case of other
+ * implementations in user file.
+ * @retval None
+ */
+__weak void HAL_IncTick(void)
+{
+ uwTick++;
+}
+
+/**
+ * @brief Provides a tick value in millisecond.
+ * @note This function is declared as __weak to be overwritten in case of other
+ * implementations in user file.
+ * @retval tick value
+ */
+__weak uint32_t HAL_GetTick(void)
+{
+ return uwTick;
+}
+
+/**
+ * @brief This function provides accurate delay (in milliseconds) based
+ * on variable incremented.
+ * @note In the default implementation , SysTick timer is the source of time base.
+ * It is used to generate interrupts at regular time intervals where uwTick
+ * is incremented.
+ * @note ThiS function is declared as __weak to be overwritten in case of other
+ * implementations in user file.
+ * @param Delay: specifies the delay time length, in milliseconds.
+ * @retval None
+ */
+__weak void HAL_Delay(__IO uint32_t Delay)
+{
+ uint32_t tickstart = 0;
+ tickstart = HAL_GetTick();
+ while((HAL_GetTick() - tickstart) < Delay)
+ {
+ }
+}
+
+/**
+ * @brief Suspend Tick increment.
+ * @note In the default implementation , SysTick timer is the source of time base. It is
+ * used to generate interrupts at regular time intervals. Once HAL_SuspendTick()
+ * is called, the the SysTick interrupt will be disabled and so Tick increment
+ * is suspended.
+ * @note This function is declared as __weak to be overwritten in case of other
+ * implementations in user file.
+ * @retval None
+ */
+__weak void HAL_SuspendTick(void)
+{
+ /* Disable SysTick Interrupt */
+ CLEAR_BIT(SysTick->CTRL,SysTick_CTRL_TICKINT_Msk);
+}
+
+/**
+ * @brief Resume Tick increment.
+ * @note In the default implementation , SysTick timer is the source of time base. It is
+ * used to generate interrupts at regular time intervals. Once HAL_ResumeTick()
+ * is called, the the SysTick interrupt will be enabled and so Tick increment
+ * is resumed.
+ * @note This function is declared as __weak to be overwritten in case of other
+ * implementations in user file.
+ * @retval None
+ */
+__weak void HAL_ResumeTick(void)
+{
+ /* Enable SysTick Interrupt */
+ SET_BIT(SysTick->CTRL,SysTick_CTRL_TICKINT_Msk);
+}
+
+/**
+ * @brief This method returns the HAL revision
+ * @retval version: 0xXYZR (8bits for each decimal, R for RC)
+ */
+uint32_t HAL_GetHalVersion(void)
+{
+ return __STM32F1xx_HAL_VERSION;
+}
+
+/**
+ * @brief Returns the device revision identifier.
+ * Note: On devices STM32F10xx8 and STM32F10xxB,
+ * STM32F101xC/D/E and STM32F103xC/D/E,
+ * STM32F101xF/G and STM32F103xF/G
+ * STM32F10xx4 and STM32F10xx6
+ * Debug registers DBGMCU_IDCODE and DBGMCU_CR are accessible only in
+ * debug mode (not accessible by the user software in normal mode).
+ * Refer to errata sheet of these devices for more details.
+ * @retval Device revision identifier
+ */
+uint32_t HAL_GetREVID(void)
+{
+ return((DBGMCU->IDCODE) >> POSITION_VAL(DBGMCU_IDCODE_REV_ID));
+}
+
+/**
+ * @brief Returns the device identifier.
+ * Note: On devices STM32F10xx8 and STM32F10xxB,
+ * STM32F101xC/D/E and STM32F103xC/D/E,
+ * STM32F101xF/G and STM32F103xF/G
+ * STM32F10xx4 and STM32F10xx6
+ * Debug registers DBGMCU_IDCODE and DBGMCU_CR are accessible only in
+ * debug mode (not accessible by the user software in normal mode).
+ * Refer to errata sheet of these devices for more details.
+ * @retval Device identifier
+ */
+uint32_t HAL_GetDEVID(void)
+{
+ return((DBGMCU->IDCODE) & IDCODE_DEVID_MASK);
+}
+
+/**
+ * @brief Enable the Debug Module during SLEEP mode
+ * @retval None
+ */
+void HAL_DBGMCU_EnableDBGSleepMode(void)
+{
+ SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_SLEEP);
+}
+
+/**
+ * @brief Disable the Debug Module during SLEEP mode
+ * Note: On devices STM32F10xx8 and STM32F10xxB,
+ * STM32F101xC/D/E and STM32F103xC/D/E,
+ * STM32F101xF/G and STM32F103xF/G
+ * STM32F10xx4 and STM32F10xx6
+ * Debug registers DBGMCU_IDCODE and DBGMCU_CR are accessible only in
+ * debug mode (not accessible by the user software in normal mode).
+ * Refer to errata sheet of these devices for more details.
+ * @retval None
+ */
+void HAL_DBGMCU_DisableDBGSleepMode(void)
+{
+ CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_SLEEP);
+}
+
+/**
+ * @brief Enable the Debug Module during STOP mode
+ * Note: On devices STM32F10xx8 and STM32F10xxB,
+ * STM32F101xC/D/E and STM32F103xC/D/E,
+ * STM32F101xF/G and STM32F103xF/G
+ * STM32F10xx4 and STM32F10xx6
+ * Debug registers DBGMCU_IDCODE and DBGMCU_CR are accessible only in
+ * debug mode (not accessible by the user software in normal mode).
+ * Refer to errata sheet of these devices for more details.
+ * Note: On all STM32F1 devices:
+ * If the system tick timer interrupt is enabled during the Stop mode
+ * debug (DBG_STOP bit set in the DBGMCU_CR register ), it will wakeup
+ * the system from Stop mode.
+ * Workaround: To debug the Stop mode, disable the system tick timer
+ * interrupt.
+ * Refer to errata sheet of these devices for more details.
+ * Note: On all STM32F1 devices:
+ * If the system tick timer interrupt is enabled during the Stop mode
+ * debug (DBG_STOP bit set in the DBGMCU_CR register ), it will wakeup
+ * the system from Stop mode.
+ * Workaround: To debug the Stop mode, disable the system tick timer
+ * interrupt.
+ * Refer to errata sheet of these devices for more details.
+ * @retval None
+ */
+void HAL_DBGMCU_EnableDBGStopMode(void)
+{
+ SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STOP);
+}
+
+/**
+ * @brief Disable the Debug Module during STOP mode
+ * Note: On devices STM32F10xx8 and STM32F10xxB,
+ * STM32F101xC/D/E and STM32F103xC/D/E,
+ * STM32F101xF/G and STM32F103xF/G
+ * STM32F10xx4 and STM32F10xx6
+ * Debug registers DBGMCU_IDCODE and DBGMCU_CR are accessible only in
+ * debug mode (not accessible by the user software in normal mode).
+ * Refer to errata sheet of these devices for more details.
+ * @retval None
+ */
+void HAL_DBGMCU_DisableDBGStopMode(void)
+{
+ CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STOP);
+}
+
+/**
+ * @brief Enable the Debug Module during STANDBY mode
+ * Note: On devices STM32F10xx8 and STM32F10xxB,
+ * STM32F101xC/D/E and STM32F103xC/D/E,
+ * STM32F101xF/G and STM32F103xF/G
+ * STM32F10xx4 and STM32F10xx6
+ * Debug registers DBGMCU_IDCODE and DBGMCU_CR are accessible only in
+ * debug mode (not accessible by the user software in normal mode).
+ * Refer to errata sheet of these devices for more details.
+ * @retval None
+ */
+void HAL_DBGMCU_EnableDBGStandbyMode(void)
+{
+ SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STANDBY);
+}
+
+/**
+ * @brief Disable the Debug Module during STANDBY mode
+ * Note: On devices STM32F10xx8 and STM32F10xxB,
+ * STM32F101xC/D/E and STM32F103xC/D/E,
+ * STM32F101xF/G and STM32F103xF/G
+ * STM32F10xx4 and STM32F10xx6
+ * Debug registers DBGMCU_IDCODE and DBGMCU_CR are accessible only in
+ * debug mode (not accessible by the user software in normal mode).
+ * Refer to errata sheet of these devices for more details.
+ * @retval None
+ */
+void HAL_DBGMCU_DisableDBGStandbyMode(void)
+{
+ CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STANDBY);
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* HAL_MODULE_ENABLED */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/bsp/radio-controller-1/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_cortex.c b/bsp/radio-controller-1/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_cortex.c
new file mode 100644
index 0000000..836503c
--- /dev/null
+++ b/bsp/radio-controller-1/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_cortex.c
@@ -0,0 +1,494 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_cortex.c
+ * @author MCD Application Team
+ * @version V1.0.4
+ * @date 29-April-2016
+ * @brief CORTEX HAL module driver.
+ *
+ * This file provides firmware functions to manage the following
+ * functionalities of the CORTEX:
+ * + Initialization and de-initialization functions
+ * + Peripheral Control functions
+ *
+ * @verbatim
+ ==============================================================================
+ ##### How to use this driver #####
+ ==============================================================================
+
+ [..]
+ *** How to configure Interrupts using Cortex HAL driver ***
+ ===========================================================
+ [..]
+ This section provide functions allowing to configure the NVIC interrupts (IRQ).
+ The Cortex-M3 exceptions are managed by CMSIS functions.
+
+ (#) Configure the NVIC Priority Grouping using HAL_NVIC_SetPriorityGrouping()
+ function according to the following table.
+
+ The table below gives the allowed values of the pre-emption priority and subpriority according
+ to the Priority Grouping configuration performed by HAL_NVIC_SetPriorityGrouping() function.
+ ==========================================================================================================================
+ NVIC_PriorityGroup | NVIC_IRQChannelPreemptionPriority | NVIC_IRQChannelSubPriority | Description
+ ==========================================================================================================================
+ NVIC_PRIORITYGROUP_0 | 0 | 0-15 | 0 bits for pre-emption priority
+ | | | 4 bits for subpriority
+ --------------------------------------------------------------------------------------------------------------------------
+ NVIC_PRIORITYGROUP_1 | 0-1 | 0-7 | 1 bits for pre-emption priority
+ | | | 3 bits for subpriority
+ --------------------------------------------------------------------------------------------------------------------------
+ NVIC_PRIORITYGROUP_2 | 0-3 | 0-3 | 2 bits for pre-emption priority
+ | | | 2 bits for subpriority
+ --------------------------------------------------------------------------------------------------------------------------
+ NVIC_PRIORITYGROUP_3 | 0-7 | 0-1 | 3 bits for pre-emption priority
+ | | | 1 bits for subpriority
+ --------------------------------------------------------------------------------------------------------------------------
+ NVIC_PRIORITYGROUP_4 | 0-15 | 0 | 4 bits for pre-emption priority
+ | | | 0 bits for subpriority
+ ==========================================================================================================================
+ (#) Configure the priority of the selected IRQ Channels using HAL_NVIC_SetPriority()
+
+ (#) Enable the selected IRQ Channels using HAL_NVIC_EnableIRQ()
+
+
+ -@- When the NVIC_PRIORITYGROUP_0 is selected, IRQ pre-emption is no more possible.
+ The pending IRQ priority will be managed only by the sub priority.
+
+ -@- IRQ priority order (sorted by highest to lowest priority):
+ (+@) Lowest pre-emption priority
+ (+@) Lowest sub priority
+ (+@) Lowest hardware priority (IRQ number)
+
+ [..]
+ *** How to configure Systick using Cortex HAL driver ***
+ ========================================================
+ [..]
+ Setup SysTick Timer for 1 msec interrupts.
+
+ (+) The HAL_SYSTICK_Config()function calls the SysTick_Config() function which
+ is a CMSIS function that:
+ (++) Configures the SysTick Reload register with value passed as function parameter.
+ (++) Configures the SysTick IRQ priority to the lowest value (0x0F).
+ (++) Resets the SysTick Counter register.
+ (++) Configures the SysTick Counter clock source to be Core Clock Source (HCLK).
+ (++) Enables the SysTick Interrupt.
+ (++) Starts the SysTick Counter.
+
+ (+) You can change the SysTick Clock source to be HCLK_Div8 by calling the function
+ HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK_DIV8) just after the
+ HAL_SYSTICK_Config() function call.
+
+ (+) You can change the SysTick IRQ priority by calling the
+ HAL_NVIC_SetPriority(SysTick_IRQn,...) function just after the HAL_SYSTICK_Config() function
+ call. The HAL_NVIC_SetPriority() call the NVIC_SetPriority() function which is a CMSIS function.
+
+ (+) To adjust the SysTick time base, use the following formula:
+
+ Reload Value = SysTick Counter Clock (Hz) x Desired Time base (s)
+ (++) Reload Value is the parameter to be passed for HAL_SYSTICK_Config() function
+ (++) Reload Value should not exceed 0xFFFFFF
+
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+/** @defgroup CORTEX CORTEX
+ * @brief CORTEX HAL module driver
+ * @{
+ */
+
+#ifdef HAL_CORTEX_MODULE_ENABLED
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+/** @defgroup CORTEX_Exported_Functions CORTEX Exported Functions
+ * @{
+ */
+
+
+/** @defgroup CORTEX_Exported_Functions_Group1 Initialization and de-initialization functions
+ * @brief Initialization and Configuration functions
+ *
+@verbatim
+ ==============================================================================
+ ##### Initialization and de-initialization functions #####
+ ==============================================================================
+ [..]
+ This section provide the Cortex HAL driver functions allowing to configure Interrupts
+ Systick functionalities
+
+@endverbatim
+ * @{
+ */
+
+
+/**
+ * @brief Sets the priority grouping field (pre-emption priority and subpriority)
+ * using the required unlock sequence.
+ * @param PriorityGroup: The priority grouping bits length.
+ * This parameter can be one of the following values:
+ * @arg NVIC_PRIORITYGROUP_0: 0 bits for pre-emption priority
+ * 4 bits for subpriority
+ * @arg NVIC_PRIORITYGROUP_1: 1 bits for pre-emption priority
+ * 3 bits for subpriority
+ * @arg NVIC_PRIORITYGROUP_2: 2 bits for pre-emption priority
+ * 2 bits for subpriority
+ * @arg NVIC_PRIORITYGROUP_3: 3 bits for pre-emption priority
+ * 1 bits for subpriority
+ * @arg NVIC_PRIORITYGROUP_4: 4 bits for pre-emption priority
+ * 0 bits for subpriority
+ * @note When the NVIC_PriorityGroup_0 is selected, IRQ pre-emption is no more possible.
+ * The pending IRQ priority will be managed only by the subpriority.
+ * @retval None
+ */
+void HAL_NVIC_SetPriorityGrouping(uint32_t PriorityGroup)
+{
+ /* Check the parameters */
+ assert_param(IS_NVIC_PRIORITY_GROUP(PriorityGroup));
+
+ /* Set the PRIGROUP[10:8] bits according to the PriorityGroup parameter value */
+ NVIC_SetPriorityGrouping(PriorityGroup);
+}
+
+/**
+ * @brief Sets the priority of an interrupt.
+ * @param IRQn: External interrupt number
+ * This parameter can be an enumerator of IRQn_Type enumeration
+ * (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f10xxx.h))
+ * @param PreemptPriority: The pre-emption priority for the IRQn channel.
+ * This parameter can be a value between 0 and 15
+ * A lower priority value indicates a higher priority
+ * @param SubPriority: the subpriority level for the IRQ channel.
+ * This parameter can be a value between 0 and 15
+ * A lower priority value indicates a higher priority.
+ * @retval None
+ */
+void HAL_NVIC_SetPriority(IRQn_Type IRQn, uint32_t PreemptPriority, uint32_t SubPriority)
+{
+ uint32_t prioritygroup = 0x00;
+
+ /* Check the parameters */
+ assert_param(IS_NVIC_SUB_PRIORITY(SubPriority));
+ assert_param(IS_NVIC_PREEMPTION_PRIORITY(PreemptPriority));
+
+ prioritygroup = NVIC_GetPriorityGrouping();
+
+ NVIC_SetPriority(IRQn, NVIC_EncodePriority(prioritygroup, PreemptPriority, SubPriority));
+}
+
+/**
+ * @brief Enables a device specific interrupt in the NVIC interrupt controller.
+ * @note To configure interrupts priority correctly, the NVIC_PriorityGroupConfig()
+ * function should be called before.
+ * @param IRQn External interrupt number
+ * This parameter can be an enumerator of IRQn_Type enumeration
+ * (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f10xxx.h))
+ * @retval None
+ */
+void HAL_NVIC_EnableIRQ(IRQn_Type IRQn)
+{
+ /* Check the parameters */
+ assert_param(IS_NVIC_DEVICE_IRQ(IRQn));
+
+ /* Enable interrupt */
+ NVIC_EnableIRQ(IRQn);
+}
+
+/**
+ * @brief Disables a device specific interrupt in the NVIC interrupt controller.
+ * @param IRQn External interrupt number
+ * This parameter can be an enumerator of IRQn_Type enumeration
+ * (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f10xxx.h))
+ * @retval None
+ */
+void HAL_NVIC_DisableIRQ(IRQn_Type IRQn)
+{
+ /* Check the parameters */
+ assert_param(IS_NVIC_DEVICE_IRQ(IRQn));
+
+
+ /* Disable interrupt */
+ NVIC_DisableIRQ(IRQn);
+}
+
+/**
+ * @brief Initiates a system reset request to reset the MCU.
+ * @retval None
+ */
+void HAL_NVIC_SystemReset(void)
+{
+ /* System Reset */
+ NVIC_SystemReset();
+}
+
+/**
+ * @brief Initializes the System Timer and its interrupt, and starts the System Tick Timer.
+ * Counter is in free running mode to generate periodic interrupts.
+ * @param TicksNumb: Specifies the ticks Number of ticks between two interrupts.
+ * @retval status: - 0 Function succeeded.
+ * - 1 Function failed.
+ */
+uint32_t HAL_SYSTICK_Config(uint32_t TicksNumb)
+{
+ return SysTick_Config(TicksNumb);
+}
+/**
+ * @}
+ */
+
+/** @defgroup CORTEX_Exported_Functions_Group2 Peripheral Control functions
+ * @brief Cortex control functions
+ *
+@verbatim
+ ==============================================================================
+ ##### Peripheral Control functions #####
+ ==============================================================================
+ [..]
+ This subsection provides a set of functions allowing to control the CORTEX
+ (NVIC, SYSTICK, MPU) functionalities.
+
+
+@endverbatim
+ * @{
+ */
+
+#if (__MPU_PRESENT == 1)
+/**
+ * @brief Initializes and configures the Region and the memory to be protected.
+ * @param MPU_Init: Pointer to a MPU_Region_InitTypeDef structure that contains
+ * the initialization and configuration information.
+ * @retval None
+ */
+void HAL_MPU_ConfigRegion(MPU_Region_InitTypeDef *MPU_Init)
+{
+ /* Check the parameters */
+ assert_param(IS_MPU_REGION_NUMBER(MPU_Init->Number));
+ assert_param(IS_MPU_REGION_ENABLE(MPU_Init->Enable));
+
+ /* Set the Region number */
+ MPU->RNR = MPU_Init->Number;
+
+ if ((MPU_Init->Enable) != RESET)
+ {
+ /* Check the parameters */
+ assert_param(IS_MPU_INSTRUCTION_ACCESS(MPU_Init->DisableExec));
+ assert_param(IS_MPU_REGION_PERMISSION_ATTRIBUTE(MPU_Init->AccessPermission));
+ assert_param(IS_MPU_TEX_LEVEL(MPU_Init->TypeExtField));
+ assert_param(IS_MPU_ACCESS_SHAREABLE(MPU_Init->IsShareable));
+ assert_param(IS_MPU_ACCESS_CACHEABLE(MPU_Init->IsCacheable));
+ assert_param(IS_MPU_ACCESS_BUFFERABLE(MPU_Init->IsBufferable));
+ assert_param(IS_MPU_SUB_REGION_DISABLE(MPU_Init->SubRegionDisable));
+ assert_param(IS_MPU_REGION_SIZE(MPU_Init->Size));
+
+ MPU->RBAR = MPU_Init->BaseAddress;
+ MPU->RASR = ((uint32_t)MPU_Init->DisableExec << MPU_RASR_XN_Pos) |
+ ((uint32_t)MPU_Init->AccessPermission << MPU_RASR_AP_Pos) |
+ ((uint32_t)MPU_Init->TypeExtField << MPU_RASR_TEX_Pos) |
+ ((uint32_t)MPU_Init->IsShareable << MPU_RASR_S_Pos) |
+ ((uint32_t)MPU_Init->IsCacheable << MPU_RASR_C_Pos) |
+ ((uint32_t)MPU_Init->IsBufferable << MPU_RASR_B_Pos) |
+ ((uint32_t)MPU_Init->SubRegionDisable << MPU_RASR_SRD_Pos) |
+ ((uint32_t)MPU_Init->Size << MPU_RASR_SIZE_Pos) |
+ ((uint32_t)MPU_Init->Enable << MPU_RASR_ENABLE_Pos);
+ }
+ else
+ {
+ MPU->RBAR = 0x00;
+ MPU->RASR = 0x00;
+ }
+}
+#endif /* __MPU_PRESENT */
+
+/**
+ * @brief Gets the priority grouping field from the NVIC Interrupt Controller.
+ * @retval Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field)
+ */
+uint32_t HAL_NVIC_GetPriorityGrouping(void)
+{
+ /* Get the PRIGROUP[10:8] field value */
+ return NVIC_GetPriorityGrouping();
+}
+
+/**
+ * @brief Gets the priority of an interrupt.
+ * @param IRQn: External interrupt number
+ * This parameter can be an enumerator of IRQn_Type enumeration
+ * (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f10xxx.h))
+ * @param PriorityGroup: the priority grouping bits length.
+ * This parameter can be one of the following values:
+ * @arg NVIC_PRIORITYGROUP_0: 0 bits for pre-emption priority
+ * 4 bits for subpriority
+ * @arg NVIC_PRIORITYGROUP_1: 1 bits for pre-emption priority
+ * 3 bits for subpriority
+ * @arg NVIC_PRIORITYGROUP_2: 2 bits for pre-emption priority
+ * 2 bits for subpriority
+ * @arg NVIC_PRIORITYGROUP_3: 3 bits for pre-emption priority
+ * 1 bits for subpriority
+ * @arg NVIC_PRIORITYGROUP_4: 4 bits for pre-emption priority
+ * 0 bits for subpriority
+ * @param pPreemptPriority: Pointer on the Preemptive priority value (starting from 0).
+ * @param pSubPriority: Pointer on the Subpriority value (starting from 0).
+ * @retval None
+ */
+void HAL_NVIC_GetPriority(IRQn_Type IRQn, uint32_t PriorityGroup, uint32_t* pPreemptPriority, uint32_t* pSubPriority)
+{
+ /* Check the parameters */
+ assert_param(IS_NVIC_PRIORITY_GROUP(PriorityGroup));
+ /* Get priority for Cortex-M system or device specific interrupts */
+ NVIC_DecodePriority(NVIC_GetPriority(IRQn), PriorityGroup, pPreemptPriority, pSubPriority);
+}
+
+/**
+ * @brief Sets Pending bit of an external interrupt.
+ * @param IRQn External interrupt number
+ * This parameter can be an enumerator of IRQn_Type enumeration
+ * (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f10xxx.h))
+ * @retval None
+ */
+void HAL_NVIC_SetPendingIRQ(IRQn_Type IRQn)
+{
+ /* Set interrupt pending */
+ NVIC_SetPendingIRQ(IRQn);
+}
+
+/**
+ * @brief Gets Pending Interrupt (reads the pending register in the NVIC
+ * and returns the pending bit for the specified interrupt).
+ * @param IRQn External interrupt number
+ * This parameter can be an enumerator of IRQn_Type enumeration
+ * (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f10xxx.h))
+ * @retval status: - 0 Interrupt status is not pending.
+ * - 1 Interrupt status is pending.
+ */
+uint32_t HAL_NVIC_GetPendingIRQ(IRQn_Type IRQn)
+{
+ /* Return 1 if pending else 0 */
+ return NVIC_GetPendingIRQ(IRQn);
+}
+
+/**
+ * @brief Clears the pending bit of an external interrupt.
+ * @param IRQn External interrupt number
+ * This parameter can be an enumerator of IRQn_Type enumeration
+ * (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f10xxx.h))
+ * @retval None
+ */
+void HAL_NVIC_ClearPendingIRQ(IRQn_Type IRQn)
+{
+ /* Clear pending interrupt */
+ NVIC_ClearPendingIRQ(IRQn);
+}
+
+/**
+ * @brief Gets active interrupt ( reads the active register in NVIC and returns the active bit).
+ * @param IRQn External interrupt number
+ * This parameter can be an enumerator of IRQn_Type enumeration
+ * (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f10xxx.h))
+ * @retval status: - 0 Interrupt status is not pending.
+ * - 1 Interrupt status is pending.
+ */
+uint32_t HAL_NVIC_GetActive(IRQn_Type IRQn)
+{
+ /* Return 1 if active else 0 */
+ return NVIC_GetActive(IRQn);
+}
+
+/**
+ * @brief Configures the SysTick clock source.
+ * @param CLKSource: specifies the SysTick clock source.
+ * This parameter can be one of the following values:
+ * @arg SYSTICK_CLKSOURCE_HCLK_DIV8: AHB clock divided by 8 selected as SysTick clock source.
+ * @arg SYSTICK_CLKSOURCE_HCLK: AHB clock selected as SysTick clock source.
+ * @retval None
+ */
+void HAL_SYSTICK_CLKSourceConfig(uint32_t CLKSource)
+{
+ /* Check the parameters */
+ assert_param(IS_SYSTICK_CLK_SOURCE(CLKSource));
+ if (CLKSource == SYSTICK_CLKSOURCE_HCLK)
+ {
+ SysTick->CTRL |= SYSTICK_CLKSOURCE_HCLK;
+ }
+ else
+ {
+ SysTick->CTRL &= ~SYSTICK_CLKSOURCE_HCLK;
+ }
+}
+
+/**
+ * @brief This function handles SYSTICK interrupt request.
+ * @retval None
+ */
+void HAL_SYSTICK_IRQHandler(void)
+{
+ HAL_SYSTICK_Callback();
+}
+
+/**
+ * @brief SYSTICK callback.
+ * @retval None
+ */
+__weak void HAL_SYSTICK_Callback(void)
+{
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_SYSTICK_Callback could be implemented in the user file
+ */
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* HAL_CORTEX_MODULE_ENABLED */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/bsp/radio-controller-1/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_dma.c b/bsp/radio-controller-1/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_dma.c
new file mode 100644
index 0000000..a249c81
--- /dev/null
+++ b/bsp/radio-controller-1/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_dma.c
@@ -0,0 +1,709 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_dma.c
+ * @author MCD Application Team
+ * @version V1.0.4
+ * @date 29-April-2016
+ * @brief DMA HAL module driver.
+ *
+ * This file provides firmware functions to manage the following
+ * functionalities of the Direct Memory Access (DMA) peripheral:
+ * + Initialization and de-initialization functions
+ * + IO operation functions
+ * + Peripheral State and errors functions
+ @verbatim
+ ==============================================================================
+ ##### How to use this driver #####
+ ==============================================================================
+ [..]
+ (#) Enable and configure the peripheral to be connected to the DMA Channel
+ (except for internal SRAM / FLASH memories: no initialization is
+ necessary) please refer to Reference manual for connection between peripherals
+ and DMA requests.
+
+ (#) For a given Channel, program the required configuration through the following parameters:
+ Transfer Direction, Source and Destination data formats,
+ Circular or Normal mode, Channel Priority level, Source and Destination Increment mode,
+ using HAL_DMA_Init() function.
+
+ (#) Use HAL_DMA_GetState() function to return the DMA state and HAL_DMA_GetError() in case of error
+ detection.
+
+ (#) Use HAL_DMA_Abort() function to abort the current transfer
+
+ -@- In Memory-to-Memory transfer mode, Circular mode is not allowed.
+ *** Polling mode IO operation ***
+ =================================
+ [..]
+ (+) Use HAL_DMA_Start() to start DMA transfer after the configuration of Source
+ address and destination address and the Length of data to be transferred
+ (+) Use HAL_DMA_PollForTransfer() to poll for the end of current transfer, in this
+ case a fixed Timeout can be configured by User depending from his application.
+
+ *** Interrupt mode IO operation ***
+ ===================================
+ [..]
+ (+) Configure the DMA interrupt priority using HAL_NVIC_SetPriority()
+ (+) Enable the DMA IRQ handler using HAL_NVIC_EnableIRQ()
+ (+) Use HAL_DMA_Start_IT() to start DMA transfer after the configuration of
+ Source address and destination address and the Length of data to be transferred.
+ In this case the DMA interrupt is configured
+ (+) Use HAL_DMAy_Channelx_IRQHandler() called under DMA_IRQHandler() Interrupt subroutine
+ (+) At the end of data transfer HAL_DMA_IRQHandler() function is executed and user can
+ add his own function by customization of function pointer XferCpltCallback and
+ XferErrorCallback (i.e a member of DMA handle structure).
+
+ *** DMA HAL driver macros list ***
+ =============================================
+ [..]
+ Below the list of most used macros in DMA HAL driver.
+
+ (+) __HAL_DMA_ENABLE: Enable the specified DMA Channel.
+ (+) __HAL_DMA_DISABLE: Disable the specified DMA Channel.
+ (+) __HAL_DMA_GET_FLAG: Get the DMA Channel pending flags.
+ (+) __HAL_DMA_CLEAR_FLAG: Clear the DMA Channel pending flags.
+ (+) __HAL_DMA_ENABLE_IT: Enable the specified DMA Channel interrupts.
+ (+) __HAL_DMA_DISABLE_IT: Disable the specified DMA Channel interrupts.
+ (+) __HAL_DMA_GET_IT_SOURCE: Check whether the specified DMA Channel interrupt has occurred or not.
+
+ [..]
+ (@) You can refer to the DMA HAL driver header file for more useful macros
+
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+/** @defgroup DMA DMA
+ * @brief DMA HAL module driver
+ * @{
+ */
+
+#ifdef HAL_DMA_MODULE_ENABLED
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/** @defgroup DMA_Private_Constants DMA Private Constants
+ * @{
+ */
+#define HAL_TIMEOUT_DMA_ABORT ((uint32_t)1000) /* 1s */
+/**
+ * @}
+ */
+
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/** @defgroup DMA_Private_Functions DMA Private Functions
+ * @{
+ */
+static void DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength);
+/**
+ * @}
+ */
+
+/* Exported functions ---------------------------------------------------------*/
+
+/** @defgroup DMA_Exported_Functions DMA Exported Functions
+ * @{
+ */
+
+/** @defgroup DMA_Exported_Functions_Group1 Initialization and de-initialization functions
+ * @brief Initialization and de-initialization functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Initialization and de-initialization functions #####
+ ===============================================================================
+ [..]
+ This section provides functions allowing to initialize the DMA Channel source
+ and destination addresses, incrementation and data sizes, transfer direction,
+ circular/normal mode selection, memory-to-memory mode selection and Channel priority value.
+ [..]
+ The HAL_DMA_Init() function follows the DMA configuration procedures as described in
+ reference manual.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Initializes the DMA according to the specified
+ * parameters in the DMA_InitTypeDef and create the associated handle.
+ * @param hdma: Pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA Channel.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_DMA_Init(DMA_HandleTypeDef *hdma)
+{
+ uint32_t tmp = 0;
+
+ /* Check the DMA handle allocation */
+ if(hdma == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check the parameters */
+ assert_param(IS_DMA_ALL_INSTANCE(hdma->Instance));
+ assert_param(IS_DMA_DIRECTION(hdma->Init.Direction));
+ assert_param(IS_DMA_PERIPHERAL_INC_STATE(hdma->Init.PeriphInc));
+ assert_param(IS_DMA_MEMORY_INC_STATE(hdma->Init.MemInc));
+ assert_param(IS_DMA_PERIPHERAL_DATA_SIZE(hdma->Init.PeriphDataAlignment));
+ assert_param(IS_DMA_MEMORY_DATA_SIZE(hdma->Init.MemDataAlignment));
+ assert_param(IS_DMA_MODE(hdma->Init.Mode));
+ assert_param(IS_DMA_PRIORITY(hdma->Init.Priority));
+
+ if(hdma->State == HAL_DMA_STATE_RESET)
+ {
+ /* Allocate lock resource and initialize it */
+ hdma->Lock = HAL_UNLOCKED;
+ }
+
+ /* Change DMA peripheral state */
+ hdma->State = HAL_DMA_STATE_BUSY;
+
+ /* Get the CR register value */
+ tmp = hdma->Instance->CCR;
+
+ /* Clear PL, MSIZE, PSIZE, MINC, PINC, CIRC, DIR bits */
+ tmp &= ((uint32_t)~(DMA_CCR_PL | DMA_CCR_MSIZE | DMA_CCR_PSIZE | \
+ DMA_CCR_MINC | DMA_CCR_PINC | DMA_CCR_CIRC | \
+ DMA_CCR_DIR));
+
+ /* Prepare the DMA Channel configuration */
+ tmp |= hdma->Init.Direction |
+ hdma->Init.PeriphInc | hdma->Init.MemInc |
+ hdma->Init.PeriphDataAlignment | hdma->Init.MemDataAlignment |
+ hdma->Init.Mode | hdma->Init.Priority;
+
+ /* Write to DMA Channel CR register */
+ hdma->Instance->CCR = tmp;
+
+ /* Initialise the error code */
+ hdma->ErrorCode = HAL_DMA_ERROR_NONE;
+
+ /* Initialize the DMA state*/
+ hdma->State = HAL_DMA_STATE_READY;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief DeInitializes the DMA peripheral
+ * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA Channel.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_DMA_DeInit(DMA_HandleTypeDef *hdma)
+{
+ /* Check the DMA handle allocation */
+ if(hdma == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check the parameters */
+ assert_param(IS_DMA_ALL_INSTANCE(hdma->Instance));
+
+ /* Check the DMA peripheral state */
+ if(hdma->State == HAL_DMA_STATE_BUSY)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Disable the selected DMA Channelx */
+ __HAL_DMA_DISABLE(hdma);
+
+ /* Reset DMA Channel control register */
+ hdma->Instance->CCR = 0;
+
+ /* Reset DMA Channel Number of Data to Transfer register */
+ hdma->Instance->CNDTR = 0;
+
+ /* Reset DMA Channel peripheral address register */
+ hdma->Instance->CPAR = 0;
+
+ /* Reset DMA Channel memory address register */
+ hdma->Instance->CMAR = 0;
+
+ /* Clear all flags */
+ __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma));
+ __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma));
+ __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));
+
+ /* Initialize the error code */
+ hdma->ErrorCode = HAL_DMA_ERROR_NONE;
+
+ /* Initialize the DMA state */
+ hdma->State = HAL_DMA_STATE_RESET;
+
+ /* Release Lock */
+ __HAL_UNLOCK(hdma);
+
+ return HAL_OK;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup DMA_Exported_Functions_Group2 Input and Output operation functions
+ * @brief I/O operation functions
+ *
+@verbatim
+ ===============================================================================
+ ##### IO operation functions #####
+ ===============================================================================
+ [..] This section provides functions allowing to:
+ (+) Configure the source, destination address and data length and Start DMA transfer
+ (+) Configure the source, destination address and data length and
+ Start DMA transfer with interrupt
+ (+) Abort DMA transfer
+ (+) Poll for transfer complete
+ (+) Handle DMA interrupt request
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Starts the DMA Transfer.
+ * @param hdma : pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA Channel.
+ * @param SrcAddress: The source memory Buffer address
+ * @param DstAddress: The destination memory Buffer address
+ * @param DataLength: The length of data to be transferred from source to destination
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_DMA_Start(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
+{
+ /* Process locked */
+ __HAL_LOCK(hdma);
+
+ /* Change DMA peripheral state */
+ hdma->State = HAL_DMA_STATE_BUSY;
+
+ /* Check the parameters */
+ assert_param(IS_DMA_BUFFER_SIZE(DataLength));
+
+ /* Disable the peripheral */
+ __HAL_DMA_DISABLE(hdma);
+
+ /* Configure the source, destination address and the data length */
+ DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength);
+
+ /* Enable the Peripheral */
+ __HAL_DMA_ENABLE(hdma);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Start the DMA Transfer with interrupt enabled.
+ * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA Channel.
+ * @param SrcAddress: The source memory Buffer address
+ * @param DstAddress: The destination memory Buffer address
+ * @param DataLength: The length of data to be transferred from source to destination
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_DMA_Start_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
+{
+ /* Process locked */
+ __HAL_LOCK(hdma);
+
+ /* Change DMA peripheral state */
+ hdma->State = HAL_DMA_STATE_BUSY;
+
+ /* Check the parameters */
+ assert_param(IS_DMA_BUFFER_SIZE(DataLength));
+
+ /* Disable the peripheral */
+ __HAL_DMA_DISABLE(hdma);
+
+ /* Configure the source, destination address and the data length */
+ DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength);
+
+ /* Enable the transfer complete interrupt */
+ __HAL_DMA_ENABLE_IT(hdma, DMA_IT_TC);
+
+ /* Enable the Half transfer complete interrupt */
+ __HAL_DMA_ENABLE_IT(hdma, DMA_IT_HT);
+
+ /* Enable the transfer Error interrupt */
+ __HAL_DMA_ENABLE_IT(hdma, DMA_IT_TE);
+
+ /* Enable the Peripheral */
+ __HAL_DMA_ENABLE(hdma);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Aborts the DMA Transfer.
+ * @param hdma : pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA Channel.
+ *
+ * @note After disabling a DMA Channel, a check for wait until the DMA Channel is
+ * effectively disabled is added. If a Channel is disabled
+ * while a data transfer is ongoing, the current data will be transferred
+ * and the Channel will be effectively disabled only after the transfer of
+ * this single data is finished.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_DMA_Abort(DMA_HandleTypeDef *hdma)
+{
+ uint32_t tickstart = 0x00;
+
+ /* Disable the channel */
+ __HAL_DMA_DISABLE(hdma);
+
+ /* Get tick */
+ tickstart = HAL_GetTick();
+
+ /* Check if the DMA Channel is effectively disabled */
+ while((hdma->Instance->CCR & DMA_CCR_EN) != 0)
+ {
+ /* Check for the Timeout */
+ if((HAL_GetTick() - tickstart) > HAL_TIMEOUT_DMA_ABORT)
+ {
+ /* Update error code */
+ SET_BIT(hdma->ErrorCode, HAL_DMA_ERROR_TIMEOUT);
+
+ /* Change the DMA state */
+ hdma->State = HAL_DMA_STATE_TIMEOUT;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hdma);
+
+ return HAL_TIMEOUT;
+ }
+ }
+ /* Change the DMA state */
+ hdma->State = HAL_DMA_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hdma);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Polling for transfer complete.
+ * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA Channel.
+ * @param CompleteLevel: Specifies the DMA level complete.
+ * @param Timeout: Timeout duration.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_DMA_PollForTransfer(DMA_HandleTypeDef *hdma, uint32_t CompleteLevel, uint32_t Timeout)
+{
+ uint32_t temp;
+ uint32_t tickstart = 0x00;
+
+ /* Get the level transfer complete flag */
+ if(CompleteLevel == HAL_DMA_FULL_TRANSFER)
+ {
+ /* Transfer Complete flag */
+ temp = __HAL_DMA_GET_TC_FLAG_INDEX(hdma);
+ }
+ else
+ {
+ /* Half Transfer Complete flag */
+ temp = __HAL_DMA_GET_HT_FLAG_INDEX(hdma);
+ }
+
+ /* Get tick */
+ tickstart = HAL_GetTick();
+
+ while(__HAL_DMA_GET_FLAG(hdma, temp) == RESET)
+ {
+ if((__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma)) != RESET))
+ {
+ /* Clear the transfer error flags */
+ __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma));
+
+ /* Update error code */
+ SET_BIT(hdma->ErrorCode, HAL_DMA_ERROR_TE);
+
+ /* Change the DMA state */
+ hdma->State= HAL_DMA_STATE_ERROR;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hdma);
+
+ return HAL_ERROR;
+ }
+ /* Check for the Timeout */
+ if(Timeout != HAL_MAX_DELAY)
+ {
+ if((Timeout == 0) || ((HAL_GetTick() - tickstart) > Timeout))
+ {
+ /* Update error code */
+ SET_BIT(hdma->ErrorCode, HAL_DMA_ERROR_TIMEOUT);
+
+ /* Change the DMA state */
+ hdma->State = HAL_DMA_STATE_TIMEOUT;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hdma);
+
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+
+ if(CompleteLevel == HAL_DMA_FULL_TRANSFER)
+ {
+ /* Clear the transfer complete flag */
+ __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma));
+
+ /* The selected Channelx EN bit is cleared (DMA is disabled and
+ all transfers are complete) */
+ hdma->State = HAL_DMA_STATE_READY;
+
+ }
+ else
+ {
+ /* Clear the half transfer complete flag */
+ __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));
+
+ /* The selected Channelx EN bit is cleared (DMA is disabled and
+ all transfers of half buffer are complete) */
+ hdma->State = HAL_DMA_STATE_READY_HALF;
+ }
+
+ /* Process unlocked */
+ __HAL_UNLOCK(hdma);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Handles DMA interrupt request.
+ * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA Channel.
+ * @retval None
+ */
+void HAL_DMA_IRQHandler(DMA_HandleTypeDef *hdma)
+{
+ /* Transfer Error Interrupt management ***************************************/
+ if(__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma)) != RESET)
+ {
+ if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_TE) != RESET)
+ {
+ /* Disable the transfer error interrupt */
+ __HAL_DMA_DISABLE_IT(hdma, DMA_IT_TE);
+
+ /* Clear the transfer error flag */
+ __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma));
+
+ /* Update error code */
+ SET_BIT(hdma->ErrorCode, HAL_DMA_ERROR_TE);
+
+ /* Change the DMA state */
+ hdma->State = HAL_DMA_STATE_ERROR;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hdma);
+
+ if (hdma->XferErrorCallback != NULL)
+ {
+ /* Transfer error callback */
+ hdma->XferErrorCallback(hdma);
+ }
+ }
+ }
+
+ /* Half Transfer Complete Interrupt management ******************************/
+ if(__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma)) != RESET)
+ {
+ if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_HT) != RESET)
+ {
+ /* Disable the half transfer interrupt if the DMA mode is not CIRCULAR */
+ if((hdma->Instance->CCR & DMA_CCR_CIRC) == 0)
+ {
+ /* Disable the half transfer interrupt */
+ __HAL_DMA_DISABLE_IT(hdma, DMA_IT_HT);
+ }
+ /* Clear the half transfer complete flag */
+ __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));
+
+ /* Change DMA peripheral state */
+ hdma->State = HAL_DMA_STATE_READY_HALF;
+
+ if(hdma->XferHalfCpltCallback != NULL)
+ {
+ /* Half transfer callback */
+ hdma->XferHalfCpltCallback(hdma);
+ }
+ }
+ }
+
+ /* Transfer Complete Interrupt management ***********************************/
+ if(__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma)) != RESET)
+ {
+ if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_TC) != RESET)
+ {
+ if((hdma->Instance->CCR & DMA_CCR_CIRC) == 0)
+ {
+ /* Disable the transfer complete interrupt */
+ __HAL_DMA_DISABLE_IT(hdma, DMA_IT_TC);
+ }
+ /* Clear the transfer complete flag */
+ __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma));
+
+ /* Update error code */
+ SET_BIT(hdma->ErrorCode, HAL_DMA_ERROR_NONE);
+
+ /* Change the DMA state */
+ hdma->State = HAL_DMA_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hdma);
+
+ if(hdma->XferCpltCallback != NULL)
+ {
+ /* Transfer complete callback */
+ hdma->XferCpltCallback(hdma);
+ }
+ }
+ }
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup DMA_Exported_Functions_Group3 Peripheral State functions
+ * @brief Peripheral State functions
+ *
+@verbatim
+ ===============================================================================
+ ##### State and Errors functions #####
+ ===============================================================================
+ [..]
+ This subsection provides functions allowing to
+ (+) Check the DMA state
+ (+) Get error code
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Returns the DMA state.
+ * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA Channel.
+ * @retval HAL state
+ */
+HAL_DMA_StateTypeDef HAL_DMA_GetState(DMA_HandleTypeDef *hdma)
+{
+ return hdma->State;
+}
+
+/**
+ * @brief Return the DMA error code
+ * @param hdma : pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA Channel.
+ * @retval DMA Error Code
+ */
+uint32_t HAL_DMA_GetError(DMA_HandleTypeDef *hdma)
+{
+ return hdma->ErrorCode;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/** @addtogroup DMA_Private_Functions DMA Private Functions
+ * @{
+ */
+
+/**
+ * @brief Sets the DMA Transfer parameter.
+ * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA Channel.
+ * @param SrcAddress: The source memory Buffer address
+ * @param DstAddress: The destination memory Buffer address
+ * @param DataLength: The length of data to be transferred from source to destination
+ * @retval HAL status
+ */
+static void DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
+{
+ /* Configure DMA Channel data length */
+ hdma->Instance->CNDTR = DataLength;
+
+ /* Peripheral to Memory */
+ if((hdma->Init.Direction) == DMA_MEMORY_TO_PERIPH)
+ {
+ /* Configure DMA Channel destination address */
+ hdma->Instance->CPAR = DstAddress;
+
+ /* Configure DMA Channel source address */
+ hdma->Instance->CMAR = SrcAddress;
+ }
+ /* Memory to Peripheral */
+ else
+ {
+ /* Configure DMA Channel source address */
+ hdma->Instance->CPAR = SrcAddress;
+
+ /* Configure DMA Channel destination address */
+ hdma->Instance->CMAR = DstAddress;
+ }
+}
+
+/**
+ * @}
+ */
+
+#endif /* HAL_DMA_MODULE_ENABLED */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/bsp/radio-controller-1/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_flash.c b/bsp/radio-controller-1/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_flash.c
new file mode 100644
index 0000000..b59e08c
--- /dev/null
+++ b/bsp/radio-controller-1/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_flash.c
@@ -0,0 +1,974 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_flash.c
+ * @author MCD Application Team
+ * @version V1.0.4
+ * @date 29-April-2016
+ * @brief FLASH HAL module driver.
+ * This file provides firmware functions to manage the following
+ * functionalities of the internal FLASH memory:
+ * + Program operations functions
+ * + Memory Control functions
+ * + Peripheral State functions
+ *
+ @verbatim
+ ==============================================================================
+ ##### FLASH peripheral features #####
+ ==============================================================================
+ [..] The Flash memory interface manages CPU AHB I-Code and D-Code accesses
+ to the Flash memory. It implements the erase and program Flash memory operations
+ and the read and write protection mechanisms.
+
+ [..] The Flash memory interface accelerates code execution with a system of instruction
+ prefetch.
+
+ [..] The FLASH main features are:
+ (+) Flash memory read operations
+ (+) Flash memory program/erase operations
+ (+) Read / write protections
+ (+) Prefetch on I-Code
+ (+) Option Bytes programming
+
+
+ ##### How to use this driver #####
+ ==============================================================================
+ [..]
+ This driver provides functions and macros to configure and program the FLASH
+ memory of all STM32F1xx devices.
+
+ (#) FLASH Memory I/O Programming functions: this group includes all needed
+ functions to erase and program the main memory:
+ (++) Lock and Unlock the FLASH interface
+ (++) Erase function: Erase page, erase all pages
+ (++) Program functions: half word, word and doubleword
+
+ (#) FLASH Option Bytes Programming functions: this group includes all needed
+ functions to manage the Option Bytes:
+ (++) Lock and Unlock the Option Bytes
+ (++) Set/Reset the write protection
+ (++) Set the Read protection Level
+ (++) Program the user Option Bytes
+ (++) Launch the Option Bytes loader
+ (++) Erase Option Bytes
+ (++) Program the data Option Bytes
+ (++) Get the Write protection.
+ (++) Get the user option bytes.
+
+ (#) Interrupts and flags management functions : this group
+ includes all needed functions to:
+ (++) Handle FLASH interrupts
+ (++) Wait for last FLASH operation according to its status
+ (++) Get error flag status
+
+ [..] In addition to these function, this driver includes a set of macros allowing
+ to handle the following operations:
+
+ (+) Set/Get the latency
+ (+) Enable/Disable the prefetch buffer
+ (+) Enable/Disable the half cycle access
+ (+) Enable/Disable the FLASH interrupts
+ (+) Monitor the FLASH flags status
+
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+#ifdef HAL_FLASH_MODULE_ENABLED
+
+/** @defgroup FLASH FLASH
+ * @brief FLASH HAL module driver
+ * @{
+ */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/** @defgroup FLASH_Private_Constants FLASH Private Constants
+ * @{
+ */
+/**
+ * @}
+ */
+
+/* Private macro ---------------------------- ---------------------------------*/
+/** @defgroup FLASH_Private_Macros FLASH Private Macros
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/* Private variables ---------------------------------------------------------*/
+/** @defgroup FLASH_Private_Variables FLASH Private Variables
+ * @{
+ */
+/* Variables used for Erase pages under interruption*/
+FLASH_ProcessTypeDef pFlash;
+/**
+ * @}
+ */
+
+/* Private function prototypes -----------------------------------------------*/
+/** @defgroup FLASH_Private_Functions FLASH Private Functions
+ * @{
+ */
+static void FLASH_Program_HalfWord(uint32_t Address, uint16_t Data);
+static void FLASH_SetErrorCode(void);
+/**
+ * @}
+ */
+
+/* Exported functions ---------------------------------------------------------*/
+/** @defgroup FLASH_Exported_Functions FLASH Exported Functions
+ * @{
+ */
+
+/** @defgroup FLASH_Exported_Functions_Group1 Programming operation functions
+ * @brief Programming operation functions
+ *
+@verbatim
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Program halfword, word or double word at a specified address
+ * @note The function HAL_FLASH_Unlock() should be called before to unlock the FLASH interface
+ * The function HAL_FLASH_Lock() should be called after to lock the FLASH interface
+ *
+ * @note If an erase and a program operations are requested simultaneously,
+ * the erase operation is performed before the program one.
+ *
+ * @note FLASH should be previously erased before new programmation (only exception to this
+ * is when 0x0000 is programmed)
+ *
+ * @param TypeProgram: Indicate the way to program at a specified address.
+ * This parameter can be a value of @ref FLASH_Type_Program
+ * @param Address: Specifies the address to be programmed.
+ * @param Data: Specifies the data to be programmed
+ *
+ * @retval HAL_StatusTypeDef HAL Status
+ */
+HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t Address, uint64_t Data)
+{
+ HAL_StatusTypeDef status = HAL_ERROR;
+ uint8_t index = 0;
+ uint8_t nbiterations = 0;
+
+ /* Process Locked */
+ __HAL_LOCK(&pFlash);
+
+ /* Check the parameters */
+ assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram));
+ assert_param(IS_FLASH_PROGRAM_ADDRESS(Address));
+
+#if defined(FLASH_BANK2_END)
+ if(Address <= FLASH_BANK1_END)
+ {
+#endif /* FLASH_BANK2_END */
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
+#if defined(FLASH_BANK2_END)
+ }
+ else
+ {
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperationBank2((uint32_t)FLASH_TIMEOUT_VALUE);
+ }
+#endif /* FLASH_BANK2_END */
+
+ if(status == HAL_OK)
+ {
+ if(TypeProgram == FLASH_TYPEPROGRAM_HALFWORD)
+ {
+ /* Program halfword (16-bit) at a specified address. */
+ nbiterations = 1;
+ }
+ else if(TypeProgram == FLASH_TYPEPROGRAM_WORD)
+ {
+ /* Program word (32-bit = 2*16-bit) at a specified address. */
+ nbiterations = 2;
+ }
+ else
+ {
+ /* Program double word (64-bit = 4*16-bit) at a specified address. */
+ nbiterations = 4;
+ }
+
+ for (index = 0; index < nbiterations; index++)
+ {
+ FLASH_Program_HalfWord((Address + (2*index)), (uint16_t)(Data >> (16*index)));
+
+#if defined(FLASH_BANK2_END)
+ if(Address <= FLASH_BANK1_END)
+ {
+#endif /* FLASH_BANK2_END */
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
+
+ /* If the program operation is completed, disable the PG Bit */
+ CLEAR_BIT(FLASH->CR, FLASH_CR_PG);
+#if defined(FLASH_BANK2_END)
+ }
+ else
+ {
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperationBank2((uint32_t)FLASH_TIMEOUT_VALUE);
+
+ /* If the program operation is completed, disable the PG Bit */
+ CLEAR_BIT(FLASH->CR2, FLASH_CR2_PG);
+ }
+#endif /* FLASH_BANK2_END */
+ /* In case of error, stop programation procedure */
+ if (status != HAL_OK)
+ {
+ break;
+ }
+ }
+ }
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(&pFlash);
+
+ return status;
+}
+
+/**
+ * @brief Program halfword, word or double word at a specified address with interrupt enabled.
+ * @note The function HAL_FLASH_Unlock() should be called before to unlock the FLASH interface
+ * The function HAL_FLASH_Lock() should be called after to lock the FLASH interface
+ *
+ * @note If an erase and a program operations are requested simultaneously,
+ * the erase operation is performed before the program one.
+ *
+ * @param TypeProgram: Indicate the way to program at a specified address.
+ * This parameter can be a value of @ref FLASH_Type_Program
+ * @param Address: Specifies the address to be programmed.
+ * @param Data: Specifies the data to be programmed
+ *
+ * @retval HAL_StatusTypeDef HAL Status
+ */
+HAL_StatusTypeDef HAL_FLASH_Program_IT(uint32_t TypeProgram, uint32_t Address, uint64_t Data)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+
+ /* Process Locked */
+ __HAL_LOCK(&pFlash);
+
+ /* Check the parameters */
+ assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram));
+ assert_param(IS_FLASH_PROGRAM_ADDRESS(Address));
+
+#if defined(FLASH_BANK2_END)
+ /* If procedure already ongoing, reject the next one */
+ if (pFlash.ProcedureOnGoing != FLASH_PROC_NONE)
+ {
+ return HAL_ERROR;
+ }
+
+ if(Address <= FLASH_BANK1_END)
+ {
+ /* Enable End of FLASH Operation and Error source interrupts */
+ __HAL_FLASH_ENABLE_IT(FLASH_IT_EOP_BANK1 | FLASH_IT_ERR_BANK1);
+
+ }else
+ {
+ /* Enable End of FLASH Operation and Error source interrupts */
+ __HAL_FLASH_ENABLE_IT(FLASH_IT_EOP_BANK2 | FLASH_IT_ERR_BANK2);
+ }
+#else
+ /* Enable End of FLASH Operation and Error source interrupts */
+ __HAL_FLASH_ENABLE_IT(FLASH_IT_EOP | FLASH_IT_ERR);
+#endif /* FLASH_BANK2_END */
+
+ pFlash.Address = Address;
+ pFlash.Data = Data;
+
+ if(TypeProgram == FLASH_TYPEPROGRAM_HALFWORD)
+ {
+ pFlash.ProcedureOnGoing = FLASH_PROC_PROGRAMHALFWORD;
+ /*Program halfword (16-bit) at a specified address.*/
+ pFlash.DataRemaining = 1;
+ }
+ else if(TypeProgram == FLASH_TYPEPROGRAM_WORD)
+ {
+ pFlash.ProcedureOnGoing = FLASH_PROC_PROGRAMWORD;
+ /*Program word (32-bit : 2*16-bit) at a specified address.*/
+ pFlash.DataRemaining = 2;
+ }
+ else
+ {
+ pFlash.ProcedureOnGoing = FLASH_PROC_PROGRAMDOUBLEWORD;
+ /*Program double word (64-bit : 4*16-bit) at a specified address.*/
+ pFlash.DataRemaining = 4;
+ }
+
+ /*Program halfword (16-bit) at a specified address.*/
+ FLASH_Program_HalfWord(Address, (uint16_t)Data);
+
+ return status;
+}
+
+/**
+ * @brief This function handles FLASH interrupt request.
+ * @retval None
+ */
+void HAL_FLASH_IRQHandler(void)
+{
+ uint32_t addresstmp = 0;
+
+ /* Check FLASH operation error flags */
+#if defined(FLASH_BANK2_END)
+ if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR_BANK1) || __HAL_FLASH_GET_FLAG(FLASH_FLAG_PGERR_BANK1) || \
+ (__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR_BANK2) || __HAL_FLASH_GET_FLAG(FLASH_FLAG_PGERR_BANK2)))
+#else
+ if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR) ||__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGERR))
+#endif /* FLASH_BANK2_END */
+ {
+ /*return the faulty address*/
+ addresstmp = pFlash.Address;
+ /* Reset address */
+ pFlash.Address = 0xFFFFFFFF;
+
+ /*Save the Error code*/
+ FLASH_SetErrorCode();
+
+ /* FLASH error interrupt user callback */
+ HAL_FLASH_OperationErrorCallback(addresstmp);
+
+ /* Stop the procedure ongoing*/
+ pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
+ }
+
+ /* Check FLASH End of Operation flag */
+#if defined(FLASH_BANK2_END)
+ if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP_BANK1))
+ {
+ /* Clear FLASH End of Operation pending bit */
+ __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP_BANK1);
+#else
+ if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP))
+ {
+ /* Clear FLASH End of Operation pending bit */
+ __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP);
+#endif /* FLASH_BANK2_END */
+
+ /* Process can continue only if no error detected */
+ if(pFlash.ProcedureOnGoing != FLASH_PROC_NONE)
+ {
+ if(pFlash.ProcedureOnGoing == FLASH_PROC_PAGEERASE)
+ {
+ /* Nb of pages to erased can be decreased */
+ pFlash.DataRemaining--;
+
+ /* Check if there are still pages to erase*/
+ if(pFlash.DataRemaining != 0)
+ {
+ addresstmp = pFlash.Address;
+ /*Indicate user which sector has been erased*/
+ HAL_FLASH_EndOfOperationCallback(addresstmp);
+
+ /*Increment sector number*/
+ addresstmp = pFlash.Address + FLASH_PAGE_SIZE;
+ pFlash.Address = addresstmp;
+
+ /* If the erase operation is completed, disable the PER Bit */
+ CLEAR_BIT(FLASH->CR, FLASH_CR_PER);
+
+ FLASH_PageErase(addresstmp);
+ }
+ else
+ {
+ /*No more pages to Erase, user callback can be called.*/
+ /*Reset Sector and stop Erase pages procedure*/
+ pFlash.Address = addresstmp = 0xFFFFFFFF;
+ pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
+ /* FLASH EOP interrupt user callback */
+ HAL_FLASH_EndOfOperationCallback(addresstmp);
+ }
+ }
+ else if(pFlash.ProcedureOnGoing == FLASH_PROC_MASSERASE)
+ {
+ /* Operation is completed, disable the MER Bit */
+ CLEAR_BIT(FLASH->CR, FLASH_CR_MER);
+
+#if defined(FLASH_BANK2_END)
+ /* Stop Mass Erase procedure if no pending mass erase on other bank */
+ if (HAL_IS_BIT_CLR(FLASH->CR2, FLASH_CR2_MER))
+ {
+#endif /* FLASH_BANK2_END */
+ /* MassErase ended. Return the selected bank*/
+ /* FLASH EOP interrupt user callback */
+ HAL_FLASH_EndOfOperationCallback(0);
+
+ /* Stop Mass Erase procedure*/
+ pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
+ }
+#if defined(FLASH_BANK2_END)
+ }
+#endif /* FLASH_BANK2_END */
+ else
+ {
+ /* Nb of 16-bit data to program can be decreased */
+ pFlash.DataRemaining--;
+
+ /* Check if there are still 16-bit data to program */
+ if(pFlash.DataRemaining != 0)
+ {
+ /* Increment address to 16-bit */
+ pFlash.Address += 2;
+ addresstmp = pFlash.Address;
+
+ /* Shift to have next 16-bit data */
+ pFlash.Data = (pFlash.Data >> 16);
+
+ /* Operation is completed, disable the PG Bit */
+ CLEAR_BIT(FLASH->CR, FLASH_CR_PG);
+
+ /*Program halfword (16-bit) at a specified address.*/
+ FLASH_Program_HalfWord(addresstmp, (uint16_t)pFlash.Data);
+ }
+ else
+ {
+ /*Program ended. Return the selected address*/
+ /* FLASH EOP interrupt user callback */
+ if (pFlash.ProcedureOnGoing == FLASH_PROC_PROGRAMHALFWORD)
+ {
+ HAL_FLASH_EndOfOperationCallback(pFlash.Address);
+ }
+ else if (pFlash.ProcedureOnGoing == FLASH_PROC_PROGRAMWORD)
+ {
+ HAL_FLASH_EndOfOperationCallback(pFlash.Address - 2);
+ }
+ else
+ {
+ HAL_FLASH_EndOfOperationCallback(pFlash.Address - 6);
+ }
+
+ /* Reset Address and stop Program procedure*/
+ pFlash.Address = 0xFFFFFFFF;
+ pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
+ }
+ }
+ }
+ }
+
+#if defined(FLASH_BANK2_END)
+ /* Check FLASH End of Operation flag */
+ if(__HAL_FLASH_GET_FLAG( FLASH_FLAG_EOP_BANK2))
+ {
+ /* Clear FLASH End of Operation pending bit */
+ __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP_BANK2);
+
+ /* Process can continue only if no error detected */
+ if(pFlash.ProcedureOnGoing != FLASH_PROC_NONE)
+ {
+ if(pFlash.ProcedureOnGoing == FLASH_PROC_PAGEERASE)
+ {
+ /* Nb of pages to erased can be decreased */
+ pFlash.DataRemaining--;
+
+ /* Check if there are still pages to erase*/
+ if(pFlash.DataRemaining != 0)
+ {
+ /* Indicate user which page address has been erased*/
+ HAL_FLASH_EndOfOperationCallback(pFlash.Address);
+
+ /* Increment page address to next page */
+ pFlash.Address += FLASH_PAGE_SIZE;
+ addresstmp = pFlash.Address;
+
+ /* Operation is completed, disable the PER Bit */
+ CLEAR_BIT(FLASH->CR2, FLASH_CR2_PER);
+
+ FLASH_PageErase(addresstmp);
+ }
+ else
+ {
+ /*No more pages to Erase*/
+
+ /*Reset Address and stop Erase pages procedure*/
+ pFlash.Address = 0xFFFFFFFF;
+ pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
+
+ /* FLASH EOP interrupt user callback */
+ HAL_FLASH_EndOfOperationCallback(pFlash.Address);
+ }
+ }
+ else if(pFlash.ProcedureOnGoing == FLASH_PROC_MASSERASE)
+ {
+ /* Operation is completed, disable the MER Bit */
+ CLEAR_BIT(FLASH->CR2, FLASH_CR2_MER);
+
+ if (HAL_IS_BIT_CLR(FLASH->CR, FLASH_CR_MER))
+ {
+ /* MassErase ended. Return the selected bank*/
+ /* FLASH EOP interrupt user callback */
+ HAL_FLASH_EndOfOperationCallback(0);
+
+ pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
+ }
+ }
+ else
+ {
+ /* Nb of 16-bit data to program can be decreased */
+ pFlash.DataRemaining--;
+
+ /* Check if there are still 16-bit data to program */
+ if(pFlash.DataRemaining != 0)
+ {
+ /* Increment address to 16-bit */
+ pFlash.Address += 2;
+ addresstmp = pFlash.Address;
+
+ /* Shift to have next 16-bit data */
+ pFlash.Data = (pFlash.Data >> 16);
+
+ /* Operation is completed, disable the PG Bit */
+ CLEAR_BIT(FLASH->CR2, FLASH_CR2_PG);
+
+ /*Program halfword (16-bit) at a specified address.*/
+ FLASH_Program_HalfWord(addresstmp, (uint16_t)pFlash.Data);
+ }
+ else
+ {
+ /*Program ended. Return the selected address*/
+ /* FLASH EOP interrupt user callback */
+ if (pFlash.ProcedureOnGoing == FLASH_PROC_PROGRAMHALFWORD)
+ {
+ HAL_FLASH_EndOfOperationCallback(pFlash.Address);
+ }
+ else if (pFlash.ProcedureOnGoing == FLASH_PROC_PROGRAMWORD)
+ {
+ HAL_FLASH_EndOfOperationCallback(pFlash.Address-2);
+ }
+ else
+ {
+ HAL_FLASH_EndOfOperationCallback(pFlash.Address-6);
+ }
+
+ /* Reset Address and stop Program procedure*/
+ pFlash.Address = 0xFFFFFFFF;
+ pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
+ }
+ }
+ }
+ }
+#endif
+
+ if(pFlash.ProcedureOnGoing == FLASH_PROC_NONE)
+ {
+#if defined(FLASH_BANK2_END)
+ /* Operation is completed, disable the PG, PER and MER Bits for both bank */
+ CLEAR_BIT(FLASH->CR, (FLASH_CR_PG | FLASH_CR_PER | FLASH_CR_MER));
+ CLEAR_BIT(FLASH->CR2, (FLASH_CR2_PG | FLASH_CR2_PER | FLASH_CR2_MER));
+
+ /* Disable End of FLASH Operation and Error source interrupts for both banks */
+ __HAL_FLASH_DISABLE_IT(FLASH_IT_EOP_BANK1 | FLASH_IT_ERR_BANK1 | FLASH_IT_EOP_BANK2 | FLASH_IT_ERR_BANK2);
+#else
+ /* Operation is completed, disable the PG, PER and MER Bits */
+ CLEAR_BIT(FLASH->CR, (FLASH_CR_PG | FLASH_CR_PER | FLASH_CR_MER));
+
+ /* Disable End of FLASH Operation and Error source interrupts */
+ __HAL_FLASH_DISABLE_IT(FLASH_IT_EOP | FLASH_IT_ERR);
+#endif /* FLASH_BANK2_END */
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(&pFlash);
+ }
+}
+
+
+/**
+ * @brief FLASH end of operation interrupt callback
+ * @param ReturnValue: The value saved in this parameter depends on the ongoing procedure
+ * - Mass Erase: No return value expected
+ * - Pages Erase: Address of the page which has been erased
+ * (if 0xFFFFFFFF, it means that all the selected pages have been erased)
+ * - Program: Address which was selected for data program
+ * @retval none
+ */
+__weak void HAL_FLASH_EndOfOperationCallback(uint32_t ReturnValue)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(ReturnValue);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_FLASH_EndOfOperationCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief FLASH operation error interrupt callback
+ * @param ReturnValue: The value saved in this parameter depends on the ongoing procedure
+ * - Mass Erase: No return value expected
+ * - Pages Erase: Address of the page which returned an error
+ * - Program: Address which was selected for data program
+ * @retval none
+ */
+__weak void HAL_FLASH_OperationErrorCallback(uint32_t ReturnValue)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(ReturnValue);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_FLASH_OperationErrorCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup FLASH_Exported_Functions_Group2 Peripheral Control functions
+ * @brief management functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Peripheral Control functions #####
+ ===============================================================================
+ [..]
+ This subsection provides a set of functions allowing to control the FLASH
+ memory operations.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Unlock the FLASH control register access
+ * @retval HAL Status
+ */
+HAL_StatusTypeDef HAL_FLASH_Unlock(void)
+{
+ if (HAL_IS_BIT_SET(FLASH->CR, FLASH_CR_LOCK))
+ {
+ /* Authorize the FLASH Registers access */
+ WRITE_REG(FLASH->KEYR, FLASH_KEY1);
+ WRITE_REG(FLASH->KEYR, FLASH_KEY2);
+ }
+ else
+ {
+ return HAL_ERROR;
+ }
+
+#if defined(FLASH_BANK2_END)
+ if (HAL_IS_BIT_SET(FLASH->CR2, FLASH_CR2_LOCK))
+ {
+ /* Authorize the FLASH BANK2 Registers access */
+ WRITE_REG(FLASH->KEYR2, FLASH_KEY1);
+ WRITE_REG(FLASH->KEYR2, FLASH_KEY2);
+ }
+ else
+ {
+ return HAL_ERROR;
+ }
+
+#endif /* FLASH_BANK2_END */
+ return HAL_OK;
+}
+
+/**
+ * @brief Locks the FLASH control register access
+ * @retval HAL Status
+ */
+HAL_StatusTypeDef HAL_FLASH_Lock(void)
+{
+ /* Set the LOCK Bit to lock the FLASH Registers access */
+ SET_BIT(FLASH->CR, FLASH_CR_LOCK);
+
+#if defined(FLASH_BANK2_END)
+ /* Set the LOCK Bit to lock the FLASH BANK2 Registers access */
+ SET_BIT(FLASH->CR2, FLASH_CR2_LOCK);
+#endif /* FLASH_BANK2_END */
+
+ return HAL_OK;
+}
+
+
+/**
+ * @brief Unlock the FLASH Option Control Registers access.
+ * @retval HAL Status
+ */
+HAL_StatusTypeDef HAL_FLASH_OB_Unlock(void)
+{
+ if (HAL_IS_BIT_CLR(FLASH->CR, FLASH_CR_OPTWRE))
+ {
+ /* Authorizes the Option Byte register programming */
+ WRITE_REG(FLASH->OPTKEYR, FLASH_OPTKEY1);
+ WRITE_REG(FLASH->OPTKEYR, FLASH_OPTKEY2);
+ }
+ else
+ {
+ return HAL_ERROR;
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Lock the FLASH Option Control Registers access.
+ * @retval HAL Status
+ */
+HAL_StatusTypeDef HAL_FLASH_OB_Lock(void)
+{
+ /* Clear the OPTWRE Bit to lock the FLASH Option Byte Registers access */
+ CLEAR_BIT(FLASH->CR, FLASH_CR_OPTWRE);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Launch the option byte loading.
+ * @note This function will reset automatically the MCU.
+ * @retval HAL_StatusTypeDef HAL Status
+ */
+HAL_StatusTypeDef HAL_FLASH_OB_Launch(void)
+{
+ /* Initiates a system reset request to launch the option byte loading */
+ HAL_NVIC_SystemReset();
+
+ return HAL_OK;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup FLASH_Exported_Functions_Group3 Peripheral State functions
+ * @brief Peripheral State functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Peripheral State functions #####
+ ===============================================================================
+ [..]
+ This subsection permit to get in run-time the status of the FLASH peripheral.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Get the specific FLASH error flag.
+ * @retval FLASH_ErrorCode: The returned value can be:
+ * @ref FLASH_Error_Codes
+ */
+uint32_t HAL_FLASH_GetError(void)
+{
+ return pFlash.ErrorCode;
+}
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/** @addtogroup FLASH_Private_Functions
+ * @{
+ */
+
+/**
+ * @brief Program a half-word (16-bit) at a specified address.
+ * @param Address: specifies the address to be programmed.
+ * @param Data: specifies the data to be programmed.
+ * @retval None
+ */
+static void FLASH_Program_HalfWord(uint32_t Address, uint16_t Data)
+{
+ /* Clean the error context */
+ pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
+
+#if defined(FLASH_BANK2_END)
+ if(Address <= FLASH_BANK1_END)
+ {
+#endif /* FLASH_BANK2_END */
+ /* Proceed to program the new data */
+ SET_BIT(FLASH->CR, FLASH_CR_PG);
+#if defined(FLASH_BANK2_END)
+ }
+ else
+ {
+ /* Proceed to program the new data */
+ SET_BIT(FLASH->CR2, FLASH_CR2_PG);
+ }
+#endif /* FLASH_BANK2_END */
+
+ /* Write data in the address */
+ *(__IO uint16_t*)Address = Data;
+}
+
+/**
+ * @brief Wait for a FLASH operation to complete.
+ * @param Timeout: maximum flash operation timeout
+ * @retval HAL_StatusTypeDef HAL Status
+ */
+HAL_StatusTypeDef FLASH_WaitForLastOperation(uint32_t Timeout)
+{
+ /* Wait for the FLASH operation to complete by polling on BUSY flag to be reset.
+ Even if the FLASH operation fails, the BUSY flag will be reset and an error
+ flag will be set */
+
+ uint32_t tickstart = HAL_GetTick();
+
+ while(__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY))
+ {
+ if (Timeout != HAL_MAX_DELAY)
+ {
+ if((Timeout == 0) || ((HAL_GetTick()-tickstart) > Timeout))
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+
+ /* Check FLASH End of Operation flag */
+ if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP))
+ {
+ /* Clear FLASH End of Operation pending bit */
+ __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP);
+ }
+
+ if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR) ||
+ __HAL_FLASH_GET_FLAG(FLASH_FLAG_OPTVERR) ||
+ __HAL_FLASH_GET_FLAG(FLASH_FLAG_PGERR))
+ {
+ /*Save the error code*/
+ FLASH_SetErrorCode();
+ return HAL_ERROR;
+ }
+
+ /* If there is no error flag set */
+ return HAL_OK;
+}
+
+#if defined(FLASH_BANK2_END)
+/**
+ * @brief Wait for a FLASH BANK2 operation to complete.
+ * @param Timeout: maximum flash operation timeout
+ * @retval HAL_StatusTypeDef HAL Status
+ */
+HAL_StatusTypeDef FLASH_WaitForLastOperationBank2(uint32_t Timeout)
+{
+ /* Wait for the FLASH BANK2 operation to complete by polling on BUSY flag to be reset.
+ Even if the FLASH BANK2 operation fails, the BUSY flag will be reset and an error
+ flag will be set */
+
+ uint32_t tickstart = HAL_GetTick();
+
+ while(__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY_BANK2))
+ {
+ if (Timeout != HAL_MAX_DELAY)
+ {
+ if((Timeout == 0) || ((HAL_GetTick()-tickstart) > Timeout))
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+
+ /* Check FLASH End of Operation flag */
+ if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP_BANK2))
+ {
+ /* Clear FLASH End of Operation pending bit */
+ __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP_BANK2);
+ }
+
+ if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR_BANK2) || __HAL_FLASH_GET_FLAG(FLASH_FLAG_PGERR_BANK2))
+ {
+ /*Save the error code*/
+ FLASH_SetErrorCode();
+ return HAL_ERROR;
+ }
+
+ /* If there is an error flag set */
+ return HAL_OK;
+
+}
+#endif /* FLASH_BANK2_END */
+
+/**
+ * @brief Set the specific FLASH error flag.
+ * @retval None
+ */
+static void FLASH_SetErrorCode(void)
+{
+#if defined(FLASH_BANK2_END)
+ if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR) || __HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR_BANK2))
+#else
+ if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR))
+#endif /* FLASH_BANK2_END */
+ {
+ pFlash.ErrorCode |= HAL_FLASH_ERROR_WRP;
+ }
+#if defined(FLASH_BANK2_END)
+ if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGERR) || __HAL_FLASH_GET_FLAG(FLASH_FLAG_PGERR_BANK2))
+#else
+ if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGERR))
+#endif /* FLASH_BANK2_END */
+ {
+ pFlash.ErrorCode |= HAL_FLASH_ERROR_PROG;
+ }
+
+ if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_OPTVERR))
+ {
+ pFlash.ErrorCode |= HAL_FLASH_ERROR_OPTV;
+ __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPTVERR);
+ }
+
+ /* Clear FLASH error pending bits */
+#if defined(FLASH_BANK2_END)
+ __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_WRPERR | FLASH_FLAG_WRPERR_BANK2 | FLASH_FLAG_PGERR | FLASH_FLAG_PGERR_BANK2);
+#else
+ __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_WRPERR | FLASH_FLAG_PGERR);
+#endif /* FLASH_BANK2_END */
+}
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* HAL_FLASH_MODULE_ENABLED */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/bsp/radio-controller-1/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_flash_ex.c b/bsp/radio-controller-1/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_flash_ex.c
new file mode 100644
index 0000000..0416efe
--- /dev/null
+++ b/bsp/radio-controller-1/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_flash_ex.c
@@ -0,0 +1,1140 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_flash_ex.c
+ * @author MCD Application Team
+ * @version V1.0.4
+ * @date 29-April-2016
+ * @brief Extended FLASH HAL module driver.
+ *
+ * This file provides firmware functions to manage the following
+ * functionalities of the FLASH peripheral:
+ * + Extended Initialization/de-initialization functions
+ * + Extended I/O operation functions
+ * + Extended Peripheral Control functions
+ *
+ @verbatim
+ ==============================================================================
+ ##### Flash peripheral extended features #####
+ ==============================================================================
+
+ ##### How to use this driver #####
+ ==============================================================================
+ [..] This driver provides functions to configure and program the FLASH memory
+ of all STM32F1xxx devices. It includes
+
+ (++) Set/Reset the write protection
+ (++) Program the user Option Bytes
+ (++) Get the Read protection Level
+
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+#ifdef HAL_FLASH_MODULE_ENABLED
+
+/** @addtogroup FLASH
+ * @{
+ */
+/** @addtogroup FLASH_Private_Variables
+ * @{
+ */
+/* Variables used for Erase pages under interruption*/
+extern FLASH_ProcessTypeDef pFlash;
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup FLASHEx FLASHEx
+ * @brief FLASH HAL Extension module driver
+ * @{
+ */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/** @defgroup FLASHEx_Private_Constants FLASHEx Private Constants
+ * @{
+ */
+#define FLASH_POSITION_IWDGSW_BIT (uint32_t)POSITION_VAL(FLASH_OBR_IWDG_SW)
+#define FLASH_POSITION_OB_USERDATA0_BIT (uint32_t)POSITION_VAL(FLASH_OBR_DATA0)
+#define FLASH_POSITION_OB_USERDATA1_BIT (uint32_t)POSITION_VAL(FLASH_OBR_DATA1)
+/**
+ * @}
+ */
+
+/* Private macro -------------------------------------------------------------*/
+/** @defgroup FLASHEx_Private_Macros FLASHEx Private Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/** @defgroup FLASHEx_Private_Functions FLASHEx Private Functions
+ * @{
+ */
+/* Erase operations */
+static void FLASH_MassErase(uint32_t Banks);
+
+/* Option bytes control */
+static HAL_StatusTypeDef FLASH_OB_EnableWRP(uint32_t WriteProtectPage);
+static HAL_StatusTypeDef FLASH_OB_DisableWRP(uint32_t WriteProtectPage);
+static HAL_StatusTypeDef FLASH_OB_RDP_LevelConfig(uint8_t ReadProtectLevel);
+static HAL_StatusTypeDef FLASH_OB_UserConfig(uint8_t UserConfig);
+static HAL_StatusTypeDef FLASH_OB_ProgramData(uint32_t Address, uint8_t Data);
+static uint32_t FLASH_OB_GetWRP(void);
+static uint32_t FLASH_OB_GetRDP(void);
+static uint8_t FLASH_OB_GetUser(void);
+
+/**
+ * @}
+ */
+
+/* Exported functions ---------------------------------------------------------*/
+/** @defgroup FLASHEx_Exported_Functions FLASHEx Exported Functions
+ * @{
+ */
+
+/** @defgroup FLASHEx_Exported_Functions_Group1 FLASHEx Memory Erasing functions
+ * @brief FLASH Memory Erasing functions
+ *
+@verbatim
+ ==============================================================================
+ ##### FLASH Erasing Programming functions #####
+ ==============================================================================
+
+ [..] The FLASH Memory Erasing functions, includes the following functions:
+ (+) @ref HAL_FLASHEx_Erase: return only when erase has been done
+ (+) @ref HAL_FLASHEx_Erase_IT: end of erase is done when @ref HAL_FLASH_EndOfOperationCallback
+ is called with parameter 0xFFFFFFFF
+
+ [..] Any operation of erase should follow these steps:
+ (#) Call the @ref HAL_FLASH_Unlock() function to enable the flash control register and
+ program memory access.
+ (#) Call the desired function to erase page.
+ (#) Call the @ref HAL_FLASH_Lock() to disable the flash program memory access
+ (recommended to protect the FLASH memory against possible unwanted operation).
+
+@endverbatim
+ * @{
+ */
+
+
+/**
+ * @brief Perform a mass erase or erase the specified FLASH memory pages
+ * @note To correctly run this function, the @ref HAL_FLASH_Unlock() function
+ * must be called before.
+ * Call the @ref HAL_FLASH_Lock() to disable the flash memory access
+ * (recommended to protect the FLASH memory against possible unwanted operation)
+ * @param[in] pEraseInit pointer to an FLASH_EraseInitTypeDef structure that
+ * contains the configuration information for the erasing.
+ *
+ * @param[out] PageError pointer to variable that
+ * contains the configuration information on faulty page in case of error
+ * (0xFFFFFFFF means that all the pages have been correctly erased)
+ *
+ * @retval HAL_StatusTypeDef HAL Status
+ */
+HAL_StatusTypeDef HAL_FLASHEx_Erase(FLASH_EraseInitTypeDef *pEraseInit, uint32_t *PageError)
+{
+ HAL_StatusTypeDef status = HAL_ERROR;
+ uint32_t address = 0;
+
+ /* Process Locked */
+ __HAL_LOCK(&pFlash);
+
+ /* Check the parameters */
+ assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase));
+
+ if (pEraseInit->TypeErase == FLASH_TYPEERASE_MASSERASE)
+ {
+#if defined(FLASH_BANK2_END)
+ if (pEraseInit->Banks == FLASH_BANK_BOTH)
+ {
+ /* Mass Erase requested for Bank1 and Bank2 */
+ /* Wait for last operation to be completed */
+ if ((FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE) == HAL_OK) && \
+ (FLASH_WaitForLastOperationBank2((uint32_t)FLASH_TIMEOUT_VALUE) == HAL_OK))
+ {
+ /*Mass erase to be done*/
+ FLASH_MassErase(FLASH_BANK_BOTH);
+
+ /* Wait for last operation to be completed */
+ if ((FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE) == HAL_OK) && \
+ (FLASH_WaitForLastOperationBank2((uint32_t)FLASH_TIMEOUT_VALUE) == HAL_OK))
+ {
+ status = HAL_OK;
+ }
+
+ /* If the erase operation is completed, disable the MER Bit */
+ CLEAR_BIT(FLASH->CR, FLASH_CR_MER);
+ CLEAR_BIT(FLASH->CR2, FLASH_CR2_MER);
+ }
+ }
+ else if (pEraseInit->Banks == FLASH_BANK_2)
+ {
+ /* Mass Erase requested for Bank2 */
+ /* Wait for last operation to be completed */
+ if (FLASH_WaitForLastOperationBank2((uint32_t)FLASH_TIMEOUT_VALUE) == HAL_OK)
+ {
+ /*Mass erase to be done*/
+ FLASH_MassErase(FLASH_BANK_2);
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperationBank2((uint32_t)FLASH_TIMEOUT_VALUE);
+
+ /* If the erase operation is completed, disable the MER Bit */
+ CLEAR_BIT(FLASH->CR2, FLASH_CR2_MER);
+ }
+ }
+ else
+#endif /* FLASH_BANK2_END */
+ {
+ /* Mass Erase requested for Bank1 */
+ /* Wait for last operation to be completed */
+ if (FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE) == HAL_OK)
+ {
+ /*Mass erase to be done*/
+ FLASH_MassErase(FLASH_BANK_1);
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
+
+ /* If the erase operation is completed, disable the MER Bit */
+ CLEAR_BIT(FLASH->CR, FLASH_CR_MER);
+ }
+ }
+ }
+ else
+ {
+ /* Page Erase is requested */
+ /* Check the parameters */
+ assert_param(IS_FLASH_PROGRAM_ADDRESS(pEraseInit->PageAddress));
+ assert_param(IS_FLASH_NB_PAGES(pEraseInit->PageAddress, pEraseInit->NbPages));
+
+#if defined(FLASH_BANK2_END)
+ /* Page Erase requested on address located on bank2 */
+ if(pEraseInit->PageAddress > FLASH_BANK1_END)
+ {
+ /* Wait for last operation to be completed */
+ if (FLASH_WaitForLastOperationBank2((uint32_t)FLASH_TIMEOUT_VALUE) == HAL_OK)
+ {
+ /*Initialization of PageError variable*/
+ *PageError = 0xFFFFFFFF;
+
+ /* Erase by page by page to be done*/
+ for(address = pEraseInit->PageAddress;
+ address < (pEraseInit->PageAddress + (pEraseInit->NbPages)*FLASH_PAGE_SIZE);
+ address += FLASH_PAGE_SIZE)
+ {
+ FLASH_PageErase(address);
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperationBank2((uint32_t)FLASH_TIMEOUT_VALUE);
+
+ /* If the erase operation is completed, disable the PER Bit */
+ CLEAR_BIT(FLASH->CR2, FLASH_CR2_PER);
+
+ if (status != HAL_OK)
+ {
+ /* In case of error, stop erase procedure and return the faulty address */
+ *PageError = address;
+ break;
+ }
+ }
+ }
+ }
+ else
+#endif /* FLASH_BANK2_END */
+ {
+ /* Page Erase requested on address located on bank1 */
+ /* Wait for last operation to be completed */
+ if (FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE) == HAL_OK)
+ {
+ /*Initialization of PageError variable*/
+ *PageError = 0xFFFFFFFF;
+
+ /* Erase page by page to be done*/
+ for(address = pEraseInit->PageAddress;
+ address < ((pEraseInit->NbPages * FLASH_PAGE_SIZE) + pEraseInit->PageAddress);
+ address += FLASH_PAGE_SIZE)
+ {
+ FLASH_PageErase(address);
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
+
+ /* If the erase operation is completed, disable the PER Bit */
+ CLEAR_BIT(FLASH->CR, FLASH_CR_PER);
+
+ if (status != HAL_OK)
+ {
+ /* In case of error, stop erase procedure and return the faulty address */
+ *PageError = address;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(&pFlash);
+
+ return status;
+}
+
+/**
+ * @brief Perform a mass erase or erase the specified FLASH memory pages with interrupt enabled
+ * @note To correctly run this function, the @ref HAL_FLASH_Unlock() function
+ * must be called before.
+ * Call the @ref HAL_FLASH_Lock() to disable the flash memory access
+ * (recommended to protect the FLASH memory against possible unwanted operation)
+ * @param pEraseInit pointer to an FLASH_EraseInitTypeDef structure that
+ * contains the configuration information for the erasing.
+ *
+ * @retval HAL_StatusTypeDef HAL Status
+ */
+HAL_StatusTypeDef HAL_FLASHEx_Erase_IT(FLASH_EraseInitTypeDef *pEraseInit)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+
+ /* Process Locked */
+ __HAL_LOCK(&pFlash);
+
+ /* If procedure already ongoing, reject the next one */
+ if (pFlash.ProcedureOnGoing != FLASH_PROC_NONE)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check the parameters */
+ assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase));
+
+ /* Enable End of FLASH Operation and Error source interrupts */
+ __HAL_FLASH_ENABLE_IT(FLASH_IT_EOP | FLASH_IT_ERR);
+
+#if defined(FLASH_BANK2_END)
+ /* Enable End of FLASH Operation and Error source interrupts */
+ __HAL_FLASH_ENABLE_IT(FLASH_IT_EOP_BANK2 | FLASH_IT_ERR_BANK2);
+
+#endif
+ if (pEraseInit->TypeErase == FLASH_TYPEERASE_MASSERASE)
+ {
+ /*Mass erase to be done*/
+ pFlash.ProcedureOnGoing = FLASH_PROC_MASSERASE;
+ FLASH_MassErase(pEraseInit->Banks);
+ }
+ else
+ {
+ /* Erase by page to be done*/
+
+ /* Check the parameters */
+ assert_param(IS_FLASH_PROGRAM_ADDRESS(pEraseInit->PageAddress));
+ assert_param(IS_FLASH_NB_PAGES(pEraseInit->PageAddress, pEraseInit->NbPages));
+
+ pFlash.ProcedureOnGoing = FLASH_PROC_PAGEERASE;
+ pFlash.DataRemaining = pEraseInit->NbPages;
+ pFlash.Address = pEraseInit->PageAddress;
+
+ /*Erase 1st page and wait for IT*/
+ FLASH_PageErase(pEraseInit->PageAddress);
+ }
+
+ return status;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup FLASHEx_Exported_Functions_Group2 Option Bytes Programming functions
+ * @brief Option Bytes Programming functions
+ *
+@verbatim
+ ==============================================================================
+ ##### Option Bytes Programming functions #####
+ ==============================================================================
+ [..]
+ This subsection provides a set of functions allowing to control the FLASH
+ option bytes operations.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Erases the FLASH option bytes.
+ * @note This functions erases all option bytes except the Read protection (RDP).
+ * The function @ref HAL_FLASH_Unlock() should be called before to unlock the FLASH interface
+ * The function @ref HAL_FLASH_OB_Unlock() should be called before to unlock the options bytes
+ * The function @ref HAL_FLASH_OB_Launch() should be called after to force the reload of the options bytes
+ * (system reset will occur)
+ * @retval HAL status
+ */
+
+HAL_StatusTypeDef HAL_FLASHEx_OBErase(void)
+{
+ uint8_t rdptmp = OB_RDP_LEVEL_0;
+ HAL_StatusTypeDef status = HAL_ERROR;
+
+ /* Get the actual read protection Option Byte value */
+ rdptmp = FLASH_OB_GetRDP();
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
+
+ if(status == HAL_OK)
+ {
+ /* Clean the error context */
+ pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
+
+ /* If the previous operation is completed, proceed to erase the option bytes */
+ SET_BIT(FLASH->CR, FLASH_CR_OPTER);
+ SET_BIT(FLASH->CR, FLASH_CR_STRT);
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
+
+ /* If the erase operation is completed, disable the OPTER Bit */
+ CLEAR_BIT(FLASH->CR, FLASH_CR_OPTER);
+
+ if(status == HAL_OK)
+ {
+ /* Restore the last read protection Option Byte value */
+ status = FLASH_OB_RDP_LevelConfig(rdptmp);
+ }
+ }
+
+ /* Return the erase status */
+ return status;
+}
+
+/**
+ * @brief Program option bytes
+ * @note The function @ref HAL_FLASH_Unlock() should be called before to unlock the FLASH interface
+ * The function @ref HAL_FLASH_OB_Unlock() should be called before to unlock the options bytes
+ * The function @ref HAL_FLASH_OB_Launch() should be called after to force the reload of the options bytes
+ * (system reset will occur)
+ *
+ * @param pOBInit pointer to an FLASH_OBInitStruct structure that
+ * contains the configuration information for the programming.
+ *
+ * @retval HAL_StatusTypeDef HAL Status
+ */
+HAL_StatusTypeDef HAL_FLASHEx_OBProgram(FLASH_OBProgramInitTypeDef *pOBInit)
+{
+ HAL_StatusTypeDef status = HAL_ERROR;
+
+ /* Process Locked */
+ __HAL_LOCK(&pFlash);
+
+ /* Check the parameters */
+ assert_param(IS_OPTIONBYTE(pOBInit->OptionType));
+
+ /* Write protection configuration */
+ if((pOBInit->OptionType & OPTIONBYTE_WRP) == OPTIONBYTE_WRP)
+ {
+ assert_param(IS_WRPSTATE(pOBInit->WRPState));
+ if (pOBInit->WRPState == OB_WRPSTATE_ENABLE)
+ {
+ /* Enable of Write protection on the selected page */
+ status = FLASH_OB_EnableWRP(pOBInit->WRPPage);
+ }
+ else
+ {
+ /* Disable of Write protection on the selected page */
+ status = FLASH_OB_DisableWRP(pOBInit->WRPPage);
+ }
+ if (status != HAL_OK)
+ {
+ /* Process Unlocked */
+ __HAL_UNLOCK(&pFlash);
+ return status;
+ }
+ }
+
+ /* Read protection configuration */
+ if((pOBInit->OptionType & OPTIONBYTE_RDP) == OPTIONBYTE_RDP)
+ {
+ status = FLASH_OB_RDP_LevelConfig(pOBInit->RDPLevel);
+ if (status != HAL_OK)
+ {
+ /* Process Unlocked */
+ __HAL_UNLOCK(&pFlash);
+ return status;
+ }
+ }
+
+ /* USER configuration */
+ if((pOBInit->OptionType & OPTIONBYTE_USER) == OPTIONBYTE_USER)
+ {
+ status = FLASH_OB_UserConfig(pOBInit->USERConfig);
+ if (status != HAL_OK)
+ {
+ /* Process Unlocked */
+ __HAL_UNLOCK(&pFlash);
+ return status;
+ }
+ }
+
+ /* DATA configuration*/
+ if((pOBInit->OptionType & OPTIONBYTE_DATA) == OPTIONBYTE_DATA)
+ {
+ status = FLASH_OB_ProgramData(pOBInit->DATAAddress, pOBInit->DATAData);
+ if (status != HAL_OK)
+ {
+ /* Process Unlocked */
+ __HAL_UNLOCK(&pFlash);
+ return status;
+ }
+ }
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(&pFlash);
+
+ return status;
+}
+
+/**
+ * @brief Get the Option byte configuration
+ * @param pOBInit pointer to an FLASH_OBInitStruct structure that
+ * contains the configuration information for the programming.
+ *
+ * @retval None
+ */
+void HAL_FLASHEx_OBGetConfig(FLASH_OBProgramInitTypeDef *pOBInit)
+{
+ pOBInit->OptionType = OPTIONBYTE_WRP | OPTIONBYTE_RDP | OPTIONBYTE_USER;
+
+ /*Get WRP*/
+ pOBInit->WRPPage = FLASH_OB_GetWRP();
+
+ /*Get RDP Level*/
+ pOBInit->RDPLevel = FLASH_OB_GetRDP();
+
+ /*Get USER*/
+ pOBInit->USERConfig = FLASH_OB_GetUser();
+}
+
+/**
+ * @brief Get the Option byte user data
+ * @param DATAAdress Address of the option byte DATA
+ * This parameter can be one of the following values:
+ * @arg @ref OB_DATA_ADDRESS_DATA0
+ * @arg @ref OB_DATA_ADDRESS_DATA1
+ * @retval Value programmed in USER data
+ */
+uint32_t HAL_FLASHEx_OBGetUserData(uint32_t DATAAdress)
+{
+ uint32_t value = 0;
+
+ if (DATAAdress == OB_DATA_ADDRESS_DATA0)
+ {
+ /* Get value programmed in OB USER Data0 */
+ value = READ_BIT(FLASH->OBR, FLASH_OBR_DATA0) >> FLASH_POSITION_OB_USERDATA0_BIT;
+ }
+ else
+ {
+ /* Get value programmed in OB USER Data1 */
+ value = READ_BIT(FLASH->OBR, FLASH_OBR_DATA1) >> FLASH_POSITION_OB_USERDATA1_BIT;
+ }
+
+ return value;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/** @addtogroup FLASHEx_Private_Functions
+ * @{
+ */
+
+/**
+ * @brief Full erase of FLASH memory Bank
+ * @param Banks Banks to be erased
+ * This parameter can be one of the following values:
+ * @arg @ref FLASH_BANK_1 Bank1 to be erased
+ @if STM32F101xG
+ * @arg @ref FLASH_BANK_2 Bank2 to be erased
+ * @arg @ref FLASH_BANK_BOTH Bank1 and Bank2 to be erased
+ @endif
+ @if STM32F103xG
+ * @arg @ref FLASH_BANK_2 Bank2 to be erased
+ * @arg @ref FLASH_BANK_BOTH Bank1 and Bank2 to be erased
+ @endif
+ *
+ * @retval None
+ */
+static void FLASH_MassErase(uint32_t Banks)
+{
+ /* Check the parameters */
+ assert_param(IS_FLASH_BANK(Banks));
+
+ /* Clean the error context */
+ pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
+
+#if defined(FLASH_BANK2_END)
+ if(Banks == FLASH_BANK_BOTH)
+ {
+ /* bank1 & bank2 will be erased*/
+ SET_BIT(FLASH->CR, FLASH_CR_MER);
+ SET_BIT(FLASH->CR2, FLASH_CR2_MER);
+ SET_BIT(FLASH->CR, FLASH_CR_STRT);
+ SET_BIT(FLASH->CR2, FLASH_CR2_STRT);
+ }
+ else if(Banks == FLASH_BANK_2)
+ {
+ /*Only bank2 will be erased*/
+ SET_BIT(FLASH->CR2, FLASH_CR2_MER);
+ SET_BIT(FLASH->CR2, FLASH_CR2_STRT);
+ }
+ else
+ {
+#endif /* FLASH_BANK2_END */
+ /* Only bank1 will be erased*/
+ SET_BIT(FLASH->CR, FLASH_CR_MER);
+ SET_BIT(FLASH->CR, FLASH_CR_STRT);
+#if defined(FLASH_BANK2_END)
+ }
+#endif /* FLASH_BANK2_END */
+}
+
+/**
+ * @brief Enable the write protection of the desired pages
+ * @note An option byte erase is done automatically in this function.
+ * @note When the memory read protection level is selected (RDP level = 1),
+ * it is not possible to program or erase the flash page i if
+ * debug features are connected or boot code is executed in RAM, even if nWRPi = 1
+ *
+ * @param WriteProtectPage specifies the page(s) to be write protected.
+ * The value of this parameter depend on device used within the same series
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef FLASH_OB_EnableWRP(uint32_t WriteProtectPage)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+ uint16_t WRP0_Data = 0xFFFF;
+#if defined(FLASH_WRP1_WRP1)
+ uint16_t WRP1_Data = 0xFFFF;
+#endif /* FLASH_WRP1_WRP1 */
+#if defined(FLASH_WRP2_WRP2)
+ uint16_t WRP2_Data = 0xFFFF;
+#endif /* FLASH_WRP2_WRP2 */
+#if defined(FLASH_WRP3_WRP3)
+ uint16_t WRP3_Data = 0xFFFF;
+#endif /* FLASH_WRP3_WRP3 */
+
+ /* Check the parameters */
+ assert_param(IS_OB_WRP(WriteProtectPage));
+
+ /* Get current write protected pages and the new pages to be protected ******/
+ WriteProtectPage = (uint32_t)(~((~FLASH_OB_GetWRP()) | WriteProtectPage));
+
+#if defined(OB_WRP_PAGES0TO15MASK)
+ WRP0_Data = (uint16_t)(WriteProtectPage & OB_WRP_PAGES0TO15MASK);
+#elif defined(OB_WRP_PAGES0TO31MASK)
+ WRP0_Data = (uint16_t)(WriteProtectPage & OB_WRP_PAGES0TO31MASK);
+#endif /* OB_WRP_PAGES0TO31MASK */
+
+#if defined(OB_WRP_PAGES16TO31MASK)
+ WRP1_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES16TO31MASK) >> 8);
+#elif defined(OB_WRP_PAGES32TO63MASK)
+ WRP1_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES32TO63MASK) >> 8);
+#endif /* OB_WRP_PAGES32TO63MASK */
+
+#if defined(OB_WRP_PAGES64TO95MASK)
+ WRP2_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES64TO95MASK) >> 16);
+#endif /* OB_WRP_PAGES64TO95MASK */
+#if defined(OB_WRP_PAGES32TO47MASK)
+ WRP2_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES32TO47MASK) >> 16);
+#endif /* OB_WRP_PAGES32TO47MASK */
+
+#if defined(OB_WRP_PAGES96TO127MASK)
+ WRP3_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES96TO127MASK) >> 24);
+#elif defined(OB_WRP_PAGES48TO255MASK)
+ WRP3_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES48TO255MASK) >> 24);
+#elif defined(OB_WRP_PAGES48TO511MASK)
+ WRP3_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES48TO511MASK) >> 24);
+#elif defined(OB_WRP_PAGES48TO127MASK)
+ WRP3_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES48TO127MASK) >> 24);
+#endif /* OB_WRP_PAGES96TO127MASK */
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
+
+ if(status == HAL_OK)
+ {
+ /* Clean the error context */
+ pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
+
+ /* To be able to write again option byte, need to perform a option byte erase */
+ status = HAL_FLASHEx_OBErase();
+ if (status == HAL_OK)
+ {
+ /* Enable write protection */
+ SET_BIT(FLASH->CR, FLASH_CR_OPTPG);
+
+#if defined(FLASH_WRP0_WRP0)
+ if(WRP0_Data != 0xFF)
+ {
+ OB->WRP0 &= WRP0_Data;
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
+ }
+#endif /* FLASH_WRP0_WRP0 */
+
+#if defined(FLASH_WRP1_WRP1)
+ if((status == HAL_OK) && (WRP1_Data != 0xFF))
+ {
+ OB->WRP1 &= WRP1_Data;
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
+ }
+#endif /* FLASH_WRP1_WRP1 */
+
+#if defined(FLASH_WRP2_WRP2)
+ if((status == HAL_OK) && (WRP2_Data != 0xFF))
+ {
+ OB->WRP2 &= WRP2_Data;
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
+ }
+#endif /* FLASH_WRP2_WRP2 */
+
+#if defined(FLASH_WRP3_WRP3)
+ if((status == HAL_OK) && (WRP3_Data != 0xFF))
+ {
+ OB->WRP3 &= WRP3_Data;
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
+ }
+#endif /* FLASH_WRP3_WRP3 */
+
+ /* if the program operation is completed, disable the OPTPG Bit */
+ CLEAR_BIT(FLASH->CR, FLASH_CR_OPTPG);
+ }
+ }
+
+ return status;
+}
+
+/**
+ * @brief Disable the write protection of the desired pages
+ * @note An option byte erase is done automatically in this function.
+ * @note When the memory read protection level is selected (RDP level = 1),
+ * it is not possible to program or erase the flash page i if
+ * debug features are connected or boot code is executed in RAM, even if nWRPi = 1
+ *
+ * @param WriteProtectPage specifies the page(s) to be write unprotected.
+ * The value of this parameter depend on device used within the same series
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef FLASH_OB_DisableWRP(uint32_t WriteProtectPage)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+ uint16_t WRP0_Data = 0xFFFF;
+#if defined(FLASH_WRP1_WRP1)
+ uint16_t WRP1_Data = 0xFFFF;
+#endif /* FLASH_WRP1_WRP1 */
+#if defined(FLASH_WRP2_WRP2)
+ uint16_t WRP2_Data = 0xFFFF;
+#endif /* FLASH_WRP2_WRP2 */
+#if defined(FLASH_WRP3_WRP3)
+ uint16_t WRP3_Data = 0xFFFF;
+#endif /* FLASH_WRP3_WRP3 */
+
+ /* Check the parameters */
+ assert_param(IS_OB_WRP(WriteProtectPage));
+
+ /* Get current write protected pages and the new pages to be unprotected ******/
+ WriteProtectPage = (FLASH_OB_GetWRP() | WriteProtectPage);
+
+#if defined(OB_WRP_PAGES0TO15MASK)
+ WRP0_Data = (uint16_t)(WriteProtectPage & OB_WRP_PAGES0TO15MASK);
+#elif defined(OB_WRP_PAGES0TO31MASK)
+ WRP0_Data = (uint16_t)(WriteProtectPage & OB_WRP_PAGES0TO31MASK);
+#endif /* OB_WRP_PAGES0TO31MASK */
+
+#if defined(OB_WRP_PAGES16TO31MASK)
+ WRP1_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES16TO31MASK) >> 8);
+#elif defined(OB_WRP_PAGES32TO63MASK)
+ WRP1_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES32TO63MASK) >> 8);
+#endif /* OB_WRP_PAGES32TO63MASK */
+
+#if defined(OB_WRP_PAGES64TO95MASK)
+ WRP2_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES64TO95MASK) >> 16);
+#endif /* OB_WRP_PAGES64TO95MASK */
+#if defined(OB_WRP_PAGES32TO47MASK)
+ WRP2_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES32TO47MASK) >> 16);
+#endif /* OB_WRP_PAGES32TO47MASK */
+
+#if defined(OB_WRP_PAGES96TO127MASK)
+ WRP3_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES96TO127MASK) >> 24);
+#elif defined(OB_WRP_PAGES48TO255MASK)
+ WRP3_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES48TO255MASK) >> 24);
+#elif defined(OB_WRP_PAGES48TO511MASK)
+ WRP3_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES48TO511MASK) >> 24);
+#elif defined(OB_WRP_PAGES48TO127MASK)
+ WRP3_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES48TO127MASK) >> 24);
+#endif /* OB_WRP_PAGES96TO127MASK */
+
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
+
+ if(status == HAL_OK)
+ {
+ /* Clean the error context */
+ pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
+
+ /* To be able to write again option byte, need to perform a option byte erase */
+ status = HAL_FLASHEx_OBErase();
+ if (status == HAL_OK)
+ {
+ SET_BIT(FLASH->CR, FLASH_CR_OPTPG);
+
+#if defined(FLASH_WRP0_WRP0)
+ if(WRP0_Data != 0xFF)
+ {
+ OB->WRP0 |= WRP0_Data;
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
+ }
+#endif /* FLASH_WRP0_WRP0 */
+
+#if defined(FLASH_WRP1_WRP1)
+ if((status == HAL_OK) && (WRP1_Data != 0xFF))
+ {
+ OB->WRP1 |= WRP1_Data;
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
+ }
+#endif /* FLASH_WRP1_WRP1 */
+
+#if defined(FLASH_WRP2_WRP2)
+ if((status == HAL_OK) && (WRP2_Data != 0xFF))
+ {
+ OB->WRP2 |= WRP2_Data;
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
+ }
+#endif /* FLASH_WRP2_WRP2 */
+
+#if defined(FLASH_WRP3_WRP3)
+ if((status == HAL_OK) && (WRP3_Data != 0xFF))
+ {
+ OB->WRP3 |= WRP3_Data;
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
+ }
+#endif /* FLASH_WRP3_WRP3 */
+
+ /* if the program operation is completed, disable the OPTPG Bit */
+ CLEAR_BIT(FLASH->CR, FLASH_CR_OPTPG);
+ }
+ }
+ return status;
+}
+
+/**
+ * @brief Set the read protection level.
+ * @param ReadProtectLevel specifies the read protection level.
+ * This parameter can be one of the following values:
+ * @arg @ref OB_RDP_LEVEL_0 No protection
+ * @arg @ref OB_RDP_LEVEL_1 Read protection of the memory
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef FLASH_OB_RDP_LevelConfig(uint8_t ReadProtectLevel)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+
+ /* Check the parameters */
+ assert_param(IS_OB_RDP_LEVEL(ReadProtectLevel));
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
+
+ if(status == HAL_OK)
+ {
+ /* Clean the error context */
+ pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
+
+ /* If the previous operation is completed, proceed to erase the option bytes */
+ SET_BIT(FLASH->CR, FLASH_CR_OPTER);
+ SET_BIT(FLASH->CR, FLASH_CR_STRT);
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
+
+ /* If the erase operation is completed, disable the OPTER Bit */
+ CLEAR_BIT(FLASH->CR, FLASH_CR_OPTER);
+
+ if(status == HAL_OK)
+ {
+ /* Enable the Option Bytes Programming operation */
+ SET_BIT(FLASH->CR, FLASH_CR_OPTPG);
+
+ WRITE_REG(OB->RDP, ReadProtectLevel);
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
+
+ /* if the program operation is completed, disable the OPTPG Bit */
+ CLEAR_BIT(FLASH->CR, FLASH_CR_OPTPG);
+ }
+ }
+
+ return status;
+}
+
+/**
+ * @brief Program the FLASH User Option Byte.
+ * @note Programming of the OB should be performed only after an erase (otherwise PGERR occurs)
+ * @param UserConfig The FLASH User Option Bytes values FLASH_OBR_IWDG_SW(Bit2),
+ * FLASH_OBR_nRST_STOP(Bit3),FLASH_OBR_nRST_STDBY(Bit4).
+ * And BFBF2(Bit5) for STM32F101xG and STM32F103xG .
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef FLASH_OB_UserConfig(uint8_t UserConfig)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+
+ /* Check the parameters */
+ assert_param(IS_OB_IWDG_SOURCE((UserConfig&OB_IWDG_SW)));
+ assert_param(IS_OB_STOP_SOURCE((UserConfig&OB_STOP_NO_RST)));
+ assert_param(IS_OB_STDBY_SOURCE((UserConfig&OB_STDBY_NO_RST)));
+#if defined(FLASH_BANK2_END)
+ assert_param(IS_OB_BOOT1((UserConfig&OB_BOOT1_SET)));
+#endif /* FLASH_BANK2_END */
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
+
+ if(status == HAL_OK)
+ {
+ /* Clean the error context */
+ pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
+
+ /* Enable the Option Bytes Programming operation */
+ SET_BIT(FLASH->CR, FLASH_CR_OPTPG);
+
+#if defined(FLASH_BANK2_END)
+ OB->USER = (UserConfig | 0xF0);
+#else
+ OB->USER = (UserConfig | 0x88);
+#endif /* FLASH_BANK2_END */
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
+
+ /* if the program operation is completed, disable the OPTPG Bit */
+ CLEAR_BIT(FLASH->CR, FLASH_CR_OPTPG);
+ }
+
+ return status;
+}
+
+/**
+ * @brief Programs a half word at a specified Option Byte Data address.
+ * @note The function @ref HAL_FLASH_Unlock() should be called before to unlock the FLASH interface
+ * The function @ref HAL_FLASH_OB_Unlock() should be called before to unlock the options bytes
+ * The function @ref HAL_FLASH_OB_Launch() should be called after to force the reload of the options bytes
+ * (system reset will occur)
+ * Programming of the OB should be performed only after an erase (otherwise PGERR occurs)
+ * @param Address specifies the address to be programmed.
+ * This parameter can be 0x1FFFF804 or 0x1FFFF806.
+ * @param Data specifies the data to be programmed.
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef FLASH_OB_ProgramData(uint32_t Address, uint8_t Data)
+{
+ HAL_StatusTypeDef status = HAL_ERROR;
+
+ /* Check the parameters */
+ assert_param(IS_OB_DATA_ADDRESS(Address));
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
+
+ if(status == HAL_OK)
+ {
+ /* Clean the error context */
+ pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
+
+ /* Enables the Option Bytes Programming operation */
+ SET_BIT(FLASH->CR, FLASH_CR_OPTPG);
+ *(__IO uint16_t*)Address = Data;
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
+
+ /* If the program operation is completed, disable the OPTPG Bit */
+ CLEAR_BIT(FLASH->CR, FLASH_CR_OPTPG);
+ }
+ /* Return the Option Byte Data Program Status */
+ return status;
+}
+
+/**
+ * @brief Return the FLASH Write Protection Option Bytes value.
+ * @retval The FLASH Write Protection Option Bytes value
+ */
+static uint32_t FLASH_OB_GetWRP(void)
+{
+ /* Return the FLASH write protection Register value */
+ return (uint32_t)(READ_REG(FLASH->WRPR));
+}
+
+/**
+ * @brief Returns the FLASH Read Protection level.
+ * @retval FLASH ReadOut Protection Status:
+ * This parameter can be one of the following values:
+ * @arg @ref OB_RDP_LEVEL_0 No protection
+ * @arg @ref OB_RDP_LEVEL_1 Read protection of the memory
+ */
+static uint32_t FLASH_OB_GetRDP(void)
+{
+ uint32_t readstatus = OB_RDP_LEVEL_0;
+ uint32_t tmp_reg = 0;
+
+ /* Read RDP level bits */
+ tmp_reg = READ_BIT(FLASH->OBR, FLASH_OBR_RDPRT);
+
+ if (tmp_reg == FLASH_OBR_RDPRT)
+ {
+ readstatus = OB_RDP_LEVEL_1;
+ }
+ else
+ {
+ readstatus = OB_RDP_LEVEL_0;
+ }
+
+ return readstatus;
+}
+
+/**
+ * @brief Return the FLASH User Option Byte value.
+ * @retval The FLASH User Option Bytes values: FLASH_OBR_IWDG_SW(Bit2),
+ * FLASH_OBR_nRST_STOP(Bit3),FLASH_OBR_nRST_STDBY(Bit4).
+ * And FLASH_OBR_BFB2(Bit5) for STM32F101xG and STM32F103xG .
+ */
+static uint8_t FLASH_OB_GetUser(void)
+{
+ /* Return the User Option Byte */
+ return (uint8_t)((READ_REG(FLASH->OBR) & FLASH_OBR_USER) >> FLASH_POSITION_IWDGSW_BIT);
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/** @addtogroup FLASH
+ * @{
+ */
+
+/** @addtogroup FLASH_Private_Functions
+ * @{
+ */
+
+/**
+ * @brief Erase the specified FLASH memory page
+ * @param PageAddress FLASH page to erase
+ * The value of this parameter depend on device used within the same series
+ *
+ * @retval None
+ */
+void FLASH_PageErase(uint32_t PageAddress)
+{
+ /* Clean the error context */
+ pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
+
+#if defined(FLASH_BANK2_END)
+ if(PageAddress > FLASH_BANK1_END)
+ {
+ /* Proceed to erase the page */
+ SET_BIT(FLASH->CR2, FLASH_CR2_PER);
+ WRITE_REG(FLASH->AR2, PageAddress);
+ SET_BIT(FLASH->CR2, FLASH_CR2_STRT);
+ }
+ else
+ {
+#endif /* FLASH_BANK2_END */
+ /* Proceed to erase the page */
+ SET_BIT(FLASH->CR, FLASH_CR_PER);
+ WRITE_REG(FLASH->AR, PageAddress);
+ SET_BIT(FLASH->CR, FLASH_CR_STRT);
+#if defined(FLASH_BANK2_END)
+ }
+#endif /* FLASH_BANK2_END */
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* HAL_FLASH_MODULE_ENABLED */
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/bsp/radio-controller-1/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio.c b/bsp/radio-controller-1/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio.c
new file mode 100644
index 0000000..4e7c78a
--- /dev/null
+++ b/bsp/radio-controller-1/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio.c
@@ -0,0 +1,597 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_gpio.c
+ * @author MCD Application Team
+ * @version V1.0.4
+ * @date 29-April-2016
+ * @brief GPIO HAL module driver.
+ * This file provides firmware functions to manage the following
+ * functionalities of the General Purpose Input/Output (GPIO) peripheral:
+ * + Initialization and de-initialization functions
+ * + IO operation functions
+ *
+ @verbatim
+ ==============================================================================
+ ##### GPIO Peripheral features #####
+ ==============================================================================
+ [..]
+ Subject to the specific hardware characteristics of each I/O port listed in the datasheet, each
+ port bit of the General Purpose IO (GPIO) Ports, can be individually configured by software
+ in several modes:
+ (+) Input mode
+ (+) Analog mode
+ (+) Output mode
+ (+) Alternate function mode
+ (+) External interrupt/event lines
+
+ [..]
+ During and just after reset, the alternate functions and external interrupt
+ lines are not active and the I/O ports are configured in input floating mode.
+
+ [..]
+ All GPIO pins have weak internal pull-up and pull-down resistors, which can be
+ activated or not.
+
+ [..]
+ In Output or Alternate mode, each IO can be configured on open-drain or push-pull
+ type and the IO speed can be selected depending on the VDD value.
+
+ [..]
+ All ports have external interrupt/event capability. To use external interrupt
+ lines, the port must be configured in input mode. All available GPIO pins are
+ connected to the 16 external interrupt/event lines from EXTI0 to EXTI15.
+
+ [..]
+ The external interrupt/event controller consists of up to 20 edge detectors in connectivity
+ line devices, or 19 edge detectors in other devices for generating event/interrupt requests.
+ Each input line can be independently configured to select the type (event or interrupt) and
+ the corresponding trigger event (rising or falling or both). Each line can also masked
+ independently. A pending register maintains the status line of the interrupt requests
+
+ ##### How to use this driver #####
+ ==============================================================================
+ [..]
+ (#) Enable the GPIO APB2 clock using the following function : __HAL_RCC_GPIOx_CLK_ENABLE().
+
+ (#) Configure the GPIO pin(s) using HAL_GPIO_Init().
+ (++) Configure the IO mode using "Mode" member from GPIO_InitTypeDef structure
+ (++) Activate Pull-up, Pull-down resistor using "Pull" member from GPIO_InitTypeDef
+ structure.
+ (++) In case of Output or alternate function mode selection: the speed is
+ configured through "Speed" member from GPIO_InitTypeDef structure
+ (++) Analog mode is required when a pin is to be used as ADC channel
+ or DAC output.
+ (++) In case of external interrupt/event selection the "Mode" member from
+ GPIO_InitTypeDef structure select the type (interrupt or event) and
+ the corresponding trigger event (rising or falling or both).
+
+ (#) In case of external interrupt/event mode selection, configure NVIC IRQ priority
+ mapped to the EXTI line using HAL_NVIC_SetPriority() and enable it using
+ HAL_NVIC_EnableIRQ().
+
+ (#) To get the level of a pin configured in input mode use HAL_GPIO_ReadPin().
+
+ (#) To set/reset the level of a pin configured in output mode use
+ HAL_GPIO_WritePin()/HAL_GPIO_TogglePin().
+
+ (#) To lock pin configuration until next reset use HAL_GPIO_LockPin().
+
+ (#) 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 PD0 and PD1, respectively, when the HSE oscillator is off.
+ The HSE has priority over the GPIO function.
+
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+/** @defgroup GPIO GPIO
+ * @brief GPIO HAL module driver
+ * @{
+ */
+
+#ifdef HAL_GPIO_MODULE_ENABLED
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/** @defgroup GPIO_Private_Constants GPIO Private Constants
+ * @{
+ */
+
+#define GPIO_MODE ((uint32_t)0x00000003)
+#define EXTI_MODE ((uint32_t)0x10000000)
+#define GPIO_MODE_IT ((uint32_t)0x00010000)
+#define GPIO_MODE_EVT ((uint32_t)0x00020000)
+#define RISING_EDGE ((uint32_t)0x00100000)
+#define FALLING_EDGE ((uint32_t)0x00200000)
+#define GPIO_OUTPUT_TYPE ((uint32_t)0x00000010)
+#define GPIO_NUMBER ((uint32_t)16)
+
+/* Definitions for bit manipulation of CRL and CRH register */
+#define GPIO_CR_MODE_INPUT ((uint32_t)0x00000000) /*!< 00: Input mode (reset state) */
+#define GPIO_CR_CNF_ANALOG ((uint32_t)0x00000000) /*!< 00: Analog mode */
+#define GPIO_CR_CNF_INPUT_FLOATING ((uint32_t)0x00000004) /*!< 01: Floating input (reset state) */
+#define GPIO_CR_CNF_INPUT_PU_PD ((uint32_t)0x00000008) /*!< 10: Input with pull-up / pull-down */
+#define GPIO_CR_CNF_GP_OUTPUT_PP ((uint32_t)0x00000000) /*!< 00: General purpose output push-pull */
+#define GPIO_CR_CNF_GP_OUTPUT_OD ((uint32_t)0x00000004) /*!< 01: General purpose output Open-drain */
+#define GPIO_CR_CNF_AF_OUTPUT_PP ((uint32_t)0x00000008) /*!< 10: Alternate function output Push-pull */
+#define GPIO_CR_CNF_AF_OUTPUT_OD ((uint32_t)0x0000000C) /*!< 11: Alternate function output Open-drain */
+
+/**
+ * @}
+ */
+
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+/** @defgroup GPIO_Exported_Functions GPIO Exported Functions
+ * @{
+ */
+
+/** @defgroup GPIO_Exported_Functions_Group1 Initialization and deinitialization functions
+ * @brief Initialization and Configuration functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Initialization and deinitialization functions #####
+ ===============================================================================
+ [..]
+ This section provides functions allowing to initialize and de-initialize the GPIOs
+ to be ready for use.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Initializes the GPIOx peripheral according to the specified parameters in the GPIO_Init.
+ * @param GPIOx: where x can be (A..G depending on device used) to select the GPIO peripheral
+ * @param GPIO_Init: pointer to a GPIO_InitTypeDef structure that contains
+ * the configuration information for the specified GPIO peripheral.
+ * @retval None
+ */
+void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init)
+{
+ uint32_t position;
+ uint32_t ioposition = 0x00;
+ uint32_t iocurrent = 0x00;
+ uint32_t temp = 0x00;
+ uint32_t config = 0x00;
+ __IO uint32_t *configregister; /* Store the address of CRL or CRH register based on pin number */
+ uint32_t registeroffset = 0; /* offset used during computation of CNF and MODE bits placement inside CRL or CRH register */
+
+ /* Check the parameters */
+ assert_param(IS_GPIO_ALL_INSTANCE(GPIOx));
+ assert_param(IS_GPIO_PIN(GPIO_Init->Pin));
+ assert_param(IS_GPIO_MODE(GPIO_Init->Mode));
+
+ /* Configure the port pins */
+ for (position = 0; position < GPIO_NUMBER; position++)
+ {
+ /* Get the IO position */
+ ioposition = ((uint32_t)0x01) << position;
+
+ /* Get the current IO position */
+ iocurrent = (uint32_t)(GPIO_Init->Pin) & ioposition;
+
+ if (iocurrent == ioposition)
+ {
+ /* Check the Alternate function parameters */
+ assert_param(IS_GPIO_AF_INSTANCE(GPIOx));
+
+ /* Based on the required mode, filling config variable with MODEy[1:0] and CNFy[3:2] corresponding bits */
+ switch (GPIO_Init->Mode)
+ {
+ /* If we are configuring the pin in OUTPUT push-pull mode */
+ case GPIO_MODE_OUTPUT_PP:
+ /* Check the GPIO speed parameter */
+ assert_param(IS_GPIO_SPEED(GPIO_Init->Speed));
+ config = GPIO_Init->Speed + GPIO_CR_CNF_GP_OUTPUT_PP;
+ break;
+
+ /* If we are configuring the pin in OUTPUT open-drain mode */
+ case GPIO_MODE_OUTPUT_OD:
+ /* Check the GPIO speed parameter */
+ assert_param(IS_GPIO_SPEED(GPIO_Init->Speed));
+ config = GPIO_Init->Speed + GPIO_CR_CNF_GP_OUTPUT_OD;
+ break;
+
+ /* If we are configuring the pin in ALTERNATE FUNCTION push-pull mode */
+ case GPIO_MODE_AF_PP:
+ /* Check the GPIO speed parameter */
+ assert_param(IS_GPIO_SPEED(GPIO_Init->Speed));
+ config = GPIO_Init->Speed + GPIO_CR_CNF_AF_OUTPUT_PP;
+ break;
+
+ /* If we are configuring the pin in ALTERNATE FUNCTION open-drain mode */
+ case GPIO_MODE_AF_OD:
+ /* Check the GPIO speed parameter */
+ assert_param(IS_GPIO_SPEED(GPIO_Init->Speed));
+ config = GPIO_Init->Speed + GPIO_CR_CNF_AF_OUTPUT_OD;
+ break;
+
+ /* If we are configuring the pin in INPUT (also applicable to EVENT and IT mode) */
+ case GPIO_MODE_INPUT:
+ case GPIO_MODE_IT_RISING:
+ case GPIO_MODE_IT_FALLING:
+ case GPIO_MODE_IT_RISING_FALLING:
+ case GPIO_MODE_EVT_RISING:
+ case GPIO_MODE_EVT_FALLING:
+ case GPIO_MODE_EVT_RISING_FALLING:
+ /* Check the GPIO pull parameter */
+ assert_param(IS_GPIO_PULL(GPIO_Init->Pull));
+ if(GPIO_Init->Pull == GPIO_NOPULL)
+ {
+ config = GPIO_CR_MODE_INPUT + GPIO_CR_CNF_INPUT_FLOATING;
+ }
+ else if(GPIO_Init->Pull == GPIO_PULLUP)
+ {
+ config = GPIO_CR_MODE_INPUT + GPIO_CR_CNF_INPUT_PU_PD;
+
+ /* Set the corresponding ODR bit */
+ GPIOx->BSRR = ioposition;
+ }
+ else /* GPIO_PULLDOWN */
+ {
+ config = GPIO_CR_MODE_INPUT + GPIO_CR_CNF_INPUT_PU_PD;
+
+ /* Reset the corresponding ODR bit */
+ GPIOx->BRR = ioposition;
+ }
+ break;
+
+ /* If we are configuring the pin in INPUT analog mode */
+ case GPIO_MODE_ANALOG:
+ config = GPIO_CR_MODE_INPUT + GPIO_CR_CNF_ANALOG;
+ break;
+
+ /* Parameters are checked with assert_param */
+ default:
+ break;
+ }
+
+ /* Check if the current bit belongs to first half or last half of the pin count number
+ in order to address CRH or CRL register*/
+ configregister = (iocurrent < GPIO_PIN_8) ? &GPIOx->CRL : &GPIOx->CRH;
+ registeroffset = (iocurrent < GPIO_PIN_8) ? (position << 2) : ((position - 8) << 2);
+
+ /* Apply the new configuration of the pin to the register */
+ MODIFY_REG((*configregister), ((GPIO_CRL_MODE0 | GPIO_CRL_CNF0) << registeroffset ), (config << registeroffset));
+
+ /*--------------------- EXTI Mode Configuration ------------------------*/
+ /* Configure the External Interrupt or event for the current IO */
+ if((GPIO_Init->Mode & EXTI_MODE) == EXTI_MODE)
+ {
+ /* Enable AFIO Clock */
+ __HAL_RCC_AFIO_CLK_ENABLE();
+ temp = AFIO->EXTICR[position >> 2];
+ CLEAR_BIT(temp, ((uint32_t)0x0F) << (4 * (position & 0x03)));
+ SET_BIT(temp, (GPIO_GET_INDEX(GPIOx)) << (4 * (position & 0x03)));
+ AFIO->EXTICR[position >> 2] = temp;
+
+
+ /* Configure the interrupt mask */
+ if((GPIO_Init->Mode & GPIO_MODE_IT) == GPIO_MODE_IT)
+ {
+ SET_BIT(EXTI->IMR, iocurrent);
+ }
+ else
+ {
+ CLEAR_BIT(EXTI->IMR, iocurrent);
+ }
+
+ /* Configure the event mask */
+ if((GPIO_Init->Mode & GPIO_MODE_EVT) == GPIO_MODE_EVT)
+ {
+ SET_BIT(EXTI->EMR, iocurrent);
+ }
+ else
+ {
+ CLEAR_BIT(EXTI->EMR, iocurrent);
+ }
+
+ /* Enable or disable the rising trigger */
+ if((GPIO_Init->Mode & RISING_EDGE) == RISING_EDGE)
+ {
+ SET_BIT(EXTI->RTSR, iocurrent);
+ }
+ else
+ {
+ CLEAR_BIT(EXTI->RTSR, iocurrent);
+ }
+
+ /* Enable or disable the falling trigger */
+ if((GPIO_Init->Mode & FALLING_EDGE) == FALLING_EDGE)
+ {
+ SET_BIT(EXTI->FTSR, iocurrent);
+ }
+ else
+ {
+ CLEAR_BIT(EXTI->FTSR, iocurrent);
+ }
+ }
+ }
+ }
+}
+
+/**
+ * @brief De-initializes the GPIOx peripheral registers to their default reset values.
+ * @param GPIOx: where x can be (A..G depending on device used) to select the GPIO peripheral
+ * @param GPIO_Pin: specifies the port bit to be written.
+ * This parameter can be one of GPIO_PIN_x where x can be (0..15).
+ * @retval None
+ */
+void HAL_GPIO_DeInit(GPIO_TypeDef *GPIOx, uint32_t GPIO_Pin)
+{
+ uint32_t position = 0x00;
+ uint32_t iocurrent = 0x00;
+ uint32_t tmp = 0x00;
+ __IO uint32_t *configregister; /* Store the address of CRL or CRH register based on pin number */
+ uint32_t registeroffset = 0;
+
+ /* Check the parameters */
+ assert_param(IS_GPIO_ALL_INSTANCE(GPIOx));
+ assert_param(IS_GPIO_PIN(GPIO_Pin));
+
+ /* Configure the port pins */
+ while ((GPIO_Pin >> position) != 0)
+ {
+ /* Get current io position */
+ iocurrent = (GPIO_Pin) & ((uint32_t)1 << position);
+
+ if (iocurrent)
+ {
+ /*------------------------- GPIO Mode Configuration --------------------*/
+ /* Check if the current bit belongs to first half or last half of the pin count number
+ in order to address CRH or CRL register */
+ configregister = (iocurrent < GPIO_PIN_8) ? &GPIOx->CRL : &GPIOx->CRH;
+ registeroffset = (iocurrent < GPIO_PIN_8) ? (position << 2) : ((position - 8) << 2);
+
+ /* CRL/CRH default value is floating input(0x04) shifted to correct position */
+ MODIFY_REG(*configregister, ((GPIO_CRL_MODE0 | GPIO_CRL_CNF0) << registeroffset ), GPIO_CRL_CNF0_0 << registeroffset);
+
+ /* ODR default value is 0 */
+ CLEAR_BIT(GPIOx->ODR, iocurrent);
+
+ /*------------------------- EXTI Mode Configuration --------------------*/
+ /* Clear the External Interrupt or Event for the current IO */
+
+ tmp = AFIO->EXTICR[position >> 2];
+ tmp &= (((uint32_t)0x0F) << (4 * (position & 0x03)));
+ if(tmp == (GPIO_GET_INDEX(GPIOx) << (4 * (position & 0x03))))
+ {
+ tmp = ((uint32_t)0x0F) << (4 * (position & 0x03));
+ CLEAR_BIT(AFIO->EXTICR[position >> 2], tmp);
+
+ /* Clear EXTI line configuration */
+ CLEAR_BIT(EXTI->IMR, (uint32_t)iocurrent);
+ CLEAR_BIT(EXTI->EMR, (uint32_t)iocurrent);
+
+ /* Clear Rising Falling edge configuration */
+ CLEAR_BIT(EXTI->RTSR, (uint32_t)iocurrent);
+ CLEAR_BIT(EXTI->FTSR, (uint32_t)iocurrent);
+ }
+ }
+
+ position++;
+ }
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup GPIO_Exported_Functions_Group2 IO operation functions
+ * @brief GPIO Read and Write
+ *
+@verbatim
+ ===============================================================================
+ ##### IO operation functions #####
+ ===============================================================================
+ [..]
+ This subsection provides a set of functions allowing to manage the GPIOs.
+
+@endverbatim
+ * @{
+ */
+/**
+ * @brief Reads the specified input port pin.
+ * @param GPIOx: where x can be (A..G depending on device used) to select the GPIO peripheral
+ * @param GPIO_Pin: specifies the port bit to read.
+ * This parameter can be GPIO_PIN_x where x can be (0..15).
+ * @retval The input port pin value.
+ */
+GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
+{
+ GPIO_PinState bitstatus;
+
+ /* Check the parameters */
+ assert_param(IS_GPIO_PIN(GPIO_Pin));
+
+ if ((GPIOx->IDR & GPIO_Pin) != (uint32_t)GPIO_PIN_RESET)
+ {
+ bitstatus = GPIO_PIN_SET;
+ }
+ else
+ {
+ bitstatus = GPIO_PIN_RESET;
+ }
+ return bitstatus;
+}
+
+/**
+ * @brief Sets or clears the selected data port bit.
+ *
+ * @note This function uses GPIOx_BSRR register to allow atomic read/modify
+ * accesses. In this way, there is no risk of an IRQ occurring between
+ * the read and the modify access.
+ *
+ * @param GPIOx: where x can be (A..G depending on device used) to select the GPIO peripheral
+ * @param GPIO_Pin: specifies the port bit to be written.
+ * This parameter can be one of GPIO_PIN_x where x can be (0..15).
+ * @param PinState: specifies the value to be written to the selected bit.
+ * This parameter can be one of the GPIO_PinState enum values:
+ * @arg GPIO_BIT_RESET: to clear the port pin
+ * @arg GPIO_BIT_SET: to set the port pin
+ * @retval None
+ */
+void HAL_GPIO_WritePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState)
+{
+ /* Check the parameters */
+ assert_param(IS_GPIO_PIN(GPIO_Pin));
+ assert_param(IS_GPIO_PIN_ACTION(PinState));
+
+ if(PinState != GPIO_PIN_RESET)
+ {
+ GPIOx->BSRR = GPIO_Pin;
+ }
+ else
+ {
+ GPIOx->BSRR = (uint32_t)GPIO_Pin << 16;
+ }
+}
+
+/**
+ * @brief Toggles the specified GPIO pin
+ * @param GPIOx: where x can be (A..G depending on device used) to select the GPIO peripheral
+ * @param GPIO_Pin: Specifies the pins to be toggled.
+ * @retval None
+ */
+void HAL_GPIO_TogglePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
+{
+ /* Check the parameters */
+ assert_param(IS_GPIO_PIN(GPIO_Pin));
+
+ GPIOx->ODR ^= GPIO_Pin;
+}
+
+/**
+* @brief Locks GPIO Pins configuration registers.
+* @note The locking mechanism allows the IO configuration to be frozen. When the LOCK sequence
+* has been applied on a port bit, it is no longer possible to modify the value of the port bit until
+* the next reset.
+* @param GPIOx: where x can be (A..G depending on device used) to select the GPIO peripheral
+* @param GPIO_Pin: specifies the port bit to be locked.
+* This parameter can be any combination of GPIO_Pin_x where x can be (0..15).
+* @retval None
+*/
+HAL_StatusTypeDef HAL_GPIO_LockPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
+{
+ __IO uint32_t tmp = GPIO_LCKR_LCKK;
+
+ /* Check the parameters */
+ assert_param(IS_GPIO_LOCK_INSTANCE(GPIOx));
+ assert_param(IS_GPIO_PIN(GPIO_Pin));
+
+ /* Apply lock key write sequence */
+ SET_BIT(tmp, GPIO_Pin);
+ /* Set LCKx bit(s): LCKK='1' + LCK[15-0] */
+ GPIOx->LCKR = tmp;
+ /* Reset LCKx bit(s): LCKK='0' + LCK[15-0] */
+ GPIOx->LCKR = GPIO_Pin;
+ /* Set LCKx bit(s): LCKK='1' + LCK[15-0] */
+ GPIOx->LCKR = tmp;
+ /* Read LCKK bit*/
+ tmp = GPIOx->LCKR;
+
+ if((uint32_t)(GPIOx->LCKR & GPIO_LCKR_LCKK))
+ {
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_ERROR;
+ }
+}
+
+/**
+ * @brief This function handles EXTI interrupt request.
+ * @param GPIO_Pin: Specifies the pins connected EXTI line
+ * @retval None
+ */
+void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)
+{
+ /* EXTI line interrupt detected */
+ if(__HAL_GPIO_EXTI_GET_IT(GPIO_Pin) != RESET)
+ {
+ __HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin);
+ HAL_GPIO_EXTI_Callback(GPIO_Pin);
+ }
+}
+
+/**
+ * @brief EXTI line detection callback
+ * @param GPIO_Pin: Specifies the pins connected EXTI line
+ * @retval None
+ */
+__weak void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(GPIO_Pin);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_GPIO_EXTI_Callback could be implemented in the user file
+ */
+}
+
+/**
+ * @}
+ */
+
+
+/**
+ * @}
+ */
+
+#endif /* HAL_GPIO_MODULE_ENABLED */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/bsp/radio-controller-1/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio_ex.c b/bsp/radio-controller-1/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio_ex.c
new file mode 100644
index 0000000..da0b4a5
--- /dev/null
+++ b/bsp/radio-controller-1/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio_ex.c
@@ -0,0 +1,145 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_gpio_ex.c
+ * @author MCD Application Team
+ * @version V1.0.4
+ * @date 29-April-2016
+ * @brief GPIO Extension HAL module driver.
+ * This file provides firmware functions to manage the following
+ * functionalities of the General Purpose Input/Output (GPIO) extension peripheral.
+ * + Extended features functions
+ *
+ @verbatim
+ ==============================================================================
+ ##### GPIO Peripheral extension features #####
+ ==============================================================================
+ [..] GPIO module on STM32F1 family, manage also the AFIO register:
+ (+) Possibility to use the EVENTOUT Cortex feature
+
+ ##### How to use this driver #####
+ ==============================================================================
+ [..] This driver provides functions to use EVENTOUT Cortex feature
+ (#) Configure EVENTOUT Cortex feature using the function HAL_GPIOEx_ConfigEventout()
+ (#) Activate EVENTOUT Cortex feature using the HAL_GPIOEx_EnableEventout()
+ (#) Deactivate EVENTOUT Cortex feature using the HAL_GPIOEx_DisableEventout()
+
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+/** @defgroup GPIOEx GPIOEx
+ * @brief GPIO HAL module driver
+ * @{
+ */
+
+#ifdef HAL_GPIO_MODULE_ENABLED
+
+/** @defgroup GPIOEx_Exported_Functions GPIOEx Exported Functions
+ * @{
+ */
+
+/** @defgroup GPIOEx_Exported_Functions_Group1 Extended features functions
+ * @brief Extended features functions
+ *
+@verbatim
+ ==============================================================================
+ ##### Extended features functions #####
+ ==============================================================================
+ [..] This section provides functions allowing to:
+ (+) Configure EVENTOUT Cortex feature using the function HAL_GPIOEx_ConfigEventout()
+ (+) Activate EVENTOUT Cortex feature using the HAL_GPIOEx_EnableEventout()
+ (+) Deactivate EVENTOUT Cortex feature using the HAL_GPIOEx_DisableEventout()
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Configures the port and pin on which the EVENTOUT Cortex signal will be connected.
+ * @param GPIO_PortSource Select the port used to output the Cortex EVENTOUT signal.
+ * This parameter can be a value of @ref GPIOEx_EVENTOUT_PORT.
+ * @param GPIO_PinSource Select the pin used to output the Cortex EVENTOUT signal.
+ * This parameter can be a value of @ref GPIOEx_EVENTOUT_PIN.
+ * @retval None
+ */
+void HAL_GPIOEx_ConfigEventout(uint32_t GPIO_PortSource, uint32_t GPIO_PinSource)
+{
+ /* Verify the parameters */
+ assert_param(IS_AFIO_EVENTOUT_PORT(GPIO_PortSource));
+ assert_param(IS_AFIO_EVENTOUT_PIN(GPIO_PinSource));
+
+ /* Apply the new configuration */
+ MODIFY_REG(AFIO->EVCR, (AFIO_EVCR_PORT)|(AFIO_EVCR_PIN), (GPIO_PortSource)|(GPIO_PinSource));
+}
+
+/**
+ * @brief Enables the Event Output.
+ * @retval None
+ */
+void HAL_GPIOEx_EnableEventout(void)
+{
+ SET_BIT(AFIO->EVCR, AFIO_EVCR_EVOE);
+}
+
+/**
+ * @brief Disables the Event Output.
+ * @retval None
+ */
+void HAL_GPIOEx_DisableEventout(void)
+{
+ CLEAR_BIT(AFIO->EVCR, AFIO_EVCR_EVOE);
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* HAL_GPIO_MODULE_ENABLED */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/bsp/radio-controller-1/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pcd.c b/bsp/radio-controller-1/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pcd.c
new file mode 100644
index 0000000..a058955
--- /dev/null
+++ b/bsp/radio-controller-1/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pcd.c
@@ -0,0 +1,1440 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_pcd.c
+ * @author MCD Application Team
+ * @version V1.0.4
+ * @date 29-April-2016
+ * @brief PCD HAL module driver.
+ * This file provides firmware functions to manage the following
+ * functionalities of the USB Peripheral Controller:
+ * + Initialization and de-initialization functions
+ * + IO operation functions
+ * + Peripheral Control functions
+ * + Peripheral State functions
+ *
+ @verbatim
+ ==============================================================================
+ ##### How to use this driver #####
+ ==============================================================================
+ [..]
+ The PCD HAL driver can be used as follows:
+
+ (#) Declare a PCD_HandleTypeDef handle structure, for example:
+ PCD_HandleTypeDef hpcd;
+
+ (#) Fill parameters of Init structure in HCD handle
+
+ (#) Call HAL_PCD_Init() API to initialize the HCD peripheral (Core, Device core, ...)
+
+ (#) Initialize the PCD low level resources through the HAL_PCD_MspInit() API:
+ (##) Enable the PCD/USB Low Level interface clock using the following macro
+ (+++) __HAL_RCC_USB_CLK_ENABLE(); For USB Device FS peripheral available
+ on STM32F102xx and STM32F103xx devices
+ (+++) __HAL_RCC_USB_OTG_FS_CLK_ENABLE(); For USB OTG FS peripheral available
+ on STM32F105xx and STM32F107xx devices
+
+ (##) Initialize the related GPIO clocks
+ (##) Configure PCD pin-out
+ (##) Configure PCD NVIC interrupt
+
+ (#)Associate the Upper USB device stack to the HAL PCD Driver:
+ (##) hpcd.pData = pdev;
+
+ (#)Enable HCD transmission and reception:
+ (##) HAL_PCD_Start();
+
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+
+
+#ifdef HAL_PCD_MODULE_ENABLED
+
+#if defined(STM32F102x6) || defined(STM32F102xB) || \
+ defined(STM32F103x6) || defined(STM32F103xB) || \
+ defined(STM32F103xE) || defined(STM32F103xG) || \
+ defined(STM32F105xC) || defined(STM32F107xC)
+
+/** @defgroup PCD PCD
+ * @brief PCD HAL module driver
+ * @{
+ */
+
+/* Private types -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private constants ---------------------------------------------------------*/
+/* Private macros ------------------------------------------------------------*/
+/** @defgroup PCD_Private_Macros PCD Private Macros
+ * @{
+ */
+#define PCD_MIN(a, b) (((a) < (b)) ? (a) : (b))
+#define PCD_MAX(a, b) (((a) > (b)) ? (a) : (b))
+/**
+ * @}
+ */
+
+/* Private functions ---------------------------------------------------------*/
+/** @defgroup PCD_Private_Functions PCD Private Functions
+ * @{
+ */
+#if defined (USB_OTG_FS)
+static HAL_StatusTypeDef PCD_WriteEmptyTxFifo(PCD_HandleTypeDef *hpcd, uint32_t epnum);
+#endif /* USB_OTG_FS */
+
+#if defined (USB)
+static HAL_StatusTypeDef PCD_EP_ISR_Handler(PCD_HandleTypeDef *hpcd);
+#endif /* USB */
+/**
+ * @}
+ */
+
+/* Exported functions --------------------------------------------------------*/
+/** @defgroup PCD_Exported_Functions PCD Exported Functions
+ * @{
+ */
+
+/** @defgroup PCD_Exported_Functions_Group1 Initialization and de-initialization functions
+ * @brief Initialization and Configuration functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Initialization and de-initialization functions #####
+ ===============================================================================
+ [..] This section provides functions allowing to:
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Initializes the PCD according to the specified
+ * parameters in the PCD_InitTypeDef and create the associated handle.
+ * @param hpcd: PCD handle
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_PCD_Init(PCD_HandleTypeDef *hpcd)
+{
+ uint32_t index = 0;
+
+ /* Check the PCD handle allocation */
+ if(hpcd == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check the parameters */
+ assert_param(IS_PCD_ALL_INSTANCE(hpcd->Instance));
+
+ if(hpcd->State == HAL_PCD_STATE_RESET)
+ {
+ /* Allocate lock resource and initialize it */
+ hpcd->Lock = HAL_UNLOCKED;
+
+ /* Init the low level hardware : GPIO, CLOCK, NVIC... */
+ HAL_PCD_MspInit(hpcd);
+ }
+
+ hpcd->State = HAL_PCD_STATE_BUSY;
+
+ /* Disable the Interrupts */
+ __HAL_PCD_DISABLE(hpcd);
+
+ /*Init the Core (common init.) */
+ USB_CoreInit(hpcd->Instance, hpcd->Init);
+
+ /* Force Device Mode*/
+ USB_SetCurrentMode(hpcd->Instance , USB_DEVICE_MODE);
+
+ /* Init endpoints structures */
+ for (index = 0; index < 15 ; index++)
+ {
+ /* Init ep structure */
+ hpcd->IN_ep[index].is_in = 1;
+ hpcd->IN_ep[index].num = index;
+ hpcd->IN_ep[index].tx_fifo_num = index;
+ /* Control until ep is actvated */
+ hpcd->IN_ep[index].type = EP_TYPE_CTRL;
+ hpcd->IN_ep[index].maxpacket = 0;
+ hpcd->IN_ep[index].xfer_buff = 0;
+ hpcd->IN_ep[index].xfer_len = 0;
+ }
+
+ for (index = 0; index < 15 ; index++)
+ {
+ hpcd->OUT_ep[index].is_in = 0;
+ hpcd->OUT_ep[index].num = index;
+ hpcd->IN_ep[index].tx_fifo_num = index;
+ /* Control until ep is activated */
+ hpcd->OUT_ep[index].type = EP_TYPE_CTRL;
+ hpcd->OUT_ep[index].maxpacket = 0;
+ hpcd->OUT_ep[index].xfer_buff = 0;
+ hpcd->OUT_ep[index].xfer_len = 0;
+ }
+
+ /* Init Device */
+ USB_DevInit(hpcd->Instance, hpcd->Init);
+
+ hpcd->USB_Address = 0;
+ hpcd->State= HAL_PCD_STATE_READY;
+
+ USB_DevDisconnect (hpcd->Instance);
+ return HAL_OK;
+}
+
+/**
+ * @brief DeInitializes the PCD peripheral
+ * @param hpcd: PCD handle
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_PCD_DeInit(PCD_HandleTypeDef *hpcd)
+{
+ /* Check the PCD handle allocation */
+ if(hpcd == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ hpcd->State = HAL_PCD_STATE_BUSY;
+
+ /* Stop Device */
+ HAL_PCD_Stop(hpcd);
+
+ /* DeInit the low level hardware */
+ HAL_PCD_MspDeInit(hpcd);
+
+ hpcd->State = HAL_PCD_STATE_RESET;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Initializes the PCD MSP.
+ * @param hpcd: PCD handle
+ * @retval None
+ */
+__weak void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hpcd);
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_PCD_MspInit could be implemented in the user file
+ */
+}
+
+/**
+ * @brief DeInitializes PCD MSP.
+ * @param hpcd: PCD handle
+ * @retval None
+ */
+__weak void HAL_PCD_MspDeInit(PCD_HandleTypeDef *hpcd)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hpcd);
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_PCD_MspDeInit could be implemented in the user file
+ */
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup PCD_Exported_Functions_Group2 IO operation functions
+ * @brief Data transfers functions
+ *
+@verbatim
+ ===============================================================================
+ ##### IO operation functions #####
+ ===============================================================================
+ [..]
+ This subsection provides a set of functions allowing to manage the PCD data
+ transfers.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Start The USB Device.
+ * @param hpcd: PCD handle
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_PCD_Start(PCD_HandleTypeDef *hpcd)
+{
+ __HAL_LOCK(hpcd);
+ HAL_PCDEx_SetConnectionState (hpcd, 1);
+ USB_DevConnect (hpcd->Instance);
+ __HAL_PCD_ENABLE(hpcd);
+ __HAL_UNLOCK(hpcd);
+ return HAL_OK;
+}
+
+/**
+ * @brief Stop The USB Device.
+ * @param hpcd: PCD handle
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_PCD_Stop(PCD_HandleTypeDef *hpcd)
+{
+ __HAL_LOCK(hpcd);
+ __HAL_PCD_DISABLE(hpcd);
+ USB_StopDevice(hpcd->Instance);
+ USB_DevDisconnect (hpcd->Instance);
+ __HAL_UNLOCK(hpcd);
+ return HAL_OK;
+}
+
+#if defined (USB_OTG_FS)
+/**
+ * @brief This function handles PCD interrupt request.
+ * @param hpcd: PCD handle
+ * @retval HAL status
+ */
+void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd)
+{
+ USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
+ uint32_t index = 0, ep_intr = 0, epint = 0, epnum = 0;
+ uint32_t fifoemptymsk = 0, temp = 0;
+ USB_OTG_EPTypeDef *ep = NULL;
+
+ /* ensure that we are in device mode */
+ if (USB_GetMode(hpcd->Instance) == USB_OTG_MODE_DEVICE)
+ {
+ /* avoid spurious interrupt */
+ if(__HAL_PCD_IS_INVALID_INTERRUPT(hpcd))
+ {
+ return;
+ }
+
+ if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_MMIS))
+ {
+ /* incorrect mode, acknowledge the interrupt */
+ __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_MMIS);
+ }
+
+ if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_OEPINT))
+ {
+ epnum = 0;
+
+ /* Read in the device interrupt bits */
+ ep_intr = USB_ReadDevAllOutEpInterrupt(hpcd->Instance);
+
+ while ( ep_intr )
+ {
+ if (ep_intr & 0x1)
+ {
+ epint = USB_ReadDevOutEPInterrupt(hpcd->Instance, epnum);
+
+ if(( epint & USB_OTG_DOEPINT_XFRC) == USB_OTG_DOEPINT_XFRC)
+ {
+ CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_XFRC);
+
+ HAL_PCD_DataOutStageCallback(hpcd, epnum);
+ }
+
+ if(( epint & USB_OTG_DOEPINT_STUP) == USB_OTG_DOEPINT_STUP)
+ {
+ /* Inform the upper layer that a setup packet is available */
+ HAL_PCD_SetupStageCallback(hpcd);
+ CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STUP);
+ }
+
+ if(( epint & USB_OTG_DOEPINT_OTEPDIS) == USB_OTG_DOEPINT_OTEPDIS)
+ {
+ CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_OTEPDIS);
+ }
+ }
+ epnum++;
+ ep_intr >>= 1;
+ }
+ }
+
+ if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_IEPINT))
+ {
+ /* Read in the device interrupt bits */
+ ep_intr = USB_ReadDevAllInEpInterrupt(hpcd->Instance);
+
+ epnum = 0;
+
+ while ( ep_intr )
+ {
+ if (ep_intr & 0x1) /* In ITR */
+ {
+ epint = USB_ReadDevInEPInterrupt(hpcd->Instance, epnum);
+
+ if(( epint & USB_OTG_DIEPINT_XFRC) == USB_OTG_DIEPINT_XFRC)
+ {
+ fifoemptymsk = 0x1 << epnum;
+ USBx_DEVICE->DIEPEMPMSK &= ~fifoemptymsk;
+
+ CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_XFRC);
+
+ HAL_PCD_DataInStageCallback(hpcd, epnum);
+ }
+ if(( epint & USB_OTG_DIEPINT_TOC) == USB_OTG_DIEPINT_TOC)
+ {
+ CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_TOC);
+ }
+ if(( epint & USB_OTG_DIEPINT_ITTXFE) == USB_OTG_DIEPINT_ITTXFE)
+ {
+ CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_ITTXFE);
+ }
+ if(( epint & USB_OTG_DIEPINT_INEPNE) == USB_OTG_DIEPINT_INEPNE)
+ {
+ CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_INEPNE);
+ }
+ if(( epint & USB_OTG_DIEPINT_EPDISD) == USB_OTG_DIEPINT_EPDISD)
+ {
+ CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_EPDISD);
+ }
+ if(( epint & USB_OTG_DIEPINT_TXFE) == USB_OTG_DIEPINT_TXFE)
+ {
+ PCD_WriteEmptyTxFifo(hpcd , epnum);
+ }
+ }
+ epnum++;
+ ep_intr >>= 1;
+ }
+ }
+
+ /* Handle Resume Interrupt */
+ if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_WKUINT))
+ {
+ /* Clear the Remote Wake-up signalling */
+ USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_RWUSIG;
+
+ HAL_PCD_ResumeCallback(hpcd);
+
+ __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_WKUINT);
+ }
+
+ /* Handle Suspend Interrupt */
+ if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_USBSUSP))
+ {
+ if((USBx_DEVICE->DSTS & USB_OTG_DSTS_SUSPSTS) == USB_OTG_DSTS_SUSPSTS)
+ {
+
+ HAL_PCD_SuspendCallback(hpcd);
+ }
+ __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_USBSUSP);
+ }
+
+ /* Handle Reset Interrupt */
+ if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_USBRST))
+ {
+ USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_RWUSIG;
+ USB_FlushTxFifo(hpcd->Instance , 0 );
+
+ for (index = 0; index < hpcd->Init.dev_endpoints ; index++)
+ {
+ USBx_INEP(index)->DIEPINT = 0xFF;
+ USBx_OUTEP(index)->DOEPINT = 0xFF;
+ }
+ USBx_DEVICE->DAINT = 0xFFFFFFFF;
+ USBx_DEVICE->DAINTMSK |= 0x10001;
+
+ USBx_DEVICE->DOEPMSK |= (USB_OTG_DOEPMSK_STUPM | USB_OTG_DOEPMSK_XFRCM | USB_OTG_DOEPMSK_EPDM);
+ USBx_DEVICE->DIEPMSK |= (USB_OTG_DIEPMSK_TOM | USB_OTG_DIEPMSK_XFRCM | USB_OTG_DIEPMSK_EPDM);
+
+ /* Set Default Address to 0 */
+ USBx_DEVICE->DCFG &= ~USB_OTG_DCFG_DAD;
+
+ /* setup EP0 to receive SETUP packets */
+ USB_EP0_OutStart(hpcd->Instance, (uint8_t *)hpcd->Setup);
+
+ __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_USBRST);
+ }
+
+ /* Handle Enumeration done Interrupt */
+ if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_ENUMDNE))
+ {
+ USB_ActivateSetup(hpcd->Instance);
+ hpcd->Instance->GUSBCFG &= ~USB_OTG_GUSBCFG_TRDT;
+
+ hpcd->Init.speed = USB_OTG_SPEED_FULL;
+ hpcd->Init.ep0_mps = USB_OTG_FS_MAX_PACKET_SIZE ;
+ hpcd->Instance->GUSBCFG |= (uint32_t)((USBD_FS_TRDT_VALUE << 10) & USB_OTG_GUSBCFG_TRDT);
+
+ HAL_PCD_ResetCallback(hpcd);
+
+ __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_ENUMDNE);
+ }
+
+ /* Handle RxQLevel Interrupt */
+ if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_RXFLVL))
+ {
+ USB_MASK_INTERRUPT(hpcd->Instance, USB_OTG_GINTSTS_RXFLVL);
+ temp = USBx->GRXSTSP;
+ ep = &hpcd->OUT_ep[temp & USB_OTG_GRXSTSP_EPNUM];
+
+ if(((temp & USB_OTG_GRXSTSP_PKTSTS) >> 17) == STS_DATA_UPDT)
+ {
+ if((temp & USB_OTG_GRXSTSP_BCNT) != 0)
+ {
+ USB_ReadPacket(USBx, ep->xfer_buff, (temp & USB_OTG_GRXSTSP_BCNT) >> 4);
+ ep->xfer_buff += (temp & USB_OTG_GRXSTSP_BCNT) >> 4;
+ ep->xfer_count += (temp & USB_OTG_GRXSTSP_BCNT) >> 4;
+ }
+ }
+ else if (((temp & USB_OTG_GRXSTSP_PKTSTS) >> 17) == STS_SETUP_UPDT)
+ {
+ USB_ReadPacket(USBx, (uint8_t *)hpcd->Setup, 8);
+ ep->xfer_count += (temp & USB_OTG_GRXSTSP_BCNT) >> 4;
+ }
+ USB_UNMASK_INTERRUPT(hpcd->Instance, USB_OTG_GINTSTS_RXFLVL);
+ }
+
+ /* Handle SOF Interrupt */
+ if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_SOF))
+ {
+ HAL_PCD_SOFCallback(hpcd);
+ __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_SOF);
+ }
+
+ /* Handle Incomplete ISO IN Interrupt */
+ if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_IISOIXFR))
+ {
+ HAL_PCD_ISOINIncompleteCallback(hpcd, epnum);
+ __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_IISOIXFR);
+ }
+
+ /* Handle Incomplete ISO OUT Interrupt */
+ if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT))
+ {
+ HAL_PCD_ISOOUTIncompleteCallback(hpcd, epnum);
+ __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT);
+ }
+
+ /* Handle Connection event Interrupt */
+ if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_SRQINT))
+ {
+ HAL_PCD_ConnectCallback(hpcd);
+ __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_SRQINT);
+ }
+
+ /* Handle Disconnection event Interrupt */
+ if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_OTGINT))
+ {
+ temp = hpcd->Instance->GOTGINT;
+
+ if((temp & USB_OTG_GOTGINT_SEDET) == USB_OTG_GOTGINT_SEDET)
+ {
+ HAL_PCD_DisconnectCallback(hpcd);
+ }
+ hpcd->Instance->GOTGINT |= temp;
+ }
+ }
+}
+#endif /* USB_OTG_FS */
+
+#if defined (USB)
+/**
+ * @brief This function handles PCD interrupt request.
+ * @param hpcd: PCD handle
+ * @retval HAL status
+ */
+void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd)
+{
+ uint32_t wInterrupt_Mask = 0;
+
+ if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_CTR))
+ {
+ /* servicing of the endpoint correct transfer interrupt */
+ /* clear of the CTR flag into the sub */
+ PCD_EP_ISR_Handler(hpcd);
+ }
+
+ if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_RESET))
+ {
+ __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_RESET);
+ HAL_PCD_ResetCallback(hpcd);
+ HAL_PCD_SetAddress(hpcd, 0);
+ }
+
+ if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_PMAOVR))
+ {
+ __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_PMAOVR);
+ }
+ if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_ERR))
+ {
+ __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_ERR);
+ }
+
+ if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_WKUP))
+ {
+ hpcd->Instance->CNTR &= ~(USB_CNTR_LP_MODE);
+
+ /*set wInterrupt_Mask global variable*/
+ wInterrupt_Mask = USB_CNTR_CTRM | USB_CNTR_WKUPM | USB_CNTR_SUSPM | USB_CNTR_ERRM \
+ | USB_CNTR_ESOFM | USB_CNTR_RESETM;
+
+ /*Set interrupt mask*/
+ hpcd->Instance->CNTR = wInterrupt_Mask;
+
+ HAL_PCD_ResumeCallback(hpcd);
+
+ __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_WKUP);
+ }
+
+ if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_SUSP))
+ {
+ /* clear of the ISTR bit must be done after setting of CNTR_FSUSP */
+ __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_SUSP);
+
+ /* Force low-power mode in the macrocell */
+ hpcd->Instance->CNTR |= USB_CNTR_FSUSP;
+ hpcd->Instance->CNTR |= USB_CNTR_LP_MODE;
+ if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_WKUP) == 0)
+ {
+ HAL_PCD_SuspendCallback(hpcd);
+ }
+ }
+
+ if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_SOF))
+ {
+ __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_SOF);
+ HAL_PCD_SOFCallback(hpcd);
+ }
+
+ if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_ESOF))
+ {
+ /* clear ESOF flag in ISTR */
+ __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_ESOF);
+ }
+}
+#endif /* USB */
+
+/**
+ * @brief Data out stage callbacks
+ * @param hpcd: PCD handle
+ * @param epnum: endpoint number
+ * @retval None
+ */
+ __weak void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hpcd);
+ UNUSED(epnum);
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_PCD_DataOutStageCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief Data IN stage callbacks
+ * @param hpcd: PCD handle
+ * @param epnum: endpoint number
+ * @retval None
+ */
+ __weak void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hpcd);
+ UNUSED(epnum);
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_PCD_DataInStageCallback could be implemented in the user file
+ */
+}
+/**
+ * @brief Setup stage callback
+ * @param hpcd: PCD handle
+ * @retval None
+ */
+ __weak void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hpcd);
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_PCD_SetupStageCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief USB Start Of Frame callbacks
+ * @param hpcd: PCD handle
+ * @retval None
+ */
+ __weak void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hpcd);
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_PCD_SOFCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief USB Reset callbacks
+ * @param hpcd: PCD handle
+ * @retval None
+ */
+ __weak void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hpcd);
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_PCD_ResetCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief Suspend event callbacks
+ * @param hpcd: PCD handle
+ * @retval None
+ */
+ __weak void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hpcd);
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_PCD_SuspendCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief Resume event callbacks
+ * @param hpcd: PCD handle
+ * @retval None
+ */
+ __weak void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hpcd);
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_PCD_ResumeCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief Incomplete ISO OUT callbacks
+ * @param hpcd: PCD handle
+ * @param epnum: endpoint number
+ * @retval None
+ */
+ __weak void HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hpcd);
+ UNUSED(epnum);
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_PCD_ISOOUTIncompleteCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief Incomplete ISO IN callbacks
+ * @param hpcd: PCD handle
+ * @param epnum: endpoint number
+ * @retval None
+ */
+ __weak void HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hpcd);
+ UNUSED(epnum);
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_PCD_ISOINIncompleteCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief Connection event callbacks
+ * @param hpcd: PCD handle
+ * @retval None
+ */
+ __weak void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hpcd);
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_PCD_ConnectCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief Disconnection event callbacks
+ * @param hpcd: PCD handle
+ * @retval None
+ */
+ __weak void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hpcd);
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_PCD_DisconnectCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup PCD_Exported_Functions_Group3 Peripheral Control functions
+ * @brief management functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Peripheral Control functions #####
+ ===============================================================================
+ [..]
+ This subsection provides a set of functions allowing to control the PCD data
+ transfers.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Connect the USB device
+ * @param hpcd: PCD handle
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_PCD_DevConnect(PCD_HandleTypeDef *hpcd)
+{
+ __HAL_LOCK(hpcd);
+ HAL_PCDEx_SetConnectionState (hpcd, 1);
+ USB_DevConnect(hpcd->Instance);
+ __HAL_UNLOCK(hpcd);
+ return HAL_OK;
+}
+
+/**
+ * @brief Disconnect the USB device
+ * @param hpcd: PCD handle
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_PCD_DevDisconnect(PCD_HandleTypeDef *hpcd)
+{
+ __HAL_LOCK(hpcd);
+ HAL_PCDEx_SetConnectionState (hpcd, 0);
+ USB_DevDisconnect(hpcd->Instance);
+ __HAL_UNLOCK(hpcd);
+ return HAL_OK;
+}
+
+/**
+ * @brief Set the USB Device address
+ * @param hpcd: PCD handle
+ * @param address: new device address
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_PCD_SetAddress(PCD_HandleTypeDef *hpcd, uint8_t address)
+{
+ __HAL_LOCK(hpcd);
+ hpcd->USB_Address = address;
+ USB_SetDevAddress(hpcd->Instance, address);
+ __HAL_UNLOCK(hpcd);
+ return HAL_OK;
+}
+/**
+ * @brief Open and configure an endpoint
+ * @param hpcd: PCD handle
+ * @param ep_addr: endpoint address
+ * @param ep_mps: endpoint max packet size
+ * @param ep_type: endpoint type
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_PCD_EP_Open(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint16_t ep_mps, uint8_t ep_type)
+{
+ HAL_StatusTypeDef ret = HAL_OK;
+ PCD_EPTypeDef *ep = NULL;
+
+ if ((ep_addr & 0x80) == 0x80)
+ {
+ ep = &hpcd->IN_ep[ep_addr & 0x7F];
+ }
+ else
+ {
+ ep = &hpcd->OUT_ep[ep_addr & 0x7F];
+ }
+ ep->num = ep_addr & 0x7F;
+
+ ep->is_in = (0x80 & ep_addr) != 0;
+ ep->maxpacket = ep_mps;
+ ep->type = ep_type;
+
+ __HAL_LOCK(hpcd);
+ USB_ActivateEndpoint(hpcd->Instance , ep);
+ __HAL_UNLOCK(hpcd);
+ return ret;
+}
+
+/**
+ * @brief Deactivate an endpoint
+ * @param hpcd: PCD handle
+ * @param ep_addr: endpoint address
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_PCD_EP_Close(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
+{
+ PCD_EPTypeDef *ep = NULL;
+
+ if ((ep_addr & 0x80) == 0x80)
+ {
+ ep = &hpcd->IN_ep[ep_addr & 0x7F];
+ }
+ else
+ {
+ ep = &hpcd->OUT_ep[ep_addr & 0x7F];
+ }
+ ep->num = ep_addr & 0x7F;
+
+ ep->is_in = (0x80 & ep_addr) != 0;
+
+ __HAL_LOCK(hpcd);
+ USB_DeactivateEndpoint(hpcd->Instance , ep);
+ __HAL_UNLOCK(hpcd);
+ return HAL_OK;
+}
+
+
+/**
+ * @brief Receive an amount of data
+ * @param hpcd: PCD handle
+ * @param ep_addr: endpoint address
+ * @param pBuf: pointer to the reception buffer
+ * @param len: amount of data to be received
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_PCD_EP_Receive(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len)
+{
+ PCD_EPTypeDef *ep = NULL;
+
+ ep = &hpcd->OUT_ep[ep_addr & 0x7F];
+
+ /*setup and start the Xfer */
+ ep->xfer_buff = pBuf;
+ ep->xfer_len = len;
+ ep->xfer_count = 0;
+ ep->is_in = 0;
+ ep->num = ep_addr & 0x7F;
+
+ __HAL_LOCK(hpcd);
+
+ if ((ep_addr & 0x7F) == 0 )
+ {
+ USB_EP0StartXfer(hpcd->Instance , ep);
+ }
+ else
+ {
+ USB_EPStartXfer(hpcd->Instance , ep);
+ }
+ __HAL_UNLOCK(hpcd);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Get Received Data Size
+ * @param hpcd: PCD handle
+ * @param ep_addr: endpoint address
+ * @retval Data Size
+ */
+uint16_t HAL_PCD_EP_GetRxCount(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
+{
+ return hpcd->OUT_ep[ep_addr & 0x7F].xfer_count;
+}
+/**
+ * @brief Send an amount of data
+ * @param hpcd: PCD handle
+ * @param ep_addr: endpoint address
+ * @param pBuf: pointer to the transmission buffer
+ * @param len: amount of data to be sent
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_PCD_EP_Transmit(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len)
+{
+ PCD_EPTypeDef *ep = NULL;
+
+ ep = &hpcd->IN_ep[ep_addr & 0x7F];
+
+ /*setup and start the Xfer */
+ ep->xfer_buff = pBuf;
+ ep->xfer_len = len;
+ ep->xfer_count = 0;
+ ep->is_in = 1;
+ ep->num = ep_addr & 0x7F;
+
+ __HAL_LOCK(hpcd);
+
+ if ((ep_addr & 0x7F) == 0 )
+ {
+ USB_EP0StartXfer(hpcd->Instance , ep);
+ }
+ else
+ {
+ USB_EPStartXfer(hpcd->Instance , ep);
+ }
+
+ __HAL_UNLOCK(hpcd);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Set a STALL condition over an endpoint
+ * @param hpcd: PCD handle
+ * @param ep_addr: endpoint address
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_PCD_EP_SetStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
+{
+ PCD_EPTypeDef *ep = NULL;
+
+ if ((0x80 & ep_addr) == 0x80)
+ {
+ ep = &hpcd->IN_ep[ep_addr & 0x7F];
+ }
+ else
+ {
+ ep = &hpcd->OUT_ep[ep_addr];
+ }
+
+ ep->is_stall = 1;
+ ep->num = ep_addr & 0x7F;
+ ep->is_in = ((ep_addr & 0x80) == 0x80);
+
+ __HAL_LOCK(hpcd);
+ USB_EPSetStall(hpcd->Instance , ep);
+ if((ep_addr & 0x7F) == 0)
+ {
+ USB_EP0_OutStart(hpcd->Instance, (uint8_t *)hpcd->Setup);
+ }
+ __HAL_UNLOCK(hpcd);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Clear a STALL condition over in an endpoint
+ * @param hpcd: PCD handle
+ * @param ep_addr: endpoint address
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_PCD_EP_ClrStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
+{
+ PCD_EPTypeDef *ep = NULL;
+
+ if ((0x80 & ep_addr) == 0x80)
+ {
+ ep = &hpcd->IN_ep[ep_addr & 0x7F];
+ }
+ else
+ {
+ ep = &hpcd->OUT_ep[ep_addr];
+ }
+
+ ep->is_stall = 0;
+ ep->num = ep_addr & 0x7F;
+ ep->is_in = ((ep_addr & 0x80) == 0x80);
+
+ __HAL_LOCK(hpcd);
+ USB_EPClearStall(hpcd->Instance , ep);
+ __HAL_UNLOCK(hpcd);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Flush an endpoint
+ * @param hpcd: PCD handle
+ * @param ep_addr: endpoint address
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_PCD_EP_Flush(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
+{
+ __HAL_LOCK(hpcd);
+
+ if ((ep_addr & 0x80) == 0x80)
+ {
+ USB_FlushTxFifo(hpcd->Instance, ep_addr & 0x7F);
+ }
+ else
+ {
+ USB_FlushRxFifo(hpcd->Instance);
+ }
+
+ __HAL_UNLOCK(hpcd);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief HAL_PCD_ActivateRemoteWakeup : active remote wakeup signalling
+ * @param hpcd: PCD handle
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_PCD_ActivateRemoteWakeup(PCD_HandleTypeDef *hpcd)
+{
+ return(USB_ActivateRemoteWakeup(hpcd->Instance));
+}
+
+/**
+ * @brief HAL_PCD_DeActivateRemoteWakeup : de-active remote wakeup signalling
+ * @param hpcd: PCD handle
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_PCD_DeActivateRemoteWakeup(PCD_HandleTypeDef *hpcd)
+{
+ return(USB_DeActivateRemoteWakeup(hpcd->Instance));
+}
+/**
+ * @}
+ */
+
+/** @defgroup PCD_Exported_Functions_Group4 Peripheral State functions
+ * @brief Peripheral State functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Peripheral State functions #####
+ ===============================================================================
+ [..]
+ This subsection permits to get in run-time the status of the peripheral
+ and the data flow.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Return the PCD state
+ * @param hpcd: PCD handle
+ * @retval HAL state
+ */
+PCD_StateTypeDef HAL_PCD_GetState(PCD_HandleTypeDef *hpcd)
+{
+ return hpcd->State;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/** @addtogroup PCD_Private_Functions
+ * @{
+ */
+#if defined (USB_OTG_FS)
+/**
+ * @brief DCD_WriteEmptyTxFifo
+ * check FIFO for the next packet to be loaded
+ * @param hpcd: PCD handle
+ * @param epnum : endpoint number
+ * This parameter can be a value from 0 to 15
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef PCD_WriteEmptyTxFifo(PCD_HandleTypeDef *hpcd, uint32_t epnum)
+{
+ USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
+ USB_OTG_EPTypeDef *ep = NULL;
+ int32_t len = 0;
+ uint32_t len32b = 0;
+ uint32_t fifoemptymsk = 0;
+
+ ep = &hpcd->IN_ep[epnum];
+ len = ep->xfer_len - ep->xfer_count;
+
+ if (len > ep->maxpacket)
+ {
+ len = ep->maxpacket;
+ }
+
+ len32b = (len + 3) / 4;
+
+ while ((USBx_INEP(epnum)->DTXFSTS & USB_OTG_DTXFSTS_INEPTFSAV) > len32b &&
+ ep->xfer_count < ep->xfer_len &&
+ ep->xfer_len != 0)
+ {
+ /* Write the FIFO */
+ len = ep->xfer_len - ep->xfer_count;
+
+ if (len > ep->maxpacket)
+ {
+ len = ep->maxpacket;
+ }
+ len32b = (len + 3) / 4;
+
+ USB_WritePacket(USBx, ep->xfer_buff, epnum, len);
+
+ ep->xfer_buff += len;
+ ep->xfer_count += len;
+ }
+
+ if(len <= 0)
+ {
+ fifoemptymsk = 0x1 << epnum;
+ USBx_DEVICE->DIEPEMPMSK &= ~fifoemptymsk;
+
+ }
+
+ return HAL_OK;
+}
+#endif /* USB_OTG_FS */
+
+#if defined (USB)
+/**
+ * @brief This function handles PCD Endpoint interrupt request.
+ * @param hpcd: PCD handle
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef PCD_EP_ISR_Handler(PCD_HandleTypeDef *hpcd)
+{
+ PCD_EPTypeDef *ep = NULL;
+ uint16_t count = 0;
+ uint8_t epindex = 0;
+ __IO uint16_t wIstr = 0;
+ __IO uint16_t wEPVal = 0;
+
+ /* stay in loop while pending interrupts */
+ while (((wIstr = hpcd->Instance->ISTR) & USB_ISTR_CTR) != 0)
+ {
+ /* extract highest priority endpoint number */
+ epindex = (uint8_t)(wIstr & USB_ISTR_EP_ID);
+
+ if (epindex == 0)
+ {
+ /* Decode and service control endpoint interrupt */
+
+ /* DIR bit = origin of the interrupt */
+ if ((wIstr & USB_ISTR_DIR) == 0)
+ {
+ /* DIR = 0 */
+
+ /* DIR = 0 => IN int */
+ /* DIR = 0 implies that (EP_CTR_TX = 1) always */
+ PCD_CLEAR_TX_EP_CTR(hpcd->Instance, PCD_ENDP0);
+ ep = &hpcd->IN_ep[0];
+
+ ep->xfer_count = PCD_GET_EP_TX_CNT(hpcd->Instance, ep->num);
+ ep->xfer_buff += ep->xfer_count;
+
+ /* TX COMPLETE */
+ HAL_PCD_DataInStageCallback(hpcd, 0);
+
+
+ if((hpcd->USB_Address > 0)&& ( ep->xfer_len == 0))
+ {
+ hpcd->Instance->DADDR = (hpcd->USB_Address | USB_DADDR_EF);
+ hpcd->USB_Address = 0;
+ }
+
+ }
+ else
+ {
+ /* DIR = 1 */
+
+ /* DIR = 1 & CTR_RX => SETUP or OUT int */
+ /* DIR = 1 & (CTR_TX | CTR_RX) => 2 int pending */
+ ep = &hpcd->OUT_ep[0];
+ wEPVal = PCD_GET_ENDPOINT(hpcd->Instance, PCD_ENDP0);
+
+ if ((wEPVal & USB_EP_SETUP) != 0)
+ {
+ /* Get SETUP Packet*/
+ ep->xfer_count = PCD_GET_EP_RX_CNT(hpcd->Instance, ep->num);
+ USB_ReadPMA(hpcd->Instance, (uint8_t*)hpcd->Setup ,ep->pmaadress , ep->xfer_count);
+ /* SETUP bit kept frozen while CTR_RX = 1*/
+ PCD_CLEAR_RX_EP_CTR(hpcd->Instance, PCD_ENDP0);
+
+ /* Process SETUP Packet*/
+ HAL_PCD_SetupStageCallback(hpcd);
+ }
+
+ else if ((wEPVal & USB_EP_CTR_RX) != 0)
+ {
+ PCD_CLEAR_RX_EP_CTR(hpcd->Instance, PCD_ENDP0);
+ /* Get Control Data OUT Packet*/
+ ep->xfer_count = PCD_GET_EP_RX_CNT(hpcd->Instance, ep->num);
+
+ if (ep->xfer_count != 0)
+ {
+ USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaadress, ep->xfer_count);
+ ep->xfer_buff+=ep->xfer_count;
+ }
+
+ /* Process Control Data OUT Packet*/
+ HAL_PCD_DataOutStageCallback(hpcd, 0);
+
+ PCD_SET_EP_RX_CNT(hpcd->Instance, PCD_ENDP0, ep->maxpacket);
+ PCD_SET_EP_RX_STATUS(hpcd->Instance, PCD_ENDP0, USB_EP_RX_VALID);
+ }
+ }
+ }
+ else
+ {
+ /* Decode and service non control endpoints interrupt */
+
+ /* process related endpoint register */
+ wEPVal = PCD_GET_ENDPOINT(hpcd->Instance, epindex);
+ if ((wEPVal & USB_EP_CTR_RX) != 0)
+ {
+ /* clear int flag */
+ PCD_CLEAR_RX_EP_CTR(hpcd->Instance, epindex);
+ ep = &hpcd->OUT_ep[epindex];
+
+ /* OUT double Buffering*/
+ if (ep->doublebuffer == 0)
+ {
+ count = PCD_GET_EP_RX_CNT(hpcd->Instance, ep->num);
+ if (count != 0)
+ {
+ USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaadress, count);
+ }
+ }
+ else
+ {
+ if (PCD_GET_ENDPOINT(hpcd->Instance, ep->num) & USB_EP_DTOG_RX)
+ {
+ /*read from endpoint BUF0Addr buffer*/
+ count = PCD_GET_EP_DBUF0_CNT(hpcd->Instance, ep->num);
+ if (count != 0)
+ {
+ USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr0, count);
+ }
+ }
+ else
+ {
+ /*read from endpoint BUF1Addr buffer*/
+ count = PCD_GET_EP_DBUF1_CNT(hpcd->Instance, ep->num);
+ if (count != 0)
+ {
+ USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr1, count);
+ }
+ }
+ PCD_FreeUserBuffer(hpcd->Instance, ep->num, PCD_EP_DBUF_OUT);
+ }
+ /*multi-packet on the NON control OUT endpoint*/
+ ep->xfer_count+=count;
+ ep->xfer_buff+=count;
+
+ if ((ep->xfer_len == 0) || (count < ep->maxpacket))
+ {
+ /* RX COMPLETE */
+ HAL_PCD_DataOutStageCallback(hpcd, ep->num);
+ }
+ else
+ {
+ HAL_PCD_EP_Receive(hpcd, ep->num, ep->xfer_buff, ep->xfer_len);
+ }
+
+ } /* if((wEPVal & EP_CTR_RX) */
+
+ if ((wEPVal & USB_EP_CTR_TX) != 0)
+ {
+ ep = &hpcd->IN_ep[epindex];
+
+ /* clear int flag */
+ PCD_CLEAR_TX_EP_CTR(hpcd->Instance, epindex);
+
+ /* IN double Buffering*/
+ if (ep->doublebuffer == 0)
+ {
+ ep->xfer_count = PCD_GET_EP_TX_CNT(hpcd->Instance, ep->num);
+ if (ep->xfer_count != 0)
+ {
+ USB_WritePMA(hpcd->Instance, ep->xfer_buff, ep->pmaadress, ep->xfer_count);
+ }
+ }
+ else
+ {
+ if (PCD_GET_ENDPOINT(hpcd->Instance, ep->num) & USB_EP_DTOG_TX)
+ {
+ /*read from endpoint BUF0Addr buffer*/
+ ep->xfer_count = PCD_GET_EP_DBUF0_CNT(hpcd->Instance, ep->num);
+ if (ep->xfer_count != 0)
+ {
+ USB_WritePMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr0, ep->xfer_count);
+ }
+ }
+ else
+ {
+ /*read from endpoint BUF1Addr buffer*/
+ ep->xfer_count = PCD_GET_EP_DBUF1_CNT(hpcd->Instance, ep->num);
+ if (ep->xfer_count != 0)
+ {
+ USB_WritePMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr1, ep->xfer_count);
+ }
+ }
+ PCD_FreeUserBuffer(hpcd->Instance, ep->num, PCD_EP_DBUF_IN);
+ }
+ /*multi-packet on the NON control IN endpoint*/
+ ep->xfer_count = PCD_GET_EP_TX_CNT(hpcd->Instance, ep->num);
+ ep->xfer_buff+=ep->xfer_count;
+
+ /* Zero Length Packet? */
+ if (ep->xfer_len == 0)
+ {
+ /* TX COMPLETE */
+ HAL_PCD_DataInStageCallback(hpcd, ep->num);
+ }
+ else
+ {
+ HAL_PCD_EP_Transmit(hpcd, ep->num, ep->xfer_buff, ep->xfer_len);
+ }
+ }
+ }
+ }
+ return HAL_OK;
+}
+#endif /* USB */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* STM32F102x6 || STM32F102xB || */
+ /* STM32F103x6 || STM32F103xB || */
+ /* STM32F103xE || STM32F103xG || */
+ /* STM32F105xC || STM32F107xC */
+
+#endif /* HAL_PCD_MODULE_ENABLED */
+
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/bsp/radio-controller-1/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pcd_ex.c b/bsp/radio-controller-1/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pcd_ex.c
new file mode 100644
index 0000000..5f3002d
--- /dev/null
+++ b/bsp/radio-controller-1/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pcd_ex.c
@@ -0,0 +1,252 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_pcd_ex.c
+ * @author MCD Application Team
+ * @version V1.0.4
+ * @date 29-April-2016
+ * @brief Extended PCD HAL module driver.
+ * This file provides firmware functions to manage the following
+ * functionalities of the USB Peripheral Controller:
+ * + Extended features functions: Update FIFO configuration,
+ * PMA configuration for EPs
+ *
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+#ifdef HAL_PCD_MODULE_ENABLED
+
+#if defined(STM32F102x6) || defined(STM32F102xB) || \
+ defined(STM32F103x6) || defined(STM32F103xB) || \
+ defined(STM32F103xE) || defined(STM32F103xG) || \
+ defined(STM32F105xC) || defined(STM32F107xC)
+
+
+/** @defgroup PCDEx PCDEx
+ * @brief PCD Extended HAL module driver
+ * @{
+ */
+
+
+/* Private types -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private constants ---------------------------------------------------------*/
+/* Private macros ------------------------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+/* Exported functions --------------------------------------------------------*/
+/** @defgroup PCDEx_Exported_Functions PCDEx Exported Functions
+ * @{
+ */
+
+/** @defgroup PCDEx_Exported_Functions_Group1 Peripheral Control functions
+ * @brief PCDEx control functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Extended Peripheral Control functions #####
+ ===============================================================================
+ [..] This section provides functions allowing to:
+ (+) Update FIFO (USB_OTG_FS)
+ (+) Update PMA configuration (USB)
+
+@endverbatim
+ * @{
+ */
+
+#if defined (USB_OTG_FS)
+/**
+ * @brief Set Tx FIFO
+ * @param hpcd: PCD handle
+ * @param fifo: The number of Tx fifo
+ * @param size: Fifo size
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_PCDEx_SetTxFiFo(PCD_HandleTypeDef *hpcd, uint8_t fifo, uint16_t size)
+{
+ uint8_t index = 0;
+ uint32_t Tx_Offset = 0;
+
+ /* TXn min size = 16 words. (n : Transmit FIFO index)
+ When a TxFIFO is not used, the Configuration should be as follows:
+ case 1 : n > m and Txn is not used (n,m : Transmit FIFO indexes)
+ --> Txm can use the space allocated for Txn.
+ case2 : n < m and Txn is not used (n,m : Transmit FIFO indexes)
+ --> Txn should be configured with the minimum space of 16 words
+ The FIFO is used optimally when used TxFIFOs are allocated in the top
+ of the FIFO.Ex: use EP1 and EP2 as IN instead of EP1 and EP3 as IN ones.
+ When DMA is used 3n * FIFO locations should be reserved for internal DMA registers */
+
+ Tx_Offset = hpcd->Instance->GRXFSIZ;
+
+ if(fifo == 0)
+ {
+ hpcd->Instance->DIEPTXF0_HNPTXFSIZ = (size << 16) | Tx_Offset;
+ }
+ else
+ {
+ Tx_Offset += (hpcd->Instance->DIEPTXF0_HNPTXFSIZ) >> 16;
+ for (index = 0; index < (fifo - 1); index++)
+ {
+ Tx_Offset += (hpcd->Instance->DIEPTXF[index] >> 16);
+ }
+
+ /* Multiply Tx_Size by 2 to get higher performance */
+ hpcd->Instance->DIEPTXF[fifo - 1] = (size << 16) | Tx_Offset;
+
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Set Rx FIFO
+ * @param hpcd: PCD handle
+ * @param size: Size of Rx fifo
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_PCDEx_SetRxFiFo(PCD_HandleTypeDef *hpcd, uint16_t size)
+{
+ hpcd->Instance->GRXFSIZ = size;
+ return HAL_OK;
+}
+#endif /* USB_OTG_FS */
+
+#if defined (USB)
+/**
+ * @brief Configure PMA for EP
+ * @param hpcd : Device instance
+ * @param ep_addr: endpoint address
+ * @param ep_kind: endpoint Kind
+ * USB_SNG_BUF: Single Buffer used
+ * USB_DBL_BUF: Double Buffer used
+ * @param pmaadress: EP address in The PMA: In case of single buffer endpoint
+ * this parameter is 16-bit value providing the address
+ * in PMA allocated to endpoint.
+ * In case of double buffer endpoint this parameter
+ * is a 32-bit value providing the endpoint buffer 0 address
+ * in the LSB part of 32-bit value and endpoint buffer 1 address
+ * in the MSB part of 32-bit value.
+ * @retval HAL status
+ */
+
+HAL_StatusTypeDef HAL_PCDEx_PMAConfig(PCD_HandleTypeDef *hpcd,
+ uint16_t ep_addr,
+ uint16_t ep_kind,
+ uint32_t pmaadress)
+
+{
+ PCD_EPTypeDef *ep = NULL;
+
+ /* initialize ep structure*/
+ if ((0x80 & ep_addr) == 0x80)
+ {
+ ep = &hpcd->IN_ep[ep_addr & 0x7F];
+ }
+ else
+ {
+ ep = &hpcd->OUT_ep[ep_addr];
+ }
+
+ /* Here we check if the endpoint is single or double Buffer*/
+ if (ep_kind == PCD_SNG_BUF)
+ {
+ /*Single Buffer*/
+ ep->doublebuffer = 0;
+ /*Configure te PMA*/
+ ep->pmaadress = (uint16_t)pmaadress;
+ }
+ else /*USB_DBL_BUF*/
+ {
+ /*Double Buffer Endpoint*/
+ ep->doublebuffer = 1;
+ /*Configure the PMA*/
+ ep->pmaaddr0 = pmaadress & 0xFFFF;
+ ep->pmaaddr1 = (pmaadress & 0xFFFF0000) >> 16;
+ }
+
+ return HAL_OK;
+}
+#endif /* USB */
+/**
+ * @}
+ */
+
+/** @defgroup PCDEx_Exported_Functions_Group2 Peripheral State functions
+ * @brief Manage device connection state
+ * @{
+ */
+/**
+ * @brief Software Device Connection,
+ * this function is not required by USB OTG FS peripheral, it is used
+ * only by USB Device FS peripheral.
+ * @param hpcd: PCD handle
+ * @param state: connection state (0 : disconnected / 1: connected)
+ * @retval None
+ */
+__weak void HAL_PCDEx_SetConnectionState(PCD_HandleTypeDef *hpcd, uint8_t state)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hpcd);
+ UNUSED(state);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_PCDEx_SetConnectionState could be implemented in the user file
+ */
+}
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* STM32F102x6 || STM32F102xB || */
+ /* STM32F103x6 || STM32F103xB || */
+ /* STM32F103xE || STM32F103xG || */
+ /* STM32F105xC || STM32F107xC */
+
+#endif /* HAL_PCD_MODULE_ENABLED */
+
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/bsp/radio-controller-1/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pwr.c b/bsp/radio-controller-1/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pwr.c
new file mode 100644
index 0000000..bf00707
--- /dev/null
+++ b/bsp/radio-controller-1/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pwr.c
@@ -0,0 +1,636 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_pwr.c
+ * @author MCD Application Team
+ * @version V1.0.4
+ * @date 29-April-2016
+ * @brief PWR HAL module driver.
+ *
+ * This file provides firmware functions to manage the following
+ * functionalities of the Power Controller (PWR) peripheral:
+ * + Initialization/de-initialization functions
+ * + Peripheral Control functions
+ *
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+/** @defgroup PWR PWR
+ * @brief PWR HAL module driver
+ * @{
+ */
+
+#ifdef HAL_PWR_MODULE_ENABLED
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+
+/** @defgroup PWR_Private_Constants PWR Private Constants
+ * @{
+ */
+
+/** @defgroup PWR_PVD_Mode_Mask PWR PVD Mode Mask
+ * @{
+ */
+#define PVD_MODE_IT ((uint32_t)0x00010000)
+#define PVD_MODE_EVT ((uint32_t)0x00020000)
+#define PVD_RISING_EDGE ((uint32_t)0x00000001)
+#define PVD_FALLING_EDGE ((uint32_t)0x00000002)
+/**
+ * @}
+ */
+
+
+/** @defgroup PWR_register_alias_address PWR Register alias address
+ * @{
+ */
+/* ------------- PWR registers bit address in the alias region ---------------*/
+#define PWR_OFFSET (PWR_BASE - PERIPH_BASE)
+#define PWR_CR_OFFSET 0x00
+#define PWR_CSR_OFFSET 0x04
+#define PWR_CR_OFFSET_BB (PWR_OFFSET + PWR_CR_OFFSET)
+#define PWR_CSR_OFFSET_BB (PWR_OFFSET + PWR_CSR_OFFSET)
+/**
+ * @}
+ */
+
+/** @defgroup PWR_CR_register_alias PWR CR Register alias address
+ * @{
+ */
+/* --- CR Register ---*/
+/* Alias word address of LPSDSR bit */
+#define LPSDSR_BIT_NUMBER POSITION_VAL(PWR_CR_LPDS)
+#define CR_LPSDSR_BB ((uint32_t)(PERIPH_BB_BASE + (PWR_CR_OFFSET_BB * 32) + (LPSDSR_BIT_NUMBER * 4)))
+
+/* Alias word address of DBP bit */
+#define DBP_BIT_NUMBER POSITION_VAL(PWR_CR_DBP)
+#define CR_DBP_BB ((uint32_t)(PERIPH_BB_BASE + (PWR_CR_OFFSET_BB * 32) + (DBP_BIT_NUMBER * 4)))
+
+/* Alias word address of PVDE bit */
+#define PVDE_BIT_NUMBER POSITION_VAL(PWR_CR_PVDE)
+#define CR_PVDE_BB ((uint32_t)(PERIPH_BB_BASE + (PWR_CR_OFFSET_BB * 32) + (PVDE_BIT_NUMBER * 4)))
+
+/**
+ * @}
+ */
+
+/** @defgroup PWR_CSR_register_alias PWR CSR Register alias address
+ * @{
+ */
+
+/* --- CSR Register ---*/
+/* Alias word address of EWUP1 bit */
+#define CSR_EWUP_BB(VAL) ((uint32_t)(PERIPH_BB_BASE + (PWR_CSR_OFFSET_BB * 32) + (POSITION_VAL(VAL) * 4)))
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/** @defgroup PWR_Private_Functions PWR Private Functions
+ * brief WFE cortex command overloaded for HAL_PWR_EnterSTOPMode usage only (see Workaround section)
+ * @{
+ */
+static void PWR_OverloadWfe(void);
+
+/* Private functions ---------------------------------------------------------*/
+__NOINLINE
+static void PWR_OverloadWfe(void)
+{
+ __asm volatile( "wfe" );
+ __asm volatile( "nop" );
+}
+
+/**
+ * @}
+ */
+
+
+/** @defgroup PWR_Exported_Functions PWR Exported Functions
+ * @{
+ */
+
+/** @defgroup PWR_Exported_Functions_Group1 Initialization and de-initialization functions
+ * @brief Initialization and de-initialization functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Initialization and de-initialization functions #####
+ ===============================================================================
+ [..]
+ After reset, the backup domain (RTC registers, RTC backup data
+ registers) is protected against possible unwanted
+ write accesses.
+ To enable access to the RTC Domain and RTC registers, proceed as follows:
+ (+) Enable the Power Controller (PWR) APB1 interface clock using the
+ __HAL_RCC_PWR_CLK_ENABLE() macro.
+ (+) Enable access to RTC domain using the HAL_PWR_EnableBkUpAccess() function.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Deinitializes the PWR peripheral registers to their default reset values.
+ * @retval None
+ */
+void HAL_PWR_DeInit(void)
+{
+ __HAL_RCC_PWR_FORCE_RESET();
+ __HAL_RCC_PWR_RELEASE_RESET();
+}
+
+/**
+ * @brief Enables access to the backup domain (RTC registers, RTC
+ * backup data registers ).
+ * @note If the HSE divided by 128 is used as the RTC clock, the
+ * Backup Domain Access should be kept enabled.
+ * @retval None
+ */
+void HAL_PWR_EnableBkUpAccess(void)
+{
+ /* Enable access to RTC and backup registers */
+ *(__IO uint32_t *) CR_DBP_BB = (uint32_t)ENABLE;
+}
+
+/**
+ * @brief Disables access to the backup domain (RTC registers, RTC
+ * backup data registers).
+ * @note If the HSE divided by 128 is used as the RTC clock, the
+ * Backup Domain Access should be kept enabled.
+ * @retval None
+ */
+void HAL_PWR_DisableBkUpAccess(void)
+{
+ /* Disable access to RTC and backup registers */
+ *(__IO uint32_t *) CR_DBP_BB = (uint32_t)DISABLE;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup PWR_Exported_Functions_Group2 Peripheral Control functions
+ * @brief Low Power modes configuration functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Peripheral Control functions #####
+ ===============================================================================
+
+ *** PVD configuration ***
+ =========================
+ [..]
+ (+) 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. This is done through
+ __HAL_PVD_EXTI_ENABLE_IT() macro.
+ (+) The PVD is stopped in Standby mode.
+
+ *** WakeUp pin configuration ***
+ ================================
+ [..]
+ (+) WakeUp pin is used to wake up the system from Standby mode. This pin is
+ forced in input pull-down configuration and is active on rising edges.
+ (+) There is one WakeUp pin:
+ WakeUp Pin 1 on PA.00.
+
+ [..]
+
+ *** Low Power modes configuration ***
+ =====================================
+ [..]
+ The device features 3 low-power modes:
+ (+) Sleep mode: CPU clock off, all peripherals including Cortex-M3 core peripherals like
+ NVIC, SysTick, etc. are kept running
+ (+) Stop mode: All clocks are stopped
+ (+) Standby mode: 1.8V domain powered off
+
+
+ *** Sleep mode ***
+ ==================
+ [..]
+ (+) Entry:
+ The Sleep mode is entered by using the HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFx)
+ functions with
+ (++) PWR_SLEEPENTRY_WFI: enter SLEEP mode with WFI instruction
+ (++) PWR_SLEEPENTRY_WFE: enter SLEEP mode with WFE instruction
+
+ (+) Exit:
+ (++) WFI entry mode, Any peripheral interrupt acknowledged by the nested vectored interrupt
+ controller (NVIC) can wake up the device from Sleep mode.
+ (++) WFE entry mode, Any wakeup event can wake up the device from Sleep mode.
+ (+++) Any peripheral interrupt w/o NVIC configuration & SEVONPEND bit set in the Cortex (HAL_PWR_EnableSEVOnPend)
+ (+++) Any EXTI Line (Internal or External) configured in Event mode
+
+ *** Stop mode ***
+ =================
+ [..]
+ The Stop mode is based on the Cortex-M3 deepsleep mode combined with peripheral
+ clock gating. The voltage regulator can be configured either in normal or low-power mode.
+ In Stop mode, all clocks in the 1.8 V domain are stopped, the PLL, the HSI and the HSE RC
+ oscillators are disabled. SRAM and register contents are preserved.
+ In Stop mode, all I/O pins keep the same state as in Run mode.
+
+ (+) Entry:
+ The Stop mode is entered using the HAL_PWR_EnterSTOPMode(PWR_REGULATOR_VALUE, PWR_SLEEPENTRY_WFx )
+ function with:
+ (++) PWR_REGULATOR_VALUE= PWR_MAINREGULATOR_ON: Main regulator ON.
+ (++) PWR_REGULATOR_VALUE= PWR_LOWPOWERREGULATOR_ON: Low Power regulator ON.
+ (++) PWR_SLEEPENTRY_WFx= PWR_SLEEPENTRY_WFI: enter STOP mode with WFI instruction
+ (++) PWR_SLEEPENTRY_WFx= PWR_SLEEPENTRY_WFE: enter STOP mode with WFE instruction
+ (+) Exit:
+ (++) WFI entry mode, Any EXTI Line (Internal or External) configured in Interrupt mode with NVIC configured
+ (++) WFE entry mode, Any EXTI Line (Internal or External) configured in Event mode.
+
+ *** Standby mode ***
+ ====================
+ [..]
+ The Standby mode allows to achieve the lowest power consumption. It is based on the
+ Cortex-M3 deepsleep mode, with the voltage regulator disabled. The 1.8 V domain is
+ consequently powered off. The PLL, the HSI oscillator and the HSE oscillator are also
+ switched off. SRAM and register contents are lost except for registers in the Backup domain
+ and Standby circuitry
+
+ (+) Entry:
+ (++) The Standby mode is entered using the HAL_PWR_EnterSTANDBYMode() function.
+ (+) Exit:
+ (++) WKUP pin rising edge, RTC alarm event rising edge, external Reset in
+ NRSTpin, IWDG Reset
+
+ *** Auto-wakeup (AWU) from low-power mode ***
+ =============================================
+ [..]
+
+ (+) The MCU can be woken up from low-power mode by an RTC Alarm event,
+ without depending on an external interrupt (Auto-wakeup mode).
+
+ (+) RTC auto-wakeup (AWU) from the Stop and Standby modes
+
+ (++) To wake up from the Stop mode with an RTC alarm event, it is necessary to
+ configure the RTC to generate the RTC alarm using the HAL_RTC_SetAlarm_IT() function.
+
+ *** PWR Workarounds linked to Silicon Limitation ***
+ ====================================================
+ [..]
+ Below the list of all silicon limitations known on STM32F1xx prouct.
+
+ (#)Workarounds Implemented inside PWR HAL Driver
+ (##)Debugging Stop mode with WFE entry - overloaded the WFE by an internal function
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Configures the voltage threshold detected by the Power Voltage Detector(PVD).
+ * @param sConfigPVD: pointer to an PWR_PVDTypeDef structure that contains the configuration
+ * information for the PVD.
+ * @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 HAL_PWR_ConfigPVD(PWR_PVDTypeDef *sConfigPVD)
+{
+ /* Check the parameters */
+ assert_param(IS_PWR_PVD_LEVEL(sConfigPVD->PVDLevel));
+ assert_param(IS_PWR_PVD_MODE(sConfigPVD->Mode));
+
+ /* Set PLS[7:5] bits according to PVDLevel value */
+ MODIFY_REG(PWR->CR, PWR_CR_PLS, sConfigPVD->PVDLevel);
+
+ /* Clear any previous config. Keep it clear if no event or IT mode is selected */
+ __HAL_PWR_PVD_EXTI_DISABLE_EVENT();
+ __HAL_PWR_PVD_EXTI_DISABLE_IT();
+ __HAL_PWR_PVD_EXTI_DISABLE_FALLING_EDGE();
+ __HAL_PWR_PVD_EXTI_DISABLE_RISING_EDGE();
+
+ /* Configure interrupt mode */
+ if((sConfigPVD->Mode & PVD_MODE_IT) == PVD_MODE_IT)
+ {
+ __HAL_PWR_PVD_EXTI_ENABLE_IT();
+ }
+
+ /* Configure event mode */
+ if((sConfigPVD->Mode & PVD_MODE_EVT) == PVD_MODE_EVT)
+ {
+ __HAL_PWR_PVD_EXTI_ENABLE_EVENT();
+ }
+
+ /* Configure the edge */
+ if((sConfigPVD->Mode & PVD_RISING_EDGE) == PVD_RISING_EDGE)
+ {
+ __HAL_PWR_PVD_EXTI_ENABLE_RISING_EDGE();
+ }
+
+ if((sConfigPVD->Mode & PVD_FALLING_EDGE) == PVD_FALLING_EDGE)
+ {
+ __HAL_PWR_PVD_EXTI_ENABLE_FALLING_EDGE();
+ }
+}
+
+/**
+ * @brief Enables the Power Voltage Detector(PVD).
+ * @retval None
+ */
+void HAL_PWR_EnablePVD(void)
+{
+ /* Enable the power voltage detector */
+ *(__IO uint32_t *) CR_PVDE_BB = (uint32_t)ENABLE;
+}
+
+/**
+ * @brief Disables the Power Voltage Detector(PVD).
+ * @retval None
+ */
+void HAL_PWR_DisablePVD(void)
+{
+ /* Disable the power voltage detector */
+ *(__IO uint32_t *) CR_PVDE_BB = (uint32_t)DISABLE;
+}
+
+/**
+ * @brief Enables the WakeUp PINx functionality.
+ * @param WakeUpPinx: Specifies the Power Wake-Up pin to enable.
+ * This parameter can be one of the following values:
+ * @arg PWR_WAKEUP_PIN1
+ * @retval None
+ */
+void HAL_PWR_EnableWakeUpPin(uint32_t WakeUpPinx)
+{
+ /* Check the parameter */
+ assert_param(IS_PWR_WAKEUP_PIN(WakeUpPinx));
+ /* Enable the EWUPx pin */
+ *(__IO uint32_t *) CSR_EWUP_BB(WakeUpPinx) = (uint32_t)ENABLE;
+}
+
+/**
+ * @brief Disables the WakeUp PINx functionality.
+ * @param WakeUpPinx: Specifies the Power Wake-Up pin to disable.
+ * This parameter can be one of the following values:
+ * @arg PWR_WAKEUP_PIN1
+ * @retval None
+ */
+void HAL_PWR_DisableWakeUpPin(uint32_t WakeUpPinx)
+{
+ /* Check the parameter */
+ assert_param(IS_PWR_WAKEUP_PIN(WakeUpPinx));
+ /* Disable the EWUPx pin */
+ *(__IO uint32_t *) CSR_EWUP_BB(WakeUpPinx) = (uint32_t)DISABLE;
+}
+
+/**
+ * @brief Enters Sleep mode.
+ * @note In Sleep mode, all I/O pins keep the same state as in Run mode.
+ * @param Regulator: Regulator state as no effect in SLEEP mode - allows to support portability from legacy software
+ * @param SLEEPEntry: Specifies if SLEEP mode is entered with WFI or WFE instruction.
+ * When WFI entry is used, tick interrupt have to be disabled if not desired as
+ * the interrupt wake up source.
+ * 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 HAL_PWR_EnterSLEEPMode(uint32_t Regulator, uint8_t SLEEPEntry)
+{
+ /* Check the parameters */
+ /* No check on Regulator because parameter not used in SLEEP mode */
+ assert_param(IS_PWR_SLEEP_ENTRY(SLEEPEntry));
+
+ /* Clear SLEEPDEEP bit of Cortex System Control Register */
+ CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
+
+ /* Select SLEEP mode entry -------------------------------------------------*/
+ if(SLEEPEntry == PWR_SLEEPENTRY_WFI)
+ {
+ /* Request Wait For Interrupt */
+ __WFI();
+ }
+ else
+ {
+ /* Request Wait For Event */
+ __SEV();
+ __WFE();
+ __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 using an interrupt or a wakeup event,
+ * 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 Regulator: Specifies the regulator state in Stop mode.
+ * This parameter can be one of the following values:
+ * @arg PWR_MAINREGULATOR_ON: Stop mode with regulator ON
+ * @arg PWR_LOWPOWERREGULATOR_ON: Stop mode with low power regulator ON
+ * @param 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 HAL_PWR_EnterSTOPMode(uint32_t Regulator, uint8_t STOPEntry)
+{
+ /* Check the parameters */
+ assert_param(IS_PWR_REGULATOR(Regulator));
+ assert_param(IS_PWR_STOP_ENTRY(STOPEntry));
+
+ /* Clear PDDS bit in PWR register to specify entering in STOP mode when CPU enter in Deepsleep */
+ CLEAR_BIT(PWR->CR, PWR_CR_PDDS);
+
+ /* Select the voltage regulator mode by setting LPDS bit in PWR register according to Regulator parameter value */
+ MODIFY_REG(PWR->CR, PWR_CR_LPDS, Regulator);
+
+ /* Set SLEEPDEEP bit of Cortex System Control Register */
+ SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
+
+ /* Select Stop mode entry --------------------------------------------------*/
+ if(STOPEntry == PWR_STOPENTRY_WFI)
+ {
+ /* Request Wait For Interrupt */
+ __WFI();
+ }
+ else
+ {
+ /* Request Wait For Event */
+ __SEV();
+ PWR_OverloadWfe(); /* WFE redefine locally */
+ PWR_OverloadWfe(); /* WFE redefine locally */
+ }
+ /* Reset SLEEPDEEP bit of Cortex System Control Register */
+ CLEAR_BIT(SCB->SCR, ((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)
+ * - TAMPER pin if configured for tamper or calibration out.
+ * - WKUP pin (PA0) if enabled.
+ * @retval None
+ */
+void HAL_PWR_EnterSTANDBYMode(void)
+{
+ /* Select Standby mode */
+ SET_BIT(PWR->CR, PWR_CR_PDDS);
+
+ /* Set SLEEPDEEP bit of Cortex System Control Register */
+ SET_BIT(SCB->SCR, ((uint32_t)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();
+}
+
+
+/**
+ * @brief Indicates Sleep-On-Exit when returning from Handler mode to Thread mode.
+ * @note Set SLEEPONEXIT bit of SCR register. When this bit is set, the processor
+ * re-enters SLEEP mode when an interruption handling is over.
+ * Setting this bit is useful when the processor is expected to run only on
+ * interruptions handling.
+ * @retval None
+ */
+void HAL_PWR_EnableSleepOnExit(void)
+{
+ /* Set SLEEPONEXIT bit of Cortex System Control Register */
+ SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPONEXIT_Msk));
+}
+
+
+/**
+ * @brief Disables Sleep-On-Exit feature when returning from Handler mode to Thread mode.
+ * @note Clears SLEEPONEXIT bit of SCR register. When this bit is set, the processor
+ * re-enters SLEEP mode when an interruption handling is over.
+ * @retval None
+ */
+void HAL_PWR_DisableSleepOnExit(void)
+{
+ /* Clear SLEEPONEXIT bit of Cortex System Control Register */
+ CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPONEXIT_Msk));
+}
+
+
+/**
+ * @brief Enables CORTEX M3 SEVONPEND bit.
+ * @note Sets SEVONPEND bit of SCR register. When this bit is set, this causes
+ * WFE to wake up when an interrupt moves from inactive to pended.
+ * @retval None
+ */
+void HAL_PWR_EnableSEVOnPend(void)
+{
+ /* Set SEVONPEND bit of Cortex System Control Register */
+ SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SEVONPEND_Msk));
+}
+
+
+/**
+ * @brief Disables CORTEX M3 SEVONPEND bit.
+ * @note Clears SEVONPEND bit of SCR register. When this bit is set, this causes
+ * WFE to wake up when an interrupt moves from inactive to pended.
+ * @retval None
+ */
+void HAL_PWR_DisableSEVOnPend(void)
+{
+ /* Clear SEVONPEND bit of Cortex System Control Register */
+ CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SEVONPEND_Msk));
+}
+
+
+
+/**
+ * @brief This function handles the PWR PVD interrupt request.
+ * @note This API should be called under the PVD_IRQHandler().
+ * @retval None
+ */
+void HAL_PWR_PVD_IRQHandler(void)
+{
+ /* Check PWR exti flag */
+ if(__HAL_PWR_PVD_EXTI_GET_FLAG() != RESET)
+ {
+ /* PWR PVD interrupt user callback */
+ HAL_PWR_PVDCallback();
+
+ /* Clear PWR Exti pending bit */
+ __HAL_PWR_PVD_EXTI_CLEAR_FLAG();
+ }
+}
+
+/**
+ * @brief PWR PVD interrupt callback
+ * @retval None
+ */
+__weak void HAL_PWR_PVDCallback(void)
+{
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_PWR_PVDCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* HAL_PWR_MODULE_ENABLED */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/bsp/radio-controller-1/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc.c b/bsp/radio-controller-1/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc.c
new file mode 100644
index 0000000..e23f65c
--- /dev/null
+++ b/bsp/radio-controller-1/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc.c
@@ -0,0 +1,1270 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_rcc.c
+ * @author MCD Application Team
+ * @version V1.0.4
+ * @date 29-April-2016
+ * @brief RCC HAL module driver.
+ * This file provides firmware functions to manage the following
+ * functionalities of the Reset and Clock Control (RCC) peripheral:
+ * + Initialization and de-initialization functions
+ * + Peripheral Control functions
+ *
+ @verbatim
+ ==============================================================================
+ ##### RCC specific features #####
+ ==============================================================================
+ [..]
+ After reset the device is running from Internal High Speed oscillator
+ (HSI 8MHz) with Flash 0 wait state, Flash prefetch buffer is enabled,
+ and all peripherals are off except internal SRAM, Flash and JTAG.
+ (+) There is no prescaler on High speed (AHB) and Low speed (APB) buses;
+ all peripherals mapped on these buses are running at HSI speed.
+ (+) The clock for all peripherals is switched off, except the SRAM and FLASH.
+ (+) All GPIOs are in input floating state, except the JTAG pins which
+ are assigned to be used for debug purpose.
+ [..] Once the device started from reset, the user application has to:
+ (+) Configure the clock source to be used to drive the System clock
+ (if the application needs higher frequency/performance)
+ (+) Configure the System clock frequency and Flash settings
+ (+) Configure the AHB and APB buses prescalers
+ (+) Enable the clock for the peripheral(s) to be used
+ (+) Configure the clock source(s) for peripherals whose clocks are not
+ derived from the System clock (I2S, RTC, ADC, USB OTG FS)
+
+ ##### RCC Limitations #####
+ ==============================================================================
+ [..]
+ A delay between an RCC peripheral clock enable and the effective peripheral
+ enabling should be taken into account in order to manage the peripheral read/write
+ from/to registers.
+ (+) This delay depends on the peripheral mapping.
+ (++) AHB & APB peripherals, 1 dummy read is necessary
+
+ [..]
+ Workarounds:
+ (#) For AHB & APB peripherals, a dummy read to the peripheral register has been
+ inserted in each __HAL_RCC_PPP_CLK_ENABLE() macro.
+
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+/** @defgroup RCC RCC
+* @brief RCC HAL module driver
+ * @{
+ */
+
+#ifdef HAL_RCC_MODULE_ENABLED
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/** @defgroup RCC_Private_Constants RCC Private Constants
+ * @{
+ */
+/* Bits position in in the CFGR register */
+#define RCC_CFGR_HPRE_BITNUMBER POSITION_VAL(RCC_CFGR_HPRE)
+#define RCC_CFGR_PPRE1_BITNUMBER POSITION_VAL(RCC_CFGR_PPRE1)
+#define RCC_CFGR_PPRE2_BITNUMBER POSITION_VAL(RCC_CFGR_PPRE2)
+/**
+ * @}
+ */
+/* Private macro -------------------------------------------------------------*/
+/** @defgroup RCC_Private_Macros RCC Private Macros
+ * @{
+ */
+
+#define MCO1_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
+#define MCO1_GPIO_PORT GPIOA
+#define MCO1_PIN GPIO_PIN_8
+
+/**
+ * @}
+ */
+
+/* Private variables ---------------------------------------------------------*/
+/** @defgroup RCC_Private_Variables RCC Private Variables
+ * @{
+ */
+/**
+ * @}
+ */
+
+/* Private function prototypes -----------------------------------------------*/
+/* Exported functions ---------------------------------------------------------*/
+
+/** @defgroup RCC_Exported_Functions RCC Exported Functions
+ * @{
+ */
+
+/** @defgroup RCC_Exported_Functions_Group1 Initialization and de-initialization functions
+ * @brief Initialization and Configuration functions
+ *
+ @verbatim
+ ===============================================================================
+ ##### Initialization and de-initialization functions #####
+ ===============================================================================
+ [..]
+ This section provides functions allowing to configure the internal/external oscillators
+ (HSE, HSI, LSE, LSI, PLL, CSS and MCO) and the System buses clocks (SYSCLK, AHB, APB1
+ and APB2).
+
+ [..] Internal/external clock and PLL configuration
+ (#) HSI (high-speed internal), 8 MHz factory-trimmed RC used directly or through
+ the PLL as System clock source.
+ (#) LSI (low-speed internal), ~40 KHz low consumption RC used as IWDG and/or RTC
+ clock source.
+
+ (#) HSE (high-speed external), 4 to 24 MHz (STM32F100xx) or 4 to 16 MHz (STM32F101x/STM32F102x/STM32F103x) or 3 to 25 MHz (STM32F105x/STM32F107x) 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.
+
+ (#) PLL (clocked by HSI or HSE), featuring different output clocks:
+ (++) The first output is used to generate the high speed system clock (up to 72 MHz for STM32F10xxx or up to 24 MHz for STM32F100xx)
+ (++) The second output is used to generate the clock for the USB OTG FS (48 MHz)
+
+ (#) CSS (Clock security system), once enable using the macro __HAL_RCC_CSS_ENABLE()
+ and if a HSE clock failure occurs(HSE used directly or through PLL as System
+ clock source), the System clocks automatically switched to HSI and an interrupt
+ is generated if enabled. The interrupt is linked to the Cortex-M3 NMI
+ (Non-Maskable Interrupt) exception vector.
+
+ (#) MCO1 (microcontroller clock output), used to output SYSCLK, HSI,
+ HSE or PLL clock (divided by 2) on PA8 pin + PLL2CLK, PLL3CLK/2, PLL3CLK and XTI for STM32F105x/STM32F107x
+
+ [..] System, AHB and APB buses clocks configuration
+ (#) Several clock sources can be used to drive the System clock (SYSCLK): HSI,
+ HSE and PLL.
+ The AHB clock (HCLK) is derived from System clock through configurable
+ prescaler and used to clock the CPU, memory and peripherals mapped
+ on AHB bus (DMA, GPIO...). APB1 (PCLK1) and APB2 (PCLK2) clocks are derived
+ from AHB clock through configurable prescalers and used to clock
+ the peripherals mapped on these buses. You can use
+ "@ref HAL_RCC_GetSysClockFreq()" function to retrieve the frequencies of these clocks.
+
+ -@- All the peripheral clocks are derived from the System clock (SYSCLK) except:
+ (+@) RTC: RTC clock can be derived either from the LSI, LSE or HSE clock
+ divided by 128.
+ (+@) USB OTG FS and RTC: USB OTG FS require a frequency equal to 48 MHz
+ to work correctly. This clock is derived of the main PLL through PLL Multiplier.
+ (+@) I2S interface on STM32F105x/STM32F107x can be derived from PLL3CLK
+ (+@) IWDG clock which is always the LSI clock.
+
+ (#) For STM32F10xxx, the maximum frequency of the SYSCLK and HCLK/PCLK2 is 72 MHz, PCLK1 36 MHz.
+ For STM32F100xx, the maximum frequency of the SYSCLK and HCLK/PCLK1/PCLK2 is 24 MHz.
+ Depending on the SYSCLK frequency, the flash latency should be adapted accordingly.
+ @endverbatim
+ * @{
+ */
+
+/*
+ Additional consideration on the SYSCLK based on Latency settings:
+ +-----------------------------------------------+
+ | Latency | SYSCLK clock frequency (MHz) |
+ |---------------|-------------------------------|
+ |0WS(1CPU cycle)| 0 < SYSCLK <= 24 |
+ |---------------|-------------------------------|
+ |1WS(2CPU cycle)| 24 < SYSCLK <= 48 |
+ |---------------|-------------------------------|
+ |2WS(3CPU cycle)| 48 < SYSCLK <= 72 |
+ +-----------------------------------------------+
+ */
+
+/**
+ * @brief Resets the RCC clock configuration to the default reset state.
+ * @note The default reset state of the clock configuration is given below:
+ * - HSI ON and used as system clock source
+ * - HSE and PLL OFF
+ * - AHB, APB1 and APB2 prescaler set to 1.
+ * - CSS and MCO1 OFF
+ * - All interrupts disabled
+ * @note This function does not modify the configuration of the
+ * - Peripheral clocks
+ * - LSI, LSE and RTC clocks
+ * @retval None
+ */
+void HAL_RCC_DeInit(void)
+{
+ /* Switch SYSCLK to HSI */
+ CLEAR_BIT(RCC->CFGR, RCC_CFGR_SW);
+
+ /* Reset HSEON, CSSON, & PLLON bits */
+ CLEAR_BIT(RCC->CR, RCC_CR_HSEON | RCC_CR_CSSON | RCC_CR_PLLON);
+
+ /* Reset HSEBYP bit */
+ CLEAR_BIT(RCC->CR, RCC_CR_HSEBYP);
+
+ /* Reset CFGR register */
+ CLEAR_REG(RCC->CFGR);
+
+ /* Set HSITRIM bits to the reset value */
+ MODIFY_REG(RCC->CR, RCC_CR_HSITRIM, ((uint32_t)0x10 << POSITION_VAL(RCC_CR_HSITRIM)));
+
+#if (defined(STM32F105xC) || defined(STM32F107xC) || defined (STM32F100xB) || defined (STM32F100xE))
+ /* Reset CFGR2 register */
+ CLEAR_REG(RCC->CFGR2);
+
+#endif /* STM32F105xC || STM32F107xC || STM32F100xB || STM32F100xE */
+ /* Disable all interrupts */
+ CLEAR_REG(RCC->CIR);
+
+ /* Update the SystemCoreClock global variable */
+ SystemCoreClock = HSI_VALUE;
+}
+
+/**
+ * @brief Initializes the RCC Oscillators according to the specified parameters in the
+ * RCC_OscInitTypeDef.
+ * @param RCC_OscInitStruct pointer to an RCC_OscInitTypeDef structure that
+ * contains the configuration information for the RCC Oscillators.
+ * @note The PLL is not disabled when used as system clock.
+ * @note The PLL is not disabled when USB OTG FS clock is enabled (specific to devices with USB FS)
+ * @note Transitions LSE Bypass to LSE On and LSE On to LSE Bypass are not
+ * supported by this macro. User should request a transition to LSE Off
+ * first and then LSE On or LSE Bypass.
+ * @note Transition HSE Bypass to HSE On and HSE On to HSE Bypass are not
+ * supported by this macro. User should request a transition to HSE Off
+ * first and then HSE On or HSE Bypass.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct)
+{
+ uint32_t tickstart = 0;
+
+ /* Check the parameters */
+ assert_param(RCC_OscInitStruct != NULL);
+ assert_param(IS_RCC_OSCILLATORTYPE(RCC_OscInitStruct->OscillatorType));
+
+ /*------------------------------- HSE Configuration ------------------------*/
+ if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSE) == RCC_OSCILLATORTYPE_HSE)
+ {
+ /* Check the parameters */
+ assert_param(IS_RCC_HSE(RCC_OscInitStruct->HSEState));
+
+ /* When the HSE is used as system clock or clock source for PLL in these cases it is not allowed to be disabled */
+ if((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_HSE)
+ || ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && (__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSE)))
+ {
+ if((__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) != RESET) && (RCC_OscInitStruct->HSEState == RCC_HSE_OFF))
+ {
+ return HAL_ERROR;
+ }
+ }
+ else
+ {
+ /* Set the new HSE configuration ---------------------------------------*/
+ __HAL_RCC_HSE_CONFIG(RCC_OscInitStruct->HSEState);
+
+
+ /* Check the HSE State */
+ if(RCC_OscInitStruct->HSEState != RCC_HSE_OFF)
+ {
+ /* Get Start Tick */
+ tickstart = HAL_GetTick();
+
+ /* Wait till HSE is ready */
+ while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) == RESET)
+ {
+ if((HAL_GetTick() - tickstart ) > HSE_TIMEOUT_VALUE)
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+ else
+ {
+ /* Get Start Tick */
+ tickstart = HAL_GetTick();
+
+ /* Wait till HSE is disabled */
+ while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) != RESET)
+ {
+ if((HAL_GetTick() - tickstart ) > HSE_TIMEOUT_VALUE)
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+ }
+ }
+ /*----------------------------- HSI Configuration --------------------------*/
+ if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI) == RCC_OSCILLATORTYPE_HSI)
+ {
+ /* Check the parameters */
+ assert_param(IS_RCC_HSI(RCC_OscInitStruct->HSIState));
+ assert_param(IS_RCC_CALIBRATION_VALUE(RCC_OscInitStruct->HSICalibrationValue));
+
+ /* Check if HSI is used as system clock or as PLL source when PLL is selected as system clock */
+ if((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_HSI)
+ || ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && (__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSI_DIV2)))
+ {
+ /* When HSI is used as system clock it will not disabled */
+ if((__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) != RESET) && (RCC_OscInitStruct->HSIState != RCC_HSI_ON))
+ {
+ return HAL_ERROR;
+ }
+ /* Otherwise, just the calibration is allowed */
+ else
+ {
+ /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/
+ __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue);
+ }
+ }
+ else
+ {
+ /* Check the HSI State */
+ if(RCC_OscInitStruct->HSIState != RCC_HSI_OFF)
+ {
+ /* Enable the Internal High Speed oscillator (HSI). */
+ __HAL_RCC_HSI_ENABLE();
+
+ /* Get Start Tick */
+ tickstart = HAL_GetTick();
+
+ /* Wait till HSI is ready */
+ while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) == RESET)
+ {
+ if((HAL_GetTick() - tickstart ) > HSI_TIMEOUT_VALUE)
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+
+ /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/
+ __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue);
+ }
+ else
+ {
+ /* Disable the Internal High Speed oscillator (HSI). */
+ __HAL_RCC_HSI_DISABLE();
+
+ /* Get Start Tick */
+ tickstart = HAL_GetTick();
+
+ /* Wait till HSI is disabled */
+ while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) != RESET)
+ {
+ if((HAL_GetTick() - tickstart ) > HSI_TIMEOUT_VALUE)
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+ }
+ }
+ /*------------------------------ LSI Configuration -------------------------*/
+ if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSI) == RCC_OSCILLATORTYPE_LSI)
+ {
+ /* Check the parameters */
+ assert_param(IS_RCC_LSI(RCC_OscInitStruct->LSIState));
+
+ /* Check the LSI State */
+ if(RCC_OscInitStruct->LSIState != RCC_LSI_OFF)
+ {
+ /* Enable the Internal Low Speed oscillator (LSI). */
+ __HAL_RCC_LSI_ENABLE();
+
+ /* Get Start Tick */
+ tickstart = HAL_GetTick();
+
+ /* Wait till LSI is ready */
+ while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSIRDY) == RESET)
+ {
+ if((HAL_GetTick() - tickstart ) > LSI_TIMEOUT_VALUE)
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+ /* To have a fully stabilized clock in the specified range, a software delay of 1ms
+ should be added.*/
+ HAL_Delay(1);
+ }
+ else
+ {
+ /* Disable the Internal Low Speed oscillator (LSI). */
+ __HAL_RCC_LSI_DISABLE();
+
+ /* Get Start Tick */
+ tickstart = HAL_GetTick();
+
+ /* Wait till LSI is disabled */
+ while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSIRDY) != RESET)
+ {
+ if((HAL_GetTick() - tickstart ) > LSI_TIMEOUT_VALUE)
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+ }
+ /*------------------------------ LSE Configuration -------------------------*/
+ if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSE) == RCC_OSCILLATORTYPE_LSE)
+ {
+ /* Check the parameters */
+ assert_param(IS_RCC_LSE(RCC_OscInitStruct->LSEState));
+
+ /* Enable Power Clock*/
+ __HAL_RCC_PWR_CLK_ENABLE();
+
+ /* Enable write access to Backup domain */
+ SET_BIT(PWR->CR, PWR_CR_DBP);
+
+ /* Wait for Backup domain Write protection disable */
+ tickstart = HAL_GetTick();
+
+ while((PWR->CR & PWR_CR_DBP) == RESET)
+ {
+ if((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE)
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+
+ /* Set the new LSE configuration -----------------------------------------*/
+ __HAL_RCC_LSE_CONFIG(RCC_OscInitStruct->LSEState);
+ /* Check the LSE State */
+ if(RCC_OscInitStruct->LSEState != RCC_LSE_OFF)
+ {
+ /* Get Start Tick */
+ tickstart = HAL_GetTick();
+
+ /* Wait till LSE is ready */
+ while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET)
+ {
+ if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE)
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+ else
+ {
+ /* Get Start Tick */
+ tickstart = HAL_GetTick();
+
+ /* Wait till LSE is disabled */
+ while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) != RESET)
+ {
+ if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE)
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+ }
+
+#if defined(RCC_CR_PLL2ON)
+ /*-------------------------------- PLL2 Configuration -----------------------*/
+ /* Check the parameters */
+ assert_param(IS_RCC_PLL2(RCC_OscInitStruct->PLL2.PLL2State));
+ if ((RCC_OscInitStruct->PLL2.PLL2State) != RCC_PLL2_NONE)
+ {
+ /* This bit can not be cleared if the PLL2 clock is used indirectly as system
+ clock (i.e. it is used as PLL clock entry that is used as system clock). */
+ if((__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSE) && \
+ (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && \
+ ((READ_BIT(RCC->CFGR2,RCC_CFGR2_PREDIV1SRC)) == RCC_CFGR2_PREDIV1SRC_PLL2))
+ {
+ return HAL_ERROR;
+ }
+ else
+ {
+ if((RCC_OscInitStruct->PLL2.PLL2State) == RCC_PLL2_ON)
+ {
+ /* Check the parameters */
+ assert_param(IS_RCC_PLL2_MUL(RCC_OscInitStruct->PLL2.PLL2MUL));
+ assert_param(IS_RCC_HSE_PREDIV2(RCC_OscInitStruct->PLL2.HSEPrediv2Value));
+
+ /* Prediv2 can be written only when the PLLI2S is disabled. */
+ /* Return an error only if new value is different from the programmed value */
+ if (HAL_IS_BIT_SET(RCC->CR,RCC_CR_PLL3ON) && \
+ (__HAL_RCC_HSE_GET_PREDIV2() != RCC_OscInitStruct->PLL2.HSEPrediv2Value))
+ {
+ return HAL_ERROR;
+ }
+
+ /* Disable the main PLL2. */
+ __HAL_RCC_PLL2_DISABLE();
+
+ /* Get Start Tick */
+ tickstart = HAL_GetTick();
+
+ /* Wait till PLL2 is disabled */
+ while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLL2RDY) != RESET)
+ {
+ if((HAL_GetTick() - tickstart ) > PLL2_TIMEOUT_VALUE)
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+
+ /* Configure the HSE prediv2 factor --------------------------------*/
+ __HAL_RCC_HSE_PREDIV2_CONFIG(RCC_OscInitStruct->PLL2.HSEPrediv2Value);
+
+ /* Configure the main PLL2 multiplication factors. */
+ __HAL_RCC_PLL2_CONFIG(RCC_OscInitStruct->PLL2.PLL2MUL);
+
+ /* Enable the main PLL2. */
+ __HAL_RCC_PLL2_ENABLE();
+
+ /* Get Start Tick */
+ tickstart = HAL_GetTick();
+
+ /* Wait till PLL2 is ready */
+ while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLL2RDY) == RESET)
+ {
+ if((HAL_GetTick() - tickstart ) > PLL2_TIMEOUT_VALUE)
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+ else
+ {
+ /* Set PREDIV1 source to HSE */
+ CLEAR_BIT(RCC->CFGR2, RCC_CFGR2_PREDIV1SRC);
+
+ /* Disable the main PLL2. */
+ __HAL_RCC_PLL2_DISABLE();
+
+ /* Get Start Tick */
+ tickstart = HAL_GetTick();
+
+ /* Wait till PLL2 is disabled */
+ while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLL2RDY) != RESET)
+ {
+ if((HAL_GetTick() - tickstart ) > PLL2_TIMEOUT_VALUE)
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+ }
+ }
+
+#endif /* RCC_CR_PLL2ON */
+ /*-------------------------------- PLL Configuration -----------------------*/
+ /* Check the parameters */
+ assert_param(IS_RCC_PLL(RCC_OscInitStruct->PLL.PLLState));
+ if ((RCC_OscInitStruct->PLL.PLLState) != RCC_PLL_NONE)
+ {
+ /* Check if the PLL is used as system clock or not */
+ if(__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_PLLCLK)
+ {
+ if((RCC_OscInitStruct->PLL.PLLState) == RCC_PLL_ON)
+ {
+ /* Check the parameters */
+ assert_param(IS_RCC_PLLSOURCE(RCC_OscInitStruct->PLL.PLLSource));
+ assert_param(IS_RCC_PLL_MUL(RCC_OscInitStruct->PLL.PLLMUL));
+
+ /* Disable the main PLL. */
+ __HAL_RCC_PLL_DISABLE();
+
+ /* Get Start Tick */
+ tickstart = HAL_GetTick();
+
+ /* Wait till PLL is disabled */
+ while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) != RESET)
+ {
+ if((HAL_GetTick() - tickstart ) > PLL_TIMEOUT_VALUE)
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+
+ /* Configure the HSE prediv factor --------------------------------*/
+ /* It can be written only when the PLL is disabled. Not used in PLL source is different than HSE */
+ if(RCC_OscInitStruct->PLL.PLLSource == RCC_PLLSOURCE_HSE)
+ {
+ /* Check the parameter */
+ assert_param(IS_RCC_HSE_PREDIV(RCC_OscInitStruct->HSEPredivValue));
+#if defined(RCC_CFGR2_PREDIV1SRC)
+ assert_param(IS_RCC_PREDIV1_SOURCE(RCC_OscInitStruct->Prediv1Source));
+
+ /* Set PREDIV1 source */
+ SET_BIT(RCC->CFGR2, RCC_OscInitStruct->Prediv1Source);
+#endif /* RCC_CFGR2_PREDIV1SRC */
+
+ /* Set PREDIV1 Value */
+ __HAL_RCC_HSE_PREDIV_CONFIG(RCC_OscInitStruct->HSEPredivValue);
+ }
+
+ /* Configure the main PLL clock source and multiplication factors. */
+ __HAL_RCC_PLL_CONFIG(RCC_OscInitStruct->PLL.PLLSource,
+ RCC_OscInitStruct->PLL.PLLMUL);
+ /* Enable the main PLL. */
+ __HAL_RCC_PLL_ENABLE();
+
+ /* Get Start Tick */
+ tickstart = HAL_GetTick();
+
+ /* Wait till PLL is ready */
+ while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) == RESET)
+ {
+ if((HAL_GetTick() - tickstart ) > PLL_TIMEOUT_VALUE)
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+ else
+ {
+ /* Disable the main PLL. */
+ __HAL_RCC_PLL_DISABLE();
+
+ /* Get Start Tick */
+ tickstart = HAL_GetTick();
+
+ /* Wait till PLL is disabled */
+ while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) != RESET)
+ {
+ if((HAL_GetTick() - tickstart ) > PLL_TIMEOUT_VALUE)
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+ }
+ else
+ {
+ return HAL_ERROR;
+ }
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Initializes the CPU, AHB and APB buses clocks according to the specified
+ * parameters in the RCC_ClkInitStruct.
+ * @param RCC_ClkInitStruct pointer to an RCC_OscInitTypeDef structure that
+ * contains the configuration information for the RCC peripheral.
+ * @param FLatency FLASH Latency
+ * The value of this parameter depend on device used within the same series
+ * @note The SystemCoreClock CMSIS variable is used to store System Clock Frequency
+ * and updated by @ref HAL_RCC_GetHCLKFreq() function called within this function
+ *
+ * @note The HSI is used (enabled by hardware) as system clock source after
+ * start-up 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 start-up 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 @ref HAL_RCC_GetClockConfig() function to know which clock is
+ * currently used as system clock source.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_RCC_ClockConfig(RCC_ClkInitTypeDef *RCC_ClkInitStruct, uint32_t FLatency)
+{
+ uint32_t tickstart = 0;
+
+ /* Check the parameters */
+ assert_param(RCC_ClkInitStruct != NULL);
+ assert_param(IS_RCC_CLOCKTYPE(RCC_ClkInitStruct->ClockType));
+ assert_param(IS_FLASH_LATENCY(FLatency));
+
+ /* To correctly read data from FLASH memory, the number of wait states (LATENCY)
+ must be correctly programmed according to the frequency of the CPU clock
+ (HCLK) of the device. */
+
+#if defined(FLASH_ACR_LATENCY)
+ /* Increasing the number of wait states because of higher CPU frequency */
+ if(FLatency > (FLASH->ACR & FLASH_ACR_LATENCY))
+ {
+ /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
+ __HAL_FLASH_SET_LATENCY(FLatency);
+
+ /* Check that the new number of wait states is taken into account to access the Flash
+ memory by reading the FLASH_ACR register */
+ if((FLASH->ACR & FLASH_ACR_LATENCY) != FLatency)
+ {
+ return HAL_ERROR;
+ }
+ }
+
+#endif /* FLASH_ACR_LATENCY */
+ /*-------------------------- HCLK Configuration --------------------------*/
+ if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_HCLK) == RCC_CLOCKTYPE_HCLK)
+ {
+ assert_param(IS_RCC_HCLK(RCC_ClkInitStruct->AHBCLKDivider));
+ MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_ClkInitStruct->AHBCLKDivider);
+ }
+
+ /*------------------------- SYSCLK Configuration ---------------------------*/
+ if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_SYSCLK) == RCC_CLOCKTYPE_SYSCLK)
+ {
+ assert_param(IS_RCC_SYSCLKSOURCE(RCC_ClkInitStruct->SYSCLKSource));
+
+ /* HSE is selected as System Clock Source */
+ if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSE)
+ {
+ /* Check the HSE ready flag */
+ if(__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) == RESET)
+ {
+ return HAL_ERROR;
+ }
+ }
+ /* PLL is selected as System Clock Source */
+ else if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_PLLCLK)
+ {
+ /* Check the PLL ready flag */
+ if(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) == RESET)
+ {
+ return HAL_ERROR;
+ }
+ }
+ /* HSI is selected as System Clock Source */
+ else
+ {
+ /* Check the HSI ready flag */
+ if(__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) == RESET)
+ {
+ return HAL_ERROR;
+ }
+ }
+ __HAL_RCC_SYSCLK_CONFIG(RCC_ClkInitStruct->SYSCLKSource);
+
+ /* Get Start Tick */
+ tickstart = HAL_GetTick();
+
+ if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSE)
+ {
+ while (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_HSE)
+ {
+ if((HAL_GetTick() - tickstart ) > CLOCKSWITCH_TIMEOUT_VALUE)
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+ else if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_PLLCLK)
+ {
+ while (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_PLLCLK)
+ {
+ if((HAL_GetTick() - tickstart ) > CLOCKSWITCH_TIMEOUT_VALUE)
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+ else
+ {
+ while (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_HSI)
+ {
+ if((HAL_GetTick() - tickstart ) > CLOCKSWITCH_TIMEOUT_VALUE)
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+ }
+#if defined(FLASH_ACR_LATENCY)
+ /* Decreasing the number of wait states because of lower CPU frequency */
+ if(FLatency < (FLASH->ACR & FLASH_ACR_LATENCY))
+ {
+ /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
+ __HAL_FLASH_SET_LATENCY(FLatency);
+
+ /* Check that the new number of wait states is taken into account to access the Flash
+ memory by reading the FLASH_ACR register */
+ if((FLASH->ACR & FLASH_ACR_LATENCY) != FLatency)
+ {
+ return HAL_ERROR;
+ }
+ }
+#endif /* FLASH_ACR_LATENCY */
+
+ /*-------------------------- PCLK1 Configuration ---------------------------*/
+ if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK1) == RCC_CLOCKTYPE_PCLK1)
+ {
+ assert_param(IS_RCC_PCLK(RCC_ClkInitStruct->APB1CLKDivider));
+ MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE1, RCC_ClkInitStruct->APB1CLKDivider);
+ }
+
+ /*-------------------------- PCLK2 Configuration ---------------------------*/
+ if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK2) == RCC_CLOCKTYPE_PCLK2)
+ {
+ assert_param(IS_RCC_PCLK(RCC_ClkInitStruct->APB2CLKDivider));
+ MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE2, ((RCC_ClkInitStruct->APB2CLKDivider) << 3));
+ }
+
+ /* Update the SystemCoreClock global variable */
+ SystemCoreClock = HAL_RCC_GetSysClockFreq() >> AHBPrescTable[(RCC->CFGR & RCC_CFGR_HPRE)>> RCC_CFGR_HPRE_BITNUMBER];
+
+ /* Configure the source of time base considering new system clocks settings*/
+ HAL_InitTick (TICK_INT_PRIORITY);
+
+ return HAL_OK;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup RCC_Exported_Functions_Group2 Peripheral Control functions
+ * @brief RCC clocks control functions
+ *
+ @verbatim
+ ===============================================================================
+ ##### Peripheral Control functions #####
+ ===============================================================================
+ [..]
+ This subsection provides a set of functions allowing to control the RCC Clocks
+ frequencies.
+
+ @endverbatim
+ * @{
+ */
+
+/**
+ * @brief Selects the clock source to output on MCO pin.
+ * @note MCO pin should be configured in alternate function mode.
+ * @param RCC_MCOx specifies the output direction for the clock source.
+ * This parameter can be one of the following values:
+ * @arg @ref RCC_MCO1 Clock source to output on MCO1 pin(PA8).
+ * @param RCC_MCOSource specifies the clock source to output.
+ * This parameter can be one of the following values:
+ * @arg @ref RCC_MCO1SOURCE_NOCLOCK No clock selected as MCO clock
+ * @arg @ref RCC_MCO1SOURCE_SYSCLK System clock selected as MCO clock
+ * @arg @ref RCC_MCO1SOURCE_HSI HSI selected as MCO clock
+ * @arg @ref RCC_MCO1SOURCE_HSE HSE selected as MCO clock
+ @if STM32F105xC
+ * @arg @ref RCC_MCO1SOURCE_PLLCLK PLL clock divided by 2 selected as MCO source
+ * @arg @ref RCC_MCO1SOURCE_PLL2CLK PLL2 clock selected as MCO source
+ * @arg @ref RCC_MCO1SOURCE_PLL3CLK_DIV2 PLL3 clock divided by 2 selected as MCO source
+ * @arg @ref RCC_MCO1SOURCE_EXT_HSE XT1 external 3-25 MHz oscillator clock selected as MCO source
+ * @arg @ref RCC_MCO1SOURCE_PLL3CLK PLL3 clock selected as MCO source
+ @endif
+ @if STM32F107xC
+ * @arg @ref RCC_MCO1SOURCE_PLLCLK PLL clock divided by 2 selected as MCO source
+ * @arg @ref RCC_MCO1SOURCE_PLL2CLK PLL2 clock selected as MCO source
+ * @arg @ref RCC_MCO1SOURCE_PLL3CLK_DIV2 PLL3 clock divided by 2 selected as MCO source
+ * @arg @ref RCC_MCO1SOURCE_EXT_HSE XT1 external 3-25 MHz oscillator clock selected as MCO source
+ * @arg @ref RCC_MCO1SOURCE_PLL3CLK PLL3 clock selected as MCO source
+ @endif
+ * @param RCC_MCODiv specifies the MCO DIV.
+ * This parameter can be one of the following values:
+ * @arg @ref RCC_MCODIV_1 no division applied to MCO clock
+ * @retval None
+ */
+void HAL_RCC_MCOConfig(uint32_t RCC_MCOx, uint32_t RCC_MCOSource, uint32_t RCC_MCODiv)
+{
+ GPIO_InitTypeDef gpio = {0};
+
+ /* Check the parameters */
+ assert_param(IS_RCC_MCO(RCC_MCOx));
+ assert_param(IS_RCC_MCODIV(RCC_MCODiv));
+ assert_param(IS_RCC_MCO1SOURCE(RCC_MCOSource));
+
+ /* Configure the MCO1 pin in alternate function mode */
+ gpio.Mode = GPIO_MODE_AF_PP;
+ gpio.Speed = GPIO_SPEED_FREQ_HIGH;
+ gpio.Pull = GPIO_NOPULL;
+ gpio.Pin = MCO1_PIN;
+
+ /* MCO1 Clock Enable */
+ MCO1_CLK_ENABLE();
+
+ HAL_GPIO_Init(MCO1_GPIO_PORT, &gpio);
+
+ /* Configure the MCO clock source */
+ __HAL_RCC_MCO1_CONFIG(RCC_MCOSource, RCC_MCODiv);
+}
+
+/**
+ * @brief Enables the Clock Security System.
+ * @note If a failure is detected on the HSE oscillator clock, this oscillator
+ * is automatically disabled and an interrupt is generated to inform the
+ * software about the failure (Clock Security System Interrupt, CSSI),
+ * allowing the MCU to perform rescue operations. The CSSI is linked to
+ * the Cortex-M3 NMI (Non-Maskable Interrupt) exception vector.
+ * @retval None
+ */
+void HAL_RCC_EnableCSS(void)
+{
+ *(__IO uint32_t *) RCC_CR_CSSON_BB = (uint32_t)ENABLE;
+}
+
+/**
+ * @brief Disables the Clock Security System.
+ * @retval None
+ */
+void HAL_RCC_DisableCSS(void)
+{
+ *(__IO uint32_t *) RCC_CR_CSSON_BB = (uint32_t)DISABLE;
+}
+
+/**
+ * @brief Returns the SYSCLK frequency
+ * @note The system frequency computed by this function is not the real
+ * frequency in the chip. It is calculated based on the predefined
+ * constant and the selected clock source:
+ * @note If SYSCLK source is HSI, function returns values based on HSI_VALUE(*)
+ * @note If SYSCLK source is HSE, function returns a value based on HSE_VALUE
+ * divided by PREDIV factor(**)
+ * @note If SYSCLK source is PLL, function returns a value based on HSE_VALUE
+ * divided by PREDIV factor(**) or HSI_VALUE(*) multiplied by the PLL factor.
+ * @note (*) HSI_VALUE is a constant defined in stm32f1xx_hal_conf.h file (default value
+ * 8 MHz) but the real value may vary depending on the variations
+ * in voltage and temperature.
+ * @note (**) HSE_VALUE is a constant defined in stm32f1xx_hal_conf.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
+ * have wrong result.
+ *
+ * @note The result of this function could be not correct when using fractional
+ * value for HSE crystal.
+ *
+ * @note This function can be used by the user application to compute the
+ * baud-rate for the communication peripherals or configure other parameters.
+ *
+ * @note Each time SYSCLK changes, this function must be called to update the
+ * right SYSCLK value. Otherwise, any configuration based on this function will be incorrect.
+ *
+ * @retval SYSCLK frequency
+ */
+uint32_t HAL_RCC_GetSysClockFreq(void)
+{
+#if defined(RCC_CFGR2_PREDIV1SRC)
+ const uint8_t aPLLMULFactorTable[12] = {0, 0, 4, 5, 6, 7, 8, 9, 0, 0, 0, 13};
+ const uint8_t aPredivFactorTable[16] = { 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11, 12, 13, 14, 15, 16};
+#else
+ const uint8_t aPLLMULFactorTable[16] = { 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 16};
+#if defined(RCC_CFGR2_PREDIV1)
+ const uint8_t aPredivFactorTable[16] = { 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11, 12, 13, 14, 15, 16};
+#else
+ const uint8_t aPredivFactorTable[2] = { 1, 2};
+#endif /*RCC_CFGR2_PREDIV1*/
+
+#endif
+ uint32_t tmpreg = 0, prediv = 0, pllclk = 0, pllmul = 0;
+ uint32_t sysclockfreq = 0;
+#if defined(RCC_CFGR2_PREDIV1SRC)
+ uint32_t prediv2 = 0, pll2mul = 0;
+#endif /*RCC_CFGR2_PREDIV1SRC*/
+
+ tmpreg = RCC->CFGR;
+
+ /* Get SYSCLK source -------------------------------------------------------*/
+ switch (tmpreg & RCC_CFGR_SWS)
+ {
+ case RCC_SYSCLKSOURCE_STATUS_HSE: /* HSE used as system clock */
+ {
+ sysclockfreq = HSE_VALUE;
+ break;
+ }
+ case RCC_SYSCLKSOURCE_STATUS_PLLCLK: /* PLL used as system clock */
+ {
+ pllmul = aPLLMULFactorTable[(uint32_t)(tmpreg & RCC_CFGR_PLLMULL) >> POSITION_VAL(RCC_CFGR_PLLMULL)];
+ if ((tmpreg & RCC_CFGR_PLLSRC) != RCC_PLLSOURCE_HSI_DIV2)
+ {
+#if defined(RCC_CFGR2_PREDIV1)
+ prediv = aPredivFactorTable[(uint32_t)(RCC->CFGR2 & RCC_CFGR2_PREDIV1) >> POSITION_VAL(RCC_CFGR2_PREDIV1)];
+#else
+ prediv = aPredivFactorTable[(uint32_t)(RCC->CFGR & RCC_CFGR_PLLXTPRE) >> POSITION_VAL(RCC_CFGR_PLLXTPRE)];
+#endif /*RCC_CFGR2_PREDIV1*/
+#if defined(RCC_CFGR2_PREDIV1SRC)
+
+ if(HAL_IS_BIT_SET(RCC->CFGR2, RCC_CFGR2_PREDIV1SRC))
+ {
+ /* PLL2 selected as Prediv1 source */
+ /* PLLCLK = PLL2CLK / PREDIV1 * PLLMUL with PLL2CLK = HSE/PREDIV2 * PLL2MUL */
+ prediv2 = ((RCC->CFGR2 & RCC_CFGR2_PREDIV2) >> POSITION_VAL(RCC_CFGR2_PREDIV2)) + 1;
+ pll2mul = ((RCC->CFGR2 & RCC_CFGR2_PLL2MUL) >> POSITION_VAL(RCC_CFGR2_PLL2MUL)) + 2;
+ pllclk = (uint32_t)((((HSE_VALUE / prediv2) * pll2mul) / prediv) * pllmul);
+ }
+ else
+ {
+ /* HSE used as PLL clock source : PLLCLK = HSE/PREDIV1 * PLLMUL */
+ pllclk = (uint32_t)((HSE_VALUE / prediv) * pllmul);
+ }
+
+ /* If PLLMUL was set to 13 means that it was to cover the case PLLMUL 6.5 (avoid using float) */
+ /* In this case need to divide pllclk by 2 */
+ if (pllmul == aPLLMULFactorTable[(uint32_t)(RCC_CFGR_PLLMULL6_5) >> POSITION_VAL(RCC_CFGR_PLLMULL)])
+ {
+ pllclk = pllclk / 2;
+ }
+#else
+ /* HSE used as PLL clock source : PLLCLK = HSE/PREDIV1 * PLLMUL */
+ pllclk = (uint32_t)((HSE_VALUE / prediv) * pllmul);
+#endif /*RCC_CFGR2_PREDIV1SRC*/
+ }
+ else
+ {
+ /* HSI used as PLL clock source : PLLCLK = HSI/2 * PLLMUL */
+ pllclk = (uint32_t)((HSI_VALUE >> 1) * pllmul);
+ }
+ sysclockfreq = pllclk;
+ break;
+ }
+ case RCC_SYSCLKSOURCE_STATUS_HSI: /* HSI used as system clock source */
+ default: /* HSI used as system clock */
+ {
+ sysclockfreq = HSI_VALUE;
+ break;
+ }
+ }
+ return sysclockfreq;
+}
+
+/**
+ * @brief Returns the HCLK frequency
+ * @note Each time HCLK changes, this function must be called to update the
+ * right HCLK value. Otherwise, any configuration based on this function will be incorrect.
+ *
+ * @note The SystemCoreClock CMSIS variable is used to store System Clock Frequency
+ * and updated within this function
+ * @retval HCLK frequency
+ */
+uint32_t HAL_RCC_GetHCLKFreq(void)
+{
+ return SystemCoreClock;
+}
+
+/**
+ * @brief Returns the PCLK1 frequency
+ * @note Each time PCLK1 changes, this function must be called to update the
+ * right PCLK1 value. Otherwise, any configuration based on this function will be incorrect.
+ * @retval PCLK1 frequency
+ */
+uint32_t HAL_RCC_GetPCLK1Freq(void)
+{
+ /* Get HCLK source and Compute PCLK1 frequency ---------------------------*/
+ return (HAL_RCC_GetHCLKFreq() >> APBPrescTable[(RCC->CFGR & RCC_CFGR_PPRE1) >> RCC_CFGR_PPRE1_BITNUMBER]);
+}
+
+/**
+ * @brief Returns the PCLK2 frequency
+ * @note Each time PCLK2 changes, this function must be called to update the
+ * right PCLK2 value. Otherwise, any configuration based on this function will be incorrect.
+ * @retval PCLK2 frequency
+ */
+uint32_t HAL_RCC_GetPCLK2Freq(void)
+{
+ /* Get HCLK source and Compute PCLK2 frequency ---------------------------*/
+ return (HAL_RCC_GetHCLKFreq()>> APBPrescTable[(RCC->CFGR & RCC_CFGR_PPRE2) >> RCC_CFGR_PPRE2_BITNUMBER]);
+}
+
+/**
+ * @brief Configures the RCC_OscInitStruct according to the internal
+ * RCC configuration registers.
+ * @param RCC_OscInitStruct pointer to an RCC_OscInitTypeDef structure that
+ * will be configured.
+ * @retval None
+ */
+void HAL_RCC_GetOscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct)
+{
+ /* Check the parameters */
+ assert_param(RCC_OscInitStruct != NULL);
+
+ /* Set all possible values for the Oscillator type parameter ---------------*/
+ RCC_OscInitStruct->OscillatorType = RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_HSI \
+ | RCC_OSCILLATORTYPE_LSE | RCC_OSCILLATORTYPE_LSI;
+
+#if defined(RCC_CFGR2_PREDIV1SRC)
+ /* Get the Prediv1 source --------------------------------------------------*/
+ RCC_OscInitStruct->Prediv1Source = READ_BIT(RCC->CFGR2,RCC_CFGR2_PREDIV1SRC);
+#endif /* RCC_CFGR2_PREDIV1SRC */
+
+ /* Get the HSE configuration -----------------------------------------------*/
+ if((RCC->CR &RCC_CR_HSEBYP) == RCC_CR_HSEBYP)
+ {
+ RCC_OscInitStruct->HSEState = RCC_HSE_BYPASS;
+ }
+ else if((RCC->CR &RCC_CR_HSEON) == RCC_CR_HSEON)
+ {
+ RCC_OscInitStruct->HSEState = RCC_HSE_ON;
+ }
+ else
+ {
+ RCC_OscInitStruct->HSEState = RCC_HSE_OFF;
+ }
+ RCC_OscInitStruct->HSEPredivValue = __HAL_RCC_HSE_GET_PREDIV();
+
+ /* Get the HSI configuration -----------------------------------------------*/
+ if((RCC->CR &RCC_CR_HSION) == RCC_CR_HSION)
+ {
+ RCC_OscInitStruct->HSIState = RCC_HSI_ON;
+ }
+ else
+ {
+ RCC_OscInitStruct->HSIState = RCC_HSI_OFF;
+ }
+
+ RCC_OscInitStruct->HSICalibrationValue = (uint32_t)((RCC->CR & RCC_CR_HSITRIM) >> POSITION_VAL(RCC_CR_HSITRIM));
+
+ /* Get the LSE configuration -----------------------------------------------*/
+ if((RCC->BDCR &RCC_BDCR_LSEBYP) == RCC_BDCR_LSEBYP)
+ {
+ RCC_OscInitStruct->LSEState = RCC_LSE_BYPASS;
+ }
+ else if((RCC->BDCR &RCC_BDCR_LSEON) == RCC_BDCR_LSEON)
+ {
+ RCC_OscInitStruct->LSEState = RCC_LSE_ON;
+ }
+ else
+ {
+ RCC_OscInitStruct->LSEState = RCC_LSE_OFF;
+ }
+
+ /* Get the LSI configuration -----------------------------------------------*/
+ if((RCC->CSR &RCC_CSR_LSION) == RCC_CSR_LSION)
+ {
+ RCC_OscInitStruct->LSIState = RCC_LSI_ON;
+ }
+ else
+ {
+ RCC_OscInitStruct->LSIState = RCC_LSI_OFF;
+ }
+
+
+ /* Get the PLL configuration -----------------------------------------------*/
+ if((RCC->CR &RCC_CR_PLLON) == RCC_CR_PLLON)
+ {
+ RCC_OscInitStruct->PLL.PLLState = RCC_PLL_ON;
+ }
+ else
+ {
+ RCC_OscInitStruct->PLL.PLLState = RCC_PLL_OFF;
+ }
+ RCC_OscInitStruct->PLL.PLLSource = (uint32_t)(RCC->CFGR & RCC_CFGR_PLLSRC);
+ RCC_OscInitStruct->PLL.PLLMUL = (uint32_t)(RCC->CFGR & RCC_CFGR_PLLMULL);
+#if defined(RCC_CR_PLL2ON)
+ /* Get the PLL2 configuration -----------------------------------------------*/
+ if((RCC->CR &RCC_CR_PLL2ON) == RCC_CR_PLL2ON)
+ {
+ RCC_OscInitStruct->PLL2.PLL2State = RCC_PLL2_ON;
+ }
+ else
+ {
+ RCC_OscInitStruct->PLL2.PLL2State = RCC_PLL2_OFF;
+ }
+ RCC_OscInitStruct->PLL2.HSEPrediv2Value = __HAL_RCC_HSE_GET_PREDIV2();
+ RCC_OscInitStruct->PLL2.PLL2MUL = (uint32_t)(RCC->CFGR2 & RCC_CFGR2_PLL2MUL);
+#endif /* RCC_CR_PLL2ON */
+}
+
+/**
+ * @brief Get the RCC_ClkInitStruct according to the internal
+ * RCC configuration registers.
+ * @param RCC_ClkInitStruct pointer to an RCC_ClkInitTypeDef structure that
+ * contains the current clock configuration.
+ * @param pFLatency Pointer on the Flash Latency.
+ * @retval None
+ */
+void HAL_RCC_GetClockConfig(RCC_ClkInitTypeDef *RCC_ClkInitStruct, uint32_t *pFLatency)
+{
+ /* Check the parameters */
+ assert_param(RCC_ClkInitStruct != NULL);
+ assert_param(pFLatency != NULL);
+
+ /* Set all possible values for the Clock type parameter --------------------*/
+ RCC_ClkInitStruct->ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
+
+ /* Get the SYSCLK configuration --------------------------------------------*/
+ RCC_ClkInitStruct->SYSCLKSource = (uint32_t)(RCC->CFGR & RCC_CFGR_SW);
+
+ /* Get the HCLK configuration ----------------------------------------------*/
+ RCC_ClkInitStruct->AHBCLKDivider = (uint32_t)(RCC->CFGR & RCC_CFGR_HPRE);
+
+ /* Get the APB1 configuration ----------------------------------------------*/
+ RCC_ClkInitStruct->APB1CLKDivider = (uint32_t)(RCC->CFGR & RCC_CFGR_PPRE1);
+
+ /* Get the APB2 configuration ----------------------------------------------*/
+ RCC_ClkInitStruct->APB2CLKDivider = (uint32_t)((RCC->CFGR & RCC_CFGR_PPRE2) >> 3);
+
+#if defined(FLASH_ACR_LATENCY)
+ /* Get the Flash Wait State (Latency) configuration ------------------------*/
+ *pFLatency = (uint32_t)(FLASH->ACR & FLASH_ACR_LATENCY);
+#else
+ /* For VALUE lines devices, only LATENCY_0 can be set*/
+ *pFLatency = (uint32_t)FLASH_LATENCY_0;
+#endif
+}
+
+/**
+ * @brief This function handles the RCC CSS interrupt request.
+ * @note This API should be called under the NMI_Handler().
+ * @retval None
+ */
+void HAL_RCC_NMI_IRQHandler(void)
+{
+ /* Check RCC CSSF flag */
+ if(__HAL_RCC_GET_IT(RCC_IT_CSS))
+ {
+ /* RCC Clock Security System interrupt user callback */
+ HAL_RCC_CSSCallback();
+
+ /* Clear RCC CSS pending bit */
+ __HAL_RCC_CLEAR_IT(RCC_IT_CSS);
+ }
+}
+
+/**
+ * @brief RCC Clock Security System interrupt callback
+ * @retval none
+ */
+__weak void HAL_RCC_CSSCallback(void)
+{
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_RCC_CSSCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* HAL_RCC_MODULE_ENABLED */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/bsp/radio-controller-1/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc_ex.c b/bsp/radio-controller-1/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc_ex.c
new file mode 100644
index 0000000..7f863f5
--- /dev/null
+++ b/bsp/radio-controller-1/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc_ex.c
@@ -0,0 +1,870 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_rcc_ex.c
+ * @author MCD Application Team
+ * @version V1.0.4
+ * @date 29-April-2016
+ * @brief Extended RCC HAL module driver.
+ * This file provides firmware functions to manage the following
+ * functionalities RCC extension peripheral:
+ * + Extended Peripheral Control functions
+ *
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+#ifdef HAL_RCC_MODULE_ENABLED
+
+/** @defgroup RCCEx RCCEx
+ * @brief RCC Extension HAL module driver.
+ * @{
+ */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/** @defgroup RCCEx_Private_Constants RCCEx Private Constants
+ * @{
+ */
+/**
+ * @}
+ */
+
+/* Private macro -------------------------------------------------------------*/
+/** @defgroup RCCEx_Private_Macros RCCEx Private Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+/** @defgroup RCCEx_Exported_Functions RCCEx Exported Functions
+ * @{
+ */
+
+/** @defgroup RCCEx_Exported_Functions_Group1 Peripheral Control functions
+ * @brief Extended Peripheral Control functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Extended Peripheral Control functions #####
+ ===============================================================================
+ [..]
+ This subsection provides a set of functions allowing to control the RCC Clocks
+ frequencies.
+ [..]
+ (@) Important note: Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to
+ select the RTC clock source; in this case the Backup domain will be reset in
+ order to modify the RTC Clock source, as consequence RTC registers (including
+ the backup registers) are set to their reset values.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Initializes the RCC extended peripherals clocks according to the specified parameters in the
+ * RCC_PeriphCLKInitTypeDef.
+ * @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that
+ * contains the configuration information for the Extended Peripherals clocks(RTC clock).
+ *
+ * @note Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to select
+ * the RTC clock source; in this case the Backup domain will be reset in
+ * order to modify the RTC Clock source, as consequence RTC registers (including
+ * the backup registers) are set to their reset values.
+ *
+ * @note In case of STM32F105xC or STM32F107xC devices, PLLI2S will be enabled if requested on
+ * one of 2 I2S interfaces. When PLLI2S is enabled, you need to call HAL_RCCEx_DisablePLLI2S to
+ * manually disable it.
+ *
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)
+{
+ uint32_t tickstart = 0, temp_reg = 0;
+#if defined(STM32F105xC) || defined(STM32F107xC)
+ uint32_t pllactive = 0;
+#endif /* STM32F105xC || STM32F107xC */
+
+ /* Check the parameters */
+ assert_param(IS_RCC_PERIPHCLOCK(PeriphClkInit->PeriphClockSelection));
+
+ /*------------------------------- RTC/LCD Configuration ------------------------*/
+ if ((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RTC) == RCC_PERIPHCLK_RTC))
+ {
+ /* check for RTC Parameters used to output RTCCLK */
+ assert_param(IS_RCC_RTCCLKSOURCE(PeriphClkInit->RTCClockSelection));
+
+ /* Enable Power Clock*/
+ __HAL_RCC_PWR_CLK_ENABLE();
+
+ /* Enable write access to Backup domain */
+ SET_BIT(PWR->CR, PWR_CR_DBP);
+
+ /* Wait for Backup domain Write protection disable */
+ tickstart = HAL_GetTick();
+
+ while((PWR->CR & PWR_CR_DBP) == RESET)
+ {
+ if((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE)
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+
+ /* Reset the Backup domain only if the RTC Clock source selection is modified from reset value */
+ temp_reg = (RCC->BDCR & RCC_BDCR_RTCSEL);
+ if((temp_reg != 0x00000000U) && (temp_reg != (PeriphClkInit->RTCClockSelection & RCC_BDCR_RTCSEL)))
+ {
+ /* Store the content of BDCR register before the reset of Backup Domain */
+ temp_reg = (RCC->BDCR & ~(RCC_BDCR_RTCSEL));
+ /* RTC Clock selection can be changed only if the Backup Domain is reset */
+ __HAL_RCC_BACKUPRESET_FORCE();
+ __HAL_RCC_BACKUPRESET_RELEASE();
+ /* Restore the Content of BDCR register */
+ RCC->BDCR = temp_reg;
+
+ /* Wait for LSERDY if LSE was enabled */
+ if (HAL_IS_BIT_SET(temp_reg, RCC_BDCR_LSEON))
+ {
+ /* Get timeout */
+ tickstart = HAL_GetTick();
+
+ /* Wait till LSE is ready */
+ while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET)
+ {
+ if((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+ }
+ __HAL_RCC_RTC_CONFIG(PeriphClkInit->RTCClockSelection);
+ }
+
+ /*------------------------------ ADC clock Configuration ------------------*/
+ if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_ADC) == RCC_PERIPHCLK_ADC)
+ {
+ /* Check the parameters */
+ assert_param(IS_RCC_ADCPLLCLK_DIV(PeriphClkInit->AdcClockSelection));
+
+ /* Configure the ADC clock source */
+ __HAL_RCC_ADC_CONFIG(PeriphClkInit->AdcClockSelection);
+ }
+
+#if defined(STM32F105xC) || defined(STM32F107xC)
+ /*------------------------------ I2S2 Configuration ------------------------*/
+ if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S2) == RCC_PERIPHCLK_I2S2)
+ {
+ /* Check the parameters */
+ assert_param(IS_RCC_I2S2CLKSOURCE(PeriphClkInit->I2s2ClockSelection));
+
+ /* Configure the I2S2 clock source */
+ __HAL_RCC_I2S2_CONFIG(PeriphClkInit->I2s2ClockSelection);
+ }
+
+ /*------------------------------ I2S3 Configuration ------------------------*/
+ if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S3) == RCC_PERIPHCLK_I2S3)
+ {
+ /* Check the parameters */
+ assert_param(IS_RCC_I2S3CLKSOURCE(PeriphClkInit->I2s3ClockSelection));
+
+ /* Configure the I2S3 clock source */
+ __HAL_RCC_I2S3_CONFIG(PeriphClkInit->I2s3ClockSelection);
+ }
+
+ /*------------------------------ PLL I2S Configuration ----------------------*/
+ /* Check that PLLI2S need to be enabled */
+ if (HAL_IS_BIT_SET(RCC->CFGR2, RCC_CFGR2_I2S2SRC) || HAL_IS_BIT_SET(RCC->CFGR2, RCC_CFGR2_I2S3SRC))
+ {
+ /* Update flag to indicate that PLL I2S should be active */
+ pllactive = 1;
+ }
+
+ /* Check if PLL I2S need to be enabled */
+ if (pllactive == 1)
+ {
+ /* Enable PLL I2S only if not active */
+ if (HAL_IS_BIT_CLR(RCC->CR, RCC_CR_PLL3ON))
+ {
+ /* Check the parameters */
+ assert_param(IS_RCC_PLLI2S_MUL(PeriphClkInit->PLLI2S.PLLI2SMUL));
+ assert_param(IS_RCC_HSE_PREDIV2(PeriphClkInit->PLLI2S.HSEPrediv2Value));
+
+ /* Prediv2 can be written only when the PLL2 is disabled. */
+ /* Return an error only if new value is different from the programmed value */
+ if (HAL_IS_BIT_SET(RCC->CR,RCC_CR_PLL2ON) && \
+ (__HAL_RCC_HSE_GET_PREDIV2() != PeriphClkInit->PLLI2S.HSEPrediv2Value))
+ {
+ return HAL_ERROR;
+ }
+
+ /* Configure the HSE prediv2 factor --------------------------------*/
+ __HAL_RCC_HSE_PREDIV2_CONFIG(PeriphClkInit->PLLI2S.HSEPrediv2Value);
+
+ /* Configure the main PLLI2S multiplication factors. */
+ __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SMUL);
+
+ /* Enable the main PLLI2S. */
+ __HAL_RCC_PLLI2S_ENABLE();
+
+ /* Get Start Tick*/
+ tickstart = HAL_GetTick();
+
+ /* Wait till PLLI2S is ready */
+ while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) == RESET)
+ {
+ if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE)
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+ else
+ {
+ /* Return an error only if user wants to change the PLLI2SMUL whereas PLLI2S is active */
+ if (READ_BIT(RCC->CFGR2, RCC_CFGR2_PLL3MUL) != PeriphClkInit->PLLI2S.PLLI2SMUL)
+ {
+ return HAL_ERROR;
+ }
+ }
+ }
+#endif /* STM32F105xC || STM32F107xC */
+
+#if defined(STM32F102x6) || defined(STM32F102xB) || defined(STM32F103x6)\
+ || defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG)\
+ || defined(STM32F105xC) || defined(STM32F107xC)
+ /*------------------------------ USB clock Configuration ------------------*/
+ if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USB) == RCC_PERIPHCLK_USB)
+ {
+ /* Check the parameters */
+ assert_param(IS_RCC_USBPLLCLK_DIV(PeriphClkInit->UsbClockSelection));
+
+ /* Configure the USB clock source */
+ __HAL_RCC_USB_CONFIG(PeriphClkInit->UsbClockSelection);
+ }
+#endif /* STM32F102x6 || STM32F102xB || STM32F103x6 || STM32F103xB || STM32F103xE || STM32F103xG || STM32F105xC || STM32F107xC */
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Get the PeriphClkInit according to the internal
+ * RCC configuration registers.
+ * @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that
+ * returns the configuration information for the Extended Peripherals clocks(RTC, I2S, ADC clocks).
+ * @retval None
+ */
+void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)
+{
+ uint32_t srcclk = 0;
+
+ /* Set all possible values for the extended clock type parameter------------*/
+ PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_RTC;
+
+ /* Get the RTC configuration -----------------------------------------------*/
+ srcclk = __HAL_RCC_GET_RTC_SOURCE();
+ /* Source clock is LSE or LSI*/
+ PeriphClkInit->RTCClockSelection = srcclk;
+
+ /* Get the ADC clock configuration -----------------------------------------*/
+ PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_ADC;
+ PeriphClkInit->AdcClockSelection = __HAL_RCC_GET_ADC_SOURCE();
+
+#if defined(STM32F105xC) || defined(STM32F107xC)
+ /* Get the I2S2 clock configuration -----------------------------------------*/
+ PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_I2S2;
+ PeriphClkInit->I2s2ClockSelection = __HAL_RCC_GET_I2S2_SOURCE();
+
+ /* Get the I2S3 clock configuration -----------------------------------------*/
+ PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_I2S3;
+ PeriphClkInit->I2s3ClockSelection = __HAL_RCC_GET_I2S3_SOURCE();
+
+#endif /* STM32F105xC || STM32F107xC */
+
+#if defined(STM32F103xE) || defined(STM32F103xG)
+ /* Get the I2S2 clock configuration -----------------------------------------*/
+ PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_I2S2;
+ PeriphClkInit->I2s2ClockSelection = RCC_I2S2CLKSOURCE_SYSCLK;
+
+ /* Get the I2S3 clock configuration -----------------------------------------*/
+ PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_I2S3;
+ PeriphClkInit->I2s3ClockSelection = RCC_I2S3CLKSOURCE_SYSCLK;
+
+#endif /* STM32F103xE || STM32F103xG */
+
+#if defined(STM32F102x6) || defined(STM32F102xB) || defined(STM32F103x6)\
+ || defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG)\
+ || defined(STM32F105xC) || defined(STM32F107xC)
+ /* Get the USB clock configuration -----------------------------------------*/
+ PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_USB;
+ PeriphClkInit->UsbClockSelection = __HAL_RCC_GET_USB_SOURCE();
+#endif /* STM32F102x6 || STM32F102xB || STM32F103x6 || STM32F103xB || STM32F103xE || STM32F103xG || STM32F105xC || STM32F107xC */
+}
+
+/**
+ * @brief Returns the peripheral clock frequency
+ * @note Returns 0 if peripheral clock is unknown
+ * @param PeriphClk Peripheral clock identifier
+ * This parameter can be one of the following values:
+ * @arg @ref RCC_PERIPHCLK_RTC RTC peripheral clock
+ * @arg @ref RCC_PERIPHCLK_ADC ADC peripheral clock
+ @if STM32F103xE
+ * @arg @ref RCC_PERIPHCLK_I2S2 I2S2 peripheral clock
+ * @arg @ref RCC_PERIPHCLK_I2S3 I2S3 peripheral clock
+ * @arg @ref RCC_PERIPHCLK_I2S3 I2S3 peripheral clock
+ @endif
+ @if STM32F103xG
+ * @arg @ref RCC_PERIPHCLK_I2S2 I2S2 peripheral clock
+ * @arg @ref RCC_PERIPHCLK_I2S3 I2S3 peripheral clock
+ * @arg @ref RCC_PERIPHCLK_I2S3 I2S3 peripheral clock
+ * @arg @ref RCC_PERIPHCLK_I2S2 I2S2 peripheral clock
+ @endif
+ @if STM32F105xC
+ * @arg @ref RCC_PERIPHCLK_I2S2 I2S2 peripheral clock
+ * @arg @ref RCC_PERIPHCLK_I2S3 I2S3 peripheral clock
+ * @arg @ref RCC_PERIPHCLK_I2S3 I2S3 peripheral clock
+ * @arg @ref RCC_PERIPHCLK_I2S2 I2S2 peripheral clock
+ * @arg @ref RCC_PERIPHCLK_I2S3 I2S3 peripheral clock
+ * @arg @ref RCC_PERIPHCLK_I2S3 I2S3 peripheral clock
+ * @arg @ref RCC_PERIPHCLK_I2S2 I2S2 peripheral clock
+ * @arg @ref RCC_PERIPHCLK_USB USB peripheral clock
+ @endif
+ @if STM32F107xC
+ * @arg @ref RCC_PERIPHCLK_I2S2 I2S2 peripheral clock
+ * @arg @ref RCC_PERIPHCLK_I2S3 I2S3 peripheral clock
+ * @arg @ref RCC_PERIPHCLK_I2S3 I2S3 peripheral clock
+ * @arg @ref RCC_PERIPHCLK_I2S2 I2S2 peripheral clock
+ * @arg @ref RCC_PERIPHCLK_I2S3 I2S3 peripheral clock
+ * @arg @ref RCC_PERIPHCLK_I2S3 I2S3 peripheral clock
+ * @arg @ref RCC_PERIPHCLK_I2S2 I2S2 peripheral clock
+ * @arg @ref RCC_PERIPHCLK_USB USB peripheral clock
+ @endif
+ @if STM32F102xx
+ * @arg @ref RCC_PERIPHCLK_USB USB peripheral clock
+ @endif
+ @if STM32F103xx
+ * @arg @ref RCC_PERIPHCLK_USB USB peripheral clock
+ @endif
+ * @retval Frequency in Hz (0: means that no available frequency for the peripheral)
+ */
+uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk)
+{
+#if defined(STM32F102x6) || defined(STM32F102xB) || defined(STM32F103x6)\
+ || defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG)\
+ || defined(STM32F105xC) || defined(STM32F107xC)
+#if defined(STM32F105xC) || defined(STM32F107xC)
+ const uint8_t aPLLMULFactorTable[12] = {0, 0, 4, 5, 6, 7, 8, 9, 0, 0, 0, 13};
+ const uint8_t aPredivFactorTable[16] = { 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11, 12, 13, 14, 15, 16};
+#else
+ const uint8_t aPLLMULFactorTable[16] = { 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 16};
+ const uint8_t aPredivFactorTable[2] = { 1, 2};
+#endif
+#endif
+ uint32_t temp_reg = 0, frequency = 0;
+#if defined(STM32F102x6) || defined(STM32F102xB) || defined(STM32F103x6)\
+ || defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG)\
+ || defined(STM32F105xC) || defined(STM32F107xC)
+ uint32_t prediv1 = 0, pllclk = 0, pllmul = 0;
+#endif /* STM32F102x6 || STM32F102xB || STM32F103x6 || STM32F103xB || STM32F103xE || STM32F103xG || STM32F105xC || STM32F107xC */
+#if defined(STM32F105xC) || defined(STM32F107xC)
+ uint32_t pll2mul = 0, pll3mul = 0, prediv2 = 0;
+#endif /* STM32F105xC || STM32F107xC */
+
+ /* Check the parameters */
+ assert_param(IS_RCC_PERIPHCLOCK(PeriphClk));
+
+ switch (PeriphClk)
+ {
+#if defined(STM32F102x6) || defined(STM32F102xB) || defined(STM32F103x6)\
+ || defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG)\
+ || defined(STM32F105xC) || defined(STM32F107xC)
+ case RCC_PERIPHCLK_USB:
+ {
+ /* Get RCC configuration ------------------------------------------------------*/
+ temp_reg = RCC->CFGR;
+
+ /* Check if PLL is enabled */
+ if (HAL_IS_BIT_SET(RCC->CR,RCC_CR_PLLON))
+ {
+ pllmul = aPLLMULFactorTable[(uint32_t)(temp_reg & RCC_CFGR_PLLMULL) >> POSITION_VAL(RCC_CFGR_PLLMULL)];
+ if ((temp_reg & RCC_CFGR_PLLSRC) != RCC_PLLSOURCE_HSI_DIV2)
+ {
+#if defined(STM32F105xC) || defined(STM32F107xC) || defined(STM32F100xB)\
+ || defined(STM32F100xE)
+ prediv1 = aPredivFactorTable[(uint32_t)(RCC->CFGR2 & RCC_CFGR2_PREDIV1) >> POSITION_VAL(RCC_CFGR2_PREDIV1)];
+#else
+ prediv1 = aPredivFactorTable[(uint32_t)(RCC->CFGR & RCC_CFGR_PLLXTPRE) >> POSITION_VAL(RCC_CFGR_PLLXTPRE)];
+#endif /* STM32F105xC || STM32F107xC || STM32F100xB || STM32F100xE */
+
+#if defined(STM32F105xC) || defined(STM32F107xC)
+ if(HAL_IS_BIT_SET(RCC->CFGR2, RCC_CFGR2_PREDIV1SRC))
+ {
+ /* PLL2 selected as Prediv1 source */
+ /* PLLCLK = PLL2CLK / PREDIV1 * PLLMUL with PLL2CLK = HSE/PREDIV2 * PLL2MUL */
+ prediv2 = ((RCC->CFGR2 & RCC_CFGR2_PREDIV2) >> POSITION_VAL(RCC_CFGR2_PREDIV2)) + 1;
+ pll2mul = ((RCC->CFGR2 & RCC_CFGR2_PLL2MUL) >> POSITION_VAL(RCC_CFGR2_PLL2MUL)) + 2;
+ pllclk = (uint32_t)((((HSE_VALUE / prediv2) * pll2mul) / prediv1) * pllmul);
+ }
+ else
+ {
+ /* HSE used as PLL clock source : PLLCLK = HSE/PREDIV1 * PLLMUL */
+ pllclk = (uint32_t)((HSE_VALUE / prediv1) * pllmul);
+ }
+
+ /* If PLLMUL was set to 13 means that it was to cover the case PLLMUL 6.5 (avoid using float) */
+ /* In this case need to divide pllclk by 2 */
+ if (pllmul == aPLLMULFactorTable[(uint32_t)(RCC_CFGR_PLLMULL6_5) >> POSITION_VAL(RCC_CFGR_PLLMULL)])
+ {
+ pllclk = pllclk / 2;
+ }
+#else
+ if ((temp_reg & RCC_CFGR_PLLSRC) != RCC_PLLSOURCE_HSI_DIV2)
+ {
+ /* HSE used as PLL clock source : PLLCLK = HSE/PREDIV1 * PLLMUL */
+ pllclk = (uint32_t)((HSE_VALUE / prediv1) * pllmul);
+ }
+#endif /* STM32F105xC || STM32F107xC */
+ }
+ else
+ {
+ /* HSI used as PLL clock source : PLLCLK = HSI/2 * PLLMUL */
+ pllclk = (uint32_t)((HSI_VALUE >> 1) * pllmul);
+ }
+
+ /* Calcul of the USB frequency*/
+#if defined(STM32F105xC) || defined(STM32F107xC)
+ /* USBCLK = PLLVCO = (2 x PLLCLK) / USB prescaler */
+ if (__HAL_RCC_GET_USB_SOURCE() == RCC_USBCLKSOURCE_PLL_DIV2)
+ {
+ /* Prescaler of 2 selected for USB */
+ frequency = pllclk;
+ }
+ else
+ {
+ /* Prescaler of 3 selected for USB */
+ frequency = (2 * pllclk) / 3;
+ }
+#else
+ /* USBCLK = PLLCLK / USB prescaler */
+ if (__HAL_RCC_GET_USB_SOURCE() == RCC_USBCLKSOURCE_PLL)
+ {
+ /* No prescaler selected for USB */
+ frequency = pllclk;
+ }
+ else
+ {
+ /* Prescaler of 1.5 selected for USB */
+ frequency = (pllclk * 2) / 3;
+ }
+#endif
+ }
+ break;
+ }
+#endif /* STM32F102x6 || STM32F102xB || STM32F103x6 || STM32F103xB || STM32F103xE || STM32F103xG || STM32F105xC || STM32F107xC */
+#if defined(STM32F103xE) || defined(STM32F103xG) || defined(STM32F105xC)\
+ || defined(STM32F107xC)
+ case RCC_PERIPHCLK_I2S2:
+ {
+#if defined(STM32F103xE) || defined(STM32F103xG)
+ /* SYSCLK used as source clock for I2S2 */
+ frequency = HAL_RCC_GetSysClockFreq();
+#else
+ if (__HAL_RCC_GET_I2S2_SOURCE() == RCC_I2S2CLKSOURCE_SYSCLK)
+ {
+ /* SYSCLK used as source clock for I2S2 */
+ frequency = HAL_RCC_GetSysClockFreq();
+ }
+ else
+ {
+ /* Check if PLLI2S is enabled */
+ if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLL3ON))
+ {
+ /* PLLI2SVCO = 2 * PLLI2SCLK = 2 * (HSE/PREDIV2 * PLL3MUL) */
+ prediv2 = ((RCC->CFGR2 & RCC_CFGR2_PREDIV2) >> POSITION_VAL(RCC_CFGR2_PREDIV2)) + 1;
+ pll3mul = ((RCC->CFGR2 & RCC_CFGR2_PLL3MUL) >> POSITION_VAL(RCC_CFGR2_PLL3MUL)) + 2;
+ frequency = (uint32_t)(2 * ((HSE_VALUE / prediv2) * pll3mul));
+ }
+ }
+#endif /* STM32F103xE || STM32F103xG */
+ break;
+ }
+ case RCC_PERIPHCLK_I2S3:
+ {
+#if defined(STM32F103xE) || defined(STM32F103xG)
+ /* SYSCLK used as source clock for I2S3 */
+ frequency = HAL_RCC_GetSysClockFreq();
+#else
+ if (__HAL_RCC_GET_I2S3_SOURCE() == RCC_I2S3CLKSOURCE_SYSCLK)
+ {
+ /* SYSCLK used as source clock for I2S3 */
+ frequency = HAL_RCC_GetSysClockFreq();
+ }
+ else
+ {
+ /* Check if PLLI2S is enabled */
+ if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLL3ON))
+ {
+ /* PLLI2SVCO = 2 * PLLI2SCLK = 2 * (HSE/PREDIV2 * PLL3MUL) */
+ prediv2 = ((RCC->CFGR2 & RCC_CFGR2_PREDIV2) >> POSITION_VAL(RCC_CFGR2_PREDIV2)) + 1;
+ pll3mul = ((RCC->CFGR2 & RCC_CFGR2_PLL3MUL) >> POSITION_VAL(RCC_CFGR2_PLL3MUL)) + 2;
+ frequency = (uint32_t)(2 * ((HSE_VALUE / prediv2) * pll3mul));
+ }
+ }
+#endif /* STM32F103xE || STM32F103xG */
+ break;
+ }
+#endif /* STM32F103xE || STM32F103xG || STM32F105xC || STM32F107xC */
+ case RCC_PERIPHCLK_RTC:
+ {
+ /* Get RCC BDCR configuration ------------------------------------------------------*/
+ temp_reg = RCC->BDCR;
+
+ /* Check if LSE is ready if RTC clock selection is LSE */
+ if (((temp_reg & RCC_BDCR_RTCSEL) == RCC_RTCCLKSOURCE_LSE) && (HAL_IS_BIT_SET(temp_reg, RCC_BDCR_LSERDY)))
+ {
+ frequency = LSE_VALUE;
+ }
+ /* Check if LSI is ready if RTC clock selection is LSI */
+ else if (((temp_reg & RCC_BDCR_RTCSEL) == RCC_RTCCLKSOURCE_LSI) && (HAL_IS_BIT_SET(RCC->CSR, RCC_CSR_LSIRDY)))
+ {
+ frequency = LSI_VALUE;
+ }
+ else if (((temp_reg & RCC_BDCR_RTCSEL) == RCC_RTCCLKSOURCE_HSE_DIV128) && (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSERDY)))
+ {
+ frequency = HSE_VALUE / 128;
+ }
+ /* Clock not enabled for RTC*/
+ else
+ {
+ frequency = 0;
+ }
+ break;
+ }
+ case RCC_PERIPHCLK_ADC:
+ {
+ frequency = HAL_RCC_GetPCLK2Freq() / (((__HAL_RCC_GET_ADC_SOURCE() >> POSITION_VAL(RCC_CFGR_ADCPRE_DIV4)) + 1) * 2);
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ return(frequency);
+}
+
+/**
+ * @}
+ */
+
+#if defined(STM32F105xC) || defined(STM32F107xC)
+/** @defgroup RCCEx_Exported_Functions_Group2 PLLI2S Management function
+ * @brief PLLI2S Management functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Extended PLLI2S Management functions #####
+ ===============================================================================
+ [..]
+ This subsection provides a set of functions allowing to control the PLLI2S
+ activation or deactivation
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Enable PLLI2S
+ * @param PLLI2SInit pointer to an RCC_PLLI2SInitTypeDef structure that
+ * contains the configuration information for the PLLI2S
+ * @note The PLLI2S configuration not modified if used by I2S2 or I2S3 Interface.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_RCCEx_EnablePLLI2S(RCC_PLLI2SInitTypeDef *PLLI2SInit)
+{
+ uint32_t tickstart = 0;
+
+ /* Check that PLL I2S has not been already enabled by I2S2 or I2S3*/
+ if (HAL_IS_BIT_CLR(RCC->CFGR2, RCC_CFGR2_I2S2SRC) && HAL_IS_BIT_CLR(RCC->CFGR2, RCC_CFGR2_I2S3SRC))
+ {
+ /* Check the parameters */
+ assert_param(IS_RCC_PLLI2S_MUL(PLLI2SInit->PLLI2SMUL));
+ assert_param(IS_RCC_HSE_PREDIV2(PLLI2SInit->HSEPrediv2Value));
+
+ /* Prediv2 can be written only when the PLL2 is disabled. */
+ /* Return an error only if new value is different from the programmed value */
+ if (HAL_IS_BIT_SET(RCC->CR,RCC_CR_PLL2ON) && \
+ (__HAL_RCC_HSE_GET_PREDIV2() != PLLI2SInit->HSEPrediv2Value))
+ {
+ return HAL_ERROR;
+ }
+
+ /* Disable the main PLLI2S. */
+ __HAL_RCC_PLLI2S_DISABLE();
+
+ /* Get Start Tick*/
+ tickstart = HAL_GetTick();
+
+ /* Wait till PLLI2S is ready */
+ while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) != RESET)
+ {
+ if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE)
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+
+ /* Configure the HSE prediv2 factor --------------------------------*/
+ __HAL_RCC_HSE_PREDIV2_CONFIG(PLLI2SInit->HSEPrediv2Value);
+
+
+ /* Configure the main PLLI2S multiplication factors. */
+ __HAL_RCC_PLLI2S_CONFIG(PLLI2SInit->PLLI2SMUL);
+
+ /* Enable the main PLLI2S. */
+ __HAL_RCC_PLLI2S_ENABLE();
+
+ /* Get Start Tick*/
+ tickstart = HAL_GetTick();
+
+ /* Wait till PLLI2S is ready */
+ while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) == RESET)
+ {
+ if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE)
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+ else
+ {
+ /* PLLI2S cannot be modified as already used by I2S2 or I2S3 */
+ return HAL_ERROR;
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Disable PLLI2S
+ * @note PLLI2S is not disabled if used by I2S2 or I2S3 Interface.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_RCCEx_DisablePLLI2S(void)
+{
+ uint32_t tickstart = 0;
+
+ /* Disable PLL I2S as not requested by I2S2 or I2S3*/
+ if (HAL_IS_BIT_CLR(RCC->CFGR2, RCC_CFGR2_I2S2SRC) && HAL_IS_BIT_CLR(RCC->CFGR2, RCC_CFGR2_I2S3SRC))
+ {
+ /* Disable the main PLLI2S. */
+ __HAL_RCC_PLLI2S_DISABLE();
+
+ /* Get Start Tick*/
+ tickstart = HAL_GetTick();
+
+ /* Wait till PLLI2S is ready */
+ while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) != RESET)
+ {
+ if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE)
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+ else
+ {
+ /* PLLI2S is currently used by I2S2 or I2S3. Cannot be disabled.*/
+ return HAL_ERROR;
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup RCCEx_Exported_Functions_Group3 PLL2 Management function
+ * @brief PLL2 Management functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Extended PLL2 Management functions #####
+ ===============================================================================
+ [..]
+ This subsection provides a set of functions allowing to control the PLL2
+ activation or deactivation
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Enable PLL2
+ * @param PLL2Init pointer to an RCC_PLL2InitTypeDef structure that
+ * contains the configuration information for the PLL2
+ * @note The PLL2 configuration not modified if used indirectly as system clock.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_RCCEx_EnablePLL2(RCC_PLL2InitTypeDef *PLL2Init)
+{
+ uint32_t tickstart = 0;
+
+ /* This bit can not be cleared if the PLL2 clock is used indirectly as system
+ clock (i.e. it is used as PLL clock entry that is used as system clock). */
+ if((__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSE) && \
+ (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && \
+ ((READ_BIT(RCC->CFGR2,RCC_CFGR2_PREDIV1SRC)) == RCC_CFGR2_PREDIV1SRC_PLL2))
+ {
+ return HAL_ERROR;
+ }
+ else
+ {
+ /* Check the parameters */
+ assert_param(IS_RCC_PLL2_MUL(PLL2Init->PLL2MUL));
+ assert_param(IS_RCC_HSE_PREDIV2(PLL2Init->HSEPrediv2Value));
+
+ /* Prediv2 can be written only when the PLLI2S is disabled. */
+ /* Return an error only if new value is different from the programmed value */
+ if (HAL_IS_BIT_SET(RCC->CR,RCC_CR_PLL3ON) && \
+ (__HAL_RCC_HSE_GET_PREDIV2() != PLL2Init->HSEPrediv2Value))
+ {
+ return HAL_ERROR;
+ }
+
+ /* Disable the main PLL2. */
+ __HAL_RCC_PLL2_DISABLE();
+
+ /* Get Start Tick*/
+ tickstart = HAL_GetTick();
+
+ /* Wait till PLL2 is disabled */
+ while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLL2RDY) != RESET)
+ {
+ if((HAL_GetTick() - tickstart ) > PLL2_TIMEOUT_VALUE)
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+
+ /* Configure the HSE prediv2 factor --------------------------------*/
+ __HAL_RCC_HSE_PREDIV2_CONFIG(PLL2Init->HSEPrediv2Value);
+
+ /* Configure the main PLL2 multiplication factors. */
+ __HAL_RCC_PLL2_CONFIG(PLL2Init->PLL2MUL);
+
+ /* Enable the main PLL2. */
+ __HAL_RCC_PLL2_ENABLE();
+
+ /* Get Start Tick*/
+ tickstart = HAL_GetTick();
+
+ /* Wait till PLL2 is ready */
+ while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLL2RDY) == RESET)
+ {
+ if((HAL_GetTick() - tickstart ) > PLL2_TIMEOUT_VALUE)
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Disable PLL2
+ * @note PLL2 is not disabled if used indirectly as system clock.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_RCCEx_DisablePLL2(void)
+{
+ uint32_t tickstart = 0;
+
+ /* This bit can not be cleared if the PLL2 clock is used indirectly as system
+ clock (i.e. it is used as PLL clock entry that is used as system clock). */
+ if((__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSE) && \
+ (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && \
+ ((READ_BIT(RCC->CFGR2,RCC_CFGR2_PREDIV1SRC)) == RCC_CFGR2_PREDIV1SRC_PLL2))
+ {
+ return HAL_ERROR;
+ }
+ else
+ {
+ /* Disable the main PLL2. */
+ __HAL_RCC_PLL2_DISABLE();
+
+ /* Get Start Tick*/
+ tickstart = HAL_GetTick();
+
+ /* Wait till PLL2 is disabled */
+ while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLL2RDY) != RESET)
+ {
+ if((HAL_GetTick() - tickstart ) > PLL2_TIMEOUT_VALUE)
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @}
+ */
+#endif /* STM32F105xC || STM32F107xC */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* HAL_RCC_MODULE_ENABLED */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
diff --git a/bsp/radio-controller-1/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim.c b/bsp/radio-controller-1/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim.c
new file mode 100644
index 0000000..f904f82
--- /dev/null
+++ b/bsp/radio-controller-1/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim.c
@@ -0,0 +1,5379 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_tim.c
+ * @author MCD Application Team
+ * @version V1.0.4
+ * @date 29-April-2016
+ * @brief TIM HAL module driver
+ * This file provides firmware functions to manage the following
+ * functionalities of the Timer (TIM) peripheral:
+ * + Time Base Initialization
+ * + Time Base Start
+ * + Time Base Start Interruption
+ * + Time Base Start DMA
+ * + Time Output Compare/PWM Initialization
+ * + Time Output Compare/PWM Channel Configuration
+ * + Time Output Compare/PWM Start
+ * + Time Output Compare/PWM Start Interruption
+ * + Time Output Compare/PWM Start DMA
+ * + Time Input Capture Initialization
+ * + Time Input Capture Channel Configuration
+ * + Time Input Capture Start
+ * + Time Input Capture Start Interruption
+ * + Time Input Capture Start DMA
+ * + Time One Pulse Initialization
+ * + Time One Pulse Channel Configuration
+ * + Time One Pulse Start
+ * + Time Encoder Interface Initialization
+ * + Time Encoder Interface Start
+ * + Time Encoder Interface Start Interruption
+ * + Time Encoder Interface Start DMA
+ * + Commutation Event configuration with Interruption and DMA
+ * + Time OCRef clear configuration
+ * + Time External Clock configuration
+ @verbatim
+ ==============================================================================
+ ##### TIMER Generic features #####
+ ==============================================================================
+ [..] The Timer features include:
+ (#) 16-bit up, down, up/down auto-reload counter.
+ (#) 16-bit programmable prescaler allowing dividing (also on the fly) the
+ counter clock frequency either by any factor between 1 and 65536.
+ (#) Up to 4 independent channels for:
+ (++) Input Capture
+ (++) Output Compare
+ (++) PWM generation (Edge and Center-aligned Mode)
+ (++) One-pulse mode output
+
+ ##### How to use this driver #####
+ ==============================================================================
+ [..]
+ (#) Initialize the TIM low level resources by implementing the following functions
+ depending from feature used :
+ (++) Time Base : HAL_TIM_Base_MspInit()
+ (++) Input Capture : HAL_TIM_IC_MspInit()
+ (++) Output Compare : HAL_TIM_OC_MspInit()
+ (++) PWM generation : HAL_TIM_PWM_MspInit()
+ (++) One-pulse mode output : HAL_TIM_OnePulse_MspInit()
+ (++) Encoder mode output : HAL_TIM_Encoder_MspInit()
+
+ (#) Initialize the TIM low level resources :
+ (##) Enable the TIM interface clock using __HAL_RCC_TIMx_CLK_ENABLE();
+ (##) TIM pins configuration
+ (+++) Enable the clock for the TIM GPIOs using the following function:
+ __HAL_RCC_GPIOx_CLK_ENABLE();
+ (+++) Configure these TIM pins in Alternate function mode using HAL_GPIO_Init();
+
+ (#) The external Clock can be configured, if needed (the default clock is the
+ internal clock from the APBx), using the following function:
+ HAL_TIM_ConfigClockSource, the clock configuration should be done before
+ any start function.
+
+ (#) Configure the TIM in the desired functioning mode using one of the
+ Initialization function of this driver:
+ (++) HAL_TIM_Base_Init: to use the Timer to generate a simple time base
+ (++) HAL_TIM_OC_Init and HAL_TIM_OC_ConfigChannel: to use the Timer to generate an
+ Output Compare signal.
+ (++) HAL_TIM_PWM_Init and HAL_TIM_PWM_ConfigChannel: to use the Timer to generate a
+ PWM signal.
+ (++) HAL_TIM_IC_Init and HAL_TIM_IC_ConfigChannel: to use the Timer to measure an
+ external signal.
+ (++) HAL_TIM_OnePulse_Init and HAL_TIM_OnePulse_ConfigChannel: to use the Timer
+ in One Pulse Mode.
+ (++) HAL_TIM_Encoder_Init: to use the Timer Encoder Interface.
+
+ (#) Activate the TIM peripheral using one of the start functions depending from the feature used:
+ (++) Time Base : HAL_TIM_Base_Start(), HAL_TIM_Base_Start_DMA(), HAL_TIM_Base_Start_IT()
+ (++) Input Capture : HAL_TIM_IC_Start(), HAL_TIM_IC_Start_DMA(), HAL_TIM_IC_Start_IT()
+ (++) Output Compare : HAL_TIM_OC_Start(), HAL_TIM_OC_Start_DMA(), HAL_TIM_OC_Start_IT()
+ (++) PWM generation : HAL_TIM_PWM_Start(), HAL_TIM_PWM_Start_DMA(), HAL_TIM_PWM_Start_IT()
+ (++) One-pulse mode output : HAL_TIM_OnePulse_Start(), HAL_TIM_OnePulse_Start_IT()
+ (++) Encoder mode output : HAL_TIM_Encoder_Start(), HAL_TIM_Encoder_Start_DMA(), HAL_TIM_Encoder_Start_IT().
+
+ (#) The DMA Burst is managed with the two following functions:
+ HAL_TIM_DMABurst_WriteStart()
+ HAL_TIM_DMABurst_ReadStart()
+
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+/** @defgroup TIM TIM
+ * @brief TIM HAL module driver
+ * @{
+ */
+
+#ifdef HAL_TIM_MODULE_ENABLED
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/** @defgroup TIM_Private_Functions TIM Private Functions
+ * @{
+ */
+static void TIM_OC1_SetConfig(TIM_TypeDef *TIMx, TIM_OC_InitTypeDef *OC_Config);
+static void TIM_OC3_SetConfig(TIM_TypeDef *TIMx, TIM_OC_InitTypeDef *OC_Config);
+static void TIM_OC4_SetConfig(TIM_TypeDef *TIMx, TIM_OC_InitTypeDef *OC_Config);
+static void TIM_TI1_ConfigInputStage(TIM_TypeDef *TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICFilter);
+static void TIM_TI2_SetConfig(TIM_TypeDef *TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICSelection,
+ uint32_t TIM_ICFilter);
+static void TIM_TI2_ConfigInputStage(TIM_TypeDef *TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICFilter);
+static void TIM_TI3_SetConfig(TIM_TypeDef *TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICSelection,
+ uint32_t TIM_ICFilter);
+static void TIM_TI4_SetConfig(TIM_TypeDef *TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICSelection,
+ uint32_t TIM_ICFilter);
+static void TIM_ETR_SetConfig(TIM_TypeDef* TIMx, uint32_t TIM_ExtTRGPrescaler,
+ uint32_t TIM_ExtTRGPolarity, uint32_t ExtTRGFilter);
+static void TIM_ITRx_SetConfig(TIM_TypeDef* TIMx, uint16_t InputTriggerSource);
+static void TIM_DMAPeriodElapsedCplt(DMA_HandleTypeDef *hdma);
+static void TIM_DMATriggerCplt(DMA_HandleTypeDef *hdma);
+static void TIM_SlaveTimer_SetConfig(TIM_HandleTypeDef *htim,
+ TIM_SlaveConfigTypeDef * sSlaveConfig);
+
+/**
+ * @}
+ */
+
+/* Exported functions ---------------------------------------------------------*/
+
+/** @defgroup TIM_Exported_Functions TIM Exported Functions
+ * @{
+ */
+
+/** @defgroup TIM_Exported_Functions_Group1 Time Base functions
+ * @brief Time Base functions
+ *
+@verbatim
+ ==============================================================================
+ ##### Time Base functions #####
+ ==============================================================================
+ [..]
+ This section provides functions allowing to:
+ (+) Initialize and configure the TIM base.
+ (+) De-initialize the TIM base.
+ (+) Start the Time Base.
+ (+) Stop the Time Base.
+ (+) Start the Time Base and enable interrupt.
+ (+) Stop the Time Base and disable interrupt.
+ (+) Start the Time Base and enable DMA transfer.
+ (+) Stop the Time Base and disable DMA transfer.
+
+@endverbatim
+ * @{
+ */
+/**
+ * @brief Initializes the TIM Time base Unit according to the specified
+ * parameters in the TIM_HandleTypeDef and create the associated handle.
+ * @param htim : TIM Base handle
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_TIM_Base_Init(TIM_HandleTypeDef *htim)
+{
+ /* Check the TIM handle allocation */
+ if(htim == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check the parameters */
+ assert_param(IS_TIM_INSTANCE(htim->Instance));
+ assert_param(IS_TIM_COUNTER_MODE(htim->Init.CounterMode));
+ assert_param(IS_TIM_CLOCKDIVISION_DIV(htim->Init.ClockDivision));
+
+ if(htim->State == HAL_TIM_STATE_RESET)
+ {
+ /* Allocate lock resource and initialize it */
+ htim->Lock = HAL_UNLOCKED;
+
+ /* Init the low level hardware : GPIO, CLOCK, NVIC */
+ HAL_TIM_Base_MspInit(htim);
+ }
+
+ /* Set the TIM state */
+ htim->State= HAL_TIM_STATE_BUSY;
+
+ /* Set the Time Base configuration */
+ TIM_Base_SetConfig(htim->Instance, &htim->Init);
+
+ /* Initialize the TIM state*/
+ htim->State= HAL_TIM_STATE_READY;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief DeInitializes the TIM Base peripheral
+ * @param htim : TIM Base handle
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_TIM_Base_DeInit(TIM_HandleTypeDef *htim)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_INSTANCE(htim->Instance));
+
+ htim->State = HAL_TIM_STATE_BUSY;
+
+ /* Disable the TIM Peripheral Clock */
+ __HAL_TIM_DISABLE(htim);
+
+ /* DeInit the low level hardware: GPIO, CLOCK, NVIC */
+ HAL_TIM_Base_MspDeInit(htim);
+
+ /* Change TIM state */
+ htim->State = HAL_TIM_STATE_RESET;
+
+ /* Release Lock */
+ __HAL_UNLOCK(htim);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Initializes the TIM Base MSP.
+ * @param htim : TIM handle
+ * @retval None
+ */
+__weak void HAL_TIM_Base_MspInit(TIM_HandleTypeDef *htim)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(htim);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_TIM_Base_MspInit could be implemented in the user file
+ */
+}
+
+/**
+ * @brief DeInitializes TIM Base MSP.
+ * @param htim : TIM handle
+ * @retval None
+ */
+__weak void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef *htim)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(htim);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_TIM_Base_MspDeInit could be implemented in the user file
+ */
+}
+
+
+/**
+ * @brief Starts the TIM Base generation.
+ * @param htim : TIM handle
+ * @retval HAL status
+*/
+HAL_StatusTypeDef HAL_TIM_Base_Start(TIM_HandleTypeDef *htim)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_INSTANCE(htim->Instance));
+
+ /* Set the TIM state */
+ htim->State= HAL_TIM_STATE_BUSY;
+
+ /* Enable the Peripheral */
+ __HAL_TIM_ENABLE(htim);
+
+ /* Change the TIM state*/
+ htim->State= HAL_TIM_STATE_READY;
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Stops the TIM Base generation.
+ * @param htim : TIM handle
+ * @retval HAL status
+*/
+HAL_StatusTypeDef HAL_TIM_Base_Stop(TIM_HandleTypeDef *htim)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_INSTANCE(htim->Instance));
+
+ /* Set the TIM state */
+ htim->State= HAL_TIM_STATE_BUSY;
+
+ /* Disable the Peripheral */
+ __HAL_TIM_DISABLE(htim);
+
+ /* Change the TIM state*/
+ htim->State= HAL_TIM_STATE_READY;
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Starts the TIM Base generation in interrupt mode.
+ * @param htim : TIM handle
+ * @retval HAL status
+*/
+HAL_StatusTypeDef HAL_TIM_Base_Start_IT(TIM_HandleTypeDef *htim)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_INSTANCE(htim->Instance));
+
+ /* Enable the TIM Update interrupt */
+ __HAL_TIM_ENABLE_IT(htim, TIM_IT_UPDATE);
+
+ /* Enable the Peripheral */
+ __HAL_TIM_ENABLE(htim);
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Stops the TIM Base generation in interrupt mode.
+ * @param htim : TIM handle
+ * @retval HAL status
+*/
+HAL_StatusTypeDef HAL_TIM_Base_Stop_IT(TIM_HandleTypeDef *htim)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_INSTANCE(htim->Instance));
+ /* Disable the TIM Update interrupt */
+ __HAL_TIM_DISABLE_IT(htim, TIM_IT_UPDATE);
+
+ /* Disable the Peripheral */
+ __HAL_TIM_DISABLE(htim);
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Starts the TIM Base generation in DMA mode.
+ * @param htim : TIM handle
+ * @param pData : The source Buffer address.
+ * @param Length : The length of data to be transferred from memory to peripheral.
+ * @retval HAL status
+*/
+HAL_StatusTypeDef HAL_TIM_Base_Start_DMA(TIM_HandleTypeDef *htim, uint32_t *pData, uint16_t Length)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_DMA_INSTANCE(htim->Instance));
+
+ if((htim->State == HAL_TIM_STATE_BUSY))
+ {
+ return HAL_BUSY;
+ }
+ else if((htim->State == HAL_TIM_STATE_READY))
+ {
+ if((pData == 0 ) && (Length > 0))
+ {
+ return HAL_ERROR;
+ }
+ else
+ {
+ htim->State = HAL_TIM_STATE_BUSY;
+ }
+ }
+ /* Set the DMA Period elapsed callback */
+ htim->hdma[TIM_DMA_ID_UPDATE]->XferCpltCallback = TIM_DMAPeriodElapsedCplt;
+
+ /* Set the DMA error callback */
+ htim->hdma[TIM_DMA_ID_UPDATE]->XferErrorCallback = TIM_DMAError ;
+
+ /* Enable the DMA channel */
+ HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_UPDATE], (uint32_t)pData, (uint32_t)&htim->Instance->ARR, Length);
+
+ /* Enable the TIM Update DMA request */
+ __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_UPDATE);
+
+ /* Enable the Peripheral */
+ __HAL_TIM_ENABLE(htim);
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Stops the TIM Base generation in DMA mode.
+ * @param htim : TIM handle
+ * @retval HAL status
+*/
+HAL_StatusTypeDef HAL_TIM_Base_Stop_DMA(TIM_HandleTypeDef *htim)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_DMA_INSTANCE(htim->Instance));
+
+ /* Disable the TIM Update DMA request */
+ __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_UPDATE);
+
+ /* Disable the Peripheral */
+ __HAL_TIM_DISABLE(htim);
+
+ /* Change the htim state */
+ htim->State = HAL_TIM_STATE_READY;
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Exported_Functions_Group2 Time Output Compare functions
+ * @brief Time Output Compare functions
+ *
+@verbatim
+ ==============================================================================
+ ##### Time Output Compare functions #####
+ ==============================================================================
+ [..]
+ This section provides functions allowing to:
+ (+) Initialize and configure the TIM Output Compare.
+ (+) De-initialize the TIM Output Compare.
+ (+) Start the Time Output Compare.
+ (+) Stop the Time Output Compare.
+ (+) Start the Time Output Compare and enable interrupt.
+ (+) Stop the Time Output Compare and disable interrupt.
+ (+) Start the Time Output Compare and enable DMA transfer.
+ (+) Stop the Time Output Compare and disable DMA transfer.
+
+@endverbatim
+ * @{
+ */
+/**
+ * @brief Initializes the TIM Output Compare according to the specified
+ * parameters in the TIM_HandleTypeDef and create the associated handle.
+ * @param htim : TIM Output Compare handle
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_TIM_OC_Init(TIM_HandleTypeDef* htim)
+{
+ /* Check the TIM handle allocation */
+ if(htim == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check the parameters */
+ assert_param(IS_TIM_INSTANCE(htim->Instance));
+ assert_param(IS_TIM_COUNTER_MODE(htim->Init.CounterMode));
+ assert_param(IS_TIM_CLOCKDIVISION_DIV(htim->Init.ClockDivision));
+
+ if(htim->State == HAL_TIM_STATE_RESET)
+ {
+ /* Allocate lock resource and initialize it */
+ htim->Lock = HAL_UNLOCKED;
+
+ /* Init the low level hardware : GPIO, CLOCK, NVIC and DMA */
+ HAL_TIM_OC_MspInit(htim);
+ }
+
+ /* Set the TIM state */
+ htim->State= HAL_TIM_STATE_BUSY;
+
+ /* Init the base time for the Output Compare */
+ TIM_Base_SetConfig(htim->Instance, &htim->Init);
+
+ /* Initialize the TIM state*/
+ htim->State= HAL_TIM_STATE_READY;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief DeInitializes the TIM peripheral
+ * @param htim : TIM Output Compare handle
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_TIM_OC_DeInit(TIM_HandleTypeDef *htim)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_INSTANCE(htim->Instance));
+
+ htim->State = HAL_TIM_STATE_BUSY;
+
+ /* Disable the TIM Peripheral Clock */
+ __HAL_TIM_DISABLE(htim);
+
+ /* DeInit the low level hardware: GPIO, CLOCK, NVIC and DMA */
+ HAL_TIM_OC_MspDeInit(htim);
+
+ /* Change TIM state */
+ htim->State = HAL_TIM_STATE_RESET;
+
+ /* Release Lock */
+ __HAL_UNLOCK(htim);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Initializes the TIM Output Compare MSP.
+ * @param htim : TIM handle
+ * @retval None
+ */
+__weak void HAL_TIM_OC_MspInit(TIM_HandleTypeDef *htim)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(htim);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_TIM_OC_MspInit could be implemented in the user file
+ */
+}
+
+/**
+ * @brief DeInitializes TIM Output Compare MSP.
+ * @param htim : TIM handle
+ * @retval None
+ */
+__weak void HAL_TIM_OC_MspDeInit(TIM_HandleTypeDef *htim)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(htim);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_TIM_OC_MspDeInit could be implemented in the user file
+ */
+}
+
+/**
+ * @brief Starts the TIM Output Compare signal generation.
+ * @param htim : TIM Output Compare handle
+ * @param Channel : TIM Channel to be enabled
+ * This parameter can be one of the following values:
+ * @arg TIM_CHANNEL_1: TIM Channel 1 selected
+ * @arg TIM_CHANNEL_2: TIM Channel 2 selected
+ * @arg TIM_CHANNEL_3: TIM Channel 3 selected
+ * @arg TIM_CHANNEL_4: TIM Channel 4 selected
+ * @retval HAL status
+*/
+HAL_StatusTypeDef HAL_TIM_OC_Start(TIM_HandleTypeDef *htim, uint32_t Channel)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel));
+
+ /* Enable the Output compare channel */
+ TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_ENABLE);
+
+ if(IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET)
+ {
+ /* Enable the main output */
+ __HAL_TIM_MOE_ENABLE(htim);
+ }
+
+ /* Enable the Peripheral */
+ __HAL_TIM_ENABLE(htim);
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Stops the TIM Output Compare signal generation.
+ * @param htim : TIM handle
+ * @param Channel : TIM Channel to be disabled
+ * This parameter can be one of the following values:
+ * @arg TIM_CHANNEL_1: TIM Channel 1 selected
+ * @arg TIM_CHANNEL_2: TIM Channel 2 selected
+ * @arg TIM_CHANNEL_3: TIM Channel 3 selected
+ * @arg TIM_CHANNEL_4: TIM Channel 4 selected
+ * @retval HAL status
+*/
+HAL_StatusTypeDef HAL_TIM_OC_Stop(TIM_HandleTypeDef *htim, uint32_t Channel)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel));
+
+ /* Disable the Output compare channel */
+ TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_DISABLE);
+
+ if(IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET)
+ {
+ /* Disable the Main Ouput */
+ __HAL_TIM_MOE_DISABLE(htim);
+ }
+
+ /* Disable the Peripheral */
+ __HAL_TIM_DISABLE(htim);
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Starts the TIM Output Compare signal generation in interrupt mode.
+ * @param htim : TIM OC handle
+ * @param Channel : TIM Channel to be enabled
+ * This parameter can be one of the following values:
+ * @arg TIM_CHANNEL_1: TIM Channel 1 selected
+ * @arg TIM_CHANNEL_2: TIM Channel 2 selected
+ * @arg TIM_CHANNEL_3: TIM Channel 3 selected
+ * @arg TIM_CHANNEL_4: TIM Channel 4 selected
+ * @retval HAL status
+*/
+HAL_StatusTypeDef HAL_TIM_OC_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel));
+
+ switch (Channel)
+ {
+ case TIM_CHANNEL_1:
+ {
+ /* Enable the TIM Capture/Compare 1 interrupt */
+ __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1);
+ }
+ break;
+
+ case TIM_CHANNEL_2:
+ {
+ /* Enable the TIM Capture/Compare 2 interrupt */
+ __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC2);
+ }
+ break;
+
+ case TIM_CHANNEL_3:
+ {
+ /* Enable the TIM Capture/Compare 3 interrupt */
+ __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC3);
+ }
+ break;
+
+ case TIM_CHANNEL_4:
+ {
+ /* Enable the TIM Capture/Compare 4 interrupt */
+ __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC4);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ /* Enable the Output compare channel */
+ TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_ENABLE);
+
+ if(IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET)
+ {
+ /* Enable the main output */
+ __HAL_TIM_MOE_ENABLE(htim);
+ }
+
+ /* Enable the Peripheral */
+ __HAL_TIM_ENABLE(htim);
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Stops the TIM Output Compare signal generation in interrupt mode.
+ * @param htim : TIM Output Compare handle
+ * @param Channel : TIM Channel to be disabled
+ * This parameter can be one of the following values:
+ * @arg TIM_CHANNEL_1: TIM Channel 1 selected
+ * @arg TIM_CHANNEL_2: TIM Channel 2 selected
+ * @arg TIM_CHANNEL_3: TIM Channel 3 selected
+ * @arg TIM_CHANNEL_4: TIM Channel 4 selected
+ * @retval HAL status
+*/
+HAL_StatusTypeDef HAL_TIM_OC_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel));
+
+ switch (Channel)
+ {
+ case TIM_CHANNEL_1:
+ {
+ /* Disable the TIM Capture/Compare 1 interrupt */
+ __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1);
+ }
+ break;
+
+ case TIM_CHANNEL_2:
+ {
+ /* Disable the TIM Capture/Compare 2 interrupt */
+ __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC2);
+ }
+ break;
+
+ case TIM_CHANNEL_3:
+ {
+ /* Disable the TIM Capture/Compare 3 interrupt */
+ __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC3);
+ }
+ break;
+
+ case TIM_CHANNEL_4:
+ {
+ /* Disable the TIM Capture/Compare 4 interrupt */
+ __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC4);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ /* Disable the Output compare channel */
+ TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_DISABLE);
+
+ if(IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET)
+ {
+ /* Disable the Main Ouput */
+ __HAL_TIM_MOE_DISABLE(htim);
+ }
+
+ /* Disable the Peripheral */
+ __HAL_TIM_DISABLE(htim);
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Starts the TIM Output Compare signal generation in DMA mode.
+ * @param htim : TIM Output Compare handle
+ * @param Channel : TIM Channel to be enabled
+ * This parameter can be one of the following values:
+ * @arg TIM_CHANNEL_1: TIM Channel 1 selected
+ * @arg TIM_CHANNEL_2: TIM Channel 2 selected
+ * @arg TIM_CHANNEL_3: TIM Channel 3 selected
+ * @arg TIM_CHANNEL_4: TIM Channel 4 selected
+ * @param pData : The source Buffer address.
+ * @param Length : The length of data to be transferred from memory to TIM peripheral
+ * @retval HAL status
+*/
+HAL_StatusTypeDef HAL_TIM_OC_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, uint32_t *pData, uint16_t Length)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel));
+
+ if((htim->State == HAL_TIM_STATE_BUSY))
+ {
+ return HAL_BUSY;
+ }
+ else if((htim->State == HAL_TIM_STATE_READY))
+ {
+ if(((uint32_t)pData == 0 ) && (Length > 0))
+ {
+ return HAL_ERROR;
+ }
+ else
+ {
+ htim->State = HAL_TIM_STATE_BUSY;
+ }
+ }
+ switch (Channel)
+ {
+ case TIM_CHANNEL_1:
+ {
+ /* Set the DMA Period elapsed callback */
+ htim->hdma[TIM_DMA_ID_CC1]->XferCpltCallback = TIM_DMADelayPulseCplt;
+
+ /* Set the DMA error callback */
+ htim->hdma[TIM_DMA_ID_CC1]->XferErrorCallback = TIM_DMAError ;
+
+ /* Enable the DMA channel */
+ HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC1], (uint32_t)pData, (uint32_t)&htim->Instance->CCR1, Length);
+
+ /* Enable the TIM Capture/Compare 1 DMA request */
+ __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC1);
+ }
+ break;
+
+ case TIM_CHANNEL_2:
+ {
+ /* Set the DMA Period elapsed callback */
+ htim->hdma[TIM_DMA_ID_CC2]->XferCpltCallback = TIM_DMADelayPulseCplt;
+
+ /* Set the DMA error callback */
+ htim->hdma[TIM_DMA_ID_CC2]->XferErrorCallback = TIM_DMAError ;
+
+ /* Enable the DMA channel */
+ HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC2], (uint32_t)pData, (uint32_t)&htim->Instance->CCR2, Length);
+
+ /* Enable the TIM Capture/Compare 2 DMA request */
+ __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC2);
+ }
+ break;
+
+ case TIM_CHANNEL_3:
+ {
+ /* Set the DMA Period elapsed callback */
+ htim->hdma[TIM_DMA_ID_CC3]->XferCpltCallback = TIM_DMADelayPulseCplt;
+
+ /* Set the DMA error callback */
+ htim->hdma[TIM_DMA_ID_CC3]->XferErrorCallback = TIM_DMAError ;
+
+ /* Enable the DMA channel */
+ HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC3], (uint32_t)pData, (uint32_t)&htim->Instance->CCR3,Length);
+
+ /* Enable the TIM Capture/Compare 3 DMA request */
+ __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC3);
+ }
+ break;
+
+ case TIM_CHANNEL_4:
+ {
+ /* Set the DMA Period elapsed callback */
+ htim->hdma[TIM_DMA_ID_CC4]->XferCpltCallback = TIM_DMADelayPulseCplt;
+
+ /* Set the DMA error callback */
+ htim->hdma[TIM_DMA_ID_CC4]->XferErrorCallback = TIM_DMAError ;
+
+ /* Enable the DMA channel */
+ HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC4], (uint32_t)pData, (uint32_t)&htim->Instance->CCR4, Length);
+
+ /* Enable the TIM Capture/Compare 4 DMA request */
+ __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC4);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ /* Enable the Output compare channel */
+ TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_ENABLE);
+
+ if(IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET)
+ {
+ /* Enable the main output */
+ __HAL_TIM_MOE_ENABLE(htim);
+ }
+
+ /* Enable the Peripheral */
+ __HAL_TIM_ENABLE(htim);
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Stops the TIM Output Compare signal generation in DMA mode.
+ * @param htim : TIM Output Compare handle
+ * @param Channel : TIM Channel to be disabled
+ * This parameter can be one of the following values:
+ * @arg TIM_CHANNEL_1: TIM Channel 1 selected
+ * @arg TIM_CHANNEL_2: TIM Channel 2 selected
+ * @arg TIM_CHANNEL_3: TIM Channel 3 selected
+ * @arg TIM_CHANNEL_4: TIM Channel 4 selected
+ * @retval HAL status
+*/
+HAL_StatusTypeDef HAL_TIM_OC_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel));
+
+ switch (Channel)
+ {
+ case TIM_CHANNEL_1:
+ {
+ /* Disable the TIM Capture/Compare 1 DMA request */
+ __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC1);
+ }
+ break;
+
+ case TIM_CHANNEL_2:
+ {
+ /* Disable the TIM Capture/Compare 2 DMA request */
+ __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC2);
+ }
+ break;
+
+ case TIM_CHANNEL_3:
+ {
+ /* Disable the TIM Capture/Compare 3 DMA request */
+ __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC3);
+ }
+ break;
+
+ case TIM_CHANNEL_4:
+ {
+ /* Disable the TIM Capture/Compare 4 interrupt */
+ __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC4);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ /* Disable the Output compare channel */
+ TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_DISABLE);
+
+ if(IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET)
+ {
+ /* Disable the Main Ouput */
+ __HAL_TIM_MOE_DISABLE(htim);
+ }
+
+ /* Disable the Peripheral */
+ __HAL_TIM_DISABLE(htim);
+
+ /* Change the htim state */
+ htim->State = HAL_TIM_STATE_READY;
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Exported_Functions_Group3 Time PWM functions
+ * @brief Time PWM functions
+ *
+@verbatim
+ ==============================================================================
+ ##### Time PWM functions #####
+ ==============================================================================
+ [..]
+ This section provides functions allowing to:
+ (+) Initialize and configure the TIM PWM.
+ (+) De-initialize the TIM PWM.
+ (+) Start the Time PWM.
+ (+) Stop the Time PWM.
+ (+) Start the Time PWM and enable interrupt.
+ (+) Stop the Time PWM and disable interrupt.
+ (+) Start the Time PWM and enable DMA transfer.
+ (+) Stop the Time PWM and disable DMA transfer.
+
+@endverbatim
+ * @{
+ */
+/**
+ * @brief Initializes the TIM PWM Time Base according to the specified
+ * parameters in the TIM_HandleTypeDef and create the associated handle.
+ * @param htim : TIM handle
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_TIM_PWM_Init(TIM_HandleTypeDef *htim)
+{
+ /* Check the TIM handle allocation */
+ if(htim == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check the parameters */
+ assert_param(IS_TIM_INSTANCE(htim->Instance));
+ assert_param(IS_TIM_COUNTER_MODE(htim->Init.CounterMode));
+ assert_param(IS_TIM_CLOCKDIVISION_DIV(htim->Init.ClockDivision));
+
+ if(htim->State == HAL_TIM_STATE_RESET)
+ {
+ /* Allocate lock resource and initialize it */
+ htim->Lock = HAL_UNLOCKED;
+
+ /* Init the low level hardware : GPIO, CLOCK, NVIC and DMA */
+ HAL_TIM_PWM_MspInit(htim);
+ }
+
+ /* Set the TIM state */
+ htim->State= HAL_TIM_STATE_BUSY;
+
+ /* Init the base time for the PWM */
+ TIM_Base_SetConfig(htim->Instance, &htim->Init);
+
+ /* Initialize the TIM state*/
+ htim->State= HAL_TIM_STATE_READY;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief DeInitializes the TIM peripheral
+ * @param htim : TIM handle
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_TIM_PWM_DeInit(TIM_HandleTypeDef *htim)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_INSTANCE(htim->Instance));
+
+ htim->State = HAL_TIM_STATE_BUSY;
+
+ /* Disable the TIM Peripheral Clock */
+ __HAL_TIM_DISABLE(htim);
+
+ /* DeInit the low level hardware: GPIO, CLOCK, NVIC and DMA */
+ HAL_TIM_PWM_MspDeInit(htim);
+
+ /* Change TIM state */
+ htim->State = HAL_TIM_STATE_RESET;
+
+ /* Release Lock */
+ __HAL_UNLOCK(htim);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Initializes the TIM PWM MSP.
+ * @param htim : TIM handle
+ * @retval None
+ */
+__weak void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef *htim)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(htim);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_TIM_PWM_MspInit could be implemented in the user file
+ */
+}
+
+/**
+ * @brief DeInitializes TIM PWM MSP.
+ * @param htim : TIM handle
+ * @retval None
+ */
+__weak void HAL_TIM_PWM_MspDeInit(TIM_HandleTypeDef *htim)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(htim);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_TIM_PWM_MspDeInit could be implemented in the user file
+ */
+}
+
+/**
+ * @brief Starts the PWM signal generation.
+ * @param htim : TIM handle
+ * @param Channel : TIM Channels to be enabled
+ * This parameter can be one of the following values:
+ * @arg TIM_CHANNEL_1: TIM Channel 1 selected
+ * @arg TIM_CHANNEL_2: TIM Channel 2 selected
+ * @arg TIM_CHANNEL_3: TIM Channel 3 selected
+ * @arg TIM_CHANNEL_4: TIM Channel 4 selected
+ * @retval HAL status
+*/
+HAL_StatusTypeDef HAL_TIM_PWM_Start(TIM_HandleTypeDef *htim, uint32_t Channel)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel));
+
+ /* Enable the Capture compare channel */
+ TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_ENABLE);
+
+ if(IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET)
+ {
+ /* Enable the main output */
+ __HAL_TIM_MOE_ENABLE(htim);
+ }
+
+ /* Enable the Peripheral */
+ __HAL_TIM_ENABLE(htim);
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Stops the PWM signal generation.
+ * @param htim : TIM handle
+ * @param Channel : TIM Channels to be disabled
+ * This parameter can be one of the following values:
+ * @arg TIM_CHANNEL_1: TIM Channel 1 selected
+ * @arg TIM_CHANNEL_2: TIM Channel 2 selected
+ * @arg TIM_CHANNEL_3: TIM Channel 3 selected
+ * @arg TIM_CHANNEL_4: TIM Channel 4 selected
+ * @retval HAL status
+*/
+HAL_StatusTypeDef HAL_TIM_PWM_Stop(TIM_HandleTypeDef *htim, uint32_t Channel)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel));
+
+ /* Disable the Capture compare channel */
+ TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_DISABLE);
+
+ if(IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET)
+ {
+ /* Disable the Main Ouput */
+ __HAL_TIM_MOE_DISABLE(htim);
+ }
+
+ /* Disable the Peripheral */
+ __HAL_TIM_DISABLE(htim);
+
+ /* Change the htim state */
+ htim->State = HAL_TIM_STATE_READY;
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Starts the PWM signal generation in interrupt mode.
+ * @param htim : TIM handle
+ * @param Channel : TIM Channel to be disabled
+ * This parameter can be one of the following values:
+ * @arg TIM_CHANNEL_1: TIM Channel 1 selected
+ * @arg TIM_CHANNEL_2: TIM Channel 2 selected
+ * @arg TIM_CHANNEL_3: TIM Channel 3 selected
+ * @arg TIM_CHANNEL_4: TIM Channel 4 selected
+ * @retval HAL status
+*/
+HAL_StatusTypeDef HAL_TIM_PWM_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel));
+
+ switch (Channel)
+ {
+ case TIM_CHANNEL_1:
+ {
+ /* Enable the TIM Capture/Compare 1 interrupt */
+ __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1);
+ }
+ break;
+
+ case TIM_CHANNEL_2:
+ {
+ /* Enable the TIM Capture/Compare 2 interrupt */
+ __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC2);
+ }
+ break;
+
+ case TIM_CHANNEL_3:
+ {
+ /* Enable the TIM Capture/Compare 3 interrupt */
+ __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC3);
+ }
+ break;
+
+ case TIM_CHANNEL_4:
+ {
+ /* Enable the TIM Capture/Compare 4 interrupt */
+ __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC4);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ /* Enable the Capture compare channel */
+ TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_ENABLE);
+
+ if(IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET)
+ {
+ /* Enable the main output */
+ __HAL_TIM_MOE_ENABLE(htim);
+ }
+
+ /* Enable the Peripheral */
+ __HAL_TIM_ENABLE(htim);
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Stops the PWM signal generation in interrupt mode.
+ * @param htim : TIM handle
+ * @param Channel : TIM Channels to be disabled
+ * This parameter can be one of the following values:
+ * @arg TIM_CHANNEL_1: TIM Channel 1 selected
+ * @arg TIM_CHANNEL_2: TIM Channel 2 selected
+ * @arg TIM_CHANNEL_3: TIM Channel 3 selected
+ * @arg TIM_CHANNEL_4: TIM Channel 4 selected
+ * @retval HAL status
+*/
+HAL_StatusTypeDef HAL_TIM_PWM_Stop_IT (TIM_HandleTypeDef *htim, uint32_t Channel)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel));
+
+ switch (Channel)
+ {
+ case TIM_CHANNEL_1:
+ {
+ /* Disable the TIM Capture/Compare 1 interrupt */
+ __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1);
+ }
+ break;
+
+ case TIM_CHANNEL_2:
+ {
+ /* Disable the TIM Capture/Compare 2 interrupt */
+ __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC2);
+ }
+ break;
+
+ case TIM_CHANNEL_3:
+ {
+ /* Disable the TIM Capture/Compare 3 interrupt */
+ __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC3);
+ }
+ break;
+
+ case TIM_CHANNEL_4:
+ {
+ /* Disable the TIM Capture/Compare 4 interrupt */
+ __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC4);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ /* Disable the Capture compare channel */
+ TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_DISABLE);
+
+ if(IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET)
+ {
+ /* Disable the Main Ouput */
+ __HAL_TIM_MOE_DISABLE(htim);
+ }
+
+ /* Disable the Peripheral */
+ __HAL_TIM_DISABLE(htim);
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Starts the TIM PWM signal generation in DMA mode.
+ * @param htim : TIM handle
+ * @param Channel : TIM Channels to be enabled
+ * This parameter can be one of the following values:
+ * @arg TIM_CHANNEL_1: TIM Channel 1 selected
+ * @arg TIM_CHANNEL_2: TIM Channel 2 selected
+ * @arg TIM_CHANNEL_3: TIM Channel 3 selected
+ * @arg TIM_CHANNEL_4: TIM Channel 4 selected
+ * @param pData : The source Buffer address.
+ * @param Length : The length of data to be transferred from memory to TIM peripheral
+ * @retval HAL status
+*/
+HAL_StatusTypeDef HAL_TIM_PWM_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, uint32_t *pData, uint16_t Length)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel));
+
+ if((htim->State == HAL_TIM_STATE_BUSY))
+ {
+ return HAL_BUSY;
+ }
+ else if((htim->State == HAL_TIM_STATE_READY))
+ {
+ if(((uint32_t)pData == 0 ) && (Length > 0))
+ {
+ return HAL_ERROR;
+ }
+ else
+ {
+ htim->State = HAL_TIM_STATE_BUSY;
+ }
+ }
+ switch (Channel)
+ {
+ case TIM_CHANNEL_1:
+ {
+ /* Set the DMA Period elapsed callback */
+ htim->hdma[TIM_DMA_ID_CC1]->XferCpltCallback = TIM_DMADelayPulseCplt;
+
+ /* Set the DMA error callback */
+ htim->hdma[TIM_DMA_ID_CC1]->XferErrorCallback = TIM_DMAError ;
+
+ /* Enable the DMA channel */
+ HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC1], (uint32_t)pData, (uint32_t)&htim->Instance->CCR1, Length);
+
+ /* Enable the TIM Capture/Compare 1 DMA request */
+ __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC1);
+ }
+ break;
+
+ case TIM_CHANNEL_2:
+ {
+ /* Set the DMA Period elapsed callback */
+ htim->hdma[TIM_DMA_ID_CC2]->XferCpltCallback = TIM_DMADelayPulseCplt;
+
+ /* Set the DMA error callback */
+ htim->hdma[TIM_DMA_ID_CC2]->XferErrorCallback = TIM_DMAError ;
+
+ /* Enable the DMA channel */
+ HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC2], (uint32_t)pData, (uint32_t)&htim->Instance->CCR2, Length);
+
+ /* Enable the TIM Capture/Compare 2 DMA request */
+ __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC2);
+ }
+ break;
+
+ case TIM_CHANNEL_3:
+ {
+ /* Set the DMA Period elapsed callback */
+ htim->hdma[TIM_DMA_ID_CC3]->XferCpltCallback = TIM_DMADelayPulseCplt;
+
+ /* Set the DMA error callback */
+ htim->hdma[TIM_DMA_ID_CC3]->XferErrorCallback = TIM_DMAError ;
+
+ /* Enable the DMA channel */
+ HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC3], (uint32_t)pData, (uint32_t)&htim->Instance->CCR3,Length);
+
+ /* Enable the TIM Output Capture/Compare 3 request */
+ __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC3);
+ }
+ break;
+
+ case TIM_CHANNEL_4:
+ {
+ /* Set the DMA Period elapsed callback */
+ htim->hdma[TIM_DMA_ID_CC4]->XferCpltCallback = TIM_DMADelayPulseCplt;
+
+ /* Set the DMA error callback */
+ htim->hdma[TIM_DMA_ID_CC4]->XferErrorCallback = TIM_DMAError ;
+
+ /* Enable the DMA channel */
+ HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC4], (uint32_t)pData, (uint32_t)&htim->Instance->CCR4, Length);
+
+ /* Enable the TIM Capture/Compare 4 DMA request */
+ __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC4);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ /* Enable the Capture compare channel */
+ TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_ENABLE);
+
+ if(IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET)
+ {
+ /* Enable the main output */
+ __HAL_TIM_MOE_ENABLE(htim);
+ }
+
+ /* Enable the Peripheral */
+ __HAL_TIM_ENABLE(htim);
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Stops the TIM PWM signal generation in DMA mode.
+ * @param htim : TIM handle
+ * @param Channel : TIM Channels to be disabled
+ * This parameter can be one of the following values:
+ * @arg TIM_CHANNEL_1: TIM Channel 1 selected
+ * @arg TIM_CHANNEL_2: TIM Channel 2 selected
+ * @arg TIM_CHANNEL_3: TIM Channel 3 selected
+ * @arg TIM_CHANNEL_4: TIM Channel 4 selected
+ * @retval HAL status
+*/
+HAL_StatusTypeDef HAL_TIM_PWM_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel));
+
+ switch (Channel)
+ {
+ case TIM_CHANNEL_1:
+ {
+ /* Disable the TIM Capture/Compare 1 DMA request */
+ __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC1);
+ }
+ break;
+
+ case TIM_CHANNEL_2:
+ {
+ /* Disable the TIM Capture/Compare 2 DMA request */
+ __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC2);
+ }
+ break;
+
+ case TIM_CHANNEL_3:
+ {
+ /* Disable the TIM Capture/Compare 3 DMA request */
+ __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC3);
+ }
+ break;
+
+ case TIM_CHANNEL_4:
+ {
+ /* Disable the TIM Capture/Compare 4 interrupt */
+ __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC4);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ /* Disable the Capture compare channel */
+ TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_DISABLE);
+
+ if(IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET)
+ {
+ /* Disable the Main Ouput */
+ __HAL_TIM_MOE_DISABLE(htim);
+ }
+
+ /* Disable the Peripheral */
+ __HAL_TIM_DISABLE(htim);
+
+ /* Change the htim state */
+ htim->State = HAL_TIM_STATE_READY;
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Exported_Functions_Group4 Time Input Capture functions
+ * @brief Time Input Capture functions
+ *
+@verbatim
+ ==============================================================================
+ ##### Time Input Capture functions #####
+ ==============================================================================
+ [..]
+ This section provides functions allowing to:
+ (+) Initialize and configure the TIM Input Capture.
+ (+) De-initialize the TIM Input Capture.
+ (+) Start the Time Input Capture.
+ (+) Stop the Time Input Capture.
+ (+) Start the Time Input Capture and enable interrupt.
+ (+) Stop the Time Input Capture and disable interrupt.
+ (+) Start the Time Input Capture and enable DMA transfer.
+ (+) Stop the Time Input Capture and disable DMA transfer.
+
+@endverbatim
+ * @{
+ */
+/**
+ * @brief Initializes the TIM Input Capture Time base according to the specified
+ * parameters in the TIM_HandleTypeDef and create the associated handle.
+ * @param htim : TIM Input Capture handle
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_TIM_IC_Init(TIM_HandleTypeDef *htim)
+{
+ /* Check the TIM handle allocation */
+ if(htim == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check the parameters */
+ assert_param(IS_TIM_INSTANCE(htim->Instance));
+ assert_param(IS_TIM_COUNTER_MODE(htim->Init.CounterMode));
+ assert_param(IS_TIM_CLOCKDIVISION_DIV(htim->Init.ClockDivision));
+
+ if(htim->State == HAL_TIM_STATE_RESET)
+ {
+ /* Allocate lock resource and initialize it */
+ htim->Lock = HAL_UNLOCKED;
+
+ /* Init the low level hardware : GPIO, CLOCK, NVIC and DMA */
+ HAL_TIM_IC_MspInit(htim);
+ }
+
+ /* Set the TIM state */
+ htim->State= HAL_TIM_STATE_BUSY;
+
+ /* Init the base time for the input capture */
+ TIM_Base_SetConfig(htim->Instance, &htim->Init);
+
+ /* Initialize the TIM state*/
+ htim->State= HAL_TIM_STATE_READY;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief DeInitializes the TIM peripheral
+ * @param htim : TIM Input Capture handle
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_TIM_IC_DeInit(TIM_HandleTypeDef *htim)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_INSTANCE(htim->Instance));
+
+ htim->State = HAL_TIM_STATE_BUSY;
+
+ /* Disable the TIM Peripheral Clock */
+ __HAL_TIM_DISABLE(htim);
+
+ /* DeInit the low level hardware: GPIO, CLOCK, NVIC and DMA */
+ HAL_TIM_IC_MspDeInit(htim);
+
+ /* Change TIM state */
+ htim->State = HAL_TIM_STATE_RESET;
+
+ /* Release Lock */
+ __HAL_UNLOCK(htim);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Initializes the TIM Input Capture MSP.
+ * @param htim : TIM handle
+ * @retval None
+ */
+__weak void HAL_TIM_IC_MspInit(TIM_HandleTypeDef *htim)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(htim);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_TIM_IC_MspInit could be implemented in the user file
+ */
+}
+
+/**
+ * @brief DeInitializes TIM Input Capture MSP.
+ * @param htim : TIM handle
+ * @retval None
+ */
+__weak void HAL_TIM_IC_MspDeInit(TIM_HandleTypeDef *htim)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(htim);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_TIM_IC_MspDeInit could be implemented in the user file
+ */
+}
+
+/**
+ * @brief Starts the TIM Input Capture measurement.
+ * @param htim : TIM Input Capture handle
+ * @param Channel : TIM Channels to be enabled
+ * This parameter can be one of the following values:
+ * @arg TIM_CHANNEL_1: TIM Channel 1 selected
+ * @arg TIM_CHANNEL_2: TIM Channel 2 selected
+ * @arg TIM_CHANNEL_3: TIM Channel 3 selected
+ * @arg TIM_CHANNEL_4: TIM Channel 4 selected
+ * @retval HAL status
+*/
+HAL_StatusTypeDef HAL_TIM_IC_Start (TIM_HandleTypeDef *htim, uint32_t Channel)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel));
+
+ /* Enable the Input Capture channel */
+ TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_ENABLE);
+
+ /* Enable the Peripheral */
+ __HAL_TIM_ENABLE(htim);
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Stops the TIM Input Capture measurement.
+ * @param htim : TIM handle
+ * @param Channel : TIM Channels to be disabled
+ * This parameter can be one of the following values:
+ * @arg TIM_CHANNEL_1: TIM Channel 1 selected
+ * @arg TIM_CHANNEL_2: TIM Channel 2 selected
+ * @arg TIM_CHANNEL_3: TIM Channel 3 selected
+ * @arg TIM_CHANNEL_4: TIM Channel 4 selected
+ * @retval HAL status
+*/
+HAL_StatusTypeDef HAL_TIM_IC_Stop(TIM_HandleTypeDef *htim, uint32_t Channel)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel));
+
+ /* Disable the Input Capture channel */
+ TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_DISABLE);
+
+ /* Disable the Peripheral */
+ __HAL_TIM_DISABLE(htim);
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Starts the TIM Input Capture measurement in interrupt mode.
+ * @param htim : TIM Input Capture handle
+ * @param Channel : TIM Channels to be enabled
+ * This parameter can be one of the following values:
+ * @arg TIM_CHANNEL_1: TIM Channel 1 selected
+ * @arg TIM_CHANNEL_2: TIM Channel 2 selected
+ * @arg TIM_CHANNEL_3: TIM Channel 3 selected
+ * @arg TIM_CHANNEL_4: TIM Channel 4 selected
+ * @retval HAL status
+*/
+HAL_StatusTypeDef HAL_TIM_IC_Start_IT (TIM_HandleTypeDef *htim, uint32_t Channel)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel));
+
+ switch (Channel)
+ {
+ case TIM_CHANNEL_1:
+ {
+ /* Enable the TIM Capture/Compare 1 interrupt */
+ __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1);
+ }
+ break;
+
+ case TIM_CHANNEL_2:
+ {
+ /* Enable the TIM Capture/Compare 2 interrupt */
+ __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC2);
+ }
+ break;
+
+ case TIM_CHANNEL_3:
+ {
+ /* Enable the TIM Capture/Compare 3 interrupt */
+ __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC3);
+ }
+ break;
+
+ case TIM_CHANNEL_4:
+ {
+ /* Enable the TIM Capture/Compare 4 interrupt */
+ __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC4);
+ }
+ break;
+
+ default:
+ break;
+ }
+ /* Enable the Input Capture channel */
+ TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_ENABLE);
+
+ /* Enable the Peripheral */
+ __HAL_TIM_ENABLE(htim);
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Stops the TIM Input Capture measurement in interrupt mode.
+ * @param htim : TIM handle
+ * @param Channel : TIM Channels to be disabled
+ * This parameter can be one of the following values:
+ * @arg TIM_CHANNEL_1: TIM Channel 1 selected
+ * @arg TIM_CHANNEL_2: TIM Channel 2 selected
+ * @arg TIM_CHANNEL_3: TIM Channel 3 selected
+ * @arg TIM_CHANNEL_4: TIM Channel 4 selected
+ * @retval HAL status
+*/
+HAL_StatusTypeDef HAL_TIM_IC_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel));
+
+ switch (Channel)
+ {
+ case TIM_CHANNEL_1:
+ {
+ /* Disable the TIM Capture/Compare 1 interrupt */
+ __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1);
+ }
+ break;
+
+ case TIM_CHANNEL_2:
+ {
+ /* Disable the TIM Capture/Compare 2 interrupt */
+ __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC2);
+ }
+ break;
+
+ case TIM_CHANNEL_3:
+ {
+ /* Disable the TIM Capture/Compare 3 interrupt */
+ __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC3);
+ }
+ break;
+
+ case TIM_CHANNEL_4:
+ {
+ /* Disable the TIM Capture/Compare 4 interrupt */
+ __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC4);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ /* Disable the Input Capture channel */
+ TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_DISABLE);
+
+ /* Disable the Peripheral */
+ __HAL_TIM_DISABLE(htim);
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Starts the TIM Input Capture measurement in DMA mode.
+ * @param htim : TIM Input Capture handle
+ * @param Channel : TIM Channels to be enabled
+ * This parameter can be one of the following values:
+ * @arg TIM_CHANNEL_1: TIM Channel 1 selected
+ * @arg TIM_CHANNEL_2: TIM Channel 2 selected
+ * @arg TIM_CHANNEL_3: TIM Channel 3 selected
+ * @arg TIM_CHANNEL_4: TIM Channel 4 selected
+ * @param pData : The destination Buffer address.
+ * @param Length : The length of data to be transferred from TIM peripheral to memory.
+ * @retval HAL status
+*/
+HAL_StatusTypeDef HAL_TIM_IC_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, uint32_t *pData, uint16_t Length)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel));
+ assert_param(IS_TIM_DMA_CC_INSTANCE(htim->Instance));
+
+ if((htim->State == HAL_TIM_STATE_BUSY))
+ {
+ return HAL_BUSY;
+ }
+ else if((htim->State == HAL_TIM_STATE_READY))
+ {
+ if((pData == 0 ) && (Length > 0))
+ {
+ return HAL_ERROR;
+ }
+ else
+ {
+ htim->State = HAL_TIM_STATE_BUSY;
+ }
+ }
+
+ switch (Channel)
+ {
+ case TIM_CHANNEL_1:
+ {
+ /* Set the DMA Period elapsed callback */
+ htim->hdma[TIM_DMA_ID_CC1]->XferCpltCallback = TIM_DMACaptureCplt;
+
+ /* Set the DMA error callback */
+ htim->hdma[TIM_DMA_ID_CC1]->XferErrorCallback = TIM_DMAError ;
+
+ /* Enable the DMA channel */
+ HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC1], (uint32_t)&htim->Instance->CCR1, (uint32_t)pData, Length);
+
+ /* Enable the TIM Capture/Compare 1 DMA request */
+ __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC1);
+ }
+ break;
+
+ case TIM_CHANNEL_2:
+ {
+ /* Set the DMA Period elapsed callback */
+ htim->hdma[TIM_DMA_ID_CC2]->XferCpltCallback = TIM_DMACaptureCplt;
+
+ /* Set the DMA error callback */
+ htim->hdma[TIM_DMA_ID_CC2]->XferErrorCallback = TIM_DMAError ;
+
+ /* Enable the DMA channel */
+ HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC2], (uint32_t)&htim->Instance->CCR2, (uint32_t)pData, Length);
+
+ /* Enable the TIM Capture/Compare 2 DMA request */
+ __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC2);
+ }
+ break;
+
+ case TIM_CHANNEL_3:
+ {
+ /* Set the DMA Period elapsed callback */
+ htim->hdma[TIM_DMA_ID_CC3]->XferCpltCallback = TIM_DMACaptureCplt;
+
+ /* Set the DMA error callback */
+ htim->hdma[TIM_DMA_ID_CC3]->XferErrorCallback = TIM_DMAError ;
+
+ /* Enable the DMA channel */
+ HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC3], (uint32_t)&htim->Instance->CCR3, (uint32_t)pData, Length);
+
+ /* Enable the TIM Capture/Compare 3 DMA request */
+ __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC3);
+ }
+ break;
+
+ case TIM_CHANNEL_4:
+ {
+ /* Set the DMA Period elapsed callback */
+ htim->hdma[TIM_DMA_ID_CC4]->XferCpltCallback = TIM_DMACaptureCplt;
+
+ /* Set the DMA error callback */
+ htim->hdma[TIM_DMA_ID_CC4]->XferErrorCallback = TIM_DMAError ;
+
+ /* Enable the DMA channel */
+ HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC4], (uint32_t)&htim->Instance->CCR4, (uint32_t)pData, Length);
+
+ /* Enable the TIM Capture/Compare 4 DMA request */
+ __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC4);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ /* Enable the Input Capture channel */
+ TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_ENABLE);
+
+ /* Enable the Peripheral */
+ __HAL_TIM_ENABLE(htim);
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Stops the TIM Input Capture measurement in DMA mode.
+ * @param htim : TIM Input Capture handle
+ * @param Channel : TIM Channels to be disabled
+ * This parameter can be one of the following values:
+ * @arg TIM_CHANNEL_1: TIM Channel 1 selected
+ * @arg TIM_CHANNEL_2: TIM Channel 2 selected
+ * @arg TIM_CHANNEL_3: TIM Channel 3 selected
+ * @arg TIM_CHANNEL_4: TIM Channel 4 selected
+ * @retval HAL status
+*/
+HAL_StatusTypeDef HAL_TIM_IC_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel));
+ assert_param(IS_TIM_DMA_CC_INSTANCE(htim->Instance));
+
+ switch (Channel)
+ {
+ case TIM_CHANNEL_1:
+ {
+ /* Disable the TIM Capture/Compare 1 DMA request */
+ __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC1);
+ }
+ break;
+
+ case TIM_CHANNEL_2:
+ {
+ /* Disable the TIM Capture/Compare 2 DMA request */
+ __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC2);
+ }
+ break;
+
+ case TIM_CHANNEL_3:
+ {
+ /* Disable the TIM Capture/Compare 3 DMA request */
+ __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC3);
+ }
+ break;
+
+ case TIM_CHANNEL_4:
+ {
+ /* Disable the TIM Capture/Compare 4 DMA request */
+ __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC4);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ /* Disable the Input Capture channel */
+ TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_DISABLE);
+
+ /* Disable the Peripheral */
+ __HAL_TIM_DISABLE(htim);
+
+ /* Change the htim state */
+ htim->State = HAL_TIM_STATE_READY;
+
+ /* Return function status */
+ return HAL_OK;
+}
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Exported_Functions_Group5 Time One Pulse functions
+ * @brief Time One Pulse functions
+ *
+@verbatim
+ ==============================================================================
+ ##### Time One Pulse functions #####
+ ==============================================================================
+ [..]
+ This section provides functions allowing to:
+ (+) Initialize and configure the TIM One Pulse.
+ (+) De-initialize the TIM One Pulse.
+ (+) Start the Time One Pulse.
+ (+) Stop the Time One Pulse.
+ (+) Start the Time One Pulse and enable interrupt.
+ (+) Stop the Time One Pulse and disable interrupt.
+ (+) Start the Time One Pulse and enable DMA transfer.
+ (+) Stop the Time One Pulse and disable DMA transfer.
+
+@endverbatim
+ * @{
+ */
+/**
+ * @brief Initializes the TIM One Pulse Time Base according to the specified
+ * parameters in the TIM_HandleTypeDef and create the associated handle.
+ * @param htim : TIM OnePulse handle
+ * @param OnePulseMode : Select the One pulse mode.
+ * This parameter can be one of the following values:
+ * @arg TIM_OPMODE_SINGLE: Only one pulse will be generated.
+ * @arg TIM_OPMODE_REPETITIVE: Repetitive pulses wil be generated.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_TIM_OnePulse_Init(TIM_HandleTypeDef *htim, uint32_t OnePulseMode)
+{
+ /* Check the TIM handle allocation */
+ if(htim == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check the parameters */
+ assert_param(IS_TIM_INSTANCE(htim->Instance));
+ assert_param(IS_TIM_COUNTER_MODE(htim->Init.CounterMode));
+ assert_param(IS_TIM_CLOCKDIVISION_DIV(htim->Init.ClockDivision));
+ assert_param(IS_TIM_OPM_MODE(OnePulseMode));
+
+ if(htim->State == HAL_TIM_STATE_RESET)
+ {
+ /* Allocate lock resource and initialize it */
+ htim->Lock = HAL_UNLOCKED;
+
+ /* Init the low level hardware : GPIO, CLOCK, NVIC and DMA */
+ HAL_TIM_OnePulse_MspInit(htim);
+ }
+
+ /* Set the TIM state */
+ htim->State= HAL_TIM_STATE_BUSY;
+
+ /* Configure the Time base in the One Pulse Mode */
+ TIM_Base_SetConfig(htim->Instance, &htim->Init);
+
+ /* Reset the OPM Bit */
+ htim->Instance->CR1 &= ~TIM_CR1_OPM;
+
+ /* Configure the OPM Mode */
+ htim->Instance->CR1 |= OnePulseMode;
+
+ /* Initialize the TIM state*/
+ htim->State= HAL_TIM_STATE_READY;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief DeInitializes the TIM One Pulse
+ * @param htim : TIM One Pulse handle
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_TIM_OnePulse_DeInit(TIM_HandleTypeDef *htim)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_INSTANCE(htim->Instance));
+
+ htim->State = HAL_TIM_STATE_BUSY;
+
+ /* Disable the TIM Peripheral Clock */
+ __HAL_TIM_DISABLE(htim);
+
+ /* DeInit the low level hardware: GPIO, CLOCK, NVIC */
+ HAL_TIM_OnePulse_MspDeInit(htim);
+
+ /* Change TIM state */
+ htim->State = HAL_TIM_STATE_RESET;
+
+ /* Release Lock */
+ __HAL_UNLOCK(htim);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Initializes the TIM One Pulse MSP.
+ * @param htim : TIM handle
+ * @retval None
+ */
+__weak void HAL_TIM_OnePulse_MspInit(TIM_HandleTypeDef *htim)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(htim);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_TIM_OnePulse_MspInit could be implemented in the user file
+ */
+}
+
+/**
+ * @brief DeInitializes TIM One Pulse MSP.
+ * @param htim : TIM handle
+ * @retval None
+ */
+__weak void HAL_TIM_OnePulse_MspDeInit(TIM_HandleTypeDef *htim)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(htim);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_TIM_OnePulse_MspDeInit could be implemented in the user file
+ */
+}
+
+/**
+ * @brief Starts the TIM One Pulse signal generation.
+ * @param htim : TIM One Pulse handle
+ * @param OutputChannel : TIM Channels to be enabled
+ * This parameter can be one of the following values:
+ * @arg TIM_CHANNEL_1: TIM Channel 1 selected
+ * @arg TIM_CHANNEL_2: TIM Channel 2 selected
+ * @retval HAL status
+*/
+HAL_StatusTypeDef HAL_TIM_OnePulse_Start(TIM_HandleTypeDef *htim, uint32_t OutputChannel)
+{
+ /* Enable the Capture compare and the Input Capture channels
+ (in the OPM Mode the two possible channels that can be used are TIM_CHANNEL_1 and TIM_CHANNEL_2)
+ if TIM_CHANNEL_1 is used as output, the TIM_CHANNEL_2 will be used as input and
+ if TIM_CHANNEL_1 is used as input, the TIM_CHANNEL_2 will be used as output
+ in all combinations, the TIM_CHANNEL_1 and TIM_CHANNEL_2 should be enabled together
+
+ No need to enable the counter, it's enabled automatically by hardware
+ (the counter starts in response to a stimulus and generate a pulse */
+
+ TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE);
+ TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_ENABLE);
+
+ if(IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET)
+ {
+ /* Enable the main output */
+ __HAL_TIM_MOE_ENABLE(htim);
+ }
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Stops the TIM One Pulse signal generation.
+ * @param htim : TIM One Pulse handle
+ * @param OutputChannel : TIM Channels to be disable
+ * This parameter can be one of the following values:
+ * @arg TIM_CHANNEL_1: TIM Channel 1 selected
+ * @arg TIM_CHANNEL_2: TIM Channel 2 selected
+ * @retval HAL status
+*/
+HAL_StatusTypeDef HAL_TIM_OnePulse_Stop(TIM_HandleTypeDef *htim, uint32_t OutputChannel)
+{
+ /* Disable the Capture compare and the Input Capture channels
+ (in the OPM Mode the two possible channels that can be used are TIM_CHANNEL_1 and TIM_CHANNEL_2)
+ if TIM_CHANNEL_1 is used as output, the TIM_CHANNEL_2 will be used as input and
+ if TIM_CHANNEL_1 is used as input, the TIM_CHANNEL_2 will be used as output
+ in all combinations, the TIM_CHANNEL_1 and TIM_CHANNEL_2 should be disabled together */
+
+ TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_DISABLE);
+ TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_DISABLE);
+
+ if(IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET)
+ {
+ /* Disable the Main Ouput */
+ __HAL_TIM_MOE_DISABLE(htim);
+ }
+
+ /* Disable the Peripheral */
+ __HAL_TIM_DISABLE(htim);
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Starts the TIM One Pulse signal generation in interrupt mode.
+ * @param htim : TIM One Pulse handle
+ * @param OutputChannel : TIM Channels to be enabled
+ * This parameter can be one of the following values:
+ * @arg TIM_CHANNEL_1: TIM Channel 1 selected
+ * @arg TIM_CHANNEL_2: TIM Channel 2 selected
+ * @retval HAL status
+*/
+HAL_StatusTypeDef HAL_TIM_OnePulse_Start_IT(TIM_HandleTypeDef *htim, uint32_t OutputChannel)
+{
+ /* Enable the Capture compare and the Input Capture channels
+ (in the OPM Mode the two possible channels that can be used are TIM_CHANNEL_1 and TIM_CHANNEL_2)
+ if TIM_CHANNEL_1 is used as output, the TIM_CHANNEL_2 will be used as input and
+ if TIM_CHANNEL_1 is used as input, the TIM_CHANNEL_2 will be used as output
+ in all combinations, the TIM_CHANNEL_1 and TIM_CHANNEL_2 should be enabled together
+
+ No need to enable the counter, it's enabled automatically by hardware
+ (the counter starts in response to a stimulus and generate a pulse */
+
+ /* Enable the TIM Capture/Compare 1 interrupt */
+ __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1);
+
+ /* Enable the TIM Capture/Compare 2 interrupt */
+ __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC2);
+
+ TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE);
+ TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_ENABLE);
+
+ if(IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET)
+ {
+ /* Enable the main output */
+ __HAL_TIM_MOE_ENABLE(htim);
+ }
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Stops the TIM One Pulse signal generation in interrupt mode.
+ * @param htim : TIM One Pulse handle
+ * @param OutputChannel : TIM Channels to be enabled
+ * This parameter can be one of the following values:
+ * @arg TIM_CHANNEL_1: TIM Channel 1 selected
+ * @arg TIM_CHANNEL_2: TIM Channel 2 selected
+ * @retval HAL status
+*/
+HAL_StatusTypeDef HAL_TIM_OnePulse_Stop_IT(TIM_HandleTypeDef *htim, uint32_t OutputChannel)
+{
+ /* Disable the TIM Capture/Compare 1 interrupt */
+ __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1);
+
+ /* Disable the TIM Capture/Compare 2 interrupt */
+ __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC2);
+
+ /* Disable the Capture compare and the Input Capture channels
+ (in the OPM Mode the two possible channels that can be used are TIM_CHANNEL_1 and TIM_CHANNEL_2)
+ if TIM_CHANNEL_1 is used as output, the TIM_CHANNEL_2 will be used as input and
+ if TIM_CHANNEL_1 is used as input, the TIM_CHANNEL_2 will be used as output
+ in all combinations, the TIM_CHANNEL_1 and TIM_CHANNEL_2 should be disabled together */
+ TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_DISABLE);
+ TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_DISABLE);
+
+ if(IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET)
+ {
+ /* Disable the Main Ouput */
+ __HAL_TIM_MOE_DISABLE(htim);
+ }
+
+ /* Disable the Peripheral */
+ __HAL_TIM_DISABLE(htim);
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Exported_Functions_Group6 Time Encoder functions
+ * @brief Time Encoder functions
+ *
+@verbatim
+ ==============================================================================
+ ##### Time Encoder functions #####
+ ==============================================================================
+ [..]
+ This section provides functions allowing to:
+ (+) Initialize and configure the TIM Encoder.
+ (+) De-initialize the TIM Encoder.
+ (+) Start the Time Encoder.
+ (+) Stop the Time Encoder.
+ (+) Start the Time Encoder and enable interrupt.
+ (+) Stop the Time Encoder and disable interrupt.
+ (+) Start the Time Encoder and enable DMA transfer.
+ (+) Stop the Time Encoder and disable DMA transfer.
+
+@endverbatim
+ * @{
+ */
+/**
+ * @brief Initializes the TIM Encoder Interface and create the associated handle.
+ * @param htim : TIM Encoder Interface handle
+ * @param sConfig : TIM Encoder Interface configuration structure
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_TIM_Encoder_Init(TIM_HandleTypeDef *htim, TIM_Encoder_InitTypeDef* sConfig)
+{
+ uint32_t tmpsmcr = 0;
+ uint32_t tmpccmr1 = 0;
+ uint32_t tmpccer = 0;
+
+ /* Check the TIM handle allocation */
+ if(htim == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check the parameters */
+ assert_param(IS_TIM_CC2_INSTANCE(htim->Instance));
+ assert_param(IS_TIM_ENCODER_MODE(sConfig->EncoderMode));
+ assert_param(IS_TIM_IC_SELECTION(sConfig->IC1Selection));
+ assert_param(IS_TIM_IC_SELECTION(sConfig->IC2Selection));
+ assert_param(IS_TIM_IC_POLARITY(sConfig->IC1Polarity));
+ assert_param(IS_TIM_IC_POLARITY(sConfig->IC2Polarity));
+ assert_param(IS_TIM_IC_PRESCALER(sConfig->IC1Prescaler));
+ assert_param(IS_TIM_IC_PRESCALER(sConfig->IC2Prescaler));
+ assert_param(IS_TIM_IC_FILTER(sConfig->IC1Filter));
+ assert_param(IS_TIM_IC_FILTER(sConfig->IC2Filter));
+
+ if(htim->State == HAL_TIM_STATE_RESET)
+ {
+ /* Allocate lock resource and initialize it */
+ htim->Lock = HAL_UNLOCKED;
+
+ /* Init the low level hardware : GPIO, CLOCK, NVIC and DMA */
+ HAL_TIM_Encoder_MspInit(htim);
+ }
+
+ /* Set the TIM state */
+ htim->State= HAL_TIM_STATE_BUSY;
+
+ /* Reset the SMS bits */
+ htim->Instance->SMCR &= ~TIM_SMCR_SMS;
+
+ /* Configure the Time base in the Encoder Mode */
+ TIM_Base_SetConfig(htim->Instance, &htim->Init);
+
+ /* Get the TIMx SMCR register value */
+ tmpsmcr = htim->Instance->SMCR;
+
+ /* Get the TIMx CCMR1 register value */
+ tmpccmr1 = htim->Instance->CCMR1;
+
+ /* Get the TIMx CCER register value */
+ tmpccer = htim->Instance->CCER;
+
+ /* Set the encoder Mode */
+ tmpsmcr |= sConfig->EncoderMode;
+
+ /* Select the Capture Compare 1 and the Capture Compare 2 as input */
+ tmpccmr1 &= ~(TIM_CCMR1_CC1S | TIM_CCMR1_CC2S);
+ tmpccmr1 |= (sConfig->IC1Selection | (sConfig->IC2Selection << 8));
+
+ /* Set the the Capture Compare 1 and the Capture Compare 2 prescalers and filters */
+ tmpccmr1 &= ~(TIM_CCMR1_IC1PSC | TIM_CCMR1_IC2PSC);
+ tmpccmr1 &= ~(TIM_CCMR1_IC1F | TIM_CCMR1_IC2F);
+ tmpccmr1 |= sConfig->IC1Prescaler | (sConfig->IC2Prescaler << 8);
+ tmpccmr1 |= (sConfig->IC1Filter << 4) | (sConfig->IC2Filter << 12);
+
+ /* Set the TI1 and the TI2 Polarities */
+ tmpccer &= ~(TIM_CCER_CC1P | TIM_CCER_CC2P);
+ tmpccer &= ~(TIM_CCER_CC1NP | TIM_CCER_CC2NP);
+ tmpccer |= sConfig->IC1Polarity | (sConfig->IC2Polarity << 4);
+
+ /* Write to TIMx SMCR */
+ htim->Instance->SMCR = tmpsmcr;
+
+ /* Write to TIMx CCMR1 */
+ htim->Instance->CCMR1 = tmpccmr1;
+
+ /* Write to TIMx CCER */
+ htim->Instance->CCER = tmpccer;
+
+ /* Initialize the TIM state*/
+ htim->State= HAL_TIM_STATE_READY;
+
+ return HAL_OK;
+}
+
+
+/**
+ * @brief DeInitializes the TIM Encoder interface
+ * @param htim : TIM Encoder handle
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_TIM_Encoder_DeInit(TIM_HandleTypeDef *htim)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_INSTANCE(htim->Instance));
+
+ htim->State = HAL_TIM_STATE_BUSY;
+
+ /* Disable the TIM Peripheral Clock */
+ __HAL_TIM_DISABLE(htim);
+
+ /* DeInit the low level hardware: GPIO, CLOCK, NVIC */
+ HAL_TIM_Encoder_MspDeInit(htim);
+
+ /* Change TIM state */
+ htim->State = HAL_TIM_STATE_RESET;
+
+ /* Release Lock */
+ __HAL_UNLOCK(htim);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Initializes the TIM Encoder Interface MSP.
+ * @param htim : TIM handle
+ * @retval None
+ */
+__weak void HAL_TIM_Encoder_MspInit(TIM_HandleTypeDef *htim)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(htim);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_TIM_Encoder_MspInit could be implemented in the user file
+ */
+}
+
+/**
+ * @brief DeInitializes TIM Encoder Interface MSP.
+ * @param htim : TIM handle
+ * @retval None
+ */
+__weak void HAL_TIM_Encoder_MspDeInit(TIM_HandleTypeDef *htim)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(htim);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_TIM_Encoder_MspDeInit could be implemented in the user file
+ */
+}
+
+/**
+ * @brief Starts the TIM Encoder Interface.
+ * @param htim : TIM Encoder Interface handle
+ * @param Channel : TIM Channels to be enabled
+ * This parameter can be one of the following values:
+ * @arg TIM_CHANNEL_1: TIM Channel 1 selected
+ * @arg TIM_CHANNEL_2: TIM Channel 2 selected
+ * @arg TIM_CHANNEL_ALL: TIM Channel 1 and TIM Channel 2 are selected
+ * @retval HAL status
+*/
+HAL_StatusTypeDef HAL_TIM_Encoder_Start(TIM_HandleTypeDef *htim, uint32_t Channel)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_CC2_INSTANCE(htim->Instance));
+
+ /* Enable the encoder interface channels */
+ switch (Channel)
+ {
+ case TIM_CHANNEL_1:
+ {
+ TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE);
+ break;
+ }
+ case TIM_CHANNEL_2:
+ {
+ TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_ENABLE);
+ break;
+ }
+ default :
+ {
+ TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE);
+ TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_ENABLE);
+ break;
+ }
+ }
+ /* Enable the Peripheral */
+ __HAL_TIM_ENABLE(htim);
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Stops the TIM Encoder Interface.
+ * @param htim : TIM Encoder Interface handle
+ * @param Channel : TIM Channels to be disabled
+ * This parameter can be one of the following values:
+ * @arg TIM_CHANNEL_1: TIM Channel 1 selected
+ * @arg TIM_CHANNEL_2: TIM Channel 2 selected
+ * @arg TIM_CHANNEL_ALL: TIM Channel 1 and TIM Channel 2 are selected
+ * @retval HAL status
+*/
+HAL_StatusTypeDef HAL_TIM_Encoder_Stop(TIM_HandleTypeDef *htim, uint32_t Channel)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_CC2_INSTANCE(htim->Instance));
+
+ /* Disable the Input Capture channels 1 and 2
+ (in the EncoderInterface the two possible channels that can be used are TIM_CHANNEL_1 and TIM_CHANNEL_2) */
+ switch (Channel)
+ {
+ case TIM_CHANNEL_1:
+ {
+ TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_DISABLE);
+ break;
+ }
+ case TIM_CHANNEL_2:
+ {
+ TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_DISABLE);
+ break;
+ }
+ default :
+ {
+ TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_DISABLE);
+ TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_DISABLE);
+ break;
+ }
+ }
+
+ /* Disable the Peripheral */
+ __HAL_TIM_DISABLE(htim);
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Starts the TIM Encoder Interface in interrupt mode.
+ * @param htim : TIM Encoder Interface handle
+ * @param Channel : TIM Channels to be enabled
+ * This parameter can be one of the following values:
+ * @arg TIM_CHANNEL_1: TIM Channel 1 selected
+ * @arg TIM_CHANNEL_2: TIM Channel 2 selected
+ * @arg TIM_CHANNEL_ALL: TIM Channel 1 and TIM Channel 2 are selected
+ * @retval HAL status
+*/
+HAL_StatusTypeDef HAL_TIM_Encoder_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_CC2_INSTANCE(htim->Instance));
+
+ /* Enable the encoder interface channels */
+ /* Enable the capture compare Interrupts 1 and/or 2 */
+ switch (Channel)
+ {
+ case TIM_CHANNEL_1:
+ {
+ TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE);
+ __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1);
+ break;
+ }
+ case TIM_CHANNEL_2:
+ {
+ TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_ENABLE);
+ __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC2);
+ break;
+ }
+ default :
+ {
+ TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE);
+ TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_ENABLE);
+ __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1);
+ __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC2);
+ break;
+ }
+ }
+
+ /* Enable the Peripheral */
+ __HAL_TIM_ENABLE(htim);
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Stops the TIM Encoder Interface in interrupt mode.
+ * @param htim : TIM Encoder Interface handle
+ * @param Channel : TIM Channels to be disabled
+ * This parameter can be one of the following values:
+ * @arg TIM_CHANNEL_1: TIM Channel 1 selected
+ * @arg TIM_CHANNEL_2: TIM Channel 2 selected
+ * @arg TIM_CHANNEL_ALL: TIM Channel 1 and TIM Channel 2 are selected
+ * @retval HAL status
+*/
+HAL_StatusTypeDef HAL_TIM_Encoder_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_CC2_INSTANCE(htim->Instance));
+
+ /* Disable the Input Capture channels 1 and 2
+ (in the EncoderInterface the two possible channels that can be used are TIM_CHANNEL_1 and TIM_CHANNEL_2) */
+ if(Channel == TIM_CHANNEL_1)
+ {
+ TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_DISABLE);
+
+ /* Disable the capture compare Interrupts 1 */
+ __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1);
+ }
+ else if(Channel == TIM_CHANNEL_2)
+ {
+ TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_DISABLE);
+
+ /* Disable the capture compare Interrupts 2 */
+ __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC2);
+ }
+ else
+ {
+ TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_DISABLE);
+ TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_DISABLE);
+
+ /* Disable the capture compare Interrupts 1 and 2 */
+ __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1);
+ __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC2);
+ }
+
+ /* Disable the Peripheral */
+ __HAL_TIM_DISABLE(htim);
+
+ /* Change the htim state */
+ htim->State = HAL_TIM_STATE_READY;
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Starts the TIM Encoder Interface in DMA mode.
+ * @param htim : TIM Encoder Interface handle
+ * @param Channel : TIM Channels to be enabled
+ * This parameter can be one of the following values:
+ * @arg TIM_CHANNEL_1: TIM Channel 1 selected
+ * @arg TIM_CHANNEL_2: TIM Channel 2 selected
+ * @arg TIM_CHANNEL_ALL: TIM Channel 1 and TIM Channel 2 are selected
+ * @param pData1 : The destination Buffer address for IC1.
+ * @param pData2 : The destination Buffer address for IC2.
+ * @param Length : The length of data to be transferred from TIM peripheral to memory.
+ * @retval HAL status
+*/
+HAL_StatusTypeDef HAL_TIM_Encoder_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, uint32_t *pData1, uint32_t *pData2, uint16_t Length)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_DMA_CC_INSTANCE(htim->Instance));
+
+ if((htim->State == HAL_TIM_STATE_BUSY))
+ {
+ return HAL_BUSY;
+ }
+ else if((htim->State == HAL_TIM_STATE_READY))
+ {
+ if((((pData1 == 0) || (pData2 == 0) )) && (Length > 0))
+ {
+ return HAL_ERROR;
+ }
+ else
+ {
+ htim->State = HAL_TIM_STATE_BUSY;
+ }
+ }
+
+ switch (Channel)
+ {
+ case TIM_CHANNEL_1:
+ {
+ /* Set the DMA Period elapsed callback */
+ htim->hdma[TIM_DMA_ID_CC1]->XferCpltCallback = TIM_DMACaptureCplt;
+
+ /* Set the DMA error callback */
+ htim->hdma[TIM_DMA_ID_CC1]->XferErrorCallback = TIM_DMAError ;
+
+ /* Enable the DMA channel */
+ HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC1], (uint32_t)&htim->Instance->CCR1, (uint32_t )pData1, Length);
+
+ /* Enable the TIM Input Capture DMA request */
+ __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC1);
+
+ /* Enable the Peripheral */
+ __HAL_TIM_ENABLE(htim);
+
+ /* Enable the Capture compare channel */
+ TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE);
+ }
+ break;
+
+ case TIM_CHANNEL_2:
+ {
+ /* Set the DMA Period elapsed callback */
+ htim->hdma[TIM_DMA_ID_CC2]->XferCpltCallback = TIM_DMACaptureCplt;
+
+ /* Set the DMA error callback */
+ htim->hdma[TIM_DMA_ID_CC2]->XferErrorCallback = TIM_DMAError;
+ /* Enable the DMA channel */
+ HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC2], (uint32_t)&htim->Instance->CCR2, (uint32_t)pData2, Length);
+
+ /* Enable the TIM Input Capture DMA request */
+ __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC2);
+
+ /* Enable the Peripheral */
+ __HAL_TIM_ENABLE(htim);
+
+ /* Enable the Capture compare channel */
+ TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_ENABLE);
+ }
+ break;
+
+ case TIM_CHANNEL_ALL:
+ {
+ /* Set the DMA Period elapsed callback */
+ htim->hdma[TIM_DMA_ID_CC1]->XferCpltCallback = TIM_DMACaptureCplt;
+
+ /* Set the DMA error callback */
+ htim->hdma[TIM_DMA_ID_CC1]->XferErrorCallback = TIM_DMAError ;
+
+ /* Enable the DMA channel */
+ HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC1], (uint32_t)&htim->Instance->CCR1, (uint32_t)pData1, Length);
+
+ /* Set the DMA Period elapsed callback */
+ htim->hdma[TIM_DMA_ID_CC2]->XferCpltCallback = TIM_DMACaptureCplt;
+
+ /* Set the DMA error callback */
+ htim->hdma[TIM_DMA_ID_CC2]->XferErrorCallback = TIM_DMAError ;
+
+ /* Enable the DMA channel */
+ HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC2], (uint32_t)&htim->Instance->CCR2, (uint32_t)pData2, Length);
+
+ /* Enable the Peripheral */
+ __HAL_TIM_ENABLE(htim);
+
+ /* Enable the Capture compare channel */
+ TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE);
+ TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_ENABLE);
+
+ /* Enable the TIM Input Capture DMA request */
+ __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC1);
+ /* Enable the TIM Input Capture DMA request */
+ __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC2);
+ }
+ break;
+
+ default:
+ break;
+ }
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Stops the TIM Encoder Interface in DMA mode.
+ * @param htim : TIM Encoder Interface handle
+ * @param Channel : TIM Channels to be enabled
+ * This parameter can be one of the following values:
+ * @arg TIM_CHANNEL_1: TIM Channel 1 selected
+ * @arg TIM_CHANNEL_2: TIM Channel 2 selected
+ * @arg TIM_CHANNEL_ALL: TIM Channel 1 and TIM Channel 2 are selected
+ * @retval HAL status
+*/
+HAL_StatusTypeDef HAL_TIM_Encoder_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_DMA_CC_INSTANCE(htim->Instance));
+
+ /* Disable the Input Capture channels 1 and 2
+ (in the EncoderInterface the two possible channels that can be used are TIM_CHANNEL_1 and TIM_CHANNEL_2) */
+ if(Channel == TIM_CHANNEL_1)
+ {
+ TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_DISABLE);
+
+ /* Disable the capture compare DMA Request 1 */
+ __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC1);
+ }
+ else if(Channel == TIM_CHANNEL_2)
+ {
+ TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_DISABLE);
+
+ /* Disable the capture compare DMA Request 2 */
+ __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC2);
+ }
+ else
+ {
+ TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_DISABLE);
+ TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_DISABLE);
+
+ /* Disable the capture compare DMA Request 1 and 2 */
+ __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC1);
+ __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC2);
+ }
+
+ /* Disable the Peripheral */
+ __HAL_TIM_DISABLE(htim);
+
+ /* Change the htim state */
+ htim->State = HAL_TIM_STATE_READY;
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @}
+ */
+/** @defgroup TIM_Exported_Functions_Group7 TIM IRQ handler management
+ * @brief IRQ handler management
+ *
+@verbatim
+ ==============================================================================
+ ##### IRQ handler management #####
+ ==============================================================================
+ [..]
+ This section provides Timer IRQ handler function.
+
+@endverbatim
+ * @{
+ */
+/**
+ * @brief This function handles TIM interrupts requests.
+ * @param htim : TIM handle
+ * @retval None
+ */
+void HAL_TIM_IRQHandler(TIM_HandleTypeDef *htim)
+{
+ /* Capture compare 1 event */
+ if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC1) != RESET)
+ {
+ if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC1) !=RESET)
+ {
+ {
+ __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC1);
+ htim->Channel = HAL_TIM_ACTIVE_CHANNEL_1;
+
+ /* Input capture event */
+ if((htim->Instance->CCMR1 & TIM_CCMR1_CC1S) != 0x00)
+ {
+ HAL_TIM_IC_CaptureCallback(htim);
+ }
+ /* Output compare event */
+ else
+ {
+ HAL_TIM_OC_DelayElapsedCallback(htim);
+ HAL_TIM_PWM_PulseFinishedCallback(htim);
+ }
+ htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;
+ }
+ }
+ }
+ /* Capture compare 2 event */
+ if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC2) != RESET)
+ {
+ if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC2) !=RESET)
+ {
+ __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC2);
+ htim->Channel = HAL_TIM_ACTIVE_CHANNEL_2;
+ /* Input capture event */
+ if((htim->Instance->CCMR1 & TIM_CCMR1_CC2S) != 0x00)
+ {
+ HAL_TIM_IC_CaptureCallback(htim);
+ }
+ /* Output compare event */
+ else
+ {
+ HAL_TIM_OC_DelayElapsedCallback(htim);
+ HAL_TIM_PWM_PulseFinishedCallback(htim);
+ }
+ htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;
+ }
+ }
+ /* Capture compare 3 event */
+ if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC3) != RESET)
+ {
+ if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC3) !=RESET)
+ {
+ __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC3);
+ htim->Channel = HAL_TIM_ACTIVE_CHANNEL_3;
+ /* Input capture event */
+ if((htim->Instance->CCMR2 & TIM_CCMR2_CC3S) != 0x00)
+ {
+ HAL_TIM_IC_CaptureCallback(htim);
+ }
+ /* Output compare event */
+ else
+ {
+ HAL_TIM_OC_DelayElapsedCallback(htim);
+ HAL_TIM_PWM_PulseFinishedCallback(htim);
+ }
+ htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;
+ }
+ }
+ /* Capture compare 4 event */
+ if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC4) != RESET)
+ {
+ if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC4) !=RESET)
+ {
+ __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC4);
+ htim->Channel = HAL_TIM_ACTIVE_CHANNEL_4;
+ /* Input capture event */
+ if((htim->Instance->CCMR2 & TIM_CCMR2_CC4S) != 0x00)
+ {
+ HAL_TIM_IC_CaptureCallback(htim);
+ }
+ /* Output compare event */
+ else
+ {
+ HAL_TIM_OC_DelayElapsedCallback(htim);
+ HAL_TIM_PWM_PulseFinishedCallback(htim);
+ }
+ htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;
+ }
+ }
+ /* TIM Update event */
+ if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_UPDATE) != RESET)
+ {
+ if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_UPDATE) !=RESET)
+ {
+ __HAL_TIM_CLEAR_IT(htim, TIM_IT_UPDATE);
+ HAL_TIM_PeriodElapsedCallback(htim);
+ }
+ }
+ /* TIM Break input event */
+ if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_BREAK) != RESET)
+ {
+ if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_BREAK) !=RESET)
+ {
+ __HAL_TIM_CLEAR_IT(htim, TIM_IT_BREAK);
+ HAL_TIMEx_BreakCallback(htim);
+ }
+ }
+ /* TIM Trigger detection event */
+ if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_TRIGGER) != RESET)
+ {
+ if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_TRIGGER) !=RESET)
+ {
+ __HAL_TIM_CLEAR_IT(htim, TIM_IT_TRIGGER);
+ HAL_TIM_TriggerCallback(htim);
+ }
+ }
+ /* TIM commutation event */
+ if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_COM) != RESET)
+ {
+ if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_COM) !=RESET)
+ {
+ __HAL_TIM_CLEAR_IT(htim, TIM_FLAG_COM);
+ HAL_TIMEx_CommutationCallback(htim);
+ }
+ }
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Exported_Functions_Group8 Peripheral Control functions
+ * @brief Peripheral Control functions
+ *
+@verbatim
+ ==============================================================================
+ ##### Peripheral Control functions #####
+ ==============================================================================
+ [..]
+ This section provides functions allowing to:
+ (+) Configure The Input Output channels for OC, PWM, IC or One Pulse mode.
+ (+) Configure External Clock source.
+ (+) Configure Complementary channels, break features and dead time.
+ (+) Configure Master and the Slave synchronization.
+ (+) Configure the DMA Burst Mode.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Initializes the TIM Output Compare Channels according to the specified
+ * parameters in the TIM_OC_InitTypeDef.
+ * @param htim : TIM Output Compare handle
+ * @param sConfig : TIM Output Compare configuration structure
+ * @param Channel : TIM Channels to be enabled
+ * This parameter can be one of the following values:
+ * @arg TIM_CHANNEL_1: TIM Channel 1 selected
+ * @arg TIM_CHANNEL_2: TIM Channel 2 selected
+ * @arg TIM_CHANNEL_3: TIM Channel 3 selected
+ * @arg TIM_CHANNEL_4: TIM Channel 4 selected
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_TIM_OC_ConfigChannel(TIM_HandleTypeDef *htim, TIM_OC_InitTypeDef* sConfig, uint32_t Channel)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_CHANNELS(Channel));
+ assert_param(IS_TIM_OC_MODE(sConfig->OCMode));
+ assert_param(IS_TIM_OC_POLARITY(sConfig->OCPolarity));
+
+ /* Check input state */
+ __HAL_LOCK(htim);
+
+ htim->State = HAL_TIM_STATE_BUSY;
+
+ switch (Channel)
+ {
+ case TIM_CHANNEL_1:
+ {
+ assert_param(IS_TIM_CC1_INSTANCE(htim->Instance));
+ /* Configure the TIM Channel 1 in Output Compare */
+ TIM_OC1_SetConfig(htim->Instance, sConfig);
+ }
+ break;
+
+ case TIM_CHANNEL_2:
+ {
+ assert_param(IS_TIM_CC2_INSTANCE(htim->Instance));
+ /* Configure the TIM Channel 2 in Output Compare */
+ TIM_OC2_SetConfig(htim->Instance, sConfig);
+ }
+ break;
+
+ case TIM_CHANNEL_3:
+ {
+ assert_param(IS_TIM_CC3_INSTANCE(htim->Instance));
+ /* Configure the TIM Channel 3 in Output Compare */
+ TIM_OC3_SetConfig(htim->Instance, sConfig);
+ }
+ break;
+
+ case TIM_CHANNEL_4:
+ {
+ assert_param(IS_TIM_CC4_INSTANCE(htim->Instance));
+ /* Configure the TIM Channel 4 in Output Compare */
+ TIM_OC4_SetConfig(htim->Instance, sConfig);
+ }
+ break;
+
+ default:
+ break;
+ }
+ htim->State = HAL_TIM_STATE_READY;
+
+ __HAL_UNLOCK(htim);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Initializes the TIM Input Capture Channels according to the specified
+ * parameters in the TIM_IC_InitTypeDef.
+ * @param htim : TIM IC handle
+ * @param sConfig : TIM Input Capture configuration structure
+ * @param Channel : TIM Channels to be enabled
+ * This parameter can be one of the following values:
+ * @arg TIM_CHANNEL_1: TIM Channel 1 selected
+ * @arg TIM_CHANNEL_2: TIM Channel 2 selected
+ * @arg TIM_CHANNEL_3: TIM Channel 3 selected
+ * @arg TIM_CHANNEL_4: TIM Channel 4 selected
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_TIM_IC_ConfigChannel(TIM_HandleTypeDef *htim, TIM_IC_InitTypeDef* sConfig, uint32_t Channel)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_CC1_INSTANCE(htim->Instance));
+ assert_param(IS_TIM_IC_POLARITY(sConfig->ICPolarity));
+ assert_param(IS_TIM_IC_SELECTION(sConfig->ICSelection));
+ assert_param(IS_TIM_IC_PRESCALER(sConfig->ICPrescaler));
+ assert_param(IS_TIM_IC_FILTER(sConfig->ICFilter));
+
+ __HAL_LOCK(htim);
+
+ htim->State = HAL_TIM_STATE_BUSY;
+
+ if (Channel == TIM_CHANNEL_1)
+ {
+ /* TI1 Configuration */
+ TIM_TI1_SetConfig(htim->Instance,
+ sConfig->ICPolarity,
+ sConfig->ICSelection,
+ sConfig->ICFilter);
+
+ /* Reset the IC1PSC Bits */
+ htim->Instance->CCMR1 &= ~TIM_CCMR1_IC1PSC;
+
+ /* Set the IC1PSC value */
+ htim->Instance->CCMR1 |= sConfig->ICPrescaler;
+ }
+ else if (Channel == TIM_CHANNEL_2)
+ {
+ /* TI2 Configuration */
+ assert_param(IS_TIM_CC2_INSTANCE(htim->Instance));
+
+ TIM_TI2_SetConfig(htim->Instance,
+ sConfig->ICPolarity,
+ sConfig->ICSelection,
+ sConfig->ICFilter);
+
+ /* Reset the IC2PSC Bits */
+ htim->Instance->CCMR1 &= ~TIM_CCMR1_IC2PSC;
+
+ /* Set the IC2PSC value */
+ htim->Instance->CCMR1 |= (sConfig->ICPrescaler << 8);
+ }
+ else if (Channel == TIM_CHANNEL_3)
+ {
+ /* TI3 Configuration */
+ assert_param(IS_TIM_CC3_INSTANCE(htim->Instance));
+
+ TIM_TI3_SetConfig(htim->Instance,
+ sConfig->ICPolarity,
+ sConfig->ICSelection,
+ sConfig->ICFilter);
+
+ /* Reset the IC3PSC Bits */
+ htim->Instance->CCMR2 &= ~TIM_CCMR2_IC3PSC;
+
+ /* Set the IC3PSC value */
+ htim->Instance->CCMR2 |= sConfig->ICPrescaler;
+ }
+ else
+ {
+ /* TI4 Configuration */
+ assert_param(IS_TIM_CC4_INSTANCE(htim->Instance));
+
+ TIM_TI4_SetConfig(htim->Instance,
+ sConfig->ICPolarity,
+ sConfig->ICSelection,
+ sConfig->ICFilter);
+
+ /* Reset the IC4PSC Bits */
+ htim->Instance->CCMR2 &= ~TIM_CCMR2_IC4PSC;
+
+ /* Set the IC4PSC value */
+ htim->Instance->CCMR2 |= (sConfig->ICPrescaler << 8);
+ }
+
+ htim->State = HAL_TIM_STATE_READY;
+
+ __HAL_UNLOCK(htim);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Initializes the TIM PWM channels according to the specified
+ * parameters in the TIM_OC_InitTypeDef.
+ * @param htim : TIM handle
+ * @param sConfig : TIM PWM configuration structure
+ * @param Channel : TIM Channels to be enabled
+ * This parameter can be one of the following values:
+ * @arg TIM_CHANNEL_1: TIM Channel 1 selected
+ * @arg TIM_CHANNEL_2: TIM Channel 2 selected
+ * @arg TIM_CHANNEL_3: TIM Channel 3 selected
+ * @arg TIM_CHANNEL_4: TIM Channel 4 selected
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_TIM_PWM_ConfigChannel(TIM_HandleTypeDef *htim, TIM_OC_InitTypeDef* sConfig, uint32_t Channel)
+{
+ __HAL_LOCK(htim);
+
+ /* Check the parameters */
+ assert_param(IS_TIM_CHANNELS(Channel));
+ assert_param(IS_TIM_PWM_MODE(sConfig->OCMode));
+ assert_param(IS_TIM_OC_POLARITY(sConfig->OCPolarity));
+ assert_param(IS_TIM_FAST_STATE(sConfig->OCFastMode));
+
+ htim->State = HAL_TIM_STATE_BUSY;
+
+ switch (Channel)
+ {
+ case TIM_CHANNEL_1:
+ {
+ assert_param(IS_TIM_CC1_INSTANCE(htim->Instance));
+ /* Configure the Channel 1 in PWM mode */
+ TIM_OC1_SetConfig(htim->Instance, sConfig);
+
+ /* Set the Preload enable bit for channel1 */
+ htim->Instance->CCMR1 |= TIM_CCMR1_OC1PE;
+
+ /* Configure the Output Fast mode */
+ htim->Instance->CCMR1 &= ~TIM_CCMR1_OC1FE;
+ htim->Instance->CCMR1 |= sConfig->OCFastMode;
+ }
+ break;
+
+ case TIM_CHANNEL_2:
+ {
+ assert_param(IS_TIM_CC2_INSTANCE(htim->Instance));
+ /* Configure the Channel 2 in PWM mode */
+ TIM_OC2_SetConfig(htim->Instance, sConfig);
+
+ /* Set the Preload enable bit for channel2 */
+ htim->Instance->CCMR1 |= TIM_CCMR1_OC2PE;
+
+ /* Configure the Output Fast mode */
+ htim->Instance->CCMR1 &= ~TIM_CCMR1_OC2FE;
+ htim->Instance->CCMR1 |= sConfig->OCFastMode << 8;
+ }
+ break;
+
+ case TIM_CHANNEL_3:
+ {
+ assert_param(IS_TIM_CC3_INSTANCE(htim->Instance));
+ /* Configure the Channel 3 in PWM mode */
+ TIM_OC3_SetConfig(htim->Instance, sConfig);
+
+ /* Set the Preload enable bit for channel3 */
+ htim->Instance->CCMR2 |= TIM_CCMR2_OC3PE;
+
+ /* Configure the Output Fast mode */
+ htim->Instance->CCMR2 &= ~TIM_CCMR2_OC3FE;
+ htim->Instance->CCMR2 |= sConfig->OCFastMode;
+ }
+ break;
+
+ case TIM_CHANNEL_4:
+ {
+ assert_param(IS_TIM_CC4_INSTANCE(htim->Instance));
+ /* Configure the Channel 4 in PWM mode */
+ TIM_OC4_SetConfig(htim->Instance, sConfig);
+
+ /* Set the Preload enable bit for channel4 */
+ htim->Instance->CCMR2 |= TIM_CCMR2_OC4PE;
+
+ /* Configure the Output Fast mode */
+ htim->Instance->CCMR2 &= ~TIM_CCMR2_OC4FE;
+ htim->Instance->CCMR2 |= sConfig->OCFastMode << 8;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ htim->State = HAL_TIM_STATE_READY;
+
+ __HAL_UNLOCK(htim);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Initializes the TIM One Pulse Channels according to the specified
+ * parameters in the TIM_OnePulse_InitTypeDef.
+ * @param htim : TIM One Pulse handle
+ * @param sConfig : TIM One Pulse configuration structure
+ * @param OutputChannel : TIM Channels to be enabled
+ * This parameter can be one of the following values:
+ * @arg TIM_CHANNEL_1: TIM Channel 1 selected
+ * @arg TIM_CHANNEL_2: TIM Channel 2 selected
+ * @param InputChannel : TIM Channels to be enabled
+ * This parameter can be one of the following values:
+ * @arg TIM_CHANNEL_1: TIM Channel 1 selected
+ * @arg TIM_CHANNEL_2: TIM Channel 2 selected
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_TIM_OnePulse_ConfigChannel(TIM_HandleTypeDef *htim, TIM_OnePulse_InitTypeDef* sConfig, uint32_t OutputChannel, uint32_t InputChannel)
+{
+ TIM_OC_InitTypeDef temp1;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_OPM_CHANNELS(OutputChannel));
+ assert_param(IS_TIM_OPM_CHANNELS(InputChannel));
+
+ if(OutputChannel != InputChannel)
+ {
+ __HAL_LOCK(htim);
+
+ htim->State = HAL_TIM_STATE_BUSY;
+
+ /* Extract the Ouput compare configuration from sConfig structure */
+ temp1.OCMode = sConfig->OCMode;
+ temp1.Pulse = sConfig->Pulse;
+ temp1.OCPolarity = sConfig->OCPolarity;
+ temp1.OCNPolarity = sConfig->OCNPolarity;
+ temp1.OCIdleState = sConfig->OCIdleState;
+ temp1.OCNIdleState = sConfig->OCNIdleState;
+
+ switch (OutputChannel)
+ {
+ case TIM_CHANNEL_1:
+ {
+ assert_param(IS_TIM_CC1_INSTANCE(htim->Instance));
+
+ TIM_OC1_SetConfig(htim->Instance, &temp1);
+ }
+ break;
+ case TIM_CHANNEL_2:
+ {
+ assert_param(IS_TIM_CC2_INSTANCE(htim->Instance));
+
+ TIM_OC2_SetConfig(htim->Instance, &temp1);
+ }
+ break;
+ default:
+ break;
+ }
+ switch (InputChannel)
+ {
+ case TIM_CHANNEL_1:
+ {
+ assert_param(IS_TIM_CC1_INSTANCE(htim->Instance));
+
+ TIM_TI1_SetConfig(htim->Instance, sConfig->ICPolarity,
+ sConfig->ICSelection, sConfig->ICFilter);
+
+ /* Reset the IC1PSC Bits */
+ htim->Instance->CCMR1 &= ~TIM_CCMR1_IC1PSC;
+
+ /* Select the Trigger source */
+ htim->Instance->SMCR &= ~TIM_SMCR_TS;
+ htim->Instance->SMCR |= TIM_TS_TI1FP1;
+
+ /* Select the Slave Mode */
+ htim->Instance->SMCR &= ~TIM_SMCR_SMS;
+ htim->Instance->SMCR |= TIM_SLAVEMODE_TRIGGER;
+ }
+ break;
+ case TIM_CHANNEL_2:
+ {
+ assert_param(IS_TIM_CC2_INSTANCE(htim->Instance));
+
+ TIM_TI2_SetConfig(htim->Instance, sConfig->ICPolarity,
+ sConfig->ICSelection, sConfig->ICFilter);
+
+ /* Reset the IC2PSC Bits */
+ htim->Instance->CCMR1 &= ~TIM_CCMR1_IC2PSC;
+
+ /* Select the Trigger source */
+ htim->Instance->SMCR &= ~TIM_SMCR_TS;
+ htim->Instance->SMCR |= TIM_TS_TI2FP2;
+
+ /* Select the Slave Mode */
+ htim->Instance->SMCR &= ~TIM_SMCR_SMS;
+ htim->Instance->SMCR |= TIM_SLAVEMODE_TRIGGER;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ htim->State = HAL_TIM_STATE_READY;
+
+ __HAL_UNLOCK(htim);
+
+ return HAL_OK;
+}
+ else
+ {
+ return HAL_ERROR;
+ }
+}
+
+/**
+ * @brief Configure the DMA Burst to transfer Data from the memory to the TIM peripheral
+ * @param htim : TIM handle
+ * @param BurstBaseAddress : TIM Base address from where the DMA will start the Data write
+ * This parameter can be one of the following values:
+ * @arg TIM_DMABASE_CR1
+ * @arg TIM_DMABASE_CR2
+ * @arg TIM_DMABASE_SMCR
+ * @arg TIM_DMABASE_DIER
+ * @arg TIM_DMABASE_SR
+ * @arg TIM_DMABASE_EGR
+ * @arg TIM_DMABASE_CCMR1
+ * @arg TIM_DMABASE_CCMR2
+ * @arg TIM_DMABASE_CCER
+ * @arg TIM_DMABASE_CNT
+ * @arg TIM_DMABASE_PSC
+ * @arg TIM_DMABASE_ARR
+ * @arg TIM_DMABASE_RCR
+ * @arg TIM_DMABASE_CCR1
+ * @arg TIM_DMABASE_CCR2
+ * @arg TIM_DMABASE_CCR3
+ * @arg TIM_DMABASE_CCR4
+ * @arg TIM_DMABASE_BDTR
+ * @arg TIM_DMABASE_DCR
+ * @param BurstRequestSrc : TIM DMA Request sources
+ * This parameter can be one of the following values:
+ * @arg TIM_DMA_UPDATE: TIM update Interrupt source
+ * @arg TIM_DMA_CC1: TIM Capture Compare 1 DMA source
+ * @arg TIM_DMA_CC2: TIM Capture Compare 2 DMA source
+ * @arg TIM_DMA_CC3: TIM Capture Compare 3 DMA source
+ * @arg TIM_DMA_CC4: TIM Capture Compare 4 DMA source
+ * @arg TIM_DMA_COM: TIM Commutation DMA source
+ * @arg TIM_DMA_TRIGGER: TIM Trigger DMA source
+ * @param BurstBuffer : The Buffer address.
+ * @param BurstLength : DMA Burst length. This parameter can be one value
+ * between: TIM_DMABURSTLENGTH_1TRANSFER and TIM_DMABURSTLENGTH_18TRANSFERS.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_TIM_DMABurst_WriteStart(TIM_HandleTypeDef *htim, uint32_t BurstBaseAddress, uint32_t BurstRequestSrc,
+ uint32_t* BurstBuffer, uint32_t BurstLength)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_DMABURST_INSTANCE(htim->Instance));
+ assert_param(IS_TIM_DMA_BASE(BurstBaseAddress));
+ assert_param(IS_TIM_DMA_SOURCE(BurstRequestSrc));
+ assert_param(IS_TIM_DMA_LENGTH(BurstLength));
+
+ if((htim->State == HAL_TIM_STATE_BUSY))
+ {
+ return HAL_BUSY;
+ }
+ else if((htim->State == HAL_TIM_STATE_READY))
+ {
+ if((BurstBuffer == 0 ) && (BurstLength > 0))
+ {
+ return HAL_ERROR;
+ }
+ else
+ {
+ htim->State = HAL_TIM_STATE_BUSY;
+ }
+ }
+ switch(BurstRequestSrc)
+ {
+ case TIM_DMA_UPDATE:
+ {
+ /* Set the DMA Period elapsed callback */
+ htim->hdma[TIM_DMA_ID_UPDATE]->XferCpltCallback = TIM_DMAPeriodElapsedCplt;
+
+ /* Set the DMA error callback */
+ htim->hdma[TIM_DMA_ID_UPDATE]->XferErrorCallback = TIM_DMAError ;
+
+ /* Enable the DMA channel */
+ HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_UPDATE], (uint32_t)BurstBuffer, (uint32_t)&htim->Instance->DMAR, ((BurstLength) >> 8) + 1);
+ }
+ break;
+ case TIM_DMA_CC1:
+ {
+ /* Set the DMA Period elapsed callback */
+ htim->hdma[TIM_DMA_ID_CC1]->XferCpltCallback = TIM_DMADelayPulseCplt;
+
+ /* Set the DMA error callback */
+ htim->hdma[TIM_DMA_ID_CC1]->XferErrorCallback = TIM_DMAError ;
+
+ /* Enable the DMA channel */
+ HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC1], (uint32_t)BurstBuffer, (uint32_t)&htim->Instance->DMAR, ((BurstLength) >> 8) + 1);
+ }
+ break;
+ case TIM_DMA_CC2:
+ {
+ /* Set the DMA Period elapsed callback */
+ htim->hdma[TIM_DMA_ID_CC2]->XferCpltCallback = TIM_DMADelayPulseCplt;
+
+ /* Set the DMA error callback */
+ htim->hdma[TIM_DMA_ID_CC2]->XferErrorCallback = TIM_DMAError ;
+
+ /* Enable the DMA channel */
+ HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC2], (uint32_t)BurstBuffer, (uint32_t)&htim->Instance->DMAR, ((BurstLength) >> 8) + 1);
+ }
+ break;
+ case TIM_DMA_CC3:
+ {
+ /* Set the DMA Period elapsed callback */
+ htim->hdma[TIM_DMA_ID_CC3]->XferCpltCallback = TIM_DMADelayPulseCplt;
+
+ /* Set the DMA error callback */
+ htim->hdma[TIM_DMA_ID_CC3]->XferErrorCallback = TIM_DMAError ;
+
+ /* Enable the DMA channel */
+ HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC3], (uint32_t)BurstBuffer, (uint32_t)&htim->Instance->DMAR, ((BurstLength) >> 8) + 1);
+ }
+ break;
+ case TIM_DMA_CC4:
+ {
+ /* Set the DMA Period elapsed callback */
+ htim->hdma[TIM_DMA_ID_CC4]->XferCpltCallback = TIM_DMADelayPulseCplt;
+
+ /* Set the DMA error callback */
+ htim->hdma[TIM_DMA_ID_CC4]->XferErrorCallback = TIM_DMAError ;
+
+ /* Enable the DMA channel */
+ HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC4], (uint32_t)BurstBuffer, (uint32_t)&htim->Instance->DMAR, ((BurstLength) >> 8) + 1);
+ }
+ break;
+ case TIM_DMA_COM:
+ {
+ /* Set the DMA Period elapsed callback */
+ htim->hdma[TIM_DMA_ID_COMMUTATION]->XferCpltCallback = TIMEx_DMACommutationCplt;
+
+ /* Set the DMA error callback */
+ htim->hdma[TIM_DMA_ID_COMMUTATION]->XferErrorCallback = TIM_DMAError ;
+
+ /* Enable the DMA channel */
+ HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_COMMUTATION], (uint32_t)BurstBuffer, (uint32_t)&htim->Instance->DMAR, ((BurstLength) >> 8) + 1);
+ }
+ break;
+ case TIM_DMA_TRIGGER:
+ {
+ /* Set the DMA Period elapsed callback */
+ htim->hdma[TIM_DMA_ID_TRIGGER]->XferCpltCallback = TIM_DMATriggerCplt;
+
+ /* Set the DMA error callback */
+ htim->hdma[TIM_DMA_ID_TRIGGER]->XferErrorCallback = TIM_DMAError ;
+
+ /* Enable the DMA channel */
+ HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_TRIGGER], (uint32_t)BurstBuffer, (uint32_t)&htim->Instance->DMAR, ((BurstLength) >> 8) + 1);
+ }
+ break;
+ default:
+ break;
+ }
+ /* configure the DMA Burst Mode */
+ htim->Instance->DCR = BurstBaseAddress | BurstLength;
+
+ /* Enable the TIM DMA Request */
+ __HAL_TIM_ENABLE_DMA(htim, BurstRequestSrc);
+
+ htim->State = HAL_TIM_STATE_READY;
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Stops the TIM DMA Burst mode
+ * @param htim : TIM handle
+ * @param BurstRequestSrc : TIM DMA Request sources to disable
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_TIM_DMABurst_WriteStop(TIM_HandleTypeDef *htim, uint32_t BurstRequestSrc)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_DMA_SOURCE(BurstRequestSrc));
+
+ /* Abort the DMA transfer (at least disable the DMA channel) */
+ switch(BurstRequestSrc)
+ {
+ case TIM_DMA_UPDATE:
+ {
+ HAL_DMA_Abort(htim->hdma[TIM_DMA_ID_UPDATE]);
+ }
+ break;
+ case TIM_DMA_CC1:
+ {
+ HAL_DMA_Abort(htim->hdma[TIM_DMA_ID_CC1]);
+ }
+ break;
+ case TIM_DMA_CC2:
+ {
+ HAL_DMA_Abort(htim->hdma[TIM_DMA_ID_CC2]);
+ }
+ break;
+ case TIM_DMA_CC3:
+ {
+ HAL_DMA_Abort(htim->hdma[TIM_DMA_ID_CC3]);
+ }
+ break;
+ case TIM_DMA_CC4:
+ {
+ HAL_DMA_Abort(htim->hdma[TIM_DMA_ID_CC4]);
+ }
+ break;
+ case TIM_DMA_COM:
+ {
+ HAL_DMA_Abort(htim->hdma[TIM_DMA_ID_COMMUTATION]);
+ }
+ break;
+ case TIM_DMA_TRIGGER:
+ {
+ HAL_DMA_Abort(htim->hdma[TIM_DMA_ID_TRIGGER]);
+ }
+ break;
+ default:
+ break;
+ }
+
+ /* Disable the TIM Update DMA request */
+ __HAL_TIM_DISABLE_DMA(htim, BurstRequestSrc);
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Configure the DMA Burst to transfer Data from the TIM peripheral to the memory
+ * @param htim : TIM handle
+ * @param BurstBaseAddress : TIM Base address from where the DMA will starts the Data read
+ * This parameter can be one of the following values:
+ * @arg TIM_DMABASE_CR1
+ * @arg TIM_DMABASE_CR2
+ * @arg TIM_DMABASE_SMCR
+ * @arg TIM_DMABASE_DIER
+ * @arg TIM_DMABASE_SR
+ * @arg TIM_DMABASE_EGR
+ * @arg TIM_DMABASE_CCMR1
+ * @arg TIM_DMABASE_CCMR2
+ * @arg TIM_DMABASE_CCER
+ * @arg TIM_DMABASE_CNT
+ * @arg TIM_DMABASE_PSC
+ * @arg TIM_DMABASE_ARR
+ * @arg TIM_DMABASE_RCR
+ * @arg TIM_DMABASE_CCR1
+ * @arg TIM_DMABASE_CCR2
+ * @arg TIM_DMABASE_CCR3
+ * @arg TIM_DMABASE_CCR4
+ * @arg TIM_DMABASE_BDTR
+ * @arg TIM_DMABASE_DCR
+ * @param BurstRequestSrc : TIM DMA Request sources
+ * This parameter can be one of the following values:
+ * @arg TIM_DMA_UPDATE: TIM update Interrupt source
+ * @arg TIM_DMA_CC1: TIM Capture Compare 1 DMA source
+ * @arg TIM_DMA_CC2: TIM Capture Compare 2 DMA source
+ * @arg TIM_DMA_CC3: TIM Capture Compare 3 DMA source
+ * @arg TIM_DMA_CC4: TIM Capture Compare 4 DMA source
+ * @arg TIM_DMA_COM: TIM Commutation DMA source
+ * @arg TIM_DMA_TRIGGER: TIM Trigger DMA source
+ * @param BurstBuffer : The Buffer address.
+ * @param BurstLength : DMA Burst length. This parameter can be one value
+ * between: TIM_DMABURSTLENGTH_1TRANSFER and TIM_DMABURSTLENGTH_18TRANSFERS.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_TIM_DMABurst_ReadStart(TIM_HandleTypeDef *htim, uint32_t BurstBaseAddress, uint32_t BurstRequestSrc,
+ uint32_t *BurstBuffer, uint32_t BurstLength)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_DMABURST_INSTANCE(htim->Instance));
+ assert_param(IS_TIM_DMA_BASE(BurstBaseAddress));
+ assert_param(IS_TIM_DMA_SOURCE(BurstRequestSrc));
+ assert_param(IS_TIM_DMA_LENGTH(BurstLength));
+
+ if((htim->State == HAL_TIM_STATE_BUSY))
+ {
+ return HAL_BUSY;
+ }
+ else if((htim->State == HAL_TIM_STATE_READY))
+ {
+ if((BurstBuffer == 0 ) && (BurstLength > 0))
+ {
+ return HAL_ERROR;
+ }
+ else
+ {
+ htim->State = HAL_TIM_STATE_BUSY;
+ }
+ }
+ switch(BurstRequestSrc)
+ {
+ case TIM_DMA_UPDATE:
+ {
+ /* Set the DMA Period elapsed callback */
+ htim->hdma[TIM_DMA_ID_UPDATE]->XferCpltCallback = TIM_DMAPeriodElapsedCplt;
+
+ /* Set the DMA error callback */
+ htim->hdma[TIM_DMA_ID_UPDATE]->XferErrorCallback = TIM_DMAError ;
+
+ /* Enable the DMA channel */
+ HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_UPDATE], (uint32_t)&htim->Instance->DMAR, (uint32_t)BurstBuffer, ((BurstLength) >> 8) + 1);
+ }
+ break;
+ case TIM_DMA_CC1:
+ {
+ /* Set the DMA Period elapsed callback */
+ htim->hdma[TIM_DMA_ID_CC1]->XferCpltCallback = TIM_DMACaptureCplt;
+
+ /* Set the DMA error callback */
+ htim->hdma[TIM_DMA_ID_CC1]->XferErrorCallback = TIM_DMAError ;
+
+ /* Enable the DMA channel */
+ HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC1], (uint32_t)&htim->Instance->DMAR, (uint32_t)BurstBuffer, ((BurstLength) >> 8) + 1);
+ }
+ break;
+ case TIM_DMA_CC2:
+ {
+ /* Set the DMA Period elapsed callback */
+ htim->hdma[TIM_DMA_ID_CC2]->XferCpltCallback = TIM_DMACaptureCplt;
+
+ /* Set the DMA error callback */
+ htim->hdma[TIM_DMA_ID_CC2]->XferErrorCallback = TIM_DMAError ;
+
+ /* Enable the DMA channel */
+ HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC2], (uint32_t)&htim->Instance->DMAR, (uint32_t)BurstBuffer, ((BurstLength) >> 8) + 1);
+ }
+ break;
+ case TIM_DMA_CC3:
+ {
+ /* Set the DMA Period elapsed callback */
+ htim->hdma[TIM_DMA_ID_CC3]->XferCpltCallback = TIM_DMACaptureCplt;
+
+ /* Set the DMA error callback */
+ htim->hdma[TIM_DMA_ID_CC3]->XferErrorCallback = TIM_DMAError ;
+
+ /* Enable the DMA channel */
+ HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC3], (uint32_t)&htim->Instance->DMAR, (uint32_t)BurstBuffer, ((BurstLength) >> 8) + 1);
+ }
+ break;
+ case TIM_DMA_CC4:
+ {
+ /* Set the DMA Period elapsed callback */
+ htim->hdma[TIM_DMA_ID_CC4]->XferCpltCallback = TIM_DMACaptureCplt;
+
+ /* Set the DMA error callback */
+ htim->hdma[TIM_DMA_ID_CC4]->XferErrorCallback = TIM_DMAError ;
+
+ /* Enable the DMA channel */
+ HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC4], (uint32_t)&htim->Instance->DMAR, (uint32_t)BurstBuffer, ((BurstLength) >> 8) + 1);
+ }
+ break;
+ case TIM_DMA_COM:
+ {
+ /* Set the DMA Period elapsed callback */
+ htim->hdma[TIM_DMA_ID_COMMUTATION]->XferCpltCallback = TIMEx_DMACommutationCplt;
+
+ /* Set the DMA error callback */
+ htim->hdma[TIM_DMA_ID_COMMUTATION]->XferErrorCallback = TIM_DMAError ;
+
+ /* Enable the DMA channel */
+ HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_COMMUTATION], (uint32_t)&htim->Instance->DMAR, (uint32_t)BurstBuffer, ((BurstLength) >> 8) + 1);
+ }
+ break;
+ case TIM_DMA_TRIGGER:
+ {
+ /* Set the DMA Period elapsed callback */
+ htim->hdma[TIM_DMA_ID_TRIGGER]->XferCpltCallback = TIM_DMATriggerCplt;
+
+ /* Set the DMA error callback */
+ htim->hdma[TIM_DMA_ID_TRIGGER]->XferErrorCallback = TIM_DMAError ;
+
+ /* Enable the DMA channel */
+ HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_TRIGGER], (uint32_t)&htim->Instance->DMAR, (uint32_t)BurstBuffer, ((BurstLength) >> 8) + 1);
+ }
+ break;
+ default:
+ break;
+ }
+
+ /* configure the DMA Burst Mode */
+ htim->Instance->DCR = BurstBaseAddress | BurstLength;
+
+ /* Enable the TIM DMA Request */
+ __HAL_TIM_ENABLE_DMA(htim, BurstRequestSrc);
+
+ htim->State = HAL_TIM_STATE_READY;
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Stop the DMA burst reading
+ * @param htim : TIM handle
+ * @param BurstRequestSrc : TIM DMA Request sources to disable.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_TIM_DMABurst_ReadStop(TIM_HandleTypeDef *htim, uint32_t BurstRequestSrc)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_DMA_SOURCE(BurstRequestSrc));
+
+ /* Abort the DMA transfer (at least disable the DMA channel) */
+ switch(BurstRequestSrc)
+ {
+ case TIM_DMA_UPDATE:
+ {
+ HAL_DMA_Abort(htim->hdma[TIM_DMA_ID_UPDATE]);
+ }
+ break;
+ case TIM_DMA_CC1:
+ {
+ HAL_DMA_Abort(htim->hdma[TIM_DMA_ID_CC1]);
+ }
+ break;
+ case TIM_DMA_CC2:
+ {
+ HAL_DMA_Abort(htim->hdma[TIM_DMA_ID_CC2]);
+ }
+ break;
+ case TIM_DMA_CC3:
+ {
+ HAL_DMA_Abort(htim->hdma[TIM_DMA_ID_CC3]);
+ }
+ break;
+ case TIM_DMA_CC4:
+ {
+ HAL_DMA_Abort(htim->hdma[TIM_DMA_ID_CC4]);
+ }
+ break;
+ case TIM_DMA_COM:
+ {
+ HAL_DMA_Abort(htim->hdma[TIM_DMA_ID_COMMUTATION]);
+ }
+ break;
+ case TIM_DMA_TRIGGER:
+ {
+ HAL_DMA_Abort(htim->hdma[TIM_DMA_ID_TRIGGER]);
+ }
+ break;
+ default:
+ break;
+ }
+
+ /* Disable the TIM Update DMA request */
+ __HAL_TIM_DISABLE_DMA(htim, BurstRequestSrc);
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Generate a software event
+ * @param htim : TIM handle
+ * @param EventSource : specifies the event source.
+ * This parameter can be one of the following values:
+ * @arg TIM_EVENTSOURCE_UPDATE: Timer update Event source
+ * @arg TIM_EVENTSOURCE_CC1: Timer Capture Compare 1 Event source
+ * @arg TIM_EVENTSOURCE_CC2: Timer Capture Compare 2 Event source
+ * @arg TIM_EVENTSOURCE_CC3: Timer Capture Compare 3 Event source
+ * @arg TIM_EVENTSOURCE_CC4: Timer Capture Compare 4 Event source
+ * @arg TIM_EVENTSOURCE_COM: Timer COM event source
+ * @arg TIM_EVENTSOURCE_TRIGGER: Timer Trigger Event source
+ * @arg TIM_EVENTSOURCE_BREAK: Timer Break event source
+ * @note TIM6 and TIM7 can only generate an update event.
+ * @note TIM_EVENTSOURCE_COM and TIM_EVENTSOURCE_BREAK are used only with TIM1, TIM15, TIM16 and TIM17.
+ * @retval HAL status
+ */
+
+HAL_StatusTypeDef HAL_TIM_GenerateEvent(TIM_HandleTypeDef *htim, uint32_t EventSource)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_INSTANCE(htim->Instance));
+ assert_param(IS_TIM_EVENT_SOURCE(EventSource));
+
+ /* Process Locked */
+ __HAL_LOCK(htim);
+
+ /* Change the TIM state */
+ htim->State = HAL_TIM_STATE_BUSY;
+
+ /* Set the event sources */
+ htim->Instance->EGR = EventSource;
+
+ /* Change the TIM state */
+ htim->State = HAL_TIM_STATE_READY;
+
+ __HAL_UNLOCK(htim);
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Configures the OCRef clear feature
+ * @param htim : TIM handle
+ * @param sClearInputConfig : pointer to a TIM_ClearInputConfigTypeDef structure that
+ * contains the OCREF clear feature and parameters for the TIM peripheral.
+ * @param Channel : specifies the TIM Channel
+ * This parameter can be one of the following values:
+ * @arg TIM_CHANNEL_1: TIM Channel 1
+ * @arg TIM_CHANNEL_2: TIM Channel 2
+ * @arg TIM_CHANNEL_3: TIM Channel 3
+ * @arg TIM_CHANNEL_4: TIM Channel 4
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_TIM_ConfigOCrefClear(TIM_HandleTypeDef *htim, TIM_ClearInputConfigTypeDef * sClearInputConfig, uint32_t Channel)
+{
+ uint32_t tmpsmcr = 0;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_OCXREF_CLEAR_INSTANCE(htim->Instance));
+ assert_param(IS_TIM_CLEARINPUT_SOURCE(sClearInputConfig->ClearInputSource));
+ assert_param(IS_TIM_CLEARINPUT_POLARITY(sClearInputConfig->ClearInputPolarity));
+ assert_param(IS_TIM_CLEARINPUT_PRESCALER(sClearInputConfig->ClearInputPrescaler));
+ assert_param(IS_TIM_CLEARINPUT_FILTER(sClearInputConfig->ClearInputFilter));
+
+ /* Process Locked */
+ __HAL_LOCK(htim);
+
+ htim->State = HAL_TIM_STATE_BUSY;
+
+ switch (sClearInputConfig->ClearInputSource)
+ {
+ case TIM_CLEARINPUTSOURCE_NONE:
+ {
+ /* Clear the OCREF clear selection bit */
+ tmpsmcr &= ~TIM_SMCR_OCCS;
+
+ /* Clear the ETR Bits */
+ tmpsmcr &= ~(TIM_SMCR_ETF | TIM_SMCR_ETPS | TIM_SMCR_ECE | TIM_SMCR_ETP);
+
+ /* Set TIMx_SMCR */
+ htim->Instance->SMCR = tmpsmcr;
+ }
+ break;
+
+ case TIM_CLEARINPUTSOURCE_ETR:
+ {
+ TIM_ETR_SetConfig(htim->Instance,
+ sClearInputConfig->ClearInputPrescaler,
+ sClearInputConfig->ClearInputPolarity,
+ sClearInputConfig->ClearInputFilter);
+
+ /* Set the OCREF clear selection bit */
+ htim->Instance->SMCR |= TIM_SMCR_OCCS;
+ }
+ break;
+ default:
+ break;
+ }
+
+ switch (Channel)
+ {
+ case TIM_CHANNEL_1:
+ {
+ if(sClearInputConfig->ClearInputState != RESET)
+ {
+ /* Enable the Ocref clear feature for Channel 1 */
+ htim->Instance->CCMR1 |= TIM_CCMR1_OC1CE;
+ }
+ else
+ {
+ /* Disable the Ocref clear feature for Channel 1 */
+ htim->Instance->CCMR1 &= ~TIM_CCMR1_OC1CE;
+ }
+ }
+ break;
+ case TIM_CHANNEL_2:
+ {
+ assert_param(IS_TIM_CC2_INSTANCE(htim->Instance));
+ if(sClearInputConfig->ClearInputState != RESET)
+ {
+ /* Enable the Ocref clear feature for Channel 2 */
+ htim->Instance->CCMR1 |= TIM_CCMR1_OC2CE;
+ }
+ else
+ {
+ /* Disable the Ocref clear feature for Channel 2 */
+ htim->Instance->CCMR1 &= ~TIM_CCMR1_OC2CE;
+ }
+ }
+ break;
+ case TIM_CHANNEL_3:
+ {
+ assert_param(IS_TIM_CC3_INSTANCE(htim->Instance));
+ if(sClearInputConfig->ClearInputState != RESET)
+ {
+ /* Enable the Ocref clear feature for Channel 3 */
+ htim->Instance->CCMR2 |= TIM_CCMR2_OC3CE;
+ }
+ else
+ {
+ /* Disable the Ocref clear feature for Channel 3 */
+ htim->Instance->CCMR2 &= ~TIM_CCMR2_OC3CE;
+ }
+ }
+ break;
+ case TIM_CHANNEL_4:
+ {
+ assert_param(IS_TIM_CC4_INSTANCE(htim->Instance));
+ if(sClearInputConfig->ClearInputState != RESET)
+ {
+ /* Enable the Ocref clear feature for Channel 4 */
+ htim->Instance->CCMR2 |= TIM_CCMR2_OC4CE;
+ }
+ else
+ {
+ /* Disable the Ocref clear feature for Channel 4 */
+ htim->Instance->CCMR2 &= ~TIM_CCMR2_OC4CE;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+
+ htim->State = HAL_TIM_STATE_READY;
+
+ __HAL_UNLOCK(htim);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Configures the clock source to be used
+ * @param htim : TIM handle
+ * @param sClockSourceConfig : pointer to a TIM_ClockConfigTypeDef structure that
+ * contains the clock source information for the TIM peripheral.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_TIM_ConfigClockSource(TIM_HandleTypeDef *htim, TIM_ClockConfigTypeDef * sClockSourceConfig)
+{
+ uint32_t tmpsmcr = 0;
+
+ /* Process Locked */
+ __HAL_LOCK(htim);
+
+ htim->State = HAL_TIM_STATE_BUSY;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_CLOCKSOURCE(sClockSourceConfig->ClockSource));
+
+ /* Reset the SMS, TS, ECE, ETPS and ETRF bits */
+ tmpsmcr = htim->Instance->SMCR;
+ tmpsmcr &= ~(TIM_SMCR_SMS | TIM_SMCR_TS);
+ tmpsmcr &= ~(TIM_SMCR_ETF | TIM_SMCR_ETPS | TIM_SMCR_ECE | TIM_SMCR_ETP);
+ htim->Instance->SMCR = tmpsmcr;
+
+ switch (sClockSourceConfig->ClockSource)
+ {
+ case TIM_CLOCKSOURCE_INTERNAL:
+ {
+ assert_param(IS_TIM_INSTANCE(htim->Instance));
+ /* Disable slave mode to clock the prescaler directly with the internal clock */
+ htim->Instance->SMCR &= ~TIM_SMCR_SMS;
+ }
+ break;
+
+ case TIM_CLOCKSOURCE_ETRMODE1:
+ {
+ /* Check whether or not the timer instance supports external trigger input mode 1 (ETRF)*/
+ assert_param(IS_TIM_CLOCKSOURCE_ETRMODE1_INSTANCE(htim->Instance));
+
+ /* Check ETR input conditioning related parameters */
+ assert_param(IS_TIM_CLOCKPRESCALER(sClockSourceConfig->ClockPrescaler));
+ assert_param(IS_TIM_CLOCKPOLARITY(sClockSourceConfig->ClockPolarity));
+ assert_param(IS_TIM_CLOCKFILTER(sClockSourceConfig->ClockFilter));
+
+ /* Configure the ETR Clock source */
+ TIM_ETR_SetConfig(htim->Instance,
+ sClockSourceConfig->ClockPrescaler,
+ sClockSourceConfig->ClockPolarity,
+ sClockSourceConfig->ClockFilter);
+ /* Get the TIMx SMCR register value */
+ tmpsmcr = htim->Instance->SMCR;
+ /* Reset the SMS and TS Bits */
+ tmpsmcr &= ~(TIM_SMCR_SMS | TIM_SMCR_TS);
+ /* Select the External clock mode1 and the ETRF trigger */
+ tmpsmcr |= (TIM_SLAVEMODE_EXTERNAL1 | TIM_CLOCKSOURCE_ETRMODE1);
+ /* Write to TIMx SMCR */
+ htim->Instance->SMCR = tmpsmcr;
+ }
+ break;
+
+ case TIM_CLOCKSOURCE_ETRMODE2:
+ {
+ /* Check whether or not the timer instance supports external trigger input mode 2 (ETRF)*/
+ assert_param(IS_TIM_CLOCKSOURCE_ETRMODE2_INSTANCE(htim->Instance));
+
+ /* Check ETR input conditioning related parameters */
+ assert_param(IS_TIM_CLOCKPRESCALER(sClockSourceConfig->ClockPrescaler));
+ assert_param(IS_TIM_CLOCKPOLARITY(sClockSourceConfig->ClockPolarity));
+ assert_param(IS_TIM_CLOCKFILTER(sClockSourceConfig->ClockFilter));
+
+ /* Configure the ETR Clock source */
+ TIM_ETR_SetConfig(htim->Instance,
+ sClockSourceConfig->ClockPrescaler,
+ sClockSourceConfig->ClockPolarity,
+ sClockSourceConfig->ClockFilter);
+ /* Enable the External clock mode2 */
+ htim->Instance->SMCR |= TIM_SMCR_ECE;
+ }
+ break;
+
+ case TIM_CLOCKSOURCE_TI1:
+ {
+ /* Check whether or not the timer instance supports external clock mode 1 */
+ assert_param(IS_TIM_CLOCKSOURCE_TIX_INSTANCE(htim->Instance));
+
+ /* Check TI1 input conditioning related parameters */
+ assert_param(IS_TIM_CLOCKPOLARITY(sClockSourceConfig->ClockPolarity));
+ assert_param(IS_TIM_CLOCKFILTER(sClockSourceConfig->ClockFilter));
+
+ TIM_TI1_ConfigInputStage(htim->Instance,
+ sClockSourceConfig->ClockPolarity,
+ sClockSourceConfig->ClockFilter);
+ TIM_ITRx_SetConfig(htim->Instance, TIM_CLOCKSOURCE_TI1);
+ }
+ break;
+ case TIM_CLOCKSOURCE_TI2:
+ {
+ /* Check whether or not the timer instance supports external clock mode 1 (ETRF)*/
+ assert_param(IS_TIM_CLOCKSOURCE_TIX_INSTANCE(htim->Instance));
+
+ /* Check TI2 input conditioning related parameters */
+ assert_param(IS_TIM_CLOCKPOLARITY(sClockSourceConfig->ClockPolarity));
+ assert_param(IS_TIM_CLOCKFILTER(sClockSourceConfig->ClockFilter));
+
+ TIM_TI2_ConfigInputStage(htim->Instance,
+ sClockSourceConfig->ClockPolarity,
+ sClockSourceConfig->ClockFilter);
+ TIM_ITRx_SetConfig(htim->Instance, TIM_CLOCKSOURCE_TI2);
+ }
+ break;
+ case TIM_CLOCKSOURCE_TI1ED:
+ {
+ /* Check whether or not the timer instance supports external clock mode 1 */
+ assert_param(IS_TIM_CLOCKSOURCE_TIX_INSTANCE(htim->Instance));
+
+ /* Check TI1 input conditioning related parameters */
+ assert_param(IS_TIM_CLOCKPOLARITY(sClockSourceConfig->ClockPolarity));
+ assert_param(IS_TIM_CLOCKFILTER(sClockSourceConfig->ClockFilter));
+
+ TIM_TI1_ConfigInputStage(htim->Instance,
+ sClockSourceConfig->ClockPolarity,
+ sClockSourceConfig->ClockFilter);
+ TIM_ITRx_SetConfig(htim->Instance, TIM_CLOCKSOURCE_TI1ED);
+ }
+ break;
+ case TIM_CLOCKSOURCE_ITR0:
+ {
+ /* Check whether or not the timer instance supports external clock mode 1 */
+ assert_param(IS_TIM_CLOCKSOURCE_ITRX_INSTANCE(htim->Instance));
+
+ TIM_ITRx_SetConfig(htim->Instance, TIM_CLOCKSOURCE_ITR0);
+ }
+ break;
+ case TIM_CLOCKSOURCE_ITR1:
+ {
+ /* Check whether or not the timer instance supports external clock mode 1 */
+ assert_param(IS_TIM_CLOCKSOURCE_ITRX_INSTANCE(htim->Instance));
+
+ TIM_ITRx_SetConfig(htim->Instance, TIM_CLOCKSOURCE_ITR1);
+ }
+ break;
+ case TIM_CLOCKSOURCE_ITR2:
+ {
+ /* Check whether or not the timer instance supports external clock mode 1 */
+ assert_param(IS_TIM_CLOCKSOURCE_ITRX_INSTANCE(htim->Instance));
+
+ TIM_ITRx_SetConfig(htim->Instance, TIM_CLOCKSOURCE_ITR2);
+ }
+ break;
+ case TIM_CLOCKSOURCE_ITR3:
+ {
+ /* Check whether or not the timer instance supports external clock mode 1 */
+ assert_param(IS_TIM_CLOCKSOURCE_ITRX_INSTANCE(htim->Instance));
+
+ TIM_ITRx_SetConfig(htim->Instance, TIM_CLOCKSOURCE_ITR3);
+ }
+ break;
+
+ default:
+ break;
+ }
+ htim->State = HAL_TIM_STATE_READY;
+
+ __HAL_UNLOCK(htim);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Selects the signal connected to the TI1 input: direct from CH1_input
+ * or a XOR combination between CH1_input, CH2_input & CH3_input
+ * @param htim : TIM handle.
+ * @param TI1_Selection : Indicate whether or not channel 1 is connected to the
+ * output of a XOR gate.
+ * This parameter can be one of the following values:
+ * @arg TIM_TI1SELECTION_CH1: The TIMx_CH1 pin is connected to TI1 input
+ * @arg TIM_TI1SELECTION_XORCOMBINATION: The TIMx_CH1, CH2 and CH3
+ * pins are connected to the TI1 input (XOR combination)
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_TIM_ConfigTI1Input(TIM_HandleTypeDef *htim, uint32_t TI1_Selection)
+{
+ uint32_t tmpcr2 = 0;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_XOR_INSTANCE(htim->Instance));
+ assert_param(IS_TIM_TI1SELECTION(TI1_Selection));
+
+ /* Get the TIMx CR2 register value */
+ tmpcr2 = htim->Instance->CR2;
+
+ /* Reset the TI1 selection */
+ tmpcr2 &= ~TIM_CR2_TI1S;
+
+ /* Set the the TI1 selection */
+ tmpcr2 |= TI1_Selection;
+
+ /* Write to TIMxCR2 */
+ htim->Instance->CR2 = tmpcr2;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Configures the TIM in Slave mode
+ * @param htim : TIM handle.
+ * @param sSlaveConfig : pointer to a TIM_SlaveConfigTypeDef structure that
+ * contains the selected trigger (internal trigger input, filtered
+ * timer input or external trigger input) and the ) and the Slave
+ * mode (Disable, Reset, Gated, Trigger, External clock mode 1).
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_TIM_SlaveConfigSynchronization(TIM_HandleTypeDef *htim, TIM_SlaveConfigTypeDef * sSlaveConfig)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_SLAVE_INSTANCE(htim->Instance));
+ assert_param(IS_TIM_SLAVE_MODE(sSlaveConfig->SlaveMode));
+ assert_param(IS_TIM_TRIGGER_SELECTION(sSlaveConfig->InputTrigger));
+
+ __HAL_LOCK(htim);
+
+ htim->State = HAL_TIM_STATE_BUSY;
+
+ TIM_SlaveTimer_SetConfig(htim, sSlaveConfig);
+
+ /* Disable Trigger Interrupt */
+ __HAL_TIM_DISABLE_IT(htim, TIM_IT_TRIGGER);
+
+ /* Disable Trigger DMA request */
+ __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_TRIGGER);
+
+ htim->State = HAL_TIM_STATE_READY;
+
+ __HAL_UNLOCK(htim);
+
+ return HAL_OK;
+ }
+
+/**
+ * @brief Configures the TIM in Slave mode in interrupt mode
+ * @param htim: TIM handle.
+ * @param sSlaveConfig: pointer to a TIM_SlaveConfigTypeDef structure that
+ * contains the selected trigger (internal trigger input, filtered
+ * timer input or external trigger input) and the ) and the Slave
+ * mode (Disable, Reset, Gated, Trigger, External clock mode 1).
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_TIM_SlaveConfigSynchronization_IT(TIM_HandleTypeDef *htim,
+ TIM_SlaveConfigTypeDef * sSlaveConfig)
+ {
+ /* Check the parameters */
+ assert_param(IS_TIM_SLAVE_INSTANCE(htim->Instance));
+ assert_param(IS_TIM_SLAVE_MODE(sSlaveConfig->SlaveMode));
+ assert_param(IS_TIM_TRIGGER_SELECTION(sSlaveConfig->InputTrigger));
+
+ __HAL_LOCK(htim);
+
+ htim->State = HAL_TIM_STATE_BUSY;
+
+ TIM_SlaveTimer_SetConfig(htim, sSlaveConfig);
+
+ /* Enable Trigger Interrupt */
+ __HAL_TIM_ENABLE_IT(htim, TIM_IT_TRIGGER);
+
+ /* Disable Trigger DMA request */
+ __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_TRIGGER);
+
+ htim->State = HAL_TIM_STATE_READY;
+
+ __HAL_UNLOCK(htim);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Read the captured value from Capture Compare unit
+ * @param htim : TIM handle.
+ * @param Channel : TIM Channels to be enabled
+ * This parameter can be one of the following values:
+ * @arg TIM_CHANNEL_1 : TIM Channel 1 selected
+ * @arg TIM_CHANNEL_2 : TIM Channel 2 selected
+ * @arg TIM_CHANNEL_3 : TIM Channel 3 selected
+ * @arg TIM_CHANNEL_4 : TIM Channel 4 selected
+ * @retval Captured value
+ */
+uint32_t HAL_TIM_ReadCapturedValue(TIM_HandleTypeDef *htim, uint32_t Channel)
+{
+ uint32_t tmpreg = 0;
+
+ __HAL_LOCK(htim);
+
+ switch (Channel)
+ {
+ case TIM_CHANNEL_1:
+ {
+ /* Check the parameters */
+ assert_param(IS_TIM_CC1_INSTANCE(htim->Instance));
+
+ /* Return the capture 1 value */
+ tmpreg = htim->Instance->CCR1;
+
+ break;
+ }
+ case TIM_CHANNEL_2:
+ {
+ /* Check the parameters */
+ assert_param(IS_TIM_CC2_INSTANCE(htim->Instance));
+
+ /* Return the capture 2 value */
+ tmpreg = htim->Instance->CCR2;
+
+ break;
+ }
+
+ case TIM_CHANNEL_3:
+ {
+ /* Check the parameters */
+ assert_param(IS_TIM_CC3_INSTANCE(htim->Instance));
+
+ /* Return the capture 3 value */
+ tmpreg = htim->Instance->CCR3;
+
+ break;
+ }
+
+ case TIM_CHANNEL_4:
+ {
+ /* Check the parameters */
+ assert_param(IS_TIM_CC4_INSTANCE(htim->Instance));
+
+ /* Return the capture 4 value */
+ tmpreg = htim->Instance->CCR4;
+
+ break;
+ }
+
+ default:
+ break;
+ }
+
+ __HAL_UNLOCK(htim);
+ return tmpreg;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Exported_Functions_Group9 TIM Callbacks functions
+ * @brief TIM Callbacks functions
+ *
+@verbatim
+ ==============================================================================
+ ##### TIM Callbacks functions #####
+ ==============================================================================
+ [..]
+ This section provides TIM callback functions:
+ (+) Timer Period elapsed callback
+ (+) Timer Output Compare callback
+ (+) Timer Input capture callback
+ (+) Timer Trigger callback
+ (+) Timer Error callback
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Period elapsed callback in non blocking mode
+ * @param htim : TIM handle
+ * @retval None
+ */
+__weak void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(htim);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the __HAL_TIM_PeriodElapsedCallback could be implemented in the user file
+ */
+
+}
+/**
+ * @brief Output Compare callback in non blocking mode
+ * @param htim : TIM OC handle
+ * @retval None
+ */
+__weak void HAL_TIM_OC_DelayElapsedCallback(TIM_HandleTypeDef *htim)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(htim);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the __HAL_TIM_OC_DelayElapsedCallback could be implemented in the user file
+ */
+}
+/**
+ * @brief Input Capture callback in non blocking mode
+ * @param htim : TIM IC handle
+ * @retval None
+ */
+__weak void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(htim);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the __HAL_TIM_IC_CaptureCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief PWM Pulse finished callback in non blocking mode
+ * @param htim : TIM handle
+ * @retval None
+ */
+__weak void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(htim);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the __HAL_TIM_PWM_PulseFinishedCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief Hall Trigger detection callback in non blocking mode
+ * @param htim : TIM handle
+ * @retval None
+ */
+__weak void HAL_TIM_TriggerCallback(TIM_HandleTypeDef *htim)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(htim);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_TIM_TriggerCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief Timer error callback in non blocking mode
+ * @param htim : TIM handle
+ * @retval None
+ */
+__weak void HAL_TIM_ErrorCallback(TIM_HandleTypeDef *htim)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(htim);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_TIM_ErrorCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup TIM_Exported_Functions_Group10 Peripheral State functions
+ * @brief Peripheral State functions
+ *
+@verbatim
+ ==============================================================================
+ ##### Peripheral State functions #####
+ ==============================================================================
+ [..]
+ This subsection permit to get in run-time the status of the peripheral
+ and the data flow.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Return the TIM Base state
+ * @param htim : TIM Base handle
+ * @retval HAL state
+ */
+HAL_TIM_StateTypeDef HAL_TIM_Base_GetState(TIM_HandleTypeDef *htim)
+{
+ return htim->State;
+}
+
+/**
+ * @brief Return the TIM OC state
+ * @param htim : TIM Ouput Compare handle
+ * @retval HAL state
+ */
+HAL_TIM_StateTypeDef HAL_TIM_OC_GetState(TIM_HandleTypeDef *htim)
+{
+ return htim->State;
+}
+
+/**
+ * @brief Return the TIM PWM state
+ * @param htim : TIM handle
+ * @retval HAL state
+ */
+HAL_TIM_StateTypeDef HAL_TIM_PWM_GetState(TIM_HandleTypeDef *htim)
+{
+ return htim->State;
+}
+
+/**
+ * @brief Return the TIM Input Capture state
+ * @param htim : TIM IC handle
+ * @retval HAL state
+ */
+HAL_TIM_StateTypeDef HAL_TIM_IC_GetState(TIM_HandleTypeDef *htim)
+{
+ return htim->State;
+}
+
+/**
+ * @brief Return the TIM One Pulse Mode state
+ * @param htim : TIM OPM handle
+ * @retval HAL state
+ */
+HAL_TIM_StateTypeDef HAL_TIM_OnePulse_GetState(TIM_HandleTypeDef *htim)
+{
+ return htim->State;
+}
+
+/**
+ * @brief Return the TIM Encoder Mode state
+ * @param htim : TIM Encoder handle
+ * @retval HAL state
+ */
+HAL_TIM_StateTypeDef HAL_TIM_Encoder_GetState(TIM_HandleTypeDef *htim)
+{
+ return htim->State;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/** @addtogroup TIM_Private_Functions
+ * @{
+ */
+
+/**
+ * @brief TIM DMA error callback
+ * @param hdma : pointer to DMA handle.
+ * @retval None
+ */
+void TIM_DMAError(DMA_HandleTypeDef *hdma)
+{
+ TIM_HandleTypeDef* htim = ( TIM_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
+
+ htim->State= HAL_TIM_STATE_READY;
+
+ HAL_TIM_ErrorCallback(htim);
+}
+
+/**
+ * @brief TIM DMA Delay Pulse complete callback.
+ * @param hdma : pointer to DMA handle.
+ * @retval None
+ */
+void TIM_DMADelayPulseCplt(DMA_HandleTypeDef *hdma)
+{
+ TIM_HandleTypeDef* htim = ( TIM_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
+
+ htim->State= HAL_TIM_STATE_READY;
+
+ if (hdma == htim->hdma[TIM_DMA_ID_CC1])
+ {
+ htim->Channel = HAL_TIM_ACTIVE_CHANNEL_1;
+ }
+ else if (hdma == htim->hdma[TIM_DMA_ID_CC2])
+ {
+ htim->Channel = HAL_TIM_ACTIVE_CHANNEL_2;
+ }
+ else if (hdma == htim->hdma[TIM_DMA_ID_CC3])
+ {
+ htim->Channel = HAL_TIM_ACTIVE_CHANNEL_3;
+ }
+ else if (hdma == htim->hdma[TIM_DMA_ID_CC4])
+ {
+ htim->Channel = HAL_TIM_ACTIVE_CHANNEL_4;
+ }
+
+ HAL_TIM_PWM_PulseFinishedCallback(htim);
+
+ htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;
+}
+/**
+ * @brief TIM DMA Capture complete callback.
+ * @param hdma : pointer to DMA handle.
+ * @retval None
+ */
+void TIM_DMACaptureCplt(DMA_HandleTypeDef *hdma)
+{
+ TIM_HandleTypeDef* htim = ( TIM_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
+
+ htim->State= HAL_TIM_STATE_READY;
+
+ if (hdma == htim->hdma[TIM_DMA_ID_CC1])
+ {
+ htim->Channel = HAL_TIM_ACTIVE_CHANNEL_1;
+ }
+ else if (hdma == htim->hdma[TIM_DMA_ID_CC2])
+ {
+ htim->Channel = HAL_TIM_ACTIVE_CHANNEL_2;
+ }
+ else if (hdma == htim->hdma[TIM_DMA_ID_CC3])
+ {
+ htim->Channel = HAL_TIM_ACTIVE_CHANNEL_3;
+ }
+ else if (hdma == htim->hdma[TIM_DMA_ID_CC4])
+ {
+ htim->Channel = HAL_TIM_ACTIVE_CHANNEL_4;
+ }
+
+ HAL_TIM_IC_CaptureCallback(htim);
+
+ htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;
+}
+
+/**
+ * @brief TIM DMA Period Elapse complete callback.
+ * @param hdma : pointer to DMA handle.
+ * @retval None
+ */
+static void TIM_DMAPeriodElapsedCplt(DMA_HandleTypeDef *hdma)
+{
+ TIM_HandleTypeDef* htim = ( TIM_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
+
+ htim->State= HAL_TIM_STATE_READY;
+
+ HAL_TIM_PeriodElapsedCallback(htim);
+}
+
+/**
+ * @brief TIM DMA Trigger callback.
+ * @param hdma : pointer to DMA handle.
+ * @retval None
+ */
+static void TIM_DMATriggerCplt(DMA_HandleTypeDef *hdma)
+{
+ TIM_HandleTypeDef* htim = ( TIM_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
+
+ htim->State= HAL_TIM_STATE_READY;
+
+ HAL_TIM_TriggerCallback(htim);
+}
+
+/**
+ * @brief Time Base configuration
+ * @param TIMx : TIM periheral
+ * @param Structure : TIM Base configuration structure
+ * @retval None
+ */
+void TIM_Base_SetConfig(TIM_TypeDef *TIMx, TIM_Base_InitTypeDef *Structure)
+{
+ uint32_t tmpcr1 = 0;
+ tmpcr1 = TIMx->CR1;
+
+ /* Set TIM Time Base Unit parameters ---------------------------------------*/
+ if (IS_TIM_COUNTER_MODE_SELECT_INSTANCE(TIMx))
+ {
+ /* Select the Counter Mode */
+ tmpcr1 &= ~(TIM_CR1_DIR | TIM_CR1_CMS);
+ tmpcr1 |= Structure->CounterMode;
+ }
+
+ if(IS_TIM_CLOCK_DIVISION_INSTANCE(TIMx))
+ {
+ /* Set the clock division */
+ tmpcr1 &= ~TIM_CR1_CKD;
+ tmpcr1 |= (uint32_t)Structure->ClockDivision;
+ }
+
+ TIMx->CR1 = tmpcr1;
+
+ /* Set the Autoreload value */
+ TIMx->ARR = (uint32_t)Structure->Period ;
+
+ /* Set the Prescaler value */
+ TIMx->PSC = (uint32_t)Structure->Prescaler;
+
+ if (IS_TIM_REPETITION_COUNTER_INSTANCE(TIMx))
+ {
+ /* Set the Repetition Counter value */
+ TIMx->RCR = Structure->RepetitionCounter;
+ }
+
+ /* Generate an update event to reload the Prescaler
+ and the repetition counter(only for TIM1 and TIM8) value immediatly */
+ TIMx->EGR = TIM_EGR_UG;
+}
+
+/**
+ * @brief Time Ouput Compare 1 configuration
+ * @param TIMx to select the TIM peripheral
+ * @param OC_Config : The ouput configuration structure
+ * @retval None
+ */
+static void TIM_OC1_SetConfig(TIM_TypeDef *TIMx, TIM_OC_InitTypeDef *OC_Config)
+{
+ uint32_t tmpccmrx = 0;
+ uint32_t tmpccer = 0;
+ uint32_t tmpcr2 = 0;
+
+ /* Disable the Channel 1: Reset the CC1E Bit */
+ TIMx->CCER &= ~TIM_CCER_CC1E;
+
+ /* Get the TIMx CCER register value */
+ tmpccer = TIMx->CCER;
+ /* Get the TIMx CR2 register value */
+ tmpcr2 = TIMx->CR2;
+
+ /* Get the TIMx CCMR1 register value */
+ tmpccmrx = TIMx->CCMR1;
+
+ /* Reset the Output Compare Mode Bits */
+ tmpccmrx &= ~TIM_CCMR1_OC1M;
+ tmpccmrx &= ~TIM_CCMR1_CC1S;
+ /* Select the Output Compare Mode */
+ tmpccmrx |= OC_Config->OCMode;
+
+ /* Reset the Output Polarity level */
+ tmpccer &= ~TIM_CCER_CC1P;
+ /* Set the Output Compare Polarity */
+ tmpccer |= OC_Config->OCPolarity;
+
+ if(IS_TIM_CCXN_INSTANCE(TIMx, TIM_CHANNEL_1))
+ {
+ /* Check parameters */
+ assert_param(IS_TIM_OCN_POLARITY(OC_Config->OCNPolarity));
+
+ /* Reset the Output N Polarity level */
+ tmpccer &= ~TIM_CCER_CC1NP;
+ /* Set the Output N Polarity */
+ tmpccer |= OC_Config->OCNPolarity;
+ /* Reset the Output N State */
+ tmpccer &= ~TIM_CCER_CC1NE;
+ }
+
+ if(IS_TIM_BREAK_INSTANCE(TIMx))
+ {
+ /* Check parameters */
+ assert_param(IS_TIM_OCNIDLE_STATE(OC_Config->OCNIdleState));
+ assert_param(IS_TIM_OCIDLE_STATE(OC_Config->OCIdleState));
+
+ /* Reset the Output Compare and Output Compare N IDLE State */
+ tmpcr2 &= ~TIM_CR2_OIS1;
+ tmpcr2 &= ~TIM_CR2_OIS1N;
+ /* Set the Output Idle state */
+ tmpcr2 |= OC_Config->OCIdleState;
+ /* Set the Output N Idle state */
+ tmpcr2 |= OC_Config->OCNIdleState;
+ }
+ /* Write to TIMx CR2 */
+ TIMx->CR2 = tmpcr2;
+
+ /* Write to TIMx CCMR1 */
+ TIMx->CCMR1 = tmpccmrx;
+
+ /* Set the Capture Compare Register value */
+ TIMx->CCR1 = OC_Config->Pulse;
+
+ /* Write to TIMx CCER */
+ TIMx->CCER = tmpccer;
+}
+
+/**
+ * @brief Time Ouput Compare 2 configuration
+ * @param TIMx to select the TIM peripheral
+ * @param OC_Config : The ouput configuration structure
+ * @retval None
+ */
+void TIM_OC2_SetConfig(TIM_TypeDef *TIMx, TIM_OC_InitTypeDef *OC_Config)
+{
+ uint32_t tmpccmrx = 0;
+ uint32_t tmpccer = 0;
+ uint32_t tmpcr2 = 0;
+
+ /* Disable the Channel 2: Reset the CC2E Bit */
+ TIMx->CCER &= ~TIM_CCER_CC2E;
+
+ /* Get the TIMx CCER register value */
+ tmpccer = TIMx->CCER;
+ /* Get the TIMx CR2 register value */
+ tmpcr2 = TIMx->CR2;
+
+ /* Get the TIMx CCMR1 register value */
+ tmpccmrx = TIMx->CCMR1;
+
+ /* Reset the Output Compare mode and Capture/Compare selection Bits */
+ tmpccmrx &= ~TIM_CCMR1_OC2M;
+ tmpccmrx &= ~TIM_CCMR1_CC2S;
+
+ /* Select the Output Compare Mode */
+ tmpccmrx |= (OC_Config->OCMode << 8);
+
+ /* Reset the Output Polarity level */
+ tmpccer &= ~TIM_CCER_CC2P;
+ /* Set the Output Compare Polarity */
+ tmpccer |= (OC_Config->OCPolarity << 4);
+
+ if(IS_TIM_CCXN_INSTANCE(TIMx, TIM_CHANNEL_2))
+ {
+ assert_param(IS_TIM_OCN_POLARITY(OC_Config->OCNPolarity));
+
+ /* Reset the Output N Polarity level */
+ tmpccer &= ~TIM_CCER_CC2NP;
+ /* Set the Output N Polarity */
+ tmpccer |= (OC_Config->OCNPolarity << 4);
+ /* Reset the Output N State */
+ tmpccer &= ~TIM_CCER_CC2NE;
+
+ }
+
+ if(IS_TIM_BREAK_INSTANCE(TIMx))
+ {
+ /* Check parameters */
+ assert_param(IS_TIM_OCNIDLE_STATE(OC_Config->OCNIdleState));
+ assert_param(IS_TIM_OCIDLE_STATE(OC_Config->OCIdleState));
+
+ /* Reset the Output Compare and Output Compare N IDLE State */
+ tmpcr2 &= ~TIM_CR2_OIS2;
+ tmpcr2 &= ~TIM_CR2_OIS2N;
+ /* Set the Output Idle state */
+ tmpcr2 |= (OC_Config->OCIdleState << 2);
+ /* Set the Output N Idle state */
+ tmpcr2 |= (OC_Config->OCNIdleState << 2);
+ }
+
+ /* Write to TIMx CR2 */
+ TIMx->CR2 = tmpcr2;
+
+ /* Write to TIMx CCMR1 */
+ TIMx->CCMR1 = tmpccmrx;
+
+ /* Set the Capture Compare Register value */
+ TIMx->CCR2 = OC_Config->Pulse;
+
+ /* Write to TIMx CCER */
+ TIMx->CCER = tmpccer;
+}
+
+/**
+ * @brief Time Ouput Compare 3 configuration
+ * @param TIMx to select the TIM peripheral
+ * @param OC_Config : The ouput configuration structure
+ * @retval None
+ */
+static void TIM_OC3_SetConfig(TIM_TypeDef *TIMx, TIM_OC_InitTypeDef *OC_Config)
+{
+ uint32_t tmpccmrx = 0;
+ uint32_t tmpccer = 0;
+ uint32_t tmpcr2 = 0;
+
+ /* Disable the Channel 3: Reset the CC2E Bit */
+ TIMx->CCER &= ~TIM_CCER_CC3E;
+
+ /* Get the TIMx CCER register value */
+ tmpccer = TIMx->CCER;
+ /* Get the TIMx CR2 register value */
+ tmpcr2 = TIMx->CR2;
+
+ /* Get the TIMx CCMR2 register value */
+ tmpccmrx = TIMx->CCMR2;
+
+ /* Reset the Output Compare mode and Capture/Compare selection Bits */
+ tmpccmrx &= ~TIM_CCMR2_OC3M;
+ tmpccmrx &= ~TIM_CCMR2_CC3S;
+ /* Select the Output Compare Mode */
+ tmpccmrx |= OC_Config->OCMode;
+
+ /* Reset the Output Polarity level */
+ tmpccer &= ~TIM_CCER_CC3P;
+ /* Set the Output Compare Polarity */
+ tmpccer |= (OC_Config->OCPolarity << 8);
+
+ if(IS_TIM_CCXN_INSTANCE(TIMx, TIM_CHANNEL_3))
+ {
+ assert_param(IS_TIM_OCN_POLARITY(OC_Config->OCNPolarity));
+
+ /* Reset the Output N Polarity level */
+ tmpccer &= ~TIM_CCER_CC3NP;
+ /* Set the Output N Polarity */
+ tmpccer |= (OC_Config->OCNPolarity << 8);
+ /* Reset the Output N State */
+ tmpccer &= ~TIM_CCER_CC3NE;
+ }
+
+ if(IS_TIM_BREAK_INSTANCE(TIMx))
+ {
+ /* Check parameters */
+ assert_param(IS_TIM_OCNIDLE_STATE(OC_Config->OCNIdleState));
+ assert_param(IS_TIM_OCIDLE_STATE(OC_Config->OCIdleState));
+
+ /* Reset the Output Compare and Output Compare N IDLE State */
+ tmpcr2 &= ~TIM_CR2_OIS3;
+ tmpcr2 &= ~TIM_CR2_OIS3N;
+ /* Set the Output Idle state */
+ tmpcr2 |= (OC_Config->OCIdleState << 4);
+ /* Set the Output N Idle state */
+ tmpcr2 |= (OC_Config->OCNIdleState << 4);
+ }
+
+ /* Write to TIMx CR2 */
+ TIMx->CR2 = tmpcr2;
+
+ /* Write to TIMx CCMR2 */
+ TIMx->CCMR2 = tmpccmrx;
+
+ /* Set the Capture Compare Register value */
+ TIMx->CCR3 = OC_Config->Pulse;
+
+ /* Write to TIMx CCER */
+ TIMx->CCER = tmpccer;
+}
+
+/**
+ * @brief Time Ouput Compare 4 configuration
+ * @param TIMx to select the TIM peripheral
+ * @param OC_Config : The ouput configuration structure
+ * @retval None
+ */
+static void TIM_OC4_SetConfig(TIM_TypeDef *TIMx, TIM_OC_InitTypeDef *OC_Config)
+{
+ uint32_t tmpccmrx = 0;
+ uint32_t tmpccer = 0;
+ uint32_t tmpcr2 = 0;
+
+ /* Disable the Channel 4: Reset the CC4E Bit */
+ TIMx->CCER &= ~TIM_CCER_CC4E;
+
+ /* Get the TIMx CCER register value */
+ tmpccer = TIMx->CCER;
+ /* Get the TIMx CR2 register value */
+ tmpcr2 = TIMx->CR2;
+
+ /* Get the TIMx CCMR2 register value */
+ tmpccmrx = TIMx->CCMR2;
+
+ /* Reset the Output Compare mode and Capture/Compare selection Bits */
+ tmpccmrx &= ~TIM_CCMR2_OC4M;
+ tmpccmrx &= ~TIM_CCMR2_CC4S;
+
+ /* Select the Output Compare Mode */
+ tmpccmrx |= (OC_Config->OCMode << 8);
+
+ /* Reset the Output Polarity level */
+ tmpccer &= ~TIM_CCER_CC4P;
+ /* Set the Output Compare Polarity */
+ tmpccer |= (OC_Config->OCPolarity << 12);
+
+ if(IS_TIM_BREAK_INSTANCE(TIMx))
+ {
+ assert_param(IS_TIM_OCIDLE_STATE(OC_Config->OCIdleState));
+
+ /* Reset the Output Compare IDLE State */
+ tmpcr2 &= ~TIM_CR2_OIS4;
+ /* Set the Output Idle state */
+ tmpcr2 |= (OC_Config->OCIdleState << 6);
+ }
+
+ /* Write to TIMx CR2 */
+ TIMx->CR2 = tmpcr2;
+
+ /* Write to TIMx CCMR2 */
+ TIMx->CCMR2 = tmpccmrx;
+
+ /* Set the Capture Compare Register value */
+ TIMx->CCR4 = OC_Config->Pulse;
+
+ /* Write to TIMx CCER */
+ TIMx->CCER = tmpccer;
+}
+
+
+/**
+ * @brief Time Slave configuration
+ * @param htim: pointer to a TIM_HandleTypeDef structure that contains
+ * the configuration information for TIM module.
+ * @param sSlaveConfig: The slave configuration structure
+ * @retval None
+ */
+static void TIM_SlaveTimer_SetConfig(TIM_HandleTypeDef *htim,
+ TIM_SlaveConfigTypeDef * sSlaveConfig)
+{
+ uint32_t tmpsmcr = 0;
+ uint32_t tmpccmr1 = 0;
+ uint32_t tmpccer = 0;
+
+ /* Get the TIMx SMCR register value */
+ tmpsmcr = htim->Instance->SMCR;
+
+ /* Reset the Trigger Selection Bits */
+ tmpsmcr &= ~TIM_SMCR_TS;
+ /* Set the Input Trigger source */
+ tmpsmcr |= sSlaveConfig->InputTrigger;
+
+ /* Reset the slave mode Bits */
+ tmpsmcr &= ~TIM_SMCR_SMS;
+ /* Set the slave mode */
+ tmpsmcr |= sSlaveConfig->SlaveMode;
+
+ /* Write to TIMx SMCR */
+ htim->Instance->SMCR = tmpsmcr;
+
+ /* Configure the trigger prescaler, filter, and polarity */
+ switch (sSlaveConfig->InputTrigger)
+ {
+ case TIM_TS_ETRF:
+ {
+ /* Check the parameters */
+ assert_param(IS_TIM_CLOCKSOURCE_ETRMODE1_INSTANCE(htim->Instance));
+ assert_param(IS_TIM_TRIGGERPRESCALER(sSlaveConfig->TriggerPrescaler));
+ assert_param(IS_TIM_TRIGGERPOLARITY(sSlaveConfig->TriggerPolarity));
+ assert_param(IS_TIM_TRIGGERFILTER(sSlaveConfig->TriggerFilter));
+ /* Configure the ETR Trigger source */
+ TIM_ETR_SetConfig(htim->Instance,
+ sSlaveConfig->TriggerPrescaler,
+ sSlaveConfig->TriggerPolarity,
+ sSlaveConfig->TriggerFilter);
+ }
+ break;
+
+ case TIM_TS_TI1F_ED:
+ {
+ /* Check the parameters */
+ assert_param(IS_TIM_CC1_INSTANCE(htim->Instance));
+ assert_param(IS_TIM_TRIGGERFILTER(sSlaveConfig->TriggerFilter));
+
+ /* Disable the Channel 1: Reset the CC1E Bit */
+ tmpccer = htim->Instance->CCER;
+ htim->Instance->CCER &= ~TIM_CCER_CC1E;
+ tmpccmr1 = htim->Instance->CCMR1;
+
+ /* Set the filter */
+ tmpccmr1 &= ~TIM_CCMR1_IC1F;
+ tmpccmr1 |= ((sSlaveConfig->TriggerFilter) << 4);
+
+ /* Write to TIMx CCMR1 and CCER registers */
+ htim->Instance->CCMR1 = tmpccmr1;
+ htim->Instance->CCER = tmpccer;
+
+ }
+ break;
+
+ case TIM_TS_TI1FP1:
+ {
+ /* Check the parameters */
+ assert_param(IS_TIM_CC1_INSTANCE(htim->Instance));
+ assert_param(IS_TIM_TRIGGERPOLARITY(sSlaveConfig->TriggerPolarity));
+ assert_param(IS_TIM_TRIGGERFILTER(sSlaveConfig->TriggerFilter));
+
+ /* Configure TI1 Filter and Polarity */
+ TIM_TI1_ConfigInputStage(htim->Instance,
+ sSlaveConfig->TriggerPolarity,
+ sSlaveConfig->TriggerFilter);
+ }
+ break;
+
+ case TIM_TS_TI2FP2:
+ {
+ /* Check the parameters */
+ assert_param(IS_TIM_CC2_INSTANCE(htim->Instance));
+ assert_param(IS_TIM_TRIGGERPOLARITY(sSlaveConfig->TriggerPolarity));
+ assert_param(IS_TIM_TRIGGERFILTER(sSlaveConfig->TriggerFilter));
+
+ /* Configure TI2 Filter and Polarity */
+ TIM_TI2_ConfigInputStage(htim->Instance,
+ sSlaveConfig->TriggerPolarity,
+ sSlaveConfig->TriggerFilter);
+ }
+ break;
+
+ case TIM_TS_ITR0:
+ {
+ /* Check the parameter */
+ assert_param(IS_TIM_CC2_INSTANCE(htim->Instance));
+ }
+ break;
+
+ case TIM_TS_ITR1:
+ {
+ /* Check the parameter */
+ assert_param(IS_TIM_CC2_INSTANCE(htim->Instance));
+ }
+ break;
+
+ case TIM_TS_ITR2:
+ {
+ /* Check the parameter */
+ assert_param(IS_TIM_CC2_INSTANCE(htim->Instance));
+ }
+ break;
+
+ case TIM_TS_ITR3:
+ {
+ /* Check the parameter */
+ assert_param(IS_TIM_CC2_INSTANCE(htim->Instance));
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+/**
+ * @brief Configure the TI1 as Input.
+ * @param TIMx to select the TIM peripheral.
+ * @param TIM_ICPolarity : The Input Polarity.
+ * This parameter can be one of the following values:
+ * @arg TIM_ICPOLARITY_RISING
+ * @arg TIM_ICPOLARITY_FALLING
+ * @arg TIM_ICPOLARITY_BOTHEDGE
+ * @param TIM_ICSelection : specifies the input to be used.
+ * This parameter can be one of the following values:
+ * @arg TIM_ICSELECTION_DIRECTTI: TIM Input 1 is selected to be connected to IC1.
+ * @arg TIM_ICSELECTION_INDIRECTTI: TIM Input 1 is selected to be connected to IC2.
+ * @arg TIM_ICSELECTION_TRC: TIM Input 1 is selected to be connected to TRC.
+ * @param TIM_ICFilter : Specifies the Input Capture Filter.
+ * This parameter must be a value between 0x00 and 0x0F.
+ * @retval None
+ * @note TIM_ICFilter and TIM_ICPolarity are not used in INDIRECT mode as TI2FP1
+ * (on channel2 path) is used as the input signal. Therefore CCMR1 must be
+ * protected against un-initialized filter and polarity values.
+ */
+void TIM_TI1_SetConfig(TIM_TypeDef *TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICSelection,
+ uint32_t TIM_ICFilter)
+{
+ uint32_t tmpccmr1 = 0;
+ uint32_t tmpccer = 0;
+
+ /* Disable the Channel 1: Reset the CC1E Bit */
+ TIMx->CCER &= ~TIM_CCER_CC1E;
+ tmpccmr1 = TIMx->CCMR1;
+ tmpccer = TIMx->CCER;
+
+ /* Select the Input */
+ if(IS_TIM_CC2_INSTANCE(TIMx) != RESET)
+ {
+ tmpccmr1 &= ~TIM_CCMR1_CC1S;
+ tmpccmr1 |= TIM_ICSelection;
+ }
+ else
+ {
+ tmpccmr1 |= TIM_CCMR1_CC1S_0;
+ }
+
+ /* Set the filter */
+ tmpccmr1 &= ~TIM_CCMR1_IC1F;
+ tmpccmr1 |= ((TIM_ICFilter << 4) & TIM_CCMR1_IC1F);
+
+ /* Select the Polarity and set the CC1E Bit */
+ tmpccer &= ~(TIM_CCER_CC1P | TIM_CCER_CC1NP);
+ tmpccer |= (TIM_ICPolarity & (TIM_CCER_CC1P | TIM_CCER_CC1NP));
+
+ /* Write to TIMx CCMR1 and CCER registers */
+ TIMx->CCMR1 = tmpccmr1;
+ TIMx->CCER = tmpccer;
+}
+
+/**
+ * @brief Configure the Polarity and Filter for TI1.
+ * @param TIMx to select the TIM peripheral.
+ * @param TIM_ICPolarity : The Input Polarity.
+ * This parameter can be one of the following values:
+ * @arg TIM_ICPOLARITY_RISING
+ * @arg TIM_ICPOLARITY_FALLING
+ * @arg TIM_ICPOLARITY_BOTHEDGE
+ * @param TIM_ICFilter : Specifies the Input Capture Filter.
+ * This parameter must be a value between 0x00 and 0x0F.
+ * @retval None
+ */
+static void TIM_TI1_ConfigInputStage(TIM_TypeDef *TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICFilter)
+{
+ uint32_t tmpccmr1 = 0;
+ uint32_t tmpccer = 0;
+
+ /* Disable the Channel 1: Reset the CC1E Bit */
+ tmpccer = TIMx->CCER;
+ TIMx->CCER &= ~TIM_CCER_CC1E;
+ tmpccmr1 = TIMx->CCMR1;
+
+ /* Set the filter */
+ tmpccmr1 &= ~TIM_CCMR1_IC1F;
+ tmpccmr1 |= (TIM_ICFilter << 4);
+
+ /* Select the Polarity and set the CC1E Bit */
+ tmpccer &= ~(TIM_CCER_CC1P | TIM_CCER_CC1NP);
+ tmpccer |= TIM_ICPolarity;
+
+ /* Write to TIMx CCMR1 and CCER registers */
+ TIMx->CCMR1 = tmpccmr1;
+ TIMx->CCER = tmpccer;
+}
+
+/**
+ * @brief Configure the TI2 as Input.
+ * @param TIMx to select the TIM peripheral
+ * @param TIM_ICPolarity : The Input Polarity.
+ * This parameter can be one of the following values:
+ * @arg TIM_ICPOLARITY_RISING
+ * @arg TIM_ICPOLARITY_FALLING
+ * @arg TIM_ICPOLARITY_BOTHEDGE
+ * @param TIM_ICSelection : specifies the input to be used.
+ * This parameter can be one of the following values:
+ * @arg TIM_ICSELECTION_DIRECTTI: TIM Input 2 is selected to be connected to IC2.
+ * @arg TIM_ICSELECTION_INDIRECTTI: TIM Input 2 is selected to be connected to IC1.
+ * @arg TIM_ICSELECTION_TRC: TIM Input 2 is selected to be connected to TRC.
+ * @param TIM_ICFilter : Specifies the Input Capture Filter.
+ * This parameter must be a value between 0x00 and 0x0F.
+ * @retval None
+ * @note TIM_ICFilter and TIM_ICPolarity are not used in INDIRECT mode as TI1FP2
+ * (on channel1 path) is used as the input signal. Therefore CCMR1 must be
+ * protected against un-initialized filter and polarity values.
+ */
+static void TIM_TI2_SetConfig(TIM_TypeDef *TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICSelection,
+ uint32_t TIM_ICFilter)
+{
+ uint32_t tmpccmr1 = 0;
+ uint32_t tmpccer = 0;
+
+ /* Disable the Channel 2: Reset the CC2E Bit */
+ TIMx->CCER &= ~TIM_CCER_CC2E;
+ tmpccmr1 = TIMx->CCMR1;
+ tmpccer = TIMx->CCER;
+
+ /* Select the Input */
+ tmpccmr1 &= ~TIM_CCMR1_CC2S;
+ tmpccmr1 |= (TIM_ICSelection << 8);
+
+ /* Set the filter */
+ tmpccmr1 &= ~TIM_CCMR1_IC2F;
+ tmpccmr1 |= ((TIM_ICFilter << 12) & TIM_CCMR1_IC2F);
+
+ /* Select the Polarity and set the CC2E Bit */
+ tmpccer &= ~(TIM_CCER_CC2P | TIM_CCER_CC2NP);
+ tmpccer |= ((TIM_ICPolarity << 4) & (TIM_CCER_CC2P | TIM_CCER_CC2NP));
+
+ /* Write to TIMx CCMR1 and CCER registers */
+ TIMx->CCMR1 = tmpccmr1 ;
+ TIMx->CCER = tmpccer;
+}
+
+/**
+ * @brief Configure the Polarity and Filter for TI2.
+ * @param TIMx to select the TIM peripheral.
+ * @param TIM_ICPolarity : The Input Polarity.
+ * This parameter can be one of the following values:
+ * @arg TIM_ICPOLARITY_RISING
+ * @arg TIM_ICPOLARITY_FALLING
+ * @arg TIM_ICPOLARITY_BOTHEDGE
+ * @param TIM_ICFilter : Specifies the Input Capture Filter.
+ * This parameter must be a value between 0x00 and 0x0F.
+ * @retval None
+ */
+static void TIM_TI2_ConfigInputStage(TIM_TypeDef *TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICFilter)
+{
+ uint32_t tmpccmr1 = 0;
+ uint32_t tmpccer = 0;
+
+ /* Disable the Channel 2: Reset the CC2E Bit */
+ TIMx->CCER &= ~TIM_CCER_CC2E;
+ tmpccmr1 = TIMx->CCMR1;
+ tmpccer = TIMx->CCER;
+
+ /* Set the filter */
+ tmpccmr1 &= ~TIM_CCMR1_IC2F;
+ tmpccmr1 |= (TIM_ICFilter << 12);
+
+ /* Select the Polarity and set the CC2E Bit */
+ tmpccer &= ~(TIM_CCER_CC2P | TIM_CCER_CC2NP);
+ tmpccer |= (TIM_ICPolarity << 4);
+
+ /* Write to TIMx CCMR1 and CCER registers */
+ TIMx->CCMR1 = tmpccmr1 ;
+ TIMx->CCER = tmpccer;
+}
+
+/**
+ * @brief Configure the TI3 as Input.
+ * @param TIMx to select the TIM peripheral
+ * @param TIM_ICPolarity : The Input Polarity.
+ * This parameter can be one of the following values:
+ * @arg TIM_ICPOLARITY_RISING
+ * @arg TIM_ICPOLARITY_FALLING
+ * @arg TIM_ICPOLARITY_BOTHEDGE
+ * @param TIM_ICSelection : specifies the input to be used.
+ * This parameter can be one of the following values:
+ * @arg TIM_ICSELECTION_DIRECTTI: TIM Input 3 is selected to be connected to IC3.
+ * @arg TIM_ICSELECTION_INDIRECTTI: TIM Input 3 is selected to be connected to IC4.
+ * @arg TIM_ICSELECTION_TRC: TIM Input 3 is selected to be connected to TRC.
+ * @param TIM_ICFilter : Specifies the Input Capture Filter.
+ * This parameter must be a value between 0x00 and 0x0F.
+ * @retval None
+ * @note TIM_ICFilter and TIM_ICPolarity are not used in INDIRECT mode as TI3FP4
+ * (on channel1 path) is used as the input signal. Therefore CCMR2 must be
+ * protected against un-initialized filter and polarity values.
+ */
+static void TIM_TI3_SetConfig(TIM_TypeDef *TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICSelection,
+ uint32_t TIM_ICFilter)
+{
+ uint32_t tmpccmr2 = 0;
+ uint32_t tmpccer = 0;
+
+ /* Disable the Channel 3: Reset the CC3E Bit */
+ TIMx->CCER &= ~TIM_CCER_CC3E;
+ tmpccmr2 = TIMx->CCMR2;
+ tmpccer = TIMx->CCER;
+
+ /* Select the Input */
+ tmpccmr2 &= ~TIM_CCMR2_CC3S;
+ tmpccmr2 |= TIM_ICSelection;
+
+ /* Set the filter */
+ tmpccmr2 &= ~TIM_CCMR2_IC3F;
+ tmpccmr2 |= ((TIM_ICFilter << 4) & TIM_CCMR2_IC3F);
+
+ /* Select the Polarity and set the CC3E Bit */
+ tmpccer &= ~(TIM_CCER_CC3P | TIM_CCER_CC3NP);
+ tmpccer |= ((TIM_ICPolarity << 8) & (TIM_CCER_CC3P | TIM_CCER_CC3NP));
+
+ /* Write to TIMx CCMR2 and CCER registers */
+ TIMx->CCMR2 = tmpccmr2;
+ TIMx->CCER = tmpccer;
+}
+
+/**
+ * @brief Configure the TI4 as Input.
+ * @param TIMx to select the TIM peripheral
+ * @param TIM_ICPolarity : The Input Polarity.
+ * This parameter can be one of the following values:
+ * @arg TIM_ICPOLARITY_RISING
+ * @arg TIM_ICPOLARITY_FALLING
+ * @arg TIM_ICPOLARITY_BOTHEDGE
+ * @param TIM_ICSelection : specifies the input to be used.
+ * This parameter can be one of the following values:
+ * @arg TIM_ICSELECTION_DIRECTTI: TIM Input 4 is selected to be connected to IC4.
+ * @arg TIM_ICSELECTION_INDIRECTTI: TIM Input 4 is selected to be connected to IC3.
+ * @arg TIM_ICSELECTION_TRC: TIM Input 4 is selected to be connected to TRC.
+ * @param TIM_ICFilter : Specifies the Input Capture Filter.
+ * This parameter must be a value between 0x00 and 0x0F.
+ * @note TIM_ICFilter and TIM_ICPolarity are not used in INDIRECT mode as TI4FP3
+ * (on channel1 path) is used as the input signal. Therefore CCMR2 must be
+ * protected against un-initialized filter and polarity values.
+ * @retval None
+ */
+static void TIM_TI4_SetConfig(TIM_TypeDef *TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICSelection,
+ uint32_t TIM_ICFilter)
+{
+ uint32_t tmpccmr2 = 0;
+ uint32_t tmpccer = 0;
+
+ /* Disable the Channel 4: Reset the CC4E Bit */
+ TIMx->CCER &= ~TIM_CCER_CC4E;
+ tmpccmr2 = TIMx->CCMR2;
+ tmpccer = TIMx->CCER;
+
+ /* Select the Input */
+ tmpccmr2 &= ~TIM_CCMR2_CC4S;
+ tmpccmr2 |= (TIM_ICSelection << 8);
+
+ /* Set the filter */
+ tmpccmr2 &= ~TIM_CCMR2_IC4F;
+ tmpccmr2 |= ((TIM_ICFilter << 12) & TIM_CCMR2_IC4F);
+
+ /* Select the Polarity and set the CC4E Bit */
+ tmpccer &= ~(TIM_CCER_CC4P | TIM_CCER_CC4NP);
+ tmpccer |= ((TIM_ICPolarity << 12) & (TIM_CCER_CC4P | TIM_CCER_CC4NP));
+
+ /* Write to TIMx CCMR2 and CCER registers */
+ TIMx->CCMR2 = tmpccmr2;
+ TIMx->CCER = tmpccer ;
+}
+
+/**
+ * @brief Selects the Input Trigger source
+ * @param TIMx to select the TIM peripheral
+ * @param InputTriggerSource : The Input Trigger source.
+ * This parameter can be one of the following values:
+ * @arg TIM_TS_ITR0 : Internal Trigger 0
+ * @arg TIM_TS_ITR1 : Internal Trigger 1
+ * @arg TIM_TS_ITR2 : Internal Trigger 2
+ * @arg TIM_TS_ITR3 : Internal Trigger 3
+ * @arg TIM_TS_TI1F_ED : TI1 Edge Detector
+ * @arg TIM_TS_TI1FP1 : Filtered Timer Input 1
+ * @arg TIM_TS_TI2FP2 : Filtered Timer Input 2
+ * @arg TIM_TS_ETRF : External Trigger input
+ * @retval None
+ */
+static void TIM_ITRx_SetConfig(TIM_TypeDef *TIMx, uint16_t InputTriggerSource)
+{
+ uint32_t tmpsmcr = 0;
+
+ /* Get the TIMx SMCR register value */
+ tmpsmcr = TIMx->SMCR;
+ /* Reset the TS Bits */
+ tmpsmcr &= ~TIM_SMCR_TS;
+ /* Set the Input Trigger source and the slave mode*/
+ tmpsmcr |= InputTriggerSource | TIM_SLAVEMODE_EXTERNAL1;
+ /* Write to TIMx SMCR */
+ TIMx->SMCR = tmpsmcr;
+}
+/**
+ * @brief Configures the TIMx External Trigger (ETR).
+ * @param TIMx to select the TIM peripheral
+ * @param TIM_ExtTRGPrescaler : The external Trigger Prescaler.
+ * This parameter can be one of the following values:
+ * @arg TIM_ETRPRESCALER_DIV1: ETRP Prescaler OFF.
+ * @arg TIM_ETRPRESCALER_DIV2: ETRP frequency divided by 2.
+ * @arg TIM_ETRPRESCALER_DIV4: ETRP frequency divided by 4.
+ * @arg TIM_ETRPRESCALER_DIV8: ETRP frequency divided by 8.
+ * @param TIM_ExtTRGPolarity : The external Trigger Polarity.
+ * This parameter can be one of the following values:
+ * @arg TIM_ETRPOLARITY_INVERTED: active low or falling edge active.
+ * @arg TIM_ETRPOLARITY_NONINVERTED: active high or rising edge active.
+ * @param ExtTRGFilter : External Trigger Filter.
+ * This parameter must be a value between 0x00 and 0x0F
+ * @retval None
+ */
+static void TIM_ETR_SetConfig(TIM_TypeDef* TIMx, uint32_t TIM_ExtTRGPrescaler,
+ uint32_t TIM_ExtTRGPolarity, uint32_t ExtTRGFilter)
+{
+ uint32_t tmpsmcr = 0;
+
+ tmpsmcr = TIMx->SMCR;
+
+ /* Reset the ETR Bits */
+ tmpsmcr &= ~(TIM_SMCR_ETF | TIM_SMCR_ETPS | TIM_SMCR_ECE | TIM_SMCR_ETP);
+
+ /* Set the Prescaler, the Filter value and the Polarity */
+ tmpsmcr |= (uint32_t)(TIM_ExtTRGPrescaler | (TIM_ExtTRGPolarity | (ExtTRGFilter << 8)));
+
+ /* Write to TIMx SMCR */
+ TIMx->SMCR = tmpsmcr;
+}
+
+/**
+ * @brief Enables or disables the TIM Capture Compare Channel x.
+ * @param TIMx to select the TIM peripheral
+ * @param Channel : specifies the TIM Channel
+ * This parameter can be one of the following values:
+ * @arg TIM_CHANNEL_1: TIM Channel 1
+ * @arg TIM_CHANNEL_2: TIM Channel 2
+ * @arg TIM_CHANNEL_3: TIM Channel 3
+ * @arg TIM_CHANNEL_4: TIM Channel 4
+ * @param ChannelState : specifies the TIM Channel CCxE bit new state.
+ * This parameter can be: TIM_CCx_ENABLE or TIM_CCx_Disable.
+ * @retval None
+ */
+void TIM_CCxChannelCmd(TIM_TypeDef* TIMx, uint32_t Channel, uint32_t ChannelState)
+{
+ uint32_t tmp = 0;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_CC1_INSTANCE(TIMx));
+ assert_param(IS_TIM_CHANNELS(Channel));
+
+ tmp = TIM_CCER_CC1E << Channel;
+
+ /* Reset the CCxE Bit */
+ TIMx->CCER &= ~tmp;
+
+ /* Set or reset the CCxE Bit */
+ TIMx->CCER |= (uint32_t)(ChannelState << Channel);
+}
+
+/**
+ * @}
+ */
+
+#endif /* HAL_TIM_MODULE_ENABLED */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/bsp/radio-controller-1/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim_ex.c b/bsp/radio-controller-1/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim_ex.c
new file mode 100644
index 0000000..75d4584
--- /dev/null
+++ b/bsp/radio-controller-1/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim_ex.c
@@ -0,0 +1,1857 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_tim_ex.c
+ * @author MCD Application Team
+ * @version V1.0.4
+ * @date 29-April-2016
+ * @brief TIM HAL module driver.
+ * This file provides firmware functions to manage the following
+ * functionalities of the Timer Extended peripheral:
+ * + Time Hall Sensor Interface Initialization
+ * + Time Hall Sensor Interface Start
+ * + Time Complementary signal bread and dead time configuration
+ * + Time Master and Slave synchronization configuration
+ * + Timer remapping capabilities configuration
+ @verbatim
+ ==============================================================================
+ ##### TIMER Extended features #####
+ ==============================================================================
+ [..]
+ The Timer Extended features include:
+ (#) Complementary outputs with programmable dead-time for :
+ (++) Output Compare
+ (++) PWM generation (Edge and Center-aligned Mode)
+ (++) One-pulse mode output
+ (#) Synchronization circuit to control the timer with external signals and to
+ interconnect several timers together.
+ (#) Break input to put the timer output signals in reset state or in a known state.
+ (#) Supports incremental (quadrature) encoder and hall-sensor circuitry for
+ positioning purposes
+
+ ##### How to use this driver #####
+ ==============================================================================
+ [..]
+ (#) Initialize the TIM low level resources by implementing the following functions
+ depending from feature used :
+ (++) Complementary Output Compare : HAL_TIM_OC_MspInit()
+ (++) Complementary PWM generation : HAL_TIM_PWM_MspInit()
+ (++) Complementary One-pulse mode output : HAL_TIM_OnePulse_MspInit()
+ (++) Hall Sensor output : HAL_TIMEx_HallSensor_MspInit()
+
+ (#) Initialize the TIM low level resources :
+ (##) Enable the TIM interface clock using __HAL_RCC_TIMx_CLK_ENABLE();
+ (##) TIM pins configuration
+ (+++) Enable the clock for the TIM GPIOs using the following function:
+ __HAL_RCC_GPIOx_CLK_ENABLE();
+ (+++) Configure these TIM pins in Alternate function mode using HAL_GPIO_Init();
+
+ (#) The external Clock can be configured, if needed (the default clock is the
+ internal clock from the APBx), using the following function:
+ HAL_TIM_ConfigClockSource, the clock configuration should be done before
+ any start function.
+
+ (#) Configure the TIM in the desired functioning mode using one of the
+ initialization function of this driver:
+ (++) HAL_TIMEx_HallSensor_Init and HAL_TIMEx_ConfigCommutationEvent: to use the
+ Timer Hall Sensor Interface and the commutation event with the corresponding
+ Interrupt and DMA request if needed (Note that One Timer is used to interface
+ with the Hall sensor Interface and another Timer should be used to use
+ the commutation event).
+
+ (#) Activate the TIM peripheral using one of the start functions:
+ (++) Complementary Output Compare : HAL_TIMEx_OCN_Start(), HAL_TIMEx_OCN_Start_DMA(), HAL_TIMEx_OCN_Start_IT()
+ (++) Complementary PWM generation : HAL_TIMEx_PWMN_Start(), HAL_TIMEx_PWMN_Start_DMA(), HAL_TIMEx_PWMN_Start_IT()
+ (++) Complementary One-pulse mode output : HAL_TIMEx_OnePulseN_Start(), HAL_TIMEx_OnePulseN_Start_IT()
+ (++) Hall Sensor output : HAL_TIMEx_HallSensor_Start(), HAL_TIMEx_HallSensor_Start_DMA(), HAL_TIMEx_HallSensor_Start_IT().
+
+
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+*/
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+/** @defgroup TIMEx TIMEx
+ * @brief TIM Extended HAL module driver
+ * @{
+ */
+
+#ifdef HAL_TIM_MODULE_ENABLED
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+
+#if defined (STM32F100xB) || defined (STM32F100xE) || \
+ defined (STM32F103x6) || defined (STM32F103xB) || defined (STM32F103xE) || defined (STM32F103xG) || \
+ defined (STM32F105xC) || defined (STM32F107xC)
+/** @defgroup TIMEx_Private_Functions TIMEx Private Functions
+ * @{
+ */
+static void TIM_CCxNChannelCmd(TIM_TypeDef* TIMx, uint32_t Channel, uint32_t ChannelNState);
+/**
+ * @}
+ */
+#endif /* defined(STM32F100xB) || defined(STM32F100xE) || */
+ /* defined(STM32F103x6) || defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG) || */
+ /* defined(STM32F105xC) || defined(STM32F107xC) */
+
+/* Exported functions ---------------------------------------------------------*/
+
+/** @defgroup TIMEx_Exported_Functions TIMEx Exported Functions
+ * @{
+ */
+
+
+/** @defgroup TIMEx_Exported_Functions_Group1 Timer Hall Sensor functions
+ * @brief Timer Hall Sensor functions
+ *
+@verbatim
+ ==============================================================================
+ ##### Timer Hall Sensor functions #####
+ ==============================================================================
+ [..]
+ This section provides functions allowing to:
+ (+) Initialize and configure TIM HAL Sensor.
+ (+) De-initialize TIM HAL Sensor.
+ (+) Start the Hall Sensor Interface.
+ (+) Stop the Hall Sensor Interface.
+ (+) Start the Hall Sensor Interface and enable interrupts.
+ (+) Stop the Hall Sensor Interface and disable interrupts.
+ (+) Start the Hall Sensor Interface and enable DMA transfers.
+ (+) Stop the Hall Sensor Interface and disable DMA transfers.
+
+@endverbatim
+ * @{
+ */
+/**
+ * @brief Initializes the TIM Hall Sensor Interface and create the associated handle.
+ * @param htim : TIM Encoder Interface handle
+ * @param sConfig : TIM Hall Sensor configuration structure
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_TIMEx_HallSensor_Init(TIM_HandleTypeDef *htim, TIM_HallSensor_InitTypeDef* sConfig)
+{
+ TIM_OC_InitTypeDef OC_Config;
+
+ /* Check the TIM handle allocation */
+ if(htim == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ assert_param(IS_TIM_XOR_INSTANCE(htim->Instance));
+ assert_param(IS_TIM_COUNTER_MODE(htim->Init.CounterMode));
+ assert_param(IS_TIM_CLOCKDIVISION_DIV(htim->Init.ClockDivision));
+ assert_param(IS_TIM_IC_POLARITY(sConfig->IC1Polarity));
+ assert_param(IS_TIM_IC_PRESCALER(sConfig->IC1Prescaler));
+ assert_param(IS_TIM_IC_FILTER(sConfig->IC1Filter));
+
+ if(htim->State == HAL_TIM_STATE_RESET)
+ {
+ /* Allocate lock resource and initialize it */
+ htim->Lock = HAL_UNLOCKED;
+
+ /* Init the low level hardware : GPIO, CLOCK, NVIC and DMA */
+ HAL_TIMEx_HallSensor_MspInit(htim);
+ }
+
+ /* Set the TIM state */
+ htim->State= HAL_TIM_STATE_BUSY;
+
+ /* Configure the Time base in the Encoder Mode */
+ TIM_Base_SetConfig(htim->Instance, &htim->Init);
+
+ /* Configure the Channel 1 as Input Channel to interface with the three Outputs of the Hall sensor */
+ TIM_TI1_SetConfig(htim->Instance, sConfig->IC1Polarity, TIM_ICSELECTION_TRC, sConfig->IC1Filter);
+
+ /* Reset the IC1PSC Bits */
+ htim->Instance->CCMR1 &= ~TIM_CCMR1_IC1PSC;
+ /* Set the IC1PSC value */
+ htim->Instance->CCMR1 |= sConfig->IC1Prescaler;
+
+ /* Enable the Hall sensor interface (XOR function of the three inputs) */
+ htim->Instance->CR2 |= TIM_CR2_TI1S;
+
+ /* Select the TIM_TS_TI1F_ED signal as Input trigger for the TIM */
+ htim->Instance->SMCR &= ~TIM_SMCR_TS;
+ htim->Instance->SMCR |= TIM_TS_TI1F_ED;
+
+ /* Use the TIM_TS_TI1F_ED signal to reset the TIM counter each edge detection */
+ htim->Instance->SMCR &= ~TIM_SMCR_SMS;
+ htim->Instance->SMCR |= TIM_SLAVEMODE_RESET;
+
+ /* Program channel 2 in PWM 2 mode with the desired Commutation_Delay*/
+ OC_Config.OCFastMode = TIM_OCFAST_DISABLE;
+ OC_Config.OCIdleState = TIM_OCIDLESTATE_RESET;
+ OC_Config.OCMode = TIM_OCMODE_PWM2;
+ OC_Config.OCNIdleState = TIM_OCNIDLESTATE_RESET;
+ OC_Config.OCNPolarity = TIM_OCNPOLARITY_HIGH;
+ OC_Config.OCPolarity = TIM_OCPOLARITY_HIGH;
+ OC_Config.Pulse = sConfig->Commutation_Delay;
+
+ TIM_OC2_SetConfig(htim->Instance, &OC_Config);
+
+ /* Select OC2REF as trigger output on TRGO: write the MMS bits in the TIMx_CR2
+ register to 101 */
+ htim->Instance->CR2 &= ~TIM_CR2_MMS;
+ htim->Instance->CR2 |= TIM_TRGO_OC2REF;
+
+ /* Initialize the TIM state*/
+ htim->State= HAL_TIM_STATE_READY;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief DeInitializes the TIM Hall Sensor interface
+ * @param htim : TIM Hall Sensor handle
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_TIMEx_HallSensor_DeInit(TIM_HandleTypeDef *htim)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_INSTANCE(htim->Instance));
+
+ htim->State = HAL_TIM_STATE_BUSY;
+
+ /* Disable the TIM Peripheral Clock */
+ __HAL_TIM_DISABLE(htim);
+
+ /* DeInit the low level hardware: GPIO, CLOCK, NVIC */
+ HAL_TIMEx_HallSensor_MspDeInit(htim);
+
+ /* Change TIM state */
+ htim->State = HAL_TIM_STATE_RESET;
+
+ /* Release Lock */
+ __HAL_UNLOCK(htim);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Initializes the TIM Hall Sensor MSP.
+ * @param htim : TIM handle
+ * @retval None
+ */
+__weak void HAL_TIMEx_HallSensor_MspInit(TIM_HandleTypeDef *htim)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(htim);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_TIMEx_HallSensor_MspInit could be implemented in the user file
+ */
+}
+
+/**
+ * @brief DeInitializes TIM Hall Sensor MSP.
+ * @param htim : TIM handle
+ * @retval None
+ */
+__weak void HAL_TIMEx_HallSensor_MspDeInit(TIM_HandleTypeDef *htim)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(htim);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_TIMEx_HallSensor_MspDeInit could be implemented in the user file
+ */
+}
+
+/**
+ * @brief Starts the TIM Hall Sensor Interface.
+ * @param htim : TIM Hall Sensor handle
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_TIMEx_HallSensor_Start(TIM_HandleTypeDef *htim)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_XOR_INSTANCE(htim->Instance));
+
+ /* Enable the Input Capture channel 1
+ (in the Hall Sensor Interface the 3 possible channels that are used are TIM_CHANNEL_1, TIM_CHANNEL_2 and TIM_CHANNEL_3) */
+ TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE);
+
+ /* Enable the Peripheral */
+ __HAL_TIM_ENABLE(htim);
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Stops the TIM Hall sensor Interface.
+ * @param htim : TIM Hall Sensor handle
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_TIMEx_HallSensor_Stop(TIM_HandleTypeDef *htim)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_XOR_INSTANCE(htim->Instance));
+
+ /* Disable the Input Capture channel 1
+ (in the Hall Sensor Interface the 3 possible channels that are used are TIM_CHANNEL_1, TIM_CHANNEL_2 and TIM_CHANNEL_3) */
+ TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_DISABLE);
+
+ /* Disable the Peripheral */
+ __HAL_TIM_DISABLE(htim);
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Starts the TIM Hall Sensor Interface in interrupt mode.
+ * @param htim : TIM Hall Sensor handle
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_TIMEx_HallSensor_Start_IT(TIM_HandleTypeDef *htim)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_XOR_INSTANCE(htim->Instance));
+
+ /* Enable the capture compare Interrupts 1 event */
+ __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1);
+
+ /* Enable the Input Capture channel 1
+ (in the Hall Sensor Interface the 3 possible channels that are used are TIM_CHANNEL_1, TIM_CHANNEL_2 and TIM_CHANNEL_3) */
+ TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE);
+
+ /* Enable the Peripheral */
+ __HAL_TIM_ENABLE(htim);
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Stops the TIM Hall Sensor Interface in interrupt mode.
+ * @param htim : TIM handle
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_TIMEx_HallSensor_Stop_IT(TIM_HandleTypeDef *htim)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_XOR_INSTANCE(htim->Instance));
+
+ /* Disable the Input Capture channel 1
+ (in the Hall Sensor Interface the 3 possible channels that are used are TIM_CHANNEL_1, TIM_CHANNEL_2 and TIM_CHANNEL_3) */
+ TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_DISABLE);
+
+ /* Disable the capture compare Interrupts event */
+ __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1);
+
+ /* Disable the Peripheral */
+ __HAL_TIM_DISABLE(htim);
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Starts the TIM Hall Sensor Interface in DMA mode.
+ * @param htim : TIM Hall Sensor handle
+ * @param pData : The destination Buffer address.
+ * @param Length : The length of data to be transferred from TIM peripheral to memory.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_TIMEx_HallSensor_Start_DMA(TIM_HandleTypeDef *htim, uint32_t *pData, uint16_t Length)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_XOR_INSTANCE(htim->Instance));
+
+ if((htim->State == HAL_TIM_STATE_BUSY))
+ {
+ return HAL_BUSY;
+ }
+ else if((htim->State == HAL_TIM_STATE_READY))
+ {
+ if(((uint32_t)pData == 0 ) && (Length > 0))
+ {
+ return HAL_ERROR;
+ }
+ else
+ {
+ htim->State = HAL_TIM_STATE_BUSY;
+ }
+ }
+ /* Enable the Input Capture channel 1
+ (in the Hall Sensor Interface the 3 possible channels that are used are TIM_CHANNEL_1, TIM_CHANNEL_2 and TIM_CHANNEL_3) */
+ TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE);
+
+ /* Set the DMA Input Capture 1 Callback */
+ htim->hdma[TIM_DMA_ID_CC1]->XferCpltCallback = TIM_DMACaptureCplt;
+ /* Set the DMA error callback */
+ htim->hdma[TIM_DMA_ID_CC1]->XferErrorCallback = TIM_DMAError ;
+
+ /* Enable the DMA channel for Capture 1*/
+ HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC1], (uint32_t)&htim->Instance->CCR1, (uint32_t)pData, Length);
+
+ /* Enable the capture compare 1 Interrupt */
+ __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC1);
+
+ /* Enable the Peripheral */
+ __HAL_TIM_ENABLE(htim);
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Stops the TIM Hall Sensor Interface in DMA mode.
+ * @param htim : TIM handle
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_TIMEx_HallSensor_Stop_DMA(TIM_HandleTypeDef *htim)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_XOR_INSTANCE(htim->Instance));
+
+ /* Disable the Input Capture channel 1
+ (in the Hall Sensor Interface the 3 possible channels that are used are TIM_CHANNEL_1, TIM_CHANNEL_2 and TIM_CHANNEL_3) */
+ TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_DISABLE);
+
+
+ /* Disable the capture compare Interrupts 1 event */
+ __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC1);
+
+ /* Disable the Peripheral */
+ __HAL_TIM_DISABLE(htim);
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @}
+ */
+
+#if defined (STM32F100xB) || defined (STM32F100xE) || \
+ defined (STM32F103x6) || defined (STM32F103xB) || defined (STM32F103xE) || defined (STM32F103xG) || \
+ defined (STM32F105xC) || defined (STM32F107xC)
+
+/** @defgroup TIMEx_Exported_Functions_Group2 Timer Complementary Output Compare functions
+ * @brief Timer Complementary Output Compare functions
+ *
+@verbatim
+ ==============================================================================
+ ##### Timer Complementary Output Compare functions #####
+ ==============================================================================
+ [..]
+ This section provides functions allowing to:
+ (+) Start the Complementary Output Compare/PWM.
+ (+) Stop the Complementary Output Compare/PWM.
+ (+) Start the Complementary Output Compare/PWM and enable interrupts.
+ (+) Stop the Complementary Output Compare/PWM and disable interrupts.
+ (+) Start the Complementary Output Compare/PWM and enable DMA transfers.
+ (+) Stop the Complementary Output Compare/PWM and disable DMA transfers.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Starts the TIM Output Compare signal generation on the complementary
+ * output.
+ * @param htim : TIM Output Compare handle
+ * @param Channel : TIM Channel to be enabled
+ * This parameter can be one of the following values:
+ * @arg TIM_CHANNEL_1: TIM Channel 1 selected
+ * @arg TIM_CHANNEL_2: TIM Channel 2 selected
+ * @arg TIM_CHANNEL_3: TIM Channel 3 selected
+ * @arg TIM_CHANNEL_4: TIM Channel 4 selected
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_TIMEx_OCN_Start(TIM_HandleTypeDef *htim, uint32_t Channel)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
+
+ /* Enable the Capture compare channel N */
+ TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_ENABLE);
+
+ /* Enable the Main Ouput */
+ __HAL_TIM_MOE_ENABLE(htim);
+
+ /* Enable the Peripheral */
+ __HAL_TIM_ENABLE(htim);
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Stops the TIM Output Compare signal generation on the complementary
+ * output.
+ * @param htim : TIM handle
+ * @param Channel : TIM Channel to be disabled
+ * This parameter can be one of the following values:
+ * @arg TIM_CHANNEL_1: TIM Channel 1 selected
+ * @arg TIM_CHANNEL_2: TIM Channel 2 selected
+ * @arg TIM_CHANNEL_3: TIM Channel 3 selected
+ * @arg TIM_CHANNEL_4: TIM Channel 4 selected
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_TIMEx_OCN_Stop(TIM_HandleTypeDef *htim, uint32_t Channel)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
+
+ /* Disable the Capture compare channel N */
+ TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_DISABLE);
+
+ /* Disable the Main Ouput */
+ __HAL_TIM_MOE_DISABLE(htim);
+
+ /* Disable the Peripheral */
+ __HAL_TIM_DISABLE(htim);
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Starts the TIM Output Compare signal generation in interrupt mode
+ * on the complementary output.
+ * @param htim : TIM OC handle
+ * @param Channel : TIM Channel to be enabled
+ * This parameter can be one of the following values:
+ * @arg TIM_CHANNEL_1: TIM Channel 1 selected
+ * @arg TIM_CHANNEL_2: TIM Channel 2 selected
+ * @arg TIM_CHANNEL_3: TIM Channel 3 selected
+ * @arg TIM_CHANNEL_4: TIM Channel 4 selected
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_TIMEx_OCN_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
+
+ switch (Channel)
+ {
+ case TIM_CHANNEL_1:
+ {
+ /* Enable the TIM Output Compare interrupt */
+ __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1);
+ }
+ break;
+
+ case TIM_CHANNEL_2:
+ {
+ /* Enable the TIM Output Compare interrupt */
+ __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC2);
+ }
+ break;
+
+ case TIM_CHANNEL_3:
+ {
+ /* Enable the TIM Output Compare interrupt */
+ __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC3);
+ }
+ break;
+
+ case TIM_CHANNEL_4:
+ {
+ /* Enable the TIM Output Compare interrupt */
+ __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC4);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ /* Enable the TIM Break interrupt */
+ __HAL_TIM_ENABLE_IT(htim, TIM_IT_BREAK);
+
+ /* Enable the Capture compare channel N */
+ TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_ENABLE);
+
+ /* Enable the Main Ouput */
+ __HAL_TIM_MOE_ENABLE(htim);
+
+ /* Enable the Peripheral */
+ __HAL_TIM_ENABLE(htim);
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Stops the TIM Output Compare signal generation in interrupt mode
+ * on the complementary output.
+ * @param htim : TIM Output Compare handle
+ * @param Channel : TIM Channel to be disabled
+ * This parameter can be one of the following values:
+ * @arg TIM_CHANNEL_1: TIM Channel 1 selected
+ * @arg TIM_CHANNEL_2: TIM Channel 2 selected
+ * @arg TIM_CHANNEL_3: TIM Channel 3 selected
+ * @arg TIM_CHANNEL_4: TIM Channel 4 selected
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_TIMEx_OCN_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel)
+{
+ uint32_t tmpccer = 0;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
+
+ switch (Channel)
+ {
+ case TIM_CHANNEL_1:
+ {
+ /* Disable the TIM Output Compare interrupt */
+ __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1);
+ }
+ break;
+
+ case TIM_CHANNEL_2:
+ {
+ /* Disable the TIM Output Compare interrupt */
+ __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC2);
+ }
+ break;
+
+ case TIM_CHANNEL_3:
+ {
+ /* Disable the TIM Output Compare interrupt */
+ __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC3);
+ }
+ break;
+
+ case TIM_CHANNEL_4:
+ {
+ /* Disable the TIM Output Compare interrupt */
+ __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC4);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ /* Disable the Capture compare channel N */
+ TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_DISABLE);
+
+ /* Disable the TIM Break interrupt (only if no more channel is active) */
+ tmpccer = htim->Instance->CCER;
+ if ((tmpccer & (TIM_CCER_CC1NE | TIM_CCER_CC2NE | TIM_CCER_CC3NE)) == RESET)
+ {
+ __HAL_TIM_DISABLE_IT(htim, TIM_IT_BREAK);
+ }
+
+ /* Disable the Main Ouput */
+ __HAL_TIM_MOE_DISABLE(htim);
+
+ /* Disable the Peripheral */
+ __HAL_TIM_DISABLE(htim);
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Starts the TIM Output Compare signal generation in DMA mode
+ * on the complementary output.
+ * @param htim : TIM Output Compare handle
+ * @param Channel : TIM Channel to be enabled
+ * This parameter can be one of the following values:
+ * @arg TIM_CHANNEL_1: TIM Channel 1 selected
+ * @arg TIM_CHANNEL_2: TIM Channel 2 selected
+ * @arg TIM_CHANNEL_3: TIM Channel 3 selected
+ * @arg TIM_CHANNEL_4: TIM Channel 4 selected
+ * @param pData : The source Buffer address.
+ * @param Length : The length of data to be transferred from memory to TIM peripheral
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_TIMEx_OCN_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, uint32_t *pData, uint16_t Length)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
+
+ if((htim->State == HAL_TIM_STATE_BUSY))
+ {
+ return HAL_BUSY;
+ }
+ else if((htim->State == HAL_TIM_STATE_READY))
+ {
+ if(((uint32_t)pData == 0 ) && (Length > 0))
+ {
+ return HAL_ERROR;
+ }
+ else
+ {
+ htim->State = HAL_TIM_STATE_BUSY;
+ }
+ }
+ switch (Channel)
+ {
+ case TIM_CHANNEL_1:
+ {
+ /* Set the DMA Period elapsed callback */
+ htim->hdma[TIM_DMA_ID_CC1]->XferCpltCallback = TIM_DMADelayPulseCplt;
+
+ /* Set the DMA error callback */
+ htim->hdma[TIM_DMA_ID_CC1]->XferErrorCallback = TIM_DMAError ;
+
+ /* Enable the DMA channel */
+ HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC1], (uint32_t)pData, (uint32_t)&htim->Instance->CCR1, Length);
+
+ /* Enable the TIM Output Compare DMA request */
+ __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC1);
+ }
+ break;
+
+ case TIM_CHANNEL_2:
+ {
+ /* Set the DMA Period elapsed callback */
+ htim->hdma[TIM_DMA_ID_CC2]->XferCpltCallback = TIM_DMADelayPulseCplt;
+
+ /* Set the DMA error callback */
+ htim->hdma[TIM_DMA_ID_CC2]->XferErrorCallback = TIM_DMAError ;
+
+ /* Enable the DMA channel */
+ HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC2], (uint32_t)pData, (uint32_t)&htim->Instance->CCR2, Length);
+
+ /* Enable the TIM Output Compare DMA request */
+ __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC2);
+ }
+ break;
+
+ case TIM_CHANNEL_3:
+{
+ /* Set the DMA Period elapsed callback */
+ htim->hdma[TIM_DMA_ID_CC3]->XferCpltCallback = TIM_DMADelayPulseCplt;
+
+ /* Set the DMA error callback */
+ htim->hdma[TIM_DMA_ID_CC3]->XferErrorCallback = TIM_DMAError ;
+
+ /* Enable the DMA channel */
+ HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC3], (uint32_t)pData, (uint32_t)&htim->Instance->CCR3,Length);
+
+ /* Enable the TIM Output Compare DMA request */
+ __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC3);
+ }
+ break;
+
+ case TIM_CHANNEL_4:
+ {
+ /* Set the DMA Period elapsed callback */
+ htim->hdma[TIM_DMA_ID_CC4]->XferCpltCallback = TIM_DMADelayPulseCplt;
+
+ /* Set the DMA error callback */
+ htim->hdma[TIM_DMA_ID_CC4]->XferErrorCallback = TIM_DMAError ;
+
+ /* Enable the DMA channel */
+ HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC4], (uint32_t)pData, (uint32_t)&htim->Instance->CCR4, Length);
+
+ /* Enable the TIM Output Compare DMA request */
+ __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC4);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ /* Enable the Capture compare channel N */
+ TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_ENABLE);
+
+ /* Enable the Main Ouput */
+ __HAL_TIM_MOE_ENABLE(htim);
+
+ /* Enable the Peripheral */
+ __HAL_TIM_ENABLE(htim);
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Stops the TIM Output Compare signal generation in DMA mode
+ * on the complementary output.
+ * @param htim : TIM Output Compare handle
+ * @param Channel : TIM Channel to be disabled
+ * This parameter can be one of the following values:
+ * @arg TIM_CHANNEL_1: TIM Channel 1 selected
+ * @arg TIM_CHANNEL_2: TIM Channel 2 selected
+ * @arg TIM_CHANNEL_3: TIM Channel 3 selected
+ * @arg TIM_CHANNEL_4: TIM Channel 4 selected
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_TIMEx_OCN_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
+
+ switch (Channel)
+ {
+ case TIM_CHANNEL_1:
+ {
+ /* Disable the TIM Output Compare DMA request */
+ __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC1);
+ }
+ break;
+
+ case TIM_CHANNEL_2:
+ {
+ /* Disable the TIM Output Compare DMA request */
+ __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC2);
+ }
+ break;
+
+ case TIM_CHANNEL_3:
+ {
+ /* Disable the TIM Output Compare DMA request */
+ __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC3);
+ }
+ break;
+
+ case TIM_CHANNEL_4:
+ {
+ /* Disable the TIM Output Compare interrupt */
+ __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC4);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ /* Disable the Capture compare channel N */
+ TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_DISABLE);
+
+ /* Disable the Main Ouput */
+ __HAL_TIM_MOE_DISABLE(htim);
+
+ /* Disable the Peripheral */
+ __HAL_TIM_DISABLE(htim);
+
+ /* Change the htim state */
+ htim->State = HAL_TIM_STATE_READY;
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup TIMEx_Exported_Functions_Group3 Timer Complementary PWM functions
+ * @brief Timer Complementary PWM functions
+ *
+@verbatim
+ ==============================================================================
+ ##### Timer Complementary PWM functions #####
+ ==============================================================================
+ [..]
+ This section provides functions allowing to:
+ (+) Start the Complementary PWM.
+ (+) Stop the Complementary PWM.
+ (+) Start the Complementary PWM and enable interrupts.
+ (+) Stop the Complementary PWM and disable interrupts.
+ (+) Start the Complementary PWM and enable DMA transfers.
+ (+) Stop the Complementary PWM and disable DMA transfers.
+ (+) Start the Complementary Input Capture measurement.
+ (+) Stop the Complementary Input Capture.
+ (+) Start the Complementary Input Capture and enable interrupts.
+ (+) Stop the Complementary Input Capture and disable interrupts.
+ (+) Start the Complementary Input Capture and enable DMA transfers.
+ (+) Stop the Complementary Input Capture and disable DMA transfers.
+ (+) Start the Complementary One Pulse generation.
+ (+) Stop the Complementary One Pulse.
+ (+) Start the Complementary One Pulse and enable interrupts.
+ (+) Stop the Complementary One Pulse and disable interrupts.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Starts the PWM signal generation on the complementary output.
+ * @param htim : TIM handle
+ * @param Channel : TIM Channel to be enabled
+ * This parameter can be one of the following values:
+ * @arg TIM_CHANNEL_1: TIM Channel 1 selected
+ * @arg TIM_CHANNEL_2: TIM Channel 2 selected
+ * @arg TIM_CHANNEL_3: TIM Channel 3 selected
+ * @arg TIM_CHANNEL_4: TIM Channel 4 selected
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_TIMEx_PWMN_Start(TIM_HandleTypeDef *htim, uint32_t Channel)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
+
+ /* Enable the complementary PWM output */
+ TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_ENABLE);
+
+ /* Enable the Main Ouput */
+ __HAL_TIM_MOE_ENABLE(htim);
+
+ /* Enable the Peripheral */
+ __HAL_TIM_ENABLE(htim);
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Stops the PWM signal generation on the complementary output.
+ * @param htim : TIM handle
+ * @param Channel : TIM Channel to be disabled
+ * This parameter can be one of the following values:
+ * @arg TIM_CHANNEL_1: TIM Channel 1 selected
+ * @arg TIM_CHANNEL_2: TIM Channel 2 selected
+ * @arg TIM_CHANNEL_3: TIM Channel 3 selected
+ * @arg TIM_CHANNEL_4: TIM Channel 4 selected
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_TIMEx_PWMN_Stop(TIM_HandleTypeDef *htim, uint32_t Channel)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
+
+ /* Disable the complementary PWM output */
+ TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_DISABLE);
+
+ /* Disable the Main Ouput */
+ __HAL_TIM_MOE_DISABLE(htim);
+
+ /* Disable the Peripheral */
+ __HAL_TIM_DISABLE(htim);
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Starts the PWM signal generation in interrupt mode on the
+ * complementary output.
+ * @param htim : TIM handle
+ * @param Channel : TIM Channel to be disabled
+ * This parameter can be one of the following values:
+ * @arg TIM_CHANNEL_1: TIM Channel 1 selected
+ * @arg TIM_CHANNEL_2: TIM Channel 2 selected
+ * @arg TIM_CHANNEL_3: TIM Channel 3 selected
+ * @arg TIM_CHANNEL_4: TIM Channel 4 selected
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_TIMEx_PWMN_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
+
+ switch (Channel)
+ {
+ case TIM_CHANNEL_1:
+ {
+ /* Enable the TIM Capture/Compare 1 interrupt */
+ __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1);
+ }
+ break;
+
+ case TIM_CHANNEL_2:
+ {
+ /* Enable the TIM Capture/Compare 2 interrupt */
+ __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC2);
+ }
+ break;
+
+ case TIM_CHANNEL_3:
+ {
+ /* Enable the TIM Capture/Compare 3 interrupt */
+ __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC3);
+ }
+ break;
+
+ case TIM_CHANNEL_4:
+ {
+ /* Enable the TIM Capture/Compare 4 interrupt */
+ __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC4);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ /* Enable the TIM Break interrupt */
+ __HAL_TIM_ENABLE_IT(htim, TIM_IT_BREAK);
+
+ /* Enable the complementary PWM output */
+ TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_ENABLE);
+
+ /* Enable the Main Ouput */
+ __HAL_TIM_MOE_ENABLE(htim);
+
+ /* Enable the Peripheral */
+ __HAL_TIM_ENABLE(htim);
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Stops the PWM signal generation in interrupt mode on the
+ * complementary output.
+ * @param htim : TIM handle
+ * @param Channel : TIM Channel to be disabled
+ * This parameter can be one of the following values:
+ * @arg TIM_CHANNEL_1: TIM Channel 1 selected
+ * @arg TIM_CHANNEL_2: TIM Channel 2 selected
+ * @arg TIM_CHANNEL_3: TIM Channel 3 selected
+ * @arg TIM_CHANNEL_4: TIM Channel 4 selected
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_TIMEx_PWMN_Stop_IT (TIM_HandleTypeDef *htim, uint32_t Channel)
+{
+ uint32_t tmpccer = 0;
+
+ /* Check the parameters */
+ assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
+
+ switch (Channel)
+ {
+ case TIM_CHANNEL_1:
+ {
+ /* Disable the TIM Capture/Compare 1 interrupt */
+ __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1);
+ }
+ break;
+
+ case TIM_CHANNEL_2:
+ {
+ /* Disable the TIM Capture/Compare 2 interrupt */
+ __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC2);
+ }
+ break;
+
+ case TIM_CHANNEL_3:
+ {
+ /* Disable the TIM Capture/Compare 3 interrupt */
+ __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC3);
+ }
+ break;
+
+ case TIM_CHANNEL_4:
+ {
+ /* Disable the TIM Capture/Compare 3 interrupt */
+ __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC4);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ /* Disable the complementary PWM output */
+ TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_DISABLE);
+
+ /* Disable the TIM Break interrupt (only if no more channel is active) */
+ tmpccer = htim->Instance->CCER;
+ if ((tmpccer & (TIM_CCER_CC1NE | TIM_CCER_CC2NE | TIM_CCER_CC3NE)) == RESET)
+ {
+ __HAL_TIM_DISABLE_IT(htim, TIM_IT_BREAK);
+ }
+
+ /* Disable the Main Ouput */
+ __HAL_TIM_MOE_DISABLE(htim);
+
+ /* Disable the Peripheral */
+ __HAL_TIM_DISABLE(htim);
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Starts the TIM PWM signal generation in DMA mode on the
+ * complementary output
+ * @param htim : TIM handle
+ * @param Channel : TIM Channel to be enabled
+ * This parameter can be one of the following values:
+ * @arg TIM_CHANNEL_1: TIM Channel 1 selected
+ * @arg TIM_CHANNEL_2: TIM Channel 2 selected
+ * @arg TIM_CHANNEL_3: TIM Channel 3 selected
+ * @arg TIM_CHANNEL_4: TIM Channel 4 selected
+ * @param pData : The source Buffer address.
+ * @param Length : The length of data to be transferred from memory to TIM peripheral
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_TIMEx_PWMN_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, uint32_t *pData, uint16_t Length)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
+
+ if((htim->State == HAL_TIM_STATE_BUSY))
+ {
+ return HAL_BUSY;
+ }
+ else if((htim->State == HAL_TIM_STATE_READY))
+ {
+ if(((uint32_t)pData == 0 ) && (Length > 0))
+ {
+ return HAL_ERROR;
+ }
+ else
+ {
+ htim->State = HAL_TIM_STATE_BUSY;
+ }
+ }
+ switch (Channel)
+ {
+ case TIM_CHANNEL_1:
+ {
+ /* Set the DMA Period elapsed callback */
+ htim->hdma[TIM_DMA_ID_CC1]->XferCpltCallback = TIM_DMADelayPulseCplt;
+
+ /* Set the DMA error callback */
+ htim->hdma[TIM_DMA_ID_CC1]->XferErrorCallback = TIM_DMAError ;
+
+ /* Enable the DMA channel */
+ HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC1], (uint32_t)pData, (uint32_t)&htim->Instance->CCR1, Length);
+
+ /* Enable the TIM Capture/Compare 1 DMA request */
+ __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC1);
+ }
+ break;
+
+ case TIM_CHANNEL_2:
+ {
+ /* Set the DMA Period elapsed callback */
+ htim->hdma[TIM_DMA_ID_CC2]->XferCpltCallback = TIM_DMADelayPulseCplt;
+
+ /* Set the DMA error callback */
+ htim->hdma[TIM_DMA_ID_CC2]->XferErrorCallback = TIM_DMAError ;
+
+ /* Enable the DMA channel */
+ HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC2], (uint32_t)pData, (uint32_t)&htim->Instance->CCR2, Length);
+
+ /* Enable the TIM Capture/Compare 2 DMA request */
+ __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC2);
+ }
+ break;
+
+ case TIM_CHANNEL_3:
+ {
+ /* Set the DMA Period elapsed callback */
+ htim->hdma[TIM_DMA_ID_CC3]->XferCpltCallback = TIM_DMADelayPulseCplt;
+
+ /* Set the DMA error callback */
+ htim->hdma[TIM_DMA_ID_CC3]->XferErrorCallback = TIM_DMAError ;
+
+ /* Enable the DMA channel */
+ HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC3], (uint32_t)pData, (uint32_t)&htim->Instance->CCR3,Length);
+
+ /* Enable the TIM Capture/Compare 3 DMA request */
+ __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC3);
+ }
+ break;
+
+ case TIM_CHANNEL_4:
+ {
+ /* Set the DMA Period elapsed callback */
+ htim->hdma[TIM_DMA_ID_CC4]->XferCpltCallback = TIM_DMADelayPulseCplt;
+
+ /* Set the DMA error callback */
+ htim->hdma[TIM_DMA_ID_CC4]->XferErrorCallback = TIM_DMAError ;
+
+ /* Enable the DMA channel */
+ HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC4], (uint32_t)pData, (uint32_t)&htim->Instance->CCR4, Length);
+
+ /* Enable the TIM Capture/Compare 4 DMA request */
+ __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC4);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ /* Enable the complementary PWM output */
+ TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_ENABLE);
+
+ /* Enable the Main Ouput */
+ __HAL_TIM_MOE_ENABLE(htim);
+
+ /* Enable the Peripheral */
+ __HAL_TIM_ENABLE(htim);
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Stops the TIM PWM signal generation in DMA mode on the complementary
+ * output
+ * @param htim : TIM handle
+ * @param Channel : TIM Channel to be disabled
+ * This parameter can be one of the following values:
+ * @arg TIM_CHANNEL_1: TIM Channel 1 selected
+ * @arg TIM_CHANNEL_2: TIM Channel 2 selected
+ * @arg TIM_CHANNEL_3: TIM Channel 3 selected
+ * @arg TIM_CHANNEL_4: TIM Channel 4 selected
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_TIMEx_PWMN_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
+
+ switch (Channel)
+ {
+ case TIM_CHANNEL_1:
+ {
+ /* Disable the TIM Capture/Compare 1 DMA request */
+ __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC1);
+ }
+ break;
+
+ case TIM_CHANNEL_2:
+ {
+ /* Disable the TIM Capture/Compare 2 DMA request */
+ __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC2);
+ }
+ break;
+
+ case TIM_CHANNEL_3:
+ {
+ /* Disable the TIM Capture/Compare 3 DMA request */
+ __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC3);
+ }
+ break;
+
+ case TIM_CHANNEL_4:
+ {
+ /* Disable the TIM Capture/Compare 4 DMA request */
+ __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC4);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ /* Disable the complementary PWM output */
+ TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_DISABLE);
+
+ /* Disable the Main Ouput */
+ __HAL_TIM_MOE_DISABLE(htim);
+
+ /* Disable the Peripheral */
+ __HAL_TIM_DISABLE(htim);
+
+ /* Change the htim state */
+ htim->State = HAL_TIM_STATE_READY;
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup TIMEx_Exported_Functions_Group4 Timer Complementary One Pulse functions
+ * @brief Timer Complementary One Pulse functions
+ *
+@verbatim
+ ==============================================================================
+ ##### Timer Complementary One Pulse functions #####
+ ==============================================================================
+ [..]
+ This section provides functions allowing to:
+ (+) Start the Complementary One Pulse generation.
+ (+) Stop the Complementary One Pulse.
+ (+) Start the Complementary One Pulse and enable interrupts.
+ (+) Stop the Complementary One Pulse and disable interrupts.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Starts the TIM One Pulse signal generation on the complemetary
+ * output.
+ * @param htim : TIM One Pulse handle
+ * @param OutputChannel : TIM Channel to be enabled
+ * This parameter can be one of the following values:
+ * @arg TIM_CHANNEL_1: TIM Channel 1 selected
+ * @arg TIM_CHANNEL_2: TIM Channel 2 selected
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Start(TIM_HandleTypeDef *htim, uint32_t OutputChannel)
+ {
+ /* Check the parameters */
+ assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, OutputChannel));
+
+ /* Enable the complementary One Pulse output */
+ TIM_CCxNChannelCmd(htim->Instance, OutputChannel, TIM_CCxN_ENABLE);
+
+ /* Enable the Main Ouput */
+ __HAL_TIM_MOE_ENABLE(htim);
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Stops the TIM One Pulse signal generation on the complementary
+ * output.
+ * @param htim : TIM One Pulse handle
+ * @param OutputChannel : TIM Channel to be disabled
+ * This parameter can be one of the following values:
+ * @arg TIM_CHANNEL_1: TIM Channel 1 selected
+ * @arg TIM_CHANNEL_2: TIM Channel 2 selected
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Stop(TIM_HandleTypeDef *htim, uint32_t OutputChannel)
+{
+
+ /* Check the parameters */
+ assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, OutputChannel));
+
+ /* Disable the complementary One Pulse output */
+ TIM_CCxNChannelCmd(htim->Instance, OutputChannel, TIM_CCxN_DISABLE);
+
+ /* Disable the Main Ouput */
+ __HAL_TIM_MOE_DISABLE(htim);
+
+ /* Disable the Peripheral */
+ __HAL_TIM_DISABLE(htim);
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @brief Starts the TIM One Pulse signal generation in interrupt mode on the
+ * complementary channel.
+ * @param htim : TIM One Pulse handle
+ * @param OutputChannel : TIM Channel to be enabled
+ * This parameter can be one of the following values:
+ * @arg TIM_CHANNEL_1: TIM Channel 1 selected
+ * @arg TIM_CHANNEL_2: TIM Channel 2 selected
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Start_IT(TIM_HandleTypeDef *htim, uint32_t OutputChannel)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, OutputChannel));
+
+ /* Enable the TIM Capture/Compare 1 interrupt */
+ __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1);
+
+ /* Enable the TIM Capture/Compare 2 interrupt */
+ __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC2);
+
+ /* Enable the complementary One Pulse output */
+ TIM_CCxNChannelCmd(htim->Instance, OutputChannel, TIM_CCxN_ENABLE);
+
+ /* Enable the Main Ouput */
+ __HAL_TIM_MOE_ENABLE(htim);
+
+ /* Return function status */
+ return HAL_OK;
+ }
+
+/**
+ * @brief Stops the TIM One Pulse signal generation in interrupt mode on the
+ * complementary channel.
+ * @param htim : TIM One Pulse handle
+ * @param OutputChannel : TIM Channel to be disabled
+ * This parameter can be one of the following values:
+ * @arg TIM_CHANNEL_1: TIM Channel 1 selected
+ * @arg TIM_CHANNEL_2: TIM Channel 2 selected
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Stop_IT(TIM_HandleTypeDef *htim, uint32_t OutputChannel)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, OutputChannel));
+
+ /* Disable the TIM Capture/Compare 1 interrupt */
+ __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1);
+
+ /* Disable the TIM Capture/Compare 2 interrupt */
+ __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC2);
+
+ /* Disable the complementary One Pulse output */
+ TIM_CCxNChannelCmd(htim->Instance, OutputChannel, TIM_CCxN_DISABLE);
+
+ /* Disable the Main Ouput */
+ __HAL_TIM_MOE_DISABLE(htim);
+
+ /* Disable the Peripheral */
+ __HAL_TIM_DISABLE(htim);
+
+ /* Return function status */
+ return HAL_OK;
+}
+
+/**
+ * @}
+ */
+
+#endif /* defined(STM32F100xB) || defined(STM32F100xE) || */
+ /* defined(STM32F103x6) || defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG) || */
+ /* defined(STM32F105xC) || defined(STM32F107xC) */
+
+/** @defgroup TIMEx_Exported_Functions_Group5 Peripheral Control functions
+ * @brief Peripheral Control functions
+ *
+@verbatim
+ ==============================================================================
+ ##### Peripheral Control functions #####
+ ==============================================================================
+ [..]
+ This section provides functions allowing to:
+ (+) Configure the commutation event in case of use of the Hall sensor interface.
+ (+) Configure Complementary channels, break features and dead time.
+ (+) Configure Master synchronization.
+
+@endverbatim
+ * @{
+ */
+
+#if defined (STM32F100xB) || defined (STM32F100xE) || \
+ defined (STM32F103x6) || defined (STM32F103xB) || defined (STM32F103xE) || defined (STM32F103xG) || \
+ defined (STM32F105xC) || defined (STM32F107xC)
+
+/**
+ * @brief Configure the TIM commutation event sequence.
+ * @note: this function is mandatory to use the commutation event in order to
+ * update the configuration at each commutation detection on the TRGI input of the Timer,
+ * the typical use of this feature is with the use of another Timer(interface Timer)
+ * configured in Hall sensor interface, this interface Timer will generate the
+ * commutation at its TRGO output (connected to Timer used in this function) each time
+ * the TI1 of the Interface Timer detect a commutation at its input TI1.
+ * @param htim : TIM handle
+ * @param InputTrigger : the Internal trigger corresponding to the Timer Interfacing with the Hall sensor
+ * This parameter can be one of the following values:
+ * @arg TIM_TS_ITR0: Internal trigger 0 selected
+ * @arg TIM_TS_ITR1: Internal trigger 1 selected
+ * @arg TIM_TS_ITR2: Internal trigger 2 selected
+ * @arg TIM_TS_ITR3: Internal trigger 3 selected
+ * @arg TIM_TS_NONE: No trigger is needed
+ * @param CommutationSource : the Commutation Event source
+ * This parameter can be one of the following values:
+ * @arg TIM_COMMUTATION_TRGI: Commutation source is the TRGI of the Interface Timer
+ * @arg TIM_COMMUTATION_SOFTWARE: Commutation source is set by software using the COMG bit
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_TIMEx_ConfigCommutationEvent(TIM_HandleTypeDef *htim, uint32_t InputTrigger, uint32_t CommutationSource)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_COMMUTATION_EVENT_INSTANCE(htim->Instance));
+ assert_param(IS_TIM_INTERNAL_TRIGGEREVENT_SELECTION(InputTrigger));
+
+ __HAL_LOCK(htim);
+
+ if ((InputTrigger == TIM_TS_ITR0) || (InputTrigger == TIM_TS_ITR1) ||
+ (InputTrigger == TIM_TS_ITR2) || (InputTrigger == TIM_TS_ITR3))
+ {
+ /* Select the Input trigger */
+ htim->Instance->SMCR &= ~TIM_SMCR_TS;
+ htim->Instance->SMCR |= InputTrigger;
+ }
+
+ /* Select the Capture Compare preload feature */
+ htim->Instance->CR2 |= TIM_CR2_CCPC;
+ /* Select the Commutation event source */
+ htim->Instance->CR2 &= ~TIM_CR2_CCUS;
+ htim->Instance->CR2 |= CommutationSource;
+
+ __HAL_UNLOCK(htim);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Configure the TIM commutation event sequence with interrupt.
+ * @note: this function is mandatory to use the commutation event in order to
+ * update the configuration at each commutation detection on the TRGI input of the Timer,
+ * the typical use of this feature is with the use of another Timer(interface Timer)
+ * configured in Hall sensor interface, this interface Timer will generate the
+ * commutation at its TRGO output (connected to Timer used in this function) each time
+ * the TI1 of the Interface Timer detect a commutation at its input TI1.
+ * @param htim : TIM handle
+ * @param InputTrigger : the Internal trigger corresponding to the Timer Interfacing with the Hall sensor
+ * This parameter can be one of the following values:
+ * @arg TIM_TS_ITR0: Internal trigger 0 selected
+ * @arg TIM_TS_ITR1: Internal trigger 1 selected
+ * @arg TIM_TS_ITR2: Internal trigger 2 selected
+ * @arg TIM_TS_ITR3: Internal trigger 3 selected
+ * @arg TIM_TS_NONE: No trigger is needed
+ * @param CommutationSource : the Commutation Event source
+ * This parameter can be one of the following values:
+ * @arg TIM_COMMUTATION_TRGI: Commutation source is the TRGI of the Interface Timer
+ * @arg TIM_COMMUTATION_SOFTWARE: Commutation source is set by software using the COMG bit
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_TIMEx_ConfigCommutationEvent_IT(TIM_HandleTypeDef *htim, uint32_t InputTrigger, uint32_t CommutationSource)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_COMMUTATION_EVENT_INSTANCE(htim->Instance));
+ assert_param(IS_TIM_INTERNAL_TRIGGEREVENT_SELECTION(InputTrigger));
+
+ __HAL_LOCK(htim);
+
+ if ((InputTrigger == TIM_TS_ITR0) || (InputTrigger == TIM_TS_ITR1) ||
+ (InputTrigger == TIM_TS_ITR2) || (InputTrigger == TIM_TS_ITR3))
+ {
+ /* Select the Input trigger */
+ htim->Instance->SMCR &= ~TIM_SMCR_TS;
+ htim->Instance->SMCR |= InputTrigger;
+ }
+
+ /* Select the Capture Compare preload feature */
+ htim->Instance->CR2 |= TIM_CR2_CCPC;
+ /* Select the Commutation event source */
+ htim->Instance->CR2 &= ~TIM_CR2_CCUS;
+ htim->Instance->CR2 |= CommutationSource;
+
+ /* Enable the Commutation Interrupt Request */
+ __HAL_TIM_ENABLE_IT(htim, TIM_IT_COM);
+
+ __HAL_UNLOCK(htim);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Configure the TIM commutation event sequence with DMA.
+ * @note: this function is mandatory to use the commutation event in order to
+ * update the configuration at each commutation detection on the TRGI input of the Timer,
+ * the typical use of this feature is with the use of another Timer(interface Timer)
+ * configured in Hall sensor interface, this interface Timer will generate the
+ * commutation at its TRGO output (connected to Timer used in this function) each time
+ * the TI1 of the Interface Timer detect a commutation at its input TI1.
+ * @note: The user should configure the DMA in his own software, in This function only the COMDE bit is set
+ * @param htim : TIM handle
+ * @param InputTrigger : the Internal trigger corresponding to the Timer Interfacing with the Hall sensor
+ * This parameter can be one of the following values:
+ * @arg TIM_TS_ITR0: Internal trigger 0 selected
+ * @arg TIM_TS_ITR1: Internal trigger 1 selected
+ * @arg TIM_TS_ITR2: Internal trigger 2 selected
+ * @arg TIM_TS_ITR3: Internal trigger 3 selected
+ * @arg TIM_TS_NONE: No trigger is needed
+ * @param CommutationSource : the Commutation Event source
+ * This parameter can be one of the following values:
+ * @arg TIM_COMMUTATION_TRGI: Commutation source is the TRGI of the Interface Timer
+ * @arg TIM_COMMUTATION_SOFTWARE: Commutation source is set by software using the COMG bit
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_TIMEx_ConfigCommutationEvent_DMA(TIM_HandleTypeDef *htim, uint32_t InputTrigger, uint32_t CommutationSource)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_COMMUTATION_EVENT_INSTANCE(htim->Instance));
+ assert_param(IS_TIM_INTERNAL_TRIGGEREVENT_SELECTION(InputTrigger));
+
+ __HAL_LOCK(htim);
+
+ if ((InputTrigger == TIM_TS_ITR0) || (InputTrigger == TIM_TS_ITR1) ||
+ (InputTrigger == TIM_TS_ITR2) || (InputTrigger == TIM_TS_ITR3))
+ {
+ /* Select the Input trigger */
+ htim->Instance->SMCR &= ~TIM_SMCR_TS;
+ htim->Instance->SMCR |= InputTrigger;
+ }
+
+ /* Select the Capture Compare preload feature */
+ htim->Instance->CR2 |= TIM_CR2_CCPC;
+ /* Select the Commutation event source */
+ htim->Instance->CR2 &= ~TIM_CR2_CCUS;
+ htim->Instance->CR2 |= CommutationSource;
+
+ /* Enable the Commutation DMA Request */
+ /* Set the DMA Commutation Callback */
+ htim->hdma[TIM_DMA_ID_COMMUTATION]->XferCpltCallback = TIMEx_DMACommutationCplt;
+ /* Set the DMA error callback */
+ htim->hdma[TIM_DMA_ID_COMMUTATION]->XferErrorCallback = TIM_DMAError;
+
+ /* Enable the Commutation DMA Request */
+ __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_COM);
+
+ __HAL_UNLOCK(htim);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Configures the Break feature, dead time, Lock level, OSSI/OSSR State
+ * and the AOE(automatic output enable).
+ * @param htim : TIM handle
+ * @param sBreakDeadTimeConfig : pointer to a TIM_ConfigBreakDeadConfigTypeDef structure that
+ * contains the BDTR Register configuration information for the TIM peripheral.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_TIMEx_ConfigBreakDeadTime(TIM_HandleTypeDef *htim,
+ TIM_BreakDeadTimeConfigTypeDef *sBreakDeadTimeConfig)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_BREAK_INSTANCE(htim->Instance));
+ assert_param(IS_TIM_OSSR_STATE(sBreakDeadTimeConfig->OffStateRunMode));
+ assert_param(IS_TIM_OSSI_STATE(sBreakDeadTimeConfig->OffStateIDLEMode));
+ assert_param(IS_TIM_LOCK_LEVEL(sBreakDeadTimeConfig->LockLevel));
+ assert_param(IS_TIM_DEADTIME(sBreakDeadTimeConfig->DeadTime));
+ assert_param(IS_TIM_BREAK_STATE(sBreakDeadTimeConfig->BreakState));
+ assert_param(IS_TIM_BREAK_POLARITY(sBreakDeadTimeConfig->BreakPolarity));
+ assert_param(IS_TIM_AUTOMATIC_OUTPUT_STATE(sBreakDeadTimeConfig->AutomaticOutput));
+
+ /* Process Locked */
+ __HAL_LOCK(htim);
+
+ htim->State = HAL_TIM_STATE_BUSY;
+
+ /* Set the Lock level, the Break enable Bit and the Polarity, the OSSR State,
+ the OSSI State, the dead time value and the Automatic Output Enable Bit */
+ htim->Instance->BDTR = (uint32_t)sBreakDeadTimeConfig->OffStateRunMode |
+ sBreakDeadTimeConfig->OffStateIDLEMode |
+ sBreakDeadTimeConfig->LockLevel |
+ sBreakDeadTimeConfig->DeadTime |
+ sBreakDeadTimeConfig->BreakState |
+ sBreakDeadTimeConfig->BreakPolarity |
+ sBreakDeadTimeConfig->AutomaticOutput;
+
+
+ htim->State = HAL_TIM_STATE_READY;
+
+ __HAL_UNLOCK(htim);
+
+ return HAL_OK;
+}
+
+#endif /* defined(STM32F100xB) || defined(STM32F100xE) || */
+ /* defined(STM32F103x6) || defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG) || */
+ /* defined(STM32F105xC) || defined(STM32F107xC) */
+
+/**
+ * @brief Configures the TIM in master mode.
+ * @param htim : TIM handle.
+ * @param sMasterConfig : pointer to a TIM_MasterConfigTypeDef structure that
+ * contains the selected trigger output (TRGO) and the Master/Slave
+ * mode.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_TIMEx_MasterConfigSynchronization(TIM_HandleTypeDef *htim, TIM_MasterConfigTypeDef * sMasterConfig)
+{
+ /* Check the parameters */
+ assert_param(IS_TIM_MASTER_INSTANCE(htim->Instance));
+ assert_param(IS_TIM_TRGO_SOURCE(sMasterConfig->MasterOutputTrigger));
+ assert_param(IS_TIM_MSM_STATE(sMasterConfig->MasterSlaveMode));
+
+ __HAL_LOCK(htim);
+
+ htim->State = HAL_TIM_STATE_BUSY;
+
+ /* Reset the MMS Bits */
+ htim->Instance->CR2 &= ~TIM_CR2_MMS;
+ /* Select the TRGO source */
+ htim->Instance->CR2 |= sMasterConfig->MasterOutputTrigger;
+
+ /* Reset the MSM Bit */
+ htim->Instance->SMCR &= ~TIM_SMCR_MSM;
+ /* Set or Reset the MSM Bit */
+ htim->Instance->SMCR |= sMasterConfig->MasterSlaveMode;
+
+ htim->State = HAL_TIM_STATE_READY;
+
+ __HAL_UNLOCK(htim);
+
+ return HAL_OK;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup TIMEx_Exported_Functions_Group6 Extension Callbacks functions
+ * @brief Extension Callbacks functions
+ *
+@verbatim
+ ==============================================================================
+ ##### Extension Callbacks functions #####
+ ==============================================================================
+ [..]
+ This section provides Extension TIM callback functions:
+ (+) Timer Commutation callback
+ (+) Timer Break callback
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Hall commutation changed callback in non blocking mode
+ * @param htim : TIM handle
+ * @retval None
+ */
+__weak void HAL_TIMEx_CommutationCallback(TIM_HandleTypeDef *htim)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(htim);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_TIMEx_CommutationCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief Hall Break detection callback in non blocking mode
+ * @param htim : TIM handle
+ * @retval None
+ */
+__weak void HAL_TIMEx_BreakCallback(TIM_HandleTypeDef *htim)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(htim);
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_TIMEx_BreakCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief TIM DMA Commutation callback.
+ * @param hdma : pointer to DMA handle.
+ * @retval None
+ */
+void TIMEx_DMACommutationCplt(DMA_HandleTypeDef *hdma)
+{
+ TIM_HandleTypeDef* htim = ( TIM_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
+
+ htim->State= HAL_TIM_STATE_READY;
+
+ HAL_TIMEx_CommutationCallback(htim);
+}
+
+/**
+ * @}
+ */
+
+#if defined (STM32F100xB) || defined (STM32F100xE) || \
+ defined (STM32F103x6) || defined (STM32F103xB) || defined (STM32F103xE) || defined (STM32F103xG) || \
+ defined (STM32F105xC) || defined (STM32F107xC)
+
+/** @defgroup TIMEx_Exported_Functions_Group7 Extension Peripheral State functions
+ * @brief Extension Peripheral State functions
+ *
+@verbatim
+ ==============================================================================
+ ##### Extension Peripheral State functions #####
+ ==============================================================================
+ [..]
+ This subsection permit to get in run-time the status of the peripheral
+ and the data flow.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Return the TIM Hall Sensor interface state
+ * @param htim : TIM Hall Sensor handle
+ * @retval HAL state
+ */
+HAL_TIM_StateTypeDef HAL_TIMEx_HallSensor_GetState(TIM_HandleTypeDef *htim)
+{
+ return htim->State;
+}
+
+/**
+ * @}
+ */
+#endif /* defined(STM32F100xB) || defined(STM32F100xE) || */
+ /* defined(STM32F103x6) || defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG) || */
+ /* defined(STM32F105xC) || defined(STM32F107xC) */
+
+/**
+ * @}
+ */
+
+#if defined (STM32F100xB) || defined (STM32F100xE) || \
+ defined (STM32F103x6) || defined (STM32F103xB) || defined (STM32F103xE) || defined (STM32F103xG) || \
+ defined (STM32F105xC) || defined (STM32F107xC)
+
+/** @addtogroup TIMEx_Private_Functions
+ * @{
+ */
+
+/**
+ * @brief Enables or disables the TIM Capture Compare Channel xN.
+ * @param TIMx to select the TIM peripheral
+ * @param Channel : specifies the TIM Channel
+ * This parameter can be one of the following values:
+ * @arg TIM_Channel_1: TIM Channel 1
+ * @arg TIM_Channel_2: TIM Channel 2
+ * @arg TIM_Channel_3: TIM Channel 3
+ * @param ChannelNState : specifies the TIM Channel CCxNE bit new state.
+ * This parameter can be: TIM_CCxN_ENABLE or TIM_CCxN_Disable.
+ * @retval None
+ */
+static void TIM_CCxNChannelCmd(TIM_TypeDef* TIMx, uint32_t Channel, uint32_t ChannelNState)
+{
+ uint32_t tmp = 0;
+
+ tmp = TIM_CCER_CC1NE << Channel;
+
+ /* Reset the CCxNE Bit */
+ TIMx->CCER &= ~tmp;
+
+ /* Set or reset the CCxNE Bit */
+ TIMx->CCER |= (uint32_t)(ChannelNState << Channel);
+}
+
+/**
+ * @}
+ */
+
+#endif /* defined(STM32F100xB) || defined(STM32F100xE) || */
+ /* defined(STM32F103x6) || defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG) || */
+ /* defined(STM32F105xC) || defined(STM32F107xC) */
+
+#endif /* HAL_TIM_MODULE_ENABLED */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/bsp/radio-controller-1/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_uart.c b/bsp/radio-controller-1/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_uart.c
new file mode 100644
index 0000000..8f06df7
--- /dev/null
+++ b/bsp/radio-controller-1/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_uart.c
@@ -0,0 +1,1921 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_hal_uart.c
+ * @author MCD Application Team
+ * @version V1.0.4
+ * @date 29-April-2016
+ * @brief UART HAL module driver.
+ * This file provides firmware functions to manage the following
+ * functionalities of the Universal Asynchronous Receiver Transmitter (UART) peripheral:
+ * + Initialization and de-initialization functions
+ * + IO operation functions
+ * + Peripheral Control functions
+ * + Peripheral State and Errors functions
+ @verbatim
+ ==============================================================================
+ ##### How to use this driver #####
+ ==============================================================================
+ [..]
+ The UART HAL driver can be used as follows:
+
+ (#) Declare a UART_HandleTypeDef handle structure.
+
+ (#) Initialize the UART low level resources by implementing the HAL_UART_MspInit() API:
+ (##) Enable the USARTx interface clock.
+ (##) UART pins configuration:
+ (+++) Enable the clock for the UART GPIOs.
+ (+++) Configure the USART pins (TX as alternate function pull-up, RX as alternate function Input).
+ (##) NVIC configuration if you need to use interrupt process (HAL_UART_Transmit_IT()
+ and HAL_UART_Receive_IT() APIs):
+ (+++) Configure the USARTx interrupt priority.
+ (+++) Enable the NVIC USART IRQ handle.
+ (##) DMA Configuration if you need to use DMA process (HAL_UART_Transmit_DMA()
+ and HAL_UART_Receive_DMA() APIs):
+ (+++) Declare a DMA handle structure for the Tx/Rx channel.
+ (+++) Enable the DMAx interface clock.
+ (+++) Configure the declared DMA handle structure with the required
+ Tx/Rx parameters.
+ (+++) Configure the DMA Tx/Rx channel.
+ (+++) Associate the initialized DMA handle to the UART DMA Tx/Rx handle.
+ (+++) Configure the priority and enable the NVIC for the transfer complete
+ interrupt on the DMA Tx/Rx channel.
+ (+++) Configure the USARTx interrupt priority and enable the NVIC USART IRQ handle
+ (used for last byte sending completion detection in DMA non circular mode)
+
+ (#) Program the Baud Rate, Word Length, Stop Bit, Parity, Hardware
+ flow control and Mode(Receiver/Transmitter) in the huart Init structure.
+
+ (#) For the UART asynchronous mode, initialize the UART registers by calling
+ the HAL_UART_Init() API.
+
+ (#) For the UART Half duplex mode, initialize the UART registers by calling
+ the HAL_HalfDuplex_Init() API.
+
+ (#) For the LIN mode, initialize the UART registers by calling the HAL_LIN_Init() API.
+
+ (#) For the Multi-Processor mode, initialize the UART registers by calling
+ the HAL_MultiProcessor_Init() API.
+
+ [..]
+ (@) The specific UART interrupts (Transmission complete interrupt,
+ RXNE interrupt and Error Interrupts) will be managed using the macros
+ __HAL_UART_ENABLE_IT() and __HAL_UART_DISABLE_IT() inside the transmit
+ and receive process.
+
+ [..]
+ (@) These APIs (HAL_UART_Init() and HAL_HalfDuplex_Init()) configure also the
+ low level Hardware GPIO, CLOCK, CORTEX...etc) by calling the customed
+ HAL_UART_MspInit() API.
+
+ [..]
+ Three operation modes are available within this driver :
+
+ *** Polling mode IO operation ***
+ =================================
+ [..]
+ (+) Send an amount of data in blocking mode using HAL_UART_Transmit()
+ (+) Receive an amount of data in blocking mode using HAL_UART_Receive()
+
+ *** Interrupt mode IO operation ***
+ ===================================
+ [..]
+ (+) Send an amount of data in non blocking mode using HAL_UART_Transmit_IT()
+ (+) At transmission end of transfer HAL_UART_TxCpltCallback is executed and user can
+ add his own code by customization of function pointer HAL_UART_TxCpltCallback
+ (+) Receive an amount of data in non blocking mode using HAL_UART_Receive_IT()
+ (+) At reception end of transfer HAL_UART_RxCpltCallback is executed and user can
+ add his own code by customization of function pointer HAL_UART_RxCpltCallback
+ (+) In case of transfer Error, HAL_UART_ErrorCallback() function is executed and user can
+ add his own code by customization of function pointer HAL_UART_ErrorCallback
+
+ *** DMA mode IO operation ***
+ ==============================
+ [..]
+ (+) Send an amount of data in non blocking mode (DMA) using HAL_UART_Transmit_DMA()
+ (+) At transmission end of half transfer HAL_UART_TxHalfCpltCallback is executed and user can
+ add his own code by customization of function pointer HAL_UART_TxHalfCpltCallback
+ (+) At transmission end of transfer HAL_UART_TxCpltCallback is executed and user can
+ add his own code by customization of function pointer HAL_UART_TxCpltCallback
+ (+) Receive an amount of data in non blocking mode (DMA) using HAL_UART_Receive_DMA()
+ (+) At reception end of half transfer HAL_UART_RxHalfCpltCallback is executed and user can
+ add his own code by customization of function pointer HAL_UART_RxHalfCpltCallback
+ (+) At reception end of transfer HAL_UART_RxCpltCallback is executed and user can
+ add his own code by customization of function pointer HAL_UART_RxCpltCallback
+ (+) In case of transfer Error, HAL_UART_ErrorCallback() function is executed and user can
+ add his own code by customization of function pointer HAL_UART_ErrorCallback
+ (+) Pause the DMA Transfer using HAL_UART_DMAPause()
+ (+) Resume the DMA Transfer using HAL_UART_DMAResume()
+ (+) Stop the DMA Transfer using HAL_UART_DMAStop()
+
+ *** UART HAL driver macros list ***
+ =============================================
+ [..]
+ Below the list of most used macros in UART HAL driver.
+
+ (+) __HAL_UART_ENABLE: Enable the UART peripheral
+ (+) __HAL_UART_DISABLE: Disable the UART peripheral
+ (+) __HAL_UART_GET_FLAG : Check whether the specified UART flag is set or not
+ (+) __HAL_UART_CLEAR_FLAG : Clear the specified UART pending flag
+ (+) __HAL_UART_ENABLE_IT: Enable the specified UART interrupt
+ (+) __HAL_UART_DISABLE_IT: Disable the specified UART interrupt
+ (+) __HAL_UART_GET_IT_SOURCE: Check whether the specified UART interrupt has occurred or not
+
+ [..]
+ (@) You can refer to the UART HAL driver header file for more useful macros
+
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+/** @defgroup UART UART
+ * @brief HAL UART module driver
+ * @{
+ */
+#ifdef HAL_UART_MODULE_ENABLED
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macros ------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/** @addtogroup UART_Private_Functions UART Private Functions
+ * @{
+ */
+static void UART_SetConfig (UART_HandleTypeDef *huart);
+static HAL_StatusTypeDef UART_Transmit_IT(UART_HandleTypeDef *huart);
+static HAL_StatusTypeDef UART_EndTransmit_IT(UART_HandleTypeDef *huart);
+static HAL_StatusTypeDef UART_Receive_IT(UART_HandleTypeDef *huart);
+static void UART_DMATransmitCplt(DMA_HandleTypeDef *hdma);
+static void UART_DMATxHalfCplt(DMA_HandleTypeDef *hdma);
+static void UART_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
+static void UART_DMARxHalfCplt(DMA_HandleTypeDef *hdma);
+static void UART_DMAError(DMA_HandleTypeDef *hdma);
+static HAL_StatusTypeDef UART_WaitOnFlagUntilTimeout(UART_HandleTypeDef *huart, uint32_t Flag, FlagStatus Status, uint32_t Timeout);
+/**
+ * @}
+ */
+
+/* Exported functions ---------------------------------------------------------*/
+
+/** @defgroup UART_Exported_Functions UART Exported Functions
+ * @{
+ */
+
+/** @defgroup UART_Exported_Functions_Group1 Initialization and de-initialization functions
+ * @brief Initialization and Configuration functions
+ *
+@verbatim
+===============================================================================
+ ##### Initialization and Configuration functions #####
+ ===============================================================================
+ [..]
+ This subsection provides a set of functions allowing to initialize the USARTx or the UARTy
+ in asynchronous mode.
+ (+) For the asynchronous mode only these parameters can be configured:
+ (++) Baud Rate
+ (++) Word Length
+ (++) Stop Bit
+ (++) Parity
+ (++) Hardware flow control
+ (++) Receiver/transmitter modes
+ [..]
+ The HAL_UART_Init(), HAL_HalfDuplex_Init(), HAL_LIN_Init() and HAL_MultiProcessor_Init() APIs
+ follow respectively the UART asynchronous, UART Half duplex, LIN and Multi-Processor
+ configuration procedures (details for the procedures are available in reference manuals
+ (RM0008 for STM32F10Xxx MCUs and RM0041 for STM32F100xx MCUs)).
+
+
+@endverbatim
+ * @{
+ */
+
+/*
+ Additionnal remark: 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 UART frame formats are as listed in the following table:
+ +-------------------------------------------------------------+
+ | M bit | PCE bit | UART 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 | |
+ +-------------------------------------------------------------+
+*/
+
+/**
+ * @brief Initializes the UART mode according to the specified parameters in
+ * the UART_InitTypeDef and create the associated handle.
+ * @param huart: Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef *huart)
+{
+ /* Check the UART handle allocation */
+ if(huart == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check the parameters */
+ if(huart->Init.HwFlowCtl != UART_HWCONTROL_NONE)
+ {
+ /* The hardware flow control is available only for USART1, USART2, USART3 */
+ assert_param(IS_UART_HWFLOW_INSTANCE(huart->Instance));
+ assert_param(IS_UART_HARDWARE_FLOW_CONTROL(huart->Init.HwFlowCtl));
+ }
+ else
+ {
+ assert_param(IS_UART_INSTANCE(huart->Instance));
+ }
+ assert_param(IS_UART_WORD_LENGTH(huart->Init.WordLength));
+ assert_param(IS_UART_OVERSAMPLING(huart->Init.OverSampling));
+
+ if(huart->State == HAL_UART_STATE_RESET)
+ {
+ /* Allocate lock resource and initialize it */
+ huart->Lock = HAL_UNLOCKED;
+
+ /* Init the low level hardware */
+ HAL_UART_MspInit(huart);
+ }
+
+ huart->State = HAL_UART_STATE_BUSY;
+
+ /* Disable the peripheral */
+ __HAL_UART_DISABLE(huart);
+
+ /* Set the UART Communication parameters */
+ UART_SetConfig(huart);
+
+ /* In asynchronous mode, the following bits must be kept cleared:
+ - LINEN and CLKEN bits in the USART_CR2 register,
+ - SCEN, HDSEL and IREN bits in the USART_CR3 register.*/
+ CLEAR_BIT(huart->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN));
+ CLEAR_BIT(huart->Instance->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN));
+
+ /* Enable the peripheral */
+ __HAL_UART_ENABLE(huart);
+
+ /* Initialize the UART state */
+ huart->ErrorCode = HAL_UART_ERROR_NONE;
+ huart->State= HAL_UART_STATE_READY;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Initializes the half-duplex mode according to the specified
+ * parameters in the UART_InitTypeDef and create the associated handle.
+ * @param huart: Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_HalfDuplex_Init(UART_HandleTypeDef *huart)
+{
+ /* Check the UART handle allocation */
+ if(huart == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check UART instance */
+ assert_param(IS_UART_HALFDUPLEX_INSTANCE(huart->Instance));
+ assert_param(IS_UART_WORD_LENGTH(huart->Init.WordLength));
+ assert_param(IS_UART_OVERSAMPLING(huart->Init.OverSampling));
+
+ if(huart->State == HAL_UART_STATE_RESET)
+ {
+ /* Allocate lock resource and initialize it */
+ huart->Lock = HAL_UNLOCKED;
+
+ /* Init the low level hardware */
+ HAL_UART_MspInit(huart);
+ }
+
+ huart->State = HAL_UART_STATE_BUSY;
+
+ /* Disable the peripheral */
+ __HAL_UART_DISABLE(huart);
+
+ /* Set the UART Communication parameters */
+ UART_SetConfig(huart);
+
+ /* 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.*/
+ CLEAR_BIT(huart->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN));
+ CLEAR_BIT(huart->Instance->CR3, (USART_CR3_IREN | USART_CR3_SCEN));
+
+ /* Enable the Half-Duplex mode by setting the HDSEL bit in the CR3 register */
+ SET_BIT(huart->Instance->CR3, USART_CR3_HDSEL);
+
+ /* Enable the peripheral */
+ __HAL_UART_ENABLE(huart);
+
+ /* Initialize the UART state*/
+ huart->ErrorCode = HAL_UART_ERROR_NONE;
+ huart->State= HAL_UART_STATE_READY;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Initializes the LIN mode according to the specified
+ * parameters in the UART_InitTypeDef and create the associated handle.
+ * @param huart: Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @param BreakDetectLength: Specifies the LIN break detection length.
+ * This parameter can be one of the following values:
+ * @arg UART_LINBREAKDETECTLENGTH_10B: 10-bit break detection
+ * @arg UART_LINBREAKDETECTLENGTH_11B: 11-bit break detection
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_LIN_Init(UART_HandleTypeDef *huart, uint32_t BreakDetectLength)
+{
+ /* Check the UART handle allocation */
+ if(huart == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check the LIN UART instance */
+ assert_param(IS_UART_LIN_INSTANCE(huart->Instance));
+ /* Check the Break detection length parameter */
+ assert_param(IS_UART_LIN_BREAK_DETECT_LENGTH(BreakDetectLength));
+ assert_param(IS_UART_LIN_WORD_LENGTH(huart->Init.WordLength));
+ assert_param(IS_UART_LIN_OVERSAMPLING(huart->Init.OverSampling));
+
+ if(huart->State == HAL_UART_STATE_RESET)
+ {
+ /* Allocate lock resource and initialize it */
+ huart->Lock = HAL_UNLOCKED;
+
+ /* Init the low level hardware */
+ HAL_UART_MspInit(huart);
+ }
+
+ huart->State = HAL_UART_STATE_BUSY;
+
+ /* Disable the peripheral */
+ __HAL_UART_DISABLE(huart);
+
+ /* Set the UART Communication parameters */
+ UART_SetConfig(huart);
+
+ /* In LIN mode, the following bits must be kept cleared:
+ - CLKEN bits in the USART_CR2 register,
+ - SCEN and IREN bits in the USART_CR3 register.*/
+ CLEAR_BIT(huart->Instance->CR2, USART_CR2_CLKEN);
+ CLEAR_BIT(huart->Instance->CR3, (USART_CR3_HDSEL | USART_CR3_IREN | USART_CR3_SCEN));
+
+ /* Enable the LIN mode by setting the LINEN bit in the CR2 register */
+ SET_BIT(huart->Instance->CR2, USART_CR2_LINEN);
+
+ /* Set the USART LIN Break detection length. */
+ MODIFY_REG(huart->Instance->CR2, USART_CR2_LBDL, BreakDetectLength);
+
+ /* Enable the peripheral */
+ __HAL_UART_ENABLE(huart);
+
+ /* Initialize the UART state*/
+ huart->ErrorCode = HAL_UART_ERROR_NONE;
+ huart->State= HAL_UART_STATE_READY;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Initializes the Multi-Processor mode according to the specified
+ * parameters in the UART_InitTypeDef and create the associated handle.
+ * @param huart: Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @param Address: UART node address
+ * @param WakeUpMethod: specifies the UART wakeup method.
+ * This parameter can be one of the following values:
+ * @arg UART_WAKEUPMETHOD_IDLELINE: Wakeup by an idle line detection
+ * @arg UART_WAKEUPMETHOD_ADDRESSMARK: Wakeup by an address mark
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_MultiProcessor_Init(UART_HandleTypeDef *huart, uint8_t Address, uint32_t WakeUpMethod)
+{
+ /* Check the UART handle allocation */
+ if(huart == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check UART instance capabilities */
+ assert_param(IS_UART_MULTIPROCESSOR_INSTANCE(huart->Instance));
+
+ /* Check the Address & wake up method parameters */
+ assert_param(IS_UART_WAKEUPMETHOD(WakeUpMethod));
+ assert_param(IS_UART_ADDRESS(Address));
+ assert_param(IS_UART_WORD_LENGTH(huart->Init.WordLength));
+ assert_param(IS_UART_OVERSAMPLING(huart->Init.OverSampling));
+
+ if(huart->State == HAL_UART_STATE_RESET)
+ {
+ /* Allocate lock resource and initialize it */
+ huart->Lock = HAL_UNLOCKED;
+
+ /* Init the low level hardware */
+ HAL_UART_MspInit(huart);
+ }
+
+ huart->State = HAL_UART_STATE_BUSY;
+
+ /* Disable the peripheral */
+ __HAL_UART_DISABLE(huart);
+
+ /* Set the UART Communication parameters */
+ UART_SetConfig(huart);
+
+ /* In Multi-Processor mode, the following bits must be kept cleared:
+ - LINEN and CLKEN bits in the USART_CR2 register,
+ - SCEN, HDSEL and IREN bits in the USART_CR3 register */
+ CLEAR_BIT(huart->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN));
+ CLEAR_BIT(huart->Instance->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN));
+
+ /* Set the USART address node */
+ MODIFY_REG(huart->Instance->CR2, USART_CR2_ADD, Address);
+
+ /* Set the wake up method by setting the WAKE bit in the CR1 register */
+ MODIFY_REG(huart->Instance->CR1, USART_CR1_WAKE, WakeUpMethod);
+
+ /* Enable the peripheral */
+ __HAL_UART_ENABLE(huart);
+
+ /* Initialize the UART state */
+ huart->ErrorCode = HAL_UART_ERROR_NONE;
+ huart->State= HAL_UART_STATE_READY;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief DeInitializes the UART peripheral.
+ * @param huart: Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_UART_DeInit(UART_HandleTypeDef *huart)
+{
+ /* Check the UART handle allocation */
+ if(huart == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check the parameters */
+ assert_param(IS_UART_INSTANCE(huart->Instance));
+
+ huart->State = HAL_UART_STATE_BUSY;
+
+ /* Disable the Peripheral */
+ __HAL_UART_DISABLE(huart);
+
+ huart->Instance->CR1 = 0x0;
+ huart->Instance->CR2 = 0x0;
+ huart->Instance->CR3 = 0x0;
+
+ /* DeInit the low level hardware */
+ HAL_UART_MspDeInit(huart);
+
+ huart->ErrorCode = HAL_UART_ERROR_NONE;
+ huart->State = HAL_UART_STATE_RESET;
+
+ /* Process Unlock */
+ __HAL_UNLOCK(huart);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief UART MSP Init.
+ * @param huart: Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval None
+ */
+ __weak void HAL_UART_MspInit(UART_HandleTypeDef *huart)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(huart);
+ /* NOTE: This function should not be modified, when the callback is needed,
+ the HAL_UART_MspInit can be implemented in the user file
+ */
+}
+
+/**
+ * @brief UART MSP DeInit.
+ * @param huart: Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval None
+ */
+ __weak void HAL_UART_MspDeInit(UART_HandleTypeDef *huart)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(huart);
+ /* NOTE: This function should not be modified, when the callback is needed,
+ the HAL_UART_MspDeInit can be implemented in the user file
+ */
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup UART_Exported_Functions_Group2 IO operation functions
+ * @brief UART Transmit and Receive functions
+ *
+@verbatim
+ ==============================================================================
+ ##### IO operation functions #####
+ ==============================================================================
+ [..]
+ This subsection provides a set of functions allowing to manage the UART asynchronous
+ and Half duplex data transfers.
+
+ (#) There are two modes of transfer:
+ (++) Blocking mode: The communication is performed in polling mode.
+ The HAL status of all data processing is returned by the same function
+ after finishing transfer.
+ (++) Non blocking mode: The communication is performed using Interrupts
+ or DMA, these APIs return the HAL status.
+ The end of the data processing will be indicated through the
+ dedicated UART IRQ when using Interrupt mode or the DMA IRQ when
+ using DMA mode.
+ The HAL_UART_TxCpltCallback(), HAL_UART_RxCpltCallback() user callbacks
+ will be executed respectively at the end of the transmit or receive process.
+ The HAL_UART_ErrorCallback() user callback will be executed when
+ a communication error is detected.
+
+ (#) Blocking mode APIs are:
+ (++) HAL_UART_Transmit()
+ (++) HAL_UART_Receive()
+
+ (#) Non Blocking mode APIs with Interrupt are:
+ (++) HAL_UART_Transmit_IT()
+ (++) HAL_UART_Receive_IT()
+ (++) HAL_UART_IRQHandler()
+
+ (#) Non Blocking mode functions with DMA are:
+ (++) HAL_UART_Transmit_DMA()
+ (++) HAL_UART_Receive_DMA()
+ (++) HAL_UART_DMAPause()
+ (++) HAL_UART_DMAResume()
+ (++) HAL_UART_DMAStop()
+
+ (#) A set of Transfer Complete Callbacks are provided in non blocking mode:
+ (++) HAL_UART_TxHalfCpltCallback()
+ (++) HAL_UART_TxCpltCallback()
+ (++) HAL_UART_RxHalfCpltCallback()
+ (++) HAL_UART_RxCpltCallback()
+ (++) HAL_UART_ErrorCallback()
+
+ [..]
+ (@) In the Half duplex communication, it is forbidden to run the transmit
+ and receive process in parallel, the UART state HAL_UART_STATE_BUSY_TX_RX
+ can't be useful.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Sends an amount of data in blocking mode.
+ * @param huart: Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @param pData: Pointer to data buffer
+ * @param Size: Amount of data to be sent
+ * @param Timeout: Timeout duration
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)
+{
+ uint16_t* tmp;
+ uint32_t tmp_state = 0;
+
+ tmp_state = huart->State;
+ if((tmp_state == HAL_UART_STATE_READY) || (tmp_state == HAL_UART_STATE_BUSY_RX))
+ {
+ if((pData == NULL) || (Size == 0))
+ {
+ return HAL_ERROR;
+ }
+
+ /* Process Locked */
+ __HAL_LOCK(huart);
+
+ huart->ErrorCode = HAL_UART_ERROR_NONE;
+ /* Check if a non-blocking receive process is ongoing or not */
+ if(huart->State == HAL_UART_STATE_BUSY_RX)
+ {
+ huart->State = HAL_UART_STATE_BUSY_TX_RX;
+ }
+ else
+ {
+ huart->State = HAL_UART_STATE_BUSY_TX;
+ }
+
+ huart->TxXferSize = Size;
+ huart->TxXferCount = Size;
+ while(huart->TxXferCount > 0)
+ {
+ huart->TxXferCount--;
+ if(huart->Init.WordLength == UART_WORDLENGTH_9B)
+ {
+ if(UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TXE, RESET, Timeout) != HAL_OK)
+ {
+ return HAL_TIMEOUT;
+ }
+ tmp = (uint16_t*) pData;
+ huart->Instance->DR = (*tmp & (uint16_t)0x01FF);
+ if(huart->Init.Parity == UART_PARITY_NONE)
+ {
+ pData +=2;
+ }
+ else
+ {
+ pData +=1;
+ }
+ }
+ else
+ {
+ if(UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TXE, RESET, Timeout) != HAL_OK)
+ {
+ return HAL_TIMEOUT;
+ }
+ huart->Instance->DR = (*pData++ & (uint8_t)0xFF);
+ }
+ }
+
+ if(UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TC, RESET, Timeout) != HAL_OK)
+ {
+ return HAL_TIMEOUT;
+ }
+
+ /* Check if a non-blocking receive process is ongoing or not */
+ if(huart->State == HAL_UART_STATE_BUSY_TX_RX)
+ {
+ huart->State = HAL_UART_STATE_BUSY_RX;
+ }
+ else
+ {
+ huart->State = HAL_UART_STATE_READY;
+ }
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(huart);
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Receives an amount of data in blocking mode.
+ * @param huart: Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @param pData: Pointer to data buffer
+ * @param Size: Amount of data to be received
+ * @param Timeout: Timeout duration
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)
+{
+ uint16_t* tmp;
+ uint32_t tmp_state = 0;
+
+ tmp_state = huart->State;
+ if((tmp_state == HAL_UART_STATE_READY) || (tmp_state == HAL_UART_STATE_BUSY_TX))
+ {
+ if((pData == NULL ) || (Size == 0))
+ {
+ return HAL_ERROR;
+ }
+
+ /* Process Locked */
+ __HAL_LOCK(huart);
+
+ huart->ErrorCode = HAL_UART_ERROR_NONE;
+ /* Check if a non-blocking transmit process is ongoing or not */
+ if(huart->State == HAL_UART_STATE_BUSY_TX)
+ {
+ huart->State = HAL_UART_STATE_BUSY_TX_RX;
+ }
+ else
+ {
+ huart->State = HAL_UART_STATE_BUSY_RX;
+ }
+
+ huart->RxXferSize = Size;
+ huart->RxXferCount = Size;
+
+ /* Check the remain data to be received */
+ while(huart->RxXferCount > 0)
+ {
+ huart->RxXferCount--;
+ if(huart->Init.WordLength == UART_WORDLENGTH_9B)
+ {
+ if(UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_RXNE, RESET, Timeout) != HAL_OK)
+ {
+ return HAL_TIMEOUT;
+ }
+ tmp = (uint16_t*) pData ;
+ if(huart->Init.Parity == UART_PARITY_NONE)
+ {
+ *tmp = (uint16_t)(huart->Instance->DR & (uint16_t)0x01FF);
+ pData +=2;
+ }
+ else
+ {
+ *tmp = (uint16_t)(huart->Instance->DR & (uint16_t)0x00FF);
+ pData +=1;
+ }
+
+ }
+ else
+ {
+ if(UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_RXNE, RESET, Timeout) != HAL_OK)
+ {
+ return HAL_TIMEOUT;
+ }
+ if(huart->Init.Parity == UART_PARITY_NONE)
+ {
+ *pData++ = (uint8_t)(huart->Instance->DR & (uint8_t)0x00FF);
+ }
+ else
+ {
+ *pData++ = (uint8_t)(huart->Instance->DR & (uint8_t)0x007F);
+ }
+
+ }
+ }
+
+ /* Check if a non-blocking transmit process is ongoing or not */
+ if(huart->State == HAL_UART_STATE_BUSY_TX_RX)
+ {
+ huart->State = HAL_UART_STATE_BUSY_TX;
+ }
+ else
+ {
+ huart->State = HAL_UART_STATE_READY;
+ }
+ /* Process Unlocked */
+ __HAL_UNLOCK(huart);
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Sends an amount of data in non blocking mode.
+ * @param huart: Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @param pData: Pointer to data buffer
+ * @param Size: Amount of data to be sent
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
+{
+ uint32_t tmp_state = 0;
+
+ tmp_state = huart->State;
+ if((tmp_state == HAL_UART_STATE_READY) || (tmp_state == HAL_UART_STATE_BUSY_RX))
+ {
+ if((pData == NULL ) || (Size == 0))
+ {
+ return HAL_ERROR;
+ }
+
+ /* Process Locked */
+ __HAL_LOCK(huart);
+
+ huart->pTxBuffPtr = pData;
+ huart->TxXferSize = Size;
+ huart->TxXferCount = Size;
+
+ huart->ErrorCode = HAL_UART_ERROR_NONE;
+ /* Check if a receive process is ongoing or not */
+ if(huart->State == HAL_UART_STATE_BUSY_RX)
+ {
+ huart->State = HAL_UART_STATE_BUSY_TX_RX;
+ }
+ else
+ {
+ huart->State = HAL_UART_STATE_BUSY_TX;
+ }
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(huart);
+
+ /* Enable the UART Transmit data register empty Interrupt */
+ __HAL_UART_ENABLE_IT(huart, UART_IT_TXE);
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Receives an amount of data in non blocking mode
+ * @param huart: Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @param pData: Pointer to data buffer
+ * @param Size: Amount of data to be received
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
+{
+ uint32_t tmp_state = 0;
+
+ tmp_state = huart->State;
+ if((tmp_state == HAL_UART_STATE_READY) || (tmp_state == HAL_UART_STATE_BUSY_TX))
+ {
+ if((pData == NULL ) || (Size == 0))
+ {
+ return HAL_ERROR;
+ }
+
+ /* Process Locked */
+ __HAL_LOCK(huart);
+
+ huart->pRxBuffPtr = pData;
+ huart->RxXferSize = Size;
+ huart->RxXferCount = Size;
+
+ huart->ErrorCode = HAL_UART_ERROR_NONE;
+ /* Check if a transmit process is ongoing or not */
+ if(huart->State == HAL_UART_STATE_BUSY_TX)
+ {
+ huart->State = HAL_UART_STATE_BUSY_TX_RX;
+ }
+ else
+ {
+ huart->State = HAL_UART_STATE_BUSY_RX;
+ }
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(huart);
+
+ /* Enable the UART Parity Error Interrupt */
+ __HAL_UART_ENABLE_IT(huart, UART_IT_PE);
+
+ /* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */
+ __HAL_UART_ENABLE_IT(huart, UART_IT_ERR);
+
+ /* Enable the UART Data Register not empty Interrupt */
+ __HAL_UART_ENABLE_IT(huart, UART_IT_RXNE);
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Sends an amount of data in non blocking mode.
+ * @param huart: Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @param pData: Pointer to data buffer
+ * @param Size: Amount of data to be sent
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
+{
+ uint32_t *tmp;
+ uint32_t tmp_state = 0;
+
+ tmp_state = huart->State;
+ if((tmp_state == HAL_UART_STATE_READY) || (tmp_state == HAL_UART_STATE_BUSY_RX))
+ {
+ if((pData == NULL ) || (Size == 0))
+ {
+ return HAL_ERROR;
+ }
+
+ /* Process Locked */
+ __HAL_LOCK(huart);
+
+ huart->pTxBuffPtr = pData;
+ huart->TxXferSize = Size;
+ huart->TxXferCount = Size;
+
+ huart->ErrorCode = HAL_UART_ERROR_NONE;
+ /* Check if a receive process is ongoing or not */
+ if(huart->State == HAL_UART_STATE_BUSY_RX)
+ {
+ huart->State = HAL_UART_STATE_BUSY_TX_RX;
+ }
+ else
+ {
+ huart->State = HAL_UART_STATE_BUSY_TX;
+ }
+
+ /* Set the UART DMA transfer complete callback */
+ huart->hdmatx->XferCpltCallback = UART_DMATransmitCplt;
+
+ /* Set the UART DMA Half transfer complete callback */
+ huart->hdmatx->XferHalfCpltCallback = UART_DMATxHalfCplt;
+
+ /* Set the DMA error callback */
+ huart->hdmatx->XferErrorCallback = UART_DMAError;
+
+ /* Enable the UART transmit DMA channel */
+ tmp = (uint32_t*)&pData;
+ HAL_DMA_Start_IT(huart->hdmatx, *(uint32_t*)tmp, (uint32_t)&huart->Instance->DR, Size);
+
+ /* Clear the TC flag in the SR register by writing 0 to it */
+ __HAL_UART_CLEAR_FLAG(huart, UART_FLAG_TC);
+
+ /* Enable the DMA transfer for transmit request by setting the DMAT bit
+ in the UART CR3 register */
+ SET_BIT(huart->Instance->CR3, USART_CR3_DMAT);
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(huart);
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Receives an amount of data in non blocking mode.
+ * @param huart: Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @param pData: Pointer to data buffer
+ * @param Size: Amount of data to be received
+ * @note When the UART parity is enabled (PCE = 1), the received data contain
+ * the parity bit (MSB position)
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_UART_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
+{
+ uint32_t *tmp;
+ uint32_t tmp_state = 0;
+
+ tmp_state = huart->State;
+ if((tmp_state == HAL_UART_STATE_READY) || (tmp_state == HAL_UART_STATE_BUSY_TX))
+ {
+ if((pData == NULL ) || (Size == 0))
+ {
+ return HAL_ERROR;
+ }
+
+ /* Process Locked */
+ __HAL_LOCK(huart);
+
+ huart->pRxBuffPtr = pData;
+ huart->RxXferSize = Size;
+
+ huart->ErrorCode = HAL_UART_ERROR_NONE;
+ /* Check if a transmit process is ongoing or not */
+ if(huart->State == HAL_UART_STATE_BUSY_TX)
+ {
+ huart->State = HAL_UART_STATE_BUSY_TX_RX;
+ }
+ else
+ {
+ huart->State = HAL_UART_STATE_BUSY_RX;
+ }
+
+ /* Set the UART DMA transfer complete callback */
+ huart->hdmarx->XferCpltCallback = UART_DMAReceiveCplt;
+
+ /* Set the UART DMA Half transfer complete callback */
+ huart->hdmarx->XferHalfCpltCallback = UART_DMARxHalfCplt;
+
+ /* Set the DMA error callback */
+ huart->hdmarx->XferErrorCallback = UART_DMAError;
+
+ /* Enable the DMA channel */
+ tmp = (uint32_t*)&pData;
+ HAL_DMA_Start_IT(huart->hdmarx, (uint32_t)&huart->Instance->DR, *(uint32_t*)tmp, Size);
+
+ /* Enable the DMA transfer for the receiver request by setting the DMAR bit
+ in the UART CR3 register */
+ SET_BIT(huart->Instance->CR3, USART_CR3_DMAR);
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(huart);
+
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Pauses the DMA Transfer.
+ * @param huart: Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_UART_DMAPause(UART_HandleTypeDef *huart)
+{
+ /* Process Locked */
+ __HAL_LOCK(huart);
+
+ if(huart->State == HAL_UART_STATE_BUSY_TX)
+ {
+ /* Disable the UART DMA Tx request */
+ CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
+ }
+ else if(huart->State == HAL_UART_STATE_BUSY_RX)
+ {
+ /* Disable the UART DMA Rx request */
+ CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
+ }
+ else if (huart->State == HAL_UART_STATE_BUSY_TX_RX)
+ {
+ /* Disable the UART DMA Tx & Rx requests */
+ CLEAR_BIT(huart->Instance->CR3, (USART_CR3_DMAT | USART_CR3_DMAR));
+ }
+ else
+ {
+ /* Process Unlocked */
+ __HAL_UNLOCK(huart);
+
+ return HAL_ERROR;
+ }
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(huart);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Resumes the DMA Transfer.
+ * @param huart: Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_UART_DMAResume(UART_HandleTypeDef *huart)
+{
+ /* Process Locked */
+ __HAL_LOCK(huart);
+
+ if(huart->State == HAL_UART_STATE_BUSY_TX)
+ {
+ /* Enable the UART DMA Tx request */
+ SET_BIT(huart->Instance->CR3, USART_CR3_DMAT);
+ }
+ else if(huart->State == HAL_UART_STATE_BUSY_RX)
+ {
+ /* Clear the Overrun flag before resumming the Rx transfer*/
+ __HAL_UART_CLEAR_OREFLAG(huart);
+ /* Enable the UART DMA Rx request */
+ SET_BIT(huart->Instance->CR3, USART_CR3_DMAR);
+ }
+ else if(huart->State == HAL_UART_STATE_BUSY_TX_RX)
+ {
+ /* Clear the Overrun flag before resumming the Rx transfer*/
+ __HAL_UART_CLEAR_OREFLAG(huart);
+ /* Enable the UART DMA Tx & Rx request */
+ SET_BIT(huart->Instance->CR3, (USART_CR3_DMAT | USART_CR3_DMAR));
+ }
+ else
+ {
+ /* Process Unlocked */
+ __HAL_UNLOCK(huart);
+
+ return HAL_ERROR;
+ }
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(huart);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Stops the DMA Transfer.
+ * @param huart: Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_UART_DMAStop(UART_HandleTypeDef *huart)
+{
+ /* The Lock is not implemented on this API to allow the user application
+ to call the HAL UART API under callbacks HAL_UART_TxCpltCallback() / HAL_UART_RxCpltCallback():
+ when calling HAL_DMA_Abort() API the DMA TX/RX Transfer complete interrupt is generated
+ and the correspond call back is executed HAL_UART_TxCpltCallback() / HAL_UART_RxCpltCallback()
+ */
+
+ /* Disable the UART Tx/Rx DMA requests */
+ CLEAR_BIT(huart->Instance->CR3, (USART_CR3_DMAT | USART_CR3_DMAR));
+
+ /* Abort the UART DMA tx channel */
+ if(huart->hdmatx != NULL)
+ {
+ HAL_DMA_Abort(huart->hdmatx);
+ }
+ /* Abort the UART DMA rx channel */
+ if(huart->hdmarx != NULL)
+ {
+ HAL_DMA_Abort(huart->hdmarx);
+ }
+
+ huart->State = HAL_UART_STATE_READY;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief This function handles UART interrupt request.
+ * @param huart: Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval None
+ */
+void HAL_UART_IRQHandler(UART_HandleTypeDef *huart)
+{
+ uint32_t tmp_flag = 0, tmp_it_source = 0;
+
+ tmp_flag = __HAL_UART_GET_FLAG(huart, UART_FLAG_PE);
+ tmp_it_source = __HAL_UART_GET_IT_SOURCE(huart, UART_IT_PE);
+ /* UART parity error interrupt occurred ------------------------------------*/
+ if((tmp_flag != RESET) && (tmp_it_source != RESET))
+ {
+ huart->ErrorCode |= HAL_UART_ERROR_PE;
+ }
+
+ tmp_flag = __HAL_UART_GET_FLAG(huart, UART_FLAG_FE);
+ tmp_it_source = __HAL_UART_GET_IT_SOURCE(huart, UART_IT_ERR);
+ /* UART frame error interrupt occurred -------------------------------------*/
+ if((tmp_flag != RESET) && (tmp_it_source != RESET))
+ {
+ huart->ErrorCode |= HAL_UART_ERROR_FE;
+ }
+
+ tmp_flag = __HAL_UART_GET_FLAG(huart, UART_FLAG_NE);
+ /* UART noise error interrupt occurred -------------------------------------*/
+ if((tmp_flag != RESET) && (tmp_it_source != RESET))
+ {
+ huart->ErrorCode |= HAL_UART_ERROR_NE;
+ }
+
+ tmp_flag = __HAL_UART_GET_FLAG(huart, UART_FLAG_ORE);
+ /* UART Over-Run interrupt occurred ----------------------------------------*/
+ if((tmp_flag != RESET) && (tmp_it_source != RESET))
+ {
+ huart->ErrorCode |= HAL_UART_ERROR_ORE;
+ }
+
+ tmp_flag = __HAL_UART_GET_FLAG(huart, UART_FLAG_RXNE);
+ tmp_it_source = __HAL_UART_GET_IT_SOURCE(huart, UART_IT_RXNE);
+ /* UART in mode Receiver ---------------------------------------------------*/
+ if((tmp_flag != RESET) && (tmp_it_source != RESET))
+ {
+ UART_Receive_IT(huart);
+ }
+
+ tmp_flag = __HAL_UART_GET_FLAG(huart, UART_FLAG_TXE);
+ tmp_it_source = __HAL_UART_GET_IT_SOURCE(huart, UART_IT_TXE);
+ /* UART in mode Transmitter ------------------------------------------------*/
+ if((tmp_flag != RESET) && (tmp_it_source != RESET))
+ {
+ UART_Transmit_IT(huart);
+ }
+
+ tmp_flag = __HAL_UART_GET_FLAG(huart, UART_FLAG_TC);
+ tmp_it_source = __HAL_UART_GET_IT_SOURCE(huart, UART_IT_TC);
+ /* UART in mode Transmitter end --------------------------------------------*/
+ if((tmp_flag != RESET) && (tmp_it_source != RESET))
+ {
+ UART_EndTransmit_IT(huart);
+ }
+
+ if(huart->ErrorCode != HAL_UART_ERROR_NONE)
+ {
+ /* Clear all the error flag at once */
+ __HAL_UART_CLEAR_PEFLAG(huart);
+
+ /* Set the UART state ready to be able to start again the process */
+ huart->State = HAL_UART_STATE_READY;
+
+ HAL_UART_ErrorCallback(huart);
+ }
+}
+
+/**
+ * @brief Tx Transfer completed callbacks.
+ * @param huart: Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval None
+ */
+ __weak void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(huart);
+ /* NOTE: This function should not be modified, when the callback is needed,
+ the HAL_UART_TxCpltCallback can be implemented in the user file
+ */
+}
+
+/**
+ * @brief Tx Half Transfer completed callbacks.
+ * @param huart: Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval None
+ */
+ __weak void HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef *huart)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(huart);
+ /* NOTE: This function should not be modified, when the callback is needed,
+ the HAL_UART_TxHalfCpltCallback can be implemented in the user file
+ */
+}
+
+/**
+ * @brief Rx Transfer completed callbacks.
+ * @param huart: Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval None
+ */
+__weak void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(huart);
+ /* NOTE: This function should not be modified, when the callback is needed,
+ the HAL_UART_RxCpltCallback can be implemented in the user file
+ */
+}
+
+/**
+ * @brief Rx Half Transfer completed callbacks.
+ * @param huart: Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval None
+ */
+__weak void HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(huart);
+ /* NOTE: This function should not be modified, when the callback is needed,
+ the HAL_UART_RxHalfCpltCallback can be implemented in the user file
+ */
+}
+
+/**
+ * @brief UART error callbacks.
+ * @param huart: Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval None
+ */
+ __weak void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(huart);
+ /* NOTE: This function should not be modified, when the callback is needed,
+ the HAL_UART_ErrorCallback can be implemented in the user file
+ */
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup UART_Exported_Functions_Group3 Peripheral Control functions
+ * @brief UART control functions
+ *
+@verbatim
+ ==============================================================================
+ ##### Peripheral Control functions #####
+ ==============================================================================
+ [..]
+ This subsection provides a set of functions allowing to control the UART:
+ (+) HAL_LIN_SendBreak() API can be helpful to transmit the break character.
+ (+) HAL_MultiProcessor_EnterMuteMode() API can be helpful to enter the UART in mute mode.
+ (+) HAL_MultiProcessor_ExitMuteMode() API can be helpful to exit the UART mute mode by software.
+ (+) HAL_HalfDuplex_EnableTransmitter() API to enable the UART transmitter and disables the UART receiver in Half Duplex mode
+ (+) HAL_HalfDuplex_EnableReceiver() API to enable the UART receiver and disables the UART transmitter in Half Duplex mode
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Transmits break characters.
+ * @param huart: Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_LIN_SendBreak(UART_HandleTypeDef *huart)
+{
+ /* Check the parameters */
+ assert_param(IS_UART_INSTANCE(huart->Instance));
+
+ /* Process Locked */
+ __HAL_LOCK(huart);
+
+ huart->State = HAL_UART_STATE_BUSY;
+
+ /* Send break characters */
+ SET_BIT(huart->Instance->CR1, USART_CR1_SBK);
+
+ huart->State = HAL_UART_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(huart);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Enters the UART in mute mode.
+ * @param huart: Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_MultiProcessor_EnterMuteMode(UART_HandleTypeDef *huart)
+{
+ /* Check the parameters */
+ assert_param(IS_UART_INSTANCE(huart->Instance));
+
+ /* Process Locked */
+ __HAL_LOCK(huart);
+
+ huart->State = HAL_UART_STATE_BUSY;
+
+ /* Enable the USART mute mode by setting the RWU bit in the CR1 register */
+ SET_BIT(huart->Instance->CR1, USART_CR1_RWU);
+
+ huart->State = HAL_UART_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(huart);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Exits the UART mute mode: wake up software.
+ * @param huart: Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_MultiProcessor_ExitMuteMode(UART_HandleTypeDef *huart)
+{
+ /* Check the parameters */
+ assert_param(IS_UART_INSTANCE(huart->Instance));
+
+ /* Process Locked */
+ __HAL_LOCK(huart);
+
+ huart->State = HAL_UART_STATE_BUSY;
+
+ /* Disable the USART mute mode by clearing the RWU bit in the CR1 register */
+ CLEAR_BIT(huart->Instance->CR1, USART_CR1_RWU);
+
+ huart->State = HAL_UART_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(huart);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Enables the UART transmitter and disables the UART receiver.
+ * @param huart: Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_HalfDuplex_EnableTransmitter(UART_HandleTypeDef *huart)
+{
+ /* Process Locked */
+ __HAL_LOCK(huart);
+
+ huart->State = HAL_UART_STATE_BUSY;
+
+ /*-------------------------- USART CR1 Configuration -----------------------*/
+ /* Clear TE and RE bits */
+ /* Enable the USART's transmit interface by setting the TE bit in the USART CR1 register */
+ MODIFY_REG(huart->Instance->CR1, (uint32_t)(USART_CR1_TE | USART_CR1_RE), USART_CR1_TE);
+
+ huart->State = HAL_UART_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(huart);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Enables the UART receiver and disables the UART transmitter.
+ * @param huart: Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_HalfDuplex_EnableReceiver(UART_HandleTypeDef *huart)
+{
+ /* Process Locked */
+ __HAL_LOCK(huart);
+
+ huart->State = HAL_UART_STATE_BUSY;
+
+ /*-------------------------- USART CR1 Configuration -----------------------*/
+ /* Clear TE and RE bits */
+ /* Enable the USART's receive interface by setting the RE bit in the USART CR1 register */
+ MODIFY_REG(huart->Instance->CR1, (uint32_t)(USART_CR1_TE | USART_CR1_RE), USART_CR1_RE);
+
+ huart->State = HAL_UART_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(huart);
+
+ return HAL_OK;
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup UART_Exported_Functions_Group4 Peripheral State and Errors functions
+ * @brief UART State and Errors functions
+ *
+@verbatim
+ ==============================================================================
+ ##### Peripheral State and Errors functions #####
+ ==============================================================================
+ [..]
+ This subsection provides a set of functions allowing to return the State of
+ UART communication process, return Peripheral Errors occurred during communication
+ process
+ (+) HAL_UART_GetState() API can be helpful to check in run-time the state of the UART peripheral.
+ (+) HAL_UART_GetError() check in run-time errors that could be occurred during communication.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Returns the UART state.
+ * @param huart: Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval HAL state
+ */
+HAL_UART_StateTypeDef HAL_UART_GetState(UART_HandleTypeDef *huart)
+{
+ return huart->State;
+}
+
+/**
+* @brief Return the UART error code
+* @param huart: Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART.
+* @retval UART Error Code
+*/
+uint32_t HAL_UART_GetError(UART_HandleTypeDef *huart)
+{
+ return huart->ErrorCode;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup UART_Private_Functions UART Private Functions
+ * @brief UART Private functions
+ * @{
+ */
+/**
+ * @brief DMA UART transmit process complete callback.
+ * @param hdma: Pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA module.
+ * @retval None
+ */
+static void UART_DMATransmitCplt(DMA_HandleTypeDef *hdma)
+{
+ UART_HandleTypeDef* huart = ( UART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
+ /* DMA Normal mode*/
+ if ( HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC) )
+ {
+ huart->TxXferCount = 0;
+
+ /* Disable the DMA transfer for transmit request by setting the DMAT bit
+ in the UART CR3 register */
+ CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
+
+ /* Enable the UART Transmit Complete Interrupt */
+ __HAL_UART_ENABLE_IT(huart, UART_IT_TC);
+ }
+ /* DMA Circular mode */
+ else
+ {
+ HAL_UART_TxCpltCallback(huart);
+ }
+}
+
+/**
+ * @brief DMA UART transmit process half complete callback
+ * @param hdma: Pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA module.
+ * @retval None
+ */
+static void UART_DMATxHalfCplt(DMA_HandleTypeDef *hdma)
+{
+ UART_HandleTypeDef* huart = (UART_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
+
+ HAL_UART_TxHalfCpltCallback(huart);
+}
+
+/**
+ * @brief DMA UART receive process complete callback.
+ * @param hdma: Pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA module.
+ * @retval None
+ */
+static void UART_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
+{
+ UART_HandleTypeDef* huart = ( UART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
+ /* DMA Normal mode*/
+ if ( HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC) )
+ {
+ huart->RxXferCount = 0;
+
+ /* Disable the DMA transfer for the receiver request by setting the DMAR bit
+ in the UART CR3 register */
+ CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
+
+ /* Check if a transmit process is ongoing or not */
+ if(huart->State == HAL_UART_STATE_BUSY_TX_RX)
+ {
+ huart->State = HAL_UART_STATE_BUSY_TX;
+ }
+ else
+ {
+ huart->State = HAL_UART_STATE_READY;
+ }
+ }
+ HAL_UART_RxCpltCallback(huart);
+}
+
+/**
+ * @brief DMA UART receive process half complete callback
+ * @param hdma: Pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA module.
+ * @retval None
+ */
+static void UART_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
+{
+ UART_HandleTypeDef* huart = (UART_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
+
+ HAL_UART_RxHalfCpltCallback(huart);
+}
+
+/**
+ * @brief DMA UART communication error callback.
+ * @param hdma: Pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA module.
+ * @retval None
+ */
+static void UART_DMAError(DMA_HandleTypeDef *hdma)
+{
+ UART_HandleTypeDef* huart = ( UART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
+ huart->RxXferCount = 0;
+ huart->TxXferCount = 0;
+ huart->State= HAL_UART_STATE_READY;
+ huart->ErrorCode |= HAL_UART_ERROR_DMA;
+ HAL_UART_ErrorCallback(huart);
+}
+
+/**
+ * @brief This function handles UART Communication Timeout.
+ * @param huart: Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @param Flag: specifies the UART flag to check.
+ * @param Status: The new Flag status (SET or RESET).
+ * @param Timeout: Timeout duration
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef UART_WaitOnFlagUntilTimeout(UART_HandleTypeDef *huart, uint32_t Flag, FlagStatus Status, uint32_t Timeout)
+{
+ uint32_t tickstart = 0;
+
+ /* Get tick */
+ tickstart = HAL_GetTick();
+
+ /* Wait until flag is set */
+ if(Status == RESET)
+ {
+ while(__HAL_UART_GET_FLAG(huart, Flag) == RESET)
+ {
+ /* Check for the Timeout */
+ if(Timeout != HAL_MAX_DELAY)
+ {
+ if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
+ {
+ /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */
+ __HAL_UART_DISABLE_IT(huart, UART_IT_TXE);
+ __HAL_UART_DISABLE_IT(huart, UART_IT_RXNE);
+ __HAL_UART_DISABLE_IT(huart, UART_IT_PE);
+ __HAL_UART_DISABLE_IT(huart, UART_IT_ERR);
+
+ huart->State= HAL_UART_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(huart);
+
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+ }
+ else
+ {
+ while(__HAL_UART_GET_FLAG(huart, Flag) != RESET)
+ {
+ /* Check for the Timeout */
+ if(Timeout != HAL_MAX_DELAY)
+ {
+ if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
+ {
+ /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */
+ __HAL_UART_DISABLE_IT(huart, UART_IT_TXE);
+ __HAL_UART_DISABLE_IT(huart, UART_IT_RXNE);
+ __HAL_UART_DISABLE_IT(huart, UART_IT_PE);
+ __HAL_UART_DISABLE_IT(huart, UART_IT_ERR);
+
+ huart->State= HAL_UART_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(huart);
+
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+ }
+ return HAL_OK;
+}
+
+/**
+ * @brief Sends an amount of data in non blocking mode.
+ * @param huart: Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef UART_Transmit_IT(UART_HandleTypeDef *huart)
+{
+ uint16_t* tmp;
+ uint32_t tmp_state = 0;
+
+ tmp_state = huart->State;
+ if((tmp_state == HAL_UART_STATE_BUSY_TX) || (tmp_state == HAL_UART_STATE_BUSY_TX_RX))
+ {
+ if(huart->Init.WordLength == UART_WORDLENGTH_9B)
+ {
+ tmp = (uint16_t*) huart->pTxBuffPtr;
+ huart->Instance->DR = (uint16_t)(*tmp & (uint16_t)0x01FF);
+ if(huart->Init.Parity == UART_PARITY_NONE)
+ {
+ huart->pTxBuffPtr += 2;
+ }
+ else
+ {
+ huart->pTxBuffPtr += 1;
+ }
+ }
+ else
+ {
+ huart->Instance->DR = (uint8_t)(*huart->pTxBuffPtr++ & (uint8_t)0x00FF);
+ }
+
+ if(--huart->TxXferCount == 0)
+ {
+ /* Disable the UART Transmit Complete Interrupt */
+ __HAL_UART_DISABLE_IT(huart, UART_IT_TXE);
+
+ /* Enable the UART Transmit Complete Interrupt */
+ __HAL_UART_ENABLE_IT(huart, UART_IT_TC);
+ }
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+
+/**
+ * @brief Wraps up transmission in non blocking mode.
+ * @param huart: pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef UART_EndTransmit_IT(UART_HandleTypeDef *huart)
+{
+ /* Disable the UART Transmit Complete Interrupt */
+ __HAL_UART_DISABLE_IT(huart, UART_IT_TC);
+
+ /* Check if a receive process is ongoing or not */
+ if(huart->State == HAL_UART_STATE_BUSY_TX_RX)
+ {
+ huart->State = HAL_UART_STATE_BUSY_RX;
+ }
+ else
+ {
+ huart->State = HAL_UART_STATE_READY;
+ }
+
+ HAL_UART_TxCpltCallback(huart);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Receives an amount of data in non blocking mode
+ * @param huart: Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef UART_Receive_IT(UART_HandleTypeDef *huart)
+{
+ uint16_t* tmp;
+ uint32_t tmp_state = 0;
+
+ tmp_state = huart->State;
+ if((tmp_state == HAL_UART_STATE_BUSY_RX) || (tmp_state == HAL_UART_STATE_BUSY_TX_RX))
+ {
+ if(huart->Init.WordLength == UART_WORDLENGTH_9B)
+ {
+ tmp = (uint16_t*) huart->pRxBuffPtr;
+ if(huart->Init.Parity == UART_PARITY_NONE)
+ {
+ *tmp = (uint16_t)(huart->Instance->DR & (uint16_t)0x01FF);
+ huart->pRxBuffPtr += 2;
+ }
+ else
+ {
+ *tmp = (uint16_t)(huart->Instance->DR & (uint16_t)0x00FF);
+ huart->pRxBuffPtr += 1;
+ }
+ }
+ else
+ {
+ if(huart->Init.Parity == UART_PARITY_NONE)
+ {
+ *huart->pRxBuffPtr++ = (uint8_t)(huart->Instance->DR & (uint8_t)0x00FF);
+ }
+ else
+ {
+ *huart->pRxBuffPtr++ = (uint8_t)(huart->Instance->DR & (uint8_t)0x007F);
+ }
+ }
+
+ if(--huart->RxXferCount == 0)
+ {
+ __HAL_UART_DISABLE_IT(huart, UART_IT_RXNE);
+
+ /* Check if a transmit process is ongoing or not */
+ if(huart->State == HAL_UART_STATE_BUSY_TX_RX)
+ {
+ huart->State = HAL_UART_STATE_BUSY_TX;
+ }
+ else
+ {
+ /* Disable the UART Parity Error Interrupt */
+ __HAL_UART_DISABLE_IT(huart, UART_IT_PE);
+
+ /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */
+ __HAL_UART_DISABLE_IT(huart, UART_IT_ERR);
+
+ huart->State = HAL_UART_STATE_READY;
+ }
+ HAL_UART_RxCpltCallback(huart);
+
+ return HAL_OK;
+ }
+ return HAL_OK;
+ }
+ else
+ {
+ return HAL_BUSY;
+ }
+}
+
+/**
+ * @brief Configures the UART peripheral.
+ * @param huart: Pointer to a UART_HandleTypeDef structure that contains
+ * the configuration information for the specified UART module.
+ * @retval None
+ */
+static void UART_SetConfig(UART_HandleTypeDef *huart)
+{
+ uint32_t tmpreg = 0x00;
+
+ /* Check the parameters */
+ assert_param(IS_UART_BAUDRATE(huart->Init.BaudRate));
+ assert_param(IS_UART_STOPBITS(huart->Init.StopBits));
+ assert_param(IS_UART_PARITY(huart->Init.Parity));
+ assert_param(IS_UART_MODE(huart->Init.Mode));
+
+ /*------- UART-associated USART registers setting : CR2 Configuration ------*/
+ /* Configure the UART Stop Bits: Set STOP[13:12] bits according
+ * to huart->Init.StopBits value */
+ MODIFY_REG(huart->Instance->CR2, USART_CR2_STOP, huart->Init.StopBits);
+
+ /*------- UART-associated USART registers setting : CR1 Configuration ------*/
+ /* Configure the UART Word Length, Parity and mode:
+ Set the M bits according to huart->Init.WordLength value
+ Set PCE and PS bits according to huart->Init.Parity value
+ Set TE and RE bits according to huart->Init.Mode value */
+ tmpreg = (uint32_t)huart->Init.WordLength | huart->Init.Parity | huart->Init.Mode ;
+ MODIFY_REG(huart->Instance->CR1,
+ (uint32_t)(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | USART_CR1_TE | USART_CR1_RE),
+ tmpreg);
+
+ /*------- UART-associated USART registers setting : CR3 Configuration ------*/
+ /* Configure the UART HFC: Set CTSE and RTSE bits according to huart->Init.HwFlowCtl value */
+ MODIFY_REG(huart->Instance->CR3, (USART_CR3_RTSE | USART_CR3_CTSE), huart->Init.HwFlowCtl);
+
+ /*------- UART-associated USART registers setting : BRR Configuration ------*/
+ if((huart->Instance == USART1))
+ {
+ huart->Instance->BRR = UART_BRR_SAMPLING16(HAL_RCC_GetPCLK2Freq(), huart->Init.BaudRate);
+ }
+ else
+ {
+ huart->Instance->BRR = UART_BRR_SAMPLING16(HAL_RCC_GetPCLK1Freq(), huart->Init.BaudRate);
+ }
+}
+/**
+ * @}
+ */
+
+#endif /* HAL_UART_MODULE_ENABLED */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/bsp/radio-controller-1/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_usb.c b/bsp/radio-controller-1/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_usb.c
new file mode 100644
index 0000000..1b673cd
--- /dev/null
+++ b/bsp/radio-controller-1/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_usb.c
@@ -0,0 +1,2211 @@
+/**
+ ******************************************************************************
+ * @file stm32f1xx_ll_usb.c
+ * @author MCD Application Team
+ * @version V1.0.4
+ * @date 29-April-2016
+ * @brief USB Low Layer HAL module driver.
+ *
+ * This file provides firmware functions to manage the following
+ * functionalities of the USB Peripheral Controller:
+ * + Initialization/de-initialization functions
+ * + I/O operation functions
+ * + Peripheral Control functions
+ * + Peripheral State functions
+ *
+ @verbatim
+ ==============================================================================
+ ##### How to use this driver #####
+ ==============================================================================
+ [..]
+ (#) Fill parameters of Init structure in USB_OTG_CfgTypeDef structure.
+
+ (#) Call USB_CoreInit() API to initialize the USB Core peripheral.
+
+ (#) The upper HAL HCD/PCD driver will call the right routines for its internal processes.
+
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f1xx_hal.h"
+
+/** @addtogroup STM32F1xx_HAL_Driver
+ * @{
+ */
+
+/** @defgroup USB_LL USB Low Layer
+ * @brief Low layer module for USB_FS and USB_OTG_FS drivers
+ * @{
+ */
+
+#if defined (HAL_PCD_MODULE_ENABLED) || defined (HAL_HCD_MODULE_ENABLED)
+
+#if defined(STM32F102x6) || defined(STM32F102xB) || \
+ defined(STM32F103x6) || defined(STM32F103xB) || \
+ defined(STM32F103xE) || defined(STM32F103xG) || \
+ defined(STM32F105xC) || defined(STM32F107xC)
+
+/* Private types -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private constants ---------------------------------------------------------*/
+/* Private macros ------------------------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+#if defined (USB_OTG_FS)
+/** @defgroup USB_LL_Private_Functions USB Low Layer Private Functions
+ * @{
+ */
+static HAL_StatusTypeDef USB_CoreReset(USB_OTG_GlobalTypeDef *USBx);
+/**
+ * @}
+ */
+#endif /* USB_OTG_FS */
+
+/* Exported functions --------------------------------------------------------*/
+/** @defgroup USB_LL_Exported_Functions USB Low Layer Exported Functions
+ * @{
+ */
+
+/** @defgroup USB_LL_Exported_Functions_Group1 Peripheral Control functions
+ * @brief management functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Peripheral Control functions #####
+ ===============================================================================
+ [..]
+ This subsection provides a set of functions allowing to control the PCD data
+ transfers.
+
+@endverbatim
+ * @{
+ */
+
+/*==============================================================================
+ USB OTG FS peripheral available on STM32F105xx and STM32F107xx devices
+==============================================================================*/
+#if defined (USB_OTG_FS)
+
+/**
+ * @brief Initializes the USB Core
+ * @param USBx: USB Instance
+ * @param cfg : pointer to a USB_OTG_CfgTypeDef structure that contains
+ * the configuration information for the specified USBx peripheral.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef USB_CoreInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg)
+{
+ /* Select FS Embedded PHY */
+ USBx->GUSBCFG |= USB_OTG_GUSBCFG_PHYSEL;
+
+ /* Reset after a PHY select and set Host mode */
+ USB_CoreReset(USBx);
+
+ /* Deactivate the power down*/
+ USBx->GCCFG = USB_OTG_GCCFG_PWRDWN;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief USB_EnableGlobalInt
+ * Enables the controller's Global Int in the AHB Config reg
+ * @param USBx : Selected device
+ * @retval HAL status
+ */
+HAL_StatusTypeDef USB_EnableGlobalInt(USB_OTG_GlobalTypeDef *USBx)
+{
+ USBx->GAHBCFG |= USB_OTG_GAHBCFG_GINT;
+ return HAL_OK;
+}
+
+/**
+ * @brief USB_DisableGlobalInt
+ * Disable the controller's Global Int in the AHB Config reg
+ * @param USBx : Selected device
+ * @retval HAL status
+*/
+HAL_StatusTypeDef USB_DisableGlobalInt(USB_OTG_GlobalTypeDef *USBx)
+{
+ USBx->GAHBCFG &= ~USB_OTG_GAHBCFG_GINT;
+ return HAL_OK;
+}
+
+/**
+ * @brief USB_SetCurrentMode : Set functional mode
+ * @param USBx : Selected device
+ * @param mode : current core mode
+ * This parameter can be one of the these values:
+ * @arg USB_DEVICE_MODE: Peripheral mode mode
+ * @arg USB_HOST_MODE: Host mode
+ * @arg USB_DRD_MODE: Dual Role Device mode
+ * @retval HAL status
+ */
+HAL_StatusTypeDef USB_SetCurrentMode(USB_OTG_GlobalTypeDef *USBx , USB_ModeTypeDef mode)
+{
+ USBx->GUSBCFG &= ~(USB_OTG_GUSBCFG_FHMOD | USB_OTG_GUSBCFG_FDMOD);
+
+ if ( mode == USB_HOST_MODE)
+ {
+ USBx->GUSBCFG |= USB_OTG_GUSBCFG_FHMOD;
+ }
+ else if ( mode == USB_DEVICE_MODE)
+ {
+ USBx->GUSBCFG |= USB_OTG_GUSBCFG_FDMOD;
+ }
+ HAL_Delay(50);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief USB_DevInit : Initializes the USB_OTG controller registers
+ * for device mode
+ * @param USBx : Selected device
+ * @param cfg : pointer to a USB_OTG_CfgTypeDef structure that contains
+ * the configuration information for the specified USBx peripheral.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef USB_DevInit (USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg)
+{
+ uint32_t index = 0;
+
+ for (index = 0; index < 15 ; index++)
+ {
+ USBx->DIEPTXF[index] = 0;
+ }
+
+ /*Activate VBUS Sensing B */
+ USBx->GCCFG |= USB_OTG_GCCFG_VBUSBSEN;
+
+ /* Restart the Phy Clock */
+ USBx_PCGCCTL = 0;
+
+ /* Device mode configuration */
+ USBx_DEVICE->DCFG |= DCFG_FRAME_INTERVAL_80;
+
+ /* Set Full speed phy */
+ USB_SetDevSpeed (USBx , USB_OTG_SPEED_FULL);
+
+ /* Flush the FIFOs */
+ USB_FlushTxFifo(USBx , 0x10); /* all Tx FIFOs */
+ USB_FlushRxFifo(USBx);
+
+ /* Clear all pending Device Interrupts */
+ USBx_DEVICE->DIEPMSK = 0;
+ USBx_DEVICE->DOEPMSK = 0;
+ USBx_DEVICE->DAINT = 0xFFFFFFFF;
+ USBx_DEVICE->DAINTMSK = 0;
+
+ for (index = 0; index < cfg.dev_endpoints; index++)
+ {
+ if ((USBx_INEP(index)->DIEPCTL & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA)
+ {
+ USBx_INEP(index)->DIEPCTL = (USB_OTG_DIEPCTL_EPDIS | USB_OTG_DIEPCTL_SNAK);
+ }
+ else
+ {
+ USBx_INEP(index)->DIEPCTL = 0;
+ }
+
+ USBx_INEP(index)->DIEPTSIZ = 0;
+ USBx_INEP(index)->DIEPINT = 0xFF;
+ }
+
+ for (index = 0; index < cfg.dev_endpoints; index++)
+ {
+ if ((USBx_OUTEP(index)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA)
+ {
+ USBx_OUTEP(index)->DOEPCTL = (USB_OTG_DOEPCTL_EPDIS | USB_OTG_DOEPCTL_SNAK);
+ }
+ else
+ {
+ USBx_OUTEP(index)->DOEPCTL = 0;
+ }
+
+ USBx_OUTEP(index)->DOEPTSIZ = 0;
+ USBx_OUTEP(index)->DOEPINT = 0xFF;
+ }
+
+ USBx_DEVICE->DIEPMSK &= ~(USB_OTG_DIEPMSK_TXFURM);
+
+ /* Disable all interrupts. */
+ USBx->GINTMSK = 0;
+
+ /* Clear any pending interrupts */
+ USBx->GINTSTS = 0xBFFFFFFF;
+
+ /* Enable the common interrupts */
+ USBx->GINTMSK |= USB_OTG_GINTMSK_RXFLVLM;
+
+ /* Enable interrupts matching to the Device mode ONLY */
+ USBx->GINTMSK |= (USB_OTG_GINTMSK_USBSUSPM | USB_OTG_GINTMSK_USBRST |\
+ USB_OTG_GINTMSK_ENUMDNEM | USB_OTG_GINTMSK_IEPINT |\
+ USB_OTG_GINTMSK_OEPINT | USB_OTG_GINTMSK_IISOIXFRM|\
+ USB_OTG_GINTMSK_PXFRM_IISOOXFRM | USB_OTG_GINTMSK_WUIM);
+
+ if(cfg.Sof_enable)
+ {
+ USBx->GINTMSK |= USB_OTG_GINTMSK_SOFM;
+ }
+
+ if (cfg.vbus_sensing_enable == ENABLE)
+ {
+ USBx->GINTMSK |= (USB_OTG_GINTMSK_SRQIM | USB_OTG_GINTMSK_OTGINT);
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief USB_OTG_FlushTxFifo : Flush a Tx FIFO
+ * @param USBx : Selected device
+ * @param num : FIFO number
+ * This parameter can be a value from 1 to 15
+ 15 means Flush all Tx FIFOs
+ * @retval HAL status
+ */
+HAL_StatusTypeDef USB_FlushTxFifo (USB_OTG_GlobalTypeDef *USBx, uint32_t num )
+{
+ uint32_t count = 0;
+
+ USBx->GRSTCTL = ( USB_OTG_GRSTCTL_TXFFLSH |(uint32_t)( num << 6));
+
+ do
+ {
+ if (++count > 200000)
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+ while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_TXFFLSH) == USB_OTG_GRSTCTL_TXFFLSH);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief USB_FlushRxFifo : Flush Rx FIFO
+ * @param USBx : Selected device
+ * @retval HAL status
+ */
+HAL_StatusTypeDef USB_FlushRxFifo(USB_OTG_GlobalTypeDef *USBx)
+{
+ uint32_t count = 0;
+
+ USBx->GRSTCTL = USB_OTG_GRSTCTL_RXFFLSH;
+
+ do
+ {
+ if (++count > 200000)
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+ while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_RXFFLSH) == USB_OTG_GRSTCTL_RXFFLSH);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief USB_SetDevSpeed :Initializes the DevSpd field of DCFG register
+ * depending the PHY type and the enumeration speed of the device.
+ * @param USBx : Selected device
+ * @param speed : device speed
+ * This parameter can be one of the these values:
+ * @arg USB_OTG_SPEED_FULL: Full speed mode
+ * @arg USB_OTG_SPEED_LOW: Low speed mode
+ * @retval Hal status
+ */
+HAL_StatusTypeDef USB_SetDevSpeed(USB_OTG_GlobalTypeDef *USBx , uint8_t speed)
+{
+ USBx_DEVICE->DCFG |= speed;
+ return HAL_OK;
+}
+
+/**
+ * @brief USB_GetDevSpeed :Return the Dev Speed
+ * @param USBx : Selected device
+ * @retval speed : device speed
+ * This parameter can be one of the these values:
+ * @arg USB_OTG_SPEED_FULL: Full speed mode
+ * @arg USB_OTG_SPEED_LOW: Low speed mode
+ */
+uint8_t USB_GetDevSpeed(USB_OTG_GlobalTypeDef *USBx)
+{
+ uint8_t speed = 0;
+
+ if (((USBx_DEVICE->DSTS & USB_OTG_DSTS_ENUMSPD) == DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ)||
+ ((USBx_DEVICE->DSTS & USB_OTG_DSTS_ENUMSPD) == DSTS_ENUMSPD_FS_PHY_48MHZ))
+ {
+ speed = USB_OTG_SPEED_FULL;
+ }
+ else if((USBx_DEVICE->DSTS & USB_OTG_DSTS_ENUMSPD) == DSTS_ENUMSPD_LS_PHY_6MHZ)
+ {
+ speed = USB_OTG_SPEED_LOW;
+ }
+
+ return speed;
+}
+
+/**
+ * @brief Activate and configure an endpoint
+ * @param USBx : Selected device
+ * @param ep: pointer to endpoint structure
+ * @retval HAL status
+ */
+HAL_StatusTypeDef USB_ActivateEndpoint(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)
+{
+ if (ep->is_in)
+ {
+ /* Assign a Tx FIFO */
+ ep->tx_fifo_num = ep->num;
+ }
+ /* Set initial data PID. */
+ if (ep->type == EP_TYPE_BULK )
+ {
+ ep->data_pid_start = 0;
+ }
+
+ if (ep->is_in == 1)
+ {
+ USBx_DEVICE->DAINTMSK |= USB_OTG_DAINTMSK_IEPM & ((1 << (ep->num)));
+
+ if (((USBx_INEP(ep->num)->DIEPCTL) & USB_OTG_DIEPCTL_USBAEP) == 0)
+ {
+ USBx_INEP(ep->num)->DIEPCTL |= ((ep->maxpacket & USB_OTG_DIEPCTL_MPSIZ ) | (ep->type << 18 ) |\
+ ((ep->num) << 22 ) | (USB_OTG_DIEPCTL_SD0PID_SEVNFRM) | (USB_OTG_DIEPCTL_USBAEP));
+ }
+ }
+ else
+ {
+ USBx_DEVICE->DAINTMSK |= USB_OTG_DAINTMSK_OEPM & ((1 << (ep->num)) << 16);
+
+ if (((USBx_OUTEP(ep->num)->DOEPCTL) & USB_OTG_DOEPCTL_USBAEP) == 0)
+ {
+ USBx_OUTEP(ep->num)->DOEPCTL |= ((ep->maxpacket & USB_OTG_DOEPCTL_MPSIZ ) | (ep->type << 18 ) |\
+ (USB_OTG_DIEPCTL_SD0PID_SEVNFRM)| (USB_OTG_DOEPCTL_USBAEP));
+ }
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief De-activate and de-initialize an endpoint
+ * @param USBx : Selected device
+ * @param ep: pointer to endpoint structure
+ * @retval HAL status
+ */
+HAL_StatusTypeDef USB_DeactivateEndpoint(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)
+{
+ /* Read DEPCTLn register */
+ if (ep->is_in == 1)
+ {
+ USBx_DEVICE->DEACHMSK &= ~(USB_OTG_DAINTMSK_IEPM & ((1 << (ep->num))));
+ USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_IEPM & ((1 << (ep->num))));
+ USBx_INEP(ep->num)->DIEPCTL &= ~ USB_OTG_DIEPCTL_USBAEP;
+ }
+ else
+ {
+ USBx_DEVICE->DEACHMSK &= ~(USB_OTG_DAINTMSK_OEPM & ((1 << (ep->num)) << 16));
+ USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_OEPM & ((1 << (ep->num)) << 16));
+ USBx_OUTEP(ep->num)->DOEPCTL &= ~USB_OTG_DOEPCTL_USBAEP;
+ }
+ return HAL_OK;
+}
+
+/**
+ * @brief USB_EPStartXfer : setup and starts a transfer over an EP
+ * @param USBx : Selected device
+ * @param ep: pointer to endpoint structure
+ * @retval HAL status
+ */
+HAL_StatusTypeDef USB_EPStartXfer(USB_OTG_GlobalTypeDef *USBx , USB_OTG_EPTypeDef *ep)
+{
+ uint16_t pktcnt = 0;
+
+ /* IN endpoint */
+ if (ep->is_in == 1)
+ {
+ /* Zero Length Packet? */
+ if (ep->xfer_len == 0)
+ {
+ USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT);
+ USBx_INEP(ep->num)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (1 << 19)) ;
+ USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ);
+ }
+ else
+ {
+ /* Program the transfer size and packet count
+ * as follows: xfersize = N * maxpacket +
+ * short_packet pktcnt = N + (short_packet
+ * exist ? 1 : 0)
+ */
+ USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ);
+ USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT);
+ USBx_INEP(ep->num)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (((ep->xfer_len + ep->maxpacket -1)/ ep->maxpacket) << 19)) ;
+ USBx_INEP(ep->num)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_XFRSIZ & ep->xfer_len);
+
+ if (ep->type == EP_TYPE_ISOC)
+ {
+ USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_MULCNT);
+ USBx_INEP(ep->num)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_MULCNT & (1 << 29));
+ }
+ }
+
+ if (ep->type != EP_TYPE_ISOC)
+ {
+ /* Enable the Tx FIFO Empty Interrupt for this EP */
+ if (ep->xfer_len > 0)
+ {
+ USBx_DEVICE->DIEPEMPMSK |= 1 << ep->num;
+ }
+ }
+
+ if (ep->type == EP_TYPE_ISOC)
+ {
+ if ((USBx_DEVICE->DSTS & ( 1 << 8 )) == 0)
+ {
+ USBx_INEP(ep->num)->DIEPCTL |= USB_OTG_DIEPCTL_SODDFRM;
+ }
+ else
+ {
+ USBx_INEP(ep->num)->DIEPCTL |= USB_OTG_DIEPCTL_SD0PID_SEVNFRM;
+ }
+ }
+
+ /* EP enable, IN data in FIFO */
+ USBx_INEP(ep->num)->DIEPCTL |= (USB_OTG_DIEPCTL_CNAK | USB_OTG_DIEPCTL_EPENA);
+
+ if (ep->type == EP_TYPE_ISOC)
+ {
+ USB_WritePacket(USBx, ep->xfer_buff, ep->num, ep->xfer_len);
+ }
+ }
+ else /* OUT endpoint */
+ {
+ /* Program the transfer size and packet count as follows:
+ * pktcnt = N
+ * xfersize = N * maxpacket
+ */
+ USBx_OUTEP(ep->num)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_XFRSIZ);
+ USBx_OUTEP(ep->num)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_PKTCNT);
+
+ if (ep->xfer_len == 0)
+ {
+ USBx_OUTEP(ep->num)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_XFRSIZ & ep->maxpacket);
+ USBx_OUTEP(ep->num)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1 << 19));
+ }
+ else
+ {
+ pktcnt = (ep->xfer_len + ep->maxpacket -1)/ ep->maxpacket;
+ USBx_OUTEP(ep->num)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (pktcnt << 19));
+ USBx_OUTEP(ep->num)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_XFRSIZ & (ep->maxpacket * pktcnt));
+ }
+
+ if (ep->type == EP_TYPE_ISOC)
+ {
+ if ((USBx_DEVICE->DSTS & ( 1 << 8 )) == 0)
+ {
+ USBx_OUTEP(ep->num)->DOEPCTL |= USB_OTG_DOEPCTL_SODDFRM;
+ }
+ else
+ {
+ USBx_OUTEP(ep->num)->DOEPCTL |= USB_OTG_DOEPCTL_SD0PID_SEVNFRM;
+ }
+ }
+ /* EP enable */
+ USBx_OUTEP(ep->num)->DOEPCTL |= (USB_OTG_DOEPCTL_CNAK | USB_OTG_DOEPCTL_EPENA);
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief USB_EP0StartXfer : setup and starts a transfer over the EP 0
+ * @param USBx : Selected device
+ * @param ep: pointer to endpoint structure
+ * @retval HAL status
+ */
+HAL_StatusTypeDef USB_EP0StartXfer(USB_OTG_GlobalTypeDef *USBx , USB_OTG_EPTypeDef *ep)
+{
+ /* IN endpoint */
+ if (ep->is_in == 1)
+ {
+ /* Zero Length Packet? */
+ if (ep->xfer_len == 0)
+ {
+ USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT);
+ USBx_INEP(ep->num)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (1 << 19));
+ USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ);
+ }
+ else
+ {
+ /* Program the transfer size and packet count
+ * as follows: xfersize = N * maxpacket +
+ * short_packet pktcnt = N + (short_packet
+ * exist ? 1 : 0)
+ */
+ USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ);
+ USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT);
+
+ if(ep->xfer_len > ep->maxpacket)
+ {
+ ep->xfer_len = ep->maxpacket;
+ }
+ USBx_INEP(ep->num)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (1 << 19));
+ USBx_INEP(ep->num)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_XFRSIZ & ep->xfer_len);
+ }
+
+ /* Enable the Tx FIFO Empty Interrupt for this EP */
+ if (ep->xfer_len > 0)
+ {
+ USBx_DEVICE->DIEPEMPMSK |= 1 << (ep->num);
+ }
+
+ /* EP enable, IN data in FIFO */
+ USBx_INEP(ep->num)->DIEPCTL |= (USB_OTG_DIEPCTL_CNAK | USB_OTG_DIEPCTL_EPENA);
+ }
+ else /* OUT endpoint */
+ {
+ /* Program the transfer size and packet count as follows:
+ * pktcnt = N
+ * xfersize = N * maxpacket
+ */
+ USBx_OUTEP(ep->num)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_XFRSIZ);
+ USBx_OUTEP(ep->num)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_PKTCNT);
+
+ if (ep->xfer_len > 0)
+ {
+ ep->xfer_len = ep->maxpacket;
+ }
+
+ USBx_OUTEP(ep->num)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1 << 19));
+ USBx_OUTEP(ep->num)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_XFRSIZ & (ep->maxpacket));
+
+ /* EP enable */
+ USBx_OUTEP(ep->num)->DOEPCTL |= (USB_OTG_DOEPCTL_CNAK | USB_OTG_DOEPCTL_EPENA);
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief USB_WritePacket : Writes a packet into the Tx FIFO associated
+ * with the EP/channel
+ * @param USBx : Selected device
+ * @param src : pointer to source buffer
+ * @param ch_ep_num : endpoint or host channel number
+ * @param len : Number of bytes to write
+ * @retval HAL status
+ */
+HAL_StatusTypeDef USB_WritePacket(USB_OTG_GlobalTypeDef *USBx, uint8_t *src, uint8_t ch_ep_num, uint16_t len)
+{
+ uint32_t count32b = 0 , index = 0;
+
+ count32b = (len + 3) / 4;
+ for (index = 0; index < count32b; index++, src += 4)
+ {
+ USBx_DFIFO(ch_ep_num) = *((__packed uint32_t *)src);
+ }
+ return HAL_OK;
+}
+
+/**
+ * @brief USB_ReadPacket : read a packet from the Tx FIFO associated
+ * with the EP/channel
+ * @param USBx : Selected device
+ * @param dest : destination pointer
+ * @param len : Number of bytes to read
+ * @retval pointer to destination buffer
+ */
+void *USB_ReadPacket(USB_OTG_GlobalTypeDef *USBx, uint8_t *dest, uint16_t len)
+{
+ uint32_t index = 0;
+ uint32_t count32b = (len + 3) / 4;
+
+ for ( index = 0; index < count32b; index++, dest += 4 )
+ {
+ *(__packed uint32_t *)dest = USBx_DFIFO(0);
+
+ }
+ return ((void *)dest);
+}
+
+/**
+ * @brief USB_EPSetStall : set a stall condition over an EP
+ * @param USBx : Selected device
+ * @param ep: pointer to endpoint structure
+ * @retval HAL status
+ */
+HAL_StatusTypeDef USB_EPSetStall(USB_OTG_GlobalTypeDef *USBx , USB_OTG_EPTypeDef *ep)
+{
+ if (ep->is_in == 1)
+ {
+ if (((USBx_INEP(ep->num)->DIEPCTL) & USB_OTG_DIEPCTL_EPENA) == 0)
+ {
+ USBx_INEP(ep->num)->DIEPCTL &= ~(USB_OTG_DIEPCTL_EPDIS);
+ }
+ USBx_INEP(ep->num)->DIEPCTL |= USB_OTG_DIEPCTL_STALL;
+ }
+ else
+ {
+ if (((USBx_OUTEP(ep->num)->DOEPCTL) & USB_OTG_DOEPCTL_EPENA) == 0)
+ {
+ USBx_OUTEP(ep->num)->DOEPCTL &= ~(USB_OTG_DOEPCTL_EPDIS);
+ }
+ USBx_OUTEP(ep->num)->DOEPCTL |= USB_OTG_DOEPCTL_STALL;
+ }
+ return HAL_OK;
+}
+
+/**
+ * @brief USB_EPClearStall : Clear a stall condition over an EP
+ * @param USBx : Selected device
+ * @param ep: pointer to endpoint structure
+ * @retval HAL status
+ */
+HAL_StatusTypeDef USB_EPClearStall(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)
+{
+ if (ep->is_in == 1)
+ {
+ USBx_INEP(ep->num)->DIEPCTL &= ~USB_OTG_DIEPCTL_STALL;
+ if (ep->type == EP_TYPE_INTR || ep->type == EP_TYPE_BULK)
+ {
+ USBx_INEP(ep->num)->DIEPCTL |= USB_OTG_DIEPCTL_SD0PID_SEVNFRM; /* DATA0 */
+ }
+ }
+ else
+ {
+ USBx_OUTEP(ep->num)->DOEPCTL &= ~USB_OTG_DOEPCTL_STALL;
+ if (ep->type == EP_TYPE_INTR || ep->type == EP_TYPE_BULK)
+ {
+ USBx_OUTEP(ep->num)->DOEPCTL |= USB_OTG_DOEPCTL_SD0PID_SEVNFRM; /* DATA0 */
+ }
+ }
+ return HAL_OK;
+}
+
+/**
+ * @brief USB_StopDevice : Stop the usb device mode
+ * @param USBx : Selected device
+ * @retval HAL status
+ */
+HAL_StatusTypeDef USB_StopDevice(USB_OTG_GlobalTypeDef *USBx)
+{
+ uint32_t index = 0;
+
+ /* Clear Pending interrupt */
+ for (index = 0; index < 15 ; index++)
+ {
+ USBx_INEP(index)->DIEPINT = 0xFF;
+ USBx_OUTEP(index)->DOEPINT = 0xFF;
+ }
+ USBx_DEVICE->DAINT = 0xFFFFFFFF;
+
+ /* Clear interrupt masks */
+ USBx_DEVICE->DIEPMSK = 0;
+ USBx_DEVICE->DOEPMSK = 0;
+ USBx_DEVICE->DAINTMSK = 0;
+
+ /* Flush the FIFO */
+ USB_FlushRxFifo(USBx);
+ USB_FlushTxFifo(USBx , 0x10 );
+
+ return HAL_OK;
+}
+
+/**
+ * @brief USB_SetDevAddress : Stop the usb device mode
+ * @param USBx : Selected device
+ * @param address : new device address to be assigned
+ * This parameter can be a value from 0 to 255
+ * @retval HAL status
+ */
+HAL_StatusTypeDef USB_SetDevAddress (USB_OTG_GlobalTypeDef *USBx, uint8_t address)
+{
+ USBx_DEVICE->DCFG &= ~ (USB_OTG_DCFG_DAD);
+ USBx_DEVICE->DCFG |= (address << 4) & USB_OTG_DCFG_DAD;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief USB_DevConnect : Connect the USB device by enabling the pull-up/pull-down
+ * @param USBx : Selected device
+ * @retval HAL status
+ */
+HAL_StatusTypeDef USB_DevConnect (USB_OTG_GlobalTypeDef *USBx)
+{
+ USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_SDIS ;
+ HAL_Delay(3);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief USB_DevDisconnect : Disconnect the USB device by disabling the pull-up/pull-down
+ * @param USBx : Selected device
+ * @retval HAL status
+ */
+HAL_StatusTypeDef USB_DevDisconnect (USB_OTG_GlobalTypeDef *USBx)
+{
+ USBx_DEVICE->DCTL |= USB_OTG_DCTL_SDIS;
+ HAL_Delay(3);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief USB_ReadInterrupts: return the global USB interrupt status
+ * @param USBx : Selected device
+ * @retval HAL status
+ */
+uint32_t USB_ReadInterrupts (USB_OTG_GlobalTypeDef *USBx)
+{
+ uint32_t tmpreg = 0;
+
+ tmpreg = USBx->GINTSTS;
+ tmpreg &= USBx->GINTMSK;
+ return tmpreg;
+}
+
+/**
+ * @brief USB_ReadDevAllOutEpInterrupt: return the USB device OUT endpoints interrupt status
+ * @param USBx : Selected device
+ * @retval HAL status
+ */
+uint32_t USB_ReadDevAllOutEpInterrupt (USB_OTG_GlobalTypeDef *USBx)
+{
+ uint32_t tmpreg = 0;
+ tmpreg = USBx_DEVICE->DAINT;
+ tmpreg &= USBx_DEVICE->DAINTMSK;
+ return ((tmpreg & 0xffff0000) >> 16);
+}
+
+/**
+ * @brief USB_ReadDevAllInEpInterrupt: return the USB device IN endpoints interrupt status
+ * @param USBx : Selected device
+ * @retval HAL status
+ */
+uint32_t USB_ReadDevAllInEpInterrupt (USB_OTG_GlobalTypeDef *USBx)
+{
+ uint32_t tmpreg = 0;
+ tmpreg = USBx_DEVICE->DAINT;
+ tmpreg &= USBx_DEVICE->DAINTMSK;
+ return ((tmpreg & 0xFFFF));
+}
+
+/**
+ * @brief Returns Device OUT EP Interrupt register
+ * @param USBx : Selected device
+ * @param epnum : endpoint number
+ * This parameter can be a value from 0 to 15
+ * @retval Device OUT EP Interrupt register
+ */
+uint32_t USB_ReadDevOutEPInterrupt (USB_OTG_GlobalTypeDef *USBx , uint8_t epnum)
+{
+ uint32_t tmpreg = 0;
+ tmpreg = USBx_OUTEP(epnum)->DOEPINT;
+ tmpreg &= USBx_DEVICE->DOEPMSK;
+ return tmpreg;
+}
+
+/**
+ * @brief Returns Device IN EP Interrupt register
+ * @param USBx : Selected device
+ * @param epnum : endpoint number
+ * This parameter can be a value from 0 to 15
+ * @retval Device IN EP Interrupt register
+ */
+uint32_t USB_ReadDevInEPInterrupt (USB_OTG_GlobalTypeDef *USBx , uint8_t epnum)
+{
+ uint32_t tmpreg = 0, msk = 0, emp = 0;
+
+ msk = USBx_DEVICE->DIEPMSK;
+ emp = USBx_DEVICE->DIEPEMPMSK;
+ msk |= ((emp >> epnum) & 0x1) << 7;
+ tmpreg = USBx_INEP(epnum)->DIEPINT & msk;
+ return tmpreg;
+}
+
+/**
+ * @brief USB_ClearInterrupts: clear a USB interrupt
+ * @param USBx : Selected device
+ * @param interrupt : interrupt flag
+ * @retval None
+ */
+void USB_ClearInterrupts (USB_OTG_GlobalTypeDef *USBx, uint32_t interrupt)
+{
+ USBx->GINTSTS |= interrupt;
+}
+
+/**
+ * @brief Returns USB core mode
+ * @param USBx : Selected device
+ * @retval return core mode : Host or Device
+ * This parameter can be one of the these values:
+ * 0 : Host
+ * 1 : Device
+ */
+uint32_t USB_GetMode(USB_OTG_GlobalTypeDef *USBx)
+{
+ return ((USBx->GINTSTS ) & 0x1);
+}
+
+/**
+ * @brief Activate EP0 for Setup transactions
+ * @param USBx : Selected device
+ * @retval HAL status
+ */
+HAL_StatusTypeDef USB_ActivateSetup (USB_OTG_GlobalTypeDef *USBx)
+{
+ /* Set the MPS of the IN EP based on the enumeration speed */
+ USBx_INEP(0)->DIEPCTL &= ~USB_OTG_DIEPCTL_MPSIZ;
+
+ if((USBx_DEVICE->DSTS & USB_OTG_DSTS_ENUMSPD) == DSTS_ENUMSPD_LS_PHY_6MHZ)
+ {
+ USBx_INEP(0)->DIEPCTL |= 3;
+ }
+ USBx_DEVICE->DCTL |= USB_OTG_DCTL_CGINAK;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Prepare the EP0 to start the first control setup
+ * @param USBx : Selected device
+ * @param psetup : pointer to setup packet
+ * @retval HAL status
+ */
+HAL_StatusTypeDef USB_EP0_OutStart(USB_OTG_GlobalTypeDef *USBx, uint8_t *psetup)
+{
+ USBx_OUTEP(0)->DOEPTSIZ = 0;
+ USBx_OUTEP(0)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1 << 19));
+ USBx_OUTEP(0)->DOEPTSIZ |= (3 * 8);
+ USBx_OUTEP(0)->DOEPTSIZ |= USB_OTG_DOEPTSIZ_STUPCNT;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief USB_HostInit : Initializes the USB OTG controller registers
+ * for Host mode
+ * @param USBx : Selected device
+ * @param cfg : pointer to a USB_OTG_CfgTypeDef structure that contains
+ * the configuration information for the specified USBx peripheral.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef USB_HostInit (USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg)
+{
+ uint32_t index = 0;
+
+ /* Restart the Phy Clock */
+ USBx_PCGCCTL = 0;
+
+ /* no VBUS sensing*/
+ USBx->GCCFG &=~ (USB_OTG_GCCFG_VBUSASEN);
+ USBx->GCCFG &=~ (USB_OTG_GCCFG_VBUSBSEN);
+
+ /* Disable the FS/LS support mode only */
+ if((cfg.speed == USB_OTG_SPEED_FULL)&&
+ (USBx != USB_OTG_FS))
+ {
+ USBx_HOST->HCFG |= USB_OTG_HCFG_FSLSS;
+ }
+ else
+ {
+ USBx_HOST->HCFG &= ~(USB_OTG_HCFG_FSLSS);
+ }
+
+ /* Make sure the FIFOs are flushed. */
+ USB_FlushTxFifo(USBx, 0x10 ); /* all Tx FIFOs */
+ USB_FlushRxFifo(USBx);
+
+ /* Clear all pending HC Interrupts */
+ for (index = 0; index < cfg.Host_channels; index++)
+ {
+ USBx_HC(index)->HCINT = 0xFFFFFFFF;
+ USBx_HC(index)->HCINTMSK = 0;
+ }
+
+ /* Enable VBUS driving */
+ USB_DriveVbus(USBx, 1);
+
+ HAL_Delay(200);
+
+ /* Disable all interrupts. */
+ USBx->GINTMSK = 0;
+
+ /* Clear any pending interrupts */
+ USBx->GINTSTS = 0xFFFFFFFF;
+
+ if(USBx == USB_OTG_FS)
+ {
+ /* set Rx FIFO size */
+ USBx->GRXFSIZ = (uint32_t )0x80;
+ USBx->DIEPTXF0_HNPTXFSIZ = (uint32_t )(((0x60 << 16)& USB_OTG_NPTXFD) | 0x80);
+ USBx->HPTXFSIZ = (uint32_t )(((0x40 << 16)& USB_OTG_HPTXFSIZ_PTXFD) | 0xE0);
+ }
+
+ /* Enable the common interrupts */
+ USBx->GINTMSK |= USB_OTG_GINTMSK_RXFLVLM;
+
+ /* Enable interrupts matching to the Host mode ONLY */
+ USBx->GINTMSK |= (USB_OTG_GINTMSK_PRTIM | USB_OTG_GINTMSK_HCIM |\
+ USB_OTG_GINTMSK_SOFM |USB_OTG_GINTSTS_DISCINT|\
+ USB_OTG_GINTMSK_PXFRM_IISOOXFRM | USB_OTG_GINTMSK_WUIM);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief USB_InitFSLSPClkSel : Initializes the FSLSPClkSel field of the
+ * HCFG register on the PHY type and set the right frame interval
+ * @param USBx : Selected device
+ * @param freq : clock frequency
+ * This parameter can be one of the these values:
+ * HCFG_48_MHZ : Full Speed 48 MHz Clock
+ * HCFG_6_MHZ : Low Speed 6 MHz Clock
+ * @retval HAL status
+ */
+HAL_StatusTypeDef USB_InitFSLSPClkSel(USB_OTG_GlobalTypeDef *USBx , uint8_t freq)
+{
+ USBx_HOST->HCFG &= ~(USB_OTG_HCFG_FSLSPCS);
+ USBx_HOST->HCFG |= (freq & USB_OTG_HCFG_FSLSPCS);
+
+ if (freq == HCFG_48_MHZ)
+ {
+ USBx_HOST->HFIR = (uint32_t)48000;
+ }
+ else if (freq == HCFG_6_MHZ)
+ {
+ USBx_HOST->HFIR = (uint32_t)6000;
+ }
+ return HAL_OK;
+}
+
+/**
+* @brief USB_OTG_ResetPort : Reset Host Port
+ * @param USBx : Selected device
+ * @retval HAL status
+ * @note : (1)The application must wait at least 10 ms
+ * before clearing the reset bit.
+ */
+HAL_StatusTypeDef USB_ResetPort(USB_OTG_GlobalTypeDef *USBx)
+{
+ __IO uint32_t hprt0 = 0;
+
+ hprt0 = USBx_HPRT0;
+
+ hprt0 &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |\
+ USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG );
+
+ USBx_HPRT0 = (USB_OTG_HPRT_PRST | hprt0);
+ HAL_Delay (10); /* See Note #1 */
+ USBx_HPRT0 = ((~USB_OTG_HPRT_PRST) & hprt0);
+ return HAL_OK;
+}
+
+/**
+ * @brief USB_DriveVbus : activate or de-activate vbus
+ * @param state : VBUS state
+ * This parameter can be one of the these values:
+ * 0 : VBUS Active
+ * 1 : VBUS Inactive
+ * @retval HAL status
+*/
+HAL_StatusTypeDef USB_DriveVbus (USB_OTG_GlobalTypeDef *USBx, uint8_t state)
+{
+ __IO uint32_t hprt0 = 0;
+
+ hprt0 = USBx_HPRT0;
+ hprt0 &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |\
+ USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG );
+
+ if (((hprt0 & USB_OTG_HPRT_PPWR) == 0 ) && (state == 1 ))
+ {
+ USBx_HPRT0 = (USB_OTG_HPRT_PPWR | hprt0);
+ }
+ if (((hprt0 & USB_OTG_HPRT_PPWR) == USB_OTG_HPRT_PPWR) && (state == 0 ))
+ {
+ USBx_HPRT0 = ((~USB_OTG_HPRT_PPWR) & hprt0);
+ }
+ return HAL_OK;
+}
+
+/**
+ * @brief Return Host Core speed
+ * @param USBx : Selected device
+ * @retval speed : Host speed
+ * This parameter can be one of the these values:
+ * @arg USB_OTG_SPEED_FULL: Full speed mode
+ * @arg USB_OTG_SPEED_LOW: Low speed mode
+ */
+uint32_t USB_GetHostSpeed (USB_OTG_GlobalTypeDef *USBx)
+{
+ __IO uint32_t hprt0 = 0;
+
+ hprt0 = USBx_HPRT0;
+ return ((hprt0 & USB_OTG_HPRT_PSPD) >> 17);
+}
+
+/**
+ * @brief Return Host Current Frame number
+ * @param USBx : Selected device
+ * @retval current frame number
+*/
+uint32_t USB_GetCurrentFrame (USB_OTG_GlobalTypeDef *USBx)
+{
+ return (USBx_HOST->HFNUM & USB_OTG_HFNUM_FRNUM);
+}
+
+/**
+ * @brief Initialize a host channel
+ * @param USBx : Selected device
+ * @param ch_num : Channel number
+ * This parameter can be a value from 1 to 15
+ * @param epnum : Endpoint number
+ * This parameter can be a value from 1 to 15
+ * @param dev_address : Current device address
+ * This parameter can be a value from 0 to 255
+ * @param speed : Current device speed
+ * This parameter can be one of the these values:
+ * @arg USB_OTG_SPEED_FULL: Full speed mode
+ * @arg USB_OTG_SPEED_LOW: Low speed mode
+ * @param ep_type : Endpoint Type
+ * This parameter can be one of the these values:
+ * @arg EP_TYPE_CTRL: Control type
+ * @arg EP_TYPE_ISOC: Isochronous type
+ * @arg EP_TYPE_BULK: Bulk type
+ * @arg EP_TYPE_INTR: Interrupt type
+ * @param mps : Max Packet Size
+ * This parameter can be a value from 0 to32K
+ * @retval HAL state
+ */
+HAL_StatusTypeDef USB_HC_Init(USB_OTG_GlobalTypeDef *USBx,
+ uint8_t ch_num,
+ uint8_t epnum,
+ uint8_t dev_address,
+ uint8_t speed,
+ uint8_t ep_type,
+ uint16_t mps)
+{
+ /* Clear old interrupt conditions for this host channel. */
+ USBx_HC(ch_num)->HCINT = 0xFFFFFFFF;
+
+ /* Enable channel interrupts required for this transfer. */
+ switch (ep_type)
+ {
+ case EP_TYPE_CTRL:
+ case EP_TYPE_BULK:
+ USBx_HC(ch_num)->HCINTMSK = USB_OTG_HCINTMSK_XFRCM |\
+ USB_OTG_HCINTMSK_STALLM |\
+ USB_OTG_HCINTMSK_TXERRM |\
+ USB_OTG_HCINTMSK_DTERRM |\
+ USB_OTG_HCINTMSK_AHBERR |\
+ USB_OTG_HCINTMSK_NAKM ;
+
+ if (epnum & 0x80)
+ {
+ USBx_HC(ch_num)->HCINTMSK |= USB_OTG_HCINTMSK_BBERRM;
+ }
+ break;
+
+ case EP_TYPE_INTR:
+ USBx_HC(ch_num)->HCINTMSK = USB_OTG_HCINTMSK_XFRCM |\
+ USB_OTG_HCINTMSK_STALLM |\
+ USB_OTG_HCINTMSK_TXERRM |\
+ USB_OTG_HCINTMSK_DTERRM |\
+ USB_OTG_HCINTMSK_NAKM |\
+ USB_OTG_HCINTMSK_AHBERR |\
+ USB_OTG_HCINTMSK_FRMORM ;
+
+ if (epnum & 0x80)
+ {
+ USBx_HC(ch_num)->HCINTMSK |= USB_OTG_HCINTMSK_BBERRM;
+ }
+
+ break;
+
+ case EP_TYPE_ISOC:
+ USBx_HC(ch_num)->HCINTMSK = USB_OTG_HCINTMSK_XFRCM |\
+ USB_OTG_HCINTMSK_ACKM |\
+ USB_OTG_HCINTMSK_AHBERR |\
+ USB_OTG_HCINTMSK_FRMORM ;
+
+ if (epnum & 0x80)
+ {
+ USBx_HC(ch_num)->HCINTMSK |= (USB_OTG_HCINTMSK_TXERRM | USB_OTG_HCINTMSK_BBERRM);
+ }
+ break;
+ }
+
+ /* Enable the top level host channel interrupt. */
+ USBx_HOST->HAINTMSK |= (1 << ch_num);
+
+ /* Make sure host channel interrupts are enabled. */
+ USBx->GINTMSK |= USB_OTG_GINTMSK_HCIM;
+
+ /* Program the HCCHAR register */
+ USBx_HC(ch_num)->HCCHAR = (((dev_address << 22) & USB_OTG_HCCHAR_DAD) |\
+ (((epnum & 0x7F)<< 11) & USB_OTG_HCCHAR_EPNUM)|\
+ ((((epnum & 0x80) == 0x80)<< 15) & USB_OTG_HCCHAR_EPDIR)|\
+ (((speed == HPRT0_PRTSPD_LOW_SPEED)<< 17) & USB_OTG_HCCHAR_LSDEV)|\
+ ((ep_type << 18) & USB_OTG_HCCHAR_EPTYP)|\
+ (mps & USB_OTG_HCCHAR_MPSIZ));
+
+ if (ep_type == EP_TYPE_INTR)
+ {
+ USBx_HC(ch_num)->HCCHAR |= USB_OTG_HCCHAR_ODDFRM ;
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Start a transfer over a host channel
+ * @param USBx : Selected device
+ * @param hc : pointer to host channel structure
+ * @retval HAL state
+ */
+#if defined (__CC_ARM) /*!< ARM Compiler */
+#pragma O0
+#elif defined (__GNUC__) /*!< GNU Compiler */
+#pragma GCC optimize ("O0")
+#endif /* __CC_ARM */
+HAL_StatusTypeDef USB_HC_StartXfer(USB_OTG_GlobalTypeDef *USBx, USB_OTG_HCTypeDef *hc)
+{
+ uint8_t is_oddframe = 0;
+ uint16_t len_words = 0;
+ uint16_t num_packets = 0;
+ uint16_t max_hc_pkt_count = 256;
+ uint32_t tmpreg = 0;
+
+ /* Compute the expected number of packets associated to the transfer */
+ if (hc->xfer_len > 0)
+ {
+ num_packets = (hc->xfer_len + hc->max_packet - 1) / hc->max_packet;
+
+ if (num_packets > max_hc_pkt_count)
+ {
+ num_packets = max_hc_pkt_count;
+ hc->xfer_len = num_packets * hc->max_packet;
+ }
+ }
+ else
+ {
+ num_packets = 1;
+ }
+ if (hc->ep_is_in)
+ {
+ hc->xfer_len = num_packets * hc->max_packet;
+ }
+
+ /* Initialize the HCTSIZn register */
+ USBx_HC(hc->ch_num)->HCTSIZ = (((hc->xfer_len) & USB_OTG_HCTSIZ_XFRSIZ)) |\
+ ((num_packets << 19) & USB_OTG_HCTSIZ_PKTCNT) |\
+ (((hc->data_pid) << 29) & USB_OTG_HCTSIZ_DPID);
+
+ is_oddframe = (USBx_HOST->HFNUM & 0x01) ? 0 : 1;
+ USBx_HC(hc->ch_num)->HCCHAR &= ~USB_OTG_HCCHAR_ODDFRM;
+ USBx_HC(hc->ch_num)->HCCHAR |= (is_oddframe << 29);
+
+ /* Set host channel enable */
+ tmpreg = USBx_HC(hc->ch_num)->HCCHAR;
+ tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
+ tmpreg |= USB_OTG_HCCHAR_CHENA;
+ USBx_HC(hc->ch_num)->HCCHAR = tmpreg;
+
+ if((hc->ep_is_in == 0) && (hc->xfer_len > 0))
+ {
+ switch(hc->ep_type)
+ {
+ /* Non periodic transfer */
+ case EP_TYPE_CTRL:
+ case EP_TYPE_BULK:
+ len_words = (hc->xfer_len + 3) / 4;
+
+ /* check if there is enough space in FIFO space */
+ if(len_words > (USBx->HNPTXSTS & 0xFFFF))
+ {
+ /* need to process data in nptxfempty interrupt */
+ USBx->GINTMSK |= USB_OTG_GINTMSK_NPTXFEM;
+ }
+ break;
+
+ /* Periodic transfer */
+ case EP_TYPE_INTR:
+ case EP_TYPE_ISOC:
+ len_words = (hc->xfer_len + 3) / 4;
+ /* check if there is enough space in FIFO space */
+ if(len_words > (USBx_HOST->HPTXSTS & 0xFFFF)) /* split the transfer */
+ {
+ /* need to process data in ptxfempty interrupt */
+ USBx->GINTMSK |= USB_OTG_GINTMSK_PTXFEM;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ /* Write packet into the Tx FIFO. */
+ USB_WritePacket(USBx, hc->xfer_buff, hc->ch_num, hc->xfer_len);
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Read all host channel interrupts status
+ * @param USBx : Selected device
+ * @retval HAL state
+ */
+uint32_t USB_HC_ReadInterrupt (USB_OTG_GlobalTypeDef *USBx)
+{
+ return ((USBx_HOST->HAINT) & 0xFFFF);
+}
+
+/**
+ * @brief Halt a host channel
+ * @param USBx : Selected device
+ * @param hc_num : Host Channel number
+ * This parameter can be a value from 1 to 15
+ * @retval HAL state
+ */
+HAL_StatusTypeDef USB_HC_Halt(USB_OTG_GlobalTypeDef *USBx , uint8_t hc_num)
+{
+ uint32_t count = 0;
+
+ /* Check for space in the request queue to issue the halt. */
+ if (((USBx_HC(hc_num)->HCCHAR) & (HCCHAR_CTRL << 18)) || ((USBx_HC(hc_num)->HCCHAR) & (HCCHAR_BULK << 18)))
+ {
+ USBx_HC(hc_num)->HCCHAR |= USB_OTG_HCCHAR_CHDIS;
+
+ if ((USBx->HNPTXSTS & 0xFFFF) == 0)
+ {
+ USBx_HC(hc_num)->HCCHAR &= ~USB_OTG_HCCHAR_CHENA;
+ USBx_HC(hc_num)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
+ USBx_HC(hc_num)->HCCHAR &= ~USB_OTG_HCCHAR_EPDIR;
+ do
+ {
+ if (++count > 1000)
+ {
+ break;
+ }
+ }
+ while ((USBx_HC(hc_num)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA);
+ }
+ else
+ {
+ USBx_HC(hc_num)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
+ }
+ }
+ else
+ {
+ USBx_HC(hc_num)->HCCHAR |= USB_OTG_HCCHAR_CHDIS;
+
+ if ((USBx_HOST->HPTXSTS & 0xFFFF) == 0)
+ {
+ USBx_HC(hc_num)->HCCHAR &= ~USB_OTG_HCCHAR_CHENA;
+ USBx_HC(hc_num)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
+ USBx_HC(hc_num)->HCCHAR &= ~USB_OTG_HCCHAR_EPDIR;
+ do
+ {
+ if (++count > 1000)
+ {
+ break;
+ }
+ }
+ while ((USBx_HC(hc_num)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA);
+ }
+ else
+ {
+ USBx_HC(hc_num)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
+ }
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Initiate Do Ping protocol
+ * @param USBx : Selected device
+ * @param hc_num : Host Channel number
+ * This parameter can be a value from 1 to 15
+ * @retval HAL state
+ */
+HAL_StatusTypeDef USB_DoPing(USB_OTG_GlobalTypeDef *USBx , uint8_t ch_num)
+{
+ uint8_t num_packets = 1;
+ uint32_t tmpreg = 0;
+
+ USBx_HC(ch_num)->HCTSIZ = ((num_packets << 19) & USB_OTG_HCTSIZ_PKTCNT) |\
+ USB_OTG_HCTSIZ_DOPING;
+
+ /* Set host channel enable */
+ tmpreg = USBx_HC(ch_num)->HCCHAR;
+ tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
+ tmpreg |= USB_OTG_HCCHAR_CHENA;
+ USBx_HC(ch_num)->HCCHAR = tmpreg;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Stop Host Core
+ * @param USBx : Selected device
+ * @retval HAL state
+ */
+HAL_StatusTypeDef USB_StopHost(USB_OTG_GlobalTypeDef *USBx)
+{
+ uint8_t index;
+ uint32_t count = 0;
+ uint32_t value = 0;
+
+ USB_DisableGlobalInt(USBx);
+
+ /* Flush FIFO */
+ USB_FlushTxFifo(USBx, 0x10);
+ USB_FlushRxFifo(USBx);
+
+ /* Flush out any leftover queued requests. */
+ for (index = 0; index <= 15; index++)
+ {
+ value = USBx_HC(index)->HCCHAR;
+ value |= USB_OTG_HCCHAR_CHDIS;
+ value &= ~USB_OTG_HCCHAR_CHENA;
+ value &= ~USB_OTG_HCCHAR_EPDIR;
+ USBx_HC(index)->HCCHAR = value;
+ }
+
+ /* Halt all channels to put them into a known state. */
+ for (index = 0; index <= 15; index++)
+ {
+ value = USBx_HC(index)->HCCHAR ;
+ value |= USB_OTG_HCCHAR_CHDIS;
+ value |= USB_OTG_HCCHAR_CHENA;
+ value &= ~USB_OTG_HCCHAR_EPDIR;
+ USBx_HC(index)->HCCHAR = value;
+
+ do
+ {
+ if (++count > 1000)
+ {
+ break;
+ }
+ }
+ while ((USBx_HC(index)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA);
+ }
+
+ /* Clear any pending Host interrupts */
+ USBx_HOST->HAINT = 0xFFFFFFFF;
+ USBx->GINTSTS = 0xFFFFFFFF;
+ USB_EnableGlobalInt(USBx);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief USB_ActivateRemoteWakeup : active remote wakeup signalling
+ * @param USBx : Selected device
+ * @retval HAL status
+ */
+HAL_StatusTypeDef USB_ActivateRemoteWakeup(USB_OTG_GlobalTypeDef *USBx)
+{
+ if((USBx_DEVICE->DSTS & USB_OTG_DSTS_SUSPSTS) == USB_OTG_DSTS_SUSPSTS)
+ {
+ /* active Remote wakeup signalling */
+ USBx_DEVICE->DCTL |= USB_OTG_DCTL_RWUSIG;
+ }
+ return HAL_OK;
+}
+
+/**
+ * @brief USB_DeActivateRemoteWakeup : de-active remote wakeup signalling
+ * @param USBx : Selected device
+ * @retval HAL status
+ */
+HAL_StatusTypeDef USB_DeActivateRemoteWakeup(USB_OTG_GlobalTypeDef *USBx)
+{
+ /* active Remote wakeup signalling */
+ USBx_DEVICE->DCTL &= ~(USB_OTG_DCTL_RWUSIG);
+ return HAL_OK;
+}
+
+#endif /* USB_OTG_FS */
+
+/*==============================================================================
+ USB Device FS peripheral available on STM32F102xx and STM32F103xx devices
+==============================================================================*/
+#if defined (USB)
+/**
+ * @brief Initializes the USB Core
+ * @param USBx: USB Instance
+ * @param cfg : pointer to a USB_CfgTypeDef structure that contains
+ * the configuration information for the specified USBx peripheral.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef USB_CoreInit(USB_TypeDef *USBx, USB_CfgTypeDef cfg)
+{
+ /* NOTE : - This function is not required by USB Device FS peripheral, it is used
+ only by USB OTG FS peripheral.
+ - This function is added to ensure compatibility across platforms.
+ */
+ return HAL_OK;
+}
+
+/**
+ * @brief USB_EnableGlobalInt
+ * Enables the controller's Global Int in the AHB Config reg
+ * @param USBx : Selected device
+ * @retval HAL status
+ */
+HAL_StatusTypeDef USB_EnableGlobalInt(USB_TypeDef *USBx)
+{
+ uint32_t winterruptmask = 0;
+
+ /* Set winterruptmask variable */
+ winterruptmask = USB_CNTR_CTRM | USB_CNTR_WKUPM | USB_CNTR_SUSPM | USB_CNTR_ERRM \
+ | USB_CNTR_ESOFM | USB_CNTR_RESETM;
+
+ /* Set interrupt mask */
+ USBx->CNTR |= winterruptmask;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief USB_DisableGlobalInt
+ * Disable the controller's Global Int in the AHB Config reg
+ * @param USBx : Selected device
+ * @retval HAL status
+*/
+HAL_StatusTypeDef USB_DisableGlobalInt(USB_TypeDef *USBx)
+{
+ uint32_t winterruptmask = 0;
+
+ /* Set winterruptmask variable */
+ winterruptmask = USB_CNTR_CTRM | USB_CNTR_WKUPM | USB_CNTR_SUSPM | USB_CNTR_ERRM \
+ | USB_CNTR_ESOFM | USB_CNTR_RESETM;
+
+ /* Clear interrupt mask */
+ USBx->CNTR &= ~winterruptmask;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief USB_SetCurrentMode : Set functional mode
+ * @param USBx : Selected device
+ * @param mode : current core mode
+ * This parameter can be one of the these values:
+ * @arg USB_DEVICE_MODE: Peripheral mode mode
+ * @retval HAL status
+ */
+HAL_StatusTypeDef USB_SetCurrentMode(USB_TypeDef *USBx , USB_ModeTypeDef mode)
+{
+ /* NOTE : - This function is not required by USB Device FS peripheral, it is used
+ only by USB OTG FS peripheral.
+ - This function is added to ensure compatibility across platforms.
+ */
+ return HAL_OK;
+}
+
+/**
+ * @brief USB_DevInit : Initializes the USB controller registers
+ * for device mode
+ * @param USBx : Selected device
+ * @param cfg : pointer to a USB_CfgTypeDef structure that contains
+ * the configuration information for the specified USBx peripheral.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef USB_DevInit (USB_TypeDef *USBx, USB_CfgTypeDef cfg)
+{
+ /* Init Device */
+ /*CNTR_FRES = 1*/
+ USBx->CNTR = USB_CNTR_FRES;
+
+ /*CNTR_FRES = 0*/
+ USBx->CNTR = 0;
+
+ /*Clear pending interrupts*/
+ USBx->ISTR = 0;
+
+ /*Set Btable Address*/
+ USBx->BTABLE = BTABLE_ADDRESS;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief USB_FlushTxFifo : Flush a Tx FIFO
+ * @param USBx : Selected device
+ * @param num : FIFO number
+ * This parameter can be a value from 1 to 15
+ 15 means Flush all Tx FIFOs
+ * @retval HAL status
+ */
+HAL_StatusTypeDef USB_FlushTxFifo (USB_TypeDef *USBx, uint32_t num )
+{
+ /* NOTE : - This function is not required by USB Device FS peripheral, it is used
+ only by USB OTG FS peripheral.
+ - This function is added to ensure compatibility across platforms.
+ */
+ return HAL_OK;
+}
+
+/**
+ * @brief USB_FlushRxFifo : Flush Rx FIFO
+ * @param USBx : Selected device
+ * @retval HAL status
+ */
+HAL_StatusTypeDef USB_FlushRxFifo(USB_TypeDef *USBx)
+{
+ /* NOTE : - This function is not required by USB Device FS peripheral, it is used
+ only by USB OTG FS peripheral.
+ - This function is added to ensure compatibility across platforms.
+ */
+ return HAL_OK;
+}
+
+/**
+ * @brief Activate and configure an endpoint
+ * @param USBx : Selected device
+ * @param ep: pointer to endpoint structure
+ * @retval HAL status
+ */
+HAL_StatusTypeDef USB_ActivateEndpoint(USB_TypeDef *USBx, USB_EPTypeDef *ep)
+{
+ /* initialize Endpoint */
+ switch (ep->type)
+ {
+ case EP_TYPE_CTRL:
+ PCD_SET_EPTYPE(USBx, ep->num, USB_EP_CONTROL);
+ break;
+ case EP_TYPE_BULK:
+ PCD_SET_EPTYPE(USBx, ep->num, USB_EP_BULK);
+ break;
+ case EP_TYPE_INTR:
+ PCD_SET_EPTYPE(USBx, ep->num, USB_EP_INTERRUPT);
+ break;
+ case EP_TYPE_ISOC:
+ PCD_SET_EPTYPE(USBx, ep->num, USB_EP_ISOCHRONOUS);
+ break;
+ default:
+ break;
+ }
+
+ PCD_SET_EP_ADDRESS(USBx, ep->num, ep->num);
+
+ if (ep->doublebuffer == 0)
+ {
+ if (ep->is_in)
+ {
+ /*Set the endpoint Transmit buffer address */
+ PCD_SET_EP_TX_ADDRESS(USBx, ep->num, ep->pmaadress);
+ PCD_CLEAR_TX_DTOG(USBx, ep->num);
+ /* Configure NAK status for the Endpoint*/
+ PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_NAK);
+ }
+ else
+ {
+ /*Set the endpoint Receive buffer address */
+ PCD_SET_EP_RX_ADDRESS(USBx, ep->num, ep->pmaadress);
+ /*Set the endpoint Receive buffer counter*/
+ PCD_SET_EP_RX_CNT(USBx, ep->num, ep->maxpacket);
+ PCD_CLEAR_RX_DTOG(USBx, ep->num);
+ /* Configure VALID status for the Endpoint*/
+ PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID);
+ }
+ }
+ /*Double Buffer*/
+ else
+ {
+ /*Set the endpoint as double buffered*/
+ PCD_SET_EP_DBUF(USBx, ep->num);
+ /*Set buffer address for double buffered mode*/
+ PCD_SET_EP_DBUF_ADDR(USBx, ep->num,ep->pmaaddr0, ep->pmaaddr1);
+
+ if (ep->is_in==0)
+ {
+ /* Clear the data toggle bits for the endpoint IN/OUT*/
+ PCD_CLEAR_RX_DTOG(USBx, ep->num);
+ PCD_CLEAR_TX_DTOG(USBx, ep->num);
+
+ /* Reset value of the data toggle bits for the endpoint out*/
+ PCD_TX_DTOG(USBx, ep->num);
+
+ PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID);
+ PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
+ }
+ else
+ {
+ /* Clear the data toggle bits for the endpoint IN/OUT*/
+ PCD_CLEAR_RX_DTOG(USBx, ep->num);
+ PCD_CLEAR_TX_DTOG(USBx, ep->num);
+ PCD_RX_DTOG(USBx, ep->num);
+ /* Configure DISABLE status for the Endpoint*/
+ PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
+ PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS);
+ }
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief De-activate and de-initialize an endpoint
+ * @param USBx : Selected device
+ * @param ep: pointer to endpoint structure
+ * @retval HAL status
+ */
+HAL_StatusTypeDef USB_DeactivateEndpoint(USB_TypeDef *USBx, USB_EPTypeDef *ep)
+{
+ if (ep->doublebuffer == 0)
+ {
+ if (ep->is_in)
+ {
+ PCD_CLEAR_TX_DTOG(USBx, ep->num);
+ /* Configure DISABLE status for the Endpoint*/
+ PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
+ }
+ else
+ {
+ PCD_CLEAR_RX_DTOG(USBx, ep->num);
+ /* Configure DISABLE status for the Endpoint*/
+ PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS);
+ }
+ }
+ /*Double Buffer*/
+ else
+ {
+ if (ep->is_in==0)
+ {
+ /* Clear the data toggle bits for the endpoint IN/OUT*/
+ PCD_CLEAR_RX_DTOG(USBx, ep->num);
+ PCD_CLEAR_TX_DTOG(USBx, ep->num);
+
+ /* Reset value of the data toggle bits for the endpoint out*/
+ PCD_TX_DTOG(USBx, ep->num);
+
+ PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS);
+ PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
+ }
+ else
+ {
+ /* Clear the data toggle bits for the endpoint IN/OUT*/
+ PCD_CLEAR_RX_DTOG(USBx, ep->num);
+ PCD_CLEAR_TX_DTOG(USBx, ep->num);
+ PCD_RX_DTOG(USBx, ep->num);
+ /* Configure DISABLE status for the Endpoint*/
+ PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
+ PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS);
+ }
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief USB_EPStartXfer : setup and starts a transfer over an EP
+ * @param USBx : Selected device
+ * @param ep: pointer to endpoint structure
+ * @retval HAL status
+ */
+HAL_StatusTypeDef USB_EPStartXfer(USB_TypeDef *USBx , USB_EPTypeDef *ep)
+{
+ uint16_t pmabuffer = 0;
+ uint32_t len = ep->xfer_len;
+
+ /* IN endpoint */
+ if (ep->is_in == 1)
+ {
+ /*Multi packet transfer*/
+ if (ep->xfer_len > ep->maxpacket)
+ {
+ len=ep->maxpacket;
+ ep->xfer_len-=len;
+ }
+ else
+ {
+ len=ep->xfer_len;
+ ep->xfer_len =0;
+ }
+
+ /* configure and validate Tx endpoint */
+ if (ep->doublebuffer == 0)
+ {
+ USB_WritePMA(USBx, ep->xfer_buff, ep->pmaadress, len);
+ PCD_SET_EP_TX_CNT(USBx, ep->num, len);
+ }
+ else
+ {
+ /* Write the data to the USB endpoint */
+ if (PCD_GET_ENDPOINT(USBx, ep->num)& USB_EP_DTOG_TX)
+ {
+ /* Set the Double buffer counter for pmabuffer1 */
+ PCD_SET_EP_DBUF1_CNT(USBx, ep->num, ep->is_in, len);
+ pmabuffer = ep->pmaaddr1;
+ }
+ else
+ {
+ /* Set the Double buffer counter for pmabuffer0 */
+ PCD_SET_EP_DBUF0_CNT(USBx, ep->num, ep->is_in, len);
+ pmabuffer = ep->pmaaddr0;
+ }
+ USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, len);
+ PCD_FreeUserBuffer(USBx, ep->num, ep->is_in);
+ }
+
+ PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_VALID);
+ }
+ else /* OUT endpoint */
+ {
+ /* Multi packet transfer*/
+ if (ep->xfer_len > ep->maxpacket)
+ {
+ len=ep->maxpacket;
+ ep->xfer_len-=len;
+ }
+ else
+ {
+ len=ep->xfer_len;
+ ep->xfer_len =0;
+ }
+
+ /* configure and validate Rx endpoint */
+ if (ep->doublebuffer == 0)
+ {
+ /*Set RX buffer count*/
+ PCD_SET_EP_RX_CNT(USBx, ep->num, len);
+ }
+ else
+ {
+ /*Set the Double buffer counter*/
+ PCD_SET_EP_DBUF_CNT(USBx, ep->num, ep->is_in, len);
+ }
+
+ PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID);
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief USB_WritePacket : Writes a packet into the Tx FIFO associated
+ * with the EP/channel
+ * @param USBx : Selected device
+ * @param src : pointer to source buffer
+ * @param ch_ep_num : endpoint or host channel number
+ * @param len : Number of bytes to write
+ * @retval HAL status
+ */
+HAL_StatusTypeDef USB_WritePacket(USB_TypeDef *USBx, uint8_t *src, uint8_t ch_ep_num, uint16_t len)
+{
+ /* NOTE : - This function is not required by USB Device FS peripheral, it is used
+ only by USB OTG FS peripheral.
+ - This function is added to ensure compatibility across platforms.
+ */
+ return HAL_OK;
+}
+
+/**
+ * @brief USB_ReadPacket : read a packet from the Tx FIFO associated
+ * with the EP/channel
+ * @param USBx : Selected device
+ * @param dest : destination pointer
+ * @param len : Number of bytes to read
+ * @retval pointer to destination buffer
+ */
+void *USB_ReadPacket(USB_TypeDef *USBx, uint8_t *dest, uint16_t len)
+{
+ /* NOTE : - This function is not required by USB Device FS peripheral, it is used
+ only by USB OTG FS peripheral.
+ - This function is added to ensure compatibility across platforms.
+ */
+ return ((void *)NULL);
+}
+
+/**
+ * @brief USB_EPSetStall : set a stall condition over an EP
+ * @param USBx : Selected device
+ * @param ep: pointer to endpoint structure
+ * @retval HAL status
+ */
+HAL_StatusTypeDef USB_EPSetStall(USB_TypeDef *USBx , USB_EPTypeDef *ep)
+{
+ if (ep->num == 0)
+ {
+ /* This macro sets STALL status for RX & TX*/
+ PCD_SET_EP_TXRX_STATUS(USBx, ep->num, USB_EP_RX_STALL, USB_EP_TX_STALL);
+ }
+ else
+ {
+ if (ep->is_in)
+ {
+ PCD_SET_EP_TX_STATUS(USBx, ep->num , USB_EP_TX_STALL);
+ }
+ else
+ {
+ PCD_SET_EP_RX_STATUS(USBx, ep->num , USB_EP_RX_STALL);
+ }
+ }
+ return HAL_OK;
+}
+
+/**
+ * @brief USB_EPClearStall : Clear a stall condition over an EP
+ * @param USBx : Selected device
+ * @param ep: pointer to endpoint structure
+ * @retval HAL status
+ */
+HAL_StatusTypeDef USB_EPClearStall(USB_TypeDef *USBx, USB_EPTypeDef *ep)
+{
+ if (ep->is_in)
+ {
+ PCD_CLEAR_TX_DTOG(USBx, ep->num);
+ PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_VALID);
+ }
+ else
+ {
+ PCD_CLEAR_RX_DTOG(USBx, ep->num);
+ PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID);
+ }
+ return HAL_OK;
+}
+
+/**
+ * @brief USB_StopDevice : Stop the usb device mode
+ * @param USBx : Selected device
+ * @retval HAL status
+ */
+HAL_StatusTypeDef USB_StopDevice(USB_TypeDef *USBx)
+{
+ /* disable all interrupts and force USB reset */
+ USBx->CNTR = USB_CNTR_FRES;
+
+ /* clear interrupt status register */
+ USBx->ISTR = 0;
+
+ /* switch-off device */
+ USBx->CNTR = (USB_CNTR_FRES | USB_CNTR_PDWN);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief USB_SetDevAddress : Stop the usb device mode
+ * @param USBx : Selected device
+ * @param address : new device address to be assigned
+ * This parameter can be a value from 0 to 255
+ * @retval HAL status
+ */
+HAL_StatusTypeDef USB_SetDevAddress (USB_TypeDef *USBx, uint8_t address)
+{
+ if(address == 0)
+ {
+ /* set device address and enable function */
+ USBx->DADDR = USB_DADDR_EF;
+ }
+
+ return HAL_OK;
+}
+
+/**
+ * @brief USB_DevConnect : Connect the USB device by enabling the pull-up/pull-down
+ * @param USBx : Selected device
+ * @retval HAL status
+ */
+HAL_StatusTypeDef USB_DevConnect (USB_TypeDef *USBx)
+{
+ /* NOTE : - This function is not required by USB Device FS peripheral, it is used
+ only by USB OTG FS peripheral.
+ - This function is added to ensure compatibility across platforms.
+ */
+ return HAL_OK;
+}
+
+/**
+ * @brief USB_DevDisconnect : Disconnect the USB device by disabling the pull-up/pull-down
+ * @param USBx : Selected device
+ * @retval HAL status
+ */
+HAL_StatusTypeDef USB_DevDisconnect (USB_TypeDef *USBx)
+{
+ /* NOTE : - This function is not required by USB Device FS peripheral, it is used
+ only by USB OTG FS peripheral.
+ - This function is added to ensure compatibility across platforms.
+ */
+ return HAL_OK;
+}
+
+/**
+ * @brief USB_ReadInterrupts: return the global USB interrupt status
+ * @param USBx : Selected device
+ * @retval HAL status
+ */
+uint32_t USB_ReadInterrupts (USB_TypeDef *USBx)
+{
+ uint32_t tmpreg = 0;
+
+ tmpreg = USBx->ISTR;
+ return tmpreg;
+}
+
+/**
+ * @brief USB_ReadDevAllOutEpInterrupt: return the USB device OUT endpoints interrupt status
+ * @param USBx : Selected device
+ * @retval HAL status
+ */
+uint32_t USB_ReadDevAllOutEpInterrupt (USB_TypeDef *USBx)
+{
+ /* NOTE : - This function is not required by USB Device FS peripheral, it is used
+ only by USB OTG FS peripheral.
+ - This function is added to ensure compatibility across platforms.
+ */
+ return (0);
+}
+
+/**
+ * @brief USB_ReadDevAllInEpInterrupt: return the USB device IN endpoints interrupt status
+ * @param USBx : Selected device
+ * @retval HAL status
+ */
+uint32_t USB_ReadDevAllInEpInterrupt (USB_TypeDef *USBx)
+{
+ /* NOTE : - This function is not required by USB Device FS peripheral, it is used
+ only by USB OTG FS peripheral.
+ - This function is added to ensure compatibility across platforms.
+ */
+ return (0);
+}
+
+/**
+ * @brief Returns Device OUT EP Interrupt register
+ * @param USBx : Selected device
+ * @param epnum : endpoint number
+ * This parameter can be a value from 0 to 15
+ * @retval Device OUT EP Interrupt register
+ */
+uint32_t USB_ReadDevOutEPInterrupt (USB_TypeDef *USBx , uint8_t epnum)
+{
+ /* NOTE : - This function is not required by USB Device FS peripheral, it is used
+ only by USB OTG FS peripheral.
+ - This function is added to ensure compatibility across platforms.
+ */
+ return (0);
+}
+
+/**
+ * @brief Returns Device IN EP Interrupt register
+ * @param USBx : Selected device
+ * @param epnum : endpoint number
+ * This parameter can be a value from 0 to 15
+ * @retval Device IN EP Interrupt register
+ */
+uint32_t USB_ReadDevInEPInterrupt (USB_TypeDef *USBx , uint8_t epnum)
+{
+ /* NOTE : - This function is not required by USB Device FS peripheral, it is used
+ only by USB OTG FS peripheral.
+ - This function is added to ensure compatibility across platforms.
+ */
+ return (0);
+}
+
+/**
+ * @brief USB_ClearInterrupts: clear a USB interrupt
+ * @param USBx : Selected device
+ * @param interrupt : interrupt flag
+ * @retval None
+ */
+void USB_ClearInterrupts (USB_TypeDef *USBx, uint32_t interrupt)
+{
+ /* NOTE : - This function is not required by USB Device FS peripheral, it is used
+ only by USB OTG FS peripheral.
+ - This function is added to ensure compatibility across platforms.
+ */
+}
+
+/**
+ * @brief Prepare the EP0 to start the first control setup
+ * @param USBx : Selected device
+ * @param psetup : pointer to setup packet
+ * @retval HAL status
+ */
+HAL_StatusTypeDef USB_EP0_OutStart(USB_TypeDef *USBx, uint8_t *psetup)
+{
+ /* NOTE : - This function is not required by USB Device FS peripheral, it is used
+ only by USB OTG FS peripheral.
+ - This function is added to ensure compatibility across platforms.
+ */
+ return HAL_OK;
+}
+
+/**
+ * @brief USB_ActivateRemoteWakeup : active remote wakeup signalling
+ * @param USBx : Selected device
+ * @retval HAL status
+ */
+HAL_StatusTypeDef USB_ActivateRemoteWakeup(USB_TypeDef *USBx)
+{
+ USBx->CNTR |= USB_CNTR_RESUME;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief USB_DeActivateRemoteWakeup : de-active remote wakeup signalling
+ * @param USBx : Selected device
+ * @retval HAL status
+ */
+HAL_StatusTypeDef USB_DeActivateRemoteWakeup(USB_TypeDef *USBx)
+{
+ USBx->CNTR &= ~(USB_CNTR_RESUME);
+ return HAL_OK;
+}
+
+/**
+ * @brief Copy a buffer from user memory area to packet memory area (PMA)
+ * @param USBx : pointer to USB register.
+ * @param pbUsrBuf : pointer to user memory area.
+ * @param wPMABufAddr : address into PMA.
+ * @param wNBytes : number of bytes to be copied.
+ * @retval None
+ */
+void USB_WritePMA(USB_TypeDef *USBx, uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes)
+{
+ uint32_t nbytes = (wNBytes + 1) >> 1; /* nbytes = (wNBytes + 1) / 2 */
+ uint32_t index = 0, temp1 = 0, temp2 = 0;
+ uint16_t *pdwVal = NULL;
+
+ pdwVal = (uint16_t *)(wPMABufAddr * 2 + (uint32_t)USBx + 0x400);
+ for (index = nbytes; index != 0; index--)
+ {
+ temp1 = (uint16_t) * pbUsrBuf;
+ pbUsrBuf++;
+ temp2 = temp1 | (uint16_t) * pbUsrBuf << 8;
+ *pdwVal++ = temp2;
+ pdwVal++;
+ pbUsrBuf++;
+ }
+}
+
+/**
+ * @brief Copy a buffer from user memory area to packet memory area (PMA)
+ * @param USBx : pointer to USB register.
+* @param pbUsrBuf : pointer to user memory area.
+ * @param wPMABufAddr : address into PMA.
+ * @param wNBytes : number of bytes to be copied.
+ * @retval None
+ */
+void USB_ReadPMA(USB_TypeDef *USBx, uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes)
+{
+ uint32_t nbytes = (wNBytes + 1) >> 1;/* /2*/
+ uint32_t index = 0;
+ uint32_t *pdwVal = NULL;
+
+ pdwVal = (uint32_t *)(wPMABufAddr * 2 + (uint32_t)USBx + 0x400);
+ for (index = nbytes; index != 0; index--)
+ {
+ *(uint16_t*)pbUsrBuf++ = *pdwVal++;
+ pbUsrBuf++;
+ }
+}
+
+#endif /* USB */
+
+/**
+ * @}
+ */
+/**
+ * @}
+ */
+
+#if defined (USB_OTG_FS)
+/** @addtogroup USB_LL_Private_Functions
+ * @{
+ */
+/**
+ * @brief Reset the USB Core (needed after USB clock settings change)
+ * @param USBx : Selected device
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef USB_CoreReset(USB_OTG_GlobalTypeDef *USBx)
+{
+ uint32_t count = 0;
+
+ /* Wait for AHB master IDLE state. */
+ do
+ {
+ if (++count > 200000)
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+ while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0);
+
+ /* Core Soft Reset */
+ count = 0;
+ USBx->GRSTCTL |= USB_OTG_GRSTCTL_CSRST;
+
+ do
+ {
+ if (++count > 200000)
+ {
+ return HAL_TIMEOUT;
+ }
+ }
+ while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_CSRST) == USB_OTG_GRSTCTL_CSRST);
+
+ return HAL_OK;
+}
+/**
+ * @}
+ */
+#endif /* USB_OTG_FS */
+
+#endif /* STM32F102x6 || STM32F102xB || */
+ /* STM32F103x6 || STM32F103xB || */
+ /* STM32F103xE || STM32F103xG || */
+ /* STM32F105xC || STM32F107xC */
+
+#endif /* defined (HAL_PCD_MODULE_ENABLED) || defined (HAL_HCD_MODULE_ENABLED) */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/