first commit

This commit is contained in:
chauyin
2025-05-06 21:46:55 +08:00
commit 2018adcf78
119 changed files with 168311 additions and 0 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,872 @@
/**
******************************************************************************
* @file stm32h5xx_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) 2023 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-M33 exceptions are managed by CMSIS functions.
(#) Configure the NVIC Priority Grouping using HAL_NVIC_SetPriorityGrouping() function.
(#) Configure the priority of the selected IRQ Channels using HAL_NVIC_SetPriority().
(#) Enable the selected IRQ Channels using HAL_NVIC_EnableIRQ().
-@- When the NVIC_PRIORITYGROUP_0 is selected, IRQ pre-emption is no more possible.
The pending IRQ priority will be managed only by the sub priority.
-@- IRQ priority order (sorted by highest to lowest priority):
(+@) Lowest pre-emption priority
(+@) Lowest sub priority
(+@) Lowest hardware priority (IRQ number)
[..]
*** How to configure SysTick using CORTEX HAL driver ***
========================================================
[..]
Setup SysTick Timer for time base.
(+) The HAL_SYSTICK_Config() function calls the SysTick_Config() function which
is a CMSIS function that:
(++) Configures the SysTick Reload register with value passed as function parameter.
(++) Configures the SysTick IRQ priority to the lowest value (0x0F).
(++) Resets the SysTick Counter register.
(++) Configures the SysTick Counter clock source to be Core Clock Source (HCLK).
(++) Enables the SysTick Interrupt.
(++) Starts the SysTick Counter.
(+) You can change the SysTick Clock source to be HCLK_Div8 by calling the macro
__HAL_CORTEX_SYSTICKCLK_CONFIG(SYSTICK_CLKSOURCE_HCLK_DIV8) just after the
HAL_SYSTICK_Config() function call. The __HAL_CORTEX_SYSTICKCLK_CONFIG() macro is defined
inside the stm32h5xx_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
[..]
*** How to configure MPU regions using CORTEX HAL driver ***
============================================================
[..]
This section provides functions allowing to configure the Memory Protection Unit (MPU).
(#) Disable the MPU using HAL_MPU_Disable().
(#) Configure the necessary MPU memory attributes using HAL_MPU_ConfigMemoryAttributes().
(#) Configure the necessary MPU regions using HAL_MPU_ConfigRegion() ennsuring that the MPU region configuration link to
the right MPU attributes number.
(#) Enable the MPU using HAL_MPU_Enable() function.
-@- The memory management fault exception is enabled in HAL_MPU_Enable() function and the system will enter the memory
management fault handler MemManage_Handler() when an illegal memory access is performed.
-@- If the MPU has previously been programmed, disable the unused regions to prevent any previous region configuration
from affecting the new MPU configuration.
-@- MPU APIs ending with '_NS' allow to control the non-secure Memory Protection Unit (MPU_NS) from the secure context
@endverbatim
******************************************************************************
The table below gives the allowed values of the pre-emption priority and subpriority according
to the Priority Grouping configuration performed by HAL_NVIC_SetPriorityGrouping() function.
========================================================================================================================
NVIC_PriorityGroup | NVIC_IRQChannelPreemptionPriority | NVIC_IRQChannelSubPriority | Description
========================================================================================================================
NVIC_PRIORITYGROUP_0 | 0 | 0-15 | 0 bit for pre-emption priority
| | | 4 bits for subpriority
------------------------------------------------------------------------------------------------------------------------
NVIC_PRIORITYGROUP_1 | 0-1 | 0-7 | 1 bit for pre-emption priority
| | | 3 bits for subpriority
------------------------------------------------------------------------------------------------------------------------
NVIC_PRIORITYGROUP_2 | 0-3 | 0-3 | 2 bits for pre-emption priority
| | | 2 bits for subpriority
------------------------------------------------------------------------------------------------------------------------
NVIC_PRIORITYGROUP_3 | 0-7 | 0-1 | 3 bits for pre-emption priority
| | | 1 bit for subpriority
------------------------------------------------------------------------------------------------------------------------
NVIC_PRIORITYGROUP_4 | 0-15 | 0 | 4 bits for pre-emption priority
| | | 0 bit for subpriority
========================================================================================================================
*/
/* Includes ------------------------------------------------------------------*/
#include "stm32h5xx_hal.h"
/** @addtogroup STM32H5xx_HAL_Driver
* @{
*/
/** @addtogroup CORTEX
* @{
*/
#ifdef HAL_CORTEX_MODULE_ENABLED
/* Private types -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private constants ---------------------------------------------------------*/
/* Private macros ------------------------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/** @defgroup CORTEX_Private_Functions CORTEX Private Functions
* @{
*/
static void MPU_ConfigRegion(MPU_Type *MPUx, const MPU_Region_InitTypeDef *const pMPU_RegionInit);
static void MPU_ConfigMemoryAttributes(MPU_Type *MPUx, const MPU_Attributes_InitTypeDef *const pMPU_AttributesInit);
/**
* @}
*/
/* Exported functions --------------------------------------------------------*/
/** @addtogroup CORTEX_Exported_Functions
* @{
*/
/** @addtogroup CORTEX_Exported_Functions_Group1
* @brief NVIC functions
*
@verbatim
==============================================================================
##### NVIC functions #####
==============================================================================
[..]
This section provides the CORTEX HAL driver functions for NVIC functionalities
@endverbatim
* @{
*/
/**
* @brief Set the priority grouping field (pre-emption priority and subpriority)
* using the required unlock sequence.
* @param PriorityGroup: The priority grouping bits length.
* This parameter can be one of the following values:
* @arg NVIC_PRIORITYGROUP_0: 0 bit for pre-emption priority,
* 4 bits for subpriority
* @arg NVIC_PRIORITYGROUP_1: 1 bit for pre-emption priority,
* 3 bits for subpriority
* @arg NVIC_PRIORITYGROUP_2: 2 bits for pre-emption priority,
* 2 bits for subpriority
* @arg NVIC_PRIORITYGROUP_3: 3 bits for pre-emption priority,
* 1 bit for subpriority
* @arg NVIC_PRIORITYGROUP_4: 4 bits for pre-emption priority,
* 0 bit for subpriority
* @note When the NVIC_PRIORITYGROUP_0 is selected, IRQ pre-emption is no more possible.
* The pending IRQ priority will be managed only by the subpriority.
* @retval None
*/
void HAL_NVIC_SetPriorityGrouping(uint32_t PriorityGroup)
{
/* Check the parameters */
assert_param(IS_NVIC_PRIORITY_GROUP(PriorityGroup));
/* Set the PRIGROUP[10:8] bits according to the PriorityGroup parameter value */
NVIC_SetPriorityGrouping(PriorityGroup);
}
/**
* @brief Set the priority of an interrupt.
* @param IRQn: External interrupt number.
* This parameter can be an enumerator of IRQn_Type enumeration
* (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate
* CMSIS device file (stm32h5xxxx.h))
* @param PreemptPriority: The pre-emption priority for the IRQn channel.
* This parameter can be a value between 0 and 15
* A lower priority value indicates a higher priority
* @param SubPriority: the subpriority level for the IRQ channel.
* This parameter can be a value between 0 and 15
* A lower priority value indicates a higher priority.
* @retval None
*/
void HAL_NVIC_SetPriority(IRQn_Type IRQn, uint32_t PreemptPriority, uint32_t SubPriority)
{
uint32_t prioritygroup;
/* Check the parameters */
assert_param(IS_NVIC_SUB_PRIORITY(SubPriority));
assert_param(IS_NVIC_PREEMPTION_PRIORITY(PreemptPriority));
prioritygroup = NVIC_GetPriorityGrouping();
NVIC_SetPriority(IRQn, NVIC_EncodePriority(prioritygroup, PreemptPriority, SubPriority));
}
/**
* @brief Enable a device specific interrupt in the NVIC interrupt controller.
* @note To configure interrupts priority correctly, the NVIC_PriorityGroupConfig()
* function should be called before.
* @param IRQn External interrupt number.
* This parameter can be an enumerator of IRQn_Type enumeration
* (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate
* CMSIS device file (stm32h5xxxx.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 (stm32h5xxxx.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 Get the priority grouping field from the NVIC Interrupt Controller.
* @retval Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field)
*/
uint32_t HAL_NVIC_GetPriorityGrouping(void)
{
/* Get the PRIGROUP[10:8] field value */
return NVIC_GetPriorityGrouping();
}
/**
* @brief Get the priority of an interrupt.
* @param IRQn: External interrupt number.
* This parameter can be an enumerator of IRQn_Type enumeration
* (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate
* CMSIS device file (stm32h5xxxx.h))
* @param PriorityGroup: the priority grouping bits length.
* This parameter can be one of the following values:
* @arg NVIC_PRIORITYGROUP_0: 0 bit for pre-emption priority,
* 4 bits for subpriority
* @arg NVIC_PRIORITYGROUP_1: 1 bit for pre-emption priority,
* 3 bits for subpriority
* @arg NVIC_PRIORITYGROUP_2: 2 bits for pre-emption priority,
* 2 bits for subpriority
* @arg NVIC_PRIORITYGROUP_3: 3 bits for pre-emption priority,
* 1 bit for subpriority
* @arg NVIC_PRIORITYGROUP_4: 4 bits for pre-emption priority,
* 0 bit for subpriority
* @param pPreemptPriority: Pointer on the Preemptive priority value (starting from 0).
* @param pSubPriority: Pointer on the Subpriority value (starting from 0).
* @retval None
*/
void HAL_NVIC_GetPriority(IRQn_Type IRQn, uint32_t PriorityGroup, uint32_t *const pPreemptPriority,
uint32_t *const pSubPriority)
{
/* Check the parameters */
assert_param(IS_NVIC_PRIORITY_GROUP(PriorityGroup));
/* Get priority for Cortex-M system or device specific interrupts */
NVIC_DecodePriority(NVIC_GetPriority(IRQn), PriorityGroup, pPreemptPriority, pSubPriority);
}
/**
* @brief Set Pending bit of an external interrupt.
* @param IRQn External interrupt number
* This parameter can be an enumerator of IRQn_Type enumeration
* (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate
* CMSIS device file (stm32h5xxxx.h))
* @retval None
*/
void HAL_NVIC_SetPendingIRQ(IRQn_Type 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 (stm32h5xxxx.h))
* @retval status: - 0 Interrupt status is not pending.
* - 1 Interrupt status is pending.
*/
uint32_t HAL_NVIC_GetPendingIRQ(IRQn_Type IRQn)
{
/* Return 1 if pending else 0 */
return NVIC_GetPendingIRQ(IRQn);
}
/**
* @brief 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 (stm32h5xxxx.h))
* @retval None
*/
void HAL_NVIC_ClearPendingIRQ(IRQn_Type IRQn)
{
/* Clear pending interrupt */
NVIC_ClearPendingIRQ(IRQn);
}
/**
* @brief Get active interrupt (read the active register in NVIC and return the active bit).
* @param IRQn External interrupt number
* This parameter can be an enumerator of IRQn_Type enumeration
* (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate
* CMSIS device file (stm32h5xxxx.h))
* @retval status: - 0 Interrupt status is not pending.
* - 1 Interrupt status is pending.
*/
uint32_t HAL_NVIC_GetActive(IRQn_Type IRQn)
{
/* Return 1 if active else 0 */
return NVIC_GetActive(IRQn);
}
/**
* @}
*/
/** @addtogroup CORTEX_Exported_Functions_Group2
* @brief SYSTICK functions
*
@verbatim
==============================================================================
##### SYSTICK functions #####
==============================================================================
[..]
This section provides the CORTEX HAL driver functions for SYSTICK functionalities
@endverbatim
* @{
*/
/**
* @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)
{
if ((TicksNumb - 1UL) > SysTick_LOAD_RELOAD_Msk)
{
/* Reload value impossible */
return (1UL);
}
/* Set reload register */
WRITE_REG(SysTick->LOAD, (uint32_t)(TicksNumb - 1UL));
/* Load the SysTick Counter Value */
WRITE_REG(SysTick->VAL, 0UL);
/* Enable SysTick IRQ and SysTick Timer */
SET_BIT(SysTick->CTRL, (SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk));
/* Function successful */
return (0UL);
}
/**
* @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_LSI: LSI clock selected as SysTick clock source.
* @arg SYSTICK_CLKSOURCE_LSE: LSE clock selected as SysTick clock source.
* @arg SYSTICK_CLKSOURCE_HCLK: AHB clock selected as SysTick clock source.
* @arg SYSTICK_CLKSOURCE_HCLK_DIV8: AHB clock divided by 8 selected as SysTick clock source.
* @retval None
*/
void HAL_SYSTICK_CLKSourceConfig(uint32_t CLKSource)
{
/* Check the parameters */
assert_param(IS_SYSTICK_CLK_SOURCE(CLKSource));
switch (CLKSource)
{
/* Select HCLK as Systick clock source */
case SYSTICK_CLKSOURCE_HCLK:
SET_BIT(SysTick->CTRL, SYSTICK_CLKSOURCE_HCLK);
break;
/* Select HCLK_DIV8 as Systick clock source */
case SYSTICK_CLKSOURCE_HCLK_DIV8:
CLEAR_BIT(SysTick->CTRL, SYSTICK_CLKSOURCE_HCLK);
MODIFY_REG(RCC->CCIPR4, RCC_CCIPR4_SYSTICKSEL, (0x00000000U));
break;
/* Select LSI as Systick clock source */
case SYSTICK_CLKSOURCE_LSI:
CLEAR_BIT(SysTick->CTRL, SYSTICK_CLKSOURCE_HCLK);
MODIFY_REG(RCC->CCIPR4, RCC_CCIPR4_SYSTICKSEL, RCC_CCIPR4_SYSTICKSEL_0);
break;
/* Select LSE as Systick clock source */
case SYSTICK_CLKSOURCE_LSE:
CLEAR_BIT(SysTick->CTRL, SYSTICK_CLKSOURCE_HCLK);
MODIFY_REG(RCC->CCIPR4, RCC_CCIPR4_SYSTICKSEL, RCC_CCIPR4_SYSTICKSEL_1);
break;
default:
/* Nothing to do */
break;
}
}
/**
* @brief Get the SysTick clock source configuration.
* @retval SysTick clock source that can be one of the following values:
* @arg SYSTICK_CLKSOURCE_LSI: LSI clock selected as SysTick clock source.
* @arg SYSTICK_CLKSOURCE_LSE: LSE clock selected as SysTick clock source.
* @arg SYSTICK_CLKSOURCE_HCLK: AHB clock selected as SysTick clock source.
* @arg SYSTICK_CLKSOURCE_HCLK_DIV8: AHB clock divided by 8 selected as SysTick clock source.
*/
uint32_t HAL_SYSTICK_GetCLKSourceConfig(void)
{
uint32_t systick_source;
uint32_t systick_rcc_source;
/* Read SysTick->CTRL register for internal or external clock source */
if (READ_BIT(SysTick->CTRL, SysTick_CTRL_CLKSOURCE_Msk) != 0U)
{
/* Internal clock source */
systick_source = SYSTICK_CLKSOURCE_HCLK;
}
else
{
/* External clock source, check the selected one in RCC */
systick_rcc_source = READ_BIT(RCC->CCIPR4, RCC_CCIPR4_SYSTICKSEL);
switch (systick_rcc_source)
{
case (0x00000000U):
systick_source = SYSTICK_CLKSOURCE_HCLK_DIV8;
break;
case (RCC_CCIPR4_SYSTICKSEL_0):
systick_source = SYSTICK_CLKSOURCE_LSI;
break;
case (RCC_CCIPR4_SYSTICKSEL_1):
systick_source = SYSTICK_CLKSOURCE_LSE;
break;
default:
systick_source = SYSTICK_CLKSOURCE_HCLK_DIV8;
break;
}
}
return systick_source;
}
/**
* @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
*/
}
/**
* @}
*/
/** @addtogroup CORTEX_Exported_Functions_Group3
* @brief MPU functions
*
@verbatim
==============================================================================
##### MPU functions #####
==============================================================================
[..]
This section provides the CORTEX HAL driver functions for MPU functionalities
@endverbatim
* @{
*/
/**
* @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)
{
__DMB(); /* Data Memory Barrier operation to force any outstanding writes to memory before enabling the MPU */
/* Enable the MPU */
MPU->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk;
/* Enable fault exceptions */
SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk;
/* Follow ARM recommendation with */
/* Data Synchronization and Instruction Synchronization Barriers to ensure MPU configuration */
__DSB(); /* Ensure that the subsequent instruction is executed only after the write to memory */
__ISB(); /* Flush and refill pipeline with updated MPU configuration settings */
}
#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
/**
* @brief Enable the non-secure 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_NS(uint32_t MPU_Control)
{
__DMB(); /* Data Memory Barrier operation to force any outstanding writes to memory before enabling the MPU */
/* Enable the MPU */
MPU_NS->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk;
/* Enable fault exceptions */
SCB_NS->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk;
/* Follow ARM recommendation with */
/* Data Synchronization and Instruction Synchronization Barriers to ensure MPU configuration */
__DSB(); /* Ensure that the subsequent instruction is executed only after the write to memory */
__ISB(); /* Flush and refill pipeline with updated MPU configuration settings */
}
#endif /* __ARM_FEATURE_CMSE */
/**
* @brief Disable the MPU.
* @retval None
*/
void HAL_MPU_Disable(void)
{
__DMB(); /* Force any outstanding transfers to complete before disabling MPU */
/* Disable fault exceptions */
SCB->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk;
/* Disable the MPU */
MPU->CTRL &= ~MPU_CTRL_ENABLE_Msk;
/* Follow ARM recommendation with */
/* Data Synchronization and Instruction Synchronization Barriers to ensure MPU configuration */
__DSB(); /* Ensure that the subsequent instruction is executed only after the write to memory */
__ISB(); /* Flush and refill pipeline with updated MPU configuration settings */
}
#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
/**
* @brief Disable the non-secure MPU.
* @retval None
*/
void HAL_MPU_Disable_NS(void)
{
__DMB(); /* Force any outstanding transfers to complete before disabling MPU */
/* Disable fault exceptions */
SCB_NS->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk;
/* Disable the MPU */
MPU_NS->CTRL &= ~MPU_CTRL_ENABLE_Msk;
/* Follow ARM recommendation with */
/* Data Synchronization and Instruction Synchronization Barriers to ensure MPU configuration */
__DSB(); /* Ensure that the subsequent instruction is executed only after the write to memory */
__ISB(); /* Flush and refill pipeline with updated MPU configuration settings */
}
#endif /* __ARM_FEATURE_CMSE */
/**
* @brief Enable the MPU Region.
* @param RegionNumber Specifies the index of the region to enable.
* this parameter can be a value of @ref CORTEX_MPU_Region_Number
* @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->RLAR, MPU_RLAR_EN_Msk);
}
#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
/**
* @brief Enable the MPU_NS Region.
* @param RegionNumber Specifies the index of the region to enable.
* this parameter can be a value of @ref CORTEX_MPU_Region_Number
* @retval None
*/
void HAL_MPU_EnableRegion_NS(uint32_t RegionNumber)
{
/* Check the parameters */
assert_param(IS_MPU_REGION_NUMBER_NS(RegionNumber));
/* Set the Region number */
MPU_NS->RNR = RegionNumber;
/* Enable the Region */
SET_BIT(MPU_NS->RLAR, MPU_RLAR_EN_Msk);
}
#endif /* __ARM_FEATURE_CMSE */
/**
* @brief Disable the MPU Region.
* @param RegionNumber Specifies the index of the region to disable.
* this parameter can be a value of @ref CORTEX_MPU_Region_Number
* @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->RLAR, MPU_RLAR_EN_Msk);
}
#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
/**
* @brief Disable the MPU_NS Region.
* @param RegionNumber Specifies the index of the region to disable.
* this parameter can be a value of @ref CORTEX_MPU_Region_Number
* @retval None
*/
void HAL_MPU_DisableRegion_NS(uint32_t RegionNumber)
{
/* Check the parameters */
assert_param(IS_MPU_REGION_NUMBER_NS(RegionNumber));
/* Set the Region number */
MPU_NS->RNR = RegionNumber;
/* Disable the Region */
CLEAR_BIT(MPU_NS->RLAR, MPU_RLAR_EN_Msk);
}
#endif /* __ARM_FEATURE_CMSE */
/**
* @brief Initialize and configure the Region and the memory to be protected.
* @param pMPU_RegionInit: Pointer to a MPU_Region_InitTypeDef structure that contains
* the initialization and configuration information.
* @retval None
*/
void HAL_MPU_ConfigRegion(const MPU_Region_InitTypeDef *const pMPU_RegionInit)
{
MPU_ConfigRegion(MPU, pMPU_RegionInit);
}
#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
/**
* @brief Initialize and configure the Region and the memory to be protected for non-secure MPU.
* @param pMPU_RegionInit: Pointer to a MPU_Region_InitTypeDef structure that contains
* the initialization and configuration information.
* @retval None
*/
void HAL_MPU_ConfigRegion_NS(const MPU_Region_InitTypeDef *const pMPU_RegionInit)
{
MPU_ConfigRegion(MPU_NS, pMPU_RegionInit);
}
#endif /* __ARM_FEATURE_CMSE */
/**
* @brief Initialize and configure the memory attributes.
* @param pMPU_AttributesInit: Pointer to a MPU_Attributes_InitTypeDef structure that contains
* the initialization and configuration information.
* @retval None
*/
void HAL_MPU_ConfigMemoryAttributes(const MPU_Attributes_InitTypeDef *const pMPU_AttributesInit)
{
MPU_ConfigMemoryAttributes(MPU, pMPU_AttributesInit);
}
#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
/**
* @brief Initialize and configure the memory attributes for non-secure MPU.
* @param pMPU_AttributesInit: Pointer to a MPU_Attributes_InitTypeDef structure that contains
* the initialization and configuration information.
* @retval None
*/
void HAL_MPU_ConfigMemoryAttributes_NS(const MPU_Attributes_InitTypeDef *const pMPU_AttributesInit)
{
MPU_ConfigMemoryAttributes(MPU_NS, pMPU_AttributesInit);
}
#endif /* __ARM_FEATURE_CMSE */
/**
* @}
*/
/**
* @}
*/
/** @addtogroup CORTEX_Private_Functions
* @{
*/
/**
* @brief Initialize and configure the Region and the memory to be protected for MPU.
* @param MPUx: Pointer to MPU_Type structure
* This parameter can be one of the following values:
* @arg MPU
* @arg MPU_NS
* @param pMPU_RegionInit: Pointer to a MPU_Region_InitTypeDef structure that contains
* the initialization and configuration information.
* @retval None
*/
static void MPU_ConfigRegion(MPU_Type *MPUx, const MPU_Region_InitTypeDef *const pMPU_RegionInit)
{
/* Check the parameters */
#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
assert_param(IS_MPU_INSTANCE(MPUx));
#endif /* __ARM_FEATURE_CMSE */
assert_param(IS_MPU_REGION_NUMBER(pMPU_RegionInit->Number));
assert_param(IS_MPU_REGION_ENABLE(pMPU_RegionInit->Enable));
assert_param(IS_MPU_INSTRUCTION_ACCESS(pMPU_RegionInit->DisableExec));
assert_param(IS_MPU_REGION_PERMISSION_ATTRIBUTE(pMPU_RegionInit->AccessPermission));
assert_param(IS_MPU_ACCESS_SHAREABLE(pMPU_RegionInit->IsShareable));
/* Follow ARM recommendation with Data Memory Barrier prior to MPU configuration */
__DMB();
/* Set the Region number */
MPUx->RNR = pMPU_RegionInit->Number;
/* Disable the Region */
CLEAR_BIT(MPUx->RLAR, MPU_RLAR_EN_Msk);
MPUx->RBAR = (((uint32_t)pMPU_RegionInit->BaseAddress & 0xFFFFFFE0UL) |
((uint32_t)pMPU_RegionInit->IsShareable << MPU_RBAR_SH_Pos) |
((uint32_t)pMPU_RegionInit->AccessPermission << MPU_RBAR_AP_Pos) |
((uint32_t)pMPU_RegionInit->DisableExec << MPU_RBAR_XN_Pos));
MPUx->RLAR = (((uint32_t)pMPU_RegionInit->LimitAddress & 0xFFFFFFE0UL) |
((uint32_t)pMPU_RegionInit->AttributesIndex << MPU_RLAR_AttrIndx_Pos) |
((uint32_t)pMPU_RegionInit->Enable << MPU_RLAR_EN_Pos));
}
/**
* @brief Initialize and configure the memory attributes for MPU.
* @param MPUx: Pointer to MPU_Type structure
* This parameter can be one of the following values:
* @arg MPU
* @arg MPU_NS
* @param pMPU_AttributesInit: Pointer to a MPU_Attributes_InitTypeDef structure that contains
* the initialization and configuration information.
* @retval None
*/
static void MPU_ConfigMemoryAttributes(MPU_Type *MPUx, const MPU_Attributes_InitTypeDef *const pMPU_AttributesInit)
{
__IO uint32_t *p_mair;
uint32_t attr_values;
uint32_t attr_number;
/* Check the parameters */
#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
assert_param(IS_MPU_INSTANCE(MPUx));
#endif /* __ARM_FEATURE_CMSE */
assert_param(IS_MPU_ATTRIBUTES_NUMBER(pMPU_AttributesInit->Number));
/* No need to check Attributes value as all 0x0..0xFF possible */
/* Follow ARM recommendation with Data Memory Barrier prior to MPUx configuration */
__DMB();
if (pMPU_AttributesInit->Number < MPU_ATTRIBUTES_NUMBER4)
{
/* Program MPU_MAIR0 */
p_mair = &(MPUx->MAIR0);
attr_number = pMPU_AttributesInit->Number;
}
else
{
/* Program MPU_MAIR1 */
p_mair = &(MPUx->MAIR1);
attr_number = (uint32_t)pMPU_AttributesInit->Number - 4U;
}
attr_values = *(p_mair);
attr_values &= ~(0xFFUL << (attr_number * 8U));
*(p_mair) = attr_values | ((uint32_t)pMPU_AttributesInit->Attributes << (attr_number * 8U));
}
/**
* @}
*/
#endif /* HAL_CORTEX_MODULE_ENABLED */
/**
* @}
*/
/**
* @}
*/

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,874 @@
/**
******************************************************************************
* @file stm32h5xx_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) 2023 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 "stm32h5xx_hal.h"
/** @addtogroup STM32H5xx_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: byte offset between: IMR1/EMR1 and IMR2/EMR2 registers */
#define EXTI_CONFIG_OFFSET 0x08U /* 0x20: byte offset between Rising1/Falling1 and Rising2/Falling2
configuration registers */
#define EXTI_PRIVCFGR_OFFSET 0x08U /* 0x20: byte offset between PRIVCFGR1 and PRIVCFGR2 registers */
#define EXTI_SECCFGR_OFFSET 0x08U /* 0x20: byte offset between SECCFGR1 and SECCFGR2 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;
}
/**
* @}
*/
/** @defgroup EXTI_Exported_Functions_Group3 EXTI line attributes management functions
* @brief EXTI attributes management functions.
*
@verbatim
===============================================================================
##### EXTI attributes functions #####
===============================================================================
@endverbatim
* @{
*/
/**
* @brief Configure the EXTI line attribute(s).
* @note Available attributes are to secure EXTI line and set EXT line as privileged.
* Default state is not secure and unprivileged access allowed.
* @note Secure and non-secure attributes can only be set from the secure
* state when the system implements the security (TZEN=1).
* @note Security and privilege attributes can be set independently.
* @param ExtiLine Exti line number.
* This parameter can be from 0 to @ref EXTI_LINE_NB.
* @param LineAttributes can be one or a combination of the following values:
* @arg @ref EXTI_LINE_PRIV Privileged-only access
* @arg @ref EXTI_LINE_NPRIV Privileged/Non-privileged access
* @arg @ref EXTI_LINE_SEC Secure-only access
* @arg @ref EXTI_LINE_NSEC Secure/Non-secure access
* @retval None
*/
void HAL_EXTI_ConfigLineAttributes(uint32_t ExtiLine, uint32_t LineAttributes)
{
__IO uint32_t *regaddr;
uint32_t regval;
uint32_t linepos;
uint32_t maskline;
uint32_t offset;
/* Check the parameters */
assert_param(IS_EXTI_LINE(ExtiLine));
assert_param(IS_EXTI_LINE_ATTRIBUTES(LineAttributes));
/* compute line register offset and line mask */
offset = ((ExtiLine & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
linepos = (ExtiLine & EXTI_PIN_MASK);
maskline = (1UL << linepos);
/* Configure privilege or non-privilege attributes */
regaddr = (__IO uint32_t *)(&EXTI->PRIVCFGR1 + (EXTI_PRIVCFGR_OFFSET * offset));
regval = *regaddr;
/* Mask or set line */
if ((LineAttributes & EXTI_LINE_PRIV) == EXTI_LINE_PRIV)
{
regval |= maskline;
}
else if ((LineAttributes & EXTI_LINE_NPRIV) == EXTI_LINE_NPRIV)
{
regval &= ~maskline;
}
else
{
/* do nothing */
}
/* Store privilege or non-privilege attribute */
*regaddr = regval;
#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
/* Configure secure or non-secure attributes */
regaddr = (__IO uint32_t *)(&EXTI->SECCFGR1 + (EXTI_SECCFGR_OFFSET * offset));
regval = *regaddr;
/* Mask or set line */
if ((LineAttributes & EXTI_LINE_SEC) == EXTI_LINE_SEC)
{
regval |= maskline;
}
else if ((LineAttributes & EXTI_LINE_NSEC) == EXTI_LINE_NSEC)
{
regval &= ~maskline;
}
else
{
/* do nothing */
}
/* Store secure or non-secure attribute */
*regaddr = regval;
#endif /* __ARM_FEATURE_CMSE */
}
/**
* @brief Get the EXTI line attribute(s).
* @note Secure and non-secure attributes are only available from secure state
* when the system implements the security (TZEN=1)
* @param ExtiLine Exti line number.
* This parameter can be from 0 to @ref EXTI_LINE_NB.
* @param pLineAttributes: pointer to return line attributes.
* @retval HAL Status.
*/
HAL_StatusTypeDef HAL_EXTI_GetConfigLineAttributes(uint32_t ExtiLine, uint32_t *pLineAttributes)
{
const __IO uint32_t *regaddr;
uint32_t linepos;
uint32_t maskline;
uint32_t offset;
uint32_t attributes;
/* Check null pointer */
if (pLineAttributes == NULL)
{
return HAL_ERROR;
}
/* Check the parameters */
assert_param(IS_EXTI_LINE(ExtiLine));
/* Compute line register offset and line mask */
offset = ((ExtiLine & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
linepos = (ExtiLine & EXTI_PIN_MASK);
maskline = (1UL << linepos);
/* Get privilege or non-privilege attribute */
regaddr = (__IO uint32_t *)(&EXTI->PRIVCFGR1 + (EXTI_PRIVCFGR_OFFSET * offset));
if ((*regaddr & maskline) != 0U)
{
attributes = EXTI_LINE_PRIV;
}
else
{
attributes = EXTI_LINE_NPRIV;
}
#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
/* Get secure or non-secure attribute */
regaddr = (__IO uint32_t *)(&EXTI->SECCFGR1 + (EXTI_SECCFGR_OFFSET * offset));
if ((*regaddr & maskline) != 0U)
{
attributes |= EXTI_LINE_SEC;
}
else
{
attributes |= EXTI_LINE_NSEC;
}
#endif /* __ARM_FEATURE_CMSE */
/* return value */
*pLineAttributes = attributes;
return HAL_OK;
}
#if defined (EXTI_LOCKR_LOCK)
#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
/**
* @brief Lock the global EXTI security and privilege configuration.
* @retval HAL Status.
*/
HAL_StatusTypeDef HAL_EXTI_LockConfigAttributes(void)
{
EXTI->LOCKR = EXTI_ATTRIBUTES_LOCKED;
return HAL_OK;
}
/**
* @brief Get the global EXTI security and privilege lock configuration.
* @param pLockState : Pointer to returned security and privilege configuration
* @retval HAL Status.
*/
HAL_StatusTypeDef HAL_EXTI_GetLockConfigAttributes(uint32_t *const pLockState)
{
uint32_t attributes;
const __IO uint32_t *regaddr;
/* Check null pointer */
if (pLockState == NULL)
{
return HAL_ERROR;
}
/* Get security and privilege configuration */
regaddr = (__IO uint32_t *)(&EXTI->LOCKR);
if ((*regaddr & EXTI_LOCKR_LOCK) != 0U)
{
attributes = EXTI_ATTRIBUTES_LOCKED;
}
else
{
attributes = EXTI_ATTRIBUTES_UNLOCKED;
}
/* return value */
*pLockState = attributes;
return HAL_OK;
}
#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */
#endif /* defined (EXTI_LOCKR_LOCK) */
/**
* @}
*/
/**
* @}
*/
#endif /* HAL_EXTI_MODULE_ENABLED */
/**
* @}
*/
/**
* @}
*/

View File

@@ -0,0 +1,964 @@
/**
******************************************************************************
* @file stm32h5xx_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) 2023 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 C-Bus accesses to the Flash memory.
It implements the erase and program Flash memory operations and the read
and write protection mechanisms.
[..] The FLASH main features are:
(+) Flash memory read operations
(+) Flash memory program/erase operations
(+) Read / write protections
(+) Option bytes programming
(+) TrustZone aware
(+) Watermark-based area protection
(+) Block-based sector protection
(+) Error code correction (ECC)
##### How to use this driver #####
==============================================================================
[..]
This driver provides functions and macros to configure and program the FLASH
memory of all STM32H5xx devices.
(#) FLASH Memory IO Programming functions:
(++) Lock and Unlock the FLASH interface using HAL_FLASH_Unlock() and
HAL_FLASH_Lock() functions
(++) Flash memory programming by 128 bits (user area, OBKeys) and 16 bits (OTP and Flash high-cycle
data area)
(++) There Two modes of programming :
(+++) Polling mode using HAL_FLASH_Program() function
(+++) Interrupt mode using HAL_FLASH_Program_IT() function
(#) Interrupts and flags management functions :
(++) Handle FLASH interrupts by calling HAL_FLASH_IRQHandler()
(++) Callback functions are called when the flash operations are finished :
HAL_FLASH_EndOfOperationCallback() when everything is ok, otherwise
HAL_FLASH_OperationErrorCallback()
(++) Get error flag status by calling HAL_FLASH_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 FLASH interrupts
(+) Monitor the FLASH flags status
[..]
(@) The contents of the Flash memory are not guaranteed if a device reset occurs during
a Flash memory operation.
@endverbatim
*/
/* Includes ------------------------------------------------------------------*/
#include "stm32h5xx_hal.h"
/** @addtogroup STM32H5xx_HAL_Driver
* @{
*/
/** @defgroup FLASH FLASH
* @brief FLASH HAL module driver
* @{
*/
#ifdef HAL_FLASH_MODULE_ENABLED
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* 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 = 0U, \
.Address = 0U, \
.Bank = FLASH_BANK_1, \
.Sector = 0U, \
.NbSectorsToErase = 0U
};
/**
* @}
*/
/* Private function prototypes -----------------------------------------------*/
/** @defgroup FLASH_Private_Functions FLASH Private Functions
* @{
*/
static void FLASH_Program_QuadWord(uint32_t FlashAddress, uint32_t DataAddress);
#if defined (FLASH_SR_OBKERR)
static void FLASH_Program_QuadWord_OBK(uint32_t FlashAddress, uint32_t DataAddress);
#endif /* FLASH_SR_OBKERR */
static void FLASH_Program_HalfWord(uint32_t FlashAddress, uint32_t DataAddress);
#if defined(FLASH_EDATAR_EDATA_EN)
static void FLASH_Program_Word(uint32_t FlashAddress, uint32_t DataAddress);
#endif /* FLASH_EDATAR_EDATA_EN */
/**
* @}
*/
/* 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 a quad-word 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 FlashAddress specifies the address to be programmed.
* This parameter shall be aligned to the Flash word (128-bit)
* @param DataAddress specifies the address of data to be programmed
* This parameter shall be 32-bit aligned
* @retval HAL_StatusTypeDef HAL Status
*/
HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t FlashAddress, uint32_t DataAddress)
{
HAL_StatusTypeDef status;
__IO uint32_t *reg_cr;
#if defined (FLASH_SR_OBKERR)
__IO uint32_t *reg_obkcfgr;
#endif /* FLASH_SR_OBKERR */
/* Check the parameters */
assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram));
/* 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)
{
/* Set current operation type */
pFlash.ProcedureOnGoing = TypeProgram;
/* Access to SECCR or NSCR depends on operation type */
#if defined (FLASH_OPTSR2_TZEN)
reg_cr = IS_FLASH_SECURE_OPERATION() ? &(FLASH->SECCR) : &(FLASH_NS->NSCR);
#else
reg_cr = &(FLASH_NS->NSCR);
#endif /* FLASH_OPTSR2_TZEN */
if ((TypeProgram & (~FLASH_NON_SECURE_MASK)) == FLASH_TYPEPROGRAM_QUADWORD)
{
/* Check the parameters */
assert_param(IS_FLASH_USER_MEM_ADDRESS(FlashAddress));
/* Program a quad-word (128-bit) at a specified address */
FLASH_Program_QuadWord(FlashAddress, DataAddress);
}
#if defined (FLASH_SR_OBKERR)
else if ((TypeProgram == FLASH_TYPEPROGRAM_QUADWORD_OBK) || (TypeProgram == FLASH_TYPEPROGRAM_QUADWORD_OBK_ALT))
{
/* Check the parameters */
assert_param(IS_FLASH_OBK_ADDRESS(FlashAddress));
/* Program a quad-word (128-bit) of OBK at a specified address */
FLASH_Program_QuadWord_OBK(FlashAddress, DataAddress);
}
#endif /* FLASH_SR_OBKERR */
#if defined (FLASH_EDATAR_EDATA_EN)
else if ((TypeProgram & (~FLASH_NON_SECURE_MASK)) == FLASH_TYPEPROGRAM_HALFWORD_EDATA)
{
/* Check the parameters */
assert_param(IS_FLASH_EDATA_ADDRESS(FlashAddress));
/* Program a Flash high-cycle data half-word at a specified address */
FLASH_Program_HalfWord(FlashAddress, DataAddress);
}
else if ((TypeProgram & (~FLASH_NON_SECURE_MASK)) == FLASH_TYPEPROGRAM_WORD_EDATA)
{
/* Check the parameters */
assert_param(IS_FLASH_EDATA_ADDRESS(FlashAddress));
/* Program a Flash high-cycle data half-word at a specified address */
FLASH_Program_Word(FlashAddress, DataAddress);
}
#endif /* FLASH_EDATAR_EDATA_EN */
else
{
/* Check the parameters */
assert_param(IS_FLASH_OTP_ADDRESS(FlashAddress));
/* Program an OTP half-word at a specified address */
FLASH_Program_HalfWord(FlashAddress, DataAddress);
}
/* Wait for last operation to be completed */
status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
#if defined (FLASH_SR_OBKERR)
/* If the program operation is completed, disable the PG */
CLEAR_BIT((*reg_cr), (TypeProgram & ~(FLASH_NON_SECURE_MASK | FLASH_OBK | FLASH_OTP | FLASH_OBKCFGR_ALT_SECT)));
/* Clear alternate sector bit */
if (TypeProgram == FLASH_TYPEPROGRAM_QUADWORD_OBK_ALT)
{
reg_obkcfgr = IS_FLASH_SECURE_OPERATION() ? &(FLASH->SECOBKCFGR) : &(FLASH_NS->NSOBKCFGR);
CLEAR_BIT((*reg_obkcfgr), FLASH_OBKCFGR_ALT_SECT);
}
#else
/* If the program operation is completed, disable the PG */
CLEAR_BIT((*reg_cr), (TypeProgram & ~(FLASH_NON_SECURE_MASK | FLASH_OTP)));
#endif /* FLASH_SR_OBKERR */
}
/* return status */
return status;
}
/**
* @brief Program a quad-word 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 FlashAddress specifies the address to be programmed.
* This parameter shall be aligned to the Flash word (128-bit)
* @param DataAddress specifies the address of data to be programmed
* This parameter shall be 32-bit aligned
* @retval HAL Status
*/
HAL_StatusTypeDef HAL_FLASH_Program_IT(uint32_t TypeProgram, uint32_t FlashAddress, uint32_t DataAddress)
{
HAL_StatusTypeDef status;
__IO uint32_t *reg_cr;
/* Check the parameters */
assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram));
/* 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 = FlashAddress;
/* Access to SECCR or NSCR depends on operation type */
#if defined (FLASH_OPTSR2_TZEN)
reg_cr = IS_FLASH_SECURE_OPERATION() ? &(FLASH->SECCR) : &(FLASH_NS->NSCR);
#else
reg_cr = &(FLASH_NS->NSCR);
#endif /* FLASH_OPTSR2_TZEN */
/* Enable End of Operation and Error interrupts */
#if defined (FLASH_SR_OBKERR)
(*reg_cr) |= (FLASH_IT_EOP | FLASH_IT_WRPERR | FLASH_IT_PGSERR | \
FLASH_IT_STRBERR | FLASH_IT_INCERR | FLASH_IT_OBKERR | \
FLASH_IT_OBKWERR);
#else
(*reg_cr) |= (FLASH_IT_EOP | FLASH_IT_WRPERR | FLASH_IT_PGSERR | \
FLASH_IT_STRBERR | FLASH_IT_INCERR);
#endif /* FLASH_SR_OBKERR */
if ((TypeProgram & (~FLASH_NON_SECURE_MASK)) == FLASH_TYPEPROGRAM_QUADWORD)
{
/* Check the parameters */
assert_param(IS_FLASH_USER_MEM_ADDRESS(FlashAddress));
/* Program a quad-word (128-bit) at a specified address */
FLASH_Program_QuadWord(FlashAddress, DataAddress);
}
#if defined (FLASH_SR_OBKERR)
else if (((TypeProgram & (~FLASH_NON_SECURE_MASK)) == FLASH_TYPEPROGRAM_QUADWORD_OBK) || \
((TypeProgram & (~FLASH_NON_SECURE_MASK)) == FLASH_TYPEPROGRAM_QUADWORD_OBK_ALT))
{
/* Check the parameters */
assert_param(IS_FLASH_OBK_ADDRESS(FlashAddress));
/* Program a quad-word (128-bit) of OBK at a specified address */
FLASH_Program_QuadWord_OBK(FlashAddress, DataAddress);
}
#endif /* FLASH_SR_OBKERR */
#if defined (FLASH_EDATAR_EDATA_EN)
else if ((TypeProgram & (~FLASH_NON_SECURE_MASK)) == FLASH_TYPEPROGRAM_HALFWORD_EDATA)
{
/* Check the parameters */
assert_param(IS_FLASH_EDATA_ADDRESS(FlashAddress));
/* Program a Flash high-cycle data half-word at a specified address */
FLASH_Program_HalfWord(FlashAddress, DataAddress);
}
else if ((TypeProgram & (~FLASH_NON_SECURE_MASK)) == FLASH_TYPEPROGRAM_WORD_EDATA)
{
/* Check the parameters */
assert_param(IS_FLASH_EDATA_ADDRESS(FlashAddress));
/* Program a Flash high-cycle data word at a specified address */
FLASH_Program_Word(FlashAddress, DataAddress);
}
#endif /* FLASH_EDATAR_EDATA_EN */
else
{
/* Check the parameters */
assert_param(IS_FLASH_OTP_ADDRESS(FlashAddress));
/* Program an OTP word at a specified address */
FLASH_Program_HalfWord(FlashAddress, DataAddress);
}
}
/* return status */
return status;
}
/**
* @brief This function handles FLASH interrupt request.
* @retval None
*/
void HAL_FLASH_IRQHandler(void)
{
uint32_t param = 0U;
uint32_t errorflag;
__IO uint32_t *reg_cr;
__IO uint32_t *reg_ccr;
const __IO uint32_t *reg_sr;
const __IO uint32_t *reg_ecccorr;
/* Access to CR, CCR and SR registers depends on operation type */
#if defined (FLASH_OPTSR2_TZEN)
reg_cr = IS_FLASH_SECURE_OPERATION() ? &(FLASH->SECCR) : &(FLASH_NS->NSCR);
reg_ccr = IS_FLASH_SECURE_OPERATION() ? &(FLASH->SECCCR) : &(FLASH_NS->NSCCR);
reg_sr = IS_FLASH_SECURE_OPERATION() ? &(FLASH->SECSR) : &(FLASH_NS->NSSR);
#else
reg_cr = &(FLASH_NS->NSCR);
reg_ccr = &(FLASH_NS->NSCCR);
reg_sr = &(FLASH_NS->NSSR);
#endif /* FLASH_OPTSR2_TZEN */
reg_ecccorr = &(FLASH->ECCCORR);
/* Save Flash errors */
errorflag = (*reg_sr) & FLASH_FLAG_SR_ERRORS;
/* Add option byte error flag, if any */
#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
errorflag |= (FLASH->NSSR & FLASH_FLAG_OPTCHANGEERR);
#endif /* __ARM_FEATURE_CMSE */
/* Set parameter of the callback */
if ((pFlash.ProcedureOnGoing & (~FLASH_NON_SECURE_MASK)) == FLASH_TYPEERASE_SECTORS)
{
param = pFlash.Sector;
}
else if ((pFlash.ProcedureOnGoing & (~FLASH_NON_SECURE_MASK)) == FLASH_TYPEERASE_MASSERASE)
{
param = pFlash.Bank;
}
else if ((pFlash.ProcedureOnGoing & (~FLASH_NON_SECURE_MASK)) == FLASH_TYPEPROGRAM_QUADWORD)
{
param = pFlash.Address;
}
else
{
/* Empty statement (to be compliant MISRA 15.7) */
}
/* Clear operation bit on the on-going procedure */
CLEAR_BIT((*reg_cr), (pFlash.ProcedureOnGoing & ~(FLASH_NON_SECURE_MASK)));
/* Check FLASH operation error flags */
if (errorflag != 0U)
{
/* Save the error code */
pFlash.ErrorCode |= errorflag;
/* Clear error programming flags */
(*reg_ccr) = errorflag & FLASH_FLAG_SR_ERRORS;
#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
if ((errorflag & FLASH_FLAG_OPTCHANGEERR) != 0U)
{
FLASH->NSCCR = FLASH_FLAG_OPTCHANGEERR;
}
#endif /* __ARM_FEATURE_CMSE */
/* Stop the procedure ongoing */
pFlash.ProcedureOnGoing = 0U;
/* FLASH error interrupt user callback */
HAL_FLASH_OperationErrorCallback(param);
}
/* Check FLASH End of Operation flag */
if (((*reg_sr) & FLASH_FLAG_EOP) != 0U)
{
/* Clear FLASH End of Operation pending bit */
(*reg_ccr) = FLASH_FLAG_EOP;
if ((pFlash.ProcedureOnGoing & (~FLASH_NON_SECURE_MASK)) == FLASH_TYPEERASE_SECTORS)
{
/* Nb of sector to erased can be decreased */
pFlash.NbSectorsToErase--;
/* Check if there are still sectors to erase */
if (pFlash.NbSectorsToErase != 0U)
{
/* Increment sector number */
pFlash.Sector++;
FLASH_Erase_Sector(pFlash.Sector, pFlash.Bank);
}
else
{
/* No more sectors to erase */
/* Reset sector parameter and stop erase sectors procedure */
param = 0xFFFFFFFFU;
pFlash.ProcedureOnGoing = 0U;
}
}
else
{
/* Clear the procedure ongoing */
pFlash.ProcedureOnGoing = 0U;
}
/* FLASH EOP interrupt user callback */
HAL_FLASH_EndOfOperationCallback(param);
}
/* Check FLASH ECC correction flag */
if ((*reg_ecccorr & FLASH_ECCR_ECCC) != 0U)
{
/* Call User callback */
HAL_FLASHEx_EccCorrectionCallback();
/* Clear ECC correction flag in order to allow new ECC error record */
FLASH->ECCCORR |= FLASH_ECCR_ECCC;
}
if (pFlash.ProcedureOnGoing == 0U)
{
/* Disable Flash Operation and Error source interrupt */
#if defined (FLASH_SR_OBKERR)
(*reg_cr) &= ~(FLASH_IT_EOP | FLASH_IT_WRPERR | FLASH_IT_PGSERR | \
FLASH_IT_STRBERR | FLASH_IT_INCERR | FLASH_IT_OBKERR | \
FLASH_IT_OBKWERR | FLASH_IT_OPTCHANGEERR);
#else
(*reg_cr) &= ~(FLASH_IT_EOP | FLASH_IT_WRPERR | FLASH_IT_PGSERR | \
FLASH_IT_STRBERR | FLASH_IT_INCERR | FLASH_IT_OPTCHANGEERR);
#endif /* FLASH_SR_OBKERR */
}
}
/**
* @brief FLASH end of operation interrupt callback
* @param ReturnValue The value saved in this parameter depends on the ongoing procedure
* Mass Erase: Bank number which has been requested to erase
* Sectors Erase: Sector which has been erased
* (if 0xFFFFFFFF, it means that all the selected sectors have been erased)
* Program: Address which was selected for data program
* @retval None
*/
__weak void HAL_FLASH_EndOfOperationCallback(uint32_t ReturnValue)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(ReturnValue);
/* NOTE : This function Should not be modified, when the callback is needed,
the HAL_FLASH_EndOfOperationCallback could be implemented in the user file
*/
}
/**
* @brief FLASH operation error interrupt callback
* @param ReturnValue The value saved in this parameter depends on the ongoing procedure
* Mass Erase: Bank number which has been requested to erase
* Sectors Erase: Sector 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 registers access
* @retval HAL Status
*/
HAL_StatusTypeDef HAL_FLASH_Unlock(void)
{
HAL_StatusTypeDef status = HAL_OK;
if (READ_BIT(FLASH->NSCR, FLASH_CR_LOCK) != 0U)
{
/* Authorize the FLASH Control Register access */
WRITE_REG(FLASH->NSKEYR, FLASH_KEY1);
WRITE_REG(FLASH->NSKEYR, FLASH_KEY2);
/* Verify Flash CR is unlocked */
if (READ_BIT(FLASH->NSCR, FLASH_CR_LOCK) != 0U)
{
status = HAL_ERROR;
}
}
#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
if (status == HAL_OK)
{
if (READ_BIT(FLASH->SECCR, FLASH_CR_LOCK) != 0U)
{
/* Authorize the FLASH Control Register access */
WRITE_REG(FLASH->SECKEYR, FLASH_KEY1);
WRITE_REG(FLASH->SECKEYR, FLASH_KEY2);
/* verify Flash CR is unlocked */
if (READ_BIT(FLASH->SECCR, FLASH_CR_LOCK) != 0U)
{
status = HAL_ERROR;
}
}
}
#endif /* __ARM_FEATURE_CMSE */
return status;
}
/**
* @brief Locks the FLASH control registers access
* @retval HAL Status
*/
HAL_StatusTypeDef HAL_FLASH_Lock(void)
{
HAL_StatusTypeDef status = HAL_OK;
/* Set the LOCK Bit to lock the FLASH Control Register access */
SET_BIT(FLASH->NSCR, FLASH_CR_LOCK);
/* Verify Flash is locked */
if (READ_BIT(FLASH->NSCR, FLASH_CR_LOCK) == 0U)
{
status = HAL_ERROR;
}
#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
if (status == HAL_OK)
{
/* Set the LOCK Bit to lock the FLASH Control Register access */
SET_BIT(FLASH->SECCR, FLASH_CR_LOCK);
/* verify Flash is locked */
if (READ_BIT(FLASH->SECCR, FLASH_CR_LOCK) == 0U)
{
status = HAL_ERROR;
}
}
#endif /* __ARM_FEATURE_CMSE */
return status;
}
/**
* @brief Unlock the FLASH Option Control Registers access.
* @retval HAL Status
*/
HAL_StatusTypeDef HAL_FLASH_OB_Unlock(void)
{
if (READ_BIT(FLASH->OPTCR, FLASH_OPTCR_OPTLOCK) != 0U)
{
/* Authorizes the Option Byte registers programming */
WRITE_REG(FLASH->OPTKEYR, FLASH_OPT_KEY1);
WRITE_REG(FLASH->OPTKEYR, FLASH_OPT_KEY2);
/* Verify that the Option Bytes are unlocked */
if (READ_BIT(FLASH->OPTCR, FLASH_OPTCR_OPTLOCK) != 0U)
{
return HAL_ERROR;
}
}
return HAL_OK;
}
/**
* @brief Lock the FLASH Option Control Registers access.
* @retval HAL Status
*/
HAL_StatusTypeDef HAL_FLASH_OB_Lock(void)
{
/* Set the OPTLOCK Bit to lock the FLASH Option Byte Registers access */
SET_BIT(FLASH->OPTCR, FLASH_OPTCR_OPTLOCK);
/* Verify that the Option Bytes are locked */
if (READ_BIT(FLASH->OPTCR, FLASH_OPTCR_OPTLOCK) != 0U)
{
return HAL_OK;
}
return HAL_ERROR;
}
/**
* @brief Launch the option bytes loading.
* @retval HAL Status
*/
HAL_StatusTypeDef HAL_FLASH_OB_Launch(void)
{
HAL_StatusTypeDef status;
/* Set OPTSTRT Bit */
SET_BIT(FLASH->OPTCR, FLASH_OPTCR_OPTSTART);
/* Wait for OB change operation to be completed */
status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
return status;
}
/**
* @}
*/
/** @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 HAL_FLASH_ERRORCode The returned value can be:
* @arg HAL_FLASH_ERROR_NONE : No error set
* @arg HAL_FLASH_ERROR_WRP : Write Protection Error
* @arg HAL_FLASH_ERROR_PGS : Program Sequence Error
* @arg HAL_FLASH_ERROR_STRB : Strobe Error
* @arg HAL_FLASH_ERROR_INC : Inconsistency Error
* @arg HAL_FLASH_ERROR_OBK : OBK Error
* @arg HAL_FLASH_ERROR_OBKW : OBK Write Error
* @arg HAL_FLASH_ERROR_OB_CHANGE : Option Byte Change Error
* @arg HAL_FLASH_ERROR_ECCC : ECC Single Correction Error
* @arg HAL_FLASH_ERROR_ECCD : ECC Double Detection 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)
{
/* Wait for the FLASH operation to complete by polling on BUSY, WBNE and DBNE flags to be reset.
Even if the FLASH operation fails, the BUSY, WBNE and DBNE flags will be reset and an error
flag will be set */
uint32_t errorflag;
const __IO uint32_t *reg_sr;
__IO uint32_t *reg_ccr;
uint32_t tickstart = HAL_GetTick();
/* Access to SR register depends on operation type */
#if defined (FLASH_OPTSR2_TZEN)
reg_sr = IS_FLASH_SECURE_OPERATION() ? &(FLASH->SECSR) : &(FLASH_NS->NSSR);
#else
reg_sr = &(FLASH_NS->NSSR);
#endif /* FLASH_OPTSR2_TZEN */
/* Wait on BSY, WBNE and DBNE flags to be reset */
while (((*reg_sr) & (FLASH_FLAG_BSY | FLASH_FLAG_WBNE | FLASH_FLAG_DBNE)) != 0U)
{
if (Timeout != HAL_MAX_DELAY)
{
if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
{
return HAL_TIMEOUT;
}
}
}
/* Access to CCR register depends on operation type */
#if defined (FLASH_OPTSR2_TZEN)
reg_ccr = IS_FLASH_SECURE_OPERATION() ? &(FLASH->SECCCR) : &(FLASH_NS->NSCCR);
#else
reg_ccr = &(FLASH_NS->NSCCR);
#endif /* FLASH_OPTSR2_TZEN */
/* Check FLASH operation error flags */
errorflag = ((*reg_sr) & FLASH_FLAG_SR_ERRORS);
/* Add option byte error flag, if any */
#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
errorflag |= (FLASH->NSSR & FLASH_FLAG_OPTCHANGEERR);
#endif /* __ARM_FEATURE_CMSE */
/* In case of error reported in Flash SR or OPTSR registers */
if (errorflag != 0U)
{
/*Save the error code*/
pFlash.ErrorCode |= errorflag;
/* Clear error flags */
(*reg_ccr) = errorflag & FLASH_FLAG_SR_ERRORS;
#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
if ((errorflag & FLASH_FLAG_OPTCHANGEERR) != 0U)
{
FLASH->NSCCR = FLASH_FLAG_OPTCHANGEERR;
}
#endif /* __ARM_FEATURE_CMSE */
return HAL_ERROR;
}
/* Check FLASH End of Operation flag */
if (((*reg_sr) & FLASH_FLAG_EOP) != 0U)
{
/* Clear FLASH End of Operation pending bit */
(*reg_ccr) = FLASH_FLAG_EOP;
}
/* If there is no error flag set */
return HAL_OK;
}
/**
* @brief Program a quad-word (128-bit) at a specified address.
* @param FlashAddress specifies the address to be programmed.
* @param DataAddress specifies the address of data to be programmed.
* @retval None
*/
static void FLASH_Program_QuadWord(uint32_t FlashAddress, uint32_t DataAddress)
{
uint8_t index = 4;
uint32_t *dest_addr = (uint32_t *)FlashAddress;
uint32_t *src_addr = (uint32_t *)DataAddress;
uint32_t primask_bit;
__IO uint32_t *reg_cr;
/* Access to SECCR or NSCR registers depends on operation type */
#if defined (FLASH_OPTSR2_TZEN)
reg_cr = IS_FLASH_SECURE_OPERATION() ? &(FLASH->SECCR) : &(FLASH_NS->NSCR);
#else
reg_cr = &(FLASH_NS->NSCR);
#endif /* FLASH_OPTSR2_TZEN */
/* Set PG bit */
SET_BIT((*reg_cr), FLASH_CR_PG);
/* Enter critical section: Disable interrupts to avoid any interruption during the loop */
primask_bit = __get_PRIMASK();
__disable_irq();
/* Program the quad-word */
do
{
*dest_addr = *src_addr;
dest_addr++;
src_addr++;
index--;
} while (index != 0U);
/* Exit critical section: restore previous priority mask */
__set_PRIMASK(primask_bit);
}
#if defined (FLASH_SR_OBKERR)
/**
* @brief Program a quad-word (128-bit) of OBK at a specified address.
* @param FlashAddress specifies the address to be programmed.
* @param DataAddress specifies the address of data to be programmed.
* @retval None
*/
static void FLASH_Program_QuadWord_OBK(uint32_t FlashAddress, uint32_t DataAddress)
{
uint8_t index = 4;
uint32_t *dest_addr = (uint32_t *)FlashAddress;
uint32_t *src_addr = (uint32_t *)DataAddress;
uint32_t primask_bit;
__IO uint32_t *reg_cr;
__IO uint32_t *reg_obkcfgr;
/* Access to SECCR or NSCR registers depends on operation type */
reg_cr = IS_FLASH_SECURE_OPERATION() ? &(FLASH->SECCR) : &(FLASH_NS->NSCR);
reg_obkcfgr = IS_FLASH_SECURE_OPERATION() ? &(FLASH->SECOBKCFGR) : &(FLASH_NS->NSOBKCFGR);
/* Set PG bit */
SET_BIT((*reg_cr), FLASH_CR_PG);
/* Set ALT_SECT bit */
SET_BIT((*reg_obkcfgr), pFlash.ProcedureOnGoing & FLASH_OBKCFGR_ALT_SECT);
/* Enter critical section: Disable interrupts to avoid any interruption during the loop */
primask_bit = __get_PRIMASK();
__disable_irq();
/* Program the quad-word */
do
{
*dest_addr = *src_addr;
dest_addr++;
src_addr++;
index--;
} while (index != 0U);
/* Exit critical section: restore previous priority mask */
__set_PRIMASK(primask_bit);
}
#endif /* FLASH_SR_OBKERR */
/**
* @brief Program a half-word (16-bit) at a specified address.
* @param FlashAddress specifies the address to be programmed.
* @param DataAddress specifies the address of data to be programmed.
* @retval None
*/
static void FLASH_Program_HalfWord(uint32_t FlashAddress, uint32_t DataAddress)
{
__IO uint32_t *reg_cr;
/* Access to SECCR or NSCR registers depends on operation type */
#if defined (FLASH_OPTSR2_TZEN)
reg_cr = IS_FLASH_SECURE_OPERATION() ? &(FLASH->SECCR) : &(FLASH_NS->NSCR);
#else
reg_cr = &(FLASH_NS->NSCR);
#endif /* FLASH_OPTSR2_TZEN */
/* Set HalfWord_PG bit */
SET_BIT((*reg_cr), FLASH_CR_PG);
/* Program a halfword word (16 bits) */
*(__IO uint16_t *)FlashAddress = *(__IO uint16_t *)DataAddress;
}
#if defined(FLASH_EDATAR_EDATA_EN)
/**
* @brief Program a word (32-bit) at a specified address.
* @param FlashAddress specifies the address to be programmed.
* @param DataAddress specifies the address of data to be programmed.
* @retval None
*/
static void FLASH_Program_Word(uint32_t FlashAddress, uint32_t DataAddress)
{
__IO uint32_t *reg_cr;
/* Access to SECCR or NSCR registers depends on operation type */
#if defined (FLASH_OPTSR2_TZEN)
reg_cr = IS_FLASH_SECURE_OPERATION() ? &(FLASH->SECCR) : &(FLASH_NS->NSCR);
#else
reg_cr = &(FLASH_NS->NSCR);
#endif /* FLASH_OPTSR2_TZEN */
/* Set PG bit */
SET_BIT((*reg_cr), FLASH_CR_PG);
*(__IO uint32_t *)FlashAddress = *(__IO uint32_t *)DataAddress;
}
#endif /* FLASH_EDATAR_EDATA_EN */
/**
* @}
*/
#endif /* HAL_FLASH_MODULE_ENABLED */
/**
* @}
*/
/**
* @}
*/

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,754 @@
/**
******************************************************************************
* @file stm32h5xx_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) 2023 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
@verbatim
==============================================================================
##### GPIO Peripheral features #####
==============================================================================
[..]
(+) Each port bit of the general-purpose I/O (GPIO) ports can be individually
configured by software in several modes:
(++) Input mode
(++) Analog mode
(++) Output mode
(++) Alternate function mode
(++) External interrupt/event lines
(+) During and just after reset, the alternate functions and external interrupt
lines are not active and the I/O ports are configured in input floating mode.
(+) All GPIO pins have weak internal pull-up and pull-down resistors, which can be
activated or not.
(+) In Output or Alternate mode, each IO can be configured on open-drain or push-pull
type and the IO speed can be selected depending on the VDD value.
(+) The microcontroller IO pins are connected to onboard peripherals/modules through a
multiplexer that allows only one peripheral alternate function (AF) connected
to an IO pin at a time. In this way, there can be no conflict between peripherals
sharing the same IO pin.
(+) All ports have external interrupt/event capability. To use external interrupt
lines, the port must be configured in input mode. All available GPIO pins are
connected to the 16 external interrupt/event lines from EXTI0 to EXTI15.
(+) The external interrupt/event controller consists of up to 39 edge detectors
(16 lines are connected to GPIO) for generating event/interrupt requests (each
input line can be independently configured to select the type (interrupt or event)
and the corresponding trigger event (rising or falling or both). Each line can
also be masked independently.
##### How to use this driver #####
==============================================================================
[..]
(#) Enable the GPIO AHB clock using the following function: __HAL_RCC_GPIOx_CLK_ENABLE().
(#) Configure the GPIO pin(s) using HAL_GPIO_Init().
(++) Configure the IO mode using "Mode" member from GPIO_InitTypeDef structure
(++) Activate Pull-up, Pull-down resistor using "Pull" member from GPIO_InitTypeDef
structure.
(++) In case of Output or alternate function mode selection: the speed is
configured through "Speed" member from GPIO_InitTypeDef structure.
(++) In alternate mode is selection, the alternate function connected to the IO
is configured through "Alternate" member from GPIO_InitTypeDef structure.
(++) Analog mode is required when a pin is to be used as ADC channel
or DAC output.
(++) In case of external interrupt/event selection the "Mode" member from
GPIO_InitTypeDef structure select the type (interrupt or event) and
the corresponding trigger event (rising or falling or both).
(#) In case of external interrupt/event mode selection, configure NVIC IRQ priority
mapped to the EXTI line using HAL_NVIC_SetPriority() and enable it using
HAL_NVIC_EnableIRQ().
(#) To get the level of a pin configured in input mode use HAL_GPIO_ReadPin().
(#) To set/reset the level of a pin configured in output mode use
HAL_GPIO_WritePin()/HAL_GPIO_TogglePin().
(#) To 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 PH0 and PH1, respectively, when the HSE oscillator is off.
The HSE has priority over the GPIO function.
@endverbatim
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "stm32h5xx_hal.h"
/** @addtogroup STM32H5xx_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 pGPIO_Init.
* @note If GPIOx peripheral pin is used in EXTI_MODE and the pin is secure in case
* the system implements the security (TZEN=1), it is up to the secure application to
* insure that the corresponding EXTI line is set secure.
* @param GPIOx: where x can be (A..I) for stm32h56xxx and stm32h57xxx family lines and
* (A..D or H) for stm32h503xx family line to select the GPIO peripheral for STM32H5 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));
assert_param(IS_GPIO_PULL(pGPIO_Init->Pull));
/* 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 &= ~(0x0FUL << ((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) != GPIO_MODE_ANALOG) ||
(((pGPIO_Init->Mode & GPIO_MODE) == GPIO_MODE_ANALOG) && (pGPIO_Init->Pull != GPIO_PULLUP)))
{
/* 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 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;
/* Clear EXTI line configuration */
tmp = EXTI->EMR1;
tmp &= ~((uint32_t)iocurrent);
if ((pGPIO_Init->Mode & GPIO_MODE_EVT) == GPIO_MODE_EVT)
{
tmp |= iocurrent;
}
EXTI->EMR1 = tmp;
tmp = EXTI->IMR1;
tmp &= ~((uint32_t)iocurrent);
if ((pGPIO_Init->Mode & GPIO_MODE_IT) == GPIO_MODE_IT)
{
tmp |= iocurrent;
}
EXTI->IMR1 = tmp;
}
}
position++;
}
}
/**
* @brief De-initialize the GPIOx peripheral registers to their default reset values.
* @param GPIOx: where x can be (A..I) for stm32h56xxx and stm32h57xxx family lines and
* (A..D or H) for stm32h503xx family line to select the GPIO peripheral for STM32H5 family
* @param GPIO_Pin: specifies the port bit to be written.
* This parameter can be one of GPIO_PIN_x where x can be (0..15).
* @retval None
*/
void HAL_GPIO_DeInit(GPIO_TypeDef *GPIOx, uint32_t GPIO_Pin)
{
uint32_t 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) << ((position & 0x03U) * EXTI_EXTICR1_EXTI1_Pos);
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++;
}
}
/**
* @}
*/
/** @defgroup GPIO_Exported_Functions_Group2 IO operation functions
* @brief GPIO Read, Write, Toggle, Lock and EXTI management functions.
*
@verbatim
===============================================================================
##### IO operation functions #####
===============================================================================
@endverbatim
* @{
*/
/**
* @brief Read the specified input port pin.
* @param GPIOx: where x can be (A..I) for stm32h56xxx and stm32h57xxx family lines and
* (A..D or H) for stm32h503xx family line to select the GPIO peripheral for STM32H5 family
* @param GPIO_Pin: specifies the port bit to read.
* This parameter can be GPIO_PIN_x where x can be (0..15).
* @retval The input port pin value.
*/
GPIO_PinState HAL_GPIO_ReadPin(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..I) for stm32h56xxx and stm32h57xxx family lines and
* (A..D or H) for stm32h503xx family line to select the GPIO peripheral for STM32H5 family
* @param GPIO_Pin: specifies the port bit to be written.
* This parameter can be one of GPIO_PIN_x where x can be (0..15).
* @param PinState: specifies the value to be written to the selected bit.
* This parameter can be one of the GPIO_PinState enum values:
* @arg GPIO_PIN_RESET: to clear the port pin
* @arg GPIO_PIN_SET: to set the port pin
* @retval None
*/
void HAL_GPIO_WritePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState)
{
/* Check the parameters */
assert_param(IS_GPIO_PIN(GPIO_Pin));
assert_param(IS_GPIO_PIN_ACTION(PinState));
if (PinState != GPIO_PIN_RESET)
{
GPIOx->BSRR = (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..I) for stm32h56xxx and stm32h57xxx family lines and
* (A..D or H) for stm32h503xx family line to select the GPIO peripheral for STM32H5 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 STM32H5 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..I) for stm32h56xxx and stm32h57xxx family lines and
* (A..D or H) for stm32h503xx family line to select the GPIO peripheral for STM32H5 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 Enable speed optimization for several pin of dedicated port.
* @note Not all I/Os support the HSLV mode. Refer to the I/O structure in the corresponding
* datasheet for the list of I/Os supporting this feature. Other I/Os HSLV configuration must
* be kept at reset value.
* @note It must be used only if the I/O supply voltage is below 2.7 V.
* @param GPIOx: where x can be (A..I) for stm32h56xxx and stm32h57xxx family lines and
* (A..D or H) for stm32h503xx family line to select the GPIO peripheral for STM32H5 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_EnableHighSPeedLowVoltage(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
{
/* Check the parameters */
assert_param(IS_GPIO_PIN(GPIO_Pin));
assert_param(IS_GPIO_ALL_INSTANCE(GPIOx));
/* Set HSLVR gpio pin */
SET_BIT(GPIOx->HSLVR, GPIO_Pin);
}
/**
* @brief Disable speed optimization for several pin of dedicated port.
* @note Not all I/Os support the HSLV mode. Refer to the I/O structure in the corresponding
* datasheet for the list of I/Os supporting this feature. Other I/Os HSLV configuration must
* be kept at reset value.
* @note It must be used only if the I/O supply voltage is below 2.7 V.
* @param GPIOx: where x can be (A..I) for stm32h56xxx and stm32h57xxx family lines and
* (A..D or H) for stm32h503xx family line to select the GPIO peripheral for STM32H5 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_DisableHighSPeedLowVoltage(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
{
/* Check the parameters */
assert_param(IS_GPIO_PIN(GPIO_Pin));
assert_param(IS_GPIO_ALL_INSTANCE(GPIOx));
/* Clear HSLVR gpio pin */
CLEAR_BIT(GPIOx->HSLVR, GPIO_Pin);
}
/**
* @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 rising 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 falling 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
*/
}
/**
* @}
*/
#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
/** @defgroup GPIO_Exported_Functions_Group3 IO attributes management functions
* @brief GPIO attributes management functions.
*
@verbatim
===============================================================================
##### IO attributes functions #####
===============================================================================
@endverbatim
* @{
*/
/**
* @brief Configure the GPIO pins attributes.
* @note Available attributes are to secure GPIO pin(s), so this function is
* only available in secure
* @param GPIOx: where x can be (A..I) for stm32h56xxx and stm32h57xxx family lines and
* (A..D or H) for stm32h503xx family line to select the GPIO peripheral for STM32H5 family
* @param GPIO_Pin: specifies the pin(s) to configure the secure attribute
* @param PinAttributes: specifies the pin(s) to be set in secure mode, other being set non secured.
* @retval None
*/
void HAL_GPIO_ConfigPinAttributes(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, uint32_t PinAttributes)
{
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));
assert_param(IS_GPIO_PIN_ATTRIBUTES(PinAttributes));
tmp = GPIOx->SECCFGR;
/* Configure the port pins */
while ((GPIO_Pin >> position) != 0U)
{
/* Get current io position */
iocurrent = GPIO_Pin & (1UL << position);
if (iocurrent != 0U)
{
/* Configure the IO secure attribute */
tmp &= ~(GPIO_SECCFGR_SEC0 << position);
tmp |= (PinAttributes << position);
}
position++;
}
/* Set secure attributes */
GPIOx->SECCFGR = tmp;
}
/**
* @brief Get the GPIO pins attributes.
* @note Available attributes are to secure GPIO pin(s), so this function is
* only available in secure
* @param GPIOx: where x can be (A..I) for stm32h56xxx and stm32h57xxx family lines and
* (A..D or H) for stm32h503xx family line to select the GPIO peripheral for STM32H5 family
* @param GPIO_Pin: specifies the single pin to get the secure attribute from
* @param pPinAttributes: pointer to return the pin attributes.
* @retval HAL Status.
*/
HAL_StatusTypeDef HAL_GPIO_GetConfigPinAttributes(const GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin,
uint32_t *pPinAttributes)
{
uint32_t iocurrent;
uint32_t position = 0U;
/* Check null pointer */
if (pPinAttributes == NULL)
{
return HAL_ERROR;
}
/* Check the parameters */
assert_param(IS_GPIO_ALL_INSTANCE(GPIOx));
assert_param(IS_GPIO_SINGLE_PIN(GPIO_Pin));
/* Get secure attribute of the port pin */
while ((GPIO_Pin >> position) != 0U)
{
/* Get current io position */
iocurrent = GPIO_Pin & (1UL << position);
if (iocurrent != 0U)
{
/* Get the IO secure attribute */
if ((GPIOx->SECCFGR & (GPIO_SECCFGR_SEC0 << position)) != 0U)
{
*pPinAttributes = GPIO_PIN_SEC;
}
else
{
*pPinAttributes = GPIO_PIN_NSEC;
}
break;
}
position++;
}
return HAL_OK;
}
/**
* @}
*/
#endif /* __ARM_FEATURE_CMSE */
/**
* @}
*/
#endif /* HAL_GPIO_MODULE_ENABLED */
/**
* @}
*/
/**
* @}
*/

