init commit

This commit is contained in:
Charlez Kwan 2020-01-15 18:02:31 +01:00
commit 441d75b3bd
88 changed files with 86448 additions and 0 deletions

View file

@ -0,0 +1,595 @@
/**
******************************************************************************
* @file stm32f1xx_hal.c
* @author MCD Application Team
* @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 V1.1.3
*/
#define __STM32F1xx_HAL_VERSION_MAIN (0x01U) /*!< [31:24] main version */
#define __STM32F1xx_HAL_VERSION_SUB1 (0x01U) /*!< [23:16] sub1 version */
#define __STM32F1xx_HAL_VERSION_SUB2 (0x03U) /*!< [15:8] sub2 version */
#define __STM32F1xx_HAL_VERSION_RC (0x00U) /*!< [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 0x00000FFFU
/**
* @}
*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/** @defgroup HAL_Private_Variables HAL Private Variables
* @{
*/
__IO uint32_t uwTick;
uint32_t uwTickPrio = (1UL << __NVIC_PRIO_BITS); /* Invalid PRIO */
HAL_TickFreqTypeDef uwTickFreq = HAL_TICK_FREQ_DEFAULT; /* 1KHz */
/**
* @}
*/
/* 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 systick 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 is used to initialize the HAL Library; it must be the first
* instruction to be executed in the main program (before to call any other
* HAL function), it performs the following:
* Configure the Flash prefetch.
* Configures the SysTick to generate an interrupt each 1 millisecond,
* which is clocked by the HSI (at this stage, the clock is not yet
* configured and thus the system is running from the internal HSI at 16 MHz).
* Set NVIC Group Priority to 4.
* Calls the HAL_MspInit() callback function defined in user file
* "stm32f1xx_hal_msp.c" to do the global low level hardware initialization
*
* @note SysTick is used as time base for the HAL_Delay() function, the application
* need to ensure that the SysTick time base is always set to 1 millisecond
* to have correct HAL operation.
* @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 HSI) */
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 systick.
* 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 Initialize 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 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*/
if (HAL_SYSTICK_Config(SystemCoreClock / (1000U / uwTickFreq)) > 0U)
{
return HAL_ERROR;
}
/* Configure the SysTick IRQ priority */
if (TickPriority < (1UL << __NVIC_PRIO_BITS))
{
HAL_NVIC_SetPriority(SysTick_IRQn, TickPriority, 0U);
uwTickPrio = TickPriority;
}
else
{
return HAL_ERROR;
}
/* 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 += uwTickFreq;
}
/**
* @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 returns a tick priority.
* @retval tick priority
*/
uint32_t HAL_GetTickPrio(void)
{
return uwTickPrio;
}
/**
* @brief Set new tick Freq.
* @retval Status
*/
HAL_StatusTypeDef HAL_SetTickFreq(HAL_TickFreqTypeDef Freq)
{
HAL_StatusTypeDef status = HAL_OK;
assert_param(IS_TICKFREQ(Freq));
if (uwTickFreq != Freq)
{
uwTickFreq = Freq;
/* Apply the new tick Freq */
status = HAL_InitTick(uwTickPrio);
}
return status;
}
/**
* @brief Return tick frequency.
* @retval tick period in Hz
*/
HAL_TickFreqTypeDef HAL_GetTickFreq(void)
{
return uwTickFreq;
}
/**
* @brief This function provides minimum 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(uint32_t Delay)
{
uint32_t tickstart = HAL_GetTick();
uint32_t wait = Delay;
/* Add a freq to guarantee minimum wait */
if (wait < HAL_MAX_DELAY)
{
wait += (uint32_t)(uwTickFreq);
}
while ((HAL_GetTick() - tickstart) < wait)
{
}
}
/**
* @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 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 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 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) >> DBGMCU_IDCODE_REV_ID_Pos);
}
/**
* @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);
}
/**
* @brief Return the unique device identifier (UID based on 96 bits)
* @param UID pointer to 3 words array.
* @retval Device identifier
*/
void HAL_GetUID(uint32_t *UID)
{
UID[0] = (uint32_t)(READ_REG(*((uint32_t *)UID_BASE)));
UID[1] = (uint32_t)(READ_REG(*((uint32_t *)(UID_BASE + 4U))));
UID[2] = (uint32_t)(READ_REG(*((uint32_t *)(UID_BASE + 8U))));
}
/**
* @}
*/
/**
* @}
*/
#endif /* HAL_MODULE_ENABLED */
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View file

