started layout
This commit is contained in:
@@ -0,0 +1,615 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32c0xx_hal.c
|
||||
* @author MCD Application Team
|
||||
* @brief HAL module driver.
|
||||
* This is the common part of the HAL initialization
|
||||
*
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2022 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 "stm32c0xx_hal.h"
|
||||
|
||||
/** @addtogroup STM32C0xx_HAL_Driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup HAL
|
||||
* @brief HAL module driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifdef HAL_MODULE_ENABLED
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
|
||||
/** @defgroup HAL_Private_Constants HAL Private Constants
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief STM32C0xx HAL Driver version number
|
||||
*/
|
||||
#define __STM32C0xx_HAL_VERSION_MAIN (0x01U) /*!< [31:24] main version */
|
||||
#define __STM32C0xx_HAL_VERSION_SUB1 (0x04U) /*!< [23:16] sub1 version */
|
||||
#define __STM32C0xx_HAL_VERSION_SUB2 (0x00U) /*!< [15:8] sub2 version */
|
||||
#define __STM32C0xx_HAL_VERSION_RC (0x00U) /*!< [7:0] release candidate */
|
||||
#define __STM32C0xx_HAL_VERSION ((__STM32C0xx_HAL_VERSION_MAIN << 24U)\
|
||||
|(__STM32C0xx_HAL_VERSION_SUB1 << 16U)\
|
||||
|(__STM32C0xx_HAL_VERSION_SUB2 << 8U )\
|
||||
|(__STM32C0xx_HAL_VERSION_RC))
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* Exported variables ---------------------------------------------------------*/
|
||||
/** @defgroup HAL_Exported_Variables HAL Exported Variables
|
||||
* @{
|
||||
*/
|
||||
__IO uint32_t uwTick;
|
||||
uint32_t uwTickPrio = (1UL << __NVIC_PRIO_BITS); /* Invalid PRIO */
|
||||
HAL_TickFreqTypeDef uwTickFreq = HAL_TICK_FREQ_DEFAULT; /* 1KHz */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* Exported functions --------------------------------------------------------*/
|
||||
|
||||
/** @addtogroup HAL_Exported_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup HAL_Exported_Functions_Group1
|
||||
* @brief HAL Initialization and Configuration functions
|
||||
*
|
||||
@verbatim
|
||||
===============================================================================
|
||||
##### HAL Initialization and Configuration 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 and the Instruction cache,
|
||||
* 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
|
||||
* stm32c0xx_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 HSI clock, as HSI is the clock
|
||||
* used after a system Reset.
|
||||
* 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 */
|
||||
/* Default configuration at reset is: */
|
||||
/* - Prefetch disabled */
|
||||
/* - Instruction cache enabled */
|
||||
|
||||
#if (INSTRUCTION_CACHE_ENABLE == 0U)
|
||||
__HAL_FLASH_INSTRUCTION_CACHE_DISABLE();
|
||||
#endif /* INSTRUCTION_CACHE_ENABLE */
|
||||
|
||||
#if (PREFETCH_ENABLE != 0U)
|
||||
__HAL_FLASH_PREFETCH_BUFFER_ENABLE();
|
||||
#endif /* PREFETCH_ENABLE */
|
||||
|
||||
/* Use SysTick as time base source and configure 1ms tick (default clock after Reset is HSI) */
|
||||
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 This function de-Initializes common part of the HAL and stops the source of time base.
|
||||
* @note This function is optional.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_DeInit(void)
|
||||
{
|
||||
/* Reset of all peripherals */
|
||||
__HAL_RCC_APB1_GRP1_FORCE_RESET();
|
||||
__HAL_RCC_APB1_GRP1_RELEASE_RESET();
|
||||
|
||||
__HAL_RCC_APB1_GRP2_FORCE_RESET();
|
||||
__HAL_RCC_APB1_GRP2_RELEASE_RESET();
|
||||
|
||||
__HAL_RCC_AHB_FORCE_RESET();
|
||||
__HAL_RCC_AHB_RELEASE_RESET();
|
||||
|
||||
__HAL_RCC_IOP_FORCE_RESET();
|
||||
__HAL_RCC_IOP_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 DeInitializes the MSP.
|
||||
* @retval None
|
||||
*/
|
||||
__weak void HAL_MspDeInit(void)
|
||||
{
|
||||
/* NOTE : This function should not be modified, when the callback is needed,
|
||||
the HAL_MspDeInit could be implemented in the user file
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function configures the source of the time base:
|
||||
* The time source is configured to have 1ms time base with a dedicated
|
||||
* Tick interrupt priority.
|
||||
* @note This function is called automatically at the beginning of program after
|
||||
* reset by HAL_Init() or at any time when clock is reconfigured by HAL_RCC_ClockConfig().
|
||||
* @note In the default implementation, SysTick timer is the source of time base.
|
||||
* It is used to generate interrupts at regular time intervals.
|
||||
* Care must be taken if HAL_Delay() is called from a peripheral ISR process,
|
||||
* The SysTick interrupt must have higher priority (numerically lower)
|
||||
* than the peripheral interrupt. Otherwise the caller ISR process will be blocked.
|
||||
* The function is declared as __weak to be overwritten in case of other
|
||||
* implementation in user file.
|
||||
* @param TickPriority Tick interrupt priority.
|
||||
* @retval HAL status
|
||||
*/
|
||||
__weak HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)
|
||||
{
|
||||
HAL_StatusTypeDef status = HAL_OK;
|
||||
|
||||
if ((uint32_t)uwTickFreq != 0UL)
|
||||
{
|
||||
/*Configure the SysTick to have interrupt in 1ms time basis*/
|
||||
if (HAL_SYSTICK_Config(SystemCoreClock / (1000UL / (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;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup HAL_Exported_Functions_Group2
|
||||
* @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 Provides a tick value in millisecond.
|
||||
* @note This function is declared as __weak to be overwritten in case of other
|
||||
* implementations in user file.
|
||||
* @retval tick value
|
||||
*/
|
||||
__weak uint32_t HAL_GetTick(void)
|
||||
{
|
||||
return uwTick;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function returns a tick priority.
|
||||
* @retval tick priority
|
||||
*/
|
||||
uint32_t HAL_GetTickPrio(void)
|
||||
{
|
||||
return uwTickPrio;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set new tick Freq.
|
||||
* @retval status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_SetTickFreq(HAL_TickFreqTypeDef Freq)
|
||||
{
|
||||
HAL_StatusTypeDef status = HAL_OK;
|
||||
|
||||
assert_param(IS_TICKFREQ(Freq));
|
||||
|
||||
if (uwTickFreq != Freq)
|
||||
{
|
||||
/* Apply the new tick Freq */
|
||||
status = HAL_InitTick(uwTickPrio);
|
||||
|
||||
if (status == HAL_OK)
|
||||
{
|
||||
uwTickFreq = Freq;
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief return tick frequency.
|
||||
* @retval Tick frequency.
|
||||
* Value of @ref HAL_TickFreqTypeDef.
|
||||
*/
|
||||
HAL_TickFreqTypeDef HAL_GetTickFreq(void)
|
||||
{
|
||||
return uwTickFreq;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function provides minimum delay (in milliseconds) based
|
||||
* on variable incremented.
|
||||
* @note In the default implementation , SysTick timer is the source of time base.
|
||||
* It is used to generate interrupts at regular time intervals where uwTick
|
||||
* is incremented.
|
||||
* @note This function is declared as __weak to be overwritten in case of other
|
||||
* implementations in user file.
|
||||
* @param Delay specifies the delay time length, in milliseconds.
|
||||
* @retval None
|
||||
*/
|
||||
__weak void HAL_Delay(uint32_t Delay)
|
||||
{
|
||||
uint32_t tickstart = HAL_GetTick();
|
||||
uint32_t wait = Delay;
|
||||
|
||||
/* Add a freq to guarantee minimum wait */
|
||||
if (wait < HAL_MAX_DELAY)
|
||||
{
|
||||
wait += (uint32_t)(uwTickFreq);
|
||||
}
|
||||
|
||||
while ((HAL_GetTick() - tickstart) < wait)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Suspend Tick increment.
|
||||
* @note In the default implementation , SysTick timer is the source of time base. It is
|
||||
* used to generate interrupts at regular time intervals. Once HAL_SuspendTick()
|
||||
* is called, the SysTick interrupt will be disabled and so Tick increment
|
||||
* is suspended.
|
||||
* @note This function is declared as __weak to be overwritten in case of other
|
||||
* implementations in user file.
|
||||
* @retval None
|
||||
*/
|
||||
__weak void HAL_SuspendTick(void)
|
||||
{
|
||||
/* Disable SysTick Interrupt */
|
||||
CLEAR_BIT(SysTick->CTRL, SysTick_CTRL_TICKINT_Msk);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Resume Tick increment.
|
||||
* @note In the default implementation , SysTick timer is the source of time base. It is
|
||||
* used to generate interrupts at regular time intervals. Once HAL_ResumeTick()
|
||||
* is called, the SysTick interrupt will be enabled and so Tick increment
|
||||
* is resumed.
|
||||
* @note This function is declared as __weak to be overwritten in case of other
|
||||
* implementations in user file.
|
||||
* @retval None
|
||||
*/
|
||||
__weak void HAL_ResumeTick(void)
|
||||
{
|
||||
/* Enable SysTick Interrupt */
|
||||
SET_BIT(SysTick->CTRL, SysTick_CTRL_TICKINT_Msk);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the HAL revision
|
||||
* @retval version : 0xXYZR (8bits for each decimal, R for RC)
|
||||
*/
|
||||
uint32_t HAL_GetHalVersion(void)
|
||||
{
|
||||
return __STM32C0xx_HAL_VERSION;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the device revision identifier.
|
||||
* @retval Device revision identifier
|
||||
*/
|
||||
uint32_t HAL_GetREVID(void)
|
||||
{
|
||||
return ((DBG->IDCODE & DBG_IDCODE_REV_ID) >> 16U);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the device identifier.
|
||||
* @retval Device identifier
|
||||
*/
|
||||
uint32_t HAL_GetDEVID(void)
|
||||
{
|
||||
return ((DBG->IDCODE) & DBG_IDCODE_DEV_ID);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns 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 Returns 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 Returns 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))));
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup HAL_Exported_Functions_Group3
|
||||
* @brief HAL Debug functions
|
||||
*
|
||||
@verbatim
|
||||
===============================================================================
|
||||
##### HAL Debug functions #####
|
||||
===============================================================================
|
||||
[..] This section provides functions allowing to:
|
||||
(+) Enable/Disable Debug module during STOP mode
|
||||
(+) Enable/Disable Debug module during STANDBY mode
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Enable the Debug Module during STOP mode
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_DBGMCU_EnableDBGStopMode(void)
|
||||
{
|
||||
SET_BIT(DBG->CR, DBG_CR_DBG_STOP);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable the Debug Module during STOP mode
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_DBGMCU_DisableDBGStopMode(void)
|
||||
{
|
||||
CLEAR_BIT(DBG->CR, DBG_CR_DBG_STOP);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable the Debug Module during STANDBY mode
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_DBGMCU_EnableDBGStandbyMode(void)
|
||||
{
|
||||
SET_BIT(DBG->CR, DBG_CR_DBG_STANDBY);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable the Debug Module during STANDBY mode
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_DBGMCU_DisableDBGStandbyMode(void)
|
||||
{
|
||||
CLEAR_BIT(DBG->CR, DBG_CR_DBG_STANDBY);
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup HAL_Exported_Functions_Group4
|
||||
* @brief SYSCFG configuration functions
|
||||
*
|
||||
@verbatim
|
||||
===============================================================================
|
||||
##### HAL SYSCFG configuration functions #####
|
||||
===============================================================================
|
||||
[..] This section provides functions allowing to:
|
||||
(+) Enable/Disable Pin remap
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Enable the remap on PA11_PA12
|
||||
* @param PinRemap specifies which pins have to be remapped
|
||||
* This parameter can be any combination of the following values:
|
||||
* @arg @ref SYSCFG_REMAP_PA11
|
||||
* @arg @ref SYSCFG_REMAP_PA12
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_SYSCFG_EnableRemap(uint32_t PinRemap)
|
||||
{
|
||||
/* Check the parameter */
|
||||
assert_param(IS_HAL_REMAP_PIN(PinRemap));
|
||||
SET_BIT(SYSCFG->CFGR1, PinRemap);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable the remap on PA11_PA12
|
||||
* @param PinRemap specifies which pins will behave normally
|
||||
* This parameter can be any combination of the following values:
|
||||
* @arg @ref SYSCFG_REMAP_PA11
|
||||
* @arg @ref SYSCFG_REMAP_PA12
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_SYSCFG_DisableRemap(uint32_t PinRemap)
|
||||
{
|
||||
/* Check the parameter */
|
||||
assert_param(IS_HAL_REMAP_PIN(PinRemap));
|
||||
CLEAR_BIT(SYSCFG->CFGR1, PinRemap);
|
||||
}
|
||||
/**
|
||||
* @brief Set Pin Binding
|
||||
* @param pin_binding specifies which pin will bind a specific GPIO
|
||||
* for each die package
|
||||
* This parameter can be a value of @ref HAL_BIND_CFG
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_SYSCFG_SetPinBinding(uint32_t pin_binding)
|
||||
{
|
||||
/* Check the parameter */
|
||||
assert_param(IS_HAL_SYSCFG_PINBINDING(pin_binding));
|
||||
LL_SYSCFG_ConfigPinMux(pin_binding);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief return Pin Binding configuration
|
||||
* @param pin_binding_source
|
||||
* This parameter can be a value of @ref HAL_BIND_SCOURCE
|
||||
* @retval PinMux configuration
|
||||
*/
|
||||
uint32_t HAL_SYSCFG_GetPinBinding(uint32_t pin_binding_source)
|
||||
{
|
||||
return LL_SYSCFG_GetConfigPinMux(pin_binding_source);
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* HAL_MODULE_ENABLED */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
@@ -0,0 +1,447 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32c0xx_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
|
||||
*
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2022 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 #####
|
||||
==============================================================================
|
||||
[..]
|
||||
*** How to configure Interrupts using CORTEX HAL driver ***
|
||||
===========================================================
|
||||
[..]
|
||||
This section provides functions allowing to configure the NVIC interrupts (IRQ).
|
||||
The Cortex M0+ exceptions are managed by CMSIS functions.
|
||||
(#) Enable and Configure the priority of the selected IRQ Channels.
|
||||
The priority can be 0..3.
|
||||
|
||||
-@- Lower priority values gives higher priority.
|
||||
-@- Priority Order:
|
||||
(#@) Lowest priority.
|
||||
(#@) Lowest hardware priority (IRQn position).
|
||||
|
||||
(#) Configure the priority of the selected IRQ Channels using HAL_NVIC_SetPriority()
|
||||
|
||||
(#) Enable the selected IRQ Channels using HAL_NVIC_EnableIRQ()
|
||||
|
||||
-@- Negative value of IRQn_Type are not allowed.
|
||||
|
||||
*** 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 (0x03).
|
||||
(++) 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 stm32c0xx_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
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32c0xx_hal.h"
|
||||
|
||||
/** @addtogroup STM32C0xx_HAL_Driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup CORTEX
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifdef HAL_CORTEX_MODULE_ENABLED
|
||||
|
||||
/* Private types -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private constants ---------------------------------------------------------*/
|
||||
/* Private macros ------------------------------------------------------------*/
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* 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 Sets the priority of an interrupt.
|
||||
* @param IRQn External interrupt number .
|
||||
* This parameter can be an enumerator of IRQn_Type enumeration
|
||||
* (For the complete STM32 Devices IRQ Channels list, please refer to stm32c0xx.h file)
|
||||
* @param PreemptPriority The preemption priority for the IRQn channel.
|
||||
* This parameter can be a value between 0 and 3.
|
||||
* A lower priority value indicates a higher priority
|
||||
* @param SubPriority the subpriority level for the IRQ channel.
|
||||
* with stm32c0xx devices, this parameter is a dummy value and it is ignored, because
|
||||
* no subpriority supported in Cortex M0+ based products.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_NVIC_SetPriority(IRQn_Type IRQn, uint32_t PreemptPriority, uint32_t SubPriority)
|
||||
{
|
||||
/* Prevent unused argument(s) compilation warning */
|
||||
UNUSED(SubPriority);
|
||||
/* Check the parameters */
|
||||
assert_param(IS_NVIC_PREEMPTION_PRIORITY(PreemptPriority));
|
||||
NVIC_SetPriority(IRQn, PreemptPriority);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable 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 (stm32c0xxxx.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 (stm32c0xxxx.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 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 (stm32c0xxxx.h))
|
||||
* @retval None
|
||||
*/
|
||||
uint32_t HAL_NVIC_GetPriority(IRQn_Type IRQn)
|
||||
{
|
||||
/* Get priority for Cortex-M system or device specific interrupts */
|
||||
return NVIC_GetPriority(IRQn);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 (stm32c0xxxx.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 (stm32c0xxxx.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 (stm32c0xxxx.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 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 == 1U)
|
||||
/**
|
||||
* @brief Enable the MPU.
|
||||
* @param MPU_Control Specifies the control mode of the MPU during hard fault,
|
||||
* NMI, FAULTMASK and privileged access to the default memory
|
||||
* This parameter can be one of the following values:
|
||||
* @arg MPU_HFNMI_PRIVDEF_NONE
|
||||
* @arg MPU_HARDFAULT_NMI
|
||||
* @arg MPU_PRIVILEGED_DEFAULT
|
||||
* @arg MPU_HFNMI_PRIVDEF
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_MPU_Enable(uint32_t MPU_Control)
|
||||
{
|
||||
/* Enable the MPU */
|
||||
MPU->CTRL = (MPU_Control | MPU_CTRL_ENABLE_Msk);
|
||||
|
||||
/* 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 Enable the MPU Region.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_MPU_EnableRegion(uint32_t RegionNumber)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_MPU_REGION_NUMBER(RegionNumber));
|
||||
|
||||
/* Set the Region number */
|
||||
MPU->RNR = RegionNumber;
|
||||
|
||||
/* Enable the Region */
|
||||
SET_BIT(MPU->RASR, MPU_RASR_ENABLE_Msk);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable the MPU Region.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_MPU_DisableRegion(uint32_t RegionNumber)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_MPU_REGION_NUMBER(RegionNumber));
|
||||
|
||||
/* Set the Region number */
|
||||
MPU->RNR = RegionNumber;
|
||||
|
||||
/* Disable the Region */
|
||||
CLEAR_BIT(MPU->RASR, MPU_RASR_ENABLE_Msk);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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(const 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));
|
||||
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));
|
||||
|
||||
/* Set the Region number */
|
||||
MPU->RNR = MPU_Init->Number;
|
||||
|
||||
/* Disable the Region */
|
||||
CLEAR_BIT(MPU->RASR, MPU_RASR_ENABLE_Msk);
|
||||
|
||||
/* Apply configuration */
|
||||
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);
|
||||
}
|
||||
#endif /* __MPU_PRESENT */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* HAL_CORTEX_MODULE_ENABLED */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,295 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32c0xx_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
|
||||
*
|
||||
@verbatim
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2022 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.
|
||||
*
|
||||
******************************************************************************
|
||||
==============================================================================
|
||||
##### 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)
|
||||
|
||||
@endverbatim
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32c0xx_hal.h"
|
||||
|
||||
/** @addtogroup STM32C0xx_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 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.
|
||||
|
||||
@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 */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
@@ -0,0 +1,662 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32c0xx_hal_exti.c
|
||||
* @author MCD Application Team
|
||||
* @brief EXTI HAL module driver.
|
||||
* This file provides firmware functions to manage the following
|
||||
* functionalities of the General Purpose Input/Output (EXTI) peripheral:
|
||||
* + Initialization and de-initialization functions
|
||||
* + IO operation functions
|
||||
*
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2022 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 diffenrents
|
||||
interrupt 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 "stm32c0xx_hal.h"
|
||||
|
||||
/** @addtogroup STM32C0xx_HAL_Driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup EXTI
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifdef HAL_EXTI_MODULE_ENABLED
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private defines ------------------------------------------------------------*/
|
||||
/** @defgroup EXTI_Private_Constants EXTI Private Constants
|
||||
* @{
|
||||
*/
|
||||
#define EXTI_MODE_OFFSET 0x04u /* 0x10: offset between CPU IMR/EMR registers */
|
||||
#define EXTI_CONFIG_OFFSET 0x08u /* 0x20: offset between CPU 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 the 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) != 0U)
|
||||
{
|
||||
assert_param(IS_EXTI_TRIGGER(pExtiConfig->Trigger));
|
||||
|
||||
/* Configure rising trigger */
|
||||
regaddr = (__IO uint32_t *)(&EXTI->RTSR1 + (EXTI_CONFIG_OFFSET * offset));
|
||||
regval = *regaddr;
|
||||
|
||||
/* Mask or set line */
|
||||
if ((pExtiConfig->Trigger & EXTI_TRIGGER_RISING) != 0U)
|
||||
{
|
||||
regval |= maskline;
|
||||
}
|
||||
else
|
||||
{
|
||||
regval &= ~maskline;
|
||||
}
|
||||
|
||||
/* Store rising trigger mode */
|
||||
*regaddr = regval;
|
||||
|
||||
/* Configure falling trigger */
|
||||
regaddr = (__IO uint32_t *)(&EXTI->FTSR1 + (EXTI_CONFIG_OFFSET * offset));
|
||||
regval = *regaddr;
|
||||
|
||||
/* Mask or set line */
|
||||
if ((pExtiConfig->Trigger & EXTI_TRIGGER_FALLING) != 0U)
|
||||
{
|
||||
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 = EXTI->EXTICR[(linepos >> 2U) & 0x03UL];
|
||||
regval &= ~(EXTI_EXTICR1_EXTI0 << (EXTI_EXTICR1_EXTI1_Pos * (linepos & 0x03U)));
|
||||
regval |= (pExtiConfig->GPIOSel << (EXTI_EXTICR1_EXTI1_Pos * (linepos & 0x03U)));
|
||||
EXTI->EXTICR[(linepos >> 2U) & 0x03UL] = regval;
|
||||
}
|
||||
}
|
||||
|
||||
/* Configure interrupt mode : read current mode */
|
||||
regaddr = (__IO uint32_t *)(&EXTI->IMR1 + (EXTI_MODE_OFFSET * offset));
|
||||
regval = *regaddr;
|
||||
|
||||
/* Mask or set line */
|
||||
if ((pExtiConfig->Mode & EXTI_MODE_INTERRUPT) != 0U)
|
||||
{
|
||||
regval |= maskline;
|
||||
}
|
||||
else
|
||||
{
|
||||
regval &= ~maskline;
|
||||
}
|
||||
|
||||
/* Store interrupt mode */
|
||||
*regaddr = regval;
|
||||
|
||||
/* Configure event mode : read current mode */
|
||||
regaddr = (__IO uint32_t *)(&EXTI->EMR1 + (EXTI_MODE_OFFSET * offset));
|
||||
regval = *regaddr;
|
||||
|
||||
/* Mask or set line */
|
||||
if ((pExtiConfig->Mode & EXTI_MODE_EVENT) != 0U)
|
||||
{
|
||||
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)
|
||||
{
|
||||
const __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 configiguration 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 = (__IO uint32_t *)(&EXTI->IMR1 + (EXTI_MODE_OFFSET * offset));
|
||||
regval = *regaddr;
|
||||
|
||||
/* Check if selected line is enable */
|
||||
if ((regval & maskline) != 0U)
|
||||
{
|
||||
pExtiConfig->Mode = EXTI_MODE_INTERRUPT;
|
||||
}
|
||||
else
|
||||
{
|
||||
pExtiConfig->Mode = EXTI_MODE_NONE;
|
||||
}
|
||||
|
||||
/* Get event mode */
|
||||
regaddr = (__IO uint32_t *)(&EXTI->EMR1 + (EXTI_MODE_OFFSET * offset));
|
||||
regval = *regaddr;
|
||||
|
||||
/* Check if selected line is enable */
|
||||
if ((regval & maskline) != 0U)
|
||||
{
|
||||
pExtiConfig->Mode |= EXTI_MODE_EVENT;
|
||||
}
|
||||
|
||||
/* 2] Get trigger for configurable lines : rising */
|
||||
if ((pExtiConfig->Line & EXTI_CONFIG) != 0U)
|
||||
{
|
||||
regaddr = (__IO uint32_t *)(&EXTI->RTSR1 + (EXTI_CONFIG_OFFSET * offset));
|
||||
regval = *regaddr;
|
||||
|
||||
/* Get default Trigger and GPIOSel configuration */
|
||||
pExtiConfig->Trigger = EXTI_TRIGGER_NONE;
|
||||
pExtiConfig->GPIOSel = 0x00u;
|
||||
|
||||
/* Check if configuration of selected line is enable */
|
||||
if ((regval & maskline) != 0U)
|
||||
{
|
||||
pExtiConfig->Trigger = EXTI_TRIGGER_RISING;
|
||||
}
|
||||
|
||||
/* Get falling configuration */
|
||||
regaddr = (__IO uint32_t *)(&EXTI->FTSR1 + (EXTI_CONFIG_OFFSET * offset));
|
||||
regval = *regaddr;
|
||||
|
||||
/* Check if configuration of selected line is enable */
|
||||
if ((regval & maskline) != 0U)
|
||||
{
|
||||
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 = EXTI->EXTICR[(linepos >> 2U) & 0x03UL];
|
||||
pExtiConfig->GPIOSel = (regval >> (EXTI_EXTICR1_EXTI1_Pos * (linepos & 0x03u))) & EXTI_EXTICR1_EXTI0;
|
||||
}
|
||||
}
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clear whole configuration of a dedicated Exti line.
|
||||
* @param hexti Exti handle.
|
||||
* @retval HAL Status.
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_EXTI_ClearConfigLine(const 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 = (__IO uint32_t *)(&EXTI->IMR1 + (EXTI_MODE_OFFSET * offset));
|
||||
regval = (*regaddr & ~maskline);
|
||||
*regaddr = regval;
|
||||
|
||||
/* 2] Clear event mode */
|
||||
regaddr = (__IO uint32_t *)(&EXTI->EMR1 + (EXTI_MODE_OFFSET * offset));
|
||||
regval = (*regaddr & ~maskline);
|
||||
*regaddr = regval;
|
||||
|
||||
/* 3] Clear triggers in case of configurable lines */
|
||||
if ((hexti->Line & EXTI_CONFIG) != 0U)
|
||||
{
|
||||
regaddr = (__IO uint32_t *)(&EXTI->RTSR1 + (EXTI_CONFIG_OFFSET * offset));
|
||||
regval = (*regaddr & ~maskline);
|
||||
*regaddr = regval;
|
||||
|
||||
regaddr = (__IO uint32_t *)(&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 = EXTI->EXTICR[(linepos >> 2U) & 0x03UL];
|
||||
regval &= ~(EXTI_EXTICR1_EXTI0 << (EXTI_EXTICR1_EXTI1_Pos * (linepos & 0x03U)));
|
||||
EXTI->EXTICR[(linepos >> 2U) & 0x03UL] = regval;
|
||||
}
|
||||
}
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Register callback for a dedicaated 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->RisingCallback = pPendingCbfn;
|
||||
hexti->FallingCallback = pPendingCbfn;
|
||||
break;
|
||||
|
||||
case HAL_EXTI_RISING_CB_ID:
|
||||
hexti->RisingCallback = pPendingCbfn;
|
||||
break;
|
||||
|
||||
case HAL_EXTI_FALLING_CB_ID:
|
||||
hexti->FallingCallback = 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(const 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 rising edge pending bit */
|
||||
regaddr = (__IO uint32_t *)(&EXTI->RPR1 + (EXTI_CONFIG_OFFSET * offset));
|
||||
regval = (*regaddr & maskline);
|
||||
|
||||
if (regval != 0U)
|
||||
{
|
||||
/* Clear pending bit */
|
||||
*regaddr = maskline;
|
||||
|
||||
/* Call rising callback */
|
||||
if (hexti->RisingCallback != NULL)
|
||||
{
|
||||
hexti->RisingCallback();
|
||||
}
|
||||
}
|
||||
|
||||
/* Get falling edge pending bit */
|
||||
regaddr = (__IO uint32_t *)(&EXTI->FPR1 + (EXTI_CONFIG_OFFSET * offset));
|
||||
regval = (*regaddr & maskline);
|
||||
|
||||
if (regval != 0U)
|
||||
{
|
||||
/* Clear pending bit */
|
||||
*regaddr = maskline;
|
||||
|
||||
/* Call rising callback */
|
||||
if (hexti->FallingCallback != NULL)
|
||||
{
|
||||
hexti->FallingCallback();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @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
|
||||
* @arg @ref EXTI_TRIGGER_FALLING
|
||||
* @retval 1 if interrupt is pending else 0.
|
||||
*/
|
||||
uint32_t HAL_EXTI_GetPending(const EXTI_HandleTypeDef *hexti, uint32_t Edge)
|
||||
{
|
||||
const __IO uint32_t *regaddr;
|
||||
uint32_t regval;
|
||||
uint32_t linepos;
|
||||
uint32_t maskline;
|
||||
uint32_t offset;
|
||||
|
||||
/* Check the 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);
|
||||
|
||||
if (Edge != EXTI_TRIGGER_RISING)
|
||||
{
|
||||
/* Get falling edge pending bit */
|
||||
regaddr = (__IO uint32_t *)(&EXTI->FPR1 + (EXTI_CONFIG_OFFSET * offset));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Get rising edge pending bit */
|
||||
regaddr = (__IO uint32_t *)(&EXTI->RPR1 + (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
|
||||
* @arg @ref EXTI_TRIGGER_FALLING
|
||||
* @retval None.
|
||||
*/
|
||||
void HAL_EXTI_ClearPending(const EXTI_HandleTypeDef *hexti, uint32_t Edge)
|
||||
{
|
||||
__IO uint32_t *regaddr;
|
||||
uint32_t maskline;
|
||||
uint32_t offset;
|
||||
|
||||
/* Check the 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));
|
||||
|
||||
if (Edge != EXTI_TRIGGER_RISING)
|
||||
{
|
||||
/* Get falling edge pending register address */
|
||||
regaddr = (__IO uint32_t *)(&EXTI->FPR1 + (EXTI_CONFIG_OFFSET * offset));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Get falling edge pending register address */
|
||||
regaddr = (__IO uint32_t *)(&EXTI->RPR1 + (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(const EXTI_HandleTypeDef *hexti)
|
||||
{
|
||||
__IO uint32_t *regaddr;
|
||||
uint32_t maskline;
|
||||
uint32_t offset;
|
||||
|
||||
/* Check the 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 = (__IO uint32_t *)(&EXTI->SWIER1 + (EXTI_CONFIG_OFFSET * offset));
|
||||
*regaddr = maskline;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* HAL_EXTI_MODULE_ENABLED */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
@@ -0,0 +1,699 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32c0xx_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
|
||||
*
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2022 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
|
||||
==============================================================================
|
||||
##### 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
|
||||
|
||||
##### How to use this driver #####
|
||||
==============================================================================
|
||||
[..]
|
||||
This driver provides functions and macros to configure and program the FLASH
|
||||
memory of all STM32C0xx 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 are 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_OB_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
|
||||
(+) Reset the Instruction cache
|
||||
(+) Enable/Disable the Flash power-down during low-power modes
|
||||
(+) Enable/Disable the Flash interrupts
|
||||
(+) Monitor the Flash flags status
|
||||
|
||||
@endverbatim
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32c0xx_hal.h"
|
||||
|
||||
/** @addtogroup STM32C0xx_HAL_Driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup FLASH FLASH
|
||||
* @brief FLASH HAL module driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifdef HAL_FLASH_MODULE_ENABLED
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private defines -----------------------------------------------------------*/
|
||||
/* 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_TYPENONE, \
|
||||
.Address = 0U, \
|
||||
.Page = 0U, \
|
||||
.NbPagesToErase = 0U
|
||||
};
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* 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;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram));
|
||||
assert_param(IS_FLASH_PROGRAM_ADDRESS(Address));
|
||||
|
||||
/* Process Locked */
|
||||
__HAL_LOCK(&pFlash);
|
||||
|
||||
/* Reset error code */
|
||||
pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
|
||||
|
||||
/* Wait for last operation to be completed */
|
||||
status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
|
||||
|
||||
if (status == HAL_OK)
|
||||
{
|
||||
if (TypeProgram == FLASH_TYPEPROGRAM_DOUBLEWORD)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_FLASH_PROGRAM_ADDRESS(Address));
|
||||
|
||||
/* Program double-word (64-bit) at a specified address */
|
||||
FLASH_Program_DoubleWord(Address, Data);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_FLASH_FAST_PROGRAM_ADDRESS(Address));
|
||||
|
||||
/* Fast program a 32 row double-word (64-bit) at a specified address */
|
||||
FLASH_Program_Fast(Address, (uint32_t)Data);
|
||||
}
|
||||
|
||||
/* Wait for last operation to be completed */
|
||||
status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
|
||||
|
||||
/* If the program operation is completed, disable the PG or FSTPG Bit */
|
||||
CLEAR_BIT(FLASH->CR, TypeProgram);
|
||||
}
|
||||
|
||||
/* Process Unlocked */
|
||||
__HAL_UNLOCK(&pFlash);
|
||||
|
||||
/* return status */
|
||||
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;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram));
|
||||
assert_param(IS_FLASH_PROGRAM_ADDRESS(Address));
|
||||
|
||||
/* Process Locked */
|
||||
__HAL_LOCK(&pFlash);
|
||||
|
||||
/* Reset error code */
|
||||
pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
|
||||
|
||||
/* Wait for last operation to be completed */
|
||||
status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
|
||||
|
||||
if (status != HAL_OK)
|
||||
{
|
||||
/* Process Unlocked */
|
||||
__HAL_UNLOCK(&pFlash);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Set internal variables used by the IRQ handler */
|
||||
pFlash.ProcedureOnGoing = TypeProgram;
|
||||
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)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_FLASH_PROGRAM_ADDRESS(Address));
|
||||
|
||||
/* Program double-word (64-bit) at a specified address */
|
||||
FLASH_Program_DoubleWord(Address, Data);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_FLASH_FAST_PROGRAM_ADDRESS(Address));
|
||||
|
||||
/* Fast program a 32 row double-word (64-bit) at a specified address */
|
||||
FLASH_Program_Fast(Address, (uint32_t)Data);
|
||||
}
|
||||
}
|
||||
|
||||
/* return status */
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Handle FLASH interrupt request.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_FLASH_IRQHandler(void)
|
||||
{
|
||||
uint32_t param = 0xFFFFFFFFU;
|
||||
uint32_t error;
|
||||
|
||||
/* Save flash errors */
|
||||
error = (FLASH->SR & FLASH_FLAG_SR_ERROR);
|
||||
|
||||
CLEAR_BIT(FLASH->CR, pFlash.ProcedureOnGoing);
|
||||
|
||||
/* A] Set parameter for user or error callbacks */
|
||||
/* check operation was a program or erase */
|
||||
if ((pFlash.ProcedureOnGoing & (FLASH_TYPEPROGRAM_DOUBLEWORD | FLASH_TYPEPROGRAM_FAST)) != 0x00U)
|
||||
{
|
||||
/* return address being programmed */
|
||||
param = pFlash.Address;
|
||||
}
|
||||
else if ((pFlash.ProcedureOnGoing & (FLASH_TYPEERASE_MASS | FLASH_TYPEERASE_PAGES)) != 0x00U)
|
||||
{
|
||||
/* return page number being erased (0 for mass erase) */
|
||||
param = pFlash.Page;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Nothing to do */
|
||||
}
|
||||
|
||||
/* B] Check errors */
|
||||
if (error != 0x00U)
|
||||
{
|
||||
/*Save the error code*/
|
||||
pFlash.ErrorCode |= error;
|
||||
|
||||
/* clear error flags */
|
||||
__HAL_FLASH_CLEAR_FLAG(error);
|
||||
|
||||
/*Stop the procedure ongoing*/
|
||||
pFlash.ProcedureOnGoing = FLASH_TYPENONE;
|
||||
|
||||
/* Error callback */
|
||||
HAL_FLASH_OperationErrorCallback(param);
|
||||
}
|
||||
|
||||
/* C] Check FLASH End of Operation flag */
|
||||
if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP) != 0x00U)
|
||||
{
|
||||
/* Clear FLASH End of Operation pending bit */
|
||||
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP);
|
||||
|
||||
if (pFlash.ProcedureOnGoing == FLASH_TYPEERASE_PAGES)
|
||||
{
|
||||
/* Nb of pages to erased can be decreased */
|
||||
pFlash.NbPagesToErase--;
|
||||
|
||||
/* Check if there are still pages to erase*/
|
||||
if (pFlash.NbPagesToErase != 0x00U)
|
||||
{
|
||||
/* Increment page number */
|
||||
pFlash.Page++;
|
||||
FLASH_PageErase(pFlash.Page);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No more pages to erase: stop erase pages procedure */
|
||||
pFlash.ProcedureOnGoing = FLASH_TYPENONE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*Stop the ongoing procedure */
|
||||
pFlash.ProcedureOnGoing = FLASH_TYPENONE;
|
||||
}
|
||||
|
||||
/* User callback */
|
||||
HAL_FLASH_EndOfOperationCallback(param);
|
||||
}
|
||||
|
||||
if (pFlash.ProcedureOnGoing == FLASH_TYPENONE)
|
||||
{
|
||||
/* 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: 0
|
||||
* Page Erase: Page which has 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: 0
|
||||
* 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) != 0x00U)
|
||||
{
|
||||
/* Authorize the FLASH Registers access */
|
||||
WRITE_REG(FLASH->KEYR, FLASH_KEY1);
|
||||
WRITE_REG(FLASH->KEYR, FLASH_KEY2);
|
||||
|
||||
/* verify Flash is unlock */
|
||||
if (READ_BIT(FLASH->CR, FLASH_CR_LOCK) != 0x00U)
|
||||
{
|
||||
status = HAL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Lock the FLASH control register access.
|
||||
* @retval HAL Status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_FLASH_Lock(void)
|
||||
{
|
||||
HAL_StatusTypeDef status = HAL_ERROR;
|
||||
|
||||
/* Set the LOCK Bit to lock the FLASH Registers access */
|
||||
SET_BIT(FLASH->CR, FLASH_CR_LOCK);
|
||||
|
||||
/* verify Flash is locked */
|
||||
if (READ_BIT(FLASH->CR, FLASH_CR_LOCK) != 0x00u)
|
||||
{
|
||||
status = HAL_OK;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Unlock the FLASH Option Bytes Registers access.
|
||||
* @retval HAL Status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_FLASH_OB_Unlock(void)
|
||||
{
|
||||
HAL_StatusTypeDef status = HAL_ERROR;
|
||||
|
||||
if (READ_BIT(FLASH->CR, FLASH_CR_OPTLOCK) != 0x00U)
|
||||
{
|
||||
/* Authorizes the Option Byte register programming */
|
||||
WRITE_REG(FLASH->OPTKEYR, FLASH_OPTKEY1);
|
||||
WRITE_REG(FLASH->OPTKEYR, FLASH_OPTKEY2);
|
||||
|
||||
/* verify option bytes are unlocked */
|
||||
if (READ_BIT(FLASH->CR, FLASH_CR_OPTLOCK) == 0x00U)
|
||||
{
|
||||
status = HAL_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Lock the FLASH Option Bytes Registers access.
|
||||
* @retval HAL Status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_FLASH_OB_Lock(void)
|
||||
{
|
||||
HAL_StatusTypeDef status = HAL_ERROR;
|
||||
|
||||
/* Set the OPTLOCK Bit to lock the FLASH Option Byte Registers access */
|
||||
SET_BIT(FLASH->CR, FLASH_CR_OPTLOCK);
|
||||
|
||||
/* verify option bytes are locked */
|
||||
if (READ_BIT(FLASH->CR, FLASH_CR_OPTLOCK) != 0x00u)
|
||||
{
|
||||
status = HAL_OK;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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);
|
||||
|
||||
/* We should not reach here : Option byte launch generates Option byte reset
|
||||
so return error */
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @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 @ref HAL_FLASH_ERROR_NONE No error set
|
||||
* @arg @ref HAL_FLASH_ERROR_OP FLASH Operation error
|
||||
* @arg @ref HAL_FLASH_ERROR_PROG FLASH Programming error
|
||||
* @arg @ref HAL_FLASH_ERROR_WRP FLASH Write protection error
|
||||
* @arg @ref HAL_FLASH_ERROR_PGA FLASH Programming alignment error
|
||||
* @arg @ref HAL_FLASH_ERROR_SIZ FLASH Size error
|
||||
* @arg @ref HAL_FLASH_ERROR_PGS FLASH Programming sequence error
|
||||
* @arg @ref HAL_FLASH_ERROR_MIS FLASH Fast programming data miss error
|
||||
* @arg @ref HAL_FLASH_ERROR_FAST FLASH Fast programming error
|
||||
* @arg @ref HAL_FLASH_ERROR_RD FLASH Read Protection error (PCROP)
|
||||
* @arg @ref HAL_FLASH_ERROR_OPTV FLASH Option validity error
|
||||
*/
|
||||
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)
|
||||
{
|
||||
uint32_t error;
|
||||
/* 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 timeout = HAL_GetTick() + Timeout;
|
||||
|
||||
/* Wait if any operation is ongoing */
|
||||
while (__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY) != 0x00U)
|
||||
{
|
||||
if (HAL_GetTick() >= timeout)
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
|
||||
/* check flash errors */
|
||||
error = (FLASH->SR & FLASH_FLAG_SR_ERROR);
|
||||
|
||||
/* clear error flags */
|
||||
__HAL_FLASH_CLEAR_FLAG(error);
|
||||
|
||||
if (error != 0x00U)
|
||||
{
|
||||
/*Save the error code*/
|
||||
pFlash.ErrorCode = error;
|
||||
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Wait for control register to be written */
|
||||
timeout = HAL_GetTick() + Timeout;
|
||||
|
||||
while (__HAL_FLASH_GET_FLAG(FLASH_FLAG_CFGBSY) != 0x00U)
|
||||
{
|
||||
if (HAL_GetTick() >= timeout)
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
/* Set PG bit */
|
||||
SET_BIT(FLASH->CR, FLASH_CR_PG);
|
||||
|
||||
/* Program first word */
|
||||
*(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 */
|
||||
*(uint32_t *)(Address + 4U) = (uint32_t)(Data >> 32U);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Fast program a 32 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 __RAM_FUNC void FLASH_Program_Fast(uint32_t Address, uint32_t DataAddress)
|
||||
{
|
||||
uint8_t index = 0;
|
||||
uint32_t dest = Address;
|
||||
uint32_t src = DataAddress;
|
||||
uint32_t primask_bit;
|
||||
|
||||
/* Set FSTPG bit */
|
||||
SET_BIT(FLASH->CR, FLASH_CR_FSTPG);
|
||||
|
||||
/* Enter critical section: row programming should not be longer than 7 ms */
|
||||
primask_bit = __get_PRIMASK();
|
||||
__disable_irq();
|
||||
|
||||
/* Fast Program : 64 words */
|
||||
while (index < 64U)
|
||||
{
|
||||
*(uint32_t *)dest = *(uint32_t *)src;
|
||||
src += 4U;
|
||||
dest += 4U;
|
||||
index++;
|
||||
}
|
||||
|
||||
/* wait for BSY1 in order to be sure that flash operation is ended befoire
|
||||
allowing prefetch in flash. Timeout does not return status, as it will
|
||||
be anyway done later */
|
||||
while ((FLASH->SR & FLASH_SR_BSY1) != 0x00U)
|
||||
{
|
||||
}
|
||||
|
||||
/* Exit critical section: restore previous priority mask */
|
||||
__set_PRIMASK(primask_bit);
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* HAL_FLASH_MODULE_ENABLED */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
@@ -0,0 +1,876 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32c0xx_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
|
||||
*
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2022 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
|
||||
==============================================================================
|
||||
##### Flash Extended features #####
|
||||
==============================================================================
|
||||
|
||||
[..] Comparing to other previous devices, the FLASH interface for STM32C0xx
|
||||
devices contains the following additional features
|
||||
|
||||
(+) Capacity up to 128 Kbytes with single bank architecture supporting read-while-write
|
||||
capability (RWW)
|
||||
(+) Single bank memory organization
|
||||
(+) PCROP protection
|
||||
|
||||
##### How to use this driver #####
|
||||
==============================================================================
|
||||
[..] This driver provides functions to configure and program the FLASH memory
|
||||
of all STM32C0xx 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
|
||||
(++) Set Securable memory area and boot entry point
|
||||
|
||||
(#) 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 Securable memory area and boot entry point information
|
||||
|
||||
(#) Enable or disable debugger usage using HAL_FLASHEx_EnableDebugger and
|
||||
HAL_FLASHEx_DisableDebugger.
|
||||
|
||||
(#) Check is flash content is empty or not using HAL_FLASHEx_FlashEmptyCheck.
|
||||
and modify this setting (for flash loader purpose e.g.) using
|
||||
HAL_FLASHEx_ForceFlashEmpty.
|
||||
|
||||
(#) Enable securable memory area protectionusing HAL_FLASHEx_EnableSecMemProtection
|
||||
|
||||
@endverbatim
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32c0xx_hal.h"
|
||||
|
||||
/** @addtogroup STM32C0xx_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(void);
|
||||
void FLASH_FlushCaches(void);
|
||||
static void FLASH_OB_WRPConfig(uint32_t WRPArea, uint32_t WRPStartOffset, uint32_t WRDPEndOffset);
|
||||
static void FLASH_OB_OptrConfig(uint32_t UserType, uint32_t UserConfig, uint32_t RDPLevel);
|
||||
static void FLASH_OB_PCROP1AConfig(uint32_t PCROPConfig, uint32_t PCROP1AStartAddr, uint32_t PCROP1AEndAddr);
|
||||
static void FLASH_OB_PCROP1BConfig(uint32_t PCROP1BStartAddr, uint32_t PCROP1BEndAddr);
|
||||
static void FLASH_OB_SecMemConfig(uint32_t BootEntry, uint32_t SecSize);
|
||||
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_GetPCROP1A(uint32_t *PCROPConfig, uint32_t *PCROP1AStartAddr, uint32_t *PCROP1AEndAddr);
|
||||
static void FLASH_OB_GetPCROP1B(uint32_t *PCROP1BStartAddr, uint32_t *PCROP1BEndAddr);
|
||||
static void FLASH_OB_GetSecMem(uint32_t *BootEntry, uint32_t *SecSize);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Exported functions -------------------------------------------------------*/
|
||||
/** @defgroup FLASHEx_Exported_Functions FLASH Extended 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 @ref 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(const FLASH_EraseInitTypeDef *pEraseInit, uint32_t *PageError)
|
||||
{
|
||||
HAL_StatusTypeDef status;
|
||||
uint32_t index;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase));
|
||||
|
||||
/* Process Locked */
|
||||
__HAL_LOCK(&pFlash);
|
||||
|
||||
/* Reset error code */
|
||||
pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
|
||||
|
||||
/* Wait for last operation to be completed */
|
||||
status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
|
||||
|
||||
if (status == HAL_OK)
|
||||
{
|
||||
if (pEraseInit->TypeErase == FLASH_TYPEERASE_MASS)
|
||||
{
|
||||
/* Mass erase to be done */
|
||||
FLASH_MassErase();
|
||||
|
||||
/* Wait for last operation to be completed */
|
||||
status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*Initialization of PageError variable*/
|
||||
*PageError = 0xFFFFFFFFU;
|
||||
|
||||
for (index = pEraseInit->Page; index < (pEraseInit->Page + pEraseInit->NbPages); index++)
|
||||
{
|
||||
/* Start erase page */
|
||||
FLASH_PageErase(index);
|
||||
|
||||
/* Wait for last operation to be completed */
|
||||
status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
|
||||
|
||||
if (status != HAL_OK)
|
||||
{
|
||||
/* In case of error, stop erase procedure and return the faulty address */
|
||||
*PageError = index;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* If operation is completed or interrupted, disable the Page Erase Bit */
|
||||
CLEAR_BIT(FLASH->CR, FLASH_CR_PER);
|
||||
}
|
||||
}
|
||||
|
||||
/* Process Unlocked */
|
||||
__HAL_UNLOCK(&pFlash);
|
||||
|
||||
/* return status */
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Perform a mass erase or erase the specified FLASH memory pages with interrupt enabled.
|
||||
* @param pEraseInit Pointer to an @ref 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;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase));
|
||||
|
||||
/* Process Locked */
|
||||
__HAL_LOCK(&pFlash);
|
||||
|
||||
/* Reset error code */
|
||||
pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
|
||||
|
||||
/* save procedure for interrupt treatment */
|
||||
pFlash.ProcedureOnGoing = pEraseInit->TypeErase;
|
||||
|
||||
/* Wait for last operation to be completed */
|
||||
status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
|
||||
|
||||
if (status != HAL_OK)
|
||||
{
|
||||
/* Process Unlocked */
|
||||
__HAL_UNLOCK(&pFlash);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Enable End of Operation and Error interrupts */
|
||||
__HAL_FLASH_ENABLE_IT(FLASH_IT_EOP | FLASH_IT_OPERR);
|
||||
|
||||
if (pEraseInit->TypeErase == FLASH_TYPEERASE_MASS)
|
||||
{
|
||||
/* Set Page to 0 for Interrupt callback management */
|
||||
pFlash.Page = 0;
|
||||
|
||||
/* Proceed to Mass Erase */
|
||||
FLASH_MassErase();
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Erase by page to be done */
|
||||
pFlash.NbPagesToErase = pEraseInit->NbPages;
|
||||
pFlash.Page = pEraseInit->Page;
|
||||
|
||||
/*Erase 1st page and wait for IT */
|
||||
FLASH_PageErase(pEraseInit->Page);
|
||||
}
|
||||
}
|
||||
|
||||
/* return status */
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Program Option bytes.
|
||||
* @param pOBInit Pointer to an @ref FLASH_OBProgramInitTypeDef structure that
|
||||
* contains the configuration information for the programming.
|
||||
* @note To configure any option bytes, the option lock bit OPTLOCK must be
|
||||
* cleared with the call of @ref HAL_FLASH_OB_Unlock() function.
|
||||
* @note New option bytes configuration will be taken into account only
|
||||
* - after an option bytes launch through the call of @ref HAL_FLASH_OB_Launch()
|
||||
* - a Power On Reset
|
||||
* - an exit from Standby or Shutdown mode.
|
||||
* @retval HAL Status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_FLASHEx_OBProgram(FLASH_OBProgramInitTypeDef *pOBInit)
|
||||
{
|
||||
uint32_t optr;
|
||||
HAL_StatusTypeDef status;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_OPTIONBYTE(pOBInit->OptionType));
|
||||
|
||||
/* Process Locked */
|
||||
__HAL_LOCK(&pFlash);
|
||||
|
||||
pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
|
||||
|
||||
/* Write protection configuration */
|
||||
if ((pOBInit->OptionType & OPTIONBYTE_WRP) != 0x00U)
|
||||
{
|
||||
/* Configure of Write protection on the selected area */
|
||||
FLASH_OB_WRPConfig(pOBInit->WRPArea, pOBInit->WRPStartOffset, pOBInit->WRPEndOffset);
|
||||
}
|
||||
|
||||
/* Option register */
|
||||
if ((pOBInit->OptionType & (OPTIONBYTE_RDP | OPTIONBYTE_USER)) == (OPTIONBYTE_RDP | OPTIONBYTE_USER))
|
||||
{
|
||||
/* Fully modify OPTR register with RDP & user data */
|
||||
FLASH_OB_OptrConfig(pOBInit->USERType, pOBInit->USERConfig, pOBInit->RDPLevel);
|
||||
}
|
||||
else if ((pOBInit->OptionType & OPTIONBYTE_RDP) != 0x00U)
|
||||
{
|
||||
/* Only modify RDP so get current user data */
|
||||
optr = FLASH_OB_GetUser();
|
||||
FLASH_OB_OptrConfig(optr, optr, pOBInit->RDPLevel);
|
||||
}
|
||||
else if ((pOBInit->OptionType & OPTIONBYTE_USER) != 0x00U)
|
||||
{
|
||||
/* Only modify user so get current RDP level */
|
||||
optr = FLASH_OB_GetRDP();
|
||||
FLASH_OB_OptrConfig(pOBInit->USERType, pOBInit->USERConfig, optr);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* nothing to do */
|
||||
}
|
||||
|
||||
/* PCROP Configuration */
|
||||
if ((pOBInit->OptionType & OPTIONBYTE_PCROP) != 0x00U)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_OB_PCROP_CONFIG(pOBInit->PCROPConfig));
|
||||
|
||||
if ((pOBInit->PCROPConfig & (OB_PCROP_ZONE_A | OB_PCROP_RDP_ERASE)) != 0x00U)
|
||||
{
|
||||
/* Configure the 1A Proprietary code readout protection */
|
||||
FLASH_OB_PCROP1AConfig(pOBInit->PCROPConfig, pOBInit->PCROP1AStartAddr, pOBInit->PCROP1AEndAddr);
|
||||
}
|
||||
|
||||
if ((pOBInit->PCROPConfig & OB_PCROP_ZONE_B) != 0x00U)
|
||||
{
|
||||
/* Configure the 1B Proprietary code readout protection */
|
||||
FLASH_OB_PCROP1BConfig(pOBInit->PCROP1BStartAddr, pOBInit->PCROP1BEndAddr);
|
||||
}
|
||||
}
|
||||
|
||||
/* Securable Memory Area Configuration */
|
||||
if ((pOBInit->OptionType & OPTIONBYTE_SEC) != 0x00U)
|
||||
{
|
||||
/* Configure the securable memory area protection */
|
||||
FLASH_OB_SecMemConfig(pOBInit->BootEntryPoint, pOBInit->SecSize);
|
||||
}
|
||||
|
||||
|
||||
/* Wait for last operation to be completed */
|
||||
status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
|
||||
|
||||
if (status == HAL_OK)
|
||||
{
|
||||
/* Set OPTSTRT Bit */
|
||||
SET_BIT(FLASH->CR, FLASH_CR_OPTSTRT);
|
||||
|
||||
/* Wait for last operation to be completed */
|
||||
status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
|
||||
|
||||
/* If the option byte program operation is completed, disable the OPTSTRT Bit */
|
||||
CLEAR_BIT(FLASH->CR, FLASH_CR_OPTSTRT);
|
||||
}
|
||||
|
||||
/* Process Unlocked */
|
||||
__HAL_UNLOCK(&pFlash);
|
||||
|
||||
/* return status */
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the Option bytes configuration.
|
||||
* @note warning: this API only read flash register, it does not reflect any
|
||||
* change that would have been programmed between previous Option byte
|
||||
* loading and current call.
|
||||
* @param pOBInit Pointer to an @ref FLASH_OBProgramInitTypeDef structure that contains the
|
||||
* configuration information. The fields pOBInit->WRPArea and
|
||||
* pOBInit->PCROPConfig should indicate which area is requested
|
||||
* for the WRP and PCROP.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_FLASHEx_OBGetConfig(FLASH_OBProgramInitTypeDef *pOBInit)
|
||||
{
|
||||
pOBInit->OptionType = OPTIONBYTE_ALL;
|
||||
|
||||
/* 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();
|
||||
pOBInit->USERType = OB_USER_ALL;
|
||||
|
||||
/* Get the Proprietary code readout protection */
|
||||
FLASH_OB_GetPCROP1A(&(pOBInit->PCROPConfig), &(pOBInit->PCROP1AStartAddr), &(pOBInit->PCROP1AEndAddr));
|
||||
FLASH_OB_GetPCROP1B(&(pOBInit->PCROP1BStartAddr), &(pOBInit->PCROP1BEndAddr));
|
||||
pOBInit->PCROPConfig |= (OB_PCROP_ZONE_A | OB_PCROP_ZONE_B);
|
||||
|
||||
/* Get the Securable Memory Area protection */
|
||||
FLASH_OB_GetSecMem(&(pOBInit->BootEntryPoint), &(pOBInit->SecSize));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable Debugger.
|
||||
* @note After calling this API, flash interface allow debugger intrusion.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_FLASHEx_EnableDebugger(void)
|
||||
{
|
||||
FLASH->ACR |= FLASH_ACR_DBG_SWEN;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable Debugger.
|
||||
* @note After calling this API, Debugger is disabled: it is no more possible to
|
||||
* break, see CPU register, etc...
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_FLASHEx_DisableDebugger(void)
|
||||
{
|
||||
FLASH->ACR &= ~FLASH_ACR_DBG_SWEN;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Flash Empty check
|
||||
* @note This API checks if first location in Flash is programmed or not.
|
||||
* This check is done once by Option Byte Loader.
|
||||
* @retval 0 if 1st location is not programmed else
|
||||
*/
|
||||
uint32_t HAL_FLASHEx_FlashEmptyCheck(void)
|
||||
{
|
||||
return ((FLASH->ACR & FLASH_ACR_PROGEMPTY));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Force Empty check value.
|
||||
* @note Allows to modify program empty check value in order to force this
|
||||
* infrmation in Flash Interface, for all next reset that do not launch
|
||||
* Option Byte Loader.
|
||||
* @param FlashEmpty this parameter can be a value of @ref FLASHEx_Empty_Check
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_FLASHEx_ForceFlashEmpty(uint32_t FlashEmpty)
|
||||
{
|
||||
uint32_t acr;
|
||||
assert_param(IS_FLASH_EMPTY_CHECK(FlashEmpty));
|
||||
|
||||
acr = (FLASH->ACR & ~FLASH_ACR_PROGEMPTY);
|
||||
FLASH->ACR = (acr | FlashEmpty);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Securable memory area protection enable
|
||||
* @param Bank Select Bank to be secured. On C0, there is only 1 bank so
|
||||
* parameter has to be set to 0.
|
||||
* @note This API locks Securable memory area which is defined in SEC_SIZE option byte
|
||||
* (that can be retrieved calling HAL_FLASHEx_OBGetConfig API and checking
|
||||
* Secsize).
|
||||
* @note SEC_PROT bit can only be set, it will be reset by system reset.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_FLASHEx_EnableSecMemProtection(uint32_t Bank)
|
||||
{
|
||||
assert_param(IS_FLASH_BANK(Bank));
|
||||
FLASH->CR |= FLASH_CR_SEC_PROT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private functions ---------------------------------------------------------*/
|
||||
/** @addtogroup FLASHEx_Private_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Mass erase of FLASH memory.
|
||||
* @retval None
|
||||
*/
|
||||
static void FLASH_MassErase(void)
|
||||
{
|
||||
/* Set the Mass Erase Bit and start bit */
|
||||
FLASH->CR |= (FLASH_CR_STRT | FLASH_CR_MER1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 Flash - 1)
|
||||
* @retval None
|
||||
*/
|
||||
void FLASH_PageErase(uint32_t Page)
|
||||
{
|
||||
uint32_t tmp;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_FLASH_PAGE(Page));
|
||||
|
||||
/* Get configuration register, then clear page number */
|
||||
tmp = (FLASH->CR & ~FLASH_CR_PNB);
|
||||
|
||||
/* Set page number, Page Erase bit & Start bit */
|
||||
FLASH->CR = (tmp | (FLASH_CR_STRT | (Page << FLASH_CR_PNB_Pos) | FLASH_CR_PER));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Flush the instruction cache.
|
||||
* @retval None
|
||||
*/
|
||||
void FLASH_FlushCaches(void)
|
||||
{
|
||||
/* Flush instruction cache */
|
||||
if (READ_BIT(FLASH->ACR, FLASH_ACR_ICEN) != 0U)
|
||||
{
|
||||
/* Disable instruction cache */
|
||||
__HAL_FLASH_INSTRUCTION_CACHE_DISABLE();
|
||||
/* Reset instruction cache */
|
||||
__HAL_FLASH_INSTRUCTION_CACHE_RESET();
|
||||
/* Enable instruction cache */
|
||||
__HAL_FLASH_INSTRUCTION_CACHE_ENABLE();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Configure the write protection of the desired pages.
|
||||
* @note When WRP is active in a zone, it cannot be erased or programmed.
|
||||
* Consequently, a software mass erase cannot be performed if one zone
|
||||
* is write-protected.
|
||||
* @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.
|
||||
* @param WRPArea Specifies the area to be configured.
|
||||
* This parameter can be one of the following values:
|
||||
* @arg @ref OB_WRPAREA_ZONE_A Flash Zone A
|
||||
* @arg @ref OB_WRPAREA_ZONE_B Flash Zone B
|
||||
* @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 Flash - 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 Flash - 1)
|
||||
* @retval None
|
||||
*/
|
||||
static void FLASH_OB_WRPConfig(uint32_t WRPArea, uint32_t WRPStartOffset, uint32_t WRDPEndOffset)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_OB_WRPAREA(WRPArea));
|
||||
assert_param(IS_FLASH_PAGE(WRPStartOffset));
|
||||
assert_param(IS_FLASH_PAGE(WRDPEndOffset));
|
||||
|
||||
/* Configure the write protected area */
|
||||
if (WRPArea != OB_WRPAREA_ZONE_A)
|
||||
{
|
||||
FLASH->WRP1BR = ((WRDPEndOffset << FLASH_WRP1AR_WRP1A_END_Pos) | WRPStartOffset);
|
||||
}
|
||||
else
|
||||
{
|
||||
FLASH->WRP1AR = ((WRDPEndOffset << FLASH_WRP1BR_WRP1B_END_Pos) | WRPStartOffset);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set user & RDP configuration
|
||||
* @note !!! Warning : When enabling OB_RDP level 2 it is no more possible
|
||||
* to go back to level 1 or 0 !!!
|
||||
* @param UserType The FLASH User Option Bytes to be modified.
|
||||
* This parameter can be a combination of @ref FLASH_OB_USER_Type
|
||||
* @param UserConfig The FLASH User Option Bytes values.
|
||||
* This parameter can be a combination of:
|
||||
* @arg @ref OB_USER_BOR_ENABLE,
|
||||
* @arg @ref OB_USER_BOR_LEVEL,
|
||||
* @arg @ref OB_USER_nRST_STOP,
|
||||
* @arg @ref OB_USER_nRST_STANDBY,
|
||||
* @arg @ref OB_USER_nRST_SHUTDOWN,
|
||||
* @arg @ref OB_USER_IWDG_SW,
|
||||
* @arg @ref OB_USER_IWDG_STOP,
|
||||
* @arg @ref OB_USER_IWDG_STANDBY,
|
||||
* @arg @ref OB_USER_WWDG_SW,
|
||||
* @arg @ref OB_USER_SRAM_PARITY,
|
||||
* @arg @ref OB_USER_nBOOT_SEL,
|
||||
* @arg @ref OB_USER_nBOOT1,
|
||||
* @arg @ref OB_USER_nBOOT0,
|
||||
* @arg @ref OB_USER_INPUT_RESET_HOLDER
|
||||
* @arg @ref OB_USER_SECURE_MUXING_EN
|
||||
* @arg @ref OB_USER_HSE_NOT_REMAPPED (*)
|
||||
* @param RDPLevel specifies the read protection level.
|
||||
* This parameter can be one of the following values:
|
||||
* @arg @ref OB_RDP_LEVEL_0 No protection
|
||||
* @arg @ref OB_RDP_LEVEL_1 Memory Read protection
|
||||
* @arg @ref OB_RDP_LEVEL_2 Full chip protection
|
||||
* @retval None
|
||||
*
|
||||
* @note (*) available only on STM32C071xx, STM32C051xx and STM32C091/92xx devices.
|
||||
*/
|
||||
static void FLASH_OB_OptrConfig(uint32_t UserType, uint32_t UserConfig, uint32_t RDPLevel)
|
||||
{
|
||||
uint32_t optr;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_OB_USER_TYPE(UserType));
|
||||
assert_param(IS_OB_USER_CONFIG(UserType, UserConfig));
|
||||
assert_param(IS_OB_RDP_LEVEL(RDPLevel));
|
||||
|
||||
/* Configure the RDP level in the option bytes register */
|
||||
optr = FLASH->OPTR;
|
||||
optr &= ~(UserType | FLASH_OPTR_RDP);
|
||||
FLASH->OPTR = (optr | UserConfig | RDPLevel);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure the 1A Proprietary code readout protection & erase configuration on RDP regression.
|
||||
* @note It is recommended to align PCROP zone with page granularity when using PCROP_RDP or avoid
|
||||
* having some executable code in a page where PCROP zone starts or ends.
|
||||
* @note Minimum PCROP area size is 2 times the chosen granularity: PCROPA_STRT and PCROPA_END.
|
||||
* So if the requirement is to be able to read-protect 1KB areas, the ROP granularity
|
||||
* has to be set to 512 Bytes
|
||||
* @param PCROPConfig specifies the erase configuration (OB_PCROP_RDP_NOT_ERASE or OB_PCROP_RDP_ERASE)
|
||||
* on RDP level 1 regression.
|
||||
* @param PCROP1AStartAddr Specifies the Zone 1A Start address of the Proprietary code readout protection
|
||||
* This parameter can be an address between begin and end of the flash
|
||||
* @param PCROP1AEndAddr Specifies the Zone 1A end address of the Proprietary code readout protection
|
||||
* This parameter can be an address between PCROP1AStartAddr and end of the flash
|
||||
* @retval None
|
||||
*/
|
||||
static void FLASH_OB_PCROP1AConfig(uint32_t PCROPConfig, uint32_t PCROP1AStartAddr, uint32_t PCROP1AEndAddr)
|
||||
{
|
||||
uint32_t startoffset;
|
||||
uint32_t endoffset;
|
||||
uint32_t pcrop1aend;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_OB_PCROP_CONFIG(PCROPConfig));
|
||||
assert_param(IS_FLASH_MAIN_MEM_ADDRESS(PCROP1AStartAddr));
|
||||
assert_param(IS_FLASH_MAIN_MEM_ADDRESS(PCROP1AEndAddr));
|
||||
|
||||
/* get pcrop 1A end register */
|
||||
pcrop1aend = FLASH->PCROP1AER;
|
||||
|
||||
/* Configure the Proprietary code readout protection offset */
|
||||
if ((PCROPConfig & OB_PCROP_ZONE_A) != 0x00U)
|
||||
{
|
||||
/* Compute offset depending on pcrop granularity */
|
||||
startoffset = ((PCROP1AStartAddr - FLASH_BASE) >> FLASH_PCROP_GRANULARITY_OFFSET);
|
||||
endoffset = ((PCROP1AEndAddr - FLASH_BASE) >> FLASH_PCROP_GRANULARITY_OFFSET);
|
||||
|
||||
/* Set Zone A start offset */
|
||||
FLASH->PCROP1ASR = startoffset;
|
||||
|
||||
/* Set Zone A end offset */
|
||||
pcrop1aend &= ~FLASH_PCROP1AER_PCROP1A_END;
|
||||
pcrop1aend |= endoffset;
|
||||
}
|
||||
|
||||
/* Set RDP erase protection if needed. This bit is only set & will be reset by mass erase */
|
||||
if ((PCROPConfig & OB_PCROP_RDP_ERASE) != 0x00U)
|
||||
{
|
||||
pcrop1aend |= FLASH_PCROP1AER_PCROP_RDP;
|
||||
}
|
||||
|
||||
/* set 1A End register */
|
||||
FLASH->PCROP1AER = pcrop1aend;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure the 1B Proprietary code readout protection.
|
||||
* @note It is recommended to align PCROP zone with page granularity when using PCROP_RDP or avoid
|
||||
* having some executable code in a page where PCROP zone starts or ends.
|
||||
* @note Minimum PCROP area size is 2 times the chosen granularity: PCROPA_STRT and PCROPA_END.
|
||||
* So if the requirement is to be able to read-protect 1KB areas, the ROP granularity
|
||||
* has to be set to 512 Bytes
|
||||
* @param PCROP1BStartAddr Specifies the Zone 1B Start address of the Proprietary code readout protection
|
||||
* This parameter can be an address between begin and end of the flash
|
||||
* @param PCROP1BEndAddr Specifies the Zone 1B end address of the Proprietary code readout protection
|
||||
* This parameter can be an address between PCROP1BStartAddr and end of the flash
|
||||
* @retval None
|
||||
*/
|
||||
static void FLASH_OB_PCROP1BConfig(uint32_t PCROP1BStartAddr, uint32_t PCROP1BEndAddr)
|
||||
{
|
||||
uint32_t startoffset;
|
||||
uint32_t endoffset;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_FLASH_MAIN_MEM_ADDRESS(PCROP1BStartAddr));
|
||||
assert_param(IS_FLASH_MAIN_MEM_ADDRESS(PCROP1BEndAddr));
|
||||
|
||||
/* Configure the Proprietary code readout protection offset */
|
||||
startoffset = ((PCROP1BStartAddr - FLASH_BASE) >> FLASH_PCROP_GRANULARITY_OFFSET);
|
||||
endoffset = ((PCROP1BEndAddr - FLASH_BASE) >> FLASH_PCROP_GRANULARITY_OFFSET);
|
||||
|
||||
/* Set Zone B start offset */
|
||||
FLASH->PCROP1BSR = startoffset;
|
||||
/* Set Zone B end offset */
|
||||
FLASH->PCROP1BER = endoffset;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure Securable Memory area feature.
|
||||
* @param BootEntry specifies if boot scheme is forced to Flash (System or user) or not
|
||||
* This parameter can be one of the following values:
|
||||
* @arg @ref OB_BOOT_ENTRY_FORCED_NONE No boot entry forced
|
||||
* @arg @ref OB_BOOT_ENTRY_FORCED_FLASH FLash selected as unique entry boot
|
||||
* @param SecSize specifies number of pages to protect as securable memory area, starting from
|
||||
* beginning of the Flash (page 0).
|
||||
* @retval None
|
||||
*/
|
||||
static void FLASH_OB_SecMemConfig(uint32_t BootEntry, uint32_t SecSize)
|
||||
{
|
||||
uint32_t secmem;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_OB_SEC_BOOT_LOCK(BootEntry));
|
||||
assert_param(IS_OB_SEC_SIZE(SecSize));
|
||||
|
||||
/* Set securable memory area configuration */
|
||||
secmem = (FLASH->SECR & ~(FLASH_SECR_BOOT_LOCK | FLASH_SECR_SEC_SIZE));
|
||||
FLASH->SECR = (secmem | BootEntry | SecSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 @ref OB_WRPAREA_ZONE_A Flash Zone A
|
||||
* @arg @ref OB_WRPAREA_ZONE_B Flash Zone B
|
||||
* @param[out] WRPStartOffset Specifies the address where to copied the start page
|
||||
* of the write protected area
|
||||
* @param[out] WRDPEndOffset Dpecifies 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)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_OB_WRPAREA(WRPArea));
|
||||
|
||||
/* Get the configuration of the write protected area */
|
||||
if (WRPArea == OB_WRPAREA_ZONE_A)
|
||||
{
|
||||
*WRPStartOffset = READ_BIT(FLASH->WRP1AR, FLASH_WRP1AR_WRP1A_STRT);
|
||||
*WRDPEndOffset = (READ_BIT(FLASH->WRP1AR, FLASH_WRP1AR_WRP1A_END) >> FLASH_WRP1AR_WRP1A_END_Pos);
|
||||
}
|
||||
else
|
||||
{
|
||||
*WRPStartOffset = READ_BIT(FLASH->WRP1BR, FLASH_WRP1BR_WRP1B_STRT);
|
||||
*WRDPEndOffset = (READ_BIT(FLASH->WRP1BR, FLASH_WRP1BR_WRP1B_END) >> FLASH_WRP1BR_WRP1B_END_Pos);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the FLASH Read Protection level.
|
||||
* @retval FLASH ReadOut Protection Status:
|
||||
* This return value can be one of the following values:
|
||||
* @arg @ref OB_RDP_LEVEL_0 No protection
|
||||
* @arg @ref OB_RDP_LEVEL_1 Read protection of the memory
|
||||
* @arg @ref OB_RDP_LEVEL_2 Full chip protection
|
||||
*/
|
||||
static uint32_t FLASH_OB_GetRDP(void)
|
||||
{
|
||||
uint32_t rdplvl = READ_BIT(FLASH->OPTR, FLASH_OPTR_RDP);
|
||||
|
||||
if ((rdplvl != OB_RDP_LEVEL_0) && (rdplvl != OB_RDP_LEVEL_2))
|
||||
{
|
||||
return (OB_RDP_LEVEL_1);
|
||||
}
|
||||
else
|
||||
{
|
||||
return rdplvl;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the FLASH User Option Byte value.
|
||||
* @retval The FLASH User Option Bytes values. It will be a combination of all the following values:
|
||||
* @arg @ref OB_USER_BOR_ENABLE,
|
||||
* @ref OB_USER_BOR_LEVEL,
|
||||
* @ref OB_USER_nRST_STOP,
|
||||
* @ref OB_USER_nRST_STANDBY,
|
||||
* @ref OB_USER_nRST_SHUTDOWN,
|
||||
* @ref OB_USER_IWDG_SW,
|
||||
* @ref OB_USER_IWDG_STOP,
|
||||
* @ref OB_USER_IWDG_STANDBY,
|
||||
* @ref OB_USER_WWDG_SW,
|
||||
* @ref OB_USER_SRAM_PARITY,
|
||||
* @ref OB_USER_nBOOT_SEL,
|
||||
* @ref OB_USER_nBOOT1,
|
||||
* @ref OB_USER_nBOOT0,
|
||||
* @ref OB_USER_INPUT_RESET_HOLDER
|
||||
* @ref OB_USER_SECURE_MUXING_EN
|
||||
* @ref OB_USER_HSE_NOT_REMAPPED (*)
|
||||
*
|
||||
* @note (*) available only on STM32C071xx, STM32C051xx and STM32C091/92xx devices.
|
||||
*/
|
||||
static uint32_t FLASH_OB_GetUser(void)
|
||||
{
|
||||
uint32_t user = ((FLASH->OPTR & ~FLASH_OPTR_RDP) & OB_USER_ALL);
|
||||
return user;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the FLASH PCROP Protection Option Bytes value.
|
||||
* @param PCROPConfig [out] specifies the configuration of PCROP_RDP option.
|
||||
* @param PCROP1AStartAddr [out] Specifies the address where to copied the start address
|
||||
* of the 1A Proprietary code readout protection
|
||||
* @param PCROP1AEndAddr [out] Specifies the address where to copied the end address of
|
||||
* the 1A Proprietary code readout protection
|
||||
* @retval None
|
||||
*/
|
||||
static void FLASH_OB_GetPCROP1A(uint32_t *PCROPConfig, uint32_t *PCROP1AStartAddr, uint32_t *PCROP1AEndAddr)
|
||||
{
|
||||
uint32_t pcrop;
|
||||
|
||||
pcrop = (FLASH->PCROP1ASR & FLASH_PCROP1ASR_PCROP1A_STRT);
|
||||
*PCROP1AStartAddr = (pcrop << FLASH_PCROP_GRANULARITY_OFFSET);
|
||||
*PCROP1AStartAddr += FLASH_BASE;
|
||||
|
||||
pcrop = FLASH->PCROP1AER;
|
||||
*PCROP1AEndAddr = ((pcrop & FLASH_PCROP1AER_PCROP1A_END) << FLASH_PCROP_GRANULARITY_OFFSET);
|
||||
*PCROP1AEndAddr += (FLASH_BASE + FLASH_PCROP_GRANULARITY - 1U);
|
||||
|
||||
*PCROPConfig &= ~OB_PCROP_RDP_ERASE;
|
||||
*PCROPConfig |= (pcrop & FLASH_PCROP1AER_PCROP_RDP);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Return the FLASH PCROP Protection Option Bytes value.
|
||||
* @param PCROP1BStartAddr [out] Specifies the address where to copied the start address
|
||||
* of the 1B Proprietary code readout protection
|
||||
* @param PCROP1BEndAddr [out] Specifies the address where to copied the end address of
|
||||
* the 1B Proprietary code readout protection
|
||||
* @retval None
|
||||
*/
|
||||
static void FLASH_OB_GetPCROP1B(uint32_t *PCROP1BStartAddr, uint32_t *PCROP1BEndAddr)
|
||||
{
|
||||
uint32_t pcrop;
|
||||
|
||||
pcrop = (FLASH->PCROP1BSR & FLASH_PCROP1BSR_PCROP1B_STRT);
|
||||
*PCROP1BStartAddr = (pcrop << FLASH_PCROP_GRANULARITY_OFFSET);
|
||||
*PCROP1BStartAddr += FLASH_BASE;
|
||||
|
||||
pcrop = (FLASH->PCROP1BER & FLASH_PCROP1BER_PCROP1B_END);
|
||||
*PCROP1BEndAddr = (pcrop << FLASH_PCROP_GRANULARITY_OFFSET);
|
||||
*PCROP1BEndAddr += (FLASH_BASE + FLASH_PCROP_GRANULARITY - 1U);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the FLASH Securable memory area protection Option Bytes value.
|
||||
* @param BootEntry specifies boot scheme configuration
|
||||
* @param SecSize specifies number of pages to protect as secure memory area, starting from
|
||||
* beginning of the Flash (page 0).
|
||||
* @retval None
|
||||
*/
|
||||
static void FLASH_OB_GetSecMem(uint32_t *BootEntry, uint32_t *SecSize)
|
||||
{
|
||||
uint32_t secmem = FLASH->SECR;
|
||||
|
||||
*BootEntry = (secmem & FLASH_SECR_BOOT_LOCK);
|
||||
*SecSize = (secmem & FLASH_SECR_SEC_SIZE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* HAL_FLASH_MODULE_ENABLED */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
@@ -0,0 +1,585 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32c0xx_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) 2022 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 28 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 set the level of several pins and reset level of several other pins in
|
||||
same cycle, use HAL_GPIO_WriteMultipleStatePin().
|
||||
|
||||
(#) 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 PF0 and PF1, respectively, when the HSE oscillator is off.
|
||||
The HSE has priority over the GPIO function.
|
||||
|
||||
@endverbatim
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32c0xx_hal.h"
|
||||
|
||||
/** @addtogroup STM32C0xx_HAL_Driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup GPIO GPIO
|
||||
* @brief GPIO HAL module driver
|
||||
* @{
|
||||
*/
|
||||
#ifdef HAL_GPIO_MODULE_ENABLED
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private defines -----------------------------------------------------------*/
|
||||
/** @defgroup GPIO_Private_Defines GPIO Private Defines
|
||||
* @{
|
||||
*/
|
||||
#define GPIO_MODE (0x00000003U)
|
||||
#define EXTI_MODE (0x10000000U)
|
||||
#define GPIO_MODE_IT (0x00010000U)
|
||||
#define GPIO_MODE_EVT (0x00020000U)
|
||||
#define RISING_EDGE (0x00100000U)
|
||||
#define FALLING_EDGE (0x00200000U)
|
||||
#define GPIO_OUTPUT_TYPE (0x00000010U)
|
||||
#define GPIO_NUMBER (16U)
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private macros ------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/** @defgroup GPIO_Private_Macros GPIO Private Macros
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* 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..F) to select the GPIO peripheral for STM32C0xx family
|
||||
* @param pGPIO_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, const GPIO_InitTypeDef *pGPIO_Init)
|
||||
{
|
||||
uint32_t tmp;
|
||||
uint32_t iocurrent;
|
||||
uint32_t position = 0U;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_GPIO_ALL_INSTANCE(GPIOx));
|
||||
assert_param(IS_GPIO_PIN(pGPIO_Init->Pin));
|
||||
assert_param(IS_GPIO_MODE(pGPIO_Init->Mode));
|
||||
|
||||
/* Configure the port pins */
|
||||
while (((pGPIO_Init->Pin) >> position) != 0U)
|
||||
{
|
||||
/* Get current io position */
|
||||
iocurrent = (pGPIO_Init->Pin) & (1UL << position);
|
||||
|
||||
if (iocurrent != 0U)
|
||||
{
|
||||
/*--------------------- GPIO Mode Configuration ------------------------*/
|
||||
/* In case of Alternate function mode selection */
|
||||
if ((pGPIO_Init->Mode == GPIO_MODE_AF_PP) || (pGPIO_Init->Mode == GPIO_MODE_AF_OD))
|
||||
{
|
||||
/* Check the Alternate function parameters */
|
||||
assert_param(IS_GPIO_AF_INSTANCE(GPIOx));
|
||||
assert_param(IS_GPIO_AF(pGPIO_Init->Alternate));
|
||||
|
||||
/* Configure Alternate function mapped with the current IO */
|
||||
tmp = GPIOx->AFR[position >> 3U];
|
||||
tmp &= ~(0xFUL << ((position & 0x07U) * GPIO_AFRL_AFSEL1_Pos)) ;
|
||||
tmp |= ((pGPIO_Init->Alternate & 0x0FUL) << ((position & 0x07U) * GPIO_AFRL_AFSEL1_Pos));
|
||||
GPIOx->AFR[position >> 3U] = tmp;
|
||||
}
|
||||
|
||||
/* Configure IO Direction mode (Input, Output, Alternate or Analog) */
|
||||
tmp = GPIOx->MODER;
|
||||
tmp &= ~(GPIO_MODER_MODE0 << (position * GPIO_MODER_MODE1_Pos));
|
||||
tmp |= ((pGPIO_Init->Mode & GPIO_MODE) << (position * GPIO_MODER_MODE1_Pos));
|
||||
GPIOx->MODER = tmp;
|
||||
|
||||
/* In case of Output or Alternate function mode selection */
|
||||
if ((pGPIO_Init->Mode == GPIO_MODE_OUTPUT_PP) || (pGPIO_Init->Mode == GPIO_MODE_AF_PP) ||
|
||||
(pGPIO_Init->Mode == GPIO_MODE_OUTPUT_OD) || (pGPIO_Init->Mode == GPIO_MODE_AF_OD))
|
||||
{
|
||||
/* Check the Speed parameter */
|
||||
assert_param(IS_GPIO_SPEED(pGPIO_Init->Speed));
|
||||
|
||||
/* Configure the IO Speed */
|
||||
tmp = GPIOx->OSPEEDR;
|
||||
tmp &= ~(GPIO_OSPEEDR_OSPEED0 << (position * GPIO_OSPEEDR_OSPEED1_Pos));
|
||||
tmp |= (pGPIO_Init->Speed << (position * GPIO_OSPEEDR_OSPEED1_Pos));
|
||||
GPIOx->OSPEEDR = tmp;
|
||||
|
||||
/* Configure the IO Output Type */
|
||||
tmp = GPIOx->OTYPER;
|
||||
tmp &= ~(GPIO_OTYPER_OT0 << position) ;
|
||||
tmp |= (((pGPIO_Init->Mode & GPIO_OUTPUT_TYPE) >> 4U) << position);
|
||||
GPIOx->OTYPER = tmp;
|
||||
}
|
||||
|
||||
if (pGPIO_Init->Mode != GPIO_MODE_ANALOG)
|
||||
{
|
||||
/* Check the Pull parameters */
|
||||
assert_param(IS_GPIO_PULL(pGPIO_Init->Pull));
|
||||
|
||||
/* Activate the Pull-up or Pull down resistor for the current IO */
|
||||
tmp = GPIOx->PUPDR;
|
||||
tmp &= ~(GPIO_PUPDR_PUPD0 << (position * GPIO_PUPDR_PUPD1_Pos));
|
||||
tmp |= ((pGPIO_Init->Pull) << (position * GPIO_PUPDR_PUPD1_Pos));
|
||||
GPIOx->PUPDR = tmp;
|
||||
}
|
||||
|
||||
/*--------------------- EXTI Mode Configuration ------------------------*/
|
||||
/* Configure the External Interrupt or event for the current IO */
|
||||
if ((pGPIO_Init->Mode & EXTI_MODE) == EXTI_MODE)
|
||||
{
|
||||
tmp = EXTI->EXTICR[position >> 2U];
|
||||
tmp &= ~((0x0FUL) << ((position & 0x03U) * EXTI_EXTICR1_EXTI1_Pos));
|
||||
tmp |= (GPIO_GET_INDEX(GPIOx) << ((position & 0x03U) * EXTI_EXTICR1_EXTI1_Pos));
|
||||
EXTI->EXTICR[position >> 2U] = tmp;
|
||||
|
||||
/* Clear EXTI line configuration */
|
||||
tmp = EXTI->IMR1;
|
||||
tmp &= ~((uint32_t)iocurrent);
|
||||
if ((pGPIO_Init->Mode & GPIO_MODE_IT) == GPIO_MODE_IT)
|
||||
{
|
||||
tmp |= iocurrent;
|
||||
}
|
||||
EXTI->IMR1 = tmp;
|
||||
|
||||
tmp = EXTI->EMR1;
|
||||
tmp &= ~((uint32_t)iocurrent);
|
||||
if ((pGPIO_Init->Mode & GPIO_MODE_EVT) == GPIO_MODE_EVT)
|
||||
{
|
||||
tmp |= iocurrent;
|
||||
}
|
||||
EXTI->EMR1 = tmp;
|
||||
|
||||
/* Clear Rising Falling edge configuration */
|
||||
tmp = EXTI->RTSR1;
|
||||
tmp &= ~((uint32_t)iocurrent);
|
||||
if ((pGPIO_Init->Mode & RISING_EDGE) == RISING_EDGE)
|
||||
{
|
||||
tmp |= iocurrent;
|
||||
}
|
||||
EXTI->RTSR1 = tmp;
|
||||
|
||||
tmp = EXTI->FTSR1;
|
||||
tmp &= ~((uint32_t)iocurrent);
|
||||
if ((pGPIO_Init->Mode & FALLING_EDGE) == FALLING_EDGE)
|
||||
{
|
||||
tmp |= iocurrent;
|
||||
}
|
||||
EXTI->FTSR1 = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
position++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief De-initialize the GPIOx peripheral registers to their default reset values.
|
||||
* @param GPIOx where x can be (A..F) to select the GPIO peripheral for STM32C0xx 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 tmp;
|
||||
uint32_t iocurrent;
|
||||
uint32_t position = 0U;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_GPIO_ALL_INSTANCE(GPIOx));
|
||||
assert_param(IS_GPIO_PIN(GPIO_Pin));
|
||||
|
||||
/* Configure the port pins */
|
||||
while ((GPIO_Pin >> position) != 0U)
|
||||
{
|
||||
/* Get current io position */
|
||||
iocurrent = (GPIO_Pin) & (1UL << position);
|
||||
|
||||
if (iocurrent != 0U)
|
||||
{
|
||||
/*------------------------- EXTI Mode Configuration --------------------*/
|
||||
/* Clear the External Interrupt or Event for the current IO */
|
||||
tmp = EXTI->EXTICR[position >> 2U];
|
||||
tmp &= ((0x0FUL) << ((position & 0x03U) * EXTI_EXTICR1_EXTI1_Pos));
|
||||
if (tmp == (GPIO_GET_INDEX(GPIOx) << ((position & 0x03U) * EXTI_EXTICR1_EXTI1_Pos)))
|
||||
{
|
||||
/* Clear EXTI line configuration */
|
||||
EXTI->IMR1 &= ~(iocurrent);
|
||||
EXTI->EMR1 &= ~(iocurrent);
|
||||
|
||||
/* Clear Rising Falling edge configuration */
|
||||
EXTI->RTSR1 &= ~(iocurrent);
|
||||
EXTI->FTSR1 &= ~(iocurrent);
|
||||
|
||||
tmp = (0x0FUL) << (8U * (position & 0x03U));
|
||||
EXTI->EXTICR[position >> 2U] &= ~tmp;
|
||||
}
|
||||
|
||||
/*------------------------- GPIO Mode Configuration --------------------*/
|
||||
/* Configure IO in Analog Mode */
|
||||
GPIOx->MODER |= (GPIO_MODER_MODE0 << (position * GPIO_MODER_MODE1_Pos));
|
||||
|
||||
/* Configure the default Alternate Function in current IO */
|
||||
GPIOx->AFR[position >> 3U] &= ~(0x0FUL << ((position & 0x07U) * GPIO_AFRL_AFSEL1_Pos)) ;
|
||||
|
||||
/* Configure the default value for IO Speed */
|
||||
GPIOx->OSPEEDR &= ~(GPIO_OSPEEDR_OSPEED0 << (position * GPIO_OSPEEDR_OSPEED1_Pos));
|
||||
|
||||
/* 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 * GPIO_PUPDR_PUPD1_Pos));
|
||||
}
|
||||
|
||||
position++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup GPIO_Exported_Functions_Group2
|
||||
* @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..F) to select the GPIO peripheral for STM32C0xx 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(const 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) != 0U)
|
||||
{
|
||||
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..F) to select the GPIO peripheral for STM32C0xx 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 Set and clear several pins of a dedicated port in same cycle.
|
||||
* @note This function uses GPIOx_BSRR and GPIOx_BRR registers to allow atomic read/modify
|
||||
* accesses.
|
||||
* @param GPIOx where x can be (A..F) to select the GPIO peripheral for STM32C0xx family
|
||||
* @param PinReset specifies the port bits to be reset
|
||||
* This parameter can be any combination of GPIO_Pin_x where x can be (0..15) or zero.
|
||||
* @param PinSet specifies the port bits to be set
|
||||
* This parameter can be any combination of GPIO_Pin_x where x can be (0..15) or zero.
|
||||
* @note Both PinReset and PinSet combinations shall not get any common bit, else
|
||||
* assert would be triggered.
|
||||
* @note At least one of the two parameters used to set or reset shall be different from zero.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_GPIO_WriteMultipleStatePin(GPIO_TypeDef *GPIOx, uint16_t PinReset, uint16_t PinSet)
|
||||
{
|
||||
uint32_t tmp;
|
||||
|
||||
/* Check the parameters */
|
||||
/* Make sure at least one parameter is different from zero and that there is no common pin */
|
||||
assert_param(IS_GPIO_PIN((uint32_t)PinReset | (uint32_t)PinSet));
|
||||
assert_param(IS_GPIO_COMMON_PIN(PinReset, PinSet));
|
||||
|
||||
tmp = (((uint32_t)PinReset << 16) | PinSet);
|
||||
GPIOx->BSRR = tmp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Toggle the specified GPIO pin.
|
||||
* @param GPIOx: where x can be (A..I) to select the GPIO peripheral for STM32C0 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..F) to select the GPIO peripheral for STM32C0xx 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 bit*/
|
||||
tmp = GPIOx->LCKR;
|
||||
|
||||
/* read again in order to confirm lock is active */
|
||||
if ((GPIOx->LCKR & GPIO_LCKR_LCKK) != GPIO_LCKR_LCKK)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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_RISING_IT(GPIO_Pin) != 0U)
|
||||
{
|
||||
__HAL_GPIO_EXTI_CLEAR_RISING_IT(GPIO_Pin);
|
||||
HAL_GPIO_EXTI_Rising_Callback(GPIO_Pin);
|
||||
}
|
||||
|
||||
if (__HAL_GPIO_EXTI_GET_FALLING_IT(GPIO_Pin) != 0U)
|
||||
{
|
||||
__HAL_GPIO_EXTI_CLEAR_FALLING_IT(GPIO_Pin);
|
||||
HAL_GPIO_EXTI_Falling_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_Rising_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_Rising_Callback could be implemented in the user file
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief EXTI line detection callback.
|
||||
* @param GPIO_Pin Specifies the port pin connected to corresponding EXTI line.
|
||||
* @retval None
|
||||
*/
|
||||
__weak void HAL_GPIO_EXTI_Falling_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_Falling_Callback could be implemented in the user file
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* HAL_GPIO_MODULE_ENABLED */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
@@ -0,0 +1,423 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32c0xx_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) 2022 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 "stm32c0xx_hal.h"
|
||||
|
||||
/** @addtogroup STM32C0xx_HAL_Driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup PWR
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifdef HAL_PWR_MODULE_ENABLED
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/** @defgroup PWR_Private_Defines PWR Private Defines
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* Exported functions --------------------------------------------------------*/
|
||||
/** @addtogroup PWR_Exported_Functions PWR Exported Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup 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();
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup PWR_Exported_Functions_Group2 Peripheral Control functions
|
||||
* @brief Low Power modes configuration functions
|
||||
*
|
||||
@verbatim
|
||||
|
||||
===============================================================================
|
||||
##### Peripheral Control functions #####
|
||||
===============================================================================
|
||||
|
||||
[..]
|
||||
|
||||
*** WakeUp pin configuration ***
|
||||
================================
|
||||
[..]
|
||||
(+) WakeUp pins are used to wakeup the system from Standby mode or
|
||||
Shutdown mode. WakeUp pins polarity can be set to configure event
|
||||
detection on high level (rising edge) or low level (falling edge).
|
||||
|
||||
*** Low Power mode configuration ***
|
||||
=====================================
|
||||
[..]
|
||||
The devices feature 4 low-power modes:
|
||||
(+) Sleep mode: Cortex-M0+ core stopped, peripherals kept running,
|
||||
regulator is main mode.
|
||||
(+) Stop 0 mode: all clocks are stopped except LSI and LSE, regulator is
|
||||
main mode.
|
||||
(+) Standby mode: all clocks are stopped except LSI and LSE, regulator is
|
||||
disable.
|
||||
(+) Shutdown mode: all clocks are stopped except LSE, regulator is
|
||||
disable.
|
||||
|
||||
|
||||
*** Sleep mode ***
|
||||
=========================================
|
||||
[..]
|
||||
(+) Entry:
|
||||
The Sleep is entered through HAL_PWR_EnterSLEEPMode() API specifying
|
||||
the main regulator per default and if exit is interrupt or event
|
||||
triggered.
|
||||
(++) PWR_MAINREGULATOR_ON: Sleep mode (regulator in main mode).
|
||||
(++) PWR_SLEEPENTRY_WFI: Core enters sleep mode with WFI instruction
|
||||
(++) PWR_SLEEPENTRY_WFE: Core enters sleep mode with WFE instruction
|
||||
(+) WFI Exit:
|
||||
(++) Any interrupt enabled in nested vectored interrupt controller (NVIC)
|
||||
(+) WFE Exit:
|
||||
(++) Any wakeup event if cortex is configured with SEVONPEND = 0
|
||||
(++) Interrupt even when disabled in NVIC if cortex is configured with
|
||||
SEVONPEND = 1
|
||||
|
||||
*** Stop 0 mode ***
|
||||
=============================
|
||||
[..]
|
||||
(+) Entry:
|
||||
The Stop modes are entered through the following APIs:
|
||||
(++) HAL_PWR_EnterSTOPMode() with following settings:
|
||||
(+++) PWR_MAINREGULATOR_ON to enter STOP0 mode.
|
||||
(+) 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
|
||||
with corresponding interrupt enable in NVIC
|
||||
(+) WFE Exit:
|
||||
(++) Any EXTI line (internal or external) configured in event mode if
|
||||
cortex is configured with SEVONPEND = 0
|
||||
(++) Any EXTI line configured in interrupt mode (even if the
|
||||
corresponding EXTI Interrupt vector is disabled in the NVIC) if
|
||||
cortex is configured with SEVONPEND = 0. The interrupt source can
|
||||
be external interrupts or peripherals with wakeup capability.
|
||||
|
||||
*** Standby mode ***
|
||||
====================
|
||||
[..]
|
||||
(+) Entry:
|
||||
(++) The Standby mode is entered through HAL_PWR_EnterSTANDBYMode() API, by
|
||||
setting SLEEPDEEP in Cortex control register.
|
||||
(+) Exit:
|
||||
(++) WKUP pin edge detection, RTC event (alarm, timestamp),
|
||||
LSE CSS detection, reset on NRST pin, IWDG reset & BOR reset.
|
||||
[..] Exiting Standby generates a power reset: Cortex is reset and execute
|
||||
Reset handler vector, all registers in the Vcore domain are set to
|
||||
their reset value. Registers outside the VCORE domain (RTC, WKUP, IWDG,
|
||||
and Standby/Shutdown modes control) are not impacted.
|
||||
|
||||
*** 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,
|
||||
by setting SLEEPDEEP in Cortex control register.
|
||||
(+) Exit:
|
||||
(++) WKUP pin edge detection, RTC event (alarm, timestamp),
|
||||
LSE CSS detection, reset on NRST pin.
|
||||
[..] Exiting Shutdown generates a brown out reset: Cortex is reset and execute
|
||||
Reset handler vector, all registers are set to their reset value but ones
|
||||
in backup domain.
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @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 (Only on STM32C071xx), PWR_WAKEUP_PIN6
|
||||
* 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 (*)
|
||||
* @arg @ref PWR_WAKEUP_PIN6_HIGH or PWR_WAKEUP_PIN6_LOW
|
||||
* @note PWR_WAKEUP_PINx and PWR_WAKEUP_PINx_HIGH are equivalent.
|
||||
* @note (*) Availability depends on devices
|
||||
* @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_CR4_WP & 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 (*), PWR_WAKEUP_PIN6
|
||||
* @note (*) Availability depends on devices
|
||||
* @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 mode.
|
||||
* @note In Sleep mode, all I/O pins keep the same state as
|
||||
* in Run mode.
|
||||
* @param Regulator Specifies the regulator state in Sleep mode.
|
||||
* This parameter can be the following value:
|
||||
* @arg @ref PWR_MAINREGULATOR_ON Sleep mode (regulator in main mode)
|
||||
* @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));
|
||||
|
||||
/* 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 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 HSI and the
|
||||
* HSE oscillators are disabled. Some peripherals with the wakeup
|
||||
* capability 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.
|
||||
* SRAM and register contents are preserved.
|
||||
* @note When exiting Stop 0 mode by issuing an interrupt or a
|
||||
* wakeup event, the HSI RC oscillator is selected as system clock
|
||||
* @param Regulator Specifies the regulator state in Stop mode
|
||||
* This parameter can be of the following value:
|
||||
* @arg @ref PWR_MAINREGULATOR_ON Stop 0 mode (main regulator ON)
|
||||
* @param STOPEntry Specifies Stop 0 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 mode with WFI
|
||||
* instruction.
|
||||
* @arg @ref PWR_STOPENTRY_WFE Enter Stop 0 mode with WFE
|
||||
* instruction.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_PWR_EnterSTOPMode(uint32_t Regulator, uint8_t STOPEntry)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_PWR_REGULATOR(Regulator));
|
||||
assert_param(IS_PWR_STOP_ENTRY(STOPEntry));
|
||||
|
||||
MODIFY_REG(PWR->CR1, PWR_CR1_LPMS, PWR_LOWPOWERMODE_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 Standby mode.
|
||||
* @note In Standby mode,the HSI and the HSE oscillators are
|
||||
* switched off. SRAM and register contents are lost except
|
||||
* for registers in the Backup domain and Standby circuitry.
|
||||
* @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 PullDown state.
|
||||
* HAL_PWREx_DisableGPIOPullUp() & 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_LOWPOWERMODE_STANDBY);
|
||||
|
||||
/* Set SLEEPDEEP bit of Cortex System Control Register */
|
||||
SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
|
||||
|
||||
/* Request Wait For Interrupt */
|
||||
__WFI();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable Sleep-On-Exit Cortex feature
|
||||
* @note Set SLEEPONEXIT bit of SCR register. When this bit is set, the
|
||||
* processor enters SLEEP or DEEPSLEEP mode when an interruption
|
||||
* handling is over returning to thread mode. 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 Cortex feature
|
||||
* @note Clear SLEEPONEXIT bit of SCR register. When this bit is set, the
|
||||
* processor enters SLEEP or DEEPSLEEP 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 Sev On Pending feature.
|
||||
* @note Set SEVONPEND bit of SCR register. When this bit is set, enabled
|
||||
* events and all interrupts, including disabled ones can wakeup
|
||||
* processor from WFE.
|
||||
* @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 Sev On Pending feature.
|
||||
* @note Clear SEVONPEND bit of SCR register. When this bit is clear, only
|
||||
* enable interrupts or events can wakeup processor from WFE
|
||||
* @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));
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* HAL_PWR_MODULE_ENABLED */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
@@ -0,0 +1,575 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32c0xx_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) 2022 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 "stm32c0xx_hal.h"
|
||||
|
||||
/** @addtogroup STM32C0xx_HAL_Driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup PWREx
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifdef HAL_PWR_MODULE_ENABLED
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/** @defgroup PWR_Extended_Private_Defines PWR Extended Private Defines
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup PWREx_Gpio_Pin_Number PWREx Gpio Pin Number
|
||||
* @{
|
||||
*/
|
||||
#define PWR_GPIO_PIN_NB 16u /*!< Number of gpio pin in bank */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* Exported functions --------------------------------------------------------*/
|
||||
/** @addtogroup PWREx_Exported_Functions PWR Extended Exported Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup PWREx_Exported_Functions_Group1 Extended Peripheral Control functions
|
||||
* @brief Extended Peripheral Control functions
|
||||
*
|
||||
@verbatim
|
||||
===============================================================================
|
||||
##### Extended Peripheral Initialization and de-initialization functions #####
|
||||
===============================================================================
|
||||
[..]
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
#if defined (PWR_PVM_SUPPORT)
|
||||
/**
|
||||
* @brief Enable the Power Voltage Monitoring for USB peripheral (power domain Vddio2)
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_PWREx_EnablePVMUSB(void)
|
||||
{
|
||||
SET_BIT(PWR->CR2, PWR_CR2_PVM_VDDIO2_0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable the Power Voltage Monitoring for USB peripheral (power domain Vddio2)
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_PWREx_DisablePVMUSB(void)
|
||||
{
|
||||
CLEAR_BIT(PWR->CR2, PWR_CR2_PVM_VDDIO2_0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 34 interrupts if so required:
|
||||
scan through PVMType to detect which PVMx is set and
|
||||
configure the corresponding EXTI line accordingly. */
|
||||
switch (sConfigPVM->PVMType)
|
||||
{
|
||||
case PWR_PVM_USB:
|
||||
/* Clear any previous config. Keep it clear if no event or IT mode is selected */
|
||||
__HAL_PWR_PVM_EXTI_DISABLE_EVENT();
|
||||
__HAL_PWR_PVM_EXTI_DISABLE_IT();
|
||||
__HAL_PWR_PVM_EXTI_DISABLE_FALLING_EDGE();
|
||||
__HAL_PWR_PVM_EXTI_DISABLE_RISING_EDGE();
|
||||
|
||||
/* Configure interrupt mode */
|
||||
if ((sConfigPVM->Mode & PVM_MODE_IT) == PVM_MODE_IT)
|
||||
{
|
||||
__HAL_PWR_PVM_EXTI_ENABLE_IT();
|
||||
}
|
||||
|
||||
/* Configure event mode */
|
||||
if ((sConfigPVM->Mode & PVM_MODE_EVT) == PVM_MODE_EVT)
|
||||
{
|
||||
__HAL_PWR_PVM_EXTI_ENABLE_EVENT();
|
||||
}
|
||||
|
||||
/* Configure the edge */
|
||||
if ((sConfigPVM->Mode & PVM_RISING_EDGE) == PVM_RISING_EDGE)
|
||||
{
|
||||
__HAL_PWR_PVM_EXTI_ENABLE_RISING_EDGE();
|
||||
}
|
||||
|
||||
if ((sConfigPVM->Mode & PVM_FALLING_EDGE) == PVM_FALLING_EDGE)
|
||||
{
|
||||
__HAL_PWR_PVM_EXTI_ENABLE_FALLING_EDGE();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
status = HAL_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
#endif /* PWR_PVM_SUPPORT */
|
||||
/**
|
||||
* @brief Enable Internal Wake-up Line.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_PWREx_EnableInternalWakeUpLine(void)
|
||||
{
|
||||
SET_BIT(PWR->CR3, PWR_CR3_EIWUL);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Disable Internal Wake-up Line.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_PWREx_DisableInternalWakeUpLine(void)
|
||||
{
|
||||
CLEAR_BIT(PWR->CR3, PWR_CR3_EIWUL);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Enable GPIO pull-up state in Standby and Shutdown modes.
|
||||
* @note Set the relevant PUy bit 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.
|
||||
* @param GPIO Specify the IO port. This parameter can be PWR_GPIO_A, ..., PWR_GPIO_F
|
||||
* 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 ports 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);
|
||||
CLEAR_BIT(PWR->PDCRA, GPIONumber);
|
||||
break;
|
||||
|
||||
case PWR_GPIO_B:
|
||||
SET_BIT(PWR->PUCRB, GPIONumber);
|
||||
CLEAR_BIT(PWR->PDCRB, GPIONumber);
|
||||
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 /* GPIOD */
|
||||
case PWR_GPIO_F:
|
||||
SET_BIT(PWR->PUCRF, GPIONumber);
|
||||
CLEAR_BIT(PWR->PDCRF, GPIONumber);
|
||||
break;
|
||||
|
||||
default:
|
||||
status = HAL_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Disable GPIO pull-up state in Standby mode and Shutdown modes.
|
||||
* @note Reset the relevant PUy bit of PWR_PUCRx register used to configure the I/O
|
||||
* in pull-up state in Standby and Shutdown modes.
|
||||
* @param GPIO Specifies the IO port. This parameter can be PWR_GPIO_A, ..., PWR_GPIO_F
|
||||
* 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 ports 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);
|
||||
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 /* GPIOD */
|
||||
case PWR_GPIO_F:
|
||||
CLEAR_BIT(PWR->PUCRF, GPIONumber);
|
||||
break;
|
||||
|
||||
default:
|
||||
status = HAL_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Enable GPIO pull-down state in Standby and Shutdown modes.
|
||||
* @note Set the relevant PDy bit 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.
|
||||
* @param GPIO Specify the IO port. This parameter can be PWR_GPIO_A..PWR_GPIO_F
|
||||
* 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 ports 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);
|
||||
CLEAR_BIT(PWR->PUCRA, GPIONumber);
|
||||
break;
|
||||
|
||||
case PWR_GPIO_B:
|
||||
SET_BIT(PWR->PDCRB, GPIONumber);
|
||||
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 /* GPIOD */
|
||||
case PWR_GPIO_F:
|
||||
SET_BIT(PWR->PDCRF, GPIONumber);
|
||||
CLEAR_BIT(PWR->PUCRF, GPIONumber);
|
||||
break;
|
||||
|
||||
default:
|
||||
status = HAL_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Disable GPIO pull-down state in Standby and Shutdown modes.
|
||||
* @note Reset the relevant PDy bit of PWR_PDCRx register used to configure the I/O
|
||||
* in pull-down state in Standby and Shutdown modes.
|
||||
* @param GPIO Specifies the IO port. This parameter can be PWR_GPIO_A..PWR_GPIO_F
|
||||
* 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 ports 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);
|
||||
break;
|
||||
|
||||
case PWR_GPIO_B:
|
||||
CLEAR_BIT(PWR->PDCRB, GPIONumber);
|
||||
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 /* GPIOD */
|
||||
case PWR_GPIO_F:
|
||||
CLEAR_BIT(PWR->PDCRF, GPIONumber);
|
||||
break;
|
||||
|
||||
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() APIs 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 Flash Power Down.
|
||||
* @note This API allows to enable flash power down capabilities in sleep and stop modes.
|
||||
* @param PowerMode this can be a combination of following values:
|
||||
* @arg @ref PWR_FLASHPD_SLEEP
|
||||
* @arg @ref PWR_FLASHPD_STOP
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_PWREx_EnableFlashPowerDown(uint32_t PowerMode)
|
||||
{
|
||||
assert_param(IS_PWR_FLASH_POWERDOWN(PowerMode));
|
||||
|
||||
PWR->CR1 |= PowerMode;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Disable Flash Power Down.
|
||||
* @note This API allows to disable flash power down capabilities in sleep and stop modes.
|
||||
* @param PowerMode this can be a combination of following values:
|
||||
* @arg @ref PWR_FLASHPD_SLEEP
|
||||
* @arg @ref PWR_FLASHPD_STOP
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_PWREx_DisableFlashPowerDown(uint32_t PowerMode)
|
||||
{
|
||||
assert_param(IS_PWR_FLASH_POWERDOWN(PowerMode));
|
||||
|
||||
PWR->CR1 &= ~PowerMode;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Enter Shutdown mode.
|
||||
* @note In Shutdown mode, the PLL, the HSI, the LSI and the HSE oscillators are switched
|
||||
* off. The voltage regulator is disabled and Vcore domain is powered off.
|
||||
* SRAM 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.
|
||||
* HAL_PWREx_EnableGPIOPullUp() and HAL_PWREx_EnableGPIOPullDown()
|
||||
* respectively enable Pull Up and PullDown state.
|
||||
* HAL_PWREx_DisableGPIOPullUp() & 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
|
||||
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_PWREx_EnterSHUTDOWNMode(void)
|
||||
{
|
||||
/* Set Shutdown mode */
|
||||
MODIFY_REG(PWR->CR1, PWR_CR1_LPMS, PWR_LOWPOWERMODE_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 /* __CC_ARM */
|
||||
|
||||
/* Request Wait For Interrupt */
|
||||
__WFI();
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup PWREx_Exported_Functions_Group2 Extended PWR Backup register functions
|
||||
* @brief Extended PWR Backup register functions
|
||||
*
|
||||
@verbatim
|
||||
===============================================================================
|
||||
##### Extended PWR Backup register functions #####
|
||||
===============================================================================
|
||||
[..]
|
||||
This subsection provides functions allowing to
|
||||
(+) Write a data in a specified PWR Backup data register
|
||||
(+) Read a data in a specified PWR Backup data register
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief Write a data in a specified PWR Backup data register.
|
||||
* @param BackupRegister PWR Backup data Register number.
|
||||
* This parameter can be PWR_BKP_DRx where x can be from 0 to PWR_BACKUP_NB
|
||||
* @param Data Data to be written in the specified Backup data register.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_PWREx_BKUPWrite(uint32_t BackupRegister, uint16_t Data)
|
||||
{
|
||||
uint32_t tmp;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_PWR_BKP(BackupRegister));
|
||||
|
||||
tmp = (uint32_t) &(PWR->BKP0R);
|
||||
tmp += (BackupRegister * 4U);
|
||||
|
||||
/* Write the specified register */
|
||||
*(__IO uint32_t *)tmp = (uint16_t)Data;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Reads data from the specified PWR Backup data Register.
|
||||
* @param BackupRegister PWR Backup data Register number.
|
||||
* This parameter can be PWR_BKP_DRx where x can be from 0 to PWR_BACKUP_NB
|
||||
* @retval Read value
|
||||
*/
|
||||
uint32_t HAL_PWREx_BKUPRead(uint32_t BackupRegister)
|
||||
{
|
||||
uint32_t tmp;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_PWR_BKP(BackupRegister));
|
||||
|
||||
tmp = (uint32_t) &(PWR->BKP0R);
|
||||
tmp += (BackupRegister * 4U);
|
||||
|
||||
/* Read the specified register */
|
||||
return (*(__IO uint32_t *)tmp);
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* HAL_PWR_MODULE_ENABLED */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,928 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32c0xx_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
|
||||
*
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2022 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 "stm32c0xx_hal.h"
|
||||
|
||||
/** @addtogroup STM32C0xx_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 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 -----------------------------------------------*/
|
||||
/* 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 @ref HAL_RCCEx_PeriphCLKConfig() is used to
|
||||
select the RTC clock source; as consequence RTC registers and RCC_CSR1 register are
|
||||
set to their reset values.
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Initialize the RCC extended peripherals clocks according to the specified
|
||||
* parameters in the @ref RCC_PeriphCLKInitTypeDef.
|
||||
* @param PeriphClkInit pointer to a @ref 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
|
||||
* @arg @ref RCC_PERIPHCLK_I2C1 I2C1 peripheral clock
|
||||
* @arg @ref RCC_PERIPHCLK_I2S1 I2S1 peripheral clock
|
||||
* @arg @ref RCC_PERIPHCLK_USART1 USART1 peripheral clock
|
||||
* @arg @ref RCC_PERIPHCLK_USB USB peripheral clock (*)
|
||||
* @arg @ref RCC_PERIPHCLK_FDCAN1 FDCAN1 peripheral clock (*)
|
||||
* @note Care must be taken when @ref HAL_RCCEx_PeriphCLKConfig() is used to select
|
||||
* the RTC clock source: in this case the access to RTC domain is enabled.
|
||||
* @note (*) not available on all devices
|
||||
*
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(const RCC_PeriphCLKInitTypeDef *PeriphClkInit)
|
||||
{
|
||||
uint32_t tmpregister;
|
||||
uint32_t tickstart;
|
||||
HAL_StatusTypeDef ret = HAL_OK; /* Intermediate status */
|
||||
HAL_StatusTypeDef status = HAL_OK; /* Final status */
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_RCC_PERIPHCLOCK(PeriphClkInit->PeriphClockSelection));
|
||||
|
||||
/*-------------------------- 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())
|
||||
{
|
||||
__HAL_RCC_PWR_CLK_ENABLE();
|
||||
pwrclkchanged = SET;
|
||||
}
|
||||
|
||||
|
||||
/* Reset the RTC domain only if the RTC Clock source selection is modified from default */
|
||||
tmpregister = READ_BIT(RCC->CSR1, RCC_CSR1_RTCSEL);
|
||||
|
||||
/* Reset the RTC domain only if the RTC Clock source selection is modified */
|
||||
if ((tmpregister != RCC_RTCCLKSOURCE_NONE) && (tmpregister != PeriphClkInit->RTCClockSelection))
|
||||
{
|
||||
/* Store the content of CSR1 register before the reset of RTC Domain */
|
||||
tmpregister = READ_BIT(RCC->CSR1, ~(RCC_CSR1_RTCSEL));
|
||||
/* RTC Clock selection can be changed only if the RTC Domain is reset */
|
||||
__HAL_RCC_BACKUPRESET_FORCE();
|
||||
__HAL_RCC_BACKUPRESET_RELEASE();
|
||||
/* Restore the Content of CSR1 register */
|
||||
RCC->CSR1 = tmpregister;
|
||||
}
|
||||
|
||||
/* Wait for LSE reactivation if LSE was enable prior to RTC Domain reset */
|
||||
if (HAL_IS_BIT_SET(tmpregister, RCC_CSR1_LSEON))
|
||||
{
|
||||
/* Get Start Tick*/
|
||||
tickstart = HAL_GetTick();
|
||||
|
||||
/* Wait till LSE is ready */
|
||||
while (READ_BIT(RCC->CSR1, RCC_CSR1_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;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
/*-------------------------- 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);
|
||||
}
|
||||
|
||||
/*-------------------------- ADC clock source configuration ----------------------*/
|
||||
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 (USB_DRD_FS)
|
||||
/*-------------------------- USB clock source configuration ----------------*/
|
||||
if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USB) == RCC_PERIPHCLK_USB)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_RCC_USBCLKSOURCE(PeriphClkInit->UsbClockSelection));
|
||||
|
||||
/* Configure the USB clock source */
|
||||
__HAL_RCC_USB_CONFIG(PeriphClkInit->UsbClockSelection);
|
||||
|
||||
}
|
||||
#endif /* USB_DRD_FS */
|
||||
#if defined (FDCAN1)
|
||||
/*-------------------------- FDCAN1 clock source configuration ----------------*/
|
||||
if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_FDCAN1) == RCC_PERIPHCLK_FDCAN1)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_RCC_FDCAN1CLKSOURCE(PeriphClkInit->Fdcan1ClockSelection));
|
||||
|
||||
/* Configure the FDCAN1 clock source */
|
||||
__HAL_RCC_FDCAN1_CONFIG(PeriphClkInit->Fdcan1ClockSelection);
|
||||
|
||||
}
|
||||
#endif /* FDCAN1 */
|
||||
/*-------------------------- I2S1 clock source configuration ---------------------*/
|
||||
if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S1) == RCC_PERIPHCLK_I2S1)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_RCC_I2S1CLKSOURCE(PeriphClkInit->I2s1ClockSelection));
|
||||
|
||||
/* Configure the I2S1 clock source */
|
||||
__HAL_RCC_I2S1_CONFIG(PeriphClkInit->I2s1ClockSelection);
|
||||
}
|
||||
/*------------------------------------ HSI Kernel clock source configuration --------------------------------------*/
|
||||
if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_HSIKER) == RCC_PERIPHCLK_HSIKER)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_RCC_HSIKERDIV(PeriphClkInit->HSIKerClockDivider));
|
||||
|
||||
/* Configure the HSI Kernel clock source Divider */
|
||||
__HAL_RCC_HSIKER_CONFIG(PeriphClkInit->HSIKerClockDivider);
|
||||
}
|
||||
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: I2C1, I2S1, USART1, RTC, ADC,
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)
|
||||
{
|
||||
/* Set all possible values for the extended clock type parameter------------*/
|
||||
PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_USART1 | RCC_PERIPHCLK_I2C1 | RCC_PERIPHCLK_I2S1 | \
|
||||
RCC_PERIPHCLK_ADC | RCC_PERIPHCLK_RTC | RCC_PERIPHCLK_HSIKER ;
|
||||
|
||||
#if defined(USB_DRD_FS)
|
||||
PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_USB;
|
||||
#endif /* USB_DRD_FS */
|
||||
#if defined(FDCAN1)
|
||||
PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_FDCAN1;
|
||||
#endif /* FDCAN1 */
|
||||
/* Get the USART1 clock source ---------------------------------------------*/
|
||||
PeriphClkInit->Usart1ClockSelection = __HAL_RCC_GET_USART1_SOURCE();
|
||||
|
||||
/* Get the I2C1 clock source -----------------------------------------------*/
|
||||
PeriphClkInit->I2c1ClockSelection = __HAL_RCC_GET_I2C1_SOURCE();
|
||||
|
||||
/* Get the RTC clock source ------------------------------------------------*/
|
||||
PeriphClkInit->RTCClockSelection = __HAL_RCC_GET_RTC_SOURCE();
|
||||
|
||||
/* Get the ADC clock source -----------------------------------------------*/
|
||||
PeriphClkInit->AdcClockSelection = __HAL_RCC_GET_ADC_SOURCE();
|
||||
|
||||
#if defined (USB_DRD_FS)
|
||||
/* Get the USB clock source -------------------------------------------------*/
|
||||
PeriphClkInit->UsbClockSelection = __HAL_RCC_GET_USB_SOURCE();
|
||||
#endif /* USB_DRD_FS */
|
||||
|
||||
#if defined (FDCAN1)
|
||||
/* Get the FDCAN1 clock source -------------------------------------------------*/
|
||||
PeriphClkInit->Fdcan1ClockSelection = __HAL_RCC_GET_FDCAN1_SOURCE();
|
||||
#endif /* FDCAN1 */
|
||||
|
||||
/* Get the I2S1 clock source -----------------------------------------------*/
|
||||
PeriphClkInit->I2s1ClockSelection = __HAL_RCC_GET_I2S1_SOURCE();
|
||||
|
||||
/* Get the HSI Kernel clock divider -----------------------------------------------*/
|
||||
PeriphClkInit->HSIKerClockDivider = __HAL_RCC_GET_HSIKER_DIVIDER();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the peripheral clock frequency for peripherals
|
||||
* @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
|
||||
* @arg @ref RCC_PERIPHCLK_I2C1 I2C1 peripheral clock
|
||||
* @arg @ref RCC_PERIPHCLK_I2S1 I2S1 peripheral clock
|
||||
* @arg @ref RCC_PERIPHCLK_USART1 USART1 peripheral clock
|
||||
* @arg @ref RCC_PERIPHCLK_USB USB peripheral clock (*)
|
||||
* @arg @ref RCC_PERIPHCLK_FDCAN1 FDCAN1 peripheral clock (*)
|
||||
* @note (*) not available on all devices
|
||||
* @retval Frequency in Hz
|
||||
*/
|
||||
uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk)
|
||||
{
|
||||
uint32_t frequency = 0U;
|
||||
uint32_t srcclk;
|
||||
|
||||
/* 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();
|
||||
|
||||
/* Check if LSE is ready and if RTC clock selection is LSE */
|
||||
if ((HAL_IS_BIT_SET(RCC->CSR1, RCC_CSR1_LSERDY)) && (srcclk == RCC_RTCCLKSOURCE_LSE))
|
||||
{
|
||||
frequency = LSE_VALUE;
|
||||
}
|
||||
/* Check if LSI is ready and if RTC clock selection is LSI */
|
||||
else if ((HAL_IS_BIT_SET(RCC->CSR2, RCC_CSR2_LSIRDY)) && (srcclk == RCC_RTCCLKSOURCE_LSI))
|
||||
{
|
||||
frequency = LSI_VALUE;
|
||||
}
|
||||
/* Check if HSE is ready and if RTC clock selection is HSI_DIV32*/
|
||||
else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSERDY)) && (srcclk == RCC_RTCCLKSOURCE_HSE_DIV32))
|
||||
{
|
||||
frequency = HSE_VALUE / 32U;
|
||||
}
|
||||
/* Clock not enabled for RTC*/
|
||||
else
|
||||
{
|
||||
/* Nothing to do as frequency already initialized to 0U */
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Other external peripheral clock source than RTC */
|
||||
|
||||
switch (PeriphClk)
|
||||
{
|
||||
|
||||
case RCC_PERIPHCLK_USART1:
|
||||
/* Get the current USART1 source */
|
||||
srcclk = __HAL_RCC_GET_USART1_SOURCE();
|
||||
|
||||
if (srcclk == RCC_USART1CLKSOURCE_PCLK1) /* PCLK1 */
|
||||
{
|
||||
frequency = HAL_RCC_GetPCLK1Freq();
|
||||
}
|
||||
else if (srcclk == RCC_USART1CLKSOURCE_SYSCLK) /* SYSCLK */
|
||||
{
|
||||
frequency = HAL_RCC_GetSysClockFreq();
|
||||
}
|
||||
else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY)) && (srcclk == RCC_USART1CLKSOURCE_HSIKER))
|
||||
{
|
||||
frequency = (HSI_VALUE / ((__HAL_RCC_GET_HSIKER_DIVIDER() >> RCC_CR_HSIKERDIV_Pos) + 1U));
|
||||
}
|
||||
else if ((HAL_IS_BIT_SET(RCC->CSR1, RCC_CSR1_LSERDY)) && (srcclk == RCC_USART1CLKSOURCE_LSE))
|
||||
{
|
||||
frequency = LSE_VALUE;
|
||||
}
|
||||
/* Clock not enabled for USART1 */
|
||||
else
|
||||
{
|
||||
/* Nothing to do as frequency already initialized to 0U */
|
||||
}
|
||||
break;
|
||||
|
||||
case RCC_PERIPHCLK_ADC:
|
||||
|
||||
srcclk = __HAL_RCC_GET_ADC_SOURCE();
|
||||
|
||||
if (srcclk == RCC_ADCCLKSOURCE_SYSCLK)
|
||||
{
|
||||
frequency = HAL_RCC_GetSysClockFreq();
|
||||
}
|
||||
else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY)) && (srcclk == RCC_ADCCLKSOURCE_HSIKER))
|
||||
{
|
||||
frequency = (HSI_VALUE / ((__HAL_RCC_GET_HSIKER_DIVIDER() >> RCC_CR_HSIKERDIV_Pos) + 1U));
|
||||
}
|
||||
/* Clock not enabled for ADC */
|
||||
else
|
||||
{
|
||||
/* Nothing to do as frequency already initialized to 0U */
|
||||
}
|
||||
break;
|
||||
|
||||
case RCC_PERIPHCLK_I2C1:
|
||||
/* Get the current I2C1 source */
|
||||
srcclk = __HAL_RCC_GET_I2C1_SOURCE();
|
||||
|
||||
if (srcclk == RCC_I2C1CLKSOURCE_PCLK1)
|
||||
{
|
||||
frequency = HAL_RCC_GetPCLK1Freq();
|
||||
}
|
||||
else if (srcclk == RCC_I2C1CLKSOURCE_SYSCLK)
|
||||
{
|
||||
frequency = HAL_RCC_GetSysClockFreq();
|
||||
}
|
||||
else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY)) && (srcclk == RCC_I2C1CLKSOURCE_HSIKER))
|
||||
{
|
||||
frequency = (HSI_VALUE / ((__HAL_RCC_GET_HSIKER_DIVIDER() >> RCC_CR_HSIKERDIV_Pos) + 1U));
|
||||
}
|
||||
/* Clock not enabled for I2C1 */
|
||||
else
|
||||
{
|
||||
/* Nothing to do as frequency already initialized to 0U */
|
||||
}
|
||||
break;
|
||||
|
||||
case RCC_PERIPHCLK_I2S1:
|
||||
/* Get the current I2S1 source */
|
||||
srcclk = __HAL_RCC_GET_I2S1_SOURCE();
|
||||
|
||||
if (srcclk == RCC_I2S1CLKSOURCE_SYSCLK)
|
||||
{
|
||||
frequency = HAL_RCC_GetSysClockFreq();
|
||||
}
|
||||
else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY)) && (srcclk == RCC_I2S1CLKSOURCE_HSIKER))
|
||||
{
|
||||
frequency = (HSI_VALUE / ((__HAL_RCC_GET_HSIKER_DIVIDER() >> RCC_CR_HSIKERDIV_Pos) + 1U));
|
||||
}
|
||||
else if (srcclk == RCC_I2S1CLKSOURCE_EXT)
|
||||
{
|
||||
/* External clock used.*/
|
||||
frequency = EXTERNAL_I2S1_CLOCK_VALUE;
|
||||
}
|
||||
/* Clock not enabled for I2S1 */
|
||||
else
|
||||
{
|
||||
/* Nothing to do as frequency already initialized to 0U */
|
||||
}
|
||||
break;
|
||||
#if defined(FDCAN1)
|
||||
case RCC_PERIPHCLK_FDCAN1:
|
||||
/* Get the current FDCAN1 source */
|
||||
srcclk = __HAL_RCC_GET_FDCAN1_SOURCE();
|
||||
|
||||
if (srcclk == RCC_FDCAN1CLKSOURCE_PCLK1)
|
||||
{
|
||||
frequency = HAL_RCC_GetPCLK1Freq();
|
||||
}
|
||||
else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY)) && (srcclk == RCC_FDCAN1CLKSOURCE_HSIKER))
|
||||
{
|
||||
frequency = (HSI_VALUE / ((__HAL_RCC_GET_HSIKER_DIVIDER() >> RCC_CR_HSIKERDIV_Pos) + 1U));
|
||||
}
|
||||
else if (srcclk == RCC_FDCAN1CLKSOURCE_HSE)
|
||||
{
|
||||
/* External clock used.*/
|
||||
frequency = HSE_VALUE;
|
||||
}
|
||||
/* Clock not enabled for FDCAN1 */
|
||||
else
|
||||
{
|
||||
/* Nothing to do as frequency already initialized to 0U */
|
||||
}
|
||||
break;
|
||||
#endif /* FDCAN1 */
|
||||
#if defined (USB_DRD_FS)
|
||||
case RCC_PERIPHCLK_USB:
|
||||
/* Get the current USB source */
|
||||
srcclk = __HAL_RCC_GET_USB_SOURCE();
|
||||
if (srcclk == RCC_USBCLKSOURCE_HSI48)
|
||||
{
|
||||
frequency = HSI48_VALUE;
|
||||
}
|
||||
else if (srcclk == RCC_USBCLKSOURCE_HSE)
|
||||
{
|
||||
frequency = HSE_VALUE;
|
||||
}
|
||||
/* Clock not enabled for USB */
|
||||
else
|
||||
{
|
||||
/* Nothing to do as frequency already initialized to 0U */
|
||||
}
|
||||
#endif /* USB_DRD_FS */
|
||||
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 LSE CSS, Low speed clock output and
|
||||
clock after wake-up from STOP mode.
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @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;
|
||||
|
||||
/* 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_VERY_HIGH;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
HAL_GPIO_Init(LSCO_GPIO_PORT, &GPIO_InitStruct);
|
||||
|
||||
MODIFY_REG(RCC->CSR1, RCC_CSR1_LSCOSEL | RCC_CSR1_LSCOEN, LSCOSource | RCC_CSR1_LSCOEN);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable the Low Speed clock output.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_RCCEx_DisableLSCO(void)
|
||||
{
|
||||
|
||||
CLEAR_BIT(RCC->CSR1, RCC_CSR1_LSCOEN);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#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 synchronization 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 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 */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* HAL_RCC_MODULE_ENABLED */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user