View File

@@ -0,0 +1,674 @@
/**
******************************************************************************
* @file stm32h5xx_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.
* + PWR Attributes Functions.
*
******************************************************************************
* @attention
*
* Copyright (c) 2023 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 "stm32h5xx_hal.h"
/** @addtogroup STM32H5xx_HAL_Driver
* @{
*/
/** @defgroup PWR PWR
* @brief PWR HAL module driver
* @{
*/
#if defined (HAL_PWR_MODULE_ENABLED)
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/** @defgroup PWR_Private_Defines PWR Private Defines
* @{
*/
/** @defgroup PWR_PVD_Mode_Mask PWR PVD Mode Mask
* @{
*/
#define PVD_RISING_EDGE (0x01U) /*!< Mask for rising edge set as PVD
trigger */
#define PVD_FALLING_EDGE (0x02U) /*!< Mask for falling edge set as PVD
trigger */
#define PVD_MODE_IT (0x04U) /*!< Mask for interruption yielded by PVD
threshold crossing */
#define PVD_MODE_EVT (0x08U) /*!< Mask for event yielded by PVD threshold
crossing */
/**
* @}
*/
/**
* @}
*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Exported functions --------------------------------------------------------*/
/** @defgroup PWR_Exported_Functions PWR Exported Functions
* @{
*/
/** @defgroup PWR_Exported_Functions_Group1 Initialization and De-Initialization Functions
* @brief Initialization and de-Initialization functions
*
@verbatim
===============================================================================
##### Initialization and De-Initialization Functions #####
===============================================================================
[..]
@endverbatim
* @{
*/
/**
* @brief Deinitialize the HAL PWR peripheral registers to their default reset
* values.
* @note This functionality is not available in this product.
* The prototype is kept just to maintain compatibility with other
* products.
* @retval None.
*/
void HAL_PWR_DeInit(void)
{
}
/**
* @brief Enable access to the backup domain (RCC Backup domain control
* register RCC_BDCR, RTC registers, TAMP registers, backup registers
* and backup SRAM).
* @note After a system reset, the backup domain is protected against
* possible unwanted write accesses.
* @retval None.
*/
void HAL_PWR_EnableBkUpAccess(void)
{
SET_BIT(PWR->DBPCR, PWR_DBPCR_DBP);
}
/**
* @brief Disable access to the backup domain (RCC Backup domain control
* register RCC_BDCR, RTC registers, TAMP registers, backup registers
* and backup SRAM).
* @retval None
*/
void HAL_PWR_DisableBkUpAccess(void)
{
CLEAR_BIT(PWR->DBPCR, PWR_DBPCR_DBP);
}
/**
* @}
*/
/** @defgroup PWR_Exported_Functions_Group2 Peripheral Control Functions
* @brief Low power modes configuration functions
*
@verbatim
===============================================================================
##### Peripheral Control functions #####
===============================================================================
[..]
@endverbatim
* @{
*/
/**
* @brief Configure the voltage threshold detected by the Programmed Voltage
* Detector (PVD).
* @param sConfigPVD : Pointer to a PWR_PVDTypeDef structure that contains the
* PVD configuration information (PVDLevel and EventMode).
* @retval None.
*/
HAL_StatusTypeDef HAL_PWR_ConfigPVD(const PWR_PVDTypeDef *sConfigPVD)
{
/* Check the parameters */
assert_param(IS_PWR_PVD_LEVEL(sConfigPVD->PVDLevel));
assert_param(IS_PWR_PVD_MODE(sConfigPVD->Mode));
/* Set PLS[3:1] bits according to PVDLevel value */
MODIFY_REG(PWR->VMCR, PWR_VMCR_PLS, sConfigPVD->PVDLevel);
/* Disable PVD Event/Interrupt */
__HAL_PWR_PVD_EXTI_DISABLE_EVENT();
__HAL_PWR_PVD_EXTI_DISABLE_IT();
__HAL_PWR_PVD_EXTI_DISABLE_RISING_EDGE();
__HAL_PWR_PVD_EXTI_DISABLE_FALLING_EDGE();
/* Configure the PVD in interrupt mode */
if ((sConfigPVD->Mode & PVD_MODE_IT) == PVD_MODE_IT)
{
__HAL_PWR_PVD_EXTI_ENABLE_IT();
}
/* Configure the PVD in event mode */
if ((sConfigPVD->Mode & PVD_MODE_EVT) == PVD_MODE_EVT)
{
__HAL_PWR_PVD_EXTI_ENABLE_EVENT();
}
/* Configure the PVD in rising edge */
if ((sConfigPVD->Mode & PVD_RISING_EDGE) == PVD_RISING_EDGE)
{
__HAL_PWR_PVD_EXTI_ENABLE_RISING_EDGE();
}
/* Configure the PVD in falling edge */
if ((sConfigPVD->Mode & PVD_FALLING_EDGE) == PVD_FALLING_EDGE)
{
__HAL_PWR_PVD_EXTI_ENABLE_FALLING_EDGE();
}
return HAL_OK;
}
/**
* @brief Enable the programmable voltage detector (PVD).
* @retval None.
*/
void HAL_PWR_EnablePVD(void)
{
SET_BIT(PWR->VMCR, PWR_VMCR_PVDEN);
}
/**
* @brief Disable the programmable voltage detector (PVD).
* @retval None.
*/
void HAL_PWR_DisablePVD(void)
{
CLEAR_BIT(PWR->VMCR, PWR_VMCR_PVDEN);
}
/**
* @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
* sets the default (rising edge):
* @arg PWR_WAKEUP_PIN1, PWR_WAKEUP_PIN2, PWR_WAKEUP_PIN3,PWR_WAKEUP_PIN4,
* PWR_WAKEUP_PIN5, PWR_WAKEUP_PIN6, PWR_WAKEUP_PIN7.PWR_WAKEUP_PIN8.
* or one of the following values where the user can explicitly states
* the enabled pin and the chosen polarity:
* @arg PWR_WAKEUP_PIN1_HIGH, PWR_WAKEUP_PIN1_LOW,
* PWR_WAKEUP_PIN2_HIGH, PWR_WAKEUP_PIN2_LOW,
* PWR_WAKEUP_PIN3_HIGH, PWR_WAKEUP_PIN3_LOW,
* PWR_WAKEUP_PIN4_HIGH, PWR_WAKEUP_PIN4_LOW,
* PWR_WAKEUP_PIN5_HIGH, PWR_WAKEUP_PIN5_LOW,
* PWR_WAKEUP_PIN6_HIGH, PWR_WAKEUP_PIN6_LOW,
* PWR_WAKEUP_PIN7_HIGH, PWR_WAKEUP_PIN7_LOW,
* PWR_WAKEUP_PIN8_HIGH, PWR_WAKEUP_PIN8_LOW.
* @note PWR_WAKEUP_PINx and PWR_WAKEUP_PINx_HIGH are equivalent.
* @note The PWR_WAKEUP_PIN6_HIGH, PWR_WAKEUP_PIN6_LOW, PWR_WAKEUP_PIN7_HIGH, PWR_WAKEUP_PIN7_LOW,
* PWR_WAKEUP_PIN8_HIGH and PWR_WAKEUP_PIN8_LOW are not available for STM32H503xx devices.
* @retval None.
*/
void HAL_PWR_EnableWakeUpPin(uint32_t WakeUpPinPolarity)
{
/* Check the parameters */
assert_param(IS_PWR_WAKEUP_PIN(WakeUpPinPolarity));
/*
Enable and Specify the Wake-Up pin polarity and the pull configuration
for the event detection (rising or falling edge).
*/
MODIFY_REG(PWR->WUCR, PWR_EWUP_MASK, 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 PWR_WAKEUP_PIN1, PWR_WAKEUP_PIN2, PWR_WAKEUP_PIN3,PWR_WAKEUP_PIN4,
* PWR_WAKEUP_PIN5, PWR_WAKEUP_PIN6, PWR_WAKEUP_PIN7.PWR_WAKEUP_PIN8.
* or one of the following values where the user can explicitly states
* the enabled pin and the chosen polarity:
* @arg PWR_WAKEUP_PIN1_HIGH, PWR_WAKEUP_PIN1_LOW,
* PWR_WAKEUP_PIN2_HIGH, PWR_WAKEUP_PIN2_LOW,
* PWR_WAKEUP_PIN3_HIGH, PWR_WAKEUP_PIN3_LOW,
* PWR_WAKEUP_PIN4_HIGH, PWR_WAKEUP_PIN4_LOW,
* PWR_WAKEUP_PIN5_HIGH, PWR_WAKEUP_PIN5_LOW,
* PWR_WAKEUP_PIN6_HIGH, PWR_WAKEUP_PIN6_LOW,
* PWR_WAKEUP_PIN7_HIGH, PWR_WAKEUP_PIN7_LOW,
* PWR_WAKEUP_PIN8_HIGH, PWR_WAKEUP_PIN8_LOW.
* @note The PWR_WAKEUP_PIN6_HIGH, PWR_WAKEUP_PIN6_LOW, PWR_WAKEUP_PIN7_HIGH, PWR_WAKEUP_PIN7_LOW,
* PWR_WAKEUP_PIN8_HIGH and PWR_WAKEUP_PIN8_LOW are not available for STM32H503xx devices.
* @retval None.
*/
void HAL_PWR_DisableWakeUpPin(uint32_t WakeUpPinx)
{
/* Check the parameters */
assert_param(IS_PWR_WAKEUP_PIN(WakeUpPinx));
/* Disable the wake up pin selected */
CLEAR_BIT(PWR->WUCR, (PWR_WUCR_WUPEN & WakeUpPinx));
}
/**
* @brief Enter the CPU in SLEEP mode.
* @note In SLEEP mode, all I/O pins keep the same state as in Run mode.
* @note CPU clock is off and all peripherals including Cortex-M33 core such
* as NVIC and SysTick can run and wake up the CPU when an interrupt
* or an event occurs.
* @param Regulator : Specifies the regulator state in Sleep mode.
* This parameter can be one of the following values :
* @arg @ref PWR_MAINREGULATOR_ON
* @arg @ref PWR_LOWPOWERREGULATOR_ON
* @note This parameter is not available in this product.
* The parameter is kept just to maintain compatibility with other
* products.
* @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 mode with Wait
* For Interrupt request.
* @arg @ref PWR_SLEEPENTRY_WFE enter SLEEP mode with Wait
* For Event request.
* @note When WFI entry is used, ticks interrupt must be disabled to avoid
* unexpected CPU wake up.
* @retval None.
*/
void HAL_PWR_EnterSLEEPMode(uint32_t Regulator, uint8_t SLEEPEntry)
{
UNUSED(Regulator);
/* Check the parameter */
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)
{
/* Wait For Interrupt Request */
__WFI();
}
else
{
/* Wait For Event Request */
__SEV();
__WFE();
__WFE();
}
}
/**
* @brief Enter the whole system to STOP mode.
* @note In STOP mode, the regulator remains in main regulator mode,
* allowing a very fast wakeup time but with much higher consumption
* comparing to other STOP modes.
* @note STOP offers the largest number of active peripherals and wakeup
* sources, a smaller wakeup time but a higher consumption.
* STOP mode achieves the lowest power consumption while retaining
* the content of SRAM and registers. All clocks in the VCORE domain
* are stopped. The PLL, the HSI, the CSI and the HSE crystal oscillators
* are disabled. The LSE or LSI is still running.
* @note The system clock when exiting from Stop mode can be either HSI
* or CSI, depending on software configuration.
* @param Regulator : Specifies the regulator state in Sleep mode.
* This parameter can be one of the following values :
* @arg @ref PWR_MAINREGULATOR_ON
* @arg @ref PWR_LOWPOWERREGULATOR_ON
* @note This parameter is not available in this product.
* The parameter is kept just to maintain compatibility with other
* products.
* @param STOPEntry : Specifies if STOP mode is entered with WFI or WFE
* instruction.
* This parameter can be one of the following values :
* @arg @ref PWR_STOPENTRY_WFI enter STOP mode with Wait
* For Interrupt request.
* @arg @ref PWR_STOPENTRY_WFE enter STOP mode with Wait
* For Event request.
* @retval None.
*/
void HAL_PWR_EnterSTOPMode(uint32_t Regulator, uint8_t STOPEntry)
{
UNUSED(Regulator);
/* Check the parameter */
assert_param(IS_PWR_STOP_ENTRY(STOPEntry));
/* Select STOP mode */
CLEAR_BIT(PWR->PMCR, PWR_PMCR_LPMS);
/* 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)
{
/* Wait For Interrupt Request */
__WFI();
}
else
{
/* Wait For Event Request */
__SEV();
__WFE();
__WFE();
}
/* Reset SLEEPDEEP bit of Cortex System Control Register */
CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
}
/**
* @brief Enter the whole system to STANDBY mode.
* @note The STANDBY mode is used to achieve the lowest power consumption
* with BOR. The internal regulator is switched off so that the VCORE
* domain is powered off. The PLL, the HSI, the CSI and the HSE crystal
* oscillators are also switched off.
* @note After entering STANDBY mode, SRAMs and register contents are lost
* except for registers and backup SRAM in the Backup domain and
* STANDBY circuitry.
* @retval None.
*/
void HAL_PWR_EnterSTANDBYMode(void)
{
/* Select STANDBY mode */
SET_BIT(PWR->PMCR, PWR_PMCR_LPMS);
/* Set SLEEPDEEP bit of Cortex System Control Register */
SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
/* Wait For all memory accesses to complete before continuing */
__DSB();
/* Ensure that the processor pipeline is flushed */
__ISB();
/* Wait For Interrupt Request */
__WFI();
}
/**
* @brief Indicate SLEEP-ON-EXIT feature when returning from handler mode to
* thread mode.
* @note Set SLEEPONEXIT bit of SCR register. When this bit is set, the
* processor re-enters SLEEP mode when an interruption handling is over.
* Setting this bit is useful when the processor is expected to run
* only on interruptions handling.
* @retval None.
*/
void HAL_PWR_EnableSleepOnExit(void)
{
/* Set SLEEPONEXIT bit of Cortex-M33 System Control Register */
SET_BIT(SCB->SCR, SCB_SCR_SLEEPONEXIT_Msk);
}
/**
* @brief Disable SLEEP-ON-EXIT feature when returning from handler mode to
* thread mode.
* @note Clears SLEEPONEXIT bit of SCR register. When this bit is set, the
* processor re-enters SLEEP mode when an interruption handling is over.
* @retval None.
*/
void HAL_PWR_DisableSleepOnExit(void)
{
/* Clear SLEEPONEXIT bit of Cortex-M33 System Control Register */
CLEAR_BIT(SCB->SCR, SCB_SCR_SLEEPONEXIT_Msk);
}
/**
* @brief Enable CORTEX SEV-ON-PEND feature.
* @note Sets SEVONPEND bit of SCR register. When this bit is set, any
* pending event / interrupt even if it's disabled or has insufficient
* priority to cause exception entry wakes up the Cortex-M33.
* @retval None.
*/
void HAL_PWR_EnableSEVOnPend(void)
{
/* Set SEVONPEND bit of Cortex-M33 System Control Register */
SET_BIT(SCB->SCR, SCB_SCR_SEVONPEND_Msk);
}
/**
* @brief Disable CORTEX SEVONPEND feature.
* @note Resets SEVONPEND bit of SCR register. When this bit is reset, only
* enabled pending causes exception entry wakes up the Cortex-M33.
* @retval None.
*/
void HAL_PWR_DisableSEVOnPend(void)
{
/* Clear SEVONPEND bit of Cortex-M33 System Control Register */
CLEAR_BIT(SCB->SCR, SCB_SCR_SEVONPEND_Msk);
}
/**
* @brief This function handles the PWR PVD interrupt request.
* @note This API should be called under the PVD_AVD_IRQHandler().
* @note The use of this API is only when we activate the PVD.
* @note When the PVD and AVD are activated at the same time you must use this API:
* HAL_PWREx_PVD_AVD_IRQHandler.
* @retval None.
*/
void HAL_PWR_PVD_IRQHandler(void)
{
uint32_t rising_flag;
uint32_t falling_flag;
/* Get pending flags */
rising_flag = READ_REG(EXTI->RPR1);
falling_flag = READ_REG(EXTI->FPR1);
/* Check PWR EXTI flags for PVD */
if (((rising_flag | falling_flag) & PWR_EXTI_LINE_PVD) != 0U)
{
/* PWR PVD interrupt user callback */
HAL_PWR_PVDCallback();
/* Clear PVD EXTI pending bit */
WRITE_REG(EXTI->RPR1, PWR_EXTI_LINE_PVD);
WRITE_REG(EXTI->FPR1, PWR_EXTI_LINE_PVD);
}
}
/**
* @brief PWR PVD interrupt callback.
* @retval None.
*/
__weak void HAL_PWR_PVDCallback(void)
{
/* NOTE : This function should not be modified, when the callback is needed,
the HAL_PWR_PVDCallback can be implemented in the user file
*/
}
/**
* @}
*/
/** @defgroup PWR_Exported_Functions_Group3 Attributes Management Functions
* @brief Attributes management functions
*
@verbatim
===============================================================================
##### PWR Attributes Functions #####
===============================================================================
[..]
@endverbatim
* @{
*/
/**
* @brief Configure the PWR item attributes.
* @note Available attributes are security and privilege protection.
* @note Security attribute can only be set only by secure access.
* @note Privilege attribute for secure items can be managed only by a secure
* privileged access.
* @note Privilege attribute for nsecure items can be managed by a secure
* privileged access or by a nsecure privileged access.
* @note As the privileged attributes concern either all secure or all non-secure
* PWR resources accesses and not each PWR individual items access attribute,
* the application must ensure that the privilege access attribute configurations
* are coherent amongst the security level set on PWR individual items so not to
* overwrite a previous more restricted access rule (consider either all secure
* and/or all non-secure PWR resources accesses by privileged-only transactions
* or privileged and unprivileged transactions).
* @param Item : Specifies the item(s) to set attributes on.
* This parameter can be a combination of @ref PWR_Items.
* @param Attributes : Specifies the available attribute(s).
* This parameter can be one of @ref PWR_Attributes.
* @retval None.
*/
void HAL_PWR_ConfigAttributes(uint32_t Item, uint32_t Attributes)
{
/* Check the parameters */
assert_param(IS_PWR_ATTRIBUTES(Attributes));
#if defined (PWR_SECCFGR_WUP1SEC)
assert_param(IS_PWR_ITEMS_ATTRIBUTES(Item));
#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
/* Secure item management (TZEN = 1) */
if ((Attributes & PWR_ITEM_ATTR_SEC_PRIV_MASK) == PWR_ITEM_ATTR_SEC_PRIV_MASK)
{
/* Privilege item management */
if ((Attributes & PWR_SEC_PRIV) == PWR_SEC_PRIV)
{
SET_BIT(PWR->SECCFGR, Item);
SET_BIT(PWR->PRIVCFGR, PWR_PRIVCFGR_SPRIV);
}
else
{
SET_BIT(PWR->SECCFGR, Item);
CLEAR_BIT(PWR->PRIVCFGR, PWR_PRIVCFGR_SPRIV);
}
}
/* NSecure item management */
else
{
/* Privilege item management */
if ((Attributes & PWR_NSEC_PRIV) == PWR_NSEC_PRIV)
{
CLEAR_BIT(PWR->SECCFGR, Item);
SET_BIT(PWR->PRIVCFGR, PWR_PRIVCFGR_NSPRIV);
}
else
{
CLEAR_BIT(PWR->SECCFGR, Item);
CLEAR_BIT(PWR->PRIVCFGR, PWR_PRIVCFGR_NSPRIV);
}
}
#else
/* NSecure item management (TZEN = 0) */
if ((Attributes & PWR_ITEM_ATTR_NSEC_PRIV_MASK) == PWR_ITEM_ATTR_NSEC_PRIV_MASK)
{
/* Privilege item management */
if ((Attributes & PWR_NSEC_PRIV) == PWR_NSEC_PRIV)
{
SET_BIT(PWR->PRIVCFGR, PWR_PRIVCFGR_NSPRIV);
}
else
{
CLEAR_BIT(PWR->PRIVCFGR, PWR_PRIVCFGR_NSPRIV);
}
}
#endif /* __ARM_FEATURE_CMSE */
#else /* PWR_SECCFGR_WUP1SEC */
/* Prevent unused argument(s) compilation warning */
UNUSED(Item);
/* NSecure item management (TZEN = 0) */
if ((Attributes & PWR_ITEM_ATTR_NSEC_PRIV_MASK) == PWR_ITEM_ATTR_NSEC_PRIV_MASK)
{
/* Privilege item management */
if ((Attributes & PWR_PRIV) == PWR_PRIV)
{
SET_BIT(PWR->PRIVCFGR, PWR_PRIVCFGR_PRIV);
}
else
{
CLEAR_BIT(PWR->PRIVCFGR, PWR_PRIVCFGR_PRIV);
}
}
#endif /* PWR_SECCFGR_WUP1SEC */
}
/**
* @brief Get attribute(s) of a PWR item.
* @param Item : Specifies the item(s) to set attributes on.
* This parameter can be one of @ref PWR_Items.
* @param pAttributes : Pointer to return attribute(s).
* Returned value could be on of @ref PWR_Attributes.
* @retval HAL Status.
*/
HAL_StatusTypeDef HAL_PWR_GetConfigAttributes(uint32_t Item, uint32_t *pAttributes)
{
uint32_t attributes;
/* Check attribute pointer */
if (pAttributes == NULL)
{
return HAL_ERROR;
}
#if defined (PWR_SECCFGR_WUP1SEC)
/* Check the parameter */
assert_param(IS_PWR_ITEMS_ATTRIBUTES(Item));
#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
/* Check item security */
if ((PWR->SECCFGR & Item) == Item)
{
/* Get Secure privileges attribute */
attributes = ((PWR->PRIVCFGR & PWR_PRIVCFGR_SPRIV) == 0U) ? PWR_SEC_NPRIV : PWR_SEC_PRIV;
}
else
{
/* Get Non-Secure privileges attribute */
attributes = ((PWR->PRIVCFGR & PWR_PRIVCFGR_NSPRIV) == 0U) ? PWR_NSEC_NPRIV : PWR_NSEC_PRIV;
}
#else
/* Get Non-Secure privileges attribute */
attributes = ((PWR->PRIVCFGR & PWR_PRIVCFGR_NSPRIV) == 0U) ? PWR_NSEC_NPRIV : PWR_NSEC_PRIV;
#endif /* __ARM_FEATURE_CMSE */
#else /* PWR_SECCFGR_WUP1SEC*/
/* Prevent unused argument(s) compilation warning */
UNUSED(Item);
/* Get Non-Secure privileges attribute */
attributes = ((PWR->PRIVCFGR & PWR_PRIVCFGR_PRIV) == 0U) ? PWR_NPRIV : PWR_PRIV;
#endif /* PWR_SECCFGR_WUP1SEC */
/* return value */
*pAttributes = attributes;
return HAL_OK;
}
/**
* @}
*/
/**
* @}
*/
#endif /* defined (HAL_PWR_MODULE_ENABLED) */
/**
* @}
*/
/**
* @}
*/