@ -0,0 +1,521 @@
/**
******************************************************************************
* @file stm32f1xx_hal_cortex.c
* @author MCD Application Team
* @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 provides 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.
(#) Configure the priority of the selected IRQ Channels using HAL_NVIC_SetPriority().
(#) Enable the selected IRQ Channels using HAL_NVIC_EnableIRQ().
(#) please refer to programming manual for details in how to configure priority.
-@- When the NVIC_PRIORITYGROUP_0 is selected, IRQ preemption 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 preemption priority
(+@) Lowest sub priority
(+@) Lowest hardware priority (IRQ number)
[..]
*** How to configure Systick using CORTEX HAL driver ***
========================================================
[..]
Setup SysTick Timer for time base.
(+) 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 macro
__HAL_CORTEX_SYSTICKCLK_CONFIG(SYSTICK_CLKSOURCE_HCLK_DIV8) just after the
HAL_SYSTICK_Config() function call. The __HAL_CORTEX_SYSTICKCLK_CONFIG() macro is defined
inside the stm32f1xx_hal_cortex.h file.
(+) 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) 2017 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 types -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private constants ---------------------------------------------------------*/
/* Private macros ------------------------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/* Exported 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 provides the CORTEX HAL driver functions allowing to configure Interrupts
Systick functionalities
@endverbatim
* @{
*/
/**
* @brief Sets the priority grouping field (preemption 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 preemption priority
* 4 bits for subpriority
* @arg NVIC_PRIORITYGROUP_1: 1 bits for preemption priority
* 3 bits for subpriority
* @arg NVIC_PRIORITYGROUP_2: 2 bits for preemption priority
* 2 bits for subpriority
* @arg NVIC_PRIORITYGROUP_3: 3 bits for preemption priority
* 1 bits for subpriority
* @arg NVIC_PRIORITYGROUP_4: 4 bits for preemption priority
* 0 bits for subpriority
* @note When the NVIC_PriorityGroup_0 is selected, IRQ preemption 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 (stm32f10xx.h))
* @param PreemptPriority: The preemption 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 = 0x00U;
/* 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 == 1U)
/**
* @brief Disables the MPU
* @retval None
*/
void HAL_MPU_Disable(void)
{
/* Make sure outstanding transfers are done */
__DMB();
/* Disable fault exceptions */
SCB->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk;
/* Disable the MPU and clear the control register*/
MPU->CTRL = 0U;
}
/**
* @brief Enable the MPU.
* @param MPU_Control: Specifies the control mode of the MPU during hard fault,
* NMI, FAULTMASK and privileged access to the default memory
* This parameter can be one of the following values:
* @arg MPU_HFNMI_PRIVDEF_NONE
* @arg MPU_HARDFAULT_NMI
* @arg MPU_PRIVILEGED_DEFAULT
* @arg MPU_HFNMI_PRIVDEF
* @retval None
*/
void HAL_MPU_Enable(uint32_t MPU_Control)
{
/* Enable the MPU */
MPU->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk;
/* Enable fault exceptions */
SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk;
/* Ensure MPU setting take effects */
__DSB();
__ISB();
}
/**
* @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 = 0x00U;
MPU->RASR = 0x00U;
}
}
#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 preemption priority
* 4 bits for subpriority
* @arg NVIC_PRIORITYGROUP_1: 1 bits for preemption priority
* 3 bits for subpriority
* @arg NVIC_PRIORITYGROUP_2: 2 bits for preemption priority
* 2 bits for subpriority
* @arg NVIC_PRIORITYGROUP_3: 3 bits for preemption priority
* 1 bits for subpriority
* @arg NVIC_PRIORITYGROUP_4: 4 bits for preemption 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)
{
/* Check the parameters */
assert_param(IS_NVIC_DEVICE_IRQ(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)
{
/* Check the parameters */
assert_param(IS_NVIC_DEVICE_IRQ(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)
{
/* Check the parameters */
assert_param(IS_NVIC_DEVICE_IRQ(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)
{
/* Check the parameters */
assert_param(IS_NVIC_DEVICE_IRQ(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****/

View file

@ -0,0 +1,902 @@
/**
******************************************************************************
* @file stm32f1xx_hal_dma.c
* @author MCD Application Team
* @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 the Reference manual for connection between peripherals
and DMA requests.
(#) For a given Channel, program the required configuration through the following parameters:
Channel request, 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_DMA_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) 2017 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 ------------------------------------------------------------*/
/* 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 Initialize the DMA according to the specified
* parameters in the DMA_InitTypeDef and initialize 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 = 0U;
/* 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 defined (STM32F101xE) || defined (STM32F101xG) || defined (STM32F103xE) || defined (STM32F103xG) || defined (STM32F100xE) || defined (STM32F105xC) || defined (STM32F107xC)
/* calculation of the channel index */
if ((uint32_t)(hdma->Instance) < (uint32_t)(DMA2_Channel1))
{
/* DMA1 */
hdma->ChannelIndex = (((uint32_t)hdma->Instance - (uint32_t)DMA1_Channel1) / ((uint32_t)DMA1_Channel2 - (uint32_t)DMA1_Channel1)) << 2;
hdma->DmaBaseAddress = DMA1;
}
else
{
/* DMA2 */
hdma->ChannelIndex = (((uint32_t)hdma->Instance - (uint32_t)DMA2_Channel1) / ((uint32_t)DMA2_Channel2 - (uint32_t)DMA2_Channel1)) << 2;
hdma->DmaBaseAddress = DMA2;
}
#else
/* DMA1 */
hdma->ChannelIndex = (((uint32_t)hdma->Instance - (uint32_t)DMA1_Channel1) / ((uint32_t)DMA1_Channel2 - (uint32_t)DMA1_Channel1)) << 2;
hdma->DmaBaseAddress = DMA1;
#endif /* STM32F101xE || STM32F101xG || STM32F103xE || STM32F103xG || STM32F100xE || STM32F105xC || STM32F107xC */
/* 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 and 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;
/* Allocate lock resource and initialize it */
hdma->Lock = HAL_UNLOCKED;
return HAL_OK;
}
/**
* @brief DeInitialize 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));
/* Disable the selected DMA Channelx */
__HAL_DMA_DISABLE(hdma);
/* Reset DMA Channel control register */
hdma->Instance->CCR = 0U;
/* Reset DMA Channel Number of Data to Transfer register */
hdma->Instance->CNDTR = 0U;
/* Reset DMA Channel peripheral address register */
hdma->Instance->CPAR = 0U;
/* Reset DMA Channel memory address register */
hdma->Instance->CMAR = 0U;
#if defined (STM32F101xE) || defined (STM32F101xG) || defined (STM32F103xE) || defined (STM32F103xG) || defined (STM32F100xE) || defined (STM32F105xC) || defined (STM32F107xC)
/* calculation of the channel index */
if ((uint32_t)(hdma->Instance) < (uint32_t)(DMA2_Channel1))
{
/* DMA1 */
hdma->ChannelIndex = (((uint32_t)hdma->Instance - (uint32_t)DMA1_Channel1) / ((uint32_t)DMA1_Channel2 - (uint32_t)DMA1_Channel1)) << 2;
hdma->DmaBaseAddress = DMA1;
}
else
{
/* DMA2 */
hdma->ChannelIndex = (((uint32_t)hdma->Instance - (uint32_t)DMA2_Channel1) / ((uint32_t)DMA2_Channel2 - (uint32_t)DMA2_Channel1)) << 2;
hdma->DmaBaseAddress = DMA2;
}
#else
/* DMA1 */
hdma->ChannelIndex = (((uint32_t)hdma->Instance - (uint32_t)DMA1_Channel1) / ((uint32_t)DMA1_Channel2 - (uint32_t)DMA1_Channel1)) << 2;
hdma->DmaBaseAddress = DMA1;
#endif /* STM32F101xE || STM32F101xG || STM32F103xE || STM32F103xG || STM32F100xE || STM32F105xC || STM32F107xC */
/* Clear all flags */
hdma->DmaBaseAddress->IFCR = (DMA_ISR_GIF1 << (hdma->ChannelIndex));
/* Clean all callbacks */
hdma->XferCpltCallback = NULL;
hdma->XferHalfCpltCallback = NULL;
hdma->XferErrorCallback = NULL;
hdma->XferAbortCallback = NULL;
/* Reset the error code */
hdma->ErrorCode = HAL_DMA_ERROR_NONE;
/* Reset 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 Input and Output 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 Start 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)
{
HAL_StatusTypeDef status = HAL_OK;
/* Check the parameters */
assert_param(IS_DMA_BUFFER_SIZE(DataLength));
/* Process locked */
__HAL_LOCK(hdma);
if(HAL_DMA_STATE_READY == hdma->State)
{
/* Change DMA peripheral state */
hdma->State = HAL_DMA_STATE_BUSY;
hdma->ErrorCode = HAL_DMA_ERROR_NONE;
/* Disable the peripheral */
__HAL_DMA_DISABLE(hdma);
/* Configure the source, destination address and the data length & clear flags*/
DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength);
/* Enable the Peripheral */
__HAL_DMA_ENABLE(hdma);
}
else
{
/* Process Unlocked */
__HAL_UNLOCK(hdma);
status = HAL_BUSY;
}
return status;
}
/**
* @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)
{
HAL_StatusTypeDef status = HAL_OK;
/* Check the parameters */
assert_param(IS_DMA_BUFFER_SIZE(DataLength));
/* Process locked */
__HAL_LOCK(hdma);
if(HAL_DMA_STATE_READY == hdma->State)
{
/* Change DMA peripheral state */
hdma->State = HAL_DMA_STATE_BUSY;
hdma->ErrorCode = HAL_DMA_ERROR_NONE;
/* Disable the peripheral */
__HAL_DMA_DISABLE(hdma);
/* Configure the source, destination address and the data length & clear flags*/
DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength);
/* Enable the transfer complete interrupt */
/* Enable the transfer Error interrupt */
if(NULL != hdma->XferHalfCpltCallback)
{
/* Enable the Half transfer complete interrupt as well */
__HAL_DMA_ENABLE_IT(hdma, (DMA_IT_TC | DMA_IT_HT | DMA_IT_TE));
}
else
{
__HAL_DMA_DISABLE_IT(hdma, DMA_IT_HT);
__HAL_DMA_ENABLE_IT(hdma, (DMA_IT_TC | DMA_IT_TE));
}
/* Enable the Peripheral */
__HAL_DMA_ENABLE(hdma);
}
else
{
/* Process Unlocked */
__HAL_UNLOCK(hdma);
/* Remain BUSY */
status = HAL_BUSY;
}
return status;
}
/**
* @brief Abort the DMA Transfer.
* @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_Abort(DMA_HandleTypeDef *hdma)
{
HAL_StatusTypeDef status = HAL_OK;
/* Disable DMA IT */
__HAL_DMA_DISABLE_IT(hdma, (DMA_IT_TC | DMA_IT_HT | DMA_IT_TE));
/* Disable the channel */
__HAL_DMA_DISABLE(hdma);
/* Clear all flags */
hdma->DmaBaseAddress->IFCR = (DMA_ISR_GIF1 << hdma->ChannelIndex);
/* Change the DMA state */
hdma->State = HAL_DMA_STATE_READY;
/* Process Unlocked */
__HAL_UNLOCK(hdma);
return status;
}
/**
* @brief Aborts the DMA Transfer in Interrupt mode.
* @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_Abort_IT(DMA_HandleTypeDef *hdma)
{
HAL_StatusTypeDef status = HAL_OK;
if(HAL_DMA_STATE_BUSY != hdma->State)
{
/* no transfer ongoing */
hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER;
status = HAL_ERROR;
}
else
{
/* Disable DMA IT */
__HAL_DMA_DISABLE_IT(hdma, (DMA_IT_TC | DMA_IT_HT | DMA_IT_TE));
/* Disable the channel */
__HAL_DMA_DISABLE(hdma);
/* Clear all flags */
__HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_GI_FLAG_INDEX(hdma));
/* Change the DMA state */
hdma->State = HAL_DMA_STATE_READY;
/* Process Unlocked */
__HAL_UNLOCK(hdma);
/* Call User Abort callback */
if(hdma->XferAbortCallback != NULL)
{
hdma->XferAbortCallback(hdma);
}
}
return status;
}
/**
* @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 = 0U;
if(HAL_DMA_STATE_BUSY != hdma->State)
{
/* no transfer ongoing */
hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER;
__HAL_UNLOCK(hdma);
return HAL_ERROR;
}
/* Polling mode not supported in circular mode */
if (RESET != (hdma->Instance->CCR & DMA_CCR_CIRC))
{
hdma->ErrorCode = HAL_DMA_ERROR_NOT_SUPPORTED;
return HAL_ERROR;
}
/* 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))
{
/* When a DMA transfer error occurs */
/* A hardware clear of its EN bits is performed */
/* Clear all flags */
hdma->DmaBaseAddress->IFCR = (DMA_ISR_GIF1 << hdma->ChannelIndex);
/* Update error code */
SET_BIT(hdma->ErrorCode, HAL_DMA_ERROR_TE);
/* Change the DMA state */
hdma->State= HAL_DMA_STATE_READY;
/* Process Unlocked */
__HAL_UNLOCK(hdma);
return HAL_ERROR;
}
/* Check for the Timeout */
if(Timeout != HAL_MAX_DELAY)
{
if((Timeout == 0U) || ((HAL_GetTick() - tickstart) > Timeout))
{
/* Update error code */
SET_BIT(hdma->ErrorCode, HAL_DMA_ERROR_TIMEOUT);
/* Change the DMA state */
hdma->State = HAL_DMA_STATE_READY;
/* Process Unlocked */
__HAL_UNLOCK(hdma);
return HAL_ERROR;
}
}
}
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));
}
/* 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)
{
uint32_t flag_it = hdma->DmaBaseAddress->ISR;
uint32_t source_it = hdma->Instance->CCR;
/* Half Transfer Complete Interrupt management ******************************/
if (((flag_it & (DMA_FLAG_HT1 << hdma->ChannelIndex)) != RESET) && ((source_it & DMA_IT_HT) != RESET))
{
/* Disable the half transfer interrupt if the DMA mode is not CIRCULAR */
if((hdma->Instance->CCR & DMA_CCR_CIRC) == 0U)
{
/* 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));
/* DMA peripheral state is not updated in Half Transfer */
/* but in Transfer Complete case */
if(hdma->XferHalfCpltCallback != NULL)
{
/* Half transfer callback */
hdma->XferHalfCpltCallback(hdma);
}
}
/* Transfer Complete Interrupt management ***********************************/
else if (((flag_it & (DMA_FLAG_TC1 << hdma->ChannelIndex)) != RESET) && ((source_it & DMA_IT_TC) != RESET))
{
if((hdma->Instance->CCR & DMA_CCR_CIRC) == 0U)
{
/* Disable the transfer complete and error interrupt */
__HAL_DMA_DISABLE_IT(hdma, DMA_IT_TE | DMA_IT_TC);
/* Change the DMA state */
hdma->State = HAL_DMA_STATE_READY;
}
/* Clear the transfer complete flag */
__HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma));
/* Process Unlocked */
__HAL_UNLOCK(hdma);
if(hdma->XferCpltCallback != NULL)
{
/* Transfer complete callback */
hdma->XferCpltCallback(hdma);
}
}
/* Transfer Error Interrupt management **************************************/
else if (( RESET != (flag_it & (DMA_FLAG_TE1 << hdma->ChannelIndex))) && (RESET != (source_it & DMA_IT_TE)))
{
/* When a DMA transfer error occurs */
/* A hardware clear of its EN bits is performed */
/* Disable ALL DMA IT */
__HAL_DMA_DISABLE_IT(hdma, (DMA_IT_TC | DMA_IT_HT | DMA_IT_TE));
/* Clear all flags */
hdma->DmaBaseAddress->IFCR = (DMA_ISR_GIF1 << hdma->ChannelIndex);
/* Update error code */
hdma->ErrorCode = HAL_DMA_ERROR_TE;
/* Change the DMA state */
hdma->State = HAL_DMA_STATE_READY;
/* Process Unlocked */
__HAL_UNLOCK(hdma);
if (hdma->XferErrorCallback != NULL)
{
/* Transfer error callback */
hdma->XferErrorCallback(hdma);
}
}
return;
}
/**
* @brief Register callbacks
* @param hdma: pointer to a DMA_HandleTypeDef structure that contains
* the configuration information for the specified DMA Channel.
* @param CallbackID: User Callback identifer
* a HAL_DMA_CallbackIDTypeDef ENUM as parameter.
* @param pCallback: pointer to private callbacsk function which has pointer to
* a DMA_HandleTypeDef structure as parameter.
* @retval HAL status
*/
HAL_StatusTypeDef HAL_DMA_RegisterCallback(DMA_HandleTypeDef *hdma, HAL_DMA_CallbackIDTypeDef CallbackID, void (* pCallback)( DMA_HandleTypeDef * _hdma))
{
HAL_StatusTypeDef status = HAL_OK;
/* Process locked */
__HAL_LOCK(hdma);
if(HAL_DMA_STATE_READY == hdma->State)
{
switch (CallbackID)
{
case HAL_DMA_XFER_CPLT_CB_ID:
hdma->XferCpltCallback = pCallback;
break;
case HAL_DMA_XFER_HALFCPLT_CB_ID:
hdma->XferHalfCpltCallback = pCallback;
break;
case HAL_DMA_XFER_ERROR_CB_ID:
hdma->XferErrorCallback = pCallback;
break;
case HAL_DMA_XFER_ABORT_CB_ID:
hdma->XferAbortCallback = pCallback;
break;
default:
status = HAL_ERROR;
break;
}
}
else
{
status = HAL_ERROR;
}
/* Release Lock */
__HAL_UNLOCK(hdma);
return status;
}
/**
* @brief UnRegister callbacks
* @param hdma: pointer to a DMA_HandleTypeDef structure that contains
* the configuration information for the specified DMA Channel.
* @param CallbackID: User Callback identifer
* a HAL_DMA_CallbackIDTypeDef ENUM as parameter.
* @retval HAL status
*/
HAL_StatusTypeDef HAL_DMA_UnRegisterCallback(DMA_HandleTypeDef *hdma, HAL_DMA_CallbackIDTypeDef CallbackID)
{
HAL_StatusTypeDef status = HAL_OK;
/* Process locked */
__HAL_LOCK(hdma);
if(HAL_DMA_STATE_READY == hdma->State)
{
switch (CallbackID)
{
case HAL_DMA_XFER_CPLT_CB_ID:
hdma->XferCpltCallback = NULL;
break;
case HAL_DMA_XFER_HALFCPLT_CB_ID:
hdma->XferHalfCpltCallback = NULL;
break;
case HAL_DMA_XFER_ERROR_CB_ID:
hdma->XferErrorCallback = NULL;
break;
case HAL_DMA_XFER_ABORT_CB_ID:
hdma->XferAbortCallback = NULL;
break;
case HAL_DMA_XFER_ALL_CB_ID:
hdma->XferCpltCallback = NULL;
hdma->XferHalfCpltCallback = NULL;
hdma->XferErrorCallback = NULL;
hdma->XferAbortCallback = NULL;
break;
default:
status = HAL_ERROR;
break;
}
}
else
{
status = HAL_ERROR;
}
/* Release Lock */
__HAL_UNLOCK(hdma);
return status;
}
/**
* @}
*/
/** @defgroup DMA_Exported_Functions_Group3 Peripheral State and Errors functions
* @brief Peripheral State and Errors functions
*
@verbatim
===============================================================================
##### Peripheral State and Errors functions #####
===============================================================================
[..]
This subsection provides functions allowing to
(+) Check the DMA state
(+) Get error code
@endverbatim
* @{
*/
/**
* @brief Return the DMA hande 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 DMA handle state */
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
* @{
*/
/**
* @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)
{
/* Clear all flags */
hdma->DmaBaseAddress->IFCR = (DMA_ISR_GIF1 << hdma->ChannelIndex);
/* Configure DMA Channel data length */
hdma->Instance->CNDTR = DataLength;
/* Memory to Peripheral */
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;
}
/* Peripheral to Memory */
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****/

