эх как она работает...
This commit is contained in:
@@ -1,764 +0,0 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32l4xx_hal.c
|
||||
* @author MCD Application Team
|
||||
* @brief HAL module driver.
|
||||
* This is the common part of the HAL initialization
|
||||
*
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2017 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
@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
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32l4xx_hal.h"
|
||||
|
||||
/** @addtogroup STM32L4xx_HAL_Driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup HAL HAL
|
||||
* @brief HAL module driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifdef HAL_MODULE_ENABLED
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief STM32L4xx HAL Driver version number
|
||||
*/
|
||||
#define STM32L4XX_HAL_VERSION_MAIN (0x01U) /*!< [31:24] main version */
|
||||
#define STM32L4XX_HAL_VERSION_SUB1 (0x0DU) /*!< [23:16] sub1 version */
|
||||
#define STM32L4XX_HAL_VERSION_SUB2 (0x02U) /*!< [15:8] sub2 version */
|
||||
#define STM32L4XX_HAL_VERSION_RC (0x00U) /*!< [7:0] release candidate */
|
||||
#define STM32L4XX_HAL_VERSION ((STM32L4XX_HAL_VERSION_MAIN << 24U)\
|
||||
|(STM32L4XX_HAL_VERSION_SUB1 << 16U)\
|
||||
|(STM32L4XX_HAL_VERSION_SUB2 << 8U)\
|
||||
|(STM32L4XX_HAL_VERSION_RC))
|
||||
|
||||
#if defined(VREFBUF)
|
||||
#define VREFBUF_TIMEOUT_VALUE 10U /* 10 ms (to be confirmed) */
|
||||
#endif /* VREFBUF */
|
||||
|
||||
/* ------------ SYSCFG registers bit address in the alias region ------------ */
|
||||
#define SYSCFG_OFFSET (SYSCFG_BASE - PERIPH_BASE)
|
||||
/* --- MEMRMP Register ---*/
|
||||
/* Alias word address of FB_MODE bit */
|
||||
#define MEMRMP_OFFSET SYSCFG_OFFSET
|
||||
#define FB_MODE_BitNumber 8U
|
||||
#define FB_MODE_BB (PERIPH_BB_BASE + (MEMRMP_OFFSET * 32U) + (FB_MODE_BitNumber * 4U))
|
||||
|
||||
/* --- SCSR Register ---*/
|
||||
/* Alias word address of SRAM2ER bit */
|
||||
#define SCSR_OFFSET (SYSCFG_OFFSET + 0x18U)
|
||||
#define BRER_BitNumber 0U
|
||||
#define SCSR_SRAM2ER_BB (PERIPH_BB_BASE + (SCSR_OFFSET * 32U) + (BRER_BitNumber * 4U))
|
||||
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
|
||||
/* Exported variables --------------------------------------------------------*/
|
||||
|
||||
/** @defgroup HAL_Exported_Variables HAL Exported Variables
|
||||
* @{
|
||||
*/
|
||||
__IO uint32_t uwTick;
|
||||
uint32_t uwTickPrio = (1UL << __NVIC_PRIO_BITS); /* Invalid priority */
|
||||
HAL_TickFreqTypeDef uwTickFreq = HAL_TICK_FREQ_DEFAULT; /* 1KHz */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* 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:
|
||||
(+) Initialize the Flash interface, the NVIC allocation and initial time base
|
||||
clock configuration.
|
||||
(+) De-initialize 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 Configure the Flash prefetch, the Instruction and Data caches,
|
||||
* the time base source, NVIC and any required global low level hardware
|
||||
* by calling the HAL_MspInit() callback function to be optionally defined in user file
|
||||
* stm32l4xx_hal_msp.c.
|
||||
*
|
||||
* @note HAL_Init() function is called at the beginning of program after reset and before
|
||||
* the clock configuration.
|
||||
*
|
||||
* @note In the default implementation the System Timer (Systick) is used as source of time base.
|
||||
* The Systick configuration is based on MSI clock, as MSI is the clock
|
||||
* used after a system Reset and the NVIC configuration is set to Priority group 4.
|
||||
* Once done, time base tick starts incrementing: the tick variable counter is incremented
|
||||
* each 1ms in the SysTick_Handler() interrupt handler.
|
||||
*
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_Init(void)
|
||||
{
|
||||
HAL_StatusTypeDef status = HAL_OK;
|
||||
|
||||
/* Configure Flash prefetch, Instruction cache, Data cache */
|
||||
/* Default configuration at reset is: */
|
||||
/* - Prefetch disabled */
|
||||
/* - Instruction cache enabled */
|
||||
/* - Data cache enabled */
|
||||
#if (INSTRUCTION_CACHE_ENABLE == 0)
|
||||
__HAL_FLASH_INSTRUCTION_CACHE_DISABLE();
|
||||
#endif /* INSTRUCTION_CACHE_ENABLE */
|
||||
|
||||
#if (DATA_CACHE_ENABLE == 0)
|
||||
__HAL_FLASH_DATA_CACHE_DISABLE();
|
||||
#endif /* DATA_CACHE_ENABLE */
|
||||
|
||||
#if (PREFETCH_ENABLE != 0)
|
||||
__HAL_FLASH_PREFETCH_BUFFER_ENABLE();
|
||||
#endif /* PREFETCH_ENABLE */
|
||||
|
||||
/* Set Interrupt Group Priority */
|
||||
HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);
|
||||
|
||||
/* Use SysTick as time base source and configure 1ms tick (default clock after Reset is MSI) */
|
||||
if (HAL_InitTick(TICK_INT_PRIORITY) != HAL_OK)
|
||||
{
|
||||
status = HAL_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Init the low level hardware */
|
||||
HAL_MspInit();
|
||||
}
|
||||
|
||||
/* Return function status */
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief De-initialize common part of the HAL and stop the source of time base.
|
||||
* @note This function is optional.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_DeInit(void)
|
||||
{
|
||||
/* Reset of all peripherals */
|
||||
__HAL_RCC_APB1_FORCE_RESET();
|
||||
__HAL_RCC_APB1_RELEASE_RESET();
|
||||
|
||||
__HAL_RCC_APB2_FORCE_RESET();
|
||||
__HAL_RCC_APB2_RELEASE_RESET();
|
||||
|
||||
__HAL_RCC_AHB1_FORCE_RESET();
|
||||
__HAL_RCC_AHB1_RELEASE_RESET();
|
||||
|
||||
__HAL_RCC_AHB2_FORCE_RESET();
|
||||
__HAL_RCC_AHB2_RELEASE_RESET();
|
||||
|
||||
__HAL_RCC_AHB3_FORCE_RESET();
|
||||
__HAL_RCC_AHB3_RELEASE_RESET();
|
||||
|
||||
/* 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 DeInitialize 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)
|
||||
{
|
||||
HAL_StatusTypeDef status = HAL_OK;
|
||||
|
||||
/* Check uwTickFreq for MisraC 2012 (even if uwTickFreq is a enum type that doesn't take the value zero)*/
|
||||
if ((uint32_t)uwTickFreq != 0U)
|
||||
{
|
||||
/*Configure the SysTick to have interrupt in 1ms time basis*/
|
||||
if (HAL_SYSTICK_Config(SystemCoreClock / (1000U / (uint32_t)uwTickFreq)) == 0U)
|
||||
{
|
||||
/* Configure the SysTick IRQ priority */
|
||||
if (TickPriority < (1UL << __NVIC_PRIO_BITS))
|
||||
{
|
||||
HAL_NVIC_SetPriority(SysTick_IRQn, TickPriority, 0U);
|
||||
uwTickPrio = TickPriority;
|
||||
}
|
||||
else
|
||||
{
|
||||
status = HAL_ERROR;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
status = HAL_ERROR;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
status = HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Return function status */
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @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
|
||||
|
||||
@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 += (uint32_t)uwTickFreq;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Provide 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.
|
||||
* @param Freq tick frequency
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_SetTickFreq(HAL_TickFreqTypeDef Freq)
|
||||
{
|
||||
HAL_StatusTypeDef status = HAL_OK;
|
||||
HAL_TickFreqTypeDef prevTickFreq;
|
||||
|
||||
if (uwTickFreq != Freq)
|
||||
{
|
||||
/* Back up uwTickFreq frequency */
|
||||
prevTickFreq = uwTickFreq;
|
||||
|
||||
/* Update uwTickFreq global variable used by HAL_InitTick() */
|
||||
uwTickFreq = Freq;
|
||||
|
||||
/* Apply the new tick Freq */
|
||||
status = HAL_InitTick(uwTickPrio);
|
||||
if (status != HAL_OK)
|
||||
{
|
||||
/* Restore previous tick frequency */
|
||||
uwTickFreq = prevTickFreq;
|
||||
}
|
||||
}
|
||||
|
||||
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 period to guaranty 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 */
|
||||
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 */
|
||||
SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the HAL revision.
|
||||
* @retval version : 0xXYZR (8bits for each decimal, R for RC)
|
||||
*/
|
||||
uint32_t HAL_GetHalVersion(void)
|
||||
{
|
||||
return STM32L4XX_HAL_VERSION;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the device revision identifier.
|
||||
* @retval Device revision identifier
|
||||
*/
|
||||
uint32_t HAL_GetREVID(void)
|
||||
{
|
||||
return((DBGMCU->IDCODE & DBGMCU_IDCODE_REV_ID) >> 16);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the device identifier.
|
||||
* @retval Device identifier
|
||||
*/
|
||||
uint32_t HAL_GetDEVID(void)
|
||||
{
|
||||
return(DBGMCU->IDCODE & DBGMCU_IDCODE_DEV_ID);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the first word of the unique device identifier (UID based on 96 bits)
|
||||
* @retval Device identifier
|
||||
*/
|
||||
uint32_t HAL_GetUIDw0(void)
|
||||
{
|
||||
return(READ_REG(*((uint32_t *)UID_BASE)));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the second word of the unique device identifier (UID based on 96 bits)
|
||||
* @retval Device identifier
|
||||
*/
|
||||
uint32_t HAL_GetUIDw1(void)
|
||||
{
|
||||
return(READ_REG(*((uint32_t *)(UID_BASE + 4U))));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the third word of the unique device identifier (UID based on 96 bits)
|
||||
* @retval Device identifier
|
||||
*/
|
||||
uint32_t HAL_GetUIDw2(void)
|
||||
{
|
||||
return(READ_REG(*((uint32_t *)(UID_BASE + 8U))));
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup HAL_Exported_Functions_Group3 HAL Debug functions
|
||||
* @brief HAL Debug functions
|
||||
*
|
||||
@verbatim
|
||||
===============================================================================
|
||||
##### HAL Debug functions #####
|
||||
===============================================================================
|
||||
[..] This section provides functions allowing to:
|
||||
(+) Enable/Disable Debug module during SLEEP mode
|
||||
(+) Enable/Disable Debug module during STOP0/STOP1/STOP2 modes
|
||||
(+) Enable/Disable Debug module during STANDBY mode
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @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.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_DBGMCU_DisableDBGSleepMode(void)
|
||||
{
|
||||
CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_SLEEP);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable the Debug Module during STOP0/STOP1/STOP2 modes.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_DBGMCU_EnableDBGStopMode(void)
|
||||
{
|
||||
SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STOP);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable the Debug Module during STOP0/STOP1/STOP2 modes.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_DBGMCU_DisableDBGStopMode(void)
|
||||
{
|
||||
CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STOP);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable the Debug Module during STANDBY mode.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_DBGMCU_EnableDBGStandbyMode(void)
|
||||
{
|
||||
SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STANDBY);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable the Debug Module during STANDBY mode.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_DBGMCU_DisableDBGStandbyMode(void)
|
||||
{
|
||||
CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STANDBY);
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup HAL_Exported_Functions_Group4 HAL SYSCFG configuration functions
|
||||
* @brief HAL SYSCFG configuration functions
|
||||
*
|
||||
@verbatim
|
||||
===============================================================================
|
||||
##### HAL SYSCFG configuration functions #####
|
||||
===============================================================================
|
||||
[..] This section provides functions allowing to:
|
||||
(+) Start a hardware SRAM2 erase operation
|
||||
(+) Enable/Disable the Internal FLASH Bank Swapping
|
||||
(+) Configure the Voltage reference buffer
|
||||
(+) Enable/Disable the Voltage reference buffer
|
||||
(+) Enable/Disable the I/O analog switch voltage booster
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Start a hardware SRAM2 erase operation.
|
||||
* @note As long as SRAM2 is not erased the SRAM2ER bit will be set.
|
||||
* This bit is automatically reset at the end of the SRAM2 erase operation.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_SYSCFG_SRAM2Erase(void)
|
||||
{
|
||||
/* unlock the write protection of the SRAM2ER bit */
|
||||
SYSCFG->SKR = 0xCA;
|
||||
SYSCFG->SKR = 0x53;
|
||||
/* Starts a hardware SRAM2 erase operation*/
|
||||
*(__IO uint32_t *) SCSR_SRAM2ER_BB = 0x00000001UL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable the Internal FLASH Bank Swapping.
|
||||
*
|
||||
* @note This function can be used only for STM32L4xx devices.
|
||||
*
|
||||
* @note Flash Bank2 mapped at 0x08000000 (and aliased @0x00000000)
|
||||
* and Flash Bank1 mapped at 0x08100000 (and aliased at 0x00100000)
|
||||
*
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_SYSCFG_EnableMemorySwappingBank(void)
|
||||
{
|
||||
*(__IO uint32_t *)FB_MODE_BB = 0x00000001UL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable the Internal FLASH Bank Swapping.
|
||||
*
|
||||
* @note This function can be used only for STM32L4xx devices.
|
||||
*
|
||||
* @note The default state : Flash Bank1 mapped at 0x08000000 (and aliased @0x0000 0000)
|
||||
* and Flash Bank2 mapped at 0x08100000 (and aliased at 0x00100000)
|
||||
*
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_SYSCFG_DisableMemorySwappingBank(void)
|
||||
{
|
||||
|
||||
*(__IO uint32_t *)FB_MODE_BB = 0x00000000UL;
|
||||
}
|
||||
|
||||
#if defined(VREFBUF)
|
||||
/**
|
||||
* @brief Configure the internal voltage reference buffer voltage scale.
|
||||
* @param VoltageScaling specifies the output voltage to achieve
|
||||
* This parameter can be one of the following values:
|
||||
* @arg SYSCFG_VREFBUF_VOLTAGE_SCALE0: VREF_OUT1 around 2.048 V.
|
||||
* This requires VDDA equal to or higher than 2.4 V.
|
||||
* @arg SYSCFG_VREFBUF_VOLTAGE_SCALE1: VREF_OUT2 around 2.5 V.
|
||||
* This requires VDDA equal to or higher than 2.8 V.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_SYSCFG_VREFBUF_VoltageScalingConfig(uint32_t VoltageScaling)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_SYSCFG_VREFBUF_VOLTAGE_SCALE(VoltageScaling));
|
||||
|
||||
MODIFY_REG(VREFBUF->CSR, VREFBUF_CSR_VRS, VoltageScaling);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure the internal voltage reference buffer high impedance mode.
|
||||
* @param Mode specifies the high impedance mode
|
||||
* This parameter can be one of the following values:
|
||||
* @arg SYSCFG_VREFBUF_HIGH_IMPEDANCE_DISABLE: VREF+ pin is internally connect to VREFINT output.
|
||||
* @arg SYSCFG_VREFBUF_HIGH_IMPEDANCE_ENABLE: VREF+ pin is high impedance.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_SYSCFG_VREFBUF_HighImpedanceConfig(uint32_t Mode)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_SYSCFG_VREFBUF_HIGH_IMPEDANCE(Mode));
|
||||
|
||||
MODIFY_REG(VREFBUF->CSR, VREFBUF_CSR_HIZ, Mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Tune the Internal Voltage Reference buffer (VREFBUF).
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_SYSCFG_VREFBUF_TrimmingConfig(uint32_t TrimmingValue)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_SYSCFG_VREFBUF_TRIMMING(TrimmingValue));
|
||||
|
||||
MODIFY_REG(VREFBUF->CCR, VREFBUF_CCR_TRIM, TrimmingValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable the Internal Voltage Reference buffer (VREFBUF).
|
||||
* @retval HAL_OK/HAL_TIMEOUT
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_SYSCFG_EnableVREFBUF(void)
|
||||
{
|
||||
uint32_t tickstart;
|
||||
|
||||
SET_BIT(VREFBUF->CSR, VREFBUF_CSR_ENVR);
|
||||
|
||||
/* Get Start Tick*/
|
||||
tickstart = HAL_GetTick();
|
||||
|
||||
/* Wait for VRR bit */
|
||||
while(READ_BIT(VREFBUF->CSR, VREFBUF_CSR_VRR) == 0U)
|
||||
{
|
||||
if((HAL_GetTick() - tickstart) > VREFBUF_TIMEOUT_VALUE)
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable the Internal Voltage Reference buffer (VREFBUF).
|
||||
*
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_SYSCFG_DisableVREFBUF(void)
|
||||
{
|
||||
CLEAR_BIT(VREFBUF->CSR, VREFBUF_CSR_ENVR);
|
||||
}
|
||||
#endif /* VREFBUF */
|
||||
|
||||
/**
|
||||
* @brief Enable the I/O analog switch voltage booster
|
||||
*
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_SYSCFG_EnableIOAnalogSwitchBooster(void)
|
||||
{
|
||||
SET_BIT(SYSCFG->CFGR1, SYSCFG_CFGR1_BOOSTEN);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable the I/O analog switch voltage booster
|
||||
*
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_SYSCFG_DisableIOAnalogSwitchBooster(void)
|
||||
{
|
||||
CLEAR_BIT(SYSCFG->CFGR1, SYSCFG_CFGR1_BOOSTEN);
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* HAL_MODULE_ENABLED */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
@@ -1,517 +0,0 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32l4xx_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 Configuration 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-M4 exceptions are managed by CMSIS functions.
|
||||
|
||||
(#) Configure the NVIC Priority Grouping using HAL_NVIC_SetPriorityGrouping() function.
|
||||
(#) Configure the priority of the selected IRQ Channels using HAL_NVIC_SetPriority().
|
||||
(#) Enable the selected IRQ Channels using HAL_NVIC_EnableIRQ().
|
||||
|
||||
-@- When the NVIC_PRIORITYGROUP_0 is selected, IRQ pre-emption is no more possible.
|
||||
The pending IRQ priority will be managed only by the sub priority.
|
||||
|
||||
-@- IRQ priority order (sorted by highest to lowest priority):
|
||||
(+@) Lowest pre-emption priority
|
||||
(+@) Lowest sub priority
|
||||
(+@) Lowest hardware priority (IRQ number)
|
||||
|
||||
[..]
|
||||
*** How to configure SysTick using CORTEX HAL driver ***
|
||||
========================================================
|
||||
[..]
|
||||
Setup SysTick Timer for 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 stm32l4xx_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
|
||||
******************************************************************************
|
||||
|
||||
The table below gives the allowed values of the pre-emption priority and subpriority according
|
||||
to the Priority Grouping configuration performed by HAL_NVIC_SetPriorityGrouping() function.
|
||||
|
||||
==========================================================================================================================
|
||||
NVIC_PriorityGroup | NVIC_IRQChannelPreemptionPriority | NVIC_IRQChannelSubPriority | Description
|
||||
==========================================================================================================================
|
||||
NVIC_PRIORITYGROUP_0 | 0 | 0-15 | 0 bit for pre-emption priority
|
||||
| | | 4 bits for subpriority
|
||||
--------------------------------------------------------------------------------------------------------------------------
|
||||
NVIC_PRIORITYGROUP_1 | 0-1 | 0-7 | 1 bit for pre-emption priority
|
||||
| | | 3 bits for subpriority
|
||||
--------------------------------------------------------------------------------------------------------------------------
|
||||
NVIC_PRIORITYGROUP_2 | 0-3 | 0-3 | 2 bits for pre-emption priority
|
||||
| | | 2 bits for subpriority
|
||||
--------------------------------------------------------------------------------------------------------------------------
|
||||
NVIC_PRIORITYGROUP_3 | 0-7 | 0-1 | 3 bits for pre-emption priority
|
||||
| | | 1 bit for subpriority
|
||||
--------------------------------------------------------------------------------------------------------------------------
|
||||
NVIC_PRIORITYGROUP_4 | 0-15 | 0 | 4 bits for pre-emption priority
|
||||
| | | 0 bit for subpriority
|
||||
==========================================================================================================================
|
||||
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2017 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file in
|
||||
* the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32l4xx_hal.h"
|
||||
|
||||
/** @addtogroup STM32L4xx_HAL_Driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup CORTEX
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifdef HAL_CORTEX_MODULE_ENABLED
|
||||
|
||||
/* Private types -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private constants ---------------------------------------------------------*/
|
||||
/* Private macros ------------------------------------------------------------*/
|
||||
/* Private functions ---------------------------------------------------------*/
|
||||
/* Exported functions --------------------------------------------------------*/
|
||||
|
||||
/** @addtogroup CORTEX_Exported_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/** @addtogroup CORTEX_Exported_Functions_Group1
|
||||
* @brief Initialization and Configuration functions
|
||||
*
|
||||
@verbatim
|
||||
==============================================================================
|
||||
##### Initialization and Configuration functions #####
|
||||
==============================================================================
|
||||
[..]
|
||||
This section provides the CORTEX HAL driver functions allowing to configure Interrupts
|
||||
SysTick functionalities
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief Set the priority grouping field (pre-emption priority and subpriority)
|
||||
* using the required unlock sequence.
|
||||
* @param PriorityGroup: The priority grouping bits length.
|
||||
* This parameter can be one of the following values:
|
||||
* @arg NVIC_PRIORITYGROUP_0: 0 bit for pre-emption priority,
|
||||
* 4 bits for subpriority
|
||||
* @arg NVIC_PRIORITYGROUP_1: 1 bit for pre-emption priority,
|
||||
* 3 bits for subpriority
|
||||
* @arg NVIC_PRIORITYGROUP_2: 2 bits for pre-emption priority,
|
||||
* 2 bits for subpriority
|
||||
* @arg NVIC_PRIORITYGROUP_3: 3 bits for pre-emption priority,
|
||||
* 1 bit for subpriority
|
||||
* @arg NVIC_PRIORITYGROUP_4: 4 bits for pre-emption priority,
|
||||
* 0 bit for subpriority
|
||||
* @note When the NVIC_PriorityGroup_0 is selected, IRQ pre-emption is no more possible.
|
||||
* The pending IRQ priority will be managed only by the subpriority.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_NVIC_SetPriorityGrouping(uint32_t PriorityGroup)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_NVIC_PRIORITY_GROUP(PriorityGroup));
|
||||
|
||||
/* Set the PRIGROUP[10:8] bits according to the PriorityGroup parameter value */
|
||||
NVIC_SetPriorityGrouping(PriorityGroup);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set 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 (stm32l4xxxx.h))
|
||||
* @param PreemptPriority: The pre-emption priority for the IRQn channel.
|
||||
* This parameter can be a value between 0 and 15
|
||||
* A lower priority value indicates a higher priority
|
||||
* @param SubPriority: the subpriority level for the IRQ channel.
|
||||
* This parameter can be a value between 0 and 15
|
||||
* A lower priority value indicates a higher priority.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_NVIC_SetPriority(IRQn_Type IRQn, uint32_t PreemptPriority, uint32_t SubPriority)
|
||||
{
|
||||
uint32_t prioritygroup = 0x00;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_NVIC_SUB_PRIORITY(SubPriority));
|
||||
assert_param(IS_NVIC_PREEMPTION_PRIORITY(PreemptPriority));
|
||||
|
||||
prioritygroup = NVIC_GetPriorityGrouping();
|
||||
|
||||
NVIC_SetPriority(IRQn, NVIC_EncodePriority(prioritygroup, PreemptPriority, SubPriority));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable 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 (stm32l4xxxx.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 Disable 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 (stm32l4xxxx.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 Initiate a system reset request to reset the MCU.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_NVIC_SystemReset(void)
|
||||
{
|
||||
/* System Reset */
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialize the System Timer with interrupt enabled and start the System Tick Timer (SysTick):
|
||||
* 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);
|
||||
}
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup CORTEX_Exported_Functions_Group2
|
||||
* @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
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Get 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 Get 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 (stm32l4xxxx.h))
|
||||
* @param PriorityGroup: the priority grouping bits length.
|
||||
* This parameter can be one of the following values:
|
||||
* @arg NVIC_PRIORITYGROUP_0: 0 bit for pre-emption priority,
|
||||
* 4 bits for subpriority
|
||||
* @arg NVIC_PRIORITYGROUP_1: 1 bit for pre-emption priority,
|
||||
* 3 bits for subpriority
|
||||
* @arg NVIC_PRIORITYGROUP_2: 2 bits for pre-emption priority,
|
||||
* 2 bits for subpriority
|
||||
* @arg NVIC_PRIORITYGROUP_3: 3 bits for pre-emption priority,
|
||||
* 1 bit for subpriority
|
||||
* @arg NVIC_PRIORITYGROUP_4: 4 bits for pre-emption priority,
|
||||
* 0 bit 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 Set 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 (stm32l4xxxx.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 Get Pending Interrupt (read the pending register in the NVIC
|
||||
* and return 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 (stm32l4xxxx.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 Clear 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 (stm32l4xxxx.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 Get active interrupt (read the active register in NVIC and return 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 (stm32l4xxxx.h))
|
||||
* @retval status: - 0 Interrupt status is not pending.
|
||||
* - 1 Interrupt status is pending.
|
||||
*/
|
||||
uint32_t HAL_NVIC_GetActive(IRQn_Type IRQn)
|
||||
{
|
||||
/* Return 1 if active else 0 */
|
||||
return NVIC_GetActive(IRQn);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure 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 Handle 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
|
||||
*/
|
||||
}
|
||||
|
||||
#if (__MPU_PRESENT == 1)
|
||||
/**
|
||||
* @brief Enable the MPU.
|
||||
* @param MPU_Control: Specifies the control mode of the MPU during hard fault,
|
||||
* NMI, FAULTMASK and privileged accessto 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);
|
||||
|
||||
/* Ensure MPU setting take effects */
|
||||
__DSB();
|
||||
__ISB();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Disable the MPU.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_MPU_Disable(void)
|
||||
{
|
||||
/* Make sure outstanding transfers are done */
|
||||
__DMB();
|
||||
|
||||
/* Disable the MPU and clear the control register*/
|
||||
MPU->CTRL = 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Initialize and configure the Region and the memory to be protected.
|
||||
* @param MPU_Init: Pointer to a MPU_Region_InitTypeDef structure that contains
|
||||
* the initialization and configuration information.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_MPU_ConfigRegion(MPU_Region_InitTypeDef *MPU_Init)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_MPU_REGION_NUMBER(MPU_Init->Number));
|
||||
assert_param(IS_MPU_REGION_ENABLE(MPU_Init->Enable));
|
||||
|
||||
/* Set the Region number */
|
||||
MPU->RNR = MPU_Init->Number;
|
||||
|
||||
if ((MPU_Init->Enable) != RESET)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_MPU_INSTRUCTION_ACCESS(MPU_Init->DisableExec));
|
||||
assert_param(IS_MPU_REGION_PERMISSION_ATTRIBUTE(MPU_Init->AccessPermission));
|
||||
assert_param(IS_MPU_TEX_LEVEL(MPU_Init->TypeExtField));
|
||||
assert_param(IS_MPU_ACCESS_SHAREABLE(MPU_Init->IsShareable));
|
||||
assert_param(IS_MPU_ACCESS_CACHEABLE(MPU_Init->IsCacheable));
|
||||
assert_param(IS_MPU_ACCESS_BUFFERABLE(MPU_Init->IsBufferable));
|
||||
assert_param(IS_MPU_SUB_REGION_DISABLE(MPU_Init->SubRegionDisable));
|
||||
assert_param(IS_MPU_REGION_SIZE(MPU_Init->Size));
|
||||
|
||||
MPU->RBAR = MPU_Init->BaseAddress;
|
||||
MPU->RASR = ((uint32_t)MPU_Init->DisableExec << MPU_RASR_XN_Pos) |
|
||||
((uint32_t)MPU_Init->AccessPermission << MPU_RASR_AP_Pos) |
|
||||
((uint32_t)MPU_Init->TypeExtField << MPU_RASR_TEX_Pos) |
|
||||
((uint32_t)MPU_Init->IsShareable << MPU_RASR_S_Pos) |
|
||||
((uint32_t)MPU_Init->IsCacheable << MPU_RASR_C_Pos) |
|
||||
((uint32_t)MPU_Init->IsBufferable << MPU_RASR_B_Pos) |
|
||||
((uint32_t)MPU_Init->SubRegionDisable << MPU_RASR_SRD_Pos) |
|
||||
((uint32_t)MPU_Init->Size << MPU_RASR_SIZE_Pos) |
|
||||
((uint32_t)MPU_Init->Enable << MPU_RASR_ENABLE_Pos);
|
||||
}
|
||||
else
|
||||
{
|
||||
MPU->RBAR = 0x00;
|
||||
MPU->RASR = 0x00;
|
||||
}
|
||||
}
|
||||
#endif /* __MPU_PRESENT */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* HAL_CORTEX_MODULE_ENABLED */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
@@ -1,1174 +0,0 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32l4xx_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
|
||||
*
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2017 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
@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.
|
||||
|
||||
Prior to HAL_DMA_Init the peripheral clock shall be enabled for both DMA & DMAMUX
|
||||
thanks to:
|
||||
(##) DMA1 or DMA2: __HAL_RCC_DMA1_CLK_ENABLE() or __HAL_RCC_DMA2_CLK_ENABLE() ;
|
||||
(##) DMAMUX1: __HAL_RCC_DMAMUX1_CLK_ENABLE();
|
||||
|
||||
(#) 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 to register callbacks with HAL_DMA_RegisterCallback().
|
||||
|
||||
*** DMA HAL driver macros list ***
|
||||
=============================================
|
||||
[..]
|
||||
Below the list of 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 is enabled or not.
|
||||
|
||||
[..]
|
||||
(@) You can refer to the DMA HAL driver header file for more useful macros
|
||||
|
||||
@endverbatim
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32l4xx_hal.h"
|
||||
|
||||
/** @addtogroup STM32L4xx_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);
|
||||
#if defined(DMAMUX1)
|
||||
static void DMA_CalcDMAMUXChannelBaseAndMask(DMA_HandleTypeDef *hdma);
|
||||
static void DMA_CalcDMAMUXRequestGenBaseAndMask(DMA_HandleTypeDef *hdma);
|
||||
#endif /* DMAMUX1 */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* 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;
|
||||
|
||||
/* 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));
|
||||
|
||||
assert_param(IS_DMA_ALL_REQUEST(hdma->Init.Request));
|
||||
|
||||
/* Compute 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)) << 2U;
|
||||
hdma->DmaBaseAddress = DMA1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* DMA2 */
|
||||
hdma->ChannelIndex = (((uint32_t)hdma->Instance - (uint32_t)DMA2_Channel1) / ((uint32_t)DMA2_Channel2 - (uint32_t)DMA2_Channel1)) << 2U;
|
||||
hdma->DmaBaseAddress = DMA2;
|
||||
}
|
||||
|
||||
/* Change DMA peripheral state */
|
||||
hdma->State = HAL_DMA_STATE_BUSY;
|
||||
|
||||
/* Get the CR register value */
|
||||
tmp = hdma->Instance->CCR;
|
||||
|
||||
/* Clear PL, MSIZE, PSIZE, MINC, PINC, CIRC, DIR and MEM2MEM 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 | DMA_CCR_MEM2MEM));
|
||||
|
||||
/* 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;
|
||||
|
||||
#if defined(DMAMUX1)
|
||||
/* Initialize parameters for DMAMUX channel :
|
||||
DMAmuxChannel, DMAmuxChannelStatus and DMAmuxChannelStatusMask
|
||||
*/
|
||||
DMA_CalcDMAMUXChannelBaseAndMask(hdma);
|
||||
|
||||
if(hdma->Init.Direction == DMA_MEMORY_TO_MEMORY)
|
||||
{
|
||||
/* if memory to memory force the request to 0*/
|
||||
hdma->Init.Request = DMA_REQUEST_MEM2MEM;
|
||||
}
|
||||
|
||||
/* Set peripheral request to DMAMUX channel */
|
||||
hdma->DMAmuxChannel->CCR = (hdma->Init.Request & DMAMUX_CxCR_DMAREQ_ID);
|
||||
|
||||
/* Clear the DMAMUX synchro overrun flag */
|
||||
hdma->DMAmuxChannelStatus->CFR = hdma->DMAmuxChannelStatusMask;
|
||||
|
||||
if(((hdma->Init.Request > 0U) && (hdma->Init.Request <= DMA_REQUEST_GENERATOR3)))
|
||||
{
|
||||
/* Initialize parameters for DMAMUX request generator :
|
||||
DMAmuxRequestGen, DMAmuxRequestGenStatus and DMAmuxRequestGenStatusMask
|
||||
*/
|
||||
DMA_CalcDMAMUXRequestGenBaseAndMask(hdma);
|
||||
|
||||
/* Reset the DMAMUX request generator register*/
|
||||
hdma->DMAmuxRequestGen->RGCR = 0U;
|
||||
|
||||
/* Clear the DMAMUX request generator overrun flag */
|
||||
hdma->DMAmuxRequestGenStatus->RGCFR = hdma->DMAmuxRequestGenStatusMask;
|
||||
}
|
||||
else
|
||||
{
|
||||
hdma->DMAmuxRequestGen = 0U;
|
||||
hdma->DMAmuxRequestGenStatus = 0U;
|
||||
hdma->DMAmuxRequestGenStatusMask = 0U;
|
||||
}
|
||||
#endif /* DMAMUX1 */
|
||||
|
||||
#if !defined (DMAMUX1)
|
||||
|
||||
/* Set request selection */
|
||||
if(hdma->Init.Direction != DMA_MEMORY_TO_MEMORY)
|
||||
{
|
||||
/* Write to DMA channel selection register */
|
||||
if (DMA1 == hdma->DmaBaseAddress)
|
||||
{
|
||||
/* Reset request selection for DMA1 Channelx */
|
||||
DMA1_CSELR->CSELR &= ~(DMA_CSELR_C1S << (hdma->ChannelIndex & 0x1cU));
|
||||
|
||||
/* Configure request selection for DMA1 Channelx */
|
||||
DMA1_CSELR->CSELR |= (uint32_t) (hdma->Init.Request << (hdma->ChannelIndex & 0x1cU));
|
||||
}
|
||||
else /* DMA2 */
|
||||
{
|
||||
/* Reset request selection for DMA2 Channelx */
|
||||
DMA2_CSELR->CSELR &= ~(DMA_CSELR_C1S << (hdma->ChannelIndex & 0x1cU));
|
||||
|
||||
/* Configure request selection for DMA2 Channelx */
|
||||
DMA2_CSELR->CSELR |= (uint32_t) (hdma->Init.Request << (hdma->ChannelIndex & 0x1cU));
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* STM32L431xx || STM32L432xx || STM32L433xx || STM32L442xx || STM32L443xx */
|
||||
/* STM32L471xx || STM32L475xx || STM32L476xx || STM32L442xx || STM32L486xx */
|
||||
/* STM32L496xx || STM32L4A6xx */
|
||||
|
||||
/* 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 (NULL == hdma )
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_DMA_ALL_INSTANCE(hdma->Instance));
|
||||
|
||||
/* Disable the selected DMA Channelx */
|
||||
__HAL_DMA_DISABLE(hdma);
|
||||
|
||||
/* Compute 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)) << 2U;
|
||||
hdma->DmaBaseAddress = DMA1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* DMA2 */
|
||||
hdma->ChannelIndex = (((uint32_t)hdma->Instance - (uint32_t)DMA2_Channel1) / ((uint32_t)DMA2_Channel2 - (uint32_t)DMA2_Channel1)) << 2U;
|
||||
hdma->DmaBaseAddress = DMA2;
|
||||
}
|
||||
|
||||
/* Reset DMA Channel control register */
|
||||
hdma->Instance->CCR = 0U;
|
||||
|
||||
/* Clear all flags */
|
||||
hdma->DmaBaseAddress->IFCR = (DMA_ISR_GIF1 << (hdma->ChannelIndex & 0x1CU));
|
||||
|
||||
#if !defined (DMAMUX1)
|
||||
|
||||
/* Reset DMA channel selection register */
|
||||
if (DMA1 == hdma->DmaBaseAddress)
|
||||
{
|
||||
/* DMA1 */
|
||||
DMA1_CSELR->CSELR &= ~(DMA_CSELR_C1S << (hdma->ChannelIndex & 0x1cU));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* DMA2 */
|
||||
DMA2_CSELR->CSELR &= ~(DMA_CSELR_C1S << (hdma->ChannelIndex & 0x1cU));
|
||||
}
|
||||
#endif /* STM32L431xx || STM32L432xx || STM32L433xx || STM32L442xx || STM32L443xx */
|
||||
/* STM32L471xx || STM32L475xx || STM32L476xx || STM32L442xx || STM32L486xx */
|
||||
/* STM32L496xx || STM32L4A6xx */
|
||||
|
||||
#if defined(DMAMUX1)
|
||||
|
||||
/* Initialize parameters for DMAMUX channel :
|
||||
DMAmuxChannel, DMAmuxChannelStatus and DMAmuxChannelStatusMask */
|
||||
|
||||
DMA_CalcDMAMUXChannelBaseAndMask(hdma);
|
||||
|
||||
/* Reset the DMAMUX channel that corresponds to the DMA channel */
|
||||
hdma->DMAmuxChannel->CCR = 0U;
|
||||
|
||||
/* Clear the DMAMUX synchro overrun flag */
|
||||
hdma->DMAmuxChannelStatus->CFR = hdma->DMAmuxChannelStatusMask;
|
||||
|
||||
/* Reset Request generator parameters if any */
|
||||
if(((hdma->Init.Request > 0U) && (hdma->Init.Request <= DMA_REQUEST_GENERATOR3)))
|
||||
{
|
||||
/* Initialize parameters for DMAMUX request generator :
|
||||
DMAmuxRequestGen, DMAmuxRequestGenStatus and DMAmuxRequestGenStatusMask
|
||||
*/
|
||||
DMA_CalcDMAMUXRequestGenBaseAndMask(hdma);
|
||||
|
||||
/* Reset the DMAMUX request generator register*/
|
||||
hdma->DMAmuxRequestGen->RGCR = 0U;
|
||||
|
||||
/* Clear the DMAMUX request generator overrun flag */
|
||||
hdma->DMAmuxRequestGenStatus->RGCFR = hdma->DMAmuxRequestGenStatusMask;
|
||||
}
|
||||
|
||||
hdma->DMAmuxRequestGen = 0U;
|
||||
hdma->DMAmuxRequestGenStatus = 0U;
|
||||
hdma->DMAmuxRequestGenStatusMask = 0U;
|
||||
|
||||
#endif /* DMAMUX1 */
|
||||
|
||||
/* Clean callbacks */
|
||||
hdma->XferCpltCallback = NULL;
|
||||
hdma->XferHalfCpltCallback = NULL;
|
||||
hdma->XferErrorCallback = NULL;
|
||||
hdma->XferAbortCallback = NULL;
|
||||
|
||||
/* Initialise the error code */
|
||||
hdma->ErrorCode = HAL_DMA_ERROR_NONE;
|
||||
|
||||
/* Initialize the DMA state */
|
||||
hdma->State = HAL_DMA_STATE_RESET;
|
||||
|
||||
/* Release Lock */
|
||||
__HAL_UNLOCK(hdma);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup DMA_Exported_Functions_Group2 Input and Output operation functions
|
||||
* @brief 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));
|
||||
}
|
||||
|
||||
#ifdef DMAMUX1
|
||||
|
||||
/* Check if DMAMUX Synchronization is enabled*/
|
||||
if((hdma->DMAmuxChannel->CCR & DMAMUX_CxCR_SE) != 0U)
|
||||
{
|
||||
/* Enable DMAMUX sync overrun IT*/
|
||||
hdma->DMAmuxChannel->CCR |= DMAMUX_CxCR_SOIE;
|
||||
}
|
||||
|
||||
if(hdma->DMAmuxRequestGen != 0U)
|
||||
{
|
||||
/* if using DMAMUX request generator, enable the DMAMUX request generator overrun IT*/
|
||||
/* enable the request gen overrun IT*/
|
||||
hdma->DMAmuxRequestGen->RGCR |= DMAMUX_RGxCR_OIE;
|
||||
}
|
||||
|
||||
#endif /* DMAMUX1 */
|
||||
|
||||
/* 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;
|
||||
|
||||
/* Check the DMA peripheral state */
|
||||
if(hdma->State != HAL_DMA_STATE_BUSY)
|
||||
{
|
||||
hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER;
|
||||
|
||||
/* Process Unlocked */
|
||||
__HAL_UNLOCK(hdma);
|
||||
|
||||
return HAL_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Disable DMA IT */
|
||||
__HAL_DMA_DISABLE_IT(hdma, (DMA_IT_TC | DMA_IT_HT | DMA_IT_TE));
|
||||
|
||||
#if defined(DMAMUX1)
|
||||
/* disable the DMAMUX sync overrun IT*/
|
||||
hdma->DMAmuxChannel->CCR &= ~DMAMUX_CxCR_SOIE;
|
||||
#endif /* DMAMUX1 */
|
||||
|
||||
/* Disable the channel */
|
||||
__HAL_DMA_DISABLE(hdma);
|
||||
|
||||
/* Clear all flags */
|
||||
hdma->DmaBaseAddress->IFCR = (DMA_ISR_GIF1 << (hdma->ChannelIndex & 0x1CU));
|
||||
|
||||
#if defined(DMAMUX1)
|
||||
/* Clear the DMAMUX synchro overrun flag */
|
||||
hdma->DMAmuxChannelStatus->CFR = hdma->DMAmuxChannelStatusMask;
|
||||
|
||||
if(hdma->DMAmuxRequestGen != 0U)
|
||||
{
|
||||
/* if using DMAMUX request generator, disable the DMAMUX request generator overrun IT*/
|
||||
/* disable the request gen overrun IT*/
|
||||
hdma->DMAmuxRequestGen->RGCR &= ~DMAMUX_RGxCR_OIE;
|
||||
|
||||
/* Clear the DMAMUX request generator overrun flag */
|
||||
hdma->DMAmuxRequestGenStatus->RGCFR = hdma->DMAmuxRequestGenStatusMask;
|
||||
}
|
||||
|
||||
#endif /* DMAMUX1 */
|
||||
|
||||
/* 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);
|
||||
|
||||
#if defined(DMAMUX1)
|
||||
/* disable the DMAMUX sync overrun IT*/
|
||||
hdma->DMAmuxChannel->CCR &= ~DMAMUX_CxCR_SOIE;
|
||||
|
||||
/* Clear all flags */
|
||||
hdma->DmaBaseAddress->IFCR = (DMA_ISR_GIF1 << (hdma->ChannelIndex & 0x1CU));
|
||||
|
||||
/* Clear the DMAMUX synchro overrun flag */
|
||||
hdma->DMAmuxChannelStatus->CFR = hdma->DMAmuxChannelStatusMask;
|
||||
|
||||
if(hdma->DMAmuxRequestGen != 0U)
|
||||
{
|
||||
/* if using DMAMUX request generator, disable the DMAMUX request generator overrun IT*/
|
||||
/* disable the request gen overrun IT*/
|
||||
hdma->DMAmuxRequestGen->RGCR &= ~DMAMUX_RGxCR_OIE;
|
||||
|
||||
/* Clear the DMAMUX request generator overrun flag */
|
||||
hdma->DMAmuxRequestGenStatus->RGCFR = hdma->DMAmuxRequestGenStatusMask;
|
||||
}
|
||||
|
||||
#else
|
||||
/* Clear all flags */
|
||||
hdma->DmaBaseAddress->IFCR = (DMA_ISR_GIF1 << (hdma->ChannelIndex & 0x1CU));
|
||||
#endif /* DMAMUX1 */
|
||||
|
||||
/* 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, HAL_DMA_LevelCompleteTypeDef CompleteLevel, uint32_t Timeout)
|
||||
{
|
||||
uint32_t temp;
|
||||
uint32_t tickstart;
|
||||
|
||||
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 ((hdma->Instance->CCR & DMA_CCR_CIRC) != 0U)
|
||||
{
|
||||
hdma->ErrorCode = HAL_DMA_ERROR_NOT_SUPPORTED;
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Get the level transfer complete flag */
|
||||
if (HAL_DMA_FULL_TRANSFER == CompleteLevel)
|
||||
{
|
||||
/* Transfer Complete flag */
|
||||
temp = DMA_FLAG_TC1 << (hdma->ChannelIndex & 0x1CU);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Half Transfer Complete flag */
|
||||
temp = DMA_FLAG_HT1 << (hdma->ChannelIndex & 0x1CU);
|
||||
}
|
||||
|
||||
/* Get tick */
|
||||
tickstart = HAL_GetTick();
|
||||
|
||||
while((hdma->DmaBaseAddress->ISR & temp) == 0U)
|
||||
{
|
||||
if((hdma->DmaBaseAddress->ISR & (DMA_FLAG_TE1 << (hdma->ChannelIndex& 0x1CU))) != 0U)
|
||||
{
|
||||
/* 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 & 0x1CU));
|
||||
|
||||
/* Update error code */
|
||||
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(((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
|
||||
{
|
||||
/* Update error code */
|
||||
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 defined(DMAMUX1)
|
||||
/*Check for DMAMUX Request generator (if used) overrun status */
|
||||
if(hdma->DMAmuxRequestGen != 0U)
|
||||
{
|
||||
/* if using DMAMUX request generator Check for DMAMUX request generator overrun */
|
||||
if((hdma->DMAmuxRequestGenStatus->RGSR & hdma->DMAmuxRequestGenStatusMask) != 0U)
|
||||
{
|
||||
/* Disable the request gen overrun interrupt */
|
||||
hdma->DMAmuxRequestGen->RGCR |= DMAMUX_RGxCR_OIE;
|
||||
|
||||
/* Clear the DMAMUX request generator overrun flag */
|
||||
hdma->DMAmuxRequestGenStatus->RGCFR = hdma->DMAmuxRequestGenStatusMask;
|
||||
|
||||
/* Update error code */
|
||||
hdma->ErrorCode |= HAL_DMA_ERROR_REQGEN;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check for DMAMUX Synchronization overrun */
|
||||
if((hdma->DMAmuxChannelStatus->CSR & hdma->DMAmuxChannelStatusMask) != 0U)
|
||||
{
|
||||
/* Clear the DMAMUX synchro overrun flag */
|
||||
hdma->DMAmuxChannelStatus->CFR = hdma->DMAmuxChannelStatusMask;
|
||||
|
||||
/* Update error code */
|
||||
hdma->ErrorCode |= HAL_DMA_ERROR_SYNC;
|
||||
}
|
||||
#endif /* DMAMUX1 */
|
||||
|
||||
if(HAL_DMA_FULL_TRANSFER == CompleteLevel)
|
||||
{
|
||||
/* Clear the transfer complete flag */
|
||||
hdma->DmaBaseAddress->IFCR = (DMA_FLAG_TC1 << (hdma->ChannelIndex& 0x1CU));
|
||||
|
||||
/* Process unlocked */
|
||||
__HAL_UNLOCK(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 */
|
||||
hdma->DmaBaseAddress->IFCR = (DMA_FLAG_HT1 << (hdma->ChannelIndex & 0x1CU));
|
||||
}
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Handle 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 & 0x1CU))) != 0U) && ((source_it & DMA_IT_HT) != 0U))
|
||||
{
|
||||
/* 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 */
|
||||
hdma->DmaBaseAddress->IFCR = DMA_ISR_HTIF1 << (hdma->ChannelIndex & 0x1CU);
|
||||
|
||||
/* 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 & 0x1CU))) != 0U) && ((source_it & DMA_IT_TC) != 0U))
|
||||
{
|
||||
if((hdma->Instance->CCR & DMA_CCR_CIRC) == 0U)
|
||||
{
|
||||
/* Disable the transfer complete interrupt if the DMA mode is not CIRCULAR */
|
||||
/* Disable the transfer complete and error interrupt */
|
||||
/* if the DMA mode is not CIRCULAR */
|
||||
__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 */
|
||||
hdma->DmaBaseAddress->IFCR = (DMA_ISR_TCIF1 << (hdma->ChannelIndex & 0x1CU));
|
||||
|
||||
/* Process Unlocked */
|
||||
__HAL_UNLOCK(hdma);
|
||||
|
||||
if(hdma->XferCpltCallback != NULL)
|
||||
{
|
||||
/* Transfer complete callback */
|
||||
hdma->XferCpltCallback(hdma);
|
||||
}
|
||||
}
|
||||
|
||||
/* Transfer Error Interrupt management **************************************/
|
||||
else if (((flag_it & (DMA_FLAG_TE1 << (hdma->ChannelIndex & 0x1CU))) != 0U) && ((source_it & DMA_IT_TE) != 0U))
|
||||
{
|
||||
/* 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 & 0x1CU));
|
||||
|
||||
/* 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);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Nothing To Do */
|
||||
}
|
||||
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 identifier
|
||||
* 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 identifier
|
||||
* 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 handle 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)
|
||||
{
|
||||
#if defined(DMAMUX1)
|
||||
/* Clear the DMAMUX synchro overrun flag */
|
||||
hdma->DMAmuxChannelStatus->CFR = hdma->DMAmuxChannelStatusMask;
|
||||
|
||||
if(hdma->DMAmuxRequestGen != 0U)
|
||||
{
|
||||
/* Clear the DMAMUX request generator overrun flag */
|
||||
hdma->DMAmuxRequestGenStatus->RGCFR = hdma->DMAmuxRequestGenStatusMask;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Clear all flags */
|
||||
hdma->DmaBaseAddress->IFCR = (DMA_ISR_GIF1 << (hdma->ChannelIndex & 0x1CU));
|
||||
|
||||
/* 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;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(DMAMUX1)
|
||||
|
||||
/**
|
||||
* @brief Updates the DMA handle with the DMAMUX channel and status mask depending on channel number
|
||||
* @param hdma pointer to a DMA_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified DMA Channel.
|
||||
* @retval None
|
||||
*/
|
||||
static void DMA_CalcDMAMUXChannelBaseAndMask(DMA_HandleTypeDef *hdma)
|
||||
{
|
||||
uint32_t channel_number;
|
||||
|
||||
/* check if instance is not outside the DMA channel range */
|
||||
if ((uint32_t)hdma->Instance < (uint32_t)DMA2_Channel1)
|
||||
{
|
||||
/* DMA1 */
|
||||
hdma->DMAmuxChannel = (DMAMUX1_Channel0 + (hdma->ChannelIndex >> 2U));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* DMA2 */
|
||||
hdma->DMAmuxChannel = (DMAMUX1_Channel7 + (hdma->ChannelIndex >> 2U));
|
||||
}
|
||||
|
||||
channel_number = (((uint32_t)hdma->Instance & 0xFFU) - 8U) / 20U;
|
||||
hdma->DMAmuxChannelStatus = DMAMUX1_ChannelStatus;
|
||||
hdma->DMAmuxChannelStatusMask = 1UL << (channel_number & 0x1FU);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Updates the DMA handle with the DMAMUX request generator params
|
||||
* @param hdma pointer to a DMA_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified DMA Channel.
|
||||
* @retval None
|
||||
*/
|
||||
|
||||
static void DMA_CalcDMAMUXRequestGenBaseAndMask(DMA_HandleTypeDef *hdma)
|
||||
{
|
||||
uint32_t request = hdma->Init.Request & DMAMUX_CxCR_DMAREQ_ID;
|
||||
|
||||
/* DMA Channels are connected to DMAMUX1 request generator blocks*/
|
||||
hdma->DMAmuxRequestGen = (DMAMUX_RequestGen_TypeDef *)((uint32_t)(((uint32_t)DMAMUX1_RequestGenerator0) + ((request - 1U) * 4U)));
|
||||
|
||||
hdma->DMAmuxRequestGenStatus = DMAMUX1_RequestGenStatus;
|
||||
|
||||
/* here "Request" is either DMA_REQUEST_GENERATOR0 to DMA_REQUEST_GENERATOR3, i.e. <= 4*/
|
||||
hdma->DMAmuxRequestGenStatusMask = 1UL << ((request - 1U) & 0x3U);
|
||||
}
|
||||
|
||||
#endif /* DMAMUX1 */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* HAL_DMA_MODULE_ENABLED */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
@@ -1,307 +0,0 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32l4xx_hal_dma_ex.c
|
||||
* @author MCD Application Team
|
||||
* @brief DMA Extension HAL module driver
|
||||
* This file provides firmware functions to manage the following
|
||||
* functionalities of the DMA Extension peripheral:
|
||||
* + Extended features functions
|
||||
*
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2017 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
@verbatim
|
||||
==============================================================================
|
||||
##### How to use this driver #####
|
||||
==============================================================================
|
||||
[..]
|
||||
The DMA Extension HAL driver can be used as follows:
|
||||
|
||||
(+) Configure the DMA_MUX Synchronization Block using HAL_DMAEx_ConfigMuxSync function.
|
||||
(+) Configure the DMA_MUX Request Generator Block using HAL_DMAEx_ConfigMuxRequestGenerator function.
|
||||
Functions HAL_DMAEx_EnableMuxRequestGenerator and HAL_DMAEx_DisableMuxRequestGenerator can then be used
|
||||
to respectively enable/disable the request generator.
|
||||
|
||||
(+) To handle the DMAMUX Interrupts, the function HAL_DMAEx_MUX_IRQHandler should be called from
|
||||
the DMAMUX IRQ handler i.e DMAMUX1_OVR_IRQHandler.
|
||||
As only one interrupt line is available for all DMAMUX channels and request generators , HAL_DMAEx_MUX_IRQHandler should be
|
||||
called with, as parameter, the appropriate DMA handle as many as used DMAs in the user project
|
||||
(exception done if a given DMA is not using the DMAMUX SYNC block neither a request generator)
|
||||
|
||||
-@- In Memory-to-Memory transfer mode, Multi (Double) Buffer mode is not allowed.
|
||||
-@- When Multi (Double) Buffer mode is enabled, the transfer is circular by default.
|
||||
-@- In Multi (Double) buffer mode, it is possible to update the base address for
|
||||
the AHB memory port on the fly (DMA_CM0ARx or DMA_CM1ARx) when the channel is enabled.
|
||||
|
||||
|
||||
@endverbatim
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32l4xx_hal.h"
|
||||
|
||||
#if defined(DMAMUX1)
|
||||
|
||||
/** @addtogroup STM32L4xx_HAL_Driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup DMAEx DMAEx
|
||||
* @brief DMA Extended HAL module driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifdef HAL_DMA_MODULE_ENABLED
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private Constants ---------------------------------------------------------*/
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* Private functions ---------------------------------------------------------*/
|
||||
|
||||
|
||||
/** @defgroup DMAEx_Exported_Functions DMAEx Exported Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup DMAEx_Exported_Functions_Group1 DMAEx Extended features functions
|
||||
* @brief Extended features functions
|
||||
*
|
||||
@verbatim
|
||||
===============================================================================
|
||||
##### Extended features functions #####
|
||||
===============================================================================
|
||||
[..] This section provides functions allowing to:
|
||||
|
||||
(+) Configure the DMAMUX Synchronization Block using HAL_DMAEx_ConfigMuxSync function.
|
||||
(+) Configure the DMAMUX Request Generator Block using HAL_DMAEx_ConfigMuxRequestGenerator function.
|
||||
Functions HAL_DMAEx_EnableMuxRequestGenerator and HAL_DMAEx_DisableMuxRequestGenerator can then be used
|
||||
to respectively enable/disable the request generator.
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief Configure the DMAMUX synchronization parameters for a given DMA channel (instance).
|
||||
* @param hdma pointer to a DMA_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified DMA channel.
|
||||
* @param pSyncConfig : pointer to HAL_DMA_MuxSyncConfigTypeDef : contains the DMAMUX synchronization parameters
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_DMAEx_ConfigMuxSync(DMA_HandleTypeDef *hdma, HAL_DMA_MuxSyncConfigTypeDef *pSyncConfig)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_DMA_ALL_INSTANCE(hdma->Instance));
|
||||
|
||||
assert_param(IS_DMAMUX_SYNC_SIGNAL_ID(pSyncConfig->SyncSignalID));
|
||||
|
||||
assert_param(IS_DMAMUX_SYNC_POLARITY(pSyncConfig-> SyncPolarity));
|
||||
assert_param(IS_DMAMUX_SYNC_STATE(pSyncConfig->SyncEnable));
|
||||
assert_param(IS_DMAMUX_SYNC_EVENT(pSyncConfig->EventEnable));
|
||||
assert_param(IS_DMAMUX_SYNC_REQUEST_NUMBER(pSyncConfig->RequestNumber));
|
||||
|
||||
/*Check if the DMA state is ready */
|
||||
if(hdma->State == HAL_DMA_STATE_READY)
|
||||
{
|
||||
/* Process Locked */
|
||||
__HAL_LOCK(hdma);
|
||||
|
||||
/* Set the new synchronization parameters (and keep the request ID filled during the Init)*/
|
||||
MODIFY_REG( hdma->DMAmuxChannel->CCR, \
|
||||
(~DMAMUX_CxCR_DMAREQ_ID) , \
|
||||
((pSyncConfig->SyncSignalID) << DMAMUX_CxCR_SYNC_ID_Pos) | ((pSyncConfig->RequestNumber - 1U) << DMAMUX_CxCR_NBREQ_Pos) | \
|
||||
pSyncConfig->SyncPolarity | ((uint32_t)pSyncConfig->SyncEnable << DMAMUX_CxCR_SE_Pos) | \
|
||||
((uint32_t)pSyncConfig->EventEnable << DMAMUX_CxCR_EGE_Pos));
|
||||
|
||||
/* Process UnLocked */
|
||||
__HAL_UNLOCK(hdma);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*DMA State not Ready*/
|
||||
return HAL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure the DMAMUX request generator block used by the given DMA channel (instance).
|
||||
* @param hdma pointer to a DMA_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified DMA channel.
|
||||
* @param pRequestGeneratorConfig : pointer to HAL_DMA_MuxRequestGeneratorConfigTypeDef :
|
||||
* contains the request generator parameters.
|
||||
*
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_DMAEx_ConfigMuxRequestGenerator (DMA_HandleTypeDef *hdma, HAL_DMA_MuxRequestGeneratorConfigTypeDef *pRequestGeneratorConfig)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_DMA_ALL_INSTANCE(hdma->Instance));
|
||||
|
||||
assert_param(IS_DMAMUX_REQUEST_GEN_SIGNAL_ID(pRequestGeneratorConfig->SignalID));
|
||||
|
||||
assert_param(IS_DMAMUX_REQUEST_GEN_POLARITY(pRequestGeneratorConfig->Polarity));
|
||||
assert_param(IS_DMAMUX_REQUEST_GEN_REQUEST_NUMBER(pRequestGeneratorConfig->RequestNumber));
|
||||
|
||||
/* check if the DMA state is ready
|
||||
and DMA is using a DMAMUX request generator block
|
||||
*/
|
||||
if((hdma->State == HAL_DMA_STATE_READY) && (hdma->DMAmuxRequestGen != 0U))
|
||||
{
|
||||
/* Process Locked */
|
||||
__HAL_LOCK(hdma);
|
||||
|
||||
/* Set the request generator new parameters */
|
||||
hdma->DMAmuxRequestGen->RGCR = pRequestGeneratorConfig->SignalID | \
|
||||
((pRequestGeneratorConfig->RequestNumber - 1U) << DMAMUX_RGxCR_GNBREQ_Pos)| \
|
||||
pRequestGeneratorConfig->Polarity;
|
||||
/* Process UnLocked */
|
||||
__HAL_UNLOCK(hdma);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable the DMAMUX request generator block used by the given DMA channel (instance).
|
||||
* @param hdma pointer to a DMA_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified DMA channel.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_DMAEx_EnableMuxRequestGenerator (DMA_HandleTypeDef *hdma)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_DMA_ALL_INSTANCE(hdma->Instance));
|
||||
|
||||
/* check if the DMA state is ready
|
||||
and DMA is using a DMAMUX request generator block
|
||||
*/
|
||||
if((hdma->State != HAL_DMA_STATE_RESET) && (hdma->DMAmuxRequestGen != 0))
|
||||
{
|
||||
|
||||
/* Enable the request generator*/
|
||||
hdma->DMAmuxRequestGen->RGCR |= DMAMUX_RGxCR_GE;
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable the DMAMUX request generator block used by the given DMA channel (instance).
|
||||
* @param hdma pointer to a DMA_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified DMA channel.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_DMAEx_DisableMuxRequestGenerator (DMA_HandleTypeDef *hdma)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_DMA_ALL_INSTANCE(hdma->Instance));
|
||||
|
||||
/* check if the DMA state is ready
|
||||
and DMA is using a DMAMUX request generator block
|
||||
*/
|
||||
if((hdma->State != HAL_DMA_STATE_RESET) && (hdma->DMAmuxRequestGen != 0))
|
||||
{
|
||||
|
||||
/* Disable the request generator*/
|
||||
hdma->DMAmuxRequestGen->RGCR &= ~DMAMUX_RGxCR_GE;
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Handles DMAMUX interrupt request.
|
||||
* @param hdma pointer to a DMA_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified DMA channel.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_DMAEx_MUX_IRQHandler(DMA_HandleTypeDef *hdma)
|
||||
{
|
||||
/* Check for DMAMUX Synchronization overrun */
|
||||
if((hdma->DMAmuxChannelStatus->CSR & hdma->DMAmuxChannelStatusMask) != 0U)
|
||||
{
|
||||
/* Disable the synchro overrun interrupt */
|
||||
hdma->DMAmuxChannel->CCR &= ~DMAMUX_CxCR_SOIE;
|
||||
|
||||
/* Clear the DMAMUX synchro overrun flag */
|
||||
hdma->DMAmuxChannelStatus->CFR = hdma->DMAmuxChannelStatusMask;
|
||||
|
||||
/* Update error code */
|
||||
hdma->ErrorCode |= HAL_DMA_ERROR_SYNC;
|
||||
|
||||
if(hdma->XferErrorCallback != NULL)
|
||||
{
|
||||
/* Transfer error callback */
|
||||
hdma->XferErrorCallback(hdma);
|
||||
}
|
||||
}
|
||||
|
||||
if(hdma->DMAmuxRequestGen != 0)
|
||||
{
|
||||
/* if using a DMAMUX request generator block Check for DMAMUX request generator overrun */
|
||||
if((hdma->DMAmuxRequestGenStatus->RGSR & hdma->DMAmuxRequestGenStatusMask) != 0U)
|
||||
{
|
||||
/* Disable the request gen overrun interrupt */
|
||||
hdma->DMAmuxRequestGen->RGCR &= ~DMAMUX_RGxCR_OIE;
|
||||
|
||||
/* Clear the DMAMUX request generator overrun flag */
|
||||
hdma->DMAmuxRequestGenStatus->RGCFR = hdma->DMAmuxRequestGenStatusMask;
|
||||
|
||||
/* Update error code */
|
||||
hdma->ErrorCode |= HAL_DMA_ERROR_REQGEN;
|
||||
|
||||
if(hdma->XferErrorCallback != NULL)
|
||||
{
|
||||
/* Transfer error callback */
|
||||
hdma->XferErrorCallback(hdma);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* HAL_DMA_MODULE_ENABLED */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* DMAMUX1 */
|
||||
@@ -1,632 +0,0 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32l4xx_hal_exti.c
|
||||
* @author MCD Application Team
|
||||
* @brief EXTI HAL module driver.
|
||||
* This file provides firmware functions to manage the following
|
||||
* functionalities of the Extended Interrupts and events controller (EXTI) peripheral:
|
||||
* + Initialization and de-initialization functions
|
||||
* + IO operation functions
|
||||
*
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2018 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
@verbatim
|
||||
==============================================================================
|
||||
##### EXTI Peripheral features #####
|
||||
==============================================================================
|
||||
[..]
|
||||
(+) Each Exti line can be configured within this driver.
|
||||
|
||||
(+) Exti line can be configured in 3 different modes
|
||||
(++) Interrupt
|
||||
(++) Event
|
||||
(++) Both of them
|
||||
|
||||
(+) Configurable Exti lines can be configured with 3 different triggers
|
||||
(++) Rising
|
||||
(++) Falling
|
||||
(++) Both of them
|
||||
|
||||
(+) When set in interrupt mode, configurable Exti lines have two different
|
||||
interrupts pending registers which allow to distinguish which transition
|
||||
occurs:
|
||||
(++) Rising edge pending interrupt
|
||||
(++) Falling
|
||||
|
||||
(+) Exti lines 0 to 15 are linked to gpio pin number 0 to 15. Gpio port can
|
||||
be selected through multiplexer.
|
||||
|
||||
##### How to use this driver #####
|
||||
==============================================================================
|
||||
[..]
|
||||
|
||||
(#) Configure the EXTI line using HAL_EXTI_SetConfigLine().
|
||||
(++) Choose the interrupt line number by setting "Line" member from
|
||||
EXTI_ConfigTypeDef structure.
|
||||
(++) Configure the interrupt and/or event mode using "Mode" member from
|
||||
EXTI_ConfigTypeDef structure.
|
||||
(++) For configurable lines, configure rising and/or falling trigger
|
||||
"Trigger" member from EXTI_ConfigTypeDef structure.
|
||||
(++) For Exti lines linked to gpio, choose gpio port using "GPIOSel"
|
||||
member from GPIO_InitTypeDef structure.
|
||||
|
||||
(#) Get current Exti configuration of a dedicated line using
|
||||
HAL_EXTI_GetConfigLine().
|
||||
(++) Provide exiting handle as parameter.
|
||||
(++) Provide pointer on EXTI_ConfigTypeDef structure as second parameter.
|
||||
|
||||
(#) Clear Exti configuration of a dedicated line using HAL_EXTI_GetConfigLine().
|
||||
(++) Provide exiting handle as parameter.
|
||||
|
||||
(#) Register callback to treat Exti interrupts using HAL_EXTI_RegisterCallback().
|
||||
(++) Provide exiting handle as first parameter.
|
||||
(++) Provide which callback will be registered using one value from
|
||||
EXTI_CallbackIDTypeDef.
|
||||
(++) Provide callback function pointer.
|
||||
|
||||
(#) Get interrupt pending bit using HAL_EXTI_GetPending().
|
||||
|
||||
(#) Clear interrupt pending bit using HAL_EXTI_GetPending().
|
||||
|
||||
(#) Generate software interrupt using HAL_EXTI_GenerateSWI().
|
||||
|
||||
@endverbatim
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32l4xx_hal.h"
|
||||
|
||||
/** @addtogroup STM32L4xx_HAL_Driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup EXTI
|
||||
* @{
|
||||
*/
|
||||
/** MISRA C:2012 deviation rule has been granted for following rule:
|
||||
* Rule-18.1_b - Medium: Array `EXTICR' 1st subscript interval [0,7] may be out
|
||||
* of bounds [0,3] in following API :
|
||||
* HAL_EXTI_SetConfigLine
|
||||
* HAL_EXTI_GetConfigLine
|
||||
* HAL_EXTI_ClearConfigLine
|
||||
*/
|
||||
|
||||
#ifdef HAL_EXTI_MODULE_ENABLED
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private defines ------------------------------------------------------------*/
|
||||
/** @defgroup EXTI_Private_Constants EXTI Private Constants
|
||||
* @{
|
||||
*/
|
||||
#define EXTI_MODE_OFFSET 0x08u /* 0x20: offset between MCU IMR/EMR registers */
|
||||
#define EXTI_CONFIG_OFFSET 0x08u /* 0x20: offset between MCU Rising/Falling configuration registers */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private macros ------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* Exported functions --------------------------------------------------------*/
|
||||
|
||||
/** @addtogroup EXTI_Exported_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup EXTI_Exported_Functions_Group1
|
||||
* @brief Configuration functions
|
||||
*
|
||||
@verbatim
|
||||
===============================================================================
|
||||
##### Configuration functions #####
|
||||
===============================================================================
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Set configuration of a dedicated Exti line.
|
||||
* @param hexti Exti handle.
|
||||
* @param pExtiConfig Pointer on EXTI configuration to be set.
|
||||
* @retval HAL Status.
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_EXTI_SetConfigLine(EXTI_HandleTypeDef *hexti, EXTI_ConfigTypeDef *pExtiConfig)
|
||||
{
|
||||
__IO uint32_t *regaddr;
|
||||
uint32_t regval;
|
||||
uint32_t linepos;
|
||||
uint32_t maskline;
|
||||
uint32_t offset;
|
||||
|
||||
/* Check null pointer */
|
||||
if ((hexti == NULL) || (pExtiConfig == NULL))
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Check parameters */
|
||||
assert_param(IS_EXTI_LINE(pExtiConfig->Line));
|
||||
assert_param(IS_EXTI_MODE(pExtiConfig->Mode));
|
||||
|
||||
/* Assign line number to handle */
|
||||
hexti->Line = pExtiConfig->Line;
|
||||
|
||||
/* Compute line register offset and line mask */
|
||||
offset = ((pExtiConfig->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
|
||||
linepos = (pExtiConfig->Line & EXTI_PIN_MASK);
|
||||
maskline = (1uL << linepos);
|
||||
|
||||
/* Configure triggers for configurable lines */
|
||||
if ((pExtiConfig->Line & EXTI_CONFIG) != 0x00u)
|
||||
{
|
||||
assert_param(IS_EXTI_TRIGGER(pExtiConfig->Trigger));
|
||||
|
||||
/* Configure rising trigger */
|
||||
regaddr = (&EXTI->RTSR1 + (EXTI_CONFIG_OFFSET * offset));
|
||||
regval = *regaddr;
|
||||
|
||||
/* Mask or set line */
|
||||
if ((pExtiConfig->Trigger & EXTI_TRIGGER_RISING) != 0x00u)
|
||||
{
|
||||
regval |= maskline;
|
||||
}
|
||||
else
|
||||
{
|
||||
regval &= ~maskline;
|
||||
}
|
||||
|
||||
/* Store rising trigger mode */
|
||||
*regaddr = regval;
|
||||
|
||||
/* Configure falling trigger */
|
||||
regaddr = (&EXTI->FTSR1 + (EXTI_CONFIG_OFFSET * offset));
|
||||
regval = *regaddr;
|
||||
|
||||
/* Mask or set line */
|
||||
if ((pExtiConfig->Trigger & EXTI_TRIGGER_FALLING) != 0x00u)
|
||||
{
|
||||
regval |= maskline;
|
||||
}
|
||||
else
|
||||
{
|
||||
regval &= ~maskline;
|
||||
}
|
||||
|
||||
/* Store falling trigger mode */
|
||||
*regaddr = regval;
|
||||
|
||||
/* Configure gpio port selection in case of gpio exti line */
|
||||
if ((pExtiConfig->Line & EXTI_GPIO) == EXTI_GPIO)
|
||||
{
|
||||
assert_param(IS_EXTI_GPIO_PORT(pExtiConfig->GPIOSel));
|
||||
assert_param(IS_EXTI_GPIO_PIN(linepos));
|
||||
|
||||
regval = SYSCFG->EXTICR[linepos >> 2u];
|
||||
regval &= ~(SYSCFG_EXTICR1_EXTI0 << (SYSCFG_EXTICR1_EXTI1_Pos * (linepos & 0x03u)));
|
||||
regval |= (pExtiConfig->GPIOSel << (SYSCFG_EXTICR1_EXTI1_Pos * (linepos & 0x03u)));
|
||||
SYSCFG->EXTICR[linepos >> 2u] = regval;
|
||||
}
|
||||
}
|
||||
|
||||
/* Configure interrupt mode : read current mode */
|
||||
regaddr = (&EXTI->IMR1 + (EXTI_MODE_OFFSET * offset));
|
||||
regval = *regaddr;
|
||||
|
||||
/* Mask or set line */
|
||||
if ((pExtiConfig->Mode & EXTI_MODE_INTERRUPT) != 0x00u)
|
||||
{
|
||||
regval |= maskline;
|
||||
}
|
||||
else
|
||||
{
|
||||
regval &= ~maskline;
|
||||
}
|
||||
|
||||
/* Store interrupt mode */
|
||||
*regaddr = regval;
|
||||
|
||||
/* The event mode cannot be configured if the line does not support it */
|
||||
assert_param(((pExtiConfig->Line & EXTI_EVENT) == EXTI_EVENT) || ((pExtiConfig->Mode & EXTI_MODE_EVENT) != EXTI_MODE_EVENT));
|
||||
|
||||
/* Configure event mode : read current mode */
|
||||
regaddr = (&EXTI->EMR1 + (EXTI_MODE_OFFSET * offset));
|
||||
regval = *regaddr;
|
||||
|
||||
/* Mask or set line */
|
||||
if ((pExtiConfig->Mode & EXTI_MODE_EVENT) != 0x00u)
|
||||
{
|
||||
regval |= maskline;
|
||||
}
|
||||
else
|
||||
{
|
||||
regval &= ~maskline;
|
||||
}
|
||||
|
||||
/* Store event mode */
|
||||
*regaddr = regval;
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Get configuration of a dedicated Exti line.
|
||||
* @param hexti Exti handle.
|
||||
* @param pExtiConfig Pointer on structure to store Exti configuration.
|
||||
* @retval HAL Status.
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_EXTI_GetConfigLine(EXTI_HandleTypeDef *hexti, EXTI_ConfigTypeDef *pExtiConfig)
|
||||
{
|
||||
__IO uint32_t *regaddr;
|
||||
uint32_t regval;
|
||||
uint32_t linepos;
|
||||
uint32_t maskline;
|
||||
uint32_t offset;
|
||||
|
||||
/* Check null pointer */
|
||||
if ((hexti == NULL) || (pExtiConfig == NULL))
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Check the parameter */
|
||||
assert_param(IS_EXTI_LINE(hexti->Line));
|
||||
|
||||
/* Store handle line number to configuration structure */
|
||||
pExtiConfig->Line = hexti->Line;
|
||||
|
||||
/* Compute line register offset and line mask */
|
||||
offset = ((pExtiConfig->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
|
||||
linepos = (pExtiConfig->Line & EXTI_PIN_MASK);
|
||||
maskline = (1uL << linepos);
|
||||
|
||||
/* 1] Get core mode : interrupt */
|
||||
regaddr = (&EXTI->IMR1 + (EXTI_MODE_OFFSET * offset));
|
||||
regval = *regaddr;
|
||||
|
||||
/* Check if selected line is enable */
|
||||
if ((regval & maskline) != 0x00u)
|
||||
{
|
||||
pExtiConfig->Mode = EXTI_MODE_INTERRUPT;
|
||||
}
|
||||
else
|
||||
{
|
||||
pExtiConfig->Mode = EXTI_MODE_NONE;
|
||||
}
|
||||
|
||||
/* Get event mode */
|
||||
regaddr = (&EXTI->EMR1 + (EXTI_MODE_OFFSET * offset));
|
||||
regval = *regaddr;
|
||||
|
||||
/* Check if selected line is enable */
|
||||
if ((regval & maskline) != 0x00u)
|
||||
{
|
||||
pExtiConfig->Mode |= EXTI_MODE_EVENT;
|
||||
}
|
||||
|
||||
/* Get default Trigger and GPIOSel configuration */
|
||||
pExtiConfig->Trigger = EXTI_TRIGGER_NONE;
|
||||
pExtiConfig->GPIOSel = 0x00u;
|
||||
|
||||
/* 2] Get trigger for configurable lines : rising */
|
||||
if ((pExtiConfig->Line & EXTI_CONFIG) != 0x00u)
|
||||
{
|
||||
regaddr = (&EXTI->RTSR1 + (EXTI_CONFIG_OFFSET * offset));
|
||||
regval = *regaddr;
|
||||
|
||||
/* Check if configuration of selected line is enable */
|
||||
if ((regval & maskline) != 0x00u)
|
||||
{
|
||||
pExtiConfig->Trigger = EXTI_TRIGGER_RISING;
|
||||
}
|
||||
|
||||
/* Get falling configuration */
|
||||
regaddr = (&EXTI->FTSR1 + (EXTI_CONFIG_OFFSET * offset));
|
||||
regval = *regaddr;
|
||||
|
||||
/* Check if configuration of selected line is enable */
|
||||
if ((regval & maskline) != 0x00u)
|
||||
{
|
||||
pExtiConfig->Trigger |= EXTI_TRIGGER_FALLING;
|
||||
}
|
||||
|
||||
/* Get Gpio port selection for gpio lines */
|
||||
if ((pExtiConfig->Line & EXTI_GPIO) == EXTI_GPIO)
|
||||
{
|
||||
assert_param(IS_EXTI_GPIO_PIN(linepos));
|
||||
|
||||
regval = SYSCFG->EXTICR[linepos >> 2u];
|
||||
pExtiConfig->GPIOSel = ((regval << (SYSCFG_EXTICR1_EXTI1_Pos * (3uL - (linepos & 0x03u)))) >> 24);
|
||||
}
|
||||
}
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Clear whole configuration of a dedicated Exti line.
|
||||
* @param hexti Exti handle.
|
||||
* @retval HAL Status.
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_EXTI_ClearConfigLine(EXTI_HandleTypeDef *hexti)
|
||||
{
|
||||
__IO uint32_t *regaddr;
|
||||
uint32_t regval;
|
||||
uint32_t linepos;
|
||||
uint32_t maskline;
|
||||
uint32_t offset;
|
||||
|
||||
/* Check null pointer */
|
||||
if (hexti == NULL)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Check the parameter */
|
||||
assert_param(IS_EXTI_LINE(hexti->Line));
|
||||
|
||||
/* compute line register offset and line mask */
|
||||
offset = ((hexti->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
|
||||
linepos = (hexti->Line & EXTI_PIN_MASK);
|
||||
maskline = (1uL << linepos);
|
||||
|
||||
/* 1] Clear interrupt mode */
|
||||
regaddr = (&EXTI->IMR1 + (EXTI_MODE_OFFSET * offset));
|
||||
regval = (*regaddr & ~maskline);
|
||||
*regaddr = regval;
|
||||
|
||||
/* 2] Clear event mode */
|
||||
regaddr = (&EXTI->EMR1 + (EXTI_MODE_OFFSET * offset));
|
||||
regval = (*regaddr & ~maskline);
|
||||
*regaddr = regval;
|
||||
|
||||
/* 3] Clear triggers in case of configurable lines */
|
||||
if ((hexti->Line & EXTI_CONFIG) != 0x00u)
|
||||
{
|
||||
regaddr = (&EXTI->RTSR1 + (EXTI_CONFIG_OFFSET * offset));
|
||||
regval = (*regaddr & ~maskline);
|
||||
*regaddr = regval;
|
||||
|
||||
regaddr = (&EXTI->FTSR1 + (EXTI_CONFIG_OFFSET * offset));
|
||||
regval = (*regaddr & ~maskline);
|
||||
*regaddr = regval;
|
||||
|
||||
/* Get Gpio port selection for gpio lines */
|
||||
if ((hexti->Line & EXTI_GPIO) == EXTI_GPIO)
|
||||
{
|
||||
assert_param(IS_EXTI_GPIO_PIN(linepos));
|
||||
|
||||
regval = SYSCFG->EXTICR[linepos >> 2u];
|
||||
regval &= ~(SYSCFG_EXTICR1_EXTI0 << (SYSCFG_EXTICR1_EXTI1_Pos * (linepos & 0x03u)));
|
||||
SYSCFG->EXTICR[linepos >> 2u] = regval;
|
||||
}
|
||||
}
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Register callback for a dedicated Exti line.
|
||||
* @param hexti Exti handle.
|
||||
* @param CallbackID User callback identifier.
|
||||
* This parameter can be one of @arg @ref EXTI_CallbackIDTypeDef values.
|
||||
* @param pPendingCbfn function pointer to be stored as callback.
|
||||
* @retval HAL Status.
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_EXTI_RegisterCallback(EXTI_HandleTypeDef *hexti, EXTI_CallbackIDTypeDef CallbackID, void (*pPendingCbfn)(void))
|
||||
{
|
||||
HAL_StatusTypeDef status = HAL_OK;
|
||||
|
||||
switch (CallbackID)
|
||||
{
|
||||
case HAL_EXTI_COMMON_CB_ID:
|
||||
hexti->PendingCallback = pPendingCbfn;
|
||||
break;
|
||||
|
||||
default:
|
||||
status = HAL_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Store line number as handle private field.
|
||||
* @param hexti Exti handle.
|
||||
* @param ExtiLine Exti line number.
|
||||
* This parameter can be from 0 to @ref EXTI_LINE_NB.
|
||||
* @retval HAL Status.
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_EXTI_GetHandle(EXTI_HandleTypeDef *hexti, uint32_t ExtiLine)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_EXTI_LINE(ExtiLine));
|
||||
|
||||
/* Check null pointer */
|
||||
if (hexti == NULL)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Store line number as handle private field */
|
||||
hexti->Line = ExtiLine;
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup EXTI_Exported_Functions_Group2
|
||||
* @brief EXTI IO functions.
|
||||
*
|
||||
@verbatim
|
||||
===============================================================================
|
||||
##### IO operation functions #####
|
||||
===============================================================================
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Handle EXTI interrupt request.
|
||||
* @param hexti Exti handle.
|
||||
* @retval none.
|
||||
*/
|
||||
void HAL_EXTI_IRQHandler(EXTI_HandleTypeDef *hexti)
|
||||
{
|
||||
__IO uint32_t *regaddr;
|
||||
uint32_t regval;
|
||||
uint32_t maskline;
|
||||
uint32_t offset;
|
||||
|
||||
/* Compute line register offset and line mask */
|
||||
offset = ((hexti->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
|
||||
maskline = (1uL << (hexti->Line & EXTI_PIN_MASK));
|
||||
|
||||
/* Get pending bit */
|
||||
regaddr = (&EXTI->PR1 + (EXTI_CONFIG_OFFSET * offset));
|
||||
regval = (*regaddr & maskline);
|
||||
|
||||
if (regval != 0x00u)
|
||||
{
|
||||
/* Clear pending bit */
|
||||
*regaddr = maskline;
|
||||
|
||||
/* Call callback */
|
||||
if (hexti->PendingCallback != NULL)
|
||||
{
|
||||
hexti->PendingCallback();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Get interrupt pending bit of a dedicated line.
|
||||
* @param hexti Exti handle.
|
||||
* @param Edge Specify which pending edge as to be checked.
|
||||
* This parameter can be one of the following values:
|
||||
* @arg @ref EXTI_TRIGGER_RISING_FALLING
|
||||
* This parameter is kept for compatibility with other series.
|
||||
* @retval 1 if interrupt is pending else 0.
|
||||
*/
|
||||
uint32_t HAL_EXTI_GetPending(EXTI_HandleTypeDef *hexti, uint32_t Edge)
|
||||
{
|
||||
__IO uint32_t *regaddr;
|
||||
uint32_t regval;
|
||||
uint32_t linepos;
|
||||
uint32_t maskline;
|
||||
uint32_t offset;
|
||||
|
||||
/* Check parameters */
|
||||
assert_param(IS_EXTI_LINE(hexti->Line));
|
||||
assert_param(IS_EXTI_CONFIG_LINE(hexti->Line));
|
||||
assert_param(IS_EXTI_PENDING_EDGE(Edge));
|
||||
|
||||
/* Compute line register offset and line mask */
|
||||
offset = ((hexti->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
|
||||
linepos = (hexti->Line & EXTI_PIN_MASK);
|
||||
maskline = (1uL << linepos);
|
||||
|
||||
/* Get pending bit */
|
||||
regaddr = (&EXTI->PR1 + (EXTI_CONFIG_OFFSET * offset));
|
||||
|
||||
/* return 1 if bit is set else 0 */
|
||||
regval = ((*regaddr & maskline) >> linepos);
|
||||
return regval;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Clear interrupt pending bit of a dedicated line.
|
||||
* @param hexti Exti handle.
|
||||
* @param Edge Specify which pending edge as to be clear.
|
||||
* This parameter can be one of the following values:
|
||||
* @arg @ref EXTI_TRIGGER_RISING_FALLING
|
||||
* This parameter is kept for compatibility with other series.
|
||||
* @retval None.
|
||||
*/
|
||||
void HAL_EXTI_ClearPending(EXTI_HandleTypeDef *hexti, uint32_t Edge)
|
||||
{
|
||||
__IO uint32_t *regaddr;
|
||||
uint32_t maskline;
|
||||
uint32_t offset;
|
||||
|
||||
/* Check parameters */
|
||||
assert_param(IS_EXTI_LINE(hexti->Line));
|
||||
assert_param(IS_EXTI_CONFIG_LINE(hexti->Line));
|
||||
assert_param(IS_EXTI_PENDING_EDGE(Edge));
|
||||
|
||||
/* compute line register offset and line mask */
|
||||
offset = ((hexti->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
|
||||
maskline = (1uL << (hexti->Line & EXTI_PIN_MASK));
|
||||
|
||||
/* Get pending register address */
|
||||
regaddr = (&EXTI->PR1 + (EXTI_CONFIG_OFFSET * offset));
|
||||
|
||||
/* Clear Pending bit */
|
||||
*regaddr = maskline;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Generate a software interrupt for a dedicated line.
|
||||
* @param hexti Exti handle.
|
||||
* @retval None.
|
||||
*/
|
||||
void HAL_EXTI_GenerateSWI(EXTI_HandleTypeDef *hexti)
|
||||
{
|
||||
__IO uint32_t *regaddr;
|
||||
uint32_t maskline;
|
||||
uint32_t offset;
|
||||
|
||||
/* Check parameters */
|
||||
assert_param(IS_EXTI_LINE(hexti->Line));
|
||||
assert_param(IS_EXTI_CONFIG_LINE(hexti->Line));
|
||||
|
||||
/* compute line register offset and line mask */
|
||||
offset = ((hexti->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
|
||||
maskline = (1uL << (hexti->Line & EXTI_PIN_MASK));
|
||||
|
||||
regaddr = (&EXTI->SWIER1 + (EXTI_CONFIG_OFFSET * offset));
|
||||
*regaddr = maskline;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* HAL_EXTI_MODULE_ENABLED */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
@@ -1,764 +0,0 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32l4xx_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 Errors 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 and cache lines.
|
||||
|
||||
[..] The FLASH main features are:
|
||||
(+) Flash memory read operations
|
||||
(+) Flash memory program/erase operations
|
||||
(+) Read / write protections
|
||||
(+) Option bytes programming
|
||||
(+) Prefetch on I-Code
|
||||
(+) 32 cache lines of 4*64 bits on I-Code
|
||||
(+) 8 cache lines of 4*64 bits on D-Code
|
||||
(+) Error code correction (ECC) : Data in flash are 72-bits word
|
||||
(8 bits added per double word)
|
||||
|
||||
|
||||
##### How to use this driver #####
|
||||
==============================================================================
|
||||
[..]
|
||||
This driver provides functions and macros to configure and program the FLASH
|
||||
memory of all STM32L4xx devices.
|
||||
|
||||
(#) Flash Memory IO Programming functions:
|
||||
(++) Lock and Unlock the FLASH interface using HAL_FLASH_Unlock() and
|
||||
HAL_FLASH_Lock() functions
|
||||
(++) Program functions: double word and fast program (full row programming)
|
||||
(++) There Two modes of programming :
|
||||
(+++) Polling mode using HAL_FLASH_Program() function
|
||||
(+++) Interrupt mode using HAL_FLASH_Program_IT() function
|
||||
|
||||
(#) Interrupts and flags management functions :
|
||||
(++) Handle FLASH interrupts by calling HAL_FLASH_IRQHandler()
|
||||
(++) Callback functions are called when the flash operations are finished :
|
||||
HAL_FLASH_EndOfOperationCallback() when everything is ok, otherwise
|
||||
HAL_FLASH_OperationErrorCallback()
|
||||
(++) Get error flag status by calling HAL_GetError()
|
||||
|
||||
(#) Option bytes management functions :
|
||||
(++) Lock and Unlock the option bytes using HAL_FLASH_OB_Unlock() and
|
||||
HAL_FLASH_OB_Lock() functions
|
||||
(++) Launch the reload of the option bytes using HAL_FLASH_Launch() function.
|
||||
In this case, a reset is generated
|
||||
|
||||
[..]
|
||||
In addition to these functions, this driver includes a set of macros allowing
|
||||
to handle the following operations:
|
||||
(+) Set the latency
|
||||
(+) Enable/Disable the prefetch buffer
|
||||
(+) Enable/Disable the Instruction cache and the Data cache
|
||||
(+) Reset the Instruction cache and the Data cache
|
||||
(+) Enable/Disable the Flash power-down during low-power run and sleep modes
|
||||
(+) Enable/Disable the Flash interrupts
|
||||
(+) Monitor the Flash flags status
|
||||
|
||||
@endverbatim
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2017 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file in
|
||||
* the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32l4xx_hal.h"
|
||||
|
||||
/** @addtogroup STM32L4xx_HAL_Driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup FLASH FLASH
|
||||
* @brief FLASH HAL module driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifdef HAL_FLASH_MODULE_ENABLED
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private defines -----------------------------------------------------------*/
|
||||
#if defined (STM32L4P5xx) || defined (STM32L4Q5xx) || defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)
|
||||
#define FLASH_NB_DOUBLE_WORDS_IN_ROW 64
|
||||
#else
|
||||
#define FLASH_NB_DOUBLE_WORDS_IN_ROW 32
|
||||
#endif
|
||||
/* Private macros ------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/** @defgroup FLASH_Private_Variables FLASH Private Variables
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Variable used for Program/Erase sectors under interruption
|
||||
*/
|
||||
FLASH_ProcessTypeDef pFlash = {.Lock = HAL_UNLOCKED, \
|
||||
.ErrorCode = HAL_FLASH_ERROR_NONE, \
|
||||
.ProcedureOnGoing = FLASH_PROC_NONE, \
|
||||
.Address = 0U, \
|
||||
.Bank = FLASH_BANK_1, \
|
||||
.Page = 0U, \
|
||||
.NbPagesToErase = 0U, \
|
||||
.CacheToReactivate = FLASH_CACHE_DISABLED};
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/** @defgroup FLASH_Private_Functions FLASH Private Functions
|
||||
* @{
|
||||
*/
|
||||
static void FLASH_Program_DoubleWord(uint32_t Address, uint64_t Data);
|
||||
static void FLASH_Program_Fast(uint32_t Address, uint32_t DataAddress);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Exported functions --------------------------------------------------------*/
|
||||
/** @defgroup FLASH_Exported_Functions FLASH Exported Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup FLASH_Exported_Functions_Group1 Programming operation functions
|
||||
* @brief Programming operation functions
|
||||
*
|
||||
@verbatim
|
||||
===============================================================================
|
||||
##### Programming operation functions #####
|
||||
===============================================================================
|
||||
[..]
|
||||
This subsection provides a set of functions allowing to manage the FLASH
|
||||
program operations.
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Program double word or fast program of a row at a specified address.
|
||||
* @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
|
||||
* This parameter is the data for the double word program and the address where
|
||||
* are stored the data for the row fast program
|
||||
*
|
||||
* @retval HAL_StatusTypeDef HAL Status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t Address, uint64_t Data)
|
||||
{
|
||||
HAL_StatusTypeDef status;
|
||||
uint32_t prog_bit = 0;
|
||||
|
||||
/* Process Locked */
|
||||
__HAL_LOCK(&pFlash);
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram));
|
||||
|
||||
/* Wait for last operation to be completed */
|
||||
status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
|
||||
|
||||
if(status == HAL_OK)
|
||||
{
|
||||
pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
|
||||
|
||||
/* Deactivate the data cache if they are activated to avoid data misbehavior */
|
||||
if(READ_BIT(FLASH->ACR, FLASH_ACR_DCEN) != 0U)
|
||||
{
|
||||
/* Disable data cache */
|
||||
__HAL_FLASH_DATA_CACHE_DISABLE();
|
||||
pFlash.CacheToReactivate = FLASH_CACHE_DCACHE_ENABLED;
|
||||
}
|
||||
else
|
||||
{
|
||||
pFlash.CacheToReactivate = FLASH_CACHE_DISABLED;
|
||||
}
|
||||
|
||||
if(TypeProgram == FLASH_TYPEPROGRAM_DOUBLEWORD)
|
||||
{
|
||||
/* Program double-word (64-bit) at a specified address */
|
||||
FLASH_Program_DoubleWord(Address, Data);
|
||||
prog_bit = FLASH_CR_PG;
|
||||
}
|
||||
else if((TypeProgram == FLASH_TYPEPROGRAM_FAST) || (TypeProgram == FLASH_TYPEPROGRAM_FAST_AND_LAST))
|
||||
{
|
||||
/* Fast program a 32 row double-word (64-bit) at a specified address */
|
||||
FLASH_Program_Fast(Address, (uint32_t)Data);
|
||||
|
||||
/* If it is the last row, the bit will be cleared at the end of the operation */
|
||||
if(TypeProgram == FLASH_TYPEPROGRAM_FAST_AND_LAST)
|
||||
{
|
||||
prog_bit = FLASH_CR_FSTPG;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Nothing to do */
|
||||
}
|
||||
|
||||
/* Wait for last operation to be completed */
|
||||
status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
|
||||
|
||||
/* If the program operation is completed, disable the PG or FSTPG Bit */
|
||||
if (prog_bit != 0U)
|
||||
{
|
||||
CLEAR_BIT(FLASH->CR, prog_bit);
|
||||
}
|
||||
|
||||
/* Flush the caches to be sure of the data consistency */
|
||||
FLASH_FlushCaches();
|
||||
}
|
||||
|
||||
/* Process Unlocked */
|
||||
__HAL_UNLOCK(&pFlash);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Program double word or fast program of a row at a specified address with interrupt enabled.
|
||||
* @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
|
||||
* This parameter is the data for the double word program and the address where
|
||||
* are stored the data for the row fast program
|
||||
*
|
||||
* @retval HAL Status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_FLASH_Program_IT(uint32_t TypeProgram, uint32_t Address, uint64_t Data)
|
||||
{
|
||||
HAL_StatusTypeDef status = HAL_OK;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram));
|
||||
|
||||
/* Process Locked */
|
||||
__HAL_LOCK(&pFlash);
|
||||
|
||||
pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
|
||||
|
||||
/* Deactivate the data cache if they are activated to avoid data misbehavior */
|
||||
if(READ_BIT(FLASH->ACR, FLASH_ACR_DCEN) != 0U)
|
||||
{
|
||||
/* Disable data cache */
|
||||
__HAL_FLASH_DATA_CACHE_DISABLE();
|
||||
pFlash.CacheToReactivate = FLASH_CACHE_DCACHE_ENABLED;
|
||||
}
|
||||
else
|
||||
{
|
||||
pFlash.CacheToReactivate = FLASH_CACHE_DISABLED;
|
||||
}
|
||||
|
||||
/* Set internal variables used by the IRQ handler */
|
||||
if(TypeProgram == FLASH_TYPEPROGRAM_FAST_AND_LAST)
|
||||
{
|
||||
pFlash.ProcedureOnGoing = FLASH_PROC_PROGRAM_LAST;
|
||||
}
|
||||
else
|
||||
{
|
||||
pFlash.ProcedureOnGoing = FLASH_PROC_PROGRAM;
|
||||
}
|
||||
pFlash.Address = Address;
|
||||
|
||||
/* Enable End of Operation and Error interrupts */
|
||||
__HAL_FLASH_ENABLE_IT(FLASH_IT_EOP | FLASH_IT_OPERR);
|
||||
|
||||
if(TypeProgram == FLASH_TYPEPROGRAM_DOUBLEWORD)
|
||||
{
|
||||
/* Program double-word (64-bit) at a specified address */
|
||||
FLASH_Program_DoubleWord(Address, Data);
|
||||
}
|
||||
else if((TypeProgram == FLASH_TYPEPROGRAM_FAST) || (TypeProgram == FLASH_TYPEPROGRAM_FAST_AND_LAST))
|
||||
{
|
||||
/* Fast program a 32 row double-word (64-bit) at a specified address */
|
||||
FLASH_Program_Fast(Address, (uint32_t)Data);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Nothing to do */
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Handle FLASH interrupt request.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_FLASH_IRQHandler(void)
|
||||
{
|
||||
uint32_t tmp_page;
|
||||
uint32_t error;
|
||||
FLASH_ProcedureTypeDef procedure;
|
||||
|
||||
/* If the operation is completed, disable the PG, PNB, MER1, MER2 and PER Bit */
|
||||
CLEAR_BIT(FLASH->CR, (FLASH_CR_PG | FLASH_CR_MER1 | FLASH_CR_PER | FLASH_CR_PNB));
|
||||
#if defined (STM32L471xx) || defined (STM32L475xx) || defined (STM32L476xx) || defined (STM32L485xx) || defined (STM32L486xx) || \
|
||||
defined (STM32L496xx) || defined (STM32L4A6xx) || \
|
||||
defined (STM32L4P5xx) || defined (STM32L4Q5xx) || \
|
||||
defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)
|
||||
CLEAR_BIT(FLASH->CR, FLASH_CR_MER2);
|
||||
#endif
|
||||
|
||||
/* Disable the FSTPG Bit only if it is the last row programmed */
|
||||
if(pFlash.ProcedureOnGoing == FLASH_PROC_PROGRAM_LAST)
|
||||
{
|
||||
CLEAR_BIT(FLASH->CR, FLASH_CR_FSTPG);
|
||||
}
|
||||
|
||||
/* Check FLASH operation error flags */
|
||||
error = (FLASH->SR & FLASH_FLAG_SR_ERRORS);
|
||||
|
||||
if (error !=0U)
|
||||
{
|
||||
/*Save the error code*/
|
||||
pFlash.ErrorCode |= error;
|
||||
|
||||
/* Clear error programming flags */
|
||||
__HAL_FLASH_CLEAR_FLAG(error);
|
||||
|
||||
/* Flush the caches to be sure of the data consistency */
|
||||
FLASH_FlushCaches() ;
|
||||
|
||||
/* FLASH error interrupt user callback */
|
||||
procedure = pFlash.ProcedureOnGoing;
|
||||
if(procedure == FLASH_PROC_PAGE_ERASE)
|
||||
{
|
||||
HAL_FLASH_OperationErrorCallback(pFlash.Page);
|
||||
}
|
||||
else if(procedure == FLASH_PROC_MASS_ERASE)
|
||||
{
|
||||
HAL_FLASH_OperationErrorCallback(pFlash.Bank);
|
||||
}
|
||||
else if((procedure == FLASH_PROC_PROGRAM) ||
|
||||
(procedure == FLASH_PROC_PROGRAM_LAST))
|
||||
{
|
||||
HAL_FLASH_OperationErrorCallback(pFlash.Address);
|
||||
}
|
||||
else
|
||||
{
|
||||
HAL_FLASH_OperationErrorCallback(0U);
|
||||
}
|
||||
|
||||
/*Stop the procedure ongoing*/
|
||||
pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
|
||||
}
|
||||
|
||||
/* Check FLASH End of Operation flag */
|
||||
if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP) != 0U)
|
||||
{
|
||||
/* Clear FLASH End of Operation pending bit */
|
||||
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP);
|
||||
|
||||
if(pFlash.ProcedureOnGoing == FLASH_PROC_PAGE_ERASE)
|
||||
{
|
||||
/* Nb of pages to erased can be decreased */
|
||||
pFlash.NbPagesToErase--;
|
||||
|
||||
/* Check if there are still pages to erase*/
|
||||
if(pFlash.NbPagesToErase != 0U)
|
||||
{
|
||||
/* Indicate user which page has been erased*/
|
||||
HAL_FLASH_EndOfOperationCallback(pFlash.Page);
|
||||
|
||||
/* Increment page number */
|
||||
pFlash.Page++;
|
||||
tmp_page = pFlash.Page;
|
||||
FLASH_PageErase(tmp_page, pFlash.Bank);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No more pages to Erase */
|
||||
/* Reset Address and stop Erase pages procedure */
|
||||
pFlash.Page = 0xFFFFFFFFU;
|
||||
pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
|
||||
|
||||
/* Flush the caches to be sure of the data consistency */
|
||||
FLASH_FlushCaches() ;
|
||||
|
||||
/* FLASH EOP interrupt user callback */
|
||||
HAL_FLASH_EndOfOperationCallback(pFlash.Page);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Flush the caches to be sure of the data consistency */
|
||||
FLASH_FlushCaches() ;
|
||||
|
||||
procedure = pFlash.ProcedureOnGoing;
|
||||
if(procedure == FLASH_PROC_MASS_ERASE)
|
||||
{
|
||||
/* MassErase ended. Return the selected bank */
|
||||
/* FLASH EOP interrupt user callback */
|
||||
HAL_FLASH_EndOfOperationCallback(pFlash.Bank);
|
||||
}
|
||||
else if((procedure == FLASH_PROC_PROGRAM) ||
|
||||
(procedure == FLASH_PROC_PROGRAM_LAST))
|
||||
{
|
||||
/* Program ended. Return the selected address */
|
||||
/* FLASH EOP interrupt user callback */
|
||||
HAL_FLASH_EndOfOperationCallback(pFlash.Address);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Nothing to do */
|
||||
}
|
||||
|
||||
/*Clear the procedure ongoing*/
|
||||
pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
if(pFlash.ProcedureOnGoing == FLASH_PROC_NONE)
|
||||
{
|
||||
/* Disable End of Operation and Error interrupts */
|
||||
__HAL_FLASH_DISABLE_IT(FLASH_IT_EOP | FLASH_IT_OPERR);
|
||||
|
||||
/* 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: Bank number which has been requested to erase
|
||||
* Page Erase: 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: Bank number which has been requested to erase
|
||||
* Page Erase: Page number 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) != 0U)
|
||||
{
|
||||
/* 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) != 0U)
|
||||
{
|
||||
status = HAL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Lock 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);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Unlock the FLASH Option Bytes Registers access.
|
||||
* @retval HAL Status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_FLASH_OB_Unlock(void)
|
||||
{
|
||||
if(READ_BIT(FLASH->CR, FLASH_CR_OPTLOCK) != 0U)
|
||||
{
|
||||
/* 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 Bytes Registers access.
|
||||
* @retval HAL Status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_FLASH_OB_Lock(void)
|
||||
{
|
||||
/* Set the OPTLOCK Bit to lock the FLASH Option Byte Registers access */
|
||||
SET_BIT(FLASH->CR, FLASH_CR_OPTLOCK);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Launch the option byte loading.
|
||||
* @retval HAL Status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_FLASH_OB_Launch(void)
|
||||
{
|
||||
/* Set the bit to force the option byte reloading */
|
||||
SET_BIT(FLASH->CR, FLASH_CR_OBL_LAUNCH);
|
||||
|
||||
/* Wait for last operation to be completed */
|
||||
return(FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE));
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup FLASH_Exported_Functions_Group3 Peripheral State and Errors functions
|
||||
* @brief Peripheral Errors functions
|
||||
*
|
||||
@verbatim
|
||||
===============================================================================
|
||||
##### Peripheral Errors functions #####
|
||||
===============================================================================
|
||||
[..]
|
||||
This subsection permits 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:
|
||||
* @arg HAL_FLASH_ERROR_RD: FLASH Read Protection error flag (PCROP)
|
||||
* @arg HAL_FLASH_ERROR_PGS: FLASH Programming Sequence error flag
|
||||
* @arg HAL_FLASH_ERROR_PGP: FLASH Programming Parallelism error flag
|
||||
* @arg HAL_FLASH_ERROR_PGA: FLASH Programming Alignment error flag
|
||||
* @arg HAL_FLASH_ERROR_WRP: FLASH Write protected error flag
|
||||
* @arg HAL_FLASH_ERROR_OPERATION: FLASH operation Error flag
|
||||
* @arg HAL_FLASH_ERROR_NONE: No error set
|
||||
* @arg HAL_FLASH_ERROR_OP: FLASH Operation error
|
||||
* @arg HAL_FLASH_ERROR_PROG: FLASH Programming error
|
||||
* @arg HAL_FLASH_ERROR_WRP: FLASH Write protection error
|
||||
* @arg HAL_FLASH_ERROR_PGA: FLASH Programming alignment error
|
||||
* @arg HAL_FLASH_ERROR_SIZ: FLASH Size error
|
||||
* @arg HAL_FLASH_ERROR_PGS: FLASH Programming sequence error
|
||||
* @arg HAL_FLASH_ERROR_MIS: FLASH Fast programming data miss error
|
||||
* @arg HAL_FLASH_ERROR_FAST: FLASH Fast programming error
|
||||
* @arg HAL_FLASH_ERROR_RD: FLASH PCROP read error
|
||||
* @arg HAL_FLASH_ERROR_OPTV: FLASH Option validity error
|
||||
* @arg FLASH_FLAG_PEMPTY : FLASH Boot from not programmed flash (apply only for STM32L43x/STM32L44x devices)
|
||||
*/
|
||||
uint32_t HAL_FLASH_GetError(void)
|
||||
{
|
||||
return pFlash.ErrorCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private functions ---------------------------------------------------------*/
|
||||
|
||||
/** @addtogroup FLASH_Private_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Wait for a FLASH operation to complete.
|
||||
* @param Timeout maximum flash operation timeout
|
||||
* @retval HAL_StatusTypeDef HAL Status
|
||||
*/
|
||||
HAL_StatusTypeDef FLASH_WaitForLastOperation(uint32_t Timeout)
|
||||
{
|
||||
/* Wait for the FLASH operation to complete by polling on BUSY flag to be reset.
|
||||
Even if the FLASH operation fails, the BUSY flag will be reset and an error
|
||||
flag will be set */
|
||||
|
||||
uint32_t tickstart = HAL_GetTick();
|
||||
uint32_t error;
|
||||
|
||||
while(__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY))
|
||||
{
|
||||
if(Timeout != HAL_MAX_DELAY)
|
||||
{
|
||||
if((HAL_GetTick() - tickstart) >= Timeout)
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
error = (FLASH->SR & FLASH_FLAG_SR_ERRORS);
|
||||
|
||||
if(error != 0u)
|
||||
{
|
||||
/*Save the error code*/
|
||||
pFlash.ErrorCode |= error;
|
||||
|
||||
/* Clear error programming flags */
|
||||
__HAL_FLASH_CLEAR_FLAG(error);
|
||||
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* 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 there is an error flag set */
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Program double-word (64-bit) at a specified address.
|
||||
* @param Address specifies the address to be programmed.
|
||||
* @param Data specifies the data to be programmed.
|
||||
* @retval None
|
||||
*/
|
||||
static void FLASH_Program_DoubleWord(uint32_t Address, uint64_t Data)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_FLASH_PROGRAM_ADDRESS(Address));
|
||||
|
||||
/* Set PG bit */
|
||||
SET_BIT(FLASH->CR, FLASH_CR_PG);
|
||||
|
||||
/* Program first word */
|
||||
*(__IO uint32_t*)Address = (uint32_t)Data;
|
||||
|
||||
/* Barrier to ensure programming is performed in 2 steps, in right order
|
||||
(independently of compiler optimization behavior) */
|
||||
__ISB();
|
||||
|
||||
/* Program second word */
|
||||
*(__IO uint32_t*)(Address+4U) = (uint32_t)(Data >> 32);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Fast program a row double-word (64-bit) at a specified address.
|
||||
* @param Address specifies the address to be programmed.
|
||||
* @param DataAddress specifies the address where the data are stored.
|
||||
* @retval None
|
||||
*/
|
||||
static void FLASH_Program_Fast(uint32_t Address, uint32_t DataAddress)
|
||||
{
|
||||
uint32_t primask_bit;
|
||||
uint8_t row_index = (2*FLASH_NB_DOUBLE_WORDS_IN_ROW);
|
||||
__IO uint32_t *dest_addr = (__IO uint32_t*)Address;
|
||||
__IO uint32_t *src_addr = (__IO uint32_t*)DataAddress;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_FLASH_MAIN_MEM_ADDRESS(Address));
|
||||
|
||||
/* Set FSTPG bit */
|
||||
SET_BIT(FLASH->CR, FLASH_CR_FSTPG);
|
||||
|
||||
/* Disable interrupts to avoid any interruption during the loop */
|
||||
primask_bit = __get_PRIMASK();
|
||||
__disable_irq();
|
||||
|
||||
/* Program the double word of the row */
|
||||
do
|
||||
{
|
||||
*dest_addr = *src_addr;
|
||||
dest_addr++;
|
||||
src_addr++;
|
||||
row_index--;
|
||||
} while (row_index != 0U);
|
||||
|
||||
/* Re-enable the interrupts */
|
||||
__set_PRIMASK(primask_bit);
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* HAL_FLASH_MODULE_ENABLED */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
@@ -1,1316 +0,0 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32l4xx_hal_flash_ex.c
|
||||
* @author MCD Application Team
|
||||
* @brief Extended FLASH HAL module driver.
|
||||
* This file provides firmware functions to manage the following
|
||||
* functionalities of the FLASH extended peripheral:
|
||||
* + Extended programming operations functions
|
||||
*
|
||||
@verbatim
|
||||
==============================================================================
|
||||
##### Flash Extended features #####
|
||||
==============================================================================
|
||||
|
||||
[..] Comparing to other previous devices, the FLASH interface for STM32L4xx
|
||||
devices contains the following additional features
|
||||
|
||||
(+) Capacity up to 2 Mbyte with dual bank architecture supporting read-while-write
|
||||
capability (RWW)
|
||||
(+) Dual bank memory organization
|
||||
(+) PCROP protection for all banks
|
||||
|
||||
##### How to use this driver #####
|
||||
==============================================================================
|
||||
[..] This driver provides functions to configure and program the FLASH memory
|
||||
of all STM32L4xx devices. It includes
|
||||
(#) Flash Memory Erase functions:
|
||||
(++) Lock and Unlock the FLASH interface using HAL_FLASH_Unlock() and
|
||||
HAL_FLASH_Lock() functions
|
||||
(++) Erase function: Erase page, erase all sectors
|
||||
(++) There are two modes of erase :
|
||||
(+++) Polling Mode using HAL_FLASHEx_Erase()
|
||||
(+++) Interrupt Mode using HAL_FLASHEx_Erase_IT()
|
||||
|
||||
(#) Option Bytes Programming function: Use HAL_FLASHEx_OBProgram() to :
|
||||
(++) Set/Reset the write protection
|
||||
(++) Set the Read protection Level
|
||||
(++) Program the user Option Bytes
|
||||
(++) Configure the PCROP protection
|
||||
|
||||
(#) Get Option Bytes Configuration function: Use HAL_FLASHEx_OBGetConfig() to :
|
||||
(++) Get the value of a write protection area
|
||||
(++) Know if the read protection is activated
|
||||
(++) Get the value of the user Option Bytes
|
||||
(++) Get the value of a PCROP area
|
||||
|
||||
@endverbatim
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2017 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file in
|
||||
* the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32l4xx_hal.h"
|
||||
|
||||
/** @addtogroup STM32L4xx_HAL_Driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup FLASHEx FLASHEx
|
||||
* @brief FLASH Extended HAL module driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifdef HAL_FLASH_MODULE_ENABLED
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/** @defgroup FLASHEx_Private_Functions FLASHEx Private Functions
|
||||
* @{
|
||||
*/
|
||||
static void FLASH_MassErase(uint32_t Banks);
|
||||
static HAL_StatusTypeDef FLASH_OB_WRPConfig(uint32_t WRPArea, uint32_t WRPStartOffset, uint32_t WRDPEndOffset);
|
||||
static HAL_StatusTypeDef FLASH_OB_RDPConfig(uint32_t RDPLevel);
|
||||
static HAL_StatusTypeDef FLASH_OB_UserConfig(uint32_t UserType, uint32_t UserConfig);
|
||||
static HAL_StatusTypeDef FLASH_OB_PCROPConfig(uint32_t PCROPConfig, uint32_t PCROPStartAddr, uint32_t PCROPEndAddr);
|
||||
static void FLASH_OB_GetWRP(uint32_t WRPArea, uint32_t * WRPStartOffset, uint32_t * WRDPEndOffset);
|
||||
static uint32_t FLASH_OB_GetRDP(void);
|
||||
static uint32_t FLASH_OB_GetUser(void);
|
||||
static void FLASH_OB_GetPCROP(uint32_t * PCROPConfig, uint32_t * PCROPStartAddr, uint32_t * PCROPEndAddr);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Exported functions -------------------------------------------------------*/
|
||||
/** @defgroup FLASHEx_Exported_Functions FLASHEx Exported Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup FLASHEx_Exported_Functions_Group1 Extended IO operation functions
|
||||
* @brief Extended IO operation functions
|
||||
*
|
||||
@verbatim
|
||||
===============================================================================
|
||||
##### Extended programming operation functions #####
|
||||
===============================================================================
|
||||
[..]
|
||||
This subsection provides a set of functions allowing to manage the Extended FLASH
|
||||
programming operations Operations.
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Perform a mass erase or erase the specified FLASH memory pages.
|
||||
* @param[in] pEraseInit: pointer to an FLASH_EraseInitTypeDef structure that
|
||||
* contains the configuration information for the erasing.
|
||||
*
|
||||
* @param[out] PageError : pointer to variable that contains the configuration
|
||||
* information on faulty page in case of error (0xFFFFFFFF means that all
|
||||
* the pages have been correctly erased)
|
||||
*
|
||||
* @retval HAL Status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_FLASHEx_Erase(FLASH_EraseInitTypeDef *pEraseInit, uint32_t *PageError)
|
||||
{
|
||||
HAL_StatusTypeDef status;
|
||||
uint32_t page_index;
|
||||
|
||||
/* Process Locked */
|
||||
__HAL_LOCK(&pFlash);
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase));
|
||||
|
||||
/* Wait for last operation to be completed */
|
||||
status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
|
||||
|
||||
if (status == HAL_OK)
|
||||
{
|
||||
pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
|
||||
|
||||
/* Deactivate the cache if they are activated to avoid data misbehavior */
|
||||
if(READ_BIT(FLASH->ACR, FLASH_ACR_ICEN) != 0U)
|
||||
{
|
||||
if(READ_BIT(FLASH->ACR, FLASH_ACR_DCEN) != 0U)
|
||||
{
|
||||
/* Disable data cache */
|
||||
__HAL_FLASH_DATA_CACHE_DISABLE();
|
||||
pFlash.CacheToReactivate = FLASH_CACHE_ICACHE_DCACHE_ENABLED;
|
||||
}
|
||||
else
|
||||
{
|
||||
pFlash.CacheToReactivate = FLASH_CACHE_ICACHE_ENABLED;
|
||||
}
|
||||
}
|
||||
else if(READ_BIT(FLASH->ACR, FLASH_ACR_DCEN) != 0U)
|
||||
{
|
||||
/* Disable data cache */
|
||||
__HAL_FLASH_DATA_CACHE_DISABLE();
|
||||
pFlash.CacheToReactivate = FLASH_CACHE_DCACHE_ENABLED;
|
||||
}
|
||||
else
|
||||
{
|
||||
pFlash.CacheToReactivate = FLASH_CACHE_DISABLED;
|
||||
}
|
||||
|
||||
if (pEraseInit->TypeErase == FLASH_TYPEERASE_MASSERASE)
|
||||
{
|
||||
/* Mass erase to be done */
|
||||
FLASH_MassErase(pEraseInit->Banks);
|
||||
|
||||
/* Wait for last operation to be completed */
|
||||
status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
|
||||
|
||||
#if defined (STM32L471xx) || defined (STM32L475xx) || defined (STM32L476xx) || defined (STM32L485xx) || defined (STM32L486xx) || \
|
||||
defined (STM32L496xx) || defined (STM32L4A6xx) || \
|
||||
defined (STM32L4P5xx) || defined (STM32L4Q5xx) || \
|
||||
defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)
|
||||
/* If the erase operation is completed, disable the MER1 and MER2 Bits */
|
||||
CLEAR_BIT(FLASH->CR, (FLASH_CR_MER1 | FLASH_CR_MER2));
|
||||
#else
|
||||
/* If the erase operation is completed, disable the MER1 Bit */
|
||||
CLEAR_BIT(FLASH->CR, (FLASH_CR_MER1));
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
/*Initialization of PageError variable*/
|
||||
*PageError = 0xFFFFFFFFU;
|
||||
|
||||
for(page_index = pEraseInit->Page; page_index < (pEraseInit->Page + pEraseInit->NbPages); page_index++)
|
||||
{
|
||||
FLASH_PageErase(page_index, pEraseInit->Banks);
|
||||
|
||||
/* Wait for last operation to be completed */
|
||||
status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
|
||||
|
||||
/* If the erase operation is completed, disable the PER Bit */
|
||||
CLEAR_BIT(FLASH->CR, (FLASH_CR_PER | FLASH_CR_PNB));
|
||||
|
||||
if (status != HAL_OK)
|
||||
{
|
||||
/* In case of error, stop erase procedure and return the faulty address */
|
||||
*PageError = page_index;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Flush the caches to be sure of the data consistency */
|
||||
FLASH_FlushCaches();
|
||||
}
|
||||
|
||||
/* Process Unlocked */
|
||||
__HAL_UNLOCK(&pFlash);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Perform a mass erase or erase the specified FLASH memory pages with interrupt enabled.
|
||||
* @param pEraseInit pointer to an FLASH_EraseInitTypeDef structure that
|
||||
* contains the configuration information for the erasing.
|
||||
*
|
||||
* @retval HAL Status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_FLASHEx_Erase_IT(FLASH_EraseInitTypeDef *pEraseInit)
|
||||
{
|
||||
HAL_StatusTypeDef status = HAL_OK;
|
||||
|
||||
/* Process Locked */
|
||||
__HAL_LOCK(&pFlash);
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase));
|
||||
|
||||
pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
|
||||
|
||||
/* Deactivate the cache if they are activated to avoid data misbehavior */
|
||||
if(READ_BIT(FLASH->ACR, FLASH_ACR_ICEN) != 0U)
|
||||
{
|
||||
if(READ_BIT(FLASH->ACR, FLASH_ACR_DCEN) != 0U)
|
||||
{
|
||||
/* Disable data cache */
|
||||
__HAL_FLASH_DATA_CACHE_DISABLE();
|
||||
pFlash.CacheToReactivate = FLASH_CACHE_ICACHE_DCACHE_ENABLED;
|
||||
}
|
||||
else
|
||||
{
|
||||
pFlash.CacheToReactivate = FLASH_CACHE_ICACHE_ENABLED;
|
||||
}
|
||||
}
|
||||
else if(READ_BIT(FLASH->ACR, FLASH_ACR_DCEN) != 0U)
|
||||
{
|
||||
/* Disable data cache */
|
||||
__HAL_FLASH_DATA_CACHE_DISABLE();
|
||||
pFlash.CacheToReactivate = FLASH_CACHE_DCACHE_ENABLED;
|
||||
}
|
||||
else
|
||||
{
|
||||
pFlash.CacheToReactivate = FLASH_CACHE_DISABLED;
|
||||
}
|
||||
|
||||
/* Enable End of Operation and Error interrupts */
|
||||
__HAL_FLASH_ENABLE_IT(FLASH_IT_EOP | FLASH_IT_OPERR);
|
||||
|
||||
pFlash.Bank = pEraseInit->Banks;
|
||||
|
||||
if (pEraseInit->TypeErase == FLASH_TYPEERASE_MASSERASE)
|
||||
{
|
||||
/* Mass erase to be done */
|
||||
pFlash.ProcedureOnGoing = FLASH_PROC_MASS_ERASE;
|
||||
FLASH_MassErase(pEraseInit->Banks);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Erase by page to be done */
|
||||
pFlash.ProcedureOnGoing = FLASH_PROC_PAGE_ERASE;
|
||||
pFlash.NbPagesToErase = pEraseInit->NbPages;
|
||||
pFlash.Page = pEraseInit->Page;
|
||||
|
||||
/*Erase 1st page and wait for IT */
|
||||
FLASH_PageErase(pEraseInit->Page, pEraseInit->Banks);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Program Option bytes.
|
||||
* @param pOBInit pointer to an FLASH_OBInitStruct structure that
|
||||
* contains the configuration information for the programming.
|
||||
*
|
||||
* @retval HAL Status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_FLASHEx_OBProgram(FLASH_OBProgramInitTypeDef *pOBInit)
|
||||
{
|
||||
HAL_StatusTypeDef status = HAL_OK;
|
||||
|
||||
/* Process Locked */
|
||||
__HAL_LOCK(&pFlash);
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_OPTIONBYTE(pOBInit->OptionType));
|
||||
|
||||
pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
|
||||
|
||||
/* Write protection configuration */
|
||||
if((pOBInit->OptionType & OPTIONBYTE_WRP) != 0U)
|
||||
{
|
||||
/* Configure of Write protection on the selected area */
|
||||
if(FLASH_OB_WRPConfig(pOBInit->WRPArea, pOBInit->WRPStartOffset, pOBInit->WRPEndOffset) != HAL_OK)
|
||||
{
|
||||
status = HAL_ERROR;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Read protection configuration */
|
||||
if((pOBInit->OptionType & OPTIONBYTE_RDP) != 0U)
|
||||
{
|
||||
/* Configure the Read protection level */
|
||||
if(FLASH_OB_RDPConfig(pOBInit->RDPLevel) != HAL_OK)
|
||||
{
|
||||
status = HAL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/* User Configuration */
|
||||
if((pOBInit->OptionType & OPTIONBYTE_USER) != 0U)
|
||||
{
|
||||
/* Configure the user option bytes */
|
||||
if(FLASH_OB_UserConfig(pOBInit->USERType, pOBInit->USERConfig) != HAL_OK)
|
||||
{
|
||||
status = HAL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/* PCROP Configuration */
|
||||
if((pOBInit->OptionType & OPTIONBYTE_PCROP) != 0U)
|
||||
{
|
||||
if (pOBInit->PCROPStartAddr != pOBInit->PCROPEndAddr)
|
||||
{
|
||||
/* Configure the Proprietary code readout protection */
|
||||
if(FLASH_OB_PCROPConfig(pOBInit->PCROPConfig, pOBInit->PCROPStartAddr, pOBInit->PCROPEndAddr) != HAL_OK)
|
||||
{
|
||||
status = HAL_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Process Unlocked */
|
||||
__HAL_UNLOCK(&pFlash);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the Option bytes configuration.
|
||||
* @param pOBInit pointer to an FLASH_OBInitStruct structure that contains the
|
||||
* configuration information.
|
||||
* @note The fields pOBInit->WRPArea and pOBInit->PCROPConfig should indicate
|
||||
* which area is requested for the WRP and PCROP, else no information will be returned
|
||||
*
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_FLASHEx_OBGetConfig(FLASH_OBProgramInitTypeDef *pOBInit)
|
||||
{
|
||||
pOBInit->OptionType = (OPTIONBYTE_RDP | OPTIONBYTE_USER);
|
||||
|
||||
#if defined (STM32L471xx) || defined (STM32L475xx) || defined (STM32L476xx) || defined (STM32L485xx) || defined (STM32L486xx) || \
|
||||
defined (STM32L496xx) || defined (STM32L4A6xx) || \
|
||||
defined (STM32L4P5xx) || defined (STM32L4Q5xx) || \
|
||||
defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)
|
||||
if((pOBInit->WRPArea == OB_WRPAREA_BANK1_AREAA) || (pOBInit->WRPArea == OB_WRPAREA_BANK1_AREAB) ||
|
||||
(pOBInit->WRPArea == OB_WRPAREA_BANK2_AREAA) || (pOBInit->WRPArea == OB_WRPAREA_BANK2_AREAB))
|
||||
#else
|
||||
if((pOBInit->WRPArea == OB_WRPAREA_BANK1_AREAA) || (pOBInit->WRPArea == OB_WRPAREA_BANK1_AREAB))
|
||||
#endif
|
||||
{
|
||||
pOBInit->OptionType |= OPTIONBYTE_WRP;
|
||||
/* Get write protection on the selected area */
|
||||
FLASH_OB_GetWRP(pOBInit->WRPArea, &(pOBInit->WRPStartOffset), &(pOBInit->WRPEndOffset));
|
||||
}
|
||||
|
||||
/* Get Read protection level */
|
||||
pOBInit->RDPLevel = FLASH_OB_GetRDP();
|
||||
|
||||
/* Get the user option bytes */
|
||||
pOBInit->USERConfig = FLASH_OB_GetUser();
|
||||
|
||||
#if defined (STM32L471xx) || defined (STM32L475xx) || defined (STM32L476xx) || defined (STM32L485xx) || defined (STM32L486xx) || \
|
||||
defined (STM32L496xx) || defined (STM32L4A6xx) || \
|
||||
defined (STM32L4P5xx) || defined (STM32L4Q5xx) || \
|
||||
defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)
|
||||
if((pOBInit->PCROPConfig == FLASH_BANK_1) || (pOBInit->PCROPConfig == FLASH_BANK_2))
|
||||
#else
|
||||
if(pOBInit->PCROPConfig == FLASH_BANK_1)
|
||||
#endif
|
||||
{
|
||||
pOBInit->OptionType |= OPTIONBYTE_PCROP;
|
||||
/* Get the Proprietary code readout protection */
|
||||
FLASH_OB_GetPCROP(&(pOBInit->PCROPConfig), &(pOBInit->PCROPStartAddr), &(pOBInit->PCROPEndAddr));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#if defined (FLASH_CFGR_LVEN)
|
||||
/** @defgroup FLASHEx_Exported_Functions_Group2 Extended specific configuration functions
|
||||
* @brief Extended specific configuration functions
|
||||
*
|
||||
@verbatim
|
||||
===============================================================================
|
||||
##### Extended specific configuration functions #####
|
||||
===============================================================================
|
||||
[..]
|
||||
This subsection provides a set of functions allowing to manage the Extended FLASH
|
||||
specific configurations.
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Configuration of the LVE pin of the Flash (managed by power controller
|
||||
* or forced to low in order to use an external SMPS)
|
||||
* @param ConfigLVE Configuration of the LVE pin,
|
||||
* This parameter can be one of the following values:
|
||||
* @arg FLASH_LVE_PIN_CTRL: LVE FLASH pin controlled by power controller
|
||||
* @arg FLASH_LVE_PIN_FORCED: LVE FLASH pin enforced to low (external SMPS used)
|
||||
*
|
||||
* @note Before enforcing the LVE pin to low, the SOC should be in low voltage
|
||||
* range 2 and the voltage VDD12 should be higher than 1.08V and SMPS is ON.
|
||||
*
|
||||
* @retval HAL Status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_FLASHEx_ConfigLVEPin(uint32_t ConfigLVE)
|
||||
{
|
||||
HAL_StatusTypeDef status;
|
||||
|
||||
/* Process Locked */
|
||||
__HAL_LOCK(&pFlash);
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_FLASH_LVE_PIN(ConfigLVE));
|
||||
|
||||
/* Wait for last operation to be completed */
|
||||
status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
|
||||
|
||||
if (status == HAL_OK)
|
||||
{
|
||||
/* Check that the voltage scaling is range 2 */
|
||||
if (HAL_PWREx_GetVoltageRange() == PWR_REGULATOR_VOLTAGE_SCALE2)
|
||||
{
|
||||
/* Configure the LVEN bit */
|
||||
MODIFY_REG(FLASH->CFGR, FLASH_CFGR_LVEN, ConfigLVE);
|
||||
|
||||
/* Check that the bit has been correctly configured */
|
||||
if (READ_BIT(FLASH->CFGR, FLASH_CFGR_LVEN) != ConfigLVE)
|
||||
{
|
||||
status = HAL_ERROR;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Not allow to force Flash LVE pin if not in voltage range 2 */
|
||||
status = HAL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/* Process Unlocked */
|
||||
__HAL_UNLOCK(&pFlash);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
#endif /* FLASH_CFGR_LVEN */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private functions ---------------------------------------------------------*/
|
||||
|
||||
/** @addtogroup FLASHEx_Private_Functions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Mass erase of FLASH memory.
|
||||
* @param Banks Banks to be erased
|
||||
* This parameter can be one of the following values:
|
||||
* @arg FLASH_BANK_1: Bank1 to be erased
|
||||
* @arg FLASH_BANK_2: Bank2 to be erased
|
||||
* @arg FLASH_BANK_BOTH: Bank1 and Bank2 to be erased
|
||||
* @retval None
|
||||
*/
|
||||
static void FLASH_MassErase(uint32_t Banks)
|
||||
{
|
||||
#if defined (STM32L4P5xx) || defined (STM32L4Q5xx) || defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)
|
||||
if (READ_BIT(FLASH->OPTR, FLASH_OPTR_DBANK) != 0U)
|
||||
#endif
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_FLASH_BANK(Banks));
|
||||
|
||||
/* Set the Mass Erase Bit for the bank 1 if requested */
|
||||
if((Banks & FLASH_BANK_1) != 0U)
|
||||
{
|
||||
SET_BIT(FLASH->CR, FLASH_CR_MER1);
|
||||
}
|
||||
|
||||
#if defined (STM32L471xx) || defined (STM32L475xx) || defined (STM32L476xx) || defined (STM32L485xx) || defined (STM32L486xx) || \
|
||||
defined (STM32L496xx) || defined (STM32L4A6xx) || \
|
||||
defined (STM32L4P5xx) || defined (STM32L4Q5xx) || \
|
||||
defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)
|
||||
/* Set the Mass Erase Bit for the bank 2 if requested */
|
||||
if((Banks & FLASH_BANK_2) != 0U)
|
||||
{
|
||||
SET_BIT(FLASH->CR, FLASH_CR_MER2);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#if defined (STM32L4P5xx) || defined (STM32L4Q5xx) || defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)
|
||||
else
|
||||
{
|
||||
SET_BIT(FLASH->CR, (FLASH_CR_MER1 | FLASH_CR_MER2));
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Proceed to erase all sectors */
|
||||
SET_BIT(FLASH->CR, FLASH_CR_STRT);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Erase the specified FLASH memory page.
|
||||
* @param Page FLASH page to erase
|
||||
* This parameter must be a value between 0 and (max number of pages in the bank - 1)
|
||||
* @param Banks Bank(s) where the page will be erased
|
||||
* This parameter can be one of the following values:
|
||||
* @arg FLASH_BANK_1: Page in bank 1 to be erased
|
||||
* @arg FLASH_BANK_2: Page in bank 2 to be erased
|
||||
* @retval None
|
||||
*/
|
||||
void FLASH_PageErase(uint32_t Page, uint32_t Banks)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_FLASH_PAGE(Page));
|
||||
|
||||
#if defined (STM32L471xx) || defined (STM32L475xx) || defined (STM32L476xx) || defined (STM32L485xx) || defined (STM32L486xx) || \
|
||||
defined (STM32L496xx) || defined (STM32L4A6xx) || \
|
||||
defined (STM32L4P5xx) || defined (STM32L4Q5xx) || \
|
||||
defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)
|
||||
#if defined (STM32L4P5xx) || defined (STM32L4Q5xx) || defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)
|
||||
if(READ_BIT(FLASH->OPTR, FLASH_OPTR_DBANK) == 0U)
|
||||
{
|
||||
CLEAR_BIT(FLASH->CR, FLASH_CR_BKER);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
assert_param(IS_FLASH_BANK_EXCLUSIVE(Banks));
|
||||
|
||||
if((Banks & FLASH_BANK_1) != 0U)
|
||||
{
|
||||
CLEAR_BIT(FLASH->CR, FLASH_CR_BKER);
|
||||
}
|
||||
else
|
||||
{
|
||||
SET_BIT(FLASH->CR, FLASH_CR_BKER);
|
||||
}
|
||||
}
|
||||
#else
|
||||
/* Prevent unused argument(s) compilation warning */
|
||||
UNUSED(Banks);
|
||||
#endif
|
||||
|
||||
/* Proceed to erase the page */
|
||||
MODIFY_REG(FLASH->CR, FLASH_CR_PNB, ((Page & 0xFFU) << FLASH_CR_PNB_Pos));
|
||||
SET_BIT(FLASH->CR, FLASH_CR_PER);
|
||||
SET_BIT(FLASH->CR, FLASH_CR_STRT);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Flush the instruction and data caches.
|
||||
* @retval None
|
||||
*/
|
||||
void FLASH_FlushCaches(void)
|
||||
{
|
||||
FLASH_CacheTypeDef cache = pFlash.CacheToReactivate;
|
||||
|
||||
/* Flush instruction cache */
|
||||
if((cache == FLASH_CACHE_ICACHE_ENABLED) ||
|
||||
(cache == FLASH_CACHE_ICACHE_DCACHE_ENABLED))
|
||||
{
|
||||
/* Disable instruction cache */
|
||||
__HAL_FLASH_INSTRUCTION_CACHE_DISABLE();
|
||||
/* Reset instruction cache */
|
||||
__HAL_FLASH_INSTRUCTION_CACHE_RESET();
|
||||
/* Enable instruction cache */
|
||||
__HAL_FLASH_INSTRUCTION_CACHE_ENABLE();
|
||||
}
|
||||
|
||||
/* Flush data cache */
|
||||
if((cache == FLASH_CACHE_DCACHE_ENABLED) ||
|
||||
(cache == FLASH_CACHE_ICACHE_DCACHE_ENABLED))
|
||||
{
|
||||
/* Reset data cache */
|
||||
__HAL_FLASH_DATA_CACHE_RESET();
|
||||
/* Enable data cache */
|
||||
__HAL_FLASH_DATA_CACHE_ENABLE();
|
||||
}
|
||||
|
||||
/* Reset internal variable */
|
||||
pFlash.CacheToReactivate = FLASH_CACHE_DISABLED;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure the write protection of the desired pages.
|
||||
*
|
||||
* @note When the memory read protection level is selected (RDP level = 1),
|
||||
* it is not possible to program or erase Flash memory if the CPU debug
|
||||
* features are connected (JTAG or single wire) or boot code is being
|
||||
* executed from RAM or System flash, even if WRP is not activated.
|
||||
* @note To configure the WRP options, the option lock bit OPTLOCK must be
|
||||
* cleared with the call of the HAL_FLASH_OB_Unlock() function.
|
||||
* @note To validate the WRP options, the option bytes must be reloaded
|
||||
* through the call of the HAL_FLASH_OB_Launch() function.
|
||||
*
|
||||
* @param WRPArea specifies the area to be configured.
|
||||
* This parameter can be one of the following values:
|
||||
* @arg OB_WRPAREA_BANK1_AREAA: Flash Bank 1 Area A
|
||||
* @arg OB_WRPAREA_BANK1_AREAB: Flash Bank 1 Area B
|
||||
* @arg OB_WRPAREA_BANK2_AREAA: Flash Bank 2 Area A (don't apply for STM32L43x/STM32L44x devices)
|
||||
* @arg OB_WRPAREA_BANK2_AREAB: Flash Bank 2 Area B (don't apply for STM32L43x/STM32L44x devices)
|
||||
*
|
||||
* @param WRPStartOffset specifies the start page of the write protected area
|
||||
* This parameter can be page number between 0 and (max number of pages in the bank - 1)
|
||||
*
|
||||
* @param WRDPEndOffset specifies the end page of the write protected area
|
||||
* This parameter can be page number between WRPStartOffset and (max number of pages in the bank - 1)
|
||||
*
|
||||
* @retval HAL Status
|
||||
*/
|
||||
static HAL_StatusTypeDef FLASH_OB_WRPConfig(uint32_t WRPArea, uint32_t WRPStartOffset, uint32_t WRDPEndOffset)
|
||||
{
|
||||
HAL_StatusTypeDef status;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_OB_WRPAREA(WRPArea));
|
||||
assert_param(IS_FLASH_PAGE(WRPStartOffset));
|
||||
assert_param(IS_FLASH_PAGE(WRDPEndOffset));
|
||||
|
||||
/* Wait for last operation to be completed */
|
||||
status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
|
||||
|
||||
if(status == HAL_OK)
|
||||
{
|
||||
/* Configure the write protected area */
|
||||
if(WRPArea == OB_WRPAREA_BANK1_AREAA)
|
||||
{
|
||||
MODIFY_REG(FLASH->WRP1AR, (FLASH_WRP1AR_WRP1A_STRT | FLASH_WRP1AR_WRP1A_END),
|
||||
(WRPStartOffset | (WRDPEndOffset << 16)));
|
||||
}
|
||||
else if(WRPArea == OB_WRPAREA_BANK1_AREAB)
|
||||
{
|
||||
MODIFY_REG(FLASH->WRP1BR, (FLASH_WRP1BR_WRP1B_STRT | FLASH_WRP1BR_WRP1B_END),
|
||||
(WRPStartOffset | (WRDPEndOffset << 16)));
|
||||
}
|
||||
#if defined (STM32L471xx) || defined (STM32L475xx) || defined (STM32L476xx) || defined (STM32L485xx) || defined (STM32L486xx) || \
|
||||
defined (STM32L496xx) || defined (STM32L4A6xx) || \
|
||||
defined (STM32L4P5xx) || defined (STM32L4Q5xx) || \
|
||||
defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)
|
||||
else if(WRPArea == OB_WRPAREA_BANK2_AREAA)
|
||||
{
|
||||
MODIFY_REG(FLASH->WRP2AR, (FLASH_WRP2AR_WRP2A_STRT | FLASH_WRP2AR_WRP2A_END),
|
||||
(WRPStartOffset | (WRDPEndOffset << 16)));
|
||||
}
|
||||
else if(WRPArea == OB_WRPAREA_BANK2_AREAB)
|
||||
{
|
||||
MODIFY_REG(FLASH->WRP2BR, (FLASH_WRP2BR_WRP2B_STRT | FLASH_WRP2BR_WRP2B_END),
|
||||
(WRPStartOffset | (WRDPEndOffset << 16)));
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
/* Nothing to do */
|
||||
}
|
||||
|
||||
/* Set OPTSTRT Bit */
|
||||
SET_BIT(FLASH->CR, FLASH_CR_OPTSTRT);
|
||||
|
||||
/* Wait for last operation to be completed */
|
||||
status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
|
||||
|
||||
/* If the option byte program operation is completed, disable the OPTSTRT Bit */
|
||||
CLEAR_BIT(FLASH->CR, FLASH_CR_OPTSTRT);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the read protection level.
|
||||
*
|
||||
* @note To configure the RDP level, the option lock bit OPTLOCK must be
|
||||
* cleared with the call of the HAL_FLASH_OB_Unlock() function.
|
||||
* @note To validate the RDP level, the option bytes must be reloaded
|
||||
* through the call of the HAL_FLASH_OB_Launch() function.
|
||||
* @note !!! Warning : When enabling OB_RDP level 2 it's no more possible
|
||||
* to go back to level 1 or 0 !!!
|
||||
*
|
||||
* @param RDPLevel specifies the read protection level.
|
||||
* This parameter can be one of the following values:
|
||||
* @arg OB_RDP_LEVEL_0: No protection
|
||||
* @arg OB_RDP_LEVEL_1: Read protection of the memory
|
||||
* @arg OB_RDP_LEVEL_2: Full chip protection
|
||||
*
|
||||
* @retval HAL status
|
||||
*/
|
||||
static HAL_StatusTypeDef FLASH_OB_RDPConfig(uint32_t RDPLevel)
|
||||
{
|
||||
HAL_StatusTypeDef status;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_OB_RDP_LEVEL(RDPLevel));
|
||||
|
||||
/* Wait for last operation to be completed */
|
||||
status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
|
||||
|
||||
if(status == HAL_OK)
|
||||
{
|
||||
/* Configure the RDP level in the option bytes register */
|
||||
MODIFY_REG(FLASH->OPTR, FLASH_OPTR_RDP, RDPLevel);
|
||||
|
||||
/* Set OPTSTRT Bit */
|
||||
SET_BIT(FLASH->CR, FLASH_CR_OPTSTRT);
|
||||
|
||||
/* Wait for last operation to be completed */
|
||||
status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
|
||||
|
||||
/* If the option byte program operation is completed, disable the OPTSTRT Bit */
|
||||
CLEAR_BIT(FLASH->CR, FLASH_CR_OPTSTRT);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Program the FLASH User Option Byte.
|
||||
*
|
||||
* @note To configure the user option bytes, the option lock bit OPTLOCK must
|
||||
* be cleared with the call of the HAL_FLASH_OB_Unlock() function.
|
||||
* @note To validate the user option bytes, the option bytes must be reloaded
|
||||
* through the call of the HAL_FLASH_OB_Launch() function.
|
||||
*
|
||||
* @param UserType The FLASH User Option Bytes to be modified
|
||||
* @param UserConfig The FLASH User Option Bytes values:
|
||||
* BOR_LEV(Bit8-10), nRST_STOP(Bit12), nRST_STDBY(Bit13), IWDG_SW(Bit16),
|
||||
* IWDG_STOP(Bit17), IWDG_STDBY(Bit18), WWDG_SW(Bit19), BFB2(Bit20),
|
||||
* DUALBANK(Bit21), nBOOT1(Bit23), SRAM2_PE(Bit24) and SRAM2_RST(Bit25).
|
||||
*
|
||||
* @retval HAL status
|
||||
*/
|
||||
static HAL_StatusTypeDef FLASH_OB_UserConfig(uint32_t UserType, uint32_t UserConfig)
|
||||
{
|
||||
uint32_t optr_reg_val = 0;
|
||||
uint32_t optr_reg_mask = 0;
|
||||
HAL_StatusTypeDef status;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_OB_USER_TYPE(UserType));
|
||||
|
||||
/* Wait for last operation to be completed */
|
||||
status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
|
||||
|
||||
if(status == HAL_OK)
|
||||
{
|
||||
if((UserType & OB_USER_BOR_LEV) != 0U)
|
||||
{
|
||||
/* BOR level option byte should be modified */
|
||||
assert_param(IS_OB_USER_BOR_LEVEL(UserConfig & FLASH_OPTR_BOR_LEV));
|
||||
|
||||
/* Set value and mask for BOR level option byte */
|
||||
optr_reg_val |= (UserConfig & FLASH_OPTR_BOR_LEV);
|
||||
optr_reg_mask |= FLASH_OPTR_BOR_LEV;
|
||||
}
|
||||
|
||||
if((UserType & OB_USER_nRST_STOP) != 0U)
|
||||
{
|
||||
/* nRST_STOP option byte should be modified */
|
||||
assert_param(IS_OB_USER_STOP(UserConfig & FLASH_OPTR_nRST_STOP));
|
||||
|
||||
/* Set value and mask for nRST_STOP option byte */
|
||||
optr_reg_val |= (UserConfig & FLASH_OPTR_nRST_STOP);
|
||||
optr_reg_mask |= FLASH_OPTR_nRST_STOP;
|
||||
}
|
||||
|
||||
if((UserType & OB_USER_nRST_STDBY) != 0U)
|
||||
{
|
||||
/* nRST_STDBY option byte should be modified */
|
||||
assert_param(IS_OB_USER_STANDBY(UserConfig & FLASH_OPTR_nRST_STDBY));
|
||||
|
||||
/* Set value and mask for nRST_STDBY option byte */
|
||||
optr_reg_val |= (UserConfig & FLASH_OPTR_nRST_STDBY);
|
||||
optr_reg_mask |= FLASH_OPTR_nRST_STDBY;
|
||||
}
|
||||
|
||||
if((UserType & OB_USER_nRST_SHDW) != 0U)
|
||||
{
|
||||
/* nRST_SHDW option byte should be modified */
|
||||
assert_param(IS_OB_USER_SHUTDOWN(UserConfig & FLASH_OPTR_nRST_SHDW));
|
||||
|
||||
/* Set value and mask for nRST_SHDW option byte */
|
||||
optr_reg_val |= (UserConfig & FLASH_OPTR_nRST_SHDW);
|
||||
optr_reg_mask |= FLASH_OPTR_nRST_SHDW;
|
||||
}
|
||||
|
||||
if((UserType & OB_USER_IWDG_SW) != 0U)
|
||||
{
|
||||
/* IWDG_SW option byte should be modified */
|
||||
assert_param(IS_OB_USER_IWDG(UserConfig & FLASH_OPTR_IWDG_SW));
|
||||
|
||||
/* Set value and mask for IWDG_SW option byte */
|
||||
optr_reg_val |= (UserConfig & FLASH_OPTR_IWDG_SW);
|
||||
optr_reg_mask |= FLASH_OPTR_IWDG_SW;
|
||||
}
|
||||
|
||||
if((UserType & OB_USER_IWDG_STOP) != 0U)
|
||||
{
|
||||
/* IWDG_STOP option byte should be modified */
|
||||
assert_param(IS_OB_USER_IWDG_STOP(UserConfig & FLASH_OPTR_IWDG_STOP));
|
||||
|
||||
/* Set value and mask for IWDG_STOP option byte */
|
||||
optr_reg_val |= (UserConfig & FLASH_OPTR_IWDG_STOP);
|
||||
optr_reg_mask |= FLASH_OPTR_IWDG_STOP;
|
||||
}
|
||||
|
||||
if((UserType & OB_USER_IWDG_STDBY) != 0U)
|
||||
{
|
||||
/* IWDG_STDBY option byte should be modified */
|
||||
assert_param(IS_OB_USER_IWDG_STDBY(UserConfig & FLASH_OPTR_IWDG_STDBY));
|
||||
|
||||
/* Set value and mask for IWDG_STDBY option byte */
|
||||
optr_reg_val |= (UserConfig & FLASH_OPTR_IWDG_STDBY);
|
||||
optr_reg_mask |= FLASH_OPTR_IWDG_STDBY;
|
||||
}
|
||||
|
||||
if((UserType & OB_USER_WWDG_SW) != 0U)
|
||||
{
|
||||
/* WWDG_SW option byte should be modified */
|
||||
assert_param(IS_OB_USER_WWDG(UserConfig & FLASH_OPTR_WWDG_SW));
|
||||
|
||||
/* Set value and mask for WWDG_SW option byte */
|
||||
optr_reg_val |= (UserConfig & FLASH_OPTR_WWDG_SW);
|
||||
optr_reg_mask |= FLASH_OPTR_WWDG_SW;
|
||||
}
|
||||
|
||||
#if defined (STM32L471xx) || defined (STM32L475xx) || defined (STM32L476xx) || defined (STM32L485xx) || defined (STM32L486xx) || \
|
||||
defined (STM32L496xx) || defined (STM32L4A6xx) || \
|
||||
defined (STM32L4P5xx) || defined (STM32L4Q5xx) || \
|
||||
defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)
|
||||
if((UserType & OB_USER_BFB2) != 0U)
|
||||
{
|
||||
/* BFB2 option byte should be modified */
|
||||
assert_param(IS_OB_USER_BFB2(UserConfig & FLASH_OPTR_BFB2));
|
||||
|
||||
/* Set value and mask for BFB2 option byte */
|
||||
optr_reg_val |= (UserConfig & FLASH_OPTR_BFB2);
|
||||
optr_reg_mask |= FLASH_OPTR_BFB2;
|
||||
}
|
||||
|
||||
if((UserType & OB_USER_DUALBANK) != 0U)
|
||||
{
|
||||
#if defined (STM32L4P5xx) || defined (STM32L4Q5xx) || defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)
|
||||
/* DUALBANK option byte should be modified */
|
||||
assert_param(IS_OB_USER_DUALBANK(UserConfig & FLASH_OPTR_DB1M));
|
||||
|
||||
/* Set value and mask for DUALBANK option byte */
|
||||
optr_reg_val |= (UserConfig & FLASH_OPTR_DB1M);
|
||||
optr_reg_mask |= FLASH_OPTR_DB1M;
|
||||
#else
|
||||
/* DUALBANK option byte should be modified */
|
||||
assert_param(IS_OB_USER_DUALBANK(UserConfig & FLASH_OPTR_DUALBANK));
|
||||
|
||||
/* Set value and mask for DUALBANK option byte */
|
||||
optr_reg_val |= (UserConfig & FLASH_OPTR_DUALBANK);
|
||||
optr_reg_mask |= FLASH_OPTR_DUALBANK;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
if((UserType & OB_USER_nBOOT1) != 0U)
|
||||
{
|
||||
/* nBOOT1 option byte should be modified */
|
||||
assert_param(IS_OB_USER_BOOT1(UserConfig & FLASH_OPTR_nBOOT1));
|
||||
|
||||
/* Set value and mask for nBOOT1 option byte */
|
||||
optr_reg_val |= (UserConfig & FLASH_OPTR_nBOOT1);
|
||||
optr_reg_mask |= FLASH_OPTR_nBOOT1;
|
||||
}
|
||||
|
||||
if((UserType & OB_USER_SRAM2_PE) != 0U)
|
||||
{
|
||||
/* SRAM2_PE option byte should be modified */
|
||||
assert_param(IS_OB_USER_SRAM2_PARITY(UserConfig & FLASH_OPTR_SRAM2_PE));
|
||||
|
||||
/* Set value and mask for SRAM2_PE option byte */
|
||||
optr_reg_val |= (UserConfig & FLASH_OPTR_SRAM2_PE);
|
||||
optr_reg_mask |= FLASH_OPTR_SRAM2_PE;
|
||||
}
|
||||
|
||||
if((UserType & OB_USER_SRAM2_RST) != 0U)
|
||||
{
|
||||
/* SRAM2_RST option byte should be modified */
|
||||
assert_param(IS_OB_USER_SRAM2_RST(UserConfig & FLASH_OPTR_SRAM2_RST));
|
||||
|
||||
/* Set value and mask for SRAM2_RST option byte */
|
||||
optr_reg_val |= (UserConfig & FLASH_OPTR_SRAM2_RST);
|
||||
optr_reg_mask |= FLASH_OPTR_SRAM2_RST;
|
||||
}
|
||||
|
||||
#if defined (STM32L412xx) || defined (STM32L422xx) || defined (STM32L431xx) || defined (STM32L432xx) || defined (STM32L433xx) || \
|
||||
defined (STM32L442xx) || defined (STM32L443xx) || defined (STM32L451xx) || defined (STM32L452xx) || defined (STM32L462xx) || \
|
||||
defined (STM32L496xx) || defined (STM32L4A6xx) || \
|
||||
defined (STM32L4P5xx) || defined (STM32L4Q5xx) || \
|
||||
defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)
|
||||
if((UserType & OB_USER_nSWBOOT0) != 0U)
|
||||
{
|
||||
/* nSWBOOT0 option byte should be modified */
|
||||
assert_param(IS_OB_USER_SWBOOT0(UserConfig & FLASH_OPTR_nSWBOOT0));
|
||||
|
||||
/* Set value and mask for nSWBOOT0 option byte */
|
||||
optr_reg_val |= (UserConfig & FLASH_OPTR_nSWBOOT0);
|
||||
optr_reg_mask |= FLASH_OPTR_nSWBOOT0;
|
||||
}
|
||||
|
||||
if((UserType & OB_USER_nBOOT0) != 0U)
|
||||
{
|
||||
/* nBOOT0 option byte should be modified */
|
||||
assert_param(IS_OB_USER_BOOT0(UserConfig & FLASH_OPTR_nBOOT0));
|
||||
|
||||
/* Set value and mask for nBOOT0 option byte */
|
||||
optr_reg_val |= (UserConfig & FLASH_OPTR_nBOOT0);
|
||||
optr_reg_mask |= FLASH_OPTR_nBOOT0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Configure the option bytes register */
|
||||
MODIFY_REG(FLASH->OPTR, optr_reg_mask, optr_reg_val);
|
||||
|
||||
/* Set OPTSTRT Bit */
|
||||
SET_BIT(FLASH->CR, FLASH_CR_OPTSTRT);
|
||||
|
||||
/* Wait for last operation to be completed */
|
||||
status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
|
||||
|
||||
/* If the option byte program operation is completed, disable the OPTSTRT Bit */
|
||||
CLEAR_BIT(FLASH->CR, FLASH_CR_OPTSTRT);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure the Proprietary code readout protection of the desired addresses.
|
||||
*
|
||||
* @note To configure the PCROP options, the option lock bit OPTLOCK must be
|
||||
* cleared with the call of the HAL_FLASH_OB_Unlock() function.
|
||||
* @note To validate the PCROP options, the option bytes must be reloaded
|
||||
* through the call of the HAL_FLASH_OB_Launch() function.
|
||||
*
|
||||
* @param PCROPConfig specifies the configuration (Bank to be configured and PCROP_RDP option).
|
||||
* This parameter must be a combination of FLASH_BANK_1 or FLASH_BANK_2
|
||||
* with OB_PCROP_RDP_NOT_ERASE or OB_PCROP_RDP_ERASE
|
||||
*
|
||||
* @param PCROPStartAddr specifies the start address of the Proprietary code readout protection
|
||||
* This parameter can be an address between begin and end of the bank
|
||||
*
|
||||
* @param PCROPEndAddr specifies the end address of the Proprietary code readout protection
|
||||
* This parameter can be an address between PCROPStartAddr and end of the bank
|
||||
*
|
||||
* @retval HAL Status
|
||||
*/
|
||||
static HAL_StatusTypeDef FLASH_OB_PCROPConfig(uint32_t PCROPConfig, uint32_t PCROPStartAddr, uint32_t PCROPEndAddr)
|
||||
{
|
||||
HAL_StatusTypeDef status;
|
||||
uint32_t reg_value;
|
||||
uint32_t bank1_addr;
|
||||
#if defined (STM32L471xx) || defined (STM32L475xx) || defined (STM32L476xx) || defined (STM32L485xx) || defined (STM32L486xx) || \
|
||||
defined (STM32L496xx) || defined (STM32L4A6xx) || \
|
||||
defined (STM32L4P5xx) || defined (STM32L4Q5xx) || \
|
||||
defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)
|
||||
uint32_t bank2_addr;
|
||||
#endif
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_FLASH_BANK_EXCLUSIVE(PCROPConfig & FLASH_BANK_BOTH));
|
||||
assert_param(IS_OB_PCROP_RDP(PCROPConfig & FLASH_PCROP1ER_PCROP_RDP));
|
||||
assert_param(IS_FLASH_MAIN_MEM_ADDRESS(PCROPStartAddr));
|
||||
assert_param(IS_FLASH_MAIN_MEM_ADDRESS(PCROPEndAddr));
|
||||
|
||||
/* Wait for last operation to be completed */
|
||||
status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
|
||||
|
||||
if(status == HAL_OK)
|
||||
{
|
||||
#if defined (STM32L471xx) || defined (STM32L475xx) || defined (STM32L476xx) || defined (STM32L485xx) || defined (STM32L486xx) || \
|
||||
defined (STM32L496xx) || defined (STM32L4A6xx) || \
|
||||
defined (STM32L4P5xx) || defined (STM32L4Q5xx) || \
|
||||
defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)
|
||||
/* Get the information about the bank swapping */
|
||||
if (READ_BIT(SYSCFG->MEMRMP, SYSCFG_MEMRMP_FB_MODE) == 0U)
|
||||
{
|
||||
bank1_addr = FLASH_BASE;
|
||||
bank2_addr = FLASH_BASE + FLASH_BANK_SIZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
bank1_addr = FLASH_BASE + FLASH_BANK_SIZE;
|
||||
bank2_addr = FLASH_BASE;
|
||||
}
|
||||
#else
|
||||
bank1_addr = FLASH_BASE;
|
||||
#endif
|
||||
|
||||
#if defined (STM32L4P5xx) || defined (STM32L4Q5xx) || defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)
|
||||
if (READ_BIT(FLASH->OPTR, FLASH_OPTR_DBANK) == 0U)
|
||||
{
|
||||
/* Configure the Proprietary code readout protection */
|
||||
if((PCROPConfig & FLASH_BANK_BOTH) == FLASH_BANK_1)
|
||||
{
|
||||
reg_value = ((PCROPStartAddr - FLASH_BASE) >> 4);
|
||||
MODIFY_REG(FLASH->PCROP1SR, FLASH_PCROP1SR_PCROP1_STRT, reg_value);
|
||||
|
||||
reg_value = ((PCROPEndAddr - FLASH_BASE) >> 4);
|
||||
MODIFY_REG(FLASH->PCROP1ER, FLASH_PCROP1ER_PCROP1_END, reg_value);
|
||||
}
|
||||
else if((PCROPConfig & FLASH_BANK_BOTH) == FLASH_BANK_2)
|
||||
{
|
||||
reg_value = ((PCROPStartAddr - FLASH_BASE) >> 4);
|
||||
MODIFY_REG(FLASH->PCROP2SR, FLASH_PCROP2SR_PCROP2_STRT, reg_value);
|
||||
|
||||
reg_value = ((PCROPEndAddr - FLASH_BASE) >> 4);
|
||||
MODIFY_REG(FLASH->PCROP2ER, FLASH_PCROP2ER_PCROP2_END, reg_value);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Nothing to do */
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
/* Configure the Proprietary code readout protection */
|
||||
if((PCROPConfig & FLASH_BANK_BOTH) == FLASH_BANK_1)
|
||||
{
|
||||
reg_value = ((PCROPStartAddr - bank1_addr) >> 3);
|
||||
MODIFY_REG(FLASH->PCROP1SR, FLASH_PCROP1SR_PCROP1_STRT, reg_value);
|
||||
|
||||
reg_value = ((PCROPEndAddr - bank1_addr) >> 3);
|
||||
MODIFY_REG(FLASH->PCROP1ER, FLASH_PCROP1ER_PCROP1_END, reg_value);
|
||||
}
|
||||
#if defined (STM32L471xx) || defined (STM32L475xx) || defined (STM32L476xx) || defined (STM32L485xx) || defined (STM32L486xx) || \
|
||||
defined (STM32L496xx) || defined (STM32L4A6xx) || \
|
||||
defined (STM32L4P5xx) || defined (STM32L4Q5xx) || \
|
||||
defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)
|
||||
else if((PCROPConfig & FLASH_BANK_BOTH) == FLASH_BANK_2)
|
||||
{
|
||||
reg_value = ((PCROPStartAddr - bank2_addr) >> 3);
|
||||
MODIFY_REG(FLASH->PCROP2SR, FLASH_PCROP2SR_PCROP2_STRT, reg_value);
|
||||
|
||||
reg_value = ((PCROPEndAddr - bank2_addr) >> 3);
|
||||
MODIFY_REG(FLASH->PCROP2ER, FLASH_PCROP2ER_PCROP2_END, reg_value);
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
/* Nothing to do */
|
||||
}
|
||||
}
|
||||
|
||||
MODIFY_REG(FLASH->PCROP1ER, FLASH_PCROP1ER_PCROP_RDP, (PCROPConfig & FLASH_PCROP1ER_PCROP_RDP));
|
||||
|
||||
/* Set OPTSTRT Bit */
|
||||
SET_BIT(FLASH->CR, FLASH_CR_OPTSTRT);
|
||||
|
||||
/* Wait for last operation to be completed */
|
||||
status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
|
||||
|
||||
/* If the option byte program operation is completed, disable the OPTSTRT Bit */
|
||||
CLEAR_BIT(FLASH->CR, FLASH_CR_OPTSTRT);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the FLASH Write Protection Option Bytes value.
|
||||
*
|
||||
* @param[in] WRPArea: specifies the area to be returned.
|
||||
* This parameter can be one of the following values:
|
||||
* @arg OB_WRPAREA_BANK1_AREAA: Flash Bank 1 Area A
|
||||
* @arg OB_WRPAREA_BANK1_AREAB: Flash Bank 1 Area B
|
||||
* @arg OB_WRPAREA_BANK2_AREAA: Flash Bank 2 Area A (don't apply to STM32L43x/STM32L44x devices)
|
||||
* @arg OB_WRPAREA_BANK2_AREAB: Flash Bank 2 Area B (don't apply to STM32L43x/STM32L44x devices)
|
||||
*
|
||||
* @param[out] WRPStartOffset: specifies the address where to copied the start page
|
||||
* of the write protected area
|
||||
*
|
||||
* @param[out] WRDPEndOffset: specifies the address where to copied the end page of
|
||||
* the write protected area
|
||||
*
|
||||
* @retval None
|
||||
*/
|
||||
static void FLASH_OB_GetWRP(uint32_t WRPArea, uint32_t * WRPStartOffset, uint32_t * WRDPEndOffset)
|
||||
{
|
||||
/* Get the configuration of the write protected area */
|
||||
if(WRPArea == OB_WRPAREA_BANK1_AREAA)
|
||||
{
|
||||
*WRPStartOffset = READ_BIT(FLASH->WRP1AR, FLASH_WRP1AR_WRP1A_STRT);
|
||||
*WRDPEndOffset = (READ_BIT(FLASH->WRP1AR, FLASH_WRP1AR_WRP1A_END) >> 16);
|
||||
}
|
||||
else if(WRPArea == OB_WRPAREA_BANK1_AREAB)
|
||||
{
|
||||
*WRPStartOffset = READ_BIT(FLASH->WRP1BR, FLASH_WRP1BR_WRP1B_STRT);
|
||||
*WRDPEndOffset = (READ_BIT(FLASH->WRP1BR, FLASH_WRP1BR_WRP1B_END) >> 16);
|
||||
}
|
||||
#if defined (STM32L471xx) || defined (STM32L475xx) || defined (STM32L476xx) || defined (STM32L485xx) || defined (STM32L486xx) || \
|
||||
defined (STM32L496xx) || defined (STM32L4A6xx) || \
|
||||
defined (STM32L4P5xx) || defined (STM32L4Q5xx) || \
|
||||
defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)
|
||||
else if(WRPArea == OB_WRPAREA_BANK2_AREAA)
|
||||
{
|
||||
*WRPStartOffset = READ_BIT(FLASH->WRP2AR, FLASH_WRP2AR_WRP2A_STRT);
|
||||
*WRDPEndOffset = (READ_BIT(FLASH->WRP2AR, FLASH_WRP2AR_WRP2A_END) >> 16);
|
||||
}
|
||||
else if(WRPArea == OB_WRPAREA_BANK2_AREAB)
|
||||
{
|
||||
*WRPStartOffset = READ_BIT(FLASH->WRP2BR, FLASH_WRP2BR_WRP2B_STRT);
|
||||
*WRDPEndOffset = (READ_BIT(FLASH->WRP2BR, FLASH_WRP2BR_WRP2B_END) >> 16);
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
/* Nothing to do */
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the FLASH Read Protection level.
|
||||
* @retval FLASH ReadOut Protection Status:
|
||||
* This return value can be one of the following values:
|
||||
* @arg OB_RDP_LEVEL_0: No protection
|
||||
* @arg OB_RDP_LEVEL_1: Read protection of the memory
|
||||
* @arg OB_RDP_LEVEL_2: Full chip protection
|
||||
*/
|
||||
static uint32_t FLASH_OB_GetRDP(void)
|
||||
{
|
||||
uint32_t rdp_level = READ_BIT(FLASH->OPTR, FLASH_OPTR_RDP);
|
||||
|
||||
if ((rdp_level != OB_RDP_LEVEL_0) && (rdp_level != OB_RDP_LEVEL_2))
|
||||
{
|
||||
return (OB_RDP_LEVEL_1);
|
||||
}
|
||||
else
|
||||
{
|
||||
return (READ_BIT(FLASH->OPTR, FLASH_OPTR_RDP));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the FLASH User Option Byte value.
|
||||
* @retval The FLASH User Option Bytes values:
|
||||
* For STM32L47x/STM32L48x devices :
|
||||
* BOR_LEV(Bit8-10), nRST_STOP(Bit12), nRST_STDBY(Bit13), nRST_SHDW(Bit14),
|
||||
* IWDG_SW(Bit16), IWDG_STOP(Bit17), IWDG_STDBY(Bit18), WWDG_SW(Bit19),
|
||||
* BFB2(Bit20), DUALBANK(Bit21), nBOOT1(Bit23), SRAM2_PE(Bit24) and SRAM2_RST(Bit25).
|
||||
* For STM32L43x/STM32L44x devices :
|
||||
* BOR_LEV(Bit8-10), nRST_STOP(Bit12), nRST_STDBY(Bit13), nRST_SHDW(Bit14),
|
||||
* IWDG_SW(Bit16), IWDG_STOP(Bit17), IWDG_STDBY(Bit18), WWDG_SW(Bit19),
|
||||
* nBOOT1(Bit23), SRAM2_PE(Bit24), SRAM2_RST(Bit25), nSWBOOT0(Bit26) and nBOOT0(Bit27).
|
||||
*/
|
||||
static uint32_t FLASH_OB_GetUser(void)
|
||||
{
|
||||
uint32_t user_config = READ_REG(FLASH->OPTR);
|
||||
CLEAR_BIT(user_config, FLASH_OPTR_RDP);
|
||||
|
||||
return user_config;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the FLASH Write Protection Option Bytes value.
|
||||
*
|
||||
* @param PCROPConfig [inout]: specifies the configuration (Bank to be configured and PCROP_RDP option).
|
||||
* This parameter must be a combination of FLASH_BANK_1 or FLASH_BANK_2
|
||||
* with OB_PCROP_RDP_NOT_ERASE or OB_PCROP_RDP_ERASE
|
||||
*
|
||||
* @param PCROPStartAddr [out]: specifies the address where to copied the start address
|
||||
* of the Proprietary code readout protection
|
||||
*
|
||||
* @param PCROPEndAddr [out]: specifies the address where to copied the end address of
|
||||
* the Proprietary code readout protection
|
||||
*
|
||||
* @retval None
|
||||
*/
|
||||
static void FLASH_OB_GetPCROP(uint32_t * PCROPConfig, uint32_t * PCROPStartAddr, uint32_t * PCROPEndAddr)
|
||||
{
|
||||
uint32_t reg_value;
|
||||
uint32_t bank1_addr;
|
||||
#if defined (STM32L471xx) || defined (STM32L475xx) || defined (STM32L476xx) || defined (STM32L485xx) || defined (STM32L486xx) || \
|
||||
defined (STM32L496xx) || defined (STM32L4A6xx) || \
|
||||
defined (STM32L4P5xx) || defined (STM32L4Q5xx) || \
|
||||
defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)
|
||||
uint32_t bank2_addr;
|
||||
#endif
|
||||
|
||||
#if defined (STM32L471xx) || defined (STM32L475xx) || defined (STM32L476xx) || defined (STM32L485xx) || defined (STM32L486xx) || \
|
||||
defined (STM32L496xx) || defined (STM32L4A6xx) || \
|
||||
defined (STM32L4P5xx) || defined (STM32L4Q5xx) || \
|
||||
defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)
|
||||
/* Get the information about the bank swapping */
|
||||
if (READ_BIT(SYSCFG->MEMRMP, SYSCFG_MEMRMP_FB_MODE) == 0U)
|
||||
{
|
||||
bank1_addr = FLASH_BASE;
|
||||
bank2_addr = FLASH_BASE + FLASH_BANK_SIZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
bank1_addr = FLASH_BASE + FLASH_BANK_SIZE;
|
||||
bank2_addr = FLASH_BASE;
|
||||
}
|
||||
#else
|
||||
bank1_addr = FLASH_BASE;
|
||||
#endif
|
||||
|
||||
#if defined (STM32L4P5xx) || defined (STM32L4Q5xx) || defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)
|
||||
if (READ_BIT(FLASH->OPTR, FLASH_OPTR_DBANK) == 0U)
|
||||
{
|
||||
if(((*PCROPConfig) & FLASH_BANK_BOTH) == FLASH_BANK_1)
|
||||
{
|
||||
reg_value = (READ_REG(FLASH->PCROP1SR) & FLASH_PCROP1SR_PCROP1_STRT);
|
||||
*PCROPStartAddr = (reg_value << 4) + FLASH_BASE;
|
||||
|
||||
reg_value = (READ_REG(FLASH->PCROP1ER) & FLASH_PCROP1ER_PCROP1_END);
|
||||
*PCROPEndAddr = (reg_value << 4) + FLASH_BASE + 0xFU;
|
||||
}
|
||||
else if(((*PCROPConfig) & FLASH_BANK_BOTH) == FLASH_BANK_2)
|
||||
{
|
||||
reg_value = (READ_REG(FLASH->PCROP2SR) & FLASH_PCROP2SR_PCROP2_STRT);
|
||||
*PCROPStartAddr = (reg_value << 4) + FLASH_BASE;
|
||||
|
||||
reg_value = (READ_REG(FLASH->PCROP2ER) & FLASH_PCROP2ER_PCROP2_END);
|
||||
*PCROPEndAddr = (reg_value << 4) + FLASH_BASE + 0xFU;;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Nothing to do */
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
if(((*PCROPConfig) & FLASH_BANK_BOTH) == FLASH_BANK_1)
|
||||
{
|
||||
reg_value = (READ_REG(FLASH->PCROP1SR) & FLASH_PCROP1SR_PCROP1_STRT);
|
||||
*PCROPStartAddr = (reg_value << 3) + bank1_addr;
|
||||
|
||||
reg_value = (READ_REG(FLASH->PCROP1ER) & FLASH_PCROP1ER_PCROP1_END);
|
||||
*PCROPEndAddr = (reg_value << 3) + bank1_addr + 0x7U;
|
||||
}
|
||||
#if defined (STM32L471xx) || defined (STM32L475xx) || defined (STM32L476xx) || defined (STM32L485xx) || defined (STM32L486xx) || \
|
||||
defined (STM32L496xx) || defined (STM32L4A6xx) || \
|
||||
defined (STM32L4P5xx) || defined (STM32L4Q5xx) || \
|
||||
defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)
|
||||
else if(((*PCROPConfig) & FLASH_BANK_BOTH) == FLASH_BANK_2)
|
||||
{
|
||||
reg_value = (READ_REG(FLASH->PCROP2SR) & FLASH_PCROP2SR_PCROP2_STRT);
|
||||
*PCROPStartAddr = (reg_value << 3) + bank2_addr;
|
||||
|
||||
reg_value = (READ_REG(FLASH->PCROP2ER) & FLASH_PCROP2ER_PCROP2_END);
|
||||
*PCROPEndAddr = (reg_value << 3) + bank2_addr + 0x7U;
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
/* Nothing to do */
|
||||
}
|
||||
}
|
||||
|
||||
*PCROPConfig |= (READ_REG(FLASH->PCROP1ER) & FLASH_PCROP1ER_PCROP_RDP);
|
||||
}
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* HAL_FLASH_MODULE_ENABLED */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
@@ -1,251 +0,0 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32l4xx_hal_flash_ramfunc.c
|
||||
* @author MCD Application Team
|
||||
* @brief FLASH RAMFUNC driver.
|
||||
* This file provides a Flash firmware functions which should be
|
||||
* executed from internal SRAM
|
||||
* + FLASH HalfPage Programming
|
||||
* + FLASH Power Down in Run mode
|
||||
*
|
||||
* @verbatim
|
||||
==============================================================================
|
||||
##### Flash RAM functions #####
|
||||
==============================================================================
|
||||
|
||||
*** ARM Compiler ***
|
||||
--------------------
|
||||
[..] RAM functions are defined using the toolchain options.
|
||||
Functions that are executed in RAM should reside in a separate
|
||||
source module. Using the 'Options for File' dialog you can simply change
|
||||
the 'Code / Const' area of a module to a memory space in physical RAM.
|
||||
Available memory areas are declared in the 'Target' tab of the
|
||||
Options for Target' dialog.
|
||||
|
||||
*** ICCARM Compiler ***
|
||||
-----------------------
|
||||
[..] RAM functions are defined using a specific toolchain keyword "__ramfunc".
|
||||
|
||||
*** GNU Compiler ***
|
||||
--------------------
|
||||
[..] RAM functions are defined using a specific toolchain attribute
|
||||
"__attribute__((section(".RamFunc")))".
|
||||
|
||||
@endverbatim
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2017 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file in
|
||||
* the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32l4xx_hal.h"
|
||||
|
||||
/** @addtogroup STM32L4xx_HAL_Driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup FLASH_RAMFUNC FLASH_RAMFUNC
|
||||
* @brief FLASH functions executed from RAM
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifdef HAL_FLASH_MODULE_ENABLED
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* Exported functions -------------------------------------------------------*/
|
||||
|
||||
/** @defgroup FLASH_RAMFUNC_Exported_Functions FLASH in RAM function Exported Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup FLASH_RAMFUNC_Exported_Functions_Group1 Peripheral features functions
|
||||
* @brief Data transfers functions
|
||||
*
|
||||
@verbatim
|
||||
===============================================================================
|
||||
##### ramfunc functions #####
|
||||
===============================================================================
|
||||
[..]
|
||||
This subsection provides a set of functions that should be executed from RAM.
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Enable the Power down in Run Mode
|
||||
* @note This function should be called and executed from SRAM memory
|
||||
* @retval HAL status
|
||||
*/
|
||||
__RAM_FUNC HAL_StatusTypeDef HAL_FLASHEx_EnableRunPowerDown(void)
|
||||
{
|
||||
/* Enable the Power Down in Run mode*/
|
||||
__HAL_FLASH_POWER_DOWN_ENABLE();
|
||||
|
||||
return HAL_OK;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable the Power down in Run Mode
|
||||
* @note This function should be called and executed from SRAM memory
|
||||
* @retval HAL status
|
||||
*/
|
||||
__RAM_FUNC HAL_StatusTypeDef HAL_FLASHEx_DisableRunPowerDown(void)
|
||||
{
|
||||
/* Disable the Power Down in Run mode*/
|
||||
__HAL_FLASH_POWER_DOWN_DISABLE();
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
#if defined (STM32L4P5xx) || defined (STM32L4Q5xx) || defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)
|
||||
/**
|
||||
* @brief Program the FLASH DBANK User Option Byte.
|
||||
*
|
||||
* @note To configure the user option bytes, the option lock bit OPTLOCK must
|
||||
* be cleared with the call of the HAL_FLASH_OB_Unlock() function.
|
||||
* @note To modify the DBANK option byte, no PCROP region should be defined.
|
||||
* To deactivate PCROP, user should perform RDP changing
|
||||
*
|
||||
* @param DBankConfig The FLASH DBANK User Option Byte value.
|
||||
* This parameter can be one of the following values:
|
||||
* @arg OB_DBANK_128_BITS: Single-bank with 128-bits data
|
||||
* @arg OB_DBANK_64_BITS: Dual-bank with 64-bits data
|
||||
*
|
||||
* @retval HAL status
|
||||
*/
|
||||
__RAM_FUNC HAL_StatusTypeDef HAL_FLASHEx_OB_DBankConfig(uint32_t DBankConfig)
|
||||
{
|
||||
uint32_t count, reg;
|
||||
HAL_StatusTypeDef status = HAL_ERROR;
|
||||
|
||||
/* Process Locked */
|
||||
__HAL_LOCK(&pFlash);
|
||||
|
||||
/* Check if the PCROP is disabled */
|
||||
reg = FLASH->PCROP1SR;
|
||||
if (reg > FLASH->PCROP1ER)
|
||||
{
|
||||
reg = FLASH->PCROP2SR;
|
||||
if (reg > FLASH->PCROP2ER)
|
||||
{
|
||||
/* Disable Flash prefetch */
|
||||
__HAL_FLASH_PREFETCH_BUFFER_DISABLE();
|
||||
|
||||
if (READ_BIT(FLASH->ACR, FLASH_ACR_ICEN) != 0U)
|
||||
{
|
||||
/* Disable Flash instruction cache */
|
||||
__HAL_FLASH_INSTRUCTION_CACHE_DISABLE();
|
||||
|
||||
/* Flush Flash instruction cache */
|
||||
__HAL_FLASH_INSTRUCTION_CACHE_RESET();
|
||||
}
|
||||
|
||||
if (READ_BIT(FLASH->ACR, FLASH_ACR_DCEN) != 0U)
|
||||
{
|
||||
/* Disable Flash data cache */
|
||||
__HAL_FLASH_DATA_CACHE_DISABLE();
|
||||
|
||||
/* Flush Flash data cache */
|
||||
__HAL_FLASH_DATA_CACHE_RESET();
|
||||
}
|
||||
|
||||
/* Disable WRP zone 1 of 1st bank if needed */
|
||||
reg = FLASH->WRP1AR;
|
||||
if (((reg & FLASH_WRP1AR_WRP1A_STRT) >> FLASH_WRP1AR_WRP1A_STRT_Pos) <=
|
||||
((reg & FLASH_WRP1AR_WRP1A_END) >> FLASH_WRP1AR_WRP1A_END_Pos))
|
||||
{
|
||||
MODIFY_REG(FLASH->WRP1AR, (FLASH_WRP1AR_WRP1A_STRT | FLASH_WRP1AR_WRP1A_END), FLASH_WRP1AR_WRP1A_STRT);
|
||||
}
|
||||
|
||||
/* Disable WRP zone 2 of 1st bank if needed */
|
||||
reg = FLASH->WRP1BR;
|
||||
if (((reg & FLASH_WRP1BR_WRP1B_STRT) >> FLASH_WRP1BR_WRP1B_STRT_Pos) <=
|
||||
((reg & FLASH_WRP1BR_WRP1B_END) >> FLASH_WRP1BR_WRP1B_END_Pos))
|
||||
{
|
||||
MODIFY_REG(FLASH->WRP1BR, (FLASH_WRP1BR_WRP1B_STRT | FLASH_WRP1BR_WRP1B_END), FLASH_WRP1BR_WRP1B_STRT);
|
||||
}
|
||||
|
||||
/* Disable WRP zone 1 of 2nd bank if needed */
|
||||
reg = FLASH->WRP2AR;
|
||||
if (((reg & FLASH_WRP2AR_WRP2A_STRT) >> FLASH_WRP2AR_WRP2A_STRT_Pos) <=
|
||||
((reg & FLASH_WRP2AR_WRP2A_END) >> FLASH_WRP2AR_WRP2A_END_Pos))
|
||||
{
|
||||
MODIFY_REG(FLASH->WRP2AR, (FLASH_WRP2AR_WRP2A_STRT | FLASH_WRP2AR_WRP2A_END), FLASH_WRP2AR_WRP2A_STRT);
|
||||
}
|
||||
|
||||
/* Disable WRP zone 2 of 2nd bank if needed */
|
||||
reg = FLASH->WRP2BR;
|
||||
if (((reg & FLASH_WRP2BR_WRP2B_STRT) >> FLASH_WRP2BR_WRP2B_STRT_Pos) <=
|
||||
((reg & FLASH_WRP2BR_WRP2B_END) >> FLASH_WRP2BR_WRP2B_END_Pos))
|
||||
{
|
||||
MODIFY_REG(FLASH->WRP2BR, (FLASH_WRP2BR_WRP2B_STRT | FLASH_WRP2BR_WRP2B_END), FLASH_WRP2BR_WRP2B_STRT);
|
||||
}
|
||||
|
||||
/* Modify the DBANK user option byte */
|
||||
MODIFY_REG(FLASH->OPTR, FLASH_OPTR_DBANK, DBankConfig);
|
||||
|
||||
/* Set OPTSTRT Bit */
|
||||
SET_BIT(FLASH->CR, FLASH_CR_OPTSTRT);
|
||||
|
||||
/* Wait for last operation to be completed */
|
||||
/* 8 is the number of required instruction cycles for the below loop statement (timeout expressed in ms) */
|
||||
count = FLASH_TIMEOUT_VALUE * (SystemCoreClock / 8U / 1000U);
|
||||
do
|
||||
{
|
||||
if (count == 0U)
|
||||
{
|
||||
break;
|
||||
}
|
||||
count--;
|
||||
} while (__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY) != RESET);
|
||||
|
||||
/* If the option byte program operation is completed, disable the OPTSTRT Bit */
|
||||
CLEAR_BIT(FLASH->CR, FLASH_CR_OPTSTRT);
|
||||
|
||||
/* Set the bit to force the option byte reloading */
|
||||
SET_BIT(FLASH->CR, FLASH_CR_OBL_LAUNCH);
|
||||
}
|
||||
}
|
||||
|
||||
/* Process Unlocked */
|
||||
__HAL_UNLOCK(&pFlash);
|
||||
|
||||
return status;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
#endif /* HAL_FLASH_MODULE_ENABLED */
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,551 +0,0 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32l4xx_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
|
||||
*
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2017 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
@verbatim
|
||||
==============================================================================
|
||||
##### GPIO Peripheral features #####
|
||||
==============================================================================
|
||||
[..]
|
||||
(+) Each port bit of the general-purpose I/O (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.
|
||||
|
||||
(+) The microcontroller IO pins are connected to onboard peripherals/modules through a
|
||||
multiplexer that allows only one peripheral alternate function (AF) connected
|
||||
to an IO pin at a time. In this way, there can be no conflict between peripherals
|
||||
sharing the same IO pin.
|
||||
|
||||
(+) 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 39 edge detectors
|
||||
(16 lines are connected to GPIO) for generating event/interrupt requests (each
|
||||
input line can be independently configured to select the type (interrupt or event)
|
||||
and the corresponding trigger event (rising or falling or both). Each line can
|
||||
also be masked independently.
|
||||
|
||||
##### How to use this driver #####
|
||||
==============================================================================
|
||||
[..]
|
||||
(#) Enable the GPIO AHB 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.
|
||||
(++) In alternate mode is selection, the alternate function connected to the IO
|
||||
is configured through "Alternate" 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 PH0 and PH1, respectively, when the HSE oscillator is off.
|
||||
The HSE has priority over the GPIO function.
|
||||
|
||||
@endverbatim
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32l4xx_hal.h"
|
||||
|
||||
/** @addtogroup STM32L4xx_HAL_Driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup GPIO GPIO
|
||||
* @brief GPIO HAL module driver
|
||||
* @{
|
||||
*/
|
||||
/** MISRA C:2012 deviation rule has been granted for following rules:
|
||||
* Rule-12.2 - Medium: RHS argument is in interval [0,INF] which is out of
|
||||
* range of the shift operator in following API :
|
||||
* HAL_GPIO_Init
|
||||
* HAL_GPIO_DeInit
|
||||
*/
|
||||
|
||||
#ifdef HAL_GPIO_MODULE_ENABLED
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private defines -----------------------------------------------------------*/
|
||||
/** @addtogroup GPIO_Private_Defines GPIO Private Defines
|
||||
* @{
|
||||
*/
|
||||
#define GPIO_NUMBER (16u)
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private macros ------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* Exported functions --------------------------------------------------------*/
|
||||
|
||||
/** @defgroup GPIO_Exported_Functions GPIO Exported Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup GPIO_Exported_Functions_Group1 Initialization/de-initialization functions
|
||||
* @brief Initialization and Configuration functions
|
||||
*
|
||||
@verbatim
|
||||
===============================================================================
|
||||
##### Initialization and de-initialization functions #####
|
||||
===============================================================================
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Initialize the GPIOx peripheral according to the specified parameters in the GPIO_Init.
|
||||
* @param GPIOx where x can be (A..H) to select the GPIO peripheral for STM32L4 family
|
||||
* @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 = 0x00u;
|
||||
uint32_t iocurrent;
|
||||
uint32_t temp;
|
||||
|
||||
/* 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 */
|
||||
while (((GPIO_Init->Pin) >> position) != 0x00u)
|
||||
{
|
||||
/* Get current io position */
|
||||
iocurrent = (GPIO_Init->Pin) & (1uL << position);
|
||||
|
||||
if (iocurrent != 0x00u)
|
||||
{
|
||||
/*--------------------- GPIO Mode Configuration ------------------------*/
|
||||
/* In case of Output or Alternate function mode selection */
|
||||
if (((GPIO_Init->Mode & GPIO_MODE) == MODE_OUTPUT) || ((GPIO_Init->Mode & GPIO_MODE) == MODE_AF))
|
||||
{
|
||||
/* Check the Speed parameter */
|
||||
assert_param(IS_GPIO_SPEED(GPIO_Init->Speed));
|
||||
|
||||
/* Configure the IO Speed */
|
||||
temp = GPIOx->OSPEEDR;
|
||||
temp &= ~(GPIO_OSPEEDR_OSPEED0 << (position * 2u));
|
||||
temp |= (GPIO_Init->Speed << (position * 2u));
|
||||
GPIOx->OSPEEDR = temp;
|
||||
|
||||
/* Configure the IO Output Type */
|
||||
temp = GPIOx->OTYPER;
|
||||
temp &= ~(GPIO_OTYPER_OT0 << position) ;
|
||||
temp |= (((GPIO_Init->Mode & OUTPUT_TYPE) >> OUTPUT_TYPE_Pos) << position);
|
||||
GPIOx->OTYPER = temp;
|
||||
}
|
||||
|
||||
#if defined(STM32L471xx) || defined(STM32L475xx) || defined(STM32L476xx) || defined(STM32L485xx) || defined(STM32L486xx)
|
||||
|
||||
/* In case of Analog mode, check if ADC control mode is selected */
|
||||
if((GPIO_Init->Mode & GPIO_MODE_ANALOG) == GPIO_MODE_ANALOG)
|
||||
{
|
||||
/* Configure the IO Output Type */
|
||||
temp = GPIOx->ASCR;
|
||||
temp &= ~(GPIO_ASCR_ASC0 << position) ;
|
||||
temp |= (((GPIO_Init->Mode & GPIO_MODE_ANALOG_ADC_CONTROL) >> 3) << position);
|
||||
GPIOx->ASCR = temp;
|
||||
}
|
||||
|
||||
#endif /* STM32L471xx || STM32L475xx || STM32L476xx || STM32L485xx || STM32L486xx */
|
||||
|
||||
/* Activate the Pull-up or Pull down resistor for the current IO */
|
||||
if ((GPIO_Init->Mode & GPIO_MODE) != MODE_ANALOG)
|
||||
{
|
||||
/* Check the Pull parameter */
|
||||
assert_param(IS_GPIO_PULL(GPIO_Init->Pull));
|
||||
|
||||
temp = GPIOx->PUPDR;
|
||||
temp &= ~(GPIO_PUPDR_PUPD0 << (position * 2U));
|
||||
temp |= ((GPIO_Init->Pull) << (position * 2U));
|
||||
GPIOx->PUPDR = temp;
|
||||
}
|
||||
|
||||
/* In case of Alternate function mode selection */
|
||||
if ((GPIO_Init->Mode & GPIO_MODE) == MODE_AF)
|
||||
{
|
||||
/* Check the Alternate function parameters */
|
||||
assert_param(IS_GPIO_AF_INSTANCE(GPIOx));
|
||||
assert_param(IS_GPIO_AF(GPIO_Init->Alternate));
|
||||
|
||||
/* Configure Alternate function mapped with the current IO */
|
||||
temp = GPIOx->AFR[position >> 3u];
|
||||
temp &= ~(0xFu << ((position & 0x07u) * 4u));
|
||||
temp |= ((GPIO_Init->Alternate) << ((position & 0x07u) * 4u));
|
||||
GPIOx->AFR[position >> 3u] = temp;
|
||||
}
|
||||
|
||||
/* Configure IO Direction mode (Input, Output, Alternate or Analog) */
|
||||
temp = GPIOx->MODER;
|
||||
temp &= ~(GPIO_MODER_MODE0 << (position * 2u));
|
||||
temp |= ((GPIO_Init->Mode & GPIO_MODE) << (position * 2u));
|
||||
GPIOx->MODER = temp;
|
||||
|
||||
/*--------------------- EXTI Mode Configuration ------------------------*/
|
||||
/* Configure the External Interrupt or event for the current IO */
|
||||
if ((GPIO_Init->Mode & EXTI_MODE) != 0x00u)
|
||||
{
|
||||
/* Enable SYSCFG Clock */
|
||||
__HAL_RCC_SYSCFG_CLK_ENABLE();
|
||||
|
||||
temp = SYSCFG->EXTICR[position >> 2u];
|
||||
temp &= ~(0x0FuL << (4u * (position & 0x03u)));
|
||||
temp |= (GPIO_GET_INDEX(GPIOx) << (4u * (position & 0x03u)));
|
||||
SYSCFG->EXTICR[position >> 2u] = temp;
|
||||
|
||||
/* Clear Rising Falling edge configuration */
|
||||
temp = EXTI->RTSR1;
|
||||
temp &= ~(iocurrent);
|
||||
if ((GPIO_Init->Mode & TRIGGER_RISING) != 0x00u)
|
||||
{
|
||||
temp |= iocurrent;
|
||||
}
|
||||
EXTI->RTSR1 = temp;
|
||||
|
||||
temp = EXTI->FTSR1;
|
||||
temp &= ~(iocurrent);
|
||||
if ((GPIO_Init->Mode & TRIGGER_FALLING) != 0x00u)
|
||||
{
|
||||
temp |= iocurrent;
|
||||
}
|
||||
EXTI->FTSR1 = temp;
|
||||
|
||||
/* Clear EXTI line configuration */
|
||||
temp = EXTI->EMR1;
|
||||
temp &= ~(iocurrent);
|
||||
if ((GPIO_Init->Mode & EXTI_EVT) != 0x00u)
|
||||
{
|
||||
temp |= iocurrent;
|
||||
}
|
||||
EXTI->EMR1 = temp;
|
||||
|
||||
temp = EXTI->IMR1;
|
||||
temp &= ~(iocurrent);
|
||||
if ((GPIO_Init->Mode & EXTI_IT) != 0x00u)
|
||||
{
|
||||
temp |= iocurrent;
|
||||
}
|
||||
EXTI->IMR1 = temp;
|
||||
}
|
||||
}
|
||||
|
||||
position++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief De-initialize the GPIOx peripheral registers to their default reset values.
|
||||
* @param GPIOx where x can be (A..H) to select the GPIO peripheral for STM32L4 family
|
||||
* @param GPIO_Pin specifies the port bit to be written.
|
||||
* This parameter can be any combination of GPIO_Pin_x where x can be (0..15).
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_GPIO_DeInit(GPIO_TypeDef *GPIOx, uint32_t GPIO_Pin)
|
||||
{
|
||||
uint32_t position = 0x00u;
|
||||
uint32_t iocurrent;
|
||||
uint32_t tmp;
|
||||
|
||||
/* 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) != 0x00u)
|
||||
{
|
||||
/* Get current io position */
|
||||
iocurrent = (GPIO_Pin) & (1uL << position);
|
||||
|
||||
if (iocurrent != 0x00u)
|
||||
{
|
||||
/*------------------------- EXTI Mode Configuration --------------------*/
|
||||
/* Clear the External Interrupt or Event for the current IO */
|
||||
|
||||
tmp = SYSCFG->EXTICR[position >> 2u];
|
||||
tmp &= (0x0FuL << (4u * (position & 0x03u)));
|
||||
if (tmp == (GPIO_GET_INDEX(GPIOx) << (4u * (position & 0x03u))))
|
||||
{
|
||||
/* Clear EXTI line configuration */
|
||||
EXTI->IMR1 &= ~(iocurrent);
|
||||
EXTI->EMR1 &= ~(iocurrent);
|
||||
|
||||
/* Clear Rising Falling edge configuration */
|
||||
EXTI->FTSR1 &= ~(iocurrent);
|
||||
EXTI->RTSR1 &= ~(iocurrent);
|
||||
|
||||
tmp = 0x0FuL << (4u * (position & 0x03u));
|
||||
SYSCFG->EXTICR[position >> 2u] &= ~tmp;
|
||||
}
|
||||
|
||||
/*------------------------- GPIO Mode Configuration --------------------*/
|
||||
/* Configure IO in Analog Mode */
|
||||
GPIOx->MODER |= (GPIO_MODER_MODE0 << (position * 2u));
|
||||
|
||||
/* Configure the default Alternate Function in current IO */
|
||||
GPIOx->AFR[position >> 3u] &= ~(0xFu << ((position & 0x07u) * 4u)) ;
|
||||
|
||||
/* Configure the default value for IO Speed */
|
||||
GPIOx->OSPEEDR &= ~(GPIO_OSPEEDR_OSPEED0 << (position * 2u));
|
||||
|
||||
/* Configure the default value IO Output Type */
|
||||
GPIOx->OTYPER &= ~(GPIO_OTYPER_OT0 << position) ;
|
||||
|
||||
/* Deactivate the Pull-up and Pull-down resistor for the current IO */
|
||||
GPIOx->PUPDR &= ~(GPIO_PUPDR_PUPD0 << (position * 2u));
|
||||
|
||||
#if defined(STM32L471xx) || defined(STM32L475xx) || defined(STM32L476xx) || defined(STM32L485xx) || defined(STM32L486xx)
|
||||
/* Deactivate the Control bit of Analog mode for the current IO */
|
||||
GPIOx->ASCR &= ~(GPIO_ASCR_ASC0<< position);
|
||||
#endif /* STM32L471xx || STM32L475xx || STM32L476xx || STM32L485xx || STM32L486xx */
|
||||
}
|
||||
|
||||
position++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup GPIO_Exported_Functions_Group2 IO operation functions
|
||||
* @brief GPIO Read, Write, Toggle, Lock and EXTI management functions.
|
||||
*
|
||||
@verbatim
|
||||
===============================================================================
|
||||
##### IO operation functions #####
|
||||
===============================================================================
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Read the specified input port pin.
|
||||
* @param GPIOx where x can be (A..H) to select the GPIO peripheral for STM32L4 family
|
||||
* @param GPIO_Pin specifies the port bit to read.
|
||||
* This parameter can be any combination of 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) != 0x00u)
|
||||
{
|
||||
bitstatus = GPIO_PIN_SET;
|
||||
}
|
||||
else
|
||||
{
|
||||
bitstatus = GPIO_PIN_RESET;
|
||||
}
|
||||
return bitstatus;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set or clear the selected data port bit.
|
||||
*
|
||||
* @note This function uses GPIOx_BSRR and GPIOx_BRR registers 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..H) to select the GPIO peripheral for STM32L4 family
|
||||
* @param GPIO_Pin specifies the port bit to be written.
|
||||
* This parameter can be any combination of GPIO_Pin_x where x can be (0..15).
|
||||
* @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 = (uint32_t)GPIO_Pin;
|
||||
}
|
||||
else
|
||||
{
|
||||
GPIOx->BRR = (uint32_t)GPIO_Pin;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Toggle the specified GPIO pin.
|
||||
* @param GPIOx where x can be (A..H) to select the GPIO peripheral for STM32L4 family
|
||||
* @param GPIO_Pin specifies the pin to be toggled.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_GPIO_TogglePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
|
||||
{
|
||||
uint32_t odr;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_GPIO_PIN(GPIO_Pin));
|
||||
|
||||
/* get current Output Data Register value */
|
||||
odr = GPIOx->ODR;
|
||||
|
||||
/* Set selected pins that were at low level, and reset ones that were high */
|
||||
GPIOx->BSRR = ((odr & GPIO_Pin) << GPIO_NUMBER) | (~odr & GPIO_Pin);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Lock GPIO Pins configuration registers.
|
||||
* @note The locked registers are GPIOx_MODER, GPIOx_OTYPER, GPIOx_OSPEEDR,
|
||||
* GPIOx_PUPDR, GPIOx_AFRL and GPIOx_AFRH.
|
||||
* @note The configuration of the locked GPIO pins can no longer be modified
|
||||
* until the next reset.
|
||||
* @param GPIOx where x can be (A..H) to select the GPIO peripheral for STM32L4 family
|
||||
* @param GPIO_Pin specifies the port bits 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 */
|
||||
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 register. This read is mandatory to complete key lock sequence */
|
||||
tmp = GPIOx->LCKR;
|
||||
|
||||
/* Read again in order to confirm lock is active */
|
||||
if ((GPIOx->LCKR & GPIO_LCKR_LCKK) != 0x00u)
|
||||
{
|
||||
return HAL_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Handle EXTI interrupt request.
|
||||
* @param GPIO_Pin Specifies the port pin connected to corresponding 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) != 0x00u)
|
||||
{
|
||||
__HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin);
|
||||
HAL_GPIO_EXTI_Callback(GPIO_Pin);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief EXTI line detection callback.
|
||||
* @param GPIO_Pin Specifies the port pin connected to corresponding 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 */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,368 +0,0 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32l4xx_hal_i2c_ex.c
|
||||
* @author MCD Application Team
|
||||
* @brief I2C Extended HAL module driver.
|
||||
* This file provides firmware functions to manage the following
|
||||
* functionalities of I2C Extended peripheral:
|
||||
* + Filter Mode Functions
|
||||
* + WakeUp Mode Functions
|
||||
* + FastModePlus Functions
|
||||
*
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2017 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
@verbatim
|
||||
==============================================================================
|
||||
##### I2C peripheral Extended features #####
|
||||
==============================================================================
|
||||
|
||||
[..] Comparing to other previous devices, the I2C interface for STM32L4xx
|
||||
devices contains the following additional features
|
||||
|
||||
(+) Possibility to disable or enable Analog Noise Filter
|
||||
(+) Use of a configured Digital Noise Filter
|
||||
(+) Disable or enable wakeup from Stop mode(s)
|
||||
(+) Disable or enable Fast Mode Plus
|
||||
|
||||
##### How to use this driver #####
|
||||
==============================================================================
|
||||
[..] This driver provides functions to configure Noise Filter and Wake Up Feature
|
||||
(#) Configure I2C Analog noise filter using the function HAL_I2CEx_ConfigAnalogFilter()
|
||||
(#) Configure I2C Digital noise filter using the function HAL_I2CEx_ConfigDigitalFilter()
|
||||
(#) Configure the enable or disable of I2C Wake Up Mode using the functions :
|
||||
(++) HAL_I2CEx_EnableWakeUp()
|
||||
(++) HAL_I2CEx_DisableWakeUp()
|
||||
(#) Configure the enable or disable of fast mode plus driving capability using the functions :
|
||||
(++) HAL_I2CEx_EnableFastModePlus()
|
||||
(++) HAL_I2CEx_DisableFastModePlus()
|
||||
@endverbatim
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32l4xx_hal.h"
|
||||
|
||||
/** @addtogroup STM32L4xx_HAL_Driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup I2CEx I2CEx
|
||||
* @brief I2C Extended HAL module driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifdef HAL_I2C_MODULE_ENABLED
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* Private functions ---------------------------------------------------------*/
|
||||
|
||||
/** @defgroup I2CEx_Exported_Functions I2C Extended Exported Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup I2CEx_Exported_Functions_Group1 Filter Mode Functions
|
||||
* @brief Filter Mode Functions
|
||||
*
|
||||
@verbatim
|
||||
===============================================================================
|
||||
##### Filter Mode Functions #####
|
||||
===============================================================================
|
||||
[..] This section provides functions allowing to:
|
||||
(+) Configure Noise Filters
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Configure I2C Analog noise filter.
|
||||
* @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified I2Cx peripheral.
|
||||
* @param AnalogFilter New state of the Analog filter.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_I2CEx_ConfigAnalogFilter(I2C_HandleTypeDef *hi2c, uint32_t AnalogFilter)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_I2C_ALL_INSTANCE(hi2c->Instance));
|
||||
assert_param(IS_I2C_ANALOG_FILTER(AnalogFilter));
|
||||
|
||||
if (hi2c->State == HAL_I2C_STATE_READY)
|
||||
{
|
||||
/* Process Locked */
|
||||
__HAL_LOCK(hi2c);
|
||||
|
||||
hi2c->State = HAL_I2C_STATE_BUSY;
|
||||
|
||||
/* Disable the selected I2C peripheral */
|
||||
__HAL_I2C_DISABLE(hi2c);
|
||||
|
||||
/* Reset I2Cx ANOFF bit */
|
||||
hi2c->Instance->CR1 &= ~(I2C_CR1_ANFOFF);
|
||||
|
||||
/* Set analog filter bit*/
|
||||
hi2c->Instance->CR1 |= AnalogFilter;
|
||||
|
||||
__HAL_I2C_ENABLE(hi2c);
|
||||
|
||||
hi2c->State = HAL_I2C_STATE_READY;
|
||||
|
||||
/* Process Unlocked */
|
||||
__HAL_UNLOCK(hi2c);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
return HAL_BUSY;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure I2C Digital noise filter.
|
||||
* @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified I2Cx peripheral.
|
||||
* @param DigitalFilter Coefficient of digital noise filter between Min_Data=0x00 and Max_Data=0x0F.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_I2CEx_ConfigDigitalFilter(I2C_HandleTypeDef *hi2c, uint32_t DigitalFilter)
|
||||
{
|
||||
uint32_t tmpreg;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_I2C_ALL_INSTANCE(hi2c->Instance));
|
||||
assert_param(IS_I2C_DIGITAL_FILTER(DigitalFilter));
|
||||
|
||||
if (hi2c->State == HAL_I2C_STATE_READY)
|
||||
{
|
||||
/* Process Locked */
|
||||
__HAL_LOCK(hi2c);
|
||||
|
||||
hi2c->State = HAL_I2C_STATE_BUSY;
|
||||
|
||||
/* Disable the selected I2C peripheral */
|
||||
__HAL_I2C_DISABLE(hi2c);
|
||||
|
||||
/* Get the old register value */
|
||||
tmpreg = hi2c->Instance->CR1;
|
||||
|
||||
/* Reset I2Cx DNF bits [11:8] */
|
||||
tmpreg &= ~(I2C_CR1_DNF);
|
||||
|
||||
/* Set I2Cx DNF coefficient */
|
||||
tmpreg |= DigitalFilter << 8U;
|
||||
|
||||
/* Store the new register value */
|
||||
hi2c->Instance->CR1 = tmpreg;
|
||||
|
||||
__HAL_I2C_ENABLE(hi2c);
|
||||
|
||||
hi2c->State = HAL_I2C_STATE_READY;
|
||||
|
||||
/* Process Unlocked */
|
||||
__HAL_UNLOCK(hi2c);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
return HAL_BUSY;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup I2CEx_Exported_Functions_Group2 WakeUp Mode Functions
|
||||
* @brief WakeUp Mode Functions
|
||||
*
|
||||
@verbatim
|
||||
===============================================================================
|
||||
##### WakeUp Mode Functions #####
|
||||
===============================================================================
|
||||
[..] This section provides functions allowing to:
|
||||
(+) Configure Wake Up Feature
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Enable I2C wakeup from Stop mode(s).
|
||||
* @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified I2Cx peripheral.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_I2CEx_EnableWakeUp(I2C_HandleTypeDef *hi2c)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_I2C_WAKEUP_FROMSTOP_INSTANCE(hi2c->Instance));
|
||||
|
||||
if (hi2c->State == HAL_I2C_STATE_READY)
|
||||
{
|
||||
/* Process Locked */
|
||||
__HAL_LOCK(hi2c);
|
||||
|
||||
hi2c->State = HAL_I2C_STATE_BUSY;
|
||||
|
||||
/* Disable the selected I2C peripheral */
|
||||
__HAL_I2C_DISABLE(hi2c);
|
||||
|
||||
/* Enable wakeup from stop mode */
|
||||
hi2c->Instance->CR1 |= I2C_CR1_WUPEN;
|
||||
|
||||
__HAL_I2C_ENABLE(hi2c);
|
||||
|
||||
hi2c->State = HAL_I2C_STATE_READY;
|
||||
|
||||
/* Process Unlocked */
|
||||
__HAL_UNLOCK(hi2c);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
return HAL_BUSY;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable I2C wakeup from Stop mode(s).
|
||||
* @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified I2Cx peripheral.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_I2CEx_DisableWakeUp(I2C_HandleTypeDef *hi2c)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_I2C_WAKEUP_FROMSTOP_INSTANCE(hi2c->Instance));
|
||||
|
||||
if (hi2c->State == HAL_I2C_STATE_READY)
|
||||
{
|
||||
/* Process Locked */
|
||||
__HAL_LOCK(hi2c);
|
||||
|
||||
hi2c->State = HAL_I2C_STATE_BUSY;
|
||||
|
||||
/* Disable the selected I2C peripheral */
|
||||
__HAL_I2C_DISABLE(hi2c);
|
||||
|
||||
/* Enable wakeup from stop mode */
|
||||
hi2c->Instance->CR1 &= ~(I2C_CR1_WUPEN);
|
||||
|
||||
__HAL_I2C_ENABLE(hi2c);
|
||||
|
||||
hi2c->State = HAL_I2C_STATE_READY;
|
||||
|
||||
/* Process Unlocked */
|
||||
__HAL_UNLOCK(hi2c);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
return HAL_BUSY;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup I2CEx_Exported_Functions_Group3 Fast Mode Plus Functions
|
||||
* @brief Fast Mode Plus Functions
|
||||
*
|
||||
@verbatim
|
||||
===============================================================================
|
||||
##### Fast Mode Plus Functions #####
|
||||
===============================================================================
|
||||
[..] This section provides functions allowing to:
|
||||
(+) Configure Fast Mode Plus
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Enable the I2C fast mode plus driving capability.
|
||||
* @param ConfigFastModePlus Selects the pin.
|
||||
* This parameter can be one of the @ref I2CEx_FastModePlus values
|
||||
* @note For I2C1, fast mode plus driving capability can be enabled on all selected
|
||||
* I2C1 pins using I2C_FASTMODEPLUS_I2C1 parameter or independently
|
||||
* on each one of the following pins PB6, PB7, PB8 and PB9.
|
||||
* @note For remaining I2C1 pins (PA14, PA15...) fast mode plus driving capability
|
||||
* can be enabled only by using I2C_FASTMODEPLUS_I2C1 parameter.
|
||||
* @note For all I2C2 pins fast mode plus driving capability can be enabled
|
||||
* only by using I2C_FASTMODEPLUS_I2C2 parameter.
|
||||
* @note For all I2C3 pins fast mode plus driving capability can be enabled
|
||||
* only by using I2C_FASTMODEPLUS_I2C3 parameter.
|
||||
* @note For all I2C4 pins fast mode plus driving capability can be enabled
|
||||
* only by using I2C_FASTMODEPLUS_I2C4 parameter.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_I2CEx_EnableFastModePlus(uint32_t ConfigFastModePlus)
|
||||
{
|
||||
/* Check the parameter */
|
||||
assert_param(IS_I2C_FASTMODEPLUS(ConfigFastModePlus));
|
||||
|
||||
/* Enable SYSCFG clock */
|
||||
__HAL_RCC_SYSCFG_CLK_ENABLE();
|
||||
|
||||
/* Enable fast mode plus driving capability for selected pin */
|
||||
SET_BIT(SYSCFG->CFGR1, (uint32_t)ConfigFastModePlus);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable the I2C fast mode plus driving capability.
|
||||
* @param ConfigFastModePlus Selects the pin.
|
||||
* This parameter can be one of the @ref I2CEx_FastModePlus values
|
||||
* @note For I2C1, fast mode plus driving capability can be disabled on all selected
|
||||
* I2C1 pins using I2C_FASTMODEPLUS_I2C1 parameter or independently
|
||||
* on each one of the following pins PB6, PB7, PB8 and PB9.
|
||||
* @note For remaining I2C1 pins (PA14, PA15...) fast mode plus driving capability
|
||||
* can be disabled only by using I2C_FASTMODEPLUS_I2C1 parameter.
|
||||
* @note For all I2C2 pins fast mode plus driving capability can be disabled
|
||||
* only by using I2C_FASTMODEPLUS_I2C2 parameter.
|
||||
* @note For all I2C3 pins fast mode plus driving capability can be disabled
|
||||
* only by using I2C_FASTMODEPLUS_I2C3 parameter.
|
||||
* @note For all I2C4 pins fast mode plus driving capability can be disabled
|
||||
* only by using I2C_FASTMODEPLUS_I2C4 parameter.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_I2CEx_DisableFastModePlus(uint32_t ConfigFastModePlus)
|
||||
{
|
||||
/* Check the parameter */
|
||||
assert_param(IS_I2C_FASTMODEPLUS(ConfigFastModePlus));
|
||||
|
||||
/* Enable SYSCFG clock */
|
||||
__HAL_RCC_SYSCFG_CLK_ENABLE();
|
||||
|
||||
/* Disable fast mode plus driving capability for selected pin */
|
||||
CLEAR_BIT(SYSCFG->CFGR1, (uint32_t)ConfigFastModePlus);
|
||||
}
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* HAL_I2C_MODULE_ENABLED */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
@@ -1,658 +0,0 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32l4xx_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
|
||||
*
|
||||
* Copyright (c) 2019 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32l4xx_hal.h"
|
||||
|
||||
/** @addtogroup STM32L4xx_HAL_Driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup PWR PWR
|
||||
* @brief PWR HAL module driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifdef HAL_PWR_MODULE_ENABLED
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
|
||||
/** @defgroup PWR_Private_Defines PWR Private Defines
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup PWR_PVD_Mode_Mask PWR PVD Mode Mask
|
||||
* @{
|
||||
*/
|
||||
#define PVD_MODE_IT ((uint32_t)0x00010000) /*!< Mask for interruption yielded by PVD threshold crossing */
|
||||
#define PVD_MODE_EVT ((uint32_t)0x00020000) /*!< Mask for event yielded by PVD threshold crossing */
|
||||
#define PVD_RISING_EDGE ((uint32_t)0x00000001) /*!< Mask for rising edge set as PVD trigger */
|
||||
#define PVD_FALLING_EDGE ((uint32_t)0x00000002) /*!< Mask for falling edge set as PVD trigger */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* Exported functions --------------------------------------------------------*/
|
||||
|
||||
/** @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 #####
|
||||
===============================================================================
|
||||
[..]
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Deinitialize the HAL 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 Enable access to the backup domain
|
||||
* (RTC registers, RTC backup data registers).
|
||||
* @note After reset, the backup domain is protected against
|
||||
* possible unwanted write accesses.
|
||||
* @note RTCSEL that sets the RTC clock source selection is in the RTC back-up domain.
|
||||
* In order to set or modify the RTC clock, the backup domain access must be
|
||||
* disabled.
|
||||
* @note LSEON bit that switches on and off the LSE crystal belongs as well to the
|
||||
* back-up domain.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_PWR_EnableBkUpAccess(void)
|
||||
{
|
||||
SET_BIT(PWR->CR1, PWR_CR1_DBP);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable access to the backup domain
|
||||
* (RTC registers, RTC backup data registers).
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_PWR_DisableBkUpAccess(void)
|
||||
{
|
||||
CLEAR_BIT(PWR->CR1, PWR_CR1_DBP);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/** @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 PWR_CR2 register).
|
||||
|
||||
(+) 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 pins are used to wakeup the system from Standby mode or Shutdown mode.
|
||||
The polarity of these pins can be set to configure event detection on high
|
||||
level (rising edge) or low level (falling edge).
|
||||
|
||||
|
||||
|
||||
*** Low Power modes configuration ***
|
||||
=====================================
|
||||
[..]
|
||||
The devices feature 8 low-power modes:
|
||||
(+) Low-power Run mode: core and peripherals are running, main regulator off, low power regulator on.
|
||||
(+) Sleep mode: Cortex-M4 core stopped, peripherals kept running, main and low power regulators on.
|
||||
(+) Low-power Sleep mode: Cortex-M4 core stopped, peripherals kept running, main regulator off, low power regulator on.
|
||||
(+) Stop 0 mode: all clocks are stopped except LSI and LSE, main and low power regulators on.
|
||||
(+) Stop 1 mode: all clocks are stopped except LSI and LSE, main regulator off, low power regulator on.
|
||||
(+) Stop 2 mode: all clocks are stopped except LSI and LSE, main regulator off, low power regulator on, reduced set of waking up IPs compared to Stop 1 mode.
|
||||
(+) Standby mode with SRAM2: all clocks are stopped except LSI and LSE, SRAM2 content preserved, main regulator off, low power regulator on.
|
||||
(+) Standby mode without SRAM2: all clocks are stopped except LSI and LSE, main and low power regulators off.
|
||||
(+) Shutdown mode: all clocks are stopped except LSE, main and low power regulators off.
|
||||
|
||||
|
||||
*** Low-power run mode ***
|
||||
==========================
|
||||
[..]
|
||||
(+) Entry: (from main run mode)
|
||||
(++) set LPR bit with HAL_PWREx_EnableLowPowerRunMode() API after having decreased the system clock below 2 MHz.
|
||||
|
||||
(+) Exit:
|
||||
(++) clear LPR bit then wait for REGLP bit to be reset with HAL_PWREx_DisableLowPowerRunMode() API. Only
|
||||
then can the system clock frequency be increased above 2 MHz.
|
||||
|
||||
|
||||
*** Sleep mode / Low-power sleep mode ***
|
||||
=========================================
|
||||
[..]
|
||||
(+) Entry:
|
||||
The Sleep mode / Low-power Sleep mode is entered through HAL_PWR_EnterSLEEPMode() API
|
||||
in specifying whether or not the regulator is forced to low-power mode and if exit is interrupt or event-triggered.
|
||||
(++) PWR_MAINREGULATOR_ON: Sleep mode (regulator in main mode).
|
||||
(++) PWR_LOWPOWERREGULATOR_ON: Low-power sleep (regulator in low power mode).
|
||||
In the latter case, the system clock frequency must have been decreased below 2 MHz beforehand.
|
||||
(++) PWR_SLEEPENTRY_WFI: enter SLEEP mode with WFI instruction
|
||||
(++) PWR_SLEEPENTRY_WFE: enter SLEEP mode with WFE instruction
|
||||
|
||||
(+) WFI Exit:
|
||||
(++) Any peripheral interrupt acknowledged by the nested vectored interrupt
|
||||
controller (NVIC) or any wake-up event.
|
||||
|
||||
(+) WFE Exit:
|
||||
(++) Any wake-up event such as an EXTI line configured in event mode.
|
||||
|
||||
[..] When exiting the Low-power sleep mode by issuing an interrupt or a wakeup event,
|
||||
the MCU is in Low-power Run mode.
|
||||
|
||||
*** Stop 0, Stop 1 and Stop 2 modes ***
|
||||
===============================
|
||||
[..]
|
||||
(+) Entry:
|
||||
The Stop 0, Stop 1 or Stop 2 modes are entered through the following API's:
|
||||
(++) HAL_PWREx_EnterSTOP0Mode() for mode 0 or HAL_PWREx_EnterSTOP1Mode() for mode 1 or for porting reasons HAL_PWR_EnterSTOPMode().
|
||||
(++) HAL_PWREx_EnterSTOP2Mode() for mode 2.
|
||||
(+) Regulator setting (applicable to HAL_PWR_EnterSTOPMode() only):
|
||||
(++) PWR_MAINREGULATOR_ON
|
||||
(++) PWR_LOWPOWERREGULATOR_ON
|
||||
(+) Exit (interrupt or event-triggered, specified when entering STOP mode):
|
||||
(++) PWR_STOPENTRY_WFI: enter Stop mode with WFI instruction
|
||||
(++) PWR_STOPENTRY_WFE: enter Stop mode with WFE instruction
|
||||
|
||||
(+) WFI Exit:
|
||||
(++) Any EXTI Line (Internal or External) configured in Interrupt mode.
|
||||
(++) Some specific communication peripherals (USART, LPUART, I2C) interrupts
|
||||
when programmed in wakeup mode.
|
||||
(+) WFE Exit:
|
||||
(++) Any EXTI Line (Internal or External) configured in Event mode.
|
||||
|
||||
[..]
|
||||
When exiting Stop 0 and Stop 1 modes, the MCU is either in Run mode or in Low-power Run mode
|
||||
depending on the LPR bit setting.
|
||||
When exiting Stop 2 mode, the MCU is in Run mode.
|
||||
|
||||
*** Standby mode ***
|
||||
====================
|
||||
[..]
|
||||
The Standby mode offers two options:
|
||||
(+) option a) all clocks off except LSI and LSE, RRS bit set (keeps voltage regulator in low power mode).
|
||||
SRAM and registers contents are lost except for the SRAM2 content, the RTC registers, RTC backup registers
|
||||
and Standby circuitry.
|
||||
(+) option b) all clocks off except LSI and LSE, RRS bit cleared (voltage regulator then disabled).
|
||||
SRAM and register contents are lost except for the RTC registers, RTC backup registers
|
||||
and Standby circuitry.
|
||||
|
||||
(++) Entry:
|
||||
(+++) The Standby mode is entered through HAL_PWR_EnterSTANDBYMode() API.
|
||||
SRAM1 and register contents are lost except for registers in the Backup domain and
|
||||
Standby circuitry. SRAM2 content can be preserved if the bit RRS is set in PWR_CR3 register.
|
||||
To enable this feature, the user can resort to HAL_PWREx_EnableSRAM2ContentRetention() API
|
||||
to set RRS bit.
|
||||
|
||||
(++) Exit:
|
||||
(+++) WKUP pin rising edge, RTC alarm or wakeup, tamper event, time-stamp event,
|
||||
external reset in NRST pin, IWDG reset.
|
||||
|
||||
[..] After waking up from Standby mode, program execution restarts in the same way as after a Reset.
|
||||
|
||||
|
||||
*** Shutdown mode ***
|
||||
======================
|
||||
[..]
|
||||
In Shutdown mode,
|
||||
voltage regulator is disabled, all clocks are off except LSE, RRS bit is cleared.
|
||||
SRAM and registers contents are lost except for backup domain registers.
|
||||
|
||||
(+) Entry:
|
||||
The Shutdown mode is entered through HAL_PWREx_EnterSHUTDOWNMode() API.
|
||||
|
||||
(+) Exit:
|
||||
(++) WKUP pin rising edge, RTC alarm or wakeup, tamper event, time-stamp event,
|
||||
external reset in NRST pin.
|
||||
|
||||
[..] After waking up from Shutdown mode, program execution restarts in the same way as after a Reset.
|
||||
|
||||
|
||||
*** Auto-wakeup (AWU) from low-power mode ***
|
||||
=============================================
|
||||
[..]
|
||||
The MCU can be woken up from low-power mode by an RTC Alarm event, an RTC
|
||||
Wakeup event, a tamper event or a time-stamp event, without depending on
|
||||
an external interrupt (Auto-wakeup mode).
|
||||
|
||||
(+) RTC auto-wakeup (AWU) from the Stop, Standby and Shutdown 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.
|
||||
|
||||
(++) To wake up from the Stop mode with an RTC Tamper or time stamp event, it
|
||||
is necessary to configure the RTC to detect the tamper or time stamp event using the
|
||||
HAL_RTCEx_SetTimeStamp_IT() or HAL_RTCEx_SetTamper_IT() functions.
|
||||
|
||||
(++) To wake up from the Stop mode with an RTC WakeUp event, it is necessary to
|
||||
configure the RTC to generate the RTC WakeUp event using the HAL_RTCEx_SetWakeUpTimer_IT() function.
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Configure the voltage threshold detected by the Power Voltage Detector (PVD).
|
||||
* @param sConfigPVD: pointer to a PWR_PVDTypeDef structure that contains the PVD
|
||||
* configuration information.
|
||||
* @note Refer to the electrical characteristics of your device datasheet for
|
||||
* more details about the voltage thresholds corresponding to each
|
||||
* detection level.
|
||||
* @retval None
|
||||
*/
|
||||
HAL_StatusTypeDef 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 bits according to PVDLevel value */
|
||||
MODIFY_REG(PWR->CR2, PWR_CR2_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();
|
||||
}
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Enable the Power Voltage Detector (PVD).
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_PWR_EnablePVD(void)
|
||||
{
|
||||
SET_BIT(PWR->CR2, PWR_CR2_PVDE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable the Power Voltage Detector (PVD).
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_PWR_DisablePVD(void)
|
||||
{
|
||||
CLEAR_BIT(PWR->CR2, PWR_CR2_PVDE);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Enable the WakeUp PINx functionality.
|
||||
* @param WakeUpPinPolarity: Specifies which Wake-Up pin to enable.
|
||||
* This parameter can be one of the following legacy values which set the default polarity
|
||||
* i.e. detection on high level (rising edge):
|
||||
* @arg @ref PWR_WAKEUP_PIN1, PWR_WAKEUP_PIN2, PWR_WAKEUP_PIN3, PWR_WAKEUP_PIN4, PWR_WAKEUP_PIN5
|
||||
*
|
||||
* or one of the following value where the user can explicitly specify the enabled pin and
|
||||
* the chosen polarity:
|
||||
* @arg @ref PWR_WAKEUP_PIN1_HIGH or PWR_WAKEUP_PIN1_LOW
|
||||
* @arg @ref PWR_WAKEUP_PIN2_HIGH or PWR_WAKEUP_PIN2_LOW
|
||||
* @arg @ref PWR_WAKEUP_PIN3_HIGH or PWR_WAKEUP_PIN3_LOW
|
||||
* @arg @ref PWR_WAKEUP_PIN4_HIGH or PWR_WAKEUP_PIN4_LOW
|
||||
* @arg @ref PWR_WAKEUP_PIN5_HIGH or PWR_WAKEUP_PIN5_LOW
|
||||
* @note PWR_WAKEUP_PINx and PWR_WAKEUP_PINx_HIGH are equivalent.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_PWR_EnableWakeUpPin(uint32_t WakeUpPinPolarity)
|
||||
{
|
||||
assert_param(IS_PWR_WAKEUP_PIN(WakeUpPinPolarity));
|
||||
|
||||
/* Specifies the Wake-Up pin polarity for the event detection
|
||||
(rising or falling edge) */
|
||||
MODIFY_REG(PWR->CR4, (PWR_CR3_EWUP & WakeUpPinPolarity), (WakeUpPinPolarity >> PWR_WUP_POLARITY_SHIFT));
|
||||
|
||||
/* Enable wake-up pin */
|
||||
SET_BIT(PWR->CR3, (PWR_CR3_EWUP & WakeUpPinPolarity));
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable the WakeUp PINx functionality.
|
||||
* @param WakeUpPinx: Specifies the Power Wake-Up pin to disable.
|
||||
* This parameter can be one of the following values:
|
||||
* @arg @ref PWR_WAKEUP_PIN1, PWR_WAKEUP_PIN2, PWR_WAKEUP_PIN3, PWR_WAKEUP_PIN4, PWR_WAKEUP_PIN5
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_PWR_DisableWakeUpPin(uint32_t WakeUpPinx)
|
||||
{
|
||||
assert_param(IS_PWR_WAKEUP_PIN(WakeUpPinx));
|
||||
|
||||
CLEAR_BIT(PWR->CR3, (PWR_CR3_EWUP & WakeUpPinx));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Enter Sleep or Low-power Sleep mode.
|
||||
* @note In Sleep/Low-power Sleep mode, all I/O pins keep the same state as in Run mode.
|
||||
* @param Regulator: Specifies the regulator state in Sleep/Low-power Sleep mode.
|
||||
* This parameter can be one of the following values:
|
||||
* @arg @ref PWR_MAINREGULATOR_ON Sleep mode (regulator in main mode)
|
||||
* @arg @ref PWR_LOWPOWERREGULATOR_ON Low-power Sleep mode (regulator in low-power mode)
|
||||
* @note Low-power Sleep mode is entered from Low-power Run mode. Therefore, if not yet
|
||||
* in Low-power Run mode before calling HAL_PWR_EnterSLEEPMode() with Regulator set
|
||||
* to PWR_LOWPOWERREGULATOR_ON, the user can optionally configure the
|
||||
* Flash in power-down monde in setting the SLEEP_PD bit in FLASH_ACR register.
|
||||
* Additionally, the clock frequency must be reduced below 2 MHz.
|
||||
* Setting SLEEP_PD in FLASH_ACR then appropriately reducing the clock frequency must
|
||||
* be done before calling HAL_PWR_EnterSLEEPMode() API.
|
||||
* @note When exiting Low-power Sleep mode, the MCU is in Low-power Run mode. To move in
|
||||
* Run mode, the user must resort to HAL_PWREx_DisableLowPowerRunMode() API.
|
||||
* @param SLEEPEntry: Specifies if Sleep mode is entered with WFI or WFE instruction.
|
||||
* This parameter can be one of the following values:
|
||||
* @arg @ref PWR_SLEEPENTRY_WFI enter Sleep or Low-power Sleep mode with WFI instruction
|
||||
* @arg @ref PWR_SLEEPENTRY_WFE enter Sleep or Low-power Sleep mode with WFE instruction
|
||||
* @note When WFI entry is used, tick interrupt have to be disabled if not desired as
|
||||
* the interrupt wake up source.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_PWR_EnterSLEEPMode(uint32_t Regulator, uint8_t SLEEPEntry)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_PWR_REGULATOR(Regulator));
|
||||
assert_param(IS_PWR_SLEEP_ENTRY(SLEEPEntry));
|
||||
|
||||
/* Set Regulator parameter */
|
||||
if (Regulator == PWR_MAINREGULATOR_ON)
|
||||
{
|
||||
/* If in low-power run mode at this point, exit it */
|
||||
if (HAL_IS_BIT_SET(PWR->SR2, PWR_SR2_REGLPF))
|
||||
{
|
||||
if (HAL_PWREx_DisableLowPowerRunMode() != HAL_OK)
|
||||
{
|
||||
return ;
|
||||
}
|
||||
}
|
||||
/* Regulator now in main mode. */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If in run mode, first move to low-power run mode.
|
||||
The system clock frequency must be below 2 MHz at this point. */
|
||||
if (HAL_IS_BIT_SET(PWR->SR2, PWR_SR2_REGLPF) == RESET)
|
||||
{
|
||||
HAL_PWREx_EnableLowPowerRunMode();
|
||||
}
|
||||
}
|
||||
|
||||
/* 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 Enter Stop mode
|
||||
* @note This API is named HAL_PWR_EnterSTOPMode to ensure compatibility with legacy code running
|
||||
* on devices where only "Stop mode" is mentioned with main or low power regulator ON.
|
||||
* @note In Stop mode, all I/O pins keep the same state as in Run mode.
|
||||
* @note All clocks in the VCORE domain are stopped; the PLL, the MSI,
|
||||
* the HSI and the HSE oscillators are disabled. Some peripherals with the wakeup capability
|
||||
* (I2Cx, USARTx and LPUART) can switch on the HSI to receive a frame, and switch off the HSI
|
||||
* after receiving the frame if it is not a wakeup frame. In this case, the HSI clock is propagated
|
||||
* only to the peripheral requesting it.
|
||||
* SRAM1, SRAM2 and register contents are preserved.
|
||||
* The BOR is available.
|
||||
* The voltage regulator can be configured either in normal (Stop 0) or low-power mode (Stop 1).
|
||||
* @note When exiting Stop 0 or Stop 1 mode by issuing an interrupt or a wakeup event,
|
||||
* the HSI RC oscillator is selected as system clock if STOPWUCK bit in RCC_CFGR register
|
||||
* is set; the MSI oscillator is selected if STOPWUCK is cleared.
|
||||
* @note When the voltage regulator operates in low power mode (Stop 1), an additional
|
||||
* startup delay is incurred when waking up.
|
||||
* By keeping the internal regulator ON during Stop mode (Stop 0), 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 @ref PWR_MAINREGULATOR_ON Stop 0 mode (main regulator ON)
|
||||
* @arg @ref PWR_LOWPOWERREGULATOR_ON Stop 1 mode (low power regulator ON)
|
||||
* @param STOPEntry: Specifies Stop 0 or Stop 1 mode is entered with WFI or WFE instruction.
|
||||
* This parameter can be one of the following values:
|
||||
* @arg @ref PWR_STOPENTRY_WFI Enter Stop 0 or Stop 1 mode with WFI instruction.
|
||||
* @arg @ref PWR_STOPENTRY_WFE Enter Stop 0 or Stop 1 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));
|
||||
|
||||
if(Regulator == PWR_LOWPOWERREGULATOR_ON)
|
||||
{
|
||||
HAL_PWREx_EnterSTOP1Mode(STOPEntry);
|
||||
}
|
||||
else
|
||||
{
|
||||
HAL_PWREx_EnterSTOP0Mode(STOPEntry);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enter Standby mode.
|
||||
* @note In Standby mode, the PLL, the HSI, the MSI and the HSE oscillators are switched
|
||||
* off. The voltage regulator is disabled, except when SRAM2 content is preserved
|
||||
* in which case the regulator is in low-power mode.
|
||||
* SRAM1 and register contents are lost except for registers in the Backup domain and
|
||||
* Standby circuitry. SRAM2 content can be preserved if the bit RRS is set in PWR_CR3 register.
|
||||
* To enable this feature, the user can resort to HAL_PWREx_EnableSRAM2ContentRetention() API
|
||||
* to set RRS bit.
|
||||
* The BOR is available.
|
||||
* @note The I/Os can be configured either with a pull-up or pull-down or can be kept in analog state.
|
||||
* HAL_PWREx_EnableGPIOPullUp() and HAL_PWREx_EnableGPIOPullDown() respectively enable Pull Up and
|
||||
* Pull Down state, HAL_PWREx_DisableGPIOPullUp() and HAL_PWREx_DisableGPIOPullDown() disable the
|
||||
* same.
|
||||
* These states are effective in Standby mode only if APC bit is set through
|
||||
* HAL_PWREx_EnablePullUpPullDownConfig() API.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_PWR_EnterSTANDBYMode(void)
|
||||
{
|
||||
/* Set Stand-by mode */
|
||||
MODIFY_REG(PWR->CR1, PWR_CR1_LPMS, PWR_CR1_LPMS_STANDBY);
|
||||
|
||||
/* 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 Indicate 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 Disable Sleep-On-Exit feature when returning from Handler mode to Thread mode.
|
||||
* @note Clear 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 Enable CORTEX M4 SEVONPEND bit.
|
||||
* @note Set 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 Disable CORTEX M4 SEVONPEND bit.
|
||||
* @note Clear 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 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 can be implemented in the user file
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* HAL_PWR_MODULE_ENABLED */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
@@ -1,1474 +0,0 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32l4xx_hal_pwr_ex.c
|
||||
* @author MCD Application Team
|
||||
* @brief Extended PWR HAL module driver.
|
||||
* This file provides firmware functions to manage the following
|
||||
* functionalities of the Power Controller (PWR) peripheral:
|
||||
* + Extended Initialization and de-initialization functions
|
||||
* + Extended Peripheral Control functions
|
||||
*
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2017 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32l4xx_hal.h"
|
||||
|
||||
/** @addtogroup STM32L4xx_HAL_Driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup PWREx PWREx
|
||||
* @brief PWR Extended HAL module driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifdef HAL_PWR_MODULE_ENABLED
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
|
||||
#if defined (STM32L412xx) || defined (STM32L422xx) || defined (STM32L431xx) || defined (STM32L432xx) || defined (STM32L433xx) || defined (STM32L442xx) || defined (STM32L443xx)
|
||||
#define PWR_PORTH_AVAILABLE_PINS ((uint32_t)0x0000000B) /* PH0/PH1/PH3 */
|
||||
#elif defined (STM32L451xx) || defined (STM32L452xx) || defined (STM32L462xx)
|
||||
#define PWR_PORTH_AVAILABLE_PINS ((uint32_t)0x0000000B) /* PH0/PH1/PH3 */
|
||||
#elif defined (STM32L471xx) || defined (STM32L475xx) || defined (STM32L476xx) || defined (STM32L485xx) || defined (STM32L486xx)
|
||||
#define PWR_PORTH_AVAILABLE_PINS ((uint32_t)0x00000003) /* PH0/PH1 */
|
||||
#elif defined (STM32L496xx) || defined (STM32L4A6xx) || defined (STM32L4P5xx) || defined (STM32L4Q5xx) || defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)
|
||||
#define PWR_PORTH_AVAILABLE_PINS ((uint32_t)0x0000FFFF) /* PH0..PH15 */
|
||||
#endif
|
||||
|
||||
#if defined (STM32L496xx) || defined (STM32L4A6xx) || defined (STM32L4P5xx) || defined (STM32L4Q5xx) || defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)
|
||||
#define PWR_PORTI_AVAILABLE_PINS ((uint32_t)0x00000FFF) /* PI0..PI11 */
|
||||
#endif
|
||||
|
||||
/** @defgroup PWR_Extended_Private_Defines PWR Extended Private Defines
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup PWREx_PVM_Mode_Mask PWR PVM Mode Mask
|
||||
* @{
|
||||
*/
|
||||
#define PVM_MODE_IT ((uint32_t)0x00010000) /*!< Mask for interruption yielded by PVM threshold crossing */
|
||||
#define PVM_MODE_EVT ((uint32_t)0x00020000) /*!< Mask for event yielded by PVM threshold crossing */
|
||||
#define PVM_RISING_EDGE ((uint32_t)0x00000001) /*!< Mask for rising edge set as PVM trigger */
|
||||
#define PVM_FALLING_EDGE ((uint32_t)0x00000002) /*!< Mask for falling edge set as PVM trigger */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup PWREx_TimeOut_Value PWR Extended Flag Setting Time Out Value
|
||||
* @{
|
||||
*/
|
||||
#define PWR_FLAG_SETTING_DELAY_US 50UL /*!< Time out value for REGLPF and VOSF flags setting */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* Exported functions --------------------------------------------------------*/
|
||||
|
||||
/** @defgroup PWREx_Exported_Functions PWR Extended Exported Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup PWREx_Exported_Functions_Group1 Extended Peripheral Control functions
|
||||
* @brief Extended Peripheral Control functions
|
||||
*
|
||||
@verbatim
|
||||
===============================================================================
|
||||
##### Extended Peripheral Initialization and de-initialization functions #####
|
||||
===============================================================================
|
||||
[..]
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief Return Voltage Scaling Range.
|
||||
* @retval VOS bit field (PWR_REGULATOR_VOLTAGE_SCALE1 or PWR_REGULATOR_VOLTAGE_SCALE2
|
||||
* or PWR_REGULATOR_VOLTAGE_SCALE1_BOOST when applicable)
|
||||
*/
|
||||
uint32_t HAL_PWREx_GetVoltageRange(void)
|
||||
{
|
||||
#if defined(PWR_CR5_R1MODE)
|
||||
if (READ_BIT(PWR->CR1, PWR_CR1_VOS) == PWR_REGULATOR_VOLTAGE_SCALE2)
|
||||
{
|
||||
return PWR_REGULATOR_VOLTAGE_SCALE2;
|
||||
}
|
||||
else if (READ_BIT(PWR->CR5, PWR_CR5_R1MODE) == PWR_CR5_R1MODE)
|
||||
{
|
||||
/* PWR_CR5_R1MODE bit set means that Range 1 Boost is disabled */
|
||||
return PWR_REGULATOR_VOLTAGE_SCALE1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return PWR_REGULATOR_VOLTAGE_SCALE1_BOOST;
|
||||
}
|
||||
#else
|
||||
return (PWR->CR1 & PWR_CR1_VOS);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Configure the main internal regulator output voltage.
|
||||
* @param VoltageScaling specifies the regulator output voltage to achieve
|
||||
* a tradeoff between performance and power consumption.
|
||||
* This parameter can be one of the following values:
|
||||
@if STM32L4S9xx
|
||||
* @arg @ref PWR_REGULATOR_VOLTAGE_SCALE1_BOOST when available, Regulator voltage output range 1 boost mode,
|
||||
* typical output voltage at 1.2 V,
|
||||
* system frequency up to 120 MHz.
|
||||
@endif
|
||||
* @arg @ref PWR_REGULATOR_VOLTAGE_SCALE1 Regulator voltage output range 1 mode,
|
||||
* typical output voltage at 1.2 V,
|
||||
* system frequency up to 80 MHz.
|
||||
* @arg @ref PWR_REGULATOR_VOLTAGE_SCALE2 Regulator voltage output range 2 mode,
|
||||
* typical output voltage at 1.0 V,
|
||||
* system frequency up to 26 MHz.
|
||||
* @note When moving from Range 1 to Range 2, the system frequency must be decreased to
|
||||
* a value below 26 MHz before calling HAL_PWREx_ControlVoltageScaling() API.
|
||||
* When moving from Range 2 to Range 1, the system frequency can be increased to
|
||||
* a value up to 80 MHz after calling HAL_PWREx_ControlVoltageScaling() API. For
|
||||
* some devices, the system frequency can be increased up to 120 MHz.
|
||||
* @note When moving from Range 2 to Range 1, the API waits for VOSF flag to be
|
||||
* cleared before returning the status. If the flag is not cleared within
|
||||
* 50 microseconds, HAL_TIMEOUT status is reported.
|
||||
* @retval HAL Status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_PWREx_ControlVoltageScaling(uint32_t VoltageScaling)
|
||||
{
|
||||
uint32_t wait_loop_index;
|
||||
|
||||
assert_param(IS_PWR_VOLTAGE_SCALING_RANGE(VoltageScaling));
|
||||
|
||||
#if defined(PWR_CR5_R1MODE)
|
||||
if (VoltageScaling == PWR_REGULATOR_VOLTAGE_SCALE1_BOOST)
|
||||
{
|
||||
/* If current range is range 2 */
|
||||
if (READ_BIT(PWR->CR1, PWR_CR1_VOS) == PWR_REGULATOR_VOLTAGE_SCALE2)
|
||||
{
|
||||
/* Make sure Range 1 Boost is enabled */
|
||||
CLEAR_BIT(PWR->CR5, PWR_CR5_R1MODE);
|
||||
|
||||
/* Set Range 1 */
|
||||
MODIFY_REG(PWR->CR1, PWR_CR1_VOS, PWR_REGULATOR_VOLTAGE_SCALE1);
|
||||
|
||||
/* Wait until VOSF is cleared */
|
||||
wait_loop_index = ((PWR_FLAG_SETTING_DELAY_US * SystemCoreClock) / 1000000U) + 1;
|
||||
while ((HAL_IS_BIT_SET(PWR->SR2, PWR_SR2_VOSF)) && (wait_loop_index != 0U))
|
||||
{
|
||||
wait_loop_index--;
|
||||
}
|
||||
if (HAL_IS_BIT_SET(PWR->SR2, PWR_SR2_VOSF))
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
/* If current range is range 1 normal or boost mode */
|
||||
else
|
||||
{
|
||||
/* Enable Range 1 Boost (no issue if bit already reset) */
|
||||
CLEAR_BIT(PWR->CR5, PWR_CR5_R1MODE);
|
||||
}
|
||||
}
|
||||
else if (VoltageScaling == PWR_REGULATOR_VOLTAGE_SCALE1)
|
||||
{
|
||||
/* If current range is range 2 */
|
||||
if (READ_BIT(PWR->CR1, PWR_CR1_VOS) == PWR_REGULATOR_VOLTAGE_SCALE2)
|
||||
{
|
||||
/* Make sure Range 1 Boost is disabled */
|
||||
SET_BIT(PWR->CR5, PWR_CR5_R1MODE);
|
||||
|
||||
/* Set Range 1 */
|
||||
MODIFY_REG(PWR->CR1, PWR_CR1_VOS, PWR_REGULATOR_VOLTAGE_SCALE1);
|
||||
|
||||
/* Wait until VOSF is cleared */
|
||||
wait_loop_index = ((PWR_FLAG_SETTING_DELAY_US * SystemCoreClock) / 1000000U) + 1;
|
||||
while ((HAL_IS_BIT_SET(PWR->SR2, PWR_SR2_VOSF)) && (wait_loop_index != 0U))
|
||||
{
|
||||
wait_loop_index--;
|
||||
}
|
||||
if (HAL_IS_BIT_SET(PWR->SR2, PWR_SR2_VOSF))
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
/* If current range is range 1 normal or boost mode */
|
||||
else
|
||||
{
|
||||
/* Disable Range 1 Boost (no issue if bit already set) */
|
||||
SET_BIT(PWR->CR5, PWR_CR5_R1MODE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Set Range 2 */
|
||||
MODIFY_REG(PWR->CR1, PWR_CR1_VOS, PWR_REGULATOR_VOLTAGE_SCALE2);
|
||||
/* No need to wait for VOSF to be cleared for this transition */
|
||||
/* PWR_CR5_R1MODE bit setting has no effect in Range 2 */
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* If Set Range 1 */
|
||||
if (VoltageScaling == PWR_REGULATOR_VOLTAGE_SCALE1)
|
||||
{
|
||||
if (READ_BIT(PWR->CR1, PWR_CR1_VOS) != PWR_REGULATOR_VOLTAGE_SCALE1)
|
||||
{
|
||||
/* Set Range 1 */
|
||||
MODIFY_REG(PWR->CR1, PWR_CR1_VOS, PWR_REGULATOR_VOLTAGE_SCALE1);
|
||||
|
||||
/* Wait until VOSF is cleared */
|
||||
wait_loop_index = ((PWR_FLAG_SETTING_DELAY_US * SystemCoreClock) / 1000000U) + 1U;
|
||||
while ((HAL_IS_BIT_SET(PWR->SR2, PWR_SR2_VOSF)) && (wait_loop_index != 0U))
|
||||
{
|
||||
wait_loop_index--;
|
||||
}
|
||||
if (HAL_IS_BIT_SET(PWR->SR2, PWR_SR2_VOSF))
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (READ_BIT(PWR->CR1, PWR_CR1_VOS) != PWR_REGULATOR_VOLTAGE_SCALE2)
|
||||
{
|
||||
/* Set Range 2 */
|
||||
MODIFY_REG(PWR->CR1, PWR_CR1_VOS, PWR_REGULATOR_VOLTAGE_SCALE2);
|
||||
/* No need to wait for VOSF to be cleared for this transition */
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Enable battery charging.
|
||||
* When VDD is present, charge the external battery on VBAT through an internal resistor.
|
||||
* @param ResistorSelection specifies the resistor impedance.
|
||||
* This parameter can be one of the following values:
|
||||
* @arg @ref PWR_BATTERY_CHARGING_RESISTOR_5 5 kOhms resistor
|
||||
* @arg @ref PWR_BATTERY_CHARGING_RESISTOR_1_5 1.5 kOhms resistor
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_PWREx_EnableBatteryCharging(uint32_t ResistorSelection)
|
||||
{
|
||||
assert_param(IS_PWR_BATTERY_RESISTOR_SELECT(ResistorSelection));
|
||||
|
||||
/* Specify resistor selection */
|
||||
MODIFY_REG(PWR->CR4, PWR_CR4_VBRS, ResistorSelection);
|
||||
|
||||
/* Enable battery charging */
|
||||
SET_BIT(PWR->CR4, PWR_CR4_VBE);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Disable battery charging.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_PWREx_DisableBatteryCharging(void)
|
||||
{
|
||||
CLEAR_BIT(PWR->CR4, PWR_CR4_VBE);
|
||||
}
|
||||
|
||||
|
||||
#if defined(PWR_CR2_USV)
|
||||
/**
|
||||
* @brief Enable VDDUSB supply.
|
||||
* @note Remove VDDUSB electrical and logical isolation, once VDDUSB supply is present.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_PWREx_EnableVddUSB(void)
|
||||
{
|
||||
SET_BIT(PWR->CR2, PWR_CR2_USV);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Disable VDDUSB supply.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_PWREx_DisableVddUSB(void)
|
||||
{
|
||||
CLEAR_BIT(PWR->CR2, PWR_CR2_USV);
|
||||
}
|
||||
#endif /* PWR_CR2_USV */
|
||||
|
||||
#if defined(PWR_CR2_IOSV)
|
||||
/**
|
||||
* @brief Enable VDDIO2 supply.
|
||||
* @note Remove VDDIO2 electrical and logical isolation, once VDDIO2 supply is present.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_PWREx_EnableVddIO2(void)
|
||||
{
|
||||
SET_BIT(PWR->CR2, PWR_CR2_IOSV);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Disable VDDIO2 supply.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_PWREx_DisableVddIO2(void)
|
||||
{
|
||||
CLEAR_BIT(PWR->CR2, PWR_CR2_IOSV);
|
||||
}
|
||||
#endif /* PWR_CR2_IOSV */
|
||||
|
||||
|
||||
/**
|
||||
* @brief Enable Internal Wake-up Line.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_PWREx_EnableInternalWakeUpLine(void)
|
||||
{
|
||||
SET_BIT(PWR->CR3, PWR_CR3_EIWF);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Disable Internal Wake-up Line.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_PWREx_DisableInternalWakeUpLine(void)
|
||||
{
|
||||
CLEAR_BIT(PWR->CR3, PWR_CR3_EIWF);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Enable GPIO pull-up state in Standby and Shutdown modes.
|
||||
* @note Set the relevant PUy bits of PWR_PUCRx register to configure the I/O in
|
||||
* pull-up state in Standby and Shutdown modes.
|
||||
* @note This state is effective in Standby and Shutdown modes only if APC bit
|
||||
* is set through HAL_PWREx_EnablePullUpPullDownConfig() API.
|
||||
* @note The configuration is lost when exiting the Shutdown mode due to the
|
||||
* power-on reset, maintained when exiting the Standby mode.
|
||||
* @note To avoid any conflict at Standby and Shutdown modes exits, the corresponding
|
||||
* PDy bit of PWR_PDCRx register is cleared unless it is reserved.
|
||||
* @note Even if a PUy bit to set is reserved, the other PUy bits entered as input
|
||||
* parameter at the same time are set.
|
||||
* @param GPIO Specify the IO port. This parameter can be PWR_GPIO_A, ..., PWR_GPIO_H
|
||||
* (or PWR_GPIO_I depending on the devices) to select the GPIO peripheral.
|
||||
* @param GPIONumber Specify the I/O pins numbers.
|
||||
* This parameter can be one of the following values:
|
||||
* PWR_GPIO_BIT_0, ..., PWR_GPIO_BIT_15 (except for the port where less
|
||||
* I/O pins are available) or the logical OR of several of them to set
|
||||
* several bits for a given port in a single API call.
|
||||
* @retval HAL Status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_PWREx_EnableGPIOPullUp(uint32_t GPIO, uint32_t GPIONumber)
|
||||
{
|
||||
HAL_StatusTypeDef status = HAL_OK;
|
||||
|
||||
assert_param(IS_PWR_GPIO(GPIO));
|
||||
assert_param(IS_PWR_GPIO_BIT_NUMBER(GPIONumber));
|
||||
|
||||
switch (GPIO)
|
||||
{
|
||||
case PWR_GPIO_A:
|
||||
SET_BIT(PWR->PUCRA, (GPIONumber & (~(PWR_GPIO_BIT_14))));
|
||||
CLEAR_BIT(PWR->PDCRA, (GPIONumber & (~(PWR_GPIO_BIT_13|PWR_GPIO_BIT_15))));
|
||||
break;
|
||||
case PWR_GPIO_B:
|
||||
SET_BIT(PWR->PUCRB, GPIONumber);
|
||||
CLEAR_BIT(PWR->PDCRB, (GPIONumber & (~(PWR_GPIO_BIT_4))));
|
||||
break;
|
||||
case PWR_GPIO_C:
|
||||
SET_BIT(PWR->PUCRC, GPIONumber);
|
||||
CLEAR_BIT(PWR->PDCRC, GPIONumber);
|
||||
break;
|
||||
#if defined(GPIOD)
|
||||
case PWR_GPIO_D:
|
||||
SET_BIT(PWR->PUCRD, GPIONumber);
|
||||
CLEAR_BIT(PWR->PDCRD, GPIONumber);
|
||||
break;
|
||||
#endif
|
||||
#if defined(GPIOE)
|
||||
case PWR_GPIO_E:
|
||||
SET_BIT(PWR->PUCRE, GPIONumber);
|
||||
CLEAR_BIT(PWR->PDCRE, GPIONumber);
|
||||
break;
|
||||
#endif
|
||||
#if defined(GPIOF)
|
||||
case PWR_GPIO_F:
|
||||
SET_BIT(PWR->PUCRF, GPIONumber);
|
||||
CLEAR_BIT(PWR->PDCRF, GPIONumber);
|
||||
break;
|
||||
#endif
|
||||
#if defined(GPIOG)
|
||||
case PWR_GPIO_G:
|
||||
SET_BIT(PWR->PUCRG, GPIONumber);
|
||||
CLEAR_BIT(PWR->PDCRG, GPIONumber);
|
||||
break;
|
||||
#endif
|
||||
case PWR_GPIO_H:
|
||||
SET_BIT(PWR->PUCRH, (GPIONumber & PWR_PORTH_AVAILABLE_PINS));
|
||||
#if defined (STM32L496xx) || defined (STM32L4A6xx)
|
||||
CLEAR_BIT(PWR->PDCRH, ((GPIONumber & PWR_PORTH_AVAILABLE_PINS) & (~(PWR_GPIO_BIT_3))));
|
||||
#else
|
||||
CLEAR_BIT(PWR->PDCRH, (GPIONumber & PWR_PORTH_AVAILABLE_PINS));
|
||||
#endif
|
||||
break;
|
||||
#if defined(GPIOI)
|
||||
case PWR_GPIO_I:
|
||||
SET_BIT(PWR->PUCRI, (GPIONumber & PWR_PORTI_AVAILABLE_PINS));
|
||||
CLEAR_BIT(PWR->PDCRI, (GPIONumber & PWR_PORTI_AVAILABLE_PINS));
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
status = HAL_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Disable GPIO pull-up state in Standby mode and Shutdown modes.
|
||||
* @note Reset the relevant PUy bits of PWR_PUCRx register used to configure the I/O
|
||||
* in pull-up state in Standby and Shutdown modes.
|
||||
* @note Even if a PUy bit to reset is reserved, the other PUy bits entered as input
|
||||
* parameter at the same time are reset.
|
||||
* @param GPIO Specifies the IO port. This parameter can be PWR_GPIO_A, ..., PWR_GPIO_H
|
||||
* (or PWR_GPIO_I depending on the devices) to select the GPIO peripheral.
|
||||
* @param GPIONumber Specify the I/O pins numbers.
|
||||
* This parameter can be one of the following values:
|
||||
* PWR_GPIO_BIT_0, ..., PWR_GPIO_BIT_15 (except for the port where less
|
||||
* I/O pins are available) or the logical OR of several of them to reset
|
||||
* several bits for a given port in a single API call.
|
||||
* @retval HAL Status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_PWREx_DisableGPIOPullUp(uint32_t GPIO, uint32_t GPIONumber)
|
||||
{
|
||||
HAL_StatusTypeDef status = HAL_OK;
|
||||
|
||||
assert_param(IS_PWR_GPIO(GPIO));
|
||||
assert_param(IS_PWR_GPIO_BIT_NUMBER(GPIONumber));
|
||||
|
||||
switch (GPIO)
|
||||
{
|
||||
case PWR_GPIO_A:
|
||||
CLEAR_BIT(PWR->PUCRA, (GPIONumber & (~(PWR_GPIO_BIT_14))));
|
||||
break;
|
||||
case PWR_GPIO_B:
|
||||
CLEAR_BIT(PWR->PUCRB, GPIONumber);
|
||||
break;
|
||||
case PWR_GPIO_C:
|
||||
CLEAR_BIT(PWR->PUCRC, GPIONumber);
|
||||
break;
|
||||
#if defined(GPIOD)
|
||||
case PWR_GPIO_D:
|
||||
CLEAR_BIT(PWR->PUCRD, GPIONumber);
|
||||
break;
|
||||
#endif
|
||||
#if defined(GPIOE)
|
||||
case PWR_GPIO_E:
|
||||
CLEAR_BIT(PWR->PUCRE, GPIONumber);
|
||||
break;
|
||||
#endif
|
||||
#if defined(GPIOF)
|
||||
case PWR_GPIO_F:
|
||||
CLEAR_BIT(PWR->PUCRF, GPIONumber);
|
||||
break;
|
||||
#endif
|
||||
#if defined(GPIOG)
|
||||
case PWR_GPIO_G:
|
||||
CLEAR_BIT(PWR->PUCRG, GPIONumber);
|
||||
break;
|
||||
#endif
|
||||
case PWR_GPIO_H:
|
||||
CLEAR_BIT(PWR->PUCRH, (GPIONumber & PWR_PORTH_AVAILABLE_PINS));
|
||||
break;
|
||||
#if defined(GPIOI)
|
||||
case PWR_GPIO_I:
|
||||
CLEAR_BIT(PWR->PUCRI, (GPIONumber & PWR_PORTI_AVAILABLE_PINS));
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
status = HAL_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Enable GPIO pull-down state in Standby and Shutdown modes.
|
||||
* @note Set the relevant PDy bits of PWR_PDCRx register to configure the I/O in
|
||||
* pull-down state in Standby and Shutdown modes.
|
||||
* @note This state is effective in Standby and Shutdown modes only if APC bit
|
||||
* is set through HAL_PWREx_EnablePullUpPullDownConfig() API.
|
||||
* @note The configuration is lost when exiting the Shutdown mode due to the
|
||||
* power-on reset, maintained when exiting the Standby mode.
|
||||
* @note To avoid any conflict at Standby and Shutdown modes exits, the corresponding
|
||||
* PUy bit of PWR_PUCRx register is cleared unless it is reserved.
|
||||
* @note Even if a PDy bit to set is reserved, the other PDy bits entered as input
|
||||
* parameter at the same time are set.
|
||||
* @param GPIO Specify the IO port. This parameter can be PWR_GPIO_A..PWR_GPIO_H
|
||||
* (or PWR_GPIO_I depending on the devices) to select the GPIO peripheral.
|
||||
* @param GPIONumber Specify the I/O pins numbers.
|
||||
* This parameter can be one of the following values:
|
||||
* PWR_GPIO_BIT_0, ..., PWR_GPIO_BIT_15 (except for the port where less
|
||||
* I/O pins are available) or the logical OR of several of them to set
|
||||
* several bits for a given port in a single API call.
|
||||
* @retval HAL Status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_PWREx_EnableGPIOPullDown(uint32_t GPIO, uint32_t GPIONumber)
|
||||
{
|
||||
HAL_StatusTypeDef status = HAL_OK;
|
||||
|
||||
assert_param(IS_PWR_GPIO(GPIO));
|
||||
assert_param(IS_PWR_GPIO_BIT_NUMBER(GPIONumber));
|
||||
|
||||
switch (GPIO)
|
||||
{
|
||||
case PWR_GPIO_A:
|
||||
SET_BIT(PWR->PDCRA, (GPIONumber & (~(PWR_GPIO_BIT_13|PWR_GPIO_BIT_15))));
|
||||
CLEAR_BIT(PWR->PUCRA, (GPIONumber & (~(PWR_GPIO_BIT_14))));
|
||||
break;
|
||||
case PWR_GPIO_B:
|
||||
SET_BIT(PWR->PDCRB, (GPIONumber & (~(PWR_GPIO_BIT_4))));
|
||||
CLEAR_BIT(PWR->PUCRB, GPIONumber);
|
||||
break;
|
||||
case PWR_GPIO_C:
|
||||
SET_BIT(PWR->PDCRC, GPIONumber);
|
||||
CLEAR_BIT(PWR->PUCRC, GPIONumber);
|
||||
break;
|
||||
#if defined(GPIOD)
|
||||
case PWR_GPIO_D:
|
||||
SET_BIT(PWR->PDCRD, GPIONumber);
|
||||
CLEAR_BIT(PWR->PUCRD, GPIONumber);
|
||||
break;
|
||||
#endif
|
||||
#if defined(GPIOE)
|
||||
case PWR_GPIO_E:
|
||||
SET_BIT(PWR->PDCRE, GPIONumber);
|
||||
CLEAR_BIT(PWR->PUCRE, GPIONumber);
|
||||
break;
|
||||
#endif
|
||||
#if defined(GPIOF)
|
||||
case PWR_GPIO_F:
|
||||
SET_BIT(PWR->PDCRF, GPIONumber);
|
||||
CLEAR_BIT(PWR->PUCRF, GPIONumber);
|
||||
break;
|
||||
#endif
|
||||
#if defined(GPIOG)
|
||||
case PWR_GPIO_G:
|
||||
SET_BIT(PWR->PDCRG, GPIONumber);
|
||||
CLEAR_BIT(PWR->PUCRG, GPIONumber);
|
||||
break;
|
||||
#endif
|
||||
case PWR_GPIO_H:
|
||||
#if defined (STM32L496xx) || defined (STM32L4A6xx)
|
||||
SET_BIT(PWR->PDCRH, ((GPIONumber & PWR_PORTH_AVAILABLE_PINS) & (~(PWR_GPIO_BIT_3))));
|
||||
#else
|
||||
SET_BIT(PWR->PDCRH, (GPIONumber & PWR_PORTH_AVAILABLE_PINS));
|
||||
#endif
|
||||
CLEAR_BIT(PWR->PUCRH, (GPIONumber & PWR_PORTH_AVAILABLE_PINS));
|
||||
break;
|
||||
#if defined(GPIOI)
|
||||
case PWR_GPIO_I:
|
||||
SET_BIT(PWR->PDCRI, (GPIONumber & PWR_PORTI_AVAILABLE_PINS));
|
||||
CLEAR_BIT(PWR->PUCRI, (GPIONumber & PWR_PORTI_AVAILABLE_PINS));
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
status = HAL_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Disable GPIO pull-down state in Standby and Shutdown modes.
|
||||
* @note Reset the relevant PDy bits of PWR_PDCRx register used to configure the I/O
|
||||
* in pull-down state in Standby and Shutdown modes.
|
||||
* @note Even if a PDy bit to reset is reserved, the other PDy bits entered as input
|
||||
* parameter at the same time are reset.
|
||||
* @param GPIO Specifies the IO port. This parameter can be PWR_GPIO_A..PWR_GPIO_H
|
||||
* (or PWR_GPIO_I depending on the devices) to select the GPIO peripheral.
|
||||
* @param GPIONumber Specify the I/O pins numbers.
|
||||
* This parameter can be one of the following values:
|
||||
* PWR_GPIO_BIT_0, ..., PWR_GPIO_BIT_15 (except for the port where less
|
||||
* I/O pins are available) or the logical OR of several of them to reset
|
||||
* several bits for a given port in a single API call.
|
||||
* @retval HAL Status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_PWREx_DisableGPIOPullDown(uint32_t GPIO, uint32_t GPIONumber)
|
||||
{
|
||||
HAL_StatusTypeDef status = HAL_OK;
|
||||
|
||||
assert_param(IS_PWR_GPIO(GPIO));
|
||||
assert_param(IS_PWR_GPIO_BIT_NUMBER(GPIONumber));
|
||||
|
||||
switch (GPIO)
|
||||
{
|
||||
case PWR_GPIO_A:
|
||||
CLEAR_BIT(PWR->PDCRA, (GPIONumber & (~(PWR_GPIO_BIT_13|PWR_GPIO_BIT_15))));
|
||||
break;
|
||||
case PWR_GPIO_B:
|
||||
CLEAR_BIT(PWR->PDCRB, (GPIONumber & (~(PWR_GPIO_BIT_4))));
|
||||
break;
|
||||
case PWR_GPIO_C:
|
||||
CLEAR_BIT(PWR->PDCRC, GPIONumber);
|
||||
break;
|
||||
#if defined(GPIOD)
|
||||
case PWR_GPIO_D:
|
||||
CLEAR_BIT(PWR->PDCRD, GPIONumber);
|
||||
break;
|
||||
#endif
|
||||
#if defined(GPIOE)
|
||||
case PWR_GPIO_E:
|
||||
CLEAR_BIT(PWR->PDCRE, GPIONumber);
|
||||
break;
|
||||
#endif
|
||||
#if defined(GPIOF)
|
||||
case PWR_GPIO_F:
|
||||
CLEAR_BIT(PWR->PDCRF, GPIONumber);
|
||||
break;
|
||||
#endif
|
||||
#if defined(GPIOG)
|
||||
case PWR_GPIO_G:
|
||||
CLEAR_BIT(PWR->PDCRG, GPIONumber);
|
||||
break;
|
||||
#endif
|
||||
case PWR_GPIO_H:
|
||||
#if defined (STM32L496xx) || defined (STM32L4A6xx)
|
||||
CLEAR_BIT(PWR->PDCRH, ((GPIONumber & PWR_PORTH_AVAILABLE_PINS) & (~(PWR_GPIO_BIT_3))));
|
||||
#else
|
||||
CLEAR_BIT(PWR->PDCRH, (GPIONumber & PWR_PORTH_AVAILABLE_PINS));
|
||||
#endif
|
||||
break;
|
||||
#if defined(GPIOI)
|
||||
case PWR_GPIO_I:
|
||||
CLEAR_BIT(PWR->PDCRI, (GPIONumber & PWR_PORTI_AVAILABLE_PINS));
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
status = HAL_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Enable pull-up and pull-down configuration.
|
||||
* @note When APC bit is set, the I/O pull-up and pull-down configurations defined in
|
||||
* PWR_PUCRx and PWR_PDCRx registers are applied in Standby and Shutdown modes.
|
||||
* @note Pull-up set by PUy bit of PWR_PUCRx register is not activated if the corresponding
|
||||
* PDy bit of PWR_PDCRx register is also set (pull-down configuration priority is higher).
|
||||
* HAL_PWREx_EnableGPIOPullUp() and HAL_PWREx_EnableGPIOPullDown() API's ensure there
|
||||
* is no conflict when setting PUy or PDy bit.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_PWREx_EnablePullUpPullDownConfig(void)
|
||||
{
|
||||
SET_BIT(PWR->CR3, PWR_CR3_APC);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Disable pull-up and pull-down configuration.
|
||||
* @note When APC bit is cleared, the I/O pull-up and pull-down configurations defined in
|
||||
* PWR_PUCRx and PWR_PDCRx registers are not applied in Standby and Shutdown modes.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_PWREx_DisablePullUpPullDownConfig(void)
|
||||
{
|
||||
CLEAR_BIT(PWR->CR3, PWR_CR3_APC);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Enable Full SRAM2 content retention in Standby mode.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_PWREx_EnableSRAM2ContentRetention(void)
|
||||
{
|
||||
(void) HAL_PWREx_SetSRAM2ContentRetention(PWR_FULL_SRAM2_RETENTION);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable SRAM2 content retention in Standby mode.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_PWREx_DisableSRAM2ContentRetention(void)
|
||||
{
|
||||
(void) HAL_PWREx_SetSRAM2ContentRetention(PWR_NO_SRAM2_RETENTION);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable SRAM2 content retention in Standby mode.
|
||||
* @param SRAM2Size: specifies the SRAM2 size kept in Standby mode
|
||||
* This parameter can be one of the following values:
|
||||
* @arg @ref PWR_NO_SRAM2_RETENTION SRAM2 is powered off in Standby mode (SRAM2 content is lost)
|
||||
* @arg @ref PWR_FULL_SRAM2_RETENTION Full SRAM2 is powered by the low-power regulator in Standby mode
|
||||
* @arg @ref PWR_4KBYTES_SRAM2_RETENTION Only 4 Kbytes of SRAM2 is powered by the low-power regulator in Standby mode
|
||||
* @note PWR_4KBYTES_SRAM2_RETENTION parameter is not available on all devices
|
||||
* @retval HAL Status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_PWREx_SetSRAM2ContentRetention(uint32_t SRAM2Size)
|
||||
{
|
||||
assert_param(IS_PWR_SRAM2_RETENTION(SRAM2Size));
|
||||
|
||||
if (SRAM2Size == PWR_NO_SRAM2_RETENTION)
|
||||
{
|
||||
CLEAR_BIT(PWR->CR3, PWR_CR3_RRS);
|
||||
}
|
||||
else if (SRAM2Size == PWR_FULL_SRAM2_RETENTION)
|
||||
{
|
||||
MODIFY_REG(PWR->CR3, PWR_CR3_RRS, PWR_FULL_SRAM2_RETENTION);
|
||||
}
|
||||
#if defined(PWR_CR3_RRS_1)
|
||||
else if (SRAM2Size == PWR_4KBYTES_SRAM2_RETENTION)
|
||||
{
|
||||
MODIFY_REG(PWR->CR3, PWR_CR3_RRS, PWR_4KBYTES_SRAM2_RETENTION);
|
||||
}
|
||||
#endif /* PWR_CR3_RRS_1 */
|
||||
else {
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
|
||||
#if defined(PWR_CR3_ENULP)
|
||||
/**
|
||||
* @brief Enable Ultra Low Power BORL, BORH and PVD for STOP2 and Standby modes.
|
||||
* @note All the other modes are not affected by this bit.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_PWREx_EnableBORPVD_ULP(void)
|
||||
{
|
||||
SET_BIT(PWR->CR3, PWR_CR3_ENULP);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Disable Ultra Low Power BORL, BORH and PVD for STOP2 and Standby modes.
|
||||
* @note All the other modes are not affected by this bit
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_PWREx_DisableBORPVD_ULP(void)
|
||||
{
|
||||
CLEAR_BIT(PWR->CR3, PWR_CR3_ENULP);
|
||||
}
|
||||
#endif /* PWR_CR3_ENULP */
|
||||
|
||||
|
||||
#if defined(PWR_CR4_EXT_SMPS_ON)
|
||||
/**
|
||||
* @brief Enable the CFLDO working @ 0.95V.
|
||||
* @note When external SMPS is used & CFLDO operating in Range 2, the regulated voltage of the
|
||||
* internal CFLDO can be reduced to 0.95V.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_PWREx_EnableExtSMPS_0V95(void)
|
||||
{
|
||||
SET_BIT(PWR->CR4, PWR_CR4_EXT_SMPS_ON);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable the CFLDO working @ 0.95V
|
||||
* @note Before SMPS is switched off, the regulated voltage of the
|
||||
* internal CFLDO shall be set to 1.00V.
|
||||
* 1.00V. is also default operating Range 2 voltage.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_PWREx_DisableExtSMPS_0V95(void)
|
||||
{
|
||||
CLEAR_BIT(PWR->CR4, PWR_CR4_EXT_SMPS_ON);
|
||||
}
|
||||
#endif /* PWR_CR4_EXT_SMPS_ON */
|
||||
|
||||
|
||||
#if defined(PWR_CR1_RRSTP)
|
||||
/**
|
||||
* @brief Enable SRAM3 content retention in Stop 2 mode.
|
||||
* @note When RRSTP bit is set, SRAM3 is powered by the low-power regulator in
|
||||
* Stop 2 mode and its content is kept.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_PWREx_EnableSRAM3ContentRetention(void)
|
||||
{
|
||||
SET_BIT(PWR->CR1, PWR_CR1_RRSTP);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Disable SRAM3 content retention in Stop 2 mode.
|
||||
* @note When RRSTP bit is reset, SRAM3 is powered off in Stop 2 mode
|
||||
* and its content is lost.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_PWREx_DisableSRAM3ContentRetention(void)
|
||||
{
|
||||
CLEAR_BIT(PWR->CR1, PWR_CR1_RRSTP);
|
||||
}
|
||||
#endif /* PWR_CR1_RRSTP */
|
||||
|
||||
#if defined(PWR_CR3_DSIPDEN)
|
||||
/**
|
||||
* @brief Enable pull-down activation on DSI pins.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_PWREx_EnableDSIPinsPDActivation(void)
|
||||
{
|
||||
SET_BIT(PWR->CR3, PWR_CR3_DSIPDEN);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Disable pull-down activation on DSI pins.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_PWREx_DisableDSIPinsPDActivation(void)
|
||||
{
|
||||
CLEAR_BIT(PWR->CR3, PWR_CR3_DSIPDEN);
|
||||
}
|
||||
#endif /* PWR_CR3_DSIPDEN */
|
||||
|
||||
#if defined(PWR_CR2_PVME1)
|
||||
/**
|
||||
* @brief Enable the Power Voltage Monitoring 1: VDDUSB versus 1.2V.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_PWREx_EnablePVM1(void)
|
||||
{
|
||||
SET_BIT(PWR->CR2, PWR_PVM_1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable the Power Voltage Monitoring 1: VDDUSB versus 1.2V.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_PWREx_DisablePVM1(void)
|
||||
{
|
||||
CLEAR_BIT(PWR->CR2, PWR_PVM_1);
|
||||
}
|
||||
#endif /* PWR_CR2_PVME1 */
|
||||
|
||||
|
||||
#if defined(PWR_CR2_PVME2)
|
||||
/**
|
||||
* @brief Enable the Power Voltage Monitoring 2: VDDIO2 versus 0.9V.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_PWREx_EnablePVM2(void)
|
||||
{
|
||||
SET_BIT(PWR->CR2, PWR_PVM_2);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable the Power Voltage Monitoring 2: VDDIO2 versus 0.9V.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_PWREx_DisablePVM2(void)
|
||||
{
|
||||
CLEAR_BIT(PWR->CR2, PWR_PVM_2);
|
||||
}
|
||||
#endif /* PWR_CR2_PVME2 */
|
||||
|
||||
|
||||
/**
|
||||
* @brief Enable the Power Voltage Monitoring 3: VDDA versus 1.62V.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_PWREx_EnablePVM3(void)
|
||||
{
|
||||
SET_BIT(PWR->CR2, PWR_PVM_3);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable the Power Voltage Monitoring 3: VDDA versus 1.62V.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_PWREx_DisablePVM3(void)
|
||||
{
|
||||
CLEAR_BIT(PWR->CR2, PWR_PVM_3);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Enable the Power Voltage Monitoring 4: VDDA versus 2.2V.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_PWREx_EnablePVM4(void)
|
||||
{
|
||||
SET_BIT(PWR->CR2, PWR_PVM_4);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable the Power Voltage Monitoring 4: VDDA versus 2.2V.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_PWREx_DisablePVM4(void)
|
||||
{
|
||||
CLEAR_BIT(PWR->CR2, PWR_PVM_4);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Configure the Peripheral Voltage Monitoring (PVM).
|
||||
* @param sConfigPVM: pointer to a PWR_PVMTypeDef structure that contains the
|
||||
* PVM configuration information.
|
||||
* @note The API configures a single PVM according to the information contained
|
||||
* in the input structure. To configure several PVMs, the API must be singly
|
||||
* called for each PVM used.
|
||||
* @note Refer to the electrical characteristics of your device datasheet for
|
||||
* more details about the voltage thresholds corresponding to each
|
||||
* detection level and to each monitored supply.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_PWREx_ConfigPVM(PWR_PVMTypeDef *sConfigPVM)
|
||||
{
|
||||
HAL_StatusTypeDef status = HAL_OK;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_PWR_PVM_TYPE(sConfigPVM->PVMType));
|
||||
assert_param(IS_PWR_PVM_MODE(sConfigPVM->Mode));
|
||||
|
||||
|
||||
/* Configure EXTI 35 to 38 interrupts if so required:
|
||||
scan through PVMType to detect which PVMx is set and
|
||||
configure the corresponding EXTI line accordingly. */
|
||||
switch (sConfigPVM->PVMType)
|
||||
{
|
||||
#if defined(PWR_CR2_PVME1)
|
||||
case PWR_PVM_1:
|
||||
/* Clear any previous config. Keep it clear if no event or IT mode is selected */
|
||||
__HAL_PWR_PVM1_EXTI_DISABLE_EVENT();
|
||||
__HAL_PWR_PVM1_EXTI_DISABLE_IT();
|
||||
__HAL_PWR_PVM1_EXTI_DISABLE_FALLING_EDGE();
|
||||
__HAL_PWR_PVM1_EXTI_DISABLE_RISING_EDGE();
|
||||
|
||||
/* Configure interrupt mode */
|
||||
if((sConfigPVM->Mode & PVM_MODE_IT) == PVM_MODE_IT)
|
||||
{
|
||||
__HAL_PWR_PVM1_EXTI_ENABLE_IT();
|
||||
}
|
||||
|
||||
/* Configure event mode */
|
||||
if((sConfigPVM->Mode & PVM_MODE_EVT) == PVM_MODE_EVT)
|
||||
{
|
||||
__HAL_PWR_PVM1_EXTI_ENABLE_EVENT();
|
||||
}
|
||||
|
||||
/* Configure the edge */
|
||||
if((sConfigPVM->Mode & PVM_RISING_EDGE) == PVM_RISING_EDGE)
|
||||
{
|
||||
__HAL_PWR_PVM1_EXTI_ENABLE_RISING_EDGE();
|
||||
}
|
||||
|
||||
if((sConfigPVM->Mode & PVM_FALLING_EDGE) == PVM_FALLING_EDGE)
|
||||
{
|
||||
__HAL_PWR_PVM1_EXTI_ENABLE_FALLING_EDGE();
|
||||
}
|
||||
break;
|
||||
#endif /* PWR_CR2_PVME1 */
|
||||
|
||||
#if defined(PWR_CR2_PVME2)
|
||||
case PWR_PVM_2:
|
||||
/* Clear any previous config. Keep it clear if no event or IT mode is selected */
|
||||
__HAL_PWR_PVM2_EXTI_DISABLE_EVENT();
|
||||
__HAL_PWR_PVM2_EXTI_DISABLE_IT();
|
||||
__HAL_PWR_PVM2_EXTI_DISABLE_FALLING_EDGE();
|
||||
__HAL_PWR_PVM2_EXTI_DISABLE_RISING_EDGE();
|
||||
|
||||
/* Configure interrupt mode */
|
||||
if((sConfigPVM->Mode & PVM_MODE_IT) == PVM_MODE_IT)
|
||||
{
|
||||
__HAL_PWR_PVM2_EXTI_ENABLE_IT();
|
||||
}
|
||||
|
||||
/* Configure event mode */
|
||||
if((sConfigPVM->Mode & PVM_MODE_EVT) == PVM_MODE_EVT)
|
||||
{
|
||||
__HAL_PWR_PVM2_EXTI_ENABLE_EVENT();
|
||||
}
|
||||
|
||||
/* Configure the edge */
|
||||
if((sConfigPVM->Mode & PVM_RISING_EDGE) == PVM_RISING_EDGE)
|
||||
{
|
||||
__HAL_PWR_PVM2_EXTI_ENABLE_RISING_EDGE();
|
||||
}
|
||||
|
||||
if((sConfigPVM->Mode & PVM_FALLING_EDGE) == PVM_FALLING_EDGE)
|
||||
{
|
||||
__HAL_PWR_PVM2_EXTI_ENABLE_FALLING_EDGE();
|
||||
}
|
||||
break;
|
||||
#endif /* PWR_CR2_PVME2 */
|
||||
|
||||
case PWR_PVM_3:
|
||||
/* Clear any previous config. Keep it clear if no event or IT mode is selected */
|
||||
__HAL_PWR_PVM3_EXTI_DISABLE_EVENT();
|
||||
__HAL_PWR_PVM3_EXTI_DISABLE_IT();
|
||||
__HAL_PWR_PVM3_EXTI_DISABLE_FALLING_EDGE();
|
||||
__HAL_PWR_PVM3_EXTI_DISABLE_RISING_EDGE();
|
||||
|
||||
/* Configure interrupt mode */
|
||||
if((sConfigPVM->Mode & PVM_MODE_IT) == PVM_MODE_IT)
|
||||
{
|
||||
__HAL_PWR_PVM3_EXTI_ENABLE_IT();
|
||||
}
|
||||
|
||||
/* Configure event mode */
|
||||
if((sConfigPVM->Mode & PVM_MODE_EVT) == PVM_MODE_EVT)
|
||||
{
|
||||
__HAL_PWR_PVM3_EXTI_ENABLE_EVENT();
|
||||
}
|
||||
|
||||
/* Configure the edge */
|
||||
if((sConfigPVM->Mode & PVM_RISING_EDGE) == PVM_RISING_EDGE)
|
||||
{
|
||||
__HAL_PWR_PVM3_EXTI_ENABLE_RISING_EDGE();
|
||||
}
|
||||
|
||||
if((sConfigPVM->Mode & PVM_FALLING_EDGE) == PVM_FALLING_EDGE)
|
||||
{
|
||||
__HAL_PWR_PVM3_EXTI_ENABLE_FALLING_EDGE();
|
||||
}
|
||||
break;
|
||||
|
||||
case PWR_PVM_4:
|
||||
/* Clear any previous config. Keep it clear if no event or IT mode is selected */
|
||||
__HAL_PWR_PVM4_EXTI_DISABLE_EVENT();
|
||||
__HAL_PWR_PVM4_EXTI_DISABLE_IT();
|
||||
__HAL_PWR_PVM4_EXTI_DISABLE_FALLING_EDGE();
|
||||
__HAL_PWR_PVM4_EXTI_DISABLE_RISING_EDGE();
|
||||
|
||||
/* Configure interrupt mode */
|
||||
if((sConfigPVM->Mode & PVM_MODE_IT) == PVM_MODE_IT)
|
||||
{
|
||||
__HAL_PWR_PVM4_EXTI_ENABLE_IT();
|
||||
}
|
||||
|
||||
/* Configure event mode */
|
||||
if((sConfigPVM->Mode & PVM_MODE_EVT) == PVM_MODE_EVT)
|
||||
{
|
||||
__HAL_PWR_PVM4_EXTI_ENABLE_EVENT();
|
||||
}
|
||||
|
||||
/* Configure the edge */
|
||||
if((sConfigPVM->Mode & PVM_RISING_EDGE) == PVM_RISING_EDGE)
|
||||
{
|
||||
__HAL_PWR_PVM4_EXTI_ENABLE_RISING_EDGE();
|
||||
}
|
||||
|
||||
if((sConfigPVM->Mode & PVM_FALLING_EDGE) == PVM_FALLING_EDGE)
|
||||
{
|
||||
__HAL_PWR_PVM4_EXTI_ENABLE_FALLING_EDGE();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
status = HAL_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Enter Low-power Run mode
|
||||
* @note In Low-power Run mode, all I/O pins keep the same state as in Run mode.
|
||||
* @note When Regulator is set to PWR_LOWPOWERREGULATOR_ON, the user can optionally configure the
|
||||
* Flash in power-down monde in setting the RUN_PD bit in FLASH_ACR register.
|
||||
* Additionally, the clock frequency must be reduced below 2 MHz.
|
||||
* Setting RUN_PD in FLASH_ACR then appropriately reducing the clock frequency must
|
||||
* be done before calling HAL_PWREx_EnableLowPowerRunMode() API.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_PWREx_EnableLowPowerRunMode(void)
|
||||
{
|
||||
/* Set Regulator parameter */
|
||||
SET_BIT(PWR->CR1, PWR_CR1_LPR);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Exit Low-power Run mode.
|
||||
* @note Before HAL_PWREx_DisableLowPowerRunMode() completion, the function checks that
|
||||
* REGLPF has been properly reset (otherwise, HAL_PWREx_DisableLowPowerRunMode
|
||||
* returns HAL_TIMEOUT status). The system clock frequency can then be
|
||||
* increased above 2 MHz.
|
||||
* @retval HAL Status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_PWREx_DisableLowPowerRunMode(void)
|
||||
{
|
||||
uint32_t wait_loop_index;
|
||||
|
||||
/* Clear LPR bit */
|
||||
CLEAR_BIT(PWR->CR1, PWR_CR1_LPR);
|
||||
|
||||
/* Wait until REGLPF is reset */
|
||||
wait_loop_index = ((PWR_FLAG_SETTING_DELAY_US * SystemCoreClock) / 1000000U) + 1U;
|
||||
while ((HAL_IS_BIT_SET(PWR->SR2, PWR_SR2_REGLPF)) && (wait_loop_index != 0U))
|
||||
{
|
||||
wait_loop_index--;
|
||||
}
|
||||
if (HAL_IS_BIT_SET(PWR->SR2, PWR_SR2_REGLPF))
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Enter Stop 0 mode.
|
||||
* @note In Stop 0 mode, main and low voltage regulators are ON.
|
||||
* @note In Stop 0 mode, all I/O pins keep the same state as in Run mode.
|
||||
* @note All clocks in the VCORE domain are stopped; the PLL, the MSI,
|
||||
* the HSI and the HSE oscillators are disabled. Some peripherals with the wakeup capability
|
||||
* (I2Cx, USARTx and LPUART) can switch on the HSI to receive a frame, and switch off the HSI
|
||||
* after receiving the frame if it is not a wakeup frame. In this case, the HSI clock is propagated
|
||||
* only to the peripheral requesting it.
|
||||
* SRAM1, SRAM2 and register contents are preserved.
|
||||
* The BOR is available.
|
||||
* @note When exiting Stop 0 mode by issuing an interrupt or a wakeup event,
|
||||
* the HSI RC oscillator is selected as system clock if STOPWUCK bit in RCC_CFGR register
|
||||
* is set; the MSI oscillator is selected if STOPWUCK is cleared.
|
||||
* @note By keeping the internal regulator ON during Stop 0 mode, the consumption
|
||||
* is higher although the startup time is reduced.
|
||||
* @param STOPEntry specifies if Stop mode in entered with WFI or WFE instruction.
|
||||
* This parameter can be one of the following values:
|
||||
* @arg @ref PWR_STOPENTRY_WFI Enter Stop mode with WFI instruction
|
||||
* @arg @ref PWR_STOPENTRY_WFE Enter Stop mode with WFE instruction
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_PWREx_EnterSTOP0Mode(uint8_t STOPEntry)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_PWR_STOP_ENTRY(STOPEntry));
|
||||
|
||||
/* Stop 0 mode with Main Regulator */
|
||||
MODIFY_REG(PWR->CR1, PWR_CR1_LPMS, PWR_CR1_LPMS_STOP0);
|
||||
|
||||
/* 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();
|
||||
__WFE();
|
||||
__WFE();
|
||||
}
|
||||
|
||||
/* Reset SLEEPDEEP bit of Cortex System Control Register */
|
||||
CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Enter Stop 1 mode.
|
||||
* @note In Stop 1 mode, only low power voltage regulator is ON.
|
||||
* @note In Stop 1 mode, all I/O pins keep the same state as in Run mode.
|
||||
* @note All clocks in the VCORE domain are stopped; the PLL, the MSI,
|
||||
* the HSI and the HSE oscillators are disabled. Some peripherals with the wakeup capability
|
||||
* (I2Cx, USARTx and LPUART) can switch on the HSI to receive a frame, and switch off the HSI
|
||||
* after receiving the frame if it is not a wakeup frame. In this case, the HSI clock is propagated
|
||||
* only to the peripheral requesting it.
|
||||
* SRAM1, SRAM2 and register contents are preserved.
|
||||
* The BOR is available.
|
||||
* @note When exiting Stop 1 mode by issuing an interrupt or a wakeup event,
|
||||
* the HSI RC oscillator is selected as system clock if STOPWUCK bit in RCC_CFGR register
|
||||
* is set; the MSI oscillator is selected if STOPWUCK is cleared.
|
||||
* @note Due to low power mode, an additional startup delay is incurred when waking up from Stop 1 mode.
|
||||
* @param STOPEntry specifies if Stop mode in entered with WFI or WFE instruction.
|
||||
* This parameter can be one of the following values:
|
||||
* @arg @ref PWR_STOPENTRY_WFI Enter Stop mode with WFI instruction
|
||||
* @arg @ref PWR_STOPENTRY_WFE Enter Stop mode with WFE instruction
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_PWREx_EnterSTOP1Mode(uint8_t STOPEntry)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_PWR_STOP_ENTRY(STOPEntry));
|
||||
|
||||
/* Stop 1 mode with Low-Power Regulator */
|
||||
MODIFY_REG(PWR->CR1, PWR_CR1_LPMS, PWR_CR1_LPMS_STOP1);
|
||||
|
||||
/* 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();
|
||||
__WFE();
|
||||
__WFE();
|
||||
}
|
||||
|
||||
/* Reset SLEEPDEEP bit of Cortex System Control Register */
|
||||
CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Enter Stop 2 mode.
|
||||
* @note In Stop 2 mode, only low power voltage regulator is ON.
|
||||
* @note In Stop 2 mode, all I/O pins keep the same state as in Run mode.
|
||||
* @note All clocks in the VCORE domain are stopped, the PLL, the MSI,
|
||||
* the HSI and the HSE oscillators are disabled. Some peripherals with wakeup capability
|
||||
* (LCD, LPTIM1, I2C3 and LPUART) can switch on the HSI to receive a frame, and switch off the HSI after
|
||||
* receiving the frame if it is not a wakeup frame. In this case the HSI clock is propagated only
|
||||
* to the peripheral requesting it.
|
||||
* SRAM1, SRAM2 and register contents are preserved.
|
||||
* SRAM3 content is preserved depending on RRSTP bit setting (not available on all devices).
|
||||
* The BOR is available.
|
||||
* The voltage regulator is set in low-power mode but LPR bit must be cleared to enter stop 2 mode.
|
||||
* Otherwise, Stop 1 mode is entered.
|
||||
* @note When exiting Stop 2 mode by issuing an interrupt or a wakeup event,
|
||||
* the HSI RC oscillator is selected as system clock if STOPWUCK bit in RCC_CFGR register
|
||||
* is set; the MSI oscillator is selected if STOPWUCK is cleared.
|
||||
* @param STOPEntry specifies if Stop mode in entered with WFI or WFE instruction.
|
||||
* This parameter can be one of the following values:
|
||||
* @arg @ref PWR_STOPENTRY_WFI Enter Stop mode with WFI instruction
|
||||
* @arg @ref PWR_STOPENTRY_WFE Enter Stop mode with WFE instruction
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_PWREx_EnterSTOP2Mode(uint8_t STOPEntry)
|
||||
{
|
||||
/* Check the parameter */
|
||||
assert_param(IS_PWR_STOP_ENTRY(STOPEntry));
|
||||
|
||||
/* Set Stop mode 2 */
|
||||
MODIFY_REG(PWR->CR1, PWR_CR1_LPMS, PWR_CR1_LPMS_STOP2);
|
||||
|
||||
/* 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();
|
||||
__WFE();
|
||||
__WFE();
|
||||
}
|
||||
|
||||
/* Reset SLEEPDEEP bit of Cortex System Control Register */
|
||||
CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Enter Shutdown mode.
|
||||
* @note In Shutdown mode, the PLL, the HSI, the MSI, the LSI and the HSE oscillators are switched
|
||||
* off. The voltage regulator is disabled and Vcore domain is powered off.
|
||||
* SRAM1, SRAM2 and registers contents are lost except for registers in the Backup domain.
|
||||
* The BOR is not available.
|
||||
* @note The I/Os can be configured either with a pull-up or pull-down or can be kept in analog state.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_PWREx_EnterSHUTDOWNMode(void)
|
||||
{
|
||||
|
||||
/* Set Shutdown mode */
|
||||
MODIFY_REG(PWR->CR1, PWR_CR1_LPMS, PWR_CR1_LPMS_SHUTDOWN);
|
||||
|
||||
/* 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 This function handles the PWR PVD/PVMx interrupt request.
|
||||
* @note This API should be called under the PVD_PVM_IRQHandler().
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_PWREx_PVD_PVM_IRQHandler(void)
|
||||
{
|
||||
/* Check PWR exti flag */
|
||||
if(__HAL_PWR_PVD_EXTI_GET_FLAG() != 0x0U)
|
||||
{
|
||||
/* PWR PVD interrupt user callback */
|
||||
HAL_PWR_PVDCallback();
|
||||
|
||||
/* Clear PVD exti pending bit */
|
||||
__HAL_PWR_PVD_EXTI_CLEAR_FLAG();
|
||||
}
|
||||
/* Next, successively check PVMx exti flags */
|
||||
#if defined(PWR_CR2_PVME1)
|
||||
if(__HAL_PWR_PVM1_EXTI_GET_FLAG() != 0x0U)
|
||||
{
|
||||
/* PWR PVM1 interrupt user callback */
|
||||
HAL_PWREx_PVM1Callback();
|
||||
|
||||
/* Clear PVM1 exti pending bit */
|
||||
__HAL_PWR_PVM1_EXTI_CLEAR_FLAG();
|
||||
}
|
||||
#endif /* PWR_CR2_PVME1 */
|
||||
#if defined(PWR_CR2_PVME2)
|
||||
if(__HAL_PWR_PVM2_EXTI_GET_FLAG() != 0x0U)
|
||||
{
|
||||
/* PWR PVM2 interrupt user callback */
|
||||
HAL_PWREx_PVM2Callback();
|
||||
|
||||
/* Clear PVM2 exti pending bit */
|
||||
__HAL_PWR_PVM2_EXTI_CLEAR_FLAG();
|
||||
}
|
||||
#endif /* PWR_CR2_PVME2 */
|
||||
if(__HAL_PWR_PVM3_EXTI_GET_FLAG() != 0x0U)
|
||||
{
|
||||
/* PWR PVM3 interrupt user callback */
|
||||
HAL_PWREx_PVM3Callback();
|
||||
|
||||
/* Clear PVM3 exti pending bit */
|
||||
__HAL_PWR_PVM3_EXTI_CLEAR_FLAG();
|
||||
}
|
||||
if(__HAL_PWR_PVM4_EXTI_GET_FLAG() != 0x0U)
|
||||
{
|
||||
/* PWR PVM4 interrupt user callback */
|
||||
HAL_PWREx_PVM4Callback();
|
||||
|
||||
/* Clear PVM4 exti pending bit */
|
||||
__HAL_PWR_PVM4_EXTI_CLEAR_FLAG();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if defined(PWR_CR2_PVME1)
|
||||
/**
|
||||
* @brief PWR PVM1 interrupt callback
|
||||
* @retval None
|
||||
*/
|
||||
__weak void HAL_PWREx_PVM1Callback(void)
|
||||
{
|
||||
/* NOTE : This function should not be modified; when the callback is needed,
|
||||
HAL_PWREx_PVM1Callback() API can be implemented in the user file
|
||||
*/
|
||||
}
|
||||
#endif /* PWR_CR2_PVME1 */
|
||||
|
||||
#if defined(PWR_CR2_PVME2)
|
||||
/**
|
||||
* @brief PWR PVM2 interrupt callback
|
||||
* @retval None
|
||||
*/
|
||||
__weak void HAL_PWREx_PVM2Callback(void)
|
||||
{
|
||||
/* NOTE : This function should not be modified; when the callback is needed,
|
||||
HAL_PWREx_PVM2Callback() API can be implemented in the user file
|
||||
*/
|
||||
}
|
||||
#endif /* PWR_CR2_PVME2 */
|
||||
|
||||
/**
|
||||
* @brief PWR PVM3 interrupt callback
|
||||
* @retval None
|
||||
*/
|
||||
__weak void HAL_PWREx_PVM3Callback(void)
|
||||
{
|
||||
/* NOTE : This function should not be modified; when the callback is needed,
|
||||
HAL_PWREx_PVM3Callback() API can be implemented in the user file
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief PWR PVM4 interrupt callback
|
||||
* @retval None
|
||||
*/
|
||||
__weak void HAL_PWREx_PVM4Callback(void)
|
||||
{
|
||||
/* NOTE : This function should not be modified; when the callback is needed,
|
||||
HAL_PWREx_PVM4Callback() API can be implemented in the user file
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* HAL_PWR_MODULE_ENABLED */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
@@ -1,1948 +0,0 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32l4xx_hal_rcc.c
|
||||
* @author MCD Application Team
|
||||
* @brief RCC HAL module driver.
|
||||
* This file provides firmware functions to manage the following
|
||||
* functionalities of the Reset and Clock Control (RCC) peripheral:
|
||||
* + Initialization and de-initialization functions
|
||||
* + Peripheral Control functions
|
||||
*
|
||||
@verbatim
|
||||
==============================================================================
|
||||
##### RCC specific features #####
|
||||
==============================================================================
|
||||
[..]
|
||||
After reset the device is running from Multiple Speed Internal oscillator
|
||||
(4 MHz) with Flash 0 wait state. Flash prefetch buffer, D-Cache
|
||||
and I-Cache are disabled, and all peripherals are off except internal
|
||||
SRAM, Flash and JTAG.
|
||||
|
||||
(+) There is no prescaler on High speed (AHBs) and Low speed (APBs) busses:
|
||||
all peripherals mapped on these busses are running at MSI speed.
|
||||
(+) The clock for all peripherals is switched off, except the SRAM and FLASH.
|
||||
(+) All GPIOs are in analog mode, except the JTAG pins which
|
||||
are assigned to be used for debug purpose.
|
||||
|
||||
[..]
|
||||
Once the device started from reset, the user application has to:
|
||||
(+) Configure the clock source to be used to drive the System clock
|
||||
(if the application needs higher frequency/performance)
|
||||
(+) Configure the System clock frequency and Flash settings
|
||||
(+) Configure the AHB and APB busses prescalers
|
||||
(+) Enable the clock for the peripheral(s) to be used
|
||||
(+) Configure the clock source(s) for peripherals which clocks are not
|
||||
derived from the System clock (SAIx, RTC, ADC, USB OTG FS/SDMMC1/RNG)
|
||||
|
||||
@endverbatim
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2017 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file in
|
||||
* the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32l4xx_hal.h"
|
||||
|
||||
/** @addtogroup STM32L4xx_HAL_Driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup RCC RCC
|
||||
* @brief RCC HAL module driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifdef HAL_RCC_MODULE_ENABLED
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/** @defgroup RCC_Private_Constants RCC Private Constants
|
||||
* @{
|
||||
*/
|
||||
#define HSE_TIMEOUT_VALUE HSE_STARTUP_TIMEOUT
|
||||
#define HSI_TIMEOUT_VALUE 2U /* 2 ms (minimum Tick + 1) */
|
||||
#define MSI_TIMEOUT_VALUE 2U /* 2 ms (minimum Tick + 1) */
|
||||
#if defined(RCC_CSR_LSIPREDIV)
|
||||
#define LSI_TIMEOUT_VALUE 17U /* 17 ms (16 ms starting time + 1) */
|
||||
#else
|
||||
#define LSI_TIMEOUT_VALUE 2U /* 2 ms (minimum Tick + 1) */
|
||||
#endif /* RCC_CSR_LSIPREDIV */
|
||||
#define HSI48_TIMEOUT_VALUE 2U /* 2 ms (minimum Tick + 1) */
|
||||
#define PLL_TIMEOUT_VALUE 2U /* 2 ms (minimum Tick + 1) */
|
||||
#define CLOCKSWITCH_TIMEOUT_VALUE 5000U /* 5 s */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/** @defgroup RCC_Private_Macros RCC Private Macros
|
||||
* @{
|
||||
*/
|
||||
#define __MCO1_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
|
||||
#define MCO1_GPIO_PORT GPIOA
|
||||
#define MCO1_PIN GPIO_PIN_8
|
||||
|
||||
#define RCC_PLL_OSCSOURCE_CONFIG(__HAL_RCC_PLLSOURCE__) \
|
||||
(MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC, (__HAL_RCC_PLLSOURCE__)))
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/** @defgroup RCC_Private_Functions RCC Private Functions
|
||||
* @{
|
||||
*/
|
||||
static HAL_StatusTypeDef RCC_SetFlashLatencyFromMSIRange(uint32_t msirange);
|
||||
#if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || \
|
||||
defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
|
||||
static uint32_t RCC_GetSysClockFreqFromPLLSource(void);
|
||||
#endif
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Exported functions --------------------------------------------------------*/
|
||||
|
||||
/** @defgroup RCC_Exported_Functions RCC Exported Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup RCC_Exported_Functions_Group1 Initialization and de-initialization functions
|
||||
* @brief Initialization and Configuration functions
|
||||
*
|
||||
@verbatim
|
||||
===============================================================================
|
||||
##### Initialization and de-initialization functions #####
|
||||
===============================================================================
|
||||
[..]
|
||||
This section provides functions allowing to configure the internal and external oscillators
|
||||
(HSE, HSI, LSE, MSI, LSI, PLL, CSS and MCO) and the System busses clocks (SYSCLK, AHB, APB1
|
||||
and APB2).
|
||||
|
||||
[..] Internal/external clock and PLL configuration
|
||||
(+) HSI (high-speed internal): 16 MHz factory-trimmed RC used directly or through
|
||||
the PLL as System clock source.
|
||||
|
||||
(+) MSI (Multiple Speed Internal): Its frequency is software trimmable from 100KHZ to 48MHZ.
|
||||
It can be used to generate the clock for the USB OTG FS (48 MHz).
|
||||
The number of flash wait states is automatically adjusted when MSI range is updated with
|
||||
HAL_RCC_OscConfig() and the MSI is used as System clock source.
|
||||
|
||||
(+) LSI (low-speed internal): 32 KHz low consumption RC used as IWDG and/or RTC
|
||||
clock source.
|
||||
|
||||
(+) HSE (high-speed external): 4 to 48 MHz crystal oscillator used directly or
|
||||
through the PLL as System clock source. Can be used also optionally as RTC clock source.
|
||||
|
||||
(+) LSE (low-speed external): 32.768 KHz oscillator used optionally as RTC clock source.
|
||||
|
||||
(+) PLL (clocked by HSI, HSE or MSI) providing up to three independent output clocks:
|
||||
(++) The first output is used to generate the high speed system clock (up to 80MHz).
|
||||
(++) The second output is used to generate the clock for the USB OTG FS (48 MHz),
|
||||
the random analog generator (<=48 MHz) and the SDMMC1 (<= 48 MHz).
|
||||
(++) The third output is used to generate an accurate clock to achieve
|
||||
high-quality audio performance on SAI interface.
|
||||
|
||||
(+) PLLSAI1 (clocked by HSI, HSE or MSI) providing up to three independent output clocks:
|
||||
(++) The first output is used to generate SAR ADC1 clock.
|
||||
(++) The second output is used to generate the clock for the USB OTG FS (48 MHz),
|
||||
the random analog generator (<=48 MHz) and the SDMMC1 (<= 48 MHz).
|
||||
(++) The third output is used to generate an accurate clock to achieve
|
||||
high-quality audio performance on SAI interface.
|
||||
|
||||
(+) PLLSAI2 (clocked by HSI, HSE or MSI) providing up to three independent output clocks:
|
||||
(++) The first output is used to generate an accurate clock to achieve
|
||||
high-quality audio performance on SAI interface.
|
||||
(++) The second output is used to generate either SAR ADC2 clock if ADC2 is present
|
||||
or LCD clock if LTDC is present.
|
||||
(++) The third output is used to generate DSI clock if DSI is present.
|
||||
|
||||
(+) CSS (Clock security system): once enabled, if a HSE clock failure occurs
|
||||
(HSE used directly or through PLL as System clock source), the System clock
|
||||
is automatically switched to HSI and an interrupt is generated if enabled.
|
||||
The interrupt is linked to the Cortex-M4 NMI (Non-Maskable Interrupt)
|
||||
exception vector.
|
||||
|
||||
(+) MCO (microcontroller clock output): used to output MSI, LSI, HSI, LSE, HSE or
|
||||
main PLL clock (through a configurable prescaler) on PA8 pin.
|
||||
|
||||
[..] System, AHB and APB busses clocks configuration
|
||||
(+) Several clock sources can be used to drive the System clock (SYSCLK): MSI, HSI,
|
||||
HSE and main PLL.
|
||||
The AHB clock (HCLK) is derived from System clock through configurable
|
||||
prescaler and used to clock the CPU, memory and peripherals mapped
|
||||
on AHB bus (DMA, GPIO...). APB1 (PCLK1) and APB2 (PCLK2) clocks are derived
|
||||
from AHB clock through configurable prescalers and used to clock
|
||||
the peripherals mapped on these busses. You can use
|
||||
"HAL_RCC_GetSysClockFreq()" function to retrieve the frequencies of these clocks.
|
||||
|
||||
-@- All the peripheral clocks are derived from the System clock (SYSCLK) except:
|
||||
|
||||
(+@) SAI: the SAI clock can be derived either from a specific PLL (PLLSAI1) or (PLLSAI2) or
|
||||
from an external clock mapped on the SAI_CKIN pin.
|
||||
You have to use HAL_RCCEx_PeriphCLKConfig() function to configure this clock.
|
||||
(+@) RTC: the RTC clock can be derived either from the LSI, LSE or HSE clock
|
||||
divided by 2 to 31.
|
||||
You have to use __HAL_RCC_RTC_ENABLE() and HAL_RCCEx_PeriphCLKConfig() function
|
||||
to configure this clock.
|
||||
(+@) USB OTG FS, SDMMC1 and RNG: USB OTG FS requires a frequency equal to 48 MHz
|
||||
to work correctly, while the SDMMC1 and RNG peripherals require a frequency
|
||||
equal or lower than to 48 MHz. This clock is derived of the main PLL or PLLSAI1
|
||||
through PLLQ divider. You have to enable the peripheral clock and use
|
||||
HAL_RCCEx_PeriphCLKConfig() function to configure this clock.
|
||||
(+@) IWDG clock which is always the LSI clock.
|
||||
|
||||
|
||||
(+) The maximum frequency of the SYSCLK, HCLK, PCLK1 and PCLK2 is 80 MHz.
|
||||
The clock source frequency should be adapted depending on the device voltage range
|
||||
as listed in the Reference Manual "Clock source frequency versus voltage scaling" chapter.
|
||||
|
||||
@endverbatim
|
||||
|
||||
Table 1. HCLK clock frequency for other STM32L4 devices
|
||||
+-------------------------------------------------------+
|
||||
| Latency | HCLK clock frequency (MHz) |
|
||||
| |-------------------------------------|
|
||||
| | voltage range 1 | voltage range 2 |
|
||||
| | 1.2 V | 1.0 V |
|
||||
|-----------------|------------------|------------------|
|
||||
|0WS(1 CPU cycles)| 0 < HCLK <= 16 | 0 < HCLK <= 6 |
|
||||
|-----------------|------------------|------------------|
|
||||
|1WS(2 CPU cycles)| 16 < HCLK <= 32 | 6 < HCLK <= 12 |
|
||||
|-----------------|------------------|------------------|
|
||||
|2WS(3 CPU cycles)| 32 < HCLK <= 48 | 12 < HCLK <= 18 |
|
||||
|-----------------|------------------|------------------|
|
||||
|3WS(4 CPU cycles)| 48 < HCLK <= 64 | 18 < HCLK <= 26 |
|
||||
|-----------------|------------------|------------------|
|
||||
|4WS(5 CPU cycles)| 64 < HCLK <= 80 | 18 < HCLK <= 26 |
|
||||
+-------------------------------------------------------+
|
||||
|
||||
Table 2. HCLK clock frequency for STM32L4+ devices
|
||||
+--------------------------------------------------------+
|
||||
| Latency | HCLK clock frequency (MHz) |
|
||||
| |--------------------------------------|
|
||||
| | voltage range 1 | voltage range 2 |
|
||||
| | 1.2 V | 1.0 V |
|
||||
|-----------------|-------------------|------------------|
|
||||
|0WS(1 CPU cycles)| 0 < HCLK <= 20 | 0 < HCLK <= 8 |
|
||||
|-----------------|-------------------|------------------|
|
||||
|1WS(2 CPU cycles)| 20 < HCLK <= 40 | 8 < HCLK <= 16 |
|
||||
|-----------------|-------------------|------------------|
|
||||
|2WS(3 CPU cycles)| 40 < HCLK <= 60 | 16 < HCLK <= 26 |
|
||||
|-----------------|-------------------|------------------|
|
||||
|3WS(4 CPU cycles)| 60 < HCLK <= 80 | 16 < HCLK <= 26 |
|
||||
|-----------------|-------------------|------------------|
|
||||
|4WS(5 CPU cycles)| 80 < HCLK <= 100 | 16 < HCLK <= 26 |
|
||||
|-----------------|-------------------|------------------|
|
||||
|5WS(6 CPU cycles)| 100 < HCLK <= 120 | 16 < HCLK <= 26 |
|
||||
+--------------------------------------------------------+
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Reset the RCC clock configuration to the default reset state.
|
||||
* @note The default reset state of the clock configuration is given below:
|
||||
* - MSI ON and used as system clock source
|
||||
* - HSE, HSI, PLL, PLLSAI1 and PLLSAI2 OFF
|
||||
* - AHB, APB1 and APB2 prescalers set to 1.
|
||||
* - CSS, MCO1 OFF
|
||||
* - All interrupts disabled
|
||||
* - All interrupt and reset flags cleared
|
||||
* @note This function does not modify the configuration of the
|
||||
* - Peripheral clock sources
|
||||
* - LSI, LSE and RTC clocks (Backup domain)
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_RCC_DeInit(void)
|
||||
{
|
||||
uint32_t tickstart;
|
||||
|
||||
/* Reset to default System clock */
|
||||
/* Set MSION bit */
|
||||
SET_BIT(RCC->CR, RCC_CR_MSION);
|
||||
|
||||
/* Insure MSIRDY bit is set before writing default MSIRANGE value */
|
||||
/* Get start tick */
|
||||
tickstart = HAL_GetTick();
|
||||
|
||||
/* Wait till MSI is ready */
|
||||
while(READ_BIT(RCC->CR, RCC_CR_MSIRDY) == 0U)
|
||||
{
|
||||
if((HAL_GetTick() - tickstart) > MSI_TIMEOUT_VALUE)
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set MSIRANGE default value */
|
||||
MODIFY_REG(RCC->CR, RCC_CR_MSIRANGE, RCC_MSIRANGE_6);
|
||||
|
||||
/* Reset CFGR register (MSI is selected as system clock source) */
|
||||
CLEAR_REG(RCC->CFGR);
|
||||
|
||||
/* Update the SystemCoreClock global variable for MSI as system clock source */
|
||||
SystemCoreClock = MSI_VALUE;
|
||||
|
||||
/* Configure the source of time base considering new system clock settings */
|
||||
if(HAL_InitTick(uwTickPrio) != HAL_OK)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Insure MSI selected as system clock source */
|
||||
/* Get start tick */
|
||||
tickstart = HAL_GetTick();
|
||||
|
||||
/* Wait till system clock source is ready */
|
||||
while(READ_BIT(RCC->CFGR, RCC_CFGR_SWS) != RCC_CFGR_SWS_MSI)
|
||||
{
|
||||
if((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
|
||||
/* Reset HSION, HSIKERON, HSIASFS, HSEON, HSECSSON, PLLON, PLLSAIxON bits */
|
||||
#if defined(RCC_PLLSAI2_SUPPORT)
|
||||
|
||||
CLEAR_BIT(RCC->CR, RCC_CR_HSEON | RCC_CR_HSION | RCC_CR_HSIKERON| RCC_CR_HSIASFS | RCC_CR_PLLON | RCC_CR_PLLSAI1ON | RCC_CR_PLLSAI2ON);
|
||||
|
||||
#elif defined(RCC_PLLSAI1_SUPPORT)
|
||||
|
||||
CLEAR_BIT(RCC->CR, RCC_CR_HSEON | RCC_CR_HSION | RCC_CR_HSIKERON| RCC_CR_HSIASFS | RCC_CR_PLLON | RCC_CR_PLLSAI1ON);
|
||||
|
||||
#else
|
||||
|
||||
CLEAR_BIT(RCC->CR, RCC_CR_HSEON | RCC_CR_HSION | RCC_CR_HSIKERON| RCC_CR_HSIASFS | RCC_CR_PLLON);
|
||||
|
||||
#endif /* RCC_PLLSAI2_SUPPORT */
|
||||
|
||||
/* Insure PLLRDY, PLLSAI1RDY and PLLSAI2RDY (if present) are reset */
|
||||
/* Get start tick */
|
||||
tickstart = HAL_GetTick();
|
||||
|
||||
#if defined(RCC_PLLSAI2_SUPPORT)
|
||||
|
||||
while(READ_BIT(RCC->CR, RCC_CR_PLLRDY | RCC_CR_PLLSAI1RDY | RCC_CR_PLLSAI2RDY) != 0U)
|
||||
|
||||
#elif defined(RCC_PLLSAI1_SUPPORT)
|
||||
|
||||
while(READ_BIT(RCC->CR, RCC_CR_PLLRDY | RCC_CR_PLLSAI1RDY) != 0U)
|
||||
|
||||
#else
|
||||
|
||||
while(READ_BIT(RCC->CR, RCC_CR_PLLRDY) != 0U)
|
||||
|
||||
#endif
|
||||
{
|
||||
if((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
|
||||
/* Reset PLLCFGR register */
|
||||
CLEAR_REG(RCC->PLLCFGR);
|
||||
SET_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN_4 );
|
||||
|
||||
#if defined(RCC_PLLSAI1_SUPPORT)
|
||||
|
||||
/* Reset PLLSAI1CFGR register */
|
||||
CLEAR_REG(RCC->PLLSAI1CFGR);
|
||||
SET_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1N_4 );
|
||||
|
||||
#endif /* RCC_PLLSAI1_SUPPORT */
|
||||
|
||||
#if defined(RCC_PLLSAI2_SUPPORT)
|
||||
|
||||
/* Reset PLLSAI2CFGR register */
|
||||
CLEAR_REG(RCC->PLLSAI2CFGR);
|
||||
SET_BIT(RCC->PLLSAI2CFGR, RCC_PLLSAI2CFGR_PLLSAI2N_4 );
|
||||
|
||||
#endif /* RCC_PLLSAI2_SUPPORT */
|
||||
|
||||
/* Reset HSEBYP bit */
|
||||
CLEAR_BIT(RCC->CR, RCC_CR_HSEBYP);
|
||||
|
||||
/* Disable all interrupts */
|
||||
CLEAR_REG(RCC->CIER);
|
||||
|
||||
/* Clear all interrupt flags */
|
||||
WRITE_REG(RCC->CICR, 0xFFFFFFFFU);
|
||||
|
||||
/* Clear all reset flags */
|
||||
SET_BIT(RCC->CSR, RCC_CSR_RMVF);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialize the RCC Oscillators according to the specified parameters in the
|
||||
* RCC_OscInitTypeDef.
|
||||
* @param RCC_OscInitStruct pointer to an RCC_OscInitTypeDef structure that
|
||||
* contains the configuration information for the RCC Oscillators.
|
||||
* @note The PLL is not disabled when used as system clock.
|
||||
* @note The PLL source is not updated when used as PLLSAI(s) clock source.
|
||||
* @note Transitions LSE Bypass to LSE On and LSE On to LSE Bypass are not
|
||||
* supported by this macro. User should request a transition to LSE Off
|
||||
* first and then LSE On or LSE Bypass.
|
||||
* @note Transition HSE Bypass to HSE On and HSE On to HSE Bypass are not
|
||||
* supported by this macro. User should request a transition to HSE Off
|
||||
* first and then HSE On or HSE Bypass.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct)
|
||||
{
|
||||
uint32_t tickstart;
|
||||
HAL_StatusTypeDef status;
|
||||
uint32_t sysclk_source, pll_config;
|
||||
|
||||
/* Check Null pointer */
|
||||
if(RCC_OscInitStruct == NULL)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_RCC_OSCILLATORTYPE(RCC_OscInitStruct->OscillatorType));
|
||||
|
||||
sysclk_source = __HAL_RCC_GET_SYSCLK_SOURCE();
|
||||
pll_config = __HAL_RCC_GET_PLL_OSCSOURCE();
|
||||
|
||||
/*----------------------------- MSI Configuration --------------------------*/
|
||||
if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_MSI) == RCC_OSCILLATORTYPE_MSI)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_RCC_MSI(RCC_OscInitStruct->MSIState));
|
||||
assert_param(IS_RCC_MSICALIBRATION_VALUE(RCC_OscInitStruct->MSICalibrationValue));
|
||||
assert_param(IS_RCC_MSI_CLOCK_RANGE(RCC_OscInitStruct->MSIClockRange));
|
||||
|
||||
/* Check if MSI is used as system clock or as PLL source when PLL is selected as system clock */
|
||||
if((sysclk_source == RCC_CFGR_SWS_MSI) ||
|
||||
((sysclk_source == RCC_CFGR_SWS_PLL) && (pll_config == RCC_PLLSOURCE_MSI)))
|
||||
{
|
||||
if((READ_BIT(RCC->CR, RCC_CR_MSIRDY) != 0U) && (RCC_OscInitStruct->MSIState == RCC_MSI_OFF))
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Otherwise, just the calibration and MSI range change are allowed */
|
||||
else
|
||||
{
|
||||
/* To correctly read data from FLASH memory, the number of wait states (LATENCY)
|
||||
must be correctly programmed according to the frequency of the CPU clock
|
||||
(HCLK) and the supply voltage of the device. */
|
||||
if(RCC_OscInitStruct->MSIClockRange > __HAL_RCC_GET_MSI_RANGE())
|
||||
{
|
||||
/* First increase number of wait states update if necessary */
|
||||
if(RCC_SetFlashLatencyFromMSIRange(RCC_OscInitStruct->MSIClockRange) != HAL_OK)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Selects the Multiple Speed oscillator (MSI) clock range .*/
|
||||
__HAL_RCC_MSI_RANGE_CONFIG(RCC_OscInitStruct->MSIClockRange);
|
||||
/* Adjusts the Multiple Speed oscillator (MSI) calibration value.*/
|
||||
__HAL_RCC_MSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->MSICalibrationValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Else, keep current flash latency while decreasing applies */
|
||||
/* Selects the Multiple Speed oscillator (MSI) clock range .*/
|
||||
__HAL_RCC_MSI_RANGE_CONFIG(RCC_OscInitStruct->MSIClockRange);
|
||||
/* Adjusts the Multiple Speed oscillator (MSI) calibration value.*/
|
||||
__HAL_RCC_MSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->MSICalibrationValue);
|
||||
|
||||
/* Decrease number of wait states update if necessary */
|
||||
/* Only possible when MSI is the System clock source */
|
||||
if(sysclk_source == RCC_CFGR_SWS_MSI)
|
||||
{
|
||||
if(RCC_SetFlashLatencyFromMSIRange(RCC_OscInitStruct->MSIClockRange) != HAL_OK)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Update the SystemCoreClock global variable */
|
||||
SystemCoreClock = HAL_RCC_GetSysClockFreq() >> (AHBPrescTable[READ_BIT(RCC->CFGR, RCC_CFGR_HPRE) >> RCC_CFGR_HPRE_Pos] & 0x1FU);
|
||||
|
||||
/* Configure the source of time base considering new system clocks settings*/
|
||||
status = HAL_InitTick(uwTickPrio);
|
||||
if(status != HAL_OK)
|
||||
{
|
||||
return status;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Check the MSI State */
|
||||
if(RCC_OscInitStruct->MSIState != RCC_MSI_OFF)
|
||||
{
|
||||
/* Enable the Internal High Speed oscillator (MSI). */
|
||||
__HAL_RCC_MSI_ENABLE();
|
||||
|
||||
/* Get timeout */
|
||||
tickstart = HAL_GetTick();
|
||||
|
||||
/* Wait till MSI is ready */
|
||||
while(READ_BIT(RCC->CR, RCC_CR_MSIRDY) == 0U)
|
||||
{
|
||||
if((HAL_GetTick() - tickstart) > MSI_TIMEOUT_VALUE)
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
/* Selects the Multiple Speed oscillator (MSI) clock range .*/
|
||||
__HAL_RCC_MSI_RANGE_CONFIG(RCC_OscInitStruct->MSIClockRange);
|
||||
/* Adjusts the Multiple Speed oscillator (MSI) calibration value.*/
|
||||
__HAL_RCC_MSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->MSICalibrationValue);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Disable the Internal High Speed oscillator (MSI). */
|
||||
__HAL_RCC_MSI_DISABLE();
|
||||
|
||||
/* Get timeout */
|
||||
tickstart = HAL_GetTick();
|
||||
|
||||
/* Wait till MSI is ready */
|
||||
while(READ_BIT(RCC->CR, RCC_CR_MSIRDY) != 0U)
|
||||
{
|
||||
if((HAL_GetTick() - tickstart) > MSI_TIMEOUT_VALUE)
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/*------------------------------- HSE Configuration ------------------------*/
|
||||
if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSE) == RCC_OSCILLATORTYPE_HSE)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_RCC_HSE(RCC_OscInitStruct->HSEState));
|
||||
|
||||
/* When the HSE is used as system clock or clock source for PLL in these cases it is not allowed to be disabled */
|
||||
if((sysclk_source == RCC_CFGR_SWS_HSE) ||
|
||||
((sysclk_source == RCC_CFGR_SWS_PLL) && (pll_config == RCC_PLLSOURCE_HSE)))
|
||||
{
|
||||
if((READ_BIT(RCC->CR, RCC_CR_HSERDY) != 0U) && (RCC_OscInitStruct->HSEState == RCC_HSE_OFF))
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Set the new HSE configuration ---------------------------------------*/
|
||||
__HAL_RCC_HSE_CONFIG(RCC_OscInitStruct->HSEState);
|
||||
|
||||
/* Check the HSE State */
|
||||
if(RCC_OscInitStruct->HSEState != RCC_HSE_OFF)
|
||||
{
|
||||
/* Get Start Tick*/
|
||||
tickstart = HAL_GetTick();
|
||||
|
||||
/* Wait till HSE is ready */
|
||||
while(READ_BIT(RCC->CR, RCC_CR_HSERDY) == 0U)
|
||||
{
|
||||
if((HAL_GetTick() - tickstart) > HSE_TIMEOUT_VALUE)
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Get Start Tick*/
|
||||
tickstart = HAL_GetTick();
|
||||
|
||||
/* Wait till HSE is disabled */
|
||||
while(READ_BIT(RCC->CR, RCC_CR_HSERDY) != 0U)
|
||||
{
|
||||
if((HAL_GetTick() - tickstart) > HSE_TIMEOUT_VALUE)
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/*----------------------------- HSI Configuration --------------------------*/
|
||||
if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI) == RCC_OSCILLATORTYPE_HSI)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_RCC_HSI(RCC_OscInitStruct->HSIState));
|
||||
assert_param(IS_RCC_HSI_CALIBRATION_VALUE(RCC_OscInitStruct->HSICalibrationValue));
|
||||
|
||||
/* Check if HSI is used as system clock or as PLL source when PLL is selected as system clock */
|
||||
if((sysclk_source == RCC_CFGR_SWS_HSI) ||
|
||||
((sysclk_source == RCC_CFGR_SWS_PLL) && (pll_config == RCC_PLLSOURCE_HSI)))
|
||||
{
|
||||
/* When HSI is used as system clock it will not be disabled */
|
||||
if((READ_BIT(RCC->CR, RCC_CR_HSIRDY) != 0U) && (RCC_OscInitStruct->HSIState == RCC_HSI_OFF))
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
/* Otherwise, just the calibration is allowed */
|
||||
else
|
||||
{
|
||||
/* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/
|
||||
__HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Check the HSI State */
|
||||
if(RCC_OscInitStruct->HSIState != RCC_HSI_OFF)
|
||||
{
|
||||
/* Enable the Internal High Speed oscillator (HSI). */
|
||||
__HAL_RCC_HSI_ENABLE();
|
||||
|
||||
/* Get Start Tick*/
|
||||
tickstart = HAL_GetTick();
|
||||
|
||||
/* Wait till HSI is ready */
|
||||
while(READ_BIT(RCC->CR, RCC_CR_HSIRDY) == 0U)
|
||||
{
|
||||
if((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE)
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
|
||||
/* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/
|
||||
__HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Disable the Internal High Speed oscillator (HSI). */
|
||||
__HAL_RCC_HSI_DISABLE();
|
||||
|
||||
/* Get Start Tick*/
|
||||
tickstart = HAL_GetTick();
|
||||
|
||||
/* Wait till HSI is disabled */
|
||||
while(READ_BIT(RCC->CR, RCC_CR_HSIRDY) != 0U)
|
||||
{
|
||||
if((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE)
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/*------------------------------ LSI Configuration -------------------------*/
|
||||
if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSI) == RCC_OSCILLATORTYPE_LSI)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_RCC_LSI(RCC_OscInitStruct->LSIState));
|
||||
|
||||
/* Check the LSI State */
|
||||
if(RCC_OscInitStruct->LSIState != RCC_LSI_OFF)
|
||||
{
|
||||
#if defined(RCC_CSR_LSIPREDIV)
|
||||
uint32_t csr_temp = RCC->CSR;
|
||||
|
||||
/* Check LSI division factor */
|
||||
assert_param(IS_RCC_LSIDIV(RCC_OscInitStruct->LSIDiv));
|
||||
|
||||
if (RCC_OscInitStruct->LSIDiv != (csr_temp & RCC_CSR_LSIPREDIV))
|
||||
{
|
||||
if (((csr_temp & RCC_CSR_LSIRDY) == RCC_CSR_LSIRDY) && \
|
||||
((csr_temp & RCC_CSR_LSION) != RCC_CSR_LSION))
|
||||
{
|
||||
/* If LSIRDY is set while LSION is not enabled,
|
||||
LSIPREDIV can't be updated */
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Turn off LSI before changing RCC_CSR_LSIPREDIV */
|
||||
if ((csr_temp & RCC_CSR_LSION) == RCC_CSR_LSION)
|
||||
{
|
||||
__HAL_RCC_LSI_DISABLE();
|
||||
|
||||
/* Get Start Tick*/
|
||||
tickstart = HAL_GetTick();
|
||||
|
||||
/* Wait till LSI is disabled */
|
||||
while(READ_BIT(RCC->CSR, RCC_CSR_LSIRDY) != 0U)
|
||||
{
|
||||
if((HAL_GetTick() - tickstart) > LSI_TIMEOUT_VALUE)
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Set LSI division factor */
|
||||
MODIFY_REG(RCC->CSR, RCC_CSR_LSIPREDIV, RCC_OscInitStruct->LSIDiv);
|
||||
}
|
||||
#endif /* RCC_CSR_LSIPREDIV */
|
||||
|
||||
/* Enable the Internal Low Speed oscillator (LSI). */
|
||||
__HAL_RCC_LSI_ENABLE();
|
||||
|
||||
/* Get Start Tick*/
|
||||
tickstart = HAL_GetTick();
|
||||
|
||||
/* Wait till LSI is ready */
|
||||
while(READ_BIT(RCC->CSR, RCC_CSR_LSIRDY) == 0U)
|
||||
{
|
||||
if((HAL_GetTick() - tickstart) > LSI_TIMEOUT_VALUE)
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Disable the Internal Low Speed oscillator (LSI). */
|
||||
__HAL_RCC_LSI_DISABLE();
|
||||
|
||||
/* Get Start Tick*/
|
||||
tickstart = HAL_GetTick();
|
||||
|
||||
/* Wait till LSI is disabled */
|
||||
while(READ_BIT(RCC->CSR, RCC_CSR_LSIRDY) != 0U)
|
||||
{
|
||||
if((HAL_GetTick() - tickstart) > LSI_TIMEOUT_VALUE)
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/*------------------------------ LSE Configuration -------------------------*/
|
||||
if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSE) == RCC_OSCILLATORTYPE_LSE)
|
||||
{
|
||||
FlagStatus pwrclkchanged = RESET;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_RCC_LSE(RCC_OscInitStruct->LSEState));
|
||||
|
||||
/* Update LSE configuration in Backup Domain control register */
|
||||
/* Requires to enable write access to Backup Domain of necessary */
|
||||
if(HAL_IS_BIT_CLR(RCC->APB1ENR1, RCC_APB1ENR1_PWREN))
|
||||
{
|
||||
__HAL_RCC_PWR_CLK_ENABLE();
|
||||
pwrclkchanged = SET;
|
||||
}
|
||||
|
||||
if(HAL_IS_BIT_CLR(PWR->CR1, PWR_CR1_DBP))
|
||||
{
|
||||
/* Enable write access to Backup domain */
|
||||
SET_BIT(PWR->CR1, PWR_CR1_DBP);
|
||||
|
||||
/* Wait for Backup domain Write protection disable */
|
||||
tickstart = HAL_GetTick();
|
||||
|
||||
while(HAL_IS_BIT_CLR(PWR->CR1, PWR_CR1_DBP))
|
||||
{
|
||||
if((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE)
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Set the new LSE configuration -----------------------------------------*/
|
||||
#if defined(RCC_BDCR_LSESYSDIS)
|
||||
if((RCC_OscInitStruct->LSEState & RCC_BDCR_LSEON) != 0U)
|
||||
{
|
||||
/* Set LSESYSDIS bit according to LSE propagation option (enabled or disabled) */
|
||||
MODIFY_REG(RCC->BDCR, RCC_BDCR_LSESYSDIS, (RCC_OscInitStruct->LSEState & RCC_BDCR_LSESYSDIS));
|
||||
|
||||
if((RCC_OscInitStruct->LSEState & RCC_BDCR_LSEBYP) != 0U)
|
||||
{
|
||||
/* LSE oscillator bypass enable */
|
||||
SET_BIT(RCC->BDCR, RCC_BDCR_LSEBYP);
|
||||
SET_BIT(RCC->BDCR, RCC_BDCR_LSEON);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* LSE oscillator enable */
|
||||
SET_BIT(RCC->BDCR, RCC_BDCR_LSEON);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSEON);
|
||||
CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSEBYP);
|
||||
}
|
||||
#else
|
||||
__HAL_RCC_LSE_CONFIG(RCC_OscInitStruct->LSEState);
|
||||
#endif /* RCC_BDCR_LSESYSDIS */
|
||||
|
||||
/* Check the LSE State */
|
||||
if(RCC_OscInitStruct->LSEState != RCC_LSE_OFF)
|
||||
{
|
||||
/* Get Start Tick*/
|
||||
tickstart = HAL_GetTick();
|
||||
|
||||
/* Wait till LSE is ready */
|
||||
while(READ_BIT(RCC->BDCR, RCC_BDCR_LSERDY) == 0U)
|
||||
{
|
||||
if((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Get Start Tick*/
|
||||
tickstart = HAL_GetTick();
|
||||
|
||||
/* Wait till LSE is disabled */
|
||||
while(READ_BIT(RCC->BDCR, RCC_BDCR_LSERDY) != 0U)
|
||||
{
|
||||
if((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(RCC_BDCR_LSESYSDIS)
|
||||
/* By default, stop disabling LSE propagation */
|
||||
CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSESYSDIS);
|
||||
#endif /* RCC_BDCR_LSESYSDIS */
|
||||
}
|
||||
|
||||
/* Restore clock configuration if changed */
|
||||
if(pwrclkchanged == SET)
|
||||
{
|
||||
__HAL_RCC_PWR_CLK_DISABLE();
|
||||
}
|
||||
}
|
||||
#if defined(RCC_HSI48_SUPPORT)
|
||||
/*------------------------------ HSI48 Configuration -----------------------*/
|
||||
if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI48) == RCC_OSCILLATORTYPE_HSI48)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_RCC_HSI48(RCC_OscInitStruct->HSI48State));
|
||||
|
||||
/* Check the LSI State */
|
||||
if(RCC_OscInitStruct->HSI48State != RCC_HSI48_OFF)
|
||||
{
|
||||
/* Enable the Internal Low Speed oscillator (HSI48). */
|
||||
__HAL_RCC_HSI48_ENABLE();
|
||||
|
||||
/* Get Start Tick*/
|
||||
tickstart = HAL_GetTick();
|
||||
|
||||
/* Wait till HSI48 is ready */
|
||||
while(READ_BIT(RCC->CRRCR, RCC_CRRCR_HSI48RDY) == 0U)
|
||||
{
|
||||
if((HAL_GetTick() - tickstart) > HSI48_TIMEOUT_VALUE)
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Disable the Internal Low Speed oscillator (HSI48). */
|
||||
__HAL_RCC_HSI48_DISABLE();
|
||||
|
||||
/* Get Start Tick*/
|
||||
tickstart = HAL_GetTick();
|
||||
|
||||
/* Wait till HSI48 is disabled */
|
||||
while(READ_BIT(RCC->CRRCR, RCC_CRRCR_HSI48RDY) != 0U)
|
||||
{
|
||||
if((HAL_GetTick() - tickstart) > HSI48_TIMEOUT_VALUE)
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* RCC_HSI48_SUPPORT */
|
||||
/*-------------------------------- PLL Configuration -----------------------*/
|
||||
/* Check the parameters */
|
||||
assert_param(IS_RCC_PLL(RCC_OscInitStruct->PLL.PLLState));
|
||||
|
||||
if(RCC_OscInitStruct->PLL.PLLState != RCC_PLL_NONE)
|
||||
{
|
||||
/* PLL On ? */
|
||||
if(RCC_OscInitStruct->PLL.PLLState == RCC_PLL_ON)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_RCC_PLLSOURCE(RCC_OscInitStruct->PLL.PLLSource));
|
||||
assert_param(IS_RCC_PLLM_VALUE(RCC_OscInitStruct->PLL.PLLM));
|
||||
assert_param(IS_RCC_PLLN_VALUE(RCC_OscInitStruct->PLL.PLLN));
|
||||
#if defined(RCC_PLLP_SUPPORT)
|
||||
assert_param(IS_RCC_PLLP_VALUE(RCC_OscInitStruct->PLL.PLLP));
|
||||
#endif /* RCC_PLLP_SUPPORT */
|
||||
assert_param(IS_RCC_PLLQ_VALUE(RCC_OscInitStruct->PLL.PLLQ));
|
||||
assert_param(IS_RCC_PLLR_VALUE(RCC_OscInitStruct->PLL.PLLR));
|
||||
|
||||
/* Do nothing if PLL configuration is the unchanged */
|
||||
pll_config = RCC->PLLCFGR;
|
||||
if((READ_BIT(pll_config, RCC_PLLCFGR_PLLSRC) != RCC_OscInitStruct->PLL.PLLSource) ||
|
||||
(READ_BIT(pll_config, RCC_PLLCFGR_PLLM) != ((RCC_OscInitStruct->PLL.PLLM - 1U) << RCC_PLLCFGR_PLLM_Pos)) ||
|
||||
(READ_BIT(pll_config, RCC_PLLCFGR_PLLN) != (RCC_OscInitStruct->PLL.PLLN << RCC_PLLCFGR_PLLN_Pos)) ||
|
||||
#if defined(RCC_PLLP_SUPPORT)
|
||||
#if defined(RCC_PLLP_DIV_2_31_SUPPORT)
|
||||
(READ_BIT(pll_config, RCC_PLLCFGR_PLLPDIV) != (RCC_OscInitStruct->PLL.PLLP << RCC_PLLCFGR_PLLPDIV_Pos)) ||
|
||||
#else
|
||||
(READ_BIT(pll_config, RCC_PLLCFGR_PLLP) != ((RCC_OscInitStruct->PLL.PLLP == RCC_PLLP_DIV7) ? 0U : 1U)) ||
|
||||
#endif
|
||||
#endif
|
||||
(READ_BIT(pll_config, RCC_PLLCFGR_PLLQ) != ((((RCC_OscInitStruct->PLL.PLLQ) >> 1U) - 1U) << RCC_PLLCFGR_PLLQ_Pos)) ||
|
||||
(READ_BIT(pll_config, RCC_PLLCFGR_PLLR) != ((((RCC_OscInitStruct->PLL.PLLR) >> 1U) - 1U) << RCC_PLLCFGR_PLLR_Pos)))
|
||||
{
|
||||
/* Check if the PLL is used as system clock or not */
|
||||
if(sysclk_source != RCC_CFGR_SWS_PLL)
|
||||
{
|
||||
#if defined(RCC_PLLSAI1_SUPPORT) || defined(RCC_PLLSAI2_SUPPORT)
|
||||
/* Check if main PLL can be updated */
|
||||
/* Not possible if the source is shared by other enabled PLLSAIx */
|
||||
if((READ_BIT(RCC->CR, RCC_CR_PLLSAI1ON) != 0U)
|
||||
#if defined(RCC_PLLSAI2_SUPPORT)
|
||||
|| (READ_BIT(RCC->CR, RCC_CR_PLLSAI2ON) != 0U)
|
||||
#endif
|
||||
)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
else
|
||||
#endif /* RCC_PLLSAI1_SUPPORT || RCC_PLLSAI2_SUPPORT */
|
||||
{
|
||||
/* Disable the main PLL. */
|
||||
__HAL_RCC_PLL_DISABLE();
|
||||
|
||||
/* Get Start Tick*/
|
||||
tickstart = HAL_GetTick();
|
||||
|
||||
/* Wait till PLL is ready */
|
||||
while(READ_BIT(RCC->CR, RCC_CR_PLLRDY) != 0U)
|
||||
{
|
||||
if((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
|
||||
/* Configure the main PLL clock source, multiplication and division factors. */
|
||||
#if defined(RCC_PLLP_SUPPORT)
|
||||
__HAL_RCC_PLL_CONFIG(RCC_OscInitStruct->PLL.PLLSource,
|
||||
RCC_OscInitStruct->PLL.PLLM,
|
||||
RCC_OscInitStruct->PLL.PLLN,
|
||||
RCC_OscInitStruct->PLL.PLLP,
|
||||
RCC_OscInitStruct->PLL.PLLQ,
|
||||
RCC_OscInitStruct->PLL.PLLR);
|
||||
#else
|
||||
__HAL_RCC_PLL_CONFIG(RCC_OscInitStruct->PLL.PLLSource,
|
||||
RCC_OscInitStruct->PLL.PLLM,
|
||||
RCC_OscInitStruct->PLL.PLLN,
|
||||
RCC_OscInitStruct->PLL.PLLQ,
|
||||
RCC_OscInitStruct->PLL.PLLR);
|
||||
#endif
|
||||
|
||||
/* Enable the main PLL. */
|
||||
__HAL_RCC_PLL_ENABLE();
|
||||
|
||||
/* Enable PLL System Clock output. */
|
||||
__HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_SYSCLK);
|
||||
|
||||
/* Get Start Tick*/
|
||||
tickstart = HAL_GetTick();
|
||||
|
||||
/* Wait till PLL is ready */
|
||||
while(READ_BIT(RCC->CR, RCC_CR_PLLRDY) == 0U)
|
||||
{
|
||||
if((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* PLL is already used as System core clock */
|
||||
return HAL_ERROR;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* PLL configuration is unchanged */
|
||||
/* Re-enable PLL if it was disabled (ie. low power mode) */
|
||||
if(READ_BIT(RCC->CR, RCC_CR_PLLRDY) == 0U)
|
||||
{
|
||||
/* Enable the main PLL. */
|
||||
__HAL_RCC_PLL_ENABLE();
|
||||
|
||||
/* Enable PLL System Clock output. */
|
||||
__HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_SYSCLK);
|
||||
|
||||
/* Get Start Tick*/
|
||||
tickstart = HAL_GetTick();
|
||||
|
||||
/* Wait till PLL is ready */
|
||||
while(READ_BIT(RCC->CR, RCC_CR_PLLRDY) == 0U)
|
||||
{
|
||||
if((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Check that PLL is not used as system clock or not */
|
||||
if(sysclk_source != RCC_CFGR_SWS_PLL)
|
||||
{
|
||||
/* Disable the main PLL. */
|
||||
__HAL_RCC_PLL_DISABLE();
|
||||
|
||||
/* Disable all PLL outputs to save power if no PLLs on */
|
||||
#if defined(RCC_PLLSAI1_SUPPORT) && defined(RCC_CR_PLLSAI2RDY)
|
||||
if(READ_BIT(RCC->CR, (RCC_CR_PLLSAI1RDY | RCC_CR_PLLSAI2RDY)) == 0U)
|
||||
{
|
||||
MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC, RCC_PLLSOURCE_NONE);
|
||||
}
|
||||
#elif defined(RCC_PLLSAI1_SUPPORT)
|
||||
if(READ_BIT(RCC->CR, RCC_CR_PLLSAI1RDY) == 0U)
|
||||
{
|
||||
MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC, RCC_PLLSOURCE_NONE);
|
||||
}
|
||||
#else
|
||||
MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC, RCC_PLLSOURCE_NONE);
|
||||
#endif /* RCC_PLLSAI1_SUPPORT && RCC_CR_PLLSAI2RDY */
|
||||
|
||||
#if defined(RCC_PLLSAI2_SUPPORT)
|
||||
__HAL_RCC_PLLCLKOUT_DISABLE(RCC_PLL_SYSCLK | RCC_PLL_48M1CLK | RCC_PLL_SAI3CLK);
|
||||
#elif defined(RCC_PLLSAI1_SUPPORT)
|
||||
__HAL_RCC_PLLCLKOUT_DISABLE(RCC_PLL_SYSCLK | RCC_PLL_48M1CLK | RCC_PLL_SAI2CLK);
|
||||
#else
|
||||
__HAL_RCC_PLLCLKOUT_DISABLE(RCC_PLL_SYSCLK | RCC_PLL_48M1CLK);
|
||||
#endif /* RCC_PLLSAI2_SUPPORT */
|
||||
|
||||
/* Get Start Tick*/
|
||||
tickstart = HAL_GetTick();
|
||||
|
||||
/* Wait till PLL is disabled */
|
||||
while(READ_BIT(RCC->CR, RCC_CR_PLLRDY) != 0U)
|
||||
{
|
||||
if((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* PLL is already used as System core clock */
|
||||
return HAL_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialize the CPU, AHB and APB busses clocks according to the specified
|
||||
* parameters in the RCC_ClkInitStruct.
|
||||
* @param RCC_ClkInitStruct pointer to an RCC_OscInitTypeDef structure that
|
||||
* contains the configuration information for the RCC peripheral.
|
||||
* @param FLatency FLASH Latency
|
||||
* This parameter can be one of the following values:
|
||||
* @arg FLASH_LATENCY_0 FLASH 0 Latency cycle
|
||||
* @arg FLASH_LATENCY_1 FLASH 1 Latency cycle
|
||||
* @arg FLASH_LATENCY_2 FLASH 2 Latency cycles
|
||||
* @arg FLASH_LATENCY_3 FLASH 3 Latency cycles
|
||||
* @arg FLASH_LATENCY_4 FLASH 4 Latency cycles
|
||||
@if STM32L4S9xx
|
||||
* @arg FLASH_LATENCY_5 FLASH 5 Latency cycles
|
||||
* @arg FLASH_LATENCY_6 FLASH 6 Latency cycles
|
||||
* @arg FLASH_LATENCY_7 FLASH 7 Latency cycles
|
||||
* @arg FLASH_LATENCY_8 FLASH 8 Latency cycles
|
||||
* @arg FLASH_LATENCY_9 FLASH 9 Latency cycles
|
||||
* @arg FLASH_LATENCY_10 FLASH 10 Latency cycles
|
||||
* @arg FLASH_LATENCY_11 FLASH 11 Latency cycles
|
||||
* @arg FLASH_LATENCY_12 FLASH 12 Latency cycles
|
||||
* @arg FLASH_LATENCY_13 FLASH 13 Latency cycles
|
||||
* @arg FLASH_LATENCY_14 FLASH 14 Latency cycles
|
||||
* @arg FLASH_LATENCY_15 FLASH 15 Latency cycles
|
||||
@endif
|
||||
*
|
||||
* @note The SystemCoreClock CMSIS variable is used to store System Clock Frequency
|
||||
* and updated by HAL_RCC_GetHCLKFreq() function called within this function
|
||||
*
|
||||
* @note The MSI is used by default as system clock source after
|
||||
* startup from Reset, wake-up from STANDBY mode. After restart from Reset,
|
||||
* the MSI frequency is set to its default value 4 MHz.
|
||||
*
|
||||
* @note The HSI can be selected as system clock source after
|
||||
* from STOP modes or in case of failure of the HSE used directly or indirectly
|
||||
* as system clock (if the Clock Security System CSS is enabled).
|
||||
*
|
||||
* @note A switch from one clock source to another occurs only if the target
|
||||
* clock source is ready (clock stable after startup delay or PLL locked).
|
||||
* If a clock source which is not yet ready is selected, the switch will
|
||||
* occur when the clock source is ready.
|
||||
*
|
||||
* @note You can use HAL_RCC_GetClockConfig() function to know which clock is
|
||||
* currently used as system clock source.
|
||||
*
|
||||
* @note Depending on the device voltage range, the software has to set correctly
|
||||
* HPRE[3:0] bits to ensure that HCLK not exceed the maximum allowed frequency
|
||||
* (for more details refer to section above "Initialization/de-initialization functions")
|
||||
* @retval None
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_RCC_ClockConfig(RCC_ClkInitTypeDef *RCC_ClkInitStruct, uint32_t FLatency)
|
||||
{
|
||||
uint32_t tickstart;
|
||||
#if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || \
|
||||
defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
|
||||
uint32_t hpre = RCC_SYSCLK_DIV1;
|
||||
#endif
|
||||
HAL_StatusTypeDef status;
|
||||
|
||||
/* Check Null pointer */
|
||||
if(RCC_ClkInitStruct == NULL)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_RCC_CLOCKTYPE(RCC_ClkInitStruct->ClockType));
|
||||
assert_param(IS_FLASH_LATENCY(FLatency));
|
||||
|
||||
/* To correctly read data from FLASH memory, the number of wait states (LATENCY)
|
||||
must be correctly programmed according to the frequency of the CPU clock
|
||||
(HCLK) and the supply voltage of the device. */
|
||||
|
||||
/* Increasing the number of wait states because of higher CPU frequency */
|
||||
if(FLatency > __HAL_FLASH_GET_LATENCY())
|
||||
{
|
||||
/* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
|
||||
__HAL_FLASH_SET_LATENCY(FLatency);
|
||||
|
||||
/* Check that the new number of wait states is taken into account to access the Flash
|
||||
memory by reading the FLASH_ACR register */
|
||||
if(__HAL_FLASH_GET_LATENCY() != FLatency)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/*------------------------- SYSCLK Configuration ---------------------------*/
|
||||
if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_SYSCLK) == RCC_CLOCKTYPE_SYSCLK)
|
||||
{
|
||||
assert_param(IS_RCC_SYSCLKSOURCE(RCC_ClkInitStruct->SYSCLKSource));
|
||||
|
||||
/* PLL is selected as System Clock Source */
|
||||
if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_PLLCLK)
|
||||
{
|
||||
/* Check the PLL ready flag */
|
||||
if(READ_BIT(RCC->CR, RCC_CR_PLLRDY) == 0U)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
#if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || \
|
||||
defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
|
||||
/* Undershoot management when selection PLL as SYSCLK source and frequency above 80Mhz */
|
||||
/* Compute target PLL output frequency */
|
||||
if(RCC_GetSysClockFreqFromPLLSource() > 80000000U)
|
||||
{
|
||||
if(READ_BIT(RCC->CFGR, RCC_CFGR_HPRE) == RCC_SYSCLK_DIV1)
|
||||
{
|
||||
/* Intermediate step with HCLK prescaler 2 necessary before to go over 80Mhz */
|
||||
MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_SYSCLK_DIV2);
|
||||
hpre = RCC_SYSCLK_DIV2;
|
||||
}
|
||||
else if((((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_HCLK) == RCC_CLOCKTYPE_HCLK) && (RCC_ClkInitStruct->AHBCLKDivider == RCC_SYSCLK_DIV1))
|
||||
{
|
||||
/* Intermediate step with HCLK prescaler 2 necessary before to go over 80Mhz */
|
||||
MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_SYSCLK_DIV2);
|
||||
hpre = RCC_SYSCLK_DIV2;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* nothing to do */
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
/* HSE is selected as System Clock Source */
|
||||
if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSE)
|
||||
{
|
||||
/* Check the HSE ready flag */
|
||||
if(READ_BIT(RCC->CR, RCC_CR_HSERDY) == 0U)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
}
|
||||
/* MSI is selected as System Clock Source */
|
||||
else if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_MSI)
|
||||
{
|
||||
/* Check the MSI ready flag */
|
||||
if(READ_BIT(RCC->CR, RCC_CR_MSIRDY) == 0U)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
}
|
||||
/* HSI is selected as System Clock Source */
|
||||
else
|
||||
{
|
||||
/* Check the HSI ready flag */
|
||||
if(READ_BIT(RCC->CR, RCC_CR_HSIRDY) == 0U)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
}
|
||||
#if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || \
|
||||
defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
|
||||
/* Overshoot management when going down from PLL as SYSCLK source and frequency above 80Mhz */
|
||||
if(HAL_RCC_GetSysClockFreq() > 80000000U)
|
||||
{
|
||||
/* Intermediate step with HCLK prescaler 2 necessary before to go under 80Mhz */
|
||||
MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_SYSCLK_DIV2);
|
||||
hpre = RCC_SYSCLK_DIV2;
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
MODIFY_REG(RCC->CFGR, RCC_CFGR_SW, RCC_ClkInitStruct->SYSCLKSource);
|
||||
|
||||
/* Get Start Tick*/
|
||||
tickstart = HAL_GetTick();
|
||||
|
||||
while(__HAL_RCC_GET_SYSCLK_SOURCE() != (RCC_ClkInitStruct->SYSCLKSource << RCC_CFGR_SWS_Pos))
|
||||
{
|
||||
if((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------- HCLK Configuration --------------------------*/
|
||||
if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_HCLK) == RCC_CLOCKTYPE_HCLK)
|
||||
{
|
||||
assert_param(IS_RCC_HCLK(RCC_ClkInitStruct->AHBCLKDivider));
|
||||
MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_ClkInitStruct->AHBCLKDivider);
|
||||
}
|
||||
#if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || \
|
||||
defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
|
||||
else
|
||||
{
|
||||
/* Is intermediate HCLK prescaler 2 applied internally, complete with HCLK prescaler 1 */
|
||||
if(hpre == RCC_SYSCLK_DIV2)
|
||||
{
|
||||
MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_SYSCLK_DIV1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Decreasing the number of wait states because of lower CPU frequency */
|
||||
if(FLatency < __HAL_FLASH_GET_LATENCY())
|
||||
{
|
||||
/* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
|
||||
__HAL_FLASH_SET_LATENCY(FLatency);
|
||||
|
||||
/* Check that the new number of wait states is taken into account to access the Flash
|
||||
memory by reading the FLASH_ACR register */
|
||||
if(__HAL_FLASH_GET_LATENCY() != FLatency)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------- PCLK1 Configuration ---------------------------*/
|
||||
if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK1) == RCC_CLOCKTYPE_PCLK1)
|
||||
{
|
||||
assert_param(IS_RCC_PCLK(RCC_ClkInitStruct->APB1CLKDivider));
|
||||
MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE1, RCC_ClkInitStruct->APB1CLKDivider);
|
||||
}
|
||||
|
||||
/*-------------------------- PCLK2 Configuration ---------------------------*/
|
||||
if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK2) == RCC_CLOCKTYPE_PCLK2)
|
||||
{
|
||||
assert_param(IS_RCC_PCLK(RCC_ClkInitStruct->APB2CLKDivider));
|
||||
MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE2, ((RCC_ClkInitStruct->APB2CLKDivider) << 3U));
|
||||
}
|
||||
|
||||
/* Update the SystemCoreClock global variable */
|
||||
SystemCoreClock = HAL_RCC_GetSysClockFreq() >> (AHBPrescTable[READ_BIT(RCC->CFGR, RCC_CFGR_HPRE) >> RCC_CFGR_HPRE_Pos] & 0x1FU);
|
||||
|
||||
/* Configure the source of time base considering new system clocks settings*/
|
||||
status = HAL_InitTick(uwTickPrio);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup RCC_Exported_Functions_Group2 Peripheral Control functions
|
||||
* @brief RCC clocks control functions
|
||||
*
|
||||
@verbatim
|
||||
===============================================================================
|
||||
##### Peripheral Control functions #####
|
||||
===============================================================================
|
||||
[..]
|
||||
This subsection provides a set of functions allowing to:
|
||||
|
||||
(+) Output clock to MCO pin.
|
||||
(+) Retrieve current clock frequencies.
|
||||
(+) Enable the Clock Security System.
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Select the clock source to output on MCO pin(PA8).
|
||||
* @note PA8 should be configured in alternate function mode.
|
||||
* @param RCC_MCOx specifies the output direction for the clock source.
|
||||
* For STM32L4xx family this parameter can have only one value:
|
||||
* @arg @ref RCC_MCO1 Clock source to output on MCO1 pin(PA8).
|
||||
* @param RCC_MCOSource specifies the clock source to output.
|
||||
* This parameter can be one of the following values:
|
||||
* @arg @ref RCC_MCO1SOURCE_NOCLOCK MCO output disabled, no clock on MCO
|
||||
* @arg @ref RCC_MCO1SOURCE_SYSCLK system clock selected as MCO source
|
||||
* @arg @ref RCC_MCO1SOURCE_MSI MSI clock selected as MCO source
|
||||
* @arg @ref RCC_MCO1SOURCE_HSI HSI clock selected as MCO source
|
||||
* @arg @ref RCC_MCO1SOURCE_HSE HSE clock selected as MCO sourcee
|
||||
* @arg @ref RCC_MCO1SOURCE_PLLCLK main PLL clock selected as MCO source
|
||||
* @arg @ref RCC_MCO1SOURCE_LSI LSI clock selected as MCO source
|
||||
* @arg @ref RCC_MCO1SOURCE_LSE LSE clock selected as MCO source
|
||||
@if STM32L443xx
|
||||
* @arg @ref RCC_MCO1SOURCE_HSI48 HSI48 clock selected as MCO source for devices with HSI48
|
||||
@endif
|
||||
* @param RCC_MCODiv specifies the MCO prescaler.
|
||||
* This parameter can be one of the following values:
|
||||
* @arg @ref RCC_MCODIV_1 no division applied to MCO clock
|
||||
* @arg @ref RCC_MCODIV_2 division by 2 applied to MCO clock
|
||||
* @arg @ref RCC_MCODIV_4 division by 4 applied to MCO clock
|
||||
* @arg @ref RCC_MCODIV_8 division by 8 applied to MCO clock
|
||||
* @arg @ref RCC_MCODIV_16 division by 16 applied to MCO clock
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_RCC_MCOConfig( uint32_t RCC_MCOx, uint32_t RCC_MCOSource, uint32_t RCC_MCODiv)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStruct;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_RCC_MCO(RCC_MCOx));
|
||||
assert_param(IS_RCC_MCODIV(RCC_MCODiv));
|
||||
assert_param(IS_RCC_MCO1SOURCE(RCC_MCOSource));
|
||||
|
||||
/* Prevent unused argument(s) compilation warning if no assert_param check */
|
||||
UNUSED(RCC_MCOx);
|
||||
|
||||
/* MCO Clock Enable */
|
||||
__MCO1_CLK_ENABLE();
|
||||
|
||||
/* Configure the MCO1 pin in alternate function mode */
|
||||
GPIO_InitStruct.Pin = MCO1_PIN;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Alternate = GPIO_AF0_MCO;
|
||||
HAL_GPIO_Init(MCO1_GPIO_PORT, &GPIO_InitStruct);
|
||||
|
||||
/* Mask MCOSEL[] and MCOPRE[] bits then set MCO1 clock source and prescaler */
|
||||
MODIFY_REG(RCC->CFGR, (RCC_CFGR_MCOSEL | RCC_CFGR_MCOPRE), (RCC_MCOSource | RCC_MCODiv ));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the SYSCLK frequency.
|
||||
*
|
||||
* @note The system frequency computed by this function is not the real
|
||||
* frequency in the chip. It is calculated based on the predefined
|
||||
* constant and the selected clock source:
|
||||
* @note If SYSCLK source is MSI, function returns values based on MSI
|
||||
* Value as defined by the MSI range.
|
||||
* @note If SYSCLK source is HSI, function returns values based on HSI_VALUE(*)
|
||||
* @note If SYSCLK source is HSE, function returns values based on HSE_VALUE(**)
|
||||
* @note If SYSCLK source is PLL, function returns values based on HSE_VALUE(**),
|
||||
* HSI_VALUE(*) or MSI Value multiplied/divided by the PLL factors.
|
||||
* @note (*) HSI_VALUE is a constant defined in stm32l4xx_hal_conf.h file (default value
|
||||
* 16 MHz) but the real value may vary depending on the variations
|
||||
* in voltage and temperature.
|
||||
* @note (**) HSE_VALUE is a constant defined in stm32l4xx_hal_conf.h file (default value
|
||||
* 8 MHz), user has to ensure that HSE_VALUE is same as the real
|
||||
* frequency of the crystal used. Otherwise, this function may
|
||||
* have wrong result.
|
||||
*
|
||||
* @note The result of this function could be not correct when using fractional
|
||||
* value for HSE crystal.
|
||||
*
|
||||
* @note This function can be used by the user application to compute the
|
||||
* baudrate for the communication peripherals or configure other parameters.
|
||||
*
|
||||
* @note Each time SYSCLK changes, this function must be called to update the
|
||||
* right SYSCLK value. Otherwise, any configuration based on this function will be incorrect.
|
||||
*
|
||||
*
|
||||
* @retval SYSCLK frequency
|
||||
*/
|
||||
uint32_t HAL_RCC_GetSysClockFreq(void)
|
||||
{
|
||||
uint32_t msirange = 0U, sysclockfreq = 0U;
|
||||
uint32_t pllvco, pllsource, pllr, pllm; /* no init needed */
|
||||
uint32_t sysclk_source, pll_oscsource;
|
||||
|
||||
sysclk_source = __HAL_RCC_GET_SYSCLK_SOURCE();
|
||||
pll_oscsource = __HAL_RCC_GET_PLL_OSCSOURCE();
|
||||
|
||||
if((sysclk_source == RCC_CFGR_SWS_MSI) ||
|
||||
((sysclk_source == RCC_CFGR_SWS_PLL) && (pll_oscsource == RCC_PLLSOURCE_MSI)))
|
||||
{
|
||||
/* MSI or PLL with MSI source used as system clock source */
|
||||
|
||||
/* Get SYSCLK source */
|
||||
if(READ_BIT(RCC->CR, RCC_CR_MSIRGSEL) == 0U)
|
||||
{ /* MSISRANGE from RCC_CSR applies */
|
||||
msirange = READ_BIT(RCC->CSR, RCC_CSR_MSISRANGE) >> RCC_CSR_MSISRANGE_Pos;
|
||||
}
|
||||
else
|
||||
{ /* MSIRANGE from RCC_CR applies */
|
||||
msirange = READ_BIT(RCC->CR, RCC_CR_MSIRANGE) >> RCC_CR_MSIRANGE_Pos;
|
||||
}
|
||||
/*MSI frequency range in HZ*/
|
||||
msirange = MSIRangeTable[msirange];
|
||||
|
||||
if(sysclk_source == RCC_CFGR_SWS_MSI)
|
||||
{
|
||||
/* MSI used as system clock source */
|
||||
sysclockfreq = msirange;
|
||||
}
|
||||
}
|
||||
else if(sysclk_source == RCC_CFGR_SWS_HSI)
|
||||
{
|
||||
/* HSI used as system clock source */
|
||||
sysclockfreq = HSI_VALUE;
|
||||
}
|
||||
else if(sysclk_source == RCC_CFGR_SWS_HSE)
|
||||
{
|
||||
/* HSE used as system clock source */
|
||||
sysclockfreq = HSE_VALUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* unexpected case: sysclockfreq at 0 */
|
||||
}
|
||||
|
||||
if(sysclk_source == RCC_CFGR_SWS_PLL)
|
||||
{
|
||||
/* PLL used as system clock source */
|
||||
|
||||
/* PLL_VCO = (HSE_VALUE or HSI_VALUE or MSI_VALUE) * PLLN / PLLM
|
||||
SYSCLK = PLL_VCO / PLLR
|
||||
*/
|
||||
pllsource = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC);
|
||||
|
||||
switch (pllsource)
|
||||
{
|
||||
case RCC_PLLSOURCE_HSI: /* HSI used as PLL clock source */
|
||||
pllvco = HSI_VALUE;
|
||||
break;
|
||||
|
||||
case RCC_PLLSOURCE_HSE: /* HSE used as PLL clock source */
|
||||
pllvco = HSE_VALUE;
|
||||
break;
|
||||
|
||||
case RCC_PLLSOURCE_MSI: /* MSI used as PLL clock source */
|
||||
default:
|
||||
pllvco = msirange;
|
||||
break;
|
||||
}
|
||||
pllm = (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U ;
|
||||
pllvco = (pllvco * (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos)) / pllm;
|
||||
pllr = ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLR) >> RCC_PLLCFGR_PLLR_Pos) + 1U ) * 2U;
|
||||
sysclockfreq = pllvco / pllr;
|
||||
}
|
||||
|
||||
return sysclockfreq;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the HCLK frequency.
|
||||
* @note Each time HCLK changes, this function must be called to update the
|
||||
* right HCLK value. Otherwise, any configuration based on this function will be incorrect.
|
||||
*
|
||||
* @note The SystemCoreClock CMSIS variable is used to store System Clock Frequency.
|
||||
* @retval HCLK frequency in Hz
|
||||
*/
|
||||
uint32_t HAL_RCC_GetHCLKFreq(void)
|
||||
{
|
||||
return SystemCoreClock;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the PCLK1 frequency.
|
||||
* @note Each time PCLK1 changes, this function must be called to update the
|
||||
* right PCLK1 value. Otherwise, any configuration based on this function will be incorrect.
|
||||
* @retval PCLK1 frequency in Hz
|
||||
*/
|
||||
uint32_t HAL_RCC_GetPCLK1Freq(void)
|
||||
{
|
||||
/* Get HCLK source and Compute PCLK1 frequency ---------------------------*/
|
||||
return (HAL_RCC_GetHCLKFreq() >> (APBPrescTable[READ_BIT(RCC->CFGR, RCC_CFGR_PPRE1) >> RCC_CFGR_PPRE1_Pos] & 0x1FU));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the PCLK2 frequency.
|
||||
* @note Each time PCLK2 changes, this function must be called to update the
|
||||
* right PCLK2 value. Otherwise, any configuration based on this function will be incorrect.
|
||||
* @retval PCLK2 frequency in Hz
|
||||
*/
|
||||
uint32_t HAL_RCC_GetPCLK2Freq(void)
|
||||
{
|
||||
/* Get HCLK source and Compute PCLK2 frequency ---------------------------*/
|
||||
return (HAL_RCC_GetHCLKFreq()>> (APBPrescTable[READ_BIT(RCC->CFGR, RCC_CFGR_PPRE2) >> RCC_CFGR_PPRE2_Pos] & 0x1FU));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure the RCC_OscInitStruct according to the internal
|
||||
* RCC configuration registers.
|
||||
* @param RCC_OscInitStruct pointer to an RCC_OscInitTypeDef structure that
|
||||
* will be configured.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_RCC_GetOscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(RCC_OscInitStruct != (void *)NULL);
|
||||
|
||||
/* Set all possible values for the Oscillator type parameter ---------------*/
|
||||
#if defined(RCC_HSI48_SUPPORT)
|
||||
RCC_OscInitStruct->OscillatorType = RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_MSI | \
|
||||
RCC_OSCILLATORTYPE_LSE | RCC_OSCILLATORTYPE_LSI | RCC_OSCILLATORTYPE_HSI48;
|
||||
#else
|
||||
RCC_OscInitStruct->OscillatorType = RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_MSI | \
|
||||
RCC_OSCILLATORTYPE_LSE | RCC_OSCILLATORTYPE_LSI;
|
||||
#endif /* RCC_HSI48_SUPPORT */
|
||||
|
||||
/* Get the HSE configuration -----------------------------------------------*/
|
||||
if(READ_BIT(RCC->CR, RCC_CR_HSEBYP) == RCC_CR_HSEBYP)
|
||||
{
|
||||
RCC_OscInitStruct->HSEState = RCC_HSE_BYPASS;
|
||||
}
|
||||
else if(READ_BIT(RCC->CR, RCC_CR_HSEON) == RCC_CR_HSEON)
|
||||
{
|
||||
RCC_OscInitStruct->HSEState = RCC_HSE_ON;
|
||||
}
|
||||
else
|
||||
{
|
||||
RCC_OscInitStruct->HSEState = RCC_HSE_OFF;
|
||||
}
|
||||
|
||||
/* Get the MSI configuration -----------------------------------------------*/
|
||||
if(READ_BIT(RCC->CR, RCC_CR_MSION) == RCC_CR_MSION)
|
||||
{
|
||||
RCC_OscInitStruct->MSIState = RCC_MSI_ON;
|
||||
}
|
||||
else
|
||||
{
|
||||
RCC_OscInitStruct->MSIState = RCC_MSI_OFF;
|
||||
}
|
||||
|
||||
RCC_OscInitStruct->MSICalibrationValue = READ_BIT(RCC->ICSCR, RCC_ICSCR_MSITRIM) >> RCC_ICSCR_MSITRIM_Pos;
|
||||
RCC_OscInitStruct->MSIClockRange = READ_BIT(RCC->CR, RCC_CR_MSIRANGE);
|
||||
|
||||
/* Get the HSI configuration -----------------------------------------------*/
|
||||
if(READ_BIT(RCC->CR, RCC_CR_HSION) == RCC_CR_HSION)
|
||||
{
|
||||
RCC_OscInitStruct->HSIState = RCC_HSI_ON;
|
||||
}
|
||||
else
|
||||
{
|
||||
RCC_OscInitStruct->HSIState = RCC_HSI_OFF;
|
||||
}
|
||||
|
||||
RCC_OscInitStruct->HSICalibrationValue = READ_BIT(RCC->ICSCR, RCC_ICSCR_HSITRIM) >> RCC_ICSCR_HSITRIM_Pos;
|
||||
|
||||
/* Get the LSE configuration -----------------------------------------------*/
|
||||
if(READ_BIT(RCC->BDCR, RCC_BDCR_LSEBYP) == RCC_BDCR_LSEBYP)
|
||||
{
|
||||
#if defined(RCC_BDCR_LSESYSDIS)
|
||||
if((RCC->BDCR & RCC_BDCR_LSESYSDIS) == RCC_BDCR_LSESYSDIS)
|
||||
{
|
||||
RCC_OscInitStruct->LSEState = RCC_LSE_BYPASS_RTC_ONLY;
|
||||
}
|
||||
else
|
||||
#endif /* RCC_BDCR_LSESYSDIS */
|
||||
{
|
||||
RCC_OscInitStruct->LSEState = RCC_LSE_BYPASS;
|
||||
}
|
||||
}
|
||||
else if(READ_BIT(RCC->BDCR, RCC_BDCR_LSEON) == RCC_BDCR_LSEON)
|
||||
{
|
||||
#if defined(RCC_BDCR_LSESYSDIS)
|
||||
if((RCC->BDCR & RCC_BDCR_LSESYSDIS) == RCC_BDCR_LSESYSDIS)
|
||||
{
|
||||
RCC_OscInitStruct->LSEState = RCC_LSE_ON_RTC_ONLY;
|
||||
}
|
||||
else
|
||||
#endif /* RCC_BDCR_LSESYSDIS */
|
||||
{
|
||||
RCC_OscInitStruct->LSEState = RCC_LSE_ON;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
RCC_OscInitStruct->LSEState = RCC_LSE_OFF;
|
||||
}
|
||||
|
||||
/* Get the LSI configuration -----------------------------------------------*/
|
||||
if(READ_BIT(RCC->CSR, RCC_CSR_LSION) == RCC_CSR_LSION)
|
||||
{
|
||||
RCC_OscInitStruct->LSIState = RCC_LSI_ON;
|
||||
}
|
||||
else
|
||||
{
|
||||
RCC_OscInitStruct->LSIState = RCC_LSI_OFF;
|
||||
}
|
||||
#if defined(RCC_CSR_LSIPREDIV)
|
||||
|
||||
/* Get the LSI configuration -----------------------------------------------*/
|
||||
if((RCC->CSR & RCC_CSR_LSIPREDIV) == RCC_CSR_LSIPREDIV)
|
||||
{
|
||||
RCC_OscInitStruct->LSIDiv = RCC_LSI_DIV128;
|
||||
}
|
||||
else
|
||||
{
|
||||
RCC_OscInitStruct->LSIDiv = RCC_LSI_DIV1;
|
||||
}
|
||||
#endif /* RCC_CSR_LSIPREDIV */
|
||||
|
||||
#if defined(RCC_HSI48_SUPPORT)
|
||||
/* Get the HSI48 configuration ---------------------------------------------*/
|
||||
if(READ_BIT(RCC->CRRCR, RCC_CRRCR_HSI48ON) == RCC_CRRCR_HSI48ON)
|
||||
{
|
||||
RCC_OscInitStruct->HSI48State = RCC_HSI48_ON;
|
||||
}
|
||||
else
|
||||
{
|
||||
RCC_OscInitStruct->HSI48State = RCC_HSI48_OFF;
|
||||
}
|
||||
#else
|
||||
RCC_OscInitStruct->HSI48State = RCC_HSI48_OFF;
|
||||
#endif /* RCC_HSI48_SUPPORT */
|
||||
|
||||
/* Get the PLL configuration -----------------------------------------------*/
|
||||
if(READ_BIT(RCC->CR, RCC_CR_PLLON) == RCC_CR_PLLON)
|
||||
{
|
||||
RCC_OscInitStruct->PLL.PLLState = RCC_PLL_ON;
|
||||
}
|
||||
else
|
||||
{
|
||||
RCC_OscInitStruct->PLL.PLLState = RCC_PLL_OFF;
|
||||
}
|
||||
RCC_OscInitStruct->PLL.PLLSource = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC);
|
||||
RCC_OscInitStruct->PLL.PLLM = (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U;
|
||||
RCC_OscInitStruct->PLL.PLLN = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos;
|
||||
RCC_OscInitStruct->PLL.PLLQ = (((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLQ) >> RCC_PLLCFGR_PLLQ_Pos) + 1U) << 1U);
|
||||
RCC_OscInitStruct->PLL.PLLR = (((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLR) >> RCC_PLLCFGR_PLLR_Pos) + 1U) << 1U);
|
||||
#if defined(RCC_PLLP_SUPPORT)
|
||||
#if defined(RCC_PLLP_DIV_2_31_SUPPORT)
|
||||
RCC_OscInitStruct->PLL.PLLP = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLPDIV) >> RCC_PLLCFGR_PLLPDIV_Pos;
|
||||
#else
|
||||
if(READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLP) != 0U)
|
||||
{
|
||||
RCC_OscInitStruct->PLL.PLLP = RCC_PLLP_DIV17;
|
||||
}
|
||||
else
|
||||
{
|
||||
RCC_OscInitStruct->PLL.PLLP = RCC_PLLP_DIV7;
|
||||
}
|
||||
#endif /* RCC_PLLP_DIV_2_31_SUPPORT */
|
||||
#endif /* RCC_PLLP_SUPPORT */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure the RCC_ClkInitStruct according to the internal
|
||||
* RCC configuration registers.
|
||||
* @param RCC_ClkInitStruct pointer to an RCC_ClkInitTypeDef structure that
|
||||
* will be configured.
|
||||
* @param pFLatency Pointer on the Flash Latency.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_RCC_GetClockConfig(RCC_ClkInitTypeDef *RCC_ClkInitStruct, uint32_t *pFLatency)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(RCC_ClkInitStruct != (void *)NULL);
|
||||
assert_param(pFLatency != (void *)NULL);
|
||||
|
||||
/* Set all possible values for the Clock type parameter --------------------*/
|
||||
RCC_ClkInitStruct->ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
|
||||
|
||||
/* Get the SYSCLK configuration --------------------------------------------*/
|
||||
RCC_ClkInitStruct->SYSCLKSource = READ_BIT(RCC->CFGR, RCC_CFGR_SW);
|
||||
|
||||
/* Get the HCLK configuration ----------------------------------------------*/
|
||||
RCC_ClkInitStruct->AHBCLKDivider = READ_BIT(RCC->CFGR, RCC_CFGR_HPRE);
|
||||
|
||||
/* Get the APB1 configuration ----------------------------------------------*/
|
||||
RCC_ClkInitStruct->APB1CLKDivider = READ_BIT(RCC->CFGR, RCC_CFGR_PPRE1);
|
||||
|
||||
/* Get the APB2 configuration ----------------------------------------------*/
|
||||
RCC_ClkInitStruct->APB2CLKDivider = (READ_BIT(RCC->CFGR, RCC_CFGR_PPRE2) >> 3U);
|
||||
|
||||
/* Get the Flash Wait State (Latency) configuration ------------------------*/
|
||||
*pFLatency = __HAL_FLASH_GET_LATENCY();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable the Clock Security System.
|
||||
* @note If a failure is detected on the HSE oscillator clock, this oscillator
|
||||
* is automatically disabled and an interrupt is generated to inform the
|
||||
* software about the failure (Clock Security System Interrupt, CSSI),
|
||||
* allowing the MCU to perform rescue operations. The CSSI is linked to
|
||||
* the Cortex-M4 NMI (Non-Maskable Interrupt) exception vector.
|
||||
* @note The Clock Security System can only be cleared by reset.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_RCC_EnableCSS(void)
|
||||
{
|
||||
SET_BIT(RCC->CR, RCC_CR_CSSON) ;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Handle the RCC Clock Security System interrupt request.
|
||||
* @note This API should be called under the NMI_Handler().
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_RCC_NMI_IRQHandler(void)
|
||||
{
|
||||
/* Check RCC CSSF interrupt flag */
|
||||
if(__HAL_RCC_GET_IT(RCC_IT_CSS))
|
||||
{
|
||||
/* RCC Clock Security System interrupt user callback */
|
||||
HAL_RCC_CSSCallback();
|
||||
|
||||
/* Clear RCC CSS pending bit */
|
||||
__HAL_RCC_CLEAR_IT(RCC_IT_CSS);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief RCC Clock Security System interrupt callback.
|
||||
* @retval none
|
||||
*/
|
||||
__weak void HAL_RCC_CSSCallback(void)
|
||||
{
|
||||
/* NOTE : This function should not be modified, when the callback is needed,
|
||||
the HAL_RCC_CSSCallback should be implemented in the user file
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get and clear reset flags
|
||||
* @param None
|
||||
* @note Once reset flags are retrieved, this API is clearing them in order
|
||||
* to isolate next reset reason.
|
||||
* @retval can be a combination of @ref RCC_Reset_Flag
|
||||
*/
|
||||
uint32_t HAL_RCC_GetResetSource(void)
|
||||
{
|
||||
uint32_t reset;
|
||||
|
||||
/* Get all reset flags */
|
||||
reset = RCC->CSR & RCC_RESET_FLAG_ALL;
|
||||
|
||||
/* Clear Reset flags */
|
||||
RCC->CSR |= RCC_CSR_RMVF;
|
||||
|
||||
return reset;
|
||||
}
|
||||
|
||||
/** * @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/** @addtogroup RCC_Private_Functions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Update number of Flash wait states in line with MSI range and current
|
||||
voltage range.
|
||||
* @param msirange MSI range value from RCC_MSIRANGE_0 to RCC_MSIRANGE_11
|
||||
* @retval HAL status
|
||||
*/
|
||||
static HAL_StatusTypeDef RCC_SetFlashLatencyFromMSIRange(uint32_t msirange)
|
||||
{
|
||||
uint32_t vos;
|
||||
uint32_t latency = FLASH_LATENCY_0; /* default value 0WS */
|
||||
|
||||
if(__HAL_RCC_PWR_IS_CLK_ENABLED())
|
||||
{
|
||||
vos = HAL_PWREx_GetVoltageRange();
|
||||
}
|
||||
else
|
||||
{
|
||||
__HAL_RCC_PWR_CLK_ENABLE();
|
||||
vos = HAL_PWREx_GetVoltageRange();
|
||||
__HAL_RCC_PWR_CLK_DISABLE();
|
||||
}
|
||||
|
||||
if(vos == PWR_REGULATOR_VOLTAGE_SCALE1)
|
||||
{
|
||||
if(msirange > RCC_MSIRANGE_8)
|
||||
{
|
||||
/* MSI > 16Mhz */
|
||||
if(msirange > RCC_MSIRANGE_10)
|
||||
{
|
||||
/* MSI 48Mhz */
|
||||
latency = FLASH_LATENCY_2; /* 2WS */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* MSI 24Mhz or 32Mhz */
|
||||
latency = FLASH_LATENCY_1; /* 1WS */
|
||||
}
|
||||
}
|
||||
/* else MSI <= 16Mhz default FLASH_LATENCY_0 0WS */
|
||||
}
|
||||
else
|
||||
{
|
||||
#if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || \
|
||||
defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
|
||||
if(msirange >= RCC_MSIRANGE_8)
|
||||
{
|
||||
/* MSI >= 16Mhz */
|
||||
latency = FLASH_LATENCY_2; /* 2WS */
|
||||
}
|
||||
else
|
||||
{
|
||||
if(msirange == RCC_MSIRANGE_7)
|
||||
{
|
||||
/* MSI 8Mhz */
|
||||
latency = FLASH_LATENCY_1; /* 1WS */
|
||||
}
|
||||
/* else MSI < 8Mhz default FLASH_LATENCY_0 0WS */
|
||||
}
|
||||
#else
|
||||
if(msirange > RCC_MSIRANGE_8)
|
||||
{
|
||||
/* MSI > 16Mhz */
|
||||
latency = FLASH_LATENCY_3; /* 3WS */
|
||||
}
|
||||
else
|
||||
{
|
||||
if(msirange == RCC_MSIRANGE_8)
|
||||
{
|
||||
/* MSI 16Mhz */
|
||||
latency = FLASH_LATENCY_2; /* 2WS */
|
||||
}
|
||||
else if(msirange == RCC_MSIRANGE_7)
|
||||
{
|
||||
/* MSI 8Mhz */
|
||||
latency = FLASH_LATENCY_1; /* 1WS */
|
||||
}
|
||||
/* else MSI < 8Mhz default FLASH_LATENCY_0 0WS */
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
__HAL_FLASH_SET_LATENCY(latency);
|
||||
|
||||
/* Check that the new number of wait states is taken into account to access the Flash
|
||||
memory by reading the FLASH_ACR register */
|
||||
if(__HAL_FLASH_GET_LATENCY() != latency)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
#if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || \
|
||||
defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
|
||||
/**
|
||||
* @brief Compute SYSCLK frequency based on PLL SYSCLK source.
|
||||
* @retval SYSCLK frequency
|
||||
*/
|
||||
static uint32_t RCC_GetSysClockFreqFromPLLSource(void)
|
||||
{
|
||||
uint32_t msirange = 0U;
|
||||
uint32_t pllvco, pllsource, pllr, pllm, sysclockfreq; /* no init needed */
|
||||
|
||||
if(__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_MSI)
|
||||
{
|
||||
/* Get MSI range source */
|
||||
if(READ_BIT(RCC->CR, RCC_CR_MSIRGSEL) == 0U)
|
||||
{ /* MSISRANGE from RCC_CSR applies */
|
||||
msirange = READ_BIT(RCC->CSR, RCC_CSR_MSISRANGE) >> RCC_CSR_MSISRANGE_Pos;
|
||||
}
|
||||
else
|
||||
{ /* MSIRANGE from RCC_CR applies */
|
||||
msirange = READ_BIT(RCC->CR, RCC_CR_MSIRANGE) >> RCC_CR_MSIRANGE_Pos;
|
||||
}
|
||||
/*MSI frequency range in HZ*/
|
||||
msirange = MSIRangeTable[msirange];
|
||||
}
|
||||
|
||||
/* PLL_VCO = (HSE_VALUE or HSI_VALUE or MSI_VALUE) * PLLN / PLLM
|
||||
SYSCLK = PLL_VCO / PLLR
|
||||
*/
|
||||
pllsource = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC);
|
||||
|
||||
switch (pllsource)
|
||||
{
|
||||
case RCC_PLLSOURCE_HSI: /* HSI used as PLL clock source */
|
||||
pllvco = HSI_VALUE;
|
||||
break;
|
||||
|
||||
case RCC_PLLSOURCE_HSE: /* HSE used as PLL clock source */
|
||||
pllvco = HSE_VALUE;
|
||||
break;
|
||||
|
||||
case RCC_PLLSOURCE_MSI: /* MSI used as PLL clock source */
|
||||
default:
|
||||
pllvco = msirange;
|
||||
break;
|
||||
}
|
||||
pllm = (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U ;
|
||||
pllvco = (pllvco * (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos)) / pllm;
|
||||
pllr = ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLR) >> RCC_PLLCFGR_PLLR_Pos) + 1U ) * 2U;
|
||||
sysclockfreq = pllvco / pllr;
|
||||
|
||||
return sysclockfreq;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* HAL_RCC_MODULE_ENABLED */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
@@ -1,3552 +0,0 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32l4xx_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 extended peripheral:
|
||||
* + Extended Peripheral Control functions
|
||||
* + Extended Clock management functions
|
||||
* + Extended Clock Recovery System Control functions
|
||||
*
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2017 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file in
|
||||
* the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32l4xx_hal.h"
|
||||
|
||||
/** @addtogroup STM32L4xx_HAL_Driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup RCCEx RCCEx
|
||||
* @brief RCC Extended HAL module driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifdef HAL_RCC_MODULE_ENABLED
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private defines -----------------------------------------------------------*/
|
||||
/** @defgroup RCCEx_Private_Constants RCCEx Private Constants
|
||||
* @{
|
||||
*/
|
||||
#define PLLSAI1_TIMEOUT_VALUE 2U /* 2 ms (minimum Tick + 1) */
|
||||
#define PLLSAI2_TIMEOUT_VALUE 2U /* 2 ms (minimum Tick + 1) */
|
||||
#define PLL_TIMEOUT_VALUE 2U /* 2 ms (minimum Tick + 1) */
|
||||
|
||||
#define DIVIDER_P_UPDATE 0U
|
||||
#define DIVIDER_Q_UPDATE 1U
|
||||
#define DIVIDER_R_UPDATE 2U
|
||||
|
||||
#define __LSCO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
|
||||
#define LSCO_GPIO_PORT GPIOA
|
||||
#define LSCO_PIN GPIO_PIN_2
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private macros ------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/** @defgroup RCCEx_Private_Functions RCCEx Private Functions
|
||||
* @{
|
||||
*/
|
||||
#if defined(RCC_PLLSAI1_SUPPORT)
|
||||
|
||||
static HAL_StatusTypeDef RCCEx_PLLSAI1_Config(RCC_PLLSAI1InitTypeDef *PllSai1, uint32_t Divider);
|
||||
|
||||
#endif /* RCC_PLLSAI1_SUPPORT */
|
||||
|
||||
#if defined(RCC_PLLSAI2_SUPPORT)
|
||||
|
||||
static HAL_StatusTypeDef RCCEx_PLLSAI2_Config(RCC_PLLSAI2InitTypeDef *PllSai2, uint32_t Divider);
|
||||
|
||||
#endif /* RCC_PLLSAI2_SUPPORT */
|
||||
|
||||
#if defined(SAI1)
|
||||
|
||||
static uint32_t RCCEx_GetSAIxPeriphCLKFreq(uint32_t PeriphClk, uint32_t InputFrequency);
|
||||
|
||||
#endif /* SAI1 */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Exported functions --------------------------------------------------------*/
|
||||
|
||||
/** @defgroup RCCEx_Exported_Functions RCCEx Exported Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup RCCEx_Exported_Functions_Group1 Extended 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 Initialize the RCC extended peripherals clocks according to the specified
|
||||
* parameters in the RCC_PeriphCLKInitTypeDef.
|
||||
* @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that
|
||||
* contains a field PeriphClockSelection which can be a combination of the following values:
|
||||
* @arg @ref RCC_PERIPHCLK_RTC RTC peripheral clock
|
||||
* @arg @ref RCC_PERIPHCLK_ADC ADC peripheral clock
|
||||
@if STM32L462xx
|
||||
* @arg @ref RCC_PERIPHCLK_DFSDM1 DFSDM1 peripheral clock (only for devices with DFSDM1)
|
||||
@endif
|
||||
@if STM32L486xx
|
||||
* @arg @ref RCC_PERIPHCLK_DFSDM1 DFSDM1 peripheral clock (only for devices with DFSDM1)
|
||||
@endif
|
||||
@if STM32L4A6xx
|
||||
* @arg @ref RCC_PERIPHCLK_DFSDM1 DFSDM1 peripheral clock (only for devices with DFSDM1)
|
||||
@endif
|
||||
* @arg @ref RCC_PERIPHCLK_I2C1 I2C1 peripheral clock
|
||||
* @arg @ref RCC_PERIPHCLK_I2C2 I2C2 peripheral clock
|
||||
* @arg @ref RCC_PERIPHCLK_I2C3 I2C3 peripheral clock
|
||||
@if STM32L462xx
|
||||
* @arg @ref RCC_PERIPHCLK_I2C4 I2C4 peripheral clock (only for devices with I2C4)
|
||||
@endif
|
||||
@if STM32L4A6xx
|
||||
* @arg @ref RCC_PERIPHCLK_I2C4 I2C4 peripheral clock (only for devices with I2C4)
|
||||
@endif
|
||||
@if STM32L4S9xx
|
||||
* @arg @ref RCC_PERIPHCLK_I2C4 I2C4 peripheral clock (only for devices with I2C4)
|
||||
@endif
|
||||
* @arg @ref RCC_PERIPHCLK_LPTIM1 LPTIM1 peripheral clock
|
||||
* @arg @ref RCC_PERIPHCLK_LPTIM2 LPTIM2 peripheral clock
|
||||
* @arg @ref RCC_PERIPHCLK_LPUART1 LPUART1 peripheral clock
|
||||
* @arg @ref RCC_PERIPHCLK_RNG RNG peripheral clock
|
||||
* @arg @ref RCC_PERIPHCLK_SAI1 SAI1 peripheral clock (only for devices with SAI1)
|
||||
@if STM32L486xx
|
||||
* @arg @ref RCC_PERIPHCLK_SAI2 SAI2 peripheral clock (only for devices with SAI2)
|
||||
@endif
|
||||
@if STM32L4A6xx
|
||||
* @arg @ref RCC_PERIPHCLK_SAI2 SAI2 peripheral clock (only for devices with SAI2)
|
||||
@endif
|
||||
@if STM32L4S9xx
|
||||
* @arg @ref RCC_PERIPHCLK_SAI2 SAI2 peripheral clock (only for devices with SAI2)
|
||||
@endif
|
||||
* @arg @ref RCC_PERIPHCLK_SDMMC1 SDMMC1 peripheral clock
|
||||
@if STM32L443xx
|
||||
* @arg @ref RCC_PERIPHCLK_SWPMI1 SWPMI1 peripheral clock (only for devices with SWPMI1)
|
||||
@endif
|
||||
@if STM32L486xx
|
||||
* @arg @ref RCC_PERIPHCLK_SWPMI1 SWPMI1 peripheral clock (only for devices with SWPMI1)
|
||||
@endif
|
||||
@if STM32L4A6xx
|
||||
* @arg @ref RCC_PERIPHCLK_SWPMI1 SWPMI1 peripheral clock (only for devices with SWPMI1)
|
||||
@endif
|
||||
* @arg @ref RCC_PERIPHCLK_USART1 USART1 peripheral clock
|
||||
* @arg @ref RCC_PERIPHCLK_USART2 USART1 peripheral clock
|
||||
* @arg @ref RCC_PERIPHCLK_USART3 USART1 peripheral clock
|
||||
@if STM32L462xx
|
||||
* @arg @ref RCC_PERIPHCLK_UART4 USART1 peripheral clock (only for devices with UART4)
|
||||
@endif
|
||||
@if STM32L486xx
|
||||
* @arg @ref RCC_PERIPHCLK_UART4 USART1 peripheral clock (only for devices with UART4)
|
||||
* @arg @ref RCC_PERIPHCLK_UART5 USART1 peripheral clock (only for devices with UART5)
|
||||
* @arg @ref RCC_PERIPHCLK_USB USB peripheral clock (only for devices with USB)
|
||||
@endif
|
||||
@if STM32L4A6xx
|
||||
* @arg @ref RCC_PERIPHCLK_UART4 USART1 peripheral clock (only for devices with UART4)
|
||||
* @arg @ref RCC_PERIPHCLK_UART5 USART1 peripheral clock (only for devices with UART5)
|
||||
* @arg @ref RCC_PERIPHCLK_USB USB peripheral clock (only for devices with USB)
|
||||
@endif
|
||||
@if STM32L4S9xx
|
||||
* @arg @ref RCC_PERIPHCLK_UART4 USART1 peripheral clock (only for devices with UART4)
|
||||
* @arg @ref RCC_PERIPHCLK_UART5 USART1 peripheral clock (only for devices with UART5)
|
||||
* @arg @ref RCC_PERIPHCLK_USB USB peripheral clock (only for devices with USB)
|
||||
* @arg @ref RCC_PERIPHCLK_DFSDM1 DFSDM1 peripheral kernel clock (only for devices with DFSDM1)
|
||||
* @arg @ref RCC_PERIPHCLK_DFSDM1AUDIO DFSDM1 peripheral audio clock (only for devices with DFSDM1)
|
||||
* @arg @ref RCC_PERIPHCLK_LTDC LTDC peripheral clock (only for devices with LTDC)
|
||||
* @arg @ref RCC_PERIPHCLK_DSI DSI peripheral clock (only for devices with DSI)
|
||||
* @arg @ref RCC_PERIPHCLK_OSPI OctoSPI peripheral clock (only for devices with OctoSPI)
|
||||
@endif
|
||||
*
|
||||
* @note Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to select
|
||||
* the RTC clock source: in this case the access to Backup domain is enabled.
|
||||
*
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)
|
||||
{
|
||||
uint32_t tmpregister, tickstart; /* no init needed */
|
||||
HAL_StatusTypeDef ret = HAL_OK; /* Intermediate status */
|
||||
HAL_StatusTypeDef status = HAL_OK; /* Final status */
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_RCC_PERIPHCLOCK(PeriphClkInit->PeriphClockSelection));
|
||||
|
||||
#if defined(SAI1)
|
||||
|
||||
/*-------------------------- SAI1 clock source configuration ---------------------*/
|
||||
if((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI1) == RCC_PERIPHCLK_SAI1))
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_RCC_SAI1CLK(PeriphClkInit->Sai1ClockSelection));
|
||||
|
||||
switch(PeriphClkInit->Sai1ClockSelection)
|
||||
{
|
||||
case RCC_SAI1CLKSOURCE_PLL: /* PLL is used as clock source for SAI1*/
|
||||
/* Enable SAI Clock output generated from System PLL . */
|
||||
#if defined(RCC_PLLSAI2_SUPPORT)
|
||||
__HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_SAI3CLK);
|
||||
#else
|
||||
__HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_SAI2CLK);
|
||||
#endif /* RCC_PLLSAI2_SUPPORT */
|
||||
/* SAI1 clock source config set later after clock selection check */
|
||||
break;
|
||||
|
||||
case RCC_SAI1CLKSOURCE_PLLSAI1: /* PLLSAI1 is used as clock source for SAI1*/
|
||||
/* PLLSAI1 input clock, parameters M, N & P configuration and clock output (PLLSAI1ClockOut) */
|
||||
ret = RCCEx_PLLSAI1_Config(&(PeriphClkInit->PLLSAI1), DIVIDER_P_UPDATE);
|
||||
/* SAI1 clock source config set later after clock selection check */
|
||||
break;
|
||||
|
||||
#if defined(RCC_PLLSAI2_SUPPORT)
|
||||
|
||||
case RCC_SAI1CLKSOURCE_PLLSAI2: /* PLLSAI2 is used as clock source for SAI1*/
|
||||
/* PLLSAI2 input clock, parameters M, N & P configuration clock output (PLLSAI2ClockOut) */
|
||||
ret = RCCEx_PLLSAI2_Config(&(PeriphClkInit->PLLSAI2), DIVIDER_P_UPDATE);
|
||||
/* SAI1 clock source config set later after clock selection check */
|
||||
break;
|
||||
|
||||
#endif /* RCC_PLLSAI2_SUPPORT */
|
||||
|
||||
case RCC_SAI1CLKSOURCE_PIN: /* External clock is used as source of SAI1 clock*/
|
||||
#if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
|
||||
case RCC_SAI1CLKSOURCE_HSI: /* HSI is used as source of SAI1 clock*/
|
||||
#endif /* STM32L4P5xx || STM32L4Q5xx || STM32L4R5xx || STM32L4R7xx || STM32L4R9xx || STM32L4S5xx || STM32L4S7xx || STM32L4S9xx */
|
||||
/* SAI1 clock source config set later after clock selection check */
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = HAL_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
if(ret == HAL_OK)
|
||||
{
|
||||
/* Set the source of SAI1 clock*/
|
||||
__HAL_RCC_SAI1_CONFIG(PeriphClkInit->Sai1ClockSelection);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* set overall return value */
|
||||
status = ret;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* SAI1 */
|
||||
|
||||
#if defined(SAI2)
|
||||
|
||||
/*-------------------------- SAI2 clock source configuration ---------------------*/
|
||||
if((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI2) == RCC_PERIPHCLK_SAI2))
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_RCC_SAI2CLK(PeriphClkInit->Sai2ClockSelection));
|
||||
|
||||
switch(PeriphClkInit->Sai2ClockSelection)
|
||||
{
|
||||
case RCC_SAI2CLKSOURCE_PLL: /* PLL is used as clock source for SAI2*/
|
||||
/* Enable SAI Clock output generated from System PLL . */
|
||||
__HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_SAI3CLK);
|
||||
/* SAI2 clock source config set later after clock selection check */
|
||||
break;
|
||||
|
||||
case RCC_SAI2CLKSOURCE_PLLSAI1: /* PLLSAI1 is used as clock source for SAI2*/
|
||||
/* PLLSAI1 input clock, parameters M, N & P configuration and clock output (PLLSAI1ClockOut) */
|
||||
ret = RCCEx_PLLSAI1_Config(&(PeriphClkInit->PLLSAI1), DIVIDER_P_UPDATE);
|
||||
/* SAI2 clock source config set later after clock selection check */
|
||||
break;
|
||||
|
||||
case RCC_SAI2CLKSOURCE_PLLSAI2: /* PLLSAI2 is used as clock source for SAI2*/
|
||||
/* PLLSAI2 input clock, parameters M, N & P configuration and clock output (PLLSAI2ClockOut) */
|
||||
ret = RCCEx_PLLSAI2_Config(&(PeriphClkInit->PLLSAI2), DIVIDER_P_UPDATE);
|
||||
/* SAI2 clock source config set later after clock selection check */
|
||||
break;
|
||||
|
||||
case RCC_SAI2CLKSOURCE_PIN: /* External clock is used as source of SAI2 clock*/
|
||||
#if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
|
||||
case RCC_SAI2CLKSOURCE_HSI: /* HSI is used as source of SAI2 clock*/
|
||||
#endif /* STM32L4P5xx || STM32L4Q5xx || STM32L4R5xx || STM32L4R7xx || STM32L4R9xx || STM32L4S5xx || STM32L4S7xx || STM32L4S9xx */
|
||||
/* SAI2 clock source config set later after clock selection check */
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = HAL_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
if(ret == HAL_OK)
|
||||
{
|
||||
/* Set the source of SAI2 clock*/
|
||||
__HAL_RCC_SAI2_CONFIG(PeriphClkInit->Sai2ClockSelection);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* set overall return value */
|
||||
status = ret;
|
||||
}
|
||||
}
|
||||
#endif /* SAI2 */
|
||||
|
||||
/*-------------------------- RTC clock source configuration ----------------------*/
|
||||
if((PeriphClkInit->PeriphClockSelection & RCC_PERIPHCLK_RTC) == RCC_PERIPHCLK_RTC)
|
||||
{
|
||||
FlagStatus pwrclkchanged = RESET;
|
||||
|
||||
/* Check for RTC Parameters used to output RTCCLK */
|
||||
assert_param(IS_RCC_RTCCLKSOURCE(PeriphClkInit->RTCClockSelection));
|
||||
|
||||
/* Enable Power Clock */
|
||||
if(__HAL_RCC_PWR_IS_CLK_DISABLED() != 0U)
|
||||
{
|
||||
__HAL_RCC_PWR_CLK_ENABLE();
|
||||
pwrclkchanged = SET;
|
||||
}
|
||||
|
||||
/* Enable write access to Backup domain */
|
||||
SET_BIT(PWR->CR1, PWR_CR1_DBP);
|
||||
|
||||
/* Wait for Backup domain Write protection disable */
|
||||
tickstart = HAL_GetTick();
|
||||
|
||||
while(READ_BIT(PWR->CR1, PWR_CR1_DBP) == 0U)
|
||||
{
|
||||
if((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE)
|
||||
{
|
||||
ret = HAL_TIMEOUT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(ret == HAL_OK)
|
||||
{
|
||||
/* Reset the Backup domain only if the RTC Clock source selection is modified from default */
|
||||
tmpregister = READ_BIT(RCC->BDCR, RCC_BDCR_RTCSEL);
|
||||
|
||||
if((tmpregister != RCC_RTCCLKSOURCE_NONE) && (tmpregister != PeriphClkInit->RTCClockSelection))
|
||||
{
|
||||
/* Store the content of BDCR register before the reset of Backup Domain */
|
||||
tmpregister = READ_BIT(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 = tmpregister;
|
||||
}
|
||||
|
||||
/* Wait for LSE reactivation if LSE was enable prior to Backup Domain reset */
|
||||
if (HAL_IS_BIT_SET(tmpregister, RCC_BDCR_LSEON))
|
||||
{
|
||||
/* Get Start Tick*/
|
||||
tickstart = HAL_GetTick();
|
||||
|
||||
/* Wait till LSE is ready */
|
||||
while(READ_BIT(RCC->BDCR, RCC_BDCR_LSERDY) == 0U)
|
||||
{
|
||||
if((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
|
||||
{
|
||||
ret = HAL_TIMEOUT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(ret == HAL_OK)
|
||||
{
|
||||
/* Apply new RTC clock source selection */
|
||||
__HAL_RCC_RTC_CONFIG(PeriphClkInit->RTCClockSelection);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* set overall return value */
|
||||
status = ret;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* set overall return value */
|
||||
status = ret;
|
||||
}
|
||||
|
||||
/* Restore clock configuration if changed */
|
||||
if(pwrclkchanged == SET)
|
||||
{
|
||||
__HAL_RCC_PWR_CLK_DISABLE();
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------- USART1 clock source configuration -------------------*/
|
||||
if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USART1) == RCC_PERIPHCLK_USART1)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_RCC_USART1CLKSOURCE(PeriphClkInit->Usart1ClockSelection));
|
||||
|
||||
/* Configure the USART1 clock source */
|
||||
__HAL_RCC_USART1_CONFIG(PeriphClkInit->Usart1ClockSelection);
|
||||
}
|
||||
|
||||
/*-------------------------- USART2 clock source configuration -------------------*/
|
||||
if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USART2) == RCC_PERIPHCLK_USART2)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_RCC_USART2CLKSOURCE(PeriphClkInit->Usart2ClockSelection));
|
||||
|
||||
/* Configure the USART2 clock source */
|
||||
__HAL_RCC_USART2_CONFIG(PeriphClkInit->Usart2ClockSelection);
|
||||
}
|
||||
|
||||
#if defined(USART3)
|
||||
|
||||
/*-------------------------- USART3 clock source configuration -------------------*/
|
||||
if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USART3) == RCC_PERIPHCLK_USART3)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_RCC_USART3CLKSOURCE(PeriphClkInit->Usart3ClockSelection));
|
||||
|
||||
/* Configure the USART3 clock source */
|
||||
__HAL_RCC_USART3_CONFIG(PeriphClkInit->Usart3ClockSelection);
|
||||
}
|
||||
|
||||
#endif /* USART3 */
|
||||
|
||||
#if defined(UART4)
|
||||
|
||||
/*-------------------------- UART4 clock source configuration --------------------*/
|
||||
if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_UART4) == RCC_PERIPHCLK_UART4)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_RCC_UART4CLKSOURCE(PeriphClkInit->Uart4ClockSelection));
|
||||
|
||||
/* Configure the UART4 clock source */
|
||||
__HAL_RCC_UART4_CONFIG(PeriphClkInit->Uart4ClockSelection);
|
||||
}
|
||||
|
||||
#endif /* UART4 */
|
||||
|
||||
#if defined(UART5)
|
||||
|
||||
/*-------------------------- UART5 clock source configuration --------------------*/
|
||||
if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_UART5) == RCC_PERIPHCLK_UART5)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_RCC_UART5CLKSOURCE(PeriphClkInit->Uart5ClockSelection));
|
||||
|
||||
/* Configure the UART5 clock source */
|
||||
__HAL_RCC_UART5_CONFIG(PeriphClkInit->Uart5ClockSelection);
|
||||
}
|
||||
|
||||
#endif /* UART5 */
|
||||
|
||||
/*-------------------------- LPUART1 clock source configuration ------------------*/
|
||||
if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LPUART1) == RCC_PERIPHCLK_LPUART1)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_RCC_LPUART1CLKSOURCE(PeriphClkInit->Lpuart1ClockSelection));
|
||||
|
||||
/* Configure the LPUART1 clock source */
|
||||
__HAL_RCC_LPUART1_CONFIG(PeriphClkInit->Lpuart1ClockSelection);
|
||||
}
|
||||
|
||||
/*-------------------------- LPTIM1 clock source configuration -------------------*/
|
||||
if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LPTIM1) == (RCC_PERIPHCLK_LPTIM1))
|
||||
{
|
||||
assert_param(IS_RCC_LPTIM1CLK(PeriphClkInit->Lptim1ClockSelection));
|
||||
__HAL_RCC_LPTIM1_CONFIG(PeriphClkInit->Lptim1ClockSelection);
|
||||
}
|
||||
|
||||
/*-------------------------- LPTIM2 clock source configuration -------------------*/
|
||||
if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LPTIM2) == (RCC_PERIPHCLK_LPTIM2))
|
||||
{
|
||||
assert_param(IS_RCC_LPTIM2CLK(PeriphClkInit->Lptim2ClockSelection));
|
||||
__HAL_RCC_LPTIM2_CONFIG(PeriphClkInit->Lptim2ClockSelection);
|
||||
}
|
||||
|
||||
/*-------------------------- I2C1 clock source configuration ---------------------*/
|
||||
if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2C1) == RCC_PERIPHCLK_I2C1)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_RCC_I2C1CLKSOURCE(PeriphClkInit->I2c1ClockSelection));
|
||||
|
||||
/* Configure the I2C1 clock source */
|
||||
__HAL_RCC_I2C1_CONFIG(PeriphClkInit->I2c1ClockSelection);
|
||||
}
|
||||
|
||||
#if defined(I2C2)
|
||||
|
||||
/*-------------------------- I2C2 clock source configuration ---------------------*/
|
||||
if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2C2) == RCC_PERIPHCLK_I2C2)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_RCC_I2C2CLKSOURCE(PeriphClkInit->I2c2ClockSelection));
|
||||
|
||||
/* Configure the I2C2 clock source */
|
||||
__HAL_RCC_I2C2_CONFIG(PeriphClkInit->I2c2ClockSelection);
|
||||
}
|
||||
|
||||
#endif /* I2C2 */
|
||||
|
||||
/*-------------------------- I2C3 clock source configuration ---------------------*/
|
||||
if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2C3) == RCC_PERIPHCLK_I2C3)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_RCC_I2C3CLKSOURCE(PeriphClkInit->I2c3ClockSelection));
|
||||
|
||||
/* Configure the I2C3 clock source */
|
||||
__HAL_RCC_I2C3_CONFIG(PeriphClkInit->I2c3ClockSelection);
|
||||
}
|
||||
|
||||
#if defined(I2C4)
|
||||
|
||||
/*-------------------------- I2C4 clock source configuration ---------------------*/
|
||||
if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2C4) == RCC_PERIPHCLK_I2C4)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_RCC_I2C4CLKSOURCE(PeriphClkInit->I2c4ClockSelection));
|
||||
|
||||
/* Configure the I2C4 clock source */
|
||||
__HAL_RCC_I2C4_CONFIG(PeriphClkInit->I2c4ClockSelection);
|
||||
}
|
||||
|
||||
#endif /* I2C4 */
|
||||
|
||||
#if defined(USB_OTG_FS) || defined(USB)
|
||||
|
||||
/*-------------------------- USB clock source configuration ----------------------*/
|
||||
if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USB) == (RCC_PERIPHCLK_USB))
|
||||
{
|
||||
assert_param(IS_RCC_USBCLKSOURCE(PeriphClkInit->UsbClockSelection));
|
||||
__HAL_RCC_USB_CONFIG(PeriphClkInit->UsbClockSelection);
|
||||
|
||||
if(PeriphClkInit->UsbClockSelection == RCC_USBCLKSOURCE_PLL)
|
||||
{
|
||||
/* Enable PLL48M1CLK output clock */
|
||||
__HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_48M1CLK);
|
||||
}
|
||||
else
|
||||
{
|
||||
#if defined(RCC_PLLSAI1_SUPPORT)
|
||||
if(PeriphClkInit->UsbClockSelection == RCC_USBCLKSOURCE_PLLSAI1)
|
||||
{
|
||||
/* PLLSAI1 input clock, parameters M, N & Q configuration and clock output (PLLSAI1ClockOut) */
|
||||
ret = RCCEx_PLLSAI1_Config(&(PeriphClkInit->PLLSAI1), DIVIDER_Q_UPDATE);
|
||||
|
||||
if(ret != HAL_OK)
|
||||
{
|
||||
/* set overall return value */
|
||||
status = ret;
|
||||
}
|
||||
}
|
||||
#endif /* RCC_PLLSAI1_SUPPORT */
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* USB_OTG_FS || USB */
|
||||
|
||||
#if defined(SDMMC1)
|
||||
|
||||
/*-------------------------- SDMMC1 clock source configuration -------------------*/
|
||||
if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SDMMC1) == (RCC_PERIPHCLK_SDMMC1))
|
||||
{
|
||||
assert_param(IS_RCC_SDMMC1CLKSOURCE(PeriphClkInit->Sdmmc1ClockSelection));
|
||||
__HAL_RCC_SDMMC1_CONFIG(PeriphClkInit->Sdmmc1ClockSelection);
|
||||
|
||||
if(PeriphClkInit->Sdmmc1ClockSelection == RCC_SDMMC1CLKSOURCE_PLL) /* PLL "Q" ? */
|
||||
{
|
||||
/* Enable PLL48M1CLK output clock */
|
||||
__HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_48M1CLK);
|
||||
}
|
||||
#if defined(RCC_CCIPR2_SDMMCSEL)
|
||||
else if(PeriphClkInit->Sdmmc1ClockSelection == RCC_SDMMC1CLKSOURCE_PLLP) /* PLL "P" ? */
|
||||
{
|
||||
/* Enable PLLSAI3CLK output */
|
||||
__HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_SAI3CLK);
|
||||
}
|
||||
#endif
|
||||
else if(PeriphClkInit->Sdmmc1ClockSelection == RCC_SDMMC1CLKSOURCE_PLLSAI1)
|
||||
{
|
||||
/* PLLSAI1 input clock, parameters M, N & Q configuration and clock output (PLLSAI1ClockOut) */
|
||||
ret = RCCEx_PLLSAI1_Config(&(PeriphClkInit->PLLSAI1), DIVIDER_Q_UPDATE);
|
||||
|
||||
if(ret != HAL_OK)
|
||||
{
|
||||
/* set overall return value */
|
||||
status = ret;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* nothing to do */
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* SDMMC1 */
|
||||
|
||||
/*-------------------------- RNG clock source configuration ----------------------*/
|
||||
if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RNG) == (RCC_PERIPHCLK_RNG))
|
||||
{
|
||||
assert_param(IS_RCC_RNGCLKSOURCE(PeriphClkInit->RngClockSelection));
|
||||
__HAL_RCC_RNG_CONFIG(PeriphClkInit->RngClockSelection);
|
||||
|
||||
if(PeriphClkInit->RngClockSelection == RCC_RNGCLKSOURCE_PLL)
|
||||
{
|
||||
/* Enable PLL48M1CLK output clock */
|
||||
__HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_48M1CLK);
|
||||
}
|
||||
#if defined(RCC_PLLSAI1_SUPPORT)
|
||||
else if(PeriphClkInit->RngClockSelection == RCC_RNGCLKSOURCE_PLLSAI1)
|
||||
{
|
||||
/* PLLSAI1 input clock, parameters M, N & Q configuration and clock output (PLLSAI1ClockOut) */
|
||||
ret = RCCEx_PLLSAI1_Config(&(PeriphClkInit->PLLSAI1), DIVIDER_Q_UPDATE);
|
||||
|
||||
if(ret != HAL_OK)
|
||||
{
|
||||
/* set overall return value */
|
||||
status = ret;
|
||||
}
|
||||
}
|
||||
#endif /* RCC_PLLSAI1_SUPPORT */
|
||||
else
|
||||
{
|
||||
/* nothing to do */
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------- ADC clock source configuration ----------------------*/
|
||||
#if !defined(STM32L412xx) && !defined(STM32L422xx)
|
||||
if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_ADC) == RCC_PERIPHCLK_ADC)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_RCC_ADCCLKSOURCE(PeriphClkInit->AdcClockSelection));
|
||||
|
||||
/* Configure the ADC interface clock source */
|
||||
__HAL_RCC_ADC_CONFIG(PeriphClkInit->AdcClockSelection);
|
||||
|
||||
#if defined(RCC_PLLSAI1_SUPPORT)
|
||||
if(PeriphClkInit->AdcClockSelection == RCC_ADCCLKSOURCE_PLLSAI1)
|
||||
{
|
||||
/* PLLSAI1 input clock, parameters M, N & R configuration and clock output (PLLSAI1ClockOut) */
|
||||
ret = RCCEx_PLLSAI1_Config(&(PeriphClkInit->PLLSAI1), DIVIDER_R_UPDATE);
|
||||
|
||||
if(ret != HAL_OK)
|
||||
{
|
||||
/* set overall return value */
|
||||
status = ret;
|
||||
}
|
||||
}
|
||||
#endif /* RCC_PLLSAI1_SUPPORT */
|
||||
|
||||
#if defined(STM32L471xx) || defined(STM32L475xx) || defined(STM32L476xx) || defined(STM32L485xx) || defined(STM32L486xx) || defined(STM32L496xx) || defined(STM32L4A6xx)
|
||||
|
||||
else if(PeriphClkInit->AdcClockSelection == RCC_ADCCLKSOURCE_PLLSAI2)
|
||||
{
|
||||
/* PLLSAI2 input clock, parameters M, N & R configuration and clock output (PLLSAI2ClockOut) */
|
||||
ret = RCCEx_PLLSAI2_Config(&(PeriphClkInit->PLLSAI2), DIVIDER_R_UPDATE);
|
||||
|
||||
if(ret != HAL_OK)
|
||||
{
|
||||
/* set overall return value */
|
||||
status = ret;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* STM32L471xx || STM32L475xx || STM32L476xx || STM32L485xx || STM32L486xx || STM32L496xx || STM32L4A6xx */
|
||||
|
||||
}
|
||||
#endif /* !STM32L412xx && !STM32L422xx */
|
||||
|
||||
#if defined(SWPMI1)
|
||||
|
||||
/*-------------------------- SWPMI1 clock source configuration -------------------*/
|
||||
if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SWPMI1) == RCC_PERIPHCLK_SWPMI1)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_RCC_SWPMI1CLKSOURCE(PeriphClkInit->Swpmi1ClockSelection));
|
||||
|
||||
/* Configure the SWPMI1 clock source */
|
||||
__HAL_RCC_SWPMI1_CONFIG(PeriphClkInit->Swpmi1ClockSelection);
|
||||
}
|
||||
|
||||
#endif /* SWPMI1 */
|
||||
|
||||
#if defined(DFSDM1_Filter0)
|
||||
|
||||
/*-------------------------- DFSDM1 clock source configuration -------------------*/
|
||||
if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_DFSDM1) == RCC_PERIPHCLK_DFSDM1)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_RCC_DFSDM1CLKSOURCE(PeriphClkInit->Dfsdm1ClockSelection));
|
||||
|
||||
/* Configure the DFSDM1 interface clock source */
|
||||
__HAL_RCC_DFSDM1_CONFIG(PeriphClkInit->Dfsdm1ClockSelection);
|
||||
}
|
||||
|
||||
#if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
|
||||
/*-------------------------- DFSDM1 audio clock source configuration -------------*/
|
||||
if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_DFSDM1AUDIO) == RCC_PERIPHCLK_DFSDM1AUDIO)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_RCC_DFSDM1AUDIOCLKSOURCE(PeriphClkInit->Dfsdm1AudioClockSelection));
|
||||
|
||||
/* Configure the DFSDM1 interface audio clock source */
|
||||
__HAL_RCC_DFSDM1AUDIO_CONFIG(PeriphClkInit->Dfsdm1AudioClockSelection);
|
||||
}
|
||||
|
||||
#endif /* STM32L4P5xx || STM32L4Q5xx || STM32L4R5xx || STM32L4R7xx || STM32L4R9xx || STM32L4S5xx || STM32L4S7xx || STM32L4S9xx */
|
||||
|
||||
#endif /* DFSDM1_Filter0 */
|
||||
|
||||
#if defined(LTDC)
|
||||
|
||||
/*-------------------------- LTDC clock source configuration --------------------*/
|
||||
if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LTDC) == RCC_PERIPHCLK_LTDC)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_RCC_LTDCCLKSOURCE(PeriphClkInit->LtdcClockSelection));
|
||||
|
||||
/* Disable the PLLSAI2 */
|
||||
__HAL_RCC_PLLSAI2_DISABLE();
|
||||
|
||||
/* Get Start Tick*/
|
||||
tickstart = HAL_GetTick();
|
||||
|
||||
/* Wait till PLLSAI2 is ready */
|
||||
while(READ_BIT(RCC->CR, RCC_CR_PLLSAI2RDY) != 0U)
|
||||
{
|
||||
if((HAL_GetTick() - tickstart) > PLLSAI2_TIMEOUT_VALUE)
|
||||
{
|
||||
ret = HAL_TIMEOUT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(ret == HAL_OK)
|
||||
{
|
||||
/* Configure the LTDC clock source */
|
||||
__HAL_RCC_LTDC_CONFIG(PeriphClkInit->LtdcClockSelection);
|
||||
|
||||
/* PLLSAI2 input clock, parameters M, N & R configuration and clock output (PLLSAI2ClockOut) */
|
||||
ret = RCCEx_PLLSAI2_Config(&(PeriphClkInit->PLLSAI2), DIVIDER_R_UPDATE);
|
||||
}
|
||||
|
||||
if(ret != HAL_OK)
|
||||
{
|
||||
/* set overall return value */
|
||||
status = ret;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* LTDC */
|
||||
|
||||
#if defined(DSI)
|
||||
|
||||
/*-------------------------- DSI clock source configuration ---------------------*/
|
||||
if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_DSI) == RCC_PERIPHCLK_DSI)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_RCC_DSICLKSOURCE(PeriphClkInit->DsiClockSelection));
|
||||
|
||||
/* Configure the DSI clock source */
|
||||
__HAL_RCC_DSI_CONFIG(PeriphClkInit->DsiClockSelection);
|
||||
|
||||
if(PeriphClkInit->DsiClockSelection == RCC_DSICLKSOURCE_PLLSAI2)
|
||||
{
|
||||
/* PLLSAI2 input clock, parameters M, N & Q configuration and clock output (PLLSAI2ClockOut) */
|
||||
ret = RCCEx_PLLSAI2_Config(&(PeriphClkInit->PLLSAI2), DIVIDER_Q_UPDATE);
|
||||
|
||||
if(ret != HAL_OK)
|
||||
{
|
||||
/* set overall return value */
|
||||
status = ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* DSI */
|
||||
|
||||
#if defined(OCTOSPI1) || defined(OCTOSPI2)
|
||||
|
||||
/*-------------------------- OctoSPIx clock source configuration ----------------*/
|
||||
if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_OSPI) == RCC_PERIPHCLK_OSPI)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_RCC_OSPICLKSOURCE(PeriphClkInit->OspiClockSelection));
|
||||
|
||||
/* Configure the OctoSPI clock source */
|
||||
__HAL_RCC_OSPI_CONFIG(PeriphClkInit->OspiClockSelection);
|
||||
|
||||
if(PeriphClkInit->OspiClockSelection == RCC_OSPICLKSOURCE_PLL)
|
||||
{
|
||||
/* Enable PLL48M1CLK output */
|
||||
__HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_48M1CLK);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* OCTOSPI1 || OCTOSPI2 */
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the RCC_ClkInitStruct 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(SAI1, SAI2, LPTIM1, LPTIM2, I2C1, I2C2, I2C3, I2C4, LPUART1,
|
||||
* USART1, USART2, USART3, UART4, UART5, RTC, ADCx, DFSDMx, SWPMI1, USB, SDMMC1 and RNG).
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)
|
||||
{
|
||||
/* Set all possible values for the extended clock type parameter------------*/
|
||||
|
||||
#if defined(STM32L412xx) || defined(STM32L422xx)
|
||||
|
||||
PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_USART1 | RCC_PERIPHCLK_USART2 | RCC_PERIPHCLK_USART3 | \
|
||||
RCC_PERIPHCLK_LPUART1 | RCC_PERIPHCLK_I2C1 | RCC_PERIPHCLK_I2C2 | RCC_PERIPHCLK_I2C3 | \
|
||||
RCC_PERIPHCLK_LPTIM1 | RCC_PERIPHCLK_LPTIM2 | RCC_PERIPHCLK_USB | \
|
||||
RCC_PERIPHCLK_RNG | \
|
||||
RCC_PERIPHCLK_RTC ;
|
||||
|
||||
#elif defined(STM32L431xx)
|
||||
|
||||
PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_USART1 | RCC_PERIPHCLK_USART2 | RCC_PERIPHCLK_USART3 | \
|
||||
RCC_PERIPHCLK_LPUART1 | RCC_PERIPHCLK_I2C1 | RCC_PERIPHCLK_I2C2 | RCC_PERIPHCLK_I2C3 | \
|
||||
RCC_PERIPHCLK_LPTIM1 | RCC_PERIPHCLK_LPTIM2 | RCC_PERIPHCLK_SAI1 | \
|
||||
RCC_PERIPHCLK_SDMMC1 | RCC_PERIPHCLK_RNG | RCC_PERIPHCLK_ADC | RCC_PERIPHCLK_SWPMI1 | \
|
||||
RCC_PERIPHCLK_RTC ;
|
||||
|
||||
#elif defined(STM32L432xx) || defined(STM32L442xx)
|
||||
|
||||
PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_USART1 | RCC_PERIPHCLK_USART2 | \
|
||||
RCC_PERIPHCLK_LPUART1 | RCC_PERIPHCLK_I2C1 | RCC_PERIPHCLK_I2C3 | \
|
||||
RCC_PERIPHCLK_LPTIM1 | RCC_PERIPHCLK_LPTIM2 | RCC_PERIPHCLK_SAI1 | RCC_PERIPHCLK_USB | \
|
||||
RCC_PERIPHCLK_RNG | RCC_PERIPHCLK_ADC | RCC_PERIPHCLK_SWPMI1 | \
|
||||
RCC_PERIPHCLK_RTC ;
|
||||
|
||||
#elif defined(STM32L433xx) || defined(STM32L443xx)
|
||||
|
||||
PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_USART1 | RCC_PERIPHCLK_USART2 | RCC_PERIPHCLK_USART3 | \
|
||||
RCC_PERIPHCLK_LPUART1 | RCC_PERIPHCLK_I2C1 | RCC_PERIPHCLK_I2C2 | RCC_PERIPHCLK_I2C3 | \
|
||||
RCC_PERIPHCLK_LPTIM1 | RCC_PERIPHCLK_LPTIM2 | RCC_PERIPHCLK_SAI1 | RCC_PERIPHCLK_USB | \
|
||||
RCC_PERIPHCLK_SDMMC1 | RCC_PERIPHCLK_RNG | RCC_PERIPHCLK_ADC | RCC_PERIPHCLK_SWPMI1 | \
|
||||
RCC_PERIPHCLK_RTC ;
|
||||
|
||||
#elif defined(STM32L451xx)
|
||||
|
||||
PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_USART1 | RCC_PERIPHCLK_USART2 | RCC_PERIPHCLK_USART3 | RCC_PERIPHCLK_UART4 | \
|
||||
RCC_PERIPHCLK_LPUART1 | RCC_PERIPHCLK_I2C1 | RCC_PERIPHCLK_I2C2 | RCC_PERIPHCLK_I2C3 | RCC_PERIPHCLK_I2C4 | \
|
||||
RCC_PERIPHCLK_LPTIM1 | RCC_PERIPHCLK_LPTIM2 | RCC_PERIPHCLK_SAI1 | \
|
||||
RCC_PERIPHCLK_SDMMC1 | RCC_PERIPHCLK_RNG | RCC_PERIPHCLK_ADC | RCC_PERIPHCLK_DFSDM1 | \
|
||||
RCC_PERIPHCLK_RTC ;
|
||||
|
||||
#elif defined(STM32L452xx) || defined(STM32L462xx)
|
||||
|
||||
PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_USART1 | RCC_PERIPHCLK_USART2 | RCC_PERIPHCLK_USART3 | RCC_PERIPHCLK_UART4 | \
|
||||
RCC_PERIPHCLK_LPUART1 | RCC_PERIPHCLK_I2C1 | RCC_PERIPHCLK_I2C2 | RCC_PERIPHCLK_I2C3 | RCC_PERIPHCLK_I2C4 | \
|
||||
RCC_PERIPHCLK_LPTIM1 | RCC_PERIPHCLK_LPTIM2 | RCC_PERIPHCLK_SAI1 | RCC_PERIPHCLK_USB | \
|
||||
RCC_PERIPHCLK_SDMMC1 | RCC_PERIPHCLK_RNG | RCC_PERIPHCLK_ADC | RCC_PERIPHCLK_DFSDM1 | \
|
||||
RCC_PERIPHCLK_RTC ;
|
||||
|
||||
#elif defined(STM32L471xx)
|
||||
|
||||
PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_USART1 | RCC_PERIPHCLK_USART2 | RCC_PERIPHCLK_USART3 | RCC_PERIPHCLK_UART4 | RCC_PERIPHCLK_UART5 | \
|
||||
RCC_PERIPHCLK_LPUART1 | RCC_PERIPHCLK_I2C1 | RCC_PERIPHCLK_I2C2 | RCC_PERIPHCLK_I2C3 | \
|
||||
RCC_PERIPHCLK_LPTIM1 | RCC_PERIPHCLK_LPTIM2 | RCC_PERIPHCLK_SAI1 | RCC_PERIPHCLK_SAI2 | \
|
||||
RCC_PERIPHCLK_SDMMC1 | RCC_PERIPHCLK_RNG | RCC_PERIPHCLK_ADC | RCC_PERIPHCLK_SWPMI1 | RCC_PERIPHCLK_DFSDM1 | \
|
||||
RCC_PERIPHCLK_RTC ;
|
||||
|
||||
#elif defined(STM32L475xx) || defined(STM32L476xx) || defined(STM32L485xx) || defined(STM32L486xx)
|
||||
|
||||
PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_USART1 | RCC_PERIPHCLK_USART2 | RCC_PERIPHCLK_USART3 | RCC_PERIPHCLK_UART4 | RCC_PERIPHCLK_UART5 | \
|
||||
RCC_PERIPHCLK_LPUART1 | RCC_PERIPHCLK_I2C1 | RCC_PERIPHCLK_I2C2 | RCC_PERIPHCLK_I2C3 | \
|
||||
RCC_PERIPHCLK_LPTIM1 | RCC_PERIPHCLK_LPTIM2 | RCC_PERIPHCLK_SAI1 | RCC_PERIPHCLK_SAI2 | RCC_PERIPHCLK_USB | \
|
||||
RCC_PERIPHCLK_SDMMC1 | RCC_PERIPHCLK_RNG | RCC_PERIPHCLK_ADC | RCC_PERIPHCLK_SWPMI1 | RCC_PERIPHCLK_DFSDM1 | \
|
||||
RCC_PERIPHCLK_RTC ;
|
||||
|
||||
#elif defined(STM32L496xx) || defined(STM32L4A6xx)
|
||||
|
||||
PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_USART1 | RCC_PERIPHCLK_USART2 | RCC_PERIPHCLK_USART3 | RCC_PERIPHCLK_UART4 | RCC_PERIPHCLK_UART5 | \
|
||||
RCC_PERIPHCLK_LPUART1 | RCC_PERIPHCLK_I2C1 | RCC_PERIPHCLK_I2C2 | RCC_PERIPHCLK_I2C3 | RCC_PERIPHCLK_I2C4 | \
|
||||
RCC_PERIPHCLK_LPTIM1 | RCC_PERIPHCLK_LPTIM2 | RCC_PERIPHCLK_SAI1 | RCC_PERIPHCLK_SAI2 | RCC_PERIPHCLK_USB | \
|
||||
RCC_PERIPHCLK_SDMMC1 | RCC_PERIPHCLK_RNG | RCC_PERIPHCLK_ADC | RCC_PERIPHCLK_SWPMI1 | RCC_PERIPHCLK_DFSDM1 | \
|
||||
RCC_PERIPHCLK_RTC ;
|
||||
|
||||
#elif defined(STM32L4R5xx) || defined(STM32L4S5xx)
|
||||
|
||||
PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_USART1 | RCC_PERIPHCLK_USART2 | RCC_PERIPHCLK_USART3 | RCC_PERIPHCLK_UART4 | RCC_PERIPHCLK_UART5 | \
|
||||
RCC_PERIPHCLK_LPUART1 | RCC_PERIPHCLK_I2C1 | RCC_PERIPHCLK_I2C2 | RCC_PERIPHCLK_I2C3 | RCC_PERIPHCLK_I2C4 | \
|
||||
RCC_PERIPHCLK_LPTIM1 | RCC_PERIPHCLK_LPTIM2 | RCC_PERIPHCLK_SAI1 | RCC_PERIPHCLK_SAI2 | RCC_PERIPHCLK_USB | \
|
||||
RCC_PERIPHCLK_SDMMC1 | RCC_PERIPHCLK_RNG | RCC_PERIPHCLK_ADC | RCC_PERIPHCLK_DFSDM1 | \
|
||||
RCC_PERIPHCLK_DFSDM1AUDIO | RCC_PERIPHCLK_RTC | RCC_PERIPHCLK_OSPI;
|
||||
|
||||
#elif defined(STM32L4R7xx) || defined(STM32L4S7xx) || defined(STM32L4Q5xx)
|
||||
|
||||
PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_USART1 | RCC_PERIPHCLK_USART2 | RCC_PERIPHCLK_USART3 | RCC_PERIPHCLK_UART4 | RCC_PERIPHCLK_UART5 | \
|
||||
RCC_PERIPHCLK_LPUART1 | RCC_PERIPHCLK_I2C1 | RCC_PERIPHCLK_I2C2 | RCC_PERIPHCLK_I2C3 | RCC_PERIPHCLK_I2C4 | \
|
||||
RCC_PERIPHCLK_LPTIM1 | RCC_PERIPHCLK_LPTIM2 | RCC_PERIPHCLK_SAI1 | RCC_PERIPHCLK_SAI2 | RCC_PERIPHCLK_USB | \
|
||||
RCC_PERIPHCLK_SDMMC1 | RCC_PERIPHCLK_RNG | RCC_PERIPHCLK_ADC | RCC_PERIPHCLK_DFSDM1 | \
|
||||
RCC_PERIPHCLK_DFSDM1AUDIO | RCC_PERIPHCLK_RTC | RCC_PERIPHCLK_OSPI | RCC_PERIPHCLK_LTDC;
|
||||
|
||||
#elif defined(STM32L4R9xx) || defined(STM32L4S9xx)
|
||||
|
||||
PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_USART1 | RCC_PERIPHCLK_USART2 | RCC_PERIPHCLK_USART3 | RCC_PERIPHCLK_UART4 | RCC_PERIPHCLK_UART5 | \
|
||||
RCC_PERIPHCLK_LPUART1 | RCC_PERIPHCLK_I2C1 | RCC_PERIPHCLK_I2C2 | RCC_PERIPHCLK_I2C3 | RCC_PERIPHCLK_I2C4 | \
|
||||
RCC_PERIPHCLK_LPTIM1 | RCC_PERIPHCLK_LPTIM2 | RCC_PERIPHCLK_SAI1 | RCC_PERIPHCLK_SAI2 | RCC_PERIPHCLK_USB | \
|
||||
RCC_PERIPHCLK_SDMMC1 | RCC_PERIPHCLK_RNG | RCC_PERIPHCLK_ADC | RCC_PERIPHCLK_DFSDM1 | \
|
||||
RCC_PERIPHCLK_DFSDM1AUDIO | RCC_PERIPHCLK_RTC | RCC_PERIPHCLK_OSPI | RCC_PERIPHCLK_LTDC | RCC_PERIPHCLK_DSI;
|
||||
|
||||
#endif /* STM32L431xx */
|
||||
|
||||
#if defined(RCC_PLLSAI1_SUPPORT)
|
||||
|
||||
/* Get the PLLSAI1 Clock configuration -----------------------------------------------*/
|
||||
|
||||
PeriphClkInit->PLLSAI1.PLLSAI1Source = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC) >> RCC_PLLCFGR_PLLSRC_Pos;
|
||||
#if defined(RCC_PLLSAI1M_DIV_1_16_SUPPORT)
|
||||
PeriphClkInit->PLLSAI1.PLLSAI1M = (READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1M) >> RCC_PLLSAI1CFGR_PLLSAI1M_Pos) + 1U;
|
||||
#else
|
||||
PeriphClkInit->PLLSAI1.PLLSAI1M = (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U;
|
||||
#endif /* RCC_PLLSAI1M_DIV_1_16_SUPPORT */
|
||||
PeriphClkInit->PLLSAI1.PLLSAI1N = READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1N) >> RCC_PLLSAI1CFGR_PLLSAI1N_Pos;
|
||||
PeriphClkInit->PLLSAI1.PLLSAI1P = ((READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1P) >> RCC_PLLSAI1CFGR_PLLSAI1P_Pos) << 4U) + 7U;
|
||||
PeriphClkInit->PLLSAI1.PLLSAI1Q = ((READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1Q) >> RCC_PLLSAI1CFGR_PLLSAI1Q_Pos) + 1U) * 2U;
|
||||
PeriphClkInit->PLLSAI1.PLLSAI1R = ((READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1R) >> RCC_PLLSAI1CFGR_PLLSAI1R_Pos) + 1U) * 2U;
|
||||
|
||||
#endif /* RCC_PLLSAI1_SUPPORT */
|
||||
|
||||
#if defined(RCC_PLLSAI2_SUPPORT)
|
||||
|
||||
/* Get the PLLSAI2 Clock configuration -----------------------------------------------*/
|
||||
|
||||
PeriphClkInit->PLLSAI2.PLLSAI2Source = PeriphClkInit->PLLSAI1.PLLSAI1Source;
|
||||
#if defined(RCC_PLLSAI2M_DIV_1_16_SUPPORT)
|
||||
PeriphClkInit->PLLSAI2.PLLSAI2M = (READ_BIT(RCC->PLLSAI2CFGR, RCC_PLLSAI2CFGR_PLLSAI2M) >> RCC_PLLSAI2CFGR_PLLSAI2M_Pos) + 1U;
|
||||
#else
|
||||
PeriphClkInit->PLLSAI2.PLLSAI2M = PeriphClkInit->PLLSAI1.PLLSAI1M;
|
||||
#endif /* RCC_PLLSAI2M_DIV_1_16_SUPPORT */
|
||||
PeriphClkInit->PLLSAI2.PLLSAI2N = READ_BIT(RCC->PLLSAI2CFGR, RCC_PLLSAI2CFGR_PLLSAI2N) >> RCC_PLLSAI2CFGR_PLLSAI2N_Pos;
|
||||
PeriphClkInit->PLLSAI2.PLLSAI2P = ((READ_BIT(RCC->PLLSAI2CFGR, RCC_PLLSAI2CFGR_PLLSAI2P) >> RCC_PLLSAI2CFGR_PLLSAI2P_Pos) << 4U) + 7U;
|
||||
#if defined(RCC_PLLSAI2Q_DIV_SUPPORT)
|
||||
PeriphClkInit->PLLSAI2.PLLSAI2Q = ((READ_BIT(RCC->PLLSAI2CFGR, RCC_PLLSAI2CFGR_PLLSAI2Q) >> RCC_PLLSAI2CFGR_PLLSAI2Q_Pos) + 1U) * 2U;
|
||||
#endif /* RCC_PLLSAI2Q_DIV_SUPPORT */
|
||||
PeriphClkInit->PLLSAI2.PLLSAI2R = ((READ_BIT(RCC->PLLSAI2CFGR, RCC_PLLSAI2CFGR_PLLSAI2R)>> RCC_PLLSAI2CFGR_PLLSAI2R_Pos) + 1U) * 2U;
|
||||
|
||||
#endif /* RCC_PLLSAI2_SUPPORT */
|
||||
|
||||
/* Get the USART1 clock source ---------------------------------------------*/
|
||||
PeriphClkInit->Usart1ClockSelection = __HAL_RCC_GET_USART1_SOURCE();
|
||||
/* Get the USART2 clock source ---------------------------------------------*/
|
||||
PeriphClkInit->Usart2ClockSelection = __HAL_RCC_GET_USART2_SOURCE();
|
||||
|
||||
#if defined(USART3)
|
||||
/* Get the USART3 clock source ---------------------------------------------*/
|
||||
PeriphClkInit->Usart3ClockSelection = __HAL_RCC_GET_USART3_SOURCE();
|
||||
#endif /* USART3 */
|
||||
|
||||
#if defined(UART4)
|
||||
/* Get the UART4 clock source ----------------------------------------------*/
|
||||
PeriphClkInit->Uart4ClockSelection = __HAL_RCC_GET_UART4_SOURCE();
|
||||
#endif /* UART4 */
|
||||
|
||||
#if defined(UART5)
|
||||
/* Get the UART5 clock source ----------------------------------------------*/
|
||||
PeriphClkInit->Uart5ClockSelection = __HAL_RCC_GET_UART5_SOURCE();
|
||||
#endif /* UART5 */
|
||||
|
||||
/* Get the LPUART1 clock source --------------------------------------------*/
|
||||
PeriphClkInit->Lpuart1ClockSelection = __HAL_RCC_GET_LPUART1_SOURCE();
|
||||
|
||||
/* Get the I2C1 clock source -----------------------------------------------*/
|
||||
PeriphClkInit->I2c1ClockSelection = __HAL_RCC_GET_I2C1_SOURCE();
|
||||
|
||||
#if defined(I2C2)
|
||||
/* Get the I2C2 clock source ----------------------------------------------*/
|
||||
PeriphClkInit->I2c2ClockSelection = __HAL_RCC_GET_I2C2_SOURCE();
|
||||
#endif /* I2C2 */
|
||||
|
||||
/* Get the I2C3 clock source -----------------------------------------------*/
|
||||
PeriphClkInit->I2c3ClockSelection = __HAL_RCC_GET_I2C3_SOURCE();
|
||||
|
||||
#if defined(I2C4)
|
||||
/* Get the I2C4 clock source -----------------------------------------------*/
|
||||
PeriphClkInit->I2c4ClockSelection = __HAL_RCC_GET_I2C4_SOURCE();
|
||||
#endif /* I2C4 */
|
||||
|
||||
/* Get the LPTIM1 clock source ---------------------------------------------*/
|
||||
PeriphClkInit->Lptim1ClockSelection = __HAL_RCC_GET_LPTIM1_SOURCE();
|
||||
|
||||
/* Get the LPTIM2 clock source ---------------------------------------------*/
|
||||
PeriphClkInit->Lptim2ClockSelection = __HAL_RCC_GET_LPTIM2_SOURCE();
|
||||
|
||||
#if defined(SAI1)
|
||||
/* Get the SAI1 clock source -----------------------------------------------*/
|
||||
PeriphClkInit->Sai1ClockSelection = __HAL_RCC_GET_SAI1_SOURCE();
|
||||
#endif /* SAI1 */
|
||||
|
||||
#if defined(SAI2)
|
||||
/* Get the SAI2 clock source -----------------------------------------------*/
|
||||
PeriphClkInit->Sai2ClockSelection = __HAL_RCC_GET_SAI2_SOURCE();
|
||||
#endif /* SAI2 */
|
||||
|
||||
/* Get the RTC clock source ------------------------------------------------*/
|
||||
PeriphClkInit->RTCClockSelection = __HAL_RCC_GET_RTC_SOURCE();
|
||||
|
||||
#if defined(USB_OTG_FS) || defined(USB)
|
||||
/* Get the USB clock source ------------------------------------------------*/
|
||||
PeriphClkInit->UsbClockSelection = __HAL_RCC_GET_USB_SOURCE();
|
||||
#endif /* USB_OTG_FS || USB */
|
||||
|
||||
#if defined(SDMMC1)
|
||||
/* Get the SDMMC1 clock source ---------------------------------------------*/
|
||||
PeriphClkInit->Sdmmc1ClockSelection = __HAL_RCC_GET_SDMMC1_SOURCE();
|
||||
#endif /* SDMMC1 */
|
||||
|
||||
/* Get the RNG clock source ------------------------------------------------*/
|
||||
PeriphClkInit->RngClockSelection = __HAL_RCC_GET_RNG_SOURCE();
|
||||
|
||||
#if !defined(STM32L412xx) && !defined(STM32L422xx)
|
||||
/* Get the ADC clock source ------------------------------------------------*/
|
||||
PeriphClkInit->AdcClockSelection = __HAL_RCC_GET_ADC_SOURCE();
|
||||
#endif /* !STM32L412xx && !STM32L422xx */
|
||||
|
||||
#if defined(SWPMI1)
|
||||
/* Get the SWPMI1 clock source ---------------------------------------------*/
|
||||
PeriphClkInit->Swpmi1ClockSelection = __HAL_RCC_GET_SWPMI1_SOURCE();
|
||||
#endif /* SWPMI1 */
|
||||
|
||||
#if defined(DFSDM1_Filter0)
|
||||
/* Get the DFSDM1 clock source ---------------------------------------------*/
|
||||
PeriphClkInit->Dfsdm1ClockSelection = __HAL_RCC_GET_DFSDM1_SOURCE();
|
||||
|
||||
#if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
|
||||
/* Get the DFSDM1 audio clock source ---------------------------------------*/
|
||||
PeriphClkInit->Dfsdm1AudioClockSelection = __HAL_RCC_GET_DFSDM1AUDIO_SOURCE();
|
||||
#endif /* STM32L4R5xx || STM32L4R7xx || STM32L4R9xx || STM32L4S5xx || STM32L4S7xx || STM32L4S9xx */
|
||||
#endif /* DFSDM1_Filter0 */
|
||||
|
||||
#if defined(LTDC)
|
||||
/* Get the LTDC clock source -----------------------------------------------*/
|
||||
PeriphClkInit->LtdcClockSelection = __HAL_RCC_GET_LTDC_SOURCE();
|
||||
#endif /* LTDC */
|
||||
|
||||
#if defined(DSI)
|
||||
/* Get the DSI clock source ------------------------------------------------*/
|
||||
PeriphClkInit->DsiClockSelection = __HAL_RCC_GET_DSI_SOURCE();
|
||||
#endif /* DSI */
|
||||
|
||||
#if defined(OCTOSPI1) || defined(OCTOSPI2)
|
||||
/* Get the OctoSPIclock source --------------------------------------------*/
|
||||
PeriphClkInit->OspiClockSelection = __HAL_RCC_GET_OSPI_SOURCE();
|
||||
#endif /* OCTOSPI1 || OCTOSPI2 */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the peripheral clock frequency for peripherals with clock source from PLLSAIs
|
||||
* @note Return 0 if peripheral clock identifier not managed by this API
|
||||
* @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 STM32L462xx
|
||||
* @arg @ref RCC_PERIPHCLK_DFSDM1 DFSDM1 peripheral clock (only for devices with DFSDM)
|
||||
@endif
|
||||
@if STM32L486xx
|
||||
* @arg @ref RCC_PERIPHCLK_DFSDM1 DFSDM1 peripheral clock (only for devices with DFSDM)
|
||||
@endif
|
||||
@if STM32L4A6xx
|
||||
* @arg @ref RCC_PERIPHCLK_DFSDM1 DFSDM1 peripheral clock (only for devices with DFSDM)
|
||||
@endif
|
||||
* @arg @ref RCC_PERIPHCLK_I2C1 I2C1 peripheral clock
|
||||
* @arg @ref RCC_PERIPHCLK_I2C2 I2C2 peripheral clock
|
||||
* @arg @ref RCC_PERIPHCLK_I2C3 I2C3 peripheral clock
|
||||
@if STM32L462xx
|
||||
* @arg @ref RCC_PERIPHCLK_I2C4 I2C4 peripheral clock (only for devices with I2C4)
|
||||
@endif
|
||||
@if STM32L4A6xx
|
||||
* @arg @ref RCC_PERIPHCLK_I2C4 I2C4 peripheral clock (only for devices with I2C4)
|
||||
@endif
|
||||
@if STM32L4S9xx
|
||||
* @arg @ref RCC_PERIPHCLK_I2C4 I2C4 peripheral clock (only for devices with I2C4)
|
||||
@endif
|
||||
* @arg @ref RCC_PERIPHCLK_LPTIM1 LPTIM1 peripheral clock
|
||||
* @arg @ref RCC_PERIPHCLK_LPTIM2 LPTIM2 peripheral clock
|
||||
* @arg @ref RCC_PERIPHCLK_LPUART1 LPUART1 peripheral clock
|
||||
* @arg @ref RCC_PERIPHCLK_RNG RNG peripheral clock
|
||||
* @arg @ref RCC_PERIPHCLK_SAI1 SAI1 peripheral clock (only for devices with SAI1)
|
||||
@if STM32L486xx
|
||||
* @arg @ref RCC_PERIPHCLK_SAI2 SAI2 peripheral clock (only for devices with SAI2)
|
||||
@endif
|
||||
@if STM32L4A6xx
|
||||
* @arg @ref RCC_PERIPHCLK_SAI2 SAI2 peripheral clock (only for devices with SAI2)
|
||||
@endif
|
||||
@if STM32L4S9xx
|
||||
* @arg @ref RCC_PERIPHCLK_SAI2 SAI2 peripheral clock (only for devices with SAI2)
|
||||
@endif
|
||||
* @arg @ref RCC_PERIPHCLK_SDMMC1 SDMMC1 peripheral clock
|
||||
@if STM32L443xx
|
||||
* @arg @ref RCC_PERIPHCLK_SWPMI1 SWPMI1 peripheral clock (only for devices with SWPMI1)
|
||||
@endif
|
||||
@if STM32L486xx
|
||||
* @arg @ref RCC_PERIPHCLK_SWPMI1 SWPMI1 peripheral clock (only for devices with SWPMI1)
|
||||
@endif
|
||||
@if STM32L4A6xx
|
||||
* @arg @ref RCC_PERIPHCLK_SWPMI1 SWPMI1 peripheral clock (only for devices with SWPMI1)
|
||||
@endif
|
||||
* @arg @ref RCC_PERIPHCLK_USART1 USART1 peripheral clock
|
||||
* @arg @ref RCC_PERIPHCLK_USART2 USART1 peripheral clock
|
||||
* @arg @ref RCC_PERIPHCLK_USART3 USART1 peripheral clock
|
||||
@if STM32L462xx
|
||||
* @arg @ref RCC_PERIPHCLK_UART4 UART4 peripheral clock (only for devices with UART4)
|
||||
* @arg @ref RCC_PERIPHCLK_USB USB peripheral clock (only for devices with USB)
|
||||
@endif
|
||||
@if STM32L486xx
|
||||
* @arg @ref RCC_PERIPHCLK_UART4 UART4 peripheral clock (only for devices with UART4)
|
||||
* @arg @ref RCC_PERIPHCLK_UART5 UART5 peripheral clock (only for devices with UART5)
|
||||
* @arg @ref RCC_PERIPHCLK_USB USB peripheral clock (only for devices with USB)
|
||||
@endif
|
||||
@if STM32L4A6xx
|
||||
* @arg @ref RCC_PERIPHCLK_UART4 UART4 peripheral clock (only for devices with UART4)
|
||||
* @arg @ref RCC_PERIPHCLK_UART5 UART5 peripheral clock (only for devices with UART5)
|
||||
* @arg @ref RCC_PERIPHCLK_USB USB peripheral clock (only for devices with USB)
|
||||
@endif
|
||||
@if STM32L4S9xx
|
||||
* @arg @ref RCC_PERIPHCLK_UART4 USART1 peripheral clock (only for devices with UART4)
|
||||
* @arg @ref RCC_PERIPHCLK_UART5 USART1 peripheral clock (only for devices with UART5)
|
||||
* @arg @ref RCC_PERIPHCLK_USB USB peripheral clock (only for devices with USB)
|
||||
* @arg @ref RCC_PERIPHCLK_DFSDM1 DFSDM1 peripheral kernel clock (only for devices with DFSDM1)
|
||||
* @arg @ref RCC_PERIPHCLK_DFSDM1AUDIO DFSDM1 peripheral audio clock (only for devices with DFSDM1)
|
||||
* @arg @ref RCC_PERIPHCLK_LTDC LTDC peripheral clock (only for devices with LTDC)
|
||||
* @arg @ref RCC_PERIPHCLK_DSI DSI peripheral clock (only for devices with DSI)
|
||||
* @arg @ref RCC_PERIPHCLK_OSPI OctoSPI peripheral clock (only for devices with OctoSPI)
|
||||
@endif
|
||||
* @retval Frequency in Hz
|
||||
*/
|
||||
uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk)
|
||||
{
|
||||
uint32_t frequency = 0U;
|
||||
uint32_t srcclk, pll_oscsource, pllvco, plln; /* no init needed */
|
||||
#if defined(SDMMC1) && defined(RCC_CCIPR2_SDMMCSEL)
|
||||
uint32_t pllp; /* no init needed */
|
||||
#endif
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_RCC_PERIPHCLOCK(PeriphClk));
|
||||
|
||||
if(PeriphClk == RCC_PERIPHCLK_RTC)
|
||||
{
|
||||
/* Get the current RTC source */
|
||||
srcclk = __HAL_RCC_GET_RTC_SOURCE();
|
||||
|
||||
switch(srcclk)
|
||||
{
|
||||
case RCC_RTCCLKSOURCE_LSE:
|
||||
/* Check if LSE is ready */
|
||||
if(HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY))
|
||||
{
|
||||
frequency = LSE_VALUE;
|
||||
}
|
||||
break;
|
||||
case RCC_RTCCLKSOURCE_LSI:
|
||||
/* Check if LSI is ready */
|
||||
if(HAL_IS_BIT_SET(RCC->CSR, RCC_CSR_LSIRDY))
|
||||
{
|
||||
#if defined(RCC_CSR_LSIPREDIV)
|
||||
if(HAL_IS_BIT_SET(RCC->CSR, RCC_CSR_LSIPREDIV))
|
||||
{
|
||||
frequency = LSI_VALUE/128U;
|
||||
}
|
||||
else
|
||||
#endif /* RCC_CSR_LSIPREDIV */
|
||||
{
|
||||
frequency = LSI_VALUE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case RCC_RTCCLKSOURCE_HSE_DIV32:
|
||||
/* Check if HSE is ready */
|
||||
if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSERDY))
|
||||
{
|
||||
frequency = HSE_VALUE / 32U;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* No clock source, frequency default init at 0 */
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Other external peripheral clock source than RTC */
|
||||
pll_oscsource = __HAL_RCC_GET_PLL_OSCSOURCE();
|
||||
|
||||
/* Compute PLL clock input */
|
||||
switch(pll_oscsource)
|
||||
{
|
||||
case RCC_PLLSOURCE_MSI: /* MSI ? */
|
||||
if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_MSIRDY))
|
||||
{
|
||||
/*MSI frequency range in HZ*/
|
||||
pllvco = MSIRangeTable[(__HAL_RCC_GET_MSI_RANGE() >> 4U)];
|
||||
}
|
||||
else
|
||||
{
|
||||
pllvco = 0U;
|
||||
}
|
||||
break;
|
||||
case RCC_PLLSOURCE_HSI: /* HSI ? */
|
||||
if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))
|
||||
{
|
||||
pllvco = HSI_VALUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
pllvco = 0U;
|
||||
}
|
||||
break;
|
||||
case RCC_PLLSOURCE_HSE: /* HSE ? */
|
||||
if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSERDY))
|
||||
{
|
||||
pllvco = HSE_VALUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
pllvco = 0U;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* No source */
|
||||
pllvco = 0U;
|
||||
break;
|
||||
}
|
||||
|
||||
switch(PeriphClk)
|
||||
{
|
||||
#if defined(SAI1)
|
||||
|
||||
case RCC_PERIPHCLK_SAI1:
|
||||
frequency = RCCEx_GetSAIxPeriphCLKFreq(RCC_PERIPHCLK_SAI1, pllvco);
|
||||
break;
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(SAI2)
|
||||
|
||||
case RCC_PERIPHCLK_SAI2:
|
||||
frequency = RCCEx_GetSAIxPeriphCLKFreq(RCC_PERIPHCLK_SAI2, pllvco);
|
||||
break;
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(USB_OTG_FS) || defined(USB)
|
||||
|
||||
case RCC_PERIPHCLK_USB:
|
||||
|
||||
#endif /* USB_OTG_FS || USB */
|
||||
|
||||
case RCC_PERIPHCLK_RNG:
|
||||
|
||||
#if defined(SDMMC1) && !defined(RCC_CCIPR2_SDMMCSEL)
|
||||
|
||||
case RCC_PERIPHCLK_SDMMC1:
|
||||
|
||||
#endif /* SDMMC1 && !RCC_CCIPR2_SDMMCSEL */
|
||||
{
|
||||
srcclk = READ_BIT(RCC->CCIPR, RCC_CCIPR_CLK48SEL);
|
||||
|
||||
switch(srcclk)
|
||||
{
|
||||
case RCC_CCIPR_CLK48SEL: /* MSI ? */
|
||||
if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_MSIRDY))
|
||||
{
|
||||
/*MSI frequency range in HZ*/
|
||||
frequency = MSIRangeTable[(__HAL_RCC_GET_MSI_RANGE() >> 4U)];
|
||||
}
|
||||
break;
|
||||
case RCC_CCIPR_CLK48SEL_1: /* PLL ? */
|
||||
if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLLRDY))
|
||||
{
|
||||
if(HAL_IS_BIT_SET(RCC->PLLCFGR, RCC_PLLCFGR_PLLQEN))
|
||||
{
|
||||
/* f(PLL Source) * PLLN / PLLM */
|
||||
plln = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos;
|
||||
pllvco = ((pllvco * plln) / ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U));
|
||||
/* f(PLL48M1CLK) = f(VCO input) / PLLQ */
|
||||
frequency = (pllvco / (((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLQ) >> RCC_PLLCFGR_PLLQ_Pos) + 1U) << 1U));
|
||||
}
|
||||
}
|
||||
break;
|
||||
#if defined(RCC_PLLSAI1_SUPPORT)
|
||||
case RCC_CCIPR_CLK48SEL_0: /* PLLSAI1 ? */
|
||||
if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLLSAI1RDY))
|
||||
{
|
||||
if(HAL_IS_BIT_SET(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1QEN))
|
||||
{
|
||||
plln = READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1N) >> RCC_PLLSAI1CFGR_PLLSAI1N_Pos;
|
||||
#if defined(RCC_PLLSAI1M_DIV_1_16_SUPPORT)
|
||||
/* PLLSAI1M exists: apply PLLSAI1M divider for PLLSAI1 output computation */
|
||||
/* f(PLLSAI1 Source) * PLLSAI1N / PLLSAI1M */
|
||||
pllvco = ((pllvco * plln) / ((READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1M) >> RCC_PLLSAI1CFGR_PLLSAI1M_Pos) + 1U));
|
||||
#else
|
||||
/* f(PLL Source) * PLLSAI1N / PLLM */
|
||||
pllvco = ((pllvco * plln) / ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U));
|
||||
#endif
|
||||
/* f(PLL48M2CLK) = f(VCOSAI1 input) / PLLSAI1Q */
|
||||
frequency = (pllvco / (((READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1Q) >> RCC_PLLSAI1CFGR_PLLSAI1Q_Pos) + 1U) << 1U));
|
||||
}
|
||||
}
|
||||
break;
|
||||
#endif /* RCC_PLLSAI1_SUPPORT */
|
||||
#if defined(RCC_HSI48_SUPPORT)
|
||||
case 0U:
|
||||
if(HAL_IS_BIT_SET(RCC->CRRCR, RCC_CRRCR_HSI48RDY)) /* HSI48 ? */
|
||||
{
|
||||
frequency = HSI48_VALUE;
|
||||
}
|
||||
break;
|
||||
#endif /* RCC_HSI48_SUPPORT */
|
||||
default:
|
||||
/* No clock source, frequency default init at 0 */
|
||||
break;
|
||||
} /* switch(srcclk) */
|
||||
break;
|
||||
}
|
||||
|
||||
#if defined(SDMMC1) && defined(RCC_CCIPR2_SDMMCSEL)
|
||||
|
||||
case RCC_PERIPHCLK_SDMMC1:
|
||||
|
||||
if(HAL_IS_BIT_SET(RCC->CCIPR2, RCC_CCIPR2_SDMMCSEL)) /* PLL "P" ? */
|
||||
{
|
||||
if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLLRDY))
|
||||
{
|
||||
if(HAL_IS_BIT_SET(RCC->PLLCFGR, RCC_PLLCFGR_PLLPEN))
|
||||
{
|
||||
/* f(PLL Source) * PLLN / PLLM */
|
||||
plln = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos;
|
||||
pllvco = ((pllvco * plln) / ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U));
|
||||
/* f(PLLSAI3CLK) = f(VCO input) / PLLP */
|
||||
pllp = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLPDIV) >> RCC_PLLCFGR_PLLPDIV_Pos;
|
||||
if(pllp == 0U)
|
||||
{
|
||||
if(READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLP) != 0U)
|
||||
{
|
||||
pllp = 17U;
|
||||
}
|
||||
else
|
||||
{
|
||||
pllp = 7U;
|
||||
}
|
||||
}
|
||||
frequency = (pllvco / pllp);
|
||||
}
|
||||
}
|
||||
}
|
||||
else /* 48MHz from PLL "Q" or MSI or PLLSAI1Q or HSI48 */
|
||||
{
|
||||
srcclk = READ_BIT(RCC->CCIPR, RCC_CCIPR_CLK48SEL);
|
||||
|
||||
switch(srcclk)
|
||||
{
|
||||
case RCC_CCIPR_CLK48SEL: /* MSI ? */
|
||||
if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_MSIRDY))
|
||||
{
|
||||
/*MSI frequency range in HZ*/
|
||||
frequency = MSIRangeTable[(__HAL_RCC_GET_MSI_RANGE() >> 4U)];
|
||||
}
|
||||
break;
|
||||
case RCC_CCIPR_CLK48SEL_1: /* PLL "Q" ? */
|
||||
if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLLRDY))
|
||||
{
|
||||
if(HAL_IS_BIT_SET(RCC->PLLCFGR, RCC_PLLCFGR_PLLQEN))
|
||||
{
|
||||
/* f(PLL Source) * PLLN / PLLM */
|
||||
plln = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos;
|
||||
pllvco = ((pllvco * plln) / ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U));
|
||||
/* f(PLL48M1CLK) = f(VCO input) / PLLQ */
|
||||
frequency = (pllvco / (((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLQ) >> RCC_PLLCFGR_PLLQ_Pos) + 1U) << 1U));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case RCC_CCIPR_CLK48SEL_0: /* PLLSAI1 ? */
|
||||
if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLLSAI1RDY))
|
||||
{
|
||||
if(HAL_IS_BIT_SET(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1QEN))
|
||||
{
|
||||
/* f(PLLSAI1 Source) * PLLSAI1N / PLLSAI1M */
|
||||
plln = READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1N) >> RCC_PLLSAI1CFGR_PLLSAI1N_Pos;
|
||||
pllvco = ((pllvco * plln) / ((READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1M) >> RCC_PLLSAI1CFGR_PLLSAI1M_Pos) + 1U));
|
||||
/* f(PLL48M2CLK) = f(VCOSAI1 input) / PLLSAI1Q */
|
||||
frequency = (pllvco / (((READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1Q) >> RCC_PLLSAI1CFGR_PLLSAI1Q_Pos) + 1U) << 1U));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0U:
|
||||
if(HAL_IS_BIT_SET(RCC->CRRCR, RCC_CRRCR_HSI48RDY)) /* HSI48 ? */
|
||||
{
|
||||
frequency = HSI48_VALUE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* No clock source, frequency default init at 0 */
|
||||
break;
|
||||
} /* switch(srcclk) */
|
||||
}
|
||||
break;
|
||||
|
||||
#endif /* SDMMC1 && RCC_CCIPR2_SDMMCSEL */
|
||||
|
||||
case RCC_PERIPHCLK_USART1:
|
||||
{
|
||||
/* Get the current USART1 source */
|
||||
srcclk = __HAL_RCC_GET_USART1_SOURCE();
|
||||
|
||||
switch(srcclk)
|
||||
{
|
||||
case RCC_USART1CLKSOURCE_PCLK2:
|
||||
frequency = HAL_RCC_GetPCLK2Freq();
|
||||
break;
|
||||
case RCC_USART1CLKSOURCE_SYSCLK:
|
||||
frequency = HAL_RCC_GetSysClockFreq();
|
||||
break;
|
||||
case RCC_USART1CLKSOURCE_HSI:
|
||||
if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))
|
||||
{
|
||||
frequency = HSI_VALUE;
|
||||
}
|
||||
break;
|
||||
case RCC_USART1CLKSOURCE_LSE:
|
||||
if(HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY))
|
||||
{
|
||||
frequency = LSE_VALUE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* No clock source, frequency default init at 0 */
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case RCC_PERIPHCLK_USART2:
|
||||
{
|
||||
/* Get the current USART2 source */
|
||||
srcclk = __HAL_RCC_GET_USART2_SOURCE();
|
||||
|
||||
switch(srcclk)
|
||||
{
|
||||
case RCC_USART2CLKSOURCE_PCLK1:
|
||||
frequency = HAL_RCC_GetPCLK1Freq();
|
||||
break;
|
||||
case RCC_USART2CLKSOURCE_SYSCLK:
|
||||
frequency = HAL_RCC_GetSysClockFreq();
|
||||
break;
|
||||
case RCC_USART2CLKSOURCE_HSI:
|
||||
if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))
|
||||
{
|
||||
frequency = HSI_VALUE;
|
||||
}
|
||||
break;
|
||||
case RCC_USART2CLKSOURCE_LSE:
|
||||
if(HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY))
|
||||
{
|
||||
frequency = LSE_VALUE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* No clock source, frequency default init at 0 */
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
#if defined(USART3)
|
||||
|
||||
case RCC_PERIPHCLK_USART3:
|
||||
{
|
||||
/* Get the current USART3 source */
|
||||
srcclk = __HAL_RCC_GET_USART3_SOURCE();
|
||||
|
||||
switch(srcclk)
|
||||
{
|
||||
case RCC_USART3CLKSOURCE_PCLK1:
|
||||
frequency = HAL_RCC_GetPCLK1Freq();
|
||||
break;
|
||||
case RCC_USART3CLKSOURCE_SYSCLK:
|
||||
frequency = HAL_RCC_GetSysClockFreq();
|
||||
break;
|
||||
case RCC_USART3CLKSOURCE_HSI:
|
||||
if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))
|
||||
{
|
||||
frequency = HSI_VALUE;
|
||||
}
|
||||
break;
|
||||
case RCC_USART3CLKSOURCE_LSE:
|
||||
if(HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY))
|
||||
{
|
||||
frequency = LSE_VALUE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* No clock source, frequency default init at 0 */
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
#endif /* USART3 */
|
||||
|
||||
#if defined(UART4)
|
||||
|
||||
case RCC_PERIPHCLK_UART4:
|
||||
{
|
||||
/* Get the current UART4 source */
|
||||
srcclk = __HAL_RCC_GET_UART4_SOURCE();
|
||||
|
||||
switch(srcclk)
|
||||
{
|
||||
case RCC_UART4CLKSOURCE_PCLK1:
|
||||
frequency = HAL_RCC_GetPCLK1Freq();
|
||||
break;
|
||||
case RCC_UART4CLKSOURCE_SYSCLK:
|
||||
frequency = HAL_RCC_GetSysClockFreq();
|
||||
break;
|
||||
case RCC_UART4CLKSOURCE_HSI:
|
||||
if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))
|
||||
{
|
||||
frequency = HSI_VALUE;
|
||||
}
|
||||
break;
|
||||
case RCC_UART4CLKSOURCE_LSE:
|
||||
if(HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY))
|
||||
{
|
||||
frequency = LSE_VALUE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* No clock source, frequency default init at 0 */
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
#endif /* UART4 */
|
||||
|
||||
#if defined(UART5)
|
||||
|
||||
case RCC_PERIPHCLK_UART5:
|
||||
{
|
||||
/* Get the current UART5 source */
|
||||
srcclk = __HAL_RCC_GET_UART5_SOURCE();
|
||||
|
||||
switch(srcclk)
|
||||
{
|
||||
case RCC_UART5CLKSOURCE_PCLK1:
|
||||
frequency = HAL_RCC_GetPCLK1Freq();
|
||||
break;
|
||||
case RCC_UART5CLKSOURCE_SYSCLK:
|
||||
frequency = HAL_RCC_GetSysClockFreq();
|
||||
break;
|
||||
case RCC_UART5CLKSOURCE_HSI:
|
||||
if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))
|
||||
{
|
||||
frequency = HSI_VALUE;
|
||||
}
|
||||
break;
|
||||
case RCC_UART5CLKSOURCE_LSE:
|
||||
if(HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY))
|
||||
{
|
||||
frequency = LSE_VALUE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* No clock source, frequency default init at 0 */
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
#endif /* UART5 */
|
||||
|
||||
case RCC_PERIPHCLK_LPUART1:
|
||||
{
|
||||
/* Get the current LPUART1 source */
|
||||
srcclk = __HAL_RCC_GET_LPUART1_SOURCE();
|
||||
|
||||
switch(srcclk)
|
||||
{
|
||||
case RCC_LPUART1CLKSOURCE_PCLK1:
|
||||
frequency = HAL_RCC_GetPCLK1Freq();
|
||||
break;
|
||||
case RCC_LPUART1CLKSOURCE_SYSCLK:
|
||||
frequency = HAL_RCC_GetSysClockFreq();
|
||||
break;
|
||||
case RCC_LPUART1CLKSOURCE_HSI:
|
||||
if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))
|
||||
{
|
||||
frequency = HSI_VALUE;
|
||||
}
|
||||
break;
|
||||
case RCC_LPUART1CLKSOURCE_LSE:
|
||||
if(HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY))
|
||||
{
|
||||
frequency = LSE_VALUE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* No clock source, frequency default init at 0 */
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case RCC_PERIPHCLK_ADC:
|
||||
{
|
||||
srcclk = __HAL_RCC_GET_ADC_SOURCE();
|
||||
|
||||
switch(srcclk)
|
||||
{
|
||||
case RCC_ADCCLKSOURCE_SYSCLK:
|
||||
frequency = HAL_RCC_GetSysClockFreq();
|
||||
break;
|
||||
#if defined(RCC_PLLSAI1_SUPPORT)
|
||||
case RCC_ADCCLKSOURCE_PLLSAI1:
|
||||
if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLLSAI1RDY) && (__HAL_RCC_GET_PLLSAI1CLKOUT_CONFIG(RCC_PLLSAI1_ADC1CLK) != 0U))
|
||||
{
|
||||
plln = READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1N) >> RCC_PLLSAI1CFGR_PLLSAI1N_Pos;
|
||||
#if defined(RCC_PLLSAI1M_DIV_1_16_SUPPORT)
|
||||
/* PLLSAI1M exists: apply PLLSAI1M divider for PLLSAI1 output computation */
|
||||
/* f(PLLSAI1 Source) * PLLSAI1N / PLLSAI1M */
|
||||
pllvco = ((pllvco * plln) / ((READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1M) >> RCC_PLLSAI1CFGR_PLLSAI1M_Pos) + 1U));
|
||||
#else
|
||||
/* f(PLL Source) * PLLSAI1N / PLLM */
|
||||
pllvco = ((pllvco * plln) / ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U));
|
||||
#endif
|
||||
/* f(PLLADC1CLK) = f(VCOSAI1 input) / PLLSAI1R */
|
||||
frequency = (pllvco / (((READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1R) >> RCC_PLLSAI1CFGR_PLLSAI1R_Pos) + 1U) << 1U));
|
||||
}
|
||||
break;
|
||||
#endif /* RCC_PLLSAI1_SUPPORT */
|
||||
#if defined(STM32L471xx) || defined(STM32L475xx) || defined(STM32L476xx) || defined(STM32L485xx) || defined(STM32L486xx) || defined(STM32L496xx) || defined(STM32L4A6xx)
|
||||
case RCC_ADCCLKSOURCE_PLLSAI2:
|
||||
if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLLSAI2RDY) && (__HAL_RCC_GET_PLLSAI2CLKOUT_CONFIG(RCC_PLLSAI2_ADC2CLK) != 0U))
|
||||
{
|
||||
plln = READ_BIT(RCC->PLLSAI2CFGR, RCC_PLLSAI2CFGR_PLLSAI2N) >> RCC_PLLSAI2CFGR_PLLSAI2N_Pos;
|
||||
#if defined(RCC_PLLSAI2M_DIV_1_16_SUPPORT)
|
||||
/* PLLSAI2M exists: apply PLLSAI2M divider for PLLSAI2 output computation */
|
||||
/* f(PLLSAI2 Source) * PLLSAI2N / PLLSAI2M */
|
||||
pllvco = ((pllvco * plln) / ((READ_BIT(RCC->PLLSAI2CFGR, RCC_PLLSAI2CFGR_PLLSAI2M) >> RCC_PLLSAI2CFGR_PLLSAI2M_Pos) + 1U));
|
||||
#else
|
||||
/* f(PLL Source) * PLLSAI2N / PLLM */
|
||||
pllvco = ((pllvco * plln) / ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U));
|
||||
#endif
|
||||
/* f(PLLADC2CLK) = f(VCOSAI2 input) / PLLSAI2R */
|
||||
frequency = (pllvco / (((READ_BIT(RCC->PLLSAI2CFGR, RCC_PLLSAI2CFGR_PLLSAI2R) >> RCC_PLLSAI2CFGR_PLLSAI2R_Pos) + 1U) << 1U));
|
||||
}
|
||||
break;
|
||||
#endif /* STM32L471xx || STM32L475xx || STM32L476xx || STM32L485xx || STM32L486xx || STM32L496xx || STM32L4A6xx */
|
||||
default:
|
||||
/* No clock source, frequency default init at 0 */
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
#if defined(DFSDM1_Filter0)
|
||||
|
||||
case RCC_PERIPHCLK_DFSDM1:
|
||||
{
|
||||
/* Get the current DFSDM1 source */
|
||||
srcclk = __HAL_RCC_GET_DFSDM1_SOURCE();
|
||||
|
||||
if(srcclk == RCC_DFSDM1CLKSOURCE_PCLK2)
|
||||
{
|
||||
frequency = HAL_RCC_GetPCLK2Freq();
|
||||
}
|
||||
else
|
||||
{
|
||||
frequency = HAL_RCC_GetSysClockFreq();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
#if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
|
||||
|
||||
case RCC_PERIPHCLK_DFSDM1AUDIO:
|
||||
{
|
||||
/* Get the current DFSDM1 audio source */
|
||||
srcclk = __HAL_RCC_GET_DFSDM1AUDIO_SOURCE();
|
||||
|
||||
switch(srcclk)
|
||||
{
|
||||
case RCC_DFSDM1AUDIOCLKSOURCE_SAI1:
|
||||
frequency = RCCEx_GetSAIxPeriphCLKFreq(RCC_PERIPHCLK_SAI1, pllvco);
|
||||
break;
|
||||
case RCC_DFSDM1AUDIOCLKSOURCE_MSI:
|
||||
if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_MSIRDY))
|
||||
{
|
||||
/*MSI frequency range in HZ*/
|
||||
frequency = MSIRangeTable[(__HAL_RCC_GET_MSI_RANGE() >> 4U)];
|
||||
}
|
||||
break;
|
||||
case RCC_DFSDM1AUDIOCLKSOURCE_HSI:
|
||||
if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))
|
||||
{
|
||||
frequency = HSI_VALUE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* No clock source, frequency default init at 0 */
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
#endif /* STM32L4R5xx || STM32L4R7xx || STM32L4R9xx || STM32L4S5xx || STM32L4S7xx || STM32L4S9xx */
|
||||
|
||||
#endif /* DFSDM1_Filter0 */
|
||||
|
||||
case RCC_PERIPHCLK_I2C1:
|
||||
{
|
||||
/* Get the current I2C1 source */
|
||||
srcclk = __HAL_RCC_GET_I2C1_SOURCE();
|
||||
|
||||
switch(srcclk)
|
||||
{
|
||||
case RCC_I2C1CLKSOURCE_PCLK1:
|
||||
frequency = HAL_RCC_GetPCLK1Freq();
|
||||
break;
|
||||
case RCC_I2C1CLKSOURCE_SYSCLK:
|
||||
frequency = HAL_RCC_GetSysClockFreq();
|
||||
break;
|
||||
case RCC_I2C1CLKSOURCE_HSI:
|
||||
if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))
|
||||
{
|
||||
frequency = HSI_VALUE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* No clock source, frequency default init at 0 */
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
#if defined(I2C2)
|
||||
|
||||
case RCC_PERIPHCLK_I2C2:
|
||||
{
|
||||
/* Get the current I2C2 source */
|
||||
srcclk = __HAL_RCC_GET_I2C2_SOURCE();
|
||||
|
||||
switch(srcclk)
|
||||
{
|
||||
case RCC_I2C2CLKSOURCE_PCLK1:
|
||||
frequency = HAL_RCC_GetPCLK1Freq();
|
||||
break;
|
||||
case RCC_I2C2CLKSOURCE_SYSCLK:
|
||||
frequency = HAL_RCC_GetSysClockFreq();
|
||||
break;
|
||||
case RCC_I2C2CLKSOURCE_HSI:
|
||||
if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))
|
||||
{
|
||||
frequency = HSI_VALUE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* No clock source, frequency default init at 0 */
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
#endif /* I2C2 */
|
||||
|
||||
case RCC_PERIPHCLK_I2C3:
|
||||
{
|
||||
/* Get the current I2C3 source */
|
||||
srcclk = __HAL_RCC_GET_I2C3_SOURCE();
|
||||
|
||||
switch(srcclk)
|
||||
{
|
||||
case RCC_I2C3CLKSOURCE_PCLK1:
|
||||
frequency = HAL_RCC_GetPCLK1Freq();
|
||||
break;
|
||||
case RCC_I2C3CLKSOURCE_SYSCLK:
|
||||
frequency = HAL_RCC_GetSysClockFreq();
|
||||
break;
|
||||
case RCC_I2C3CLKSOURCE_HSI:
|
||||
if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))
|
||||
{
|
||||
frequency = HSI_VALUE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* No clock source, frequency default init at 0 */
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
#if defined(I2C4)
|
||||
|
||||
case RCC_PERIPHCLK_I2C4:
|
||||
{
|
||||
/* Get the current I2C4 source */
|
||||
srcclk = __HAL_RCC_GET_I2C4_SOURCE();
|
||||
|
||||
switch(srcclk)
|
||||
{
|
||||
case RCC_I2C4CLKSOURCE_PCLK1:
|
||||
frequency = HAL_RCC_GetPCLK1Freq();
|
||||
break;
|
||||
case RCC_I2C4CLKSOURCE_SYSCLK:
|
||||
frequency = HAL_RCC_GetSysClockFreq();
|
||||
break;
|
||||
case RCC_I2C4CLKSOURCE_HSI:
|
||||
if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))
|
||||
{
|
||||
frequency = HSI_VALUE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* No clock source, frequency default init at 0 */
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
#endif /* I2C4 */
|
||||
|
||||
case RCC_PERIPHCLK_LPTIM1:
|
||||
{
|
||||
/* Get the current LPTIM1 source */
|
||||
srcclk = __HAL_RCC_GET_LPTIM1_SOURCE();
|
||||
|
||||
switch(srcclk)
|
||||
{
|
||||
case RCC_LPTIM1CLKSOURCE_PCLK1:
|
||||
frequency = HAL_RCC_GetPCLK1Freq();
|
||||
break;
|
||||
case RCC_LPTIM1CLKSOURCE_LSI:
|
||||
if(HAL_IS_BIT_SET(RCC->CSR, RCC_CSR_LSIRDY))
|
||||
{
|
||||
#if defined(RCC_CSR_LSIPREDIV)
|
||||
if(HAL_IS_BIT_SET(RCC->CSR, RCC_CSR_LSIPREDIV))
|
||||
{
|
||||
frequency = LSI_VALUE/128U;
|
||||
}
|
||||
else
|
||||
#endif /* RCC_CSR_LSIPREDIV */
|
||||
{
|
||||
frequency = LSI_VALUE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case RCC_LPTIM1CLKSOURCE_HSI:
|
||||
if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))
|
||||
{
|
||||
frequency = HSI_VALUE;
|
||||
}
|
||||
break;
|
||||
case RCC_LPTIM1CLKSOURCE_LSE:
|
||||
if(HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY))
|
||||
{
|
||||
frequency = LSE_VALUE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* No clock source, frequency default init at 0 */
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case RCC_PERIPHCLK_LPTIM2:
|
||||
{
|
||||
/* Get the current LPTIM2 source */
|
||||
srcclk = __HAL_RCC_GET_LPTIM2_SOURCE();
|
||||
|
||||
switch(srcclk)
|
||||
{
|
||||
case RCC_LPTIM2CLKSOURCE_PCLK1:
|
||||
frequency = HAL_RCC_GetPCLK1Freq();
|
||||
break;
|
||||
case RCC_LPTIM2CLKSOURCE_LSI:
|
||||
if(HAL_IS_BIT_SET(RCC->CSR, RCC_CSR_LSIRDY))
|
||||
{
|
||||
#if defined(RCC_CSR_LSIPREDIV)
|
||||
if(HAL_IS_BIT_SET(RCC->CSR, RCC_CSR_LSIPREDIV))
|
||||
{
|
||||
frequency = LSI_VALUE/128U;
|
||||
}
|
||||
else
|
||||
#endif /* RCC_CSR_LSIPREDIV */
|
||||
{
|
||||
frequency = LSI_VALUE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case RCC_LPTIM2CLKSOURCE_HSI:
|
||||
if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))
|
||||
{
|
||||
frequency = HSI_VALUE;
|
||||
}
|
||||
break;
|
||||
case RCC_LPTIM2CLKSOURCE_LSE:
|
||||
if(HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY))
|
||||
{
|
||||
frequency = LSE_VALUE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* No clock source, frequency default init at 0 */
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
#if defined(SWPMI1)
|
||||
|
||||
case RCC_PERIPHCLK_SWPMI1:
|
||||
{
|
||||
/* Get the current SWPMI1 source */
|
||||
srcclk = __HAL_RCC_GET_SWPMI1_SOURCE();
|
||||
|
||||
switch(srcclk)
|
||||
{
|
||||
case RCC_SWPMI1CLKSOURCE_PCLK1:
|
||||
frequency = HAL_RCC_GetPCLK1Freq();
|
||||
break;
|
||||
case RCC_SWPMI1CLKSOURCE_HSI:
|
||||
if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))
|
||||
{
|
||||
frequency = HSI_VALUE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* No clock source, frequency default init at 0 */
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
#endif /* SWPMI1 */
|
||||
|
||||
#if defined(OCTOSPI1) || defined(OCTOSPI2)
|
||||
|
||||
case RCC_PERIPHCLK_OSPI:
|
||||
{
|
||||
/* Get the current OctoSPI clock source */
|
||||
srcclk = __HAL_RCC_GET_OSPI_SOURCE();
|
||||
|
||||
switch(srcclk)
|
||||
{
|
||||
case RCC_OSPICLKSOURCE_SYSCLK:
|
||||
frequency = HAL_RCC_GetSysClockFreq();
|
||||
break;
|
||||
case RCC_OSPICLKSOURCE_MSI:
|
||||
if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_MSIRDY))
|
||||
{
|
||||
/*MSI frequency range in HZ*/
|
||||
frequency = MSIRangeTable[(__HAL_RCC_GET_MSI_RANGE() >> 4U)];
|
||||
}
|
||||
break;
|
||||
case RCC_OSPICLKSOURCE_PLL:
|
||||
if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLLRDY))
|
||||
{
|
||||
if(HAL_IS_BIT_SET(RCC->PLLCFGR, RCC_PLLCFGR_PLLQEN))
|
||||
{
|
||||
/* f(PLL Source) * PLLN / PLLM */
|
||||
plln = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos;
|
||||
pllvco = ((pllvco * plln) / ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U));
|
||||
/* f(PLL48M1CLK) = f(VCO input) / PLLQ */
|
||||
frequency = (pllvco / (((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLQ) >> RCC_PLLCFGR_PLLQ_Pos) + 1U) << 1U));
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* No clock source, frequency default init at 0 */
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
#endif /* OCTOSPI1 || OCTOSPI2 */
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return(frequency);
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup RCCEx_Exported_Functions_Group2 Extended Clock management functions
|
||||
* @brief Extended Clock management functions
|
||||
*
|
||||
@verbatim
|
||||
===============================================================================
|
||||
##### Extended clock management functions #####
|
||||
===============================================================================
|
||||
[..]
|
||||
This subsection provides a set of functions allowing to control the
|
||||
activation or deactivation of MSI PLL-mode, PLLSAI1, PLLSAI2, LSE CSS,
|
||||
Low speed clock output and clock after wake-up from STOP mode.
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
#if defined(RCC_PLLSAI1_SUPPORT)
|
||||
|
||||
/**
|
||||
* @brief Enable PLLSAI1.
|
||||
* @param PLLSAI1Init pointer to an RCC_PLLSAI1InitTypeDef structure that
|
||||
* contains the configuration information for the PLLSAI1
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_RCCEx_EnablePLLSAI1(RCC_PLLSAI1InitTypeDef *PLLSAI1Init)
|
||||
{
|
||||
uint32_t tickstart;
|
||||
HAL_StatusTypeDef status = HAL_OK;
|
||||
|
||||
/* check for PLLSAI1 Parameters used to output PLLSAI1CLK */
|
||||
assert_param(IS_RCC_PLLSAI1SOURCE(PLLSAI1Init->PLLSAI1Source));
|
||||
assert_param(IS_RCC_PLLSAI1M_VALUE(PLLSAI1Init->PLLSAI1M));
|
||||
assert_param(IS_RCC_PLLSAI1N_VALUE(PLLSAI1Init->PLLSAI1N));
|
||||
assert_param(IS_RCC_PLLSAI1P_VALUE(PLLSAI1Init->PLLSAI1P));
|
||||
assert_param(IS_RCC_PLLSAI1Q_VALUE(PLLSAI1Init->PLLSAI1Q));
|
||||
assert_param(IS_RCC_PLLSAI1R_VALUE(PLLSAI1Init->PLLSAI1R));
|
||||
assert_param(IS_RCC_PLLSAI1CLOCKOUT_VALUE(PLLSAI1Init->PLLSAI1ClockOut));
|
||||
|
||||
/* Disable the PLLSAI1 */
|
||||
__HAL_RCC_PLLSAI1_DISABLE();
|
||||
|
||||
/* Get Start Tick*/
|
||||
tickstart = HAL_GetTick();
|
||||
|
||||
/* Wait till PLLSAI1 is ready to be updated */
|
||||
while(READ_BIT(RCC->CR, RCC_CR_PLLSAI1RDY) != 0U)
|
||||
{
|
||||
if((HAL_GetTick() - tickstart) > PLLSAI1_TIMEOUT_VALUE)
|
||||
{
|
||||
status = HAL_TIMEOUT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(status == HAL_OK)
|
||||
{
|
||||
#if defined(RCC_PLLSAI1M_DIV_1_16_SUPPORT)
|
||||
/* Configure the PLLSAI1 Multiplication factor N */
|
||||
/* Configure the PLLSAI1 Division factors M, P, Q and R */
|
||||
__HAL_RCC_PLLSAI1_CONFIG(PLLSAI1Init->PLLSAI1M, PLLSAI1Init->PLLSAI1N, PLLSAI1Init->PLLSAI1P, PLLSAI1Init->PLLSAI1Q, PLLSAI1Init->PLLSAI1R);
|
||||
#else
|
||||
/* Configure the PLLSAI1 Multiplication factor N */
|
||||
/* Configure the PLLSAI1 Division factors P, Q and R */
|
||||
__HAL_RCC_PLLSAI1_CONFIG(PLLSAI1Init->PLLSAI1N, PLLSAI1Init->PLLSAI1P, PLLSAI1Init->PLLSAI1Q, PLLSAI1Init->PLLSAI1R);
|
||||
#endif /* RCC_PLLSAI1M_DIV_1_16_SUPPORT */
|
||||
/* Configure the PLLSAI1 Clock output(s) */
|
||||
__HAL_RCC_PLLSAI1CLKOUT_ENABLE(PLLSAI1Init->PLLSAI1ClockOut);
|
||||
|
||||
/* Enable the PLLSAI1 again by setting PLLSAI1ON to 1*/
|
||||
__HAL_RCC_PLLSAI1_ENABLE();
|
||||
|
||||
/* Get Start Tick*/
|
||||
tickstart = HAL_GetTick();
|
||||
|
||||
/* Wait till PLLSAI1 is ready */
|
||||
while(READ_BIT(RCC->CR, RCC_CR_PLLSAI1RDY) == 0U)
|
||||
{
|
||||
if((HAL_GetTick() - tickstart) > PLLSAI1_TIMEOUT_VALUE)
|
||||
{
|
||||
status = HAL_TIMEOUT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable PLLSAI1.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_RCCEx_DisablePLLSAI1(void)
|
||||
{
|
||||
uint32_t tickstart;
|
||||
HAL_StatusTypeDef status = HAL_OK;
|
||||
|
||||
/* Disable the PLLSAI1 */
|
||||
__HAL_RCC_PLLSAI1_DISABLE();
|
||||
|
||||
/* Get Start Tick*/
|
||||
tickstart = HAL_GetTick();
|
||||
|
||||
/* Wait till PLLSAI1 is ready */
|
||||
while(READ_BIT(RCC->CR, RCC_CR_PLLSAI1RDY) != 0U)
|
||||
{
|
||||
if((HAL_GetTick() - tickstart) > PLLSAI1_TIMEOUT_VALUE)
|
||||
{
|
||||
status = HAL_TIMEOUT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Disable the PLLSAI1 Clock outputs */
|
||||
__HAL_RCC_PLLSAI1CLKOUT_DISABLE(RCC_PLLSAI1CFGR_PLLSAI1PEN|RCC_PLLSAI1CFGR_PLLSAI1QEN|RCC_PLLSAI1CFGR_PLLSAI1REN);
|
||||
|
||||
/* Reset PLL source to save power if no PLLs on */
|
||||
#if defined(RCC_PLLSAI2_SUPPORT)
|
||||
if(READ_BIT(RCC->CR, (RCC_CR_PLLRDY | RCC_CR_PLLSAI2RDY)) == 0U)
|
||||
{
|
||||
MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC, RCC_PLLSOURCE_NONE);
|
||||
}
|
||||
#else
|
||||
if(READ_BIT(RCC->CR, RCC_CR_PLLRDY) == 0U)
|
||||
{
|
||||
MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC, RCC_PLLSOURCE_NONE);
|
||||
}
|
||||
#endif /* RCC_PLLSAI2_SUPPORT */
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
#endif /* RCC_PLLSAI1_SUPPORT */
|
||||
|
||||
#if defined(RCC_PLLSAI2_SUPPORT)
|
||||
|
||||
/**
|
||||
* @brief Enable PLLSAI2.
|
||||
* @param PLLSAI2Init pointer to an RCC_PLLSAI2InitTypeDef structure that
|
||||
* contains the configuration information for the PLLSAI2
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_RCCEx_EnablePLLSAI2(RCC_PLLSAI2InitTypeDef *PLLSAI2Init)
|
||||
{
|
||||
uint32_t tickstart;
|
||||
HAL_StatusTypeDef status = HAL_OK;
|
||||
|
||||
/* check for PLLSAI2 Parameters used to output PLLSAI2CLK */
|
||||
assert_param(IS_RCC_PLLSAI2SOURCE(PLLSAI2Init->PLLSAI2Source));
|
||||
assert_param(IS_RCC_PLLSAI2M_VALUE(PLLSAI2Init->PLLSAI2M));
|
||||
assert_param(IS_RCC_PLLSAI2N_VALUE(PLLSAI2Init->PLLSAI2N));
|
||||
assert_param(IS_RCC_PLLSAI2P_VALUE(PLLSAI2Init->PLLSAI2P));
|
||||
#if defined(RCC_PLLSAI2Q_DIV_SUPPORT)
|
||||
assert_param(IS_RCC_PLLSAI2Q_VALUE(PLLSAI2Init->PLLSAI2Q));
|
||||
#endif /* RCC_PLLSAI2Q_DIV_SUPPORT */
|
||||
assert_param(IS_RCC_PLLSAI2R_VALUE(PLLSAI2Init->PLLSAI2R));
|
||||
assert_param(IS_RCC_PLLSAI2CLOCKOUT_VALUE(PLLSAI2Init->PLLSAI2ClockOut));
|
||||
|
||||
/* Disable the PLLSAI2 */
|
||||
__HAL_RCC_PLLSAI2_DISABLE();
|
||||
|
||||
/* Get Start Tick*/
|
||||
tickstart = HAL_GetTick();
|
||||
|
||||
/* Wait till PLLSAI2 is ready to be updated */
|
||||
while(READ_BIT(RCC->CR, RCC_CR_PLLSAI2RDY) != 0U)
|
||||
{
|
||||
if((HAL_GetTick() - tickstart) > PLLSAI2_TIMEOUT_VALUE)
|
||||
{
|
||||
status = HAL_TIMEOUT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(status == HAL_OK)
|
||||
{
|
||||
#if defined(RCC_PLLSAI2M_DIV_1_16_SUPPORT) && defined(RCC_PLLSAI2Q_DIV_SUPPORT)
|
||||
/* Configure the PLLSAI2 Multiplication factor N */
|
||||
/* Configure the PLLSAI2 Division factors M, P, Q and R */
|
||||
__HAL_RCC_PLLSAI2_CONFIG(PLLSAI2Init->PLLSAI2M, PLLSAI2Init->PLLSAI2N, PLLSAI2Init->PLLSAI2P, PLLSAI2Init->PLLSAI2Q, PLLSAI2Init->PLLSAI2R);
|
||||
#elif defined(RCC_PLLSAI2M_DIV_1_16_SUPPORT)
|
||||
/* Configure the PLLSAI2 Multiplication factor N */
|
||||
/* Configure the PLLSAI2 Division factors M, P and R */
|
||||
__HAL_RCC_PLLSAI2_CONFIG(PLLSAI2Init->PLLSAI2M, PLLSAI2Init->PLLSAI2N, PLLSAI2Init->PLLSAI2P, PLLSAI2Init->PLLSAI2R);
|
||||
#elif defined(RCC_PLLSAI2Q_DIV_SUPPORT)
|
||||
/* Configure the PLLSAI2 Multiplication factor N */
|
||||
/* Configure the PLLSAI2 Division factors P, Q and R */
|
||||
__HAL_RCC_PLLSAI2_CONFIG(PLLSAI2Init->PLLSAI2N, PLLSAI2Init->PLLSAI2P, PLLSAI2Init->PLLSAI2Q, PLLSAI2Init->PLLSAI2R);
|
||||
#else
|
||||
/* Configure the PLLSAI2 Multiplication factor N */
|
||||
/* Configure the PLLSAI2 Division factors P and R */
|
||||
__HAL_RCC_PLLSAI2_CONFIG(PLLSAI2Init->PLLSAI2N, PLLSAI2Init->PLLSAI2P, PLLSAI2Init->PLLSAI2R);
|
||||
#endif /* RCC_PLLSAI2M_DIV_1_16_SUPPORT && RCC_PLLSAI2Q_DIV_SUPPORT */
|
||||
/* Configure the PLLSAI2 Clock output(s) */
|
||||
__HAL_RCC_PLLSAI2CLKOUT_ENABLE(PLLSAI2Init->PLLSAI2ClockOut);
|
||||
|
||||
/* Enable the PLLSAI2 again by setting PLLSAI2ON to 1*/
|
||||
__HAL_RCC_PLLSAI2_ENABLE();
|
||||
|
||||
/* Get Start Tick*/
|
||||
tickstart = HAL_GetTick();
|
||||
|
||||
/* Wait till PLLSAI2 is ready */
|
||||
while(READ_BIT(RCC->CR, RCC_CR_PLLSAI2RDY) == 0U)
|
||||
{
|
||||
if((HAL_GetTick() - tickstart) > PLLSAI2_TIMEOUT_VALUE)
|
||||
{
|
||||
status = HAL_TIMEOUT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable PLLISAI2.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_RCCEx_DisablePLLSAI2(void)
|
||||
{
|
||||
uint32_t tickstart;
|
||||
HAL_StatusTypeDef status = HAL_OK;
|
||||
|
||||
/* Disable the PLLSAI2 */
|
||||
__HAL_RCC_PLLSAI2_DISABLE();
|
||||
|
||||
/* Get Start Tick*/
|
||||
tickstart = HAL_GetTick();
|
||||
|
||||
/* Wait till PLLSAI2 is ready */
|
||||
while(READ_BIT(RCC->CR, RCC_CR_PLLSAI2RDY) != 0U)
|
||||
{
|
||||
if((HAL_GetTick() - tickstart) > PLLSAI2_TIMEOUT_VALUE)
|
||||
{
|
||||
status = HAL_TIMEOUT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Disable the PLLSAI2 Clock outputs */
|
||||
#if defined(RCC_PLLSAI2Q_DIV_SUPPORT)
|
||||
__HAL_RCC_PLLSAI2CLKOUT_DISABLE(RCC_PLLSAI2CFGR_PLLSAI2PEN|RCC_PLLSAI2CFGR_PLLSAI2QEN|RCC_PLLSAI2CFGR_PLLSAI2REN);
|
||||
#else
|
||||
__HAL_RCC_PLLSAI2CLKOUT_DISABLE(RCC_PLLSAI2CFGR_PLLSAI2PEN|RCC_PLLSAI2CFGR_PLLSAI2REN);
|
||||
#endif /* RCC_PLLSAI2M_DIV_1_16_SUPPORT && RCC_PLLSAI2Q_DIV_SUPPORT */
|
||||
|
||||
/* Reset PLL source to save power if no PLLs on */
|
||||
if(READ_BIT(RCC->CR, (RCC_CR_PLLRDY | RCC_CR_PLLSAI1RDY)) == 0U)
|
||||
{
|
||||
MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC, RCC_PLLSOURCE_NONE);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
#endif /* RCC_PLLSAI2_SUPPORT */
|
||||
|
||||
/**
|
||||
* @brief Configure the oscillator clock source for wakeup from Stop and CSS backup clock.
|
||||
* @param WakeUpClk Wakeup clock
|
||||
* This parameter can be one of the following values:
|
||||
* @arg @ref RCC_STOP_WAKEUPCLOCK_MSI MSI oscillator selection
|
||||
* @arg @ref RCC_STOP_WAKEUPCLOCK_HSI HSI oscillator selection
|
||||
* @note This function shall not be called after the Clock Security System on HSE has been
|
||||
* enabled.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_RCCEx_WakeUpStopCLKConfig(uint32_t WakeUpClk)
|
||||
{
|
||||
assert_param(IS_RCC_STOP_WAKEUPCLOCK(WakeUpClk));
|
||||
|
||||
__HAL_RCC_WAKEUPSTOP_CLK_CONFIG(WakeUpClk);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure the MSI range after standby mode.
|
||||
* @note After Standby its frequency can be selected between 4 possible values (1, 2, 4 or 8 MHz).
|
||||
* @param MSIRange MSI range
|
||||
* This parameter can be one of the following values:
|
||||
* @arg @ref RCC_MSIRANGE_4 Range 4 around 1 MHz
|
||||
* @arg @ref RCC_MSIRANGE_5 Range 5 around 2 MHz
|
||||
* @arg @ref RCC_MSIRANGE_6 Range 6 around 4 MHz (reset value)
|
||||
* @arg @ref RCC_MSIRANGE_7 Range 7 around 8 MHz
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_RCCEx_StandbyMSIRangeConfig(uint32_t MSIRange)
|
||||
{
|
||||
assert_param(IS_RCC_MSI_STANDBY_CLOCK_RANGE(MSIRange));
|
||||
|
||||
__HAL_RCC_MSI_STANDBY_RANGE_CONFIG(MSIRange);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable the LSE Clock Security System.
|
||||
* @note Prior to enable the LSE Clock Security System, LSE oscillator is to be enabled
|
||||
* with HAL_RCC_OscConfig() and the LSE oscillator clock is to be selected as RTC
|
||||
* clock with HAL_RCCEx_PeriphCLKConfig().
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_RCCEx_EnableLSECSS(void)
|
||||
{
|
||||
SET_BIT(RCC->BDCR, RCC_BDCR_LSECSSON);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable the LSE Clock Security System.
|
||||
* @note LSE Clock Security System can only be disabled after a LSE failure detection.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_RCCEx_DisableLSECSS(void)
|
||||
{
|
||||
CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSECSSON) ;
|
||||
|
||||
/* Disable LSE CSS IT if any */
|
||||
__HAL_RCC_DISABLE_IT(RCC_IT_LSECSS);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable the LSE Clock Security System Interrupt & corresponding EXTI line.
|
||||
* @note LSE Clock Security System Interrupt is mapped on RTC EXTI line 19
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_RCCEx_EnableLSECSS_IT(void)
|
||||
{
|
||||
/* Enable LSE CSS */
|
||||
SET_BIT(RCC->BDCR, RCC_BDCR_LSECSSON) ;
|
||||
|
||||
/* Enable LSE CSS IT */
|
||||
__HAL_RCC_ENABLE_IT(RCC_IT_LSECSS);
|
||||
|
||||
/* Enable IT on EXTI Line 19 */
|
||||
__HAL_RCC_LSECSS_EXTI_ENABLE_IT();
|
||||
__HAL_RCC_LSECSS_EXTI_ENABLE_RISING_EDGE();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Handle the RCC LSE Clock Security System interrupt request.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_RCCEx_LSECSS_IRQHandler(void)
|
||||
{
|
||||
/* Check RCC LSE CSSF flag */
|
||||
if(__HAL_RCC_GET_IT(RCC_IT_LSECSS))
|
||||
{
|
||||
/* RCC LSE Clock Security System interrupt user callback */
|
||||
HAL_RCCEx_LSECSS_Callback();
|
||||
|
||||
/* Clear RCC LSE CSS pending bit */
|
||||
__HAL_RCC_CLEAR_IT(RCC_IT_LSECSS);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief RCCEx LSE Clock Security System interrupt callback.
|
||||
* @retval none
|
||||
*/
|
||||
__weak void HAL_RCCEx_LSECSS_Callback(void)
|
||||
{
|
||||
/* NOTE : This function should not be modified, when the callback is needed,
|
||||
the @ref HAL_RCCEx_LSECSS_Callback should be implemented in the user file
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Select the Low Speed clock source to output on LSCO pin (PA2).
|
||||
* @param LSCOSource specifies the Low Speed clock source to output.
|
||||
* This parameter can be one of the following values:
|
||||
* @arg @ref RCC_LSCOSOURCE_LSI LSI clock selected as LSCO source
|
||||
* @arg @ref RCC_LSCOSOURCE_LSE LSE clock selected as LSCO source
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_RCCEx_EnableLSCO(uint32_t LSCOSource)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStruct;
|
||||
FlagStatus pwrclkchanged = RESET;
|
||||
FlagStatus backupchanged = RESET;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_RCC_LSCOSOURCE(LSCOSource));
|
||||
|
||||
/* LSCO Pin Clock Enable */
|
||||
__LSCO_CLK_ENABLE();
|
||||
|
||||
/* Configure the LSCO pin in analog mode */
|
||||
GPIO_InitStruct.Pin = LSCO_PIN;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
HAL_GPIO_Init(LSCO_GPIO_PORT, &GPIO_InitStruct);
|
||||
|
||||
/* Update LSCOSEL clock source in Backup Domain control register */
|
||||
if(__HAL_RCC_PWR_IS_CLK_DISABLED())
|
||||
{
|
||||
__HAL_RCC_PWR_CLK_ENABLE();
|
||||
pwrclkchanged = SET;
|
||||
}
|
||||
if(HAL_IS_BIT_CLR(PWR->CR1, PWR_CR1_DBP))
|
||||
{
|
||||
HAL_PWR_EnableBkUpAccess();
|
||||
backupchanged = SET;
|
||||
}
|
||||
|
||||
MODIFY_REG(RCC->BDCR, RCC_BDCR_LSCOSEL | RCC_BDCR_LSCOEN, LSCOSource | RCC_BDCR_LSCOEN);
|
||||
|
||||
if(backupchanged == SET)
|
||||
{
|
||||
HAL_PWR_DisableBkUpAccess();
|
||||
}
|
||||
if(pwrclkchanged == SET)
|
||||
{
|
||||
__HAL_RCC_PWR_CLK_DISABLE();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable the Low Speed clock output.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_RCCEx_DisableLSCO(void)
|
||||
{
|
||||
FlagStatus pwrclkchanged = RESET;
|
||||
FlagStatus backupchanged = RESET;
|
||||
|
||||
/* Update LSCOEN bit in Backup Domain control register */
|
||||
if(__HAL_RCC_PWR_IS_CLK_DISABLED())
|
||||
{
|
||||
__HAL_RCC_PWR_CLK_ENABLE();
|
||||
pwrclkchanged = SET;
|
||||
}
|
||||
if(HAL_IS_BIT_CLR(PWR->CR1, PWR_CR1_DBP))
|
||||
{
|
||||
/* Enable access to the backup domain */
|
||||
HAL_PWR_EnableBkUpAccess();
|
||||
backupchanged = SET;
|
||||
}
|
||||
|
||||
CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSCOEN);
|
||||
|
||||
/* Restore previous configuration */
|
||||
if(backupchanged == SET)
|
||||
{
|
||||
/* Disable access to the backup domain */
|
||||
HAL_PWR_DisableBkUpAccess();
|
||||
}
|
||||
if(pwrclkchanged == SET)
|
||||
{
|
||||
__HAL_RCC_PWR_CLK_DISABLE();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable the PLL-mode of the MSI.
|
||||
* @note Prior to enable the PLL-mode of the MSI for automatic hardware
|
||||
* calibration LSE oscillator is to be enabled with HAL_RCC_OscConfig().
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_RCCEx_EnableMSIPLLMode(void)
|
||||
{
|
||||
SET_BIT(RCC->CR, RCC_CR_MSIPLLEN) ;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable the PLL-mode of the MSI.
|
||||
* @note PLL-mode of the MSI is automatically reset when LSE oscillator is disabled.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_RCCEx_DisableMSIPLLMode(void)
|
||||
{
|
||||
CLEAR_BIT(RCC->CR, RCC_CR_MSIPLLEN) ;
|
||||
}
|
||||
|
||||
#if defined (OCTOSPI1) && defined (OCTOSPI2)
|
||||
/**
|
||||
* @brief Configure OCTOSPI instances DQS delays.
|
||||
* @param Delay1 OCTOSPI1 DQS delay
|
||||
* @param Delay2 OCTOSPI2 DQS delay
|
||||
* @note Delay parameters stand for unitary delays from 0 to 15. Actual delay is Delay1 or Delay2 + 1.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_RCCEx_OCTOSPIDelayConfig(uint32_t Delay1, uint32_t Delay2)
|
||||
{
|
||||
assert_param(IS_RCC_OCTOSPIDELAY(Delay1));
|
||||
assert_param(IS_RCC_OCTOSPIDELAY(Delay2));
|
||||
|
||||
MODIFY_REG(RCC->DLYCFGR, RCC_DLYCFGR_OCTOSPI1_DLY|RCC_DLYCFGR_OCTOSPI2_DLY, (Delay1 | (Delay2 << RCC_DLYCFGR_OCTOSPI2_DLY_Pos))) ;
|
||||
}
|
||||
#endif /* OCTOSPI1 && OCTOSPI2 */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#if defined(CRS)
|
||||
|
||||
/** @defgroup RCCEx_Exported_Functions_Group3 Extended Clock Recovery System Control functions
|
||||
* @brief Extended Clock Recovery System Control functions
|
||||
*
|
||||
@verbatim
|
||||
===============================================================================
|
||||
##### Extended Clock Recovery System Control functions #####
|
||||
===============================================================================
|
||||
[..]
|
||||
For devices with Clock Recovery System feature (CRS), RCC Extension HAL driver can be used as follows:
|
||||
|
||||
(#) In System clock config, HSI48 needs to be enabled
|
||||
|
||||
(#) Enable CRS clock in IP MSP init which will use CRS functions
|
||||
|
||||
(#) Call CRS functions as follows:
|
||||
(##) Prepare synchronization configuration necessary for HSI48 calibration
|
||||
(+++) Default values can be set for frequency Error Measurement (reload and error limit)
|
||||
and also HSI48 oscillator smooth trimming.
|
||||
(+++) Macro __HAL_RCC_CRS_RELOADVALUE_CALCULATE can be also used to calculate
|
||||
directly reload value with target and sychronization frequencies values
|
||||
(##) Call function HAL_RCCEx_CRSConfig which
|
||||
(+++) Resets CRS registers to their default values.
|
||||
(+++) Configures CRS registers with synchronization configuration
|
||||
(+++) Enables automatic calibration and frequency error counter feature
|
||||
Note: When using USB LPM (Link Power Management) and the device is in Sleep mode, the
|
||||
periodic USB SOF will not be generated by the host. No SYNC signal will therefore be
|
||||
provided to the CRS to calibrate the HSI48 on the run. To guarantee the required clock
|
||||
precision after waking up from Sleep mode, the LSE or reference clock on the GPIOs
|
||||
should be used as SYNC signal.
|
||||
|
||||
(##) A polling function is provided to wait for complete synchronization
|
||||
(+++) Call function HAL_RCCEx_CRSWaitSynchronization()
|
||||
(+++) According to CRS status, user can decide to adjust again the calibration or continue
|
||||
application if synchronization is OK
|
||||
|
||||
(#) User can retrieve information related to synchronization in calling function
|
||||
HAL_RCCEx_CRSGetSynchronizationInfo()
|
||||
|
||||
(#) Regarding synchronization status and synchronization information, user can try a new calibration
|
||||
in changing synchronization configuration and call again HAL_RCCEx_CRSConfig.
|
||||
Note: When the SYNC event is detected during the downcounting phase (before reaching the zero value),
|
||||
it means that the actual frequency is lower than the target (and so, that the TRIM value should be
|
||||
incremented), while when it is detected during the upcounting phase it means that the actual frequency
|
||||
is higher (and that the TRIM value should be decremented).
|
||||
|
||||
(#) In interrupt mode, user can resort to the available macros (__HAL_RCC_CRS_XXX_IT). Interrupts will go
|
||||
through CRS Handler (CRS_IRQn/CRS_IRQHandler)
|
||||
(++) Call function HAL_RCCEx_CRSConfig()
|
||||
(++) Enable CRS_IRQn (thanks to NVIC functions)
|
||||
(++) Enable CRS interrupt (__HAL_RCC_CRS_ENABLE_IT)
|
||||
(++) Implement CRS status management in the following user callbacks called from
|
||||
HAL_RCCEx_CRS_IRQHandler():
|
||||
(+++) HAL_RCCEx_CRS_SyncOkCallback()
|
||||
(+++) HAL_RCCEx_CRS_SyncWarnCallback()
|
||||
(+++) HAL_RCCEx_CRS_ExpectedSyncCallback()
|
||||
(+++) HAL_RCCEx_CRS_ErrorCallback()
|
||||
|
||||
(#) To force a SYNC EVENT, user can use the function HAL_RCCEx_CRSSoftwareSynchronizationGenerate().
|
||||
This function can be called before calling HAL_RCCEx_CRSConfig (for instance in Systick handler)
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Start automatic synchronization for polling mode
|
||||
* @param pInit Pointer on RCC_CRSInitTypeDef structure
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_RCCEx_CRSConfig(RCC_CRSInitTypeDef *pInit)
|
||||
{
|
||||
uint32_t value; /* no init needed */
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_RCC_CRS_SYNC_DIV(pInit->Prescaler));
|
||||
assert_param(IS_RCC_CRS_SYNC_SOURCE(pInit->Source));
|
||||
assert_param(IS_RCC_CRS_SYNC_POLARITY(pInit->Polarity));
|
||||
assert_param(IS_RCC_CRS_RELOADVALUE(pInit->ReloadValue));
|
||||
assert_param(IS_RCC_CRS_ERRORLIMIT(pInit->ErrorLimitValue));
|
||||
assert_param(IS_RCC_CRS_HSI48CALIBRATION(pInit->HSI48CalibrationValue));
|
||||
|
||||
/* CONFIGURATION */
|
||||
|
||||
/* Before configuration, reset CRS registers to their default values*/
|
||||
__HAL_RCC_CRS_FORCE_RESET();
|
||||
__HAL_RCC_CRS_RELEASE_RESET();
|
||||
|
||||
/* Set the SYNCDIV[2:0] bits according to Prescaler value */
|
||||
/* Set the SYNCSRC[1:0] bits according to Source value */
|
||||
/* Set the SYNCSPOL bit according to Polarity value */
|
||||
value = (pInit->Prescaler | pInit->Source | pInit->Polarity);
|
||||
/* Set the RELOAD[15:0] bits according to ReloadValue value */
|
||||
value |= pInit->ReloadValue;
|
||||
/* Set the FELIM[7:0] bits according to ErrorLimitValue value */
|
||||
value |= (pInit->ErrorLimitValue << CRS_CFGR_FELIM_Pos);
|
||||
WRITE_REG(CRS->CFGR, value);
|
||||
|
||||
/* Adjust HSI48 oscillator smooth trimming */
|
||||
/* Set the TRIM[6:0] bits for STM32L412xx/L422xx or TRIM[5:0] bits otherwise
|
||||
according to RCC_CRS_HSI48CalibrationValue value */
|
||||
MODIFY_REG(CRS->CR, CRS_CR_TRIM, (pInit->HSI48CalibrationValue << CRS_CR_TRIM_Pos));
|
||||
|
||||
/* START AUTOMATIC SYNCHRONIZATION*/
|
||||
|
||||
/* Enable Automatic trimming & Frequency error counter */
|
||||
SET_BIT(CRS->CR, CRS_CR_AUTOTRIMEN | CRS_CR_CEN);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Generate the software synchronization event
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_RCCEx_CRSSoftwareSynchronizationGenerate(void)
|
||||
{
|
||||
SET_BIT(CRS->CR, CRS_CR_SWSYNC);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return synchronization info
|
||||
* @param pSynchroInfo Pointer on RCC_CRSSynchroInfoTypeDef structure
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_RCCEx_CRSGetSynchronizationInfo(RCC_CRSSynchroInfoTypeDef *pSynchroInfo)
|
||||
{
|
||||
/* Check the parameter */
|
||||
assert_param(pSynchroInfo != (void *)NULL);
|
||||
|
||||
/* Get the reload value */
|
||||
pSynchroInfo->ReloadValue = (READ_BIT(CRS->CFGR, CRS_CFGR_RELOAD));
|
||||
|
||||
/* Get HSI48 oscillator smooth trimming */
|
||||
pSynchroInfo->HSI48CalibrationValue = (READ_BIT(CRS->CR, CRS_CR_TRIM) >> CRS_CR_TRIM_Pos);
|
||||
|
||||
/* Get Frequency error capture */
|
||||
pSynchroInfo->FreqErrorCapture = (READ_BIT(CRS->ISR, CRS_ISR_FECAP) >> CRS_ISR_FECAP_Pos);
|
||||
|
||||
/* Get Frequency error direction */
|
||||
pSynchroInfo->FreqErrorDirection = (READ_BIT(CRS->ISR, CRS_ISR_FEDIR));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Wait for CRS Synchronization status.
|
||||
* @param Timeout Duration of the timeout
|
||||
* @note Timeout is based on the maximum time to receive a SYNC event based on synchronization
|
||||
* frequency.
|
||||
* @note If Timeout set to HAL_MAX_DELAY, HAL_TIMEOUT will be never returned.
|
||||
* @retval Combination of Synchronization status
|
||||
* This parameter can be a combination of the following values:
|
||||
* @arg @ref RCC_CRS_TIMEOUT
|
||||
* @arg @ref RCC_CRS_SYNCOK
|
||||
* @arg @ref RCC_CRS_SYNCWARN
|
||||
* @arg @ref RCC_CRS_SYNCERR
|
||||
* @arg @ref RCC_CRS_SYNCMISS
|
||||
* @arg @ref RCC_CRS_TRIMOVF
|
||||
*/
|
||||
uint32_t HAL_RCCEx_CRSWaitSynchronization(uint32_t Timeout)
|
||||
{
|
||||
uint32_t crsstatus = RCC_CRS_NONE;
|
||||
uint32_t tickstart;
|
||||
|
||||
/* Get timeout */
|
||||
tickstart = HAL_GetTick();
|
||||
|
||||
/* Wait for CRS flag or timeout detection */
|
||||
do
|
||||
{
|
||||
if(Timeout != HAL_MAX_DELAY)
|
||||
{
|
||||
if(((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
|
||||
{
|
||||
crsstatus = RCC_CRS_TIMEOUT;
|
||||
}
|
||||
}
|
||||
/* Check CRS SYNCOK flag */
|
||||
if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCOK))
|
||||
{
|
||||
/* CRS SYNC event OK */
|
||||
crsstatus |= RCC_CRS_SYNCOK;
|
||||
|
||||
/* Clear CRS SYNC event OK bit */
|
||||
__HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCOK);
|
||||
}
|
||||
|
||||
/* Check CRS SYNCWARN flag */
|
||||
if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCWARN))
|
||||
{
|
||||
/* CRS SYNC warning */
|
||||
crsstatus |= RCC_CRS_SYNCWARN;
|
||||
|
||||
/* Clear CRS SYNCWARN bit */
|
||||
__HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCWARN);
|
||||
}
|
||||
|
||||
/* Check CRS TRIM overflow flag */
|
||||
if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_TRIMOVF))
|
||||
{
|
||||
/* CRS SYNC Error */
|
||||
crsstatus |= RCC_CRS_TRIMOVF;
|
||||
|
||||
/* Clear CRS Error bit */
|
||||
__HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_TRIMOVF);
|
||||
}
|
||||
|
||||
/* Check CRS Error flag */
|
||||
if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCERR))
|
||||
{
|
||||
/* CRS SYNC Error */
|
||||
crsstatus |= RCC_CRS_SYNCERR;
|
||||
|
||||
/* Clear CRS Error bit */
|
||||
__HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCERR);
|
||||
}
|
||||
|
||||
/* Check CRS SYNC Missed flag */
|
||||
if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCMISS))
|
||||
{
|
||||
/* CRS SYNC Missed */
|
||||
crsstatus |= RCC_CRS_SYNCMISS;
|
||||
|
||||
/* Clear CRS SYNC Missed bit */
|
||||
__HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCMISS);
|
||||
}
|
||||
|
||||
/* Check CRS Expected SYNC flag */
|
||||
if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_ESYNC))
|
||||
{
|
||||
/* frequency error counter reached a zero value */
|
||||
__HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_ESYNC);
|
||||
}
|
||||
} while(RCC_CRS_NONE == crsstatus);
|
||||
|
||||
return crsstatus;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Handle the Clock Recovery System interrupt request.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_RCCEx_CRS_IRQHandler(void)
|
||||
{
|
||||
uint32_t crserror = RCC_CRS_NONE;
|
||||
/* Get current IT flags and IT sources values */
|
||||
uint32_t itflags = READ_REG(CRS->ISR);
|
||||
uint32_t itsources = READ_REG(CRS->CR);
|
||||
|
||||
/* Check CRS SYNCOK flag */
|
||||
if(((itflags & RCC_CRS_FLAG_SYNCOK) != 0U) && ((itsources & RCC_CRS_IT_SYNCOK) != 0U))
|
||||
{
|
||||
/* Clear CRS SYNC event OK flag */
|
||||
WRITE_REG(CRS->ICR, CRS_ICR_SYNCOKC);
|
||||
|
||||
/* user callback */
|
||||
HAL_RCCEx_CRS_SyncOkCallback();
|
||||
}
|
||||
/* Check CRS SYNCWARN flag */
|
||||
else if(((itflags & RCC_CRS_FLAG_SYNCWARN) != 0U) && ((itsources & RCC_CRS_IT_SYNCWARN) != 0U))
|
||||
{
|
||||
/* Clear CRS SYNCWARN flag */
|
||||
WRITE_REG(CRS->ICR, CRS_ICR_SYNCWARNC);
|
||||
|
||||
/* user callback */
|
||||
HAL_RCCEx_CRS_SyncWarnCallback();
|
||||
}
|
||||
/* Check CRS Expected SYNC flag */
|
||||
else if(((itflags & RCC_CRS_FLAG_ESYNC) != 0U) && ((itsources & RCC_CRS_IT_ESYNC) != 0U))
|
||||
{
|
||||
/* frequency error counter reached a zero value */
|
||||
WRITE_REG(CRS->ICR, CRS_ICR_ESYNCC);
|
||||
|
||||
/* user callback */
|
||||
HAL_RCCEx_CRS_ExpectedSyncCallback();
|
||||
}
|
||||
/* Check CRS Error flags */
|
||||
else
|
||||
{
|
||||
if(((itflags & RCC_CRS_FLAG_ERR) != 0U) && ((itsources & RCC_CRS_IT_ERR) != 0U))
|
||||
{
|
||||
if((itflags & RCC_CRS_FLAG_SYNCERR) != 0U)
|
||||
{
|
||||
crserror |= RCC_CRS_SYNCERR;
|
||||
}
|
||||
if((itflags & RCC_CRS_FLAG_SYNCMISS) != 0U)
|
||||
{
|
||||
crserror |= RCC_CRS_SYNCMISS;
|
||||
}
|
||||
if((itflags & RCC_CRS_FLAG_TRIMOVF) != 0U)
|
||||
{
|
||||
crserror |= RCC_CRS_TRIMOVF;
|
||||
}
|
||||
|
||||
/* Clear CRS Error flags */
|
||||
WRITE_REG(CRS->ICR, CRS_ICR_ERRC);
|
||||
|
||||
/* user error callback */
|
||||
HAL_RCCEx_CRS_ErrorCallback(crserror);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief RCCEx Clock Recovery System SYNCOK interrupt callback.
|
||||
* @retval none
|
||||
*/
|
||||
__weak void HAL_RCCEx_CRS_SyncOkCallback(void)
|
||||
{
|
||||
/* NOTE : This function should not be modified, when the callback is needed,
|
||||
the @ref HAL_RCCEx_CRS_SyncOkCallback should be implemented in the user file
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief RCCEx Clock Recovery System SYNCWARN interrupt callback.
|
||||
* @retval none
|
||||
*/
|
||||
__weak void HAL_RCCEx_CRS_SyncWarnCallback(void)
|
||||
{
|
||||
/* NOTE : This function should not be modified, when the callback is needed,
|
||||
the @ref HAL_RCCEx_CRS_SyncWarnCallback should be implemented in the user file
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief RCCEx Clock Recovery System Expected SYNC interrupt callback.
|
||||
* @retval none
|
||||
*/
|
||||
__weak void HAL_RCCEx_CRS_ExpectedSyncCallback(void)
|
||||
{
|
||||
/* NOTE : This function should not be modified, when the callback is needed,
|
||||
the @ref HAL_RCCEx_CRS_ExpectedSyncCallback should be implemented in the user file
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief RCCEx Clock Recovery System Error interrupt callback.
|
||||
* @param Error Combination of Error status.
|
||||
* This parameter can be a combination of the following values:
|
||||
* @arg @ref RCC_CRS_SYNCERR
|
||||
* @arg @ref RCC_CRS_SYNCMISS
|
||||
* @arg @ref RCC_CRS_TRIMOVF
|
||||
* @retval none
|
||||
*/
|
||||
__weak void HAL_RCCEx_CRS_ErrorCallback(uint32_t Error)
|
||||
{
|
||||
/* Prevent unused argument(s) compilation warning */
|
||||
UNUSED(Error);
|
||||
|
||||
/* NOTE : This function should not be modified, when the callback is needed,
|
||||
the @ref HAL_RCCEx_CRS_ErrorCallback should be implemented in the user file
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* CRS */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup RCCEx_Private_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
#if defined(RCC_PLLSAI1_SUPPORT)
|
||||
|
||||
/**
|
||||
* @brief Configure the parameters N & P & optionally M of PLLSAI1 and enable PLLSAI1 output clock(s).
|
||||
* @param PllSai1 pointer to an RCC_PLLSAI1InitTypeDef structure that
|
||||
* contains the configuration parameters N & P & optionally M as well as PLLSAI1 output clock(s)
|
||||
* @param Divider divider parameter to be updated
|
||||
*
|
||||
* @note PLLSAI1 is temporary disable to apply new parameters
|
||||
*
|
||||
* @retval HAL status
|
||||
*/
|
||||
static HAL_StatusTypeDef RCCEx_PLLSAI1_Config(RCC_PLLSAI1InitTypeDef *PllSai1, uint32_t Divider)
|
||||
{
|
||||
uint32_t tickstart;
|
||||
HAL_StatusTypeDef status = HAL_OK;
|
||||
|
||||
/* check for PLLSAI1 Parameters used to output PLLSAI1CLK */
|
||||
/* P, Q and R dividers are verified in each specific divider case below */
|
||||
assert_param(IS_RCC_PLLSAI1SOURCE(PllSai1->PLLSAI1Source));
|
||||
assert_param(IS_RCC_PLLSAI1M_VALUE(PllSai1->PLLSAI1M));
|
||||
assert_param(IS_RCC_PLLSAI1N_VALUE(PllSai1->PLLSAI1N));
|
||||
assert_param(IS_RCC_PLLSAI1CLOCKOUT_VALUE(PllSai1->PLLSAI1ClockOut));
|
||||
|
||||
/* Check that PLLSAI1 clock source and divider M can be applied */
|
||||
if(__HAL_RCC_GET_PLL_OSCSOURCE() != RCC_PLLSOURCE_NONE)
|
||||
{
|
||||
/* PLL clock source and divider M already set, check that no request for change */
|
||||
if((__HAL_RCC_GET_PLL_OSCSOURCE() != PllSai1->PLLSAI1Source)
|
||||
||
|
||||
(PllSai1->PLLSAI1Source == RCC_PLLSOURCE_NONE)
|
||||
#if !defined(RCC_PLLSAI1M_DIV_1_16_SUPPORT)
|
||||
||
|
||||
(((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U) != PllSai1->PLLSAI1M)
|
||||
#endif
|
||||
)
|
||||
{
|
||||
status = HAL_ERROR;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Check PLLSAI1 clock source availability */
|
||||
switch(PllSai1->PLLSAI1Source)
|
||||
{
|
||||
case RCC_PLLSOURCE_MSI:
|
||||
if(HAL_IS_BIT_CLR(RCC->CR, RCC_CR_MSIRDY))
|
||||
{
|
||||
status = HAL_ERROR;
|
||||
}
|
||||
break;
|
||||
case RCC_PLLSOURCE_HSI:
|
||||
if(HAL_IS_BIT_CLR(RCC->CR, RCC_CR_HSIRDY))
|
||||
{
|
||||
status = HAL_ERROR;
|
||||
}
|
||||
break;
|
||||
case RCC_PLLSOURCE_HSE:
|
||||
if(HAL_IS_BIT_CLR(RCC->CR, RCC_CR_HSERDY))
|
||||
{
|
||||
if(HAL_IS_BIT_CLR(RCC->CR, RCC_CR_HSEBYP))
|
||||
{
|
||||
status = HAL_ERROR;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
status = HAL_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
if(status == HAL_OK)
|
||||
{
|
||||
#if defined(RCC_PLLSAI1M_DIV_1_16_SUPPORT)
|
||||
/* Set PLLSAI1 clock source */
|
||||
MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC, PllSai1->PLLSAI1Source);
|
||||
#else
|
||||
/* Set PLLSAI1 clock source and divider M */
|
||||
MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC | RCC_PLLCFGR_PLLM, PllSai1->PLLSAI1Source | (PllSai1->PLLSAI1M - 1U) << RCC_PLLCFGR_PLLM_Pos);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if(status == HAL_OK)
|
||||
{
|
||||
/* Disable the PLLSAI1 */
|
||||
__HAL_RCC_PLLSAI1_DISABLE();
|
||||
|
||||
/* Get Start Tick*/
|
||||
tickstart = HAL_GetTick();
|
||||
|
||||
/* Wait till PLLSAI1 is ready to be updated */
|
||||
while(READ_BIT(RCC->CR, RCC_CR_PLLSAI1RDY) != 0U)
|
||||
{
|
||||
if((HAL_GetTick() - tickstart) > PLLSAI1_TIMEOUT_VALUE)
|
||||
{
|
||||
status = HAL_TIMEOUT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(status == HAL_OK)
|
||||
{
|
||||
if(Divider == DIVIDER_P_UPDATE)
|
||||
{
|
||||
assert_param(IS_RCC_PLLSAI1P_VALUE(PllSai1->PLLSAI1P));
|
||||
#if defined(RCC_PLLSAI1M_DIV_1_16_SUPPORT)
|
||||
|
||||
/* Configure the PLLSAI1 Division factor M, P and Multiplication factor N*/
|
||||
#if defined(RCC_PLLSAI1P_DIV_2_31_SUPPORT)
|
||||
MODIFY_REG(RCC->PLLSAI1CFGR,
|
||||
RCC_PLLSAI1CFGR_PLLSAI1N | RCC_PLLSAI1CFGR_PLLSAI1PDIV | RCC_PLLSAI1CFGR_PLLSAI1M,
|
||||
(PllSai1->PLLSAI1N << RCC_PLLSAI1CFGR_PLLSAI1N_Pos) |
|
||||
(PllSai1->PLLSAI1P << RCC_PLLSAI1CFGR_PLLSAI1PDIV_Pos) |
|
||||
((PllSai1->PLLSAI1M - 1U) << RCC_PLLSAI1CFGR_PLLSAI1M_Pos));
|
||||
#else
|
||||
MODIFY_REG(RCC->PLLSAI1CFGR,
|
||||
RCC_PLLSAI1CFGR_PLLSAI1N | RCC_PLLSAI1CFGR_PLLSAI1P | RCC_PLLSAI1CFGR_PLLSAI1M,
|
||||
(PllSai1->PLLSAI1N << RCC_PLLSAI1CFGR_PLLSAI1N_Pos) |
|
||||
((PllSai1->PLLSAI1P >> 4U) << RCC_PLLSAI1CFGR_PLLSAI1P_Pos) |
|
||||
((PllSai1->PLLSAI1M - 1U) << RCC_PLLSAI1CFGR_PLLSAI1M_Pos));
|
||||
#endif /* RCC_PLLSAI1P_DIV_2_31_SUPPORT */
|
||||
|
||||
#else
|
||||
/* Configure the PLLSAI1 Division factor P and Multiplication factor N*/
|
||||
#if defined(RCC_PLLSAI1P_DIV_2_31_SUPPORT)
|
||||
MODIFY_REG(RCC->PLLSAI1CFGR,
|
||||
RCC_PLLSAI1CFGR_PLLSAI1N | RCC_PLLSAI1CFGR_PLLSAI1PDIV,
|
||||
(PllSai1->PLLSAI1N << RCC_PLLSAI1CFGR_PLLSAI1N_Pos) |
|
||||
(PllSai1->PLLSAI1P << RCC_PLLSAI1CFGR_PLLSAI1PDIV_Pos));
|
||||
#else
|
||||
MODIFY_REG(RCC->PLLSAI1CFGR,
|
||||
RCC_PLLSAI1CFGR_PLLSAI1N | RCC_PLLSAI1CFGR_PLLSAI1P,
|
||||
(PllSai1->PLLSAI1N << RCC_PLLSAI1CFGR_PLLSAI1N_Pos) |
|
||||
((PllSai1->PLLSAI1P >> 4U) << RCC_PLLSAI1CFGR_PLLSAI1P_Pos));
|
||||
#endif /* RCC_PLLSAI1P_DIV_2_31_SUPPORT */
|
||||
|
||||
#endif /* RCC_PLLSAI1M_DIV_1_16_SUPPORT */
|
||||
}
|
||||
else if(Divider == DIVIDER_Q_UPDATE)
|
||||
{
|
||||
assert_param(IS_RCC_PLLSAI1Q_VALUE(PllSai1->PLLSAI1Q));
|
||||
#if defined(RCC_PLLSAI1M_DIV_1_16_SUPPORT)
|
||||
/* Configure the PLLSAI1 Division factor M, Q and Multiplication factor N*/
|
||||
MODIFY_REG(RCC->PLLSAI1CFGR,
|
||||
RCC_PLLSAI1CFGR_PLLSAI1N | RCC_PLLSAI1CFGR_PLLSAI1Q | RCC_PLLSAI1CFGR_PLLSAI1M,
|
||||
(PllSai1->PLLSAI1N << RCC_PLLSAI1CFGR_PLLSAI1N_Pos) |
|
||||
(((PllSai1->PLLSAI1Q >> 1U) - 1U) << RCC_PLLSAI1CFGR_PLLSAI1Q_Pos) |
|
||||
((PllSai1->PLLSAI1M - 1U) << RCC_PLLSAI1CFGR_PLLSAI1M_Pos));
|
||||
#else
|
||||
/* Configure the PLLSAI1 Division factor Q and Multiplication factor N*/
|
||||
MODIFY_REG(RCC->PLLSAI1CFGR,
|
||||
RCC_PLLSAI1CFGR_PLLSAI1N | RCC_PLLSAI1CFGR_PLLSAI1Q,
|
||||
(PllSai1->PLLSAI1N << RCC_PLLSAI1CFGR_PLLSAI1N_Pos) |
|
||||
(((PllSai1->PLLSAI1Q >> 1U) - 1U) << RCC_PLLSAI1CFGR_PLLSAI1Q_Pos));
|
||||
#endif /* RCC_PLLSAI1M_DIV_1_16_SUPPORT */
|
||||
}
|
||||
else
|
||||
{
|
||||
assert_param(IS_RCC_PLLSAI1R_VALUE(PllSai1->PLLSAI1R));
|
||||
#if defined(RCC_PLLSAI1M_DIV_1_16_SUPPORT)
|
||||
/* Configure the PLLSAI1 Division factor M, R and Multiplication factor N*/
|
||||
MODIFY_REG(RCC->PLLSAI1CFGR,
|
||||
RCC_PLLSAI1CFGR_PLLSAI1N | RCC_PLLSAI1CFGR_PLLSAI1R | RCC_PLLSAI1CFGR_PLLSAI1M,
|
||||
(PllSai1->PLLSAI1N << RCC_PLLSAI1CFGR_PLLSAI1N_Pos) |
|
||||
(((PllSai1->PLLSAI1R >> 1U) - 1U) << RCC_PLLSAI1CFGR_PLLSAI1R_Pos) |
|
||||
((PllSai1->PLLSAI1M - 1U) << RCC_PLLSAI1CFGR_PLLSAI1M_Pos));
|
||||
#else
|
||||
/* Configure the PLLSAI1 Division factor R and Multiplication factor N*/
|
||||
MODIFY_REG(RCC->PLLSAI1CFGR,
|
||||
RCC_PLLSAI1CFGR_PLLSAI1N | RCC_PLLSAI1CFGR_PLLSAI1R,
|
||||
(PllSai1->PLLSAI1N << RCC_PLLSAI1CFGR_PLLSAI1N_Pos) |
|
||||
(((PllSai1->PLLSAI1R >> 1U) - 1U) << RCC_PLLSAI1CFGR_PLLSAI1R_Pos));
|
||||
#endif /* RCC_PLLSAI1M_DIV_1_16_SUPPORT */
|
||||
}
|
||||
|
||||
/* Enable the PLLSAI1 again by setting PLLSAI1ON to 1*/
|
||||
__HAL_RCC_PLLSAI1_ENABLE();
|
||||
|
||||
/* Get Start Tick*/
|
||||
tickstart = HAL_GetTick();
|
||||
|
||||
/* Wait till PLLSAI1 is ready */
|
||||
while(READ_BIT(RCC->CR, RCC_CR_PLLSAI1RDY) == 0U)
|
||||
{
|
||||
if((HAL_GetTick() - tickstart) > PLLSAI1_TIMEOUT_VALUE)
|
||||
{
|
||||
status = HAL_TIMEOUT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(status == HAL_OK)
|
||||
{
|
||||
/* Configure the PLLSAI1 Clock output(s) */
|
||||
__HAL_RCC_PLLSAI1CLKOUT_ENABLE(PllSai1->PLLSAI1ClockOut);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
#endif /* RCC_PLLSAI1_SUPPORT */
|
||||
|
||||
#if defined(RCC_PLLSAI2_SUPPORT)
|
||||
|
||||
/**
|
||||
* @brief Configure the parameters N & P & optionally M of PLLSAI2 and enable PLLSAI2 output clock(s).
|
||||
* @param PllSai2 pointer to an RCC_PLLSAI2InitTypeDef structure that
|
||||
* contains the configuration parameters N & P & optionally M as well as PLLSAI2 output clock(s)
|
||||
* @param Divider divider parameter to be updated
|
||||
*
|
||||
* @note PLLSAI2 is temporary disable to apply new parameters
|
||||
*
|
||||
* @retval HAL status
|
||||
*/
|
||||
static HAL_StatusTypeDef RCCEx_PLLSAI2_Config(RCC_PLLSAI2InitTypeDef *PllSai2, uint32_t Divider)
|
||||
{
|
||||
uint32_t tickstart;
|
||||
HAL_StatusTypeDef status = HAL_OK;
|
||||
|
||||
/* check for PLLSAI2 Parameters used to output PLLSAI2CLK */
|
||||
/* P, Q and R dividers are verified in each specific divider case below */
|
||||
assert_param(IS_RCC_PLLSAI2SOURCE(PllSai2->PLLSAI2Source));
|
||||
assert_param(IS_RCC_PLLSAI2M_VALUE(PllSai2->PLLSAI2M));
|
||||
assert_param(IS_RCC_PLLSAI2N_VALUE(PllSai2->PLLSAI2N));
|
||||
assert_param(IS_RCC_PLLSAI2CLOCKOUT_VALUE(PllSai2->PLLSAI2ClockOut));
|
||||
|
||||
/* Check that PLLSAI2 clock source and divider M can be applied */
|
||||
if(__HAL_RCC_GET_PLL_OSCSOURCE() != RCC_PLLSOURCE_NONE)
|
||||
{
|
||||
/* PLL clock source and divider M already set, check that no request for change */
|
||||
if((__HAL_RCC_GET_PLL_OSCSOURCE() != PllSai2->PLLSAI2Source)
|
||||
||
|
||||
(PllSai2->PLLSAI2Source == RCC_PLLSOURCE_NONE)
|
||||
#if !defined(RCC_PLLSAI2M_DIV_1_16_SUPPORT)
|
||||
||
|
||||
(((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U) != PllSai2->PLLSAI2M)
|
||||
#endif
|
||||
)
|
||||
{
|
||||
status = HAL_ERROR;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Check PLLSAI2 clock source availability */
|
||||
switch(PllSai2->PLLSAI2Source)
|
||||
{
|
||||
case RCC_PLLSOURCE_MSI:
|
||||
if(HAL_IS_BIT_CLR(RCC->CR, RCC_CR_MSIRDY))
|
||||
{
|
||||
status = HAL_ERROR;
|
||||
}
|
||||
break;
|
||||
case RCC_PLLSOURCE_HSI:
|
||||
if(HAL_IS_BIT_CLR(RCC->CR, RCC_CR_HSIRDY))
|
||||
{
|
||||
status = HAL_ERROR;
|
||||
}
|
||||
break;
|
||||
case RCC_PLLSOURCE_HSE:
|
||||
if(HAL_IS_BIT_CLR(RCC->CR, RCC_CR_HSERDY))
|
||||
{
|
||||
if(HAL_IS_BIT_CLR(RCC->CR, RCC_CR_HSEBYP))
|
||||
{
|
||||
status = HAL_ERROR;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
status = HAL_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
if(status == HAL_OK)
|
||||
{
|
||||
#if defined(RCC_PLLSAI2M_DIV_1_16_SUPPORT)
|
||||
/* Set PLLSAI2 clock source */
|
||||
MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC, PllSai2->PLLSAI2Source);
|
||||
#else
|
||||
/* Set PLLSAI2 clock source and divider M */
|
||||
MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC | RCC_PLLCFGR_PLLM, PllSai2->PLLSAI2Source | (PllSai2->PLLSAI2M - 1U) << RCC_PLLCFGR_PLLM_Pos);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if(status == HAL_OK)
|
||||
{
|
||||
/* Disable the PLLSAI2 */
|
||||
__HAL_RCC_PLLSAI2_DISABLE();
|
||||
|
||||
/* Get Start Tick*/
|
||||
tickstart = HAL_GetTick();
|
||||
|
||||
/* Wait till PLLSAI2 is ready to be updated */
|
||||
while(READ_BIT(RCC->CR, RCC_CR_PLLSAI2RDY) != 0U)
|
||||
{
|
||||
if((HAL_GetTick() - tickstart) > PLLSAI2_TIMEOUT_VALUE)
|
||||
{
|
||||
status = HAL_TIMEOUT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(status == HAL_OK)
|
||||
{
|
||||
if(Divider == DIVIDER_P_UPDATE)
|
||||
{
|
||||
assert_param(IS_RCC_PLLSAI2P_VALUE(PllSai2->PLLSAI2P));
|
||||
#if defined(RCC_PLLSAI2M_DIV_1_16_SUPPORT)
|
||||
|
||||
/* Configure the PLLSAI2 Division factor M, P and Multiplication factor N*/
|
||||
#if defined(RCC_PLLSAI2P_DIV_2_31_SUPPORT)
|
||||
MODIFY_REG(RCC->PLLSAI2CFGR,
|
||||
RCC_PLLSAI2CFGR_PLLSAI2N | RCC_PLLSAI2CFGR_PLLSAI2PDIV | RCC_PLLSAI2CFGR_PLLSAI2M,
|
||||
(PllSai2->PLLSAI2N << RCC_PLLSAI2CFGR_PLLSAI2N_Pos) |
|
||||
(PllSai2->PLLSAI2P << RCC_PLLSAI2CFGR_PLLSAI2PDIV_Pos) |
|
||||
((PllSai2->PLLSAI2M - 1U) << RCC_PLLSAI2CFGR_PLLSAI2M_Pos));
|
||||
#else
|
||||
MODIFY_REG(RCC->PLLSAI2CFGR,
|
||||
RCC_PLLSAI2CFGR_PLLSAI2N | RCC_PLLSAI2CFGR_PLLSAI2P | RCC_PLLSAI2CFGR_PLLSAI2M,
|
||||
(PllSai2->PLLSAI2N << RCC_PLLSAI2CFGR_PLLSAI2N_Pos) |
|
||||
((PllSai2->PLLSAI2P >> 4U) << RCC_PLLSAI2CFGR_PLLSAI2P_Pos) |
|
||||
((PllSai2->PLLSAI2M - 1U) << RCC_PLLSAI2CFGR_PLLSAI2M_Pos));
|
||||
#endif /* RCC_PLLSAI2P_DIV_2_31_SUPPORT */
|
||||
|
||||
#else
|
||||
/* Configure the PLLSAI2 Division factor P and Multiplication factor N*/
|
||||
#if defined(RCC_PLLSAI2P_DIV_2_31_SUPPORT)
|
||||
MODIFY_REG(RCC->PLLSAI2CFGR,
|
||||
RCC_PLLSAI2CFGR_PLLSAI2N | RCC_PLLSAI2CFGR_PLLSAI2PDIV,
|
||||
(PllSai2->PLLSAI2N << RCC_PLLSAI2CFGR_PLLSAI2N_Pos) |
|
||||
(PllSai2->PLLSAI2P << RCC_PLLSAI2CFGR_PLLSAI2PDIV_Pos));
|
||||
#else
|
||||
MODIFY_REG(RCC->PLLSAI2CFGR,
|
||||
RCC_PLLSAI2CFGR_PLLSAI2N | RCC_PLLSAI2CFGR_PLLSAI2P,
|
||||
(PllSai2->PLLSAI2N << RCC_PLLSAI2CFGR_PLLSAI2N_Pos) |
|
||||
((PllSai2->PLLSAI2P >> 4U) << RCC_PLLSAI2CFGR_PLLSAI2P_Pos));
|
||||
#endif /* RCC_PLLSAI2P_DIV_2_31_SUPPORT */
|
||||
|
||||
#endif /* RCC_PLLSAI2M_DIV_1_16_SUPPORT */
|
||||
}
|
||||
#if defined(RCC_PLLSAI2Q_DIV_SUPPORT)
|
||||
else if(Divider == DIVIDER_Q_UPDATE)
|
||||
{
|
||||
assert_param(IS_RCC_PLLSAI2Q_VALUE(PllSai2->PLLSAI2Q));
|
||||
#if defined(RCC_PLLSAI2M_DIV_1_16_SUPPORT)
|
||||
/* Configure the PLLSAI2 Division factor M, Q and Multiplication factor N*/
|
||||
MODIFY_REG(RCC->PLLSAI2CFGR,
|
||||
RCC_PLLSAI2CFGR_PLLSAI2N | RCC_PLLSAI2CFGR_PLLSAI2Q | RCC_PLLSAI2CFGR_PLLSAI2M,
|
||||
(PllSai2->PLLSAI2N << RCC_PLLSAI2CFGR_PLLSAI2N_Pos) |
|
||||
(((PllSai2->PLLSAI2Q >> 1U) - 1U) << RCC_PLLSAI2CFGR_PLLSAI2Q_Pos) |
|
||||
((PllSai2->PLLSAI2M - 1U) << RCC_PLLSAI2CFGR_PLLSAI2M_Pos));
|
||||
#else
|
||||
/* Configure the PLLSAI2 Division factor Q and Multiplication factor N*/
|
||||
MODIFY_REG(RCC->PLLSAI2CFGR,
|
||||
RCC_PLLSAI2CFGR_PLLSAI2N | RCC_PLLSAI2CFGR_PLLSAI2Q,
|
||||
(PllSai2->PLLSAI2N << RCC_PLLSAI2CFGR_PLLSAI2N_Pos) |
|
||||
(((PllSai2->PLLSAI2Q >> 1U) - 1U) << RCC_PLLSAI2CFGR_PLLSAI2Q_Pos));
|
||||
#endif /* RCC_PLLSAI2M_DIV_1_16_SUPPORT */
|
||||
}
|
||||
#endif /* RCC_PLLSAI2Q_DIV_SUPPORT */
|
||||
else
|
||||
{
|
||||
assert_param(IS_RCC_PLLSAI2R_VALUE(PllSai2->PLLSAI2R));
|
||||
#if defined(RCC_PLLSAI2M_DIV_1_16_SUPPORT)
|
||||
/* Configure the PLLSAI2 Division factor M, R and Multiplication factor N*/
|
||||
MODIFY_REG(RCC->PLLSAI2CFGR,
|
||||
RCC_PLLSAI2CFGR_PLLSAI2N | RCC_PLLSAI2CFGR_PLLSAI2R | RCC_PLLSAI2CFGR_PLLSAI2M,
|
||||
(PllSai2->PLLSAI2N << RCC_PLLSAI2CFGR_PLLSAI2N_Pos) |
|
||||
(((PllSai2->PLLSAI2R >> 1U) - 1U) << RCC_PLLSAI2CFGR_PLLSAI2R_Pos) |
|
||||
((PllSai2->PLLSAI2M - 1U) << RCC_PLLSAI2CFGR_PLLSAI2M_Pos));
|
||||
#else
|
||||
/* Configure the PLLSAI2 Division factor R and Multiplication factor N*/
|
||||
MODIFY_REG(RCC->PLLSAI2CFGR,
|
||||
RCC_PLLSAI2CFGR_PLLSAI2N | RCC_PLLSAI2CFGR_PLLSAI2R,
|
||||
(PllSai2->PLLSAI2N << RCC_PLLSAI2CFGR_PLLSAI2N_Pos) |
|
||||
(((PllSai2->PLLSAI2R >> 1U) - 1U) << RCC_PLLSAI2CFGR_PLLSAI2R_Pos));
|
||||
#endif /* RCC_PLLSAI2M_DIV_1_16_SUPPORT */
|
||||
}
|
||||
|
||||
/* Enable the PLLSAI2 again by setting PLLSAI2ON to 1*/
|
||||
__HAL_RCC_PLLSAI2_ENABLE();
|
||||
|
||||
/* Get Start Tick*/
|
||||
tickstart = HAL_GetTick();
|
||||
|
||||
/* Wait till PLLSAI2 is ready */
|
||||
while(READ_BIT(RCC->CR, RCC_CR_PLLSAI2RDY) == 0U)
|
||||
{
|
||||
if((HAL_GetTick() - tickstart) > PLLSAI2_TIMEOUT_VALUE)
|
||||
{
|
||||
status = HAL_TIMEOUT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(status == HAL_OK)
|
||||
{
|
||||
/* Configure the PLLSAI2 Clock output(s) */
|
||||
__HAL_RCC_PLLSAI2CLKOUT_ENABLE(PllSai2->PLLSAI2ClockOut);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
#endif /* RCC_PLLSAI2_SUPPORT */
|
||||
|
||||
#if defined(SAI1)
|
||||
|
||||
static uint32_t RCCEx_GetSAIxPeriphCLKFreq(uint32_t PeriphClk, uint32_t InputFrequency)
|
||||
{
|
||||
uint32_t frequency = 0U;
|
||||
uint32_t srcclk = 0U;
|
||||
uint32_t pllvco, plln; /* no init needed */
|
||||
#if defined(RCC_PLLP_SUPPORT)
|
||||
uint32_t pllp = 0U;
|
||||
#endif /* RCC_PLLP_SUPPORT */
|
||||
|
||||
/* Handle SAIx */
|
||||
if(PeriphClk == RCC_PERIPHCLK_SAI1)
|
||||
{
|
||||
srcclk = __HAL_RCC_GET_SAI1_SOURCE();
|
||||
if(srcclk == RCC_SAI1CLKSOURCE_PIN)
|
||||
{
|
||||
frequency = EXTERNAL_SAI1_CLOCK_VALUE;
|
||||
}
|
||||
/* Else, PLL clock output to check below */
|
||||
}
|
||||
#if defined(SAI2)
|
||||
else
|
||||
{
|
||||
if(PeriphClk == RCC_PERIPHCLK_SAI2)
|
||||
{
|
||||
srcclk = __HAL_RCC_GET_SAI2_SOURCE();
|
||||
if(srcclk == RCC_SAI2CLKSOURCE_PIN)
|
||||
{
|
||||
frequency = EXTERNAL_SAI2_CLOCK_VALUE;
|
||||
}
|
||||
/* Else, PLL clock output to check below */
|
||||
}
|
||||
}
|
||||
#endif /* SAI2 */
|
||||
|
||||
if(frequency == 0U)
|
||||
{
|
||||
pllvco = InputFrequency;
|
||||
|
||||
#if defined(SAI2)
|
||||
if((srcclk == RCC_SAI1CLKSOURCE_PLL) || (srcclk == RCC_SAI2CLKSOURCE_PLL))
|
||||
{
|
||||
if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLLRDY) && (__HAL_RCC_GET_PLLCLKOUT_CONFIG(RCC_PLL_SAI3CLK) != 0U))
|
||||
{
|
||||
/* f(PLL Source) / PLLM */
|
||||
pllvco = (pllvco / ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U));
|
||||
/* f(PLLSAI3CLK) = f(VCO input) * PLLN / PLLP */
|
||||
plln = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos;
|
||||
#if defined(RCC_PLLP_DIV_2_31_SUPPORT)
|
||||
pllp = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLPDIV) >> RCC_PLLCFGR_PLLPDIV_Pos;
|
||||
#endif
|
||||
if(pllp == 0U)
|
||||
{
|
||||
if(READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLP) != 0U)
|
||||
{
|
||||
pllp = 17U;
|
||||
}
|
||||
else
|
||||
{
|
||||
pllp = 7U;
|
||||
}
|
||||
}
|
||||
frequency = (pllvco * plln) / pllp;
|
||||
}
|
||||
}
|
||||
else if(srcclk == 0U) /* RCC_SAI1CLKSOURCE_PLLSAI1 || RCC_SAI2CLKSOURCE_PLLSAI1 */
|
||||
{
|
||||
if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLLSAI1RDY) && (__HAL_RCC_GET_PLLSAI1CLKOUT_CONFIG(RCC_PLLSAI1_SAI1CLK) != 0U))
|
||||
{
|
||||
#if defined(RCC_PLLSAI1M_DIV_1_16_SUPPORT)
|
||||
/* PLLSAI1M exists: apply PLLSAI1M divider for PLLSAI1 output computation */
|
||||
/* f(PLLSAI1 Source) / PLLSAI1M */
|
||||
pllvco = (pllvco / ((READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1M) >> RCC_PLLSAI1CFGR_PLLSAI1M_Pos) + 1U));
|
||||
#else
|
||||
/* f(PLL Source) / PLLM */
|
||||
pllvco = (pllvco / ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U));
|
||||
#endif
|
||||
/* f(PLLSAI1CLK) = f(VCOSAI1 input) * PLLSAI1N / PLLSAI1P */
|
||||
plln = READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1N) >> RCC_PLLSAI1CFGR_PLLSAI1N_Pos;
|
||||
#if defined(RCC_PLLSAI1P_DIV_2_31_SUPPORT)
|
||||
pllp = READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1PDIV) >> RCC_PLLSAI1CFGR_PLLSAI1PDIV_Pos;
|
||||
#endif
|
||||
if(pllp == 0U)
|
||||
{
|
||||
if(READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1P) != 0U)
|
||||
{
|
||||
pllp = 17U;
|
||||
}
|
||||
else
|
||||
{
|
||||
pllp = 7U;
|
||||
}
|
||||
}
|
||||
frequency = (pllvco * plln) / pllp;
|
||||
}
|
||||
}
|
||||
#if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
|
||||
else if((srcclk == RCC_SAI1CLKSOURCE_HSI) || (srcclk == RCC_SAI2CLKSOURCE_HSI))
|
||||
{
|
||||
if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))
|
||||
{
|
||||
frequency = HSI_VALUE;
|
||||
}
|
||||
}
|
||||
#endif /* STM32L4P5xx || STM32L4Q5xx || STM32L4R5xx || STM32L4R7xx || STM32L4R9xx || STM32L4S5xx || STM32L4S7xx || STM32L4S9xx */
|
||||
|
||||
#else
|
||||
if(srcclk == RCC_SAI1CLKSOURCE_PLL)
|
||||
{
|
||||
if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLLRDY) && (__HAL_RCC_GET_PLLCLKOUT_CONFIG(RCC_PLL_SAI2CLK) != 0U))
|
||||
{
|
||||
/* f(PLL Source) / PLLM */
|
||||
pllvco = (pllvco / ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U));
|
||||
/* f(PLLSAI2CLK) = f(VCO input) * PLLN / PLLP */
|
||||
plln = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos;
|
||||
#if defined(RCC_PLLP_DIV_2_31_SUPPORT)
|
||||
pllp = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLPDIV) >> RCC_PLLCFGR_PLLPDIV_Pos;
|
||||
#endif
|
||||
if(pllp == 0U)
|
||||
{
|
||||
if(READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLP) != 0U)
|
||||
{
|
||||
pllp = 17U;
|
||||
}
|
||||
else
|
||||
{
|
||||
pllp = 7U;
|
||||
}
|
||||
}
|
||||
frequency = (pllvco * plln) / pllp;
|
||||
}
|
||||
else if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))
|
||||
{
|
||||
/* HSI automatically selected as clock source if PLLs not enabled */
|
||||
frequency = HSI_VALUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No clock source, frequency default init at 0 */
|
||||
}
|
||||
}
|
||||
else if(srcclk == RCC_SAI1CLKSOURCE_PLLSAI1)
|
||||
{
|
||||
if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLLSAI1RDY) && (__HAL_RCC_GET_PLLSAI1CLKOUT_CONFIG(RCC_PLLSAI1_SAI1CLK) != 0U))
|
||||
{
|
||||
#if defined(RCC_PLLSAI1M_DIV_1_16_SUPPORT)
|
||||
/* PLLSAI1M exists: apply PLLSAI1M divider for PLLSAI1 output computation */
|
||||
/* f(PLLSAI1 Source) / PLLSAI1M */
|
||||
pllvco = (pllvco / ((READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1M) >> RCC_PLLSAI1CFGR_PLLSAI1M_Pos) + 1U));
|
||||
#else
|
||||
/* f(PLL Source) / PLLM */
|
||||
pllvco = (pllvco / ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U));
|
||||
#endif
|
||||
/* f(PLLSAI1CLK) = f(VCOSAI1 input) * PLLSAI1N / PLLSAI1P */
|
||||
plln = READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1N) >> RCC_PLLSAI1CFGR_PLLSAI1N_Pos;
|
||||
#if defined(RCC_PLLSAI1P_DIV_2_31_SUPPORT)
|
||||
pllp = READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1PDIV) >> RCC_PLLSAI1CFGR_PLLSAI1PDIV_Pos;
|
||||
#endif
|
||||
if(pllp == 0U)
|
||||
{
|
||||
if(READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1P) != 0U)
|
||||
{
|
||||
pllp = 17U;
|
||||
}
|
||||
else
|
||||
{
|
||||
pllp = 7U;
|
||||
}
|
||||
}
|
||||
frequency = (pllvco * plln) / pllp;
|
||||
}
|
||||
else if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))
|
||||
{
|
||||
/* HSI automatically selected as clock source if PLLs not enabled */
|
||||
frequency = HSI_VALUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No clock source, frequency default init at 0 */
|
||||
}
|
||||
}
|
||||
#endif /* SAI2 */
|
||||
|
||||
#if defined(RCC_PLLSAI2_SUPPORT)
|
||||
|
||||
else if((srcclk == RCC_SAI1CLKSOURCE_PLLSAI2) || (srcclk == RCC_SAI2CLKSOURCE_PLLSAI2))
|
||||
{
|
||||
if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLLSAI2RDY) && (__HAL_RCC_GET_PLLSAI2CLKOUT_CONFIG(RCC_PLLSAI2_SAI2CLK) != 0U))
|
||||
{
|
||||
#if defined(RCC_PLLSAI2M_DIV_1_16_SUPPORT)
|
||||
/* PLLSAI2M exists: apply PLLSAI2M divider for PLLSAI2 output computation */
|
||||
/* f(PLLSAI2 Source) / PLLSAI2M */
|
||||
pllvco = (pllvco / ((READ_BIT(RCC->PLLSAI2CFGR, RCC_PLLSAI2CFGR_PLLSAI2M) >> RCC_PLLSAI2CFGR_PLLSAI2M_Pos) + 1U));
|
||||
#else
|
||||
/* f(PLL Source) / PLLM */
|
||||
pllvco = (pllvco / ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U));
|
||||
#endif
|
||||
/* f(PLLSAI2CLK) = f(VCOSAI2 input) * PLLSAI2N / PLLSAI2P */
|
||||
plln = READ_BIT(RCC->PLLSAI2CFGR, RCC_PLLSAI2CFGR_PLLSAI2N) >> RCC_PLLSAI2CFGR_PLLSAI2N_Pos;
|
||||
#if defined(RCC_PLLSAI2P_DIV_2_31_SUPPORT)
|
||||
pllp = READ_BIT(RCC->PLLSAI2CFGR, RCC_PLLSAI2CFGR_PLLSAI2PDIV) >> RCC_PLLSAI2CFGR_PLLSAI2PDIV_Pos;
|
||||
#endif
|
||||
if(pllp == 0U)
|
||||
{
|
||||
if(READ_BIT(RCC->PLLSAI2CFGR, RCC_PLLSAI2CFGR_PLLSAI2P) != 0U)
|
||||
{
|
||||
pllp = 17U;
|
||||
}
|
||||
else
|
||||
{
|
||||
pllp = 7U;
|
||||
}
|
||||
}
|
||||
frequency = (pllvco * plln) / pllp;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* RCC_PLLSAI2_SUPPORT */
|
||||
|
||||
else
|
||||
{
|
||||
/* No clock source, frequency default init at 0 */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return frequency;
|
||||
}
|
||||
|
||||
#endif /* SAI1 */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* HAL_RCC_MODULE_ENABLED */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,2838 +0,0 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32l4xx_hal_tim_ex.c
|
||||
* @author MCD Application Team
|
||||
* @brief TIM HAL module driver.
|
||||
* This file provides firmware functions to manage the following
|
||||
* functionalities of the Timer Extended peripheral:
|
||||
* + Time Hall Sensor Interface Initialization
|
||||
* + Time Hall Sensor Interface Start
|
||||
* + Time Complementary signal break and dead time configuration
|
||||
* + Time Master and Slave synchronization configuration
|
||||
* + Time Output Compare/PWM Channel Configuration (for channels 5 and 6)
|
||||
* + Time OCRef clear configuration
|
||||
* + Timer remapping capabilities configuration
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2017 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
@verbatim
|
||||
==============================================================================
|
||||
##### TIMER Extended features #####
|
||||
==============================================================================
|
||||
[..]
|
||||
The Timer Extended features include:
|
||||
(#) Complementary outputs with programmable dead-time for :
|
||||
(++) Output Compare
|
||||
(++) PWM generation (Edge and Center-aligned Mode)
|
||||
(++) One-pulse mode output
|
||||
(#) Synchronization circuit to control the timer with external signals and to
|
||||
interconnect several timers together.
|
||||
(#) Break input to put the timer output signals in reset state or in a known state.
|
||||
(#) Supports incremental (quadrature) encoder and hall-sensor circuitry for
|
||||
positioning purposes
|
||||
|
||||
##### How to use this driver #####
|
||||
==============================================================================
|
||||
[..]
|
||||
(#) Initialize the TIM low level resources by implementing the following functions
|
||||
depending on the selected feature:
|
||||
(++) Hall Sensor output : HAL_TIMEx_HallSensor_MspInit()
|
||||
|
||||
(#) Initialize the TIM low level resources :
|
||||
(##) Enable the TIM interface clock using __HAL_RCC_TIMx_CLK_ENABLE();
|
||||
(##) TIM pins configuration
|
||||
(+++) Enable the clock for the TIM GPIOs using the following function:
|
||||
__HAL_RCC_GPIOx_CLK_ENABLE();
|
||||
(+++) Configure these TIM pins in Alternate function mode using HAL_GPIO_Init();
|
||||
|
||||
(#) The external Clock can be configured, if needed (the default clock is the
|
||||
internal clock from the APBx), using the following function:
|
||||
HAL_TIM_ConfigClockSource, the clock configuration should be done before
|
||||
any start function.
|
||||
|
||||
(#) Configure the TIM in the desired functioning mode using one of the
|
||||
initialization function of this driver:
|
||||
(++) HAL_TIMEx_HallSensor_Init() and HAL_TIMEx_ConfigCommutEvent(): to use the
|
||||
Timer Hall Sensor Interface and the commutation event with the corresponding
|
||||
Interrupt and DMA request if needed (Note that One Timer is used to interface
|
||||
with the Hall sensor Interface and another Timer should be used to use
|
||||
the commutation event).
|
||||
|
||||
(#) Activate the TIM peripheral using one of the start functions:
|
||||
(++) Complementary Output Compare : HAL_TIMEx_OCN_Start(), HAL_TIMEx_OCN_Start_DMA(),
|
||||
HAL_TIMEx_OCN_Start_IT()
|
||||
(++) Complementary PWM generation : HAL_TIMEx_PWMN_Start(), HAL_TIMEx_PWMN_Start_DMA(),
|
||||
HAL_TIMEx_PWMN_Start_IT()
|
||||
(++) Complementary One-pulse mode output : HAL_TIMEx_OnePulseN_Start(), HAL_TIMEx_OnePulseN_Start_IT()
|
||||
(++) Hall Sensor output : HAL_TIMEx_HallSensor_Start(), HAL_TIMEx_HallSensor_Start_DMA(),
|
||||
HAL_TIMEx_HallSensor_Start_IT().
|
||||
|
||||
@endverbatim
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32l4xx_hal.h"
|
||||
|
||||
/** @addtogroup STM32L4xx_HAL_Driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup TIMEx TIMEx
|
||||
* @brief TIM Extended HAL module driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifdef HAL_TIM_MODULE_ENABLED
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* Private macros ------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
static void TIM_DMADelayPulseNCplt(DMA_HandleTypeDef *hdma);
|
||||
static void TIM_DMAErrorCCxN(DMA_HandleTypeDef *hdma);
|
||||
static void TIM_CCxNChannelCmd(TIM_TypeDef *TIMx, uint32_t Channel, uint32_t ChannelNState);
|
||||
|
||||
/* Exported functions --------------------------------------------------------*/
|
||||
/** @defgroup TIMEx_Exported_Functions TIM Extended Exported Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup TIMEx_Exported_Functions_Group1 Extended Timer Hall Sensor functions
|
||||
* @brief Timer Hall Sensor functions
|
||||
*
|
||||
@verbatim
|
||||
==============================================================================
|
||||
##### Timer Hall Sensor functions #####
|
||||
==============================================================================
|
||||
[..]
|
||||
This section provides functions allowing to:
|
||||
(+) Initialize and configure TIM HAL Sensor.
|
||||
(+) De-initialize TIM HAL Sensor.
|
||||
(+) Start the Hall Sensor Interface.
|
||||
(+) Stop the Hall Sensor Interface.
|
||||
(+) Start the Hall Sensor Interface and enable interrupts.
|
||||
(+) Stop the Hall Sensor Interface and disable interrupts.
|
||||
(+) Start the Hall Sensor Interface and enable DMA transfers.
|
||||
(+) Stop the Hall Sensor Interface and disable DMA transfers.
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Initializes the TIM Hall Sensor Interface and initialize the associated handle.
|
||||
* @note When the timer instance is initialized in Hall Sensor Interface mode,
|
||||
* timer channels 1 and channel 2 are reserved and cannot be used for
|
||||
* other purpose.
|
||||
* @param htim TIM Hall Sensor Interface handle
|
||||
* @param sConfig TIM Hall Sensor configuration structure
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_TIMEx_HallSensor_Init(TIM_HandleTypeDef *htim, TIM_HallSensor_InitTypeDef *sConfig)
|
||||
{
|
||||
TIM_OC_InitTypeDef OC_Config;
|
||||
|
||||
/* Check the TIM handle allocation */
|
||||
if (htim == NULL)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_HALL_SENSOR_INTERFACE_INSTANCE(htim->Instance));
|
||||
assert_param(IS_TIM_COUNTER_MODE(htim->Init.CounterMode));
|
||||
assert_param(IS_TIM_CLOCKDIVISION_DIV(htim->Init.ClockDivision));
|
||||
assert_param(IS_TIM_AUTORELOAD_PRELOAD(htim->Init.AutoReloadPreload));
|
||||
assert_param(IS_TIM_IC_POLARITY(sConfig->IC1Polarity));
|
||||
assert_param(IS_TIM_IC_PRESCALER(sConfig->IC1Prescaler));
|
||||
assert_param(IS_TIM_IC_FILTER(sConfig->IC1Filter));
|
||||
|
||||
if (htim->State == HAL_TIM_STATE_RESET)
|
||||
{
|
||||
/* Allocate lock resource and initialize it */
|
||||
htim->Lock = HAL_UNLOCKED;
|
||||
|
||||
#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
|
||||
/* Reset interrupt callbacks to legacy week callbacks */
|
||||
TIM_ResetCallback(htim);
|
||||
|
||||
if (htim->HallSensor_MspInitCallback == NULL)
|
||||
{
|
||||
htim->HallSensor_MspInitCallback = HAL_TIMEx_HallSensor_MspInit;
|
||||
}
|
||||
/* Init the low level hardware : GPIO, CLOCK, NVIC */
|
||||
htim->HallSensor_MspInitCallback(htim);
|
||||
#else
|
||||
/* Init the low level hardware : GPIO, CLOCK, NVIC and DMA */
|
||||
HAL_TIMEx_HallSensor_MspInit(htim);
|
||||
#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
|
||||
}
|
||||
|
||||
/* Set the TIM state */
|
||||
htim->State = HAL_TIM_STATE_BUSY;
|
||||
|
||||
/* Configure the Time base in the Encoder Mode */
|
||||
TIM_Base_SetConfig(htim->Instance, &htim->Init);
|
||||
|
||||
/* Configure the Channel 1 as Input Channel to interface with the three Outputs of the Hall sensor */
|
||||
TIM_TI1_SetConfig(htim->Instance, sConfig->IC1Polarity, TIM_ICSELECTION_TRC, sConfig->IC1Filter);
|
||||
|
||||
/* Reset the IC1PSC Bits */
|
||||
htim->Instance->CCMR1 &= ~TIM_CCMR1_IC1PSC;
|
||||
/* Set the IC1PSC value */
|
||||
htim->Instance->CCMR1 |= sConfig->IC1Prescaler;
|
||||
|
||||
/* Enable the Hall sensor interface (XOR function of the three inputs) */
|
||||
htim->Instance->CR2 |= TIM_CR2_TI1S;
|
||||
|
||||
/* Select the TIM_TS_TI1F_ED signal as Input trigger for the TIM */
|
||||
htim->Instance->SMCR &= ~TIM_SMCR_TS;
|
||||
htim->Instance->SMCR |= TIM_TS_TI1F_ED;
|
||||
|
||||
/* Use the TIM_TS_TI1F_ED signal to reset the TIM counter each edge detection */
|
||||
htim->Instance->SMCR &= ~TIM_SMCR_SMS;
|
||||
htim->Instance->SMCR |= TIM_SLAVEMODE_RESET;
|
||||
|
||||
/* Program channel 2 in PWM 2 mode with the desired Commutation_Delay*/
|
||||
OC_Config.OCFastMode = TIM_OCFAST_DISABLE;
|
||||
OC_Config.OCIdleState = TIM_OCIDLESTATE_RESET;
|
||||
OC_Config.OCMode = TIM_OCMODE_PWM2;
|
||||
OC_Config.OCNIdleState = TIM_OCNIDLESTATE_RESET;
|
||||
OC_Config.OCNPolarity = TIM_OCNPOLARITY_HIGH;
|
||||
OC_Config.OCPolarity = TIM_OCPOLARITY_HIGH;
|
||||
OC_Config.Pulse = sConfig->Commutation_Delay;
|
||||
|
||||
TIM_OC2_SetConfig(htim->Instance, &OC_Config);
|
||||
|
||||
/* Select OC2REF as trigger output on TRGO: write the MMS bits in the TIMx_CR2
|
||||
register to 101 */
|
||||
htim->Instance->CR2 &= ~TIM_CR2_MMS;
|
||||
htim->Instance->CR2 |= TIM_TRGO_OC2REF;
|
||||
|
||||
/* Initialize the DMA burst operation state */
|
||||
htim->DMABurstState = HAL_DMA_BURST_STATE_READY;
|
||||
|
||||
/* Initialize the TIM channels state */
|
||||
TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY);
|
||||
TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY);
|
||||
TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY);
|
||||
TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY);
|
||||
|
||||
/* Initialize the TIM state*/
|
||||
htim->State = HAL_TIM_STATE_READY;
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DeInitializes the TIM Hall Sensor interface
|
||||
* @param htim TIM Hall Sensor Interface handle
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_TIMEx_HallSensor_DeInit(TIM_HandleTypeDef *htim)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_INSTANCE(htim->Instance));
|
||||
|
||||
htim->State = HAL_TIM_STATE_BUSY;
|
||||
|
||||
/* Disable the TIM Peripheral Clock */
|
||||
__HAL_TIM_DISABLE(htim);
|
||||
|
||||
#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
|
||||
if (htim->HallSensor_MspDeInitCallback == NULL)
|
||||
{
|
||||
htim->HallSensor_MspDeInitCallback = HAL_TIMEx_HallSensor_MspDeInit;
|
||||
}
|
||||
/* DeInit the low level hardware */
|
||||
htim->HallSensor_MspDeInitCallback(htim);
|
||||
#else
|
||||
/* DeInit the low level hardware: GPIO, CLOCK, NVIC */
|
||||
HAL_TIMEx_HallSensor_MspDeInit(htim);
|
||||
#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
|
||||
|
||||
/* Change the DMA burst operation state */
|
||||
htim->DMABurstState = HAL_DMA_BURST_STATE_RESET;
|
||||
|
||||
/* Change the TIM channels state */
|
||||
TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_RESET);
|
||||
TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_RESET);
|
||||
TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_RESET);
|
||||
TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_RESET);
|
||||
|
||||
/* Change TIM state */
|
||||
htim->State = HAL_TIM_STATE_RESET;
|
||||
|
||||
/* Release Lock */
|
||||
__HAL_UNLOCK(htim);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initializes the TIM Hall Sensor MSP.
|
||||
* @param htim TIM Hall Sensor Interface handle
|
||||
* @retval None
|
||||
*/
|
||||
__weak void HAL_TIMEx_HallSensor_MspInit(TIM_HandleTypeDef *htim)
|
||||
{
|
||||
/* Prevent unused argument(s) compilation warning */
|
||||
UNUSED(htim);
|
||||
|
||||
/* NOTE : This function should not be modified, when the callback is needed,
|
||||
the HAL_TIMEx_HallSensor_MspInit could be implemented in the user file
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DeInitializes TIM Hall Sensor MSP.
|
||||
* @param htim TIM Hall Sensor Interface handle
|
||||
* @retval None
|
||||
*/
|
||||
__weak void HAL_TIMEx_HallSensor_MspDeInit(TIM_HandleTypeDef *htim)
|
||||
{
|
||||
/* Prevent unused argument(s) compilation warning */
|
||||
UNUSED(htim);
|
||||
|
||||
/* NOTE : This function should not be modified, when the callback is needed,
|
||||
the HAL_TIMEx_HallSensor_MspDeInit could be implemented in the user file
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Starts the TIM Hall Sensor Interface.
|
||||
* @param htim TIM Hall Sensor Interface handle
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_TIMEx_HallSensor_Start(TIM_HandleTypeDef *htim)
|
||||
{
|
||||
uint32_t tmpsmcr;
|
||||
HAL_TIM_ChannelStateTypeDef channel_1_state = TIM_CHANNEL_STATE_GET(htim, TIM_CHANNEL_1);
|
||||
HAL_TIM_ChannelStateTypeDef channel_2_state = TIM_CHANNEL_STATE_GET(htim, TIM_CHANNEL_2);
|
||||
HAL_TIM_ChannelStateTypeDef complementary_channel_1_state = TIM_CHANNEL_N_STATE_GET(htim, TIM_CHANNEL_1);
|
||||
HAL_TIM_ChannelStateTypeDef complementary_channel_2_state = TIM_CHANNEL_N_STATE_GET(htim, TIM_CHANNEL_2);
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_HALL_SENSOR_INTERFACE_INSTANCE(htim->Instance));
|
||||
|
||||
/* Check the TIM channels state */
|
||||
if ((channel_1_state != HAL_TIM_CHANNEL_STATE_READY)
|
||||
|| (channel_2_state != HAL_TIM_CHANNEL_STATE_READY)
|
||||
|| (complementary_channel_1_state != HAL_TIM_CHANNEL_STATE_READY)
|
||||
|| (complementary_channel_2_state != HAL_TIM_CHANNEL_STATE_READY))
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Set the TIM channels state */
|
||||
TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY);
|
||||
TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY);
|
||||
TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY);
|
||||
TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY);
|
||||
|
||||
/* Enable the Input Capture channel 1
|
||||
(in the Hall Sensor Interface the three possible channels that can be used are TIM_CHANNEL_1,
|
||||
TIM_CHANNEL_2 and TIM_CHANNEL_3) */
|
||||
TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE);
|
||||
|
||||
/* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */
|
||||
if (IS_TIM_SLAVE_INSTANCE(htim->Instance))
|
||||
{
|
||||
tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS;
|
||||
if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr))
|
||||
{
|
||||
__HAL_TIM_ENABLE(htim);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
__HAL_TIM_ENABLE(htim);
|
||||
}
|
||||
|
||||
/* Return function status */
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stops the TIM Hall sensor Interface.
|
||||
* @param htim TIM Hall Sensor Interface handle
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_TIMEx_HallSensor_Stop(TIM_HandleTypeDef *htim)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_HALL_SENSOR_INTERFACE_INSTANCE(htim->Instance));
|
||||
|
||||
/* Disable the Input Capture channels 1, 2 and 3
|
||||
(in the Hall Sensor Interface the three possible channels that can be used are TIM_CHANNEL_1,
|
||||
TIM_CHANNEL_2 and TIM_CHANNEL_3) */
|
||||
TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_DISABLE);
|
||||
|
||||
/* Disable the Peripheral */
|
||||
__HAL_TIM_DISABLE(htim);
|
||||
|
||||
/* Set the TIM channels state */
|
||||
TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY);
|
||||
TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY);
|
||||
TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY);
|
||||
TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY);
|
||||
|
||||
/* Return function status */
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Starts the TIM Hall Sensor Interface in interrupt mode.
|
||||
* @param htim TIM Hall Sensor Interface handle
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_TIMEx_HallSensor_Start_IT(TIM_HandleTypeDef *htim)
|
||||
{
|
||||
uint32_t tmpsmcr;
|
||||
HAL_TIM_ChannelStateTypeDef channel_1_state = TIM_CHANNEL_STATE_GET(htim, TIM_CHANNEL_1);
|
||||
HAL_TIM_ChannelStateTypeDef channel_2_state = TIM_CHANNEL_STATE_GET(htim, TIM_CHANNEL_2);
|
||||
HAL_TIM_ChannelStateTypeDef complementary_channel_1_state = TIM_CHANNEL_N_STATE_GET(htim, TIM_CHANNEL_1);
|
||||
HAL_TIM_ChannelStateTypeDef complementary_channel_2_state = TIM_CHANNEL_N_STATE_GET(htim, TIM_CHANNEL_2);
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_HALL_SENSOR_INTERFACE_INSTANCE(htim->Instance));
|
||||
|
||||
/* Check the TIM channels state */
|
||||
if ((channel_1_state != HAL_TIM_CHANNEL_STATE_READY)
|
||||
|| (channel_2_state != HAL_TIM_CHANNEL_STATE_READY)
|
||||
|| (complementary_channel_1_state != HAL_TIM_CHANNEL_STATE_READY)
|
||||
|| (complementary_channel_2_state != HAL_TIM_CHANNEL_STATE_READY))
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Set the TIM channels state */
|
||||
TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY);
|
||||
TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY);
|
||||
TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY);
|
||||
TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY);
|
||||
|
||||
/* Enable the capture compare Interrupts 1 event */
|
||||
__HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1);
|
||||
|
||||
/* Enable the Input Capture channel 1
|
||||
(in the Hall Sensor Interface the three possible channels that can be used are TIM_CHANNEL_1,
|
||||
TIM_CHANNEL_2 and TIM_CHANNEL_3) */
|
||||
TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE);
|
||||
|
||||
/* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */
|
||||
if (IS_TIM_SLAVE_INSTANCE(htim->Instance))
|
||||
{
|
||||
tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS;
|
||||
if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr))
|
||||
{
|
||||
__HAL_TIM_ENABLE(htim);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
__HAL_TIM_ENABLE(htim);
|
||||
}
|
||||
|
||||
/* Return function status */
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stops the TIM Hall Sensor Interface in interrupt mode.
|
||||
* @param htim TIM Hall Sensor Interface handle
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_TIMEx_HallSensor_Stop_IT(TIM_HandleTypeDef *htim)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_HALL_SENSOR_INTERFACE_INSTANCE(htim->Instance));
|
||||
|
||||
/* Disable the Input Capture channel 1
|
||||
(in the Hall Sensor Interface the three possible channels that can be used are TIM_CHANNEL_1,
|
||||
TIM_CHANNEL_2 and TIM_CHANNEL_3) */
|
||||
TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_DISABLE);
|
||||
|
||||
/* Disable the capture compare Interrupts event */
|
||||
__HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1);
|
||||
|
||||
/* Disable the Peripheral */
|
||||
__HAL_TIM_DISABLE(htim);
|
||||
|
||||
/* Set the TIM channels state */
|
||||
TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY);
|
||||
TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY);
|
||||
TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY);
|
||||
TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY);
|
||||
|
||||
/* Return function status */
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Starts the TIM Hall Sensor Interface in DMA mode.
|
||||
* @param htim TIM Hall Sensor Interface handle
|
||||
* @param pData The destination Buffer address.
|
||||
* @param Length The length of data to be transferred from TIM peripheral to memory.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_TIMEx_HallSensor_Start_DMA(TIM_HandleTypeDef *htim, uint32_t *pData, uint16_t Length)
|
||||
{
|
||||
uint32_t tmpsmcr;
|
||||
HAL_TIM_ChannelStateTypeDef channel_1_state = TIM_CHANNEL_STATE_GET(htim, TIM_CHANNEL_1);
|
||||
HAL_TIM_ChannelStateTypeDef complementary_channel_1_state = TIM_CHANNEL_N_STATE_GET(htim, TIM_CHANNEL_1);
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_HALL_SENSOR_INTERFACE_INSTANCE(htim->Instance));
|
||||
|
||||
/* Set the TIM channel state */
|
||||
if ((channel_1_state == HAL_TIM_CHANNEL_STATE_BUSY)
|
||||
|| (complementary_channel_1_state == HAL_TIM_CHANNEL_STATE_BUSY))
|
||||
{
|
||||
return HAL_BUSY;
|
||||
}
|
||||
else if ((channel_1_state == HAL_TIM_CHANNEL_STATE_READY)
|
||||
&& (complementary_channel_1_state == HAL_TIM_CHANNEL_STATE_READY))
|
||||
{
|
||||
if ((pData == NULL) && (Length > 0U))
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY);
|
||||
TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Enable the Input Capture channel 1
|
||||
(in the Hall Sensor Interface the three possible channels that can be used are TIM_CHANNEL_1,
|
||||
TIM_CHANNEL_2 and TIM_CHANNEL_3) */
|
||||
TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE);
|
||||
|
||||
/* Set the DMA Input Capture 1 Callbacks */
|
||||
htim->hdma[TIM_DMA_ID_CC1]->XferCpltCallback = TIM_DMACaptureCplt;
|
||||
htim->hdma[TIM_DMA_ID_CC1]->XferHalfCpltCallback = TIM_DMACaptureHalfCplt;
|
||||
/* Set the DMA error callback */
|
||||
htim->hdma[TIM_DMA_ID_CC1]->XferErrorCallback = TIM_DMAError ;
|
||||
|
||||
/* Enable the DMA channel for Capture 1*/
|
||||
if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC1], (uint32_t)&htim->Instance->CCR1, (uint32_t)pData, Length) != HAL_OK)
|
||||
{
|
||||
/* Return error status */
|
||||
return HAL_ERROR;
|
||||
}
|
||||
/* Enable the capture compare 1 Interrupt */
|
||||
__HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC1);
|
||||
|
||||
/* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */
|
||||
if (IS_TIM_SLAVE_INSTANCE(htim->Instance))
|
||||
{
|
||||
tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS;
|
||||
if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr))
|
||||
{
|
||||
__HAL_TIM_ENABLE(htim);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
__HAL_TIM_ENABLE(htim);
|
||||
}
|
||||
|
||||
/* Return function status */
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stops the TIM Hall Sensor Interface in DMA mode.
|
||||
* @param htim TIM Hall Sensor Interface handle
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_TIMEx_HallSensor_Stop_DMA(TIM_HandleTypeDef *htim)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_HALL_SENSOR_INTERFACE_INSTANCE(htim->Instance));
|
||||
|
||||
/* Disable the Input Capture channel 1
|
||||
(in the Hall Sensor Interface the three possible channels that can be used are TIM_CHANNEL_1,
|
||||
TIM_CHANNEL_2 and TIM_CHANNEL_3) */
|
||||
TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_DISABLE);
|
||||
|
||||
|
||||
/* Disable the capture compare Interrupts 1 event */
|
||||
__HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC1);
|
||||
|
||||
(void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC1]);
|
||||
|
||||
/* Disable the Peripheral */
|
||||
__HAL_TIM_DISABLE(htim);
|
||||
|
||||
/* Set the TIM channel state */
|
||||
TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY);
|
||||
TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY);
|
||||
|
||||
/* Return function status */
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup TIMEx_Exported_Functions_Group2 Extended Timer Complementary Output Compare functions
|
||||
* @brief Timer Complementary Output Compare functions
|
||||
*
|
||||
@verbatim
|
||||
==============================================================================
|
||||
##### Timer Complementary Output Compare functions #####
|
||||
==============================================================================
|
||||
[..]
|
||||
This section provides functions allowing to:
|
||||
(+) Start the Complementary Output Compare/PWM.
|
||||
(+) Stop the Complementary Output Compare/PWM.
|
||||
(+) Start the Complementary Output Compare/PWM and enable interrupts.
|
||||
(+) Stop the Complementary Output Compare/PWM and disable interrupts.
|
||||
(+) Start the Complementary Output Compare/PWM and enable DMA transfers.
|
||||
(+) Stop the Complementary Output Compare/PWM and disable DMA transfers.
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Starts the TIM Output Compare signal generation on the complementary
|
||||
* output.
|
||||
* @param htim TIM Output Compare handle
|
||||
* @param Channel TIM Channel to be enabled
|
||||
* This parameter can be one of the following values:
|
||||
* @arg TIM_CHANNEL_1: TIM Channel 1 selected
|
||||
* @arg TIM_CHANNEL_2: TIM Channel 2 selected
|
||||
* @arg TIM_CHANNEL_3: TIM Channel 3 selected
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_TIMEx_OCN_Start(TIM_HandleTypeDef *htim, uint32_t Channel)
|
||||
{
|
||||
uint32_t tmpsmcr;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
|
||||
|
||||
/* Check the TIM complementary channel state */
|
||||
if (TIM_CHANNEL_N_STATE_GET(htim, Channel) != HAL_TIM_CHANNEL_STATE_READY)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Set the TIM complementary channel state */
|
||||
TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_BUSY);
|
||||
|
||||
/* Enable the Capture compare channel N */
|
||||
TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_ENABLE);
|
||||
|
||||
/* Enable the Main Output */
|
||||
__HAL_TIM_MOE_ENABLE(htim);
|
||||
|
||||
/* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */
|
||||
if (IS_TIM_SLAVE_INSTANCE(htim->Instance))
|
||||
{
|
||||
tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS;
|
||||
if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr))
|
||||
{
|
||||
__HAL_TIM_ENABLE(htim);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
__HAL_TIM_ENABLE(htim);
|
||||
}
|
||||
|
||||
/* Return function status */
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stops the TIM Output Compare signal generation on the complementary
|
||||
* output.
|
||||
* @param htim TIM handle
|
||||
* @param Channel TIM Channel to be disabled
|
||||
* This parameter can be one of the following values:
|
||||
* @arg TIM_CHANNEL_1: TIM Channel 1 selected
|
||||
* @arg TIM_CHANNEL_2: TIM Channel 2 selected
|
||||
* @arg TIM_CHANNEL_3: TIM Channel 3 selected
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_TIMEx_OCN_Stop(TIM_HandleTypeDef *htim, uint32_t Channel)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
|
||||
|
||||
/* Disable the Capture compare channel N */
|
||||
TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_DISABLE);
|
||||
|
||||
/* Disable the Main Output */
|
||||
__HAL_TIM_MOE_DISABLE(htim);
|
||||
|
||||
/* Disable the Peripheral */
|
||||
__HAL_TIM_DISABLE(htim);
|
||||
|
||||
/* Set the TIM complementary channel state */
|
||||
TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY);
|
||||
|
||||
/* Return function status */
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Starts the TIM Output Compare signal generation in interrupt mode
|
||||
* on the complementary output.
|
||||
* @param htim TIM OC handle
|
||||
* @param Channel TIM Channel to be enabled
|
||||
* This parameter can be one of the following values:
|
||||
* @arg TIM_CHANNEL_1: TIM Channel 1 selected
|
||||
* @arg TIM_CHANNEL_2: TIM Channel 2 selected
|
||||
* @arg TIM_CHANNEL_3: TIM Channel 3 selected
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_TIMEx_OCN_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel)
|
||||
{
|
||||
HAL_StatusTypeDef status = HAL_OK;
|
||||
uint32_t tmpsmcr;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
|
||||
|
||||
/* Check the TIM complementary channel state */
|
||||
if (TIM_CHANNEL_N_STATE_GET(htim, Channel) != HAL_TIM_CHANNEL_STATE_READY)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Set the TIM complementary channel state */
|
||||
TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_BUSY);
|
||||
|
||||
switch (Channel)
|
||||
{
|
||||
case TIM_CHANNEL_1:
|
||||
{
|
||||
/* Enable the TIM Output Compare interrupt */
|
||||
__HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1);
|
||||
break;
|
||||
}
|
||||
|
||||
case TIM_CHANNEL_2:
|
||||
{
|
||||
/* Enable the TIM Output Compare interrupt */
|
||||
__HAL_TIM_ENABLE_IT(htim, TIM_IT_CC2);
|
||||
break;
|
||||
}
|
||||
|
||||
case TIM_CHANNEL_3:
|
||||
{
|
||||
/* Enable the TIM Output Compare interrupt */
|
||||
__HAL_TIM_ENABLE_IT(htim, TIM_IT_CC3);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
default:
|
||||
status = HAL_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
if (status == HAL_OK)
|
||||
{
|
||||
/* Enable the TIM Break interrupt */
|
||||
__HAL_TIM_ENABLE_IT(htim, TIM_IT_BREAK);
|
||||
|
||||
/* Enable the Capture compare channel N */
|
||||
TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_ENABLE);
|
||||
|
||||
/* Enable the Main Output */
|
||||
__HAL_TIM_MOE_ENABLE(htim);
|
||||
|
||||
/* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */
|
||||
if (IS_TIM_SLAVE_INSTANCE(htim->Instance))
|
||||
{
|
||||
tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS;
|
||||
if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr))
|
||||
{
|
||||
__HAL_TIM_ENABLE(htim);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
__HAL_TIM_ENABLE(htim);
|
||||
}
|
||||
}
|
||||
|
||||
/* Return function status */
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stops the TIM Output Compare signal generation in interrupt mode
|
||||
* on the complementary output.
|
||||
* @param htim TIM Output Compare handle
|
||||
* @param Channel TIM Channel to be disabled
|
||||
* This parameter can be one of the following values:
|
||||
* @arg TIM_CHANNEL_1: TIM Channel 1 selected
|
||||
* @arg TIM_CHANNEL_2: TIM Channel 2 selected
|
||||
* @arg TIM_CHANNEL_3: TIM Channel 3 selected
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_TIMEx_OCN_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel)
|
||||
{
|
||||
HAL_StatusTypeDef status = HAL_OK;
|
||||
uint32_t tmpccer;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
|
||||
|
||||
switch (Channel)
|
||||
{
|
||||
case TIM_CHANNEL_1:
|
||||
{
|
||||
/* Disable the TIM Output Compare interrupt */
|
||||
__HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1);
|
||||
break;
|
||||
}
|
||||
|
||||
case TIM_CHANNEL_2:
|
||||
{
|
||||
/* Disable the TIM Output Compare interrupt */
|
||||
__HAL_TIM_DISABLE_IT(htim, TIM_IT_CC2);
|
||||
break;
|
||||
}
|
||||
|
||||
case TIM_CHANNEL_3:
|
||||
{
|
||||
/* Disable the TIM Output Compare interrupt */
|
||||
__HAL_TIM_DISABLE_IT(htim, TIM_IT_CC3);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
status = HAL_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
if (status == HAL_OK)
|
||||
{
|
||||
/* Disable the Capture compare channel N */
|
||||
TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_DISABLE);
|
||||
|
||||
/* Disable the TIM Break interrupt (only if no more channel is active) */
|
||||
tmpccer = htim->Instance->CCER;
|
||||
if ((tmpccer & (TIM_CCER_CC1NE | TIM_CCER_CC2NE | TIM_CCER_CC3NE)) == (uint32_t)RESET)
|
||||
{
|
||||
__HAL_TIM_DISABLE_IT(htim, TIM_IT_BREAK);
|
||||
}
|
||||
|
||||
/* Disable the Main Output */
|
||||
__HAL_TIM_MOE_DISABLE(htim);
|
||||
|
||||
/* Disable the Peripheral */
|
||||
__HAL_TIM_DISABLE(htim);
|
||||
|
||||
/* Set the TIM complementary channel state */
|
||||
TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY);
|
||||
}
|
||||
|
||||
/* Return function status */
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Starts the TIM Output Compare signal generation in DMA mode
|
||||
* on the complementary output.
|
||||
* @param htim TIM Output Compare handle
|
||||
* @param Channel TIM Channel to be enabled
|
||||
* This parameter can be one of the following values:
|
||||
* @arg TIM_CHANNEL_1: TIM Channel 1 selected
|
||||
* @arg TIM_CHANNEL_2: TIM Channel 2 selected
|
||||
* @arg TIM_CHANNEL_3: TIM Channel 3 selected
|
||||
* @param pData The source Buffer address.
|
||||
* @param Length The length of data to be transferred from memory to TIM peripheral
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_TIMEx_OCN_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, uint32_t *pData, uint16_t Length)
|
||||
{
|
||||
HAL_StatusTypeDef status = HAL_OK;
|
||||
uint32_t tmpsmcr;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
|
||||
|
||||
/* Set the TIM complementary channel state */
|
||||
if (TIM_CHANNEL_N_STATE_GET(htim, Channel) == HAL_TIM_CHANNEL_STATE_BUSY)
|
||||
{
|
||||
return HAL_BUSY;
|
||||
}
|
||||
else if (TIM_CHANNEL_N_STATE_GET(htim, Channel) == HAL_TIM_CHANNEL_STATE_READY)
|
||||
{
|
||||
if ((pData == NULL) && (Length > 0U))
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_BUSY);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
switch (Channel)
|
||||
{
|
||||
case TIM_CHANNEL_1:
|
||||
{
|
||||
/* Set the DMA compare callbacks */
|
||||
htim->hdma[TIM_DMA_ID_CC1]->XferCpltCallback = TIM_DMADelayPulseNCplt;
|
||||
htim->hdma[TIM_DMA_ID_CC1]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt;
|
||||
|
||||
/* Set the DMA error callback */
|
||||
htim->hdma[TIM_DMA_ID_CC1]->XferErrorCallback = TIM_DMAErrorCCxN ;
|
||||
|
||||
/* Enable the DMA channel */
|
||||
if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC1], (uint32_t)pData, (uint32_t)&htim->Instance->CCR1,
|
||||
Length) != HAL_OK)
|
||||
{
|
||||
/* Return error status */
|
||||
return HAL_ERROR;
|
||||
}
|
||||
/* Enable the TIM Output Compare DMA request */
|
||||
__HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC1);
|
||||
break;
|
||||
}
|
||||
|
||||
case TIM_CHANNEL_2:
|
||||
{
|
||||
/* Set the DMA compare callbacks */
|
||||
htim->hdma[TIM_DMA_ID_CC2]->XferCpltCallback = TIM_DMADelayPulseNCplt;
|
||||
htim->hdma[TIM_DMA_ID_CC2]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt;
|
||||
|
||||
/* Set the DMA error callback */
|
||||
htim->hdma[TIM_DMA_ID_CC2]->XferErrorCallback = TIM_DMAErrorCCxN ;
|
||||
|
||||
/* Enable the DMA channel */
|
||||
if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC2], (uint32_t)pData, (uint32_t)&htim->Instance->CCR2,
|
||||
Length) != HAL_OK)
|
||||
{
|
||||
/* Return error status */
|
||||
return HAL_ERROR;
|
||||
}
|
||||
/* Enable the TIM Output Compare DMA request */
|
||||
__HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC2);
|
||||
break;
|
||||
}
|
||||
|
||||
case TIM_CHANNEL_3:
|
||||
{
|
||||
/* Set the DMA compare callbacks */
|
||||
htim->hdma[TIM_DMA_ID_CC3]->XferCpltCallback = TIM_DMADelayPulseNCplt;
|
||||
htim->hdma[TIM_DMA_ID_CC3]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt;
|
||||
|
||||
/* Set the DMA error callback */
|
||||
htim->hdma[TIM_DMA_ID_CC3]->XferErrorCallback = TIM_DMAErrorCCxN ;
|
||||
|
||||
/* Enable the DMA channel */
|
||||
if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC3], (uint32_t)pData, (uint32_t)&htim->Instance->CCR3,
|
||||
Length) != HAL_OK)
|
||||
{
|
||||
/* Return error status */
|
||||
return HAL_ERROR;
|
||||
}
|
||||
/* Enable the TIM Output Compare DMA request */
|
||||
__HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC3);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
status = HAL_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
if (status == HAL_OK)
|
||||
{
|
||||
/* Enable the Capture compare channel N */
|
||||
TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_ENABLE);
|
||||
|
||||
/* Enable the Main Output */
|
||||
__HAL_TIM_MOE_ENABLE(htim);
|
||||
|
||||
/* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */
|
||||
if (IS_TIM_SLAVE_INSTANCE(htim->Instance))
|
||||
{
|
||||
tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS;
|
||||
if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr))
|
||||
{
|
||||
__HAL_TIM_ENABLE(htim);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
__HAL_TIM_ENABLE(htim);
|
||||
}
|
||||
}
|
||||
|
||||
/* Return function status */
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stops the TIM Output Compare signal generation in DMA mode
|
||||
* on the complementary output.
|
||||
* @param htim TIM Output Compare handle
|
||||
* @param Channel TIM Channel to be disabled
|
||||
* This parameter can be one of the following values:
|
||||
* @arg TIM_CHANNEL_1: TIM Channel 1 selected
|
||||
* @arg TIM_CHANNEL_2: TIM Channel 2 selected
|
||||
* @arg TIM_CHANNEL_3: TIM Channel 3 selected
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_TIMEx_OCN_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel)
|
||||
{
|
||||
HAL_StatusTypeDef status = HAL_OK;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
|
||||
|
||||
switch (Channel)
|
||||
{
|
||||
case TIM_CHANNEL_1:
|
||||
{
|
||||
/* Disable the TIM Output Compare DMA request */
|
||||
__HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC1);
|
||||
(void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC1]);
|
||||
break;
|
||||
}
|
||||
|
||||
case TIM_CHANNEL_2:
|
||||
{
|
||||
/* Disable the TIM Output Compare DMA request */
|
||||
__HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC2);
|
||||
(void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC2]);
|
||||
break;
|
||||
}
|
||||
|
||||
case TIM_CHANNEL_3:
|
||||
{
|
||||
/* Disable the TIM Output Compare DMA request */
|
||||
__HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC3);
|
||||
(void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC3]);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
status = HAL_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
if (status == HAL_OK)
|
||||
{
|
||||
/* Disable the Capture compare channel N */
|
||||
TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_DISABLE);
|
||||
|
||||
/* Disable the Main Output */
|
||||
__HAL_TIM_MOE_DISABLE(htim);
|
||||
|
||||
/* Disable the Peripheral */
|
||||
__HAL_TIM_DISABLE(htim);
|
||||
|
||||
/* Set the TIM complementary channel state */
|
||||
TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY);
|
||||
}
|
||||
|
||||
/* Return function status */
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup TIMEx_Exported_Functions_Group3 Extended Timer Complementary PWM functions
|
||||
* @brief Timer Complementary PWM functions
|
||||
*
|
||||
@verbatim
|
||||
==============================================================================
|
||||
##### Timer Complementary PWM functions #####
|
||||
==============================================================================
|
||||
[..]
|
||||
This section provides functions allowing to:
|
||||
(+) Start the Complementary PWM.
|
||||
(+) Stop the Complementary PWM.
|
||||
(+) Start the Complementary PWM and enable interrupts.
|
||||
(+) Stop the Complementary PWM and disable interrupts.
|
||||
(+) Start the Complementary PWM and enable DMA transfers.
|
||||
(+) Stop the Complementary PWM and disable DMA transfers.
|
||||
(+) Start the Complementary Input Capture measurement.
|
||||
(+) Stop the Complementary Input Capture.
|
||||
(+) Start the Complementary Input Capture and enable interrupts.
|
||||
(+) Stop the Complementary Input Capture and disable interrupts.
|
||||
(+) Start the Complementary Input Capture and enable DMA transfers.
|
||||
(+) Stop the Complementary Input Capture and disable DMA transfers.
|
||||
(+) Start the Complementary One Pulse generation.
|
||||
(+) Stop the Complementary One Pulse.
|
||||
(+) Start the Complementary One Pulse and enable interrupts.
|
||||
(+) Stop the Complementary One Pulse and disable interrupts.
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Starts the PWM signal generation on the complementary output.
|
||||
* @param htim TIM handle
|
||||
* @param Channel TIM Channel to be enabled
|
||||
* This parameter can be one of the following values:
|
||||
* @arg TIM_CHANNEL_1: TIM Channel 1 selected
|
||||
* @arg TIM_CHANNEL_2: TIM Channel 2 selected
|
||||
* @arg TIM_CHANNEL_3: TIM Channel 3 selected
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_TIMEx_PWMN_Start(TIM_HandleTypeDef *htim, uint32_t Channel)
|
||||
{
|
||||
uint32_t tmpsmcr;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
|
||||
|
||||
/* Check the TIM complementary channel state */
|
||||
if (TIM_CHANNEL_N_STATE_GET(htim, Channel) != HAL_TIM_CHANNEL_STATE_READY)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Set the TIM complementary channel state */
|
||||
TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_BUSY);
|
||||
|
||||
/* Enable the complementary PWM output */
|
||||
TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_ENABLE);
|
||||
|
||||
/* Enable the Main Output */
|
||||
__HAL_TIM_MOE_ENABLE(htim);
|
||||
|
||||
/* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */
|
||||
if (IS_TIM_SLAVE_INSTANCE(htim->Instance))
|
||||
{
|
||||
tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS;
|
||||
if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr))
|
||||
{
|
||||
__HAL_TIM_ENABLE(htim);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
__HAL_TIM_ENABLE(htim);
|
||||
}
|
||||
|
||||
/* Return function status */
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stops the PWM signal generation on the complementary output.
|
||||
* @param htim TIM handle
|
||||
* @param Channel TIM Channel to be disabled
|
||||
* This parameter can be one of the following values:
|
||||
* @arg TIM_CHANNEL_1: TIM Channel 1 selected
|
||||
* @arg TIM_CHANNEL_2: TIM Channel 2 selected
|
||||
* @arg TIM_CHANNEL_3: TIM Channel 3 selected
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_TIMEx_PWMN_Stop(TIM_HandleTypeDef *htim, uint32_t Channel)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
|
||||
|
||||
/* Disable the complementary PWM output */
|
||||
TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_DISABLE);
|
||||
|
||||
/* Disable the Main Output */
|
||||
__HAL_TIM_MOE_DISABLE(htim);
|
||||
|
||||
/* Disable the Peripheral */
|
||||
__HAL_TIM_DISABLE(htim);
|
||||
|
||||
/* Set the TIM complementary channel state */
|
||||
TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY);
|
||||
|
||||
/* Return function status */
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Starts the PWM signal generation in interrupt mode on the
|
||||
* complementary output.
|
||||
* @param htim TIM handle
|
||||
* @param Channel TIM Channel to be disabled
|
||||
* This parameter can be one of the following values:
|
||||
* @arg TIM_CHANNEL_1: TIM Channel 1 selected
|
||||
* @arg TIM_CHANNEL_2: TIM Channel 2 selected
|
||||
* @arg TIM_CHANNEL_3: TIM Channel 3 selected
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_TIMEx_PWMN_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel)
|
||||
{
|
||||
HAL_StatusTypeDef status = HAL_OK;
|
||||
uint32_t tmpsmcr;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
|
||||
|
||||
/* Check the TIM complementary channel state */
|
||||
if (TIM_CHANNEL_N_STATE_GET(htim, Channel) != HAL_TIM_CHANNEL_STATE_READY)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Set the TIM complementary channel state */
|
||||
TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_BUSY);
|
||||
|
||||
switch (Channel)
|
||||
{
|
||||
case TIM_CHANNEL_1:
|
||||
{
|
||||
/* Enable the TIM Capture/Compare 1 interrupt */
|
||||
__HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1);
|
||||
break;
|
||||
}
|
||||
|
||||
case TIM_CHANNEL_2:
|
||||
{
|
||||
/* Enable the TIM Capture/Compare 2 interrupt */
|
||||
__HAL_TIM_ENABLE_IT(htim, TIM_IT_CC2);
|
||||
break;
|
||||
}
|
||||
|
||||
case TIM_CHANNEL_3:
|
||||
{
|
||||
/* Enable the TIM Capture/Compare 3 interrupt */
|
||||
__HAL_TIM_ENABLE_IT(htim, TIM_IT_CC3);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
status = HAL_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
if (status == HAL_OK)
|
||||
{
|
||||
/* Enable the TIM Break interrupt */
|
||||
__HAL_TIM_ENABLE_IT(htim, TIM_IT_BREAK);
|
||||
|
||||
/* Enable the complementary PWM output */
|
||||
TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_ENABLE);
|
||||
|
||||
/* Enable the Main Output */
|
||||
__HAL_TIM_MOE_ENABLE(htim);
|
||||
|
||||
/* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */
|
||||
if (IS_TIM_SLAVE_INSTANCE(htim->Instance))
|
||||
{
|
||||
tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS;
|
||||
if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr))
|
||||
{
|
||||
__HAL_TIM_ENABLE(htim);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
__HAL_TIM_ENABLE(htim);
|
||||
}
|
||||
}
|
||||
|
||||
/* Return function status */
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stops the PWM signal generation in interrupt mode on the
|
||||
* complementary output.
|
||||
* @param htim TIM handle
|
||||
* @param Channel TIM Channel to be disabled
|
||||
* This parameter can be one of the following values:
|
||||
* @arg TIM_CHANNEL_1: TIM Channel 1 selected
|
||||
* @arg TIM_CHANNEL_2: TIM Channel 2 selected
|
||||
* @arg TIM_CHANNEL_3: TIM Channel 3 selected
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_TIMEx_PWMN_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel)
|
||||
{
|
||||
HAL_StatusTypeDef status = HAL_OK;
|
||||
uint32_t tmpccer;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
|
||||
|
||||
switch (Channel)
|
||||
{
|
||||
case TIM_CHANNEL_1:
|
||||
{
|
||||
/* Disable the TIM Capture/Compare 1 interrupt */
|
||||
__HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1);
|
||||
break;
|
||||
}
|
||||
|
||||
case TIM_CHANNEL_2:
|
||||
{
|
||||
/* Disable the TIM Capture/Compare 2 interrupt */
|
||||
__HAL_TIM_DISABLE_IT(htim, TIM_IT_CC2);
|
||||
break;
|
||||
}
|
||||
|
||||
case TIM_CHANNEL_3:
|
||||
{
|
||||
/* Disable the TIM Capture/Compare 3 interrupt */
|
||||
__HAL_TIM_DISABLE_IT(htim, TIM_IT_CC3);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
status = HAL_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
if (status == HAL_OK)
|
||||
{
|
||||
/* Disable the complementary PWM output */
|
||||
TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_DISABLE);
|
||||
|
||||
/* Disable the TIM Break interrupt (only if no more channel is active) */
|
||||
tmpccer = htim->Instance->CCER;
|
||||
if ((tmpccer & (TIM_CCER_CC1NE | TIM_CCER_CC2NE | TIM_CCER_CC3NE)) == (uint32_t)RESET)
|
||||
{
|
||||
__HAL_TIM_DISABLE_IT(htim, TIM_IT_BREAK);
|
||||
}
|
||||
|
||||
/* Disable the Main Output */
|
||||
__HAL_TIM_MOE_DISABLE(htim);
|
||||
|
||||
/* Disable the Peripheral */
|
||||
__HAL_TIM_DISABLE(htim);
|
||||
|
||||
/* Set the TIM complementary channel state */
|
||||
TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY);
|
||||
}
|
||||
|
||||
/* Return function status */
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Starts the TIM PWM signal generation in DMA mode on the
|
||||
* complementary output
|
||||
* @param htim TIM handle
|
||||
* @param Channel TIM Channel to be enabled
|
||||
* This parameter can be one of the following values:
|
||||
* @arg TIM_CHANNEL_1: TIM Channel 1 selected
|
||||
* @arg TIM_CHANNEL_2: TIM Channel 2 selected
|
||||
* @arg TIM_CHANNEL_3: TIM Channel 3 selected
|
||||
* @param pData The source Buffer address.
|
||||
* @param Length The length of data to be transferred from memory to TIM peripheral
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_TIMEx_PWMN_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, uint32_t *pData, uint16_t Length)
|
||||
{
|
||||
HAL_StatusTypeDef status = HAL_OK;
|
||||
uint32_t tmpsmcr;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
|
||||
|
||||
/* Set the TIM complementary channel state */
|
||||
if (TIM_CHANNEL_N_STATE_GET(htim, Channel) == HAL_TIM_CHANNEL_STATE_BUSY)
|
||||
{
|
||||
return HAL_BUSY;
|
||||
}
|
||||
else if (TIM_CHANNEL_N_STATE_GET(htim, Channel) == HAL_TIM_CHANNEL_STATE_READY)
|
||||
{
|
||||
if ((pData == NULL) && (Length > 0U))
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_BUSY);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
switch (Channel)
|
||||
{
|
||||
case TIM_CHANNEL_1:
|
||||
{
|
||||
/* Set the DMA compare callbacks */
|
||||
htim->hdma[TIM_DMA_ID_CC1]->XferCpltCallback = TIM_DMADelayPulseNCplt;
|
||||
htim->hdma[TIM_DMA_ID_CC1]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt;
|
||||
|
||||
/* Set the DMA error callback */
|
||||
htim->hdma[TIM_DMA_ID_CC1]->XferErrorCallback = TIM_DMAErrorCCxN ;
|
||||
|
||||
/* Enable the DMA channel */
|
||||
if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC1], (uint32_t)pData, (uint32_t)&htim->Instance->CCR1,
|
||||
Length) != HAL_OK)
|
||||
{
|
||||
/* Return error status */
|
||||
return HAL_ERROR;
|
||||
}
|
||||
/* Enable the TIM Capture/Compare 1 DMA request */
|
||||
__HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC1);
|
||||
break;
|
||||
}
|
||||
|
||||
case TIM_CHANNEL_2:
|
||||
{
|
||||
/* Set the DMA compare callbacks */
|
||||
htim->hdma[TIM_DMA_ID_CC2]->XferCpltCallback = TIM_DMADelayPulseNCplt;
|
||||
htim->hdma[TIM_DMA_ID_CC2]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt;
|
||||
|
||||
/* Set the DMA error callback */
|
||||
htim->hdma[TIM_DMA_ID_CC2]->XferErrorCallback = TIM_DMAErrorCCxN ;
|
||||
|
||||
/* Enable the DMA channel */
|
||||
if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC2], (uint32_t)pData, (uint32_t)&htim->Instance->CCR2,
|
||||
Length) != HAL_OK)
|
||||
{
|
||||
/* Return error status */
|
||||
return HAL_ERROR;
|
||||
}
|
||||
/* Enable the TIM Capture/Compare 2 DMA request */
|
||||
__HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC2);
|
||||
break;
|
||||
}
|
||||
|
||||
case TIM_CHANNEL_3:
|
||||
{
|
||||
/* Set the DMA compare callbacks */
|
||||
htim->hdma[TIM_DMA_ID_CC3]->XferCpltCallback = TIM_DMADelayPulseNCplt;
|
||||
htim->hdma[TIM_DMA_ID_CC3]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt;
|
||||
|
||||
/* Set the DMA error callback */
|
||||
htim->hdma[TIM_DMA_ID_CC3]->XferErrorCallback = TIM_DMAErrorCCxN ;
|
||||
|
||||
/* Enable the DMA channel */
|
||||
if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC3], (uint32_t)pData, (uint32_t)&htim->Instance->CCR3,
|
||||
Length) != HAL_OK)
|
||||
{
|
||||
/* Return error status */
|
||||
return HAL_ERROR;
|
||||
}
|
||||
/* Enable the TIM Capture/Compare 3 DMA request */
|
||||
__HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC3);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
status = HAL_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
if (status == HAL_OK)
|
||||
{
|
||||
/* Enable the complementary PWM output */
|
||||
TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_ENABLE);
|
||||
|
||||
/* Enable the Main Output */
|
||||
__HAL_TIM_MOE_ENABLE(htim);
|
||||
|
||||
/* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */
|
||||
if (IS_TIM_SLAVE_INSTANCE(htim->Instance))
|
||||
{
|
||||
tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS;
|
||||
if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr))
|
||||
{
|
||||
__HAL_TIM_ENABLE(htim);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
__HAL_TIM_ENABLE(htim);
|
||||
}
|
||||
}
|
||||
|
||||
/* Return function status */
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stops the TIM PWM signal generation in DMA mode on the complementary
|
||||
* output
|
||||
* @param htim TIM handle
|
||||
* @param Channel TIM Channel to be disabled
|
||||
* This parameter can be one of the following values:
|
||||
* @arg TIM_CHANNEL_1: TIM Channel 1 selected
|
||||
* @arg TIM_CHANNEL_2: TIM Channel 2 selected
|
||||
* @arg TIM_CHANNEL_3: TIM Channel 3 selected
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_TIMEx_PWMN_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel)
|
||||
{
|
||||
HAL_StatusTypeDef status = HAL_OK;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
|
||||
|
||||
switch (Channel)
|
||||
{
|
||||
case TIM_CHANNEL_1:
|
||||
{
|
||||
/* Disable the TIM Capture/Compare 1 DMA request */
|
||||
__HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC1);
|
||||
(void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC1]);
|
||||
break;
|
||||
}
|
||||
|
||||
case TIM_CHANNEL_2:
|
||||
{
|
||||
/* Disable the TIM Capture/Compare 2 DMA request */
|
||||
__HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC2);
|
||||
(void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC2]);
|
||||
break;
|
||||
}
|
||||
|
||||
case TIM_CHANNEL_3:
|
||||
{
|
||||
/* Disable the TIM Capture/Compare 3 DMA request */
|
||||
__HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC3);
|
||||
(void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC3]);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
status = HAL_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
if (status == HAL_OK)
|
||||
{
|
||||
/* Disable the complementary PWM output */
|
||||
TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_DISABLE);
|
||||
|
||||
/* Disable the Main Output */
|
||||
__HAL_TIM_MOE_DISABLE(htim);
|
||||
|
||||
/* Disable the Peripheral */
|
||||
__HAL_TIM_DISABLE(htim);
|
||||
|
||||
/* Set the TIM complementary channel state */
|
||||
TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY);
|
||||
}
|
||||
|
||||
/* Return function status */
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup TIMEx_Exported_Functions_Group4 Extended Timer Complementary One Pulse functions
|
||||
* @brief Timer Complementary One Pulse functions
|
||||
*
|
||||
@verbatim
|
||||
==============================================================================
|
||||
##### Timer Complementary One Pulse functions #####
|
||||
==============================================================================
|
||||
[..]
|
||||
This section provides functions allowing to:
|
||||
(+) Start the Complementary One Pulse generation.
|
||||
(+) Stop the Complementary One Pulse.
|
||||
(+) Start the Complementary One Pulse and enable interrupts.
|
||||
(+) Stop the Complementary One Pulse and disable interrupts.
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Starts the TIM One Pulse signal generation on the complementary
|
||||
* output.
|
||||
* @note OutputChannel must match the pulse output channel chosen when calling
|
||||
* @ref HAL_TIM_OnePulse_ConfigChannel().
|
||||
* @param htim TIM One Pulse handle
|
||||
* @param OutputChannel pulse output channel to enable
|
||||
* This parameter can be one of the following values:
|
||||
* @arg TIM_CHANNEL_1: TIM Channel 1 selected
|
||||
* @arg TIM_CHANNEL_2: TIM Channel 2 selected
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Start(TIM_HandleTypeDef *htim, uint32_t OutputChannel)
|
||||
{
|
||||
uint32_t input_channel = (OutputChannel == TIM_CHANNEL_1) ? TIM_CHANNEL_2 : TIM_CHANNEL_1;
|
||||
HAL_TIM_ChannelStateTypeDef channel_1_state = TIM_CHANNEL_STATE_GET(htim, TIM_CHANNEL_1);
|
||||
HAL_TIM_ChannelStateTypeDef channel_2_state = TIM_CHANNEL_STATE_GET(htim, TIM_CHANNEL_2);
|
||||
HAL_TIM_ChannelStateTypeDef complementary_channel_1_state = TIM_CHANNEL_N_STATE_GET(htim, TIM_CHANNEL_1);
|
||||
HAL_TIM_ChannelStateTypeDef complementary_channel_2_state = TIM_CHANNEL_N_STATE_GET(htim, TIM_CHANNEL_2);
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, OutputChannel));
|
||||
|
||||
/* Check the TIM channels state */
|
||||
if ((channel_1_state != HAL_TIM_CHANNEL_STATE_READY)
|
||||
|| (channel_2_state != HAL_TIM_CHANNEL_STATE_READY)
|
||||
|| (complementary_channel_1_state != HAL_TIM_CHANNEL_STATE_READY)
|
||||
|| (complementary_channel_2_state != HAL_TIM_CHANNEL_STATE_READY))
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Set the TIM channels state */
|
||||
TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY);
|
||||
TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY);
|
||||
TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY);
|
||||
TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY);
|
||||
|
||||
/* Enable the complementary One Pulse output channel and the Input Capture channel */
|
||||
TIM_CCxNChannelCmd(htim->Instance, OutputChannel, TIM_CCxN_ENABLE);
|
||||
TIM_CCxChannelCmd(htim->Instance, input_channel, TIM_CCx_ENABLE);
|
||||
|
||||
/* Enable the Main Output */
|
||||
__HAL_TIM_MOE_ENABLE(htim);
|
||||
|
||||
/* Return function status */
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stops the TIM One Pulse signal generation on the complementary
|
||||
* output.
|
||||
* @note OutputChannel must match the pulse output channel chosen when calling
|
||||
* @ref HAL_TIM_OnePulse_ConfigChannel().
|
||||
* @param htim TIM One Pulse handle
|
||||
* @param OutputChannel pulse output channel to disable
|
||||
* This parameter can be one of the following values:
|
||||
* @arg TIM_CHANNEL_1: TIM Channel 1 selected
|
||||
* @arg TIM_CHANNEL_2: TIM Channel 2 selected
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Stop(TIM_HandleTypeDef *htim, uint32_t OutputChannel)
|
||||
{
|
||||
uint32_t input_channel = (OutputChannel == TIM_CHANNEL_1) ? TIM_CHANNEL_2 : TIM_CHANNEL_1;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, OutputChannel));
|
||||
|
||||
/* Disable the complementary One Pulse output channel and the Input Capture channel */
|
||||
TIM_CCxNChannelCmd(htim->Instance, OutputChannel, TIM_CCxN_DISABLE);
|
||||
TIM_CCxChannelCmd(htim->Instance, input_channel, TIM_CCx_DISABLE);
|
||||
|
||||
/* Disable the Main Output */
|
||||
__HAL_TIM_MOE_DISABLE(htim);
|
||||
|
||||
/* Disable the Peripheral */
|
||||
__HAL_TIM_DISABLE(htim);
|
||||
|
||||
/* Set the TIM channels state */
|
||||
TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY);
|
||||
TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY);
|
||||
TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY);
|
||||
TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY);
|
||||
|
||||
/* Return function status */
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Starts the TIM One Pulse signal generation in interrupt mode on the
|
||||
* complementary channel.
|
||||
* @note OutputChannel must match the pulse output channel chosen when calling
|
||||
* @ref HAL_TIM_OnePulse_ConfigChannel().
|
||||
* @param htim TIM One Pulse handle
|
||||
* @param OutputChannel pulse output channel to enable
|
||||
* This parameter can be one of the following values:
|
||||
* @arg TIM_CHANNEL_1: TIM Channel 1 selected
|
||||
* @arg TIM_CHANNEL_2: TIM Channel 2 selected
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Start_IT(TIM_HandleTypeDef *htim, uint32_t OutputChannel)
|
||||
{
|
||||
uint32_t input_channel = (OutputChannel == TIM_CHANNEL_1) ? TIM_CHANNEL_2 : TIM_CHANNEL_1;
|
||||
HAL_TIM_ChannelStateTypeDef channel_1_state = TIM_CHANNEL_STATE_GET(htim, TIM_CHANNEL_1);
|
||||
HAL_TIM_ChannelStateTypeDef channel_2_state = TIM_CHANNEL_STATE_GET(htim, TIM_CHANNEL_2);
|
||||
HAL_TIM_ChannelStateTypeDef complementary_channel_1_state = TIM_CHANNEL_N_STATE_GET(htim, TIM_CHANNEL_1);
|
||||
HAL_TIM_ChannelStateTypeDef complementary_channel_2_state = TIM_CHANNEL_N_STATE_GET(htim, TIM_CHANNEL_2);
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, OutputChannel));
|
||||
|
||||
/* Check the TIM channels state */
|
||||
if ((channel_1_state != HAL_TIM_CHANNEL_STATE_READY)
|
||||
|| (channel_2_state != HAL_TIM_CHANNEL_STATE_READY)
|
||||
|| (complementary_channel_1_state != HAL_TIM_CHANNEL_STATE_READY)
|
||||
|| (complementary_channel_2_state != HAL_TIM_CHANNEL_STATE_READY))
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Set the TIM channels state */
|
||||
TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY);
|
||||
TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY);
|
||||
TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY);
|
||||
TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY);
|
||||
|
||||
/* Enable the TIM Capture/Compare 1 interrupt */
|
||||
__HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1);
|
||||
|
||||
/* Enable the TIM Capture/Compare 2 interrupt */
|
||||
__HAL_TIM_ENABLE_IT(htim, TIM_IT_CC2);
|
||||
|
||||
/* Enable the complementary One Pulse output channel and the Input Capture channel */
|
||||
TIM_CCxNChannelCmd(htim->Instance, OutputChannel, TIM_CCxN_ENABLE);
|
||||
TIM_CCxChannelCmd(htim->Instance, input_channel, TIM_CCx_ENABLE);
|
||||
|
||||
/* Enable the Main Output */
|
||||
__HAL_TIM_MOE_ENABLE(htim);
|
||||
|
||||
/* Return function status */
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stops the TIM One Pulse signal generation in interrupt mode on the
|
||||
* complementary channel.
|
||||
* @note OutputChannel must match the pulse output channel chosen when calling
|
||||
* @ref HAL_TIM_OnePulse_ConfigChannel().
|
||||
* @param htim TIM One Pulse handle
|
||||
* @param OutputChannel pulse output channel to disable
|
||||
* This parameter can be one of the following values:
|
||||
* @arg TIM_CHANNEL_1: TIM Channel 1 selected
|
||||
* @arg TIM_CHANNEL_2: TIM Channel 2 selected
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Stop_IT(TIM_HandleTypeDef *htim, uint32_t OutputChannel)
|
||||
{
|
||||
uint32_t input_channel = (OutputChannel == TIM_CHANNEL_1) ? TIM_CHANNEL_2 : TIM_CHANNEL_1;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, OutputChannel));
|
||||
|
||||
/* Disable the TIM Capture/Compare 1 interrupt */
|
||||
__HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1);
|
||||
|
||||
/* Disable the TIM Capture/Compare 2 interrupt */
|
||||
__HAL_TIM_DISABLE_IT(htim, TIM_IT_CC2);
|
||||
|
||||
/* Disable the complementary One Pulse output channel and the Input Capture channel */
|
||||
TIM_CCxNChannelCmd(htim->Instance, OutputChannel, TIM_CCxN_DISABLE);
|
||||
TIM_CCxChannelCmd(htim->Instance, input_channel, TIM_CCx_DISABLE);
|
||||
|
||||
/* Disable the Main Output */
|
||||
__HAL_TIM_MOE_DISABLE(htim);
|
||||
|
||||
/* Disable the Peripheral */
|
||||
__HAL_TIM_DISABLE(htim);
|
||||
|
||||
/* Set the TIM channels state */
|
||||
TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY);
|
||||
TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY);
|
||||
TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY);
|
||||
TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY);
|
||||
|
||||
/* Return function status */
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup TIMEx_Exported_Functions_Group5 Extended Peripheral Control functions
|
||||
* @brief Peripheral Control functions
|
||||
*
|
||||
@verbatim
|
||||
==============================================================================
|
||||
##### Peripheral Control functions #####
|
||||
==============================================================================
|
||||
[..]
|
||||
This section provides functions allowing to:
|
||||
(+) Configure the commutation event in case of use of the Hall sensor interface.
|
||||
(+) Configure Output channels for OC and PWM mode.
|
||||
|
||||
(+) Configure Complementary channels, break features and dead time.
|
||||
(+) Configure Master synchronization.
|
||||
(+) Configure timer remapping capabilities.
|
||||
(+) Enable or disable channel grouping.
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Configure the TIM commutation event sequence.
|
||||
* @note This function is mandatory to use the commutation event in order to
|
||||
* update the configuration at each commutation detection on the TRGI input of the Timer,
|
||||
* the typical use of this feature is with the use of another Timer(interface Timer)
|
||||
* configured in Hall sensor interface, this interface Timer will generate the
|
||||
* commutation at its TRGO output (connected to Timer used in this function) each time
|
||||
* the TI1 of the Interface Timer detect a commutation at its input TI1.
|
||||
* @param htim TIM handle
|
||||
* @param InputTrigger the Internal trigger corresponding to the Timer Interfacing with the Hall sensor
|
||||
* This parameter can be one of the following values:
|
||||
* @arg TIM_TS_ITR0: Internal trigger 0 selected
|
||||
* @arg TIM_TS_ITR1: Internal trigger 1 selected
|
||||
* @arg TIM_TS_ITR2: Internal trigger 2 selected
|
||||
* @arg TIM_TS_ITR3: Internal trigger 3 selected
|
||||
* @arg TIM_TS_NONE: No trigger is needed
|
||||
* @param CommutationSource the Commutation Event source
|
||||
* This parameter can be one of the following values:
|
||||
* @arg TIM_COMMUTATION_TRGI: Commutation source is the TRGI of the Interface Timer
|
||||
* @arg TIM_COMMUTATION_SOFTWARE: Commutation source is set by software using the COMG bit
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_TIMEx_ConfigCommutEvent(TIM_HandleTypeDef *htim, uint32_t InputTrigger,
|
||||
uint32_t CommutationSource)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_COMMUTATION_EVENT_INSTANCE(htim->Instance));
|
||||
assert_param(IS_TIM_INTERNAL_TRIGGEREVENT_SELECTION(InputTrigger));
|
||||
|
||||
__HAL_LOCK(htim);
|
||||
|
||||
if ((InputTrigger == TIM_TS_ITR0) || (InputTrigger == TIM_TS_ITR1) ||
|
||||
(InputTrigger == TIM_TS_ITR2) || (InputTrigger == TIM_TS_ITR3))
|
||||
{
|
||||
/* Select the Input trigger */
|
||||
htim->Instance->SMCR &= ~TIM_SMCR_TS;
|
||||
htim->Instance->SMCR |= InputTrigger;
|
||||
}
|
||||
|
||||
/* Select the Capture Compare preload feature */
|
||||
htim->Instance->CR2 |= TIM_CR2_CCPC;
|
||||
/* Select the Commutation event source */
|
||||
htim->Instance->CR2 &= ~TIM_CR2_CCUS;
|
||||
htim->Instance->CR2 |= CommutationSource;
|
||||
|
||||
/* Disable Commutation Interrupt */
|
||||
__HAL_TIM_DISABLE_IT(htim, TIM_IT_COM);
|
||||
|
||||
/* Disable Commutation DMA request */
|
||||
__HAL_TIM_DISABLE_DMA(htim, TIM_DMA_COM);
|
||||
|
||||
__HAL_UNLOCK(htim);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure the TIM commutation event sequence with interrupt.
|
||||
* @note This function is mandatory to use the commutation event in order to
|
||||
* update the configuration at each commutation detection on the TRGI input of the Timer,
|
||||
* the typical use of this feature is with the use of another Timer(interface Timer)
|
||||
* configured in Hall sensor interface, this interface Timer will generate the
|
||||
* commutation at its TRGO output (connected to Timer used in this function) each time
|
||||
* the TI1 of the Interface Timer detect a commutation at its input TI1.
|
||||
* @param htim TIM handle
|
||||
* @param InputTrigger the Internal trigger corresponding to the Timer Interfacing with the Hall sensor
|
||||
* This parameter can be one of the following values:
|
||||
* @arg TIM_TS_ITR0: Internal trigger 0 selected
|
||||
* @arg TIM_TS_ITR1: Internal trigger 1 selected
|
||||
* @arg TIM_TS_ITR2: Internal trigger 2 selected
|
||||
* @arg TIM_TS_ITR3: Internal trigger 3 selected
|
||||
* @arg TIM_TS_NONE: No trigger is needed
|
||||
* @param CommutationSource the Commutation Event source
|
||||
* This parameter can be one of the following values:
|
||||
* @arg TIM_COMMUTATION_TRGI: Commutation source is the TRGI of the Interface Timer
|
||||
* @arg TIM_COMMUTATION_SOFTWARE: Commutation source is set by software using the COMG bit
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_TIMEx_ConfigCommutEvent_IT(TIM_HandleTypeDef *htim, uint32_t InputTrigger,
|
||||
uint32_t CommutationSource)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_COMMUTATION_EVENT_INSTANCE(htim->Instance));
|
||||
assert_param(IS_TIM_INTERNAL_TRIGGEREVENT_SELECTION(InputTrigger));
|
||||
|
||||
__HAL_LOCK(htim);
|
||||
|
||||
if ((InputTrigger == TIM_TS_ITR0) || (InputTrigger == TIM_TS_ITR1) ||
|
||||
(InputTrigger == TIM_TS_ITR2) || (InputTrigger == TIM_TS_ITR3))
|
||||
{
|
||||
/* Select the Input trigger */
|
||||
htim->Instance->SMCR &= ~TIM_SMCR_TS;
|
||||
htim->Instance->SMCR |= InputTrigger;
|
||||
}
|
||||
|
||||
/* Select the Capture Compare preload feature */
|
||||
htim->Instance->CR2 |= TIM_CR2_CCPC;
|
||||
/* Select the Commutation event source */
|
||||
htim->Instance->CR2 &= ~TIM_CR2_CCUS;
|
||||
htim->Instance->CR2 |= CommutationSource;
|
||||
|
||||
/* Disable Commutation DMA request */
|
||||
__HAL_TIM_DISABLE_DMA(htim, TIM_DMA_COM);
|
||||
|
||||
/* Enable the Commutation Interrupt */
|
||||
__HAL_TIM_ENABLE_IT(htim, TIM_IT_COM);
|
||||
|
||||
__HAL_UNLOCK(htim);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure the TIM commutation event sequence with DMA.
|
||||
* @note This function is mandatory to use the commutation event in order to
|
||||
* update the configuration at each commutation detection on the TRGI input of the Timer,
|
||||
* the typical use of this feature is with the use of another Timer(interface Timer)
|
||||
* configured in Hall sensor interface, this interface Timer will generate the
|
||||
* commutation at its TRGO output (connected to Timer used in this function) each time
|
||||
* the TI1 of the Interface Timer detect a commutation at its input TI1.
|
||||
* @note The user should configure the DMA in his own software, in This function only the COMDE bit is set
|
||||
* @param htim TIM handle
|
||||
* @param InputTrigger the Internal trigger corresponding to the Timer Interfacing with the Hall sensor
|
||||
* This parameter can be one of the following values:
|
||||
* @arg TIM_TS_ITR0: Internal trigger 0 selected
|
||||
* @arg TIM_TS_ITR1: Internal trigger 1 selected
|
||||
* @arg TIM_TS_ITR2: Internal trigger 2 selected
|
||||
* @arg TIM_TS_ITR3: Internal trigger 3 selected
|
||||
* @arg TIM_TS_NONE: No trigger is needed
|
||||
* @param CommutationSource the Commutation Event source
|
||||
* This parameter can be one of the following values:
|
||||
* @arg TIM_COMMUTATION_TRGI: Commutation source is the TRGI of the Interface Timer
|
||||
* @arg TIM_COMMUTATION_SOFTWARE: Commutation source is set by software using the COMG bit
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_TIMEx_ConfigCommutEvent_DMA(TIM_HandleTypeDef *htim, uint32_t InputTrigger,
|
||||
uint32_t CommutationSource)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_COMMUTATION_EVENT_INSTANCE(htim->Instance));
|
||||
assert_param(IS_TIM_INTERNAL_TRIGGEREVENT_SELECTION(InputTrigger));
|
||||
|
||||
__HAL_LOCK(htim);
|
||||
|
||||
if ((InputTrigger == TIM_TS_ITR0) || (InputTrigger == TIM_TS_ITR1) ||
|
||||
(InputTrigger == TIM_TS_ITR2) || (InputTrigger == TIM_TS_ITR3))
|
||||
{
|
||||
/* Select the Input trigger */
|
||||
htim->Instance->SMCR &= ~TIM_SMCR_TS;
|
||||
htim->Instance->SMCR |= InputTrigger;
|
||||
}
|
||||
|
||||
/* Select the Capture Compare preload feature */
|
||||
htim->Instance->CR2 |= TIM_CR2_CCPC;
|
||||
/* Select the Commutation event source */
|
||||
htim->Instance->CR2 &= ~TIM_CR2_CCUS;
|
||||
htim->Instance->CR2 |= CommutationSource;
|
||||
|
||||
/* Enable the Commutation DMA Request */
|
||||
/* Set the DMA Commutation Callback */
|
||||
htim->hdma[TIM_DMA_ID_COMMUTATION]->XferCpltCallback = TIMEx_DMACommutationCplt;
|
||||
htim->hdma[TIM_DMA_ID_COMMUTATION]->XferHalfCpltCallback = TIMEx_DMACommutationHalfCplt;
|
||||
/* Set the DMA error callback */
|
||||
htim->hdma[TIM_DMA_ID_COMMUTATION]->XferErrorCallback = TIM_DMAError;
|
||||
|
||||
/* Disable Commutation Interrupt */
|
||||
__HAL_TIM_DISABLE_IT(htim, TIM_IT_COM);
|
||||
|
||||
/* Enable the Commutation DMA Request */
|
||||
__HAL_TIM_ENABLE_DMA(htim, TIM_DMA_COM);
|
||||
|
||||
__HAL_UNLOCK(htim);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configures the TIM in master mode.
|
||||
* @param htim TIM handle.
|
||||
* @param sMasterConfig pointer to a TIM_MasterConfigTypeDef structure that
|
||||
* contains the selected trigger output (TRGO) and the Master/Slave
|
||||
* mode.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_TIMEx_MasterConfigSynchronization(TIM_HandleTypeDef *htim,
|
||||
TIM_MasterConfigTypeDef *sMasterConfig)
|
||||
{
|
||||
uint32_t tmpcr2;
|
||||
uint32_t tmpsmcr;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_MASTER_INSTANCE(htim->Instance));
|
||||
assert_param(IS_TIM_TRGO_SOURCE(sMasterConfig->MasterOutputTrigger));
|
||||
assert_param(IS_TIM_MSM_STATE(sMasterConfig->MasterSlaveMode));
|
||||
|
||||
/* Check input state */
|
||||
__HAL_LOCK(htim);
|
||||
|
||||
/* Change the handler state */
|
||||
htim->State = HAL_TIM_STATE_BUSY;
|
||||
|
||||
/* Get the TIMx CR2 register value */
|
||||
tmpcr2 = htim->Instance->CR2;
|
||||
|
||||
/* Get the TIMx SMCR register value */
|
||||
tmpsmcr = htim->Instance->SMCR;
|
||||
|
||||
/* If the timer supports ADC synchronization through TRGO2, set the master mode selection 2 */
|
||||
if (IS_TIM_TRGO2_INSTANCE(htim->Instance))
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_TRGO2_SOURCE(sMasterConfig->MasterOutputTrigger2));
|
||||
|
||||
/* Clear the MMS2 bits */
|
||||
tmpcr2 &= ~TIM_CR2_MMS2;
|
||||
/* Select the TRGO2 source*/
|
||||
tmpcr2 |= sMasterConfig->MasterOutputTrigger2;
|
||||
}
|
||||
|
||||
/* Reset the MMS Bits */
|
||||
tmpcr2 &= ~TIM_CR2_MMS;
|
||||
/* Select the TRGO source */
|
||||
tmpcr2 |= sMasterConfig->MasterOutputTrigger;
|
||||
|
||||
/* Update TIMx CR2 */
|
||||
htim->Instance->CR2 = tmpcr2;
|
||||
|
||||
if (IS_TIM_SLAVE_INSTANCE(htim->Instance))
|
||||
{
|
||||
/* Reset the MSM Bit */
|
||||
tmpsmcr &= ~TIM_SMCR_MSM;
|
||||
/* Set master mode */
|
||||
tmpsmcr |= sMasterConfig->MasterSlaveMode;
|
||||
|
||||
/* Update TIMx SMCR */
|
||||
htim->Instance->SMCR = tmpsmcr;
|
||||
}
|
||||
|
||||
/* Change the htim state */
|
||||
htim->State = HAL_TIM_STATE_READY;
|
||||
|
||||
__HAL_UNLOCK(htim);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configures the Break feature, dead time, Lock level, OSSI/OSSR State
|
||||
* and the AOE(automatic output enable).
|
||||
* @param htim TIM handle
|
||||
* @param sBreakDeadTimeConfig pointer to a TIM_ConfigBreakDeadConfigTypeDef structure that
|
||||
* contains the BDTR Register configuration information for the TIM peripheral.
|
||||
* @note Interrupts can be generated when an active level is detected on the
|
||||
* break input, the break 2 input or the system break input. Break
|
||||
* interrupt can be enabled by calling the @ref __HAL_TIM_ENABLE_IT macro.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_TIMEx_ConfigBreakDeadTime(TIM_HandleTypeDef *htim,
|
||||
TIM_BreakDeadTimeConfigTypeDef *sBreakDeadTimeConfig)
|
||||
{
|
||||
/* Keep this variable initialized to 0 as it is used to configure BDTR register */
|
||||
uint32_t tmpbdtr = 0U;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_BREAK_INSTANCE(htim->Instance));
|
||||
assert_param(IS_TIM_OSSR_STATE(sBreakDeadTimeConfig->OffStateRunMode));
|
||||
assert_param(IS_TIM_OSSI_STATE(sBreakDeadTimeConfig->OffStateIDLEMode));
|
||||
assert_param(IS_TIM_LOCK_LEVEL(sBreakDeadTimeConfig->LockLevel));
|
||||
assert_param(IS_TIM_DEADTIME(sBreakDeadTimeConfig->DeadTime));
|
||||
assert_param(IS_TIM_BREAK_STATE(sBreakDeadTimeConfig->BreakState));
|
||||
assert_param(IS_TIM_BREAK_POLARITY(sBreakDeadTimeConfig->BreakPolarity));
|
||||
assert_param(IS_TIM_BREAK_FILTER(sBreakDeadTimeConfig->BreakFilter));
|
||||
assert_param(IS_TIM_AUTOMATIC_OUTPUT_STATE(sBreakDeadTimeConfig->AutomaticOutput));
|
||||
|
||||
/* Check input state */
|
||||
__HAL_LOCK(htim);
|
||||
|
||||
/* Set the Lock level, the Break enable Bit and the Polarity, the OSSR State,
|
||||
the OSSI State, the dead time value and the Automatic Output Enable Bit */
|
||||
|
||||
/* Set the BDTR bits */
|
||||
MODIFY_REG(tmpbdtr, TIM_BDTR_DTG, sBreakDeadTimeConfig->DeadTime);
|
||||
MODIFY_REG(tmpbdtr, TIM_BDTR_LOCK, sBreakDeadTimeConfig->LockLevel);
|
||||
MODIFY_REG(tmpbdtr, TIM_BDTR_OSSI, sBreakDeadTimeConfig->OffStateIDLEMode);
|
||||
MODIFY_REG(tmpbdtr, TIM_BDTR_OSSR, sBreakDeadTimeConfig->OffStateRunMode);
|
||||
MODIFY_REG(tmpbdtr, TIM_BDTR_BKE, sBreakDeadTimeConfig->BreakState);
|
||||
MODIFY_REG(tmpbdtr, TIM_BDTR_BKP, sBreakDeadTimeConfig->BreakPolarity);
|
||||
MODIFY_REG(tmpbdtr, TIM_BDTR_AOE, sBreakDeadTimeConfig->AutomaticOutput);
|
||||
MODIFY_REG(tmpbdtr, TIM_BDTR_BKF, (sBreakDeadTimeConfig->BreakFilter << TIM_BDTR_BKF_Pos));
|
||||
|
||||
if (IS_TIM_BKIN2_INSTANCE(htim->Instance))
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_BREAK2_STATE(sBreakDeadTimeConfig->Break2State));
|
||||
assert_param(IS_TIM_BREAK2_POLARITY(sBreakDeadTimeConfig->Break2Polarity));
|
||||
assert_param(IS_TIM_BREAK_FILTER(sBreakDeadTimeConfig->Break2Filter));
|
||||
|
||||
/* Set the BREAK2 input related BDTR bits */
|
||||
MODIFY_REG(tmpbdtr, TIM_BDTR_BK2F, (sBreakDeadTimeConfig->Break2Filter << TIM_BDTR_BK2F_Pos));
|
||||
MODIFY_REG(tmpbdtr, TIM_BDTR_BK2E, sBreakDeadTimeConfig->Break2State);
|
||||
MODIFY_REG(tmpbdtr, TIM_BDTR_BK2P, sBreakDeadTimeConfig->Break2Polarity);
|
||||
}
|
||||
|
||||
/* Set TIMx_BDTR */
|
||||
htim->Instance->BDTR = tmpbdtr;
|
||||
|
||||
__HAL_UNLOCK(htim);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configures the break input source.
|
||||
* @param htim TIM handle.
|
||||
* @param BreakInput Break input to configure
|
||||
* This parameter can be one of the following values:
|
||||
* @arg TIM_BREAKINPUT_BRK: Timer break input
|
||||
* @arg TIM_BREAKINPUT_BRK2: Timer break 2 input
|
||||
* @param sBreakInputConfig Break input source configuration
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_TIMEx_ConfigBreakInput(TIM_HandleTypeDef *htim,
|
||||
uint32_t BreakInput,
|
||||
TIMEx_BreakInputConfigTypeDef *sBreakInputConfig)
|
||||
|
||||
{
|
||||
HAL_StatusTypeDef status = HAL_OK;
|
||||
uint32_t tmporx;
|
||||
uint32_t bkin_enable_mask;
|
||||
uint32_t bkin_polarity_mask;
|
||||
uint32_t bkin_enable_bitpos;
|
||||
uint32_t bkin_polarity_bitpos;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_BREAK_INSTANCE(htim->Instance));
|
||||
assert_param(IS_TIM_BREAKINPUT(BreakInput));
|
||||
assert_param(IS_TIM_BREAKINPUTSOURCE(sBreakInputConfig->Source));
|
||||
assert_param(IS_TIM_BREAKINPUTSOURCE_STATE(sBreakInputConfig->Enable));
|
||||
#if defined(DFSDM1_Channel0)
|
||||
if (sBreakInputConfig->Source != TIM_BREAKINPUTSOURCE_DFSDM1)
|
||||
{
|
||||
assert_param(IS_TIM_BREAKINPUTSOURCE_POLARITY(sBreakInputConfig->Polarity));
|
||||
}
|
||||
#else
|
||||
assert_param(IS_TIM_BREAKINPUTSOURCE_POLARITY(sBreakInputConfig->Polarity));
|
||||
#endif /* DFSDM1_Channel0 */
|
||||
|
||||
/* Check input state */
|
||||
__HAL_LOCK(htim);
|
||||
|
||||
switch (sBreakInputConfig->Source)
|
||||
{
|
||||
case TIM_BREAKINPUTSOURCE_BKIN:
|
||||
{
|
||||
bkin_enable_mask = TIM1_OR2_BKINE;
|
||||
bkin_enable_bitpos = TIM1_OR2_BKINE_Pos;
|
||||
bkin_polarity_mask = TIM1_OR2_BKINP;
|
||||
bkin_polarity_bitpos = TIM1_OR2_BKINP_Pos;
|
||||
break;
|
||||
}
|
||||
case TIM_BREAKINPUTSOURCE_COMP1:
|
||||
{
|
||||
bkin_enable_mask = TIM1_OR2_BKCMP1E;
|
||||
bkin_enable_bitpos = TIM1_OR2_BKCMP1E_Pos;
|
||||
bkin_polarity_mask = TIM1_OR2_BKCMP1P;
|
||||
bkin_polarity_bitpos = TIM1_OR2_BKCMP1P_Pos;
|
||||
break;
|
||||
}
|
||||
case TIM_BREAKINPUTSOURCE_COMP2:
|
||||
{
|
||||
bkin_enable_mask = TIM1_OR2_BKCMP2E;
|
||||
bkin_enable_bitpos = TIM1_OR2_BKCMP2E_Pos;
|
||||
bkin_polarity_mask = TIM1_OR2_BKCMP2P;
|
||||
bkin_polarity_bitpos = TIM1_OR2_BKCMP2P_Pos;
|
||||
break;
|
||||
}
|
||||
#if defined(DFSDM1_Channel0)
|
||||
case TIM_BREAKINPUTSOURCE_DFSDM1:
|
||||
{
|
||||
bkin_enable_mask = TIM1_OR2_BKDF1BK0E;
|
||||
bkin_enable_bitpos = TIM1_OR2_BKDF1BK0E_Pos;
|
||||
bkin_polarity_mask = 0U;
|
||||
bkin_polarity_bitpos = 0U;
|
||||
break;
|
||||
}
|
||||
#endif /* DFSDM1_Channel0 */
|
||||
|
||||
default:
|
||||
{
|
||||
bkin_enable_mask = 0U;
|
||||
bkin_polarity_mask = 0U;
|
||||
bkin_enable_bitpos = 0U;
|
||||
bkin_polarity_bitpos = 0U;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch (BreakInput)
|
||||
{
|
||||
case TIM_BREAKINPUT_BRK:
|
||||
{
|
||||
/* Get the TIMx_OR2 register value */
|
||||
tmporx = htim->Instance->OR2;
|
||||
|
||||
/* Enable the break input */
|
||||
tmporx &= ~bkin_enable_mask;
|
||||
tmporx |= (sBreakInputConfig->Enable << bkin_enable_bitpos) & bkin_enable_mask;
|
||||
|
||||
/* Set the break input polarity */
|
||||
#if defined(DFSDM1_Channel0)
|
||||
if (sBreakInputConfig->Source != TIM_BREAKINPUTSOURCE_DFSDM1)
|
||||
#endif /* DFSDM1_Channel0 */
|
||||
{
|
||||
tmporx &= ~bkin_polarity_mask;
|
||||
tmporx |= (sBreakInputConfig->Polarity << bkin_polarity_bitpos) & bkin_polarity_mask;
|
||||
}
|
||||
|
||||
/* Set TIMx_OR2 */
|
||||
htim->Instance->OR2 = tmporx;
|
||||
break;
|
||||
}
|
||||
case TIM_BREAKINPUT_BRK2:
|
||||
{
|
||||
/* Get the TIMx_OR3 register value */
|
||||
tmporx = htim->Instance->OR3;
|
||||
|
||||
/* Enable the break input */
|
||||
tmporx &= ~bkin_enable_mask;
|
||||
tmporx |= (sBreakInputConfig->Enable << bkin_enable_bitpos) & bkin_enable_mask;
|
||||
|
||||
/* Set the break input polarity */
|
||||
#if defined(DFSDM1_Channel0)
|
||||
if (sBreakInputConfig->Source != TIM_BREAKINPUTSOURCE_DFSDM1)
|
||||
#endif /* DFSDM1_Channel0 */
|
||||
{
|
||||
tmporx &= ~bkin_polarity_mask;
|
||||
tmporx |= (sBreakInputConfig->Polarity << bkin_polarity_bitpos) & bkin_polarity_mask;
|
||||
}
|
||||
|
||||
/* Set TIMx_OR3 */
|
||||
htim->Instance->OR3 = tmporx;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
status = HAL_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
__HAL_UNLOCK(htim);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configures the TIMx Remapping input capabilities.
|
||||
* @param htim TIM handle.
|
||||
* @param Remap specifies the TIM remapping source.
|
||||
@if STM32L422xx
|
||||
* For TIM1, the parameter is a combination of 2 fields (field1 | field2):
|
||||
*
|
||||
* field1 can have the following values:
|
||||
* @arg TIM_TIM1_ETR_ADC1_NONE: TIM1_ETR is not connected to any ADC1 AWD (analog watchdog)
|
||||
* @arg TIM_TIM1_ETR_ADC1_AWD1: TIM1_ETR is connected to ADC1 AWD1
|
||||
* @arg TIM_TIM1_ETR_ADC1_AWD2: TIM1_ETR is connected to ADC1 AWD2
|
||||
* @arg TIM_TIM1_ETR_ADC1_AWD3: TIM1_ETR is connected to ADC1 AWD3
|
||||
*
|
||||
* field2 can have the following values:
|
||||
* @arg TIM_TIM1_TI1_GPIO: TIM1 TI1 is connected to GPIO
|
||||
* @arg TIM_TIM1_TI1_COMP1: TIM1 TI1 is connected to COMP1 output
|
||||
*
|
||||
@endif
|
||||
@if STM32L486xx
|
||||
* For TIM1, the parameter is a combination of 4 fields (field1 | field2 | field3 | field4):
|
||||
*
|
||||
* field1 can have the following values:
|
||||
* @arg TIM_TIM1_ETR_ADC1_NONE: TIM1_ETR is not connected to any ADC1 AWD (analog watchdog)
|
||||
* @arg TIM_TIM1_ETR_ADC1_AWD1: TIM1_ETR is connected to ADC1 AWD1
|
||||
* @arg TIM_TIM1_ETR_ADC1_AWD2: TIM1_ETR is connected to ADC1 AWD2
|
||||
* @arg TIM_TIM1_ETR_ADC1_AWD3: TIM1_ETR is connected to ADC1 AWD3
|
||||
*
|
||||
* field2 can have the following values:
|
||||
* @arg TIM_TIM1_ETR_ADC3_NONE: TIM1_ETR is not connected to any ADC3 AWD (analog watchdog)
|
||||
* @arg TIM_TIM1_ETR_ADC3_AWD1: TIM1_ETR is connected to ADC3 AWD1
|
||||
* @arg TIM_TIM1_ETR_ADC3_AWD2: TIM1_ETR is connected to ADC3 AWD2
|
||||
* @arg TIM_TIM1_ETR_ADC3_AWD3: TIM1_ETR is connected to ADC3 AWD3
|
||||
*
|
||||
* field3 can have the following values:
|
||||
* @arg TIM_TIM1_TI1_GPIO: TIM1 TI1 is connected to GPIO
|
||||
* @arg TIM_TIM1_TI1_COMP1: TIM1 TI1 is connected to COMP1 output
|
||||
*
|
||||
* field4 can have the following values:
|
||||
* @arg TIM_TIM1_ETR_COMP1: TIM1_ETR is connected to COMP1 output
|
||||
* @arg TIM_TIM1_ETR_COMP2: TIM1_ETR is connected to COMP2 output
|
||||
* @note When field4 is set to TIM_TIM1_ETR_COMP1 or TIM_TIM1_ETR_COMP2 field1 and field2 values are not significant
|
||||
@endif
|
||||
@if STM32L443xx
|
||||
* For TIM1, the parameter is a combination of 3 fields (field1 | field2 | field3):
|
||||
*
|
||||
* field1 can have the following values:
|
||||
* @arg TIM_TIM1_ETR_ADC1_NONE: TIM1_ETR is not connected to any ADC1 AWD (analog watchdog)
|
||||
* @arg TIM_TIM1_ETR_ADC1_AWD1: TIM1_ETR is connected to ADC1 AWD1
|
||||
* @arg TIM_TIM1_ETR_ADC1_AWD2: TIM1_ETR is connected to ADC1 AWD2
|
||||
* @arg TIM_TIM1_ETR_ADC1_AWD3: TIM1_ETR is connected to ADC1 AWD3
|
||||
*
|
||||
* field2 can have the following values:
|
||||
* @arg TIM_TIM1_TI1_GPIO: TIM1 TI1 is connected to GPIO
|
||||
* @arg TIM_TIM1_TI1_COMP1: TIM1 TI1 is connected to COMP1 output
|
||||
*
|
||||
* field3 can have the following values:
|
||||
* @arg TIM_TIM1_ETR_COMP1: TIM1_ETR is connected to COMP1 output
|
||||
* @arg TIM_TIM1_ETR_COMP2: TIM1_ETR is connected to COMP2 output
|
||||
*
|
||||
* @note When field3 is set to TIM_TIM1_ETR_COMP1 or TIM_TIM1_ETR_COMP2 field1 values is not significant
|
||||
*
|
||||
@endif
|
||||
@if STM32L486xx
|
||||
* For TIM2, the parameter is a combination of 3 fields (field1 | field2 | field3):
|
||||
*
|
||||
* field1 can have the following values:
|
||||
* @arg TIM_TIM2_ITR1_TIM8_TRGO: TIM2_ITR1 is connected to TIM8_TRGO
|
||||
* @arg TIM_TIM2_ITR1_OTG_FS_SOF: TIM2_ITR1 is connected to OTG_FS SOF
|
||||
*
|
||||
* field2 can have the following values:
|
||||
* @arg TIM_TIM2_ETR_GPIO: TIM2_ETR is connected to GPIO
|
||||
* @arg TIM_TIM2_ETR_LSE: TIM2_ETR is connected to LSE
|
||||
* @arg TIM_TIM2_ETR_COMP1: TIM2_ETR is connected to COMP1 output
|
||||
* @arg TIM_TIM2_ETR_COMP2: TIM2_ETR is connected to COMP2 output
|
||||
*
|
||||
* field3 can have the following values:
|
||||
* @arg TIM_TIM2_TI4_GPIO: TIM2 TI4 is connected to GPIO
|
||||
* @arg TIM_TIM2_TI4_COMP1: TIM2 TI4 is connected to COMP1 output
|
||||
* @arg TIM_TIM2_TI4_COMP2: TIM2 TI4 is connected to COMP2 output
|
||||
* @arg TIM_TIM2_TI4_COMP1_COMP2: TIM2 TI4 is connected to logical OR between COMP1 and COMP2 output
|
||||
@endif
|
||||
@if STM32L422xx
|
||||
* For TIM2, the parameter is a combination of 3 fields (field1 | field2 | field3):
|
||||
*
|
||||
* field1 can have the following values:
|
||||
* @arg TIM_TIM2_ITR1_NONE: No internal trigger on TIM2_ITR1
|
||||
* @arg TIM_TIM2_ITR1_USB_SOF: TIM2_ITR1 is connected to USB SOF
|
||||
*
|
||||
* field2 can have the following values:
|
||||
* @arg TIM_TIM2_ETR_GPIO: TIM2_ETR is connected to GPIO
|
||||
* @arg TIM_TIM2_ETR_LSE: TIM2_ETR is connected to LSE
|
||||
* @arg TIM_TIM2_ETR_COMP1: TIM2_ETR is connected to COMP1 output
|
||||
*
|
||||
* field3 can have the following values:
|
||||
* @arg TIM_TIM2_TI4_GPIO: TIM2 TI4 is connected to GPIO
|
||||
* @arg TIM_TIM2_TI4_COMP1: TIM2 TI4 is connected to COMP1 output
|
||||
*
|
||||
@endif
|
||||
@if STM32L443xx
|
||||
* For TIM2, the parameter is a combination of 3 fields (field1 | field2 | field3):
|
||||
*
|
||||
* field1 can have the following values:
|
||||
* @arg TIM_TIM2_ITR1_NONE: No internal trigger on TIM2_ITR1
|
||||
* @arg TIM_TIM2_ITR1_USB_SOF: TIM2_ITR1 is connected to USB SOF
|
||||
*
|
||||
* field2 can have the following values:
|
||||
* @arg TIM_TIM2_ETR_GPIO: TIM2_ETR is connected to GPIO
|
||||
* @arg TIM_TIM2_ETR_LSE: TIM2_ETR is connected to LSE
|
||||
* @arg TIM_TIM2_ETR_COMP1: TIM2_ETR is connected to COMP1 output
|
||||
* @arg TIM_TIM2_ETR_COMP2: TIM2_ETR is connected to COMP2 output
|
||||
*
|
||||
* field3 can have the following values:
|
||||
* @arg TIM_TIM2_TI4_GPIO: TIM2 TI4 is connected to GPIO
|
||||
* @arg TIM_TIM2_TI4_COMP1: TIM2 TI4 is connected to COMP1 output
|
||||
* @arg TIM_TIM2_TI4_COMP2: TIM2 TI4 is connected to COMP2 output
|
||||
* @arg TIM_TIM2_TI4_COMP1_COMP2: TIM2 TI4 is connected to logical OR between COMP1 and COMP2 output
|
||||
*
|
||||
@endif
|
||||
@if STM32L486xx
|
||||
* For TIM3, the parameter is a combination 2 fields(field1 | field2):
|
||||
*
|
||||
* field1 can have the following values:
|
||||
* @arg TIM_TIM3_TI1_GPIO: TIM3 TI1 is connected to GPIO
|
||||
* @arg TIM_TIM3_TI1_COMP1: TIM3 TI1 is connected to COMP1 output
|
||||
* @arg TIM_TIM3_TI1_COMP2: TIM3 TI1 is connected to COMP2 output
|
||||
* @arg TIM_TIM3_TI1_COMP1_COMP2: TIM3 TI1 is connected to logical OR between COMP1 and COMP2 output
|
||||
*
|
||||
* field2 can have the following values:
|
||||
* @arg TIM_TIM3_ETR_GPIO: TIM3_ETR is connected to GPIO
|
||||
* @arg TIM_TIM3_ETR_COMP1: TIM3_ETR is connected to COMP1 output
|
||||
*
|
||||
@endif
|
||||
@if STM32L486xx
|
||||
* For TIM8, the parameter is a combination of 3 fields (field1 | field2 | field3):
|
||||
*
|
||||
* field1 can have the following values:
|
||||
* @arg TIM_TIM8_ETR_ADC2_NONE: TIM8_ETR is not connected to any ADC2 AWD (analog watchdog)
|
||||
* @arg TIM_TIM8_ETR_ADC2_AWD1: TIM8_ETR is connected to ADC2 AWD1
|
||||
* @arg TIM_TIM8_ETR_ADC2_AWD2: TIM8_ETR is connected to ADC2 AWD2
|
||||
* @arg TIM_TIM8_ETR_ADC2_AWD3: TIM8_ETR is connected to ADC2 AWD3
|
||||
*
|
||||
* field2 can have the following values:
|
||||
* @arg TIM_TIM8_ETR_ADC3_NONE: TIM8_ETR is not connected to any ADC3 AWD (analog watchdog)
|
||||
* @arg TIM_TIM8_ETR_ADC3_AWD1: TIM8_ETR is connected to ADC3 AWD1
|
||||
* @arg TIM_TIM8_ETR_ADC3_AWD2: TIM8_ETR is connected to ADC3 AWD2
|
||||
* @arg TIM_TIM8_ETR_ADC3_AWD3: TIM8_ETR is connected to ADC3 AWD3
|
||||
*
|
||||
* field3 can have the following values:
|
||||
* @arg TIM_TIM8_TI1_GPIO: TIM8 TI1 is connected to GPIO
|
||||
* @arg TIM_TIM8_TI1_COMP2: TIM8 TI1 is connected to COMP2 output
|
||||
*
|
||||
* field4 can have the following values:
|
||||
* @arg TIM_TIM8_ETR_COMP1: TIM8_ETR is connected to COMP1 output
|
||||
* @arg TIM_TIM8_ETR_COMP2: TIM8_ETR is connected to COMP2 output
|
||||
* @note When field4 is set to TIM_TIM8_ETR_COMP1 or TIM_TIM8_ETR_COMP2 field1 and field2 values are not significant
|
||||
*
|
||||
@endif
|
||||
@if STM32L422xx
|
||||
* For TIM15, the parameter is a combination of 2 fields (field1 | field2):
|
||||
*
|
||||
* field1 can have the following values:
|
||||
* @arg TIM_TIM15_TI1_GPIO: TIM15 TI1 is connected to GPIO
|
||||
* @arg TIM_TIM15_TI1_LSE: TIM15 TI1 is connected to LSE
|
||||
*
|
||||
* field2 can have the following values:
|
||||
* @arg TIM_TIM15_ENCODERMODE_NONE: No redirection
|
||||
* @arg TIM_TIM15_ENCODERMODE_TIM2: TIM2 IC1 and TIM2 IC2 are connected to TIM15 IC1 and TIM15 IC2 respectively
|
||||
*
|
||||
@endif
|
||||
@if STM32L443xx
|
||||
* For TIM15, the parameter is a combination of 2 fields (field1 | field2):
|
||||
*
|
||||
* field1 can have the following values:
|
||||
* @arg TIM_TIM15_TI1_GPIO: TIM15 TI1 is connected to GPIO
|
||||
* @arg TIM_TIM15_TI1_LSE: TIM15 TI1 is connected to LSE
|
||||
*
|
||||
* field2 can have the following values:
|
||||
* @arg TIM_TIM15_ENCODERMODE_NONE: No redirection
|
||||
* @arg TIM_TIM15_ENCODERMODE_TIM2: TIM2 IC1 and TIM2 IC2 are connected to TIM15 IC1 and TIM15 IC2 respectively
|
||||
* @arg TIM_TIM15_ENCODERMODE_TIM3: TIM3 IC1 and TIM3 IC2 are connected to TIM15 IC1 and TIM15 IC2 respectively
|
||||
* @arg TIM_TIM15_ENCODERMODE_TIM4: TIM4 IC1 and TIM4 IC2 are connected to TIM15 IC1 and TIM15 IC2 respectively
|
||||
*
|
||||
@endif
|
||||
@if STM32L486xx
|
||||
* @arg TIM_TIM16_TI1_GPIO: TIM16 TI1 is connected to GPIO
|
||||
* @arg TIM_TIM16_TI1_LSI: TIM16 TI1 is connected to LSI
|
||||
* @arg TIM_TIM16_TI1_LSE: TIM16 TI1 is connected to LSE
|
||||
* @arg TIM_TIM16_TI1_RTC: TIM16 TI1 is connected to RTC wakeup interrupt
|
||||
*
|
||||
@endif
|
||||
@if STM32L422xx
|
||||
* For TIM16, the parameter can have the following values:
|
||||
* @arg TIM_TIM16_TI1_GPIO: TIM16 TI1 is connected to GPIO
|
||||
* @arg TIM_TIM16_TI1_LSI: TIM16 TI1 is connected to LSI
|
||||
* @arg TIM_TIM16_TI1_LSE: TIM16 TI1 is connected to LSE
|
||||
* @arg TIM_TIM16_TI1_RTC: TIM16 TI1 is connected to RTC wakeup interrupt
|
||||
* @arg TIM_TIM16_TI1_MSI: TIM16 TI1 is connected to MSI (constraints: MSI clock < 1/4 TIM APB clock)
|
||||
* @arg TIM_TIM16_TI1_HSE_32: TIM16 TI1 is connected to HSE div 32 (note that HSE div 32 must be selected as RTC clock source)
|
||||
* @arg TIM_TIM16_TI1_MCO: TIM16 TI1 is connected to MCO
|
||||
*
|
||||
@endif
|
||||
@if STM32L443xx
|
||||
* For TIM16, the parameter can have the following values:
|
||||
* @arg TIM_TIM16_TI1_GPIO: TIM16 TI1 is connected to GPIO
|
||||
* @arg TIM_TIM16_TI1_LSI: TIM16 TI1 is connected to LSI
|
||||
* @arg TIM_TIM16_TI1_LSE: TIM16 TI1 is connected to LSE
|
||||
* @arg TIM_TIM16_TI1_RTC: TIM16 TI1 is connected to RTC wakeup interrupt
|
||||
* @arg TIM_TIM16_TI1_MSI: TIM16 TI1 is connected to MSI (constraints: MSI clock < 1/4 TIM APB clock)
|
||||
* @arg TIM_TIM16_TI1_HSE_32: TIM16 TI1 is connected to HSE div 32 (note that HSE div 32 must be selected as RTC clock source)
|
||||
* @arg TIM_TIM16_TI1_MCO: TIM16 TI1 is connected to MCO
|
||||
*
|
||||
@endif
|
||||
@if STM32L486xx
|
||||
* For TIM17, the parameter can have the following values:
|
||||
* @arg TIM_TIM17_TI1_GPIO: TIM17 TI1 is connected to GPIO
|
||||
* @arg TIM_TIM17_TI1_MSI: TIM17 TI1 is connected to MSI (constraints: MSI clock < 1/4 TIM APB clock)
|
||||
* @arg TIM_TIM17_TI1_HSE_32: TIM17 TI1 is connected to HSE div 32
|
||||
* @arg TIM_TIM17_TI1_MCO: TIM17 TI1 is connected to MCO
|
||||
@endif
|
||||
*
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_TIMEx_RemapConfig(TIM_HandleTypeDef *htim, uint32_t Remap)
|
||||
{
|
||||
uint32_t tmpor1;
|
||||
uint32_t tmpor2;
|
||||
|
||||
/* Check parameters */
|
||||
assert_param(IS_TIM_REMAP_INSTANCE(htim->Instance));
|
||||
assert_param(IS_TIM_REMAP(Remap));
|
||||
|
||||
__HAL_LOCK(htim);
|
||||
|
||||
/* Set ETR_SEL bit field (if required) */
|
||||
if (IS_TIM_ETRSEL_INSTANCE(htim->Instance))
|
||||
{
|
||||
tmpor2 = htim->Instance->OR2;
|
||||
tmpor2 &= ~TIM1_OR2_ETRSEL_Msk;
|
||||
tmpor2 |= (Remap & TIM1_OR2_ETRSEL_Msk);
|
||||
|
||||
/* Set TIMx_OR2 */
|
||||
htim->Instance->OR2 = tmpor2;
|
||||
}
|
||||
|
||||
/* Set other remapping capabilities */
|
||||
tmpor1 = Remap;
|
||||
tmpor1 &= ~TIM1_OR2_ETRSEL_Msk;
|
||||
|
||||
/* Set TIMx_OR1 */
|
||||
htim->Instance->OR1 = tmpor1;
|
||||
|
||||
__HAL_UNLOCK(htim);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Group channel 5 and channel 1, 2 or 3
|
||||
* @param htim TIM handle.
|
||||
* @param Channels specifies the reference signal(s) the OC5REF is combined with.
|
||||
* This parameter can be any combination of the following values:
|
||||
* TIM_GROUPCH5_NONE: No effect of OC5REF on OC1REFC, OC2REFC and OC3REFC
|
||||
* TIM_GROUPCH5_OC1REFC: OC1REFC is the logical AND of OC1REFC and OC5REF
|
||||
* TIM_GROUPCH5_OC2REFC: OC2REFC is the logical AND of OC2REFC and OC5REF
|
||||
* TIM_GROUPCH5_OC3REFC: OC3REFC is the logical AND of OC3REFC and OC5REF
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_TIMEx_GroupChannel5(TIM_HandleTypeDef *htim, uint32_t Channels)
|
||||
{
|
||||
/* Check parameters */
|
||||
assert_param(IS_TIM_COMBINED3PHASEPWM_INSTANCE(htim->Instance));
|
||||
assert_param(IS_TIM_GROUPCH5(Channels));
|
||||
|
||||
/* Process Locked */
|
||||
__HAL_LOCK(htim);
|
||||
|
||||
htim->State = HAL_TIM_STATE_BUSY;
|
||||
|
||||
/* Clear GC5Cx bit fields */
|
||||
htim->Instance->CCR5 &= ~(TIM_CCR5_GC5C3 | TIM_CCR5_GC5C2 | TIM_CCR5_GC5C1);
|
||||
|
||||
/* Set GC5Cx bit fields */
|
||||
htim->Instance->CCR5 |= Channels;
|
||||
|
||||
/* Change the htim state */
|
||||
htim->State = HAL_TIM_STATE_READY;
|
||||
|
||||
__HAL_UNLOCK(htim);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup TIMEx_Exported_Functions_Group6 Extended Callbacks functions
|
||||
* @brief Extended Callbacks functions
|
||||
*
|
||||
@verbatim
|
||||
==============================================================================
|
||||
##### Extended Callbacks functions #####
|
||||
==============================================================================
|
||||
[..]
|
||||
This section provides Extended TIM callback functions:
|
||||
(+) Timer Commutation callback
|
||||
(+) Timer Break callback
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Hall commutation changed callback in non-blocking mode
|
||||
* @param htim TIM handle
|
||||
* @retval None
|
||||
*/
|
||||
__weak void HAL_TIMEx_CommutCallback(TIM_HandleTypeDef *htim)
|
||||
{
|
||||
/* Prevent unused argument(s) compilation warning */
|
||||
UNUSED(htim);
|
||||
|
||||
/* NOTE : This function should not be modified, when the callback is needed,
|
||||
the HAL_TIMEx_CommutCallback could be implemented in the user file
|
||||
*/
|
||||
}
|
||||
/**
|
||||
* @brief Hall commutation changed half complete callback in non-blocking mode
|
||||
* @param htim TIM handle
|
||||
* @retval None
|
||||
*/
|
||||
__weak void HAL_TIMEx_CommutHalfCpltCallback(TIM_HandleTypeDef *htim)
|
||||
{
|
||||
/* Prevent unused argument(s) compilation warning */
|
||||
UNUSED(htim);
|
||||
|
||||
/* NOTE : This function should not be modified, when the callback is needed,
|
||||
the HAL_TIMEx_CommutHalfCpltCallback could be implemented in the user file
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Hall Break detection callback in non-blocking mode
|
||||
* @param htim TIM handle
|
||||
* @retval None
|
||||
*/
|
||||
__weak void HAL_TIMEx_BreakCallback(TIM_HandleTypeDef *htim)
|
||||
{
|
||||
/* Prevent unused argument(s) compilation warning */
|
||||
UNUSED(htim);
|
||||
|
||||
/* NOTE : This function should not be modified, when the callback is needed,
|
||||
the HAL_TIMEx_BreakCallback could be implemented in the user file
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Hall Break2 detection callback in non blocking mode
|
||||
* @param htim: TIM handle
|
||||
* @retval None
|
||||
*/
|
||||
__weak void HAL_TIMEx_Break2Callback(TIM_HandleTypeDef *htim)
|
||||
{
|
||||
/* Prevent unused argument(s) compilation warning */
|
||||
UNUSED(htim);
|
||||
|
||||
/* NOTE : This function Should not be modified, when the callback is needed,
|
||||
the HAL_TIMEx_Break2Callback could be implemented in the user file
|
||||
*/
|
||||
}
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup TIMEx_Exported_Functions_Group7 Extended Peripheral State functions
|
||||
* @brief Extended Peripheral State functions
|
||||
*
|
||||
@verbatim
|
||||
==============================================================================
|
||||
##### Extended Peripheral State functions #####
|
||||
==============================================================================
|
||||
[..]
|
||||
This subsection permits to get in run-time the status of the peripheral
|
||||
and the data flow.
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Return the TIM Hall Sensor interface handle state.
|
||||
* @param htim TIM Hall Sensor handle
|
||||
* @retval HAL state
|
||||
*/
|
||||
HAL_TIM_StateTypeDef HAL_TIMEx_HallSensor_GetState(TIM_HandleTypeDef *htim)
|
||||
{
|
||||
return htim->State;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return actual state of the TIM complementary channel.
|
||||
* @param htim TIM handle
|
||||
* @param ChannelN TIM Complementary channel
|
||||
* This parameter can be one of the following values:
|
||||
* @arg TIM_CHANNEL_1: TIM Channel 1
|
||||
* @arg TIM_CHANNEL_2: TIM Channel 2
|
||||
* @arg TIM_CHANNEL_3: TIM Channel 3
|
||||
* @retval TIM Complementary channel state
|
||||
*/
|
||||
HAL_TIM_ChannelStateTypeDef HAL_TIMEx_GetChannelNState(TIM_HandleTypeDef *htim, uint32_t ChannelN)
|
||||
{
|
||||
HAL_TIM_ChannelStateTypeDef channel_state;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, ChannelN));
|
||||
|
||||
channel_state = TIM_CHANNEL_N_STATE_GET(htim, ChannelN);
|
||||
|
||||
return channel_state;
|
||||
}
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private functions ---------------------------------------------------------*/
|
||||
/** @defgroup TIMEx_Private_Functions TIM Extended Private Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief TIM DMA Commutation callback.
|
||||
* @param hdma pointer to DMA handle.
|
||||
* @retval None
|
||||
*/
|
||||
void TIMEx_DMACommutationCplt(DMA_HandleTypeDef *hdma)
|
||||
{
|
||||
TIM_HandleTypeDef *htim = (TIM_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
|
||||
|
||||
/* Change the htim state */
|
||||
htim->State = HAL_TIM_STATE_READY;
|
||||
|
||||
#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
|
||||
htim->CommutationCallback(htim);
|
||||
#else
|
||||
HAL_TIMEx_CommutCallback(htim);
|
||||
#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief TIM DMA Commutation half complete callback.
|
||||
* @param hdma pointer to DMA handle.
|
||||
* @retval None
|
||||
*/
|
||||
void TIMEx_DMACommutationHalfCplt(DMA_HandleTypeDef *hdma)
|
||||
{
|
||||
TIM_HandleTypeDef *htim = (TIM_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
|
||||
|
||||
/* Change the htim state */
|
||||
htim->State = HAL_TIM_STATE_READY;
|
||||
|
||||
#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
|
||||
htim->CommutationHalfCpltCallback(htim);
|
||||
#else
|
||||
HAL_TIMEx_CommutHalfCpltCallback(htim);
|
||||
#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief TIM DMA Delay Pulse complete callback (complementary channel).
|
||||
* @param hdma pointer to DMA handle.
|
||||
* @retval None
|
||||
*/
|
||||
static void TIM_DMADelayPulseNCplt(DMA_HandleTypeDef *hdma)
|
||||
{
|
||||
TIM_HandleTypeDef *htim = (TIM_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
|
||||
|
||||
if (hdma == htim->hdma[TIM_DMA_ID_CC1])
|
||||
{
|
||||
htim->Channel = HAL_TIM_ACTIVE_CHANNEL_1;
|
||||
|
||||
if (hdma->Init.Mode == DMA_NORMAL)
|
||||
{
|
||||
TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY);
|
||||
}
|
||||
}
|
||||
else if (hdma == htim->hdma[TIM_DMA_ID_CC2])
|
||||
{
|
||||
htim->Channel = HAL_TIM_ACTIVE_CHANNEL_2;
|
||||
|
||||
if (hdma->Init.Mode == DMA_NORMAL)
|
||||
{
|
||||
TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY);
|
||||
}
|
||||
}
|
||||
else if (hdma == htim->hdma[TIM_DMA_ID_CC3])
|
||||
{
|
||||
htim->Channel = HAL_TIM_ACTIVE_CHANNEL_3;
|
||||
|
||||
if (hdma->Init.Mode == DMA_NORMAL)
|
||||
{
|
||||
TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_3, HAL_TIM_CHANNEL_STATE_READY);
|
||||
}
|
||||
}
|
||||
else if (hdma == htim->hdma[TIM_DMA_ID_CC4])
|
||||
{
|
||||
htim->Channel = HAL_TIM_ACTIVE_CHANNEL_4;
|
||||
|
||||
if (hdma->Init.Mode == DMA_NORMAL)
|
||||
{
|
||||
TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_4, HAL_TIM_CHANNEL_STATE_READY);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* nothing to do */
|
||||
}
|
||||
|
||||
#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
|
||||
htim->PWM_PulseFinishedCallback(htim);
|
||||
#else
|
||||
HAL_TIM_PWM_PulseFinishedCallback(htim);
|
||||
#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
|
||||
|
||||
htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief TIM DMA error callback (complementary channel)
|
||||
* @param hdma pointer to DMA handle.
|
||||
* @retval None
|
||||
*/
|
||||
static void TIM_DMAErrorCCxN(DMA_HandleTypeDef *hdma)
|
||||
{
|
||||
TIM_HandleTypeDef *htim = (TIM_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
|
||||
|
||||
if (hdma == htim->hdma[TIM_DMA_ID_CC1])
|
||||
{
|
||||
htim->Channel = HAL_TIM_ACTIVE_CHANNEL_1;
|
||||
TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY);
|
||||
}
|
||||
else if (hdma == htim->hdma[TIM_DMA_ID_CC2])
|
||||
{
|
||||
htim->Channel = HAL_TIM_ACTIVE_CHANNEL_2;
|
||||
TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY);
|
||||
}
|
||||
else if (hdma == htim->hdma[TIM_DMA_ID_CC3])
|
||||
{
|
||||
htim->Channel = HAL_TIM_ACTIVE_CHANNEL_3;
|
||||
TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_3, HAL_TIM_CHANNEL_STATE_READY);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* nothing to do */
|
||||
}
|
||||
|
||||
#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
|
||||
htim->ErrorCallback(htim);
|
||||
#else
|
||||
HAL_TIM_ErrorCallback(htim);
|
||||
#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
|
||||
|
||||
htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enables or disables the TIM Capture Compare Channel xN.
|
||||
* @param TIMx to select the TIM peripheral
|
||||
* @param Channel specifies the TIM Channel
|
||||
* This parameter can be one of the following values:
|
||||
* @arg TIM_CHANNEL_1: TIM Channel 1
|
||||
* @arg TIM_CHANNEL_2: TIM Channel 2
|
||||
* @arg TIM_CHANNEL_3: TIM Channel 3
|
||||
* @param ChannelNState specifies the TIM Channel CCxNE bit new state.
|
||||
* This parameter can be: TIM_CCxN_ENABLE or TIM_CCxN_Disable.
|
||||
* @retval None
|
||||
*/
|
||||
static void TIM_CCxNChannelCmd(TIM_TypeDef *TIMx, uint32_t Channel, uint32_t ChannelNState)
|
||||
{
|
||||
uint32_t tmp;
|
||||
|
||||
tmp = TIM_CCER_CC1NE << (Channel & 0x1FU); /* 0x1FU = 31 bits max shift */
|
||||
|
||||
/* Reset the CCxNE Bit */
|
||||
TIMx->CCER &= ~tmp;
|
||||
|
||||
/* Set or reset the CCxNE Bit */
|
||||
TIMx->CCER |= (uint32_t)(ChannelNState << (Channel & 0x1FU)); /* 0x1FU = 31 bits max shift */
|
||||
}
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* HAL_TIM_MODULE_ENABLED */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
400
Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_ll_dma.c
Normal file
400
Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_ll_dma.c
Normal file
@@ -0,0 +1,400 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32l4xx_ll_dma.c
|
||||
* @author MCD Application Team
|
||||
* @brief DMA LL module driver.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2017 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
#if defined(USE_FULL_LL_DRIVER)
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32l4xx_ll_dma.h"
|
||||
#include "stm32l4xx_ll_bus.h"
|
||||
#ifdef USE_FULL_ASSERT
|
||||
#include "stm32_assert.h"
|
||||
#else
|
||||
#define assert_param(expr) ((void)0U)
|
||||
#endif
|
||||
|
||||
/** @addtogroup STM32L4xx_LL_Driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
#if defined (DMA1) || defined (DMA2)
|
||||
|
||||
/** @defgroup DMA_LL DMA
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Private types -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private constants ---------------------------------------------------------*/
|
||||
/* Private macros ------------------------------------------------------------*/
|
||||
/** @addtogroup DMA_LL_Private_Macros
|
||||
* @{
|
||||
*/
|
||||
#define IS_LL_DMA_DIRECTION(__VALUE__) (((__VALUE__) == LL_DMA_DIRECTION_PERIPH_TO_MEMORY) || \
|
||||
((__VALUE__) == LL_DMA_DIRECTION_MEMORY_TO_PERIPH) || \
|
||||
((__VALUE__) == LL_DMA_DIRECTION_MEMORY_TO_MEMORY))
|
||||
|
||||
#define IS_LL_DMA_MODE(__VALUE__) (((__VALUE__) == LL_DMA_MODE_NORMAL) || \
|
||||
((__VALUE__) == LL_DMA_MODE_CIRCULAR))
|
||||
|
||||
#define IS_LL_DMA_PERIPHINCMODE(__VALUE__) (((__VALUE__) == LL_DMA_PERIPH_INCREMENT) || \
|
||||
((__VALUE__) == LL_DMA_PERIPH_NOINCREMENT))
|
||||
|
||||
#define IS_LL_DMA_MEMORYINCMODE(__VALUE__) (((__VALUE__) == LL_DMA_MEMORY_INCREMENT) || \
|
||||
((__VALUE__) == LL_DMA_MEMORY_NOINCREMENT))
|
||||
|
||||
#define IS_LL_DMA_PERIPHDATASIZE(__VALUE__) (((__VALUE__) == LL_DMA_PDATAALIGN_BYTE) || \
|
||||
((__VALUE__) == LL_DMA_PDATAALIGN_HALFWORD) || \
|
||||
((__VALUE__) == LL_DMA_PDATAALIGN_WORD))
|
||||
|
||||
#define IS_LL_DMA_MEMORYDATASIZE(__VALUE__) (((__VALUE__) == LL_DMA_MDATAALIGN_BYTE) || \
|
||||
((__VALUE__) == LL_DMA_MDATAALIGN_HALFWORD) || \
|
||||
((__VALUE__) == LL_DMA_MDATAALIGN_WORD))
|
||||
|
||||
#define IS_LL_DMA_NBDATA(__VALUE__) ((__VALUE__) <= 0x0000FFFFU)
|
||||
|
||||
#if defined(DMAMUX1)
|
||||
#define IS_LL_DMA_PERIPHREQUEST(__VALUE__) ((__VALUE__) <= 93U)
|
||||
#else
|
||||
#define IS_LL_DMA_PERIPHREQUEST(__VALUE__) (((__VALUE__) == LL_DMA_REQUEST_0) || \
|
||||
((__VALUE__) == LL_DMA_REQUEST_1) || \
|
||||
((__VALUE__) == LL_DMA_REQUEST_2) || \
|
||||
((__VALUE__) == LL_DMA_REQUEST_3) || \
|
||||
((__VALUE__) == LL_DMA_REQUEST_4) || \
|
||||
((__VALUE__) == LL_DMA_REQUEST_5) || \
|
||||
((__VALUE__) == LL_DMA_REQUEST_6) || \
|
||||
((__VALUE__) == LL_DMA_REQUEST_7))
|
||||
#endif /* DMAMUX1 */
|
||||
|
||||
#define IS_LL_DMA_PRIORITY(__VALUE__) (((__VALUE__) == LL_DMA_PRIORITY_LOW) || \
|
||||
((__VALUE__) == LL_DMA_PRIORITY_MEDIUM) || \
|
||||
((__VALUE__) == LL_DMA_PRIORITY_HIGH) || \
|
||||
((__VALUE__) == LL_DMA_PRIORITY_VERYHIGH))
|
||||
|
||||
#if defined (DMA2)
|
||||
#if defined (DMA2_Channel6) && defined (DMA2_Channel7)
|
||||
#define IS_LL_DMA_ALL_CHANNEL_INSTANCE(INSTANCE, CHANNEL) ((((INSTANCE) == DMA1) && \
|
||||
(((CHANNEL) == LL_DMA_CHANNEL_1) || \
|
||||
((CHANNEL) == LL_DMA_CHANNEL_2) || \
|
||||
((CHANNEL) == LL_DMA_CHANNEL_3) || \
|
||||
((CHANNEL) == LL_DMA_CHANNEL_4) || \
|
||||
((CHANNEL) == LL_DMA_CHANNEL_5) || \
|
||||
((CHANNEL) == LL_DMA_CHANNEL_6) || \
|
||||
((CHANNEL) == LL_DMA_CHANNEL_7))) || \
|
||||
(((INSTANCE) == DMA2) && \
|
||||
(((CHANNEL) == LL_DMA_CHANNEL_1) || \
|
||||
((CHANNEL) == LL_DMA_CHANNEL_2) || \
|
||||
((CHANNEL) == LL_DMA_CHANNEL_3) || \
|
||||
((CHANNEL) == LL_DMA_CHANNEL_4) || \
|
||||
((CHANNEL) == LL_DMA_CHANNEL_5) || \
|
||||
((CHANNEL) == LL_DMA_CHANNEL_6) || \
|
||||
((CHANNEL) == LL_DMA_CHANNEL_7))))
|
||||
#else
|
||||
#define IS_LL_DMA_ALL_CHANNEL_INSTANCE(INSTANCE, CHANNEL) ((((INSTANCE) == DMA1) && \
|
||||
(((CHANNEL) == LL_DMA_CHANNEL_1) || \
|
||||
((CHANNEL) == LL_DMA_CHANNEL_2) || \
|
||||
((CHANNEL) == LL_DMA_CHANNEL_3) || \
|
||||
((CHANNEL) == LL_DMA_CHANNEL_4) || \
|
||||
((CHANNEL) == LL_DMA_CHANNEL_5) || \
|
||||
((CHANNEL) == LL_DMA_CHANNEL_6) || \
|
||||
((CHANNEL) == LL_DMA_CHANNEL_7))) || \
|
||||
(((INSTANCE) == DMA2) && \
|
||||
(((CHANNEL) == LL_DMA_CHANNEL_1) || \
|
||||
((CHANNEL) == LL_DMA_CHANNEL_2) || \
|
||||
((CHANNEL) == LL_DMA_CHANNEL_3) || \
|
||||
((CHANNEL) == LL_DMA_CHANNEL_4) || \
|
||||
((CHANNEL) == LL_DMA_CHANNEL_5))))
|
||||
#endif
|
||||
#else
|
||||
#define IS_LL_DMA_ALL_CHANNEL_INSTANCE(INSTANCE, CHANNEL) ((((INSTANCE) == DMA1) && \
|
||||
(((CHANNEL) == LL_DMA_CHANNEL_1)|| \
|
||||
((CHANNEL) == LL_DMA_CHANNEL_2) || \
|
||||
((CHANNEL) == LL_DMA_CHANNEL_3) || \
|
||||
((CHANNEL) == LL_DMA_CHANNEL_4) || \
|
||||
((CHANNEL) == LL_DMA_CHANNEL_5) || \
|
||||
((CHANNEL) == LL_DMA_CHANNEL_6) || \
|
||||
((CHANNEL) == LL_DMA_CHANNEL_7))))
|
||||
#endif
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
|
||||
/* Exported functions --------------------------------------------------------*/
|
||||
/** @addtogroup DMA_LL_Exported_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup DMA_LL_EF_Init
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief De-initialize the DMA registers to their default reset values.
|
||||
* @param DMAx DMAx Instance
|
||||
* @param Channel This parameter can be one of the following values:
|
||||
* @arg @ref LL_DMA_CHANNEL_1
|
||||
* @arg @ref LL_DMA_CHANNEL_2
|
||||
* @arg @ref LL_DMA_CHANNEL_3
|
||||
* @arg @ref LL_DMA_CHANNEL_4
|
||||
* @arg @ref LL_DMA_CHANNEL_5
|
||||
* @arg @ref LL_DMA_CHANNEL_6
|
||||
* @arg @ref LL_DMA_CHANNEL_7
|
||||
* @arg @ref LL_DMA_CHANNEL_ALL
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: DMA registers are de-initialized
|
||||
* - ERROR: DMA registers are not de-initialized
|
||||
*/
|
||||
ErrorStatus LL_DMA_DeInit(DMA_TypeDef *DMAx, uint32_t Channel)
|
||||
{
|
||||
ErrorStatus status = SUCCESS;
|
||||
DMA_Channel_TypeDef *tmp;
|
||||
|
||||
/* Check the DMA Instance DMAx and Channel parameters*/
|
||||
assert_param(IS_LL_DMA_ALL_CHANNEL_INSTANCE(DMAx, Channel) || (Channel == LL_DMA_CHANNEL_ALL));
|
||||
|
||||
if (Channel == LL_DMA_CHANNEL_ALL)
|
||||
{
|
||||
if (DMAx == DMA1)
|
||||
{
|
||||
/* Force reset of DMA clock */
|
||||
LL_AHB1_GRP1_ForceReset(LL_AHB1_GRP1_PERIPH_DMA1);
|
||||
|
||||
/* Release reset of DMA clock */
|
||||
LL_AHB1_GRP1_ReleaseReset(LL_AHB1_GRP1_PERIPH_DMA1);
|
||||
}
|
||||
#if defined(DMA2)
|
||||
else if (DMAx == DMA2)
|
||||
{
|
||||
/* Force reset of DMA clock */
|
||||
LL_AHB1_GRP1_ForceReset(LL_AHB1_GRP1_PERIPH_DMA2);
|
||||
|
||||
/* Release reset of DMA clock */
|
||||
LL_AHB1_GRP1_ReleaseReset(LL_AHB1_GRP1_PERIPH_DMA2);
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
status = ERROR;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp = (DMA_Channel_TypeDef *)(__LL_DMA_GET_CHANNEL_INSTANCE(DMAx, Channel));
|
||||
|
||||
/* Disable the selected DMAx_Channely */
|
||||
CLEAR_BIT(tmp->CCR, DMA_CCR_EN);
|
||||
|
||||
/* Reset DMAx_Channely control register */
|
||||
WRITE_REG(tmp->CCR, 0U);
|
||||
|
||||
/* Reset DMAx_Channely remaining bytes register */
|
||||
WRITE_REG(tmp->CNDTR, 0U);
|
||||
|
||||
/* Reset DMAx_Channely peripheral address register */
|
||||
WRITE_REG(tmp->CPAR, 0U);
|
||||
|
||||
/* Reset DMAx_Channely memory 0 address register */
|
||||
WRITE_REG(tmp->CMAR, 0U);
|
||||
|
||||
#if defined(DMAMUX1)
|
||||
/* Reset Request register field for DMAx Channel */
|
||||
LL_DMA_SetPeriphRequest(DMAx, Channel, LL_DMAMUX_REQ_MEM2MEM);
|
||||
#else
|
||||
/* Reset Request register field for DMAx Channel */
|
||||
LL_DMA_SetPeriphRequest(DMAx, Channel, LL_DMA_REQUEST_0);
|
||||
#endif /* DMAMUX1 */
|
||||
|
||||
if (Channel == LL_DMA_CHANNEL_1)
|
||||
{
|
||||
/* Reset interrupt pending bits for DMAx Channel1 */
|
||||
LL_DMA_ClearFlag_GI1(DMAx);
|
||||
}
|
||||
else if (Channel == LL_DMA_CHANNEL_2)
|
||||
{
|
||||
/* Reset interrupt pending bits for DMAx Channel2 */
|
||||
LL_DMA_ClearFlag_GI2(DMAx);
|
||||
}
|
||||
else if (Channel == LL_DMA_CHANNEL_3)
|
||||
{
|
||||
/* Reset interrupt pending bits for DMAx Channel3 */
|
||||
LL_DMA_ClearFlag_GI3(DMAx);
|
||||
}
|
||||
else if (Channel == LL_DMA_CHANNEL_4)
|
||||
{
|
||||
/* Reset interrupt pending bits for DMAx Channel4 */
|
||||
LL_DMA_ClearFlag_GI4(DMAx);
|
||||
}
|
||||
else if (Channel == LL_DMA_CHANNEL_5)
|
||||
{
|
||||
/* Reset interrupt pending bits for DMAx Channel5 */
|
||||
LL_DMA_ClearFlag_GI5(DMAx);
|
||||
}
|
||||
|
||||
else if (Channel == LL_DMA_CHANNEL_6)
|
||||
{
|
||||
/* Reset interrupt pending bits for DMAx Channel6 */
|
||||
LL_DMA_ClearFlag_GI6(DMAx);
|
||||
}
|
||||
else if (Channel == LL_DMA_CHANNEL_7)
|
||||
{
|
||||
/* Reset interrupt pending bits for DMAx Channel7 */
|
||||
LL_DMA_ClearFlag_GI7(DMAx);
|
||||
}
|
||||
else
|
||||
{
|
||||
status = ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialize the DMA registers according to the specified parameters in DMA_InitStruct.
|
||||
* @note To convert DMAx_Channely Instance to DMAx Instance and Channely, use helper macros :
|
||||
* @arg @ref __LL_DMA_GET_INSTANCE
|
||||
* @arg @ref __LL_DMA_GET_CHANNEL
|
||||
* @param DMAx DMAx Instance
|
||||
* @param Channel This parameter can be one of the following values:
|
||||
* @arg @ref LL_DMA_CHANNEL_1
|
||||
* @arg @ref LL_DMA_CHANNEL_2
|
||||
* @arg @ref LL_DMA_CHANNEL_3
|
||||
* @arg @ref LL_DMA_CHANNEL_4
|
||||
* @arg @ref LL_DMA_CHANNEL_5
|
||||
* @arg @ref LL_DMA_CHANNEL_6
|
||||
* @arg @ref LL_DMA_CHANNEL_7
|
||||
* @param DMA_InitStruct pointer to a @ref LL_DMA_InitTypeDef structure.
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: DMA registers are initialized
|
||||
* - ERROR: Not applicable
|
||||
*/
|
||||
ErrorStatus LL_DMA_Init(DMA_TypeDef *DMAx, uint32_t Channel, LL_DMA_InitTypeDef *DMA_InitStruct)
|
||||
{
|
||||
/* Check the DMA Instance DMAx and Channel parameters*/
|
||||
assert_param(IS_LL_DMA_ALL_CHANNEL_INSTANCE(DMAx, Channel));
|
||||
|
||||
/* Check the DMA parameters from DMA_InitStruct */
|
||||
assert_param(IS_LL_DMA_DIRECTION(DMA_InitStruct->Direction));
|
||||
assert_param(IS_LL_DMA_MODE(DMA_InitStruct->Mode));
|
||||
assert_param(IS_LL_DMA_PERIPHINCMODE(DMA_InitStruct->PeriphOrM2MSrcIncMode));
|
||||
assert_param(IS_LL_DMA_MEMORYINCMODE(DMA_InitStruct->MemoryOrM2MDstIncMode));
|
||||
assert_param(IS_LL_DMA_PERIPHDATASIZE(DMA_InitStruct->PeriphOrM2MSrcDataSize));
|
||||
assert_param(IS_LL_DMA_MEMORYDATASIZE(DMA_InitStruct->MemoryOrM2MDstDataSize));
|
||||
assert_param(IS_LL_DMA_NBDATA(DMA_InitStruct->NbData));
|
||||
assert_param(IS_LL_DMA_PERIPHREQUEST(DMA_InitStruct->PeriphRequest));
|
||||
assert_param(IS_LL_DMA_PRIORITY(DMA_InitStruct->Priority));
|
||||
|
||||
/*---------------------------- DMAx CCR Configuration ------------------------
|
||||
* Configure DMAx_Channely: data transfer direction, data transfer mode,
|
||||
* peripheral and memory increment mode,
|
||||
* data size alignment and priority level with parameters :
|
||||
* - Direction: DMA_CCR_DIR and DMA_CCR_MEM2MEM bits
|
||||
* - Mode: DMA_CCR_CIRC bit
|
||||
* - PeriphOrM2MSrcIncMode: DMA_CCR_PINC bit
|
||||
* - MemoryOrM2MDstIncMode: DMA_CCR_MINC bit
|
||||
* - PeriphOrM2MSrcDataSize: DMA_CCR_PSIZE[1:0] bits
|
||||
* - MemoryOrM2MDstDataSize: DMA_CCR_MSIZE[1:0] bits
|
||||
* - Priority: DMA_CCR_PL[1:0] bits
|
||||
*/
|
||||
LL_DMA_ConfigTransfer(DMAx, Channel, DMA_InitStruct->Direction | \
|
||||
DMA_InitStruct->Mode | \
|
||||
DMA_InitStruct->PeriphOrM2MSrcIncMode | \
|
||||
DMA_InitStruct->MemoryOrM2MDstIncMode | \
|
||||
DMA_InitStruct->PeriphOrM2MSrcDataSize | \
|
||||
DMA_InitStruct->MemoryOrM2MDstDataSize | \
|
||||
DMA_InitStruct->Priority);
|
||||
|
||||
/*-------------------------- DMAx CMAR Configuration -------------------------
|
||||
* Configure the memory or destination base address with parameter :
|
||||
* - MemoryOrM2MDstAddress: DMA_CMAR_MA[31:0] bits
|
||||
*/
|
||||
LL_DMA_SetMemoryAddress(DMAx, Channel, DMA_InitStruct->MemoryOrM2MDstAddress);
|
||||
|
||||
/*-------------------------- DMAx CPAR Configuration -------------------------
|
||||
* Configure the peripheral or source base address with parameter :
|
||||
* - PeriphOrM2MSrcAddress: DMA_CPAR_PA[31:0] bits
|
||||
*/
|
||||
LL_DMA_SetPeriphAddress(DMAx, Channel, DMA_InitStruct->PeriphOrM2MSrcAddress);
|
||||
|
||||
/*--------------------------- DMAx CNDTR Configuration -----------------------
|
||||
* Configure the peripheral base address with parameter :
|
||||
* - NbData: DMA_CNDTR_NDT[15:0] bits
|
||||
*/
|
||||
LL_DMA_SetDataLength(DMAx, Channel, DMA_InitStruct->NbData);
|
||||
|
||||
#if defined(DMAMUX1)
|
||||
/*--------------------------- DMAMUXx CCR Configuration ----------------------
|
||||
* Configure the DMA request for DMA Channels on DMAMUX Channel x with parameter :
|
||||
* - PeriphRequest: DMA_CxCR[7:0] bits
|
||||
*/
|
||||
LL_DMA_SetPeriphRequest(DMAx, Channel, DMA_InitStruct->PeriphRequest);
|
||||
#else
|
||||
/*--------------------------- DMAx CSELR Configuration -----------------------
|
||||
* Configure the DMA request for DMA instance on Channel x with parameter :
|
||||
* - PeriphRequest: DMA_CSELR[31:0] bits
|
||||
*/
|
||||
LL_DMA_SetPeriphRequest(DMAx, Channel, DMA_InitStruct->PeriphRequest);
|
||||
#endif /* DMAMUX1 */
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set each @ref LL_DMA_InitTypeDef field to default value.
|
||||
* @param DMA_InitStruct Pointer to a @ref LL_DMA_InitTypeDef structure.
|
||||
* @retval None
|
||||
*/
|
||||
void LL_DMA_StructInit(LL_DMA_InitTypeDef *DMA_InitStruct)
|
||||
{
|
||||
/* Set DMA_InitStruct fields to default values */
|
||||
DMA_InitStruct->PeriphOrM2MSrcAddress = 0x00000000U;
|
||||
DMA_InitStruct->MemoryOrM2MDstAddress = 0x00000000U;
|
||||
DMA_InitStruct->Direction = LL_DMA_DIRECTION_PERIPH_TO_MEMORY;
|
||||
DMA_InitStruct->Mode = LL_DMA_MODE_NORMAL;
|
||||
DMA_InitStruct->PeriphOrM2MSrcIncMode = LL_DMA_PERIPH_NOINCREMENT;
|
||||
DMA_InitStruct->MemoryOrM2MDstIncMode = LL_DMA_MEMORY_NOINCREMENT;
|
||||
DMA_InitStruct->PeriphOrM2MSrcDataSize = LL_DMA_PDATAALIGN_BYTE;
|
||||
DMA_InitStruct->MemoryOrM2MDstDataSize = LL_DMA_MDATAALIGN_BYTE;
|
||||
DMA_InitStruct->NbData = 0x00000000U;
|
||||
#if defined(DMAMUX1)
|
||||
DMA_InitStruct->PeriphRequest = LL_DMAMUX_REQ_MEM2MEM;
|
||||
#else
|
||||
DMA_InitStruct->PeriphRequest = LL_DMA_REQUEST_0;
|
||||
#endif /* DMAMUX1 */
|
||||
DMA_InitStruct->Priority = LL_DMA_PRIORITY_LOW;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* DMA1 || DMA2 */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* USE_FULL_LL_DRIVER */
|
||||
288
Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_ll_exti.c
Normal file
288
Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_ll_exti.c
Normal file
@@ -0,0 +1,288 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32l4xx_ll_exti.c
|
||||
* @author MCD Application Team
|
||||
* @brief EXTI LL module driver.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2017 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
#if defined(USE_FULL_LL_DRIVER)
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32l4xx_ll_exti.h"
|
||||
#ifdef USE_FULL_ASSERT
|
||||
#include "stm32_assert.h"
|
||||
#else
|
||||
#define assert_param(expr) ((void)0U)
|
||||
#endif
|
||||
|
||||
/** @addtogroup STM32L4xx_LL_Driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
#if defined (EXTI)
|
||||
|
||||
/** @defgroup EXTI_LL EXTI
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Private types -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private constants ---------------------------------------------------------*/
|
||||
/* Private macros ------------------------------------------------------------*/
|
||||
/** @addtogroup EXTI_LL_Private_Macros
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define IS_LL_EXTI_LINE_0_31(__VALUE__) (((__VALUE__) & ~LL_EXTI_LINE_ALL_0_31) == 0x00000000U)
|
||||
#define IS_LL_EXTI_LINE_32_63(__VALUE__) (((__VALUE__) & ~LL_EXTI_LINE_ALL_32_63) == 0x00000000U)
|
||||
|
||||
#define IS_LL_EXTI_MODE(__VALUE__) (((__VALUE__) == LL_EXTI_MODE_IT) \
|
||||
|| ((__VALUE__) == LL_EXTI_MODE_EVENT) \
|
||||
|| ((__VALUE__) == LL_EXTI_MODE_IT_EVENT))
|
||||
|
||||
|
||||
#define IS_LL_EXTI_TRIGGER(__VALUE__) (((__VALUE__) == LL_EXTI_TRIGGER_NONE) \
|
||||
|| ((__VALUE__) == LL_EXTI_TRIGGER_RISING) \
|
||||
|| ((__VALUE__) == LL_EXTI_TRIGGER_FALLING) \
|
||||
|| ((__VALUE__) == LL_EXTI_TRIGGER_RISING_FALLING))
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
|
||||
/* Exported functions --------------------------------------------------------*/
|
||||
/** @addtogroup EXTI_LL_Exported_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup EXTI_LL_EF_Init
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief De-initialize the EXTI registers to their default reset values.
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - 0x00: EXTI registers are de-initialized
|
||||
*/
|
||||
uint32_t LL_EXTI_DeInit(void)
|
||||
{
|
||||
/* Interrupt mask register set to default reset values */
|
||||
LL_EXTI_WriteReg(IMR1, 0xFF820000U);
|
||||
/* Event mask register set to default reset values */
|
||||
LL_EXTI_WriteReg(EMR1, 0x00000000U);
|
||||
/* Rising Trigger selection register set to default reset values */
|
||||
LL_EXTI_WriteReg(RTSR1, 0x00000000U);
|
||||
/* Falling Trigger selection register set to default reset values */
|
||||
LL_EXTI_WriteReg(FTSR1, 0x00000000U);
|
||||
/* Software interrupt event register set to default reset values */
|
||||
LL_EXTI_WriteReg(SWIER1, 0x00000000U);
|
||||
/* Pending register clear */
|
||||
LL_EXTI_WriteReg(PR1, 0x007DFFFFU);
|
||||
|
||||
/* Interrupt mask register 2 set to default reset values */
|
||||
#if defined(LL_EXTI_LINE_40)
|
||||
LL_EXTI_WriteReg(IMR2, 0x00000187U);
|
||||
#else
|
||||
LL_EXTI_WriteReg(IMR2, 0x00000087U);
|
||||
#endif
|
||||
/* Event mask register 2 set to default reset values */
|
||||
LL_EXTI_WriteReg(EMR2, 0x00000000U);
|
||||
/* Rising Trigger selection register 2 set to default reset values */
|
||||
LL_EXTI_WriteReg(RTSR2, 0x00000000U);
|
||||
/* Falling Trigger selection register 2 set to default reset values */
|
||||
LL_EXTI_WriteReg(FTSR2, 0x00000000U);
|
||||
/* Software interrupt event register 2 set to default reset values */
|
||||
LL_EXTI_WriteReg(SWIER2, 0x00000000U);
|
||||
/* Pending register 2 clear */
|
||||
LL_EXTI_WriteReg(PR2, 0x00000078U);
|
||||
|
||||
return 0x00u;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialize the EXTI registers according to the specified parameters in EXTI_InitStruct.
|
||||
* @param EXTI_InitStruct pointer to a @ref LL_EXTI_InitTypeDef structure.
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - 0x00: EXTI registers are initialized
|
||||
* - any other value : wrong configuration
|
||||
*/
|
||||
uint32_t LL_EXTI_Init(LL_EXTI_InitTypeDef *EXTI_InitStruct)
|
||||
{
|
||||
uint32_t status = 0x00u;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_LL_EXTI_LINE_0_31(EXTI_InitStruct->Line_0_31));
|
||||
assert_param(IS_LL_EXTI_LINE_32_63(EXTI_InitStruct->Line_32_63));
|
||||
assert_param(IS_FUNCTIONAL_STATE(EXTI_InitStruct->LineCommand));
|
||||
assert_param(IS_LL_EXTI_MODE(EXTI_InitStruct->Mode));
|
||||
|
||||
/* ENABLE LineCommand */
|
||||
if (EXTI_InitStruct->LineCommand != DISABLE)
|
||||
{
|
||||
assert_param(IS_LL_EXTI_TRIGGER(EXTI_InitStruct->Trigger));
|
||||
|
||||
/* Configure EXTI Lines in range from 0 to 31 */
|
||||
if (EXTI_InitStruct->Line_0_31 != LL_EXTI_LINE_NONE)
|
||||
{
|
||||
switch (EXTI_InitStruct->Mode)
|
||||
{
|
||||
case LL_EXTI_MODE_IT:
|
||||
/* First Disable Event on provided Lines */
|
||||
LL_EXTI_DisableEvent_0_31(EXTI_InitStruct->Line_0_31);
|
||||
/* Then Enable IT on provided Lines */
|
||||
LL_EXTI_EnableIT_0_31(EXTI_InitStruct->Line_0_31);
|
||||
break;
|
||||
case LL_EXTI_MODE_EVENT:
|
||||
/* First Disable IT on provided Lines */
|
||||
LL_EXTI_DisableIT_0_31(EXTI_InitStruct->Line_0_31);
|
||||
/* Then Enable Event on provided Lines */
|
||||
LL_EXTI_EnableEvent_0_31(EXTI_InitStruct->Line_0_31);
|
||||
break;
|
||||
case LL_EXTI_MODE_IT_EVENT:
|
||||
/* Directly Enable IT & Event on provided Lines */
|
||||
LL_EXTI_EnableIT_0_31(EXTI_InitStruct->Line_0_31);
|
||||
LL_EXTI_EnableEvent_0_31(EXTI_InitStruct->Line_0_31);
|
||||
break;
|
||||
default:
|
||||
status = 0x01u;
|
||||
break;
|
||||
}
|
||||
if (EXTI_InitStruct->Trigger != LL_EXTI_TRIGGER_NONE)
|
||||
{
|
||||
switch (EXTI_InitStruct->Trigger)
|
||||
{
|
||||
case LL_EXTI_TRIGGER_RISING:
|
||||
/* First Disable Falling Trigger on provided Lines */
|
||||
LL_EXTI_DisableFallingTrig_0_31(EXTI_InitStruct->Line_0_31);
|
||||
/* Then Enable Rising Trigger on provided Lines */
|
||||
LL_EXTI_EnableRisingTrig_0_31(EXTI_InitStruct->Line_0_31);
|
||||
break;
|
||||
case LL_EXTI_TRIGGER_FALLING:
|
||||
/* First Disable Rising Trigger on provided Lines */
|
||||
LL_EXTI_DisableRisingTrig_0_31(EXTI_InitStruct->Line_0_31);
|
||||
/* Then Enable Falling Trigger on provided Lines */
|
||||
LL_EXTI_EnableFallingTrig_0_31(EXTI_InitStruct->Line_0_31);
|
||||
break;
|
||||
case LL_EXTI_TRIGGER_RISING_FALLING:
|
||||
LL_EXTI_EnableRisingTrig_0_31(EXTI_InitStruct->Line_0_31);
|
||||
LL_EXTI_EnableFallingTrig_0_31(EXTI_InitStruct->Line_0_31);
|
||||
break;
|
||||
default:
|
||||
status |= 0x02u;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Configure EXTI Lines in range from 32 to 63 */
|
||||
if (EXTI_InitStruct->Line_32_63 != LL_EXTI_LINE_NONE)
|
||||
{
|
||||
switch (EXTI_InitStruct->Mode)
|
||||
{
|
||||
case LL_EXTI_MODE_IT:
|
||||
/* First Disable Event on provided Lines */
|
||||
LL_EXTI_DisableEvent_32_63(EXTI_InitStruct->Line_32_63);
|
||||
/* Then Enable IT on provided Lines */
|
||||
LL_EXTI_EnableIT_32_63(EXTI_InitStruct->Line_32_63);
|
||||
break;
|
||||
case LL_EXTI_MODE_EVENT:
|
||||
/* First Disable IT on provided Lines */
|
||||
LL_EXTI_DisableIT_32_63(EXTI_InitStruct->Line_32_63);
|
||||
/* Then Enable Event on provided Lines */
|
||||
LL_EXTI_EnableEvent_32_63(EXTI_InitStruct->Line_32_63);
|
||||
break;
|
||||
case LL_EXTI_MODE_IT_EVENT:
|
||||
/* Directly Enable IT & Event on provided Lines */
|
||||
LL_EXTI_EnableIT_32_63(EXTI_InitStruct->Line_32_63);
|
||||
LL_EXTI_EnableEvent_32_63(EXTI_InitStruct->Line_32_63);
|
||||
break;
|
||||
default:
|
||||
status |= 0x04u;
|
||||
break;
|
||||
}
|
||||
if (EXTI_InitStruct->Trigger != LL_EXTI_TRIGGER_NONE)
|
||||
{
|
||||
switch (EXTI_InitStruct->Trigger)
|
||||
{
|
||||
case LL_EXTI_TRIGGER_RISING:
|
||||
/* First Disable Falling Trigger on provided Lines */
|
||||
LL_EXTI_DisableFallingTrig_32_63(EXTI_InitStruct->Line_32_63);
|
||||
/* Then Enable IT on provided Lines */
|
||||
LL_EXTI_EnableRisingTrig_32_63(EXTI_InitStruct->Line_32_63);
|
||||
break;
|
||||
case LL_EXTI_TRIGGER_FALLING:
|
||||
/* First Disable Rising Trigger on provided Lines */
|
||||
LL_EXTI_DisableRisingTrig_32_63(EXTI_InitStruct->Line_32_63);
|
||||
/* Then Enable Falling Trigger on provided Lines */
|
||||
LL_EXTI_EnableFallingTrig_32_63(EXTI_InitStruct->Line_32_63);
|
||||
break;
|
||||
case LL_EXTI_TRIGGER_RISING_FALLING:
|
||||
LL_EXTI_EnableRisingTrig_32_63(EXTI_InitStruct->Line_32_63);
|
||||
LL_EXTI_EnableFallingTrig_32_63(EXTI_InitStruct->Line_32_63);
|
||||
break;
|
||||
default:
|
||||
status = ERROR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* DISABLE LineCommand */
|
||||
else
|
||||
{
|
||||
/* De-configure EXTI Lines in range from 0 to 31 */
|
||||
LL_EXTI_DisableIT_0_31(EXTI_InitStruct->Line_0_31);
|
||||
LL_EXTI_DisableEvent_0_31(EXTI_InitStruct->Line_0_31);
|
||||
/* De-configure EXTI Lines in range from 32 to 63 */
|
||||
LL_EXTI_DisableIT_32_63(EXTI_InitStruct->Line_32_63);
|
||||
LL_EXTI_DisableEvent_32_63(EXTI_InitStruct->Line_32_63);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set each @ref LL_EXTI_InitTypeDef field to default value.
|
||||
* @param EXTI_InitStruct Pointer to a @ref LL_EXTI_InitTypeDef structure.
|
||||
* @retval None
|
||||
*/
|
||||
void LL_EXTI_StructInit(LL_EXTI_InitTypeDef *EXTI_InitStruct)
|
||||
{
|
||||
EXTI_InitStruct->Line_0_31 = LL_EXTI_LINE_NONE;
|
||||
EXTI_InitStruct->Line_32_63 = LL_EXTI_LINE_NONE;
|
||||
EXTI_InitStruct->LineCommand = DISABLE;
|
||||
EXTI_InitStruct->Mode = LL_EXTI_MODE_IT;
|
||||
EXTI_InitStruct->Trigger = LL_EXTI_TRIGGER_FALLING;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* defined (EXTI) */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* USE_FULL_LL_DRIVER */
|
||||
|
||||
293
Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_ll_gpio.c
Normal file
293
Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_ll_gpio.c
Normal file
@@ -0,0 +1,293 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32l4xx_ll_gpio.c
|
||||
* @author MCD Application Team
|
||||
* @brief GPIO LL module driver.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2017 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
#if defined(USE_FULL_LL_DRIVER)
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32l4xx_ll_gpio.h"
|
||||
#include "stm32l4xx_ll_bus.h"
|
||||
#ifdef USE_FULL_ASSERT
|
||||
#include "stm32_assert.h"
|
||||
#else
|
||||
#define assert_param(expr) ((void)0U)
|
||||
#endif
|
||||
|
||||
/** @addtogroup STM32L4xx_LL_Driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
#if defined (GPIOA) || defined (GPIOB) || defined (GPIOC) || defined (GPIOD) || defined (GPIOE) || defined (GPIOF) || defined (GPIOG) || defined (GPIOH) || defined (GPIOI)
|
||||
|
||||
/** @addtogroup GPIO_LL
|
||||
* @{
|
||||
*/
|
||||
/** MISRA C:2012 deviation rule has been granted for following rules:
|
||||
* Rule-12.2 - Medium: RHS argument is in interval [0,INF] which is out of
|
||||
* range of the shift operator in following API :
|
||||
* LL_GPIO_Init
|
||||
*/
|
||||
|
||||
/* Private types -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private constants ---------------------------------------------------------*/
|
||||
/* Private macros ------------------------------------------------------------*/
|
||||
/** @addtogroup GPIO_LL_Private_Macros
|
||||
* @{
|
||||
*/
|
||||
#define IS_LL_GPIO_PIN(__VALUE__) (((0x00u) < (__VALUE__)) && ((__VALUE__) <= (LL_GPIO_PIN_ALL)))
|
||||
|
||||
#define IS_LL_GPIO_MODE(__VALUE__) (((__VALUE__) == LL_GPIO_MODE_INPUT) ||\
|
||||
((__VALUE__) == LL_GPIO_MODE_OUTPUT) ||\
|
||||
((__VALUE__) == LL_GPIO_MODE_ALTERNATE) ||\
|
||||
((__VALUE__) == LL_GPIO_MODE_ANALOG))
|
||||
|
||||
#define IS_LL_GPIO_OUTPUT_TYPE(__VALUE__) (((__VALUE__) == LL_GPIO_OUTPUT_PUSHPULL) ||\
|
||||
((__VALUE__) == LL_GPIO_OUTPUT_OPENDRAIN))
|
||||
|
||||
#define IS_LL_GPIO_SPEED(__VALUE__) (((__VALUE__) == LL_GPIO_SPEED_FREQ_LOW) ||\
|
||||
((__VALUE__) == LL_GPIO_SPEED_FREQ_MEDIUM) ||\
|
||||
((__VALUE__) == LL_GPIO_SPEED_FREQ_HIGH) ||\
|
||||
((__VALUE__) == LL_GPIO_SPEED_FREQ_VERY_HIGH))
|
||||
|
||||
#define IS_LL_GPIO_PULL(__VALUE__) (((__VALUE__) == LL_GPIO_PULL_NO) ||\
|
||||
((__VALUE__) == LL_GPIO_PULL_UP) ||\
|
||||
((__VALUE__) == LL_GPIO_PULL_DOWN))
|
||||
|
||||
#define IS_LL_GPIO_ALTERNATE(__VALUE__) (((__VALUE__) == LL_GPIO_AF_0 ) ||\
|
||||
((__VALUE__) == LL_GPIO_AF_1 ) ||\
|
||||
((__VALUE__) == LL_GPIO_AF_2 ) ||\
|
||||
((__VALUE__) == LL_GPIO_AF_3 ) ||\
|
||||
((__VALUE__) == LL_GPIO_AF_4 ) ||\
|
||||
((__VALUE__) == LL_GPIO_AF_5 ) ||\
|
||||
((__VALUE__) == LL_GPIO_AF_6 ) ||\
|
||||
((__VALUE__) == LL_GPIO_AF_7 ) ||\
|
||||
((__VALUE__) == LL_GPIO_AF_8 ) ||\
|
||||
((__VALUE__) == LL_GPIO_AF_9 ) ||\
|
||||
((__VALUE__) == LL_GPIO_AF_10 ) ||\
|
||||
((__VALUE__) == LL_GPIO_AF_11 ) ||\
|
||||
((__VALUE__) == LL_GPIO_AF_12 ) ||\
|
||||
((__VALUE__) == LL_GPIO_AF_13 ) ||\
|
||||
((__VALUE__) == LL_GPIO_AF_14 ) ||\
|
||||
((__VALUE__) == LL_GPIO_AF_15 ))
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
|
||||
/* Exported functions --------------------------------------------------------*/
|
||||
/** @addtogroup GPIO_LL_Exported_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup GPIO_LL_EF_Init
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief De-initialize GPIO registers (Registers restored to their default values).
|
||||
* @param GPIOx GPIO Port
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: GPIO registers are de-initialized
|
||||
* - ERROR: Wrong GPIO Port
|
||||
*/
|
||||
ErrorStatus LL_GPIO_DeInit(GPIO_TypeDef *GPIOx)
|
||||
{
|
||||
ErrorStatus status = SUCCESS;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_GPIO_ALL_INSTANCE(GPIOx));
|
||||
|
||||
/* Force and Release reset on clock of GPIOx Port */
|
||||
if (GPIOx == GPIOA)
|
||||
{
|
||||
LL_AHB2_GRP1_ForceReset(LL_AHB2_GRP1_PERIPH_GPIOA);
|
||||
LL_AHB2_GRP1_ReleaseReset(LL_AHB2_GRP1_PERIPH_GPIOA);
|
||||
}
|
||||
else if (GPIOx == GPIOB)
|
||||
{
|
||||
LL_AHB2_GRP1_ForceReset(LL_AHB2_GRP1_PERIPH_GPIOB);
|
||||
LL_AHB2_GRP1_ReleaseReset(LL_AHB2_GRP1_PERIPH_GPIOB);
|
||||
}
|
||||
else if (GPIOx == GPIOC)
|
||||
{
|
||||
LL_AHB2_GRP1_ForceReset(LL_AHB2_GRP1_PERIPH_GPIOC);
|
||||
LL_AHB2_GRP1_ReleaseReset(LL_AHB2_GRP1_PERIPH_GPIOC);
|
||||
}
|
||||
#if defined(GPIOD)
|
||||
else if (GPIOx == GPIOD)
|
||||
{
|
||||
LL_AHB2_GRP1_ForceReset(LL_AHB2_GRP1_PERIPH_GPIOD);
|
||||
LL_AHB2_GRP1_ReleaseReset(LL_AHB2_GRP1_PERIPH_GPIOD);
|
||||
}
|
||||
#endif /* GPIOD */
|
||||
#if defined(GPIOE)
|
||||
else if (GPIOx == GPIOE)
|
||||
{
|
||||
LL_AHB2_GRP1_ForceReset(LL_AHB2_GRP1_PERIPH_GPIOE);
|
||||
LL_AHB2_GRP1_ReleaseReset(LL_AHB2_GRP1_PERIPH_GPIOE);
|
||||
}
|
||||
#endif /* GPIOE */
|
||||
#if defined(GPIOF)
|
||||
else if (GPIOx == GPIOF)
|
||||
{
|
||||
LL_AHB2_GRP1_ForceReset(LL_AHB2_GRP1_PERIPH_GPIOF);
|
||||
LL_AHB2_GRP1_ReleaseReset(LL_AHB2_GRP1_PERIPH_GPIOF);
|
||||
}
|
||||
#endif /* GPIOF */
|
||||
#if defined(GPIOG)
|
||||
else if (GPIOx == GPIOG)
|
||||
{
|
||||
LL_AHB2_GRP1_ForceReset(LL_AHB2_GRP1_PERIPH_GPIOG);
|
||||
LL_AHB2_GRP1_ReleaseReset(LL_AHB2_GRP1_PERIPH_GPIOG);
|
||||
}
|
||||
#endif /* GPIOG */
|
||||
#if defined(GPIOH)
|
||||
else if (GPIOx == GPIOH)
|
||||
{
|
||||
LL_AHB2_GRP1_ForceReset(LL_AHB2_GRP1_PERIPH_GPIOH);
|
||||
LL_AHB2_GRP1_ReleaseReset(LL_AHB2_GRP1_PERIPH_GPIOH);
|
||||
}
|
||||
#endif /* GPIOH */
|
||||
#if defined(GPIOI)
|
||||
else if (GPIOx == GPIOI)
|
||||
{
|
||||
LL_AHB2_GRP1_ForceReset(LL_AHB2_GRP1_PERIPH_GPIOI);
|
||||
LL_AHB2_GRP1_ReleaseReset(LL_AHB2_GRP1_PERIPH_GPIOI);
|
||||
}
|
||||
#endif /* GPIOI */
|
||||
else
|
||||
{
|
||||
status = ERROR;
|
||||
}
|
||||
|
||||
return (status);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialize GPIO registers according to the specified parameters in GPIO_InitStruct.
|
||||
* @param GPIOx GPIO Port
|
||||
* @param GPIO_InitStruct pointer to a @ref LL_GPIO_InitTypeDef structure
|
||||
* that contains the configuration information for the specified GPIO peripheral.
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: GPIO registers are initialized according to GPIO_InitStruct content
|
||||
* - ERROR: Not applicable
|
||||
*/
|
||||
ErrorStatus LL_GPIO_Init(GPIO_TypeDef *GPIOx, LL_GPIO_InitTypeDef *GPIO_InitStruct)
|
||||
{
|
||||
uint32_t pinpos;
|
||||
uint32_t currentpin;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_GPIO_ALL_INSTANCE(GPIOx));
|
||||
assert_param(IS_LL_GPIO_PIN(GPIO_InitStruct->Pin));
|
||||
assert_param(IS_LL_GPIO_MODE(GPIO_InitStruct->Mode));
|
||||
assert_param(IS_LL_GPIO_PULL(GPIO_InitStruct->Pull));
|
||||
|
||||
/* ------------------------- Configure the port pins ---------------- */
|
||||
/* Initialize pinpos on first pin set */
|
||||
pinpos = POSITION_VAL(GPIO_InitStruct->Pin);
|
||||
|
||||
/* Configure the port pins */
|
||||
while (((GPIO_InitStruct->Pin) >> pinpos) != 0x00u)
|
||||
{
|
||||
/* Get current io position */
|
||||
currentpin = (GPIO_InitStruct->Pin) & (0x00000001uL << pinpos);
|
||||
|
||||
if (currentpin != 0x00u)
|
||||
{
|
||||
if ((GPIO_InitStruct->Mode == LL_GPIO_MODE_OUTPUT) || (GPIO_InitStruct->Mode == LL_GPIO_MODE_ALTERNATE))
|
||||
{
|
||||
/* Check Speed mode parameters */
|
||||
assert_param(IS_LL_GPIO_SPEED(GPIO_InitStruct->Speed));
|
||||
|
||||
/* Speed mode configuration */
|
||||
LL_GPIO_SetPinSpeed(GPIOx, currentpin, GPIO_InitStruct->Speed);
|
||||
|
||||
/* Check Output mode parameters */
|
||||
assert_param(IS_LL_GPIO_OUTPUT_TYPE(GPIO_InitStruct->OutputType));
|
||||
|
||||
/* Output mode configuration*/
|
||||
LL_GPIO_SetPinOutputType(GPIOx, GPIO_InitStruct->Pin, GPIO_InitStruct->OutputType);
|
||||
}
|
||||
|
||||
/* Pull-up Pull down resistor configuration*/
|
||||
LL_GPIO_SetPinPull(GPIOx, currentpin, GPIO_InitStruct->Pull);
|
||||
|
||||
if (GPIO_InitStruct->Mode == LL_GPIO_MODE_ALTERNATE)
|
||||
{
|
||||
/* Check Alternate parameter */
|
||||
assert_param(IS_LL_GPIO_ALTERNATE(GPIO_InitStruct->Alternate));
|
||||
|
||||
/* Speed mode configuration */
|
||||
if (currentpin < LL_GPIO_PIN_8)
|
||||
{
|
||||
LL_GPIO_SetAFPin_0_7(GPIOx, currentpin, GPIO_InitStruct->Alternate);
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_GPIO_SetAFPin_8_15(GPIOx, currentpin, GPIO_InitStruct->Alternate);
|
||||
}
|
||||
}
|
||||
|
||||
/* Pin Mode configuration */
|
||||
LL_GPIO_SetPinMode(GPIOx, currentpin, GPIO_InitStruct->Mode);
|
||||
}
|
||||
pinpos++;
|
||||
}
|
||||
|
||||
return (SUCCESS);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set each @ref LL_GPIO_InitTypeDef field to default value.
|
||||
* @param GPIO_InitStruct pointer to a @ref LL_GPIO_InitTypeDef structure
|
||||
* whose fields will be set to default values.
|
||||
* @retval None
|
||||
*/
|
||||
|
||||
void LL_GPIO_StructInit(LL_GPIO_InitTypeDef *GPIO_InitStruct)
|
||||
{
|
||||
/* Reset GPIO init structure parameters values */
|
||||
GPIO_InitStruct->Pin = LL_GPIO_PIN_ALL;
|
||||
GPIO_InitStruct->Mode = LL_GPIO_MODE_ANALOG;
|
||||
GPIO_InitStruct->Speed = LL_GPIO_SPEED_FREQ_LOW;
|
||||
GPIO_InitStruct->OutputType = LL_GPIO_OUTPUT_PUSHPULL;
|
||||
GPIO_InitStruct->Pull = LL_GPIO_PULL_NO;
|
||||
GPIO_InitStruct->Alternate = LL_GPIO_AF_0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* defined (GPIOA) || defined (GPIOB) || defined (GPIOC) || defined (GPIOD) || defined (GPIOE) || defined (GPIOF) || defined (GPIOG) || defined (GPIOH) || defined (GPIOI) */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* USE_FULL_LL_DRIVER */
|
||||
|
||||
82
Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_ll_pwr.c
Normal file
82
Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_ll_pwr.c
Normal file
@@ -0,0 +1,82 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32l4xx_ll_pwr.c
|
||||
* @author MCD Application Team
|
||||
* @brief PWR LL module driver.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2017 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
#if defined(USE_FULL_LL_DRIVER)
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32l4xx_ll_pwr.h"
|
||||
#include "stm32l4xx_ll_bus.h"
|
||||
|
||||
/** @addtogroup STM32L4xx_LL_Driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
#if defined(PWR)
|
||||
|
||||
/** @defgroup PWR_LL PWR
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Private types -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private constants ---------------------------------------------------------*/
|
||||
/* Private macros ------------------------------------------------------------*/
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
|
||||
/* Exported functions --------------------------------------------------------*/
|
||||
/** @addtogroup PWR_LL_Exported_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup PWR_LL_EF_Init
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief De-initialize the PWR registers to their default reset values.
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: PWR registers are de-initialized
|
||||
* - ERROR: not applicable
|
||||
*/
|
||||
ErrorStatus LL_PWR_DeInit(void)
|
||||
{
|
||||
/* Force reset of PWR clock */
|
||||
LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_PWR);
|
||||
|
||||
/* Release reset of PWR clock */
|
||||
LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_PWR);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
#endif /* defined(PWR) */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* USE_FULL_LL_DRIVER */
|
||||
2039
Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_ll_rcc.c
Normal file
2039
Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_ll_rcc.c
Normal file
@@ -0,0 +1,2039 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32l4xx_ll_rcc.c
|
||||
* @author MCD Application Team
|
||||
* @brief RCC LL module driver.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2017 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file in
|
||||
* the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
******************************************************************************
|
||||
*/
|
||||
#if defined(USE_FULL_LL_DRIVER)
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32l4xx_ll_rcc.h"
|
||||
#ifdef USE_FULL_ASSERT
|
||||
#include "stm32_assert.h"
|
||||
#else
|
||||
#define assert_param(expr) ((void)0U)
|
||||
#endif
|
||||
/** @addtogroup STM32L4xx_LL_Driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
#if defined(RCC)
|
||||
|
||||
/** @addtogroup RCC_LL
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Private types -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private constants ---------------------------------------------------------*/
|
||||
/* Private macros ------------------------------------------------------------*/
|
||||
/** @addtogroup RCC_LL_Private_Macros
|
||||
* @{
|
||||
*/
|
||||
#if defined(RCC_CCIPR_USART3SEL)
|
||||
#define IS_LL_RCC_USART_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_USART1_CLKSOURCE) \
|
||||
|| ((__VALUE__) == LL_RCC_USART2_CLKSOURCE) \
|
||||
|| ((__VALUE__) == LL_RCC_USART3_CLKSOURCE))
|
||||
#else
|
||||
#define IS_LL_RCC_USART_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_USART1_CLKSOURCE) \
|
||||
|| ((__VALUE__) == LL_RCC_USART2_CLKSOURCE))
|
||||
|
||||
#endif /* RCC_CCIPR_USART3SEL */
|
||||
#if defined(RCC_CCIPR_UART4SEL) && defined(RCC_CCIPR_UART5SEL)
|
||||
#define IS_LL_RCC_UART_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_UART4_CLKSOURCE) \
|
||||
|| ((__VALUE__) == LL_RCC_UART5_CLKSOURCE))
|
||||
#elif defined(RCC_CCIPR_UART4SEL)
|
||||
#define IS_LL_RCC_UART_CLKSOURCE(__VALUE__) ((__VALUE__) == LL_RCC_UART4_CLKSOURCE)
|
||||
#elif defined(RCC_CCIPR_UART5SEL)
|
||||
#define IS_LL_RCC_UART_CLKSOURCE(__VALUE__) ((__VALUE__) == LL_RCC_UART5_CLKSOURCE)
|
||||
#endif /* RCC_CCIPR_UART4SEL && RCC_CCIPR_UART5SEL*/
|
||||
|
||||
#define IS_LL_RCC_LPUART_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_LPUART1_CLKSOURCE))
|
||||
|
||||
#if defined(RCC_CCIPR_I2C2SEL) && defined(RCC_CCIPR_I2C3SEL) && defined(RCC_CCIPR2_I2C4SEL)
|
||||
#define IS_LL_RCC_I2C_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_I2C1_CLKSOURCE) \
|
||||
|| ((__VALUE__) == LL_RCC_I2C2_CLKSOURCE) \
|
||||
|| ((__VALUE__) == LL_RCC_I2C3_CLKSOURCE) \
|
||||
|| ((__VALUE__) == LL_RCC_I2C4_CLKSOURCE))
|
||||
#elif defined(RCC_CCIPR_I2C2SEL) && defined(RCC_CCIPR_I2C3SEL)
|
||||
#define IS_LL_RCC_I2C_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_I2C1_CLKSOURCE) \
|
||||
|| ((__VALUE__) == LL_RCC_I2C2_CLKSOURCE) \
|
||||
|| ((__VALUE__) == LL_RCC_I2C3_CLKSOURCE))
|
||||
|
||||
#elif !defined(RCC_CCIPR_I2C2SEL) && defined(RCC_CCIPR_I2C3SEL)
|
||||
#define IS_LL_RCC_I2C_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_I2C1_CLKSOURCE) \
|
||||
|| ((__VALUE__) == LL_RCC_I2C3_CLKSOURCE))
|
||||
|
||||
#else
|
||||
#define IS_LL_RCC_I2C_CLKSOURCE(__VALUE__) ((__VALUE__) == LL_RCC_I2C1_CLKSOURCE)
|
||||
|
||||
#endif /* RCC_CCIPR_I2C2SEL && RCC_CCIPR_I2C3SEL && RCC_CCIPR2_I2C4SEL */
|
||||
#define IS_LL_RCC_LPTIM_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_LPTIM1_CLKSOURCE) \
|
||||
|| ((__VALUE__) == LL_RCC_LPTIM2_CLKSOURCE))
|
||||
|
||||
#if defined(RCC_CCIPR_SAI2SEL) || defined(RCC_CCIPR2_SAI2SEL)
|
||||
#define IS_LL_RCC_SAI_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_SAI1_CLKSOURCE) \
|
||||
|| ((__VALUE__) == LL_RCC_SAI2_CLKSOURCE))
|
||||
#elif defined(RCC_CCIPR_SAI1SEL) || defined(RCC_CCIPR2_SAI1SEL)
|
||||
#define IS_LL_RCC_SAI_CLKSOURCE(__VALUE__) ((__VALUE__) == LL_RCC_SAI1_CLKSOURCE)
|
||||
#endif /* RCC_CCIPR_SAI2SEL RCC_CCIPR2_SAI2SEL ||*/
|
||||
|
||||
#if defined(SDMMC1)
|
||||
#if defined(RCC_CCIPR2_SDMMCSEL)
|
||||
#define IS_LL_RCC_SDMMC_KERNELCLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_SDMMC1_KERNELCLKSOURCE))
|
||||
#endif /* RCC_CCIPR2_SDMMCSEL */
|
||||
|
||||
#define IS_LL_RCC_SDMMC_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_SDMMC1_CLKSOURCE))
|
||||
#endif /* SDMMC1 */
|
||||
|
||||
#define IS_LL_RCC_RNG_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_RNG_CLKSOURCE))
|
||||
|
||||
#if defined(USB_OTG_FS) || defined(USB)
|
||||
#define IS_LL_RCC_USB_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_USB_CLKSOURCE))
|
||||
#endif /* USB_OTG_FS || USB */
|
||||
|
||||
#define IS_LL_RCC_ADC_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_ADC_CLKSOURCE))
|
||||
|
||||
#if defined(SWPMI1)
|
||||
#define IS_LL_RCC_SWPMI_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_SWPMI1_CLKSOURCE))
|
||||
#endif /* SWPMI1 */
|
||||
|
||||
#if defined(DFSDM1_Channel0)
|
||||
#define IS_LL_RCC_DFSDM_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_DFSDM1_CLKSOURCE))
|
||||
#if defined(RCC_CCIPR2_DFSDM1SEL)
|
||||
#define IS_LL_RCC_DFSDM_AUDIO_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_DFSDM1_AUDIO_CLKSOURCE))
|
||||
#endif /* RCC_CCIPR2_DFSDM1SEL */
|
||||
#endif /* DFSDM1_Channel0 */
|
||||
|
||||
#if defined(DSI)
|
||||
#define IS_LL_RCC_DSI_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_DSI_CLKSOURCE))
|
||||
#endif /* DSI */
|
||||
|
||||
#if defined(LTDC)
|
||||
#define IS_LL_RCC_LTDC_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_LTDC_CLKSOURCE))
|
||||
#endif /* LTDC */
|
||||
|
||||
#if defined(OCTOSPI1)
|
||||
#define IS_LL_RCC_OCTOSPI_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_OCTOSPI_CLKSOURCE))
|
||||
#endif /* OCTOSPI */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/** @defgroup RCC_LL_Private_Functions RCC Private functions
|
||||
* @{
|
||||
*/
|
||||
static uint32_t RCC_GetSystemClockFreq(void);
|
||||
static uint32_t RCC_GetHCLKClockFreq(uint32_t SYSCLK_Frequency);
|
||||
static uint32_t RCC_GetPCLK1ClockFreq(uint32_t HCLK_Frequency);
|
||||
static uint32_t RCC_GetPCLK2ClockFreq(uint32_t HCLK_Frequency);
|
||||
static uint32_t RCC_PLL_GetFreqDomain_SYS(void);
|
||||
#if defined(RCC_CCIPR_SAI1SEL) || defined(RCC_CCIPR_SAI2SEL) || defined(RCC_CCIPR2_SAI1SEL) || defined(RCC_CCIPR2_SAI2SEL)
|
||||
static uint32_t RCC_PLL_GetFreqDomain_SAI(void);
|
||||
#endif
|
||||
static uint32_t RCC_PLL_GetFreqDomain_48M(void);
|
||||
#if defined(RCC_PLLSAI1_SUPPORT)
|
||||
static uint32_t RCC_PLLSAI1_GetFreqDomain_SAI(void);
|
||||
static uint32_t RCC_PLLSAI1_GetFreqDomain_48M(void);
|
||||
static uint32_t RCC_PLLSAI1_GetFreqDomain_ADC(void);
|
||||
#endif /* RCC_PLLSAI1_SUPPORT */
|
||||
#if defined(RCC_PLLSAI2_SUPPORT)
|
||||
static uint32_t RCC_PLLSAI2_GetFreqDomain_SAI(void);
|
||||
#if defined(LTDC)
|
||||
static uint32_t RCC_PLLSAI2_GetFreqDomain_LTDC(void);
|
||||
#else
|
||||
static uint32_t RCC_PLLSAI2_GetFreqDomain_ADC(void);
|
||||
#endif /* LTDC */
|
||||
#if defined(DSI)
|
||||
static uint32_t RCC_PLLSAI2_GetFreqDomain_DSI(void);
|
||||
#endif /* DSI */
|
||||
#endif /*RCC_PLLSAI2_SUPPORT*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/* Exported functions --------------------------------------------------------*/
|
||||
/** @addtogroup RCC_LL_Exported_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup RCC_LL_EF_Init
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Reset the RCC clock configuration to the default reset state.
|
||||
* @note The default reset state of the clock configuration is given below:
|
||||
* - MSI ON and used as system clock source
|
||||
* - HSE, HSI, PLL, PLLSAI1 and PLLSAI2 OFF
|
||||
* - AHB, APB1 and APB2 prescaler set to 1.
|
||||
* - CSS, MCO OFF
|
||||
* - All interrupts disabled
|
||||
* @note This function doesn't modify the configuration of the
|
||||
* - Peripheral clocks
|
||||
* - LSI, LSE and RTC clocks
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: RCC registers are de-initialized
|
||||
* - ERROR: not applicable
|
||||
*/
|
||||
ErrorStatus LL_RCC_DeInit(void)
|
||||
{
|
||||
__IO uint32_t vl_mask;
|
||||
|
||||
/* Set MSION bit */
|
||||
LL_RCC_MSI_Enable();
|
||||
|
||||
/* Insure MSIRDY bit is set before writing default MSIRANGE value */
|
||||
while (LL_RCC_MSI_IsReady() == 0U)
|
||||
{
|
||||
}
|
||||
|
||||
/* Set MSIRANGE default value */
|
||||
LL_RCC_MSI_SetRange(LL_RCC_MSIRANGE_6);
|
||||
|
||||
/* Set MSITRIM bits to the reset value*/
|
||||
LL_RCC_MSI_SetCalibTrimming(0);
|
||||
|
||||
/* Set HSITRIM bits to the reset value*/
|
||||
#if defined(RCC_ICSCR_HSITRIM_6)
|
||||
LL_RCC_HSI_SetCalibTrimming(0x40U);
|
||||
#else
|
||||
LL_RCC_HSI_SetCalibTrimming(0x10U);
|
||||
#endif /* RCC_ICSCR_HSITRIM_6 */
|
||||
|
||||
/* Reset CFGR register */
|
||||
LL_RCC_WriteReg(CFGR, 0x00000000U);
|
||||
|
||||
/* Read CR register */
|
||||
vl_mask = LL_RCC_ReadReg(CR);
|
||||
|
||||
/* Reset HSION, HSIKERON, HSIASFS, HSEON, PLLON bits */
|
||||
CLEAR_BIT(vl_mask,
|
||||
(RCC_CR_HSION | RCC_CR_HSIASFS | RCC_CR_HSIKERON | RCC_CR_HSEON | RCC_CR_PLLON));
|
||||
|
||||
#if defined(RCC_PLLSAI1_SUPPORT)
|
||||
/* Reset PLLSAI1ON bit */
|
||||
CLEAR_BIT(vl_mask, RCC_CR_PLLSAI1ON);
|
||||
#endif /*RCC_PLLSAI1_SUPPORT*/
|
||||
|
||||
#if defined(RCC_PLLSAI2_SUPPORT)
|
||||
/* Reset PLLSAI2ON bit */
|
||||
CLEAR_BIT(vl_mask, RCC_CR_PLLSAI2ON);
|
||||
#endif /*RCC_PLLSAI2_SUPPORT*/
|
||||
|
||||
/* Write new value in CR register */
|
||||
LL_RCC_WriteReg(CR, vl_mask);
|
||||
|
||||
#if defined(RCC_PLLSAI2_SUPPORT)
|
||||
/* Wait for PLLRDY, PLLSAI1RDY and PLLSAI2RDY bits to be reset */
|
||||
while(READ_BIT(RCC->CR, RCC_CR_PLLRDY | RCC_CR_PLLSAI1RDY | RCC_CR_PLLSAI2RDY) != 0U)
|
||||
{
|
||||
}
|
||||
#elif defined(RCC_PLLSAI1_SUPPORT)
|
||||
/* Wait for PLLRDY and PLLSAI1RDY to be reset */
|
||||
while(READ_BIT(RCC->CR, RCC_CR_PLLRDY | RCC_CR_PLLSAI1RDY) != 0U)
|
||||
{
|
||||
}
|
||||
#else
|
||||
/* Wait for PLLRDY bit to be reset */
|
||||
while(READ_BIT(RCC->CR, RCC_CR_PLLRDY) != 0U)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Reset PLLCFGR register */
|
||||
LL_RCC_WriteReg(PLLCFGR, 16U << RCC_PLLCFGR_PLLN_Pos);
|
||||
|
||||
#if defined(RCC_PLLSAI1_SUPPORT)
|
||||
/* Reset PLLSAI1CFGR register */
|
||||
LL_RCC_WriteReg(PLLSAI1CFGR, 16U << RCC_PLLSAI1CFGR_PLLSAI1N_Pos);
|
||||
#endif /*RCC_PLLSAI1_SUPPORT*/
|
||||
|
||||
#if defined(RCC_PLLSAI2_SUPPORT)
|
||||
/* Reset PLLSAI2CFGR register */
|
||||
LL_RCC_WriteReg(PLLSAI2CFGR, 16U << RCC_PLLSAI2CFGR_PLLSAI2N_Pos);
|
||||
#endif /*RCC_PLLSAI2_SUPPORT*/
|
||||
|
||||
/* Reset HSEBYP bit */
|
||||
LL_RCC_HSE_DisableBypass();
|
||||
|
||||
/* Disable all interrupts */
|
||||
LL_RCC_WriteReg(CIER, 0x00000000U);
|
||||
|
||||
/* Clear all interrupt flags */
|
||||
vl_mask = RCC_CICR_LSIRDYC | RCC_CICR_LSERDYC | RCC_CICR_MSIRDYC | RCC_CICR_HSIRDYC | RCC_CICR_HSERDYC | RCC_CICR_PLLRDYC | \
|
||||
RCC_CICR_CSSC | RCC_CICR_LSECSSC;
|
||||
#if defined(RCC_HSI48_SUPPORT)
|
||||
vl_mask |= RCC_CICR_HSI48RDYC;
|
||||
#endif
|
||||
#if defined(RCC_PLLSAI1_SUPPORT)
|
||||
vl_mask |= RCC_CICR_PLLSAI1RDYC;
|
||||
#endif
|
||||
#if defined(RCC_PLLSAI2_SUPPORT)
|
||||
vl_mask |= RCC_CICR_PLLSAI2RDYC;
|
||||
#endif
|
||||
LL_RCC_WriteReg(CICR, vl_mask);
|
||||
|
||||
/* Clear reset flags */
|
||||
LL_RCC_ClearResetFlags();
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup RCC_LL_EF_Get_Freq
|
||||
* @brief Return the frequencies of different on chip clocks; System, AHB, APB1 and APB2 buses clocks
|
||||
* and different peripheral clocks available on the device.
|
||||
* @note If SYSCLK source is MSI, function returns values based on MSI_VALUE(*)
|
||||
* @note If SYSCLK source is HSI, function returns values based on HSI_VALUE(**)
|
||||
* @note If SYSCLK source is HSE, function returns values based on HSE_VALUE(***)
|
||||
* @note If SYSCLK source is PLL, function returns values based on HSE_VALUE(***)
|
||||
* or HSI_VALUE(**) or MSI_VALUE(*) multiplied/divided by the PLL factors.
|
||||
* @note (*) MSI_VALUE is a constant defined in this file (default value
|
||||
* 4 MHz) but the real value may vary depending on the variations
|
||||
* in voltage and temperature.
|
||||
* @note (**) HSI_VALUE is a constant defined in this file (default value
|
||||
* 16 MHz) but the real value may vary depending on the variations
|
||||
* in voltage and temperature.
|
||||
* @note (***) HSE_VALUE is a constant defined in this file (default value
|
||||
* 8 MHz), user has to ensure that HSE_VALUE is same as the real
|
||||
* frequency of the crystal used. Otherwise, this function may
|
||||
* have wrong result.
|
||||
* @note The result of this function could be incorrect when using fractional
|
||||
* value for HSE crystal.
|
||||
* @note This function can be used by the user application to compute the
|
||||
* baud-rate for the communication peripherals or configure other parameters.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Return the frequencies of different on chip clocks; System, AHB, APB1 and APB2 buses clocks
|
||||
* @note Each time SYSCLK, HCLK, PCLK1 and/or PCLK2 clock changes, this function
|
||||
* must be called to update structure fields. Otherwise, any
|
||||
* configuration based on this function will be incorrect.
|
||||
* @param RCC_Clocks pointer to a @ref LL_RCC_ClocksTypeDef structure which will hold the clocks frequencies
|
||||
* @retval None
|
||||
*/
|
||||
void LL_RCC_GetSystemClocksFreq(LL_RCC_ClocksTypeDef *RCC_Clocks)
|
||||
{
|
||||
/* Get SYSCLK frequency */
|
||||
RCC_Clocks->SYSCLK_Frequency = RCC_GetSystemClockFreq();
|
||||
|
||||
/* HCLK clock frequency */
|
||||
RCC_Clocks->HCLK_Frequency = RCC_GetHCLKClockFreq(RCC_Clocks->SYSCLK_Frequency);
|
||||
|
||||
/* PCLK1 clock frequency */
|
||||
RCC_Clocks->PCLK1_Frequency = RCC_GetPCLK1ClockFreq(RCC_Clocks->HCLK_Frequency);
|
||||
|
||||
/* PCLK2 clock frequency */
|
||||
RCC_Clocks->PCLK2_Frequency = RCC_GetPCLK2ClockFreq(RCC_Clocks->HCLK_Frequency);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return USARTx clock frequency
|
||||
* @param USARTxSource This parameter can be one of the following values:
|
||||
* @arg @ref LL_RCC_USART1_CLKSOURCE
|
||||
* @arg @ref LL_RCC_USART2_CLKSOURCE
|
||||
* @arg @ref LL_RCC_USART3_CLKSOURCE (*)
|
||||
*
|
||||
* (*) value not defined in all devices.
|
||||
* @retval USART clock frequency (in Hz)
|
||||
* - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator (HSI or LSE) is not ready
|
||||
*/
|
||||
uint32_t LL_RCC_GetUSARTClockFreq(uint32_t USARTxSource)
|
||||
{
|
||||
uint32_t usart_frequency = LL_RCC_PERIPH_FREQUENCY_NO;
|
||||
|
||||
/* Check parameter */
|
||||
assert_param(IS_LL_RCC_USART_CLKSOURCE(USARTxSource));
|
||||
|
||||
if (USARTxSource == LL_RCC_USART1_CLKSOURCE)
|
||||
{
|
||||
/* USART1CLK clock frequency */
|
||||
switch (LL_RCC_GetUSARTClockSource(USARTxSource))
|
||||
{
|
||||
case LL_RCC_USART1_CLKSOURCE_SYSCLK: /* USART1 Clock is System Clock */
|
||||
usart_frequency = RCC_GetSystemClockFreq();
|
||||
break;
|
||||
|
||||
case LL_RCC_USART1_CLKSOURCE_HSI: /* USART1 Clock is HSI Osc. */
|
||||
if (LL_RCC_HSI_IsReady() != 0U)
|
||||
{
|
||||
usart_frequency = HSI_VALUE;
|
||||
}
|
||||
break;
|
||||
|
||||
case LL_RCC_USART1_CLKSOURCE_LSE: /* USART1 Clock is LSE Osc. */
|
||||
if (LL_RCC_LSE_IsReady() != 0U)
|
||||
{
|
||||
usart_frequency = LSE_VALUE;
|
||||
}
|
||||
break;
|
||||
|
||||
case LL_RCC_USART1_CLKSOURCE_PCLK2: /* USART1 Clock is PCLK2 */
|
||||
usart_frequency = RCC_GetPCLK2ClockFreq(RCC_GetHCLKClockFreq(RCC_GetSystemClockFreq()));
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (USARTxSource == LL_RCC_USART2_CLKSOURCE)
|
||||
{
|
||||
/* USART2CLK clock frequency */
|
||||
switch (LL_RCC_GetUSARTClockSource(USARTxSource))
|
||||
{
|
||||
case LL_RCC_USART2_CLKSOURCE_SYSCLK: /* USART2 Clock is System Clock */
|
||||
usart_frequency = RCC_GetSystemClockFreq();
|
||||
break;
|
||||
|
||||
case LL_RCC_USART2_CLKSOURCE_HSI: /* USART2 Clock is HSI Osc. */
|
||||
if (LL_RCC_HSI_IsReady() != 0U)
|
||||
{
|
||||
usart_frequency = HSI_VALUE;
|
||||
}
|
||||
break;
|
||||
|
||||
case LL_RCC_USART2_CLKSOURCE_LSE: /* USART2 Clock is LSE Osc. */
|
||||
if (LL_RCC_LSE_IsReady() != 0U)
|
||||
{
|
||||
usart_frequency = LSE_VALUE;
|
||||
}
|
||||
break;
|
||||
|
||||
case LL_RCC_USART2_CLKSOURCE_PCLK1: /* USART2 Clock is PCLK1 */
|
||||
usart_frequency = RCC_GetPCLK1ClockFreq(RCC_GetHCLKClockFreq(RCC_GetSystemClockFreq()));
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#if defined(RCC_CCIPR_USART3SEL)
|
||||
if (USARTxSource == LL_RCC_USART3_CLKSOURCE)
|
||||
{
|
||||
/* USART3CLK clock frequency */
|
||||
switch (LL_RCC_GetUSARTClockSource(USARTxSource))
|
||||
{
|
||||
case LL_RCC_USART3_CLKSOURCE_SYSCLK: /* USART3 Clock is System Clock */
|
||||
usart_frequency = RCC_GetSystemClockFreq();
|
||||
break;
|
||||
|
||||
case LL_RCC_USART3_CLKSOURCE_HSI: /* USART3 Clock is HSI Osc. */
|
||||
if (LL_RCC_HSI_IsReady() != 0U)
|
||||
{
|
||||
usart_frequency = HSI_VALUE;
|
||||
}
|
||||
break;
|
||||
|
||||
case LL_RCC_USART3_CLKSOURCE_LSE: /* USART3 Clock is LSE Osc. */
|
||||
if (LL_RCC_LSE_IsReady() != 0U)
|
||||
{
|
||||
usart_frequency = LSE_VALUE;
|
||||
}
|
||||
break;
|
||||
|
||||
case LL_RCC_USART3_CLKSOURCE_PCLK1: /* USART3 Clock is PCLK1 */
|
||||
usart_frequency = RCC_GetPCLK1ClockFreq(RCC_GetHCLKClockFreq(RCC_GetSystemClockFreq()));
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif /* RCC_CCIPR_USART3SEL */
|
||||
}
|
||||
return usart_frequency;
|
||||
}
|
||||
|
||||
#if defined(RCC_CCIPR_UART4SEL) || defined(RCC_CCIPR_UART5SEL)
|
||||
/**
|
||||
* @brief Return UARTx clock frequency
|
||||
* @param UARTxSource This parameter can be one of the following values:
|
||||
* @arg @ref LL_RCC_UART4_CLKSOURCE
|
||||
* @arg @ref LL_RCC_UART5_CLKSOURCE
|
||||
* @retval UART clock frequency (in Hz)
|
||||
* - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator (HSI or LSE) is not ready
|
||||
*/
|
||||
uint32_t LL_RCC_GetUARTClockFreq(uint32_t UARTxSource)
|
||||
{
|
||||
uint32_t uart_frequency = LL_RCC_PERIPH_FREQUENCY_NO;
|
||||
|
||||
/* Check parameter */
|
||||
assert_param(IS_LL_RCC_UART_CLKSOURCE(UARTxSource));
|
||||
|
||||
#if defined(RCC_CCIPR_UART4SEL)
|
||||
if (UARTxSource == LL_RCC_UART4_CLKSOURCE)
|
||||
{
|
||||
/* UART4CLK clock frequency */
|
||||
switch (LL_RCC_GetUARTClockSource(UARTxSource))
|
||||
{
|
||||
case LL_RCC_UART4_CLKSOURCE_SYSCLK: /* UART4 Clock is System Clock */
|
||||
uart_frequency = RCC_GetSystemClockFreq();
|
||||
break;
|
||||
|
||||
case LL_RCC_UART4_CLKSOURCE_HSI: /* UART4 Clock is HSI Osc. */
|
||||
if (LL_RCC_HSI_IsReady() != 0U)
|
||||
{
|
||||
uart_frequency = HSI_VALUE;
|
||||
}
|
||||
break;
|
||||
|
||||
case LL_RCC_UART4_CLKSOURCE_LSE: /* UART4 Clock is LSE Osc. */
|
||||
if (LL_RCC_LSE_IsReady() != 0U)
|
||||
{
|
||||
uart_frequency = LSE_VALUE;
|
||||
}
|
||||
break;
|
||||
|
||||
case LL_RCC_UART4_CLKSOURCE_PCLK1: /* UART4 Clock is PCLK1 */
|
||||
uart_frequency = RCC_GetPCLK1ClockFreq(RCC_GetHCLKClockFreq(RCC_GetSystemClockFreq()));
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif /* RCC_CCIPR_UART4SEL */
|
||||
|
||||
#if defined(RCC_CCIPR_UART5SEL)
|
||||
if (UARTxSource == LL_RCC_UART5_CLKSOURCE)
|
||||
{
|
||||
/* UART5CLK clock frequency */
|
||||
switch (LL_RCC_GetUARTClockSource(UARTxSource))
|
||||
{
|
||||
case LL_RCC_UART5_CLKSOURCE_SYSCLK: /* UART5 Clock is System Clock */
|
||||
uart_frequency = RCC_GetSystemClockFreq();
|
||||
break;
|
||||
|
||||
case LL_RCC_UART5_CLKSOURCE_HSI: /* UART5 Clock is HSI Osc. */
|
||||
if (LL_RCC_HSI_IsReady() != 0U)
|
||||
{
|
||||
uart_frequency = HSI_VALUE;
|
||||
}
|
||||
break;
|
||||
|
||||
case LL_RCC_UART5_CLKSOURCE_LSE: /* UART5 Clock is LSE Osc. */
|
||||
if (LL_RCC_LSE_IsReady() != 0U)
|
||||
{
|
||||
uart_frequency = LSE_VALUE;
|
||||
}
|
||||
break;
|
||||
|
||||
case LL_RCC_UART5_CLKSOURCE_PCLK1: /* UART5 Clock is PCLK1 */
|
||||
uart_frequency = RCC_GetPCLK1ClockFreq(RCC_GetHCLKClockFreq(RCC_GetSystemClockFreq()));
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif /* RCC_CCIPR_UART5SEL */
|
||||
|
||||
return uart_frequency;
|
||||
}
|
||||
#endif /* RCC_CCIPR_UART4SEL || RCC_CCIPR_UART5SEL */
|
||||
|
||||
/**
|
||||
* @brief Return I2Cx clock frequency
|
||||
* @param I2CxSource This parameter can be one of the following values:
|
||||
* @arg @ref LL_RCC_I2C1_CLKSOURCE
|
||||
* @arg @ref LL_RCC_I2C2_CLKSOURCE (*)
|
||||
* @arg @ref LL_RCC_I2C3_CLKSOURCE
|
||||
* @arg @ref LL_RCC_I2C4_CLKSOURCE (*)
|
||||
*
|
||||
* (*) value not defined in all devices.
|
||||
* @retval I2C clock frequency (in Hz)
|
||||
* - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that HSI oscillator is not ready
|
||||
*/
|
||||
uint32_t LL_RCC_GetI2CClockFreq(uint32_t I2CxSource)
|
||||
{
|
||||
uint32_t i2c_frequency = LL_RCC_PERIPH_FREQUENCY_NO;
|
||||
|
||||
/* Check parameter */
|
||||
assert_param(IS_LL_RCC_I2C_CLKSOURCE(I2CxSource));
|
||||
|
||||
if (I2CxSource == LL_RCC_I2C1_CLKSOURCE)
|
||||
{
|
||||
/* I2C1 CLK clock frequency */
|
||||
switch (LL_RCC_GetI2CClockSource(I2CxSource))
|
||||
{
|
||||
case LL_RCC_I2C1_CLKSOURCE_SYSCLK: /* I2C1 Clock is System Clock */
|
||||
i2c_frequency = RCC_GetSystemClockFreq();
|
||||
break;
|
||||
|
||||
case LL_RCC_I2C1_CLKSOURCE_HSI: /* I2C1 Clock is HSI Osc. */
|
||||
if (LL_RCC_HSI_IsReady() != 0U)
|
||||
{
|
||||
i2c_frequency = HSI_VALUE;
|
||||
}
|
||||
break;
|
||||
|
||||
case LL_RCC_I2C1_CLKSOURCE_PCLK1: /* I2C1 Clock is PCLK1 */
|
||||
i2c_frequency = RCC_GetPCLK1ClockFreq(RCC_GetHCLKClockFreq(RCC_GetSystemClockFreq()));
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
#if defined(RCC_CCIPR_I2C2SEL)
|
||||
else if (I2CxSource == LL_RCC_I2C2_CLKSOURCE)
|
||||
{
|
||||
/* I2C2 CLK clock frequency */
|
||||
switch (LL_RCC_GetI2CClockSource(I2CxSource))
|
||||
{
|
||||
case LL_RCC_I2C2_CLKSOURCE_SYSCLK: /* I2C2 Clock is System Clock */
|
||||
i2c_frequency = RCC_GetSystemClockFreq();
|
||||
break;
|
||||
|
||||
case LL_RCC_I2C2_CLKSOURCE_HSI: /* I2C2 Clock is HSI Osc. */
|
||||
if (LL_RCC_HSI_IsReady() != 0U)
|
||||
{
|
||||
i2c_frequency = HSI_VALUE;
|
||||
}
|
||||
break;
|
||||
|
||||
case LL_RCC_I2C2_CLKSOURCE_PCLK1: /* I2C2 Clock is PCLK1 */
|
||||
i2c_frequency = RCC_GetPCLK1ClockFreq(RCC_GetHCLKClockFreq(RCC_GetSystemClockFreq()));
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif /*RCC_CCIPR_I2C2SEL*/
|
||||
else
|
||||
{
|
||||
if (I2CxSource == LL_RCC_I2C3_CLKSOURCE)
|
||||
{
|
||||
/* I2C3 CLK clock frequency */
|
||||
switch (LL_RCC_GetI2CClockSource(I2CxSource))
|
||||
{
|
||||
case LL_RCC_I2C3_CLKSOURCE_SYSCLK: /* I2C3 Clock is System Clock */
|
||||
i2c_frequency = RCC_GetSystemClockFreq();
|
||||
break;
|
||||
|
||||
case LL_RCC_I2C3_CLKSOURCE_HSI: /* I2C3 Clock is HSI Osc. */
|
||||
if (LL_RCC_HSI_IsReady() != 0U)
|
||||
{
|
||||
i2c_frequency = HSI_VALUE;
|
||||
}
|
||||
break;
|
||||
|
||||
case LL_RCC_I2C3_CLKSOURCE_PCLK1: /* I2C3 Clock is PCLK1 */
|
||||
i2c_frequency = RCC_GetPCLK1ClockFreq(RCC_GetHCLKClockFreq(RCC_GetSystemClockFreq()));
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
#if defined(RCC_CCIPR2_I2C4SEL)
|
||||
else
|
||||
{
|
||||
if (I2CxSource == LL_RCC_I2C4_CLKSOURCE)
|
||||
{
|
||||
/* I2C4 CLK clock frequency */
|
||||
switch (LL_RCC_GetI2CClockSource(I2CxSource))
|
||||
{
|
||||
case LL_RCC_I2C4_CLKSOURCE_SYSCLK: /* I2C4 Clock is System Clock */
|
||||
i2c_frequency = RCC_GetSystemClockFreq();
|
||||
break;
|
||||
|
||||
case LL_RCC_I2C4_CLKSOURCE_HSI: /* I2C4 Clock is HSI Osc. */
|
||||
if (LL_RCC_HSI_IsReady() != 0U)
|
||||
{
|
||||
i2c_frequency = HSI_VALUE;
|
||||
}
|
||||
break;
|
||||
|
||||
case LL_RCC_I2C4_CLKSOURCE_PCLK1: /* I2C4 Clock is PCLK1 */
|
||||
i2c_frequency = RCC_GetPCLK1ClockFreq(RCC_GetHCLKClockFreq(RCC_GetSystemClockFreq()));
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /*RCC_CCIPR2_I2C4SEL*/
|
||||
}
|
||||
|
||||
return i2c_frequency;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Return LPUARTx clock frequency
|
||||
* @param LPUARTxSource This parameter can be one of the following values:
|
||||
* @arg @ref LL_RCC_LPUART1_CLKSOURCE
|
||||
* @retval LPUART clock frequency (in Hz)
|
||||
* - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator (HSI or LSE) is not ready
|
||||
*/
|
||||
uint32_t LL_RCC_GetLPUARTClockFreq(uint32_t LPUARTxSource)
|
||||
{
|
||||
uint32_t lpuart_frequency = LL_RCC_PERIPH_FREQUENCY_NO;
|
||||
|
||||
/* Check parameter */
|
||||
assert_param(IS_LL_RCC_LPUART_CLKSOURCE(LPUARTxSource));
|
||||
|
||||
/* LPUART1CLK clock frequency */
|
||||
switch (LL_RCC_GetLPUARTClockSource(LPUARTxSource))
|
||||
{
|
||||
case LL_RCC_LPUART1_CLKSOURCE_SYSCLK: /* LPUART1 Clock is System Clock */
|
||||
lpuart_frequency = RCC_GetSystemClockFreq();
|
||||
break;
|
||||
|
||||
case LL_RCC_LPUART1_CLKSOURCE_HSI: /* LPUART1 Clock is HSI Osc. */
|
||||
if (LL_RCC_HSI_IsReady() != 0U)
|
||||
{
|
||||
lpuart_frequency = HSI_VALUE;
|
||||
}
|
||||
break;
|
||||
|
||||
case LL_RCC_LPUART1_CLKSOURCE_LSE: /* LPUART1 Clock is LSE Osc. */
|
||||
if (LL_RCC_LSE_IsReady() != 0U)
|
||||
{
|
||||
lpuart_frequency = LSE_VALUE;
|
||||
}
|
||||
break;
|
||||
|
||||
case LL_RCC_LPUART1_CLKSOURCE_PCLK1: /* LPUART1 Clock is PCLK1 */
|
||||
lpuart_frequency = RCC_GetPCLK1ClockFreq(RCC_GetHCLKClockFreq(RCC_GetSystemClockFreq()));
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return lpuart_frequency;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return LPTIMx clock frequency
|
||||
* @param LPTIMxSource This parameter can be one of the following values:
|
||||
* @arg @ref LL_RCC_LPTIM1_CLKSOURCE
|
||||
* @arg @ref LL_RCC_LPTIM2_CLKSOURCE
|
||||
* @retval LPTIM clock frequency (in Hz)
|
||||
* - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator (HSI, LSI or LSE) is not ready
|
||||
*/
|
||||
uint32_t LL_RCC_GetLPTIMClockFreq(uint32_t LPTIMxSource)
|
||||
{
|
||||
uint32_t lptim_frequency = LL_RCC_PERIPH_FREQUENCY_NO;
|
||||
|
||||
/* Check parameter */
|
||||
assert_param(IS_LL_RCC_LPTIM_CLKSOURCE(LPTIMxSource));
|
||||
|
||||
if (LPTIMxSource == LL_RCC_LPTIM1_CLKSOURCE)
|
||||
{
|
||||
/* LPTIM1CLK clock frequency */
|
||||
switch (LL_RCC_GetLPTIMClockSource(LPTIMxSource))
|
||||
{
|
||||
case LL_RCC_LPTIM1_CLKSOURCE_LSI: /* LPTIM1 Clock is LSI Osc. */
|
||||
if (LL_RCC_LSI_IsReady() != 0U)
|
||||
{
|
||||
#if defined(RCC_CSR_LSIPREDIV)
|
||||
if (LL_RCC_LSI_GetPrediv() == LL_RCC_LSI_PREDIV_128)
|
||||
{
|
||||
lptim_frequency = LSI_VALUE / 128U;
|
||||
}
|
||||
else
|
||||
#endif /* RCC_CSR_LSIPREDIV */
|
||||
{
|
||||
lptim_frequency = LSI_VALUE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case LL_RCC_LPTIM1_CLKSOURCE_HSI: /* LPTIM1 Clock is HSI Osc. */
|
||||
if (LL_RCC_HSI_IsReady() != 0U)
|
||||
{
|
||||
lptim_frequency = HSI_VALUE;
|
||||
}
|
||||
break;
|
||||
|
||||
case LL_RCC_LPTIM1_CLKSOURCE_LSE: /* LPTIM1 Clock is LSE Osc. */
|
||||
if (LL_RCC_LSE_IsReady() != 0U)
|
||||
{
|
||||
lptim_frequency = LSE_VALUE;
|
||||
}
|
||||
break;
|
||||
|
||||
case LL_RCC_LPTIM1_CLKSOURCE_PCLK1: /* LPTIM1 Clock is PCLK1 */
|
||||
lptim_frequency = RCC_GetPCLK1ClockFreq(RCC_GetHCLKClockFreq(RCC_GetSystemClockFreq()));
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (LPTIMxSource == LL_RCC_LPTIM2_CLKSOURCE)
|
||||
{
|
||||
/* LPTIM2CLK clock frequency */
|
||||
switch (LL_RCC_GetLPTIMClockSource(LPTIMxSource))
|
||||
{
|
||||
case LL_RCC_LPTIM2_CLKSOURCE_LSI: /* LPTIM2 Clock is LSI Osc. */
|
||||
if (LL_RCC_LSI_IsReady() != 0U)
|
||||
{
|
||||
#if defined(RCC_CSR_LSIPREDIV)
|
||||
if (LL_RCC_LSI_GetPrediv() == LL_RCC_LSI_PREDIV_128)
|
||||
{
|
||||
lptim_frequency = LSI_VALUE / 128U;
|
||||
}
|
||||
else
|
||||
#endif /* RCC_CSR_LSIPREDIV */
|
||||
{
|
||||
lptim_frequency = LSI_VALUE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case LL_RCC_LPTIM2_CLKSOURCE_HSI: /* LPTIM2 Clock is HSI Osc. */
|
||||
if (LL_RCC_HSI_IsReady() != 0U)
|
||||
{
|
||||
lptim_frequency = HSI_VALUE;
|
||||
}
|
||||
break;
|
||||
|
||||
case LL_RCC_LPTIM2_CLKSOURCE_LSE: /* LPTIM2 Clock is LSE Osc. */
|
||||
if (LL_RCC_LSE_IsReady() != 0U)
|
||||
{
|
||||
lptim_frequency = LSE_VALUE;
|
||||
}
|
||||
break;
|
||||
|
||||
case LL_RCC_LPTIM2_CLKSOURCE_PCLK1: /* LPTIM2 Clock is PCLK1 */
|
||||
lptim_frequency = RCC_GetPCLK1ClockFreq(RCC_GetHCLKClockFreq(RCC_GetSystemClockFreq()));
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return lptim_frequency;
|
||||
}
|
||||
|
||||
#if defined(RCC_CCIPR_SAI1SEL) || defined(RCC_CCIPR_SAI2SEL) || defined(RCC_CCIPR2_SAI1SEL) || defined(RCC_CCIPR2_SAI2SEL)
|
||||
/**
|
||||
* @brief Return SAIx clock frequency
|
||||
* @param SAIxSource This parameter can be one of the following values:
|
||||
* @arg @ref LL_RCC_SAI1_CLKSOURCE
|
||||
* @arg @ref LL_RCC_SAI2_CLKSOURCE (*)
|
||||
*
|
||||
* (*) value not defined in all devices.
|
||||
* @retval SAI clock frequency (in Hz)
|
||||
* - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that PLL is not ready
|
||||
|
||||
*/
|
||||
uint32_t LL_RCC_GetSAIClockFreq(uint32_t SAIxSource)
|
||||
{
|
||||
uint32_t sai_frequency = LL_RCC_PERIPH_FREQUENCY_NO;
|
||||
|
||||
/* Check parameter */
|
||||
assert_param(IS_LL_RCC_SAI_CLKSOURCE(SAIxSource));
|
||||
|
||||
if (SAIxSource == LL_RCC_SAI1_CLKSOURCE)
|
||||
{
|
||||
/* SAI1CLK clock frequency */
|
||||
switch (LL_RCC_GetSAIClockSource(SAIxSource))
|
||||
{
|
||||
case LL_RCC_SAI1_CLKSOURCE_PLLSAI1: /* PLLSAI1 clock used as SAI1 clock source */
|
||||
if (LL_RCC_PLLSAI1_IsReady() != 0U)
|
||||
{
|
||||
if (LL_RCC_PLLSAI1_IsEnabledDomain_SAI() != 0U)
|
||||
{
|
||||
sai_frequency = RCC_PLLSAI1_GetFreqDomain_SAI();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
#if defined(RCC_PLLSAI2_SUPPORT)
|
||||
case LL_RCC_SAI1_CLKSOURCE_PLLSAI2: /* PLLSAI2 clock used as SAI1 clock source */
|
||||
if (LL_RCC_PLLSAI2_IsReady() != 0U)
|
||||
{
|
||||
if (LL_RCC_PLLSAI2_IsEnabledDomain_SAI() != 0U)
|
||||
{
|
||||
sai_frequency = RCC_PLLSAI2_GetFreqDomain_SAI();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
#endif /* RCC_PLLSAI2_SUPPORT */
|
||||
case LL_RCC_SAI1_CLKSOURCE_PLL: /* PLL clock used as SAI1 clock source */
|
||||
if (LL_RCC_PLL_IsReady() != 0U)
|
||||
{
|
||||
if (LL_RCC_PLL_IsEnabledDomain_SAI() != 0U)
|
||||
{
|
||||
sai_frequency = RCC_PLL_GetFreqDomain_SAI();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case LL_RCC_SAI1_CLKSOURCE_PIN: /* External input clock used as SAI1 clock source */
|
||||
sai_frequency = EXTERNAL_SAI1_CLOCK_VALUE;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#if defined(RCC_CCIPR_SAI2SEL) || defined(RCC_CCIPR2_SAI2SEL)
|
||||
if (SAIxSource == LL_RCC_SAI2_CLKSOURCE)
|
||||
{
|
||||
/* SAI2CLK clock frequency */
|
||||
switch (LL_RCC_GetSAIClockSource(SAIxSource))
|
||||
{
|
||||
case LL_RCC_SAI2_CLKSOURCE_PLLSAI1: /* PLLSAI1 clock used as SAI2 clock source */
|
||||
if (LL_RCC_PLLSAI1_IsReady() != 0U)
|
||||
{
|
||||
if (LL_RCC_PLLSAI1_IsEnabledDomain_SAI() != 0U)
|
||||
{
|
||||
sai_frequency = RCC_PLLSAI1_GetFreqDomain_SAI();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
#if defined(RCC_PLLSAI2_SUPPORT)
|
||||
case LL_RCC_SAI2_CLKSOURCE_PLLSAI2: /* PLLSAI2 clock used as SAI2 clock source */
|
||||
if (LL_RCC_PLLSAI2_IsReady() != 0U)
|
||||
{
|
||||
if (LL_RCC_PLLSAI2_IsEnabledDomain_SAI() != 0U)
|
||||
{
|
||||
sai_frequency = RCC_PLLSAI2_GetFreqDomain_SAI();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
#endif /* RCC_PLLSAI2_SUPPORT */
|
||||
case LL_RCC_SAI2_CLKSOURCE_PLL: /* PLL clock used as SAI2 clock source */
|
||||
if (LL_RCC_PLL_IsReady() != 0U)
|
||||
{
|
||||
if (LL_RCC_PLL_IsEnabledDomain_SAI() != 0U)
|
||||
{
|
||||
sai_frequency = RCC_PLL_GetFreqDomain_SAI();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case LL_RCC_SAI2_CLKSOURCE_PIN: /* External input clock used as SAI2 clock source */
|
||||
sai_frequency = EXTERNAL_SAI2_CLOCK_VALUE;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif /* RCC_CCIPR_SAI2SEL || RCC_CCIPR2_SAI2SEL */
|
||||
}
|
||||
|
||||
return sai_frequency;
|
||||
}
|
||||
#endif /* RCC_CCIPR_SAI1SEL || RCC_CCIPR_SAI2SEL || RCC_CCIPR2_SAI1SEL || RCC_CCIPR2_SAI2SEL*/
|
||||
|
||||
#if defined(SDMMC1)
|
||||
#if defined(RCC_CCIPR2_SDMMCSEL)
|
||||
/**
|
||||
* @brief Return SDMMCx kernel clock frequency
|
||||
* @param SDMMCxSource This parameter can be one of the following values:
|
||||
* @arg @ref LL_RCC_SDMMC1_KERNELCLKSOURCE
|
||||
* @retval SDMMC clock frequency (in Hz)
|
||||
* - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator (MSI) or PLL is not ready
|
||||
* - @ref LL_RCC_PERIPH_FREQUENCY_NA indicates that no clock source selected
|
||||
*/
|
||||
uint32_t LL_RCC_GetSDMMCKernelClockFreq(uint32_t SDMMCxSource)
|
||||
{
|
||||
uint32_t sdmmc_frequency = LL_RCC_PERIPH_FREQUENCY_NO;
|
||||
|
||||
/* Check parameter */
|
||||
assert_param(IS_LL_RCC_SDMMC_KERNELCLKSOURCE(SDMMCxSource));
|
||||
|
||||
/* SDMMC1CLK kernel clock frequency */
|
||||
switch (LL_RCC_GetSDMMCKernelClockSource(SDMMCxSource))
|
||||
{
|
||||
case LL_RCC_SDMMC1_KERNELCLKSOURCE_48CLK: /* 48MHz clock from internal multiplexor used as SDMMC1 clock source */
|
||||
sdmmc_frequency = LL_RCC_GetSDMMCClockFreq(LL_RCC_SDMMC1_CLKSOURCE);
|
||||
break;
|
||||
|
||||
case LL_RCC_SDMMC1_KERNELCLKSOURCE_PLLP: /* PLL "P" output (PLLSAI3CLK) clock used as SDMMC1 clock source */
|
||||
if (LL_RCC_PLL_IsReady() != 0U)
|
||||
{
|
||||
if (LL_RCC_PLL_IsEnabledDomain_SAI() != 0U)
|
||||
{
|
||||
sdmmc_frequency = RCC_PLL_GetFreqDomain_SAI();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
sdmmc_frequency = LL_RCC_PERIPH_FREQUENCY_NA;
|
||||
break;
|
||||
}
|
||||
|
||||
return sdmmc_frequency;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Return SDMMCx clock frequency
|
||||
* @param SDMMCxSource This parameter can be one of the following values:
|
||||
* @arg @ref LL_RCC_SDMMC1_CLKSOURCE
|
||||
* @retval SDMMC clock frequency (in Hz)
|
||||
* - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator (MSI) or PLL is not ready
|
||||
* - @ref LL_RCC_PERIPH_FREQUENCY_NA indicates that no clock source selected
|
||||
*/
|
||||
uint32_t LL_RCC_GetSDMMCClockFreq(uint32_t SDMMCxSource)
|
||||
{
|
||||
uint32_t sdmmc_frequency = LL_RCC_PERIPH_FREQUENCY_NO;
|
||||
|
||||
/* Check parameter */
|
||||
assert_param(IS_LL_RCC_SDMMC_CLKSOURCE(SDMMCxSource));
|
||||
|
||||
/* SDMMC1CLK clock frequency */
|
||||
switch (LL_RCC_GetSDMMCClockSource(SDMMCxSource))
|
||||
{
|
||||
#if defined(LL_RCC_SDMMC1_CLKSOURCE_PLLSAI1)
|
||||
case LL_RCC_SDMMC1_CLKSOURCE_PLLSAI1: /* PLLSAI1 clock used as SDMMC1 clock source */
|
||||
if (LL_RCC_PLLSAI1_IsReady() != 0U)
|
||||
{
|
||||
if (LL_RCC_PLLSAI1_IsEnabledDomain_48M() != 0U)
|
||||
{
|
||||
sdmmc_frequency = RCC_PLLSAI1_GetFreqDomain_48M();
|
||||
}
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
case LL_RCC_SDMMC1_CLKSOURCE_PLL: /* PLL clock used as SDMMC1 clock source */
|
||||
if (LL_RCC_PLL_IsReady() != 0U)
|
||||
{
|
||||
if (LL_RCC_PLL_IsEnabledDomain_48M() != 0U)
|
||||
{
|
||||
sdmmc_frequency = RCC_PLL_GetFreqDomain_48M();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
#if defined(LL_RCC_SDMMC1_CLKSOURCE_MSI)
|
||||
case LL_RCC_SDMMC1_CLKSOURCE_MSI: /* MSI clock used as SDMMC1 clock source */
|
||||
if (LL_RCC_MSI_IsReady() != 0U)
|
||||
{
|
||||
sdmmc_frequency = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_IsEnabledRangeSelect(),
|
||||
((LL_RCC_MSI_IsEnabledRangeSelect() != 0U) ?
|
||||
LL_RCC_MSI_GetRange() :
|
||||
LL_RCC_MSI_GetRangeAfterStandby()));
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if defined(RCC_HSI48_SUPPORT)
|
||||
case LL_RCC_SDMMC1_CLKSOURCE_HSI48: /* HSI48 used as SDMMC1 clock source */
|
||||
if (LL_RCC_HSI48_IsReady() != 0U)
|
||||
{
|
||||
sdmmc_frequency = HSI48_VALUE;
|
||||
}
|
||||
break;
|
||||
#else
|
||||
case LL_RCC_SDMMC1_CLKSOURCE_NONE: /* No clock used as SDMMC1 clock source */
|
||||
#endif
|
||||
default:
|
||||
sdmmc_frequency = LL_RCC_PERIPH_FREQUENCY_NA;
|
||||
break;
|
||||
}
|
||||
|
||||
return sdmmc_frequency;
|
||||
}
|
||||
#endif /* SDMMC1 */
|
||||
|
||||
/**
|
||||
* @brief Return RNGx clock frequency
|
||||
* @param RNGxSource This parameter can be one of the following values:
|
||||
* @arg @ref LL_RCC_RNG_CLKSOURCE
|
||||
* @retval RNG clock frequency (in Hz)
|
||||
* - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator (MSI) or PLL is not ready
|
||||
* - @ref LL_RCC_PERIPH_FREQUENCY_NA indicates that no clock source selected
|
||||
*/
|
||||
uint32_t LL_RCC_GetRNGClockFreq(uint32_t RNGxSource)
|
||||
{
|
||||
uint32_t rng_frequency = LL_RCC_PERIPH_FREQUENCY_NO;
|
||||
|
||||
/* Check parameter */
|
||||
assert_param(IS_LL_RCC_RNG_CLKSOURCE(RNGxSource));
|
||||
|
||||
/* RNGCLK clock frequency */
|
||||
switch (LL_RCC_GetRNGClockSource(RNGxSource))
|
||||
{
|
||||
#if defined(RCC_PLLSAI1_SUPPORT)
|
||||
case LL_RCC_RNG_CLKSOURCE_PLLSAI1: /* PLLSAI1 clock used as RNG clock source */
|
||||
if (LL_RCC_PLLSAI1_IsReady() != 0U)
|
||||
{
|
||||
if (LL_RCC_PLLSAI1_IsEnabledDomain_48M() !=0U)
|
||||
{
|
||||
rng_frequency = RCC_PLLSAI1_GetFreqDomain_48M();
|
||||
}
|
||||
}
|
||||
break;
|
||||
#endif /* RCC_PLLSAI1_SUPPORT */
|
||||
|
||||
case LL_RCC_RNG_CLKSOURCE_PLL: /* PLL clock used as RNG clock source */
|
||||
if (LL_RCC_PLL_IsReady() != 0U)
|
||||
{
|
||||
if (LL_RCC_PLL_IsEnabledDomain_48M() != 0U)
|
||||
{
|
||||
rng_frequency = RCC_PLL_GetFreqDomain_48M();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case LL_RCC_RNG_CLKSOURCE_MSI: /* MSI clock used as RNG clock source */
|
||||
if (LL_RCC_MSI_IsReady() != 0U)
|
||||
{
|
||||
rng_frequency = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_IsEnabledRangeSelect(),
|
||||
((LL_RCC_MSI_IsEnabledRangeSelect() != 0U) ?
|
||||
LL_RCC_MSI_GetRange() :
|
||||
LL_RCC_MSI_GetRangeAfterStandby()));
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
#if defined(RCC_HSI48_SUPPORT)
|
||||
case LL_RCC_RNG_CLKSOURCE_HSI48: /* HSI48 used as RNG clock source */
|
||||
if (LL_RCC_HSI48_IsReady() != 0U)
|
||||
{
|
||||
rng_frequency = HSI48_VALUE;
|
||||
}
|
||||
break;
|
||||
#else
|
||||
case LL_RCC_RNG_CLKSOURCE_NONE: /* No clock used as RNG clock source */
|
||||
#endif
|
||||
default:
|
||||
rng_frequency = LL_RCC_PERIPH_FREQUENCY_NA;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
return rng_frequency;
|
||||
}
|
||||
|
||||
|
||||
#if defined(USB_OTG_FS)||defined(USB)
|
||||
/**
|
||||
* @brief Return USBx clock frequency
|
||||
* @param USBxSource This parameter can be one of the following values:
|
||||
* @arg @ref LL_RCC_USB_CLKSOURCE
|
||||
* @retval USB clock frequency (in Hz)
|
||||
* - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator (MSI) or PLL is not ready
|
||||
* - @ref LL_RCC_PERIPH_FREQUENCY_NA indicates that no clock source selected
|
||||
*/
|
||||
uint32_t LL_RCC_GetUSBClockFreq(uint32_t USBxSource)
|
||||
{
|
||||
uint32_t usb_frequency = LL_RCC_PERIPH_FREQUENCY_NO;
|
||||
|
||||
/* Check parameter */
|
||||
assert_param(IS_LL_RCC_USB_CLKSOURCE(USBxSource));
|
||||
|
||||
/* USBCLK clock frequency */
|
||||
switch (LL_RCC_GetUSBClockSource(USBxSource))
|
||||
{
|
||||
#if defined(RCC_PLLSAI1_SUPPORT)
|
||||
case LL_RCC_USB_CLKSOURCE_PLLSAI1: /* PLLSAI1 clock used as USB clock source */
|
||||
if (LL_RCC_PLLSAI1_IsReady() != 0U)
|
||||
{
|
||||
if (LL_RCC_PLLSAI1_IsEnabledDomain_48M() != 0U)
|
||||
{
|
||||
usb_frequency = RCC_PLLSAI1_GetFreqDomain_48M();
|
||||
}
|
||||
}
|
||||
break;
|
||||
#endif /* RCC_PLLSAI1_SUPPORT */
|
||||
|
||||
case LL_RCC_USB_CLKSOURCE_PLL: /* PLL clock used as USB clock source */
|
||||
if (LL_RCC_PLL_IsReady() != 0U)
|
||||
{
|
||||
if (LL_RCC_PLL_IsEnabledDomain_48M() != 0U)
|
||||
{
|
||||
usb_frequency = RCC_PLL_GetFreqDomain_48M();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case LL_RCC_USB_CLKSOURCE_MSI: /* MSI clock used as USB clock source */
|
||||
if (LL_RCC_MSI_IsReady() != 0U)
|
||||
{
|
||||
usb_frequency = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_IsEnabledRangeSelect(),
|
||||
((LL_RCC_MSI_IsEnabledRangeSelect() != 0U) ?
|
||||
LL_RCC_MSI_GetRange() :
|
||||
LL_RCC_MSI_GetRangeAfterStandby()));
|
||||
}
|
||||
break;
|
||||
|
||||
#if defined(RCC_HSI48_SUPPORT)
|
||||
case LL_RCC_USB_CLKSOURCE_HSI48: /* HSI48 used as USB clock source */
|
||||
if (LL_RCC_HSI48_IsReady() != 0U)
|
||||
{
|
||||
usb_frequency = HSI48_VALUE;
|
||||
}
|
||||
break;
|
||||
#else
|
||||
case LL_RCC_USB_CLKSOURCE_NONE: /* No clock used as USB clock source */
|
||||
#endif
|
||||
default:
|
||||
usb_frequency = LL_RCC_PERIPH_FREQUENCY_NA;
|
||||
break;
|
||||
}
|
||||
|
||||
return usb_frequency;
|
||||
}
|
||||
#endif /* USB_OTG_FS || USB */
|
||||
|
||||
/**
|
||||
* @brief Return ADCx clock frequency
|
||||
* @param ADCxSource This parameter can be one of the following values:
|
||||
* @arg @ref LL_RCC_ADC_CLKSOURCE
|
||||
* @retval ADC clock frequency (in Hz)
|
||||
* - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator (MSI) or PLL is not ready
|
||||
* - @ref LL_RCC_PERIPH_FREQUENCY_NA indicates that no clock source selected
|
||||
*/
|
||||
uint32_t LL_RCC_GetADCClockFreq(uint32_t ADCxSource)
|
||||
{
|
||||
uint32_t adc_frequency = LL_RCC_PERIPH_FREQUENCY_NO;
|
||||
|
||||
/* Check parameter */
|
||||
assert_param(IS_LL_RCC_ADC_CLKSOURCE(ADCxSource));
|
||||
|
||||
/* ADCCLK clock frequency */
|
||||
switch (LL_RCC_GetADCClockSource(ADCxSource))
|
||||
{
|
||||
#if defined(RCC_PLLSAI1_SUPPORT)
|
||||
case LL_RCC_ADC_CLKSOURCE_PLLSAI1: /* PLLSAI1 clock used as ADC clock source */
|
||||
if (LL_RCC_PLLSAI1_IsReady() != 0U)
|
||||
{
|
||||
if (LL_RCC_PLLSAI1_IsEnabledDomain_ADC() != 0U)
|
||||
{
|
||||
adc_frequency = RCC_PLLSAI1_GetFreqDomain_ADC();
|
||||
}
|
||||
}
|
||||
break;
|
||||
#endif /* RCC_PLLSAI1_SUPPORT */
|
||||
|
||||
#if defined(RCC_PLLSAI2_SUPPORT) && defined(LL_RCC_ADC_CLKSOURCE_PLLSAI2)
|
||||
case LL_RCC_ADC_CLKSOURCE_PLLSAI2: /* PLLSAI2 clock used as ADC clock source */
|
||||
if (LL_RCC_PLLSAI2_IsReady() != 0U)
|
||||
{
|
||||
if (LL_RCC_PLLSAI2_IsEnabledDomain_ADC() != 0U)
|
||||
{
|
||||
adc_frequency = RCC_PLLSAI2_GetFreqDomain_ADC();
|
||||
}
|
||||
}
|
||||
break;
|
||||
#endif /* RCC_PLLSAI2_SUPPORT && LL_RCC_ADC_CLKSOURCE_PLLSAI2 */
|
||||
|
||||
case LL_RCC_ADC_CLKSOURCE_SYSCLK: /* SYSCLK clock used as ADC clock source */
|
||||
adc_frequency = RCC_GetSystemClockFreq();
|
||||
break;
|
||||
|
||||
case LL_RCC_ADC_CLKSOURCE_NONE: /* No clock used as ADC clock source */
|
||||
default:
|
||||
adc_frequency = LL_RCC_PERIPH_FREQUENCY_NA;
|
||||
break;
|
||||
}
|
||||
|
||||
return adc_frequency;
|
||||
}
|
||||
|
||||
#if defined(SWPMI1)
|
||||
/**
|
||||
* @brief Return SWPMIx clock frequency
|
||||
* @param SWPMIxSource This parameter can be one of the following values:
|
||||
* @arg @ref LL_RCC_SWPMI1_CLKSOURCE
|
||||
* @retval SWPMI clock frequency (in Hz)
|
||||
* - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator (HSI) is not ready
|
||||
*/
|
||||
uint32_t LL_RCC_GetSWPMIClockFreq(uint32_t SWPMIxSource)
|
||||
{
|
||||
uint32_t swpmi_frequency = LL_RCC_PERIPH_FREQUENCY_NO;
|
||||
|
||||
/* Check parameter */
|
||||
assert_param(IS_LL_RCC_SWPMI_CLKSOURCE(SWPMIxSource));
|
||||
|
||||
/* SWPMI1CLK clock frequency */
|
||||
switch (LL_RCC_GetSWPMIClockSource(SWPMIxSource))
|
||||
{
|
||||
case LL_RCC_SWPMI1_CLKSOURCE_HSI: /* SWPMI1 Clock is HSI Osc. */
|
||||
if (LL_RCC_HSI_IsReady())
|
||||
{
|
||||
swpmi_frequency = HSI_VALUE;
|
||||
}
|
||||
break;
|
||||
|
||||
case LL_RCC_SWPMI1_CLKSOURCE_PCLK1: /* SWPMI1 Clock is PCLK1 */
|
||||
swpmi_frequency = RCC_GetPCLK1ClockFreq(RCC_GetHCLKClockFreq(RCC_GetSystemClockFreq()));
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return swpmi_frequency;
|
||||
}
|
||||
#endif /* SWPMI1 */
|
||||
|
||||
#if defined(DFSDM1_Channel0)
|
||||
/**
|
||||
* @brief Return DFSDMx clock frequency
|
||||
* @param DFSDMxSource This parameter can be one of the following values:
|
||||
* @arg @ref LL_RCC_DFSDM1_CLKSOURCE
|
||||
* @retval DFSDM clock frequency (in Hz)
|
||||
*/
|
||||
uint32_t LL_RCC_GetDFSDMClockFreq(uint32_t DFSDMxSource)
|
||||
{
|
||||
uint32_t dfsdm_frequency = LL_RCC_PERIPH_FREQUENCY_NO;
|
||||
|
||||
/* Check parameter */
|
||||
assert_param(IS_LL_RCC_DFSDM_CLKSOURCE(DFSDMxSource));
|
||||
|
||||
/* DFSDM1CLK clock frequency */
|
||||
switch (LL_RCC_GetDFSDMClockSource(DFSDMxSource))
|
||||
{
|
||||
case LL_RCC_DFSDM1_CLKSOURCE_SYSCLK: /* DFSDM1 Clock is SYSCLK */
|
||||
dfsdm_frequency = RCC_GetSystemClockFreq();
|
||||
break;
|
||||
|
||||
case LL_RCC_DFSDM1_CLKSOURCE_PCLK2: /* DFSDM1 Clock is PCLK2 */
|
||||
dfsdm_frequency = RCC_GetPCLK2ClockFreq(RCC_GetHCLKClockFreq(RCC_GetSystemClockFreq()));
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return dfsdm_frequency;
|
||||
}
|
||||
|
||||
#if defined(RCC_CCIPR2_DFSDM1SEL)
|
||||
/**
|
||||
* @brief Return DFSDMx Audio clock frequency
|
||||
* @param DFSDMxSource This parameter can be one of the following values:
|
||||
* @arg @ref LL_RCC_DFSDM1_AUDIO_CLKSOURCE
|
||||
* @retval DFSDM clock frequency (in Hz)
|
||||
* - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator is not ready
|
||||
*/
|
||||
uint32_t LL_RCC_GetDFSDMAudioClockFreq(uint32_t DFSDMxSource)
|
||||
{
|
||||
uint32_t dfsdm_frequency = LL_RCC_PERIPH_FREQUENCY_NO;
|
||||
|
||||
/* Check parameter */
|
||||
assert_param(IS_LL_RCC_DFSDM_AUDIO_CLKSOURCE(DFSDMxSource));
|
||||
|
||||
/* DFSDM1CLK clock frequency */
|
||||
switch (LL_RCC_GetDFSDMAudioClockSource(DFSDMxSource))
|
||||
{
|
||||
case LL_RCC_DFSDM1_AUDIO_CLKSOURCE_SAI1: /* SAI1 clock used as DFSDM1 audio clock */
|
||||
dfsdm_frequency = LL_RCC_GetSAIClockFreq(LL_RCC_SAI1_CLKSOURCE);
|
||||
break;
|
||||
|
||||
case LL_RCC_DFSDM1_AUDIO_CLKSOURCE_MSI: /* MSI clock used as DFSDM1 audio clock */
|
||||
if (LL_RCC_MSI_IsReady() != 0U)
|
||||
{
|
||||
dfsdm_frequency = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_IsEnabledRangeSelect(),
|
||||
((LL_RCC_MSI_IsEnabledRangeSelect() != 0U) ?
|
||||
LL_RCC_MSI_GetRange() :
|
||||
LL_RCC_MSI_GetRangeAfterStandby()));
|
||||
}
|
||||
break;
|
||||
|
||||
case LL_RCC_DFSDM1_AUDIO_CLKSOURCE_HSI: /* HSI clock used as DFSDM1 audio clock */
|
||||
default:
|
||||
if (LL_RCC_HSI_IsReady() != 0U)
|
||||
{
|
||||
dfsdm_frequency = HSI_VALUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return dfsdm_frequency;
|
||||
}
|
||||
#endif /* RCC_CCIPR2_DFSDM1SEL */
|
||||
#endif /* DFSDM1_Channel0 */
|
||||
|
||||
#if defined(DSI)
|
||||
/**
|
||||
* @brief Return DSI clock frequency
|
||||
* @param DSIxSource This parameter can be one of the following values:
|
||||
* @arg @ref LL_RCC_DSI_CLKSOURCE
|
||||
* @retval DSI clock frequency (in Hz)
|
||||
* - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator is not ready
|
||||
* - @ref LL_RCC_PERIPH_FREQUENCY_NA indicates that external clock is used
|
||||
*/
|
||||
uint32_t LL_RCC_GetDSIClockFreq(uint32_t DSIxSource)
|
||||
{
|
||||
uint32_t dsi_frequency = LL_RCC_PERIPH_FREQUENCY_NO;
|
||||
|
||||
/* Check parameter */
|
||||
assert_param(IS_LL_RCC_DSI_CLKSOURCE(DSIxSource));
|
||||
|
||||
/* DSICLK clock frequency */
|
||||
switch (LL_RCC_GetDSIClockSource(DSIxSource))
|
||||
{
|
||||
case LL_RCC_DSI_CLKSOURCE_PLL: /* DSI Clock is PLLSAI2 Osc. */
|
||||
if (LL_RCC_PLLSAI2_IsReady() != 0U)
|
||||
{
|
||||
if (LL_RCC_PLLSAI2_IsEnabledDomain_DSI() != 0U)
|
||||
{
|
||||
dsi_frequency = RCC_PLLSAI2_GetFreqDomain_DSI();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case LL_RCC_DSI_CLKSOURCE_PHY: /* DSI Clock is DSI physical clock. */
|
||||
default:
|
||||
dsi_frequency = LL_RCC_PERIPH_FREQUENCY_NA;
|
||||
break;
|
||||
}
|
||||
|
||||
return dsi_frequency;
|
||||
}
|
||||
#endif /* DSI */
|
||||
|
||||
#if defined(LTDC)
|
||||
/**
|
||||
* @brief Return LTDC clock frequency
|
||||
* @param LTDCxSource This parameter can be one of the following values:
|
||||
* @arg @ref LL_RCC_LTDC_CLKSOURCE
|
||||
* @retval LTDC clock frequency (in Hz)
|
||||
* - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator PLLSAI is not ready
|
||||
*/
|
||||
uint32_t LL_RCC_GetLTDCClockFreq(uint32_t LTDCxSource)
|
||||
{
|
||||
uint32_t ltdc_frequency = LL_RCC_PERIPH_FREQUENCY_NO;
|
||||
|
||||
/* Check parameter */
|
||||
assert_param(IS_LL_RCC_LTDC_CLKSOURCE(LTDCxSource));
|
||||
|
||||
if (LL_RCC_PLLSAI2_IsReady() != 0U)
|
||||
{
|
||||
if (LL_RCC_PLLSAI2_IsEnabledDomain_LTDC() != 0U)
|
||||
{
|
||||
ltdc_frequency = RCC_PLLSAI2_GetFreqDomain_LTDC();
|
||||
}
|
||||
}
|
||||
|
||||
return ltdc_frequency;
|
||||
}
|
||||
#endif /* LTDC */
|
||||
|
||||
#if defined(OCTOSPI1)
|
||||
/**
|
||||
* @brief Return OCTOSPI clock frequency
|
||||
* @param OCTOSPIxSource This parameter can be one of the following values:
|
||||
* @arg @ref LL_RCC_OCTOSPI_CLKSOURCE
|
||||
* @retval OCTOSPI clock frequency (in Hz)
|
||||
* - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator PLLSAI is not ready
|
||||
*/
|
||||
uint32_t LL_RCC_GetOCTOSPIClockFreq(uint32_t OCTOSPIxSource)
|
||||
{
|
||||
uint32_t octospi_frequency = LL_RCC_PERIPH_FREQUENCY_NO;
|
||||
|
||||
/* Check parameter */
|
||||
assert_param(IS_LL_RCC_OCTOSPI_CLKSOURCE(OCTOSPIxSource));
|
||||
|
||||
/* OCTOSPI clock frequency */
|
||||
switch (LL_RCC_GetOCTOSPIClockSource(OCTOSPIxSource))
|
||||
{
|
||||
case LL_RCC_OCTOSPI_CLKSOURCE_SYSCLK: /* OCTOSPI clock is SYSCLK */
|
||||
octospi_frequency = RCC_GetSystemClockFreq();
|
||||
break;
|
||||
|
||||
case LL_RCC_OCTOSPI_CLKSOURCE_MSI: /* MSI clock used as OCTOSPI clock */
|
||||
if (LL_RCC_MSI_IsReady() != 0U)
|
||||
{
|
||||
octospi_frequency = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_IsEnabledRangeSelect(),
|
||||
((LL_RCC_MSI_IsEnabledRangeSelect() != 0U) ?
|
||||
LL_RCC_MSI_GetRange() :
|
||||
LL_RCC_MSI_GetRangeAfterStandby()));
|
||||
}
|
||||
break;
|
||||
|
||||
case LL_RCC_OCTOSPI_CLKSOURCE_PLL: /* PLL clock used as OCTOSPI source */
|
||||
if (LL_RCC_PLL_IsReady() != 0U)
|
||||
{
|
||||
if (LL_RCC_PLL_IsEnabledDomain_48M() != 0U)
|
||||
{
|
||||
octospi_frequency = RCC_PLL_GetFreqDomain_48M();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
octospi_frequency = LL_RCC_PERIPH_FREQUENCY_NO;
|
||||
break;
|
||||
}
|
||||
|
||||
return octospi_frequency;
|
||||
}
|
||||
#endif /* OCTOSPI1 */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup RCC_LL_Private_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Return SYSTEM clock frequency
|
||||
* @retval SYSTEM clock frequency (in Hz)
|
||||
*/
|
||||
static uint32_t RCC_GetSystemClockFreq(void)
|
||||
{
|
||||
uint32_t frequency;
|
||||
|
||||
/* Get SYSCLK source -------------------------------------------------------*/
|
||||
switch (LL_RCC_GetSysClkSource())
|
||||
{
|
||||
case LL_RCC_SYS_CLKSOURCE_STATUS_MSI: /* MSI used as system clock source */
|
||||
frequency = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_IsEnabledRangeSelect(),
|
||||
((LL_RCC_MSI_IsEnabledRangeSelect() != 0U) ?
|
||||
LL_RCC_MSI_GetRange() :
|
||||
LL_RCC_MSI_GetRangeAfterStandby()));
|
||||
break;
|
||||
|
||||
case LL_RCC_SYS_CLKSOURCE_STATUS_HSI: /* HSI used as system clock source */
|
||||
frequency = HSI_VALUE;
|
||||
break;
|
||||
|
||||
case LL_RCC_SYS_CLKSOURCE_STATUS_HSE: /* HSE used as system clock source */
|
||||
frequency = HSE_VALUE;
|
||||
break;
|
||||
|
||||
case LL_RCC_SYS_CLKSOURCE_STATUS_PLL: /* PLL used as system clock source */
|
||||
frequency = RCC_PLL_GetFreqDomain_SYS();
|
||||
break;
|
||||
|
||||
default:
|
||||
frequency = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_IsEnabledRangeSelect(),
|
||||
((LL_RCC_MSI_IsEnabledRangeSelect() != 0U) ?
|
||||
LL_RCC_MSI_GetRange() :
|
||||
LL_RCC_MSI_GetRangeAfterStandby()));
|
||||
break;
|
||||
}
|
||||
|
||||
return frequency;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return HCLK clock frequency
|
||||
* @param SYSCLK_Frequency SYSCLK clock frequency
|
||||
* @retval HCLK clock frequency (in Hz)
|
||||
*/
|
||||
static uint32_t RCC_GetHCLKClockFreq(uint32_t SYSCLK_Frequency)
|
||||
{
|
||||
/* HCLK clock frequency */
|
||||
return __LL_RCC_CALC_HCLK_FREQ(SYSCLK_Frequency, LL_RCC_GetAHBPrescaler());
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return PCLK1 clock frequency
|
||||
* @param HCLK_Frequency HCLK clock frequency
|
||||
* @retval PCLK1 clock frequency (in Hz)
|
||||
*/
|
||||
static uint32_t RCC_GetPCLK1ClockFreq(uint32_t HCLK_Frequency)
|
||||
{
|
||||
/* PCLK1 clock frequency */
|
||||
return __LL_RCC_CALC_PCLK1_FREQ(HCLK_Frequency, LL_RCC_GetAPB1Prescaler());
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return PCLK2 clock frequency
|
||||
* @param HCLK_Frequency HCLK clock frequency
|
||||
* @retval PCLK2 clock frequency (in Hz)
|
||||
*/
|
||||
static uint32_t RCC_GetPCLK2ClockFreq(uint32_t HCLK_Frequency)
|
||||
{
|
||||
/* PCLK2 clock frequency */
|
||||
return __LL_RCC_CALC_PCLK2_FREQ(HCLK_Frequency, LL_RCC_GetAPB2Prescaler());
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return PLL clock frequency used for system domain
|
||||
* @retval PLL clock frequency (in Hz)
|
||||
*/
|
||||
static uint32_t RCC_PLL_GetFreqDomain_SYS(void)
|
||||
{
|
||||
uint32_t pllinputfreq, pllsource;
|
||||
|
||||
/* PLL_VCO = (HSE_VALUE or HSI_VALUE or MSI_VALUE/ PLLM) * PLLN
|
||||
SYSCLK = PLL_VCO / PLLR
|
||||
*/
|
||||
pllsource = LL_RCC_PLL_GetMainSource();
|
||||
|
||||
switch (pllsource)
|
||||
{
|
||||
case LL_RCC_PLLSOURCE_MSI: /* MSI used as PLL clock source */
|
||||
pllinputfreq = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_IsEnabledRangeSelect(),
|
||||
((LL_RCC_MSI_IsEnabledRangeSelect() != 0U) ?
|
||||
LL_RCC_MSI_GetRange() :
|
||||
LL_RCC_MSI_GetRangeAfterStandby()));
|
||||
break;
|
||||
|
||||
case LL_RCC_PLLSOURCE_HSI: /* HSI used as PLL clock source */
|
||||
pllinputfreq = HSI_VALUE;
|
||||
break;
|
||||
|
||||
case LL_RCC_PLLSOURCE_HSE: /* HSE used as PLL clock source */
|
||||
pllinputfreq = HSE_VALUE;
|
||||
break;
|
||||
|
||||
default:
|
||||
pllinputfreq = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_IsEnabledRangeSelect(),
|
||||
((LL_RCC_MSI_IsEnabledRangeSelect() != 0U) ?
|
||||
LL_RCC_MSI_GetRange() :
|
||||
LL_RCC_MSI_GetRangeAfterStandby()));
|
||||
break;
|
||||
}
|
||||
return __LL_RCC_CALC_PLLCLK_FREQ(pllinputfreq, LL_RCC_PLL_GetDivider(),
|
||||
LL_RCC_PLL_GetN(), LL_RCC_PLL_GetR());
|
||||
}
|
||||
|
||||
#if defined(SAI1)
|
||||
/**
|
||||
* @brief Return PLL clock frequency used for SAI domain
|
||||
* @retval PLL clock frequency (in Hz)
|
||||
*/
|
||||
static uint32_t RCC_PLL_GetFreqDomain_SAI(void)
|
||||
{
|
||||
uint32_t pllinputfreq, pllsource;
|
||||
|
||||
/* PLL_VCO = (HSE_VALUE or HSI_VALUE or MSI_VALUE / PLLM) * PLLN
|
||||
SAI Domain clock = PLL_VCO / PLLP
|
||||
*/
|
||||
pllsource = LL_RCC_PLL_GetMainSource();
|
||||
|
||||
switch (pllsource)
|
||||
{
|
||||
case LL_RCC_PLLSOURCE_MSI: /* MSI used as PLL clock source */
|
||||
pllinputfreq = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_IsEnabledRangeSelect(),
|
||||
((LL_RCC_MSI_IsEnabledRangeSelect() != 0U) ?
|
||||
LL_RCC_MSI_GetRange() :
|
||||
LL_RCC_MSI_GetRangeAfterStandby()));
|
||||
break;
|
||||
|
||||
case LL_RCC_PLLSOURCE_HSI: /* HSI used as PLL clock source */
|
||||
pllinputfreq = HSI_VALUE;
|
||||
break;
|
||||
|
||||
case LL_RCC_PLLSOURCE_HSE: /* HSE used as PLL clock source */
|
||||
pllinputfreq = HSE_VALUE;
|
||||
break;
|
||||
|
||||
default:
|
||||
pllinputfreq = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_IsEnabledRangeSelect(),
|
||||
((LL_RCC_MSI_IsEnabledRangeSelect() != 0U) ?
|
||||
LL_RCC_MSI_GetRange() :
|
||||
LL_RCC_MSI_GetRangeAfterStandby()));
|
||||
break;
|
||||
}
|
||||
return __LL_RCC_CALC_PLLCLK_SAI_FREQ(pllinputfreq, LL_RCC_PLL_GetDivider(),
|
||||
LL_RCC_PLL_GetN(), LL_RCC_PLL_GetP());
|
||||
}
|
||||
#endif /* SAI1 */
|
||||
|
||||
/**
|
||||
* @brief Return PLL clock frequency used for 48 MHz domain
|
||||
* @retval PLL clock frequency (in Hz)
|
||||
*/
|
||||
static uint32_t RCC_PLL_GetFreqDomain_48M(void)
|
||||
{
|
||||
uint32_t pllinputfreq, pllsource;
|
||||
|
||||
/* PLL_VCO = (HSE_VALUE or HSI_VALUE or MSI_VALUE/ PLLM) * PLLN
|
||||
48M Domain clock = PLL_VCO / PLLQ
|
||||
*/
|
||||
pllsource = LL_RCC_PLL_GetMainSource();
|
||||
|
||||
switch (pllsource)
|
||||
{
|
||||
case LL_RCC_PLLSOURCE_MSI: /* MSI used as PLL clock source */
|
||||
pllinputfreq = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_IsEnabledRangeSelect(),
|
||||
((LL_RCC_MSI_IsEnabledRangeSelect() != 0U) ?
|
||||
LL_RCC_MSI_GetRange() :
|
||||
LL_RCC_MSI_GetRangeAfterStandby()));
|
||||
break;
|
||||
|
||||
case LL_RCC_PLLSOURCE_HSI: /* HSI used as PLL clock source */
|
||||
pllinputfreq = HSI_VALUE;
|
||||
break;
|
||||
|
||||
case LL_RCC_PLLSOURCE_HSE: /* HSE used as PLL clock source */
|
||||
pllinputfreq = HSE_VALUE;
|
||||
break;
|
||||
|
||||
default:
|
||||
pllinputfreq = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_IsEnabledRangeSelect(),
|
||||
((LL_RCC_MSI_IsEnabledRangeSelect() != 0U) ?
|
||||
LL_RCC_MSI_GetRange() :
|
||||
LL_RCC_MSI_GetRangeAfterStandby()));
|
||||
break;
|
||||
}
|
||||
return __LL_RCC_CALC_PLLCLK_48M_FREQ(pllinputfreq, LL_RCC_PLL_GetDivider(),
|
||||
LL_RCC_PLL_GetN(), LL_RCC_PLL_GetQ());
|
||||
}
|
||||
#if defined(DSI)
|
||||
/**
|
||||
* @brief Return PLL clock frequency used for DSI clock
|
||||
* @retval PLL clock frequency (in Hz)
|
||||
*/
|
||||
static uint32_t RCC_PLLSAI2_GetFreqDomain_DSI(void)
|
||||
{
|
||||
uint32_t pllinputfreq, pllsource;
|
||||
|
||||
/* PLLSAI2_VCO = (HSE_VALUE or HSI_VALUE or MSI_VALUE/ PLLSAI2M) * PLLSAI2N */
|
||||
/* DSICLK = PLLSAI2_VCO / PLLSAI2R */
|
||||
pllsource = LL_RCC_PLL_GetMainSource();
|
||||
|
||||
switch (pllsource)
|
||||
{
|
||||
case LL_RCC_PLLSOURCE_MSI: /* MSI used as PLLSAI2 clock source */
|
||||
pllinputfreq = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_IsEnabledRangeSelect(),
|
||||
((LL_RCC_MSI_IsEnabledRangeSelect() != 0U) ?
|
||||
LL_RCC_MSI_GetRange() :
|
||||
LL_RCC_MSI_GetRangeAfterStandby()));
|
||||
break;
|
||||
|
||||
case LL_RCC_PLLSOURCE_HSI: /* HSI used as PLLSAI2 clock source */
|
||||
pllinputfreq = HSI_VALUE;
|
||||
break;
|
||||
|
||||
case LL_RCC_PLLSOURCE_HSE: /* HSE used as PLLSAI2 clock source */
|
||||
pllinputfreq = HSE_VALUE;
|
||||
break;
|
||||
|
||||
default:
|
||||
pllinputfreq = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_IsEnabledRangeSelect(),
|
||||
((LL_RCC_MSI_IsEnabledRangeSelect() != 0U) ?
|
||||
LL_RCC_MSI_GetRange() :
|
||||
LL_RCC_MSI_GetRangeAfterStandby()));
|
||||
break;
|
||||
}
|
||||
|
||||
return __LL_RCC_CALC_PLLSAI2_DSI_FREQ(pllinputfreq, LL_RCC_PLLSAI2_GetDivider(),
|
||||
LL_RCC_PLLSAI2_GetN(), LL_RCC_PLLSAI2_GetR());
|
||||
}
|
||||
#endif /* DSI */
|
||||
|
||||
#if defined(RCC_PLLSAI1_SUPPORT)
|
||||
/**
|
||||
* @brief Return PLLSAI1 clock frequency used for SAI domain
|
||||
* @retval PLLSAI1 clock frequency (in Hz)
|
||||
*/
|
||||
static uint32_t RCC_PLLSAI1_GetFreqDomain_SAI(void)
|
||||
{
|
||||
uint32_t pllinputfreq, pllsource;
|
||||
|
||||
#if defined(RCC_PLLSAI2M_DIV_1_16_SUPPORT)
|
||||
/* PLLSAI1_VCO = (HSE_VALUE or HSI_VALUE or MSI_VALUE/ PLLSAI1M) * PLLSAI1N */
|
||||
#else
|
||||
/* PLLSAI1_VCO = (HSE_VALUE or HSI_VALUE or MSI_VALUE/ PLLM) * PLLSAI1N */
|
||||
#endif
|
||||
/* SAI Domain clock = PLLSAI1_VCO / PLLSAI1P */
|
||||
pllsource = LL_RCC_PLL_GetMainSource();
|
||||
|
||||
switch (pllsource)
|
||||
{
|
||||
case LL_RCC_PLLSOURCE_MSI: /* MSI used as PLLSAI1 clock source */
|
||||
pllinputfreq = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_IsEnabledRangeSelect(),
|
||||
((LL_RCC_MSI_IsEnabledRangeSelect() != 0U) ?
|
||||
LL_RCC_MSI_GetRange() :
|
||||
LL_RCC_MSI_GetRangeAfterStandby()));
|
||||
break;
|
||||
|
||||
case LL_RCC_PLLSOURCE_HSI: /* HSI used as PLLSAI1 clock source */
|
||||
pllinputfreq = HSI_VALUE;
|
||||
break;
|
||||
|
||||
case LL_RCC_PLLSOURCE_HSE: /* HSE used as PLLSAI1 clock source */
|
||||
pllinputfreq = HSE_VALUE;
|
||||
break;
|
||||
|
||||
default:
|
||||
pllinputfreq = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_IsEnabledRangeSelect(),
|
||||
((LL_RCC_MSI_IsEnabledRangeSelect() != 0U) ?
|
||||
LL_RCC_MSI_GetRange() :
|
||||
LL_RCC_MSI_GetRangeAfterStandby()));
|
||||
break;
|
||||
}
|
||||
return __LL_RCC_CALC_PLLSAI1_SAI_FREQ(pllinputfreq, LL_RCC_PLL_GetDivider(),
|
||||
LL_RCC_PLLSAI1_GetN(), LL_RCC_PLLSAI1_GetP());
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return PLLSAI1 clock frequency used for 48Mhz domain
|
||||
* @retval PLLSAI1 clock frequency (in Hz)
|
||||
*/
|
||||
static uint32_t RCC_PLLSAI1_GetFreqDomain_48M(void)
|
||||
{
|
||||
uint32_t pllinputfreq, pllsource;
|
||||
|
||||
#if defined(RCC_PLLSAI2M_DIV_1_16_SUPPORT)
|
||||
/* PLLSAI1_VCO = (HSE_VALUE or HSI_VALUE or MSI_VALUE/ PLLSAI1M) * PLLSAI1N */
|
||||
#else
|
||||
/* PLLSAI1_VCO = (HSE_VALUE or HSI_VALUE or MSI_VALUE/ PLLM) * PLLSAI1N */
|
||||
#endif
|
||||
/* 48M Domain clock = PLLSAI1_VCO / PLLSAI1Q */
|
||||
pllsource = LL_RCC_PLL_GetMainSource();
|
||||
|
||||
switch (pllsource)
|
||||
{
|
||||
case LL_RCC_PLLSOURCE_MSI: /* MSI used as PLLSAI1 clock source */
|
||||
pllinputfreq = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_IsEnabledRangeSelect(),
|
||||
((LL_RCC_MSI_IsEnabledRangeSelect() != 0U) ?
|
||||
LL_RCC_MSI_GetRange() :
|
||||
LL_RCC_MSI_GetRangeAfterStandby()));
|
||||
break;
|
||||
|
||||
case LL_RCC_PLLSOURCE_HSI: /* HSI used as PLLSAI1 clock source */
|
||||
pllinputfreq = HSI_VALUE;
|
||||
break;
|
||||
|
||||
case LL_RCC_PLLSOURCE_HSE: /* HSE used as PLLSAI1 clock source */
|
||||
pllinputfreq = HSE_VALUE;
|
||||
break;
|
||||
|
||||
default:
|
||||
pllinputfreq = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_IsEnabledRangeSelect(),
|
||||
((LL_RCC_MSI_IsEnabledRangeSelect() != 0U) ?
|
||||
LL_RCC_MSI_GetRange() :
|
||||
LL_RCC_MSI_GetRangeAfterStandby()));
|
||||
break;
|
||||
}
|
||||
return __LL_RCC_CALC_PLLSAI1_48M_FREQ(pllinputfreq, LL_RCC_PLL_GetDivider(),
|
||||
LL_RCC_PLLSAI1_GetN(), LL_RCC_PLLSAI1_GetQ());
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return PLLSAI1 clock frequency used for ADC domain
|
||||
* @retval PLLSAI1 clock frequency (in Hz)
|
||||
*/
|
||||
static uint32_t RCC_PLLSAI1_GetFreqDomain_ADC(void)
|
||||
{
|
||||
uint32_t pllinputfreq, pllsource;
|
||||
|
||||
#if defined(RCC_PLLSAI2M_DIV_1_16_SUPPORT)
|
||||
/* PLLSAI1_VCO = (HSE_VALUE or HSI_VALUE or MSI_VALUE/ PLLSAI1M) * PLLSAI1N */
|
||||
#else
|
||||
/* PLLSAI1_VCO = (HSE_VALUE or HSI_VALUE or MSI_VALUE/ PLLM) * PLLSAI1N */
|
||||
#endif
|
||||
/* 48M Domain clock = PLLSAI1_VCO / PLLSAI1R */
|
||||
pllsource = LL_RCC_PLL_GetMainSource();
|
||||
|
||||
switch (pllsource)
|
||||
{
|
||||
case LL_RCC_PLLSOURCE_MSI: /* MSI used as PLLSAI1 clock source */
|
||||
pllinputfreq = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_IsEnabledRangeSelect(),
|
||||
((LL_RCC_MSI_IsEnabledRangeSelect() != 0U) ?
|
||||
LL_RCC_MSI_GetRange() :
|
||||
LL_RCC_MSI_GetRangeAfterStandby()));
|
||||
break;
|
||||
|
||||
case LL_RCC_PLLSOURCE_HSI: /* HSI used as PLLSAI1 clock source */
|
||||
pllinputfreq = HSI_VALUE;
|
||||
break;
|
||||
|
||||
case LL_RCC_PLLSOURCE_HSE: /* HSE used as PLLSAI1 clock source */
|
||||
pllinputfreq = HSE_VALUE;
|
||||
break;
|
||||
|
||||
default:
|
||||
pllinputfreq = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_IsEnabledRangeSelect(),
|
||||
((LL_RCC_MSI_IsEnabledRangeSelect() != 0U) ?
|
||||
LL_RCC_MSI_GetRange() :
|
||||
LL_RCC_MSI_GetRangeAfterStandby()));
|
||||
break;
|
||||
}
|
||||
return __LL_RCC_CALC_PLLSAI1_ADC_FREQ(pllinputfreq, LL_RCC_PLL_GetDivider(),
|
||||
LL_RCC_PLLSAI1_GetN(), LL_RCC_PLLSAI1_GetR());
|
||||
}
|
||||
#endif /* RCC_PLLSAI1_SUPPORT */
|
||||
|
||||
#if defined(RCC_PLLSAI2_SUPPORT)
|
||||
/**
|
||||
* @brief Return PLLSAI2 clock frequency used for SAI domain
|
||||
* @retval PLLSAI2 clock frequency (in Hz)
|
||||
*/
|
||||
static uint32_t RCC_PLLSAI2_GetFreqDomain_SAI(void)
|
||||
{
|
||||
uint32_t pllinputfreq, pllsource;
|
||||
|
||||
#if defined(RCC_PLLSAI2M_DIV_1_16_SUPPORT)
|
||||
/* PLLSAI2_VCO = (HSE_VALUE or HSI_VALUE or MSI_VALUE/ PLLSAI2M) * PLLSAI2N */
|
||||
#else
|
||||
/* PLLSAI2_VCO = (HSE_VALUE or HSI_VALUE or MSI_VALUE/ PLLM) * PLLSAI2N */
|
||||
#endif
|
||||
/* SAI Domain clock = PLLSAI2_VCO / PLLSAI2P */
|
||||
pllsource = LL_RCC_PLL_GetMainSource();
|
||||
|
||||
switch (pllsource)
|
||||
{
|
||||
case LL_RCC_PLLSOURCE_MSI: /* MSI used as PLLSAI2 clock source */
|
||||
pllinputfreq = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_IsEnabledRangeSelect(),
|
||||
((LL_RCC_MSI_IsEnabledRangeSelect() != 0U) ?
|
||||
LL_RCC_MSI_GetRange() :
|
||||
LL_RCC_MSI_GetRangeAfterStandby()));
|
||||
break;
|
||||
|
||||
case LL_RCC_PLLSOURCE_HSI: /* HSI used as PLLSAI2 clock source */
|
||||
pllinputfreq = HSI_VALUE;
|
||||
break;
|
||||
|
||||
case LL_RCC_PLLSOURCE_HSE: /* HSE used as PLLSAI2 clock source */
|
||||
pllinputfreq = HSE_VALUE;
|
||||
break;
|
||||
|
||||
default:
|
||||
pllinputfreq = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_IsEnabledRangeSelect(),
|
||||
((LL_RCC_MSI_IsEnabledRangeSelect() != 0U) ?
|
||||
LL_RCC_MSI_GetRange() :
|
||||
LL_RCC_MSI_GetRangeAfterStandby()));
|
||||
break;
|
||||
}
|
||||
#if defined(RCC_PLLSAI2M_DIV_1_16_SUPPORT)
|
||||
return __LL_RCC_CALC_PLLSAI2_SAI_FREQ(pllinputfreq, LL_RCC_PLLSAI2_GetDivider(),
|
||||
LL_RCC_PLLSAI2_GetN(), LL_RCC_PLLSAI2_GetP());
|
||||
#else
|
||||
return __LL_RCC_CALC_PLLSAI2_SAI_FREQ(pllinputfreq, LL_RCC_PLL_GetDivider(),
|
||||
LL_RCC_PLLSAI2_GetN(), LL_RCC_PLLSAI2_GetP());
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(LTDC)
|
||||
/**
|
||||
* @brief Return PLLSAI2 clock frequency used for LTDC domain
|
||||
* @retval PLLSAI2 clock frequency (in Hz)
|
||||
*/
|
||||
static uint32_t RCC_PLLSAI2_GetFreqDomain_LTDC(void)
|
||||
{
|
||||
uint32_t pllinputfreq, pllsource;
|
||||
|
||||
/* PLLSAI2_VCO = (HSE_VALUE or HSI_VALUE or MSI_VALUE/ PLLSAI2M) * PLLSAI2N */
|
||||
/* LTDC Domain clock = (PLLSAI2_VCO / PLLSAI2R) / PLLSAI2DIVR */
|
||||
pllsource = LL_RCC_PLL_GetMainSource();
|
||||
|
||||
switch (pllsource)
|
||||
{
|
||||
case LL_RCC_PLLSOURCE_MSI: /* MSI used as PLLSAI2 clock source */
|
||||
pllinputfreq = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_IsEnabledRangeSelect(),
|
||||
((LL_RCC_MSI_IsEnabledRangeSelect() != 0U) ?
|
||||
LL_RCC_MSI_GetRange() :
|
||||
LL_RCC_MSI_GetRangeAfterStandby()));
|
||||
break;
|
||||
|
||||
case LL_RCC_PLLSOURCE_HSI: /* HSI used as PLLSAI2 clock source */
|
||||
pllinputfreq = HSI_VALUE;
|
||||
break;
|
||||
|
||||
case LL_RCC_PLLSOURCE_HSE: /* HSE used as PLLSAI2 clock source */
|
||||
pllinputfreq = HSE_VALUE;
|
||||
break;
|
||||
|
||||
default:
|
||||
pllinputfreq = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_IsEnabledRangeSelect(),
|
||||
((LL_RCC_MSI_IsEnabledRangeSelect() != 0U) ?
|
||||
LL_RCC_MSI_GetRange() :
|
||||
LL_RCC_MSI_GetRangeAfterStandby()));
|
||||
break;
|
||||
}
|
||||
|
||||
return __LL_RCC_CALC_PLLSAI2_LTDC_FREQ(pllinputfreq, LL_RCC_PLLSAI2_GetDivider(),
|
||||
LL_RCC_PLLSAI2_GetN(), LL_RCC_PLLSAI2_GetR(), LL_RCC_PLLSAI2_GetDIVR());
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/**
|
||||
* @brief Return PLLSAI2 clock frequency used for ADC domain
|
||||
* @retval PLLSAI2 clock frequency (in Hz)
|
||||
*/
|
||||
static uint32_t RCC_PLLSAI2_GetFreqDomain_ADC(void)
|
||||
{
|
||||
uint32_t pllinputfreq = 0U, pllsource = 0U;
|
||||
|
||||
/* PLLSAI2_VCO = (HSE_VALUE or HSI_VALUE or MSI_VALUE/ PLLM) * PLLSAI2N */
|
||||
/* 48M Domain clock = PLLSAI2_VCO / PLLSAI2R */
|
||||
pllsource = LL_RCC_PLL_GetMainSource();
|
||||
|
||||
switch (pllsource)
|
||||
{
|
||||
case LL_RCC_PLLSOURCE_MSI: /* MSI used as PLLSAI2 clock source */
|
||||
pllinputfreq = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_IsEnabledRangeSelect(),
|
||||
((LL_RCC_MSI_IsEnabledRangeSelect() != 0U) ?
|
||||
LL_RCC_MSI_GetRange() :
|
||||
LL_RCC_MSI_GetRangeAfterStandby()));
|
||||
break;
|
||||
|
||||
case LL_RCC_PLLSOURCE_HSI: /* HSI used as PLLSAI2 clock source */
|
||||
pllinputfreq = HSI_VALUE;
|
||||
break;
|
||||
|
||||
case LL_RCC_PLLSOURCE_HSE: /* HSE used as PLLSAI2 clock source */
|
||||
pllinputfreq = HSE_VALUE;
|
||||
break;
|
||||
|
||||
default:
|
||||
pllinputfreq = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_IsEnabledRangeSelect(),
|
||||
((LL_RCC_MSI_IsEnabledRangeSelect() != 0U) ?
|
||||
LL_RCC_MSI_GetRange() :
|
||||
LL_RCC_MSI_GetRangeAfterStandby()));
|
||||
break;
|
||||
}
|
||||
return __LL_RCC_CALC_PLLSAI2_ADC_FREQ(pllinputfreq, LL_RCC_PLL_GetDivider(),
|
||||
LL_RCC_PLLSAI2_GetN(), LL_RCC_PLLSAI2_GetR());
|
||||
}
|
||||
#endif /* LTDC */
|
||||
|
||||
#endif /*RCC_PLLSAI2_SUPPORT*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* defined(RCC) */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* USE_FULL_LL_DRIVER */
|
||||
|
||||
295
Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_ll_spi.c
Normal file
295
Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_ll_spi.c
Normal file
@@ -0,0 +1,295 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32l4xx_ll_spi.c
|
||||
* @author MCD Application Team
|
||||
* @brief SPI LL module driver.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2017 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
#if defined(USE_FULL_LL_DRIVER)
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32l4xx_ll_spi.h"
|
||||
#include "stm32l4xx_ll_bus.h"
|
||||
|
||||
#ifdef USE_FULL_ASSERT
|
||||
#include "stm32_assert.h"
|
||||
#else
|
||||
#define assert_param(expr) ((void)0U)
|
||||
#endif /* USE_FULL_ASSERT */
|
||||
|
||||
/** @addtogroup STM32L4xx_LL_Driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
#if defined (SPI1) || defined (SPI2) || defined (SPI3)
|
||||
|
||||
/** @addtogroup SPI_LL
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Private types -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
|
||||
/* Private constants ---------------------------------------------------------*/
|
||||
/** @defgroup SPI_LL_Private_Constants SPI Private Constants
|
||||
* @{
|
||||
*/
|
||||
/* SPI registers Masks */
|
||||
#define SPI_CR1_CLEAR_MASK (SPI_CR1_CPHA | SPI_CR1_CPOL | SPI_CR1_MSTR | \
|
||||
SPI_CR1_BR | SPI_CR1_LSBFIRST | SPI_CR1_SSI | \
|
||||
SPI_CR1_SSM | SPI_CR1_RXONLY | SPI_CR1_CRCL | \
|
||||
SPI_CR1_CRCNEXT | SPI_CR1_CRCEN | SPI_CR1_BIDIOE | \
|
||||
SPI_CR1_BIDIMODE)
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private macros ------------------------------------------------------------*/
|
||||
/** @defgroup SPI_LL_Private_Macros SPI Private Macros
|
||||
* @{
|
||||
*/
|
||||
#define IS_LL_SPI_TRANSFER_DIRECTION(__VALUE__) (((__VALUE__) == LL_SPI_FULL_DUPLEX) \
|
||||
|| ((__VALUE__) == LL_SPI_SIMPLEX_RX) \
|
||||
|| ((__VALUE__) == LL_SPI_HALF_DUPLEX_RX) \
|
||||
|| ((__VALUE__) == LL_SPI_HALF_DUPLEX_TX))
|
||||
|
||||
#define IS_LL_SPI_MODE(__VALUE__) (((__VALUE__) == LL_SPI_MODE_MASTER) \
|
||||
|| ((__VALUE__) == LL_SPI_MODE_SLAVE))
|
||||
|
||||
#define IS_LL_SPI_DATAWIDTH(__VALUE__) (((__VALUE__) == LL_SPI_DATAWIDTH_4BIT) \
|
||||
|| ((__VALUE__) == LL_SPI_DATAWIDTH_5BIT) \
|
||||
|| ((__VALUE__) == LL_SPI_DATAWIDTH_6BIT) \
|
||||
|| ((__VALUE__) == LL_SPI_DATAWIDTH_7BIT) \
|
||||
|| ((__VALUE__) == LL_SPI_DATAWIDTH_8BIT) \
|
||||
|| ((__VALUE__) == LL_SPI_DATAWIDTH_9BIT) \
|
||||
|| ((__VALUE__) == LL_SPI_DATAWIDTH_10BIT) \
|
||||
|| ((__VALUE__) == LL_SPI_DATAWIDTH_11BIT) \
|
||||
|| ((__VALUE__) == LL_SPI_DATAWIDTH_12BIT) \
|
||||
|| ((__VALUE__) == LL_SPI_DATAWIDTH_13BIT) \
|
||||
|| ((__VALUE__) == LL_SPI_DATAWIDTH_14BIT) \
|
||||
|| ((__VALUE__) == LL_SPI_DATAWIDTH_15BIT) \
|
||||
|| ((__VALUE__) == LL_SPI_DATAWIDTH_16BIT))
|
||||
|
||||
#define IS_LL_SPI_POLARITY(__VALUE__) (((__VALUE__) == LL_SPI_POLARITY_LOW) \
|
||||
|| ((__VALUE__) == LL_SPI_POLARITY_HIGH))
|
||||
|
||||
#define IS_LL_SPI_PHASE(__VALUE__) (((__VALUE__) == LL_SPI_PHASE_1EDGE) \
|
||||
|| ((__VALUE__) == LL_SPI_PHASE_2EDGE))
|
||||
|
||||
#define IS_LL_SPI_NSS(__VALUE__) (((__VALUE__) == LL_SPI_NSS_SOFT) \
|
||||
|| ((__VALUE__) == LL_SPI_NSS_HARD_INPUT) \
|
||||
|| ((__VALUE__) == LL_SPI_NSS_HARD_OUTPUT))
|
||||
|
||||
#define IS_LL_SPI_BAUDRATE(__VALUE__) (((__VALUE__) == LL_SPI_BAUDRATEPRESCALER_DIV2) \
|
||||
|| ((__VALUE__) == LL_SPI_BAUDRATEPRESCALER_DIV4) \
|
||||
|| ((__VALUE__) == LL_SPI_BAUDRATEPRESCALER_DIV8) \
|
||||
|| ((__VALUE__) == LL_SPI_BAUDRATEPRESCALER_DIV16) \
|
||||
|| ((__VALUE__) == LL_SPI_BAUDRATEPRESCALER_DIV32) \
|
||||
|| ((__VALUE__) == LL_SPI_BAUDRATEPRESCALER_DIV64) \
|
||||
|| ((__VALUE__) == LL_SPI_BAUDRATEPRESCALER_DIV128) \
|
||||
|| ((__VALUE__) == LL_SPI_BAUDRATEPRESCALER_DIV256))
|
||||
|
||||
#define IS_LL_SPI_BITORDER(__VALUE__) (((__VALUE__) == LL_SPI_LSB_FIRST) \
|
||||
|| ((__VALUE__) == LL_SPI_MSB_FIRST))
|
||||
|
||||
#define IS_LL_SPI_CRCCALCULATION(__VALUE__) (((__VALUE__) == LL_SPI_CRCCALCULATION_ENABLE) \
|
||||
|| ((__VALUE__) == LL_SPI_CRCCALCULATION_DISABLE))
|
||||
|
||||
#define IS_LL_SPI_CRC_POLYNOMIAL(__VALUE__) ((__VALUE__) >= 0x1U)
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
|
||||
/* Exported functions --------------------------------------------------------*/
|
||||
/** @addtogroup SPI_LL_Exported_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup SPI_LL_EF_Init
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief De-initialize the SPI registers to their default reset values.
|
||||
* @param SPIx SPI Instance
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: SPI registers are de-initialized
|
||||
* - ERROR: SPI registers are not de-initialized
|
||||
*/
|
||||
ErrorStatus LL_SPI_DeInit(SPI_TypeDef *SPIx)
|
||||
{
|
||||
ErrorStatus status = ERROR;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_SPI_ALL_INSTANCE(SPIx));
|
||||
|
||||
#if defined(SPI1)
|
||||
if (SPIx == SPI1)
|
||||
{
|
||||
/* Force reset of SPI clock */
|
||||
LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_SPI1);
|
||||
|
||||
/* Release reset of SPI clock */
|
||||
LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_SPI1);
|
||||
|
||||
status = SUCCESS;
|
||||
}
|
||||
#endif /* SPI1 */
|
||||
#if defined(SPI2)
|
||||
if (SPIx == SPI2)
|
||||
{
|
||||
/* Force reset of SPI clock */
|
||||
LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_SPI2);
|
||||
|
||||
/* Release reset of SPI clock */
|
||||
LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_SPI2);
|
||||
|
||||
status = SUCCESS;
|
||||
}
|
||||
#endif /* SPI2 */
|
||||
#if defined(SPI3)
|
||||
if (SPIx == SPI3)
|
||||
{
|
||||
/* Force reset of SPI clock */
|
||||
LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_SPI3);
|
||||
|
||||
/* Release reset of SPI clock */
|
||||
LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_SPI3);
|
||||
|
||||
status = SUCCESS;
|
||||
}
|
||||
#endif /* SPI3 */
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialize the SPI registers according to the specified parameters in SPI_InitStruct.
|
||||
* @note As some bits in SPI configuration registers can only be written when the SPI is disabled (SPI_CR1_SPE bit =0),
|
||||
* SPI peripheral should be in disabled state prior calling this function. Otherwise, ERROR result will be returned.
|
||||
* @param SPIx SPI Instance
|
||||
* @param SPI_InitStruct pointer to a @ref LL_SPI_InitTypeDef structure
|
||||
* @retval An ErrorStatus enumeration value. (Return always SUCCESS)
|
||||
*/
|
||||
ErrorStatus LL_SPI_Init(SPI_TypeDef *SPIx, LL_SPI_InitTypeDef *SPI_InitStruct)
|
||||
{
|
||||
ErrorStatus status = ERROR;
|
||||
|
||||
/* Check the SPI Instance SPIx*/
|
||||
assert_param(IS_SPI_ALL_INSTANCE(SPIx));
|
||||
|
||||
/* Check the SPI parameters from SPI_InitStruct*/
|
||||
assert_param(IS_LL_SPI_TRANSFER_DIRECTION(SPI_InitStruct->TransferDirection));
|
||||
assert_param(IS_LL_SPI_MODE(SPI_InitStruct->Mode));
|
||||
assert_param(IS_LL_SPI_DATAWIDTH(SPI_InitStruct->DataWidth));
|
||||
assert_param(IS_LL_SPI_POLARITY(SPI_InitStruct->ClockPolarity));
|
||||
assert_param(IS_LL_SPI_PHASE(SPI_InitStruct->ClockPhase));
|
||||
assert_param(IS_LL_SPI_NSS(SPI_InitStruct->NSS));
|
||||
assert_param(IS_LL_SPI_BAUDRATE(SPI_InitStruct->BaudRate));
|
||||
assert_param(IS_LL_SPI_BITORDER(SPI_InitStruct->BitOrder));
|
||||
assert_param(IS_LL_SPI_CRCCALCULATION(SPI_InitStruct->CRCCalculation));
|
||||
|
||||
if (LL_SPI_IsEnabled(SPIx) == 0x00000000U)
|
||||
{
|
||||
/*---------------------------- SPIx CR1 Configuration ------------------------
|
||||
* Configure SPIx CR1 with parameters:
|
||||
* - TransferDirection: SPI_CR1_BIDIMODE, SPI_CR1_BIDIOE and SPI_CR1_RXONLY bits
|
||||
* - Master/Slave Mode: SPI_CR1_MSTR bit
|
||||
* - ClockPolarity: SPI_CR1_CPOL bit
|
||||
* - ClockPhase: SPI_CR1_CPHA bit
|
||||
* - NSS management: SPI_CR1_SSM bit
|
||||
* - BaudRate prescaler: SPI_CR1_BR[2:0] bits
|
||||
* - BitOrder: SPI_CR1_LSBFIRST bit
|
||||
* - CRCCalculation: SPI_CR1_CRCEN bit
|
||||
*/
|
||||
MODIFY_REG(SPIx->CR1,
|
||||
SPI_CR1_CLEAR_MASK,
|
||||
SPI_InitStruct->TransferDirection | SPI_InitStruct->Mode |
|
||||
SPI_InitStruct->ClockPolarity | SPI_InitStruct->ClockPhase |
|
||||
SPI_InitStruct->NSS | SPI_InitStruct->BaudRate |
|
||||
SPI_InitStruct->BitOrder | SPI_InitStruct->CRCCalculation);
|
||||
|
||||
/*---------------------------- SPIx CR2 Configuration ------------------------
|
||||
* Configure SPIx CR2 with parameters:
|
||||
* - DataWidth: DS[3:0] bits
|
||||
* - NSS management: SSOE bit
|
||||
*/
|
||||
MODIFY_REG(SPIx->CR2,
|
||||
SPI_CR2_DS | SPI_CR2_SSOE,
|
||||
SPI_InitStruct->DataWidth | (SPI_InitStruct->NSS >> 16U));
|
||||
|
||||
/* Set Rx FIFO to Quarter (1 Byte) in case of 8 Bits mode. No DataPacking by default */
|
||||
if (SPI_InitStruct->DataWidth < LL_SPI_DATAWIDTH_9BIT)
|
||||
{
|
||||
LL_SPI_SetRxFIFOThreshold(SPIx, LL_SPI_RX_FIFO_TH_QUARTER);
|
||||
}
|
||||
|
||||
/*---------------------------- SPIx CRCPR Configuration ----------------------
|
||||
* Configure SPIx CRCPR with parameters:
|
||||
* - CRCPoly: CRCPOLY[15:0] bits
|
||||
*/
|
||||
if (SPI_InitStruct->CRCCalculation == LL_SPI_CRCCALCULATION_ENABLE)
|
||||
{
|
||||
assert_param(IS_LL_SPI_CRC_POLYNOMIAL(SPI_InitStruct->CRCPoly));
|
||||
LL_SPI_SetCRCPolynomial(SPIx, SPI_InitStruct->CRCPoly);
|
||||
}
|
||||
status = SUCCESS;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set each @ref LL_SPI_InitTypeDef field to default value.
|
||||
* @param SPI_InitStruct pointer to a @ref LL_SPI_InitTypeDef structure
|
||||
* whose fields will be set to default values.
|
||||
* @retval None
|
||||
*/
|
||||
void LL_SPI_StructInit(LL_SPI_InitTypeDef *SPI_InitStruct)
|
||||
{
|
||||
/* Set SPI_InitStruct fields to default values */
|
||||
SPI_InitStruct->TransferDirection = LL_SPI_FULL_DUPLEX;
|
||||
SPI_InitStruct->Mode = LL_SPI_MODE_SLAVE;
|
||||
SPI_InitStruct->DataWidth = LL_SPI_DATAWIDTH_8BIT;
|
||||
SPI_InitStruct->ClockPolarity = LL_SPI_POLARITY_LOW;
|
||||
SPI_InitStruct->ClockPhase = LL_SPI_PHASE_1EDGE;
|
||||
SPI_InitStruct->NSS = LL_SPI_NSS_HARD_INPUT;
|
||||
SPI_InitStruct->BaudRate = LL_SPI_BAUDRATEPRESCALER_DIV2;
|
||||
SPI_InitStruct->BitOrder = LL_SPI_MSB_FIRST;
|
||||
SPI_InitStruct->CRCCalculation = LL_SPI_CRCCALCULATION_DISABLE;
|
||||
SPI_InitStruct->CRCPoly = 7U;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* defined (SPI1) || defined (SPI2) || defined (SPI3) */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* USE_FULL_LL_DRIVER */
|
||||
|
||||
1360
Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_ll_tim.c
Normal file
1360
Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_ll_tim.c
Normal file
@@ -0,0 +1,1360 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32l4xx_ll_tim.c
|
||||
* @author MCD Application Team
|
||||
* @brief TIM LL module driver.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2017 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
#if defined(USE_FULL_LL_DRIVER)
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32l4xx_ll_tim.h"
|
||||
#include "stm32l4xx_ll_bus.h"
|
||||
|
||||
#ifdef USE_FULL_ASSERT
|
||||
#include "stm32_assert.h"
|
||||
#else
|
||||
#define assert_param(expr) ((void)0U)
|
||||
#endif /* USE_FULL_ASSERT */
|
||||
|
||||
/** @addtogroup STM32L4xx_LL_Driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
#if defined (TIM1) || defined (TIM8) || defined (TIM2) || defined (TIM3) || defined (TIM4) || defined (TIM5) || defined (TIM15) || defined (TIM16) || defined (TIM17) || defined (TIM6) || defined (TIM7)
|
||||
|
||||
/** @addtogroup TIM_LL
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Private types -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private constants ---------------------------------------------------------*/
|
||||
/* Private macros ------------------------------------------------------------*/
|
||||
/** @addtogroup TIM_LL_Private_Macros
|
||||
* @{
|
||||
*/
|
||||
#define IS_LL_TIM_COUNTERMODE(__VALUE__) (((__VALUE__) == LL_TIM_COUNTERMODE_UP) \
|
||||
|| ((__VALUE__) == LL_TIM_COUNTERMODE_DOWN) \
|
||||
|| ((__VALUE__) == LL_TIM_COUNTERMODE_CENTER_UP) \
|
||||
|| ((__VALUE__) == LL_TIM_COUNTERMODE_CENTER_DOWN) \
|
||||
|| ((__VALUE__) == LL_TIM_COUNTERMODE_CENTER_UP_DOWN))
|
||||
|
||||
#define IS_LL_TIM_CLOCKDIVISION(__VALUE__) (((__VALUE__) == LL_TIM_CLOCKDIVISION_DIV1) \
|
||||
|| ((__VALUE__) == LL_TIM_CLOCKDIVISION_DIV2) \
|
||||
|| ((__VALUE__) == LL_TIM_CLOCKDIVISION_DIV4))
|
||||
|
||||
#define IS_LL_TIM_OCMODE(__VALUE__) (((__VALUE__) == LL_TIM_OCMODE_FROZEN) \
|
||||
|| ((__VALUE__) == LL_TIM_OCMODE_ACTIVE) \
|
||||
|| ((__VALUE__) == LL_TIM_OCMODE_INACTIVE) \
|
||||
|| ((__VALUE__) == LL_TIM_OCMODE_TOGGLE) \
|
||||
|| ((__VALUE__) == LL_TIM_OCMODE_FORCED_INACTIVE) \
|
||||
|| ((__VALUE__) == LL_TIM_OCMODE_FORCED_ACTIVE) \
|
||||
|| ((__VALUE__) == LL_TIM_OCMODE_PWM1) \
|
||||
|| ((__VALUE__) == LL_TIM_OCMODE_PWM2) \
|
||||
|| ((__VALUE__) == LL_TIM_OCMODE_RETRIG_OPM1) \
|
||||
|| ((__VALUE__) == LL_TIM_OCMODE_RETRIG_OPM2) \
|
||||
|| ((__VALUE__) == LL_TIM_OCMODE_COMBINED_PWM1) \
|
||||
|| ((__VALUE__) == LL_TIM_OCMODE_COMBINED_PWM2) \
|
||||
|| ((__VALUE__) == LL_TIM_OCMODE_ASSYMETRIC_PWM1) \
|
||||
|| ((__VALUE__) == LL_TIM_OCMODE_ASSYMETRIC_PWM2))
|
||||
|
||||
#define IS_LL_TIM_OCSTATE(__VALUE__) (((__VALUE__) == LL_TIM_OCSTATE_DISABLE) \
|
||||
|| ((__VALUE__) == LL_TIM_OCSTATE_ENABLE))
|
||||
|
||||
#define IS_LL_TIM_OCPOLARITY(__VALUE__) (((__VALUE__) == LL_TIM_OCPOLARITY_HIGH) \
|
||||
|| ((__VALUE__) == LL_TIM_OCPOLARITY_LOW))
|
||||
|
||||
#define IS_LL_TIM_OCIDLESTATE(__VALUE__) (((__VALUE__) == LL_TIM_OCIDLESTATE_LOW) \
|
||||
|| ((__VALUE__) == LL_TIM_OCIDLESTATE_HIGH))
|
||||
|
||||
#define IS_LL_TIM_ACTIVEINPUT(__VALUE__) (((__VALUE__) == LL_TIM_ACTIVEINPUT_DIRECTTI) \
|
||||
|| ((__VALUE__) == LL_TIM_ACTIVEINPUT_INDIRECTTI) \
|
||||
|| ((__VALUE__) == LL_TIM_ACTIVEINPUT_TRC))
|
||||
|
||||
#define IS_LL_TIM_ICPSC(__VALUE__) (((__VALUE__) == LL_TIM_ICPSC_DIV1) \
|
||||
|| ((__VALUE__) == LL_TIM_ICPSC_DIV2) \
|
||||
|| ((__VALUE__) == LL_TIM_ICPSC_DIV4) \
|
||||
|| ((__VALUE__) == LL_TIM_ICPSC_DIV8))
|
||||
|
||||
#define IS_LL_TIM_IC_FILTER(__VALUE__) (((__VALUE__) == LL_TIM_IC_FILTER_FDIV1) \
|
||||
|| ((__VALUE__) == LL_TIM_IC_FILTER_FDIV1_N2) \
|
||||
|| ((__VALUE__) == LL_TIM_IC_FILTER_FDIV1_N4) \
|
||||
|| ((__VALUE__) == LL_TIM_IC_FILTER_FDIV1_N8) \
|
||||
|| ((__VALUE__) == LL_TIM_IC_FILTER_FDIV2_N6) \
|
||||
|| ((__VALUE__) == LL_TIM_IC_FILTER_FDIV2_N8) \
|
||||
|| ((__VALUE__) == LL_TIM_IC_FILTER_FDIV4_N6) \
|
||||
|| ((__VALUE__) == LL_TIM_IC_FILTER_FDIV4_N8) \
|
||||
|| ((__VALUE__) == LL_TIM_IC_FILTER_FDIV8_N6) \
|
||||
|| ((__VALUE__) == LL_TIM_IC_FILTER_FDIV8_N8) \
|
||||
|| ((__VALUE__) == LL_TIM_IC_FILTER_FDIV16_N5) \
|
||||
|| ((__VALUE__) == LL_TIM_IC_FILTER_FDIV16_N6) \
|
||||
|| ((__VALUE__) == LL_TIM_IC_FILTER_FDIV16_N8) \
|
||||
|| ((__VALUE__) == LL_TIM_IC_FILTER_FDIV32_N5) \
|
||||
|| ((__VALUE__) == LL_TIM_IC_FILTER_FDIV32_N6) \
|
||||
|| ((__VALUE__) == LL_TIM_IC_FILTER_FDIV32_N8))
|
||||
|
||||
#define IS_LL_TIM_IC_POLARITY(__VALUE__) (((__VALUE__) == LL_TIM_IC_POLARITY_RISING) \
|
||||
|| ((__VALUE__) == LL_TIM_IC_POLARITY_FALLING) \
|
||||
|| ((__VALUE__) == LL_TIM_IC_POLARITY_BOTHEDGE))
|
||||
|
||||
#define IS_LL_TIM_ENCODERMODE(__VALUE__) (((__VALUE__) == LL_TIM_ENCODERMODE_X2_TI1) \
|
||||
|| ((__VALUE__) == LL_TIM_ENCODERMODE_X2_TI2) \
|
||||
|| ((__VALUE__) == LL_TIM_ENCODERMODE_X4_TI12))
|
||||
|
||||
#define IS_LL_TIM_IC_POLARITY_ENCODER(__VALUE__) (((__VALUE__) == LL_TIM_IC_POLARITY_RISING) \
|
||||
|| ((__VALUE__) == LL_TIM_IC_POLARITY_FALLING))
|
||||
|
||||
#define IS_LL_TIM_OSSR_STATE(__VALUE__) (((__VALUE__) == LL_TIM_OSSR_DISABLE) \
|
||||
|| ((__VALUE__) == LL_TIM_OSSR_ENABLE))
|
||||
|
||||
#define IS_LL_TIM_OSSI_STATE(__VALUE__) (((__VALUE__) == LL_TIM_OSSI_DISABLE) \
|
||||
|| ((__VALUE__) == LL_TIM_OSSI_ENABLE))
|
||||
|
||||
#define IS_LL_TIM_LOCK_LEVEL(__VALUE__) (((__VALUE__) == LL_TIM_LOCKLEVEL_OFF) \
|
||||
|| ((__VALUE__) == LL_TIM_LOCKLEVEL_1) \
|
||||
|| ((__VALUE__) == LL_TIM_LOCKLEVEL_2) \
|
||||
|| ((__VALUE__) == LL_TIM_LOCKLEVEL_3))
|
||||
|
||||
#define IS_LL_TIM_BREAK_STATE(__VALUE__) (((__VALUE__) == LL_TIM_BREAK_DISABLE) \
|
||||
|| ((__VALUE__) == LL_TIM_BREAK_ENABLE))
|
||||
|
||||
#define IS_LL_TIM_BREAK_POLARITY(__VALUE__) (((__VALUE__) == LL_TIM_BREAK_POLARITY_LOW) \
|
||||
|| ((__VALUE__) == LL_TIM_BREAK_POLARITY_HIGH))
|
||||
|
||||
#define IS_LL_TIM_BREAK_FILTER(__VALUE__) (((__VALUE__) == LL_TIM_BREAK_FILTER_FDIV1) \
|
||||
|| ((__VALUE__) == LL_TIM_BREAK_FILTER_FDIV1_N2) \
|
||||
|| ((__VALUE__) == LL_TIM_BREAK_FILTER_FDIV1_N4) \
|
||||
|| ((__VALUE__) == LL_TIM_BREAK_FILTER_FDIV1_N8) \
|
||||
|| ((__VALUE__) == LL_TIM_BREAK_FILTER_FDIV2_N6) \
|
||||
|| ((__VALUE__) == LL_TIM_BREAK_FILTER_FDIV2_N8) \
|
||||
|| ((__VALUE__) == LL_TIM_BREAK_FILTER_FDIV4_N6) \
|
||||
|| ((__VALUE__) == LL_TIM_BREAK_FILTER_FDIV4_N8) \
|
||||
|| ((__VALUE__) == LL_TIM_BREAK_FILTER_FDIV8_N6) \
|
||||
|| ((__VALUE__) == LL_TIM_BREAK_FILTER_FDIV8_N8) \
|
||||
|| ((__VALUE__) == LL_TIM_BREAK_FILTER_FDIV16_N5) \
|
||||
|| ((__VALUE__) == LL_TIM_BREAK_FILTER_FDIV16_N6) \
|
||||
|| ((__VALUE__) == LL_TIM_BREAK_FILTER_FDIV16_N8) \
|
||||
|| ((__VALUE__) == LL_TIM_BREAK_FILTER_FDIV32_N5) \
|
||||
|| ((__VALUE__) == LL_TIM_BREAK_FILTER_FDIV32_N6) \
|
||||
|| ((__VALUE__) == LL_TIM_BREAK_FILTER_FDIV32_N8))
|
||||
|
||||
#define IS_LL_TIM_BREAK2_STATE(__VALUE__) (((__VALUE__) == LL_TIM_BREAK2_DISABLE) \
|
||||
|| ((__VALUE__) == LL_TIM_BREAK2_ENABLE))
|
||||
|
||||
#define IS_LL_TIM_BREAK2_POLARITY(__VALUE__) (((__VALUE__) == LL_TIM_BREAK2_POLARITY_LOW) \
|
||||
|| ((__VALUE__) == LL_TIM_BREAK2_POLARITY_HIGH))
|
||||
|
||||
#define IS_LL_TIM_BREAK2_FILTER(__VALUE__) (((__VALUE__) == LL_TIM_BREAK2_FILTER_FDIV1) \
|
||||
|| ((__VALUE__) == LL_TIM_BREAK2_FILTER_FDIV1_N2) \
|
||||
|| ((__VALUE__) == LL_TIM_BREAK2_FILTER_FDIV1_N4) \
|
||||
|| ((__VALUE__) == LL_TIM_BREAK2_FILTER_FDIV1_N8) \
|
||||
|| ((__VALUE__) == LL_TIM_BREAK2_FILTER_FDIV2_N6) \
|
||||
|| ((__VALUE__) == LL_TIM_BREAK2_FILTER_FDIV2_N8) \
|
||||
|| ((__VALUE__) == LL_TIM_BREAK2_FILTER_FDIV4_N6) \
|
||||
|| ((__VALUE__) == LL_TIM_BREAK2_FILTER_FDIV4_N8) \
|
||||
|| ((__VALUE__) == LL_TIM_BREAK2_FILTER_FDIV8_N6) \
|
||||
|| ((__VALUE__) == LL_TIM_BREAK2_FILTER_FDIV8_N8) \
|
||||
|| ((__VALUE__) == LL_TIM_BREAK2_FILTER_FDIV16_N5) \
|
||||
|| ((__VALUE__) == LL_TIM_BREAK2_FILTER_FDIV16_N6) \
|
||||
|| ((__VALUE__) == LL_TIM_BREAK2_FILTER_FDIV16_N8) \
|
||||
|| ((__VALUE__) == LL_TIM_BREAK2_FILTER_FDIV32_N5) \
|
||||
|| ((__VALUE__) == LL_TIM_BREAK2_FILTER_FDIV32_N6) \
|
||||
|| ((__VALUE__) == LL_TIM_BREAK2_FILTER_FDIV32_N8))
|
||||
|
||||
#define IS_LL_TIM_AUTOMATIC_OUTPUT_STATE(__VALUE__) (((__VALUE__) == LL_TIM_AUTOMATICOUTPUT_DISABLE) \
|
||||
|| ((__VALUE__) == LL_TIM_AUTOMATICOUTPUT_ENABLE))
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/** @defgroup TIM_LL_Private_Functions TIM Private Functions
|
||||
* @{
|
||||
*/
|
||||
static ErrorStatus OC1Config(TIM_TypeDef *TIMx, LL_TIM_OC_InitTypeDef *TIM_OCInitStruct);
|
||||
static ErrorStatus OC2Config(TIM_TypeDef *TIMx, LL_TIM_OC_InitTypeDef *TIM_OCInitStruct);
|
||||
static ErrorStatus OC3Config(TIM_TypeDef *TIMx, LL_TIM_OC_InitTypeDef *TIM_OCInitStruct);
|
||||
static ErrorStatus OC4Config(TIM_TypeDef *TIMx, LL_TIM_OC_InitTypeDef *TIM_OCInitStruct);
|
||||
static ErrorStatus OC5Config(TIM_TypeDef *TIMx, LL_TIM_OC_InitTypeDef *TIM_OCInitStruct);
|
||||
static ErrorStatus OC6Config(TIM_TypeDef *TIMx, LL_TIM_OC_InitTypeDef *TIM_OCInitStruct);
|
||||
static ErrorStatus IC1Config(TIM_TypeDef *TIMx, LL_TIM_IC_InitTypeDef *TIM_ICInitStruct);
|
||||
static ErrorStatus IC2Config(TIM_TypeDef *TIMx, LL_TIM_IC_InitTypeDef *TIM_ICInitStruct);
|
||||
static ErrorStatus IC3Config(TIM_TypeDef *TIMx, LL_TIM_IC_InitTypeDef *TIM_ICInitStruct);
|
||||
static ErrorStatus IC4Config(TIM_TypeDef *TIMx, LL_TIM_IC_InitTypeDef *TIM_ICInitStruct);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Exported functions --------------------------------------------------------*/
|
||||
/** @addtogroup TIM_LL_Exported_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup TIM_LL_EF_Init
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Set TIMx registers to their reset values.
|
||||
* @param TIMx Timer instance
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: TIMx registers are de-initialized
|
||||
* - ERROR: invalid TIMx instance
|
||||
*/
|
||||
ErrorStatus LL_TIM_DeInit(TIM_TypeDef *TIMx)
|
||||
{
|
||||
ErrorStatus result = SUCCESS;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_INSTANCE(TIMx));
|
||||
|
||||
if (TIMx == TIM1)
|
||||
{
|
||||
LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_TIM1);
|
||||
LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_TIM1);
|
||||
}
|
||||
else if (TIMx == TIM2)
|
||||
{
|
||||
LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_TIM2);
|
||||
LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_TIM2);
|
||||
}
|
||||
#if defined(TIM3)
|
||||
else if (TIMx == TIM3)
|
||||
{
|
||||
LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_TIM3);
|
||||
LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_TIM3);
|
||||
}
|
||||
#endif /* TIM3 */
|
||||
#if defined(TIM4)
|
||||
else if (TIMx == TIM4)
|
||||
{
|
||||
LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_TIM4);
|
||||
LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_TIM4);
|
||||
}
|
||||
#endif /* TIM4 */
|
||||
#if defined(TIM5)
|
||||
else if (TIMx == TIM5)
|
||||
{
|
||||
LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_TIM5);
|
||||
LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_TIM5);
|
||||
}
|
||||
#endif /* TIM5 */
|
||||
else if (TIMx == TIM6)
|
||||
{
|
||||
LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_TIM6);
|
||||
LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_TIM6);
|
||||
}
|
||||
#if defined (TIM7)
|
||||
else if (TIMx == TIM7)
|
||||
{
|
||||
LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_TIM7);
|
||||
LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_TIM7);
|
||||
}
|
||||
#endif /* TIM7 */
|
||||
#if defined(TIM8)
|
||||
else if (TIMx == TIM8)
|
||||
{
|
||||
LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_TIM8);
|
||||
LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_TIM8);
|
||||
}
|
||||
#endif /* TIM8 */
|
||||
else if (TIMx == TIM15)
|
||||
{
|
||||
LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_TIM15);
|
||||
LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_TIM15);
|
||||
}
|
||||
else if (TIMx == TIM16)
|
||||
{
|
||||
LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_TIM16);
|
||||
LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_TIM16);
|
||||
}
|
||||
#if defined(TIM17)
|
||||
else if (TIMx == TIM17)
|
||||
{
|
||||
LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_TIM17);
|
||||
LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_TIM17);
|
||||
}
|
||||
#endif /* TIM17 */
|
||||
else
|
||||
{
|
||||
result = ERROR;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the fields of the time base unit configuration data structure
|
||||
* to their default values.
|
||||
* @param TIM_InitStruct pointer to a @ref LL_TIM_InitTypeDef structure (time base unit configuration data structure)
|
||||
* @retval None
|
||||
*/
|
||||
void LL_TIM_StructInit(LL_TIM_InitTypeDef *TIM_InitStruct)
|
||||
{
|
||||
/* Set the default configuration */
|
||||
TIM_InitStruct->Prescaler = (uint16_t)0x0000;
|
||||
TIM_InitStruct->CounterMode = LL_TIM_COUNTERMODE_UP;
|
||||
TIM_InitStruct->Autoreload = 0xFFFFFFFFU;
|
||||
TIM_InitStruct->ClockDivision = LL_TIM_CLOCKDIVISION_DIV1;
|
||||
TIM_InitStruct->RepetitionCounter = 0x00000000U;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure the TIMx time base unit.
|
||||
* @param TIMx Timer Instance
|
||||
* @param TIM_InitStruct pointer to a @ref LL_TIM_InitTypeDef structure
|
||||
* (TIMx time base unit configuration data structure)
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: TIMx registers are de-initialized
|
||||
* - ERROR: not applicable
|
||||
*/
|
||||
ErrorStatus LL_TIM_Init(TIM_TypeDef *TIMx, LL_TIM_InitTypeDef *TIM_InitStruct)
|
||||
{
|
||||
uint32_t tmpcr1;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_INSTANCE(TIMx));
|
||||
assert_param(IS_LL_TIM_COUNTERMODE(TIM_InitStruct->CounterMode));
|
||||
assert_param(IS_LL_TIM_CLOCKDIVISION(TIM_InitStruct->ClockDivision));
|
||||
|
||||
tmpcr1 = LL_TIM_ReadReg(TIMx, CR1);
|
||||
|
||||
if (IS_TIM_COUNTER_MODE_SELECT_INSTANCE(TIMx))
|
||||
{
|
||||
/* Select the Counter Mode */
|
||||
MODIFY_REG(tmpcr1, (TIM_CR1_DIR | TIM_CR1_CMS), TIM_InitStruct->CounterMode);
|
||||
}
|
||||
|
||||
if (IS_TIM_CLOCK_DIVISION_INSTANCE(TIMx))
|
||||
{
|
||||
/* Set the clock division */
|
||||
MODIFY_REG(tmpcr1, TIM_CR1_CKD, TIM_InitStruct->ClockDivision);
|
||||
}
|
||||
|
||||
/* Write to TIMx CR1 */
|
||||
LL_TIM_WriteReg(TIMx, CR1, tmpcr1);
|
||||
|
||||
/* Set the Autoreload value */
|
||||
LL_TIM_SetAutoReload(TIMx, TIM_InitStruct->Autoreload);
|
||||
|
||||
/* Set the Prescaler value */
|
||||
LL_TIM_SetPrescaler(TIMx, TIM_InitStruct->Prescaler);
|
||||
|
||||
if (IS_TIM_REPETITION_COUNTER_INSTANCE(TIMx))
|
||||
{
|
||||
/* Set the Repetition Counter value */
|
||||
LL_TIM_SetRepetitionCounter(TIMx, TIM_InitStruct->RepetitionCounter);
|
||||
}
|
||||
|
||||
/* Generate an update event to reload the Prescaler
|
||||
and the repetition counter value (if applicable) immediately */
|
||||
LL_TIM_GenerateEvent_UPDATE(TIMx);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the fields of the TIMx output channel configuration data
|
||||
* structure to their default values.
|
||||
* @param TIM_OC_InitStruct pointer to a @ref LL_TIM_OC_InitTypeDef structure
|
||||
* (the output channel configuration data structure)
|
||||
* @retval None
|
||||
*/
|
||||
void LL_TIM_OC_StructInit(LL_TIM_OC_InitTypeDef *TIM_OC_InitStruct)
|
||||
{
|
||||
/* Set the default configuration */
|
||||
TIM_OC_InitStruct->OCMode = LL_TIM_OCMODE_FROZEN;
|
||||
TIM_OC_InitStruct->OCState = LL_TIM_OCSTATE_DISABLE;
|
||||
TIM_OC_InitStruct->OCNState = LL_TIM_OCSTATE_DISABLE;
|
||||
TIM_OC_InitStruct->CompareValue = 0x00000000U;
|
||||
TIM_OC_InitStruct->OCPolarity = LL_TIM_OCPOLARITY_HIGH;
|
||||
TIM_OC_InitStruct->OCNPolarity = LL_TIM_OCPOLARITY_HIGH;
|
||||
TIM_OC_InitStruct->OCIdleState = LL_TIM_OCIDLESTATE_LOW;
|
||||
TIM_OC_InitStruct->OCNIdleState = LL_TIM_OCIDLESTATE_LOW;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure the TIMx output channel.
|
||||
* @param TIMx Timer Instance
|
||||
* @param Channel This parameter can be one of the following values:
|
||||
* @arg @ref LL_TIM_CHANNEL_CH1
|
||||
* @arg @ref LL_TIM_CHANNEL_CH2
|
||||
* @arg @ref LL_TIM_CHANNEL_CH3
|
||||
* @arg @ref LL_TIM_CHANNEL_CH4
|
||||
* @arg @ref LL_TIM_CHANNEL_CH5
|
||||
* @arg @ref LL_TIM_CHANNEL_CH6
|
||||
* @param TIM_OC_InitStruct pointer to a @ref LL_TIM_OC_InitTypeDef structure (TIMx output channel configuration
|
||||
* data structure)
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: TIMx output channel is initialized
|
||||
* - ERROR: TIMx output channel is not initialized
|
||||
*/
|
||||
ErrorStatus LL_TIM_OC_Init(TIM_TypeDef *TIMx, uint32_t Channel, LL_TIM_OC_InitTypeDef *TIM_OC_InitStruct)
|
||||
{
|
||||
ErrorStatus result = ERROR;
|
||||
|
||||
switch (Channel)
|
||||
{
|
||||
case LL_TIM_CHANNEL_CH1:
|
||||
result = OC1Config(TIMx, TIM_OC_InitStruct);
|
||||
break;
|
||||
case LL_TIM_CHANNEL_CH2:
|
||||
result = OC2Config(TIMx, TIM_OC_InitStruct);
|
||||
break;
|
||||
case LL_TIM_CHANNEL_CH3:
|
||||
result = OC3Config(TIMx, TIM_OC_InitStruct);
|
||||
break;
|
||||
case LL_TIM_CHANNEL_CH4:
|
||||
result = OC4Config(TIMx, TIM_OC_InitStruct);
|
||||
break;
|
||||
case LL_TIM_CHANNEL_CH5:
|
||||
result = OC5Config(TIMx, TIM_OC_InitStruct);
|
||||
break;
|
||||
case LL_TIM_CHANNEL_CH6:
|
||||
result = OC6Config(TIMx, TIM_OC_InitStruct);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the fields of the TIMx input channel configuration data
|
||||
* structure to their default values.
|
||||
* @param TIM_ICInitStruct pointer to a @ref LL_TIM_IC_InitTypeDef structure (the input channel configuration
|
||||
* data structure)
|
||||
* @retval None
|
||||
*/
|
||||
void LL_TIM_IC_StructInit(LL_TIM_IC_InitTypeDef *TIM_ICInitStruct)
|
||||
{
|
||||
/* Set the default configuration */
|
||||
TIM_ICInitStruct->ICPolarity = LL_TIM_IC_POLARITY_RISING;
|
||||
TIM_ICInitStruct->ICActiveInput = LL_TIM_ACTIVEINPUT_DIRECTTI;
|
||||
TIM_ICInitStruct->ICPrescaler = LL_TIM_ICPSC_DIV1;
|
||||
TIM_ICInitStruct->ICFilter = LL_TIM_IC_FILTER_FDIV1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure the TIMx input channel.
|
||||
* @param TIMx Timer Instance
|
||||
* @param Channel This parameter can be one of the following values:
|
||||
* @arg @ref LL_TIM_CHANNEL_CH1
|
||||
* @arg @ref LL_TIM_CHANNEL_CH2
|
||||
* @arg @ref LL_TIM_CHANNEL_CH3
|
||||
* @arg @ref LL_TIM_CHANNEL_CH4
|
||||
* @param TIM_IC_InitStruct pointer to a @ref LL_TIM_IC_InitTypeDef structure (TIMx input channel configuration data
|
||||
* structure)
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: TIMx output channel is initialized
|
||||
* - ERROR: TIMx output channel is not initialized
|
||||
*/
|
||||
ErrorStatus LL_TIM_IC_Init(TIM_TypeDef *TIMx, uint32_t Channel, LL_TIM_IC_InitTypeDef *TIM_IC_InitStruct)
|
||||
{
|
||||
ErrorStatus result = ERROR;
|
||||
|
||||
switch (Channel)
|
||||
{
|
||||
case LL_TIM_CHANNEL_CH1:
|
||||
result = IC1Config(TIMx, TIM_IC_InitStruct);
|
||||
break;
|
||||
case LL_TIM_CHANNEL_CH2:
|
||||
result = IC2Config(TIMx, TIM_IC_InitStruct);
|
||||
break;
|
||||
case LL_TIM_CHANNEL_CH3:
|
||||
result = IC3Config(TIMx, TIM_IC_InitStruct);
|
||||
break;
|
||||
case LL_TIM_CHANNEL_CH4:
|
||||
result = IC4Config(TIMx, TIM_IC_InitStruct);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Fills each TIM_EncoderInitStruct field with its default value
|
||||
* @param TIM_EncoderInitStruct pointer to a @ref LL_TIM_ENCODER_InitTypeDef structure (encoder interface
|
||||
* configuration data structure)
|
||||
* @retval None
|
||||
*/
|
||||
void LL_TIM_ENCODER_StructInit(LL_TIM_ENCODER_InitTypeDef *TIM_EncoderInitStruct)
|
||||
{
|
||||
/* Set the default configuration */
|
||||
TIM_EncoderInitStruct->EncoderMode = LL_TIM_ENCODERMODE_X2_TI1;
|
||||
TIM_EncoderInitStruct->IC1Polarity = LL_TIM_IC_POLARITY_RISING;
|
||||
TIM_EncoderInitStruct->IC1ActiveInput = LL_TIM_ACTIVEINPUT_DIRECTTI;
|
||||
TIM_EncoderInitStruct->IC1Prescaler = LL_TIM_ICPSC_DIV1;
|
||||
TIM_EncoderInitStruct->IC1Filter = LL_TIM_IC_FILTER_FDIV1;
|
||||
TIM_EncoderInitStruct->IC2Polarity = LL_TIM_IC_POLARITY_RISING;
|
||||
TIM_EncoderInitStruct->IC2ActiveInput = LL_TIM_ACTIVEINPUT_DIRECTTI;
|
||||
TIM_EncoderInitStruct->IC2Prescaler = LL_TIM_ICPSC_DIV1;
|
||||
TIM_EncoderInitStruct->IC2Filter = LL_TIM_IC_FILTER_FDIV1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure the encoder interface of the timer instance.
|
||||
* @param TIMx Timer Instance
|
||||
* @param TIM_EncoderInitStruct pointer to a @ref LL_TIM_ENCODER_InitTypeDef structure (TIMx encoder interface
|
||||
* configuration data structure)
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: TIMx registers are de-initialized
|
||||
* - ERROR: not applicable
|
||||
*/
|
||||
ErrorStatus LL_TIM_ENCODER_Init(TIM_TypeDef *TIMx, LL_TIM_ENCODER_InitTypeDef *TIM_EncoderInitStruct)
|
||||
{
|
||||
uint32_t tmpccmr1;
|
||||
uint32_t tmpccer;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_ENCODER_INTERFACE_INSTANCE(TIMx));
|
||||
assert_param(IS_LL_TIM_ENCODERMODE(TIM_EncoderInitStruct->EncoderMode));
|
||||
assert_param(IS_LL_TIM_IC_POLARITY_ENCODER(TIM_EncoderInitStruct->IC1Polarity));
|
||||
assert_param(IS_LL_TIM_ACTIVEINPUT(TIM_EncoderInitStruct->IC1ActiveInput));
|
||||
assert_param(IS_LL_TIM_ICPSC(TIM_EncoderInitStruct->IC1Prescaler));
|
||||
assert_param(IS_LL_TIM_IC_FILTER(TIM_EncoderInitStruct->IC1Filter));
|
||||
assert_param(IS_LL_TIM_IC_POLARITY_ENCODER(TIM_EncoderInitStruct->IC2Polarity));
|
||||
assert_param(IS_LL_TIM_ACTIVEINPUT(TIM_EncoderInitStruct->IC2ActiveInput));
|
||||
assert_param(IS_LL_TIM_ICPSC(TIM_EncoderInitStruct->IC2Prescaler));
|
||||
assert_param(IS_LL_TIM_IC_FILTER(TIM_EncoderInitStruct->IC2Filter));
|
||||
|
||||
/* Disable the CC1 and CC2: Reset the CC1E and CC2E Bits */
|
||||
TIMx->CCER &= (uint32_t)~(TIM_CCER_CC1E | TIM_CCER_CC2E);
|
||||
|
||||
/* Get the TIMx CCMR1 register value */
|
||||
tmpccmr1 = LL_TIM_ReadReg(TIMx, CCMR1);
|
||||
|
||||
/* Get the TIMx CCER register value */
|
||||
tmpccer = LL_TIM_ReadReg(TIMx, CCER);
|
||||
|
||||
/* Configure TI1 */
|
||||
tmpccmr1 &= (uint32_t)~(TIM_CCMR1_CC1S | TIM_CCMR1_IC1F | TIM_CCMR1_IC1PSC);
|
||||
tmpccmr1 |= (uint32_t)(TIM_EncoderInitStruct->IC1ActiveInput >> 16U);
|
||||
tmpccmr1 |= (uint32_t)(TIM_EncoderInitStruct->IC1Filter >> 16U);
|
||||
tmpccmr1 |= (uint32_t)(TIM_EncoderInitStruct->IC1Prescaler >> 16U);
|
||||
|
||||
/* Configure TI2 */
|
||||
tmpccmr1 &= (uint32_t)~(TIM_CCMR1_CC2S | TIM_CCMR1_IC2F | TIM_CCMR1_IC2PSC);
|
||||
tmpccmr1 |= (uint32_t)(TIM_EncoderInitStruct->IC2ActiveInput >> 8U);
|
||||
tmpccmr1 |= (uint32_t)(TIM_EncoderInitStruct->IC2Filter >> 8U);
|
||||
tmpccmr1 |= (uint32_t)(TIM_EncoderInitStruct->IC2Prescaler >> 8U);
|
||||
|
||||
/* Set TI1 and TI2 polarity and enable TI1 and TI2 */
|
||||
tmpccer &= (uint32_t)~(TIM_CCER_CC1P | TIM_CCER_CC1NP | TIM_CCER_CC2P | TIM_CCER_CC2NP);
|
||||
tmpccer |= (uint32_t)(TIM_EncoderInitStruct->IC1Polarity);
|
||||
tmpccer |= (uint32_t)(TIM_EncoderInitStruct->IC2Polarity << 4U);
|
||||
tmpccer |= (uint32_t)(TIM_CCER_CC1E | TIM_CCER_CC2E);
|
||||
|
||||
/* Set encoder mode */
|
||||
LL_TIM_SetEncoderMode(TIMx, TIM_EncoderInitStruct->EncoderMode);
|
||||
|
||||
/* Write to TIMx CCMR1 */
|
||||
LL_TIM_WriteReg(TIMx, CCMR1, tmpccmr1);
|
||||
|
||||
/* Write to TIMx CCER */
|
||||
LL_TIM_WriteReg(TIMx, CCER, tmpccer);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the fields of the TIMx Hall sensor interface configuration data
|
||||
* structure to their default values.
|
||||
* @param TIM_HallSensorInitStruct pointer to a @ref LL_TIM_HALLSENSOR_InitTypeDef structure (HALL sensor interface
|
||||
* configuration data structure)
|
||||
* @retval None
|
||||
*/
|
||||
void LL_TIM_HALLSENSOR_StructInit(LL_TIM_HALLSENSOR_InitTypeDef *TIM_HallSensorInitStruct)
|
||||
{
|
||||
/* Set the default configuration */
|
||||
TIM_HallSensorInitStruct->IC1Polarity = LL_TIM_IC_POLARITY_RISING;
|
||||
TIM_HallSensorInitStruct->IC1Prescaler = LL_TIM_ICPSC_DIV1;
|
||||
TIM_HallSensorInitStruct->IC1Filter = LL_TIM_IC_FILTER_FDIV1;
|
||||
TIM_HallSensorInitStruct->CommutationDelay = 0U;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure the Hall sensor interface of the timer instance.
|
||||
* @note TIMx CH1, CH2 and CH3 inputs connected through a XOR
|
||||
* to the TI1 input channel
|
||||
* @note TIMx slave mode controller is configured in reset mode.
|
||||
Selected internal trigger is TI1F_ED.
|
||||
* @note Channel 1 is configured as input, IC1 is mapped on TRC.
|
||||
* @note Captured value stored in TIMx_CCR1 correspond to the time elapsed
|
||||
* between 2 changes on the inputs. It gives information about motor speed.
|
||||
* @note Channel 2 is configured in output PWM 2 mode.
|
||||
* @note Compare value stored in TIMx_CCR2 corresponds to the commutation delay.
|
||||
* @note OC2REF is selected as trigger output on TRGO.
|
||||
* @note LL_TIM_IC_POLARITY_BOTHEDGE must not be used for TI1 when it is used
|
||||
* when TIMx operates in Hall sensor interface mode.
|
||||
* @param TIMx Timer Instance
|
||||
* @param TIM_HallSensorInitStruct pointer to a @ref LL_TIM_HALLSENSOR_InitTypeDef structure (TIMx HALL sensor
|
||||
* interface configuration data structure)
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: TIMx registers are de-initialized
|
||||
* - ERROR: not applicable
|
||||
*/
|
||||
ErrorStatus LL_TIM_HALLSENSOR_Init(TIM_TypeDef *TIMx, LL_TIM_HALLSENSOR_InitTypeDef *TIM_HallSensorInitStruct)
|
||||
{
|
||||
uint32_t tmpcr2;
|
||||
uint32_t tmpccmr1;
|
||||
uint32_t tmpccer;
|
||||
uint32_t tmpsmcr;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_HALL_SENSOR_INTERFACE_INSTANCE(TIMx));
|
||||
assert_param(IS_LL_TIM_IC_POLARITY_ENCODER(TIM_HallSensorInitStruct->IC1Polarity));
|
||||
assert_param(IS_LL_TIM_ICPSC(TIM_HallSensorInitStruct->IC1Prescaler));
|
||||
assert_param(IS_LL_TIM_IC_FILTER(TIM_HallSensorInitStruct->IC1Filter));
|
||||
|
||||
/* Disable the CC1 and CC2: Reset the CC1E and CC2E Bits */
|
||||
TIMx->CCER &= (uint32_t)~(TIM_CCER_CC1E | TIM_CCER_CC2E);
|
||||
|
||||
/* Get the TIMx CR2 register value */
|
||||
tmpcr2 = LL_TIM_ReadReg(TIMx, CR2);
|
||||
|
||||
/* Get the TIMx CCMR1 register value */
|
||||
tmpccmr1 = LL_TIM_ReadReg(TIMx, CCMR1);
|
||||
|
||||
/* Get the TIMx CCER register value */
|
||||
tmpccer = LL_TIM_ReadReg(TIMx, CCER);
|
||||
|
||||
/* Get the TIMx SMCR register value */
|
||||
tmpsmcr = LL_TIM_ReadReg(TIMx, SMCR);
|
||||
|
||||
/* Connect TIMx_CH1, CH2 and CH3 pins to the TI1 input */
|
||||
tmpcr2 |= TIM_CR2_TI1S;
|
||||
|
||||
/* OC2REF signal is used as trigger output (TRGO) */
|
||||
tmpcr2 |= LL_TIM_TRGO_OC2REF;
|
||||
|
||||
/* Configure the slave mode controller */
|
||||
tmpsmcr &= (uint32_t)~(TIM_SMCR_TS | TIM_SMCR_SMS);
|
||||
tmpsmcr |= LL_TIM_TS_TI1F_ED;
|
||||
tmpsmcr |= LL_TIM_SLAVEMODE_RESET;
|
||||
|
||||
/* Configure input channel 1 */
|
||||
tmpccmr1 &= (uint32_t)~(TIM_CCMR1_CC1S | TIM_CCMR1_IC1F | TIM_CCMR1_IC1PSC);
|
||||
tmpccmr1 |= (uint32_t)(LL_TIM_ACTIVEINPUT_TRC >> 16U);
|
||||
tmpccmr1 |= (uint32_t)(TIM_HallSensorInitStruct->IC1Filter >> 16U);
|
||||
tmpccmr1 |= (uint32_t)(TIM_HallSensorInitStruct->IC1Prescaler >> 16U);
|
||||
|
||||
/* Configure input channel 2 */
|
||||
tmpccmr1 &= (uint32_t)~(TIM_CCMR1_OC2M | TIM_CCMR1_OC2FE | TIM_CCMR1_OC2PE | TIM_CCMR1_OC2CE);
|
||||
tmpccmr1 |= (uint32_t)(LL_TIM_OCMODE_PWM2 << 8U);
|
||||
|
||||
/* Set Channel 1 polarity and enable Channel 1 and Channel2 */
|
||||
tmpccer &= (uint32_t)~(TIM_CCER_CC1P | TIM_CCER_CC1NP | TIM_CCER_CC2P | TIM_CCER_CC2NP);
|
||||
tmpccer |= (uint32_t)(TIM_HallSensorInitStruct->IC1Polarity);
|
||||
tmpccer |= (uint32_t)(TIM_CCER_CC1E | TIM_CCER_CC2E);
|
||||
|
||||
/* Write to TIMx CR2 */
|
||||
LL_TIM_WriteReg(TIMx, CR2, tmpcr2);
|
||||
|
||||
/* Write to TIMx SMCR */
|
||||
LL_TIM_WriteReg(TIMx, SMCR, tmpsmcr);
|
||||
|
||||
/* Write to TIMx CCMR1 */
|
||||
LL_TIM_WriteReg(TIMx, CCMR1, tmpccmr1);
|
||||
|
||||
/* Write to TIMx CCER */
|
||||
LL_TIM_WriteReg(TIMx, CCER, tmpccer);
|
||||
|
||||
/* Write to TIMx CCR2 */
|
||||
LL_TIM_OC_SetCompareCH2(TIMx, TIM_HallSensorInitStruct->CommutationDelay);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the fields of the Break and Dead Time configuration data structure
|
||||
* to their default values.
|
||||
* @param TIM_BDTRInitStruct pointer to a @ref LL_TIM_BDTR_InitTypeDef structure (Break and Dead Time configuration
|
||||
* data structure)
|
||||
* @retval None
|
||||
*/
|
||||
void LL_TIM_BDTR_StructInit(LL_TIM_BDTR_InitTypeDef *TIM_BDTRInitStruct)
|
||||
{
|
||||
/* Set the default configuration */
|
||||
TIM_BDTRInitStruct->OSSRState = LL_TIM_OSSR_DISABLE;
|
||||
TIM_BDTRInitStruct->OSSIState = LL_TIM_OSSI_DISABLE;
|
||||
TIM_BDTRInitStruct->LockLevel = LL_TIM_LOCKLEVEL_OFF;
|
||||
TIM_BDTRInitStruct->DeadTime = (uint8_t)0x00;
|
||||
TIM_BDTRInitStruct->BreakState = LL_TIM_BREAK_DISABLE;
|
||||
TIM_BDTRInitStruct->BreakPolarity = LL_TIM_BREAK_POLARITY_LOW;
|
||||
TIM_BDTRInitStruct->BreakFilter = LL_TIM_BREAK_FILTER_FDIV1;
|
||||
TIM_BDTRInitStruct->Break2State = LL_TIM_BREAK2_DISABLE;
|
||||
TIM_BDTRInitStruct->Break2Polarity = LL_TIM_BREAK2_POLARITY_LOW;
|
||||
TIM_BDTRInitStruct->Break2Filter = LL_TIM_BREAK2_FILTER_FDIV1;
|
||||
TIM_BDTRInitStruct->AutomaticOutput = LL_TIM_AUTOMATICOUTPUT_DISABLE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure the Break and Dead Time feature of the timer instance.
|
||||
* @note As the bits BK2P, BK2E, BK2F[3:0], BKF[3:0], AOE, BKP, BKE, OSSI, OSSR
|
||||
* and DTG[7:0] can be write-locked depending on the LOCK configuration, it
|
||||
* can be necessary to configure all of them during the first write access to
|
||||
* the TIMx_BDTR register.
|
||||
* @note Macro IS_TIM_BREAK_INSTANCE(TIMx) can be used to check whether or not
|
||||
* a timer instance provides a break input.
|
||||
* @note Macro IS_TIM_BKIN2_INSTANCE(TIMx) can be used to check whether or not
|
||||
* a timer instance provides a second break input.
|
||||
* @param TIMx Timer Instance
|
||||
* @param TIM_BDTRInitStruct pointer to a @ref LL_TIM_BDTR_InitTypeDef structure (Break and Dead Time configuration
|
||||
* data structure)
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: Break and Dead Time is initialized
|
||||
* - ERROR: not applicable
|
||||
*/
|
||||
ErrorStatus LL_TIM_BDTR_Init(TIM_TypeDef *TIMx, LL_TIM_BDTR_InitTypeDef *TIM_BDTRInitStruct)
|
||||
{
|
||||
uint32_t tmpbdtr = 0;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_BREAK_INSTANCE(TIMx));
|
||||
assert_param(IS_LL_TIM_OSSR_STATE(TIM_BDTRInitStruct->OSSRState));
|
||||
assert_param(IS_LL_TIM_OSSI_STATE(TIM_BDTRInitStruct->OSSIState));
|
||||
assert_param(IS_LL_TIM_LOCK_LEVEL(TIM_BDTRInitStruct->LockLevel));
|
||||
assert_param(IS_LL_TIM_BREAK_STATE(TIM_BDTRInitStruct->BreakState));
|
||||
assert_param(IS_LL_TIM_BREAK_POLARITY(TIM_BDTRInitStruct->BreakPolarity));
|
||||
assert_param(IS_LL_TIM_AUTOMATIC_OUTPUT_STATE(TIM_BDTRInitStruct->AutomaticOutput));
|
||||
|
||||
/* Set the Lock level, the Break enable Bit and the Polarity, the OSSR State,
|
||||
the OSSI State, the dead time value and the Automatic Output Enable Bit */
|
||||
|
||||
/* Set the BDTR bits */
|
||||
MODIFY_REG(tmpbdtr, TIM_BDTR_DTG, TIM_BDTRInitStruct->DeadTime);
|
||||
MODIFY_REG(tmpbdtr, TIM_BDTR_LOCK, TIM_BDTRInitStruct->LockLevel);
|
||||
MODIFY_REG(tmpbdtr, TIM_BDTR_OSSI, TIM_BDTRInitStruct->OSSIState);
|
||||
MODIFY_REG(tmpbdtr, TIM_BDTR_OSSR, TIM_BDTRInitStruct->OSSRState);
|
||||
MODIFY_REG(tmpbdtr, TIM_BDTR_BKE, TIM_BDTRInitStruct->BreakState);
|
||||
MODIFY_REG(tmpbdtr, TIM_BDTR_BKP, TIM_BDTRInitStruct->BreakPolarity);
|
||||
MODIFY_REG(tmpbdtr, TIM_BDTR_AOE, TIM_BDTRInitStruct->AutomaticOutput);
|
||||
MODIFY_REG(tmpbdtr, TIM_BDTR_MOE, TIM_BDTRInitStruct->AutomaticOutput);
|
||||
if (IS_TIM_ADVANCED_INSTANCE(TIMx))
|
||||
{
|
||||
assert_param(IS_LL_TIM_BREAK_FILTER(TIM_BDTRInitStruct->BreakFilter));
|
||||
MODIFY_REG(tmpbdtr, TIM_BDTR_BKF, TIM_BDTRInitStruct->BreakFilter);
|
||||
}
|
||||
|
||||
if (IS_TIM_BKIN2_INSTANCE(TIMx))
|
||||
{
|
||||
assert_param(IS_LL_TIM_BREAK2_STATE(TIM_BDTRInitStruct->Break2State));
|
||||
assert_param(IS_LL_TIM_BREAK2_POLARITY(TIM_BDTRInitStruct->Break2Polarity));
|
||||
assert_param(IS_LL_TIM_BREAK2_FILTER(TIM_BDTRInitStruct->Break2Filter));
|
||||
|
||||
/* Set the BREAK2 input related BDTR bit-fields */
|
||||
MODIFY_REG(tmpbdtr, TIM_BDTR_BK2F, (TIM_BDTRInitStruct->Break2Filter));
|
||||
MODIFY_REG(tmpbdtr, TIM_BDTR_BK2E, TIM_BDTRInitStruct->Break2State);
|
||||
MODIFY_REG(tmpbdtr, TIM_BDTR_BK2P, TIM_BDTRInitStruct->Break2Polarity);
|
||||
}
|
||||
|
||||
/* Set TIMx_BDTR */
|
||||
LL_TIM_WriteReg(TIMx, BDTR, tmpbdtr);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup TIM_LL_Private_Functions TIM Private Functions
|
||||
* @brief Private functions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Configure the TIMx output channel 1.
|
||||
* @param TIMx Timer Instance
|
||||
* @param TIM_OCInitStruct pointer to the the TIMx output channel 1 configuration data structure
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: TIMx registers are de-initialized
|
||||
* - ERROR: not applicable
|
||||
*/
|
||||
static ErrorStatus OC1Config(TIM_TypeDef *TIMx, LL_TIM_OC_InitTypeDef *TIM_OCInitStruct)
|
||||
{
|
||||
uint32_t tmpccmr1;
|
||||
uint32_t tmpccer;
|
||||
uint32_t tmpcr2;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_CC1_INSTANCE(TIMx));
|
||||
assert_param(IS_LL_TIM_OCMODE(TIM_OCInitStruct->OCMode));
|
||||
assert_param(IS_LL_TIM_OCSTATE(TIM_OCInitStruct->OCState));
|
||||
assert_param(IS_LL_TIM_OCPOLARITY(TIM_OCInitStruct->OCPolarity));
|
||||
assert_param(IS_LL_TIM_OCSTATE(TIM_OCInitStruct->OCNState));
|
||||
assert_param(IS_LL_TIM_OCPOLARITY(TIM_OCInitStruct->OCNPolarity));
|
||||
|
||||
/* Disable the Channel 1: Reset the CC1E Bit */
|
||||
CLEAR_BIT(TIMx->CCER, TIM_CCER_CC1E);
|
||||
|
||||
/* Get the TIMx CCER register value */
|
||||
tmpccer = LL_TIM_ReadReg(TIMx, CCER);
|
||||
|
||||
/* Get the TIMx CR2 register value */
|
||||
tmpcr2 = LL_TIM_ReadReg(TIMx, CR2);
|
||||
|
||||
/* Get the TIMx CCMR1 register value */
|
||||
tmpccmr1 = LL_TIM_ReadReg(TIMx, CCMR1);
|
||||
|
||||
/* Reset Capture/Compare selection Bits */
|
||||
CLEAR_BIT(tmpccmr1, TIM_CCMR1_CC1S);
|
||||
|
||||
/* Set the Output Compare Mode */
|
||||
MODIFY_REG(tmpccmr1, TIM_CCMR1_OC1M, TIM_OCInitStruct->OCMode);
|
||||
|
||||
/* Set the Output Compare Polarity */
|
||||
MODIFY_REG(tmpccer, TIM_CCER_CC1P, TIM_OCInitStruct->OCPolarity);
|
||||
|
||||
/* Set the Output State */
|
||||
MODIFY_REG(tmpccer, TIM_CCER_CC1E, TIM_OCInitStruct->OCState);
|
||||
|
||||
if (IS_TIM_BREAK_INSTANCE(TIMx))
|
||||
{
|
||||
assert_param(IS_LL_TIM_OCIDLESTATE(TIM_OCInitStruct->OCNIdleState));
|
||||
assert_param(IS_LL_TIM_OCIDLESTATE(TIM_OCInitStruct->OCIdleState));
|
||||
|
||||
/* Set the complementary output Polarity */
|
||||
MODIFY_REG(tmpccer, TIM_CCER_CC1NP, TIM_OCInitStruct->OCNPolarity << 2U);
|
||||
|
||||
/* Set the complementary output State */
|
||||
MODIFY_REG(tmpccer, TIM_CCER_CC1NE, TIM_OCInitStruct->OCNState << 2U);
|
||||
|
||||
/* Set the Output Idle state */
|
||||
MODIFY_REG(tmpcr2, TIM_CR2_OIS1, TIM_OCInitStruct->OCIdleState);
|
||||
|
||||
/* Set the complementary output Idle state */
|
||||
MODIFY_REG(tmpcr2, TIM_CR2_OIS1N, TIM_OCInitStruct->OCNIdleState << 1U);
|
||||
}
|
||||
|
||||
/* Write to TIMx CR2 */
|
||||
LL_TIM_WriteReg(TIMx, CR2, tmpcr2);
|
||||
|
||||
/* Write to TIMx CCMR1 */
|
||||
LL_TIM_WriteReg(TIMx, CCMR1, tmpccmr1);
|
||||
|
||||
/* Set the Capture Compare Register value */
|
||||
LL_TIM_OC_SetCompareCH1(TIMx, TIM_OCInitStruct->CompareValue);
|
||||
|
||||
/* Write to TIMx CCER */
|
||||
LL_TIM_WriteReg(TIMx, CCER, tmpccer);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure the TIMx output channel 2.
|
||||
* @param TIMx Timer Instance
|
||||
* @param TIM_OCInitStruct pointer to the the TIMx output channel 2 configuration data structure
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: TIMx registers are de-initialized
|
||||
* - ERROR: not applicable
|
||||
*/
|
||||
static ErrorStatus OC2Config(TIM_TypeDef *TIMx, LL_TIM_OC_InitTypeDef *TIM_OCInitStruct)
|
||||
{
|
||||
uint32_t tmpccmr1;
|
||||
uint32_t tmpccer;
|
||||
uint32_t tmpcr2;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_CC2_INSTANCE(TIMx));
|
||||
assert_param(IS_LL_TIM_OCMODE(TIM_OCInitStruct->OCMode));
|
||||
assert_param(IS_LL_TIM_OCSTATE(TIM_OCInitStruct->OCState));
|
||||
assert_param(IS_LL_TIM_OCPOLARITY(TIM_OCInitStruct->OCPolarity));
|
||||
assert_param(IS_LL_TIM_OCSTATE(TIM_OCInitStruct->OCNState));
|
||||
assert_param(IS_LL_TIM_OCPOLARITY(TIM_OCInitStruct->OCNPolarity));
|
||||
|
||||
/* Disable the Channel 2: Reset the CC2E Bit */
|
||||
CLEAR_BIT(TIMx->CCER, TIM_CCER_CC2E);
|
||||
|
||||
/* Get the TIMx CCER register value */
|
||||
tmpccer = LL_TIM_ReadReg(TIMx, CCER);
|
||||
|
||||
/* Get the TIMx CR2 register value */
|
||||
tmpcr2 = LL_TIM_ReadReg(TIMx, CR2);
|
||||
|
||||
/* Get the TIMx CCMR1 register value */
|
||||
tmpccmr1 = LL_TIM_ReadReg(TIMx, CCMR1);
|
||||
|
||||
/* Reset Capture/Compare selection Bits */
|
||||
CLEAR_BIT(tmpccmr1, TIM_CCMR1_CC2S);
|
||||
|
||||
/* Select the Output Compare Mode */
|
||||
MODIFY_REG(tmpccmr1, TIM_CCMR1_OC2M, TIM_OCInitStruct->OCMode << 8U);
|
||||
|
||||
/* Set the Output Compare Polarity */
|
||||
MODIFY_REG(tmpccer, TIM_CCER_CC2P, TIM_OCInitStruct->OCPolarity << 4U);
|
||||
|
||||
/* Set the Output State */
|
||||
MODIFY_REG(tmpccer, TIM_CCER_CC2E, TIM_OCInitStruct->OCState << 4U);
|
||||
|
||||
if (IS_TIM_BREAK_INSTANCE(TIMx))
|
||||
{
|
||||
assert_param(IS_LL_TIM_OCIDLESTATE(TIM_OCInitStruct->OCNIdleState));
|
||||
assert_param(IS_LL_TIM_OCIDLESTATE(TIM_OCInitStruct->OCIdleState));
|
||||
|
||||
/* Set the complementary output Polarity */
|
||||
MODIFY_REG(tmpccer, TIM_CCER_CC2NP, TIM_OCInitStruct->OCNPolarity << 6U);
|
||||
|
||||
/* Set the complementary output State */
|
||||
MODIFY_REG(tmpccer, TIM_CCER_CC2NE, TIM_OCInitStruct->OCNState << 6U);
|
||||
|
||||
/* Set the Output Idle state */
|
||||
MODIFY_REG(tmpcr2, TIM_CR2_OIS2, TIM_OCInitStruct->OCIdleState << 2U);
|
||||
|
||||
/* Set the complementary output Idle state */
|
||||
MODIFY_REG(tmpcr2, TIM_CR2_OIS2N, TIM_OCInitStruct->OCNIdleState << 3U);
|
||||
}
|
||||
|
||||
/* Write to TIMx CR2 */
|
||||
LL_TIM_WriteReg(TIMx, CR2, tmpcr2);
|
||||
|
||||
/* Write to TIMx CCMR1 */
|
||||
LL_TIM_WriteReg(TIMx, CCMR1, tmpccmr1);
|
||||
|
||||
/* Set the Capture Compare Register value */
|
||||
LL_TIM_OC_SetCompareCH2(TIMx, TIM_OCInitStruct->CompareValue);
|
||||
|
||||
/* Write to TIMx CCER */
|
||||
LL_TIM_WriteReg(TIMx, CCER, tmpccer);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure the TIMx output channel 3.
|
||||
* @param TIMx Timer Instance
|
||||
* @param TIM_OCInitStruct pointer to the the TIMx output channel 3 configuration data structure
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: TIMx registers are de-initialized
|
||||
* - ERROR: not applicable
|
||||
*/
|
||||
static ErrorStatus OC3Config(TIM_TypeDef *TIMx, LL_TIM_OC_InitTypeDef *TIM_OCInitStruct)
|
||||
{
|
||||
uint32_t tmpccmr2;
|
||||
uint32_t tmpccer;
|
||||
uint32_t tmpcr2;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_CC3_INSTANCE(TIMx));
|
||||
assert_param(IS_LL_TIM_OCMODE(TIM_OCInitStruct->OCMode));
|
||||
assert_param(IS_LL_TIM_OCSTATE(TIM_OCInitStruct->OCState));
|
||||
assert_param(IS_LL_TIM_OCPOLARITY(TIM_OCInitStruct->OCPolarity));
|
||||
assert_param(IS_LL_TIM_OCSTATE(TIM_OCInitStruct->OCNState));
|
||||
assert_param(IS_LL_TIM_OCPOLARITY(TIM_OCInitStruct->OCNPolarity));
|
||||
|
||||
/* Disable the Channel 3: Reset the CC3E Bit */
|
||||
CLEAR_BIT(TIMx->CCER, TIM_CCER_CC3E);
|
||||
|
||||
/* Get the TIMx CCER register value */
|
||||
tmpccer = LL_TIM_ReadReg(TIMx, CCER);
|
||||
|
||||
/* Get the TIMx CR2 register value */
|
||||
tmpcr2 = LL_TIM_ReadReg(TIMx, CR2);
|
||||
|
||||
/* Get the TIMx CCMR2 register value */
|
||||
tmpccmr2 = LL_TIM_ReadReg(TIMx, CCMR2);
|
||||
|
||||
/* Reset Capture/Compare selection Bits */
|
||||
CLEAR_BIT(tmpccmr2, TIM_CCMR2_CC3S);
|
||||
|
||||
/* Select the Output Compare Mode */
|
||||
MODIFY_REG(tmpccmr2, TIM_CCMR2_OC3M, TIM_OCInitStruct->OCMode);
|
||||
|
||||
/* Set the Output Compare Polarity */
|
||||
MODIFY_REG(tmpccer, TIM_CCER_CC3P, TIM_OCInitStruct->OCPolarity << 8U);
|
||||
|
||||
/* Set the Output State */
|
||||
MODIFY_REG(tmpccer, TIM_CCER_CC3E, TIM_OCInitStruct->OCState << 8U);
|
||||
|
||||
if (IS_TIM_BREAK_INSTANCE(TIMx))
|
||||
{
|
||||
assert_param(IS_LL_TIM_OCIDLESTATE(TIM_OCInitStruct->OCNIdleState));
|
||||
assert_param(IS_LL_TIM_OCIDLESTATE(TIM_OCInitStruct->OCIdleState));
|
||||
|
||||
/* Set the complementary output Polarity */
|
||||
MODIFY_REG(tmpccer, TIM_CCER_CC3NP, TIM_OCInitStruct->OCNPolarity << 10U);
|
||||
|
||||
/* Set the complementary output State */
|
||||
MODIFY_REG(tmpccer, TIM_CCER_CC3NE, TIM_OCInitStruct->OCNState << 10U);
|
||||
|
||||
/* Set the Output Idle state */
|
||||
MODIFY_REG(tmpcr2, TIM_CR2_OIS3, TIM_OCInitStruct->OCIdleState << 4U);
|
||||
|
||||
/* Set the complementary output Idle state */
|
||||
MODIFY_REG(tmpcr2, TIM_CR2_OIS3N, TIM_OCInitStruct->OCNIdleState << 5U);
|
||||
}
|
||||
|
||||
/* Write to TIMx CR2 */
|
||||
LL_TIM_WriteReg(TIMx, CR2, tmpcr2);
|
||||
|
||||
/* Write to TIMx CCMR2 */
|
||||
LL_TIM_WriteReg(TIMx, CCMR2, tmpccmr2);
|
||||
|
||||
/* Set the Capture Compare Register value */
|
||||
LL_TIM_OC_SetCompareCH3(TIMx, TIM_OCInitStruct->CompareValue);
|
||||
|
||||
/* Write to TIMx CCER */
|
||||
LL_TIM_WriteReg(TIMx, CCER, tmpccer);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure the TIMx output channel 4.
|
||||
* @param TIMx Timer Instance
|
||||
* @param TIM_OCInitStruct pointer to the the TIMx output channel 4 configuration data structure
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: TIMx registers are de-initialized
|
||||
* - ERROR: not applicable
|
||||
*/
|
||||
static ErrorStatus OC4Config(TIM_TypeDef *TIMx, LL_TIM_OC_InitTypeDef *TIM_OCInitStruct)
|
||||
{
|
||||
uint32_t tmpccmr2;
|
||||
uint32_t tmpccer;
|
||||
uint32_t tmpcr2;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_CC4_INSTANCE(TIMx));
|
||||
assert_param(IS_LL_TIM_OCMODE(TIM_OCInitStruct->OCMode));
|
||||
assert_param(IS_LL_TIM_OCSTATE(TIM_OCInitStruct->OCState));
|
||||
assert_param(IS_LL_TIM_OCPOLARITY(TIM_OCInitStruct->OCPolarity));
|
||||
assert_param(IS_LL_TIM_OCPOLARITY(TIM_OCInitStruct->OCNPolarity));
|
||||
assert_param(IS_LL_TIM_OCSTATE(TIM_OCInitStruct->OCNState));
|
||||
|
||||
/* Disable the Channel 4: Reset the CC4E Bit */
|
||||
CLEAR_BIT(TIMx->CCER, TIM_CCER_CC4E);
|
||||
|
||||
/* Get the TIMx CCER register value */
|
||||
tmpccer = LL_TIM_ReadReg(TIMx, CCER);
|
||||
|
||||
/* Get the TIMx CR2 register value */
|
||||
tmpcr2 = LL_TIM_ReadReg(TIMx, CR2);
|
||||
|
||||
/* Get the TIMx CCMR2 register value */
|
||||
tmpccmr2 = LL_TIM_ReadReg(TIMx, CCMR2);
|
||||
|
||||
/* Reset Capture/Compare selection Bits */
|
||||
CLEAR_BIT(tmpccmr2, TIM_CCMR2_CC4S);
|
||||
|
||||
/* Select the Output Compare Mode */
|
||||
MODIFY_REG(tmpccmr2, TIM_CCMR2_OC4M, TIM_OCInitStruct->OCMode << 8U);
|
||||
|
||||
/* Set the Output Compare Polarity */
|
||||
MODIFY_REG(tmpccer, TIM_CCER_CC4P, TIM_OCInitStruct->OCPolarity << 12U);
|
||||
|
||||
/* Set the Output State */
|
||||
MODIFY_REG(tmpccer, TIM_CCER_CC4E, TIM_OCInitStruct->OCState << 12U);
|
||||
|
||||
if (IS_TIM_BREAK_INSTANCE(TIMx))
|
||||
{
|
||||
assert_param(IS_LL_TIM_OCIDLESTATE(TIM_OCInitStruct->OCNIdleState));
|
||||
assert_param(IS_LL_TIM_OCIDLESTATE(TIM_OCInitStruct->OCIdleState));
|
||||
|
||||
/* Set the Output Idle state */
|
||||
MODIFY_REG(tmpcr2, TIM_CR2_OIS4, TIM_OCInitStruct->OCIdleState << 6U);
|
||||
}
|
||||
|
||||
/* Write to TIMx CR2 */
|
||||
LL_TIM_WriteReg(TIMx, CR2, tmpcr2);
|
||||
|
||||
/* Write to TIMx CCMR2 */
|
||||
LL_TIM_WriteReg(TIMx, CCMR2, tmpccmr2);
|
||||
|
||||
/* Set the Capture Compare Register value */
|
||||
LL_TIM_OC_SetCompareCH4(TIMx, TIM_OCInitStruct->CompareValue);
|
||||
|
||||
/* Write to TIMx CCER */
|
||||
LL_TIM_WriteReg(TIMx, CCER, tmpccer);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure the TIMx output channel 5.
|
||||
* @param TIMx Timer Instance
|
||||
* @param TIM_OCInitStruct pointer to the the TIMx output channel 5 configuration data structure
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: TIMx registers are de-initialized
|
||||
* - ERROR: not applicable
|
||||
*/
|
||||
static ErrorStatus OC5Config(TIM_TypeDef *TIMx, LL_TIM_OC_InitTypeDef *TIM_OCInitStruct)
|
||||
{
|
||||
uint32_t tmpccmr3;
|
||||
uint32_t tmpccer;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_CC5_INSTANCE(TIMx));
|
||||
assert_param(IS_LL_TIM_OCMODE(TIM_OCInitStruct->OCMode));
|
||||
assert_param(IS_LL_TIM_OCSTATE(TIM_OCInitStruct->OCState));
|
||||
assert_param(IS_LL_TIM_OCPOLARITY(TIM_OCInitStruct->OCPolarity));
|
||||
assert_param(IS_LL_TIM_OCPOLARITY(TIM_OCInitStruct->OCNPolarity));
|
||||
assert_param(IS_LL_TIM_OCSTATE(TIM_OCInitStruct->OCNState));
|
||||
|
||||
/* Disable the Channel 5: Reset the CC5E Bit */
|
||||
CLEAR_BIT(TIMx->CCER, TIM_CCER_CC5E);
|
||||
|
||||
/* Get the TIMx CCER register value */
|
||||
tmpccer = LL_TIM_ReadReg(TIMx, CCER);
|
||||
|
||||
/* Get the TIMx CCMR3 register value */
|
||||
tmpccmr3 = LL_TIM_ReadReg(TIMx, CCMR3);
|
||||
|
||||
/* Select the Output Compare Mode */
|
||||
MODIFY_REG(tmpccmr3, TIM_CCMR3_OC5M, TIM_OCInitStruct->OCMode);
|
||||
|
||||
/* Set the Output Compare Polarity */
|
||||
MODIFY_REG(tmpccer, TIM_CCER_CC5P, TIM_OCInitStruct->OCPolarity << 16U);
|
||||
|
||||
/* Set the Output State */
|
||||
MODIFY_REG(tmpccer, TIM_CCER_CC5E, TIM_OCInitStruct->OCState << 16U);
|
||||
|
||||
if (IS_TIM_BREAK_INSTANCE(TIMx))
|
||||
{
|
||||
assert_param(IS_LL_TIM_OCIDLESTATE(TIM_OCInitStruct->OCNIdleState));
|
||||
assert_param(IS_LL_TIM_OCIDLESTATE(TIM_OCInitStruct->OCIdleState));
|
||||
|
||||
/* Set the Output Idle state */
|
||||
MODIFY_REG(TIMx->CR2, TIM_CR2_OIS5, TIM_OCInitStruct->OCIdleState << 8U);
|
||||
|
||||
}
|
||||
|
||||
/* Write to TIMx CCMR3 */
|
||||
LL_TIM_WriteReg(TIMx, CCMR3, tmpccmr3);
|
||||
|
||||
/* Set the Capture Compare Register value */
|
||||
LL_TIM_OC_SetCompareCH5(TIMx, TIM_OCInitStruct->CompareValue);
|
||||
|
||||
/* Write to TIMx CCER */
|
||||
LL_TIM_WriteReg(TIMx, CCER, tmpccer);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure the TIMx output channel 6.
|
||||
* @param TIMx Timer Instance
|
||||
* @param TIM_OCInitStruct pointer to the the TIMx output channel 6 configuration data structure
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: TIMx registers are de-initialized
|
||||
* - ERROR: not applicable
|
||||
*/
|
||||
static ErrorStatus OC6Config(TIM_TypeDef *TIMx, LL_TIM_OC_InitTypeDef *TIM_OCInitStruct)
|
||||
{
|
||||
uint32_t tmpccmr3;
|
||||
uint32_t tmpccer;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_CC6_INSTANCE(TIMx));
|
||||
assert_param(IS_LL_TIM_OCMODE(TIM_OCInitStruct->OCMode));
|
||||
assert_param(IS_LL_TIM_OCSTATE(TIM_OCInitStruct->OCState));
|
||||
assert_param(IS_LL_TIM_OCPOLARITY(TIM_OCInitStruct->OCPolarity));
|
||||
assert_param(IS_LL_TIM_OCPOLARITY(TIM_OCInitStruct->OCNPolarity));
|
||||
assert_param(IS_LL_TIM_OCSTATE(TIM_OCInitStruct->OCNState));
|
||||
|
||||
/* Disable the Channel 5: Reset the CC6E Bit */
|
||||
CLEAR_BIT(TIMx->CCER, TIM_CCER_CC6E);
|
||||
|
||||
/* Get the TIMx CCER register value */
|
||||
tmpccer = LL_TIM_ReadReg(TIMx, CCER);
|
||||
|
||||
/* Get the TIMx CCMR3 register value */
|
||||
tmpccmr3 = LL_TIM_ReadReg(TIMx, CCMR3);
|
||||
|
||||
/* Select the Output Compare Mode */
|
||||
MODIFY_REG(tmpccmr3, TIM_CCMR3_OC6M, TIM_OCInitStruct->OCMode << 8U);
|
||||
|
||||
/* Set the Output Compare Polarity */
|
||||
MODIFY_REG(tmpccer, TIM_CCER_CC6P, TIM_OCInitStruct->OCPolarity << 20U);
|
||||
|
||||
/* Set the Output State */
|
||||
MODIFY_REG(tmpccer, TIM_CCER_CC6E, TIM_OCInitStruct->OCState << 20U);
|
||||
|
||||
if (IS_TIM_BREAK_INSTANCE(TIMx))
|
||||
{
|
||||
assert_param(IS_LL_TIM_OCIDLESTATE(TIM_OCInitStruct->OCNIdleState));
|
||||
assert_param(IS_LL_TIM_OCIDLESTATE(TIM_OCInitStruct->OCIdleState));
|
||||
|
||||
/* Set the Output Idle state */
|
||||
MODIFY_REG(TIMx->CR2, TIM_CR2_OIS6, TIM_OCInitStruct->OCIdleState << 10U);
|
||||
}
|
||||
|
||||
/* Write to TIMx CCMR3 */
|
||||
LL_TIM_WriteReg(TIMx, CCMR3, tmpccmr3);
|
||||
|
||||
/* Set the Capture Compare Register value */
|
||||
LL_TIM_OC_SetCompareCH6(TIMx, TIM_OCInitStruct->CompareValue);
|
||||
|
||||
/* Write to TIMx CCER */
|
||||
LL_TIM_WriteReg(TIMx, CCER, tmpccer);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure the TIMx input channel 1.
|
||||
* @param TIMx Timer Instance
|
||||
* @param TIM_ICInitStruct pointer to the the TIMx input channel 1 configuration data structure
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: TIMx registers are de-initialized
|
||||
* - ERROR: not applicable
|
||||
*/
|
||||
static ErrorStatus IC1Config(TIM_TypeDef *TIMx, LL_TIM_IC_InitTypeDef *TIM_ICInitStruct)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_CC1_INSTANCE(TIMx));
|
||||
assert_param(IS_LL_TIM_IC_POLARITY(TIM_ICInitStruct->ICPolarity));
|
||||
assert_param(IS_LL_TIM_ACTIVEINPUT(TIM_ICInitStruct->ICActiveInput));
|
||||
assert_param(IS_LL_TIM_ICPSC(TIM_ICInitStruct->ICPrescaler));
|
||||
assert_param(IS_LL_TIM_IC_FILTER(TIM_ICInitStruct->ICFilter));
|
||||
|
||||
/* Disable the Channel 1: Reset the CC1E Bit */
|
||||
TIMx->CCER &= (uint32_t)~TIM_CCER_CC1E;
|
||||
|
||||
/* Select the Input and set the filter and the prescaler value */
|
||||
MODIFY_REG(TIMx->CCMR1,
|
||||
(TIM_CCMR1_CC1S | TIM_CCMR1_IC1F | TIM_CCMR1_IC1PSC),
|
||||
(TIM_ICInitStruct->ICActiveInput | TIM_ICInitStruct->ICFilter | TIM_ICInitStruct->ICPrescaler) >> 16U);
|
||||
|
||||
/* Select the Polarity and set the CC1E Bit */
|
||||
MODIFY_REG(TIMx->CCER,
|
||||
(TIM_CCER_CC1P | TIM_CCER_CC1NP),
|
||||
(TIM_ICInitStruct->ICPolarity | TIM_CCER_CC1E));
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure the TIMx input channel 2.
|
||||
* @param TIMx Timer Instance
|
||||
* @param TIM_ICInitStruct pointer to the the TIMx input channel 2 configuration data structure
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: TIMx registers are de-initialized
|
||||
* - ERROR: not applicable
|
||||
*/
|
||||
static ErrorStatus IC2Config(TIM_TypeDef *TIMx, LL_TIM_IC_InitTypeDef *TIM_ICInitStruct)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_CC2_INSTANCE(TIMx));
|
||||
assert_param(IS_LL_TIM_IC_POLARITY(TIM_ICInitStruct->ICPolarity));
|
||||
assert_param(IS_LL_TIM_ACTIVEINPUT(TIM_ICInitStruct->ICActiveInput));
|
||||
assert_param(IS_LL_TIM_ICPSC(TIM_ICInitStruct->ICPrescaler));
|
||||
assert_param(IS_LL_TIM_IC_FILTER(TIM_ICInitStruct->ICFilter));
|
||||
|
||||
/* Disable the Channel 2: Reset the CC2E Bit */
|
||||
TIMx->CCER &= (uint32_t)~TIM_CCER_CC2E;
|
||||
|
||||
/* Select the Input and set the filter and the prescaler value */
|
||||
MODIFY_REG(TIMx->CCMR1,
|
||||
(TIM_CCMR1_CC2S | TIM_CCMR1_IC2F | TIM_CCMR1_IC2PSC),
|
||||
(TIM_ICInitStruct->ICActiveInput | TIM_ICInitStruct->ICFilter | TIM_ICInitStruct->ICPrescaler) >> 8U);
|
||||
|
||||
/* Select the Polarity and set the CC2E Bit */
|
||||
MODIFY_REG(TIMx->CCER,
|
||||
(TIM_CCER_CC2P | TIM_CCER_CC2NP),
|
||||
((TIM_ICInitStruct->ICPolarity << 4U) | TIM_CCER_CC2E));
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure the TIMx input channel 3.
|
||||
* @param TIMx Timer Instance
|
||||
* @param TIM_ICInitStruct pointer to the the TIMx input channel 3 configuration data structure
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: TIMx registers are de-initialized
|
||||
* - ERROR: not applicable
|
||||
*/
|
||||
static ErrorStatus IC3Config(TIM_TypeDef *TIMx, LL_TIM_IC_InitTypeDef *TIM_ICInitStruct)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_CC3_INSTANCE(TIMx));
|
||||
assert_param(IS_LL_TIM_IC_POLARITY(TIM_ICInitStruct->ICPolarity));
|
||||
assert_param(IS_LL_TIM_ACTIVEINPUT(TIM_ICInitStruct->ICActiveInput));
|
||||
assert_param(IS_LL_TIM_ICPSC(TIM_ICInitStruct->ICPrescaler));
|
||||
assert_param(IS_LL_TIM_IC_FILTER(TIM_ICInitStruct->ICFilter));
|
||||
|
||||
/* Disable the Channel 3: Reset the CC3E Bit */
|
||||
TIMx->CCER &= (uint32_t)~TIM_CCER_CC3E;
|
||||
|
||||
/* Select the Input and set the filter and the prescaler value */
|
||||
MODIFY_REG(TIMx->CCMR2,
|
||||
(TIM_CCMR2_CC3S | TIM_CCMR2_IC3F | TIM_CCMR2_IC3PSC),
|
||||
(TIM_ICInitStruct->ICActiveInput | TIM_ICInitStruct->ICFilter | TIM_ICInitStruct->ICPrescaler) >> 16U);
|
||||
|
||||
/* Select the Polarity and set the CC3E Bit */
|
||||
MODIFY_REG(TIMx->CCER,
|
||||
(TIM_CCER_CC3P | TIM_CCER_CC3NP),
|
||||
((TIM_ICInitStruct->ICPolarity << 8U) | TIM_CCER_CC3E));
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure the TIMx input channel 4.
|
||||
* @param TIMx Timer Instance
|
||||
* @param TIM_ICInitStruct pointer to the the TIMx input channel 4 configuration data structure
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: TIMx registers are de-initialized
|
||||
* - ERROR: not applicable
|
||||
*/
|
||||
static ErrorStatus IC4Config(TIM_TypeDef *TIMx, LL_TIM_IC_InitTypeDef *TIM_ICInitStruct)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_CC4_INSTANCE(TIMx));
|
||||
assert_param(IS_LL_TIM_IC_POLARITY(TIM_ICInitStruct->ICPolarity));
|
||||
assert_param(IS_LL_TIM_ACTIVEINPUT(TIM_ICInitStruct->ICActiveInput));
|
||||
assert_param(IS_LL_TIM_ICPSC(TIM_ICInitStruct->ICPrescaler));
|
||||
assert_param(IS_LL_TIM_IC_FILTER(TIM_ICInitStruct->ICFilter));
|
||||
|
||||
/* Disable the Channel 4: Reset the CC4E Bit */
|
||||
TIMx->CCER &= (uint32_t)~TIM_CCER_CC4E;
|
||||
|
||||
/* Select the Input and set the filter and the prescaler value */
|
||||
MODIFY_REG(TIMx->CCMR2,
|
||||
(TIM_CCMR2_CC4S | TIM_CCMR2_IC4F | TIM_CCMR2_IC4PSC),
|
||||
(TIM_ICInitStruct->ICActiveInput | TIM_ICInitStruct->ICFilter | TIM_ICInitStruct->ICPrescaler) >> 8U);
|
||||
|
||||
/* Select the Polarity and set the CC2E Bit */
|
||||
MODIFY_REG(TIMx->CCER,
|
||||
(TIM_CCER_CC4P | TIM_CCER_CC4NP),
|
||||
((TIM_ICInitStruct->ICPolarity << 12U) | TIM_CCER_CC4E));
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* TIM1 || TIM8 || TIM2 || TIM3 || TIM4 || TIM5 || TIM15 || TIM16 || TIM17 || TIM6 || TIM7 */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* USE_FULL_LL_DRIVER */
|
||||
|
||||
476
Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_ll_usart.c
Normal file
476
Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_ll_usart.c
Normal file
@@ -0,0 +1,476 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32l4xx_ll_usart.c
|
||||
* @author MCD Application Team
|
||||
* @brief USART LL module driver.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2017 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
#if defined(USE_FULL_LL_DRIVER)
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32l4xx_ll_usart.h"
|
||||
#include "stm32l4xx_ll_rcc.h"
|
||||
#include "stm32l4xx_ll_bus.h"
|
||||
#ifdef USE_FULL_ASSERT
|
||||
#include "stm32_assert.h"
|
||||
#else
|
||||
#define assert_param(expr) ((void)0U)
|
||||
#endif /* USE_FULL_ASSERT */
|
||||
|
||||
/** @addtogroup STM32L4xx_LL_Driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
#if defined (USART1) || defined (USART2) || defined (USART3) || defined (UART4) || defined (UART5)
|
||||
|
||||
/** @addtogroup USART_LL
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Private types -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private constants ---------------------------------------------------------*/
|
||||
/* Private macros ------------------------------------------------------------*/
|
||||
/** @addtogroup USART_LL_Private_Macros
|
||||
* @{
|
||||
*/
|
||||
|
||||
#if defined(USART_PRESC_PRESCALER)
|
||||
#define IS_LL_USART_PRESCALER(__VALUE__) (((__VALUE__) == LL_USART_PRESCALER_DIV1) \
|
||||
|| ((__VALUE__) == LL_USART_PRESCALER_DIV2) \
|
||||
|| ((__VALUE__) == LL_USART_PRESCALER_DIV4) \
|
||||
|| ((__VALUE__) == LL_USART_PRESCALER_DIV6) \
|
||||
|| ((__VALUE__) == LL_USART_PRESCALER_DIV8) \
|
||||
|| ((__VALUE__) == LL_USART_PRESCALER_DIV10) \
|
||||
|| ((__VALUE__) == LL_USART_PRESCALER_DIV12) \
|
||||
|| ((__VALUE__) == LL_USART_PRESCALER_DIV16) \
|
||||
|| ((__VALUE__) == LL_USART_PRESCALER_DIV32) \
|
||||
|| ((__VALUE__) == LL_USART_PRESCALER_DIV64) \
|
||||
|| ((__VALUE__) == LL_USART_PRESCALER_DIV128) \
|
||||
|| ((__VALUE__) == LL_USART_PRESCALER_DIV256))
|
||||
|
||||
#endif /* USART_PRESC_PRESCALER */
|
||||
/* __BAUDRATE__ The maximum Baud Rate is derived from the maximum clock available
|
||||
* divided by the smallest oversampling used on the USART (i.e. 8) */
|
||||
#if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
|
||||
#define IS_LL_USART_BAUDRATE(__BAUDRATE__) ((__BAUDRATE__) <= 15000000U)
|
||||
#else
|
||||
#define IS_LL_USART_BAUDRATE(__BAUDRATE__) ((__BAUDRATE__) <= 10000000U)
|
||||
#endif /* STM32L4R5xx || STM32L4R7xx || STM32L4R9xx || STM32L4S5xx || STM32L4S7xx || STM32L4S9xx */
|
||||
|
||||
/* __VALUE__ In case of oversampling by 16 and 8, BRR content must be greater than or equal to 16d. */
|
||||
#define IS_LL_USART_BRR_MIN(__VALUE__) ((__VALUE__) >= 16U)
|
||||
|
||||
#define IS_LL_USART_DIRECTION(__VALUE__) (((__VALUE__) == LL_USART_DIRECTION_NONE) \
|
||||
|| ((__VALUE__) == LL_USART_DIRECTION_RX) \
|
||||
|| ((__VALUE__) == LL_USART_DIRECTION_TX) \
|
||||
|| ((__VALUE__) == LL_USART_DIRECTION_TX_RX))
|
||||
|
||||
#define IS_LL_USART_PARITY(__VALUE__) (((__VALUE__) == LL_USART_PARITY_NONE) \
|
||||
|| ((__VALUE__) == LL_USART_PARITY_EVEN) \
|
||||
|| ((__VALUE__) == LL_USART_PARITY_ODD))
|
||||
|
||||
#define IS_LL_USART_DATAWIDTH(__VALUE__) (((__VALUE__) == LL_USART_DATAWIDTH_7B) \
|
||||
|| ((__VALUE__) == LL_USART_DATAWIDTH_8B) \
|
||||
|| ((__VALUE__) == LL_USART_DATAWIDTH_9B))
|
||||
|
||||
#define IS_LL_USART_OVERSAMPLING(__VALUE__) (((__VALUE__) == LL_USART_OVERSAMPLING_16) \
|
||||
|| ((__VALUE__) == LL_USART_OVERSAMPLING_8))
|
||||
|
||||
#define IS_LL_USART_LASTBITCLKOUTPUT(__VALUE__) (((__VALUE__) == LL_USART_LASTCLKPULSE_NO_OUTPUT) \
|
||||
|| ((__VALUE__) == LL_USART_LASTCLKPULSE_OUTPUT))
|
||||
|
||||
#define IS_LL_USART_CLOCKPHASE(__VALUE__) (((__VALUE__) == LL_USART_PHASE_1EDGE) \
|
||||
|| ((__VALUE__) == LL_USART_PHASE_2EDGE))
|
||||
|
||||
#define IS_LL_USART_CLOCKPOLARITY(__VALUE__) (((__VALUE__) == LL_USART_POLARITY_LOW) \
|
||||
|| ((__VALUE__) == LL_USART_POLARITY_HIGH))
|
||||
|
||||
#define IS_LL_USART_CLOCKOUTPUT(__VALUE__) (((__VALUE__) == LL_USART_CLOCK_DISABLE) \
|
||||
|| ((__VALUE__) == LL_USART_CLOCK_ENABLE))
|
||||
|
||||
#define IS_LL_USART_STOPBITS(__VALUE__) (((__VALUE__) == LL_USART_STOPBITS_0_5) \
|
||||
|| ((__VALUE__) == LL_USART_STOPBITS_1) \
|
||||
|| ((__VALUE__) == LL_USART_STOPBITS_1_5) \
|
||||
|| ((__VALUE__) == LL_USART_STOPBITS_2))
|
||||
|
||||
#define IS_LL_USART_HWCONTROL(__VALUE__) (((__VALUE__) == LL_USART_HWCONTROL_NONE) \
|
||||
|| ((__VALUE__) == LL_USART_HWCONTROL_RTS) \
|
||||
|| ((__VALUE__) == LL_USART_HWCONTROL_CTS) \
|
||||
|| ((__VALUE__) == LL_USART_HWCONTROL_RTS_CTS))
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
|
||||
/* Exported functions --------------------------------------------------------*/
|
||||
/** @addtogroup USART_LL_Exported_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup USART_LL_EF_Init
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief De-initialize USART registers (Registers restored to their default values).
|
||||
* @param USARTx USART Instance
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: USART registers are de-initialized
|
||||
* - ERROR: USART registers are not de-initialized
|
||||
*/
|
||||
ErrorStatus LL_USART_DeInit(USART_TypeDef *USARTx)
|
||||
{
|
||||
ErrorStatus status = SUCCESS;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_UART_INSTANCE(USARTx));
|
||||
|
||||
if (USARTx == USART1)
|
||||
{
|
||||
/* Force reset of USART clock */
|
||||
LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_USART1);
|
||||
|
||||
/* Release reset of USART clock */
|
||||
LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_USART1);
|
||||
}
|
||||
else if (USARTx == USART2)
|
||||
{
|
||||
/* Force reset of USART clock */
|
||||
LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_USART2);
|
||||
|
||||
/* Release reset of USART clock */
|
||||
LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_USART2);
|
||||
}
|
||||
#if defined(USART3)
|
||||
else if (USARTx == USART3)
|
||||
{
|
||||
/* Force reset of USART clock */
|
||||
LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_USART3);
|
||||
|
||||
/* Release reset of USART clock */
|
||||
LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_USART3);
|
||||
}
|
||||
#endif /* USART3 */
|
||||
#if defined(UART4)
|
||||
else if (USARTx == UART4)
|
||||
{
|
||||
/* Force reset of UART clock */
|
||||
LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_UART4);
|
||||
|
||||
/* Release reset of UART clock */
|
||||
LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_UART4);
|
||||
}
|
||||
#endif /* UART4 */
|
||||
#if defined(UART5)
|
||||
else if (USARTx == UART5)
|
||||
{
|
||||
/* Force reset of UART clock */
|
||||
LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_UART5);
|
||||
|
||||
/* Release reset of UART clock */
|
||||
LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_UART5);
|
||||
}
|
||||
#endif /* UART5 */
|
||||
else
|
||||
{
|
||||
status = ERROR;
|
||||
}
|
||||
|
||||
return (status);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialize USART registers according to the specified
|
||||
* parameters in USART_InitStruct.
|
||||
* @note As some bits in USART configuration registers can only be written when
|
||||
* the USART is disabled (USART_CR1_UE bit =0), USART Peripheral should be in disabled state prior calling
|
||||
* this function. Otherwise, ERROR result will be returned.
|
||||
* @note Baud rate value stored in USART_InitStruct BaudRate field, should be valid (different from 0).
|
||||
* @param USARTx USART Instance
|
||||
* @param USART_InitStruct pointer to a LL_USART_InitTypeDef structure
|
||||
* that contains the configuration information for the specified USART peripheral.
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: USART registers are initialized according to USART_InitStruct content
|
||||
* - ERROR: Problem occurred during USART Registers initialization
|
||||
*/
|
||||
ErrorStatus LL_USART_Init(USART_TypeDef *USARTx, LL_USART_InitTypeDef *USART_InitStruct)
|
||||
{
|
||||
ErrorStatus status = ERROR;
|
||||
uint32_t periphclk = LL_RCC_PERIPH_FREQUENCY_NO;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_UART_INSTANCE(USARTx));
|
||||
#if defined(USART_PRESC_PRESCALER)
|
||||
assert_param(IS_LL_USART_PRESCALER(USART_InitStruct->PrescalerValue));
|
||||
#endif /* USART_PRESC_PRESCALER */
|
||||
assert_param(IS_LL_USART_BAUDRATE(USART_InitStruct->BaudRate));
|
||||
assert_param(IS_LL_USART_DATAWIDTH(USART_InitStruct->DataWidth));
|
||||
assert_param(IS_LL_USART_STOPBITS(USART_InitStruct->StopBits));
|
||||
assert_param(IS_LL_USART_PARITY(USART_InitStruct->Parity));
|
||||
assert_param(IS_LL_USART_DIRECTION(USART_InitStruct->TransferDirection));
|
||||
assert_param(IS_LL_USART_HWCONTROL(USART_InitStruct->HardwareFlowControl));
|
||||
assert_param(IS_LL_USART_OVERSAMPLING(USART_InitStruct->OverSampling));
|
||||
|
||||
/* USART needs to be in disabled state, in order to be able to configure some bits in
|
||||
CRx registers */
|
||||
if (LL_USART_IsEnabled(USARTx) == 0U)
|
||||
{
|
||||
/*---------------------------- USART CR1 Configuration ---------------------
|
||||
* Configure USARTx CR1 (USART Word Length, Parity, Mode and Oversampling bits) with parameters:
|
||||
* - DataWidth: USART_CR1_M bits according to USART_InitStruct->DataWidth value
|
||||
* - Parity: USART_CR1_PCE, USART_CR1_PS bits according to USART_InitStruct->Parity value
|
||||
* - TransferDirection: USART_CR1_TE, USART_CR1_RE bits according to USART_InitStruct->TransferDirection value
|
||||
* - Oversampling: USART_CR1_OVER8 bit according to USART_InitStruct->OverSampling value.
|
||||
*/
|
||||
MODIFY_REG(USARTx->CR1,
|
||||
(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS |
|
||||
USART_CR1_TE | USART_CR1_RE | USART_CR1_OVER8),
|
||||
(USART_InitStruct->DataWidth | USART_InitStruct->Parity |
|
||||
USART_InitStruct->TransferDirection | USART_InitStruct->OverSampling));
|
||||
|
||||
/*---------------------------- USART CR2 Configuration ---------------------
|
||||
* Configure USARTx CR2 (Stop bits) with parameters:
|
||||
* - Stop Bits: USART_CR2_STOP bits according to USART_InitStruct->StopBits value.
|
||||
* - CLKEN, CPOL, CPHA and LBCL bits are to be configured using LL_USART_ClockInit().
|
||||
*/
|
||||
LL_USART_SetStopBitsLength(USARTx, USART_InitStruct->StopBits);
|
||||
|
||||
/*---------------------------- USART CR3 Configuration ---------------------
|
||||
* Configure USARTx CR3 (Hardware Flow Control) with parameters:
|
||||
* - HardwareFlowControl: USART_CR3_RTSE, USART_CR3_CTSE bits according to
|
||||
* USART_InitStruct->HardwareFlowControl value.
|
||||
*/
|
||||
LL_USART_SetHWFlowCtrl(USARTx, USART_InitStruct->HardwareFlowControl);
|
||||
|
||||
/*---------------------------- USART BRR Configuration ---------------------
|
||||
* Retrieve Clock frequency used for USART Peripheral
|
||||
*/
|
||||
if (USARTx == USART1)
|
||||
{
|
||||
periphclk = LL_RCC_GetUSARTClockFreq(LL_RCC_USART1_CLKSOURCE);
|
||||
}
|
||||
else if (USARTx == USART2)
|
||||
{
|
||||
periphclk = LL_RCC_GetUSARTClockFreq(LL_RCC_USART2_CLKSOURCE);
|
||||
}
|
||||
#if defined(USART3)
|
||||
else if (USARTx == USART3)
|
||||
{
|
||||
periphclk = LL_RCC_GetUSARTClockFreq(LL_RCC_USART3_CLKSOURCE);
|
||||
}
|
||||
#endif /* USART3 */
|
||||
#if defined(UART4)
|
||||
else if (USARTx == UART4)
|
||||
{
|
||||
periphclk = LL_RCC_GetUARTClockFreq(LL_RCC_UART4_CLKSOURCE);
|
||||
}
|
||||
#endif /* UART4 */
|
||||
#if defined(UART5)
|
||||
else if (USARTx == UART5)
|
||||
{
|
||||
periphclk = LL_RCC_GetUARTClockFreq(LL_RCC_UART5_CLKSOURCE);
|
||||
}
|
||||
#endif /* UART5 */
|
||||
else
|
||||
{
|
||||
/* Nothing to do, as error code is already assigned to ERROR value */
|
||||
}
|
||||
|
||||
/* Configure the USART Baud Rate :
|
||||
#if defined(USART_PRESC_PRESCALER)
|
||||
- prescaler value is required
|
||||
#endif
|
||||
- valid baud rate value (different from 0) is required
|
||||
- Peripheral clock as returned by RCC service, should be valid (different from 0).
|
||||
*/
|
||||
if ((periphclk != LL_RCC_PERIPH_FREQUENCY_NO)
|
||||
&& (USART_InitStruct->BaudRate != 0U))
|
||||
{
|
||||
status = SUCCESS;
|
||||
LL_USART_SetBaudRate(USARTx,
|
||||
periphclk,
|
||||
#if defined(USART_PRESC_PRESCALER)
|
||||
USART_InitStruct->PrescalerValue,
|
||||
#endif /* USART_PRESC_PRESCALER */
|
||||
USART_InitStruct->OverSampling,
|
||||
USART_InitStruct->BaudRate);
|
||||
|
||||
/* Check BRR is greater than or equal to 16d */
|
||||
assert_param(IS_LL_USART_BRR_MIN(USARTx->BRR));
|
||||
}
|
||||
#if defined(USART_PRESC_PRESCALER)
|
||||
|
||||
/*---------------------------- USART PRESC Configuration -----------------------
|
||||
* Configure USARTx PRESC (Prescaler) with parameters:
|
||||
* - PrescalerValue: USART_PRESC_PRESCALER bits according to USART_InitStruct->PrescalerValue value.
|
||||
*/
|
||||
LL_USART_SetPrescaler(USARTx, USART_InitStruct->PrescalerValue);
|
||||
#endif /* USART_PRESC_PRESCALER */
|
||||
}
|
||||
/* Endif (=> USART not in Disabled state => return ERROR) */
|
||||
|
||||
return (status);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set each @ref LL_USART_InitTypeDef field to default value.
|
||||
* @param USART_InitStruct pointer to a @ref LL_USART_InitTypeDef structure
|
||||
* whose fields will be set to default values.
|
||||
* @retval None
|
||||
*/
|
||||
|
||||
void LL_USART_StructInit(LL_USART_InitTypeDef *USART_InitStruct)
|
||||
{
|
||||
/* Set USART_InitStruct fields to default values */
|
||||
#if defined(USART_PRESC_PRESCALER)
|
||||
USART_InitStruct->PrescalerValue = LL_USART_PRESCALER_DIV1;
|
||||
#endif /* USART_PRESC_PRESCALER */
|
||||
USART_InitStruct->BaudRate = 9600U;
|
||||
USART_InitStruct->DataWidth = LL_USART_DATAWIDTH_8B;
|
||||
USART_InitStruct->StopBits = LL_USART_STOPBITS_1;
|
||||
USART_InitStruct->Parity = LL_USART_PARITY_NONE ;
|
||||
USART_InitStruct->TransferDirection = LL_USART_DIRECTION_TX_RX;
|
||||
USART_InitStruct->HardwareFlowControl = LL_USART_HWCONTROL_NONE;
|
||||
USART_InitStruct->OverSampling = LL_USART_OVERSAMPLING_16;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialize USART Clock related settings according to the
|
||||
* specified parameters in the USART_ClockInitStruct.
|
||||
* @note As some bits in USART configuration registers can only be written when
|
||||
* the USART is disabled (USART_CR1_UE bit =0), USART Peripheral should be in disabled state prior calling
|
||||
* this function. Otherwise, ERROR result will be returned.
|
||||
* @param USARTx USART Instance
|
||||
* @param USART_ClockInitStruct pointer to a @ref LL_USART_ClockInitTypeDef structure
|
||||
* that contains the Clock configuration information for the specified USART peripheral.
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: USART registers related to Clock settings are initialized according
|
||||
* to USART_ClockInitStruct content
|
||||
* - ERROR: Problem occurred during USART Registers initialization
|
||||
*/
|
||||
ErrorStatus LL_USART_ClockInit(USART_TypeDef *USARTx, LL_USART_ClockInitTypeDef *USART_ClockInitStruct)
|
||||
{
|
||||
ErrorStatus status = SUCCESS;
|
||||
|
||||
/* Check USART Instance and Clock signal output parameters */
|
||||
assert_param(IS_UART_INSTANCE(USARTx));
|
||||
assert_param(IS_LL_USART_CLOCKOUTPUT(USART_ClockInitStruct->ClockOutput));
|
||||
|
||||
/* USART needs to be in disabled state, in order to be able to configure some bits in
|
||||
CRx registers */
|
||||
if (LL_USART_IsEnabled(USARTx) == 0U)
|
||||
{
|
||||
#if defined(USART_CR2_SLVEN)
|
||||
/* Ensure USART instance is USART capable */
|
||||
assert_param(IS_USART_INSTANCE(USARTx));
|
||||
|
||||
/* Check clock related parameters */
|
||||
assert_param(IS_LL_USART_CLOCKPOLARITY(USART_ClockInitStruct->ClockPolarity));
|
||||
assert_param(IS_LL_USART_CLOCKPHASE(USART_ClockInitStruct->ClockPhase));
|
||||
assert_param(IS_LL_USART_LASTBITCLKOUTPUT(USART_ClockInitStruct->LastBitClockPulse));
|
||||
|
||||
/*---------------------------- USART CR2 Configuration -----------------------
|
||||
* Configure USARTx CR2 (Clock signal related bits) with parameters:
|
||||
* - Clock Output: USART_CR2_CLKEN bit according to USART_ClockInitStruct->ClockOutput value
|
||||
* - Clock Polarity: USART_CR2_CPOL bit according to USART_ClockInitStruct->ClockPolarity value
|
||||
* - Clock Phase: USART_CR2_CPHA bit according to USART_ClockInitStruct->ClockPhase value
|
||||
* - Last Bit Clock Pulse Output: USART_CR2_LBCL bit according to USART_ClockInitStruct->LastBitClockPulse value.
|
||||
*/
|
||||
MODIFY_REG(USARTx->CR2,
|
||||
USART_CR2_CLKEN | USART_CR2_CPHA | USART_CR2_CPOL | USART_CR2_LBCL,
|
||||
USART_ClockInitStruct->ClockOutput | USART_ClockInitStruct->ClockPolarity |
|
||||
USART_ClockInitStruct->ClockPhase | USART_ClockInitStruct->LastBitClockPulse);
|
||||
#else
|
||||
/* If USART Clock signal is disabled */
|
||||
if (USART_ClockInitStruct->ClockOutput == LL_USART_CLOCK_DISABLE)
|
||||
{
|
||||
/* Deactivate Clock signal delivery :
|
||||
* - Disable Clock Output: USART_CR2_CLKEN cleared
|
||||
*/
|
||||
LL_USART_DisableSCLKOutput(USARTx);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Ensure USART instance is USART capable */
|
||||
assert_param(IS_USART_INSTANCE(USARTx));
|
||||
|
||||
/* Check clock related parameters */
|
||||
assert_param(IS_LL_USART_CLOCKPOLARITY(USART_ClockInitStruct->ClockPolarity));
|
||||
assert_param(IS_LL_USART_CLOCKPHASE(USART_ClockInitStruct->ClockPhase));
|
||||
assert_param(IS_LL_USART_LASTBITCLKOUTPUT(USART_ClockInitStruct->LastBitClockPulse));
|
||||
|
||||
/*---------------------------- USART CR2 Configuration -----------------------
|
||||
* Configure USARTx CR2 (Clock signal related bits) with parameters:
|
||||
* - Enable Clock Output: USART_CR2_CLKEN set
|
||||
* - Clock Polarity: USART_CR2_CPOL bit according to USART_ClockInitStruct->ClockPolarity value
|
||||
* - Clock Phase: USART_CR2_CPHA bit according to USART_ClockInitStruct->ClockPhase value
|
||||
* - Last Bit Clock Pulse Output: USART_CR2_LBCL bit according to USART_ClockInitStruct->LastBitClockPulse value.
|
||||
*/
|
||||
MODIFY_REG(USARTx->CR2,
|
||||
USART_CR2_CLKEN | USART_CR2_CPHA | USART_CR2_CPOL | USART_CR2_LBCL,
|
||||
USART_CR2_CLKEN | USART_ClockInitStruct->ClockPolarity |
|
||||
USART_ClockInitStruct->ClockPhase | USART_ClockInitStruct->LastBitClockPulse);
|
||||
}
|
||||
#endif /* USART_CR2_SLVEN */
|
||||
}
|
||||
/* Else (USART not in Disabled state => return ERROR */
|
||||
else
|
||||
{
|
||||
status = ERROR;
|
||||
}
|
||||
|
||||
return (status);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set each field of a @ref LL_USART_ClockInitTypeDef type structure to default value.
|
||||
* @param USART_ClockInitStruct pointer to a @ref LL_USART_ClockInitTypeDef structure
|
||||
* whose fields will be set to default values.
|
||||
* @retval None
|
||||
*/
|
||||
void LL_USART_ClockStructInit(LL_USART_ClockInitTypeDef *USART_ClockInitStruct)
|
||||
{
|
||||
/* Set LL_USART_ClockInitStruct fields with default values */
|
||||
USART_ClockInitStruct->ClockOutput = LL_USART_CLOCK_DISABLE;
|
||||
USART_ClockInitStruct->ClockPolarity = LL_USART_POLARITY_LOW; /* Not relevant when ClockOutput =
|
||||
LL_USART_CLOCK_DISABLE */
|
||||
USART_ClockInitStruct->ClockPhase = LL_USART_PHASE_1EDGE; /* Not relevant when ClockOutput =
|
||||
LL_USART_CLOCK_DISABLE */
|
||||
USART_ClockInitStruct->LastBitClockPulse = LL_USART_LASTCLKPULSE_NO_OUTPUT; /* Not relevant when ClockOutput =
|
||||
LL_USART_CLOCK_DISABLE */
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* USART1 || USART2 || USART3 || UART4 || UART5 */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* USE_FULL_LL_DRIVER */
|
||||
|
||||
|
||||
913
Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_ll_utils.c
Normal file
913
Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_ll_utils.c
Normal file
@@ -0,0 +1,913 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32l4xx_ll_utils.c
|
||||
* @author MCD Application Team
|
||||
* @brief UTILS LL module driver.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2017 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32l4xx_ll_utils.h"
|
||||
#include "stm32l4xx_ll_rcc.h"
|
||||
#include "stm32l4xx_ll_system.h"
|
||||
#include "stm32l4xx_ll_pwr.h"
|
||||
#ifdef USE_FULL_ASSERT
|
||||
#include "stm32_assert.h"
|
||||
#else
|
||||
#define assert_param(expr) ((void)0U)
|
||||
#endif /* USE_FULL_ASSERT */
|
||||
|
||||
/** @addtogroup STM32L4xx_LL_Driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup UTILS_LL
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Private types -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private constants ---------------------------------------------------------*/
|
||||
/** @addtogroup UTILS_LL_Private_Constants
|
||||
* @{
|
||||
*/
|
||||
#if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || \
|
||||
defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
|
||||
#define UTILS_MAX_FREQUENCY_SCALE1 120000000U /*!< Maximum frequency for system clock at power scale1, in Hz */
|
||||
#define UTILS_MAX_FREQUENCY_SCALE2 26000000U /*!< Maximum frequency for system clock at power scale2, in Hz */
|
||||
#else
|
||||
#define UTILS_MAX_FREQUENCY_SCALE1 80000000U /*!< Maximum frequency for system clock at power scale1, in Hz */
|
||||
#define UTILS_MAX_FREQUENCY_SCALE2 26000000U /*!< Maximum frequency for system clock at power scale2, in Hz */
|
||||
#endif
|
||||
|
||||
/* Defines used for PLL range */
|
||||
#define UTILS_PLLVCO_INPUT_MIN 4000000U /*!< Frequency min for PLLVCO input, in Hz */
|
||||
#define UTILS_PLLVCO_INPUT_MAX 16000000U /*!< Frequency max for PLLVCO input, in Hz */
|
||||
#define UTILS_PLLVCO_OUTPUT_MIN 64000000U /*!< Frequency min for PLLVCO output, in Hz */
|
||||
#define UTILS_PLLVCO_OUTPUT_MAX 344000000U /*!< Frequency max for PLLVCO output, in Hz */
|
||||
|
||||
/* Defines used for HSE range */
|
||||
#define UTILS_HSE_FREQUENCY_MIN 4000000U /*!< Frequency min for HSE frequency, in Hz */
|
||||
#define UTILS_HSE_FREQUENCY_MAX 48000000U /*!< Frequency max for HSE frequency, in Hz */
|
||||
|
||||
/* Defines used for FLASH latency according to HCLK Frequency */
|
||||
#if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || \
|
||||
defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
|
||||
#define UTILS_SCALE1_LATENCY1_FREQ 20000000U /*!< HCLK frequency to set FLASH latency 1 in power scale 1 */
|
||||
#define UTILS_SCALE1_LATENCY2_FREQ 40000000U /*!< HCLK frequency to set FLASH latency 2 in power scale 1 */
|
||||
#define UTILS_SCALE1_LATENCY3_FREQ 60000000U /*!< HCLK frequency to set FLASH latency 3 in power scale 1 */
|
||||
#define UTILS_SCALE1_LATENCY4_FREQ 80000000U /*!< HCLK frequency to set FLASH latency 4 in power scale 1 */
|
||||
#define UTILS_SCALE1_LATENCY5_FREQ 100000000U /*!< HCLK frequency to set FLASH latency 4 in power scale 1 */
|
||||
#define UTILS_SCALE2_LATENCY1_FREQ 8000000U /*!< HCLK frequency to set FLASH latency 1 in power scale 2 */
|
||||
#define UTILS_SCALE2_LATENCY2_FREQ 16000000U /*!< HCLK frequency to set FLASH latency 2 in power scale 2 */
|
||||
#else
|
||||
#define UTILS_SCALE1_LATENCY1_FREQ 16000000U /*!< HCLK frequency to set FLASH latency 1 in power scale 1 */
|
||||
#define UTILS_SCALE1_LATENCY2_FREQ 32000000U /*!< HCLK frequency to set FLASH latency 2 in power scale 1 */
|
||||
#define UTILS_SCALE1_LATENCY3_FREQ 48000000U /*!< HCLK frequency to set FLASH latency 3 in power scale 1 */
|
||||
#define UTILS_SCALE1_LATENCY4_FREQ 64000000U /*!< HCLK frequency to set FLASH latency 4 in power scale 1 */
|
||||
#define UTILS_SCALE2_LATENCY1_FREQ 6000000U /*!< HCLK frequency to set FLASH latency 1 in power scale 2 */
|
||||
#define UTILS_SCALE2_LATENCY2_FREQ 12000000U /*!< HCLK frequency to set FLASH latency 2 in power scale 2 */
|
||||
#define UTILS_SCALE2_LATENCY3_FREQ 18000000U /*!< HCLK frequency to set FLASH latency 3 in power scale 2 */
|
||||
#endif
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private macros ------------------------------------------------------------*/
|
||||
/** @addtogroup UTILS_LL_Private_Macros
|
||||
* @{
|
||||
*/
|
||||
#define IS_LL_UTILS_SYSCLK_DIV(__VALUE__) (((__VALUE__) == LL_RCC_SYSCLK_DIV_1) \
|
||||
|| ((__VALUE__) == LL_RCC_SYSCLK_DIV_2) \
|
||||
|| ((__VALUE__) == LL_RCC_SYSCLK_DIV_4) \
|
||||
|| ((__VALUE__) == LL_RCC_SYSCLK_DIV_8) \
|
||||
|| ((__VALUE__) == LL_RCC_SYSCLK_DIV_16) \
|
||||
|| ((__VALUE__) == LL_RCC_SYSCLK_DIV_64) \
|
||||
|| ((__VALUE__) == LL_RCC_SYSCLK_DIV_128) \
|
||||
|| ((__VALUE__) == LL_RCC_SYSCLK_DIV_256) \
|
||||
|| ((__VALUE__) == LL_RCC_SYSCLK_DIV_512))
|
||||
|
||||
#define IS_LL_UTILS_APB1_DIV(__VALUE__) (((__VALUE__) == LL_RCC_APB1_DIV_1) \
|
||||
|| ((__VALUE__) == LL_RCC_APB1_DIV_2) \
|
||||
|| ((__VALUE__) == LL_RCC_APB1_DIV_4) \
|
||||
|| ((__VALUE__) == LL_RCC_APB1_DIV_8) \
|
||||
|| ((__VALUE__) == LL_RCC_APB1_DIV_16))
|
||||
|
||||
#define IS_LL_UTILS_APB2_DIV(__VALUE__) (((__VALUE__) == LL_RCC_APB2_DIV_1) \
|
||||
|| ((__VALUE__) == LL_RCC_APB2_DIV_2) \
|
||||
|| ((__VALUE__) == LL_RCC_APB2_DIV_4) \
|
||||
|| ((__VALUE__) == LL_RCC_APB2_DIV_8) \
|
||||
|| ((__VALUE__) == LL_RCC_APB2_DIV_16))
|
||||
|
||||
#define IS_LL_UTILS_PLLM_VALUE(__VALUE__) (((__VALUE__) == LL_RCC_PLLM_DIV_1) \
|
||||
|| ((__VALUE__) == LL_RCC_PLLM_DIV_2) \
|
||||
|| ((__VALUE__) == LL_RCC_PLLM_DIV_3) \
|
||||
|| ((__VALUE__) == LL_RCC_PLLM_DIV_4) \
|
||||
|| ((__VALUE__) == LL_RCC_PLLM_DIV_5) \
|
||||
|| ((__VALUE__) == LL_RCC_PLLM_DIV_6) \
|
||||
|| ((__VALUE__) == LL_RCC_PLLM_DIV_7) \
|
||||
|| ((__VALUE__) == LL_RCC_PLLM_DIV_8))
|
||||
|
||||
#define IS_LL_UTILS_PLLN_VALUE(__VALUE__) ((8U <= (__VALUE__)) && ((__VALUE__) <= 86U))
|
||||
|
||||
#define IS_LL_UTILS_PLLR_VALUE(__VALUE__) (((__VALUE__) == LL_RCC_PLLR_DIV_2) \
|
||||
|| ((__VALUE__) == LL_RCC_PLLR_DIV_4) \
|
||||
|| ((__VALUE__) == LL_RCC_PLLR_DIV_6) \
|
||||
|| ((__VALUE__) == LL_RCC_PLLR_DIV_8))
|
||||
|
||||
#define IS_LL_UTILS_PLLVCO_INPUT(__VALUE__) ((UTILS_PLLVCO_INPUT_MIN <= (__VALUE__)) && ((__VALUE__) <= UTILS_PLLVCO_INPUT_MAX))
|
||||
|
||||
#define IS_LL_UTILS_PLLVCO_OUTPUT(__VALUE__) ((UTILS_PLLVCO_OUTPUT_MIN <= (__VALUE__)) && ((__VALUE__) <= UTILS_PLLVCO_OUTPUT_MAX))
|
||||
|
||||
#define IS_LL_UTILS_PLL_FREQUENCY(__VALUE__) ((LL_PWR_GetRegulVoltageScaling() == LL_PWR_REGU_VOLTAGE_SCALE1) ? ((__VALUE__) <= UTILS_MAX_FREQUENCY_SCALE1) : \
|
||||
((__VALUE__) <= UTILS_MAX_FREQUENCY_SCALE2))
|
||||
|
||||
#define IS_LL_UTILS_HSE_BYPASS(__STATE__) (((__STATE__) == LL_UTILS_HSEBYPASS_ON) \
|
||||
|| ((__STATE__) == LL_UTILS_HSEBYPASS_OFF))
|
||||
|
||||
#define IS_LL_UTILS_HSE_FREQUENCY(__FREQUENCY__) (((__FREQUENCY__) >= UTILS_HSE_FREQUENCY_MIN) && ((__FREQUENCY__) <= UTILS_HSE_FREQUENCY_MAX))
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/** @defgroup UTILS_LL_Private_Functions UTILS Private functions
|
||||
* @{
|
||||
*/
|
||||
static uint32_t UTILS_GetPLLOutputFrequency(uint32_t PLL_InputFrequency,
|
||||
LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct);
|
||||
static ErrorStatus UTILS_EnablePLLAndSwitchSystem(uint32_t SYSCLK_Frequency, LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct);
|
||||
static ErrorStatus UTILS_PLL_IsBusy(void);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Exported functions --------------------------------------------------------*/
|
||||
/** @addtogroup UTILS_LL_Exported_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup UTILS_LL_EF_DELAY
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief This function configures the Cortex-M SysTick source to have 1ms time base.
|
||||
* @note When a RTOS is used, it is recommended to avoid changing the Systick
|
||||
* configuration by calling this function, for a delay use rather osDelay RTOS service.
|
||||
* @param HCLKFrequency HCLK frequency in Hz
|
||||
* @note HCLK frequency can be calculated thanks to RCC helper macro or function @ref LL_RCC_GetSystemClocksFreq
|
||||
* @retval None
|
||||
*/
|
||||
void LL_Init1msTick(uint32_t HCLKFrequency)
|
||||
{
|
||||
/* Use frequency provided in argument */
|
||||
LL_InitTick(HCLKFrequency, 1000U);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function provides accurate delay (in milliseconds) based
|
||||
* on SysTick counter flag
|
||||
* @note When a RTOS is used, it is recommended to avoid using blocking delay
|
||||
* and use rather osDelay service.
|
||||
* @note To respect 1ms timebase, user should call @ref LL_Init1msTick function which
|
||||
* will configure Systick to 1ms
|
||||
* @param Delay specifies the delay time length, in milliseconds.
|
||||
* @retval None
|
||||
*/
|
||||
void LL_mDelay(uint32_t Delay)
|
||||
{
|
||||
__IO uint32_t tmp = SysTick->CTRL; /* Clear the COUNTFLAG first */
|
||||
uint32_t tmpDelay = Delay;
|
||||
|
||||
/* Add this code to indicate that local variable is not used */
|
||||
((void)tmp);
|
||||
|
||||
/* Add a period to guaranty minimum wait */
|
||||
if(tmpDelay < LL_MAX_DELAY)
|
||||
{
|
||||
tmpDelay++;
|
||||
}
|
||||
|
||||
while (tmpDelay != 0U)
|
||||
{
|
||||
if((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) != 0U)
|
||||
{
|
||||
tmpDelay--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup UTILS_EF_SYSTEM
|
||||
* @brief System Configuration functions
|
||||
*
|
||||
@verbatim
|
||||
===============================================================================
|
||||
##### System Configuration functions #####
|
||||
===============================================================================
|
||||
[..]
|
||||
System, AHB and APB buses clocks configuration
|
||||
|
||||
(+) The maximum frequency of the SYSCLK, HCLK, PCLK1 and PCLK2 is
|
||||
120000000 Hz for STM32L4Rx/STM32L4Sx devices and 80000000 Hz for others.
|
||||
@endverbatim
|
||||
@internal
|
||||
Depending on the device voltage range, the maximum frequency should be
|
||||
adapted accordingly:
|
||||
|
||||
(++) Table 1. HCLK clock frequency for STM32L4+ Series devices
|
||||
(++) +--------------------------------------------------------+
|
||||
(++) | Latency | HCLK clock frequency (MHz) |
|
||||
(++) | |--------------------------------------|
|
||||
(++) | | voltage range 1 | voltage range 2 |
|
||||
(++) | | 1.2 V | 1.0 V |
|
||||
(++) |-----------------|-------------------|------------------|
|
||||
(++) |0WS(1 CPU cycles)| 0 < HCLK <= 20 | 0 < HCLK <= 8 |
|
||||
(++) |-----------------|-------------------|------------------|
|
||||
(++) |1WS(2 CPU cycles)| 20 < HCLK <= 40 | 8 < HCLK <= 16 |
|
||||
(++) |-----------------|-------------------|------------------|
|
||||
(++) |2WS(3 CPU cycles)| 40 < HCLK <= 60 | 16 < HCLK <= 26 |
|
||||
(++) |-----------------|-------------------|------------------|
|
||||
(++) |3WS(4 CPU cycles)| 60 < HCLK <= 80 | 16 < HCLK <= 26 |
|
||||
(++) |-----------------|-------------------|------------------|
|
||||
(++) |4WS(5 CPU cycles)| 80 < HCLK <= 100 | 16 < HCLK <= 26 |
|
||||
(++) |-----------------|-------------------|------------------|
|
||||
(++) |5WS(6 CPU cycles)| 100 < HCLK <= 120 | 16 < HCLK <= 26 |
|
||||
(++) +--------------------------------------------------------+
|
||||
|
||||
(++) Table 2. HCLK clock frequency for STM32L4 Series devices
|
||||
(++) +-------------------------------------------------------+
|
||||
(++) | Latency | HCLK clock frequency (MHz) |
|
||||
(++) | |-------------------------------------|
|
||||
(++) | | voltage range 1 | voltage range 2 |
|
||||
(++) | | 1.2 V | 1.0 V |
|
||||
(++) |-----------------|------------------|------------------|
|
||||
(++) |0WS(1 CPU cycles)| 0 < HCLK <= 16 | 0 < HCLK <= 6 |
|
||||
(++) |-----------------|------------------|------------------|
|
||||
(++) |1WS(2 CPU cycles)| 16 < HCLK <= 32 | 6 < HCLK <= 12 |
|
||||
(++) |-----------------|------------------|------------------|
|
||||
(++) |2WS(3 CPU cycles)| 32 < HCLK <= 48 | 12 < HCLK <= 18 |
|
||||
(++) |-----------------|------------------|------------------|
|
||||
(++) |3WS(4 CPU cycles)| 48 < HCLK <= 64 | 18 < HCLK <= 26 |
|
||||
(++) |-----------------|------------------|------------------|
|
||||
(++) |4WS(5 CPU cycles)| 64 < HCLK <= 80 | 18 < HCLK <= 26 |
|
||||
(++) +-------------------------------------------------------+
|
||||
|
||||
@endinternal
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief This function sets directly SystemCoreClock CMSIS variable.
|
||||
* @note Variable can be calculated also through SystemCoreClockUpdate function.
|
||||
* @param HCLKFrequency HCLK frequency in Hz (can be calculated thanks to RCC helper macro)
|
||||
* @retval None
|
||||
*/
|
||||
void LL_SetSystemCoreClock(uint32_t HCLKFrequency)
|
||||
{
|
||||
/* HCLK clock frequency */
|
||||
SystemCoreClock = HCLKFrequency;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Update number of Flash wait states in line with new frequency and current
|
||||
voltage range.
|
||||
* @param HCLKFrequency HCLK frequency
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: Latency has been modified
|
||||
* - ERROR: Latency cannot be modified
|
||||
*/
|
||||
ErrorStatus LL_SetFlashLatency(uint32_t HCLKFrequency)
|
||||
{
|
||||
ErrorStatus status = SUCCESS;
|
||||
|
||||
uint32_t latency = LL_FLASH_LATENCY_0; /* default value 0WS */
|
||||
|
||||
/* Frequency cannot be equal to 0 or greater than max clock */
|
||||
if ((HCLKFrequency == 0U) || (HCLKFrequency > UTILS_MAX_FREQUENCY_SCALE1))
|
||||
{
|
||||
status = ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(LL_PWR_GetRegulVoltageScaling() == LL_PWR_REGU_VOLTAGE_SCALE1)
|
||||
{
|
||||
#if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || \
|
||||
defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
|
||||
if(HCLKFrequency > UTILS_SCALE1_LATENCY5_FREQ)
|
||||
{
|
||||
/* 100 < HCLK <= 120 => 5WS (6 CPU cycles) */
|
||||
latency = LL_FLASH_LATENCY_5;
|
||||
}
|
||||
else if(HCLKFrequency > UTILS_SCALE1_LATENCY4_FREQ)
|
||||
{
|
||||
/* 80 < HCLK <= 100 => 4WS (5 CPU cycles) */
|
||||
latency = LL_FLASH_LATENCY_4;
|
||||
}
|
||||
else if(HCLKFrequency > UTILS_SCALE1_LATENCY3_FREQ)
|
||||
{
|
||||
/* 60 < HCLK <= 80 => 3WS (4 CPU cycles) */
|
||||
latency = LL_FLASH_LATENCY_3;
|
||||
}
|
||||
else if(HCLKFrequency > UTILS_SCALE1_LATENCY2_FREQ)
|
||||
{
|
||||
/* 40 < HCLK <= 20 => 2WS (3 CPU cycles) */
|
||||
latency = LL_FLASH_LATENCY_2;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(HCLKFrequency > UTILS_SCALE1_LATENCY1_FREQ)
|
||||
{
|
||||
/* 20 < HCLK <= 40 => 1WS (2 CPU cycles) */
|
||||
latency = LL_FLASH_LATENCY_1;
|
||||
}
|
||||
/* else HCLKFrequency <= 10MHz default LL_FLASH_LATENCY_0 0WS */
|
||||
}
|
||||
#else
|
||||
if(HCLKFrequency > UTILS_SCALE1_LATENCY4_FREQ)
|
||||
{
|
||||
/* 64 < HCLK <= 80 => 4WS (5 CPU cycles) */
|
||||
latency = LL_FLASH_LATENCY_4;
|
||||
}
|
||||
else if(HCLKFrequency > UTILS_SCALE1_LATENCY3_FREQ)
|
||||
{
|
||||
/* 48 < HCLK <= 64 => 3WS (4 CPU cycles) */
|
||||
latency = LL_FLASH_LATENCY_3;
|
||||
}
|
||||
else if(HCLKFrequency > UTILS_SCALE1_LATENCY2_FREQ)
|
||||
{
|
||||
/* 32 < HCLK <= 48 => 2WS (3 CPU cycles) */
|
||||
latency = LL_FLASH_LATENCY_2;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(HCLKFrequency > UTILS_SCALE1_LATENCY1_FREQ)
|
||||
{
|
||||
/* 16 < HCLK <= 32 => 1WS (2 CPU cycles) */
|
||||
latency = LL_FLASH_LATENCY_1;
|
||||
}
|
||||
/* else HCLKFrequency <= 16MHz default LL_FLASH_LATENCY_0 0WS */
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else /* SCALE2 */
|
||||
{
|
||||
#if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || \
|
||||
defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
|
||||
if(HCLKFrequency > UTILS_MAX_FREQUENCY_SCALE2)
|
||||
{
|
||||
/* Unexpected HCLK > 26 */
|
||||
status = ERROR;
|
||||
}
|
||||
else if(HCLKFrequency > UTILS_SCALE2_LATENCY2_FREQ)
|
||||
{
|
||||
/* 16 < HCLK <= 26 => 2WS (3 CPU cycles) */
|
||||
latency = LL_FLASH_LATENCY_2;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(HCLKFrequency > UTILS_SCALE2_LATENCY1_FREQ)
|
||||
{
|
||||
/* 8 < HCLK <= 16 => 1WS (2 CPU cycles) */
|
||||
latency = LL_FLASH_LATENCY_1;
|
||||
}
|
||||
/* else HCLKFrequency <= 8MHz default LL_FLASH_LATENCY_0 0WS */
|
||||
}
|
||||
#else
|
||||
if(HCLKFrequency > UTILS_MAX_FREQUENCY_SCALE2)
|
||||
{
|
||||
/* Unexpected HCLK > 26 */
|
||||
status = ERROR;
|
||||
}
|
||||
else if(HCLKFrequency > UTILS_SCALE2_LATENCY3_FREQ)
|
||||
{
|
||||
/* 18 < HCLK <= 26 => 3WS (4 CPU cycles) */
|
||||
latency = LL_FLASH_LATENCY_3;
|
||||
}
|
||||
else if(HCLKFrequency > UTILS_SCALE2_LATENCY2_FREQ)
|
||||
{
|
||||
/* 12 < HCLK <= 18 => 2WS (3 CPU cycles) */
|
||||
latency = LL_FLASH_LATENCY_2;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(HCLKFrequency > UTILS_SCALE2_LATENCY1_FREQ)
|
||||
{
|
||||
/* 6 < HCLK <= 12 => 1WS (2 CPU cycles) */
|
||||
latency = LL_FLASH_LATENCY_1;
|
||||
}
|
||||
/* else HCLKFrequency <= 6MHz default LL_FLASH_LATENCY_0 0WS */
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
LL_FLASH_SetLatency(latency);
|
||||
|
||||
/* Check that the new number of wait states is taken into account to access the Flash
|
||||
memory by reading the FLASH_ACR register */
|
||||
if(LL_FLASH_GetLatency() != latency)
|
||||
{
|
||||
status = ERROR;
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function configures system clock with MSI as clock source of the PLL
|
||||
* @note The application needs to ensure that PLL, PLLSAI1 and/or PLLSAI2 are disabled.
|
||||
* @note Function is based on the following formula:
|
||||
* - PLL output frequency = (((MSI frequency / PLLM) * PLLN) / PLLR)
|
||||
* - PLLM: ensure that the VCO input frequency ranges from 4 to 16 MHz (PLLVCO_input = MSI frequency / PLLM)
|
||||
* - PLLN: ensure that the VCO output frequency is between 64 and 344 MHz (PLLVCO_output = PLLVCO_input * PLLN)
|
||||
* - PLLR: ensure that max frequency at 120000000 Hz is reached (PLLVCO_output / PLLR)
|
||||
* @param UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
|
||||
* the configuration information for the PLL.
|
||||
* @param UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
|
||||
* the configuration information for the BUS prescalers.
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: Max frequency configuration done
|
||||
* - ERROR: Max frequency configuration not done
|
||||
*/
|
||||
ErrorStatus LL_PLL_ConfigSystemClock_MSI(LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct,
|
||||
LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
|
||||
{
|
||||
ErrorStatus status = SUCCESS;
|
||||
uint32_t pllfreq, msi_range;
|
||||
#if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || \
|
||||
defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
|
||||
uint32_t hpre = 0U; /* Set default value */
|
||||
#endif
|
||||
|
||||
/* Check if one of the PLL is enabled */
|
||||
if(UTILS_PLL_IsBusy() == SUCCESS)
|
||||
{
|
||||
/* Get the current MSI range */
|
||||
if(LL_RCC_MSI_IsEnabledRangeSelect() != 0U)
|
||||
{
|
||||
msi_range = LL_RCC_MSI_GetRange();
|
||||
switch (msi_range)
|
||||
{
|
||||
case LL_RCC_MSIRANGE_0: /* MSI = 100 KHz */
|
||||
case LL_RCC_MSIRANGE_1: /* MSI = 200 KHz */
|
||||
case LL_RCC_MSIRANGE_2: /* MSI = 400 KHz */
|
||||
case LL_RCC_MSIRANGE_3: /* MSI = 800 KHz */
|
||||
case LL_RCC_MSIRANGE_4: /* MSI = 1 MHz */
|
||||
case LL_RCC_MSIRANGE_5: /* MSI = 2 MHz */
|
||||
/* PLLVCO input frequency is not in the range from 4 to 16 MHz*/
|
||||
status = ERROR;
|
||||
break;
|
||||
|
||||
case LL_RCC_MSIRANGE_6: /* MSI = 4 MHz */
|
||||
case LL_RCC_MSIRANGE_7: /* MSI = 8 MHz */
|
||||
case LL_RCC_MSIRANGE_8: /* MSI = 16 MHz */
|
||||
case LL_RCC_MSIRANGE_9: /* MSI = 24 MHz */
|
||||
case LL_RCC_MSIRANGE_10: /* MSI = 32 MHz */
|
||||
case LL_RCC_MSIRANGE_11: /* MSI = 48 MHz */
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
msi_range = LL_RCC_MSI_GetRangeAfterStandby();
|
||||
switch (msi_range)
|
||||
{
|
||||
case LL_RCC_MSISRANGE_4: /* MSI = 1 MHz */
|
||||
case LL_RCC_MSISRANGE_5: /* MSI = 2 MHz */
|
||||
/* PLLVCO input frequency is not in the range from 4 to 16 MHz*/
|
||||
status = ERROR;
|
||||
break;
|
||||
|
||||
case LL_RCC_MSISRANGE_7: /* MSI = 8 MHz */
|
||||
case LL_RCC_MSISRANGE_6: /* MSI = 4 MHz */
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Main PLL configuration and activation */
|
||||
if(status != ERROR)
|
||||
{
|
||||
/* Calculate the new PLL output frequency */
|
||||
pllfreq = UTILS_GetPLLOutputFrequency(__LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_IsEnabledRangeSelect(), msi_range),
|
||||
UTILS_PLLInitStruct);
|
||||
|
||||
/* Enable MSI if not enabled */
|
||||
if(LL_RCC_MSI_IsReady() != 1U)
|
||||
{
|
||||
LL_RCC_MSI_Enable();
|
||||
while ((LL_RCC_MSI_IsReady() != 1U))
|
||||
{
|
||||
/* Wait for MSI ready */
|
||||
}
|
||||
}
|
||||
|
||||
/* Configure PLL */
|
||||
LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_MSI, UTILS_PLLInitStruct->PLLM, UTILS_PLLInitStruct->PLLN,
|
||||
UTILS_PLLInitStruct->PLLR);
|
||||
|
||||
#if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || \
|
||||
defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
|
||||
/* Prevent undershoot at highest frequency by applying intermediate AHB prescaler 2 */
|
||||
if(pllfreq > 80000000U)
|
||||
{
|
||||
if(UTILS_ClkInitStruct->AHBCLKDivider == LL_RCC_SYSCLK_DIV_1)
|
||||
{
|
||||
UTILS_ClkInitStruct->AHBCLKDivider = LL_RCC_SYSCLK_DIV_2;
|
||||
hpre = LL_RCC_SYSCLK_DIV_2;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/* Enable PLL and switch system clock to PLL */
|
||||
status = UTILS_EnablePLLAndSwitchSystem(pllfreq, UTILS_ClkInitStruct);
|
||||
|
||||
#if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || \
|
||||
defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
|
||||
/* Apply definitive AHB prescaler value if necessary */
|
||||
if((status == SUCCESS) && (hpre != LL_RCC_SYSCLK_DIV_1))
|
||||
{
|
||||
/* Set FLASH latency to highest latency */
|
||||
status = LL_SetFlashLatency(pllfreq);
|
||||
if(status == SUCCESS)
|
||||
{
|
||||
UTILS_ClkInitStruct->AHBCLKDivider = LL_RCC_SYSCLK_DIV_1;
|
||||
LL_RCC_SetAHBPrescaler(UTILS_ClkInitStruct->AHBCLKDivider);
|
||||
LL_SetSystemCoreClock(pllfreq);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Current PLL configuration cannot be modified */
|
||||
status = ERROR;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function configures system clock at maximum frequency with HSI as clock source of the PLL
|
||||
* @note The application need to ensure that PLL, PLLSAI1 and/or PLLSAI2 are disabled.
|
||||
* @note Function is based on the following formula:
|
||||
* - PLL output frequency = (((HSI frequency / PLLM) * PLLN) / PLLR)
|
||||
* - PLLM: ensure that the VCO input frequency ranges from 4 to 16 MHz (PLLVCO_input = HSI frequency / PLLM)
|
||||
* - PLLN: ensure that the VCO output frequency is between 64 and 344 MHz (PLLVCO_output = PLLVCO_input * PLLN)
|
||||
* - PLLR: ensure that max frequency at 120000000 Hz is reach (PLLVCO_output / PLLR)
|
||||
* @param UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
|
||||
* the configuration information for the PLL.
|
||||
* @param UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
|
||||
* the configuration information for the BUS prescalers.
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: Max frequency configuration done
|
||||
* - ERROR: Max frequency configuration not done
|
||||
*/
|
||||
ErrorStatus LL_PLL_ConfigSystemClock_HSI(LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct,
|
||||
LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
|
||||
{
|
||||
ErrorStatus status;
|
||||
uint32_t pllfreq;
|
||||
#if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || \
|
||||
defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
|
||||
uint32_t hpre = LL_RCC_SYSCLK_DIV_1; /* Set default value */
|
||||
#endif
|
||||
|
||||
/* Check if one of the PLL is enabled */
|
||||
if(UTILS_PLL_IsBusy() == SUCCESS)
|
||||
{
|
||||
/* Calculate the new PLL output frequency */
|
||||
pllfreq = UTILS_GetPLLOutputFrequency(HSI_VALUE, UTILS_PLLInitStruct);
|
||||
|
||||
/* Enable HSI if not enabled */
|
||||
if(LL_RCC_HSI_IsReady() != 1U)
|
||||
{
|
||||
LL_RCC_HSI_Enable();
|
||||
while (LL_RCC_HSI_IsReady() != 1U)
|
||||
{
|
||||
/* Wait for HSI ready */
|
||||
}
|
||||
}
|
||||
|
||||
/* Configure PLL */
|
||||
LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSI, UTILS_PLLInitStruct->PLLM, UTILS_PLLInitStruct->PLLN,
|
||||
UTILS_PLLInitStruct->PLLR);
|
||||
|
||||
#if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || \
|
||||
defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
|
||||
/* Prevent undershoot at highest frequency by applying intermediate AHB prescaler 2 */
|
||||
if(pllfreq > 80000000U)
|
||||
{
|
||||
if(UTILS_ClkInitStruct->AHBCLKDivider == LL_RCC_SYSCLK_DIV_1)
|
||||
{
|
||||
UTILS_ClkInitStruct->AHBCLKDivider = LL_RCC_SYSCLK_DIV_2;
|
||||
hpre = LL_RCC_SYSCLK_DIV_2;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/* Enable PLL and switch system clock to PLL */
|
||||
status = UTILS_EnablePLLAndSwitchSystem(pllfreq, UTILS_ClkInitStruct);
|
||||
|
||||
#if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || \
|
||||
defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
|
||||
/* Apply definitive AHB prescaler value if necessary */
|
||||
if((status == SUCCESS) && (hpre != LL_RCC_SYSCLK_DIV_1))
|
||||
{
|
||||
/* Set FLASH latency to highest latency */
|
||||
status = LL_SetFlashLatency(pllfreq);
|
||||
if(status == SUCCESS)
|
||||
{
|
||||
UTILS_ClkInitStruct->AHBCLKDivider = LL_RCC_SYSCLK_DIV_1;
|
||||
LL_RCC_SetAHBPrescaler(UTILS_ClkInitStruct->AHBCLKDivider);
|
||||
LL_SetSystemCoreClock(pllfreq);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Current PLL configuration cannot be modified */
|
||||
status = ERROR;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function configures system clock with HSE as clock source of the PLL
|
||||
* @note The application need to ensure that PLL, PLLSAI1 and/or PLLSAI2 are disabled.
|
||||
* @note Function is based on the following formula:
|
||||
* - PLL output frequency = (((HSE frequency / PLLM) * PLLN) / PLLR)
|
||||
* - PLLM: ensure that the VCO input frequency ranges from 4 to 16 MHz (PLLVCO_input = HSE frequency / PLLM)
|
||||
* - PLLN: ensure that the VCO output frequency is between 64 and 344 MHz (PLLVCO_output = PLLVCO_input * PLLN)
|
||||
* - PLLR: ensure that max frequency at 120000000 Hz is reached (PLLVCO_output / PLLR)
|
||||
* @param HSEFrequency Value between Min_Data = 4000000 and Max_Data = 48000000
|
||||
* @param HSEBypass This parameter can be one of the following values:
|
||||
* @arg @ref LL_UTILS_HSEBYPASS_ON
|
||||
* @arg @ref LL_UTILS_HSEBYPASS_OFF
|
||||
* @param UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
|
||||
* the configuration information for the PLL.
|
||||
* @param UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
|
||||
* the configuration information for the BUS prescalers.
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: Max frequency configuration done
|
||||
* - ERROR: Max frequency configuration not done
|
||||
*/
|
||||
ErrorStatus LL_PLL_ConfigSystemClock_HSE(uint32_t HSEFrequency, uint32_t HSEBypass,
|
||||
LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct, LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
|
||||
{
|
||||
ErrorStatus status;
|
||||
uint32_t pllfreq;
|
||||
#if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || \
|
||||
defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
|
||||
uint32_t hpre = 0U; /* Set default value */
|
||||
#endif
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_LL_UTILS_HSE_FREQUENCY(HSEFrequency));
|
||||
assert_param(IS_LL_UTILS_HSE_BYPASS(HSEBypass));
|
||||
|
||||
/* Check if one of the PLL is enabled */
|
||||
if(UTILS_PLL_IsBusy() == SUCCESS)
|
||||
{
|
||||
/* Calculate the new PLL output frequency */
|
||||
pllfreq = UTILS_GetPLLOutputFrequency(HSEFrequency, UTILS_PLLInitStruct);
|
||||
|
||||
/* Enable HSE if not enabled */
|
||||
if(LL_RCC_HSE_IsReady() != 1U)
|
||||
{
|
||||
/* Check if need to enable HSE bypass feature or not */
|
||||
if(HSEBypass == LL_UTILS_HSEBYPASS_ON)
|
||||
{
|
||||
LL_RCC_HSE_EnableBypass();
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_RCC_HSE_DisableBypass();
|
||||
}
|
||||
|
||||
/* Enable HSE */
|
||||
LL_RCC_HSE_Enable();
|
||||
while (LL_RCC_HSE_IsReady() != 1U)
|
||||
{
|
||||
/* Wait for HSE ready */
|
||||
}
|
||||
}
|
||||
|
||||
/* Configure PLL */
|
||||
LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSE, UTILS_PLLInitStruct->PLLM, UTILS_PLLInitStruct->PLLN,
|
||||
UTILS_PLLInitStruct->PLLR);
|
||||
|
||||
#if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || \
|
||||
defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
|
||||
/* Prevent undershoot at highest frequency by applying intermediate AHB prescaler 2 */
|
||||
if(pllfreq > 80000000U)
|
||||
{
|
||||
if(UTILS_ClkInitStruct->AHBCLKDivider == LL_RCC_SYSCLK_DIV_1)
|
||||
{
|
||||
UTILS_ClkInitStruct->AHBCLKDivider = LL_RCC_SYSCLK_DIV_2;
|
||||
hpre = LL_RCC_SYSCLK_DIV_2;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/* Enable PLL and switch system clock to PLL */
|
||||
status = UTILS_EnablePLLAndSwitchSystem(pllfreq, UTILS_ClkInitStruct);
|
||||
|
||||
#if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || \
|
||||
defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
|
||||
/* Apply definitive AHB prescaler value if necessary */
|
||||
if((status == SUCCESS) && (hpre != LL_RCC_SYSCLK_DIV_1))
|
||||
{
|
||||
/* Set FLASH latency to highest latency */
|
||||
status = LL_SetFlashLatency(pllfreq);
|
||||
if(status == SUCCESS)
|
||||
{
|
||||
UTILS_ClkInitStruct->AHBCLKDivider = LL_RCC_SYSCLK_DIV_1;
|
||||
LL_RCC_SetAHBPrescaler(UTILS_ClkInitStruct->AHBCLKDivider);
|
||||
LL_SetSystemCoreClock(pllfreq);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Current PLL configuration cannot be modified */
|
||||
status = ERROR;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup UTILS_LL_Private_Functions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Function to check that PLL can be modified
|
||||
* @param PLL_InputFrequency PLL input frequency (in Hz)
|
||||
* @param UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
|
||||
* the configuration information for the PLL.
|
||||
* @retval PLL output frequency (in Hz)
|
||||
*/
|
||||
static uint32_t UTILS_GetPLLOutputFrequency(uint32_t PLL_InputFrequency, LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct)
|
||||
{
|
||||
uint32_t pllfreq;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_LL_UTILS_PLLM_VALUE(UTILS_PLLInitStruct->PLLM));
|
||||
assert_param(IS_LL_UTILS_PLLN_VALUE(UTILS_PLLInitStruct->PLLN));
|
||||
assert_param(IS_LL_UTILS_PLLR_VALUE(UTILS_PLLInitStruct->PLLR));
|
||||
|
||||
/* Check different PLL parameters according to RM */
|
||||
/* - PLLM: ensure that the VCO input frequency ranges from 4 to 16 MHz. */
|
||||
pllfreq = PLL_InputFrequency / (((UTILS_PLLInitStruct->PLLM >> RCC_PLLCFGR_PLLM_Pos) + 1U));
|
||||
assert_param(IS_LL_UTILS_PLLVCO_INPUT(pllfreq));
|
||||
|
||||
/* - PLLN: ensure that the VCO output frequency is between 64 and 344 MHz.*/
|
||||
pllfreq = pllfreq * (UTILS_PLLInitStruct->PLLN & (RCC_PLLCFGR_PLLN >> RCC_PLLCFGR_PLLN_Pos));
|
||||
assert_param(IS_LL_UTILS_PLLVCO_OUTPUT(pllfreq));
|
||||
|
||||
/* - PLLR: ensure that max frequency at 120000000 Hz is reached */
|
||||
pllfreq = pllfreq / (((UTILS_PLLInitStruct->PLLR >> RCC_PLLCFGR_PLLR_Pos) + 1U) * 2U);
|
||||
assert_param(IS_LL_UTILS_PLL_FREQUENCY(pllfreq));
|
||||
|
||||
return pllfreq;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Function to check that PLL can be modified
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: PLL modification can be done
|
||||
* - ERROR: PLL is busy
|
||||
*/
|
||||
static ErrorStatus UTILS_PLL_IsBusy(void)
|
||||
{
|
||||
ErrorStatus status = SUCCESS;
|
||||
|
||||
/* Check if PLL is busy*/
|
||||
if(LL_RCC_PLL_IsReady() != 0U)
|
||||
{
|
||||
/* PLL configuration cannot be modified */
|
||||
status = ERROR;
|
||||
}
|
||||
|
||||
#if defined(RCC_PLLSAI1_SUPPORT)
|
||||
/* Check if PLLSAI1 is busy*/
|
||||
if(LL_RCC_PLLSAI1_IsReady() != 0U)
|
||||
{
|
||||
/* PLLSAI1 configuration cannot be modified */
|
||||
status = ERROR;
|
||||
}
|
||||
#endif /*RCC_PLLSAI1_SUPPORT*/
|
||||
#if defined(RCC_PLLSAI2_SUPPORT)
|
||||
|
||||
/* Check if PLLSAI2 is busy*/
|
||||
if(LL_RCC_PLLSAI2_IsReady() != 0U)
|
||||
{
|
||||
/* PLLSAI2 configuration cannot be modified */
|
||||
status = ERROR;
|
||||
}
|
||||
#endif /*RCC_PLLSAI2_SUPPORT*/
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Function to enable PLL and switch system clock to PLL
|
||||
* @param SYSCLK_Frequency SYSCLK frequency
|
||||
* @param UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
|
||||
* the configuration information for the BUS prescalers.
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: No problem to switch system to PLL
|
||||
* - ERROR: Problem to switch system to PLL
|
||||
*/
|
||||
static ErrorStatus UTILS_EnablePLLAndSwitchSystem(uint32_t SYSCLK_Frequency, LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
|
||||
{
|
||||
ErrorStatus status = SUCCESS;
|
||||
uint32_t hclk_frequency;
|
||||
|
||||
assert_param(IS_LL_UTILS_SYSCLK_DIV(UTILS_ClkInitStruct->AHBCLKDivider));
|
||||
assert_param(IS_LL_UTILS_APB1_DIV(UTILS_ClkInitStruct->APB1CLKDivider));
|
||||
assert_param(IS_LL_UTILS_APB2_DIV(UTILS_ClkInitStruct->APB2CLKDivider));
|
||||
|
||||
/* Calculate HCLK frequency */
|
||||
hclk_frequency = __LL_RCC_CALC_HCLK_FREQ(SYSCLK_Frequency, UTILS_ClkInitStruct->AHBCLKDivider);
|
||||
|
||||
/* Increasing the number of wait states because of higher CPU frequency */
|
||||
if(SystemCoreClock < hclk_frequency)
|
||||
{
|
||||
/* Set FLASH latency to highest latency */
|
||||
status = LL_SetFlashLatency(hclk_frequency);
|
||||
}
|
||||
|
||||
/* Update system clock configuration */
|
||||
if(status == SUCCESS)
|
||||
{
|
||||
/* Enable PLL */
|
||||
LL_RCC_PLL_Enable();
|
||||
LL_RCC_PLL_EnableDomain_SYS();
|
||||
while (LL_RCC_PLL_IsReady() != 1U)
|
||||
{
|
||||
/* Wait for PLL ready */
|
||||
}
|
||||
|
||||
/* Sysclk activation on the main PLL */
|
||||
LL_RCC_SetAHBPrescaler(UTILS_ClkInitStruct->AHBCLKDivider);
|
||||
LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL);
|
||||
while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL)
|
||||
{
|
||||
/* Wait for system clock switch to PLL */
|
||||
}
|
||||
|
||||
/* Set APB1 & APB2 prescaler*/
|
||||
LL_RCC_SetAPB1Prescaler(UTILS_ClkInitStruct->APB1CLKDivider);
|
||||
LL_RCC_SetAPB2Prescaler(UTILS_ClkInitStruct->APB2CLKDivider);
|
||||
}
|
||||
|
||||
/* Decreasing the number of wait states because of lower CPU frequency */
|
||||
if(SystemCoreClock > hclk_frequency)
|
||||
{
|
||||
/* Set FLASH latency to lowest latency */
|
||||
status = LL_SetFlashLatency(hclk_frequency);
|
||||
}
|
||||
|
||||
/* Update SystemCoreClock variable */
|
||||
if(status == SUCCESS)
|
||||
{
|
||||
LL_SetSystemCoreClock(hclk_frequency);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
Reference in New Issue
Block a user