View File

@@ -0,0 +1,844 @@
/**
******************************************************************************
* @file stm32h5xx_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 extension peripheral :
* + Power Supply Control Functions
* + Voltage Monitoring Functions
* + Wakeup Pins configuration Functions
* + Memories Retention Functions
* + IO and JTAG Retention Functions
******************************************************************************
* @attention
*
* Copyright (c) 2023 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 "stm32h5xx_hal.h"
/** @addtogroup STM32H5xx_HAL_Driver
* @{
*/
/** @defgroup PWREx PWREx
* @brief PWR Extended HAL module driver
* @{
*/
#if defined (HAL_PWR_MODULE_ENABLED)
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/** @defgroup PWR_Extended_Private_Defines PWR Extended Private Defines
* @{
*/
/* PORTI pins mask */
#define PWR_PORTI_AVAILABLE_PINS (0xFFU)
/*!< Time out value of flags setting */
#define PWR_FLAG_SETTING_DELAY (0x32U)
/** @defgroup PWR_PVM_Mode_Mask PWR PVM Mode Mask
* @{
*/
#define PVM_RISING_EDGE (0x01U) /*!< Mask for rising edge set as PVM trigger */
#define PVM_FALLING_EDGE (0x02U) /*!< Mask for falling edge set as PVM trigger */
#define PVM_MODE_IT (0x04U) /*!< Mask for interruption yielded by PVM threshold crossing */
#define PVM_MODE_EVT (0x08U) /*!< Mask for event yielded by PVM threshold crossing */
/**
* @}
*/
/** @defgroup PWREx_WakeUp_Pins_Offsets PWREx Wake-Up Pins offsets
* @{
*/
/* Wake-Up Pins PWR Pin Pull shift offsets */
#define PWR_WAKEUP_PINS_PULL_SHIFT_OFFSET (2U)
/**
* @}
*/
/**
* @}
*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Exported functions --------------------------------------------------------*/
/** @defgroup PWREx_Exported_Functions PWR Extended Exported Functions
* @{
*/
/** @defgroup PWREx_Exported_Functions_Group1 Power Supply Control Functions
* @brief Power supply control functions
*
@verbatim
===============================================================================
##### Power supply control functions #####
===============================================================================
[..]
@endverbatim
* @{
*/
/**
* @brief Configure the system Power Supply.
* @param SupplySource : Specifies the Power Supply source to set after a
* system startup.
* This parameter can be one of the following values :
* @arg PWR_EXTERNAL_SOURCE_SUPPLY : The SMPS and the LDO are
* Bypassed. The Vcore Power
* Domains are supplied from
* external source.
* @retval HAL status.
*/
HAL_StatusTypeDef HAL_PWREx_ConfigSupply(uint32_t SupplySource)
{
uint32_t tickstart;
/* Check the parameters */
assert_param(IS_PWR_SUPPLY(SupplySource));
if ((PWR->SCCR & PWR_SCCR_BYPASS) != (PWR_SCCR_BYPASS))
{
/* Set the power supply configuration */
MODIFY_REG(PWR->SCCR, PWR_SUPPLY_CONFIG_MASK, SupplySource);
/* Get tick */
tickstart = HAL_GetTick();
/* Wait till voltage level flag is set */
while (__HAL_PWR_GET_FLAG(PWR_FLAG_ACTVOSRDY) == 0U)
{
if ((HAL_GetTick() - tickstart) > PWR_FLAG_SETTING_DELAY)
{
return HAL_ERROR;
}
}
}
return HAL_OK;
}
/**
* @brief Get the power supply configuration.
* @retval The supply configuration.
*/
uint32_t HAL_PWREx_GetSupplyConfig(void)
{
return (PWR->SCCR & PWR_SUPPLY_CONFIG_MASK);
}
/**
* @brief Configure the main internal regulator output voltage.
* @param VoltageScaling : Specifies the regulator output voltage to achieve
* a tradeoff between performance and power
* consumption.
* This parameter can be one of the following values :
* @arg PWR_REGULATOR_VOLTAGE_SCALE0 : Regulator voltage output
* Scale 0 mode.
* @arg PWR_REGULATOR_VOLTAGE_SCALE1 : Regulator voltage output
* range 1 mode.
* @arg PWR_REGULATOR_VOLTAGE_SCALE2 : Regulator voltage output
* range 2 mode.
* @arg PWR_REGULATOR_VOLTAGE_SCALE3 : Regulator voltage output
* range 3 mode.
* @retval HAL Status
*/
HAL_StatusTypeDef HAL_PWREx_ControlVoltageScaling(uint32_t VoltageScaling)
{
uint32_t tickstart = HAL_GetTick();
/* Check the parameters */
assert_param(IS_PWR_VOLTAGE_SCALING_RANGE(VoltageScaling));
/* Get the voltage scaling */
if ((PWR->VOSSR & PWR_VOSSR_ACTVOS) == (VoltageScaling << 10U))
{
/* Old and new voltage scaling configuration match : nothing to do */
return HAL_OK;
}
/* Set the voltage range */
MODIFY_REG(PWR->VOSCR, PWR_VOSCR_VOS, VoltageScaling);
/* Wait till voltage level flag is set */
while (__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY) == 0U)
{
if ((HAL_GetTick() - tickstart) > PWR_FLAG_SETTING_DELAY)
{
return HAL_ERROR;
}
}
return HAL_OK;
}
/**
* @brief Get the main internal regulator output voltage. Reflecting the last
* VOS value applied to the PMU.
* @retval The current applied VOS selection.
*/
uint32_t HAL_PWREx_GetVoltageRange(void)
{
/* Get the active voltage scaling */
return (PWR->VOSSR & PWR_VOSSR_ACTVOS);
}
/**
* @brief Configure the main internal regulator output voltage in STOP mode.
* @param VoltageScaling : Specifies the regulator output voltage when the
* system enters Stop mode to achieve a tradeoff between performance
* and power consumption.
* This parameter can be one of the following values:
* @arg PWR_REGULATOR_SVOS_SCALE3 : Regulator voltage output range
* 3 mode.
* @arg PWR_REGULATOR_SVOS_SCALE4 : Regulator voltage output range
* 4 mode.
* @arg PWR_REGULATOR_SVOS_SCALE5 : Regulator voltage output range
* 5 mode.
* @note The Stop mode voltage scaling for SVOS4 and SVOS5 sets the voltage
* regulator in Low-power (LP) mode to further reduce power consumption.
* When preselecting SVOS3, the use of the voltage regulator low-power
* mode (LP) can be selected by LPDS register bit.
* @note The selected SVOS4 and SVOS5 levels add an additional startup delay
* when exiting from system Stop mode.
* @retval HAL Status.
*/
HAL_StatusTypeDef HAL_PWREx_ControlStopModeVoltageScaling(uint32_t VoltageScaling)
{
/* Check the parameters */
assert_param(IS_PWR_STOP_MODE_REGULATOR_VOLTAGE(VoltageScaling));
/* Return the stop mode voltage range */
MODIFY_REG(PWR->PMCR, PWR_PMCR_SVOS, VoltageScaling);
return HAL_OK;
}
/**
* @brief Get the main internal regulator output voltage in STOP mode.
* @retval The actual applied VOS selection.
*/
uint32_t HAL_PWREx_GetStopModeVoltageRange(void)
{
/* Return the stop voltage scaling */
return (PWR->PMCR & PWR_PMCR_SVOS);
}
/**
* @}
*/
/** @defgroup PWREx_Exported_Functions_Group2 Voltage Monitoring Functions
* @brief Voltage monitoring functions
*
@verbatim
===============================================================================
##### Voltage Monitoring Functions #####
===============================================================================
[..]
@endverbatim
* @{
*/
/**
* @brief Configure the event mode and the voltage threshold detected by the
* Analog Voltage Detector (AVD).
* @param sConfigAVD : Pointer to an PWREx_AVDTypeDef structure that contains
* the configuration information for the AVD.
* @note Refer to the electrical characteristics of your device datasheet for
* more details about the voltage threshold corresponding to each
* detection level.
* @retval None.
*/
void HAL_PWREx_ConfigAVD(const PWREx_AVDTypeDef *sConfigAVD)
{
/* Check the parameters */
assert_param(IS_PWR_AVD_LEVEL(sConfigAVD->AVDLevel));
assert_param(IS_PWR_AVD_MODE(sConfigAVD->Mode));
/* Set the ALS[10:9] bits according to AVDLevel value */
MODIFY_REG(PWR->VMCR, PWR_VMCR_ALS, sConfigAVD->AVDLevel);
/* Clear any previous config */
__HAL_PWR_AVD_EXTI_DISABLE_EVENT();
__HAL_PWR_AVD_EXTI_DISABLE_IT();
__HAL_PWR_AVD_EXTI_DISABLE_RISING_EDGE();
__HAL_PWR_AVD_EXTI_DISABLE_FALLING_EDGE();
/* Configure the interrupt mode */
if ((sConfigAVD->Mode & AVD_MODE_IT) == AVD_MODE_IT)
{
__HAL_PWR_AVD_EXTI_ENABLE_IT();
}
/* Configure the event mode */
if ((sConfigAVD->Mode & AVD_MODE_EVT) == AVD_MODE_EVT)
{
__HAL_PWR_AVD_EXTI_ENABLE_EVENT();
}
/* Rising edge configuration */
if ((sConfigAVD->Mode & AVD_RISING_EDGE) == AVD_RISING_EDGE)
{
__HAL_PWR_AVD_EXTI_ENABLE_RISING_EDGE();
}
/* Falling edge configuration */
if ((sConfigAVD->Mode & AVD_FALLING_EDGE) == AVD_FALLING_EDGE)
{
__HAL_PWR_AVD_EXTI_ENABLE_FALLING_EDGE();
}
}
/**
* @brief Enable the Analog Voltage Detector (AVD).
* @retval None.
*/
void HAL_PWREx_EnableAVD(void)
{
/* Enable the Analog Voltage Detector */
SET_BIT(PWR->VMCR, PWR_VMCR_AVDEN);
}
/**
* @brief Disable the Analog Voltage Detector(AVD).
* @retval None.
*/
void HAL_PWREx_DisableAVD(void)
{
/* Disable the Analog Voltage Detector */
CLEAR_BIT(PWR->VMCR, PWR_VMCR_AVDEN);
}
#if defined (PWR_USBSCR_USB33DEN)
/**
* @brief Enable the USB voltage level detector.
* @retval None.
*/
void HAL_PWREx_EnableUSBVoltageDetector(void)
{
/* Enable the USB voltage detector */
SET_BIT(PWR->USBSCR, PWR_USBSCR_USB33DEN);
}
/**
* @brief Disable the USB voltage level detector.
* @retval None.
*/
void HAL_PWREx_DisableUSBVoltageDetector(void)
{
/* Disable the USB voltage detector */
CLEAR_BIT(PWR->USBSCR, PWR_USBSCR_USB33DEN);
}
/**
* @brief Enable VDDUSB supply.
* @note Remove VDDUSB electrical and logical isolation, once VDDUSB supply
* is present for consumption saving.
* @retval None.
*/
void HAL_PWREx_EnableVddUSB(void)
{
SET_BIT(PWR->USBSCR, PWR_USBSCR_USB33SV);
}
/**
* @brief Disable VDDUSB supply.
* @retval None.
*/
void HAL_PWREx_DisableVddUSB(void)
{
CLEAR_BIT(PWR->USBSCR, PWR_USBSCR_USB33SV);
}
#endif /* PWR_USBSCR_USB33DEN */
/**
* @brief Enable the VBAT and temperature monitoring.
* @retval None.
*/
void HAL_PWREx_EnableMonitoring(void)
{
SET_BIT(PWR->BDCR, PWR_BDCR_MONEN);
}
/**
* @brief Disable the VBAT and temperature monitoring.
* @retval None.
*/
void HAL_PWREx_DisableMonitoring(void)
{
CLEAR_BIT(PWR->BDCR, PWR_BDCR_MONEN);
}
#if defined (PWR_UCPDR_UCPD_STBY)
/**
* @brief Enable UCPD configuration memorization in Standby mode.
* @retval None.
*/
void HAL_PWREx_EnableUCPDStandbyMode(void)
{
SET_BIT(PWR->UCPDR, PWR_UCPDR_UCPD_STBY);
}
/**
* @brief Disable UCPD configuration memorization in Standby mode.
* @note This function must be called on exiting the Standby mode and before
* any UCPD configuration update.
* @retval None.
*/
void HAL_PWREx_DisableUCPDStandbyMode(void)
{
CLEAR_BIT(PWR->UCPDR, PWR_UCPDR_UCPD_STBY);
}
#endif /* PWR_UCPDR_UCPD_STBY */
#if defined (PWR_UCPDR_UCPD_DBDIS)
/**
* @brief Enable dead battery behavior.
* @note After exiting reset, the USB Type-C (dead battery) behavior is
* enabled, which may have a pull-down effect on CC1 and CC2 pins.
* It is recommended to disable it in all cases, either to stop this
* pull-down or to handover control to the UCPD (the UCPD must be
* initialized before doing the disable).
* @retval None.
*/
void HAL_PWREx_EnableUCPDDeadBattery(void)
{
CLEAR_BIT(PWR->UCPDR, PWR_UCPDR_UCPD_DBDIS);
}
/**
* @brief Disable dead battery behavior.
* @note After exiting reset, the USB Type-C (dead battery) behavior is
* enabled, which may have a pull-down effect on CC1 and CC2 pins.
* It is recommended to disable it in all cases, either to stop this
* pull-down or to handover control to the UCPD (the UCPD must be
* initialized before doing the disable).
* @retval None.
*/
void HAL_PWREx_DisableUCPDDeadBattery(void)
{
SET_BIT(PWR->UCPDR, PWR_UCPDR_UCPD_DBDIS);
}
#endif /* PWR_UCPDR_UCPD_DBDIS */
/**
* @brief Enable the Battery charging.
* @note When VDD is present, charge the external battery through an internal
* resistor.
* @param ResistorValue : Specifies the charging resistor.
* This parameter can be one of the following values :
* @arg PWR_BATTERY_CHARGING_RESISTOR_5 : 5 KOhm resistor.
* @arg PWR_BATTERY_CHARGING_RESISTOR_1_5 : 1.5 KOhm resistor.
* @retval None.
*/
void HAL_PWREx_EnableBatteryCharging(uint32_t ResistorValue)
{
/* Check the parameter */
assert_param(IS_PWR_BATTERY_RESISTOR_SELECT(ResistorValue));
/* Specify the charging resistor */
MODIFY_REG(PWR->BDCR, PWR_BDCR_VBRS, ResistorValue);
/* Enable the Battery charging */
SET_BIT(PWR->BDCR, PWR_BDCR_VBE);
}
/**
* @brief Disable the Battery charging.
* @retval None.
*/
void HAL_PWREx_DisableBatteryCharging(void)
{
CLEAR_BIT(PWR->BDCR, PWR_BDCR_VBE);
}
/**
* @brief Enable the booster to guarantee the analog switch AC performance when
* the VDD supply voltage is below 2V7.
* @note The VDD supply voltage can be monitored through the PVD and the PLS
* field bits.
* @retval None.
*/
void HAL_PWREx_EnableAnalogBooster(void)
{
/* Enable the Analog voltage */
SET_BIT(PWR->PMCR, PWR_PMCR_AVD_READY);
/* Enable VDDA booster */
SET_BIT(PWR->PMCR, PWR_PMCR_BOOSTE);
}
/**
* @brief Disable the analog booster.
* @retval None.
*/
void HAL_PWREx_DisableAnalogBooster(void)
{
/* Disable VDDA booster */
CLEAR_BIT(PWR->PMCR, PWR_PMCR_BOOSTE);
/* Disable the Analog voltage */
CLEAR_BIT(PWR->PMCR, PWR_PMCR_AVD_READY);
}
/**
* @brief This function handles the PWR PVD/AVD interrupt request.
* @note This API should be called under the PVD_AVD_IRQHandler().
* @note The use of this API is when the PVD and AVD are activated at the same time.
* @retval None
*/
void HAL_PWREx_PVD_AVD_IRQHandler(void)
{
/* Check PWR PVD AVD EXTI Rising flag */
if (__HAL_PWR_PVD_AVD_EXTI_GET_RISING_FLAG() != 0U)
{
/* Clear PWR PVD AVD EXTI Rising pending bit */
WRITE_REG(EXTI->RPR1, PWR_EXTI_LINE_AVD);
/* PWR PVD AVD Rising interrupt user callback */
HAL_PWREx_PVD_AVD_Rising_Callback();
}
/* Check PWR PVD AVD EXTI Falling flag */
if (__HAL_PWR_PVD_AVD_EXTI_GET_FALLING_FLAG() != 0U)
{
/* Clear PWR PVD AVD EXTI Falling pending bit */
WRITE_REG(EXTI->FPR1, PWR_EXTI_LINE_AVD);
/* PWR PVD AVD Falling interrupt user callback */
HAL_PWREx_PVD_AVD_Falling_Callback();
}
}
/**
* @brief PWR PVD AVD Rising interrupt callback.
* @retval None.
*/
__weak void HAL_PWREx_PVD_AVD_Rising_Callback(void)
{
/* NOTE : This function should not be modified, when the callback is needed,
the HAL_PWR_AVDCallback can be implemented in the user file
*/
}
/**
* @brief PWR PVD AVD Falling interrupt callback.
* @retval None.
*/
__weak void HAL_PWREx_PVD_AVD_Falling_Callback(void)
{
/* NOTE : This function should not be modified, when the callback is needed,
the HAL_PWR_AVDCallback can be implemented in the user file
*/
}
/**
* @}
*/
/** @defgroup PWREx_Exported_Functions_Group3 Wakeup Pins configuration Functions
* @brief Wakeup Pins configuration functions
*
@verbatim
===============================================================================
##### Wakeup Pins configuration Functions #####
===============================================================================
[..]
@endverbatim
* @{
*/
/**
* @brief Enable the Wake-up PINx functionality.
* @param sPinParams : Pointer to a PWREx_WakeupPinTypeDef structure that
* contains the configuration information for the wake-up
* Pin.
* @retval None.
*/
void HAL_PWREx_EnableWakeUpPin(const PWREx_WakeupPinTypeDef *sPinParams)
{
uint32_t pinConfig;
uint32_t regMask;
const uint32_t pullMask = PWR_WUCR_WUPPUPD1;
/* Check the parameters */
assert_param(IS_PWR_WAKEUP_PIN(sPinParams->WakeUpPin));
assert_param(IS_PWR_WAKEUP_PIN_POLARITY(sPinParams->PinPolarity));
assert_param(IS_PWR_WAKEUP_PIN_PULL(sPinParams->PinPull));
pinConfig = sPinParams->WakeUpPin | \
(sPinParams->PinPolarity << ((POSITION_VAL(sPinParams->WakeUpPin) + PWR_WUCR_WUPP1_Pos) & 0x1FU)) | \
(sPinParams->PinPull << (((POSITION_VAL(sPinParams->WakeUpPin) * PWR_WAKEUP_PINS_PULL_SHIFT_OFFSET) \
+ PWR_WUCR_WUPPUPD1_Pos) & 0x1FU));
regMask = sPinParams->WakeUpPin | \
(PWR_WUCR_WUPP1 << (POSITION_VAL(sPinParams->WakeUpPin) & 0x1FU)) | \
(pullMask << ((POSITION_VAL(sPinParams->WakeUpPin) * PWR_WAKEUP_PINS_PULL_SHIFT_OFFSET) & 0x1FU));
/* Enable and Specify the Wake-Up pin polarity and the pull configuration
for the event detection (rising or falling edge) */
MODIFY_REG(PWR->WUCR, regMask, pinConfig);
}
/**
* @brief Disable the Wake-up PINx functionality.
* @param WakeUpPinx : Specifies the Wake-Up pin to be disabled.
* This parameter can be one of the following values:
* @arg PWR_WAKEUP_PIN1
* @arg PWR_WAKEUP_PIN2
* @arg PWR_WAKEUP_PIN3
* @arg PWR_WAKEUP_PIN4
* @arg PWR_WAKEUP_PIN5
* @arg PWR_WAKEUP_PIN6
* @arg PWR_WAKEUP_PIN7
* @arg PWR_WAKEUP_PIN8
* @note The PWR_WAKEUP_PIN6, PWR_WAKEUP_PIN7 and PWR_WAKEUP_PIN8 are not available for
* STM32H503xx devices.
* @retval None
*/
void HAL_PWREx_DisableWakeUpPin(uint32_t WakeUpPinx)
{
/* Check the parameter */
assert_param(IS_PWR_WAKEUP_PIN(WakeUpPinx));
/* Disable the WakeUpPin */
CLEAR_BIT(PWR->WUCR, (PWR_WUCR_WUPEN & WakeUpPinx));
}
/**
* @}
*/
/** @defgroup PWREx_Exported_Functions_Group4 Memories Retention Functions
* @brief Memories retention functions
*
@verbatim
===============================================================================
##### Memories Retention Functions #####
===============================================================================
[..]
@endverbatim
* @{
*/
/**
* @brief Enable the Flash Power Down in Stop mode.
* @note When Flash Power Down is enabled the Flash memory enters low-power
* mode. This feature allows to
* obtain the best trade-off between low-power consumption and restart
* time when exiting from Stop mode.
* @retval None.
*/
void HAL_PWREx_EnableFlashPowerDown(void)
{
/* Enable the Flash Power Down */
SET_BIT(PWR->PMCR, PWR_PMCR_FLPS);
}
/**
* @brief Disable the Flash Power Down in Stop mode.
* @note When Flash Power Down is disabled the Flash memory is kept on
* normal mode. This feature allows
* to obtain the best trade-off between low-power consumption and
* restart time when exiting from Stop mode.
* @retval None.
*/
void HAL_PWREx_DisableFlashPowerDown(void)
{
/* Disable the Flash Power Down */
CLEAR_BIT(PWR->PMCR, PWR_PMCR_FLPS);
}
/**
* @brief Enable memory block shut-off in Stop mode
* @note In Stop mode, the content of the memory blocks is
* maintained. Further power optimization can be obtained by switching
* off some memory blocks. This optimization implies loss of the memory
* content. The user can select which memory is discarded during STOP
* mode by means of xxSO bits.
* @param MemoryBlock : Specifies the memory block to shut-off during Stop mode.
* This parameter can be one of the following values for STM32H573xx/STM32H563xx/STM32H562xx :
* @arg PWR_ETHERNET_MEMORY_BLOCK PWR_PMCR_ETHERNETSO : Ethernet shut-off control in Stop mode
* @arg PWR_RAM3_MEMORY_BLOCK PWR_PMCR_SRAM3SO : RAM3 shut-off control in Stop mode
* @arg PWR_RAM2_16_MEMORY_BLOCK PWR_PMCR_SRAM2_16SO : RAM2 16k byte shut-off control in Stop mode
* @arg PWR_RAM2_48_MEMORY_BLOCK PWR_PMCR_SRAM2_48SO : RAM2 48k byte shut-off control in Stop mode
* @arg PWR_RAM1_MEMORY_BLOCK PWR_PMCR_SRAM1SO : RAM1 shut-off control in Stop mode
* This parameter can be one of the following values for STM32H533xx/STM32H523xx :
* @arg PWR_RAM3_MEMORY_BLOCK PWR_PMCR_SRAM3SO : RAM3 shut-off control in Stop mode
* @arg PWR_RAM2_LOW_16_MEMORY_BLOCK PWR_PMCR_SRAM2_16LSO : RAM2 Low 16k byte shut-off control
* in Stop mode
* @arg PWR_RAM2_HIGH_16_MEMORY_BLOCK PWR_PMCR_SRAM2_16HSO : RAM2 High 16k byte shut-off control
* in Stop mode
* @arg PWR_RAM2_48_MEMORY_BLOCK PWR_PMCR_SRAM2_48SO : RAM2 48k byte shut-off control in Stop mode
* @arg PWR_RAM1_MEMORY_BLOCK PWR_PMCR_SRAM1SO : RAM1 shut-off control in Stop mode
* This parameter can be one of the following values for STM32H503xx :
* @arg PWR_RAM2_MEMORY_BLOCK PWR_PMCR_SRAM2SO : RAM2 shut-off control in Stop mode
* @arg PWR_RAM1_MEMORY_BLOCK PWR_PMCR_SRAM1SO : RAM1 shut-off control in Stop mode
* @retval None.
*/
void HAL_PWREx_EnableMemoryShutOff(uint32_t MemoryBlock)
{
/* Check the parameter */
assert_param(IS_PWR_MEMORY_BLOCK(MemoryBlock));
/* Enable memory block shut-off */
SET_BIT(PWR->PMCR, MemoryBlock);
}
/**
* @brief Disable memory block shut-off in Stop mode
* @param MemoryBlock : Specifies the memory block to keep content during
* Stop mode.
* This parameter can be one of the following values for STM32H573xx/STM32H563xx/STM32H562xx :
* @arg PWR_ETHERNET_MEMORY_BLOCK PWR_PMCR_ETHERNETSO : Ethernet shut-off control in Stop mode
* @arg PWR_RAM3_MEMORY_BLOCK PWR_PMCR_SRAM3SO : RAM3 shut-off control in Stop mode
* @arg PWR_RAM2_16_MEMORY_BLOCK PWR_PMCR_SRAM2_16SO : RAM2 16k byte shut-off control in Stop mode
* @arg PWR_RAM2_48_MEMORY_BLOCK PWR_PMCR_SRAM2_48SO : RAM2 48k byte shut-off control in Stop mode
* @arg PWR_RAM1_MEMORY_BLOCK PWR_PMCR_SRAM1SO : RAM1 shut-off control in Stop mode
* This parameter can be one of the following values for STM32H533xx/STM32H523xx :
* @arg PWR_RAM3_MEMORY_BLOCK PWR_PMCR_SRAM3SO : RAM3 shut-off control in Stop mode
* @arg PWR_RAM2_LOW_16_MEMORY_BLOCK PWR_PMCR_SRAM2_16LSO : RAM2 Low 16k byte shut-off control
* in Stop mode
* @arg PWR_RAM2_HIGH_16_MEMORY_BLOCK PWR_PMCR_SRAM2_16HSO : RAM2 High 16k byte shut-off control
* in Stop mode
* @arg PWR_RAM2_48_MEMORY_BLOCK PWR_PMCR_SRAM2_48SO : RAM2 48k byte shut-off control in Stop mode
* @arg PWR_RAM1_MEMORY_BLOCK PWR_PMCR_SRAM1SO : RAM1 shut-off control in Stop mode
* This parameter can be one of the following values for STM32H503xx :
* @arg PWR_RAM2_MEMORY_BLOCK PWR_PMCR_SRAM2SO : RAM2 shut-off control in Stop mode
* @arg PWR_RAM1_MEMORY_BLOCK PWR_PMCR_SRAM1SO : RAM1 shut-off control in Stop mode
* @retval None.
*/
void HAL_PWREx_DisableMemoryShutOff(uint32_t MemoryBlock)
{
/* Check the parameter */
assert_param(IS_PWR_MEMORY_BLOCK(MemoryBlock));
/* Disable memory block shut-off */
CLEAR_BIT(PWR->PMCR, MemoryBlock);
}
/**
* @brief Enable the Backup RAM retention in Standby and VBAT modes.
* @note If BREN is reset, the backup RAM can still be used in Run, Sleep and
* Stop modes. However, its content is lost in Standby, Shutdown and
* VBAT modes. This bit can be writte
* @retval None.
*/
HAL_StatusTypeDef HAL_PWREx_EnableBkupRAMRetention(void)
{
SET_BIT(PWR->BDCR, PWR_BDCR_BREN);
return HAL_OK;
}
/**
* @brief Disable the Backup RAM retention in Standby and VBAT modes.
* @note If BREN is reset, the backup RAM can still be used in Run, Sleep and
* Stop modes. However, its content is lost in Standby, Shutdown and
* VBAT modes. This bit can be write
* @retval None.
*/
void HAL_PWREx_DisableBkupRAMRetention(void)
{
CLEAR_BIT(PWR->BDCR, PWR_BDCR_BREN);
}
/**
* @}
*/
/** @defgroup PWREx_Exported_Functions_Group5 IO and JTAG Retention Functions
* @brief IO and JTAG Retention functions
*
@verbatim
===============================================================================
##### IO and JTAG Retention Functions #####
===============================================================================
[..]
In the Standby mode, the I/Os are by default in floating state. If the IORETEN bit in the
PWR_IORETR register is set, the I/Os output state is retained. IO Retention mode is
enabled for all IO except the IO support the standby functionality and JTAG IOs (PA13,
PA14, PA15 and PB4). When entering into Standby mode, the state of the output is
sampled, and pull-up or pull-down resistor are set to maintain the IO output during Standby
mode.
If the JTAGIORETEN bit in the PWR_IORETR register is set, the I/Os output state is
retained. IO Retention mode is enabled for PA13, PA14, PA15 and PB4 (default JTAG pullup/
pull-down after wakeup are not enabled).
@endverbatim
* @{
*/
/**
* @brief Enable GPIO state retention in Standby mode.
* @note When entering into standby mode, the output is sampled, and applied to the output IO during
* the standby power mode
* @retval None.
*/
void HAL_PWREx_EnableStandbyIORetention(void)
{
/* Enable GPIO state retention */
SET_BIT(PWR->IORETR, PWR_IORETR_IORETEN);
}
/**
* @brief Disable GPIO state retention in Standby mode.
* @retval None.
*/
void HAL_PWREx_DisableStandbyIORetention(void)
{
/* Disable GPIO state retention */
CLEAR_BIT(PWR->IORETR, PWR_IORETR_IORETEN);
}
/**
* @brief Enable JTAG IOs state retention in Standby mode.
* @note when entering into standby mode, the output is sampled, and applied to the output IO during
* the standby power mode
* @retval None.
*/
void HAL_PWREx_EnableStandbyJTAGIORetention(void)
{
/* Enable JTAG IOs state retention */
SET_BIT(PWR->IORETR, PWR_IORETR_JTAGIORETEN);
}
/**
* @brief Disable JTAG IOs state retention in Standby mode.
* @retval None.
*/
void HAL_PWREx_DisableStandbyJTAGIORetention(void)
{
/* Enable JTAG IOs state retention */
CLEAR_BIT(PWR->IORETR, PWR_IORETR_JTAGIORETEN);
}
/**
* @}
*/
#endif /* defined (HAL_PWR_MODULE_ENABLED) */
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,541 @@
/**
******************************************************************************
* @file stm32h5xx_hal_usart_ex.c
* @author MCD Application Team
* @brief Extended USART HAL module driver.
* This file provides firmware functions to manage the following extended
* functionalities of the Universal Synchronous Receiver Transmitter Peripheral (USART).
* + Peripheral Control functions
*
*
******************************************************************************
* @attention
*
* Copyright (c) 2023 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
==============================================================================
##### USART peripheral extended features #####
==============================================================================
(#) FIFO mode enabling/disabling and RX/TX FIFO threshold programming.
-@- When USART operates in FIFO mode, FIFO mode must be enabled prior
starting RX/TX transfers. Also RX/TX FIFO thresholds must be
configured prior starting RX/TX transfers.
(#) Slave mode enabling/disabling and NSS pin configuration.
-@- When USART operates in Slave mode, Slave mode must be enabled prior
starting RX/TX transfers.
@endverbatim
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "stm32h5xx_hal.h"
/** @addtogroup STM32H5xx_HAL_Driver
* @{
*/
/** @defgroup USARTEx USARTEx
* @brief USART Extended HAL module driver
* @{
*/
#ifdef HAL_USART_MODULE_ENABLED
/* Private typedef -----------------------------------------------------------*/
/** @defgroup USARTEx_Private_Constants USARTEx Private Constants
* @{
*/
/* USART RX FIFO depth */
#define RX_FIFO_DEPTH 8U
/* USART TX FIFO depth */
#define TX_FIFO_DEPTH 8U
/**
* @}
*/
/* Private define ------------------------------------------------------------*/
/* Private macros ------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/** @defgroup USARTEx_Private_Functions USARTEx Private Functions
* @{
*/
static void USARTEx_SetNbDataToProcess(USART_HandleTypeDef *husart);
/**
* @}
*/
/* Exported functions --------------------------------------------------------*/
/** @defgroup USARTEx_Exported_Functions USARTEx Exported Functions
* @{
*/
/** @defgroup USARTEx_Exported_Functions_Group1 IO operation functions
* @brief Extended USART Transmit/Receive functions
*
@verbatim
===============================================================================
##### IO operation functions #####
===============================================================================
This subsection provides a set of FIFO mode related callback functions.
(#) TX/RX Fifos Callbacks:
(+) HAL_USARTEx_RxFifoFullCallback()
(+) HAL_USARTEx_TxFifoEmptyCallback()
@endverbatim
* @{
*/
/**
* @brief USART RX Fifo full callback.
* @param husart USART handle.
* @retval None
*/
__weak void HAL_USARTEx_RxFifoFullCallback(USART_HandleTypeDef *husart)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(husart);
/* NOTE : This function should not be modified, when the callback is needed,
the HAL_USARTEx_RxFifoFullCallback can be implemented in the user file.
*/
}
/**
* @brief USART TX Fifo empty callback.
* @param husart USART handle.
* @retval None
*/
__weak void HAL_USARTEx_TxFifoEmptyCallback(USART_HandleTypeDef *husart)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(husart);
/* NOTE : This function should not be modified, when the callback is needed,
the HAL_USARTEx_TxFifoEmptyCallback can be implemented in the user file.
*/
}
/**
* @}
*/
/** @defgroup USARTEx_Exported_Functions_Group2 Peripheral Control functions
* @brief Extended Peripheral Control functions
*
@verbatim
===============================================================================
##### Peripheral Control functions #####
===============================================================================
[..] This section provides the following functions:
(+) HAL_USARTEx_EnableSPISlaveMode() API enables the SPI slave mode
(+) HAL_USARTEx_DisableSPISlaveMode() API disables the SPI slave mode
(+) HAL_USARTEx_ConfigNSS API configures the Slave Select input pin (NSS)
(+) HAL_USARTEx_EnableFifoMode() API enables the FIFO mode
(+) HAL_USARTEx_DisableFifoMode() API disables the FIFO mode
(+) HAL_USARTEx_SetTxFifoThreshold() API sets the TX FIFO threshold
(+) HAL_USARTEx_SetRxFifoThreshold() API sets the RX FIFO threshold
@endverbatim
* @{
*/
/**
* @brief Enable the SPI slave mode.
* @note When the USART operates in SPI slave mode, it handles data flow using
* the serial interface clock derived from the external SCLK signal
* provided by the external master SPI device.
* @note In SPI slave mode, the USART must be enabled before starting the master
* communications (or between frames while the clock is stable). Otherwise,
* if the USART slave is enabled while the master is in the middle of a
* frame, it will become desynchronized with the master.
* @note The data register of the slave needs to be ready before the first edge
* of the communication clock or before the end of the ongoing communication,
* otherwise the SPI slave will transmit zeros.
* @param husart USART handle.
* @retval HAL status
*/
HAL_StatusTypeDef HAL_USARTEx_EnableSlaveMode(USART_HandleTypeDef *husart)
{
uint32_t tmpcr1;
/* Check parameters */
assert_param(IS_UART_SPI_SLAVE_INSTANCE(husart->Instance));
/* Process Locked */
__HAL_LOCK(husart);
husart->State = HAL_USART_STATE_BUSY;
/* Save actual USART configuration */
tmpcr1 = READ_REG(husart->Instance->CR1);
/* Disable USART */
__HAL_USART_DISABLE(husart);
/* In SPI slave mode mode, the following bits must be kept cleared:
- LINEN and CLKEN bit in the USART_CR2 register
- HDSEL, SCEN and IREN bits in the USART_CR3 register.*/
CLEAR_BIT(husart->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN));
CLEAR_BIT(husart->Instance->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN));
/* Enable SPI slave mode */
SET_BIT(husart->Instance->CR2, USART_CR2_SLVEN);
/* Restore USART configuration */
WRITE_REG(husart->Instance->CR1, tmpcr1);
husart->SlaveMode = USART_SLAVEMODE_ENABLE;
husart->State = HAL_USART_STATE_READY;
/* Enable USART */
__HAL_USART_ENABLE(husart);
/* Process Unlocked */
__HAL_UNLOCK(husart);
return HAL_OK;
}
/**
* @brief Disable the SPI slave mode.
* @param husart USART handle.
* @retval HAL status
*/
HAL_StatusTypeDef HAL_USARTEx_DisableSlaveMode(USART_HandleTypeDef *husart)
{
uint32_t tmpcr1;
/* Check parameters */
assert_param(IS_UART_SPI_SLAVE_INSTANCE(husart->Instance));
/* Process Locked */
__HAL_LOCK(husart);
husart->State = HAL_USART_STATE_BUSY;
/* Save actual USART configuration */
tmpcr1 = READ_REG(husart->Instance->CR1);
/* Disable USART */
__HAL_USART_DISABLE(husart);
/* Disable SPI slave mode */
CLEAR_BIT(husart->Instance->CR2, USART_CR2_SLVEN);
/* Restore USART configuration */
WRITE_REG(husart->Instance->CR1, tmpcr1);
husart->SlaveMode = USART_SLAVEMODE_DISABLE;
husart->State = HAL_USART_STATE_READY;
/* Process Unlocked */
__HAL_UNLOCK(husart);
return HAL_OK;
}
/**
* @brief Configure the Slave Select input pin (NSS).
* @note Software NSS management: SPI slave will always be selected and NSS
* input pin will be ignored.
* @note Hardware NSS management: the SPI slave selection depends on NSS
* input pin. The slave is selected when NSS is low and deselected when
* NSS is high.
* @param husart USART handle.
* @param NSSConfig NSS configuration.
* This parameter can be one of the following values:
* @arg @ref USART_NSS_HARD
* @arg @ref USART_NSS_SOFT
* @retval HAL status
*/
HAL_StatusTypeDef HAL_USARTEx_ConfigNSS(USART_HandleTypeDef *husart, uint32_t NSSConfig)
{
uint32_t tmpcr1;
/* Check parameters */
assert_param(IS_UART_SPI_SLAVE_INSTANCE(husart->Instance));
assert_param(IS_USART_NSS(NSSConfig));
/* Process Locked */
__HAL_LOCK(husart);
husart->State = HAL_USART_STATE_BUSY;
/* Save actual USART configuration */
tmpcr1 = READ_REG(husart->Instance->CR1);
/* Disable USART */
__HAL_USART_DISABLE(husart);
/* Program DIS_NSS bit in the USART_CR2 register */
MODIFY_REG(husart->Instance->CR2, USART_CR2_DIS_NSS, NSSConfig);
/* Restore USART configuration */
WRITE_REG(husart->Instance->CR1, tmpcr1);
husart->State = HAL_USART_STATE_READY;
/* Process Unlocked */
__HAL_UNLOCK(husart);
return HAL_OK;
}
/**
* @brief Enable the FIFO mode.
* @param husart USART handle.
* @retval HAL status
*/
HAL_StatusTypeDef HAL_USARTEx_EnableFifoMode(USART_HandleTypeDef *husart)
{
uint32_t tmpcr1;
/* Check parameters */
assert_param(IS_UART_FIFO_INSTANCE(husart->Instance));
/* Process Locked */
__HAL_LOCK(husart);
husart->State = HAL_USART_STATE_BUSY;
/* Save actual USART configuration */
tmpcr1 = READ_REG(husart->Instance->CR1);
/* Disable USART */
__HAL_USART_DISABLE(husart);
/* Enable FIFO mode */
SET_BIT(tmpcr1, USART_CR1_FIFOEN);
husart->FifoMode = USART_FIFOMODE_ENABLE;
/* Restore USART configuration */
WRITE_REG(husart->Instance->CR1, tmpcr1);
/* Determine the number of data to process during RX/TX ISR execution */
USARTEx_SetNbDataToProcess(husart);
husart->State = HAL_USART_STATE_READY;
/* Process Unlocked */
__HAL_UNLOCK(husart);
return HAL_OK;
}
/**
* @brief Disable the FIFO mode.
* @param husart USART handle.
* @retval HAL status
*/
HAL_StatusTypeDef HAL_USARTEx_DisableFifoMode(USART_HandleTypeDef *husart)
{
uint32_t tmpcr1;
/* Check parameters */
assert_param(IS_UART_FIFO_INSTANCE(husart->Instance));
/* Process Locked */
__HAL_LOCK(husart);
husart->State = HAL_USART_STATE_BUSY;
/* Save actual USART configuration */
tmpcr1 = READ_REG(husart->Instance->CR1);
/* Disable USART */
__HAL_USART_DISABLE(husart);
/* Disable FIFO mode */
CLEAR_BIT(tmpcr1, USART_CR1_FIFOEN);
husart->FifoMode = USART_FIFOMODE_DISABLE;
/* Restore USART configuration */
WRITE_REG(husart->Instance->CR1, tmpcr1);
husart->State = HAL_USART_STATE_READY;
/* Process Unlocked */
__HAL_UNLOCK(husart);
return HAL_OK;
}
/**
* @brief Set the TXFIFO threshold.
* @param husart USART handle.
* @param Threshold TX FIFO threshold value
* This parameter can be one of the following values:
* @arg @ref USART_TXFIFO_THRESHOLD_1_8
* @arg @ref USART_TXFIFO_THRESHOLD_1_4
* @arg @ref USART_TXFIFO_THRESHOLD_1_2
* @arg @ref USART_TXFIFO_THRESHOLD_3_4
* @arg @ref USART_TXFIFO_THRESHOLD_7_8
* @arg @ref USART_TXFIFO_THRESHOLD_8_8
* @retval HAL status
*/
HAL_StatusTypeDef HAL_USARTEx_SetTxFifoThreshold(USART_HandleTypeDef *husart, uint32_t Threshold)
{
uint32_t tmpcr1;
/* Check parameters */
assert_param(IS_UART_FIFO_INSTANCE(husart->Instance));
assert_param(IS_USART_TXFIFO_THRESHOLD(Threshold));
/* Process Locked */
__HAL_LOCK(husart);
husart->State = HAL_USART_STATE_BUSY;
/* Save actual USART configuration */
tmpcr1 = READ_REG(husart->Instance->CR1);
/* Disable USART */
__HAL_USART_DISABLE(husart);
/* Update TX threshold configuration */
MODIFY_REG(husart->Instance->CR3, USART_CR3_TXFTCFG, Threshold);
/* Determine the number of data to process during RX/TX ISR execution */
USARTEx_SetNbDataToProcess(husart);
/* Restore USART configuration */
WRITE_REG(husart->Instance->CR1, tmpcr1);
husart->State = HAL_USART_STATE_READY;
/* Process Unlocked */
__HAL_UNLOCK(husart);
return HAL_OK;
}
/**
* @brief Set the RXFIFO threshold.
* @param husart USART handle.
* @param Threshold RX FIFO threshold value
* This parameter can be one of the following values:
* @arg @ref USART_RXFIFO_THRESHOLD_1_8
* @arg @ref USART_RXFIFO_THRESHOLD_1_4
* @arg @ref USART_RXFIFO_THRESHOLD_1_2
* @arg @ref USART_RXFIFO_THRESHOLD_3_4
* @arg @ref USART_RXFIFO_THRESHOLD_7_8
* @arg @ref USART_RXFIFO_THRESHOLD_8_8
* @retval HAL status
*/
HAL_StatusTypeDef HAL_USARTEx_SetRxFifoThreshold(USART_HandleTypeDef *husart, uint32_t Threshold)
{
uint32_t tmpcr1;
/* Check the parameters */
assert_param(IS_UART_FIFO_INSTANCE(husart->Instance));
assert_param(IS_USART_RXFIFO_THRESHOLD(Threshold));
/* Process Locked */
__HAL_LOCK(husart);
husart->State = HAL_USART_STATE_BUSY;
/* Save actual USART configuration */
tmpcr1 = READ_REG(husart->Instance->CR1);
/* Disable USART */
__HAL_USART_DISABLE(husart);
/* Update RX threshold configuration */
MODIFY_REG(husart->Instance->CR3, USART_CR3_RXFTCFG, Threshold);
/* Determine the number of data to process during RX/TX ISR execution */
USARTEx_SetNbDataToProcess(husart);
/* Restore USART configuration */
WRITE_REG(husart->Instance->CR1, tmpcr1);
husart->State = HAL_USART_STATE_READY;
/* Process Unlocked */
__HAL_UNLOCK(husart);
return HAL_OK;
}
/**
* @}
*/
/**
* @}
*/
/** @addtogroup USARTEx_Private_Functions
* @{
*/
/**
* @brief Calculate the number of data to process in RX/TX ISR.
* @note The RX FIFO depth and the TX FIFO depth is extracted from
* the USART configuration registers.
* @param husart USART handle.
* @retval None
*/
static void USARTEx_SetNbDataToProcess(USART_HandleTypeDef *husart)
{
uint8_t rx_fifo_depth;
uint8_t tx_fifo_depth;
uint8_t rx_fifo_threshold;
uint8_t tx_fifo_threshold;
/* 2 0U/1U added for MISRAC2012-Rule-18.1_b and MISRAC2012-Rule-18.1_d */
static const uint8_t numerator[] = {1U, 1U, 1U, 3U, 7U, 1U, 0U, 0U};
static const uint8_t denominator[] = {8U, 4U, 2U, 4U, 8U, 1U, 1U, 1U};
if (husart->FifoMode == USART_FIFOMODE_DISABLE)
{
husart->NbTxDataToProcess = 1U;
husart->NbRxDataToProcess = 1U;
}
else
{
rx_fifo_depth = RX_FIFO_DEPTH;
tx_fifo_depth = TX_FIFO_DEPTH;
rx_fifo_threshold = (uint8_t)((READ_BIT(husart->Instance->CR3,
USART_CR3_RXFTCFG) >> USART_CR3_RXFTCFG_Pos) & 0xFFU);
tx_fifo_threshold = (uint8_t)((READ_BIT(husart->Instance->CR3,
USART_CR3_TXFTCFG) >> USART_CR3_TXFTCFG_Pos) & 0xFFU);
husart->NbTxDataToProcess = ((uint16_t)tx_fifo_depth * numerator[tx_fifo_threshold]) /
(uint16_t)denominator[tx_fifo_threshold];
husart->NbRxDataToProcess = ((uint16_t)rx_fifo_depth * numerator[rx_fifo_threshold]) /
(uint16_t)denominator[rx_fifo_threshold];
}
}
/**
* @}
*/
#endif /* HAL_USART_MODULE_ENABLED */
/**
* @}
*/
/**
* @}
*/