View file

@ -0,0 +1,983 @@
/**
******************************************************************************
* @file stm32f1xx_hal_flash.c
* @author MCD Application Team
* @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);
extern void FLASH_PageErase(uint32_t PageAddress);
/**
* @}
*/
/* 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(FLASH_TIMEOUT_VALUE);
#if defined(FLASH_BANK2_END)
}
else
{
/* Wait for last operation to be completed */
status = FLASH_WaitForLastOperationBank2(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 = 1U;
}
else if(TypeProgram == FLASH_TYPEPROGRAM_WORD)
{
/* Program word (32-bit = 2*16-bit) at a specified address. */
nbiterations = 2U;
}
else
{
/* Program double word (64-bit = 4*16-bit) at a specified address. */
nbiterations = 4U;
}
for (index = 0U; index < nbiterations; index++)
{
FLASH_Program_HalfWord((Address + (2U*index)), (uint16_t)(Data >> (16U*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(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(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 = 1U;
}
else if(TypeProgram == FLASH_TYPEPROGRAM_WORD)
{
pFlash.ProcedureOnGoing = FLASH_PROC_PROGRAMWORD;
/* Program word (32-bit : 2*16-bit) at a specified address. */
pFlash.DataRemaining = 2U;
}
else
{
pFlash.ProcedureOnGoing = FLASH_PROC_PROGRAMDOUBLEWORD;
/* Program double word (64-bit : 4*16-bit) at a specified address. */
pFlash.DataRemaining = 4U;
}
/* 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 = 0U;
/* 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 = 0xFFFFFFFFU;
/* 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 != 0U)
{
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 = 0xFFFFFFFFU;
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(0U);
/* 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 != 0U)
{
/* Increment address to 16-bit */
pFlash.Address += 2U;
addresstmp = pFlash.Address;
/* Shift to have next 16-bit data */
pFlash.Data = (pFlash.Data >> 16U);
/* 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 - 2U);
}
else
{
HAL_FLASH_EndOfOperationCallback(pFlash.Address - 6U);
}
/* Reset Address and stop Program procedure */
pFlash.Address = 0xFFFFFFFFU;
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 != 0U)
{
/* 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 = 0xFFFFFFFFU;
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(0U);
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 != 0U)
{
/* Increment address to 16-bit */
pFlash.Address += 2U;
addresstmp = pFlash.Address;
/* Shift to have next 16-bit data */
pFlash.Data = (pFlash.Data >> 16U);
/* 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-2U);
}
else
{
HAL_FLASH_EndOfOperationCallback(pFlash.Address-6U);
}
/* Reset Address and stop Program procedure*/
pFlash.Address = 0xFFFFFFFFU;
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)
{
HAL_StatusTypeDef status = HAL_OK;
if(READ_BIT(FLASH->CR, FLASH_CR_LOCK) != RESET)
{
/* Authorize the FLASH Registers access */
WRITE_REG(FLASH->KEYR, FLASH_KEY1);
WRITE_REG(FLASH->KEYR, FLASH_KEY2);
/* Verify Flash is unlocked */
if(READ_BIT(FLASH->CR, FLASH_CR_LOCK) != RESET)
{
status = HAL_ERROR;
}
}
#if defined(FLASH_BANK2_END)
if(READ_BIT(FLASH->CR2, FLASH_CR2_LOCK) != RESET)
{
/* Authorize the FLASH BANK2 Registers access */
WRITE_REG(FLASH->KEYR2, FLASH_KEY1);
WRITE_REG(FLASH->KEYR2, FLASH_KEY2);
/* Verify Flash BANK2 is unlocked */
if(READ_BIT(FLASH->CR2, FLASH_CR2_LOCK) != RESET)
{
status = HAL_ERROR;
}
}
#endif /* FLASH_BANK2_END */
return status;
}
/**
* @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 None
*/
void HAL_FLASH_OB_Launch(void)
{
/* Initiates a system reset request to launch the option byte loading */
HAL_NVIC_SystemReset();
}
/**
* @}
*/
/** @defgroup FLASH_Exported_Functions_Group3 Peripheral errors functions
* @brief Peripheral errors functions
*
@verbatim
===============================================================================
##### Peripheral Errors functions #####
===============================================================================
[..]
This subsection permit to get in run-time errors 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 specify the address to be programmed.
* @param Data specify 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 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 == 0U) || ((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;
}
/* 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 == 0U) || ((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)
{
uint32_t flags = 0U;
#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)
flags |= FLASH_FLAG_WRPERR | FLASH_FLAG_WRPERR_BANK2;
#else
flags |= FLASH_FLAG_WRPERR;
#endif /* FLASH_BANK2_END */
}
#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 defined(FLASH_BANK2_END)
flags |= FLASH_FLAG_PGERR | FLASH_FLAG_PGERR_BANK2;
#else
flags |= FLASH_FLAG_PGERR;
#endif /* FLASH_BANK2_END */
}
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 */
__HAL_FLASH_CLEAR_FLAG(flags);
}
/**
* @}
*/
/**
* @}
*/
#endif /* HAL_FLASH_MODULE_ENABLED */
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,595 @@
/**
******************************************************************************
* @file stm32f1xx_hal_gpio.c
* @author MCD Application Team
* @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 ------------------------------------------------------------*/
/** @addtogroup GPIO_Private_Constants GPIO Private Constants
* @{
*/
#define GPIO_MODE 0x00000003U
#define EXTI_MODE 0x10000000U
#define GPIO_MODE_IT 0x00010000U
#define GPIO_MODE_EVT 0x00020000U
#define RISING_EDGE 0x00100000U
#define FALLING_EDGE 0x00200000U
#define GPIO_OUTPUT_TYPE 0x00000010U
#define GPIO_NUMBER 16U
/* Definitions for bit manipulation of CRL and CRH register */
#define GPIO_CR_MODE_INPUT 0x00000000U /*!< 00: Input mode (reset state) */
#define GPIO_CR_CNF_ANALOG 0x00000000U /*!< 00: Analog mode */
#define GPIO_CR_CNF_INPUT_FLOATING 0x00000004U /*!< 01: Floating input (reset state) */
#define GPIO_CR_CNF_INPUT_PU_PD 0x00000008U /*!< 10: Input with pull-up / pull-down */
#define GPIO_CR_CNF_GP_OUTPUT_PP 0x00000000U /*!< 00: General purpose output push-pull */
#define GPIO_CR_CNF_GP_OUTPUT_OD 0x00000004U /*!< 01: General purpose output Open-drain */
#define GPIO_CR_CNF_AF_OUTPUT_PP 0x00000008U /*!< 10: Alternate function output Push-pull */
#define GPIO_CR_CNF_AF_OUTPUT_OD 0x0000000CU /*!< 11: Alternate function output Open-drain */
/**
* @}
*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/* Exported functions --------------------------------------------------------*/
/** @defgroup GPIO_Exported_Functions GPIO Exported Functions
* @{
*/
/** @defgroup GPIO_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 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 = 0x00U;
uint32_t iocurrent = 0x00U;
uint32_t temp = 0x00U;
uint32_t config = 0x00U;
__IO uint32_t *configregister; /* Store the address of CRL or CRH register based on pin number */
uint32_t registeroffset = 0U; /* 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 = 0U; position < GPIO_NUMBER; position++)
{
/* Get the IO position */
ioposition = (0x01U << 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 << 2U) : ((position - 8U) << 2U);
/* 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 >> 2U];
CLEAR_BIT(temp, (0x0FU) << (4U * (position & 0x03U)));
SET_BIT(temp, (GPIO_GET_INDEX(GPIOx)) << (4U * (position & 0x03U)));
AFIO->EXTICR[position >> 2U] = 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 = 0x00U;
uint32_t iocurrent = 0x00U;
uint32_t tmp = 0x00U;
__IO uint32_t *configregister; /* Store the address of CRL or CRH register based on pin number */
uint32_t registeroffset = 0U;
/* 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) != 0U)
{
/* Get current io position */
iocurrent = (GPIO_Pin) & (1U << 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 << 2U) : ((position - 8U) << 2U);
/* 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 >> 2U];
tmp &= 0x0FU << (4U * (position & 0x03U));
if (tmp == (GPIO_GET_INDEX(GPIOx) << (4U * (position & 0x03U))))
{
tmp = 0x0FU << (4U * (position & 0x03U));
CLEAR_BIT(AFIO->EXTICR[position >> 2U], 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_PIN_RESET: to clear the port pin
* @arg GPIO_PIN_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 << 16U;
}
}
/**
* @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 callbacks.
* @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****/

View file

@ -0,0 +1,143 @@
/**
******************************************************************************
* @file stm32f1xx_hal_gpio_ex.c
* @author MCD Application Team
* @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****/

View file

@ -0,0 +1,637 @@
/**
******************************************************************************
* @file stm32f1xx_hal_pwr.c
* @author MCD Application Team
* @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 0x00010000U
#define PVD_MODE_EVT 0x00020000U
#define PVD_RISING_EDGE 0x00000001U
#define PVD_FALLING_EDGE 0x00000002U
/**
* @}
*/
/** @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 0x00U
#define PWR_CSR_OFFSET 0x04U
#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 PWR_CR_LPDS_Pos
#define CR_LPSDSR_BB ((uint32_t)(PERIPH_BB_BASE + (PWR_CR_OFFSET_BB * 32U) + (LPSDSR_BIT_NUMBER * 4U)))
/* Alias word address of DBP bit */
#define DBP_BIT_NUMBER PWR_CR_DBP_Pos
#define CR_DBP_BB ((uint32_t)(PERIPH_BB_BASE + (PWR_CR_OFFSET_BB * 32U) + (DBP_BIT_NUMBER * 4U)))
/* Alias word address of PVDE bit */
#define PVDE_BIT_NUMBER PWR_CR_PVDE_Pos
#define CR_PVDE_BB ((uint32_t)(PERIPH_BB_BASE + (PWR_CR_OFFSET_BB * 32U) + (PVDE_BIT_NUMBER * 4U)))
/**
* @}
*/
/** @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 * 32U) + (POSITION_VAL(VAL) * 4U)))
/**
* @}
*/
/**
* @}
*/
/* 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 */
/* Prevent unused argument(s) compilation warning */
UNUSED(Regulator);
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****/

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,879 @@
/**
******************************************************************************
* @file stm32f1xx_hal_rcc_ex.c
* @author MCD Application Team
* @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 = 0U, temp_reg = 0U;
#if defined(STM32F105xC) || defined(STM32F107xC)
uint32_t pllactive = 0U;
#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));
FlagStatus pwrclkchanged = RESET;
/* As soon as function is called to change RTC clock source, activation of the
power domain is done. */
/* Requires to enable write access to Backup Domain of necessary */
if(__HAL_RCC_PWR_IS_CLK_DISABLED())
{
__HAL_RCC_PWR_CLK_ENABLE();
pwrclkchanged = SET;
}
if(HAL_IS_BIT_CLR(PWR->CR, PWR_CR_DBP))
{
/* Enable write access to Backup domain */
SET_BIT(PWR->CR, PWR_CR_DBP);
/* Wait for Backup domain Write protection disable */
tickstart = HAL_GetTick();
while(HAL_IS_BIT_CLR(PWR->CR, PWR_CR_DBP))
{
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 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;
}
}
}
}
__HAL_RCC_RTC_CONFIG(PeriphClkInit->RTCClockSelection);
/* Require to disable power clock if necessary */
if(pwrclkchanged == SET)
{
__HAL_RCC_PWR_CLK_DISABLE();
}
}
/*------------------------------ 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 = 0U;
/* 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(STM32F105xC) || defined(STM32F107xC)
const uint8_t aPLLMULFactorTable[14] = {0, 0, 4, 5, 6, 7, 8, 9, 0, 0, 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};
uint32_t prediv1 = 0U, pllclk = 0U, pllmul = 0U;
uint32_t pll2mul = 0U, pll3mul = 0U, prediv2 = 0U;
#endif /* STM32F105xC || STM32F107xC */
#if defined(STM32F102x6) || defined(STM32F102xB) || defined(STM32F103x6) || \
defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG)
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};
uint32_t prediv1 = 0U, pllclk = 0U, pllmul = 0U;
#endif /* STM32F102x6 || STM32F102xB || STM32F103x6 || STM32F103xB || STM32F103xE || STM32F103xG */
uint32_t temp_reg = 0U, frequency = 0U;
/* 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) >> RCC_CFGR_PLLMULL_Pos];
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) >> RCC_CFGR2_PREDIV1_Pos];
#else
prediv1 = aPredivFactorTable[(uint32_t)(RCC->CFGR & RCC_CFGR_PLLXTPRE) >> RCC_CFGR_PLLXTPRE_Pos];
#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) >> RCC_CFGR2_PREDIV2_Pos) + 1;
pll2mul = ((RCC->CFGR2 & RCC_CFGR2_PLL2MUL) >> RCC_CFGR2_PLL2MUL_Pos) + 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) >> RCC_CFGR_PLLMULL_Pos])
{
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) >> RCC_CFGR2_PREDIV2_Pos) + 1;
pll3mul = ((RCC->CFGR2 & RCC_CFGR2_PLL3MUL) >> RCC_CFGR2_PLL3MUL_Pos) + 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) >> RCC_CFGR2_PREDIV2_Pos) + 1;
pll3mul = ((RCC->CFGR2 & RCC_CFGR2_PLL3MUL) >> RCC_CFGR2_PLL3MUL_Pos) + 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 / 128U;
}
/* Clock not enabled for RTC*/
else
{
frequency = 0U;
}
break;
}
case RCC_PERIPHCLK_ADC:
{
frequency = HAL_RCC_GetPCLK2Freq() / (((__HAL_RCC_GET_ADC_SOURCE() >> RCC_CFGR_ADCPRE_Pos) + 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 = 0U;
/* 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 = 0U;
/* 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 = 0U;
/* 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 = 0U;
/* 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****/

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,591 @@
/**
******************************************************************************
* @file stm32f1xx_hal_rtc_ex.c
* @author MCD Application Team
* @brief Extended RTC HAL module driver.
* This file provides firmware functions to manage the following
* functionalities of the Real Time Clock (RTC) Extension peripheral:
* + RTC Tamper functions
* + Extension Control functions
* + Extension RTC features 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_RTC_MODULE_ENABLED
/** @defgroup RTCEx RTCEx
* @brief RTC Extended HAL module driver
* @{
*/
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/** @defgroup RTCEx_Private_Macros RTCEx Private Macros
* @{
*/
/**
* @}
*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/** @defgroup RTCEx_Exported_Functions RTCEx Exported Functions
* @{
*/
/** @defgroup RTCEx_Exported_Functions_Group1 RTC Tamper functions
* @brief RTC Tamper functions
*
@verbatim
===============================================================================
##### RTC Tamper functions #####
===============================================================================
[..] This section provides functions allowing to configure Tamper feature
@endverbatim
* @{
*/
/**
* @brief Sets Tamper
* @note By calling this API we disable the tamper interrupt for all tampers.
* @param hrtc: pointer to a RTC_HandleTypeDef structure that contains
* the configuration information for RTC.
* @param sTamper: Pointer to Tamper Structure.
* @note Tamper can be enabled only if ASOE and CCO bit are reset
* @retval HAL status
*/
HAL_StatusTypeDef HAL_RTCEx_SetTamper(RTC_HandleTypeDef *hrtc, RTC_TamperTypeDef* sTamper)
{
/* Check input parameters */
if((hrtc == NULL) || (sTamper == NULL))
{
return HAL_ERROR;
}
/* Check the parameters */
assert_param(IS_RTC_TAMPER(sTamper->Tamper));
assert_param(IS_RTC_TAMPER_TRIGGER(sTamper->Trigger));
/* Process Locked */
__HAL_LOCK(hrtc);
hrtc->State = HAL_RTC_STATE_BUSY;
if (HAL_IS_BIT_SET(BKP->RTCCR,(BKP_RTCCR_CCO | BKP_RTCCR_ASOE)))
{
hrtc->State = HAL_RTC_STATE_ERROR;
/* Process Unlocked */
__HAL_UNLOCK(hrtc);
return HAL_ERROR;
}
MODIFY_REG(BKP->CR, (BKP_CR_TPE | BKP_CR_TPAL), (sTamper->Tamper | (sTamper->Trigger)));
hrtc->State = HAL_RTC_STATE_READY;
/* Process Unlocked */
__HAL_UNLOCK(hrtc);
return HAL_OK;
}
/**
* @brief Sets Tamper with interrupt.
* @note By calling this API we force the tamper interrupt for all tampers.
* @param hrtc: pointer to a RTC_HandleTypeDef structure that contains
* the configuration information for RTC.
* @param sTamper: Pointer to RTC Tamper.
* @note Tamper can be enabled only if ASOE and CCO bit are reset
* @retval HAL status
*/
HAL_StatusTypeDef HAL_RTCEx_SetTamper_IT(RTC_HandleTypeDef *hrtc, RTC_TamperTypeDef* sTamper)
{
/* Check input parameters */
if((hrtc == NULL) || (sTamper == NULL))
{
return HAL_ERROR;
}
/* Check the parameters */
assert_param(IS_RTC_TAMPER(sTamper->Tamper));
assert_param(IS_RTC_TAMPER_TRIGGER(sTamper->Trigger));
/* Process Locked */
__HAL_LOCK(hrtc);
hrtc->State = HAL_RTC_STATE_BUSY;
if (HAL_IS_BIT_SET(BKP->RTCCR,(BKP_RTCCR_CCO | BKP_RTCCR_ASOE)))
{
hrtc->State = HAL_RTC_STATE_ERROR;
/* Process Unlocked */
__HAL_UNLOCK(hrtc);
return HAL_ERROR;
}
MODIFY_REG(BKP->CR, (BKP_CR_TPE | BKP_CR_TPAL), (sTamper->Tamper | (sTamper->Trigger)));
/* Configure the Tamper Interrupt in the BKP->CSR */
__HAL_RTC_TAMPER_ENABLE_IT(hrtc, RTC_IT_TAMP1);
hrtc->State = HAL_RTC_STATE_READY;
/* Process Unlocked */
__HAL_UNLOCK(hrtc);
return HAL_OK;
}
/**
* @brief Deactivates Tamper.
* @param hrtc: pointer to a RTC_HandleTypeDef structure that contains
* the configuration information for RTC.
* @param Tamper: Selected tamper pin.
* This parameter can be a value of @ref RTCEx_Tamper_Pins_Definitions
* @retval HAL status
*/
HAL_StatusTypeDef HAL_RTCEx_DeactivateTamper(RTC_HandleTypeDef *hrtc, uint32_t Tamper)
{
/* Check input parameters */
if(hrtc == NULL)
{
return HAL_ERROR;
}
/* Prevent unused argument(s) compilation warning */
UNUSED(Tamper);
assert_param(IS_RTC_TAMPER(Tamper));
/* Process Locked */
__HAL_LOCK(hrtc);
hrtc->State = HAL_RTC_STATE_BUSY;
/* Disable the selected Tamper pin */
CLEAR_BIT(BKP->CR, BKP_CR_TPE);
/* Disable the Tamper Interrupt in the BKP->CSR */
/* Configure the Tamper Interrupt in the BKP->CSR */
__HAL_RTC_TAMPER_DISABLE_IT(hrtc, RTC_IT_TAMP1);
/* Clear the Tamper interrupt pending bit */
__HAL_RTC_TAMPER_CLEAR_FLAG(hrtc, RTC_FLAG_TAMP1F);
SET_BIT(BKP->CSR, BKP_CSR_CTE);
hrtc->State = HAL_RTC_STATE_READY;
/* Process Unlocked */
__HAL_UNLOCK(hrtc);
return HAL_OK;
}
/**
* @brief This function handles Tamper interrupt request.
* @param hrtc: pointer to a RTC_HandleTypeDef structure that contains
* the configuration information for RTC.
* @retval None
*/
void HAL_RTCEx_TamperIRQHandler(RTC_HandleTypeDef *hrtc)
{
/* Get the status of the Interrupt */
if(__HAL_RTC_TAMPER_GET_IT_SOURCE(hrtc, RTC_IT_TAMP1))
{
/* Get the TAMPER Interrupt enable bit and pending bit */
if(__HAL_RTC_TAMPER_GET_FLAG(hrtc, RTC_FLAG_TAMP1F) != (uint32_t)RESET)
{
/* Tamper callback */
HAL_RTCEx_Tamper1EventCallback(hrtc);
/* Clear the Tamper interrupt pending bit */
__HAL_RTC_TAMPER_CLEAR_FLAG(hrtc,RTC_FLAG_TAMP1F);
}
}
/* Change RTC state */
hrtc->State = HAL_RTC_STATE_READY;
}
/**
* @brief Tamper 1 callback.
* @param hrtc: pointer to a RTC_HandleTypeDef structure that contains
* the configuration information for RTC.
* @retval None
*/
__weak void HAL_RTCEx_Tamper1EventCallback(RTC_HandleTypeDef *hrtc)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(hrtc);
/* NOTE : This function Should not be modified, when the callback is needed,
the HAL_RTCEx_Tamper1EventCallback could be implemented in the user file
*/
}
/**
* @brief This function handles Tamper1 Polling.
* @param hrtc: pointer to a RTC_HandleTypeDef structure that contains
* the configuration information for RTC.
* @param Timeout: Timeout duration
* @retval HAL status
*/
HAL_StatusTypeDef HAL_RTCEx_PollForTamper1Event(RTC_HandleTypeDef *hrtc, uint32_t Timeout)
{
uint32_t tickstart = HAL_GetTick();
/* Check input parameters */
if(hrtc == NULL)
{
return HAL_ERROR;
}
/* Get the status of the Interrupt */
while(__HAL_RTC_TAMPER_GET_FLAG(hrtc,RTC_FLAG_TAMP1F)== RESET)
{
if(Timeout != HAL_MAX_DELAY)
{
if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
{
hrtc->State = HAL_RTC_STATE_TIMEOUT;
return HAL_TIMEOUT;
}
}
}
/* Clear the Tamper Flag */
__HAL_RTC_TAMPER_CLEAR_FLAG(hrtc,RTC_FLAG_TAMP1F);
/* Change RTC state */
hrtc->State = HAL_RTC_STATE_READY;
return HAL_OK;
}
/**
* @}
*/
/** @defgroup RTCEx_Exported_Functions_Group2 RTC Second functions
* @brief RTC Second functions
*
@verbatim
===============================================================================
##### RTC Second functions #####
===============================================================================
[..] This section provides functions implementing second interupt handlers
@endverbatim
* @{
*/
/**
* @brief Sets Interrupt for second
* @param hrtc: pointer to a RTC_HandleTypeDef structure that contains
* the configuration information for RTC.
* @retval HAL status
*/
HAL_StatusTypeDef HAL_RTCEx_SetSecond_IT(RTC_HandleTypeDef *hrtc)
{
/* Check input parameters */
if(hrtc == NULL)
{
return HAL_ERROR;
}
/* Process Locked */
__HAL_LOCK(hrtc);
hrtc->State = HAL_RTC_STATE_BUSY;
/* Enable Second interuption */
__HAL_RTC_SECOND_ENABLE_IT(hrtc, RTC_IT_SEC);
hrtc->State = HAL_RTC_STATE_READY;
/* Process Unlocked */
__HAL_UNLOCK(hrtc);
return HAL_OK;
}
/**
* @brief Deactivates Second.
* @param hrtc: pointer to a RTC_HandleTypeDef structure that contains
* the configuration information for RTC.
* @retval HAL status
*/
HAL_StatusTypeDef HAL_RTCEx_DeactivateSecond(RTC_HandleTypeDef *hrtc)
{
/* Check input parameters */
if(hrtc == NULL)
{
return HAL_ERROR;
}
/* Process Locked */
__HAL_LOCK(hrtc);
hrtc->State = HAL_RTC_STATE_BUSY;
/* Deactivate Second interuption*/
__HAL_RTC_SECOND_DISABLE_IT(hrtc, RTC_IT_SEC);
hrtc->State = HAL_RTC_STATE_READY;
/* Process Unlocked */
__HAL_UNLOCK(hrtc);
return HAL_OK;
}
/**
* @brief This function handles second interrupt request.
* @param hrtc: pointer to a RTC_HandleTypeDef structure that contains
* the configuration information for RTC.
* @retval None
*/
void HAL_RTCEx_RTCIRQHandler(RTC_HandleTypeDef* hrtc)
{
if(__HAL_RTC_SECOND_GET_IT_SOURCE(hrtc, RTC_IT_SEC))
{
/* Get the status of the Interrupt */
if(__HAL_RTC_SECOND_GET_FLAG(hrtc, RTC_FLAG_SEC))
{
/* Check if Overrun occurred */
if (__HAL_RTC_SECOND_GET_FLAG(hrtc, RTC_FLAG_OW))
{
/* Second error callback */
HAL_RTCEx_RTCEventErrorCallback(hrtc);
/* Clear flag Second */
__HAL_RTC_OVERFLOW_CLEAR_FLAG(hrtc, RTC_FLAG_OW);
/* Change RTC state */
hrtc->State = HAL_RTC_STATE_ERROR;
}
else
{
/* Second callback */
HAL_RTCEx_RTCEventCallback(hrtc);
/* Change RTC state */
hrtc->State = HAL_RTC_STATE_READY;
}
/* Clear flag Second */
__HAL_RTC_SECOND_CLEAR_FLAG(hrtc, RTC_FLAG_SEC);
}
}
}
/**
* @brief Second event callback.
* @param hrtc: pointer to a RTC_HandleTypeDef structure that contains
* the configuration information for RTC.
* @retval None
*/
__weak void HAL_RTCEx_RTCEventCallback(RTC_HandleTypeDef *hrtc)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(hrtc);
/* NOTE : This function Should not be modified, when the callback is needed,
the HAL_RTCEx_RTCEventCallback could be implemented in the user file
*/
}
/**
* @brief Second event error callback.
* @param hrtc: pointer to a RTC_HandleTypeDef structure that contains
* the configuration information for RTC.
* @retval None
*/
__weak void HAL_RTCEx_RTCEventErrorCallback(RTC_HandleTypeDef *hrtc)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(hrtc);
/* NOTE : This function Should not be modified, when the callback is needed,
the HAL_RTCEx_RTCEventErrorCallback could be implemented in the user file
*/
}
/**
* @}
*/
/** @defgroup RTCEx_Exported_Functions_Group3 Extended Peripheral Control functions
* @brief Extended Peripheral Control functions
*
@verbatim
===============================================================================
##### Extension Peripheral Control functions #####
===============================================================================
[..]
This subsection provides functions allowing to
(+) Writes a data in a specified RTC Backup data register
(+) Read a data in a specified RTC Backup data register
(+) Sets the Smooth calibration parameters.
@endverbatim
* @{
*/
/**
* @brief Writes a data in a specified RTC Backup data register.
* @param hrtc: pointer to a RTC_HandleTypeDef structure that contains
* the configuration information for RTC.
* @param BackupRegister: RTC Backup data Register number.
* This parameter can be: RTC_BKP_DRx where x can be from 1 to 10 (or 42) to
* specify the register (depending devices).
* @param Data: Data to be written in the specified RTC Backup data register.
* @retval None
*/
void HAL_RTCEx_BKUPWrite(RTC_HandleTypeDef *hrtc, uint32_t BackupRegister, uint32_t Data)
{
uint32_t tmp = 0U;
/* Prevent unused argument(s) compilation warning */
UNUSED(hrtc);
/* Check the parameters */
assert_param(IS_RTC_BKP(BackupRegister));
tmp = (uint32_t)BKP_BASE;
tmp += (BackupRegister * 4U);
*(__IO uint32_t *) tmp = (Data & BKP_DR1_D);
}
/**
* @brief Reads data from the specified RTC Backup data Register.
* @param hrtc: pointer to a RTC_HandleTypeDef structure that contains
* the configuration information for RTC.
* @param BackupRegister: RTC Backup data Register number.
* This parameter can be: RTC_BKP_DRx where x can be from 1 to 10 (or 42) to
* specify the register (depending devices).
* @retval Read value
*/
uint32_t HAL_RTCEx_BKUPRead(RTC_HandleTypeDef *hrtc, uint32_t BackupRegister)
{
uint32_t backupregister = 0U;
uint32_t pvalue = 0U;
/* Prevent unused argument(s) compilation warning */
UNUSED(hrtc);
/* Check the parameters */
assert_param(IS_RTC_BKP(BackupRegister));
backupregister = (uint32_t)BKP_BASE;
backupregister += (BackupRegister * 4U);
pvalue = (*(__IO uint32_t *)(backupregister)) & BKP_DR1_D;
/* Read the specified register */
return pvalue;
}
/**
* @brief Sets the Smooth calibration parameters.
* @param hrtc: RTC handle
* @param SmoothCalibPeriod: Not used (only present for compatibility with another families)
* @param SmoothCalibPlusPulses: Not used (only present for compatibility with another families)
* @param SmouthCalibMinusPulsesValue: specifies the RTC Clock Calibration value.
* This parameter must be a number between 0 and 0x7F.
* @retval HAL status
*/
HAL_StatusTypeDef HAL_RTCEx_SetSmoothCalib(RTC_HandleTypeDef* hrtc, uint32_t SmoothCalibPeriod, uint32_t SmoothCalibPlusPulses, uint32_t SmouthCalibMinusPulsesValue)
{
/* Check input parameters */
if(hrtc == NULL)
{
return HAL_ERROR;
}
/* Prevent unused argument(s) compilation warning */
UNUSED(SmoothCalibPeriod);
UNUSED(SmoothCalibPlusPulses);
/* Check the parameters */
assert_param(IS_RTC_SMOOTH_CALIB_MINUS(SmouthCalibMinusPulsesValue));
/* Process Locked */
__HAL_LOCK(hrtc);
hrtc->State = HAL_RTC_STATE_BUSY;
/* Sets RTC Clock Calibration value.*/
MODIFY_REG(BKP->RTCCR, BKP_RTCCR_CAL, SmouthCalibMinusPulsesValue);
/* Change RTC state */
hrtc->State = HAL_RTC_STATE_READY;
/* Process Unlocked */
__HAL_UNLOCK(hrtc);
return HAL_OK;
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
#endif /* HAL_RTC_MODULE_ENABLED */
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,231 @@
/**
******************************************************************************
* @file stm32f1xx_hal_spi_ex.c
* @author MCD Application Team
* @brief Extended SPI HAL module driver.
*
* This file provides firmware functions to manage the following
* functionalities SPI 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
* @{
*/
/** @addtogroup SPI
* @{
*/
#ifdef HAL_SPI_MODULE_ENABLED
/** @defgroup SPI_Private_Variables SPI Private Variables
* @{
*/
#if (USE_SPI_CRC != 0U)
/* Variable used to determine if device is impacted by implementation of workaround
related to wrong CRC errors detection on SPI2. Conditions in which this workaround has to be applied, are:
- STM32F101CDE/STM32F103CDE
- Revision ID : Z
- SPI2
- In receive only mode, with CRC calculation enabled, at the end of the CRC reception,
the software needs to check the CRCERR flag. If it is found set, read back the SPI_RXCRC:
+ If the value is 0, the complete data transfer is successful.
+ Otherwise, one or more errors have been detected during the data transfer by CPU or DMA.
If CRCERR is found reset, the complete data transfer is considered successful.
*/
uint8_t uCRCErrorWorkaroundCheck = 0U;
#endif /* USE_SPI_CRC */
/**
* @}
*/
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/** @addtogroup SPI_Exported_Functions
* @{
*/
/** @addtogroup SPI_Exported_Functions_Group1
*
* @{
*/
/**
* @brief Initializes the SPI according to the specified parameters
* in the SPI_InitTypeDef and create the associated handle.
* @param hspi: pointer to a SPI_HandleTypeDef structure that contains
* the configuration information for SPI module.
* @retval HAL status
*/
HAL_StatusTypeDef HAL_SPI_Init(SPI_HandleTypeDef *hspi)
{
/* Check the SPI handle allocation */
if(hspi == NULL)
{
return HAL_ERROR;
}
/* Check the parameters */
assert_param(IS_SPI_ALL_INSTANCE(hspi->Instance));
assert_param(IS_SPI_MODE(hspi->Init.Mode));
assert_param(IS_SPI_DIRECTION(hspi->Init.Direction));
assert_param(IS_SPI_DATASIZE(hspi->Init.DataSize));
assert_param(IS_SPI_CPOL(hspi->Init.CLKPolarity));
assert_param(IS_SPI_CPHA(hspi->Init.CLKPhase));
assert_param(IS_SPI_NSS(hspi->Init.NSS));
assert_param(IS_SPI_BAUDRATE_PRESCALER(hspi->Init.BaudRatePrescaler));
assert_param(IS_SPI_FIRST_BIT(hspi->Init.FirstBit));
#if (USE_SPI_CRC != 0U)
assert_param(IS_SPI_CRC_CALCULATION(hspi->Init.CRCCalculation));
if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
{
assert_param(IS_SPI_CRC_POLYNOMIAL(hspi->Init.CRCPolynomial));
}
#else
hspi->Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
#endif /* USE_SPI_CRC */
if(hspi->State == HAL_SPI_STATE_RESET)
{
/* Init the low level hardware : GPIO, CLOCK, NVIC... */
HAL_SPI_MspInit(hspi);
}
hspi->State = HAL_SPI_STATE_BUSY;
/* Disble the selected SPI peripheral */
__HAL_SPI_DISABLE(hspi);
/*----------------------- SPIx CR1 & CR2 Configuration ---------------------*/
/* Configure : SPI Mode, Communication Mode, Data size, Clock polarity and phase, NSS management,
Communication speed, First bit and CRC calculation state */
WRITE_REG(hspi->Instance->CR1, (hspi->Init.Mode | hspi->Init.Direction | hspi->Init.DataSize |
hspi->Init.CLKPolarity | hspi->Init.CLKPhase | (hspi->Init.NSS & SPI_CR1_SSM) |
hspi->Init.BaudRatePrescaler | hspi->Init.FirstBit | hspi->Init.CRCCalculation) );
/* Configure : NSS management */
WRITE_REG(hspi->Instance->CR2, (((hspi->Init.NSS >> 16U) & SPI_CR2_SSOE) | hspi->Init.TIMode));
/*---------------------------- SPIx CRCPOLY Configuration ------------------*/
/* Configure : CRC Polynomial */
WRITE_REG(hspi->Instance->CRCPR, hspi->Init.CRCPolynomial);
#if defined(SPI_I2SCFGR_I2SMOD)
/* Activate the SPI mode (Make sure that I2SMOD bit in I2SCFGR register is reset) */
CLEAR_BIT(hspi->Instance->I2SCFGR, SPI_I2SCFGR_I2SMOD);
#endif /* SPI_I2SCFGR_I2SMOD */
#if (USE_SPI_CRC != 0U)
#if defined (STM32F101xE) || defined (STM32F103xE)
/* Check RevisionID value for identifying if Device is Rev Z (0x0001) in order to enable workaround for
CRC errors wrongly detected */
/* Pb is that ES_STM32F10xxCDE also identify an issue in Debug registers access while not in Debug mode.
Revision ID information is only available in Debug mode, so Workaround could not be implemented
to distinguish Rev Z devices (issue present) from more recent version (issue fixed).
So, in case of Revison Z F101 or F103 devices, below variable should be assigned to 1 */
uCRCErrorWorkaroundCheck = 0U;
#else
uCRCErrorWorkaroundCheck = 0U;
#endif /* STM32F101xE || STM32F103xE */
#endif /* USE_SPI_CRC */
hspi->ErrorCode = HAL_SPI_ERROR_NONE;
hspi->State = HAL_SPI_STATE_READY;
return HAL_OK;
}
/**
* @}
*/
/**
* @}
*/
/** @addtogroup SPI_Private_Functions
* @{
*/
#if (USE_SPI_CRC != 0U)
/**
* @brief Checks if encountered CRC error could be corresponding to wrongly detected errors
* according to SPI instance, Device type, and revision ID.
* @param hspi: pointer to a SPI_HandleTypeDef structure that contains
* the configuration information for SPI module.
* @retval CRC error validity (SPI_INVALID_CRC_ERROR or SPI_VALID_CRC_ERROR).
*/
uint8_t SPI_ISCRCErrorValid(SPI_HandleTypeDef *hspi)
{
#if defined(STM32F101xE) || defined(STM32F103xE)
/* Check how to handle this CRC error (workaround to be applied or not) */
/* If CRC errors could be wrongly detected (issue 2.15.2 in STM32F10xxC/D/E silicon limitations ES (DocID14732 Rev 13) */
if((uCRCErrorWorkaroundCheck != 0U) && (hspi->Instance == SPI2))
{
if(hspi->Instance->RXCRCR == 0U)
{
return (SPI_INVALID_CRC_ERROR);
}
}
return (SPI_VALID_CRC_ERROR);
#else
/* Prevent unused argument(s) compilation warning */
UNUSED(hspi);
return (SPI_VALID_CRC_ERROR);
#endif
}
#endif /* USE_SPI_CRC */
/**
* @}
*/
#endif /* HAL_SPI_MODULE_ENABLED */
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff